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

References ovdump::band, BANDTYPE_HAS_NODATA, BANDTYPE_IS_NODATA, BANDTYPE_IS_OFFDB, BANDTYPE_PIXTYPE_MASK, isMachineLittleEndian(), 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: