PostGIS 3.7.0dev-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 283 of file rt_wkb.c.

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

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: