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

◆ rt_raster_from_wkb()

rt_raster rt_raster_from_wkb ( const uint8_t *  wkb,
uint32_t  wkbsize 
)

Construct an rt_raster from a binary WKB representation.

Parameters
wkb: an octet stream
wkbsize: size (in bytes) of the wkb octet stream
Returns
an rt_raster or NULL on error (out of memory or malformed WKB).

Definition at line 276 of file rt_wkb.c.

276 {
277 const uint8_t *ptr = wkb;
278 const uint8_t *wkbend = NULL;
279 rt_raster rast = NULL;
280 uint8_t endian = 0;
281 uint16_t version = 0;
282 uint16_t i = 0;
283 uint16_t j = 0;
284
285 assert(NULL != ptr);
286
287 /* Check that wkbsize is >= sizeof(rt_raster_serialized) */
288 if (wkbsize < RT_WKB_HDR_SZ) {
289 rterror("rt_raster_from_wkb: wkb size (%d) < min size (%d)",
290 wkbsize, RT_WKB_HDR_SZ);
291 return NULL;
292 }
293 wkbend = wkb + wkbsize;
294
295 RASTER_DEBUGF(3, "Parsing header from wkb position %d (expected 0)",
296 d_binptr_to_pos(ptr, wkbend, wkbsize));
297
298 CHECK_BINPTR_POSITION(ptr, wkbend, wkbsize, 0);
299
300 /* Read endianness */
301 endian = *ptr;
302 ptr += 1;
303
304 /* Read version of protocol */
305 version = read_uint16(&ptr, endian);
306 if (version != 0) {
307 rterror("rt_raster_from_wkb: WKB version %d unsupported", version);
308 return NULL;
309 }
310
311 /* Read other components of raster header */
312 rast = (rt_raster) rtalloc(sizeof (struct rt_raster_t));
313 if (!rast) {
314 rterror("rt_raster_from_wkb: Out of memory allocating raster for wkb input");
315 return NULL;
316 }
317
318 rast->numBands = read_uint16(&ptr, endian);
319 rast->scaleX = read_float64(&ptr, endian);
320 rast->scaleY = read_float64(&ptr, endian);
321 rast->ipX = read_float64(&ptr, endian);
322 rast->ipY = read_float64(&ptr, endian);
323 rast->skewX = read_float64(&ptr, endian);
324 rast->skewY = read_float64(&ptr, endian);
325 rast->srid = clamp_srid(read_int32(&ptr, endian));
326 rast->width = read_uint16(&ptr, endian);
327 rast->height = read_uint16(&ptr, endian);
328
329 /* Consistency checking, should have been checked before */
330 assert(ptr <= wkbend);
331
332 RASTER_DEBUGF(3, "rt_raster_from_wkb: Raster numBands: %d",
333 rast->numBands);
334 RASTER_DEBUGF(3, "rt_raster_from_wkb: Raster scale: %gx%g",
335 rast->scaleX, rast->scaleY);
336 RASTER_DEBUGF(3, "rt_raster_from_wkb: Raster ip: %gx%g",
337 rast->ipX, rast->ipY);
338 RASTER_DEBUGF(3, "rt_raster_from_wkb: Raster skew: %gx%g",
339 rast->skewX, rast->skewY);
340 RASTER_DEBUGF(3, "rt_raster_from_wkb: Raster srid: %d",
341 rast->srid);
342 RASTER_DEBUGF(3, "rt_raster_from_wkb: Raster dims: %dx%d",
343 rast->width, rast->height);
344 RASTER_DEBUGF(3, "Parsing raster header finished at wkb position %d (expected 61)",
345 d_binptr_to_pos(ptr, wkbend, wkbsize));
346
347 CHECK_BINPTR_POSITION(ptr, wkbend, wkbsize, 61);
348
349 /* Read all bands of raster */
350 if (!rast->numBands) {
351 /* Here ptr should have been left to right after last used byte */
352 if (ptr < wkbend) {
353 rtwarn("%d bytes of WKB remained unparsed", wkbend - ptr);
354 }
355 else if (ptr > wkbend) {
356 /* Easier to get a segfault before I guess */
357 rtwarn("We parsed %d bytes more then available!", ptr - wkbend);
358 }
359
360 rast->bands = NULL;
361 return rast;
362 }
363
364 /* Now read the bands */
365 rast->bands = (rt_band*) rtalloc(sizeof(rt_band) * rast->numBands);
366 if (!rast->bands) {
367 rterror("rt_raster_from_wkb: Out of memory allocating bands for WKB raster decoding");
368 rt_raster_destroy(rast);
369 return NULL;
370 }
371
372 /* ptr should now point to start of first band */
373 /* we should have checked this before */
374 assert(ptr <= wkbend);
375
376 for (i = 0; i < rast->numBands; ++i) {
377 RASTER_DEBUGF(3, "Parsing band %d from wkb position %d", i,
378 d_binptr_to_pos(ptr, wkbend, wkbsize));
379
380 rt_band band = rt_band_from_wkb(rast->width, rast->height,
381 &ptr, wkbend, endian);
382 if (!band) {
383 rterror("rt_raster_from_wkb: Error reading WKB form of band %d", i);
384 for (j = 0; j < i; j++) rt_band_destroy(rast->bands[j]);
385 rt_raster_destroy(rast);
386 return NULL;
387 }
388
389 band->raster = rast;
390 rast->bands[i] = band;
391 }
392
393 /* Here ptr should have been left to right after last used byte */
394 if (ptr < wkbend) {
395 rtwarn("%d bytes of WKB remained unparsed", wkbend - ptr);
396 }
397 else if (ptr > wkbend) {
398 /* Easier to get a segfault before I guess */
399 rtwarn("We parsed %d bytes more then available!", ptr - wkbend);
400 }
401
402 return rast;
403}
int32_t clamp_srid(int32_t srid)
Return a valid SRID from an arbitrary integer Raises a notice if what comes out is different from wha...
Definition lwutil.c:333
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_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
void rtwarn(const char *fmt,...)
Definition rt_context.c:224
void rt_band_destroy(rt_band band)
Destroy a raster band.
Definition rt_band.c:340
struct rt_raster_t * rt_raster
Types definitions.
Definition librtcore.h:145
double read_float64(const uint8_t **from, uint8_t littleEndian)
int32_t read_int32(const uint8_t **from, uint8_t littleEndian)
uint16_t read_uint16(const uint8_t **from, uint8_t littleEndian)
#define CHECK_BINPTR_POSITION(ptr, end, size, pos)
static rt_band rt_band_from_wkb(uint16_t width, uint16_t height, const uint8_t **ptr, const uint8_t *end, uint8_t littleEndian)
Definition rt_wkb.c:36
#define RT_WKB_HDR_SZ
Definition rt_wkb.c:273

References CHECK_BINPTR_POSITION, clamp_srid(), RASTER_DEBUGF, read_float64(), read_int32(), read_uint16(), rt_band_destroy(), rt_band_from_wkb(), rt_raster_destroy(), RT_WKB_HDR_SZ, rtalloc(), rterror(), and rtwarn().

Referenced by RASTER_fromWKB(), and rt_raster_from_hexwkb().

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