PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ rt_raster_to_wkb()

uint8_t* rt_raster_to_wkb ( rt_raster  raster,
int  outasin,
uint32_t wkbsize 
)

Return this raster in WKB form.

Parameters
raster: the raster
outasin: if TRUE, out-db bands are treated as in-db
wkbsize: will be set to the size of returned wkb form
Returns
WKB of raster or NULL on error

Definition at line 494 of file rt_wkb.c.

References ovdump::band, rt_raster_t::bands, BANDTYPE_FLAG_HASNODATA, BANDTYPE_FLAG_ISNODATA, BANDTYPE_FLAG_OFFDB, rt_band_t::data, rt_band_t::hasnodata, rt_raster_t::height, isMachineLittleEndian(), rt_band_t::isnodata, rt_band_t::nodataval, rt_raster_t::numBands, rt_band_t::offline, rt_band_t::pixtype, PT_16BSI, PT_16BUI, PT_1BB, PT_2BUI, PT_32BF, PT_32BSI, PT_32BUI, PT_4BUI, PT_64BF, PT_8BSI, PT_8BUI, RASTER_DEBUG, RASTER_DEBUGF, rt_band_get_data(), rt_pixtype_size(), rt_raster_wkb_size(), rtalloc(), rtdealloc(), rterror(), rt_raster_t::width, and write_uint16().

Referenced by RASTER_to_binary(), RASTER_to_bytea(), and rt_raster_to_hexwkb().

494  {
495 
496 #if POSTGIS_DEBUG_LEVEL > 0
497  const uint8_t *wkbend = NULL;
498 #endif
499 
500  uint8_t *wkb = NULL;
501  uint8_t *ptr = NULL;
502  uint16_t i = 0;
503  uint8_t littleEndian = isMachineLittleEndian();
504 
505  assert(NULL != raster);
506  assert(NULL != wkbsize);
507 
508  RASTER_DEBUG(2, "rt_raster_to_wkb: about to call rt_raster_wkb_size");
509 
510  *wkbsize = rt_raster_wkb_size(raster, outasin);
511  RASTER_DEBUGF(3, "rt_raster_to_wkb: found size: %d", *wkbsize);
512 
513  wkb = (uint8_t*) rtalloc(*wkbsize);
514  if (!wkb) {
515  rterror("rt_raster_to_wkb: Out of memory allocating WKB for raster");
516  return NULL;
517  }
518 
519  ptr = wkb;
520 
521 #if POSTGIS_DEBUG_LEVEL > 2
522  wkbend = ptr + (*wkbsize);
523 #endif
524  RASTER_DEBUGF(3, "Writing raster header to wkb on position %d (expected 0)",
525  d_binptr_to_pos(ptr, wkbend, *wkbsize));
526 
527  /* Write endianness */
528  *ptr = littleEndian;
529  ptr += 1;
530 
531  /* Write version(size - (end - ptr)) */
532  write_uint16(&ptr, littleEndian, 0);
533 
534  /* Copy header (from numBands up) */
535  memcpy(ptr, &(raster->numBands), sizeof (struct rt_raster_serialized_t) - 6);
536  ptr += sizeof (struct rt_raster_serialized_t) - 6;
537 
538  RASTER_DEBUGF(3, "Writing bands header to wkb position %d (expected 61)",
539  d_binptr_to_pos(ptr, wkbend, *wkbsize));
540 
541  /* Serialize bands now */
542  for (i = 0; i < raster->numBands; ++i) {
543  rt_band band = raster->bands[i];
544  rt_pixtype pixtype = band->pixtype;
545  int pixbytes = rt_pixtype_size(pixtype);
546 
547  RASTER_DEBUGF(3, "Writing WKB for band %d", i);
548  RASTER_DEBUGF(3, "Writing band pixel type to wkb position %d",
549  d_binptr_to_pos(ptr, wkbend, *wkbsize));
550 
551  if (pixbytes < 1) {
552  rterror("rt_raster_to_wkb: Corrupted band: unknown pixtype");
553  rtdealloc(wkb);
554  return NULL;
555  }
556 
557  /* Add band type */
558  *ptr = band->pixtype;
559  if (!outasin && band->offline) *ptr |= BANDTYPE_FLAG_OFFDB;
560  if (band->hasnodata) *ptr |= BANDTYPE_FLAG_HASNODATA;
561  if (band->isnodata) *ptr |= BANDTYPE_FLAG_ISNODATA;
562  ptr += 1;
563 
564 #if 0
565  /* no padding required for WKB */
566  /* Add padding (if needed) */
567  if (pixbytes > 1) {
568  memset(ptr, '\0', pixbytes - 1);
569  ptr += pixbytes - 1;
570  }
571  /* Consistency checking (ptr is pixbytes-aligned) */
572  assert(!(((uint64_t) ptr) % pixbytes));
573 #endif
574 
575  RASTER_DEBUGF(3, "Writing band nodata to wkb position %d",
576  d_binptr_to_pos(ptr, wkbend, *wkbsize));
577 
578  /* Add nodata value */
579  switch (pixtype) {
580  case PT_1BB:
581  case PT_2BUI:
582  case PT_4BUI:
583  case PT_8BUI: {
584  uint8_t v = band->nodataval;
585  *ptr = v;
586  ptr += 1;
587  break;
588  }
589  case PT_8BSI: {
590  int8_t v = band->nodataval;
591  *ptr = v;
592  ptr += 1;
593  break;
594  }
595  case PT_16BSI:
596  case PT_16BUI: {
597  uint16_t v = band->nodataval;
598  memcpy(ptr, &v, 2);
599  ptr += 2;
600  break;
601  }
602  case PT_32BSI:
603  case PT_32BUI: {
604  uint32_t v = band->nodataval;
605  memcpy(ptr, &v, 4);
606  ptr += 4;
607  break;
608  }
609  case PT_32BF: {
610  float v = band->nodataval;
611  memcpy(ptr, &v, 4);
612  ptr += 4;
613  break;
614  }
615  case PT_64BF: {
616  memcpy(ptr, &band->nodataval, 8);
617  ptr += 8;
618  break;
619  }
620  default:
621  rterror("rt_raster_to_wkb: Fatal error caused by unknown pixel type. Aborting.");
622  rtdealloc(wkb);
623  abort(); /* shoudn't happen */
624  return 0;
625  }
626 
627 #if 0
628  /* no padding for WKB */
629  /* Consistency checking (ptr is pixbytes-aligned) */
630  assert(!((uint64_t) ptr % pixbytes));
631 #endif
632 
633  if (!outasin && band->offline) {
634  /* Write band number */
635  *ptr = band->data.offline.bandNum;
636  ptr += 1;
637 
638  /* Write path */
639  strcpy((char*) ptr, band->data.offline.path);
640  ptr += strlen(band->data.offline.path) + 1;
641  }
642  else {
643  /* Write data */
644  uint32_t datasize = raster->width * raster->height * pixbytes;
645  RASTER_DEBUGF(4, "rt_raster_to_wkb: Copying %d bytes", datasize);
646 
647  memcpy(ptr, rt_band_get_data(band), datasize);
648 
649  ptr += datasize;
650  }
651 
652 #if 0
653  /* no padding for WKB */
654  /* Pad up to 8-bytes boundary */
655  while ((uint64_t) ptr % 8) {
656  *ptr = 0;
657  ++ptr;
658  }
659 
660  /* Consistency checking (ptr is pixbytes-aligned) */
661  assert(!((uint64_t) ptr % pixbytes));
662 #endif
663  }
664 
665  return wkb;
666 }
#define BANDTYPE_FLAG_HASNODATA
Definition: rt_serialize.h:38
static uint32_t rt_raster_wkb_size(rt_raster raster, int outasin)
Definition: rt_wkb.c:441
uint16_t numBands
Definition: librtcore.h:2241
rt_pixtype pixtype
Definition: librtcore.h:2265
band
Definition: ovdump.py:57
void rterror(const char *fmt,...)
Wrappers used for reporting errors and info.
Definition: rt_context.c:199
void * rtalloc(size_t size)
Wrappers used for managing memory.
Definition: rt_context.c:171
rt_pixtype
Definition: librtcore.h:185
uint16_t height
Definition: librtcore.h:2253
unsigned int uint32_t
Definition: uthash.h:78
void write_uint16(uint8_t **to, uint8_t littleEndian, uint16_t v)
Definition: rt_serialize.c:247
#define BANDTYPE_FLAG_OFFDB
Definition: rt_serialize.h:37
uint16_t width
Definition: librtcore.h:2252
union rt_band_t::@6 data
double nodataval
Definition: librtcore.h:2272
void * rt_band_get_data(rt_band band)
Get pointer to raster band data.
Definition: rt_band.c:302
#define RASTER_DEBUGF(level, msg,...)
Definition: librtcore.h:299
uint8_t isMachineLittleEndian(void)
Definition: rt_serialize.c:190
int rt_pixtype_size(rt_pixtype pixtype)
Return size in bytes of a value in the given pixtype.
Definition: rt_pixel.c:39
int32_t offline
Definition: librtcore.h:2266
void rtdealloc(void *mem)
Definition: rt_context.c:186
int32_t isnodata
Definition: librtcore.h:2270
#define RASTER_DEBUG(level, msg)
Definition: librtcore.h:295
Struct definitions.
Definition: librtcore.h:2201
rt_band * bands
Definition: librtcore.h:2254
int32_t hasnodata
Definition: librtcore.h:2269
unsigned char uint8_t
Definition: uthash.h:79
#define BANDTYPE_FLAG_ISNODATA
Definition: rt_serialize.h:39
Here is the call graph for this function:
Here is the caller graph for this function: