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

8158  {
8159  uint32_t size = 0;
8160  uint8_t* ret = NULL;
8161  uint8_t* ptr = NULL;
8162  uint16_t i = 0;
8163 
8164  assert(NULL != raster);
8165 
8166  size = rt_raster_serialized_size(raster);
8167  ret = (uint8_t*) rtalloc(size);
8168  if (!ret) {
8169  rterror("rt_raster_serialize: Out of memory allocating %d bytes for serializing a raster", size);
8170  return NULL;
8171  }
8172  memset(ret, '-', size);
8173  ptr = ret;
8174 
8175  RASTER_DEBUGF(3, "sizeof(struct rt_raster_serialized_t):%u",
8176  sizeof (struct rt_raster_serialized_t));
8177  RASTER_DEBUGF(3, "sizeof(struct rt_raster_t):%u",
8178  sizeof (struct rt_raster_t));
8179  RASTER_DEBUGF(3, "serialized size:%lu", (long unsigned) size);
8180 
8181  /* Set size */
8182  /* NOTE: Value of rt_raster.size may be updated in
8183  * returned object, for instance, by rt_pg layer to
8184  * store value calculated by SET_VARSIZE.
8185  */
8186  raster->size = size;
8187 
8188  /* Set version */
8189  raster->version = 0;
8190 
8191  /* Copy header */
8192  memcpy(ptr, raster, sizeof (struct rt_raster_serialized_t));
8193 
8194  RASTER_DEBUG(3, "Start hex dump of raster being serialized using 0x2D to mark non-written bytes");
8195 
8196 #if POSTGIS_DEBUG_LEVEL > 2
8197  uint8_t* dbg_ptr = ptr;
8198  d_print_binary_hex("HEADER", dbg_ptr, size);
8199 #endif
8200 
8201  ptr += sizeof (struct rt_raster_serialized_t);
8202 
8203  /* Serialize bands now */
8204  for (i = 0; i < raster->numBands; ++i) {
8205  rt_band band = raster->bands[i];
8206  assert(NULL != band);
8207 
8208  rt_pixtype pixtype = band->pixtype;
8209  int pixbytes = rt_pixtype_size(pixtype);
8210  if (pixbytes < 1) {
8211  rterror("rt_raster_serialize: Corrupted band: unknown pixtype");
8212  rtdealloc(ret);
8213  return NULL;
8214  }
8215 
8216  /* Add band type */
8217  *ptr = band->pixtype;
8218  if (band->offline) {
8219  *ptr |= BANDTYPE_FLAG_OFFDB;
8220  }
8221  if (band->hasnodata) {
8222  *ptr |= BANDTYPE_FLAG_HASNODATA;
8223  }
8224 
8225  if (band->isnodata) {
8226  *ptr |= BANDTYPE_FLAG_ISNODATA;
8227  }
8228 
8229 #if POSTGIS_DEBUG_LEVEL > 2
8230  d_print_binary_hex("PIXTYPE", dbg_ptr, size);
8231 #endif
8232 
8233  ptr += 1;
8234 
8235  /* Add padding (if needed) */
8236  if (pixbytes > 1) {
8237  memset(ptr, '\0', pixbytes - 1);
8238  ptr += pixbytes - 1;
8239  }
8240 
8241 #if POSTGIS_DEBUG_LEVEL > 2
8242  d_print_binary_hex("PADDING", dbg_ptr, size);
8243 #endif
8244 
8245  /* Consistency checking (ptr is pixbytes-aligned) */
8246  assert(!((ptr - ret) % pixbytes));
8247 
8248  /* Add nodata value */
8249  switch (pixtype) {
8250  case PT_1BB:
8251  case PT_2BUI:
8252  case PT_4BUI:
8253  case PT_8BUI: {
8254  uint8_t v = band->nodataval;
8255  *ptr = v;
8256  ptr += 1;
8257  break;
8258  }
8259  case PT_8BSI: {
8260  int8_t v = band->nodataval;
8261  *ptr = v;
8262  ptr += 1;
8263  break;
8264  }
8265  case PT_16BSI:
8266  case PT_16BUI: {
8267  uint16_t v = band->nodataval;
8268  memcpy(ptr, &v, 2);
8269  ptr += 2;
8270  break;
8271  }
8272  case PT_32BSI:
8273  case PT_32BUI: {
8274  uint32_t v = band->nodataval;
8275  memcpy(ptr, &v, 4);
8276  ptr += 4;
8277  break;
8278  }
8279  case PT_32BF: {
8280  float v = band->nodataval;
8281  memcpy(ptr, &v, 4);
8282  ptr += 4;
8283  break;
8284  }
8285  case PT_64BF: {
8286  memcpy(ptr, &band->nodataval, 8);
8287  ptr += 8;
8288  break;
8289  }
8290  default:
8291  rterror("rt_raster_serialize: Fatal error caused by unknown pixel type. Aborting.");
8292  rtdealloc(ret);
8293  return NULL;
8294  }
8295 
8296  /* Consistency checking (ptr is pixbytes-aligned) */
8297  assert(!((ptr - ret) % pixbytes));
8298 
8299 #if POSTGIS_DEBUG_LEVEL > 2
8300  d_print_binary_hex("nodata", dbg_ptr, size);
8301 #endif
8302 
8303  if (band->offline) {
8304  /* Write band number */
8305  *ptr = band->data.offline.bandNum;
8306  ptr += 1;
8307 
8308  /* Write path */
8309  strcpy((char*) ptr, band->data.offline.path);
8310  ptr += strlen(band->data.offline.path) + 1;
8311  }
8312  else {
8313  /* Write data */
8314  uint32_t datasize = raster->width * raster->height * pixbytes;
8315  memcpy(ptr, band->data.mem, datasize);
8316  ptr += datasize;
8317  }
8318 
8319 #if POSTGIS_DEBUG_LEVEL > 2
8320  d_print_binary_hex("BAND", dbg_ptr, size);
8321 #endif
8322 
8323  /* Pad up to 8-bytes boundary */
8324  while ((uintptr_t) ptr % 8) {
8325  *ptr = 0;
8326  ++ptr;
8327 
8328  RASTER_DEBUGF(3, "PAD at %d", (uintptr_t) ptr % 8);
8329  }
8330 
8331  /* Consistency checking (ptr is pixbytes-aligned) */
8332  assert(!((ptr - ret) % pixbytes));
8333  } /* for-loop over bands */
8334 
8335 #if POSTGIS_DEBUG_LEVEL > 2
8336  d_print_binary_hex("SERIALIZED RASTER", dbg_ptr, size);
8337 #endif
8338  return ret;
8339 }
void rtdealloc(void *mem)
Definition: rt_api.c:882
uint16_t numBands
Definition: rt_api.h:2215
rt_pixtype pixtype
Definition: rt_api.h:2239
tuple band
Definition: ovdump.py:57
Definition: rt_api.h:173
uint32_t size
Definition: rt_api.h:2210
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
rt_pixtype
Definition: rt_api.h:172
uint16_t version
Definition: rt_api.h:2211
#define RASTER_DEBUGF(level, msg,...)
Definition: rt_api.h:285
uint16_t width
Definition: rt_api.h:2226
double nodataval
Definition: rt_api.h:2246
union rt_band_t::@14 data
#define BANDTYPE_FLAG_ISNODATA
Definition: rt_api.c:7419
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
static uint32_t rt_raster_serialized_size(rt_raster raster)
Definition: rt_api.c:8099
#define BANDTYPE_FLAG_HASNODATA
Definition: rt_api.c:7418
Struct definitions.
Definition: rt_api.h:2175
rt_band * bands
Definition: rt_api.h:2228
void * mem
Definition: rt_api.h:2252
int32_t hasnodata
Definition: rt_api.h:2243
#define BANDTYPE_FLAG_OFFDB
Definition: rt_api.c:7417

Here is the call graph for this function:

Here is the caller graph for this function: