PostGIS 3.6.2dev-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 278 of file rt_wkb.c.

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

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: