GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gis/get_row.c
Go to the documentation of this file.
1 
16 #include <string.h>
17 #include <unistd.h>
18 #include <sys/types.h>
19 
20 #include <rpc/types.h> /* need this for sgi */
21 #include <rpc/xdr.h>
22 
23 #include <grass/config.h>
24 #include <grass/glocale.h>
25 
26 #include "G.h"
27 
28 /*--------------------------------------------------------------------------*/
29 
30 #define NULL_FILE "null"
31 
32 /*--------------------------------------------------------------------------*/
33 
34 static int embed_nulls(int, void *, int, RASTER_MAP_TYPE, int, int);
35 
36 /*--------------------------------------------------------------------------*/
37 
38 static int compute_window_row(int fd, int row, int *cellRow)
39 {
40  struct fileinfo *fcb = &G__.fileinfo[fd];
41  double f;
42  int r;
43 
44  /* check for row in window */
45  if (row < 0 || row >= G__.window.rows) {
46  G_warning(_("Reading raster map <%s@%s> request for row %d is outside region"),
47  fcb->name, fcb->mapset, row);
48 
49  return -1;
50  }
51 
52  /* convert window row to cell file row */
53  f = row * fcb->C1 + fcb->C2;
54  r = (int)f;
55  if (f < r) /* adjust for rounding up of negatives */
56  r--;
57 
58  if (r < 0 || r >= fcb->cellhd.rows)
59  return 0;
60 
61  *cellRow = r;
62 
63  return 1;
64 }
65 
66 /*--------------------------------------------------------------------------*/
67 
68 static void do_reclass_int(int fd, void *cell, int null_is_zero)
69 {
70  struct fileinfo *fcb = &G__.fileinfo[fd];
71  CELL *c = cell;
72  CELL *reclass_table = fcb->reclass.table;
73  CELL min = fcb->reclass.min;
74  CELL max = fcb->reclass.max;
75  int i;
76 
77  for (i = 0; i < G__.window.cols; i++) {
78  if (G_is_c_null_value(&c[i])) {
79  if (null_is_zero)
80  c[i] = 0;
81  continue;
82  }
83 
84  if (c[i] < min || c[i] > max) {
85  if (null_is_zero)
86  c[i] = 0;
87  else
88  G_set_c_null_value(&c[i], 1);
89  continue;
90  }
91 
92  c[i] = reclass_table[c[i] - min];
93 
94  if (null_is_zero && G_is_c_null_value(&c[i]))
95  c[i] = 0;
96  }
97 }
98 
99 /*--------------------------------------------------------------------------*/
100 
101 static int read_data_fp_compressed(int fd, int row, unsigned char *data_buf,
102  int *nbytes)
103 {
104  struct fileinfo *fcb = &G__.fileinfo[fd];
105  off_t t1 = fcb->row_ptr[row];
106  off_t t2 = fcb->row_ptr[row + 1];
107  size_t readamount = t2 - t1;
108  size_t bufsize = fcb->cellhd.cols * fcb->nbytes;
109 
110  if (lseek(fd, t1, SEEK_SET) < 0)
111  return -1;
112 
113  *nbytes = fcb->nbytes;
114 
115  if ((size_t) G_zlib_read(fd, readamount, data_buf, bufsize) != bufsize)
116  return -1;
117 
118  return 0;
119 }
120 
121 /*--------------------------------------------------------------------------*/
122 
123 static void rle_decompress(unsigned char *dst, const unsigned char *src,
124  int nbytes, int size)
125 {
126  int pairs = size / (nbytes + 1);
127  int i;
128 
129  for (i = 0; i < pairs; i++) {
130  int repeat = *src++;
131  int j;
132 
133  for (j = 0; j < repeat; j++) {
134  memcpy(dst, src, nbytes);
135  dst += nbytes;
136  }
137 
138  src += nbytes;
139  }
140 }
141 
142 static int read_data_compressed(int fd, int row, unsigned char *data_buf,
143  int *nbytes)
144 {
145  struct fileinfo *fcb = &G__.fileinfo[fd];
146  off_t t1 = fcb->row_ptr[row];
147  off_t t2 = fcb->row_ptr[row + 1];
148  ssize_t readamount = t2 - t1;
149  unsigned char *cmp = G__.compressed_buf;
150  int n;
151 
152  if (lseek(fd, t1, SEEK_SET) < 0)
153  return -1;
154 
155  if (read(fd, cmp, readamount) != readamount)
156  return -1;
157 
158  /* Now decompress the row */
159  if (fcb->cellhd.compressed > 0) {
160  /* one byte is nbyte count */
161  n = *nbytes = *cmp++;
162  readamount--;
163  }
164  else
165  /* pre 3.0 compression */
166  n = *nbytes = fcb->nbytes;
167 
168  if (fcb->cellhd.compressed < 0 || readamount < n * fcb->cellhd.cols) {
169  if (fcb->cellhd.compressed == 2)
170  G_zlib_expand(cmp, readamount, data_buf, n * fcb->cellhd.cols);
171  else
172  rle_decompress(data_buf, cmp, n, readamount);
173  }
174  else
175  memcpy(data_buf, cmp, readamount);
176 
177  return 0;
178 }
179 
180 /*--------------------------------------------------------------------------*/
181 
182 static int read_data_uncompressed(int fd, int row, unsigned char *data_buf,
183  int *nbytes)
184 {
185  struct fileinfo *fcb = &G__.fileinfo[fd];
186  ssize_t bufsize = fcb->cellhd.cols * fcb->nbytes;
187 
188  *nbytes = fcb->nbytes;
189 
190  if (lseek(fd, (off_t) row * bufsize, SEEK_SET) == -1)
191  return -1;
192 
193  if (read(fd, data_buf, bufsize) != bufsize)
194  return -1;
195 
196  return 0;
197 }
198 
199 /*--------------------------------------------------------------------------*/
200 
201 #ifdef HAVE_GDAL
202 static int read_data_gdal(int fd, int row, unsigned char *data_buf, int *nbytes)
203 {
204  struct fileinfo *fcb = &G__.fileinfo[fd];
205  CPLErr err;
206 
207  *nbytes = fcb->nbytes;
208 
209  err = G_gdal_raster_IO(
210  fcb->gdal->band, GF_Read, 0, row, fcb->cellhd.cols, 1, data_buf,
211  fcb->cellhd.cols, 1, fcb->gdal->type, 0, 0);
212 
213  return err == CE_None ? 0 : -1;
214 }
215 #endif
216 
217 /*--------------------------------------------------------------------------*/
218 
219 /* Actually read a row of data in */
220 
221 static int read_data(int fd, int row, unsigned char *data_buf, int *nbytes)
222 {
223  struct fileinfo *fcb = &G__.fileinfo[fd];
224 
225 #ifdef HAVE_GDAL
226  if (fcb->gdal)
227  return read_data_gdal(fd, row, data_buf, nbytes);
228 #endif
229 
230  if (!fcb->cellhd.compressed)
231  return read_data_uncompressed(fd, row, data_buf, nbytes);
232 
233  /* map is in compressed form */
234 
235  if (fcb->map_type == CELL_TYPE)
236  return read_data_compressed(fd, row, data_buf, nbytes);
237  else
238  return read_data_fp_compressed(fd, row, data_buf, nbytes);
239 }
240 
241 /*--------------------------------------------------------------------------*/
242 
243 /* copy cell file data to user buffer translated by window column mapping */
244 
245 static void cell_values_int(int fd, const unsigned char *data,
246  const COLUMN_MAPPING * cmap, int nbytes,
247  void *cell, int n)
248 {
249  CELL *c = cell;
250  COLUMN_MAPPING cmapold = 0;
251  int big = (size_t) nbytes >= sizeof(CELL);
252  int i;
253 
254  for (i = 0; i < n; i++) {
255  const unsigned char *d;
256  int neg;
257  CELL v;
258  int j;
259 
260  if (!cmap[i]) {
261  c[i] = 0;
262  continue;
263  }
264 
265  if (cmap[i] == cmapold) {
266  c[i] = c[i - 1];
267  continue;
268  }
269 
270  d = data + (cmap[i] - 1) * nbytes;
271 
272  if (big && (*d & 0x80)) {
273  neg = 1;
274  v = *d++ & 0x7f;
275  }
276  else {
277  neg = 0;
278  v = *d++;
279  }
280 
281  for (j = 1; j < nbytes; j++)
282  v = (v << 8) + *d++;
283 
284  c[i] = neg ? -v : v;
285 
286  cmapold = cmap[i];
287  }
288 }
289 
290 /*--------------------------------------------------------------------------*/
291 
292 static void cell_values_float(int fd, const unsigned char *data,
293  const COLUMN_MAPPING * cmap, int nbytes,
294  void *cell, int n)
295 {
296  struct fileinfo *fcb = &G__.fileinfo[fd];
297  FCELL *c = cell;
298  COLUMN_MAPPING cmapold = 0;
299  XDR *xdrs = &fcb->xdrstream;
300  int i;
301 
302  /* xdr stream is initialized to read from */
303  /* fcb->data in 'opencell.c' */
304  xdr_setpos(xdrs, 0);
305 
306  for (i = 0; i < n; i++) {
307  if (!cmap[i]) {
308  c[i] = 0;
309  continue;
310  }
311 
312  if (cmap[i] == cmapold) {
313  c[i] = c[i - 1];
314  continue;
315  }
316 
317  if (cmap[i] < cmapold) {
318  xdr_setpos(xdrs, 0);
319  cmapold = 0;
320  }
321 
322  while (cmapold++ != cmap[i]) /* skip */
323  if (!xdr_float(xdrs, &c[i]))
324  G_fatal_error(_("cell_values_float: xdr_float failed for index %d"),
325  i);
326 
327  cmapold--;
328  }
329 }
330 
331 /*--------------------------------------------------------------------------*/
332 
333 static void cell_values_double(int fd, const unsigned char *data,
334  const COLUMN_MAPPING * cmap, int nbytes,
335  void *cell, int n)
336 {
337  struct fileinfo *fcb = &G__.fileinfo[fd];
338  DCELL *c = cell;
339  COLUMN_MAPPING cmapold = 0;
340  XDR *xdrs = &fcb->xdrstream;
341  int i;
342 
343  /* xdr stream is initialized to read from */
344  /* fcb->data in 'opencell.c' */
345  xdr_setpos(xdrs, 0);
346 
347  for (i = 0; i < n; i++) {
348  if (!cmap[i]) {
349  c[i] = 0;
350  continue;
351  }
352 
353  if (cmap[i] == cmapold) {
354  c[i] = c[i - 1];
355  continue;
356  }
357 
358  if (cmap[i] < cmapold) {
359  xdr_setpos(xdrs, 0);
360  cmapold = 0;
361  }
362 
363  while (cmapold++ != cmap[i]) /* skip */
364  if (!xdr_double(xdrs, &c[i]))
365  G_fatal_error(_("cell_values_double: xdr_double failed for index %d"),
366  i);
367 
368  cmapold--;
369  }
370 }
371 
372 /*--------------------------------------------------------------------------*/
373 
374 /*--------------------------------------------------------------------------*/
375 
376 #ifdef HAVE_GDAL
377 
378 /*--------------------------------------------------------------------------*/
379 
380 static void gdal_values_int(int fd, const unsigned char *data,
381  const COLUMN_MAPPING *cmap, int nbytes,
382  CELL *cell, int n)
383 {
384  struct fileinfo *fcb = &G__.fileinfo[fd];
385  const unsigned char *d;
386  COLUMN_MAPPING cmapold = 0;
387  int i;
388 
389  for (i = 0; i < n; i++) {
390  if (!cmap[i]) {
391  cell[i] = 0;
392  continue;
393  }
394 
395  if (cmap[i] == cmapold) {
396  cell[i] = cell[i-1];
397  continue;
398  }
399 
400  d = data + (cmap[i] - 1) * nbytes;
401 
402  switch (fcb->gdal->type) {
403  case GDT_Byte: cell[i] = *(GByte *)d; break;
404  case GDT_Int16: cell[i] = *(GInt16 *)d; break;
405  case GDT_UInt16: cell[i] = *(GUInt16 *)d; break;
406  case GDT_Int32: cell[i] = *(GInt32 *)d; break;
407  case GDT_UInt32: cell[i] = *(GUInt32 *)d; break;
408  default:
409  /* shouldn't happen */
410  G_set_c_null_value(&cell[i], 1);
411  break;
412  }
413 
414  cmapold = cmap[i];
415  }
416 }
417 
418 /*--------------------------------------------------------------------------*/
419 
420 static void gdal_values_float(int fd, const float *data,
421  const COLUMN_MAPPING *cmap, int nbytes,
422  FCELL *cell, int n)
423 {
424  COLUMN_MAPPING cmapold = 0;
425  int i;
426 
427  for (i = 0; i < n; i++) {
428  if (!cmap[i]) {
429  cell[i] = 0;
430  continue;
431  }
432 
433  if (cmap[i] == cmapold) {
434  cell[i] = cell[i-1];
435  continue;
436  }
437 
438  cell[i] = data[cmap[i] - 1];
439 
440  cmapold = cmap[i];
441  }
442 }
443 
444 /*--------------------------------------------------------------------------*/
445 
446 static void gdal_values_double(int fd, const double *data,
447  const COLUMN_MAPPING *cmap, int nbytes,
448  DCELL *cell, int n)
449 {
450  COLUMN_MAPPING cmapold = 0;
451  int i;
452 
453  for (i = 0; i < n; i++) {
454  if (!cmap[i]) {
455  cell[i] = 0;
456  continue;
457  }
458 
459  if (cmap[i] == cmapold) {
460  cell[i] = cell[i-1];
461  continue;
462  }
463 
464  cell[i] = data[cmap[i] - 1];
465 
466  cmapold = cmap[i];
467  }
468 }
469 
470 /*--------------------------------------------------------------------------*/
471 
472 #endif
473 
474 /*--------------------------------------------------------------------------*/
475 
476 /* transfer_to_cell_XY takes bytes from fcb->data, converts these bytes with
477  the appropriate procedure (e.g. XDR or byte reordering) into type X
478  values which are put into array G__.work_buf.
479  finally the values in G__.work_buf are converted into
480  type Y and put into 'cell'.
481  if type X == type Y the intermediate step of storing the values in
482  G__.work_buf might be ommited. check the appropriate function for XY to
483  determine the procedure of conversion.
484  */
485 
486 /*--------------------------------------------------------------------------*/
487 
488 static void transfer_to_cell_XX(int fd, void *cell)
489 {
490  static void (*cell_values_type[3]) () = {
491  cell_values_int, cell_values_float, cell_values_double};
492 #ifdef HAVE_GDAL
493  static void (*gdal_values_type[3]) () = {
494  gdal_values_int, gdal_values_float, gdal_values_double};
495 #endif
496  struct fileinfo *fcb = &G__.fileinfo[fd];
497 
498 #ifdef HAVE_GDAL
499  if (fcb->gdal)
500  (gdal_values_type[fcb->map_type]) (fd, fcb->data, fcb->col_map,
501  fcb->cur_nbytes, cell,
502  G__.window.cols);
503  else
504 #endif
505  (cell_values_type[fcb->map_type]) (fd, fcb->data, fcb->col_map,
506  fcb->cur_nbytes, cell,
507  G__.window.cols);
508 }
509 
510 /*--------------------------------------------------------------------------*/
511 
512 static void transfer_to_cell_fi(int fd, void *cell)
513 {
514  struct fileinfo *fcb = &G__.fileinfo[fd];
515  int i;
516 
517  transfer_to_cell_XX(fd, G__.work_buf);
518 
519  for (i = 0; i < G__.window.cols; i++)
520  ((CELL *) cell)[i] = (fcb->col_map[i] == 0)
521  ? 0
523  ((FCELL *) G__.work_buf)[i]);
524 }
525 
526 static void transfer_to_cell_di(int fd, void *cell)
527 {
528  struct fileinfo *fcb = &G__.fileinfo[fd];
529  int i;
530 
531  transfer_to_cell_XX(fd, G__.work_buf);
532 
533  for (i = 0; i < G__.window.cols; i++)
534  ((CELL *) cell)[i] = (fcb->col_map[i] == 0)
535  ? 0
537  ((DCELL *) G__.work_buf)[i]);
538 }
539 
540 /*--------------------------------------------------------------------------*/
541 
542 static void transfer_to_cell_if(int fd, void *cell)
543 {
544  int i;
545 
546  transfer_to_cell_XX(fd, G__.work_buf);
547 
548  for (i = 0; i < G__.window.cols; i++)
549  ((FCELL *) cell)[i] = ((CELL *) G__.work_buf)[i];
550 }
551 
552 static void transfer_to_cell_df(int fd, void *cell)
553 {
554  int i;
555 
556  transfer_to_cell_XX(fd, G__.work_buf);
557 
558  for (i = 0; i < G__.window.cols; i++)
559  ((FCELL *) cell)[i] = ((DCELL *) G__.work_buf)[i];
560 }
561 
562 /*--------------------------------------------------------------------------*/
563 
564 static void transfer_to_cell_id(int fd, void *cell)
565 {
566  int i;
567 
568  transfer_to_cell_XX(fd, G__.work_buf);
569 
570  for (i = 0; i < G__.window.cols; i++)
571  ((DCELL *) cell)[i] = ((CELL *) G__.work_buf)[i];
572 }
573 
574 static void transfer_to_cell_fd(int fd, void *cell)
575 {
576  int i;
577 
578  transfer_to_cell_XX(fd, G__.work_buf);
579 
580  for (i = 0; i < G__.window.cols; i++)
581  ((DCELL *) cell)[i] = ((FCELL *) G__.work_buf)[i];
582 }
583 
584 /*--------------------------------------------------------------------------*/
585 
586 /*--------------------------------------------------------------------------*/
587 
588 /*--------------------------------------------------------------------------*/
589 /*
590  * works for all map types and doesn't consider
591  * null row corresponding to the requested row
592  */
593 static int get_map_row_nomask(int fd, void *rast, int row,
594  RASTER_MAP_TYPE data_type)
595 {
596  static void (*transfer_to_cell_FtypeOtype[3][3]) () = { {
597  transfer_to_cell_XX, transfer_to_cell_if, transfer_to_cell_id}, {
598  transfer_to_cell_fi, transfer_to_cell_XX, transfer_to_cell_fd}, {
599  transfer_to_cell_di, transfer_to_cell_df, transfer_to_cell_XX}};
600  struct fileinfo *fcb = &G__.fileinfo[fd];
601  int r;
602  int rowStatus;
603 
604  rowStatus = compute_window_row(fd, row, &r);
605 
606  if (rowStatus <= 0) {
607  fcb->cur_row = -1;
608  G_zero_raster_buf(rast, data_type);
609  return rowStatus;
610  }
611 
612  /* read cell file row if not in memory */
613  if (r != fcb->cur_row) {
614  fcb->cur_row = r;
615 
616  if (read_data(fd, fcb->cur_row, fcb->data, &fcb->cur_nbytes) < 0) {
617  G_zero_raster_buf(rast, data_type);
618 
619  if (!fcb->io_error) {
620  if (fcb->cellhd.compressed)
621  G_warning(_("Error reading compressed map <%s@%s>, row %d"),
622  fcb->name, fcb->mapset, r);
623  else
624  G_warning(_("Error reading map <%s@%s>, row %d"),
625  fcb->name, fcb->mapset, r);
626 
627  fcb->io_error = 1;
628  }
629  return -1;
630  }
631  }
632 
633  (transfer_to_cell_FtypeOtype[fcb->map_type][data_type]) (fd, rast);
634 
635  return 1;
636 }
637 
638 /*--------------------------------------------------------------------------*/
639 
640 static int get_map_row_no_reclass(int fd, void *rast, int row,
641  RASTER_MAP_TYPE data_type, int null_is_zero,
642  int with_mask)
643 {
644  int stat;
645 
646  stat = get_map_row_nomask(fd, rast, row, data_type);
647  if (stat < 0)
648  return stat;
649 
650  stat = embed_nulls(fd, rast, row, data_type, null_is_zero, with_mask);
651  if (stat < 0)
652  return stat;
653 
654  return 1;
655 }
656 
657 /*--------------------------------------------------------------------------*/
658 
659 static int get_map_row(int fd, void *rast, int row, RASTER_MAP_TYPE data_type,
660  int null_is_zero, int with_mask)
661 {
662  struct fileinfo *fcb = &G__.fileinfo[fd];
663  int size = G_raster_size(data_type);
664  void *buf;
665  int type;
666  int stat;
667  int i;
668 
669  if (fcb->reclass_flag && data_type != CELL_TYPE) {
670  buf = G__.temp_buf;
671  type = CELL_TYPE;
672  }
673  else {
674  buf = rast;
675  type = data_type;
676  }
677 
678  stat =
679  get_map_row_no_reclass(fd, buf, row, type, null_is_zero, with_mask);
680  if (stat < 0)
681  return stat;
682 
683  if (!fcb->reclass_flag)
684  return 1;
685 
686  /* if the map is reclass table, get and
687  reclass CELL row and copy results to needed type */
688 
689  do_reclass_int(fd, buf, null_is_zero);
690 
691  if (data_type == CELL_TYPE)
692  return 1;
693 
694  for (i = 0; i < G__.window.cols; i++) {
695  G_set_raster_value_c(rast, G__.temp_buf[i], data_type);
696  rast = G_incr_void_ptr(rast, size);
697  }
698 
699  return 1;
700 }
701 
702 /*--------------------------------------------------------------------------*/
703 
704 /*--------------------------------------------------------------------------*/
705 
706 /*--------------------------------------------------------------------------*/
707 
740 int G_get_map_row_nomask(int fd, CELL * buf, int row)
741 {
742  return get_map_row(fd, buf, row, CELL_TYPE, 1, 0);
743 }
744 
760 int G_get_raster_row_nomask(int fd, void *buf, int row,
761  RASTER_MAP_TYPE data_type)
762 {
763  return get_map_row(fd, buf, row, data_type, 0, 0);
764 }
765 
781 int G_get_c_raster_row_nomask(int fd, CELL * buf, int row)
782 {
783  return G_get_raster_row_nomask(fd, buf, row, CELL_TYPE);
784 }
785 
801 int G_get_f_raster_row_nomask(int fd, FCELL * buf, int row)
802 {
803  return G_get_raster_row_nomask(fd, buf, row, FCELL_TYPE);
804 }
805 
821 int G_get_d_raster_row_nomask(int fd, DCELL * buf, int row)
822 {
823  return G_get_raster_row_nomask(fd, buf, row, DCELL_TYPE);
824 }
825 
826 /*--------------------------------------------------------------------------*/
827 
848 int G_get_map_row(int fd, CELL * buf, int row)
849 {
850  return get_map_row(fd, buf, row, CELL_TYPE, 1, 1);
851 }
852 
895 int G_get_raster_row(int fd, void *buf, int row, RASTER_MAP_TYPE data_type)
896 {
897  return get_map_row(fd, buf, row, data_type, 0, 1);
898 }
899 
922 int G_get_c_raster_row(int fd, CELL * buf, int row)
923 {
924  return G_get_raster_row(fd, buf, row, CELL_TYPE);
925 }
926 
945 int G_get_f_raster_row(int fd, FCELL * buf, int row)
946 {
947  return G_get_raster_row(fd, buf, row, FCELL_TYPE);
948 }
949 
965 int G_get_d_raster_row(int fd, DCELL * buf, int row)
966 {
967  return G_get_raster_row(fd, buf, row, DCELL_TYPE);
968 }
969 
970 /*--------------------------------------------------------------------------*/
971 
972 /*--------------------------------------------------------------------------*/
973 
974 /*--------------------------------------------------------------------------*/
975 
976 static int open_null_read(int fd)
977 {
978  struct fileinfo *fcb = &G__.fileinfo[fd];
979  char *name, *mapset, *dummy;
980  int null_fd;
981 
982  if (fcb->null_file_exists == 0)
983  return -1;
984 
985  if (fcb->reclass_flag) {
986  name = fcb->reclass.name;
987  mapset = fcb->reclass.mapset;
988  }
989  else {
990  name = fcb->name;
991  mapset = fcb->mapset;
992  }
993 
994  dummy = G_find_file_misc("cell_misc", NULL_FILE, name, mapset);
995 
996  if (!dummy) {
997  /* G_warning("unable to find [%s]",path); */
998  fcb->null_file_exists = 0;
999  return -1;
1000  }
1001 
1002  null_fd = G_open_old_misc("cell_misc", NULL_FILE, name, mapset);
1003  if (null_fd < 0)
1004  return -1;
1005 
1006  fcb->null_file_exists = 1;
1007 
1008  return null_fd;
1009 }
1010 
1011 static int read_null_bits(int null_fd, unsigned char *flags, int row,
1012  int cols, int fd)
1013 {
1014  off_t offset;
1015  ssize_t size;
1016  int R;
1017 
1018  if (compute_window_row(fd, row, &R) <= 0) {
1019  G__init_null_bits(flags, cols);
1020  return 1;
1021  }
1022 
1023  if (null_fd < 0)
1024  return -1;
1025 
1026  size = G__null_bitstream_size(cols);
1027  offset = (off_t) size *R;
1028 
1029  if (lseek(null_fd, offset, SEEK_SET) < 0) {
1030  G_warning(_("Error reading null row %d"), R);
1031  return -1;
1032  }
1033 
1034  if (read(null_fd, flags, size) != size) {
1035  G_warning(_("Error reading null row %d"), R);
1036  return -1;
1037  }
1038 
1039  return 1;
1040 }
1041 
1042 static void get_null_value_row_nomask(int fd, char *flags, int row)
1043 {
1044  struct fileinfo *fcb = &G__.fileinfo[fd];
1045  int i, j, null_fd;
1046 
1047  if (row > G__.window.rows || row < 0) {
1048  G_warning(_("Reading raster map <%s@%s> request for row %d is outside region"),
1049  fcb->name, fcb->mapset, row);
1050  }
1051 
1052  if ((fcb->min_null_row > row) ||
1053  (fcb->min_null_row + NULL_ROWS_INMEM - 1 < row))
1054  /* the null row row is not in memory */
1055  {
1056  /* read in NULL_ROWS_INMEM rows from null file
1057  so that the requested row is between fcb->min_null_row
1058  and fcb->min_null_row + NULL_ROWS_INMEM */
1059 
1060  fcb->min_null_row = (row / NULL_ROWS_INMEM) * NULL_ROWS_INMEM;
1061 
1062  null_fd = open_null_read(fd);
1063 
1064  for (i = 0; i < NULL_ROWS_INMEM; i++) {
1065  /* G__.window.rows doesn't have to be a multiple of NULL_ROWS_INMEM */
1066  if (i + fcb->min_null_row >= G__.window.rows)
1067  break;
1068 
1069  if (read_null_bits(null_fd, fcb->null_work_buf,
1070  i + fcb->min_null_row, fcb->cellhd.cols,
1071  fd) < 0) {
1072  if (fcb->map_type == CELL_TYPE) {
1073  /*
1074  If can't read null row, assume that all map 0's are nulls
1075  use allocated G__.mask_buf to read map row */
1076  get_map_row_nomask(fd, (void *)G__.mask_buf,
1077  i + fcb->min_null_row, CELL_TYPE);
1078  for (j = 0; j < G__.window.cols; j++) {
1079  if (G__.mask_buf[j] == 0)
1080  flags[j] = 1;
1081  else
1082  flags[j] = 0;
1083  }
1084  }
1085  else { /* fp map */
1086 
1087  /* if can't read null row, assume that all data is valid */
1088  G_zero(flags, sizeof(char) * G__.window.cols);
1089  /* the flags row is ready now */
1090  }
1091  } /*if no null file */
1092  else {
1093  /* copy null row to flags row translated by window column mapping */
1094  /* the fcb->NULL_ROWS[row-fcb->min_null_row] has G__.window.cols bits, */
1095  /* the fcb->null_work_buf has size fcb->cellhd.cols */
1096  for (j = 0; j < G__.window.cols; j++) {
1097  if (!fcb->col_map[j])
1098  flags[j] = 1;
1099  else
1100  flags[j] = G__check_null_bit(fcb->null_work_buf,
1101  fcb->col_map[j] - 1,
1102  fcb->cellhd.cols);
1103  }
1104  }
1105  /* remember the null row for i for the future reference */
1106 
1107  /*bf-We should take of the size - or we get
1108  zeros running on their own after flags convertions -A.Sh. */
1109  fcb->NULL_ROWS[i] = G_realloc(fcb->NULL_ROWS[i],
1111  cols) + 1);
1112  if (fcb->NULL_ROWS[i] == NULL)
1113  G_fatal_error("get_null_value_row_nomask: %s",
1114  _("Unable to realloc buffer"));
1115 
1116  G__convert_01_flags(flags, fcb->NULL_ROWS[i], G__.window.cols);
1117 
1118  } /* for loop */
1119 
1120  if (null_fd > 0)
1121  close(null_fd);
1122  } /* row is not in memory */
1123 
1124  /* copy null file data translated by column mapping to user null row */
1125  /* the user requested flags row is of size G__.window.cols */
1126  G__convert_flags_01(flags, fcb->NULL_ROWS[row - fcb->min_null_row],
1127  G__.window.cols);
1128 }
1129 
1130 /*--------------------------------------------------------------------------*/
1131 
1132 #ifdef HAVE_GDAL
1133 
1134 static void get_null_value_row_gdal(int fd, char *flags, int row)
1135 {
1136  struct fileinfo *fcb = &G__.fileinfo[fd];
1137  DCELL *tmp_buf = G_allocate_d_raster_buf();
1138  int i;
1139 
1140  if (get_map_row_nomask(fd, tmp_buf, row, DCELL_TYPE) <= 0) {
1141  memset(flags, 1, G__.window.cols);
1142  G_free(tmp_buf);
1143  return;
1144  }
1145 
1146  for (i = 0; i < G__.window.cols; i++)
1147  /* note: using == won't work if the null value is NaN */
1148  flags[i] = !fcb->col_map[i] ||
1149  memcmp(&tmp_buf[i], &fcb->gdal->null_val, sizeof(DCELL)) == 0;
1150 
1151  G_free(tmp_buf);
1152 }
1153 
1154 #endif
1155 
1156 /*--------------------------------------------------------------------------*/
1157 
1158 /*--------------------------------------------------------------------------*/
1159 
1160 static void embed_mask(char *flags, int row)
1161 {
1162  int i;
1163 
1164  if (G__.auto_mask <= 0)
1165  return;
1166 
1167  if (get_map_row_nomask(G__.mask_fd, G__.mask_buf, row, CELL_TYPE) < 0)
1168  return;
1169 
1171  do_reclass_int(G__.mask_fd, G__.mask_buf, 1);
1172 
1173  for (i = 0; i < G__.window.cols; i++)
1174  if (G__.mask_buf[i] == 0)
1175  flags[i] = 1;
1176 }
1177 
1178 static void get_null_value_row(int fd, char *flags, int row, int with_mask)
1179 {
1180 #ifdef HAVE_GDAL
1181  struct fileinfo *fcb = &G__.fileinfo[fd];
1182  if (fcb->gdal)
1183  get_null_value_row_gdal(fd, flags, row);
1184  else
1185 #endif
1186  get_null_value_row_nomask(fd, flags, row);
1187 
1188  if (with_mask)
1189  embed_mask(flags, row);
1190 }
1191 
1192 static int embed_nulls(int fd, void *buf, int row, RASTER_MAP_TYPE map_type,
1193  int null_is_zero, int with_mask)
1194 {
1195  struct fileinfo *fcb = &G__.fileinfo[fd];
1196  int i;
1197 
1198  /* this is because without null file the nulls can be only due to 0's
1199  in data row or mask */
1200  if (null_is_zero && !fcb->null_file_exists
1201  && (G__.auto_mask <= 0 || !with_mask))
1202  return 1;
1203 
1204  get_null_value_row(fd, G__.null_buf, row, with_mask);
1205 
1206  for (i = 0; i < G__.window.cols; i++) {
1207  /* also check for nulls which might be already embedded by quant
1208  rules in case of fp map. */
1209  if (G__.null_buf[i] || G_is_null_value(buf, map_type)) {
1210  /* G__set_[f/d]_null_value() sets it to 0 is the embedded mode
1211  is not set and calls G_set_[f/d]_null_value() otherwise */
1212  G__set_null_value(buf, 1, null_is_zero, map_type);
1213  }
1214  buf = G_incr_void_ptr(buf, G_raster_size(map_type));
1215  }
1216 
1217  return 1;
1218 }
1219 
1220 /*--------------------------------------------------------------------------*/
1221 
1222 /*--------------------------------------------------------------------------*/
1223 
1224 /*--------------------------------------------------------------------------*/
1225 
1242 int G_get_null_value_row(int fd, char *flags, int row)
1243 {
1244  struct fileinfo *fcb = &G__.fileinfo[fd];
1245 
1246  if (!fcb->reclass_flag)
1247  get_null_value_row(fd, flags, row, 1);
1248  else {
1249  CELL *buf = G_allocate_c_raster_buf();
1250  int i;
1251 
1252  G_get_c_raster_row(fd, buf, row);
1253  for (i = 0; i < G__.window.cols; i++)
1254  flags[i] = G_is_c_null_value(&buf[i]) ? 1 : 0;
1255 
1256  G_free(buf);
1257  }
1258 
1259  return 1;
1260 }
int G_is_c_null_value(const CELL *cellVal)
Returns 1 if cell is NULL, 0 otherwise. This will test if the value cell is the largest int...
Definition: null_val.c:244
int mask_fd
Definition: G.h:80
int nbytes
Definition: G.h:58
int G_get_c_raster_row_nomask(int fd, CELL *buf, int row)
Read raster row without masking (CELL type)
Definition: gis/get_row.c:781
int auto_mask
Definition: G.h:81
int G_get_d_raster_row(int fd, DCELL *buf, int row)
Get raster row (DCELL type)
Definition: gis/get_row.c:965
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
void G__set_null_value(void *rast, int numVals, int null_is_zero, RASTER_MAP_TYPE data_type)
Definition: null_val.c:90
unsigned char * work_buf
Definition: G.h:87
RASTER_MAP_TYPE map_type
Definition: G.h:59
char * null_buf
Definition: G.h:83
char * name
Definition: G.h:63
CELL * G_allocate_c_raster_buf(void)
Allocates memory for a raster map of type CELL.
Definition: alloc_cell.c:96
off_t * row_ptr
Definition: G.h:51
FILE * fd
Definition: g3dcolor.c:368
string name
Definition: render.py:1314
int G_get_map_row_nomask(int fd, CELL *buf, int row)
Read raster row without masking (this routine is deprecated)
Definition: gis/get_row.c:740
#define min(x, y)
Definition: draw2.c:68
int io_error
Definition: G.h:65
int G_get_raster_row(int fd, void *buf, int row, RASTER_MAP_TYPE data_type)
Get raster row.
Definition: gis/get_row.c:895
float r
Definition: named_colr.c:8
unsigned char * null_work_buf
Definition: G.h:68
int G_zero_raster_buf(void *rast, RASTER_MAP_TYPE data_type)
Zero a raster buffer.
Definition: zero_cell.c:54
unsigned char * data
Definition: G.h:57
CELL G_quant_get_cell_value(struct Quant *q, DCELL dcellVal)
Returns a CELL category for the floating-point value based on the quantization rules in q...
Definition: quant.c:775
int G_get_f_raster_row_nomask(int fd, FCELL *buf, int row)
Read raster row without masking (FCELL type)
Definition: gis/get_row.c:801
int G_get_f_raster_row(int fd, FCELL *buf, int row)
Get raster row (FCELL type)
Definition: gis/get_row.c:945
const char * err
Definition: g3dcolor.c:50
COLUMN_MAPPING * col_map
Definition: G.h:52
struct GDAL_link * gdal
Definition: G.h:71
#define max(x, y)
Definition: draw2.c:69
void * G_incr_void_ptr(const void *ptr, const size_t size)
Advance void pointer.
Definition: gis/raster.c:33
int G_get_map_row(int fd, CELL *buf, int row)
Get raster row (this routine is deprecated!)
Definition: gis/get_row.c:848
struct Reclass reclass
Definition: G.h:45
int G_open_old_misc(const char *dir, const char *element, const char *name, const char *mapset)
open a database file for reading
Definition: open_misc.c:124
tuple size
value.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
Definition: tools.py:2334
int G_zero(void *buf, int i)
Zero out a buffer, buf, of length i.
Definition: gis/zero.c:29
struct Cell_head window
Definition: G.h:78
Definition: G.h:74
int G_set_raster_value_c(void *rast, CELL cval, RASTER_MAP_TYPE data_type)
Places a CELL raster value.
Definition: gis/raster.c:125
double C1
Definition: G.h:53
tuple data
int stat
Definition: g3dcolor.c:369
int G_get_c_raster_row(int fd, CELL *buf, int row)
Get raster row (CELL type)
Definition: gis/get_row.c:922
size_t G_raster_size(RASTER_MAP_TYPE data_type)
Returns size of a raster CELL in bytes.
Definition: alloc_cell.c:38
int G_get_null_value_row(int fd, char *flags, int row)
Read or simmulate null value row.
Definition: gis/get_row.c:1242
char * mapset
Definition: G.h:64
int G__convert_01_flags(const char *zero_ones, unsigned char *flags, int n)
Definition: null_val.c:524
int cur_row
Definition: G.h:54
int G__init_null_bits(unsigned char *flags, int cols)
Definition: null_val.c:598
int G__convert_flags_01(char *zero_ones, const unsigned char *flags, int n)
Definition: null_val.c:563
int
Definition: g3dcolor.c:48
int G__null_bitstream_size(int cols)
Determines null bitstream size.
Definition: alloc_cell.c:171
int cur_nbytes
Definition: G.h:56
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
Definition: g3drange.c:62
double C2
Definition: G.h:53
return NULL
Definition: dbfopen.c:1394
int null_file_exists
Definition: G.h:62
struct fileinfo * fileinfo
Definition: G.h:95
XDR xdrstream
Definition: G.h:66
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
unsigned char * compressed_buf
Definition: G.h:85
#define NULL_FILE
Definition: gis/get_row.c:30
tuple cols
struct Cell_head cellhd
Definition: G.h:44
int min_null_row
Definition: G.h:69
Definition: G.h:41
int COLUMN_MAPPING
Definition: G.h:19
CELL * temp_buf
Definition: G.h:84
#define NULL_ROWS_INMEM
Definition: G.h:11
CELL * mask_buf
Definition: G.h:82
void G_set_c_null_value(CELL *cellVals, int numVals)
Definition: null_val.c:142
char * G_find_file_misc(const char *dir, const char *element, char *name, const char *mapset)
Definition: find_file.c:164
struct Quant quant
Definition: G.h:70
int G_get_d_raster_row_nomask(int fd, DCELL *buf, int row)
Read raster row without masking (DCELL type)
Definition: gis/get_row.c:821
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
int G__check_null_bit(const unsigned char *flags, int bit_num, int n)
Definition: null_val.c:440
int n
Definition: dataquad.c:291
unsigned char * NULL_ROWS[NULL_ROWS_INMEM]
Definition: G.h:67
int G_is_null_value(const void *rast, RASTER_MAP_TYPE data_type)
If the data_type is CELL_TYPE, calls G_is_c_null_value ((CELL *) rast); If the data_type is FCELL_TYP...
Definition: null_val.c:207
int G_get_raster_row_nomask(int fd, void *buf, int row, RASTER_MAP_TYPE data_type)
Read raster row without masking.
Definition: gis/get_row.c:760
DCELL * G_allocate_d_raster_buf(void)
Allocates memory for a raster map of type DCELL.
Definition: alloc_cell.c:126
int reclass_flag
Definition: G.h:50