PostGIS  2.1.10dev-r@@SVN_REVISION@@
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 8350 of file rt_api.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(), 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_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_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_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().

8350  {
8351  rt_raster rast = NULL;
8352  const uint8_t *ptr = NULL;
8353  const uint8_t *beg = NULL;
8354  uint16_t i = 0;
8355  uint16_t j = 0;
8356  uint8_t littleEndian = isMachineLittleEndian();
8357 
8358  assert(NULL != serialized);
8359 
8360  RASTER_DEBUG(2, "rt_raster_deserialize: Entering...");
8361 
8362  /* NOTE: Value of rt_raster.size may be different
8363  * than actual size of raster data being read.
8364  * See note on SET_VARSIZE in rt_raster_serialize function above.
8365  */
8366 
8367  /* Allocate memory for deserialized raster header */
8368  RASTER_DEBUG(3, "rt_raster_deserialize: Allocating memory for deserialized raster header");
8369  rast = (rt_raster) rtalloc(sizeof (struct rt_raster_t));
8370  if (!rast) {
8371  rterror("rt_raster_deserialize: Out of memory allocating raster for deserialization");
8372  return NULL;
8373  }
8374 
8375  /* Deserialize raster header */
8376  RASTER_DEBUG(3, "rt_raster_deserialize: Deserialize raster header");
8377  memcpy(rast, serialized, sizeof (struct rt_raster_serialized_t));
8378 
8379  if (0 == rast->numBands || header_only) {
8380  rast->bands = 0;
8381  return rast;
8382  }
8383 
8384  beg = (const uint8_t*) serialized;
8385 
8386  /* Allocate registry of raster bands */
8387  RASTER_DEBUG(3, "rt_raster_deserialize: Allocating memory for bands");
8388  rast->bands = rtalloc(rast->numBands * sizeof (rt_band));
8389  if (rast->bands == NULL) {
8390  rterror("rt_raster_deserialize: Out of memory allocating bands");
8391  rtdealloc(rast);
8392  return NULL;
8393  }
8394 
8395  RASTER_DEBUGF(3, "rt_raster_deserialize: %d bands", rast->numBands);
8396 
8397  /* Move to the beginning of first band */
8398  ptr = beg;
8399  ptr += sizeof (struct rt_raster_serialized_t);
8400 
8401  /* Deserialize bands now */
8402  for (i = 0; i < rast->numBands; ++i) {
8403  rt_band band = NULL;
8404  uint8_t type = 0;
8405  int pixbytes = 0;
8406 
8407  band = rtalloc(sizeof(struct rt_band_t));
8408  if (!band) {
8409  rterror("rt_raster_deserialize: Out of memory allocating rt_band during deserialization");
8410  for (j = 0; j < i; j++) rt_band_destroy(rast->bands[j]);
8411  rt_raster_destroy(rast);
8412  return NULL;
8413  }
8414 
8415  rast->bands[i] = band;
8416 
8417  type = *ptr;
8418  ptr++;
8419  band->pixtype = type & BANDTYPE_PIXTYPE_MASK;
8420 
8421  RASTER_DEBUGF(3, "rt_raster_deserialize: band %d with pixel type %s", i, rt_pixtype_name(band->pixtype));
8422 
8423  band->offline = BANDTYPE_IS_OFFDB(type) ? 1 : 0;
8424  band->hasnodata = BANDTYPE_HAS_NODATA(type) ? 1 : 0;
8425  band->isnodata = band->hasnodata ? (BANDTYPE_IS_NODATA(type) ? 1 : 0) : 0;
8426  band->width = rast->width;
8427  band->height = rast->height;
8428  band->ownsdata = 0; /* we do NOT own this data!!! */
8429  band->raster = rast;
8430 
8431  /* Advance by data padding */
8432  pixbytes = rt_pixtype_size(band->pixtype);
8433  ptr += pixbytes - 1;
8434 
8435  /* Read nodata value */
8436  switch (band->pixtype) {
8437  case PT_1BB: {
8438  band->nodataval = ((int) read_uint8(&ptr)) & 0x01;
8439  break;
8440  }
8441  case PT_2BUI: {
8442  band->nodataval = ((int) read_uint8(&ptr)) & 0x03;
8443  break;
8444  }
8445  case PT_4BUI: {
8446  band->nodataval = ((int) read_uint8(&ptr)) & 0x0F;
8447  break;
8448  }
8449  case PT_8BSI: {
8450  band->nodataval = read_int8(&ptr);
8451  break;
8452  }
8453  case PT_8BUI: {
8454  band->nodataval = read_uint8(&ptr);
8455  break;
8456  }
8457  case PT_16BSI: {
8458  band->nodataval = read_int16(&ptr, littleEndian);
8459  break;
8460  }
8461  case PT_16BUI: {
8462  band->nodataval = read_uint16(&ptr, littleEndian);
8463  break;
8464  }
8465  case PT_32BSI: {
8466  band->nodataval = read_int32(&ptr, littleEndian);
8467  break;
8468  }
8469  case PT_32BUI: {
8470  band->nodataval = read_uint32(&ptr, littleEndian);
8471  break;
8472  }
8473  case PT_32BF: {
8474  band->nodataval = read_float32(&ptr, littleEndian);
8475  break;
8476  }
8477  case PT_64BF: {
8478  band->nodataval = read_float64(&ptr, littleEndian);
8479  break;
8480  }
8481  default: {
8482  rterror("rt_raster_deserialize: Unknown pixeltype %d", band->pixtype);
8483  for (j = 0; j <= i; j++) rt_band_destroy(rast->bands[j]);
8484  rt_raster_destroy(rast);
8485  return NULL;
8486  }
8487  }
8488 
8489  RASTER_DEBUGF(3, "rt_raster_deserialize: has nodata flag %d", band->hasnodata);
8490  RASTER_DEBUGF(3, "rt_raster_deserialize: nodata value %g", band->nodataval);
8491 
8492  /* Consistency checking (ptr is pixbytes-aligned) */
8493  assert(!((ptr - beg) % pixbytes));
8494 
8495  if (band->offline) {
8496  int pathlen = 0;
8497 
8498  /* Read band number */
8499  band->data.offline.bandNum = *ptr;
8500  ptr += 1;
8501 
8502  /* Register path */
8503  pathlen = strlen((char*) ptr);
8504  band->data.offline.path = rtalloc(sizeof(char) * (pathlen + 1));
8505  if (band->data.offline.path == NULL) {
8506  rterror("rt_raster_deserialize: Could not allocate momory for offline band path");
8507  for (j = 0; j <= i; j++) rt_band_destroy(rast->bands[j]);
8508  rt_raster_destroy(rast);
8509  return NULL;
8510  }
8511 
8512  memcpy(band->data.offline.path, ptr, pathlen);
8513  band->data.offline.path[pathlen] = '\0';
8514  ptr += pathlen + 1;
8515 
8516  band->data.offline.mem = NULL;
8517  }
8518  else {
8519  /* Register data */
8520  const uint32_t datasize = rast->width * rast->height * pixbytes;
8521  band->data.mem = (uint8_t*) ptr;
8522  ptr += datasize;
8523  }
8524 
8525  /* Skip bytes of padding up to 8-bytes boundary */
8526 #if POSTGIS_DEBUG_LEVEL > 0
8527  const uint8_t *padbeg = ptr;
8528 #endif
8529  while (0 != ((ptr - beg) % 8)) {
8530  ++ptr;
8531  }
8532 
8533  RASTER_DEBUGF(3, "rt_raster_deserialize: skip %d bytes of 8-bytes boundary padding", ptr - padbeg);
8534 
8535  /* Consistency checking (ptr is pixbytes-aligned) */
8536  assert(!((ptr - beg) % pixbytes));
8537  }
8538 
8539  return rast;
8540 }
void rtdealloc(void *mem)
Definition: rt_api.c:882
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_api.c:5387
struct rt_raster_t * rt_raster
Types definitions.
Definition: rt_api.h:133
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition: rt_api.c:1168
uint16_t numBands
Definition: rt_api.h:2215
rt_raster raster
Definition: rt_api.h:2249
rt_pixtype pixtype
Definition: rt_api.h:2239
#define BANDTYPE_PIXTYPE_MASK
Definition: rt_api.c:7416
static double read_float64(const uint8_t **from, uint8_t littleEndian)
Definition: rt_api.c:7342
tuple band
Definition: ovdump.py:57
tuple rast
Definition: rtpixdump.py:62
static int32_t read_int32(const uint8_t **from, uint8_t littleEndian)
Definition: rt_api.c:7284
uint16_t height
Definition: rt_api.h:2242
static int8_t read_int8(const uint8_t **from)
Definition: rt_api.c:7161
Definition: rt_api.h:173
uint16_t height
Definition: rt_api.h:2227
int rt_pixtype_size(rt_pixtype pixtype)
Return size in bytes of a value in the given pixtype.
Definition: rt_api.c:1097
#define RASTER_DEBUG(level, msg)
Definition: rt_api.h:281
static int16_t read_int16(const uint8_t **from, uint8_t littleEndian)
Definition: rt_api.c:7210
static uint32_t read_uint32(const uint8_t **from, uint8_t littleEndian)
Definition: rt_api.c:7237
#define RASTER_DEBUGF(level, msg,...)
Definition: rt_api.h:285
uint16_t width
Definition: rt_api.h:2226
int8_t ownsdata
Definition: rt_api.h:2247
#define BANDTYPE_HAS_NODATA(x)
Definition: rt_api.c:7424
double nodataval
Definition: rt_api.h:2246
uint16_t width
Definition: rt_api.h:2241
void rt_band_destroy(rt_band band)
Destroy a raster band.
Definition: rt_api.c:1650
#define BANDTYPE_IS_NODATA(x)
Definition: rt_api.c:7425
union rt_band_t::@14 data
void * rtalloc(size_t size)
Raster core memory management functions.
Definition: rt_api.c:867
void rterror(const char *fmt,...)
Raster core error and info handlers.
Definition: rt_api.c:895
int32_t offline
Definition: rt_api.h:2240
int32_t isnodata
Definition: rt_api.h:2244
Struct definitions.
Definition: rt_api.h:2175
rt_band * bands
Definition: rt_api.h:2228
void * mem
Definition: rt_api.h:2252
#define BANDTYPE_IS_OFFDB(x)
Definition: rt_api.c:7423
static uint8_t read_uint8(const uint8_t **from)
Definition: rt_api.c:7144
int32_t hasnodata
Definition: rt_api.h:2243
static float read_float32(const uint8_t **from, uint8_t littleEndian)
Definition: rt_api.c:7315
static uint8_t isMachineLittleEndian(void)
Definition: rt_api.c:7137
static uint16_t read_uint16(const uint8_t **from, uint8_t littleEndian)
Definition: rt_api.c:7178

Here is the call graph for this function: