40 uint16_t width, uint16_t height,
41 const uint8_t** ptr,
const uint8_t* end,
55 rterror(
"rt_band_from_wkb: Out of memory allocating rt_band during WKB parsing");
61 rterror(
"rt_band_from_wkb: Premature end of WKB on band reading (%s:%d)",
79 band->height = height;
81 RASTER_DEBUGF(3,
" Band pixtype:%s, offline:%d, hasnodata:%d",
89 if (((*ptr) + pixbytes) >= end) {
90 rterror(
"rt_band_from_wkb: Premature end of WKB on band novalue reading");
96 switch (band->pixtype) {
98 band->nodataval = ((int)
read_uint8(ptr)) & 0x01;
102 band->nodataval = ((int)
read_uint8(ptr)) & 0x03;
106 band->nodataval = ((int)
read_uint8(ptr)) & 0x0F;
118 band->nodataval =
read_int16(ptr, littleEndian);
126 band->nodataval =
read_int32(ptr, littleEndian);
146 rterror(
"rt_band_from_wkb: Unknown pixeltype %d", band->pixtype);
152 RASTER_DEBUGF(3,
" Nodata value: %g, pixbytes: %d, ptr @ %p, end @ %p",
153 band->nodataval, pixbytes, *ptr, end);
156 if (((*ptr) + 1) >= end) {
157 rterror(
"rt_band_from_wkb: Premature end of WKB on offline "
158 "band data bandNum reading (%s:%d)",
165 band->data.offline.bandNum =
read_int8(ptr);
166 band->data.offline.mem = NULL;
171 while ((*ptr)[sz] && &((*ptr)[sz]) < end) ++sz;
172 if (&((*ptr)[sz]) >= end) {
173 rterror(
"rt_band_from_wkb: Premature end of WKB on band offline path reading");
181 band->data.offline.path =
rtalloc(sz + 1);
182 if (band->data.offline.path == NULL) {
183 rterror(
"rt_band_from_wkb: Out of memory allocating for offline path of band");
188 memcpy(band->data.offline.path, *ptr, sz);
189 band->data.offline.path[sz] =
'\0';
192 band->data.offline.path, sz);
205 sz = (size_t)width * height * pixbytes;
206 if (((*ptr) + sz) > end) {
207 rterror(
"rt_band_from_wkb: Premature end of WKB on band data reading (%s:%d)",
214 if (!band->data.mem) {
215 rterror(
"rt_band_from_wkb: Out of memory during band creation in WKB parser");
221 memcpy(band->data.mem, *ptr, sz);
228 void (*flipper)(uint8_t*) = 0;
229 uint8_t *flipme = NULL;
233 else if (pixbytes == 4)
235 else if (pixbytes == 8)
238 rterror(
"rt_band_from_wkb: Unexpected pix bytes %d", pixbytes);
243 flipme = band->data.mem;
244 sz = (size_t)width * height;
245 for (v = 0; v < sz; ++v) {
253 band->pixtype ==
PT_1BB ||
257 uint8_t maxVal = band->pixtype ==
PT_1BB ? 1 : (band->pixtype ==
PT_2BUI ? 3 : 15);
260 sz = (size_t)width*height;
261 for (v = 0; v < sz; ++v) {
262 val = ((uint8_t*) band->data.mem)[v];
264 rterror(
"rt_band_from_wkb: Invalid value %d for pixel of type %s",
280#define RT_WKB_HDR_SZ (sizeof(struct rt_raster_serialized_t)-4+1)
284 const uint8_t *ptr = wkb;
285 const uint8_t *wkbend = NULL;
288 uint16_t version = 0;
296 rterror(
"rt_raster_from_wkb: wkb size (%" PRIu32
297 ") < min size (%zu)",
301 wkbend = wkb + wkbsize;
303 RASTER_DEBUGF(3,
"Parsing header from wkb position %zu (expected 0)",
304 d_binptr_to_pos(ptr, wkbend, wkbsize));
315 rterror(
"rt_raster_from_wkb: WKB version %d unsupported", version);
322 rterror(
"rt_raster_from_wkb: Out of memory allocating raster for wkb input");
338 assert(ptr <= wkbend);
343 rast->scaleX, rast->scaleY);
345 rast->ipX, rast->ipY);
347 rast->skewX, rast->skewY);
351 rast->width, rast->height);
352 RASTER_DEBUGF(3,
"Parsing raster header finished at wkb position %zu (expected 61)",
353 d_binptr_to_pos(ptr, wkbend, wkbsize));
358 if (!rast->numBands) {
361 rtwarn(
"%zu bytes of WKB remained unparsed", wkbend - ptr);
363 else if (ptr > wkbend) {
365 rtwarn(
"We parsed %zu bytes more then available!", ptr - wkbend);
375 rterror(
"rt_raster_from_wkb: Out of memory allocating bands for WKB raster decoding");
382 assert(ptr <= wkbend);
384 for (i = 0; i < rast->numBands; ++i) {
386 d_binptr_to_pos(ptr, wkbend, wkbsize));
389 &ptr, wkbend, endian);
391 rterror(
"rt_raster_from_wkb: Error reading WKB form of band %d", i);
398 rast->bands[i] = band;
403 rtwarn(
"%zu bytes of WKB remained unparsed", wkbend - ptr);
405 else if (ptr > wkbend) {
407 rtwarn(
"We parsed %zu bytes more then available!", ptr - wkbend);
417 uint32_t wkbsize = 0;
420 assert(NULL != hexwkb);
425 if (hexwkbsize % 2) {
426 rterror(
"rt_raster_from_hexwkb: Raster HEXWKB input must have an even number of characters");
429 wkbsize = hexwkbsize / 2;
433 rterror(
"rt_raster_from_hexwkb: Out of memory allocating memory for decoding HEXWKB");
438 for (i = 0; i < wkbsize; ++i) {
439 wkb[i] =
parse_hex((
char*) & (hexwkb[i * 2]));
453 assert(NULL != raster);
455 RASTER_DEBUGF(3,
"rt_raster_wkb_size: computing size for %d bands",
458 for (i = 0; i < raster->numBands; ++i) {
459 rt_band band = raster->bands[i];
463 RASTER_DEBUGF(3,
"rt_raster_wkb_size: adding size of band %d", i);
466 rterror(
"rt_raster_wkb_size: Corrupted band: unknown pixtype");
476 if (!outasin && band->offline) {
481 size += strlen(band->data.offline.path) + 1;
485 size += pixbytes * raster->width * raster->height;
504#if POSTGIS_DEBUG_LEVEL > 0
505 const uint8_t *wkbend = NULL;
513 assert(NULL != raster);
514 assert(NULL != wkbsize);
516 RASTER_DEBUG(2,
"rt_raster_to_wkb: about to call rt_raster_wkb_size");
519 RASTER_DEBUGF(3,
"rt_raster_to_wkb: found size: %d", *wkbsize);
521 wkb = (uint8_t*)
rtalloc(*wkbsize);
523 rterror(
"rt_raster_to_wkb: Out of memory allocating WKB for raster");
529#if POSTGIS_DEBUG_LEVEL > 2
530 wkbend = ptr + (*wkbsize);
532 RASTER_DEBUGF(3,
"Writing raster header to wkb on position %zu (expected 0)",
533 d_binptr_to_pos(ptr, wkbend, *wkbsize));
546 RASTER_DEBUGF(3,
"Writing bands header to wkb position %zu (expected 61)",
547 d_binptr_to_pos(ptr, wkbend, *wkbsize));
550 for (i = 0; i < raster->numBands; ++i) {
551 rt_band band = raster->bands[i];
556 RASTER_DEBUGF(3,
"Writing band pixel type to wkb position %zu",
557 d_binptr_to_pos(ptr, wkbend, *wkbsize));
560 rterror(
"rt_raster_to_wkb: Corrupted band: unknown pixtype");
566 *ptr = band->pixtype;
576 memset(ptr,
'\0', pixbytes - 1);
580 assert(!(((uint64_t) ptr) % pixbytes));
584 d_binptr_to_pos(ptr, wkbend, *wkbsize));
592 uint8_t v = band->nodataval;
598 int8_t v = band->nodataval;
604 int16_t v = band->nodataval;
610 uint16_t v = band->nodataval;
616 int32_t v = band->nodataval;
622 uint32_t v = band->nodataval;
634 float v = band->nodataval;
640 memcpy(ptr, &band->nodataval, 8);
645 rterror(
"rt_raster_to_wkb: Fatal error caused by unknown pixel type. Aborting.");
654 assert(!((uint64_t) ptr % pixbytes));
657 if (!outasin && band->offline) {
659 *ptr = band->data.offline.bandNum;
663 strcpy((
char*) ptr, band->data.offline.path);
664 ptr += strlen(band->data.offline.path) + 1;
668 uint32_t datasize = raster->width * raster->height * pixbytes;
669 RASTER_DEBUGF(4,
"rt_raster_to_wkb: Copying %d bytes", datasize);
679 while ((uint64_t) ptr % 8) {
685 assert(!((uint64_t) ptr % pixbytes));
696 uint32_t wkbsize = 0;
698 assert(NULL != raster);
699 assert(NULL != hexwkbsize);
701 RASTER_DEBUG(2,
"rt_raster_to_hexwkb: calling rt_raster_to_wkb");
705 RASTER_DEBUG(3,
"rt_raster_to_hexwkb: rt_raster_to_wkb returned");
707 *hexwkbsize = wkbsize * 2;
708 hexwkb = (
char*)
rtalloc((*hexwkbsize) + 1);
710 rterror(
"rt_raster_to_hexwkb: Out of memory hexifying raster WKB");
717 const char hexchar[]=
"0123456789ABCDEF";
720 *optr++ = hexchar[v>>4];
721 *optr++ = hexchar[v & 0x0F];
727 RASTER_DEBUGF(3,
"rt_raster_to_hexwkb: output wkb: %s", hexwkb);
uint8_t parse_hex(char *str)
Convert a single hex digit into the corresponding char.
int32_t clamp_srid(int32_t srid)
Return a valid SRID from an arbitrary integer Raises a notice if what comes out is different from wha...
void rterror(const char *fmt,...) __attribute__((format(printf
Wrappers used for reporting errors and info.
void * rtalloc(size_t size)
Wrappers used for managing memory.
#define RASTER_DEBUG(level, msg)
#define RASTER_DEBUGF(level, msg,...)
void void void rtwarn(const char *fmt,...) __attribute__((format(printf
uint16_t rt_util_float_to_float16(float value)
float rt_util_float16_to_float(uint16_t value)
void * rt_band_get_data(rt_band band)
Get pointer to raster band data.
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
const char * rt_pixtype_name(rt_pixtype pixtype)
void rt_band_destroy(rt_band band)
Destroy a raster band.
void rtdealloc(void *mem)
struct rt_raster_t * rt_raster
Types definitions.
int rt_pixtype_size(rt_pixtype pixtype)
Return size in bytes of a value in the given pixtype.
This library is the generic raster handling section of PostGIS.
uint8_t isMachineLittleEndian(void)
void flip_endian_32(uint8_t *d)
void flip_endian_16(uint8_t *d)
uint8_t read_uint8(const uint8_t **from)
void write_uint16(uint8_t **to, uint8_t littleEndian, uint16_t v)
double read_float64(const uint8_t **from, uint8_t littleEndian)
float read_float32(const uint8_t **from, uint8_t littleEndian)
void flip_endian_64(uint8_t *d)
int8_t read_int8(const uint8_t **from)
int16_t read_int16(const uint8_t **from, uint8_t littleEndian)
int32_t read_int32(const uint8_t **from, uint8_t littleEndian)
uint32_t read_uint32(const uint8_t **from, uint8_t littleEndian)
uint16_t read_uint16(const uint8_t **from, uint8_t littleEndian)
#define BANDTYPE_FLAG_HASNODATA
#define BANDTYPE_FLAG_OFFDB
#define BANDTYPE_FLAG_ISNODATA
#define BANDTYPE_HAS_NODATA(x)
#define BANDTYPE_IS_OFFDB(x)
#define BANDTYPE_IS_NODATA(x)
#define BANDTYPE_PIXTYPE_MASK
#define CHECK_BINPTR_POSITION(ptr, end, size, pos)
static rt_band rt_band_from_wkb(uint16_t width, uint16_t height, const uint8_t **ptr, const uint8_t *end, uint8_t littleEndian)
rt_raster rt_raster_from_wkb(const uint8_t *wkb, uint32_t wkbsize)
Construct an rt_raster from a binary WKB representation.
char * rt_raster_to_hexwkb(rt_raster raster, int outasin, uint32_t *hexwkbsize)
Return this raster in HEXWKB form (null-terminated hex)
rt_raster rt_raster_from_hexwkb(const char *hexwkb, uint32_t hexwkbsize)
Construct an rt_raster from a text HEXWKB representation.
uint8_t * rt_raster_to_wkb(rt_raster raster, int outasin, uint32_t *wkbsize)
Return this raster in WKB form.
static uint32_t rt_raster_wkb_size(rt_raster raster, int outasin)