38 #if POSTGIS_DEBUG_LEVEL > 2
47 assert(NULL != hexsize);
51 hex = (
char*)
rtalloc((*hexsize) + 1);
53 rterror(
"d_binary_to_hex: Out of memory hexifying raw binary");
58 for (i = 0; i < size; ++i) {
63 assert(0 == strlen(hex) % 2);
68 d_print_binary_hex(
const char* msg,
const uint8_t *
const raw,
uint32_t size) {
77 hex = d_binary_to_hex(raw, size, &hexsize);
79 rtinfo(
"%s\t%s", msg, hex);
85 d_binptr_to_pos(
const uint8_t *
const ptr,
const uint8_t *
const end,
size_t size) {
86 assert(NULL != ptr && NULL != end);
88 return (size - (end - ptr));
110 setBits(
char* ch,
double val,
int bits,
int bitOffset) {
111 char mask = 0xFF >> (8 - bits);
116 assert(8 - bitOffset >= bits);
119 ival, bits, mask, bitOffset);
123 #if POSTGIS_RASTER_WARN_ON_TRUNCATION > 0
125 rtwarn(
"Pixel value for %d-bits band got truncated"
126 " from %g to %hhu", bits, val, ival);
135 ival <<= (8 - bitOffset - bits);
141 *ch &= ~(mask << (8 - bits - bitOffset));
157 assert(NULL != a && NULL != b);
191 static int endian_check_int = 1;
193 return *((
uint8_t *) & endian_check_int);
198 assert(NULL != from);
214 assert(NULL != from);
232 assert(NULL != from);
239 ret = (*from)[0] << 8 |
251 (*to)[0] = v & 0x00FF;
254 (*to)[1] = v & 0x00FF;
262 assert(NULL != from);
290 assert(NULL != from);
293 ret = (
uint32_t) ((*from)[0] & 0xff) |
294 (
uint32_t) ((*from)[1] & 0xff) << 8 |
295 (
uint32_t) ((*from)[2] & 0xff) << 16 |
296 (
uint32_t) ((*from)[3] & 0xff) << 24;
299 ret = (
uint32_t) ((*from)[3] & 0xff) |
300 (
uint32_t) ((*from)[2] & 0xff) << 8 |
301 (
uint32_t) ((*from)[1] & 0xff) << 16 |
302 (
uint32_t) ((*from)[0] & 0xff) << 24;
334 assert(NULL != from);
396 assert(NULL != from);
399 ret.i = (uint64_t) ((*from)[0] & 0xff) |
400 (uint64_t) ((*from)[1] & 0xff) << 8 |
401 (uint64_t) ((*from)[2] & 0xff) << 16 |
402 (uint64_t) ((*from)[3] & 0xff) << 24 |
403 (uint64_t) ((*from)[4] & 0xff) << 32 |
404 (uint64_t) ((*from)[5] & 0xff) << 40 |
405 (uint64_t) ((*from)[6] & 0xff) << 48 |
406 (uint64_t) ((*from)[7] & 0xff) << 56;
409 ret.i = (uint64_t) ((*from)[7] & 0xff) |
410 (uint64_t) ((*from)[6] & 0xff) << 8 |
411 (uint64_t) ((*from)[5] & 0xff) << 16 |
412 (uint64_t) ((*from)[4] & 0xff) << 24 |
413 (uint64_t) ((*from)[3] & 0xff) << 32 |
414 (uint64_t) ((*from)[2] & 0xff) << 40 |
415 (uint64_t) ((*from)[1] & 0xff) << 48 |
416 (uint64_t) ((*from)[0] & 0xff) << 56;
468 RASTER_DEBUGF(3,
"Serialized size with just header:%d - now adding size of %d bands",
471 for (i = 0; i <
raster->numBands; ++i) {
477 rterror(
"rt_raster_serialized_size: Corrupted band: unknown pixtype");
492 size += strlen(
band->data.offline.path) + 1;
532 rterror(
"rt_raster_serialize: Out of memory allocating %d bytes for serializing a raster",
size);
535 memset(ret,
'-',
size);
557 RASTER_DEBUG(3,
"Start hex dump of raster being serialized using 0x2D to mark non-written bytes");
559 #if POSTGIS_DEBUG_LEVEL > 2
561 d_print_binary_hex(
"HEADER", dbg_ptr,
size);
567 for (i = 0; i <
raster->numBands; ++i) {
569 assert(NULL !=
band);
574 rterror(
"rt_raster_serialize: Corrupted band: unknown pixtype");
580 *ptr =
band->pixtype;
582 #ifdef POSTGIS_RASTER_DISABLE_OFFLINE
583 rterror(
"rt_raster_serialize: offdb raster support disabled at compile-time");
588 if (
band->hasnodata) {
592 if (
band->isnodata) {
596 #if POSTGIS_DEBUG_LEVEL > 2
597 d_print_binary_hex(
"PIXTYPE", dbg_ptr,
size);
604 memset(ptr,
'\0', pixbytes - 1);
608 #if POSTGIS_DEBUG_LEVEL > 2
609 d_print_binary_hex(
"PADDING", dbg_ptr,
size);
613 assert(!((ptr - ret) % pixbytes));
627 int8_t v =
band->nodataval;
633 int16_t v =
band->nodataval;
639 uint16_t v =
band->nodataval;
645 int32_t v =
band->nodataval;
657 float v =
band->nodataval;
663 memcpy(ptr, &
band->nodataval, 8);
668 rterror(
"rt_raster_serialize: Fatal error caused by unknown pixel type. Aborting.");
674 assert(!((ptr - ret) % pixbytes));
676 #if POSTGIS_DEBUG_LEVEL > 2
677 d_print_binary_hex(
"nodata", dbg_ptr,
size);
682 *ptr =
band->data.offline.bandNum;
686 strcpy((
char*) ptr,
band->data.offline.path);
687 ptr += strlen(
band->data.offline.path) + 1;
692 memcpy(ptr,
band->data.mem, datasize);
696 #if POSTGIS_DEBUG_LEVEL > 2
697 d_print_binary_hex(
"BAND", dbg_ptr,
size);
701 while ((ptr-ret) % 8) {
707 assert(!((ptr - ret) % pixbytes));
710 #if POSTGIS_DEBUG_LEVEL > 2
711 d_print_binary_hex(
"SERIALIZED RASTER", dbg_ptr,
size);
733 assert(NULL != serialized);
743 RASTER_DEBUG(3,
"rt_raster_deserialize: Allocating memory for deserialized raster header");
746 rterror(
"rt_raster_deserialize: Out of memory allocating raster for deserialization");
751 RASTER_DEBUG(3,
"rt_raster_deserialize: Deserialize raster header");
754 if (0 ==
rast->numBands || header_only) {
759 beg = (
const uint8_t*) serialized;
762 RASTER_DEBUG(3,
"rt_raster_deserialize: Allocating memory for bands");
764 if (
rast->bands == NULL) {
765 rterror(
"rt_raster_deserialize: Out of memory allocating bands");
777 for (i = 0; i <
rast->numBands; ++i) {
784 rterror(
"rt_raster_deserialize: Out of memory allocating rt_band during deserialization");
811 switch (
band->pixtype) {
857 rterror(
"rt_raster_deserialize: Unknown pixeltype %d",
band->pixtype);
868 assert(!((ptr - beg) % pixbytes));
874 band->data.offline.bandNum = *ptr;
878 pathlen = strlen((
char*) ptr);
879 band->data.offline.path =
rtalloc(
sizeof(
char) * (pathlen + 1));
880 if (
band->data.offline.path == NULL) {
881 rterror(
"rt_raster_deserialize: Could not allocate memory for offline band path");
887 memcpy(
band->data.offline.path, ptr, pathlen);
888 band->data.offline.path[pathlen] =
'\0';
891 band->data.offline.mem = NULL;
901 #if POSTGIS_DEBUG_LEVEL > 0
904 while (0 != ((ptr - beg) % 8)) {
908 RASTER_DEBUGF(3,
"rt_raster_deserialize: skip %d bytes of 8-bytes boundary padding", ptr - padbeg);
911 assert(!((ptr - beg) % pixbytes));
void deparse_hex(uint8_t str, char *result)
Convert a char into a human readable hex digit.
void rterror(const char *fmt,...)
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 rtinfo(const char *fmt,...)
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
void rtwarn(const char *fmt,...)
void rt_band_destroy(rt_band band)
Destroy a raster band.
const char * rt_pixtype_name(rt_pixtype pixtype)
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.
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
void swap_char(uint8_t *a, uint8_t *b)
uint8_t isMachineLittleEndian(void)
void flip_endian_32(uint8_t *d)
void flip_endian_16(uint8_t *d)
static uint32_t rt_raster_serialized_size(rt_raster raster)
uint8_t read_uint8(const uint8_t **from)
void write_uint16(uint8_t **to, uint8_t littleEndian, uint16_t v)
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
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)
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
#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