00001
00016 #include <string.h>
00017 #include <unistd.h>
00018 #include <sys/types.h>
00019
00020 #include <rpc/types.h>
00021 #include <rpc/xdr.h>
00022
00023 #include <grass/config.h>
00024 #include <grass/glocale.h>
00025
00026 #include "G.h"
00027
00028
00029
00030 #define NULL_FILE "null"
00031
00032
00033
00034 static int embed_nulls(int, void *, int, RASTER_MAP_TYPE, int, int);
00035
00036
00037
00038 static int compute_window_row(int fd, int row, int *cellRow)
00039 {
00040 struct fileinfo *fcb = &G__.fileinfo[fd];
00041 double f;
00042 int r;
00043
00044
00045 if (row < 0 || row >= G__.window.rows) {
00046 G_warning(_("Reading raster map <%s@%s> request for row %d is outside region"),
00047 fcb->name, fcb->mapset, row);
00048
00049 return -1;
00050 }
00051
00052
00053 f = row * fcb->C1 + fcb->C2;
00054 r = (int)f;
00055 if (f < r)
00056 r--;
00057
00058 if (r < 0 || r >= fcb->cellhd.rows)
00059 return 0;
00060
00061 *cellRow = r;
00062
00063 return 1;
00064 }
00065
00066
00067
00068 static void do_reclass_int(int fd, void *cell, int null_is_zero)
00069 {
00070 struct fileinfo *fcb = &G__.fileinfo[fd];
00071 CELL *c = cell;
00072 CELL *reclass_table = fcb->reclass.table;
00073 CELL min = fcb->reclass.min;
00074 CELL max = fcb->reclass.max;
00075 int i;
00076
00077 for (i = 0; i < G__.window.cols; i++) {
00078 if (G_is_c_null_value(&c[i])) {
00079 if (null_is_zero)
00080 c[i] = 0;
00081 continue;
00082 }
00083
00084 if (c[i] < min || c[i] > max) {
00085 if (null_is_zero)
00086 c[i] = 0;
00087 else
00088 G_set_c_null_value(&c[i], 1);
00089 continue;
00090 }
00091
00092 c[i] = reclass_table[c[i] - min];
00093
00094 if (null_is_zero && G_is_c_null_value(&c[i]))
00095 c[i] = 0;
00096 }
00097 }
00098
00099
00100
00101 static int read_data_fp_compressed(int fd, int row, unsigned char *data_buf,
00102 int *nbytes)
00103 {
00104 struct fileinfo *fcb = &G__.fileinfo[fd];
00105 off_t t1 = fcb->row_ptr[row];
00106 off_t t2 = fcb->row_ptr[row + 1];
00107 size_t readamount = t2 - t1;
00108 size_t bufsize = fcb->cellhd.cols * fcb->nbytes;
00109
00110 if (lseek(fd, t1, SEEK_SET) < 0)
00111 return -1;
00112
00113 *nbytes = fcb->nbytes;
00114
00115 if ((size_t) G_zlib_read(fd, readamount, data_buf, bufsize) != bufsize)
00116 return -1;
00117
00118 return 0;
00119 }
00120
00121
00122
00123 static void rle_decompress(unsigned char *dst, const unsigned char *src,
00124 int nbytes, int size)
00125 {
00126 int pairs = size / (nbytes + 1);
00127 int i;
00128
00129 for (i = 0; i < pairs; i++) {
00130 int repeat = *src++;
00131 int j;
00132
00133 for (j = 0; j < repeat; j++) {
00134 memcpy(dst, src, nbytes);
00135 dst += nbytes;
00136 }
00137
00138 src += nbytes;
00139 }
00140 }
00141
00142 static int read_data_compressed(int fd, int row, unsigned char *data_buf,
00143 int *nbytes)
00144 {
00145 struct fileinfo *fcb = &G__.fileinfo[fd];
00146 off_t t1 = fcb->row_ptr[row];
00147 off_t t2 = fcb->row_ptr[row + 1];
00148 ssize_t readamount = t2 - t1;
00149 unsigned char *cmp = G__.compressed_buf;
00150 int n;
00151
00152 if (lseek(fd, t1, SEEK_SET) < 0)
00153 return -1;
00154
00155 if (read(fd, cmp, readamount) != readamount)
00156 return -1;
00157
00158
00159 if (fcb->cellhd.compressed > 0) {
00160
00161 n = *nbytes = *cmp++;
00162 readamount--;
00163 }
00164 else
00165
00166 n = *nbytes = fcb->nbytes;
00167
00168 if (fcb->cellhd.compressed < 0 || readamount < n * fcb->cellhd.cols) {
00169 if (fcb->cellhd.compressed == 2)
00170 G_zlib_expand(cmp, readamount, data_buf, n * fcb->cellhd.cols);
00171 else
00172 rle_decompress(data_buf, cmp, n, readamount);
00173 }
00174 else
00175 memcpy(data_buf, cmp, readamount);
00176
00177 return 0;
00178 }
00179
00180
00181
00182 static int read_data_uncompressed(int fd, int row, unsigned char *data_buf,
00183 int *nbytes)
00184 {
00185 struct fileinfo *fcb = &G__.fileinfo[fd];
00186 ssize_t bufsize = fcb->cellhd.cols * fcb->nbytes;
00187
00188 *nbytes = fcb->nbytes;
00189
00190 if (lseek(fd, (off_t) row * bufsize, SEEK_SET) == -1)
00191 return -1;
00192
00193 if (read(fd, data_buf, bufsize) != bufsize)
00194 return -1;
00195
00196 return 0;
00197 }
00198
00199
00200
00201 #ifdef HAVE_GDAL
00202 static int read_data_gdal(int fd, int row, unsigned char *data_buf, int *nbytes)
00203 {
00204 struct fileinfo *fcb = &G__.fileinfo[fd];
00205 CPLErr err;
00206
00207 *nbytes = fcb->nbytes;
00208
00209 err = G_gdal_raster_IO(
00210 fcb->gdal->band, GF_Read, 0, row, fcb->cellhd.cols, 1, data_buf,
00211 fcb->cellhd.cols, 1, fcb->gdal->type, 0, 0);
00212
00213 return err == CE_None ? 0 : -1;
00214 }
00215 #endif
00216
00217
00218
00219
00220
00221 static int read_data(int fd, int row, unsigned char *data_buf, int *nbytes)
00222 {
00223 struct fileinfo *fcb = &G__.fileinfo[fd];
00224
00225 #ifdef HAVE_GDAL
00226 if (fcb->gdal)
00227 return read_data_gdal(fd, row, data_buf, nbytes);
00228 #endif
00229
00230 if (!fcb->cellhd.compressed)
00231 return read_data_uncompressed(fd, row, data_buf, nbytes);
00232
00233
00234
00235 if (fcb->map_type == CELL_TYPE)
00236 return read_data_compressed(fd, row, data_buf, nbytes);
00237 else
00238 return read_data_fp_compressed(fd, row, data_buf, nbytes);
00239 }
00240
00241
00242
00243
00244
00245 static void cell_values_int(int fd, const unsigned char *data,
00246 const COLUMN_MAPPING * cmap, int nbytes,
00247 void *cell, int n)
00248 {
00249 CELL *c = cell;
00250 COLUMN_MAPPING cmapold = 0;
00251 int big = (size_t) nbytes >= sizeof(CELL);
00252 int i;
00253
00254 for (i = 0; i < n; i++) {
00255 const unsigned char *d;
00256 int neg;
00257 CELL v;
00258 int j;
00259
00260 if (!cmap[i]) {
00261 c[i] = 0;
00262 continue;
00263 }
00264
00265 if (cmap[i] == cmapold) {
00266 c[i] = c[i - 1];
00267 continue;
00268 }
00269
00270 d = data + (cmap[i] - 1) * nbytes;
00271
00272 if (big && (*d & 0x80)) {
00273 neg = 1;
00274 v = *d++ & 0x7f;
00275 }
00276 else {
00277 neg = 0;
00278 v = *d++;
00279 }
00280
00281 for (j = 1; j < nbytes; j++)
00282 v = (v << 8) + *d++;
00283
00284 c[i] = neg ? -v : v;
00285
00286 cmapold = cmap[i];
00287 }
00288 }
00289
00290
00291
00292 static void cell_values_float(int fd, const unsigned char *data,
00293 const COLUMN_MAPPING * cmap, int nbytes,
00294 void *cell, int n)
00295 {
00296 struct fileinfo *fcb = &G__.fileinfo[fd];
00297 FCELL *c = cell;
00298 COLUMN_MAPPING cmapold = 0;
00299 XDR *xdrs = &fcb->xdrstream;
00300 int i;
00301
00302
00303
00304 xdr_setpos(xdrs, 0);
00305
00306 for (i = 0; i < n; i++) {
00307 if (!cmap[i]) {
00308 c[i] = 0;
00309 continue;
00310 }
00311
00312 if (cmap[i] == cmapold) {
00313 c[i] = c[i - 1];
00314 continue;
00315 }
00316
00317 if (cmap[i] < cmapold) {
00318 xdr_setpos(xdrs, 0);
00319 cmapold = 0;
00320 }
00321
00322 while (cmapold++ != cmap[i])
00323 if (!xdr_float(xdrs, &c[i]))
00324 G_fatal_error(_("cell_values_float: xdr_float failed for index %d"),
00325 i);
00326
00327 cmapold--;
00328 }
00329 }
00330
00331
00332
00333 static void cell_values_double(int fd, const unsigned char *data,
00334 const COLUMN_MAPPING * cmap, int nbytes,
00335 void *cell, int n)
00336 {
00337 struct fileinfo *fcb = &G__.fileinfo[fd];
00338 DCELL *c = cell;
00339 COLUMN_MAPPING cmapold = 0;
00340 XDR *xdrs = &fcb->xdrstream;
00341 int i;
00342
00343
00344
00345 xdr_setpos(xdrs, 0);
00346
00347 for (i = 0; i < n; i++) {
00348 if (!cmap[i]) {
00349 c[i] = 0;
00350 continue;
00351 }
00352
00353 if (cmap[i] == cmapold) {
00354 c[i] = c[i - 1];
00355 continue;
00356 }
00357
00358 if (cmap[i] < cmapold) {
00359 xdr_setpos(xdrs, 0);
00360 cmapold = 0;
00361 }
00362
00363 while (cmapold++ != cmap[i])
00364 if (!xdr_double(xdrs, &c[i]))
00365 G_fatal_error(_("cell_values_double: xdr_double failed for index %d"),
00366 i);
00367
00368 cmapold--;
00369 }
00370 }
00371
00372
00373
00374
00375
00376 #ifdef HAVE_GDAL
00377
00378
00379
00380 static void gdal_values_int(int fd, const unsigned char *data,
00381 const COLUMN_MAPPING *cmap, int nbytes,
00382 CELL *cell, int n)
00383 {
00384 struct fileinfo *fcb = &G__.fileinfo[fd];
00385 const unsigned char *d;
00386 COLUMN_MAPPING cmapold = 0;
00387 int i;
00388
00389 for (i = 0; i < n; i++) {
00390 if (!cmap[i]) {
00391 cell[i] = 0;
00392 continue;
00393 }
00394
00395 if (cmap[i] == cmapold) {
00396 cell[i] = cell[i-1];
00397 continue;
00398 }
00399
00400 d = data + (cmap[i] - 1) * nbytes;
00401
00402 switch (fcb->gdal->type) {
00403 case GDT_Byte: cell[i] = *(GByte *)d; break;
00404 case GDT_Int16: cell[i] = *(GInt16 *)d; break;
00405 case GDT_UInt16: cell[i] = *(GUInt16 *)d; break;
00406 case GDT_Int32: cell[i] = *(GInt32 *)d; break;
00407 case GDT_UInt32: cell[i] = *(GUInt32 *)d; break;
00408 default:
00409
00410 G_set_c_null_value(&cell[i], 1);
00411 break;
00412 }
00413
00414 cmapold = cmap[i];
00415 }
00416 }
00417
00418
00419
00420 static void gdal_values_float(int fd, const float *data,
00421 const COLUMN_MAPPING *cmap, int nbytes,
00422 FCELL *cell, int n)
00423 {
00424 COLUMN_MAPPING cmapold = 0;
00425 int i;
00426
00427 for (i = 0; i < n; i++) {
00428 if (!cmap[i]) {
00429 cell[i] = 0;
00430 continue;
00431 }
00432
00433 if (cmap[i] == cmapold) {
00434 cell[i] = cell[i-1];
00435 continue;
00436 }
00437
00438 cell[i] = data[cmap[i] - 1];
00439
00440 cmapold = cmap[i];
00441 }
00442 }
00443
00444
00445
00446 static void gdal_values_double(int fd, const double *data,
00447 const COLUMN_MAPPING *cmap, int nbytes,
00448 DCELL *cell, int n)
00449 {
00450 COLUMN_MAPPING cmapold = 0;
00451 int i;
00452
00453 for (i = 0; i < n; i++) {
00454 if (!cmap[i]) {
00455 cell[i] = 0;
00456 continue;
00457 }
00458
00459 if (cmap[i] == cmapold) {
00460 cell[i] = cell[i-1];
00461 continue;
00462 }
00463
00464 cell[i] = data[cmap[i] - 1];
00465
00466 cmapold = cmap[i];
00467 }
00468 }
00469
00470
00471
00472 #endif
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488 static void transfer_to_cell_XX(int fd, void *cell)
00489 {
00490 static void (*cell_values_type[3]) () = {
00491 cell_values_int, cell_values_float, cell_values_double};
00492 #ifdef HAVE_GDAL
00493 static void (*gdal_values_type[3]) () = {
00494 gdal_values_int, gdal_values_float, gdal_values_double};
00495 #endif
00496 struct fileinfo *fcb = &G__.fileinfo[fd];
00497
00498 #ifdef HAVE_GDAL
00499 if (fcb->gdal)
00500 (gdal_values_type[fcb->map_type]) (fd, fcb->data, fcb->col_map,
00501 fcb->cur_nbytes, cell,
00502 G__.window.cols);
00503 else
00504 #endif
00505 (cell_values_type[fcb->map_type]) (fd, fcb->data, fcb->col_map,
00506 fcb->cur_nbytes, cell,
00507 G__.window.cols);
00508 }
00509
00510
00511
00512 static void transfer_to_cell_fi(int fd, void *cell)
00513 {
00514 struct fileinfo *fcb = &G__.fileinfo[fd];
00515 int i;
00516
00517 transfer_to_cell_XX(fd, G__.work_buf);
00518
00519 for (i = 0; i < G__.window.cols; i++)
00520 ((CELL *) cell)[i] = (fcb->col_map[i] == 0)
00521 ? 0
00522 : G_quant_get_cell_value(&fcb->quant,
00523 ((FCELL *) G__.work_buf)[i]);
00524 }
00525
00526 static void transfer_to_cell_di(int fd, void *cell)
00527 {
00528 struct fileinfo *fcb = &G__.fileinfo[fd];
00529 int i;
00530
00531 transfer_to_cell_XX(fd, G__.work_buf);
00532
00533 for (i = 0; i < G__.window.cols; i++)
00534 ((CELL *) cell)[i] = (fcb->col_map[i] == 0)
00535 ? 0
00536 : G_quant_get_cell_value(&fcb->quant,
00537 ((DCELL *) G__.work_buf)[i]);
00538 }
00539
00540
00541
00542 static void transfer_to_cell_if(int fd, void *cell)
00543 {
00544 int i;
00545
00546 transfer_to_cell_XX(fd, G__.work_buf);
00547
00548 for (i = 0; i < G__.window.cols; i++)
00549 ((FCELL *) cell)[i] = ((CELL *) G__.work_buf)[i];
00550 }
00551
00552 static void transfer_to_cell_df(int fd, void *cell)
00553 {
00554 int i;
00555
00556 transfer_to_cell_XX(fd, G__.work_buf);
00557
00558 for (i = 0; i < G__.window.cols; i++)
00559 ((FCELL *) cell)[i] = ((DCELL *) G__.work_buf)[i];
00560 }
00561
00562
00563
00564 static void transfer_to_cell_id(int fd, void *cell)
00565 {
00566 int i;
00567
00568 transfer_to_cell_XX(fd, G__.work_buf);
00569
00570 for (i = 0; i < G__.window.cols; i++)
00571 ((DCELL *) cell)[i] = ((CELL *) G__.work_buf)[i];
00572 }
00573
00574 static void transfer_to_cell_fd(int fd, void *cell)
00575 {
00576 int i;
00577
00578 transfer_to_cell_XX(fd, G__.work_buf);
00579
00580 for (i = 0; i < G__.window.cols; i++)
00581 ((DCELL *) cell)[i] = ((FCELL *) G__.work_buf)[i];
00582 }
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593 static int get_map_row_nomask(int fd, void *rast, int row,
00594 RASTER_MAP_TYPE data_type)
00595 {
00596 static void (*transfer_to_cell_FtypeOtype[3][3]) () = { {
00597 transfer_to_cell_XX, transfer_to_cell_if, transfer_to_cell_id}, {
00598 transfer_to_cell_fi, transfer_to_cell_XX, transfer_to_cell_fd}, {
00599 transfer_to_cell_di, transfer_to_cell_df, transfer_to_cell_XX}};
00600 struct fileinfo *fcb = &G__.fileinfo[fd];
00601 int r;
00602 int rowStatus;
00603
00604 rowStatus = compute_window_row(fd, row, &r);
00605
00606 if (rowStatus <= 0) {
00607 fcb->cur_row = -1;
00608 G_zero_raster_buf(rast, data_type);
00609 return rowStatus;
00610 }
00611
00612
00613 if (r != fcb->cur_row) {
00614 fcb->cur_row = r;
00615
00616 if (read_data(fd, fcb->cur_row, fcb->data, &fcb->cur_nbytes) < 0) {
00617 G_zero_raster_buf(rast, data_type);
00618
00619 if (!fcb->io_error) {
00620 if (fcb->cellhd.compressed)
00621 G_warning(_("Error reading compressed map <%s@%s>, row %d"),
00622 fcb->name, fcb->mapset, r);
00623 else
00624 G_warning(_("Error reading map <%s@%s>, row %d"),
00625 fcb->name, fcb->mapset, r);
00626
00627 fcb->io_error = 1;
00628 }
00629 return -1;
00630 }
00631 }
00632
00633 (transfer_to_cell_FtypeOtype[fcb->map_type][data_type]) (fd, rast);
00634
00635 return 1;
00636 }
00637
00638
00639
00640 static int get_map_row_no_reclass(int fd, void *rast, int row,
00641 RASTER_MAP_TYPE data_type, int null_is_zero,
00642 int with_mask)
00643 {
00644 int stat;
00645
00646 stat = get_map_row_nomask(fd, rast, row, data_type);
00647 if (stat < 0)
00648 return stat;
00649
00650 stat = embed_nulls(fd, rast, row, data_type, null_is_zero, with_mask);
00651 if (stat < 0)
00652 return stat;
00653
00654 return 1;
00655 }
00656
00657
00658
00659 static int get_map_row(int fd, void *rast, int row, RASTER_MAP_TYPE data_type,
00660 int null_is_zero, int with_mask)
00661 {
00662 struct fileinfo *fcb = &G__.fileinfo[fd];
00663 int size = G_raster_size(data_type);
00664 void *buf;
00665 int type;
00666 int stat;
00667 int i;
00668
00669 if (fcb->reclass_flag && data_type != CELL_TYPE) {
00670 buf = G__.temp_buf;
00671 type = CELL_TYPE;
00672 }
00673 else {
00674 buf = rast;
00675 type = data_type;
00676 }
00677
00678 stat =
00679 get_map_row_no_reclass(fd, buf, row, type, null_is_zero, with_mask);
00680 if (stat < 0)
00681 return stat;
00682
00683 if (!fcb->reclass_flag)
00684 return 1;
00685
00686
00687
00688
00689 do_reclass_int(fd, buf, null_is_zero);
00690
00691 if (data_type == CELL_TYPE)
00692 return 1;
00693
00694 for (i = 0; i < G__.window.cols; i++) {
00695 G_set_raster_value_c(rast, G__.temp_buf[i], data_type);
00696 rast = G_incr_void_ptr(rast, size);
00697 }
00698
00699 return 1;
00700 }
00701
00702
00703
00704
00705
00706
00707
00740 int G_get_map_row_nomask(int fd, CELL * buf, int row)
00741 {
00742 return get_map_row(fd, buf, row, CELL_TYPE, 1, 0);
00743 }
00744
00760 int G_get_raster_row_nomask(int fd, void *buf, int row,
00761 RASTER_MAP_TYPE data_type)
00762 {
00763 return get_map_row(fd, buf, row, data_type, 0, 0);
00764 }
00765
00781 int G_get_c_raster_row_nomask(int fd, CELL * buf, int row)
00782 {
00783 return G_get_raster_row_nomask(fd, buf, row, CELL_TYPE);
00784 }
00785
00801 int G_get_f_raster_row_nomask(int fd, FCELL * buf, int row)
00802 {
00803 return G_get_raster_row_nomask(fd, buf, row, FCELL_TYPE);
00804 }
00805
00821 int G_get_d_raster_row_nomask(int fd, DCELL * buf, int row)
00822 {
00823 return G_get_raster_row_nomask(fd, buf, row, DCELL_TYPE);
00824 }
00825
00826
00827
00848 int G_get_map_row(int fd, CELL * buf, int row)
00849 {
00850 return get_map_row(fd, buf, row, CELL_TYPE, 1, 1);
00851 }
00852
00896 int G_get_raster_row(int fd, void *buf, int row, RASTER_MAP_TYPE data_type)
00897 {
00898 return get_map_row(fd, buf, row, data_type, 0, 1);
00899 }
00900
00923 int G_get_c_raster_row(int fd, CELL * buf, int row)
00924 {
00925 return G_get_raster_row(fd, buf, row, CELL_TYPE);
00926 }
00927
00946 int G_get_f_raster_row(int fd, FCELL * buf, int row)
00947 {
00948 return G_get_raster_row(fd, buf, row, FCELL_TYPE);
00949 }
00950
00966 int G_get_d_raster_row(int fd, DCELL * buf, int row)
00967 {
00968 return G_get_raster_row(fd, buf, row, DCELL_TYPE);
00969 }
00970
00971
00972
00973
00974
00975
00976
00977 static int open_null_read(int fd)
00978 {
00979 struct fileinfo *fcb = &G__.fileinfo[fd];
00980 char *name, *mapset, *dummy;
00981 int null_fd;
00982
00983 if (fcb->null_file_exists == 0)
00984 return -1;
00985
00986 if (fcb->reclass_flag) {
00987 name = fcb->reclass.name;
00988 mapset = fcb->reclass.mapset;
00989 }
00990 else {
00991 name = fcb->name;
00992 mapset = fcb->mapset;
00993 }
00994
00995 dummy = G_find_file_misc("cell_misc", NULL_FILE, name, mapset);
00996
00997 if (!dummy) {
00998
00999 fcb->null_file_exists = 0;
01000 return -1;
01001 }
01002
01003 null_fd = G_open_old_misc("cell_misc", NULL_FILE, name, mapset);
01004 if (null_fd < 0)
01005 return -1;
01006
01007 fcb->null_file_exists = 1;
01008
01009 return null_fd;
01010 }
01011
01012 static int read_null_bits(int null_fd, unsigned char *flags, int row,
01013 int cols, int fd)
01014 {
01015 off_t offset;
01016 ssize_t size;
01017 int R;
01018
01019 if (compute_window_row(fd, row, &R) <= 0) {
01020 G__init_null_bits(flags, cols);
01021 return 1;
01022 }
01023
01024 if (null_fd < 0)
01025 return -1;
01026
01027 size = G__null_bitstream_size(cols);
01028 offset = (off_t) size *R;
01029
01030 if (lseek(null_fd, offset, SEEK_SET) < 0) {
01031 G_warning(_("Error reading null row %d"), R);
01032 return -1;
01033 }
01034
01035 if (read(null_fd, flags, size) != size) {
01036 G_warning(_("Error reading null row %d"), R);
01037 return -1;
01038 }
01039
01040 return 1;
01041 }
01042
01043 static void get_null_value_row_nomask(int fd, char *flags, int row)
01044 {
01045 struct fileinfo *fcb = &G__.fileinfo[fd];
01046 int i, j, null_fd;
01047
01048 if (row > G__.window.rows || row < 0) {
01049 G_warning(_("Reading raster map <%s@%s> request for row %d is outside region"),
01050 fcb->name, fcb->mapset, row);
01051 }
01052
01053 if ((fcb->min_null_row > row) ||
01054 (fcb->min_null_row + NULL_ROWS_INMEM - 1 < row))
01055
01056 {
01057
01058
01059
01060
01061 fcb->min_null_row = (row / NULL_ROWS_INMEM) * NULL_ROWS_INMEM;
01062
01063 null_fd = open_null_read(fd);
01064
01065 for (i = 0; i < NULL_ROWS_INMEM; i++) {
01066
01067 if (i + fcb->min_null_row >= G__.window.rows)
01068 break;
01069
01070 if (read_null_bits(null_fd, fcb->null_work_buf,
01071 i + fcb->min_null_row, fcb->cellhd.cols,
01072 fd) < 0) {
01073 if (fcb->map_type == CELL_TYPE) {
01074
01075
01076
01077 get_map_row_nomask(fd, (void *)G__.mask_buf,
01078 i + fcb->min_null_row, CELL_TYPE);
01079 for (j = 0; j < G__.window.cols; j++) {
01080 if (G__.mask_buf[j] == 0)
01081 flags[j] = 1;
01082 else
01083 flags[j] = 0;
01084 }
01085 }
01086 else {
01087
01088
01089 G_zero(flags, sizeof(char) * G__.window.cols);
01090
01091 }
01092 }
01093 else {
01094
01095
01096
01097 for (j = 0; j < G__.window.cols; j++) {
01098 if (!fcb->col_map[j])
01099 flags[j] = 1;
01100 else
01101 flags[j] = G__check_null_bit(fcb->null_work_buf,
01102 fcb->col_map[j] - 1,
01103 fcb->cellhd.cols);
01104 }
01105 }
01106
01107
01108
01109
01110 fcb->NULL_ROWS[i] = G_realloc(fcb->NULL_ROWS[i],
01111 G__null_bitstream_size(G__.window.
01112 cols) + 1);
01113 if (fcb->NULL_ROWS[i] == NULL)
01114 G_fatal_error("get_null_value_row_nomask: %s",
01115 _("Unable to realloc buffer"));
01116
01117 G__convert_01_flags(flags, fcb->NULL_ROWS[i], G__.window.cols);
01118
01119 }
01120
01121 if (null_fd > 0)
01122 close(null_fd);
01123 }
01124
01125
01126
01127 G__convert_flags_01(flags, fcb->NULL_ROWS[row - fcb->min_null_row],
01128 G__.window.cols);
01129 }
01130
01131
01132
01133 #ifdef HAVE_GDAL
01134
01135 static void get_null_value_row_gdal(int fd, char *flags, int row)
01136 {
01137 struct fileinfo *fcb = &G__.fileinfo[fd];
01138 DCELL *tmp_buf = G_allocate_d_raster_buf();
01139 int i;
01140
01141 if (get_map_row_nomask(fd, tmp_buf, row, DCELL_TYPE) <= 0) {
01142 memset(flags, 1, G__.window.cols);
01143 G_free(tmp_buf);
01144 return;
01145 }
01146
01147 for (i = 0; i < G__.window.cols; i++)
01148
01149 flags[i] = !fcb->col_map[i] ||
01150 memcmp(&tmp_buf[i], &fcb->gdal->null_val, sizeof(DCELL)) == 0;
01151
01152 G_free(tmp_buf);
01153 }
01154
01155 #endif
01156
01157
01158
01159
01160
01161 static void embed_mask(char *flags, int row)
01162 {
01163 int i;
01164
01165 if (G__.auto_mask <= 0)
01166 return;
01167
01168 if (get_map_row_nomask(G__.mask_fd, G__.mask_buf, row, CELL_TYPE) < 0)
01169 return;
01170
01171 if (G__.fileinfo[G__.mask_fd].reclass_flag)
01172 do_reclass_int(G__.mask_fd, G__.mask_buf, 1);
01173
01174 for (i = 0; i < G__.window.cols; i++)
01175 if (G__.mask_buf[i] == 0)
01176 flags[i] = 1;
01177 }
01178
01179 static void get_null_value_row(int fd, char *flags, int row, int with_mask)
01180 {
01181 #ifdef HAVE_GDAL
01182 struct fileinfo *fcb = &G__.fileinfo[fd];
01183 if (fcb->gdal)
01184 get_null_value_row_gdal(fd, flags, row);
01185 else
01186 #endif
01187 get_null_value_row_nomask(fd, flags, row);
01188
01189 if (with_mask)
01190 embed_mask(flags, row);
01191 }
01192
01193 static int embed_nulls(int fd, void *buf, int row, RASTER_MAP_TYPE map_type,
01194 int null_is_zero, int with_mask)
01195 {
01196 struct fileinfo *fcb = &G__.fileinfo[fd];
01197 int i;
01198
01199
01200
01201 if (null_is_zero && !fcb->null_file_exists
01202 && (G__.auto_mask <= 0 || !with_mask))
01203 return 1;
01204
01205 get_null_value_row(fd, G__.null_buf, row, with_mask);
01206
01207 for (i = 0; i < G__.window.cols; i++) {
01208
01209
01210 if (G__.null_buf[i] || G_is_null_value(buf, map_type)) {
01211
01212
01213 G__set_null_value(buf, 1, null_is_zero, map_type);
01214 }
01215 buf = G_incr_void_ptr(buf, G_raster_size(map_type));
01216 }
01217
01218 return 1;
01219 }
01220
01221
01222
01223
01224
01225
01226
01243 int G_get_null_value_row(int fd, char *flags, int row)
01244 {
01245 get_null_value_row(fd, flags, row, 1);
01246
01247 return 1;
01248 }