get_row.c 26 KB

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