put_row.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  1. /*!
  2. \file raster/put_row.c
  3. \brief Raster library - Put raster row
  4. (C) 2003-2009 by the GRASS Development Team
  5. This program is free software under the GNU General Public License
  6. (>=v2). Read the file COPYING that comes with GRASS for details.
  7. \author Original author CERL
  8. */
  9. /**********************************************************************
  10. **********************************************************************/
  11. #include <string.h>
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14. #include <unistd.h>
  15. #include <fcntl.h>
  16. #include <grass/config.h>
  17. #include <grass/raster.h>
  18. #include <grass/glocale.h>
  19. #include "R.h"
  20. static void put_raster_row(int, const void *, RASTER_MAP_TYPE, int);
  21. /*!
  22. \brief Writes the next row for cell/fcell/dcell file
  23. Writes the next row for the cell file opened on 'fd' from 'buf' All
  24. writes go into NEW files that exactly match the current window. The
  25. file must have been opened with Rast_open_new() and be written
  26. sequentially, ie no skipping rows.
  27. When the null values are embeded into the data, corresponding cells
  28. are changed to 0's and the corresponding null value row is written
  29. into null file.
  30. A map cannot be copied using Rast_get_row() and
  31. Rast_put_row(). The former resamples the data of the original
  32. map into a row buffer that matches the current window. The later
  33. writes out rows associated with the window.
  34. Keeps track of the minimum and maximum cell value for use in
  35. updating the range file upon close of the cell file. HOWEVER when
  36. nulls are not embeded, the cells are considered 0's as far as
  37. updating range is concerned, even if the corresponding cell is null
  38. in the resulting null file, so programmer should be carefult to set
  39. all the null values using Rast_set_null_value() or
  40. G_insert_d_null_values() or G_insert_f_null_values().
  41. \param fd file descriptor where data is to be written
  42. \param buf buffer holding data
  43. \param data_type raster map type (CELL_TYPE, FCELL_TYPE, DCELL_TYPE)
  44. \return void
  45. */
  46. void Rast_put_row(int fd, const void *buf, RASTER_MAP_TYPE data_type)
  47. {
  48. put_raster_row(fd, buf, data_type, data_type);
  49. }
  50. /*!
  51. \brief Writes the next row for cell file (CELL version)
  52. See Rast_put_row() for details.
  53. \param fd file descriptor where data is to be written
  54. \param buf buffer holding data
  55. \return void
  56. */
  57. void Rast_put_c_row(int fd, const CELL * buf)
  58. {
  59. Rast_put_row(fd, buf, CELL_TYPE);
  60. }
  61. /*!
  62. \brief Writes the next row for fcell file (FCELL version)
  63. See Rast_put_row() for details.
  64. \param fd file descriptor where data is to be written
  65. \param buf buffer holding data
  66. \return void
  67. */
  68. void Rast_put_f_row(int fd, const FCELL * buf)
  69. {
  70. Rast_put_row(fd, buf, FCELL_TYPE);
  71. }
  72. /*!
  73. \brief Writes the next row for dcell file (DCELL version)
  74. See Rast_put_row() for details.
  75. \param fd file descriptor where data is to be written
  76. \param buf buffer holding data
  77. \return void
  78. */
  79. void Rast_put_d_row(int fd, const DCELL * buf)
  80. {
  81. Rast_put_row(fd, buf, DCELL_TYPE);
  82. }
  83. static void write_data(int fd, int row, unsigned char *buf, int n)
  84. {
  85. struct fileinfo *fcb = &R__.fileinfo[fd];
  86. ssize_t nwrite = fcb->nbytes * n;
  87. if (write(fcb->data_fd, buf, nwrite) != nwrite)
  88. G_fatal_error(_("Error writing uncompressed FP data for row %d of <%s>"),
  89. row, fcb->name);
  90. }
  91. static void write_data_compressed(int fd, int row, unsigned char *buf, int n)
  92. {
  93. struct fileinfo *fcb = &R__.fileinfo[fd];
  94. int nwrite = fcb->nbytes * n;
  95. if (G_zlib_write(fcb->data_fd, buf, nwrite) < 0)
  96. G_fatal_error(_("Error writing compressed FP data for row %d of <%s>"),
  97. row, fcb->name);
  98. }
  99. static void set_file_pointer(int fd, int row)
  100. {
  101. struct fileinfo *fcb = &R__.fileinfo[fd];
  102. fcb->row_ptr[row] = lseek(fcb->data_fd, 0L, SEEK_CUR);
  103. }
  104. static void convert_float(float *work_buf, int size, char *null_buf,
  105. const FCELL *rast, int row, int n)
  106. {
  107. int i;
  108. for (i = 0; i < n; i++) {
  109. FCELL f;
  110. /* substitute embeded null vals by 0's */
  111. if (Rast_is_f_null_value(&rast[i])) {
  112. f = 0.;
  113. null_buf[i] = 1;
  114. }
  115. else
  116. f = rast[i];
  117. G_xdr_put_float(&work_buf[i], &f);
  118. }
  119. }
  120. static void convert_double(double *work_buf, int size, char *null_buf,
  121. const DCELL *rast, int row, int n)
  122. {
  123. int i;
  124. for (i = 0; i < n; i++) {
  125. DCELL d;
  126. /* substitute embeded null vals by 0's */
  127. if (Rast_is_d_null_value(&rast[i])) {
  128. d = 0.;
  129. null_buf[i] = 1;
  130. }
  131. else
  132. d = rast[i];
  133. G_xdr_put_double(&work_buf[i], &d);
  134. }
  135. }
  136. /* writes data to fcell file for either full or partial rows */
  137. static void put_fp_data(int fd, char *null_buf, const void *rast,
  138. int row, int n, RASTER_MAP_TYPE data_type)
  139. {
  140. struct fileinfo *fcb = &R__.fileinfo[fd];
  141. int compressed = (fcb->open_mode == OPEN_NEW_COMPRESSED);
  142. int size = fcb->nbytes * fcb->cellhd.cols;
  143. void *work_buf;
  144. if (row < 0 || row >= fcb->cellhd.rows)
  145. return;
  146. if (n <= 0)
  147. return;
  148. work_buf = G__alloca(size + 1);
  149. if (compressed)
  150. set_file_pointer(fd, row);
  151. if (data_type == FCELL_TYPE)
  152. convert_float(work_buf, size, null_buf, rast, row, n);
  153. else
  154. convert_double(work_buf, size, null_buf, rast, row, n);
  155. if (compressed)
  156. write_data_compressed(fd, row, work_buf, n);
  157. else
  158. write_data(fd, row, work_buf, n);
  159. G__freea(work_buf);
  160. }
  161. static void convert_int(unsigned char *wk, char *null_buf, const CELL * rast,
  162. int n, int len, int zeros_r_nulls)
  163. {
  164. int i;
  165. /* transform CELL data into non-machine dependent multi-byte format */
  166. for (i = 0; i < n; i++) {
  167. CELL v = rast[i];
  168. int neg;
  169. int k;
  170. /* substitute embeded null vals by 0's */
  171. if (Rast_is_c_null_value(&v)) {
  172. v = 0;
  173. null_buf[i] = 1;
  174. }
  175. else if (zeros_r_nulls && !v)
  176. null_buf[i] = 1;
  177. /* negatives */
  178. if (v < 0) {
  179. neg = 1;
  180. v = -v;
  181. }
  182. else
  183. neg = 0;
  184. /* copy byte by byte */
  185. for (k = len - 1; k >= 0; k--) {
  186. wk[k] = v & 0xff;
  187. v >>= 8;
  188. }
  189. /* set negative bit in first byte */
  190. if (neg)
  191. wk[0] |= 0x80;
  192. wk += len;
  193. }
  194. }
  195. static int count_bytes(const unsigned char *wk, int n, int len)
  196. {
  197. int i, j;
  198. for (i = 0; i < len - 1; i++)
  199. for (j = 0; j < n; j++)
  200. if (wk[j * len + i] != 0)
  201. return len - i;
  202. return 1;
  203. }
  204. static void trim_bytes(unsigned char *wk, int n, int slen, int trim)
  205. {
  206. unsigned char *wk2 = wk;
  207. int i, j;
  208. for (i = 0; i < n; i++) {
  209. for (j = 0; j < trim; j++)
  210. wk++;
  211. for (; j < slen; j++)
  212. *wk2++ = *wk++;
  213. }
  214. }
  215. static int same(const unsigned char *x, const unsigned char *y, int n)
  216. {
  217. return (memcmp(x, y, n) == 0);
  218. }
  219. static int count_run(const unsigned char *src, int n, int nbytes)
  220. {
  221. const unsigned char *cur = src + nbytes;
  222. int i;
  223. for (i = 1; i < n; i++) {
  224. if (i == 255 || !same(cur, src, nbytes))
  225. return i;
  226. cur += nbytes;
  227. }
  228. return n;
  229. }
  230. static int rle_compress(unsigned char *dst, unsigned char *src, int n,
  231. int nbytes)
  232. {
  233. int nwrite = 0;
  234. int total = nbytes * n;
  235. while (n > 0) {
  236. int count;
  237. nwrite += nbytes + 1;
  238. if (nwrite >= total)
  239. return 0;
  240. count = count_run(src, n, nbytes);
  241. *dst++ = count;
  242. memcpy(dst, src, nbytes);
  243. dst += nbytes;
  244. src += count * nbytes;
  245. n -= count;
  246. }
  247. return nwrite;
  248. }
  249. static int zlib_compress(unsigned char *dst, unsigned char *src, int n,
  250. int nbytes)
  251. {
  252. int total = nbytes * n;
  253. int nwrite = G_zlib_compress(src, total, dst, total);
  254. return (nwrite >= total) ? 0 : nwrite;
  255. }
  256. static void put_data(int fd, char *null_buf, const CELL * cell,
  257. int row, int n, int zeros_r_nulls)
  258. {
  259. struct fileinfo *fcb = &R__.fileinfo[fd];
  260. int compressed = fcb->cellhd.compressed;
  261. int len = compressed ? sizeof(CELL) : fcb->nbytes;
  262. unsigned char *work_buf, *wk;
  263. ssize_t nwrite;
  264. if (row < 0 || row >= fcb->cellhd.rows)
  265. return;
  266. if (n <= 0)
  267. return;
  268. work_buf = G__alloca(fcb->cellhd.cols * sizeof(CELL) + 1);
  269. wk = work_buf;
  270. if (compressed)
  271. set_file_pointer(fd, row);
  272. if (compressed)
  273. wk++;
  274. convert_int(wk, null_buf, cell, n, len, zeros_r_nulls);
  275. if (compressed) {
  276. unsigned char *wk = work_buf + 1;
  277. int nbytes = count_bytes(wk, n, len);
  278. unsigned char *compressed_buf;
  279. int total;
  280. if (fcb->nbytes < nbytes)
  281. fcb->nbytes = nbytes;
  282. /* first trim away zero high bytes */
  283. if (nbytes < len)
  284. trim_bytes(wk, n, len, len - nbytes);
  285. total = nbytes * n;
  286. compressed_buf = G__alloca(total + 1);
  287. compressed_buf[0] = work_buf[0] = nbytes;
  288. /* then compress the data */
  289. nwrite = compressed == 1
  290. ? rle_compress(compressed_buf + 1, work_buf + 1, n, nbytes)
  291. : zlib_compress(compressed_buf + 1, work_buf + 1, n, nbytes);
  292. if (nwrite > 0) {
  293. nwrite++;
  294. if (write(fcb->data_fd, compressed_buf, nwrite) != nwrite)
  295. G_fatal_error(_("Error writing compressed data for row %d of <%s>"),
  296. row, fcb->name);
  297. }
  298. else {
  299. nwrite = nbytes * n + 1;
  300. if (write(fcb->data_fd, work_buf, nwrite) != nwrite)
  301. G_fatal_error(_("Error writing compressed data for row %d of <%s>"),
  302. row, fcb->name);
  303. }
  304. G__freea(compressed_buf);
  305. }
  306. else {
  307. nwrite = fcb->nbytes * n;
  308. if (write(fcb->data_fd, work_buf, nwrite) != nwrite)
  309. G_fatal_error(_("Error writing uncompressed data for row %d of <%s>"),
  310. row, fcb->name);
  311. }
  312. G__freea(work_buf);
  313. }
  314. static void put_data_gdal(int fd, const void *rast, int row, int n,
  315. int zeros_r_nulls, RASTER_MAP_TYPE map_type)
  316. {
  317. #ifdef HAVE_GDAL
  318. struct fileinfo *fcb = &R__.fileinfo[fd];
  319. int size = Rast_cell_size(map_type);
  320. DCELL null_val = fcb->gdal->null_val;
  321. const void *src;
  322. void *work_buf, *dst;
  323. GDALDataType datatype;
  324. CPLErr err;
  325. int i;
  326. if (row < 0 || row >= fcb->cellhd.rows)
  327. return;
  328. if (n <= 0)
  329. return;
  330. work_buf = G__alloca(n * size);
  331. switch (map_type) {
  332. case CELL_TYPE:
  333. datatype = GDT_Int32;
  334. break;
  335. case FCELL_TYPE:
  336. datatype = GDT_Float32;
  337. break;
  338. case DCELL_TYPE:
  339. datatype = GDT_Float64;
  340. break;
  341. }
  342. src = rast;
  343. dst = work_buf;
  344. for (i = 0; i < n; i++) {
  345. if (Rast_is_null_value(src, map_type) ||
  346. (zeros_r_nulls && !*(CELL *) src))
  347. Rast_set_d_value(dst, null_val, map_type);
  348. else
  349. memcpy(dst, src, size);
  350. src = G_incr_void_ptr(src, size);
  351. dst = G_incr_void_ptr(dst, size);
  352. }
  353. err = Rast_gdal_raster_IO(fcb->gdal->band, GF_Write, 0, row, n, 1,
  354. work_buf, n, 1, datatype, 0, 0);
  355. G__freea(work_buf);
  356. if (err != CE_None)
  357. G_fatal_error(_("Error writing data via GDAL for row %d of <%s>"),
  358. row, fcb->name);
  359. #endif
  360. }
  361. static void put_raster_data(int fd, char *null_buf, const void *rast,
  362. int row, int n,
  363. int zeros_r_nulls, RASTER_MAP_TYPE map_type)
  364. {
  365. struct fileinfo *fcb = &R__.fileinfo[fd];
  366. if (fcb->gdal)
  367. put_data_gdal(fd, rast, row, n, zeros_r_nulls, map_type);
  368. else if (map_type == CELL_TYPE)
  369. put_data(fd, null_buf, rast, row, n, zeros_r_nulls);
  370. else
  371. put_fp_data(fd, null_buf, rast, row, n, map_type);
  372. }
  373. static void put_null_data(int fd, const char *flags, int row)
  374. {
  375. struct fileinfo *fcb = &R__.fileinfo[fd];
  376. if (fcb->null_fd < 0)
  377. G_fatal_error(_("No null file for <%s>"), fcb->name);
  378. Rast__convert_01_flags(flags, fcb->null_bits,
  379. fcb->cellhd.cols);
  380. Rast__write_null_bits(fcb->null_fd, fcb->null_bits, row,
  381. fcb->cellhd.cols, fd);
  382. }
  383. static void put_null_value_row(int fd, const char *buf)
  384. {
  385. struct fileinfo *fcb = &R__.fileinfo[fd];
  386. if (fcb->gdal)
  387. G_fatal_error(_("GDAL output doesn't support writing null rows separately"));
  388. put_null_data(fd, buf, fcb->null_cur_row);
  389. fcb->null_cur_row++;
  390. }
  391. /*!
  392. \brief Open null file for write
  393. \param fd file descriptor of raster cell data file
  394. \return field descriptor of null data file
  395. */
  396. int Rast__open_null_write(int fd)
  397. {
  398. struct fileinfo *fcb = &R__.fileinfo[fd];
  399. int null_fd;
  400. if (access(fcb->null_temp_name, 0) != 0)
  401. G_fatal_error(_("Unable to find a temporary null file <%s>"),
  402. fcb->null_temp_name);
  403. null_fd = open(fcb->null_temp_name, O_WRONLY);
  404. if (null_fd < 0)
  405. G_fatal_error(_("Unable to open null file <%s>"),
  406. fcb->null_temp_name);
  407. return null_fd;
  408. }
  409. /*!
  410. \brief Write null data
  411. \param null_fd file descriptor of null file where data is to be written
  412. \param flags ?
  413. \param row row number
  414. \param col col number
  415. \param fd file descriptor of cell data file
  416. \return void
  417. */
  418. void Rast__write_null_bits(int null_fd, const unsigned char *flags, int row,
  419. int cols, int fd)
  420. {
  421. off_t offset;
  422. size_t size;
  423. size = Rast__null_bitstream_size(cols);
  424. offset = (off_t) size *row;
  425. if (lseek(null_fd, offset, SEEK_SET) < 0)
  426. G_fatal_error(_("Error writing null row %d"), row);
  427. if (write(null_fd, flags, size) != size)
  428. G_fatal_error(_("Error writing null row %d"), row);
  429. }
  430. static void convert_and_write_if(int fd, const void *vbuf)
  431. {
  432. const CELL *buf = vbuf;
  433. struct fileinfo *fcb = &R__.fileinfo[fd];
  434. FCELL *p = (FCELL *) fcb->data;
  435. int i;
  436. for (i = 0; i < fcb->cellhd.cols; i++)
  437. if (Rast_is_c_null_value(&buf[i]))
  438. Rast_set_f_null_value(&p[i], 1);
  439. else
  440. p[i] = (FCELL) buf[i];
  441. Rast_put_f_row(fd, p);
  442. }
  443. static void convert_and_write_df(int fd, const void *vbuf)
  444. {
  445. const DCELL *buf = vbuf;
  446. struct fileinfo *fcb = &R__.fileinfo[fd];
  447. FCELL *p = (FCELL *) fcb->data;
  448. int i;
  449. for (i = 0; i < fcb->cellhd.cols; i++)
  450. if (Rast_is_d_null_value(&buf[i]))
  451. Rast_set_f_null_value(&p[i], 1);
  452. else
  453. p[i] = (FCELL) buf[i];
  454. Rast_put_f_row(fd, p);
  455. }
  456. static void convert_and_write_id(int fd, const void *vbuf)
  457. {
  458. const CELL *buf = vbuf;
  459. struct fileinfo *fcb = &R__.fileinfo[fd];
  460. DCELL *p = (DCELL *) fcb->data;
  461. int i;
  462. for (i = 0; i < fcb->cellhd.cols; i++)
  463. if (Rast_is_c_null_value(&buf[i]))
  464. Rast_set_d_null_value(&p[i], 1);
  465. else
  466. p[i] = (DCELL) buf[i];
  467. Rast_put_d_row(fd, p);
  468. }
  469. static void convert_and_write_fd(int fd, const void *vbuf)
  470. {
  471. const FCELL *buf = vbuf;
  472. struct fileinfo *fcb = &R__.fileinfo[fd];
  473. DCELL *p = (DCELL *) fcb->data;
  474. int i;
  475. for (i = 0; i < fcb->cellhd.cols; i++)
  476. if (Rast_is_f_null_value(&buf[i]))
  477. Rast_set_d_null_value(&p[i], 1);
  478. else
  479. p[i] = (DCELL) buf[i];
  480. Rast_put_d_row(fd, p);
  481. }
  482. static void convert_and_write_fi(int fd, const void *vbuf)
  483. {
  484. const FCELL *buf = vbuf;
  485. struct fileinfo *fcb = &R__.fileinfo[fd];
  486. CELL *p = (CELL *) fcb->data;
  487. int i;
  488. for (i = 0; i < fcb->cellhd.cols; i++)
  489. if (Rast_is_f_null_value(&buf[i]))
  490. Rast_set_c_null_value(&p[i], 1);
  491. else
  492. p[i] = (CELL) buf[i];
  493. Rast_put_c_row(fd, p);
  494. }
  495. static void convert_and_write_di(int fd, const void *vbuf)
  496. {
  497. const DCELL *buf = vbuf;
  498. struct fileinfo *fcb = &R__.fileinfo[fd];
  499. CELL *p = (CELL *) fcb->data;
  500. int i;
  501. for (i = 0; i < fcb->cellhd.cols; i++)
  502. if (Rast_is_d_null_value(&buf[i]))
  503. Rast_set_c_null_value(&p[i], 1);
  504. else
  505. p[i] = (CELL) buf[i];
  506. Rast_put_c_row(fd, p);
  507. }
  508. /*!
  509. \brief converts a buffer of zero's and ones to bitstream.
  510. Stores this bitstream in memory. (the null rows from memory are
  511. written into null file after the limit is reached, and the place for
  512. new null rows to be kept in memory is freed. Should not be used by
  513. application programs.
  514. \param fd file descriptor where data is to be written
  515. \param buf buffer holding null data
  516. \return void
  517. */
  518. static void put_raster_row(int fd, const void *buf, RASTER_MAP_TYPE data_type,
  519. int zeros_r_nulls)
  520. {
  521. static void (*convert_and_write_FtypeOtype[3][3])(int, const void *) = {
  522. {NULL, convert_and_write_if, convert_and_write_id},
  523. {convert_and_write_fi, NULL, convert_and_write_fd},
  524. {convert_and_write_di, convert_and_write_df, NULL}
  525. };
  526. struct fileinfo *fcb = &R__.fileinfo[fd];
  527. char *null_buf;
  528. switch (fcb->open_mode) {
  529. case OPEN_OLD:
  530. G_fatal_error(_("put_raster_row: raster map <%s> not open for write - request ignored"),
  531. fcb->name);
  532. break;
  533. case OPEN_NEW_COMPRESSED:
  534. case OPEN_NEW_UNCOMPRESSED:
  535. break;
  536. default:
  537. G_fatal_error(_("put_raster_row: unopened file descriptor - request ignored"));
  538. break;
  539. }
  540. if (fcb->map_type != data_type) {
  541. convert_and_write_FtypeOtype[data_type][fcb->map_type](fd, buf);
  542. return;
  543. }
  544. null_buf = G__alloca(fcb->cellhd.cols);
  545. G_zero(null_buf, fcb->cellhd.cols);
  546. put_raster_data(fd, null_buf, buf, fcb->cur_row, fcb->cellhd.cols,
  547. zeros_r_nulls, data_type);
  548. /* only for integer maps */
  549. if (data_type == CELL_TYPE) {
  550. if (fcb->want_histogram)
  551. Rast_update_cell_stats(buf, fcb->cellhd.cols, &fcb->statf);
  552. Rast__row_update_range(buf, fcb->cellhd.cols, &fcb->range,
  553. zeros_r_nulls);
  554. }
  555. else
  556. Rast_row_update_fp_range(buf, fcb->cellhd.cols, &fcb->fp_range,
  557. data_type);
  558. fcb->cur_row++;
  559. /* write the null row for the data row */
  560. if (!fcb->gdal)
  561. put_null_value_row(fd, null_buf);
  562. G__freea(null_buf);
  563. }