PostGIS  3.0.0dev-r@@SVN_REVISION@@

◆ rt_raster_serialize()

void* rt_raster_serialize ( rt_raster  raster)

Return this raster in serialized form.

Memory (band data included) is copied from rt_raster.

Serialized form is documented in doc/RFC1-SerializedFormat.

Definition at line 521 of file rt_serialize.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, rt_band_t::isnodata, rt_band_t::mem, 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_pixtype_size(), rt_raster_serialized_size(), rtalloc(), rtdealloc(), rterror(), rt_raster_serialized_t::size, rt_raster_t::size, rt_raster_t::version, and rt_raster_t::width.

Referenced by RASTER_addBand(), RASTER_addBandOutDB(), RASTER_addBandRasterArray(), RASTER_asRaster(), RASTER_band(), RASTER_clip(), RASTER_colorMap(), RASTER_copyBand(), RASTER_fromGDALRaster(), RASTER_fromHexWKB(), RASTER_fromWKB(), RASTER_GDALWarp(), RASTER_in(), RASTER_makeEmpty(), RASTER_mapAlgebra2(), RASTER_mapAlgebraExpr(), RASTER_mapAlgebraFct(), RASTER_mapAlgebraFctNgb(), RASTER_nMapAlgebra(), RASTER_nMapAlgebraExpr(), RASTER_noop(), RASTER_reclass(), RASTER_setBandIsNoData(), RASTER_setBandNoDataValue(), RASTER_setBandPath(), RASTER_setGeotransform(), RASTER_setPixelValue(), RASTER_setPixelValuesArray(), RASTER_setPixelValuesGeomval(), RASTER_setRotation(), RASTER_setScale(), RASTER_setScaleXY(), RASTER_setSkew(), RASTER_setSkewXY(), RASTER_setSRID(), RASTER_setUpperLeftXY(), RASTER_tile(), RASTER_union_finalfn(), and test_raster_wkb().

521  {
522  uint32_t size = 0;
523  uint8_t* ret = NULL;
524  uint8_t* ptr = NULL;
525  uint16_t i = 0;
526 
527  assert(NULL != raster);
528 
529  size = rt_raster_serialized_size(raster);
530  ret = (uint8_t*) rtalloc(size);
531  if (!ret) {
532  rterror("rt_raster_serialize: Out of memory allocating %d bytes for serializing a raster", size);
533  return NULL;
534  }
535  memset(ret, '-', size);
536  ptr = ret;
537 
538  RASTER_DEBUGF(3, "sizeof(struct rt_raster_serialized_t):%u",
539  sizeof (struct rt_raster_serialized_t));
540  RASTER_DEBUGF(3, "sizeof(struct rt_raster_t):%u",
541  sizeof (struct rt_raster_t));
542  RASTER_DEBUGF(3, "serialized size:%lu", (long unsigned) size);
543 
544  /* Set size */
545  /* NOTE: Value of rt_raster.size may be updated in
546  * returned object, for instance, by rt_pg layer to
547  * store value calculated by SET_VARSIZE.
548  */
549  raster->size = size;
550 
551  /* Set version */
552  raster->version = 0;
553 
554  /* Copy header */
555  memcpy(ptr, raster, sizeof (struct rt_raster_serialized_t));
556 
557  RASTER_DEBUG(3, "Start hex dump of raster being serialized using 0x2D to mark non-written bytes");
558 
559 #if POSTGIS_DEBUG_LEVEL > 2
560  uint8_t* dbg_ptr = ptr;
561  d_print_binary_hex("HEADER", dbg_ptr, size);
562 #endif
563 
564  ptr += sizeof (struct rt_raster_serialized_t);
565 
566  /* Serialize bands now */
567  for (i = 0; i < raster->numBands; ++i) {
568  rt_band band = raster->bands[i];
569  assert(NULL != band);
570 
571  rt_pixtype pixtype = band->pixtype;
572  int pixbytes = rt_pixtype_size(pixtype);
573  if (pixbytes < 1) {
574  rterror("rt_raster_serialize: Corrupted band: unknown pixtype");
575  rtdealloc(ret);
576  return NULL;
577  }
578 
579  /* Add band type */
580  *ptr = band->pixtype;
581  if (band->offline) {
582 #ifdef POSTGIS_RASTER_DISABLE_OFFLINE
583  rterror("rt_raster_serialize: offdb raster support disabled at compile-time");
584  return NULL;
585 #endif
586  *ptr |= BANDTYPE_FLAG_OFFDB;
587  }
588  if (band->hasnodata) {
589  *ptr |= BANDTYPE_FLAG_HASNODATA;
590  }
591 
592  if (band->isnodata) {
593  *ptr |= BANDTYPE_FLAG_ISNODATA;
594  }
595 
596 #if POSTGIS_DEBUG_LEVEL > 2
597  d_print_binary_hex("PIXTYPE", dbg_ptr, size);
598 #endif
599 
600  ptr += 1;
601 
602  /* Add padding (if needed) */
603  if (pixbytes > 1) {
604  memset(ptr, '\0', pixbytes - 1);
605  ptr += pixbytes - 1;
606  }
607 
608 #if POSTGIS_DEBUG_LEVEL > 2
609  d_print_binary_hex("PADDING", dbg_ptr, size);
610 #endif
611 
612  /* Consistency checking (ptr is pixbytes-aligned) */
613  assert(!((ptr - ret) % pixbytes));
614 
615  /* Add nodata value */
616  switch (pixtype) {
617  case PT_1BB:
618  case PT_2BUI:
619  case PT_4BUI:
620  case PT_8BUI: {
621  uint8_t v = band->nodataval;
622  *ptr = v;
623  ptr += 1;
624  break;
625  }
626  case PT_8BSI: {
627  int8_t v = band->nodataval;
628  *ptr = v;
629  ptr += 1;
630  break;
631  }
632  case PT_16BSI: {
633  int16_t v = band->nodataval;
634  memcpy(ptr, &v, 2);
635  ptr += 2;
636  break;
637  }
638  case PT_16BUI: {
639  uint16_t v = band->nodataval;
640  memcpy(ptr, &v, 2);
641  ptr += 2;
642  break;
643  }
644  case PT_32BSI: {
645  int32_t v = band->nodataval;
646  memcpy(ptr, &v, 4);
647  ptr += 4;
648  break;
649  }
650  case PT_32BUI: {
651  uint32_t v = band->nodataval;
652  memcpy(ptr, &v, 4);
653  ptr += 4;
654  break;
655  }
656  case PT_32BF: {
657  float v = band->nodataval;
658  memcpy(ptr, &v, 4);
659  ptr += 4;
660  break;
661  }
662  case PT_64BF: {
663  memcpy(ptr, &band->nodataval, 8);
664  ptr += 8;
665  break;
666  }
667  default:
668  rterror("rt_raster_serialize: Fatal error caused by unknown pixel type. Aborting.");
669  rtdealloc(ret);
670  return NULL;
671  }
672 
673  /* Consistency checking (ptr is pixbytes-aligned) */
674  assert(!((ptr - ret) % pixbytes));
675 
676 #if POSTGIS_DEBUG_LEVEL > 2
677  d_print_binary_hex("nodata", dbg_ptr, size);
678 #endif
679 
680  if (band->offline) {
681  /* Write band number */
682  *ptr = band->data.offline.bandNum;
683  ptr += 1;
684 
685  /* Write path */
686  strcpy((char*) ptr, band->data.offline.path);
687  ptr += strlen(band->data.offline.path) + 1;
688  }
689  else {
690  /* Write data */
691  uint32_t datasize = raster->width * raster->height * pixbytes;
692  memcpy(ptr, band->data.mem, datasize);
693  ptr += datasize;
694  }
695 
696 #if POSTGIS_DEBUG_LEVEL > 2
697  d_print_binary_hex("BAND", dbg_ptr, size);
698 #endif
699 
700  /* Pad up to 8-bytes boundary */
701  while ((ptr-ret) % 8) {
702  *ptr = 0;
703  ++ptr;
704  }
705 
706  /* Consistency checking (ptr is pixbytes-aligned) */
707  assert(!((ptr - ret) % pixbytes));
708  } /* for-loop over bands */
709 
710 #if POSTGIS_DEBUG_LEVEL > 2
711  d_print_binary_hex("SERIALIZED RASTER", dbg_ptr, size);
712 #endif
713  return ret;
714 }
#define BANDTYPE_FLAG_HASNODATA
Definition: rt_serialize.h:38
uint16_t numBands
Definition: librtcore.h:2290
rt_pixtype pixtype
Definition: librtcore.h:2314
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
uint32_t size
Definition: librtcore.h:2285
uint16_t height
Definition: librtcore.h:2302
unsigned int uint32_t
Definition: uthash.h:78
uint16_t version
Definition: librtcore.h:2286
static uint32_t rt_raster_serialized_size(rt_raster raster)
Definition: rt_serialize.c:462
#define BANDTYPE_FLAG_OFFDB
Definition: rt_serialize.h:37
uint16_t width
Definition: librtcore.h:2301
double nodataval
Definition: librtcore.h:2321
#define RASTER_DEBUGF(level, msg,...)
Definition: librtcore.h:299
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:2315
void rtdealloc(void *mem)
Definition: rt_context.c:186
int32_t isnodata
Definition: librtcore.h:2319
#define RASTER_DEBUG(level, msg)
Definition: librtcore.h:295
Struct definitions.
Definition: librtcore.h:2250
rt_band * bands
Definition: librtcore.h:2303
void * mem
Definition: librtcore.h:2327
int32_t hasnodata
Definition: librtcore.h:2318
unsigned char uint8_t
Definition: uthash.h:79
#define BANDTYPE_FLAG_ISNODATA
Definition: rt_serialize.h:39
union rt_band_t::@8 data
Here is the call graph for this function:
Here is the caller graph for this function: