PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ 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");
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]);
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
band
Definition: ovdump.py:58
double read_float64(const uint8_t **from, uint8_t littleEndian)
Definition: rt_serialize.c:389
int32_t read_int32(const uint8_t **from, uint8_t littleEndian)
Definition: rt_serialize.c:333
uint16_t read_uint16(const uint8_t **from, uint8_t littleEndian)
Definition: rt_serialize.c:229
#define CHECK_BINPTR_POSITION(ptr, end, size, pos)
Definition: rt_serialize.h:65
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 ovdump::band, CHECK_BINPTR_POSITION, clamp_srid(), rtpixdump::rast, 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: