PostGIS  3.0.6dev-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 725 of file rt_serialize.c.

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

References ovdump::band, BANDTYPE_HAS_NODATA, BANDTYPE_IS_NODATA, BANDTYPE_IS_OFFDB, BANDTYPE_PIXTYPE_MASK, LW_FALSE, LW_TRUE, PT_16BSI, PT_16BUI, PT_1BB, PT_2BUI, PT_32BF, PT_32BSI, PT_32BUI, PT_4BUI, PT_64BF, PT_8BSI, PT_8BUI, rtpixdump::rast, 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(), and ovdump::type.

Referenced by RASTER_addBand(), RASTER_addBandOutDB(), RASTER_addBandRasterArray(), RASTER_asGDALRaster(), RASTER_asHexWKB(), RASTER_asWKB(), 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_getBandFileSize(), RASTER_getBandFileTimestamp(), 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_setBandPath(), 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_bytea(), RASTER_touches(), RASTER_union_transfn(), RASTER_valueCount(), RASTER_valueCountCoverage(), RASTER_worldToRasterCoord(), rtpg_nmapalgebra_rastbandarg_process(), and test_raster_wkb().

Here is the call graph for this function: