put_row.c

Go to the documentation of this file.
00001 /*
00002  * $Id: put_row.c,v 2.0.2.1 2006/01/25 14:15:05 markus Exp $
00003  */
00004 /**********************************************************************
00005  *
00006  *   G_zeros_r_nulls(zeros_r_nulls)
00007  *      int zeros_r_nulls       the last argument of put_data()
00008  *
00009  *   zeros_r_nulls > 0          zero values of buf to be written into files
00010  *                              are null values by default.
00011  *
00012  *   zeros_r_nulls == 0         zero values are just zero itself.
00013  *
00014  *   zeros_r_nulls < 0          do not set. return current setting.
00015  *                              1: set
00016  *                              0: not set
00017  *
00018  *   Return setting values in all cases.
00019  *
00020  *   *** NOTE *** 
00021  *   Use only to change a default behavior for zero of G_put_map_row[_random].
00022  *
00023  ********************************************************************** 
00024  *
00025  *   G_put_[c/f/d]_raster_row(fd, buf)
00026  *      int fd           file descriptor of the opened map
00027  *      [F/D]CELL *buf   buffer holding row info to be written
00028  *
00029  *   Writes the next row for the cell file opened on 'fd' from 'buf'
00030  *   All writes go into NEW files that exactly match the current window.
00031  *   The file must have been opened with G_open_cell_new()
00032  *   and be written sequentially, ie no skipping rows
00033  *
00034  *   when the null values are embeded into the data, corresponding cells are 
00035  *   changed to 0's and the corresponding null value row is written into null 
00036  *   file.
00037  *
00038  *   *** NOTE *** 
00039  *   A map cannot be copied using G_get_raster_row() and G_put_raster_row().
00040  *   The former resamples the data of the original map into a row buffer
00041  *   that matches the current window.  The later writes out rows associated
00042  *   with the window.
00043  *
00044  *   returns:    1  if successful
00045  *              -1  on fail
00046  *
00047  *  Keeps track of the minimum and maximum cell value  for use in updating
00048  *  the range file upon close of the cell file.
00049  *  HOWEVER when nulls are not embeded, the cells are considered 0's as far
00050  *  as updating range is concerned, even if the corresponding cell is null
00051  *  in the resulting null file, so programmer should be carefult to set all 
00052  *  the null values using G_set_null_value() or G_insert_[d/f_]null_values()
00053  *
00054  ********************************************************************** 
00055  *
00056  *   G_put_map_row(fd, buf)
00057  *      int fd           file descriptor of the opened map
00058  *      CELL *buf        buffer holding row info to be written
00059  *
00060  *   Writes the next row for the cell file opened on 'fd' from 'buf'
00061  *   All writes go into NEW files that exactly match the current window.
00062  *   The file must have been opened with G_open_cell_new()
00063  *   and be written sequentially, ie no skipping rows
00064  *
00065  *   NULLS are written into null bitmap file for all cells which are zero,
00066  *   and cells which have null value (these cells are converted to 0's before
00067  *   writing) 
00068  *
00069  *   *** NOTE *** 
00070  *   A map cannot be copied using G_get_map_row() and G_put_map_row().
00071  *   The former resamples the data of the original map into a row buffer
00072  *   that matches the current window.  The later writes out rows associated
00073  *   with the window.
00074  *
00075  *   returns:    1  if successful
00076  *              -1  on fail
00077  *
00078  *  Keeps track of the minimum and maximum cell value  for use in updating
00079  *  the range file upon close of the cell file.
00080  *
00081  ********************************************************************** 
00082  *
00083  *  G_put_map_row_random(fd, buf, row, col, ncells)
00084  *      int fd                  File descriptor where data is to be written
00085  *      CELL *buf               Buffer holding data
00086  *      int row                 Map row where data is to be written
00087  *      int col                 Column where data begins
00088  *      int ncells              Number of columns of data to be written
00089  *
00090  *   Writes parts of rows into open cell file.
00091  *
00092  *   Cell file must have been opened with G_open_cell_new_random()
00093  *   except it can't write null file.
00094  *
00095  *   returns:    0  if successful
00096  *              -1  on fail
00097  *
00098  *   behaves the same as G_put_map_row()
00099  *
00100  **********************************************************************
00101  *
00102  *  Note: there is no G_put_[c/f/d]_raster_row_random() because even though
00103  *  it is possible to randomly write floating and integer rows, it is not
00104  *  possible to rand. write null data, so the null file can't
00105  *  be updated correctly.
00106  *
00107  ***********************************************************************
00108  *
00109  *  G__put_null_value_row(fd, buf, row, col, ncells)
00110  *      int fd                  File descriptor where data is to be written
00111  *      char *buf               Buffer holding null data
00112  *      int row                 Map row where data is to be written
00113  *      int col                 Column where data begins
00114  *      int ncells              Number of columns of data to be written
00115  *
00116  *   converts a buffer of zero's and ones to bitstream and stores this 
00117  *   bitstream in memory. (the null rows from memory are written into null
00118  *   file after the limit is reached, and the place for new null rows
00119  *   to be kept in memory is freed. Should not be used by application
00120  *   programs.
00121  *
00122  *   returns:    0  if successful
00123  *              -1  on fail
00124  **********************************************************************/
00125 
00126 #include <string.h>
00127 
00128 #include <sys/types.h>
00129 #include <sys/stat.h>
00130 #include <unistd.h>
00131 #include <fcntl.h>
00132 
00133 #include "config.h"
00134 
00135 #include "G.h"
00136 #include "glocale.h"
00137 
00138 static int _zeros_r_nulls = 1;
00139 
00140 static int put_raster_data(int,void *,int,int,int,int,RASTER_MAP_TYPE);
00141 static int put_data(int,CELL *,int, int,int,int);
00142 static int check_open(const char *,int,int);
00143 static int adjust(int, int *, int *);
00144 static void write_error(int,int);
00145 static int same(const unsigned char *, const unsigned char *, int);
00146 static int seek_random(int, int, int);
00147 static void set_file_pointer(int,int);
00148 static int put_fp_data(int,void *,int,int,int,RASTER_MAP_TYPE);
00149 static int put_null_data(int,char *, int);
00150 static int convert_and_write_if(int, CELL *);
00151 static int convert_and_write_id(int, CELL *);
00152 static int convert_and_write_df(int, DCELL *);
00153 static int convert_and_write_fd(int, FCELL *);
00154 static int put_raster_row(int fd, void *buf, RASTER_MAP_TYPE data_type, int zeros_r_nulls);
00155 
00156 /*--------------------------------------------------------------------------*/
00157 /*--------------------------------------------------------------------------*/
00158 /*--------------------------------------------------------------------------*/
00159 
00160 int G_zeros_r_nulls(int zeros_r_nulls)
00161 {
00162     if (zeros_r_nulls >= 0)
00163         _zeros_r_nulls = zeros_r_nulls > 0;
00164 
00165     return _zeros_r_nulls;
00166 }
00167 
00168 int G_put_map_row_random(int fd, CELL *buf, int row, int col, int n)
00169 {
00170     struct fileinfo *fcb = &G__.fileinfo[fd];
00171 
00172     if (!check_open("G_put_map_row_random", fd, 1))
00173         return -1;
00174 
00175     buf += adjust(fd, &col, &n);
00176     switch (put_data(fd, buf, row, col, n, _zeros_r_nulls))
00177     {
00178     case -1: return -1;
00179     case  0: return  1;
00180     }
00181 
00182     /* only for integer maps */
00183     if (fcb->want_histogram)
00184         G_update_cell_stats (buf, n, &fcb->statf);
00185 
00186     G_row_update_range (buf, n, &fcb->range);
00187 
00188     return 1;
00189 }
00190 
00191 int G__put_null_value_row(int fd, char *buf)
00192 {
00193     struct fileinfo *fcb = &G__.fileinfo[fd];
00194 
00195     switch (put_null_data(fd, buf, fcb->null_cur_row))
00196     {
00197     case -1: return -1;
00198     case  0: return  1;
00199     }
00200 
00201     fcb->null_cur_row++;
00202     return 1;
00203 }
00204 
00205 int G_put_map_row(int fd, CELL *buf)
00206 {
00207     struct fileinfo *fcb = &G__.fileinfo[fd];
00208 
00209     if (fcb->map_type != CELL_TYPE)
00210     {
00211         G_fatal_error("G_put_map_row: %s is not integer! Use G_put_[f/d]_raster_row()!",
00212                       fcb->name);
00213         return -1;
00214     }
00215 
00216     return put_raster_row(fd, buf, CELL_TYPE, _zeros_r_nulls);
00217 }
00218 
00219 int G_put_raster_row(int fd, void *buf, RASTER_MAP_TYPE data_type)
00220 {
00221     return put_raster_row(fd, buf, data_type, 0);
00222 }
00223 
00224 int G_put_c_raster_row(int fd, CELL *buf)
00225 {
00226     return G_put_raster_row(fd, buf, CELL_TYPE);
00227 }
00228 
00229 int G_put_f_raster_row(int fd, FCELL *buf)
00230 {
00231     return G_put_raster_row(fd, buf, FCELL_TYPE);
00232 }
00233 
00234 int G_put_d_raster_row(int fd, DCELL *buf)
00235 {
00236     return G_put_raster_row(fd, buf, DCELL_TYPE);
00237 }
00238 
00239 /*--------------------------------------------------------------------------*/
00240 
00241 static int check_open(const char *me, int fd, int random)
00242 {
00243     struct fileinfo *fcb = &G__.fileinfo[fd];
00244 
00245     switch (fcb->open_mode)
00246     {
00247     case OPEN_OLD:
00248         G_warning(
00249             "%s: map [%s] not open for write - request ignored",
00250             me, fcb->name);
00251         break;
00252     case OPEN_NEW_COMPRESSED:
00253     case OPEN_NEW_UNCOMPRESSED:
00254         if (!random)
00255             return 1;
00256         G_warning(
00257             "%s: map [%s] not open for random write - request ignored",
00258             me, fcb->name);
00259         break;
00260     case OPEN_NEW_RANDOM:
00261         if (random)
00262             return 1;
00263         G_warning(
00264             "%s: map [%s] not open for sequential write - request ignored",
00265             me, fcb->name);
00266         break;
00267     default:
00268         G_warning( 
00269             "%s: unopened file descriptor - request ignored",
00270             me);
00271         break;
00272     }
00273 
00274     return 0;
00275 }
00276 
00277 /*******************************************************
00278 *  adjust the column,n so that it is within the window
00279 *  returns the adjustment to buffer that must be made
00280 *  if col,n is adjusted
00281 *
00282 *  if n comes back <= zero, do not write
00283 *******************************************************/
00284 static int adjust(int fd, int *col, int *n)
00285 {
00286     struct fileinfo *fcb = &G__.fileinfo[fd];
00287     int adj = 0;
00288     int last = *col + *n;
00289 
00290     if (*col < 0)
00291     {
00292         adj = -(*col);
00293         *col = 0;
00294     }
00295 
00296     if (last > fcb->cellhd.cols)
00297         last = fcb->cellhd.cols;
00298 
00299     *n = last - *col;
00300 
00301     return adj;
00302 }
00303 
00304 static void write_error(int fd,int row)
00305 {
00306     struct fileinfo *fcb = &G__.fileinfo[fd];
00307 
00308     if (fcb->io_error)
00309         return;
00310 
00311     G_warning(_("map [%s] - unable to write row %d"), fcb->name, row);
00312 
00313     fcb->io_error = 1;
00314 
00315     return;
00316 }
00317 
00318 /*--------------------------------------------------------------------------*/
00319 
00320 int G__write_data(int fd, int row, int n)
00321 
00322 {
00323     struct fileinfo *fcb = &G__.fileinfo[fd];
00324     int nwrite = fcb->nbytes * n;
00325 
00326     if (write(fd, G__.work_buf, nwrite) != nwrite)
00327     {
00328         write_error(fd, row);
00329         return -1;
00330     }
00331 
00332     return 0;
00333 }
00334 
00335 int G__write_data_compressed(int fd, int row, int n)
00336 {
00337     struct fileinfo *fcb = &G__.fileinfo[fd];
00338     int nwrite = fcb->nbytes * n;
00339 
00340     if (G_zlib_write(fd, G__.work_buf, nwrite) < 0)
00341     {
00342         write_error(fd, row);
00343         return -1;
00344     }
00345   
00346     return 0;
00347 }
00348 
00349 /*--------------------------------------------------------------------------*/
00350 
00351 static int seek_random(int fd, int row, int col)
00352 {
00353     struct fileinfo *fcb = &G__.fileinfo[fd];
00354     off_t offset = ((off_t) fcb->cellhd.cols * row + col) * fcb->nbytes;
00355 
00356     if (lseek(fd, offset, 0) < 0)
00357     {
00358         write_error(fd, row);
00359         return -1;
00360     }
00361 
00362     return 0;
00363 }
00364 
00365 /*--------------------------------------------------------------------------*/
00366 
00367 static void set_file_pointer(int fd, int row)
00368 {
00369     struct fileinfo *fcb = &G__.fileinfo[fd];
00370 
00371     fcb->row_ptr[row] = lseek(fd, (off_t) 0, 1);
00372 }
00373 
00374 /*--------------------------------------------------------------------------*/
00375 /*--------------------------------------------------------------------------*/
00376 /*--------------------------------------------------------------------------*/
00377 
00378 static int convert_float(
00379         XDR *xdrs, const FCELL *rast, int row, int col, int n, int random)
00380 {
00381     int i;
00382 
00383     for (i = 0; i < n; i++) 
00384     {
00385         FCELL f;
00386 
00387         /* substitute embeded null vals by 0's */
00388         if (G_is_f_null_value(&rast[i]))
00389         {
00390             f = 0.;
00391             if (!random)
00392                 G__.null_buf[col + i] = 1;
00393         }
00394         else 
00395             f = rast[i];
00396 
00397         if (!xdr_float(xdrs, &f)) 
00398         {
00399             G_warning("xdr_float failed for index %d of row %d.",  i, row);
00400             return -1;
00401         }
00402     }
00403 
00404     return 0;
00405 }
00406 
00407 static int convert_double(
00408         XDR *xdrs, const DCELL *rast, int row, int col, int n, int random)
00409 {
00410     int i;
00411 
00412     for (i = 0; i < n; i++) 
00413     {
00414         DCELL d;
00415 
00416         /* substitute embeded null vals by 0's */
00417         if (G_is_d_null_value(&rast[i]))
00418         {
00419             d = 0.;
00420             if (!random)
00421                 G__.null_buf[col + i] = 1;
00422         }
00423         else
00424             d = rast[i];
00425 
00426         if (!xdr_double(xdrs, &d)) 
00427         {
00428             G_warning("xdr_double failed for index %d of row %d.", i, row);
00429             return -1;
00430         }
00431     }
00432 
00433     return 0;
00434 }
00435 
00436 /*--------------------------------------------------------------------------*/
00437 
00438 /* writes data to fcell file for either full or partial rows */
00439 
00440 static int put_fp_data(int fd, void *rast, int row, int col, int n, RASTER_MAP_TYPE data_type)
00441 {
00442     struct fileinfo *fcb = &G__.fileinfo[fd];
00443     int random     = (fcb->open_mode == OPEN_NEW_RANDOM);
00444     int compressed = (fcb->open_mode == OPEN_NEW_COMPRESSED);
00445     XDR *xdrs = &fcb->xdrstream;
00446 
00447     if (row < 0 || row >= fcb->cellhd.rows)
00448         return 0;
00449   
00450     if (n <= 0)
00451         return 0;
00452   
00453     if (random)
00454     {
00455         if (seek_random(fd, row, col) == -1)
00456             return -1;
00457     }
00458     else if (compressed)
00459         set_file_pointer(fd, row);
00460   
00461     xdrmem_create(xdrs, (caddr_t) G__.work_buf,
00462                   (u_int) (fcb->nbytes * fcb->cellhd.cols), XDR_ENCODE);
00463     xdr_setpos (xdrs, 0);
00464   
00465     if (data_type == FCELL_TYPE)
00466     {
00467         if (convert_float(xdrs, rast, row, col, n, random) < 0)
00468             return -1;
00469     }
00470     else
00471     {
00472         if (convert_double(xdrs, rast, row, col, n, random) < 0)
00473             return -1;
00474     }
00475 
00476     xdr_destroy(&fcb->xdrstream);
00477   
00478     if (compressed)
00479     {
00480         if (G__write_data_compressed(fd, row, n) == -1)
00481             return -1;
00482     }
00483     else
00484         if (G__write_data(fd, row, n) == -1)
00485             return -1;
00486   
00487     return 1;
00488 }
00489 
00490 /*--------------------------------------------------------------------------*/
00491 /*--------------------------------------------------------------------------*/
00492 /*--------------------------------------------------------------------------*/
00493 
00494 static void convert_int(
00495     unsigned char *wk, const CELL *rast, int col, int n,
00496     int random, int len, int zeros_r_nulls)
00497 {
00498     int i;
00499 
00500     /* transform CELL data into non-machine dependent multi-byte format */
00501 
00502     for (i = 0; i < n; i++)
00503     {
00504         CELL v = rast[i];
00505         int neg;
00506         int k;
00507 
00508         /* substitute embeded null vals by 0's */
00509         if (G_is_c_null_value(&v))
00510         {
00511             v = 0;
00512             if (!random)
00513                 G__.null_buf[col + i] = 1;
00514         }
00515         else if (!random && zeros_r_nulls && !v)
00516             G__.null_buf[col + i] = 1;
00517 
00518         /* negatives */
00519         if (v < 0)
00520         {
00521             neg = 1;
00522             v = -v;
00523         }
00524         else
00525             neg = 0;
00526 
00527         /* copy byte by byte */
00528         for (k = len - 1; k >= 0; k--)
00529         {
00530             wk[k] = v & 0xff;
00531             v >>= 8;
00532         }
00533 
00534         /* set negative bit in first byte */
00535         if (neg)
00536             wk[0] |= 0x80 ;
00537 
00538         wk += len;
00539     }
00540 }
00541 
00542 static int count_bytes(const unsigned char *wk, int n, int len)
00543 {
00544     int i, j;
00545 
00546     for (i = 0; i < len - 1; i++)
00547         for (j = 0; j < n; j++)
00548             if (wk[j * len + i] != 0)
00549                 return len - i;
00550 
00551     return 1;
00552 }
00553 
00554 static void trim_bytes(unsigned char *wk, int n, int slen, int trim)
00555 {
00556     unsigned char *wk2 = wk;
00557     int i, j;
00558 
00559     for (i = 0; i < n; i++)
00560     {
00561         for (j = 0; j < trim; j++)
00562             wk++;
00563         for ( ; j < slen; j++)
00564             *wk2++ = *wk++;
00565     }
00566 }
00567 
00568 static int same(const unsigned char *x, const unsigned char *y, int n)
00569 {
00570     return memcmp(x, y, n) == 0;
00571 }
00572 
00573 static int count_run(const unsigned char *src, int n, int nbytes)
00574 {
00575     const unsigned char *cur = src + nbytes;
00576     int i;
00577 
00578     for (i = 1; i < n; i++)
00579     {
00580         if (i == 255 || !same(cur, src, nbytes))
00581             return i;
00582 
00583         cur += nbytes;
00584     }
00585 
00586     return n;
00587 }
00588 
00589 static int rle_compress(unsigned char *dst, unsigned char *src, int n, int nbytes)
00590 {
00591     int nwrite = 0;
00592     int total = nbytes * n;
00593 
00594     while (n > 0)
00595     {
00596         int count;
00597 
00598         nwrite += nbytes + 1;
00599         if (nwrite >= total)
00600             return 0;
00601 
00602         count = count_run(src, n, nbytes);
00603 
00604         *dst++ = count;
00605         memcpy(dst, src, nbytes);
00606         dst += nbytes;
00607 
00608         src += count * nbytes;
00609         n -= count;
00610     }
00611 
00612     return nwrite;
00613 }
00614 
00615 static int zlib_compress(unsigned char *dst, unsigned char *src, int n, int nbytes)
00616 {
00617     int total = nbytes * n;
00618     int nwrite = G_zlib_compress(G__.work_buf + 1, total,
00619                                  G__.compressed_buf + 1, G__.compressed_buf_size - 1);
00620 
00621     return (nwrite >= total) ? 0 : nwrite;
00622 }
00623 
00624 /*--------------------------------------------------------------------------*/
00625 
00626 static int put_data(int fd, CELL *cell, int row, int col, int n, int zeros_r_nulls)
00627 {
00628     struct fileinfo *fcb = &G__.fileinfo[fd];
00629     int random     = (fcb->open_mode == OPEN_NEW_RANDOM);
00630     int compressed = fcb->cellhd.compressed;
00631     int len = compressed ? sizeof(CELL) : fcb->nbytes;
00632     unsigned char *wk = G__.work_buf;
00633     int nwrite;
00634 
00635     if (row < 0 || row >= fcb->cellhd.rows)
00636         return 0;
00637 
00638     if (n <= 0)
00639         return 0;
00640 
00641     if (random)
00642     {
00643         if (seek_random(fd, row, col) == -1)
00644             return -1;
00645     }
00646     else if (compressed)
00647         set_file_pointer(fd, row);
00648 
00649     if (compressed)
00650         wk++;
00651 
00652     convert_int(wk, cell, col, n, random, len, zeros_r_nulls);
00653 
00654     if (compressed)
00655     {
00656         unsigned char *wk = G__.work_buf + 1;
00657         int nbytes = count_bytes(wk, n, len);
00658 
00659         if (fcb->nbytes < nbytes)
00660             fcb->nbytes = nbytes;
00661 
00662         /* first trim away zero high bytes */
00663         if (nbytes < len)
00664             trim_bytes(wk, n, len, len - nbytes);
00665 
00666         G__.compressed_buf[0] = G__.work_buf[0] = nbytes;
00667 
00668         /* then compress the data */
00669         nwrite = compressed == 1
00670             ? rle_compress(G__.compressed_buf + 1, G__.work_buf + 1, n, nbytes)
00671             : zlib_compress(G__.compressed_buf + 1, G__.work_buf + 1, n, nbytes);
00672 
00673         if (nwrite > 0)
00674         {
00675             nwrite++;
00676 
00677             if (write(fd, G__.compressed_buf, nwrite) != nwrite)
00678             {
00679                 write_error(fd, row);
00680                 return -1;
00681             }
00682         }
00683         else
00684         {
00685             nwrite = nbytes * n + 1;
00686             if (write(fd, G__.work_buf, nwrite) != nwrite)
00687             {
00688                 write_error(fd, row);
00689                 return -1;
00690             }
00691         }
00692     }
00693     else
00694     {
00695         nwrite = fcb->nbytes * n;
00696 
00697         if (write(fd, G__.work_buf, nwrite) != nwrite)
00698         {
00699             write_error(fd, row);
00700             return -1;
00701         }
00702     }
00703 
00704     return 1;
00705 }
00706 
00707 /*--------------------------------------------------------------------------*/
00708 /*--------------------------------------------------------------------------*/
00709 /*--------------------------------------------------------------------------*/
00710 
00711 static int put_raster_data(int fd, void *rast, int row, int col, int n, int zeros_r_nulls, RASTER_MAP_TYPE map_type)
00712 {
00713     return (map_type == CELL_TYPE)
00714         ? put_data(fd, rast, row, col, n, zeros_r_nulls)
00715         : put_fp_data(fd, rast, row, col, n, map_type);
00716 }
00717 
00718 /*--------------------------------------------------------------------------*/
00719 /*--------------------------------------------------------------------------*/
00720 /*--------------------------------------------------------------------------*/
00721 
00722 static int put_null_data(int fd, char *flags, int row)
00723 {
00724     struct fileinfo *fcb = &G__.fileinfo[fd];
00725     int null_fd, i;
00726 
00727     if (fcb->min_null_row + NULL_ROWS_INMEM <= row)
00728     {
00729         /* the row is out of the range of rows stored in memory */
00730         /* write out all the rows kept in memory, and initialize memory
00731            for keeping new NULL_ROWS_INMEM rows */
00732 
00733         if (fcb->min_null_row >= 0)
00734         {
00735             null_fd = G__open_null_write(fd);
00736             if (null_fd < 0)
00737                 return -1;
00738 
00739             for (i = 0; i < NULL_ROWS_INMEM; i++)
00740             {
00741                 /* fcb->cellhd.rows doesn't have to be a miultiple of NULL_ROWS_INMEM */
00742                 if (i + fcb->min_null_row >= fcb->cellhd.rows)
00743                     break;
00744 
00745                 if (G__write_null_bits(null_fd, fcb->NULL_ROWS[i], 
00746                                        i+fcb->min_null_row, fcb->cellhd.cols, fd) < 0)
00747                     return -1;
00748 
00749             } /* done writing out memory rows */
00750             if (null_fd >= 0)
00751                 close(null_fd);
00752         }
00753 
00754         /* now initialize memory to store new NULL_ROWS_INMEM rows */
00755         fcb->min_null_row = fcb->min_null_row + NULL_ROWS_INMEM;
00756         /* init memory to store next NULL_ROWS_INMEM rows */
00757     }
00758 
00759     /* remember the null row for i for the future writing */
00760     G__convert_01_flags(flags, fcb->NULL_ROWS[row - fcb->min_null_row], fcb->cellhd.cols);
00761     return 1;
00762 }
00763 
00764 int G__open_null_write(int fd)
00765 {
00766     struct fileinfo *fcb = &G__.fileinfo[fd];
00767     int null_fd;
00768 
00769     if (access(fcb->null_temp_name, 0) != 0) 
00770     {
00771         G_warning("unable to find a temporary null file %s", 
00772                   fcb->null_temp_name);
00773         return -1;
00774     }
00775 
00776     null_fd = open(fcb->null_temp_name, O_WRONLY);
00777     if (null_fd < 0)
00778         return -1;
00779 
00780     return null_fd;
00781 }
00782 
00783 int G__write_null_bits(int null_fd, unsigned char *flags, int row, int cols, int fd)
00784 {
00785     off_t offset;
00786     int size;
00787 
00788     size = G__null_bitstream_size(cols);
00789     offset = (off_t) size * row;
00790 
00791     if (lseek(null_fd, offset, 0) < 0)
00792     {
00793         G_warning(_("error writing null row %d"),row);
00794         return -1;
00795     }
00796 
00797     if (write(null_fd, flags, size) != size)
00798     {
00799         G_warning(_("error writing null row %d"),row);
00800         return -1;
00801     }
00802     return 1;
00803 }
00804 
00805 /*--------------------------------------------------------------------------*/
00806 /*--------------------------------------------------------------------------*/
00807 /*--------------------------------------------------------------------------*/
00808 
00809 static int convert_and_write_if(int fd, CELL *buf)
00810 {
00811     struct fileinfo *fcb = &G__.fileinfo[fd];
00812     FCELL *p = (FCELL *) fcb->data;
00813     int i;
00814 
00815     for (i = 0; i < fcb->cellhd.cols; i++)
00816         if (G_is_c_null_value(&buf[i]))
00817             G_set_f_null_value(&p[i], 1);
00818         else
00819             p[i] = (FCELL) buf[i];
00820 
00821     return G_put_f_raster_row(fd, p);
00822 }
00823 
00824 static int convert_and_write_df(int fd, DCELL *buf)
00825 {
00826     struct fileinfo *fcb = &G__.fileinfo[fd];
00827     FCELL *p = (FCELL *) fcb->data;
00828     int i;
00829 
00830     for (i = 0; i < fcb->cellhd.cols; i++)
00831         if (G_is_d_null_value(&buf[i]))
00832             G_set_f_null_value(&p[i], 1);
00833         else
00834             p[i] = (FCELL) buf[i];
00835 
00836     return G_put_f_raster_row(fd, p);
00837 }
00838 
00839 static int convert_and_write_id(int fd, CELL *buf)
00840 {
00841     struct fileinfo *fcb = &G__.fileinfo[fd];
00842     DCELL *p = (DCELL *) fcb->data;
00843     int i;
00844 
00845     for (i = 0; i < fcb->cellhd.cols; i++)
00846         if (G_is_c_null_value(&buf[i]))
00847             G_set_d_null_value(&p[i], 1);
00848         else
00849             p[i] = (DCELL) buf[i];
00850 
00851     return G_put_d_raster_row(fd, p);
00852 }
00853 
00854 static int convert_and_write_fd(int fd, FCELL *buf)
00855 {
00856     struct fileinfo *fcb = &G__.fileinfo[fd];
00857     DCELL *p = (DCELL *) fcb->data;
00858     int i;
00859 
00860     for (i = 0; i < fcb->cellhd.cols; i++)
00861         if (G_is_f_null_value(&buf[i]))
00862             G_set_d_null_value(&p[i], 1);
00863         else
00864             p[i] = (DCELL) buf[i];
00865 
00866     return G_put_d_raster_row(fd, p);
00867 }
00868 
00869 static int convert_and_write_fi(int fd, FCELL *buf)
00870 {
00871     struct fileinfo *fcb = &G__.fileinfo[fd];
00872     CELL *p = (CELL *) fcb->data;
00873     int i;
00874 
00875     for (i = 0; i < fcb->cellhd.cols; i++)
00876         if (G_is_f_null_value(&buf[i]))
00877             G_set_c_null_value(&p[i], 1);
00878         else
00879             p[i] = (CELL) buf[i];
00880 
00881     return G_put_c_raster_row(fd, p);
00882 }
00883 
00884 static int convert_and_write_di(int fd, DCELL *buf)
00885 {
00886     struct fileinfo *fcb = &G__.fileinfo[fd];
00887     CELL *p = (CELL *) fcb->data;
00888     int i;
00889 
00890     for (i = 0; i < fcb->cellhd.cols; i++)
00891         if (G_is_d_null_value(&buf[i]))
00892             G_set_c_null_value(&p[i], 1);
00893         else
00894             p[i] = (CELL) buf[i];
00895 
00896     return G_put_c_raster_row(fd, p);
00897 }
00898 
00899 /*--------------------------------------------------------------------------*/
00900 
00901 static int put_raster_row(
00902     int fd, void *buf, RASTER_MAP_TYPE data_type, int zeros_r_nulls)
00903 {
00904     struct fileinfo *fcb = &G__.fileinfo[fd];
00905 
00906     static int (*convert_and_write_FtypeOtype[3][3])() = {
00907         {NULL                , convert_and_write_if, convert_and_write_id},
00908         {convert_and_write_fi, NULL                , convert_and_write_fd},
00909         {convert_and_write_di, convert_and_write_df, NULL                }
00910     };
00911 
00912     if (!check_open("put_raster_row", fd, 0))
00913         return -1;
00914 
00915     if (fcb->map_type != data_type)
00916         return convert_and_write_FtypeOtype[data_type][fcb->map_type](fd, buf);
00917 
00918     G_zero(G__.null_buf, fcb->cellhd.cols * sizeof(char));
00919 
00920     switch (put_raster_data(fd, buf, fcb->cur_row, 0, fcb->cellhd.cols, zeros_r_nulls, data_type))
00921     {
00922     case -1: return -1;
00923     case  0: return  1;
00924     }
00925 
00926     /* only for integer maps */
00927     if (data_type == CELL_TYPE)
00928     {
00929         if (fcb->want_histogram)
00930             G_update_cell_stats(buf, fcb->cellhd.cols, &fcb->statf);
00931         G__row_update_range(buf, fcb->cellhd.cols, &fcb->range, zeros_r_nulls);
00932     }
00933     else
00934         G_row_update_fp_range (buf, fcb->cellhd.cols, &fcb->fp_range, data_type);
00935 
00936     fcb->cur_row++;
00937 
00938     /* write the null row for the data row */
00939     return G__put_null_value_row(fd, G__.null_buf);
00940 }
00941 
00942 /*--------------------------------------------------------------------------*/
00943 /*--------------------------------------------------------------------------*/
00944 /*--------------------------------------------------------------------------*/
00945 

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