PostGIS 3.7.0dev-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 732 of file rt_serialize.c.

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

References BANDTYPE_HAS_NODATA, BANDTYPE_IS_NODATA, BANDTYPE_IS_OFFDB, BANDTYPE_PIXTYPE_MASK, LW_FALSE, LW_TRUE, PT_16BF, 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(), rt_util_float16_to_float(), 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: