126 #include <sys/types.h>
127 #include <sys/stat.h>
131 #include <grass/config.h>
134 #include <grass/glocale.h>
136 static int _zeros_r_nulls = 1;
138 static int put_raster_data(
int,
const void *,
int,
int,
int,
int,
140 static int put_data(
int,
const CELL *,
int,
int,
int,
int);
141 static int check_open(
const char *,
int,
int);
142 static int adjust(
int,
int *,
int *);
143 static void write_error(
int,
int);
144 static int same(
const unsigned char *,
const unsigned char *,
int);
145 static int seek_random(
int,
int,
int);
146 static void set_file_pointer(
int,
int);
147 static int put_fp_data(
int,
const void *,
int,
int,
int, RASTER_MAP_TYPE);
148 static int put_null_data(
int,
const char *,
int);
149 static int convert_and_write_if(
int,
const CELL *);
150 static int convert_and_write_id(
int,
const CELL *);
151 static int convert_and_write_df(
int,
const DCELL *);
152 static int convert_and_write_fd(
int,
const FCELL *);
153 static int put_raster_row(
int fd,
const void *buf, RASTER_MAP_TYPE data_type,
164 if (zeros_r_nulls >= 0)
165 _zeros_r_nulls = zeros_r_nulls > 0;
167 return _zeros_r_nulls;
174 if (!check_open(
"G_put_map_row_random", fd, 1))
177 buf += adjust(fd, &col, &n);
178 switch (put_data(fd, buf, row, col, n, _zeros_r_nulls)) {
215 G_fatal_error(_(
"G_put_map_row: %s is not integer! Use G_put_[f/d]_raster_row()!"),
220 return put_raster_row(fd, buf, CELL_TYPE, _zeros_r_nulls);
225 return put_raster_row(fd, buf, data_type, 0);
245 static int check_open(
const char *me,
int fd,
int random)
251 G_warning(_(
"%s: map [%s] not open for write - request ignored"), me,
259 G_warning(_(
"%s: map [%s] not open for random write - request ignored"),
266 G_warning(_(
"%s: map [%s] not open for sequential write - request ignored"),
270 G_warning(_(
"%s: unopened file descriptor - request ignored"), me);
284 static int adjust(
int fd,
int *col,
int *n)
288 int last = *col + *n;
295 if (last > fcb->
cellhd.cols)
303 static void write_error(
int fd,
int row)
310 G_warning(_(
"map [%s] - unable to write row %d"), fcb->
name, row);
322 ssize_t nwrite = fcb->
nbytes * n;
325 write_error(fd, row);
335 int nwrite = fcb->
nbytes * n;
338 write_error(fd, row);
347 static int seek_random(
int fd,
int row,
int col)
350 off_t offset = ((off_t) fcb->
cellhd.cols * row + col) * fcb->
nbytes;
352 if (lseek(fd, offset, SEEK_SET) < 0) {
353 write_error(fd, row);
362 static void set_file_pointer(
int fd,
int row)
366 fcb->
row_ptr[row] = lseek(fd, 0L, SEEK_CUR);
375 static int convert_float(XDR * xdrs,
const FCELL * rast,
int row,
int col,
380 for (i = 0; i < n; i++) {
392 if (!xdr_float(xdrs, &f)) {
393 G_warning(_(
"xdr_float failed for index %d of row %d"), i, row);
401 static int convert_double(XDR * xdrs,
const DCELL * rast,
int row,
int col,
406 for (i = 0; i < n; i++) {
418 if (!xdr_double(xdrs, &d)) {
419 G_warning(_(
"xdr_double failed for index %d of row %d"), i, row);
431 static int put_fp_data(
int fd,
const void *rast,
int row,
int col,
int n,
432 RASTER_MAP_TYPE data_type)
439 if (row < 0 || row >= fcb->
cellhd.rows)
446 if (seek_random(fd, row, col) == -1)
450 set_file_pointer(fd, row);
456 if (data_type == FCELL_TYPE) {
457 if (convert_float(xdrs, rast, row, col, n, random) < 0)
461 if (convert_double(xdrs, rast, row, col, n, random) < 0)
483 static void convert_int(
unsigned char *wk,
const CELL * rast,
int col,
int n,
484 int random,
int len,
int zeros_r_nulls)
490 for (i = 0; i < n; i++) {
501 else if (!random && zeros_r_nulls && !v)
513 for (k = len - 1; k >= 0; k--) {
526 static int count_bytes(
const unsigned char *wk,
int n,
int len)
530 for (i = 0; i < len - 1; i++)
531 for (j = 0; j < n; j++)
532 if (wk[j * len + i] != 0)
538 static void trim_bytes(
unsigned char *wk,
int n,
int slen,
int trim)
540 unsigned char *wk2 = wk;
543 for (i = 0; i < n; i++) {
544 for (j = 0; j < trim; j++)
546 for (; j < slen; j++)
551 static int same(
const unsigned char *x,
const unsigned char *
y,
int n)
553 return (memcmp(x, y, n) == 0);
556 static int count_run(
const unsigned char *src,
int n,
int nbytes)
558 const unsigned char *cur = src +
nbytes;
561 for (i = 1; i < n; i++) {
562 if (i == 255 || !same(cur, src, nbytes))
571 static int rle_compress(
unsigned char *dst,
unsigned char *src,
int n,
575 int total = nbytes * n;
580 nwrite += nbytes + 1;
584 count = count_run(src, n, nbytes);
587 memcpy(dst, src, nbytes);
597 static int zlib_compress(
unsigned char *dst,
unsigned char *src,
int n,
600 int total = nbytes * n;
601 int nwrite = G_zlib_compress(
G__.
work_buf + 1, total,
605 return (nwrite >= total) ? 0 : nwrite;
610 static int put_data(
int fd,
const CELL * cell,
int row,
int col,
int n,
615 int compressed = fcb->
cellhd.compressed;
616 int len = compressed ?
sizeof(CELL) : fcb->
nbytes;
620 if (row < 0 || row >= fcb->
cellhd.rows)
627 if (seek_random(fd, row, col) == -1)
631 set_file_pointer(fd, row);
636 convert_int(wk, cell, col, n, random, len, zeros_r_nulls);
640 int nbytes = count_bytes(wk, n, len);
647 trim_bytes(wk, n, len, len - nbytes);
652 nwrite = compressed == 1
655 : zlib_compress(
G__.compressed_buf + 1,
G__.work_buf + 1, n,
662 write_error(fd, row);
667 nwrite = nbytes * n + 1;
669 write_error(fd, row);
678 write_error(fd, row);
692 static int put_raster_data(
int fd,
const void *rast,
int row,
int col,
int n,
693 int zeros_r_nulls, RASTER_MAP_TYPE
map_type)
695 return (map_type == CELL_TYPE)
696 ? put_data(fd, rast, row, col, n, zeros_r_nulls)
697 : put_fp_data(fd, rast, row, col, n, map_type);
706 static int put_null_data(
int fd,
const char *flags,
int row)
728 fcb->
cellhd.cols, fd) < 0)
754 G_warning(_(
"unable to find a temporary null file %s"),
773 offset = (off_t) size *row;
775 if (lseek(null_fd, offset, SEEK_SET) < 0) {
776 G_warning(_(
"error writing null row %d"), row);
780 if (write(null_fd, flags, size) != size) {
781 G_warning(_(
"error writing null row %d"), row);
794 static int convert_and_write_if(
int fd,
const CELL * buf)
797 FCELL *p = (FCELL *) fcb->
data;
800 for (i = 0; i < fcb->
cellhd.cols; i++)
804 p[i] = (FCELL) buf[i];
809 static int convert_and_write_df(
int fd,
const DCELL * buf)
812 FCELL *p = (FCELL *) fcb->
data;
815 for (i = 0; i < fcb->
cellhd.cols; i++)
819 p[i] = (FCELL) buf[i];
824 static int convert_and_write_id(
int fd,
const CELL * buf)
827 DCELL *p = (DCELL *) fcb->
data;
830 for (i = 0; i < fcb->
cellhd.cols; i++)
834 p[i] = (DCELL) buf[i];
839 static int convert_and_write_fd(
int fd,
const FCELL * buf)
842 DCELL *p = (DCELL *) fcb->
data;
845 for (i = 0; i < fcb->
cellhd.cols; i++)
849 p[i] = (DCELL) buf[i];
854 static int convert_and_write_fi(
int fd,
const FCELL * buf)
857 CELL *p = (CELL *) fcb->
data;
860 for (i = 0; i < fcb->
cellhd.cols; i++)
864 p[i] = (CELL) buf[i];
869 static int convert_and_write_di(
int fd,
const DCELL * buf)
872 CELL *p = (CELL *) fcb->
data;
875 for (i = 0; i < fcb->
cellhd.cols; i++)
879 p[i] = (CELL) buf[i];
886 static int put_raster_row(
int fd,
const void *buf, RASTER_MAP_TYPE data_type,
891 static int (*convert_and_write_FtypeOtype[3][3]) () = {
893 NULL, convert_and_write_if, convert_and_write_id}, {
894 convert_and_write_fi,
NULL, convert_and_write_fd}, {
895 convert_and_write_di, convert_and_write_df,
NULL}
898 if (!check_open(
"put_raster_row", fd, 0))
902 return convert_and_write_FtypeOtype[data_type][fcb->
map_type] (fd,
907 switch (put_raster_data
917 if (data_type == CELL_TYPE) {