PostGIS  2.4.9dev-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_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_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  case PT_16BUI: {
634  uint16_t v = band->nodataval;
635  memcpy(ptr, &v, 2);
636  ptr += 2;
637  break;
638  }
639  case PT_32BSI:
640  case PT_32BUI: {
641  uint32_t v = band->nodataval;
642  memcpy(ptr, &v, 4);
643  ptr += 4;
644  break;
645  }
646  case PT_32BF: {
647  float v = band->nodataval;
648  memcpy(ptr, &v, 4);
649  ptr += 4;
650  break;
651  }
652  case PT_64BF: {
653  memcpy(ptr, &band->nodataval, 8);
654  ptr += 8;
655  break;
656  }
657  default:
658  rterror("rt_raster_serialize: Fatal error caused by unknown pixel type. Aborting.");
659  rtdealloc(ret);
660  return NULL;
661  }
662 
663  /* Consistency checking (ptr is pixbytes-aligned) */
664  assert(!((ptr - ret) % pixbytes));
665 
666 #if POSTGIS_DEBUG_LEVEL > 2
667  d_print_binary_hex("nodata", dbg_ptr, size);
668 #endif
669 
670  if (band->offline) {
671  /* Write band number */
672  *ptr = band->data.offline.bandNum;
673  ptr += 1;
674 
675  /* Write path */
676  strcpy((char*) ptr, band->data.offline.path);
677  ptr += strlen(band->data.offline.path) + 1;
678  }
679  else {
680  /* Write data */
681  uint32_t datasize = raster->width * raster->height * pixbytes;
682  memcpy(ptr, band->data.mem, datasize);
683  ptr += datasize;
684  }
685 
686 #if POSTGIS_DEBUG_LEVEL > 2
687  d_print_binary_hex("BAND", dbg_ptr, size);
688 #endif
689 
690  /* Pad up to 8-bytes boundary */
691  while ((uintptr_t) ptr % 8) {
692  *ptr = 0;
693  ++ptr;
694 
695  RASTER_DEBUGF(3, "PAD at %d", (uintptr_t) ptr % 8);
696  }
697 
698  /* Consistency checking (ptr is pixbytes-aligned) */
699  assert(!((ptr - ret) % pixbytes));
700  } /* for-loop over bands */
701 
702 #if POSTGIS_DEBUG_LEVEL > 2
703  d_print_binary_hex("SERIALIZED RASTER", dbg_ptr, size);
704 #endif
705  return ret;
706 }
#define BANDTYPE_FLAG_HASNODATA
Definition: rt_serialize.h:38
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
uint32_t size
Definition: librtcore.h:2236
uint16_t height
Definition: librtcore.h:2253
unsigned int uint32_t
Definition: uthash.h:78
uint16_t version
Definition: librtcore.h:2237
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:2252
union rt_band_t::@6 data
double nodataval
Definition: librtcore.h:2272
#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: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
void * mem
Definition: librtcore.h:2278
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: