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

◆ rt_band_from_wkb()

static rt_band rt_band_from_wkb ( uint16_t  width,
uint16_t  height,
const uint8_t **  ptr,
const uint8_t *  end,
uint8_t  littleEndian 
)
static

Definition at line 39 of file rt_wkb.c.

43 {
44 rt_band band = NULL;
45 int pixbytes = 0;
46 uint8_t type = 0;
47 size_t sz = 0;
48 size_t v = 0;
49
50 assert(NULL != ptr);
51 assert(NULL != end);
52
53 band = rtalloc(sizeof (struct rt_band_t));
54 if (!band) {
55 rterror("rt_band_from_wkb: Out of memory allocating rt_band during WKB parsing");
56 return NULL;
57 }
58 band->ownsdata = 0; /* assume we don't own data */
59
60 if (end - *ptr < 1) {
61 rterror("rt_band_from_wkb: Premature end of WKB on band reading (%s:%d)",
62 __FILE__, __LINE__);
63 rt_band_destroy(band);
64 return NULL;
65 }
66 type = read_uint8(ptr);
67
68 if ((type & BANDTYPE_PIXTYPE_MASK) >= PT_END) {
69 rterror("rt_band_from_wkb: Invalid pixtype %d", type & BANDTYPE_PIXTYPE_MASK);
70 rt_band_destroy(band);
71 return NULL;
72 }
73
74 band->pixtype = type & BANDTYPE_PIXTYPE_MASK;
75 band->offline = BANDTYPE_IS_OFFDB(type) ? 1 : 0;
76 band->hasnodata = BANDTYPE_HAS_NODATA(type) ? 1 : 0;
77 band->isnodata = band->hasnodata ? (BANDTYPE_IS_NODATA(type) ? 1 : 0) : 0;
78 band->width = width;
79 band->height = height;
80
81 RASTER_DEBUGF(3, " Band pixtype:%s, offline:%d, hasnodata:%d",
82 rt_pixtype_name(band->pixtype),
83 band->offline,
84 band->hasnodata
85 );
86
87 /* Check there's enough bytes to read nodata value */
88 pixbytes = rt_pixtype_size(band->pixtype);
89 if (((*ptr) + pixbytes) >= end) {
90 rterror("rt_band_from_wkb: Premature end of WKB on band novalue reading");
91 rt_band_destroy(band);
92 return NULL;
93 }
94
95 /* Read nodata value */
96 switch (band->pixtype) {
97 case PT_1BB: {
98 band->nodataval = ((int) read_uint8(ptr)) & 0x01;
99 break;
100 }
101 case PT_2BUI: {
102 band->nodataval = ((int) read_uint8(ptr)) & 0x03;
103 break;
104 }
105 case PT_4BUI: {
106 band->nodataval = ((int) read_uint8(ptr)) & 0x0F;
107 break;
108 }
109 case PT_8BSI: {
110 band->nodataval = read_int8(ptr);
111 break;
112 }
113 case PT_8BUI: {
114 band->nodataval = read_uint8(ptr);
115 break;
116 }
117 case PT_16BSI: {
118 band->nodataval = read_int16(ptr, littleEndian);
119 break;
120 }
121 case PT_16BUI: {
122 band->nodataval = read_uint16(ptr, littleEndian);
123 break;
124 }
125 case PT_32BSI: {
126 band->nodataval = read_int32(ptr, littleEndian);
127 break;
128 }
129 case PT_32BUI: {
130 band->nodataval = read_uint32(ptr, littleEndian);
131 break;
132 }
133 case PT_16BF: {
134 band->nodataval = rt_util_float16_to_float(read_uint16(ptr, littleEndian));
135 break;
136 }
137 case PT_32BF: {
138 band->nodataval = read_float32(ptr, littleEndian);
139 break;
140 }
141 case PT_64BF: {
142 band->nodataval = read_float64(ptr, littleEndian);
143 break;
144 }
145 default: {
146 rterror("rt_band_from_wkb: Unknown pixeltype %d", band->pixtype);
147 rt_band_destroy(band);
148 return NULL;
149 }
150 }
151
152 RASTER_DEBUGF(3, " Nodata value: %g, pixbytes: %d, ptr @ %p, end @ %p",
153 band->nodataval, pixbytes, *ptr, end);
154
155 if (band->offline) {
156 if (((*ptr) + 1) >= end) {
157 rterror("rt_band_from_wkb: Premature end of WKB on offline "
158 "band data bandNum reading (%s:%d)",
159 __FILE__, __LINE__
160 );
161 rt_band_destroy(band);
162 return NULL;
163 }
164
165 band->data.offline.bandNum = read_int8(ptr);
166 band->data.offline.mem = NULL;
167
168 {
169 /* check we have a NULL-termination */
170 sz = 0;
171 while ((*ptr)[sz] && &((*ptr)[sz]) < end) ++sz;
172 if (&((*ptr)[sz]) >= end) {
173 rterror("rt_band_from_wkb: Premature end of WKB on band offline path reading");
174 rt_band_destroy(band);
175 return NULL;
176 }
177
178 /* we never own offline band data */
179 band->ownsdata = 0;
180
181 band->data.offline.path = rtalloc(sz + 1);
182 if (band->data.offline.path == NULL) {
183 rterror("rt_band_from_wkb: Out of memory allocating for offline path of band");
184 rt_band_destroy(band);
185 return NULL;
186 }
187
188 memcpy(band->data.offline.path, *ptr, sz);
189 band->data.offline.path[sz] = '\0';
190
191 RASTER_DEBUGF(3, "OFFDB band path is %s (size is %zu)",
192 band->data.offline.path, sz);
193
194 *ptr += sz + 1;
195
196 /* TODO: How could we know if the offline band is a nodata band? */
197 /* trust in the force */
198 /*band->isnodata = FALSE;*/
199 }
200
201 return band;
202 }
203
204 /* This is an on-disk band */
205 sz = (size_t)width * height * pixbytes;
206 if (((*ptr) + sz) > end) {
207 rterror("rt_band_from_wkb: Premature end of WKB on band data reading (%s:%d)",
208 __FILE__, __LINE__);
209 rt_band_destroy(band);
210 return NULL;
211 }
212
213 band->data.mem = rtalloc(sz);
214 if (!band->data.mem) {
215 rterror("rt_band_from_wkb: Out of memory during band creation in WKB parser");
216 rt_band_destroy(band);
217 return NULL;
218 }
219
220 band->ownsdata = 1; /* we DO own this data!!! */
221 memcpy(band->data.mem, *ptr, sz);
222 *ptr += sz;
223
224 /* Should now flip values if > 8bit and
225 * littleEndian != isMachineLittleEndian */
226 if (pixbytes > 1) {
227 if (isMachineLittleEndian() != littleEndian) {
228 void (*flipper)(uint8_t*) = 0;
229 uint8_t *flipme = NULL;
230
231 if (pixbytes == 2)
232 flipper = flip_endian_16;
233 else if (pixbytes == 4)
234 flipper = flip_endian_32;
235 else if (pixbytes == 8)
236 flipper = flip_endian_64;
237 else {
238 rterror("rt_band_from_wkb: Unexpected pix bytes %d", pixbytes);
239 rt_band_destroy(band);
240 return NULL;
241 }
242
243 flipme = band->data.mem;
244 sz = (size_t)width * height;
245 for (v = 0; v < sz; ++v) {
246 flipper(flipme);
247 flipme += pixbytes;
248 }
249 }
250 }
251 /* And should check for invalid values for < 8bit types */
252 else if (
253 band->pixtype == PT_1BB ||
254 band->pixtype == PT_2BUI ||
255 band->pixtype == PT_4BUI
256 ) {
257 uint8_t maxVal = band->pixtype == PT_1BB ? 1 : (band->pixtype == PT_2BUI ? 3 : 15);
258 uint8_t val;
259
260 sz = (size_t)width*height;
261 for (v = 0; v < sz; ++v) {
262 val = ((uint8_t*) band->data.mem)[v];
263 if (val > maxVal) {
264 rterror("rt_band_from_wkb: Invalid value %d for pixel of type %s",
265 val, rt_pixtype_name(band->pixtype));
266 rt_band_destroy(band);
267 return NULL;
268 }
269 }
270 }
271
272 /* And we should check if the band is a nodata band */
273 /* TODO: No!! This is too slow */
274 /*rt_band_check_is_nodata(band);*/
275
276 return band;
277}
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_DEBUGF(level, msg,...)
Definition librtcore.h:308
float rt_util_float16_to_float(uint16_t value)
Definition rt_util.c:134
@ 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_END
Definition librtcore.h:201
@ 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
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 isMachineLittleEndian(void)
void flip_endian_32(uint8_t *d)
void flip_endian_16(uint8_t *d)
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)
void flip_endian_64(uint8_t *d)
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

References BANDTYPE_HAS_NODATA, BANDTYPE_IS_NODATA, BANDTYPE_IS_OFFDB, BANDTYPE_PIXTYPE_MASK, flip_endian_16(), flip_endian_32(), flip_endian_64(), isMachineLittleEndian(), PT_16BF, PT_16BSI, PT_16BUI, PT_1BB, PT_2BUI, PT_32BF, PT_32BSI, PT_32BUI, PT_4BUI, PT_64BF, PT_8BSI, PT_8BUI, PT_END, 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_util_float16_to_float(), rtalloc(), and rterror().

Referenced by rt_raster_from_wkb().

Here is the call graph for this function:
Here is the caller graph for this function: