PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ rt_raster_deserialize()

rt_raster rt_raster_deserialize ( void *  serialized,
int  header_only 
)

Return a raster from a serialized form.

Serialized form is documented in doc/RFC1-SerializedFormat.

NOTE: the raster will contain pointer to the serialized form (including band data), which must be kept alive.

Definition at line 717 of file rt_serialize.c.

References ovdump::band, rt_raster_t::bands, BANDTYPE_HAS_NODATA, BANDTYPE_IS_NODATA, BANDTYPE_IS_OFFDB, BANDTYPE_PIXTYPE_MASK, rt_band_t::data, rt_band_t::hasnodata, rt_raster_t::height, rt_band_t::height, isMachineLittleEndian(), rt_band_t::isnodata, rt_band_t::mem, rt_band_t::nodataval, rt_raster_t::numBands, rt_band_t::offline, rt_band_t::ownsdata, 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, rtpixdump::rast, rt_band_t::raster, RASTER_DEBUG, RASTER_DEBUGF, read_float32(), read_float64(), read_int16(), read_int32(), read_int8(), read_uint16(), read_uint32(), read_uint8(), rt_band_destroy(), rt_pixtype_name(), rt_pixtype_size(), rt_raster_destroy(), rtalloc(), rtdealloc(), rterror(), ovdump::type, rt_raster_t::width, and rt_band_t::width.

Referenced by RASTER_addBand(), RASTER_addBandOutDB(), RASTER_addBandRasterArray(), RASTER_asGDALRaster(), RASTER_band(), RASTER_bandIsNoData(), RASTER_bandmetadata(), RASTER_clip(), RASTER_colorMap(), RASTER_contains(), RASTER_containsProperly(), RASTER_convex_hull(), RASTER_copyBand(), RASTER_coveredby(), RASTER_covers(), RASTER_dfullywithin(), RASTER_dumpAsPolygons(), RASTER_dumpValues(), RASTER_dwithin(), RASTER_envelope(), RASTER_GDALWarp(), RASTER_getBandNoDataValue(), RASTER_getBandPath(), RASTER_getBandPixelType(), RASTER_getBandPixelTypeName(), RASTER_getGeotransform(), RASTER_getHeight(), RASTER_getNumBands(), RASTER_getPixelHeight(), RASTER_getPixelPolygons(), RASTER_getPixelValue(), RASTER_getPixelWidth(), RASTER_getPolygon(), RASTER_getSRID(), RASTER_getWidth(), RASTER_getXScale(), RASTER_getXSkew(), RASTER_getXUpperLeft(), RASTER_getYScale(), RASTER_getYSkew(), RASTER_getYUpperLeft(), RASTER_hasNoBand(), RASTER_histogram(), RASTER_histogramCoverage(), RASTER_intersects(), RASTER_isEmpty(), RASTER_mapAlgebra2(), RASTER_mapAlgebraExpr(), RASTER_mapAlgebraFct(), RASTER_mapAlgebraFctNgb(), RASTER_metadata(), RASTER_nearestValue(), RASTER_neighborhood(), RASTER_nMapAlgebra(), RASTER_noop(), RASTER_notSameAlignmentReason(), RASTER_out(), RASTER_overlaps(), RASTER_pixelOfValue(), RASTER_quantile(), RASTER_quantileCoverage(), RASTER_rasterToWorldCoord(), RASTER_reclass(), RASTER_sameAlignment(), 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_summaryStats(), RASTER_summaryStats_transfn(), RASTER_summaryStatsCoverage(), RASTER_tile(), RASTER_to_binary(), RASTER_to_bytea(), RASTER_touches(), RASTER_union_transfn(), RASTER_valueCount(), RASTER_valueCountCoverage(), RASTER_worldToRasterCoord(), rtpg_nmapalgebra_rastbandarg_process(), and test_raster_wkb().

717  {
718  rt_raster rast = NULL;
719  const uint8_t *ptr = NULL;
720  const uint8_t *beg = NULL;
721  uint16_t i = 0;
722  uint16_t j = 0;
723  uint8_t littleEndian = isMachineLittleEndian();
724 
725  assert(NULL != serialized);
726 
727  RASTER_DEBUG(2, "rt_raster_deserialize: Entering...");
728 
729  /* NOTE: Value of rt_raster.size may be different
730  * than actual size of raster data being read.
731  * See note on SET_VARSIZE in rt_raster_serialize function above.
732  */
733 
734  /* Allocate memory for deserialized raster header */
735  RASTER_DEBUG(3, "rt_raster_deserialize: Allocating memory for deserialized raster header");
736  rast = (rt_raster) rtalloc(sizeof (struct rt_raster_t));
737  if (!rast) {
738  rterror("rt_raster_deserialize: Out of memory allocating raster for deserialization");
739  return NULL;
740  }
741 
742  /* Deserialize raster header */
743  RASTER_DEBUG(3, "rt_raster_deserialize: Deserialize raster header");
744  memcpy(rast, serialized, sizeof (struct rt_raster_serialized_t));
745 
746  if (0 == rast->numBands || header_only) {
747  rast->bands = 0;
748  return rast;
749  }
750 
751  beg = (const uint8_t*) serialized;
752 
753  /* Allocate registry of raster bands */
754  RASTER_DEBUG(3, "rt_raster_deserialize: Allocating memory for bands");
755  rast->bands = rtalloc(rast->numBands * sizeof (rt_band));
756  if (rast->bands == NULL) {
757  rterror("rt_raster_deserialize: Out of memory allocating bands");
758  rtdealloc(rast);
759  return NULL;
760  }
761 
762  RASTER_DEBUGF(3, "rt_raster_deserialize: %d bands", rast->numBands);
763 
764  /* Move to the beginning of first band */
765  ptr = beg;
766  ptr += sizeof (struct rt_raster_serialized_t);
767 
768  /* Deserialize bands now */
769  for (i = 0; i < rast->numBands; ++i) {
770  rt_band band = NULL;
771  uint8_t type = 0;
772  int pixbytes = 0;
773 
774  band = rtalloc(sizeof(struct rt_band_t));
775  if (!band) {
776  rterror("rt_raster_deserialize: Out of memory allocating rt_band during deserialization");
777  for (j = 0; j < i; j++) rt_band_destroy(rast->bands[j]);
778  rt_raster_destroy(rast);
779  return NULL;
780  }
781 
782  rast->bands[i] = band;
783 
784  type = *ptr;
785  ptr++;
786  band->pixtype = type & BANDTYPE_PIXTYPE_MASK;
787 
788  RASTER_DEBUGF(3, "rt_raster_deserialize: band %d with pixel type %s", i, rt_pixtype_name(band->pixtype));
789 
790  band->offline = BANDTYPE_IS_OFFDB(type) ? 1 : 0;
791  band->hasnodata = BANDTYPE_HAS_NODATA(type) ? 1 : 0;
792  band->isnodata = band->hasnodata ? (BANDTYPE_IS_NODATA(type) ? 1 : 0) : 0;
793  band->width = rast->width;
794  band->height = rast->height;
795  band->ownsdata = 0; /* we do NOT own this data!!! */
796  band->raster = rast;
797 
798  /* Advance by data padding */
799  pixbytes = rt_pixtype_size(band->pixtype);
800  ptr += pixbytes - 1;
801 
802  /* Read nodata value */
803  switch (band->pixtype) {
804  case PT_1BB: {
805  band->nodataval = ((int) read_uint8(&ptr)) & 0x01;
806  break;
807  }
808  case PT_2BUI: {
809  band->nodataval = ((int) read_uint8(&ptr)) & 0x03;
810  break;
811  }
812  case PT_4BUI: {
813  band->nodataval = ((int) read_uint8(&ptr)) & 0x0F;
814  break;
815  }
816  case PT_8BSI: {
817  band->nodataval = read_int8(&ptr);
818  break;
819  }
820  case PT_8BUI: {
821  band->nodataval = read_uint8(&ptr);
822  break;
823  }
824  case PT_16BSI: {
825  band->nodataval = read_int16(&ptr, littleEndian);
826  break;
827  }
828  case PT_16BUI: {
829  band->nodataval = read_uint16(&ptr, littleEndian);
830  break;
831  }
832  case PT_32BSI: {
833  band->nodataval = read_int32(&ptr, littleEndian);
834  break;
835  }
836  case PT_32BUI: {
837  band->nodataval = read_uint32(&ptr, littleEndian);
838  break;
839  }
840  case PT_32BF: {
841  band->nodataval = read_float32(&ptr, littleEndian);
842  break;
843  }
844  case PT_64BF: {
845  band->nodataval = read_float64(&ptr, littleEndian);
846  break;
847  }
848  default: {
849  rterror("rt_raster_deserialize: Unknown pixeltype %d", band->pixtype);
850  for (j = 0; j <= i; j++) rt_band_destroy(rast->bands[j]);
851  rt_raster_destroy(rast);
852  return NULL;
853  }
854  }
855 
856  RASTER_DEBUGF(3, "rt_raster_deserialize: has nodata flag %d", band->hasnodata);
857  RASTER_DEBUGF(3, "rt_raster_deserialize: nodata value %g", band->nodataval);
858 
859  /* Consistency checking (ptr is pixbytes-aligned) */
860  assert(!((ptr - beg) % pixbytes));
861 
862  if (band->offline) {
863  int pathlen = 0;
864 
865  /* Read band number */
866  band->data.offline.bandNum = *ptr;
867  ptr += 1;
868 
869  /* Register path */
870  pathlen = strlen((char*) ptr);
871  band->data.offline.path = rtalloc(sizeof(char) * (pathlen + 1));
872  if (band->data.offline.path == NULL) {
873  rterror("rt_raster_deserialize: Could not allocate memory for offline band path");
874  for (j = 0; j <= i; j++) rt_band_destroy(rast->bands[j]);
875  rt_raster_destroy(rast);
876  return NULL;
877  }
878 
879  memcpy(band->data.offline.path, ptr, pathlen);
880  band->data.offline.path[pathlen] = '\0';
881  ptr += pathlen + 1;
882 
883  band->data.offline.mem = NULL;
884  }
885  else {
886  /* Register data */
887  const uint32_t datasize = rast->width * rast->height * pixbytes;
888  band->data.mem = (uint8_t*) ptr;
889  ptr += datasize;
890  }
891 
892  /* Skip bytes of padding up to 8-bytes boundary */
893 #if POSTGIS_DEBUG_LEVEL > 0
894  const uint8_t *padbeg = ptr;
895 #endif
896  while (0 != ((ptr - beg) % 8)) {
897  ++ptr;
898  }
899 
900  RASTER_DEBUGF(3, "rt_raster_deserialize: skip %d bytes of 8-bytes boundary padding", ptr - padbeg);
901 
902  /* Consistency checking (ptr is pixbytes-aligned) */
903  assert(!((ptr - beg) % pixbytes));
904  }
905 
906  return rast;
907 }
uint16_t numBands
Definition: librtcore.h:2241
struct rt_raster_t * rt_raster
Types definitions.
Definition: librtcore.h:145
rt_raster raster
Definition: librtcore.h:2275
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
uint16_t height
Definition: librtcore.h:2268
void rt_band_destroy(rt_band band)
Destroy a raster band.
Definition: rt_band.c:242
uint16_t height
Definition: librtcore.h:2253
unsigned int uint32_t
Definition: uthash.h:78
int16_t read_int16(const uint8_t **from, uint8_t littleEndian)
Definition: rt_serialize.c:261
uint32_t read_uint32(const uint8_t **from, uint8_t littleEndian)
Definition: rt_serialize.c:287
uint16_t read_uint16(const uint8_t **from, uint8_t littleEndian)
Definition: rt_serialize.c:229
#define BANDTYPE_IS_OFFDB(x)
Definition: rt_serialize.h:43
uint16_t width
Definition: librtcore.h:2252
union rt_band_t::@6 data
int8_t ownsdata
Definition: librtcore.h:2273
#define BANDTYPE_PIXTYPE_MASK
Definition: rt_serialize.h:36
double nodataval
Definition: librtcore.h:2272
#define RASTER_DEBUGF(level, msg,...)
Definition: librtcore.h:299
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_raster.c:82
uint16_t width
Definition: librtcore.h:2267
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
uint8_t read_uint8(const uint8_t **from)
Definition: rt_serialize.c:197
int32_t offline
Definition: librtcore.h:2266
int8_t read_int8(const uint8_t **from)
Definition: rt_serialize.c:213
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
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition: rt_pixel.c:110
rt_band * bands
Definition: librtcore.h:2254
void * mem
Definition: librtcore.h:2278
int32_t hasnodata
Definition: librtcore.h:2269
type
Definition: ovdump.py:41
int32_t read_int32(const uint8_t **from, uint8_t littleEndian)
Definition: rt_serialize.c:333
double read_float64(const uint8_t **from, uint8_t littleEndian)
Definition: rt_serialize.c:389
#define BANDTYPE_HAS_NODATA(x)
Definition: rt_serialize.h:44
float read_float32(const uint8_t **from, uint8_t littleEndian)
Definition: rt_serialize.c:363
unsigned char uint8_t
Definition: uthash.h:79
#define BANDTYPE_IS_NODATA(x)
Definition: rt_serialize.h:45
Here is the call graph for this function: