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  *   Also 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 <grass/config.h>
00087 #include <grass/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, SEEK_SET) < 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     ssize_t readamount = t2 - t1;
00216     unsigned char *cmp = G__.compressed_buf;
00217     int n;
00218 
00219     if (lseek(fd, t1, SEEK_SET) < 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     ssize_t bufsize = fcb->cellhd.cols * fcb->nbytes;
00255 
00256     *nbytes = fcb->nbytes;
00257 
00258     if (lseek(fd, (off_t) row * bufsize, SEEK_SET) == -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                 G_fatal_error(_("cell_values_float: xdr_float failed for index %d"), i);
00379 
00380         cmapold--;
00381     }
00382 }
00383 
00384 /*--------------------------------------------------------------------------*/
00385 
00386 static void cell_values_double(
00387     int fd, unsigned char *data, COLUMN_MAPPING *cmap, int nbytes,
00388     void *cell, int n)
00389 {
00390     struct fileinfo *fcb = &G__.fileinfo[fd];
00391     DCELL *c = cell;
00392     COLUMN_MAPPING cmapold = 0;
00393     XDR* xdrs = &fcb->xdrstream;
00394     int i;
00395 
00396     /* xdr stream is initialized to read from */
00397     /* fcb->data in 'opencell.c' */
00398     xdr_setpos(xdrs, 0);
00399 
00400     for (i = 0; i < n; i++)
00401     {
00402         if (!cmap[i])
00403         {
00404             c[i] = 0;
00405             continue;
00406         }
00407 
00408         if (cmap[i] == cmapold)
00409         {
00410             c[i] = c[i-1];
00411             continue;
00412         }
00413 
00414         if (cmap[i] < cmapold)
00415         {
00416             xdr_setpos(xdrs, 0);
00417             cmapold = 0;
00418         }
00419 
00420         while (cmapold++ != cmap[i]) /* skip */
00421             if (!xdr_double(xdrs, &c[i]))
00422                 G_fatal_error(_("cell_values_double: xdr_double failed for index %d."), i);
00423         
00424         cmapold--;
00425     }
00426 }
00427 
00428 /*--------------------------------------------------------------------------*/
00429 /*--------------------------------------------------------------------------*/
00430 /*--------------------------------------------------------------------------*/
00431 
00432 /* transfer_to_cell_XY takes bytes from fcb->data, converts these bytes with
00433    the appropriate procedure (e.g. XDR or byte reordering) into type X 
00434    values which are put into array G__.work_buf.  
00435    finally the values in G__.work_buf are converted into 
00436    type Y and put into 'cell'.
00437    if type X == type Y the intermediate step of storing the values in 
00438    G__.work_buf might be ommited. check the appropriate function for XY to
00439    determine the procedure of conversion. 
00440 */
00441 
00442 /*--------------------------------------------------------------------------*/
00443 
00444 static void transfer_to_cell_XX(int fd, void *cell)
00445 {
00446     static void (*cell_values_type[3])() = {
00447         cell_values_int,
00448         cell_values_float,
00449         cell_values_double
00450     };
00451     struct fileinfo *fcb = &G__.fileinfo[fd];
00452 
00453     (cell_values_type[fcb->map_type])(
00454         fd, fcb->data, fcb->col_map, fcb->cur_nbytes, cell, G__.window.cols);
00455 }
00456 
00457 /*--------------------------------------------------------------------------*/
00458 
00459 static void transfer_to_cell_fi(int fd, void *cell)
00460 {
00461     struct fileinfo *fcb = &G__.fileinfo[fd];
00462     int i;
00463 
00464     transfer_to_cell_XX(fd, G__.work_buf);
00465 
00466     for (i = 0; i < G__.window.cols; i++)
00467         ((CELL *) cell)[i] = (fcb->col_map[i] == 0)
00468             ? 0
00469             : G_quant_get_cell_value(&fcb->quant, ((FCELL *) G__.work_buf)[i]);
00470 }
00471 
00472 static void transfer_to_cell_di(int fd, void *cell)
00473 {
00474     struct fileinfo *fcb = &G__.fileinfo[fd];
00475     int i;
00476 
00477     transfer_to_cell_XX(fd, G__.work_buf);
00478 
00479     for (i = 0; i < G__.window.cols; i++)
00480         ((CELL *) cell)[i] = (fcb->col_map[i] == 0)
00481             ? 0
00482             : G_quant_get_cell_value(&fcb->quant, ((DCELL *) G__.work_buf)[i]);
00483 }
00484 
00485 /*--------------------------------------------------------------------------*/
00486 
00487 static void transfer_to_cell_if(int fd, void *cell)
00488 {
00489     int i;
00490 
00491     transfer_to_cell_XX(fd, G__.work_buf);
00492 
00493     for (i = 0; i < G__.window.cols; i++)
00494         ((FCELL *) cell)[i] = ((CELL *) G__.work_buf)[i];
00495 }
00496 
00497 static void transfer_to_cell_df(int fd, void *cell)
00498 {
00499     int i;
00500 
00501     transfer_to_cell_XX(fd, G__.work_buf);
00502 
00503     for (i = 0; i < G__.window.cols; i++)
00504         ((FCELL *) cell)[i] = ((DCELL *) G__.work_buf)[i];
00505 }
00506 
00507 /*--------------------------------------------------------------------------*/
00508 
00509 static void transfer_to_cell_id(int fd, void *cell)
00510 {
00511     int i;
00512 
00513     transfer_to_cell_XX(fd, G__.work_buf);
00514 
00515     for (i = 0; i < G__.window.cols; i++)
00516         ((DCELL *) cell)[i] = ((CELL *) G__.work_buf)[i];
00517 }
00518 
00519 static void transfer_to_cell_fd(int fd, void *cell)
00520 {
00521     int i;
00522 
00523     transfer_to_cell_XX(fd, G__.work_buf);
00524 
00525     for (i = 0; i < G__.window.cols; i++)
00526         ((DCELL *) cell)[i] = ((FCELL *) G__.work_buf)[i];
00527 }
00528 
00529 /*--------------------------------------------------------------------------*/
00530 /*--------------------------------------------------------------------------*/
00531 /*--------------------------------------------------------------------------*/
00532 
00533 static int get_map_row_nomask(int fd, void *rast, int row, RASTER_MAP_TYPE data_type)
00534 {
00535     static void (*transfer_to_cell_FtypeOtype[3][3])() =
00536         {{transfer_to_cell_XX, transfer_to_cell_if, transfer_to_cell_id},
00537          {transfer_to_cell_fi, transfer_to_cell_XX, transfer_to_cell_fd},
00538          {transfer_to_cell_di, transfer_to_cell_df, transfer_to_cell_XX}};
00539     struct fileinfo *fcb = &G__.fileinfo[fd];
00540     int r;
00541     int rowStatus;
00542 
00543     rowStatus = compute_window_row(fd, row, &r);
00544 
00545     if (rowStatus <= 0)
00546     {
00547         fcb->cur_row = -1;
00548         G_zero_raster_buf(rast, data_type);
00549         return rowStatus;
00550     }
00551 
00552     /* read cell file row if not in memory */
00553     if (r != fcb->cur_row)
00554     {
00555         fcb->cur_row = r;
00556 
00557         if (read_data(fd, fcb->cur_row, fcb->data, &fcb->cur_nbytes) < 0)
00558         {
00559             G_zero_raster_buf(rast, data_type);
00560 
00561             if (!fcb->io_error)
00562             {
00563                 if (fcb->cellhd.compressed)
00564                         G_warning(_("error reading compressed map [%s] in "
00565                                 "mapset [%s], row %d"),
00566                                 fcb->name, fcb->mapset, r);
00567                 else
00568                         G_warning(_("error reading map [%s] in mapset [%s], row %d"),
00569                                 fcb->name, fcb->mapset, r);
00570 
00571                 fcb->io_error = 1;
00572             }
00573             return -1;
00574         }
00575     }
00576 
00577     (transfer_to_cell_FtypeOtype[fcb->map_type][data_type])(fd, rast);
00578 
00579     return 1;
00580 }
00581 
00582 /*--------------------------------------------------------------------------*/
00583 
00584 static int get_map_row_no_reclass(
00585     int fd, void *rast, int row, RASTER_MAP_TYPE data_type,
00586     int null_is_zero, int with_mask)
00587 {
00588     int stat;
00589 
00590     stat = get_map_row_nomask(fd, rast, row, data_type);
00591     if (stat < 0)
00592         return stat;
00593 
00594     stat = embed_nulls(fd, rast, row, data_type, null_is_zero, with_mask);
00595     if (stat < 0)
00596         return stat;
00597 
00598     return 1;
00599 }
00600 
00601 /*--------------------------------------------------------------------------*/
00602 
00603 static int get_map_row(
00604     int fd, void *rast, int row, RASTER_MAP_TYPE data_type,
00605     int null_is_zero, int with_mask)
00606 {
00607     struct fileinfo *fcb = &G__.fileinfo[fd];
00608     int size = G_raster_size(data_type);
00609     void *buf;
00610     int type;
00611     int stat;
00612     int i;
00613 
00614     if (fcb->reclass_flag && data_type != CELL_TYPE)
00615     {
00616         buf = G__.temp_buf;
00617         type = CELL_TYPE;
00618     }
00619     else
00620     {
00621         buf = rast;
00622         type = data_type;
00623     }
00624 
00625     stat = get_map_row_no_reclass(fd, buf, row, type, null_is_zero, with_mask);
00626     if (stat < 0)
00627         return stat;
00628 
00629     if (!fcb->reclass_flag) 
00630         return 1;
00631 
00632     /* if the map is reclass table, get and
00633        reclass CELL row and copy results to needed type  */
00634 
00635     do_reclass_int(fd, buf, null_is_zero);
00636 
00637     if (data_type == CELL_TYPE)
00638         return 1;
00639 
00640     for (i = 0; i < G__.window.cols; i++)
00641     {
00642         G_set_raster_value_c(rast, G__.temp_buf[i], data_type);
00643         rast = G_incr_void_ptr(rast, size);
00644     }
00645 
00646     return 1;
00647 }
00648 
00649 /*--------------------------------------------------------------------------*/
00650 /*--------------------------------------------------------------------------*/
00651 /*--------------------------------------------------------------------------*/
00652 
00678 int G_get_map_row_nomask(int fd, CELL *buf, int row)
00679 {
00680     return get_map_row(fd, buf, row, CELL_TYPE, 1, 0);
00681 }
00682 
00696 int G_get_raster_row_nomask(int fd, void *buf, int row, RASTER_MAP_TYPE data_type)
00697 {
00698     return get_map_row(fd, buf, row, data_type, 0, 0);
00699 }
00700 
00712 int G_get_c_raster_row_nomask(int fd, CELL *buf, int row)
00713 {
00714     return G_get_raster_row_nomask(fd, buf, row, CELL_TYPE);
00715 }
00716 
00728 int G_get_f_raster_row_nomask(int fd, FCELL *buf, int row)
00729 {
00730     return G_get_raster_row_nomask(fd, buf, row, FCELL_TYPE);
00731 }
00732 
00744 int G_get_d_raster_row_nomask(int fd, DCELL *buf, int row)
00745 {
00746     return G_get_raster_row_nomask(fd, buf, row, DCELL_TYPE);
00747 }
00748 
00749 /*--------------------------------------------------------------------------*/
00750 
00765 int G_get_map_row(int fd, CELL *buf, int row)
00766 {
00767     return get_map_row(fd, buf, row, CELL_TYPE, 1, 1);
00768 }
00769 
00785 int G_get_raster_row(int fd, void *buf, int row, RASTER_MAP_TYPE data_type)
00786 {
00787     return get_map_row(fd, buf, row, data_type, 0, 1);
00788 }
00789 
00808 int G_get_c_raster_row(int fd, CELL *buf, int row)
00809 {
00810     return G_get_raster_row(fd, buf, row, CELL_TYPE);
00811 }
00812 
00828 int G_get_f_raster_row(int fd, FCELL *buf, int row)
00829 {
00830     return G_get_raster_row(fd, buf, row, FCELL_TYPE);
00831 }
00832 
00845 int G_get_d_raster_row(int fd, DCELL *buf, int row)
00846 {
00847     return G_get_raster_row(fd, buf, row, DCELL_TYPE);
00848 }
00849 
00850 /*--------------------------------------------------------------------------*/
00851 /*--------------------------------------------------------------------------*/
00852 /*--------------------------------------------------------------------------*/
00853 
00854 static int open_null_read(int fd)
00855 {
00856     struct fileinfo *fcb = &G__.fileinfo[fd];
00857     char *name, *mapset, *dummy;
00858     int null_fd;
00859     char dir_name[GNAME_MAX];
00860 
00861     if (fcb->null_file_exists == 0)
00862         return -1;
00863 
00864     if (fcb->reclass_flag)
00865     {
00866         name = fcb->reclass.name;
00867         mapset = fcb->reclass.mapset;
00868     }
00869     else
00870     {
00871         name = fcb->name;
00872         mapset = fcb->mapset;
00873     }
00874                          
00875     sprintf(dir_name, "cell_misc/%s", name);
00876     dummy = G_find_file(dir_name, NULL_FILE, mapset);
00877 
00878     if (!dummy)
00879     {
00880         /* G_warning("unable to find [%s]",path); */
00881         fcb->null_file_exists = 0;
00882         return -1;
00883     }
00884 
00885     G_free(dummy);
00886  
00887     null_fd = G_open_old(dir_name, NULL_FILE, mapset);
00888     if (null_fd < 0)
00889         return -1;
00890 
00891     fcb->null_file_exists = 1;
00892 
00893     return null_fd;
00894 }
00895 
00896 static int read_null_bits(
00897     int null_fd, unsigned char *flags, int row, int cols, int fd)
00898 {
00899     off_t offset;
00900     ssize_t size;
00901     int R;
00902 
00903     if (compute_window_row(fd, row, &R) <= 0) 
00904     {
00905         G__init_null_bits(flags, cols);
00906         return 1;
00907     }
00908 
00909     if (null_fd < 0)
00910         return -1;
00911 
00912     size = G__null_bitstream_size(cols);
00913     offset = (off_t) size * R;
00914 
00915     if (lseek(null_fd, offset, SEEK_SET) < 0)
00916     {
00917         G_warning(_("error reading null row %d"), R);
00918         return -1;
00919     }
00920 
00921     if (read(null_fd, flags, size) != size)
00922     {
00923         G_warning(_("error reading null row %d"), R);
00924         return -1;
00925     }
00926 
00927     return 1;
00928 }
00929 
00930 static void get_null_value_row_nomask(int fd, char *flags, int row)
00931 { 
00932     struct fileinfo *fcb = &G__.fileinfo[fd];
00933     int i, j, null_fd;
00934 
00935     if (row > G__.window.rows || row < 0)   
00936     {
00937         G_warning("[%s in %s] - read request for row %d is outside region",
00938                   fcb->name, fcb->mapset, row);
00939     }
00940           
00941     if ((fcb->min_null_row > row) || (fcb->min_null_row + NULL_ROWS_INMEM -1 < row))
00942         /* the null row row is not in memory */ 
00943     {
00944         /* read in NULL_ROWS_INMEM rows from null file 
00945            so that the requested row is between fcb->min_null_row
00946            and fcb->min_null_row + NULL_ROWS_INMEM */
00947 
00948         fcb->min_null_row = (row / NULL_ROWS_INMEM) * NULL_ROWS_INMEM;
00949 
00950         null_fd = open_null_read(fd);
00951 
00952         for (i= 0; i < NULL_ROWS_INMEM ; i++)
00953         {
00954             /* G__.window.rows doesn't have to be a multiple of NULL_ROWS_INMEM */
00955             if (i+fcb->min_null_row >= G__.window.rows)
00956                 break;
00957 
00958             if (read_null_bits(null_fd, fcb->null_work_buf, 
00959                                i+fcb->min_null_row, fcb->cellhd.cols, fd) < 0)
00960             {
00961                 if (fcb->map_type == CELL_TYPE)
00962                 {
00963                     /*
00964                       If can't read null row, assume  that all map 0's are nulls 
00965                       use allocated G__.mask_buf to read map row */
00966                     get_map_row_nomask(fd, (void *) G__.mask_buf, i+fcb->min_null_row, 
00967                                        CELL_TYPE);
00968                     for (j = 0; j < G__.window.cols; j++)
00969                     {
00970                         if (G__.mask_buf[j] == 0)
00971                             flags[j] = 1;
00972                         else
00973                             flags[j] = 0;
00974                     }
00975                 }
00976                 else /* fp map */
00977                 {
00978                     /* if can't read null row, assume  that all data is valid */ 
00979                     G_zero(flags, sizeof(char) * G__.window.cols);
00980                     /* the flags row is ready now */
00981                 }
00982             } /*if no null file */
00983             else
00984             {
00985                 /* copy null row to flags row translated by window column mapping */
00986                 /* the fcb->NULL_ROWS[row-fcb->min_null_row] has G__.window.cols bits, */
00987                 /* the fcb->null_work_buf has size fcb->cellhd.cols */
00988                 for (j=0;j<G__.window.cols;j++)
00989                 {
00990                     if (!fcb->col_map[j])
00991                         flags[j] = 1;
00992                     else
00993                         flags[j] = G__check_null_bit(fcb->null_work_buf,
00994                                                      fcb->col_map[j]-1, fcb->cellhd.cols);
00995                 }
00996             }
00997             /* remember the null row for i for the future reference */
00998          
00999             /*bf-We should take of the size - or we get 
01000               zeros running on their own after flags convertions -A.Sh.*/
01001             fcb->NULL_ROWS[i] = G_realloc (fcb->NULL_ROWS[i],
01002                                         G__null_bitstream_size(G__.window.cols)+1);
01003             if (fcb->NULL_ROWS[i] == NULL)
01004                 G_fatal_error(_("Could not realloc buffer"));
01005                 
01006             G__convert_01_flags(flags, fcb->NULL_ROWS[i], G__.window.cols);
01007 
01008         }  /* for loop */
01009 
01010         if (null_fd > 0)
01011             close(null_fd);
01012     } /* row is not in memory */
01013 
01014     /* copy null file data translated by column mapping to user null row */
01015     /* the user requested flags row is of size G__.window.cols */
01016     G__convert_flags_01(flags, fcb->NULL_ROWS[row - fcb->min_null_row], G__.window.cols);
01017 }
01018 
01019 /*--------------------------------------------------------------------------*/
01020 /*--------------------------------------------------------------------------*/
01021 /*--------------------------------------------------------------------------*/
01022 
01023 static void embed_mask(char *flags, int row)
01024 {
01025     int i;
01026 
01027     if (G__.auto_mask <= 0)
01028         return;
01029 
01030     if (get_map_row_nomask(G__.mask_fd, G__.mask_buf, row, CELL_TYPE) < 0)
01031         return;
01032 
01033     if (G__.fileinfo[G__.mask_fd].reclass_flag) 
01034         do_reclass_int(G__.mask_fd, G__.mask_buf, 1);
01035 
01036     for (i = 0; i < G__.window.cols; i++)
01037         if (G__.mask_buf[i] == 0)
01038             flags[i] = 1;
01039 }
01040 
01041 static void get_null_value_row(int fd, char *flags, int row, int with_mask)
01042 {
01043     get_null_value_row_nomask(fd, flags, row);
01044 
01045     if (with_mask)
01046         embed_mask(flags, row);
01047 }
01048 
01049 static int embed_nulls(
01050     int fd, void *buf, int row, RASTER_MAP_TYPE map_type,
01051     int null_is_zero, int with_mask)
01052 {
01053     struct fileinfo *fcb = &G__.fileinfo[fd];
01054     int i;
01055 
01056     /* this is because without null file the nulls can be only due to 0's
01057        in data row or mask */
01058     if (null_is_zero && !fcb->null_file_exists
01059         && (G__.auto_mask<=0 || !with_mask))
01060         return 1;
01061 
01062     get_null_value_row(fd, G__.null_buf, row, with_mask);
01063 
01064     for (i = 0; i < G__.window.cols; i++)
01065     {
01066         /* also check for nulls which might be already embedded by quant
01067            rules in case of fp map. */
01068         if (G__.null_buf[i] || G_is_null_value(buf, map_type))
01069         {
01070             /* G__set_[f/d]_null_value() sets it to 0 is the embedded mode
01071                is not set and calls G_set_[f/d]_null_value() otherwise */
01072             G__set_null_value(buf, 1, null_is_zero, map_type);
01073         }
01074         buf = G_incr_void_ptr(buf, G_raster_size(map_type));
01075     }
01076 
01077     return 1;
01078 }
01079 
01080 /*--------------------------------------------------------------------------*/
01081 /*--------------------------------------------------------------------------*/
01082 /*--------------------------------------------------------------------------*/
01083 
01084 int G_get_null_value_row(int fd, char *flags, int row)
01085 {
01086     get_null_value_row(fd, flags, row, 1);
01087 
01088     return 1;
01089 }

Generated on Wed Dec 19 14:59:06 2007 for GRASS by  doxygen 1.5.4