get_row.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308
  1. /*!
  2. \file get_row.c
  3. \brief GIS library - get raster row
  4. (C) 2003-2008 by the GRASS Development Team
  5. This program is free software under the
  6. GNU General Public License (>=v2).
  7. Read the file COPYING that comes with GRASS
  8. for details.
  9. \author Original author CERL
  10. */
  11. #include <string.h>
  12. #include <unistd.h>
  13. #include <sys/types.h>
  14. #include <rpc/types.h> /* need this for sgi */
  15. #include <rpc/xdr.h>
  16. #include <grass/config.h>
  17. #include <grass/glocale.h>
  18. #include "G.h"
  19. /*--------------------------------------------------------------------------*/
  20. #define NULL_FILE "null"
  21. /*--------------------------------------------------------------------------*/
  22. static int embed_nulls(int, void *, int, RASTER_MAP_TYPE, int, int);
  23. /*--------------------------------------------------------------------------*/
  24. static int compute_window_row(int fd, int row, int *cellRow)
  25. {
  26. struct fileinfo *fcb = &G__.fileinfo[fd];
  27. double f;
  28. int r;
  29. /* check for row in window */
  30. if (row < 0 || row >= G__.window.rows) {
  31. G_warning(_("Reading raster map <%s@%s> request for row %d is outside region"),
  32. fcb->name, fcb->mapset, row);
  33. return -1;
  34. }
  35. /* convert window row to cell file row */
  36. f = row * fcb->C1 + fcb->C2;
  37. r = (int)f;
  38. if (f < r) /* adjust for rounding up of negatives */
  39. r--;
  40. if (r < 0 || r >= fcb->cellhd.rows)
  41. return 0;
  42. *cellRow = r;
  43. return 1;
  44. }
  45. /*--------------------------------------------------------------------------*/
  46. static void do_reclass_int(int fd, void *cell, int null_is_zero)
  47. {
  48. struct fileinfo *fcb = &G__.fileinfo[fd];
  49. CELL *c = cell;
  50. CELL *reclass_table = fcb->reclass.table;
  51. CELL min = fcb->reclass.min;
  52. CELL max = fcb->reclass.max;
  53. int i;
  54. for (i = 0; i < G__.window.cols; i++) {
  55. if (G_is_c_null_value(&c[i])) {
  56. if (null_is_zero)
  57. c[i] = 0;
  58. continue;
  59. }
  60. if (c[i] < min || c[i] > max) {
  61. if (null_is_zero)
  62. c[i] = 0;
  63. else
  64. G_set_c_null_value(&c[i], 1);
  65. continue;
  66. }
  67. c[i] = reclass_table[c[i] - min];
  68. if (null_is_zero && G_is_c_null_value(&c[i]))
  69. c[i] = 0;
  70. }
  71. }
  72. /*--------------------------------------------------------------------------*/
  73. static int read_data_fp_compressed(int fd, int row, unsigned char *data_buf,
  74. int *nbytes)
  75. {
  76. struct fileinfo *fcb = &G__.fileinfo[fd];
  77. off_t t1 = fcb->row_ptr[row];
  78. off_t t2 = fcb->row_ptr[row + 1];
  79. size_t readamount = t2 - t1;
  80. size_t bufsize = fcb->cellhd.cols * fcb->nbytes;
  81. if (lseek(fd, t1, SEEK_SET) < 0)
  82. return -1;
  83. *nbytes = fcb->nbytes;
  84. if ((size_t) G_zlib_read(fd, readamount, data_buf, bufsize) != bufsize)
  85. return -1;
  86. return 0;
  87. }
  88. /*--------------------------------------------------------------------------*/
  89. static void rle_decompress(unsigned char *dst, const unsigned char *src,
  90. int nbytes, int size)
  91. {
  92. int pairs = size / (nbytes + 1);
  93. int i;
  94. for (i = 0; i < pairs; i++) {
  95. int repeat = *src++;
  96. int j;
  97. for (j = 0; j < repeat; j++) {
  98. memcpy(dst, src, nbytes);
  99. dst += nbytes;
  100. }
  101. src += nbytes;
  102. }
  103. }
  104. static int read_data_compressed(int fd, int row, unsigned char *data_buf,
  105. int *nbytes)
  106. {
  107. struct fileinfo *fcb = &G__.fileinfo[fd];
  108. off_t t1 = fcb->row_ptr[row];
  109. off_t t2 = fcb->row_ptr[row + 1];
  110. ssize_t readamount = t2 - t1;
  111. unsigned char *cmp;
  112. int n;
  113. if (lseek(fd, t1, SEEK_SET) < 0)
  114. return -1;
  115. cmp = G__alloca(readamount);
  116. if (read(fd, cmp, readamount) != readamount) {
  117. G__freea(cmp);
  118. return -1;
  119. }
  120. /* Now decompress the row */
  121. if (fcb->cellhd.compressed > 0) {
  122. /* one byte is nbyte count */
  123. n = *nbytes = *cmp++;
  124. readamount--;
  125. }
  126. else
  127. /* pre 3.0 compression */
  128. n = *nbytes = fcb->nbytes;
  129. if (fcb->cellhd.compressed < 0 || readamount < n * fcb->cellhd.cols) {
  130. if (fcb->cellhd.compressed == 2)
  131. G_zlib_expand(cmp, readamount, data_buf, n * fcb->cellhd.cols);
  132. else
  133. rle_decompress(data_buf, cmp, n, readamount);
  134. }
  135. else
  136. memcpy(data_buf, cmp, readamount);
  137. G__freea(cmp);
  138. return 0;
  139. }
  140. /*--------------------------------------------------------------------------*/
  141. static int read_data_uncompressed(int fd, int row, unsigned char *data_buf,
  142. int *nbytes)
  143. {
  144. struct fileinfo *fcb = &G__.fileinfo[fd];
  145. ssize_t bufsize = fcb->cellhd.cols * fcb->nbytes;
  146. *nbytes = fcb->nbytes;
  147. if (lseek(fd, (off_t) row * bufsize, SEEK_SET) == -1)
  148. return -1;
  149. if (read(fd, data_buf, bufsize) != bufsize)
  150. return -1;
  151. return 0;
  152. }
  153. /*--------------------------------------------------------------------------*/
  154. #ifdef HAVE_GDAL
  155. static int read_data_gdal(int fd, int row, unsigned char *data_buf, int *nbytes)
  156. {
  157. struct fileinfo *fcb = &G__.fileinfo[fd];
  158. unsigned char *buf;
  159. CPLErr err;
  160. *nbytes = fcb->nbytes;
  161. if (fcb->gdal->vflip)
  162. row = fcb->cellhd.rows - 1 - row;
  163. buf = fcb->gdal->hflip
  164. ? G__alloca(fcb->cellhd.cols * fcb->cur_nbytes)
  165. : data_buf;
  166. err = G_gdal_raster_IO(
  167. fcb->gdal->band, GF_Read, 0, row, fcb->cellhd.cols, 1, buf,
  168. fcb->cellhd.cols, 1, fcb->gdal->type, 0, 0);
  169. if (fcb->gdal->hflip) {
  170. int i;
  171. for (i = 0; i < fcb->cellhd.cols; i++)
  172. memcpy(data_buf + i * fcb->cur_nbytes,
  173. buf + (fcb->cellhd.cols - 1 - i) * fcb->cur_nbytes,
  174. fcb->cur_nbytes);
  175. G__freea(buf);
  176. }
  177. return err == CE_None ? 0 : -1;
  178. }
  179. #endif
  180. /*--------------------------------------------------------------------------*/
  181. /* Actually read a row of data in */
  182. static int read_data(int fd, int row, unsigned char *data_buf, int *nbytes)
  183. {
  184. struct fileinfo *fcb = &G__.fileinfo[fd];
  185. #ifdef HAVE_GDAL
  186. if (fcb->gdal)
  187. return read_data_gdal(fd, row, data_buf, nbytes);
  188. #endif
  189. if (!fcb->cellhd.compressed)
  190. return read_data_uncompressed(fd, row, data_buf, nbytes);
  191. /* map is in compressed form */
  192. if (fcb->map_type == CELL_TYPE)
  193. return read_data_compressed(fd, row, data_buf, nbytes);
  194. else
  195. return read_data_fp_compressed(fd, row, data_buf, nbytes);
  196. }
  197. /*--------------------------------------------------------------------------*/
  198. /* copy cell file data to user buffer translated by window column mapping */
  199. static void cell_values_int(int fd, const unsigned char *data,
  200. const COLUMN_MAPPING * cmap, int nbytes,
  201. void *cell, int n)
  202. {
  203. CELL *c = cell;
  204. COLUMN_MAPPING cmapold = 0;
  205. int big = (size_t) nbytes >= sizeof(CELL);
  206. int i;
  207. for (i = 0; i < n; i++) {
  208. const unsigned char *d;
  209. int neg;
  210. CELL v;
  211. int j;
  212. if (!cmap[i]) {
  213. c[i] = 0;
  214. continue;
  215. }
  216. if (cmap[i] == cmapold) {
  217. c[i] = c[i - 1];
  218. continue;
  219. }
  220. d = data + (cmap[i] - 1) * nbytes;
  221. if (big && (*d & 0x80)) {
  222. neg = 1;
  223. v = *d++ & 0x7f;
  224. }
  225. else {
  226. neg = 0;
  227. v = *d++;
  228. }
  229. for (j = 1; j < nbytes; j++)
  230. v = (v << 8) + *d++;
  231. c[i] = neg ? -v : v;
  232. cmapold = cmap[i];
  233. }
  234. }
  235. /*--------------------------------------------------------------------------*/
  236. static void cell_values_float(int fd, const unsigned char *data,
  237. const COLUMN_MAPPING * cmap, int nbytes,
  238. void *cell, int n)
  239. {
  240. struct fileinfo *fcb = &G__.fileinfo[fd];
  241. FCELL *c = cell;
  242. COLUMN_MAPPING cmapold = 0;
  243. XDR *xdrs = &fcb->xdrstream;
  244. int i;
  245. /* xdr stream is initialized to read from */
  246. /* fcb->data in 'opencell.c' */
  247. xdr_setpos(xdrs, 0);
  248. for (i = 0; i < n; i++) {
  249. if (!cmap[i]) {
  250. c[i] = 0;
  251. continue;
  252. }
  253. if (cmap[i] == cmapold) {
  254. c[i] = c[i - 1];
  255. continue;
  256. }
  257. if (cmap[i] < cmapold) {
  258. xdr_setpos(xdrs, 0);
  259. cmapold = 0;
  260. }
  261. while (cmapold++ != cmap[i]) /* skip */
  262. if (!xdr_float(xdrs, &c[i]))
  263. G_fatal_error(_("cell_values_float: xdr_float failed for index %d"),
  264. i);
  265. cmapold--;
  266. }
  267. }
  268. /*--------------------------------------------------------------------------*/
  269. static void cell_values_double(int fd, const unsigned char *data,
  270. const COLUMN_MAPPING * cmap, int nbytes,
  271. void *cell, int n)
  272. {
  273. struct fileinfo *fcb = &G__.fileinfo[fd];
  274. DCELL *c = cell;
  275. COLUMN_MAPPING cmapold = 0;
  276. XDR *xdrs = &fcb->xdrstream;
  277. int i;
  278. /* xdr stream is initialized to read from */
  279. /* fcb->data in 'opencell.c' */
  280. xdr_setpos(xdrs, 0);
  281. for (i = 0; i < n; i++) {
  282. if (!cmap[i]) {
  283. c[i] = 0;
  284. continue;
  285. }
  286. if (cmap[i] == cmapold) {
  287. c[i] = c[i - 1];
  288. continue;
  289. }
  290. if (cmap[i] < cmapold) {
  291. xdr_setpos(xdrs, 0);
  292. cmapold = 0;
  293. }
  294. while (cmapold++ != cmap[i]) /* skip */
  295. if (!xdr_double(xdrs, &c[i]))
  296. G_fatal_error(_("cell_values_double: xdr_double failed for index %d"),
  297. i);
  298. cmapold--;
  299. }
  300. }
  301. /*--------------------------------------------------------------------------*/
  302. /*--------------------------------------------------------------------------*/
  303. #ifdef HAVE_GDAL
  304. /*--------------------------------------------------------------------------*/
  305. static void gdal_values_int(int fd, const unsigned char *data,
  306. const COLUMN_MAPPING *cmap, int nbytes,
  307. CELL *cell, int n)
  308. {
  309. struct fileinfo *fcb = &G__.fileinfo[fd];
  310. const unsigned char *d;
  311. COLUMN_MAPPING cmapold = 0;
  312. int i;
  313. for (i = 0; i < n; i++) {
  314. if (!cmap[i]) {
  315. cell[i] = 0;
  316. continue;
  317. }
  318. if (cmap[i] == cmapold) {
  319. cell[i] = cell[i-1];
  320. continue;
  321. }
  322. d = data + (cmap[i] - 1) * nbytes;
  323. switch (fcb->gdal->type) {
  324. case GDT_Byte: cell[i] = *(GByte *)d; break;
  325. case GDT_Int16: cell[i] = *(GInt16 *)d; break;
  326. case GDT_UInt16: cell[i] = *(GUInt16 *)d; break;
  327. case GDT_Int32: cell[i] = *(GInt32 *)d; break;
  328. case GDT_UInt32: cell[i] = *(GUInt32 *)d; break;
  329. default:
  330. /* shouldn't happen */
  331. G_set_c_null_value(&cell[i], 1);
  332. break;
  333. }
  334. cmapold = cmap[i];
  335. }
  336. }
  337. /*--------------------------------------------------------------------------*/
  338. static void gdal_values_float(int fd, const float *data,
  339. const COLUMN_MAPPING *cmap, int nbytes,
  340. FCELL *cell, int n)
  341. {
  342. COLUMN_MAPPING cmapold = 0;
  343. int i;
  344. for (i = 0; i < n; i++) {
  345. if (!cmap[i]) {
  346. cell[i] = 0;
  347. continue;
  348. }
  349. if (cmap[i] == cmapold) {
  350. cell[i] = cell[i-1];
  351. continue;
  352. }
  353. cell[i] = data[cmap[i] - 1];
  354. cmapold = cmap[i];
  355. }
  356. }
  357. /*--------------------------------------------------------------------------*/
  358. static void gdal_values_double(int fd, const double *data,
  359. const COLUMN_MAPPING *cmap, int nbytes,
  360. DCELL *cell, int n)
  361. {
  362. COLUMN_MAPPING cmapold = 0;
  363. int i;
  364. for (i = 0; i < n; i++) {
  365. if (!cmap[i]) {
  366. cell[i] = 0;
  367. continue;
  368. }
  369. if (cmap[i] == cmapold) {
  370. cell[i] = cell[i-1];
  371. continue;
  372. }
  373. cell[i] = data[cmap[i] - 1];
  374. cmapold = cmap[i];
  375. }
  376. }
  377. /*--------------------------------------------------------------------------*/
  378. #endif
  379. /*--------------------------------------------------------------------------*/
  380. /* transfer_to_cell_XY takes bytes from fcb->data, converts these bytes with
  381. the appropriate procedure (e.g. XDR or byte reordering) into type X
  382. values which are put into array work_buf.
  383. finally the values in work_buf are converted into
  384. type Y and put into 'cell'.
  385. if type X == type Y the intermediate step of storing the values in
  386. work_buf might be ommited. check the appropriate function for XY to
  387. determine the procedure of conversion.
  388. */
  389. /*--------------------------------------------------------------------------*/
  390. static void transfer_to_cell_XX(int fd, void *cell)
  391. {
  392. static void (*cell_values_type[3]) () = {
  393. cell_values_int, cell_values_float, cell_values_double};
  394. #ifdef HAVE_GDAL
  395. static void (*gdal_values_type[3]) () = {
  396. gdal_values_int, gdal_values_float, gdal_values_double};
  397. #endif
  398. struct fileinfo *fcb = &G__.fileinfo[fd];
  399. #ifdef HAVE_GDAL
  400. if (fcb->gdal)
  401. (gdal_values_type[fcb->map_type]) (fd, fcb->data, fcb->col_map,
  402. fcb->cur_nbytes, cell,
  403. G__.window.cols);
  404. else
  405. #endif
  406. (cell_values_type[fcb->map_type]) (fd, fcb->data, fcb->col_map,
  407. fcb->cur_nbytes, cell,
  408. G__.window.cols);
  409. }
  410. /*--------------------------------------------------------------------------*/
  411. static void transfer_to_cell_fi(int fd, void *cell)
  412. {
  413. struct fileinfo *fcb = &G__.fileinfo[fd];
  414. FCELL *work_buf = G__alloca(G__.window.cols * sizeof(FCELL));
  415. int i;
  416. transfer_to_cell_XX(fd, work_buf);
  417. for (i = 0; i < G__.window.cols; i++)
  418. ((CELL *) cell)[i] = (fcb->col_map[i] == 0)
  419. ? 0
  420. : G_quant_get_cell_value(&fcb->quant, work_buf[i]);
  421. G__freea(work_buf);
  422. }
  423. static void transfer_to_cell_di(int fd, void *cell)
  424. {
  425. struct fileinfo *fcb = &G__.fileinfo[fd];
  426. DCELL *work_buf = G__alloca(G__.window.cols * sizeof(DCELL));
  427. int i;
  428. transfer_to_cell_XX(fd, work_buf);
  429. for (i = 0; i < G__.window.cols; i++)
  430. ((CELL *) cell)[i] = (fcb->col_map[i] == 0)
  431. ? 0
  432. : G_quant_get_cell_value(&fcb->quant, work_buf[i]);
  433. G__freea(work_buf);
  434. }
  435. /*--------------------------------------------------------------------------*/
  436. static void transfer_to_cell_if(int fd, void *cell)
  437. {
  438. CELL *work_buf = G__alloca(G__.window.cols * sizeof(CELL));
  439. int i;
  440. transfer_to_cell_XX(fd, work_buf);
  441. for (i = 0; i < G__.window.cols; i++)
  442. ((FCELL *) cell)[i] = work_buf[i];
  443. G__freea(work_buf);
  444. }
  445. static void transfer_to_cell_df(int fd, void *cell)
  446. {
  447. DCELL *work_buf = G__alloca(G__.window.cols * sizeof(DCELL));
  448. int i;
  449. transfer_to_cell_XX(fd, work_buf);
  450. for (i = 0; i < G__.window.cols; i++)
  451. ((FCELL *) cell)[i] = work_buf[i];
  452. G__freea(work_buf);
  453. }
  454. /*--------------------------------------------------------------------------*/
  455. static void transfer_to_cell_id(int fd, void *cell)
  456. {
  457. CELL *work_buf = G__alloca(G__.window.cols * sizeof(CELL));
  458. int i;
  459. transfer_to_cell_XX(fd, work_buf);
  460. for (i = 0; i < G__.window.cols; i++)
  461. ((DCELL *) cell)[i] = work_buf[i];
  462. G__freea(work_buf);
  463. }
  464. static void transfer_to_cell_fd(int fd, void *cell)
  465. {
  466. FCELL *work_buf = G__alloca(G__.window.cols * sizeof(FCELL));
  467. int i;
  468. transfer_to_cell_XX(fd, work_buf);
  469. for (i = 0; i < G__.window.cols; i++)
  470. ((DCELL *) cell)[i] = work_buf[i];
  471. G__freea(work_buf);
  472. }
  473. /*--------------------------------------------------------------------------*/
  474. /*--------------------------------------------------------------------------*/
  475. /*--------------------------------------------------------------------------*/
  476. /*
  477. * works for all map types and doesn't consider
  478. * null row corresponding to the requested row
  479. */
  480. static int get_map_row_nomask(int fd, void *rast, int row,
  481. RASTER_MAP_TYPE data_type)
  482. {
  483. static void (*transfer_to_cell_FtypeOtype[3][3])() = {
  484. {transfer_to_cell_XX, transfer_to_cell_if, transfer_to_cell_id},
  485. {transfer_to_cell_fi, transfer_to_cell_XX, transfer_to_cell_fd},
  486. {transfer_to_cell_di, transfer_to_cell_df, transfer_to_cell_XX}
  487. };
  488. struct fileinfo *fcb = &G__.fileinfo[fd];
  489. int r;
  490. int rowStatus;
  491. rowStatus = compute_window_row(fd, row, &r);
  492. if (rowStatus <= 0) {
  493. fcb->cur_row = -1;
  494. G_zero_raster_buf(rast, data_type);
  495. return rowStatus;
  496. }
  497. /* read cell file row if not in memory */
  498. if (r != fcb->cur_row) {
  499. fcb->cur_row = r;
  500. if (read_data(fd, fcb->cur_row, fcb->data, &fcb->cur_nbytes) < 0) {
  501. G_zero_raster_buf(rast, data_type);
  502. if (!fcb->io_error) {
  503. if (fcb->cellhd.compressed)
  504. G_warning(_("Error reading compressed map <%s@%s>, row %d"),
  505. fcb->name, fcb->mapset, r);
  506. else
  507. G_warning(_("Error reading map <%s@%s>, row %d"),
  508. fcb->name, fcb->mapset, r);
  509. fcb->io_error = 1;
  510. }
  511. return -1;
  512. }
  513. }
  514. (transfer_to_cell_FtypeOtype[fcb->map_type][data_type]) (fd, rast);
  515. return 1;
  516. }
  517. /*--------------------------------------------------------------------------*/
  518. static int get_map_row_no_reclass(int fd, void *rast, int row,
  519. RASTER_MAP_TYPE data_type, int null_is_zero,
  520. int with_mask)
  521. {
  522. int stat;
  523. stat = get_map_row_nomask(fd, rast, row, data_type);
  524. if (stat < 0)
  525. return stat;
  526. stat = embed_nulls(fd, rast, row, data_type, null_is_zero, with_mask);
  527. if (stat < 0)
  528. return stat;
  529. return 1;
  530. }
  531. /*--------------------------------------------------------------------------*/
  532. static int get_map_row(int fd, void *rast, int row, RASTER_MAP_TYPE data_type,
  533. int null_is_zero, int with_mask)
  534. {
  535. struct fileinfo *fcb = &G__.fileinfo[fd];
  536. int size = G_raster_size(data_type);
  537. CELL *temp_buf = NULL;
  538. void *buf;
  539. int type;
  540. int stat;
  541. int i;
  542. if (fcb->reclass_flag && data_type != CELL_TYPE) {
  543. temp_buf = G__alloca(G__.window.cols * sizeof(CELL));
  544. buf = temp_buf;
  545. type = CELL_TYPE;
  546. }
  547. else {
  548. buf = rast;
  549. type = data_type;
  550. }
  551. stat = get_map_row_no_reclass(fd, buf, row, type, null_is_zero, with_mask);
  552. if (stat < 0) {
  553. if (temp_buf)
  554. G__freea(temp_buf);
  555. return stat;
  556. }
  557. if (!fcb->reclass_flag)
  558. return 1;
  559. /* if the map is reclass table, get and
  560. reclass CELL row and copy results to needed type */
  561. do_reclass_int(fd, buf, null_is_zero);
  562. if (data_type == CELL_TYPE)
  563. return 1;
  564. for (i = 0; i < G__.window.cols; i++) {
  565. G_set_raster_value_c(rast, temp_buf[i], data_type);
  566. rast = G_incr_void_ptr(rast, size);
  567. }
  568. G__freea(temp_buf);
  569. return 1;
  570. }
  571. /*--------------------------------------------------------------------------*/
  572. /*--------------------------------------------------------------------------*/
  573. /*--------------------------------------------------------------------------*/
  574. /*!
  575. * \brief Read raster row without masking (this routine is deprecated)
  576. *
  577. * This routine reads the specified <em>row</em> from the raster map
  578. * open on file descriptor <em>fd</em> into the <em>buf</em> buffer
  579. * like G_get_map_row() does. The difference is that masking is
  580. * suppressed. If the user has a mask set, G_get_map_row() will apply
  581. * the mask but G_get_map_row_nomask() will ignore it. This routine
  582. * prints a diagnostic message and returns -1 if there is an error
  583. * reading the raster map. Otherwise a nonnegative value is returned.
  584. *
  585. * <b>Note.</b> Ignoring the mask is not generally acceptable. Users
  586. * expect the mask to be applied. However, in some cases ignoring the
  587. * mask is justified. For example, the GRASS modules
  588. * <i>r.describe</i>, which reads the raster map directly to report
  589. * all data values in a raster map, and <i>r.slope.aspect</i>, which
  590. * produces slope and aspect from elevation, ignore both the mask and
  591. * the region. However, the number of GRASS modules which do this
  592. * should be minimal. See Mask for more information about the mask.
  593. *
  594. * <b>This routine is deprecated! Use G_get_raster_row_nomask()
  595. * instead.</b>
  596. *
  597. * \param fd file descriptor for the opened raster map
  598. * \param buf buffer for the row to be placed into
  599. * \param row data row desired
  600. *
  601. * \return 1 on success
  602. * \return 0 row requested not within window
  603. * \return -1 on error
  604. */
  605. int G_get_map_row_nomask(int fd, CELL * buf, int row)
  606. {
  607. return get_map_row(fd, buf, row, CELL_TYPE, 1, 0);
  608. }
  609. /*!
  610. * \brief Read raster row without masking
  611. *
  612. * Same as G_get_raster_row() except no masking occurs.
  613. *
  614. * \param fd file descriptor for the opened raster map
  615. * \param buf buffer for the row to be placed into
  616. * \param row data row desired
  617. * \param data_type data type
  618. *
  619. * \return 1 on success
  620. * \return 0 row requested not within window
  621. * \return -1 on error
  622. */
  623. int G_get_raster_row_nomask(int fd, void *buf, int row,
  624. RASTER_MAP_TYPE data_type)
  625. {
  626. return get_map_row(fd, buf, row, data_type, 0, 0);
  627. }
  628. /*!
  629. * \brief Read raster row without masking (CELL type)
  630. *
  631. * Same as G_get_c_raster_row() except no masking occurs.
  632. *
  633. * \param fd file descriptor for the opened raster map
  634. * \param buf buffer for the row to be placed into
  635. * \param row data row desired
  636. * \param data_type data type
  637. *
  638. * \return 1 on success
  639. * \return 0 row requested not within window
  640. * \return -1 on error
  641. */
  642. int G_get_c_raster_row_nomask(int fd, CELL * buf, int row)
  643. {
  644. return G_get_raster_row_nomask(fd, buf, row, CELL_TYPE);
  645. }
  646. /*!
  647. * \brief Read raster row without masking (FCELL type)
  648. *
  649. * Same as G_get_f_raster_row() except no masking occurs.
  650. *
  651. * \param fd file descriptor for the opened raster map
  652. * \param buf buffer for the row to be placed into
  653. * \param row data row desired
  654. * \param data_type data type
  655. *
  656. * \return 1 on success
  657. * \return 0 row requested not within window
  658. * \return -1 on error
  659. */
  660. int G_get_f_raster_row_nomask(int fd, FCELL * buf, int row)
  661. {
  662. return G_get_raster_row_nomask(fd, buf, row, FCELL_TYPE);
  663. }
  664. /*!
  665. * \brief Read raster row without masking (DCELL type)
  666. *
  667. * Same as G_get_d_raster_row() except no masking occurs.
  668. *
  669. * \param fd file descriptor for the opened raster map
  670. * \param buf buffer for the row to be placed into
  671. * \param row data row desired
  672. * \param data_type data type
  673. *
  674. * \return 1 on success
  675. * \return 0 row requested not within window
  676. * \return -1 on error
  677. */
  678. int G_get_d_raster_row_nomask(int fd, DCELL * buf, int row)
  679. {
  680. return G_get_raster_row_nomask(fd, buf, row, DCELL_TYPE);
  681. }
  682. /*--------------------------------------------------------------------------*/
  683. /*!
  684. * \brief Get raster row (this routine is deprecated!)
  685. *
  686. * If the map is floating-point, quantize the floating-point values to
  687. * integer using the quantization rules established for the map when
  688. * the map was opened for reading (this quantization is read from
  689. * cell_misc/name/f_quant file, but can be reset after opening raster
  690. * map by G_set_quant_rules()). NULL values are converted to zeros.
  691. *
  692. * <b>This routine is deprecated! Use G_get_raster_row() instead.</b>
  693. *
  694. * \param fd file descriptor for the opened raster map
  695. * \param buf buffer for the row to be placed into
  696. * \param row data row desired
  697. *
  698. * \return 1 on success
  699. * \return 0 row requested not within window
  700. * \return -1 on error
  701. */
  702. int G_get_map_row(int fd, CELL * buf, int row)
  703. {
  704. return get_map_row(fd, buf, row, CELL_TYPE, 1, 1);
  705. }
  706. /*!
  707. * \brief Get raster row
  708. *
  709. * If <em>data_type</em> is
  710. * - CELL_TYPE, calls G_get_c_raster_row()
  711. * - FCELL_TYPE, calls G_get_f_raster_row()
  712. * - DCELL_TYPE, calls G_get_d_raster_row()
  713. *
  714. * Reads appropriate information into the buffer <em>buf</em> associated
  715. * with the requested row <em>row</em>. <em>buf</em> is associated with the
  716. * current window.
  717. *
  718. * Note, that the type of the data in <em>buf</em> (say X) is independent of
  719. * the type of the data in the file described by <em>fd</em> (say Y).
  720. *
  721. * - Step 1: Read appropriate raw map data into a intermediate buffer.
  722. * - Step 2: Convert the data into a CPU readable format, and subsequently
  723. * resample the data. the data is stored in a second intermediate
  724. * buffer (the type of the data in this buffer is Y).
  725. * - Step 3: Convert this type Y data into type X data and store it in
  726. * buffer "buf". Conversion is performed in functions
  727. * "transfer_to_cell_XY". (For details of the conversion between
  728. * two particular types check the functions).
  729. * - Step 4: read or simmulate null value row and zero out cells corresponding
  730. * to null value cells. The masked out cells are set to null when the
  731. * mask exists. (the MASK is taken care of by null values
  732. * (if the null file doesn't exist for this map, then the null row
  733. * is simulated by assuming that all zero are nulls *** in case
  734. * of G_get_raster_row() and assuming that all data is valid
  735. * in case of G_get_f/d_raster_row(). In case of deprecated function
  736. * G_get_map_row() all nulls are converted to zeros (so there are
  737. * no embedded nulls at all). Also all masked out cells become zeros.
  738. *
  739. * \param fd file descriptor for the opened raster map
  740. * \param buf buffer for the row to be placed into
  741. * \param row data row desired
  742. * \param data_type data type
  743. *
  744. * \return 1 on success
  745. * \return 0 row requested not within window
  746. * \return -1 on error
  747. */
  748. int G_get_raster_row(int fd, void *buf, int row, RASTER_MAP_TYPE data_type)
  749. {
  750. return get_map_row(fd, buf, row, data_type, 0, 1);
  751. }
  752. /*!
  753. * \brief Get raster row (CELL type)
  754. *
  755. * Reads a row of raster data and leaves the NULL values intact. (As
  756. * opposed to the deprecated function G_get_map_row() which
  757. * converts NULL values to zero.)
  758. *
  759. * <b>NOTE.</b> When the raster map is old and null file doesn't
  760. * exist, it is assumed that all 0-cells are no-data. When map is
  761. * floating point, uses quant rules set explicitly by
  762. * G_set_quant_rules() or stored in map's quant file to convert floats
  763. * to integers.
  764. *
  765. * \param fd file descriptor for the opened raster map
  766. * \param buf buffer for the row to be placed into
  767. * \param row data row desired
  768. *
  769. * \return 1 on success
  770. * \return 0 row requested not within window
  771. * \return -1 on error
  772. */
  773. int G_get_c_raster_row(int fd, CELL * buf, int row)
  774. {
  775. return G_get_raster_row(fd, buf, row, CELL_TYPE);
  776. }
  777. /*!
  778. * \brief Get raster row (FCELL type)
  779. *
  780. * Read a row from the raster map open on <em>fd</em> into the
  781. * <tt>float</tt> array <em>fcell</em> performing type conversions as
  782. * necessary based on the actual storage type of the map. Masking,
  783. * resampling into the current region. NULL-values are always
  784. * embedded in <tt>fcell</tt> (<em>never converted to a value</em>).
  785. *
  786. * \param fd file descriptor for the opened raster map
  787. * \param buf buffer for the row to be placed into
  788. * \param row data row desired
  789. *
  790. * \return 1 on success
  791. * \return 0 row requested not within window
  792. * \return -1 on error
  793. */
  794. int G_get_f_raster_row(int fd, FCELL * buf, int row)
  795. {
  796. return G_get_raster_row(fd, buf, row, FCELL_TYPE);
  797. }
  798. /*!
  799. * \brief Get raster row (DCELL type)
  800. *
  801. * Same as G_get_f_raster_row() except that the array <em>dcell</em>
  802. * is <tt>double</tt>.
  803. *
  804. * \param fd file descriptor for the opened raster map
  805. * \param buf buffer for the row to be placed into
  806. * \param row data row desired
  807. *
  808. * \return 1 on success
  809. * \return 0 row requested not within window
  810. * \return -1 on error
  811. */
  812. int G_get_d_raster_row(int fd, DCELL * buf, int row)
  813. {
  814. return G_get_raster_row(fd, buf, row, DCELL_TYPE);
  815. }
  816. /*--------------------------------------------------------------------------*/
  817. /*--------------------------------------------------------------------------*/
  818. /*--------------------------------------------------------------------------*/
  819. static int open_null_read(int fd)
  820. {
  821. struct fileinfo *fcb = &G__.fileinfo[fd];
  822. const char *name, *mapset, *dummy;
  823. int null_fd;
  824. if (fcb->null_file_exists == 0)
  825. return -1;
  826. if (fcb->reclass_flag) {
  827. name = fcb->reclass.name;
  828. mapset = fcb->reclass.mapset;
  829. }
  830. else {
  831. name = fcb->name;
  832. mapset = fcb->mapset;
  833. }
  834. dummy = G_find_file2_misc("cell_misc", NULL_FILE, name, mapset);
  835. if (!dummy) {
  836. /* G_warning("unable to find [%s]",path); */
  837. fcb->null_file_exists = 0;
  838. return -1;
  839. }
  840. null_fd = G_open_old_misc("cell_misc", NULL_FILE, name, mapset);
  841. if (null_fd < 0)
  842. return -1;
  843. fcb->null_file_exists = 1;
  844. return null_fd;
  845. }
  846. static int read_null_bits(int null_fd, unsigned char *flags, int row,
  847. int cols, int fd)
  848. {
  849. off_t offset;
  850. ssize_t size;
  851. int R;
  852. if (compute_window_row(fd, row, &R) <= 0) {
  853. G__init_null_bits(flags, cols);
  854. return 1;
  855. }
  856. if (null_fd < 0)
  857. return -1;
  858. size = G__null_bitstream_size(cols);
  859. offset = (off_t) size *R;
  860. if (lseek(null_fd, offset, SEEK_SET) < 0) {
  861. G_warning(_("Error reading null row %d"), R);
  862. return -1;
  863. }
  864. if (read(null_fd, flags, size) != size) {
  865. G_warning(_("Error reading null row %d"), R);
  866. return -1;
  867. }
  868. return 1;
  869. }
  870. static void get_null_value_row_nomask(int fd, char *flags, int row)
  871. {
  872. struct fileinfo *fcb = &G__.fileinfo[fd];
  873. int i, j, null_fd;
  874. if (row > G__.window.rows || row < 0) {
  875. G_warning(_("Reading raster map <%s@%s> request for row %d is outside region"),
  876. fcb->name, fcb->mapset, row);
  877. }
  878. if ((fcb->min_null_row > row) ||
  879. (fcb->min_null_row + NULL_ROWS_INMEM - 1 < row))
  880. /* the null row row is not in memory */
  881. {
  882. unsigned char *null_work_buf = G__alloca(
  883. G__null_bitstream_size(fcb->cellhd.cols));
  884. /* read in NULL_ROWS_INMEM rows from null file
  885. so that the requested row is between fcb->min_null_row
  886. and fcb->min_null_row + NULL_ROWS_INMEM */
  887. fcb->min_null_row = (row / NULL_ROWS_INMEM) * NULL_ROWS_INMEM;
  888. null_fd = open_null_read(fd);
  889. for (i = 0; i < NULL_ROWS_INMEM; i++) {
  890. /* G__.window.rows doesn't have to be a multiple of NULL_ROWS_INMEM */
  891. if (i + fcb->min_null_row >= G__.window.rows)
  892. break;
  893. if (read_null_bits(null_fd, null_work_buf,
  894. i + fcb->min_null_row, fcb->cellhd.cols,
  895. fd) < 0) {
  896. if (fcb->map_type == CELL_TYPE) {
  897. /* If can't read null row, assume that all map 0's are nulls */
  898. CELL *mask_buf = G__alloca(G__.window.cols * sizeof(CELL));
  899. get_map_row_nomask(fd, mask_buf, i + fcb->min_null_row,
  900. CELL_TYPE);
  901. for (j = 0; j < G__.window.cols; j++)
  902. flags[j] = (mask_buf[j] == 0);
  903. G__freea(mask_buf);
  904. }
  905. else { /* fp map */
  906. /* if can't read null row, assume that all data is valid */
  907. G_zero(flags, sizeof(char) * G__.window.cols);
  908. /* the flags row is ready now */
  909. }
  910. } /*if no null file */
  911. else {
  912. /* copy null row to flags row translated by window column mapping */
  913. /* the fcb->NULL_ROWS[row-fcb->min_null_row] has G__.window.cols bits, */
  914. /* the null_work_buf has size fcb->cellhd.cols */
  915. for (j = 0; j < G__.window.cols; j++) {
  916. if (!fcb->col_map[j])
  917. flags[j] = 1;
  918. else
  919. flags[j] = G__check_null_bit(null_work_buf,
  920. fcb->col_map[j] - 1,
  921. fcb->cellhd.cols);
  922. }
  923. }
  924. /* remember the null row for i for the future reference */
  925. /*bf-We should take of the size - or we get
  926. zeros running on their own after flags convertions -A.Sh. */
  927. fcb->NULL_ROWS[i] = G_realloc(fcb->NULL_ROWS[i],
  928. G__null_bitstream_size(G__.window.
  929. cols) + 1);
  930. if (fcb->NULL_ROWS[i] == NULL)
  931. G_fatal_error("get_null_value_row_nomask: %s",
  932. _("Unable to realloc buffer"));
  933. G__convert_01_flags(flags, fcb->NULL_ROWS[i], G__.window.cols);
  934. } /* for loop */
  935. if (null_fd > 0)
  936. close(null_fd);
  937. G__freea(null_work_buf);
  938. } /* row is not in memory */
  939. /* copy null file data translated by column mapping to user null row */
  940. /* the user requested flags row is of size G__.window.cols */
  941. G__convert_flags_01(flags, fcb->NULL_ROWS[row - fcb->min_null_row],
  942. G__.window.cols);
  943. }
  944. /*--------------------------------------------------------------------------*/
  945. #ifdef HAVE_GDAL
  946. static void get_null_value_row_gdal(int fd, char *flags, int row)
  947. {
  948. struct fileinfo *fcb = &G__.fileinfo[fd];
  949. DCELL *tmp_buf = G_allocate_d_raster_buf();
  950. int i;
  951. if (get_map_row_nomask(fd, tmp_buf, row, DCELL_TYPE) <= 0) {
  952. memset(flags, 1, G__.window.cols);
  953. G_free(tmp_buf);
  954. return;
  955. }
  956. for (i = 0; i < G__.window.cols; i++)
  957. /* note: using == won't work if the null value is NaN */
  958. flags[i] = memcmp(&tmp_buf[i], &fcb->gdal->null_val, sizeof(DCELL)) == 0;
  959. G_free(tmp_buf);
  960. }
  961. #endif
  962. /*--------------------------------------------------------------------------*/
  963. /*--------------------------------------------------------------------------*/
  964. static void embed_mask(char *flags, int row)
  965. {
  966. CELL *mask_buf = G__alloca(G__.window.cols * sizeof(CELL));
  967. int i;
  968. if (G__.auto_mask <= 0)
  969. return;
  970. if (get_map_row_nomask(G__.mask_fd, mask_buf, row, CELL_TYPE) < 0) {
  971. G__freea(mask_buf);
  972. return;
  973. }
  974. if (G__.fileinfo[G__.mask_fd].reclass_flag)
  975. do_reclass_int(G__.mask_fd, mask_buf, 1);
  976. for (i = 0; i < G__.window.cols; i++)
  977. if (mask_buf[i] == 0)
  978. flags[i] = 1;
  979. G__freea(mask_buf);
  980. }
  981. static void get_null_value_row(int fd, char *flags, int row, int with_mask)
  982. {
  983. #ifdef HAVE_GDAL
  984. struct fileinfo *fcb = &G__.fileinfo[fd];
  985. if (fcb->gdal)
  986. get_null_value_row_gdal(fd, flags, row);
  987. else
  988. #endif
  989. get_null_value_row_nomask(fd, flags, row);
  990. if (with_mask)
  991. embed_mask(flags, row);
  992. }
  993. static int embed_nulls(int fd, void *buf, int row, RASTER_MAP_TYPE map_type,
  994. int null_is_zero, int with_mask)
  995. {
  996. struct fileinfo *fcb = &G__.fileinfo[fd];
  997. char *null_buf;
  998. int i;
  999. /* this is because without null file the nulls can be only due to 0's
  1000. in data row or mask */
  1001. if (null_is_zero && !fcb->null_file_exists
  1002. && (G__.auto_mask <= 0 || !with_mask))
  1003. return 1;
  1004. null_buf = G__alloca(G__.window.cols);
  1005. get_null_value_row(fd, null_buf, row, with_mask);
  1006. for (i = 0; i < G__.window.cols; i++) {
  1007. /* also check for nulls which might be already embedded by quant
  1008. rules in case of fp map. */
  1009. if (null_buf[i] || G_is_null_value(buf, map_type)) {
  1010. /* G__set_[f/d]_null_value() sets it to 0 is the embedded mode
  1011. is not set and calls G_set_[f/d]_null_value() otherwise */
  1012. G__set_null_value(buf, 1, null_is_zero, map_type);
  1013. }
  1014. buf = G_incr_void_ptr(buf, G_raster_size(map_type));
  1015. }
  1016. G__freea(null_buf);
  1017. return 1;
  1018. }
  1019. /*--------------------------------------------------------------------------*/
  1020. /*--------------------------------------------------------------------------*/
  1021. /*--------------------------------------------------------------------------*/
  1022. /*!
  1023. \brief Read or simmulate null value row
  1024. Read or simmulate null value row and set the cells corresponding
  1025. to null value to 1. The masked out cells are set to null when the
  1026. mask exists. (the MASK is taken care of by null values
  1027. (if the null file doesn't exist for this map, then the null row
  1028. is simulated by assuming that all zeros in raster map are nulls.
  1029. Also all masked out cells become nulls.
  1030. \param fd file descriptor for the opened map
  1031. \param buf buffer for the row to be placed into
  1032. \param row data row desired
  1033. \return 1
  1034. */
  1035. int G_get_null_value_row(int fd, char *flags, int row)
  1036. {
  1037. get_null_value_row(fd, flags, row, 1);
  1038. return 1;
  1039. }