PostGIS 3.6.2dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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]);
790 rt_raster_destroy(rast);
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]);
863 rt_raster_destroy(rast);
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]);
887 rt_raster_destroy(rast);
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 %ld 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:94
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:93
void rterror(const char *fmt,...) __attribute__((format(printf
Wrappers used for reporting errors and info.
void * rtalloc(size_t size)
Wrappers used for managing memory.
Definition rt_context.c:191
#define RASTER_DEBUG(level, msg)
Definition librtcore.h:302
#define RASTER_DEBUGF(level, msg,...)
Definition librtcore.h:306
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition rt_raster.c:86
@ PT_32BUI
Definition librtcore.h:196
@ PT_2BUI
Definition librtcore.h:189
@ PT_32BSI
Definition librtcore.h:195
@ PT_4BUI
Definition librtcore.h:190
@ PT_32BF
Definition librtcore.h:197
@ PT_1BB
Definition librtcore.h:188
@ PT_16BUI
Definition librtcore.h:194
@ PT_8BSI
Definition librtcore.h:191
@ PT_16BSI
Definition librtcore.h:193
@ PT_64BF
Definition librtcore.h:198
@ PT_8BUI
Definition librtcore.h:192
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition rt_pixel.c:110
void rt_band_destroy(rt_band band)
Destroy a raster band.
Definition rt_band.c:491
void rtdealloc(void *mem)
Definition rt_context.c:206
struct rt_raster_t * rt_raster
Types definitions.
Definition librtcore.h:146
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)
double read_float64(const uint8_t **from, uint8_t littleEndian)
float read_float32(const uint8_t **from, uint8_t littleEndian)
int8_t read_int8(const uint8_t **from)
int16_t read_int16(const uint8_t **from, uint8_t littleEndian)
int32_t read_int32(const uint8_t **from, uint8_t littleEndian)
uint32_t read_uint32(const uint8_t **from, uint8_t littleEndian)
uint16_t read_uint16(const uint8_t **from, uint8_t littleEndian)
#define BANDTYPE_HAS_NODATA(x)
#define BANDTYPE_IS_OFFDB(x)
#define BANDTYPE_IS_NODATA(x)
#define BANDTYPE_PIXTYPE_MASK
Struct definitions.
Definition librtcore.h:2440

References 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, 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(), and rterror().

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_Contour(), 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_getGeometryValues(), RASTER_getGeotransform(), RASTER_getHeight(), RASTER_getNumBands(), RASTER_getPixelCentroids(), RASTER_getPixelHeight(), RASTER_getPixelPolygons(), RASTER_getPixelValue(), RASTER_getPixelValueResample(), 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_InterpolateRaster(), RASTER_intersectionFractions(), 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_rasterToWorldCoord(), RASTER_reclass(), RASTER_reclass_exact(), 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: