get_row.c

Go to the documentation of this file.
00001 /**********************************************************************
00002  *
00003  *   get_row_nomask() works for all map types and doesn't consider
00004  *   null row corresponding to the requested row 
00005  *
00006  *   G_get_map_row(fd, buf, row)
00007  *      int fd                     file descriptor for the opened map
00008  *      CELL *buf                  buffer for the row to be placed into
00009  *      int row                    data row desired
00010  *
00011  *   G_get_raster_row(fd, buf, row, data_type)
00012  *      int fd                     file descriptor for the opened map
00013  *      void *buf                  buffer for the row to be placed into
00014  *      int row                    data row desired
00015  *      RASTER_MAP_TYPE data_type  FCELL_TYPE, DCELL_TYPE, or CELL_TYPE.
00016  *
00017  *   G_get_c_raster_row(fd, buf, row)
00018  *      int fd                     file descriptor for the opened map
00019  *      CELL *buf                  buffer for the row to be placed into
00020  *      int row                    data row desired
00021  *
00022  *   G_get_f_raster_row(fd, buf, row)
00023  *      int fd                     file descriptor for the opened map
00024  *      FCELL *buf                 buffer for the row to be placed into
00025  *      int row                    data row desired
00026  *
00027  *   G_get_d_raster_row(fd, buf, row)
00028  *      int fd                     file descriptor for the opened map
00029  *      DCELL *buf                 buffer for the row to be placed into
00030  *      int row                    data row desired
00031  *
00032  *   Reads appropriate information into the buffer "buf" associated 
00033  *   with the requested row "row".  "buf" is associated with the
00034  *   current window.
00035  *
00036  *   Note, that the type of the data in "buf" (say X) is independent of 
00037  *   the type of the data in the file described by fd (say Y).
00038  *
00039  *   Step 1:  Read appropriate raw map data into a intermediate buffer.
00040  *   Step 2:  Convert the data into a CPU readable format, and subsequently
00041  *            resample the data. the data is stored in a second intermediate 
00042  *            buffer (the type of the data in this buffer is Y).
00043  *   Step 3:  Convert this type Y data into type X data and store it in
00044  *            buffer "buf". Conversion is performed in functions 
00045  *            "transfer_to_cell_XY". (For details of the conversion between
00046  *            two particular types check the functions).
00047  *   Step 4:  read or simmulate null value row and zero out cells corresponding 
00048  *            to null value cells. The masked out cells are set to null when the
00049  *            mask exists. (the MASK is taken care of by null values
00050  *            (if the null file doesn't exist for this map, then the null row
00051  *            is simulated by assuming that all zero are nulls *** in case
00052  *            of G_get_raster_row() and assuming that all data is valid 
00053  *            in case of G_get_f/d_raster_row(). In case of deprecated function
00054  *            G_get_map_row() all nulls are converted to zeros (so there are
00055  *            no embedded nulls at all). Also all masked out cells become zeros.
00056  *
00057  *   returns:    1  if successful
00058  *               0  row requested not within window
00059  *              -1  on fail
00060  *
00061  *   diagnostics: first read request (for each open cell file)
00062  *                that fails will generate a warning message.
00063  *                subsequent failures will be silent.
00064  **********************************************************************
00065  *   G_get_null_value_row(fd, buf, row)
00066  *      int fd                     file descriptor for the opened map
00067  *      char *buf                  buffer for the row to be placed into
00068  *      int row                    data row desired
00069  *
00070  *   read or simmulate null value row and set the cells corresponding 
00071  *   to null value to 1. The masked out cells are set to null when the
00072  *   mask exists. (the MASK is taken care of by null values
00073  *   (if the null file doesn't exist for this map, then the null row
00074  *   is simulated by assuming that all zeros in raster map are nulls.
00075  *   Allso all masked out cells become nulls.
00076  *
00077  **********************************************************************/
00078 
00079 #include <string.h>
00080 #include <unistd.h>
00081 #include <sys/types.h>
00082 
00083 #include <rpc/types.h> /* need this for sgi */
00084 #include <rpc/xdr.h>
00085 
00086 #include "config.h"
00087 #include "glocale.h"
00088 
00089 #include "G.h"
00090 
00091 /*--------------------------------------------------------------------------*/
00092 
00093 #define NULL_FILE   "null"
00094 
00095 /*--------------------------------------------------------------------------*/
00096 
00097 static int embed_nulls(int, void *, int, RASTER_MAP_TYPE, int, int);
00098 
00099 /*--------------------------------------------------------------------------*/
00100 
00101 static int compute_window_row(int fd, int row, int *cellRow)
00102 {
00103     struct fileinfo *fcb = &G__.fileinfo[fd];
00104     double f;
00105     int r;
00106 
00107     /* check for row in window */
00108     if (row < 0 || row >= G__.window.rows)
00109     {
00110         G_warning(_("[%s in %s] - read request for row %d is outside region"),
00111                   fcb->name, fcb->mapset, row);
00112     
00113         return -1;
00114     }
00115 
00116     /* convert window row to cell file row */
00117     f = row * fcb->C1 + fcb->C2;
00118     r = (int) f;
00119     if (f < r) /* adjust for rounding up of negatives */
00120         r--;
00121 
00122     if (r < 0 || r >= fcb->cellhd.rows)
00123         return 0;
00124 
00125     *cellRow = r;
00126 
00127     return 1;
00128 }
00129 
00130 /*--------------------------------------------------------------------------*/
00131 
00132 static void do_reclass_int(int fd, void *cell, int null_is_zero)
00133 {
00134     struct fileinfo *fcb = &G__.fileinfo[fd];
00135     CELL *c = cell;
00136     CELL *reclass_table = fcb->reclass.table;
00137     CELL min = fcb->reclass.min;
00138     CELL max = fcb->reclass.max;
00139     int i;
00140   
00141     for (i = 0; i < G__.window.cols; i++)
00142     {
00143         if (G_is_c_null_value(&c[i])) 
00144         {
00145             if (null_is_zero)
00146                 c[i] = 0;
00147             continue;
00148         }
00149 
00150         if (c[i] < min || c[i] > max)
00151         {
00152             if (null_is_zero)
00153                 c[i] = 0;
00154             else
00155                 G_set_c_null_value(&c[i], 1);
00156             continue;
00157         }
00158 
00159         c[i] = reclass_table[c[i] - min];
00160 
00161         if (null_is_zero && G_is_c_null_value(&c[i]))
00162             c[i] = 0;
00163     }
00164 }
00165 
00166 /*--------------------------------------------------------------------------*/
00167 
00168 static int read_data_fp_compressed(int fd, int row, unsigned char *data_buf, int *nbytes)
00169 {
00170     struct fileinfo *fcb = &G__.fileinfo[fd];
00171     off_t t1 = fcb->row_ptr[row];
00172     off_t t2 = fcb->row_ptr[row + 1];
00173     size_t readamount = t2 - t1;
00174     size_t bufsize = fcb->cellhd.cols * fcb->nbytes;
00175 
00176     if (lseek(fd, t1, 0) < 0)
00177         return -1;
00178 
00179     *nbytes = fcb->nbytes;
00180 
00181     if (G_zlib_read(fd, readamount, data_buf, bufsize) != bufsize)
00182         return -1;
00183 
00184     return 0;
00185 }
00186 
00187 /*--------------------------------------------------------------------------*/
00188 
00189 static void rle_decompress(
00190     unsigned char *dst, const unsigned char *src, int nbytes, int size)
00191 {
00192     int pairs = size / (nbytes + 1);
00193     int i;
00194 
00195     for (i = 0; i < pairs; i++)
00196     {
00197         int repeat = *src++;
00198         int j;
00199 
00200         for (j = 0; j < repeat; j++)
00201         {
00202             memcpy(dst, src, nbytes);
00203             dst += nbytes;
00204         }
00205 
00206         src += nbytes;
00207     }
00208 }
00209 
00210 static int read_data_compressed(int fd, int row, unsigned char *data_buf, int *nbytes)
00211 {
00212     struct fileinfo *fcb = &G__.fileinfo[fd];
00213     off_t t1 = fcb->row_ptr[row];
00214     off_t t2 = fcb->row_ptr[row + 1];
00215     size_t readamount = t2 - t1;
00216     unsigned char *cmp = G__.compressed_buf;
00217     int n;
00218 
00219     if (lseek(fd, t1, 0) < 0)
00220         return -1;
00221 
00222     if (read(fd, cmp, readamount) != readamount)
00223         return -1;
00224   
00225     /* Now decompress the row */
00226     if (fcb->cellhd.compressed > 0)
00227     {
00228         /* one byte is nbyte count */
00229         n = *nbytes = *cmp++;
00230         readamount--;
00231     }
00232     else
00233         /* pre 3.0 compression */
00234         n = *nbytes = fcb->nbytes;
00235   
00236     if (fcb->cellhd.compressed < 0 || readamount < n * fcb->cellhd.cols)
00237     {
00238         if (fcb->cellhd.compressed == 2)
00239             G_zlib_expand(cmp, readamount, data_buf, n * fcb->cellhd.cols);
00240         else
00241             rle_decompress(data_buf, cmp, n, readamount);
00242     }
00243     else
00244         memcpy(data_buf, cmp, readamount);
00245 
00246     return 0;
00247 }
00248 
00249 /*--------------------------------------------------------------------------*/
00250 
00251 static int read_data_uncompressed(int fd, int row, unsigned char *data_buf, int *nbytes)
00252 {
00253     struct fileinfo *fcb = &G__.fileinfo[fd];
00254     int bufsize = fcb->cellhd.cols * fcb->nbytes;
00255 
00256     *nbytes = fcb->nbytes;
00257 
00258     if (lseek(fd, (off_t) row * bufsize, 0) == -1)
00259         return -1;
00260   
00261     if (read(fd, data_buf, bufsize) != bufsize)
00262         return -1;
00263 
00264     return 0;
00265 }
00266 
00267 /*--------------------------------------------------------------------------*/
00268 
00269 /* Actually read a row of data in */
00270 
00271 static int read_data(int fd, int row, unsigned char *data_buf, int *nbytes)
00272 {
00273   struct fileinfo *fcb = &G__.fileinfo[fd];
00274 
00275   if (!fcb->cellhd.compressed)
00276     return read_data_uncompressed(fd, row, data_buf, nbytes);
00277 
00278   /* map is in compressed form */
00279 
00280   if (fcb->map_type == CELL_TYPE)
00281     return read_data_compressed(fd, row, data_buf, nbytes);
00282   else
00283     return read_data_fp_compressed(fd, row, data_buf, nbytes);
00284 }
00285 
00286 /*--------------------------------------------------------------------------*/
00287 
00288 /* copy cell file data to user buffer translated by window column mapping */
00289 
00290 static void cell_values_int(
00291     int fd, unsigned char *data, COLUMN_MAPPING *cmap, int nbytes,
00292     void *cell, int n)
00293 {
00294     CELL *c = cell;
00295     COLUMN_MAPPING cmapold = 0;
00296     int big = nbytes >= sizeof(CELL);
00297     int i;
00298 
00299     for (i = 0; i < n; i++)
00300     {
00301         unsigned char *d;
00302         int neg;
00303         CELL v;
00304         int j;
00305 
00306         if (!cmap[i])
00307         {
00308             c[i] = 0;
00309             continue;
00310         }
00311 
00312         if (cmap[i] == cmapold)
00313         {
00314             c[i] = c[i-1];
00315             continue;
00316         }
00317 
00318         d = data + (cmap[i] - 1) * nbytes;
00319 
00320         if (big && (*d & 0x80))
00321         {
00322             neg = 1;
00323             v = *d++ & 0x7f;
00324         }
00325         else
00326         {
00327             neg = 0;
00328             v = *d++;
00329         }
00330 
00331         for (j = 1; j < nbytes; j++)
00332             v = (v << 8) + *d++;
00333  
00334         c[i] = neg ? -v : v;
00335 
00336         cmapold = cmap[i];
00337     }
00338 }
00339 
00340 /*--------------------------------------------------------------------------*/
00341 
00342 static void cell_values_float(
00343     int fd, unsigned char *data, COLUMN_MAPPING *cmap, int nbytes,
00344     void *cell, int n)
00345 {
00346     struct fileinfo *fcb = &G__.fileinfo[fd];
00347     FCELL *c = cell;
00348     COLUMN_MAPPING cmapold = 0;
00349     XDR* xdrs = &fcb->xdrstream;
00350     int i;
00351 
00352     /* xdr stream is initialized to read from */
00353     /* fcb->data in 'opencell.c' */
00354     xdr_setpos(xdrs, 0);
00355 
00356     for (i = 0; i < n; i++)
00357     {
00358         if (!cmap[i])
00359         {
00360             c[i] = 0;
00361             continue;
00362         }
00363 
00364         if (cmap[i] == cmapold)
00365         {
00366             c[i] = c[i-1];
00367             continue;
00368         }
00369 
00370         if (cmap[i] < cmapold)
00371         {
00372             xdr_setpos(xdrs, 0);
00373             cmapold = 0;
00374         }
00375 
00376         while (cmapold++ != cmap[i]) /* skip */
00377             if (!xdr_float(xdrs, &c[i]))
00378             {
00379                 G_fatal_error("cell_values_float: xdr_float failed for index %d.", i);
00380                 return;
00381             } 
00382 
00383         cmapold--;
00384     }
00385 }
00386 
00387 /*--------------------------------------------------------------------------*/
00388 
00389 static void cell_values_double(
00390     int fd, unsigned char *data, COLUMN_MAPPING *cmap, int nbytes,
00391     void *cell, int n)
00392 {
00393     struct fileinfo *fcb = &G__.fileinfo[fd];
00394     DCELL *c = cell;
00395     COLUMN_MAPPING cmapold = 0;
00396     XDR* xdrs = &fcb->xdrstream;
00397     int i;
00398 
00399     /* xdr stream is initialized to read from */
00400     /* fcb->data in 'opencell.c' */
00401     xdr_setpos(xdrs, 0);
00402 
00403     for (i = 0; i < n; i++)
00404     {
00405         if (!cmap[i])
00406         {
00407             c[i] = 0;
00408             continue;
00409         }
00410 
00411         if (cmap[i] == cmapold)
00412         {
00413             c[i] = c[i-1];
00414             continue;
00415         }
00416 
00417         if (cmap[i] < cmapold)
00418         {
00419             xdr_setpos(xdrs, 0);
00420             cmapold = 0;
00421         }
00422 
00423         while (cmapold++ != cmap[i]) /* skip */
00424             if (!xdr_double(xdrs, &c[i]))
00425             {
00426                 G_fatal_error(_("cell_values_double: xdr_double failed for index %d."), i);
00427                 return;
00428             } 
00429         
00430         cmapold--;
00431     }
00432 }
00433 
00434 /*--------------------------------------------------------------------------*/
00435 /*--------------------------------------------------------------------------*/
00436 /*--------------------------------------------------------------------------*/
00437 
00438 /* transfer_to_cell_XY takes bytes from fcb->data, converts these bytes with
00439    the appropriate procedure (e.g. XDR or byte reordering) into type X 
00440    values which are put into array G__.work_buf.  
00441    finally the values in G__.work_buf are converted into 
00442    type Y and put into 'cell'.
00443    if type X == type Y the intermediate step of storing the values in 
00444    G__.work_buf might be ommited. check the appropriate function for XY to
00445    determine the procedure of conversion. 
00446 */
00447 
00448 /*--------------------------------------------------------------------------*/
00449 
00450 static void transfer_to_cell_XX(int fd, void *cell)
00451 {
00452     static void (*cell_values_type[3])() = {
00453         cell_values_int,
00454         cell_values_float,
00455         cell_values_double
00456     };
00457     struct fileinfo *fcb = &G__.fileinfo[fd];
00458 
00459     (cell_values_type[fcb->map_type])(
00460         fd, fcb->data, fcb->col_map, fcb->cur_nbytes, cell, G__.window.cols);
00461 }
00462 
00463 /*--------------------------------------------------------------------------*/
00464 
00465 static void transfer_to_cell_fi(int fd, void *cell)
00466 {
00467     struct fileinfo *fcb = &G__.fileinfo[fd];
00468     int i;
00469 
00470     transfer_to_cell_XX(fd, G__.work_buf);
00471 
00472     for (i = 0; i < G__.window.cols; i++)
00473         ((CELL *) cell)[i] = (fcb->col_map[i] == 0)
00474             ? 0
00475             : G_quant_get_cell_value(&fcb->quant, ((FCELL *) G__.work_buf)[i]);
00476 }
00477 
00478 static void transfer_to_cell_di(int fd, void *cell)
00479 {
00480     struct fileinfo *fcb = &G__.fileinfo[fd];
00481     int i;
00482 
00483     transfer_to_cell_XX(fd, G__.work_buf);
00484 
00485     for (i = 0; i < G__.window.cols; i++)
00486         ((CELL *) cell)[i] = (fcb->col_map[i] == 0)
00487             ? 0
00488             : G_quant_get_cell_value(&fcb->quant, ((DCELL *) G__.work_buf)[i]);
00489 }
00490 
00491 /*--------------------------------------------------------------------------*/
00492 
00493 static void transfer_to_cell_if(int fd, void *cell)
00494 {
00495     int i;
00496 
00497     transfer_to_cell_XX(fd, G__.work_buf);
00498 
00499     for (i = 0; i < G__.window.cols; i++)
00500         ((FCELL *) cell)[i] = ((CELL *) G__.work_buf)[i];
00501 }
00502 
00503 static void transfer_to_cell_df(int fd, void *cell)
00504 {
00505     int i;
00506 
00507     transfer_to_cell_XX(fd, G__.work_buf);
00508 
00509     for (i = 0; i < G__.window.cols; i++)
00510         ((FCELL *) cell)[i] = ((DCELL *) G__.work_buf)[i];
00511 }
00512 
00513 /*--------------------------------------------------------------------------*/
00514 
00515 static void transfer_to_cell_id(int fd, void *cell)
00516 {
00517     int i;
00518 
00519     transfer_to_cell_XX(fd, G__.work_buf);
00520 
00521     for (i = 0; i < G__.window.cols; i++)
00522         ((DCELL *) cell)[i] = ((CELL *) G__.work_buf)[i];
00523 }
00524 
00525 static void transfer_to_cell_fd(int fd, void *cell)
00526 {
00527     int i;
00528 
00529     transfer_to_cell_XX(fd, G__.work_buf);
00530 
00531     for (i = 0; i < G__.window.cols; i++)
00532         ((DCELL *) cell)[i] = ((FCELL *) G__.work_buf)[i];
00533 }
00534 
00535 /*--------------------------------------------------------------------------*/
00536 /*--------------------------------------------------------------------------*/
00537 /*--------------------------------------------------------------------------*/
00538 
00539 static int get_map_row_nomask(int fd, void *rast, int row, RASTER_MAP_TYPE data_type)
00540 {
00541     static void (*transfer_to_cell_FtypeOtype[3][3])() =
00542         {{transfer_to_cell_XX, transfer_to_cell_if, transfer_to_cell_id},
00543          {transfer_to_cell_fi, transfer_to_cell_XX, transfer_to_cell_fd},
00544          {transfer_to_cell_di, transfer_to_cell_df, transfer_to_cell_XX}};
00545     struct fileinfo *fcb = &G__.fileinfo[fd];
00546     int r;
00547     int rowStatus;
00548 
00549     rowStatus = compute_window_row(fd, row, &r);
00550 
00551     if (rowStatus <= 0)
00552     {
00553         fcb->cur_row = -1;
00554         G_zero_raster_buf(rast, data_type);
00555         return rowStatus;
00556     }
00557 
00558     /* read cell file row if not in memory */
00559     if (r != fcb->cur_row)
00560     {
00561         fcb->cur_row = r;
00562 
00563         if (read_data(fd, fcb->cur_row, fcb->data, &fcb->cur_nbytes) < 0)
00564         {
00565             G_zero_raster_buf(rast, data_type);
00566 
00567             if (!fcb->io_error)
00568             {
00569                 G_warning(_("error reading %smap [%s] in mapset [%s], row %d"),
00570                           fcb->cellhd.compressed ? "compressed " : "",
00571                           fcb->name, fcb->mapset, r);
00572                 fcb->io_error = 1;
00573             }
00574             return -1;
00575         }
00576     }
00577 
00578     (transfer_to_cell_FtypeOtype[fcb->map_type][data_type])(fd, rast);
00579 
00580     return 1;
00581 }
00582 
00583 /*--------------------------------------------------------------------------*/
00584 
00585 static int get_map_row_no_reclass(
00586     int fd, void *rast, int row, RASTER_MAP_TYPE data_type,
00587     int null_is_zero, int with_mask)
00588 {
00589     int stat;
00590 
00591     stat = get_map_row_nomask(fd, rast, row, data_type);
00592     if (stat < 0)
00593         return stat;
00594 
00595     stat = embed_nulls(fd, rast, row, data_type, null_is_zero, with_mask);
00596     if (stat < 0)
00597         return stat;
00598 
00599     return 1;
00600 }
00601 
00602 /*--------------------------------------------------------------------------*/
00603 
00604 static int get_map_row(
00605     int fd, void *rast, int row, RASTER_MAP_TYPE data_type,
00606     int null_is_zero, int with_mask)
00607 {
00608     struct fileinfo *fcb = &G__.fileinfo[fd];
00609     int size = G_raster_size(data_type);
00610     void *buf;
00611     int type;
00612     int stat;
00613     int i;
00614 
00615     if (fcb->reclass_flag && data_type != CELL_TYPE)
00616     {
00617         buf = G__.temp_buf;
00618         type = CELL_TYPE;
00619     }
00620     else
00621     {
00622         buf = rast;
00623         type = data_type;
00624     }
00625 
00626     stat = get_map_row_no_reclass(fd, buf, row, type, null_is_zero, with_mask);
00627     if (stat < 0)
00628         return stat;
00629 
00630     if (!fcb->reclass_flag) 
00631         return 1;
00632 
00633     /* if the map is reclass table, get and
00634        reclass CELL row and copy results to needed type  */
00635 
00636     do_reclass_int(fd, buf, null_is_zero);
00637 
00638     if (data_type == CELL_TYPE)
00639         return 1;
00640 
00641     for (i = 0; i < G__.window.cols; i++)
00642     {
00643         G_set_raster_value_c(rast, G__.temp_buf[i], data_type);
00644         rast = G_incr_void_ptr(rast, size);
00645     }
00646 
00647     return 1;
00648 }
00649 
00650 /*--------------------------------------------------------------------------*/
00651 /*--------------------------------------------------------------------------*/
00652 /*--------------------------------------------------------------------------*/
00653 
00679 int G_get_map_row_nomask(int fd, CELL *buf, int row)
00680 {
00681     return get_map_row(fd, buf, row, CELL_TYPE, 1, 0);
00682 }
00683 
00697 int G_get_raster_row_nomask(int fd, void *buf, int row, RASTER_MAP_TYPE data_type)
00698 {
00699     return get_map_row(fd, buf, row, data_type, 0, 0);
00700 }
00701 
00713 int G_get_c_raster_row_nomask(int fd, CELL *buf, int row)
00714 {
00715     return G_get_raster_row_nomask(fd, buf, row, CELL_TYPE);
00716 }
00717 
00729 int G_get_f_raster_row_nomask(int fd, FCELL *buf, int row)
00730 {
00731     return G_get_raster_row_nomask(fd, buf, row, FCELL_TYPE);
00732 }
00733 
00745 int G_get_d_raster_row_nomask(int fd, DCELL *buf, int row)
00746 {
00747     return G_get_raster_row_nomask(fd, buf, row, DCELL_TYPE);
00748 }
00749 
00750 /*--------------------------------------------------------------------------*/
00751 
00766 int G_get_map_row(int fd, CELL *buf, int row)
00767 {
00768     return get_map_row(fd, buf, row, CELL_TYPE, 1, 1);
00769 }
00770 
00786 int G_get_raster_row(int fd, void *buf, int row, RASTER_MAP_TYPE data_type)
00787 {
00788     return get_map_row(fd, buf, row, data_type, 0, 1);
00789 }
00790 
00809 int G_get_c_raster_row(int fd, CELL *buf, int row)
00810 {
00811     return G_get_raster_row(fd, buf, row, CELL_TYPE);
00812 }
00813 
00829 int G_get_f_raster_row(int fd, FCELL *buf, int row)
00830 {
00831     return G_get_raster_row(fd, buf, row, FCELL_TYPE);
00832 }
00833 
00846 int G_get_d_raster_row(int fd, DCELL *buf, int row)
00847 {
00848     return G_get_raster_row(fd, buf, row, DCELL_TYPE);
00849 }
00850 
00851 /*--------------------------------------------------------------------------*/
00852 /*--------------------------------------------------------------------------*/
00853 /*--------------------------------------------------------------------------*/
00854 
00855 static int open_null_read(int fd)
00856 {
00857     struct fileinfo *fcb = &G__.fileinfo[fd];
00858     char *name, *mapset, *dummy;
00859     int null_fd;
00860     char dir_name[200];
00861 
00862     if (fcb->null_file_exists == 0)
00863         return -1;
00864 
00865     if (fcb->reclass_flag)
00866     {
00867         name = fcb->reclass.name;
00868         mapset = fcb->reclass.mapset;
00869     }
00870     else
00871     {
00872         name = fcb->name;
00873         mapset = fcb->mapset;
00874     }
00875                          
00876     sprintf(dir_name, "cell_misc/%s", name);
00877     dummy = G_find_file(dir_name, NULL_FILE, mapset);
00878 
00879     if (!dummy)
00880     {
00881         /* G_warning("unable to find [%s]",path); */
00882         fcb->null_file_exists = 0;
00883         return -1;
00884     }
00885 
00886     G_free(dummy);
00887  
00888     null_fd = G_open_old(dir_name, NULL_FILE, mapset);
00889     if (null_fd < 0)
00890         return -1;
00891 
00892     if (null_fd >= MAXFILES)
00893     {
00894         close(null_fd);
00895         G_warning(_("Too many open raster files"));
00896         return -1;
00897     }
00898 
00899     fcb->null_file_exists = 1;
00900     return null_fd;
00901 }
00902 
00903 static int read_null_bits(
00904     int null_fd, unsigned char *flags, int row, int cols, int fd)
00905 {
00906     off_t offset;
00907     int size, R;
00908 
00909     if (compute_window_row(fd, row, &R) <= 0) 
00910     {
00911         G__init_null_bits(flags, cols);
00912         return 1;
00913     }
00914 
00915     if (null_fd < 0)
00916         return -1;
00917 
00918     size = G__null_bitstream_size(cols);
00919     offset = (off_t) size * R;
00920 
00921     if (lseek(null_fd, offset, 0) < 0)
00922     {
00923         G_warning(_("error reading null row %d"), R);
00924         return -1;
00925     }
00926 
00927     if (read(null_fd, flags, size) != size)
00928     {
00929         G_warning(_("error reading null row %d"), R);
00930         return -1;
00931     }
00932     return 1;
00933 }
00934 
00935 static void get_null_value_row_nomask(int fd, char *flags, int row)
00936 { 
00937     struct fileinfo *fcb = &G__.fileinfo[fd];
00938     int i, j, null_fd;
00939 
00940     if (row > G__.window.rows || row < 0)   
00941     {
00942         G_warning("[%s in %s] - read request for row %d is outside region",
00943                   fcb->name, fcb->mapset, row);
00944     }
00945           
00946     if ((fcb->min_null_row > row) || (fcb->min_null_row + NULL_ROWS_INMEM -1 < row))
00947         /* the null row row is not in memory */ 
00948     {
00949         /* read in NULL_ROWS_INMEM rows from null file 
00950            so that the requested row is between fcb->min_null_row
00951            and fcb->min_null_row + NULL_ROWS_INMEM */
00952 
00953         fcb->min_null_row = (row / NULL_ROWS_INMEM) * NULL_ROWS_INMEM;
00954 
00955         null_fd = open_null_read(fd);
00956 
00957         for (i= 0; i < NULL_ROWS_INMEM ; i++)
00958         {
00959             /* G__.window.rows doesn't have to be a multiple of NULL_ROWS_INMEM */
00960             if (i+fcb->min_null_row >= G__.window.rows)
00961                 break;
00962 
00963             if (read_null_bits(null_fd, fcb->null_work_buf, 
00964                                i+fcb->min_null_row, fcb->cellhd.cols, fd) < 0)
00965             {
00966                 if (fcb->map_type == CELL_TYPE)
00967                 {
00968                     /*
00969                       If can't read null row, assume  that all map 0's are nulls 
00970                       use allocated G__.mask_buf to read map row */
00971                     get_map_row_nomask(fd, (void *) G__.mask_buf, i+fcb->min_null_row, 
00972                                        CELL_TYPE);
00973                     for (j = 0; j < G__.window.cols; j++)
00974                     {
00975                         if (G__.mask_buf[j] == 0)
00976                             flags[j] = 1;
00977                         else
00978                             flags[j] = 0;
00979                     }
00980                 }
00981                 else /* fp map */
00982                 {
00983                     /* if can't read null row, assume  that all data is valid */ 
00984                     G_zero(flags, sizeof(char) * G__.window.cols);
00985                     /* the flags row is ready now */
00986                 }
00987             } /*if no null file */
00988             else
00989             {
00990                 /* copy null row to flags row translated by window column mapping */
00991                 /* the fcb->NULL_ROWS[row-fcb->min_null_row] has G__.window.cols bits, */
00992                 /* the fcb->null_work_buf has size fcb->cellhd.cols */
00993                 for (j=0;j<G__.window.cols;j++)
00994                 {
00995                     if (!fcb->col_map[j])
00996                         flags[j] = 1;
00997                     else
00998                         flags[j] = G__check_null_bit(fcb->null_work_buf,
00999                                                      fcb->col_map[j]-1, fcb->cellhd.cols);
01000                 }
01001             }
01002             /* remember the null row for i for the future reference */
01003          
01004             /*bf-We should take of the size - or we get 
01005               zeros running on their own after flags convertions -A.Sh.*/
01006             fcb->NULL_ROWS[i] = realloc(fcb->NULL_ROWS[i],
01007                                         G__null_bitstream_size(G__.window.cols)+1);
01008             if (fcb->NULL_ROWS[i] == NULL)
01009                 G_fatal_error(_("Could not realloc buffer"));
01010                 
01011             G__convert_01_flags(flags, fcb->NULL_ROWS[i], G__.window.cols);
01012 
01013         }  /* for loop */
01014 
01015         if (null_fd > 0)
01016             close(null_fd);
01017     } /* row is not in memory */
01018 
01019     /* copy null file data translated by column mapping to user null row */
01020     /* the user requested flags row is of size G__.window.cols */
01021     G__convert_flags_01(flags, fcb->NULL_ROWS[row - fcb->min_null_row], G__.window.cols);
01022 }
01023 
01024 /*--------------------------------------------------------------------------*/
01025 /*--------------------------------------------------------------------------*/
01026 /*--------------------------------------------------------------------------*/
01027 
01028 static void embed_mask(char *flags, int row)
01029 {
01030     int i;
01031 
01032     if (G__.auto_mask <= 0)
01033         return;
01034 
01035     if (get_map_row_nomask(G__.mask_fd, G__.mask_buf, row, CELL_TYPE) < 0)
01036         return;
01037 
01038     if (G__.fileinfo[G__.mask_fd].reclass_flag) 
01039         do_reclass_int(G__.mask_fd, G__.mask_buf, 1);
01040 
01041     for (i = 0; i < G__.window.cols; i++)
01042         if (G__.mask_buf[i] == 0)
01043             flags[i] = 1;
01044 }
01045 
01046 static void get_null_value_row(int fd, char *flags, int row, int with_mask)
01047 {
01048     get_null_value_row_nomask(fd, flags, row);
01049 
01050     if (with_mask)
01051         embed_mask(flags, row);
01052 }
01053 
01054 static int embed_nulls(
01055     int fd, void *buf, int row, RASTER_MAP_TYPE map_type,
01056     int null_is_zero, int with_mask)
01057 {
01058     struct fileinfo *fcb = &G__.fileinfo[fd];
01059     int i;
01060 
01061     /* this is because without null file the nulls can be only due to 0's
01062        in data row or mask */
01063     if (null_is_zero && !fcb->null_file_exists
01064         && (G__.auto_mask<=0 || !with_mask))
01065         return 1;
01066 
01067     get_null_value_row(fd, G__.null_buf, row, with_mask);
01068 
01069     for (i = 0; i < G__.window.cols; i++)
01070     {
01071         /* also check for nulls which might be already embedded by quant
01072            rules in case of fp map. */
01073         if (G__.null_buf[i] || G_is_null_value(buf, map_type))
01074         {
01075             /* G__set_[f/d]_null_value() sets it to 0 is the embedded mode
01076                is not set and calls G_set_[f/d]_null_value() otherwise */
01077             G__set_null_value(buf, 1, null_is_zero, map_type);
01078         }
01079         buf = G_incr_void_ptr(buf, G_raster_size(map_type));
01080     }
01081 
01082     return 1;
01083 }
01084 
01085 /*--------------------------------------------------------------------------*/
01086 /*--------------------------------------------------------------------------*/
01087 /*--------------------------------------------------------------------------*/
01088 
01089 int G_get_null_value_row(int fd, char *flags, int row)
01090 {
01091     get_null_value_row(fd, flags, row, 1);
01092     return 1;
01093 }
01094    
01095 /*--------------------------------------------------------------------------*/
01096 /*--------------------------------------------------------------------------*/
01097 /*--------------------------------------------------------------------------*/
01098 

Generated on Mon Jan 1 19:49:25 2007 for GRASS by  doxygen 1.5.1