PostGIS  2.4.9dev-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 276 of file rt_wkb.c.

References ovdump::band, rt_raster_t::bands, CHECK_BINPTR_POSITION, clamp_srid(), rt_raster_t::height, rt_raster_t::ipX, rt_raster_t::ipY, rt_raster_t::numBands, rtpixdump::rast, rt_band_t::raster, RASTER_DEBUGF, read_float64(), read_int32(), read_uint16(), rt_band_destroy(), rt_band_from_wkb(), rt_raster_destroy(), RT_WKB_HDR_SZ, rtalloc(), rterror(), rtwarn(), rt_raster_t::scaleX, rt_raster_t::scaleY, rt_raster_t::skewX, rt_raster_t::skewY, rt_raster_t::srid, and rt_raster_t::width.

Referenced by rt_raster_from_hexwkb().

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 }
int clamp_srid(int srid)
Return a valid SRID from an arbitrary integer Raises a notice if what comes out is different from wha...
Definition: lwutil.c:380
#define RT_WKB_HDR_SZ
Definition: rt_wkb.c:273
double skewY
Definition: librtcore.h:2249
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
int32_t srid
Definition: librtcore.h:2251
uint16_t numBands
Definition: librtcore.h:2241
struct rt_raster_t * rt_raster
Types definitions.
Definition: librtcore.h:145
rt_raster raster
Definition: librtcore.h:2275
band
Definition: ovdump.py:57
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
double ipY
Definition: librtcore.h:2247
void rt_band_destroy(rt_band band)
Destroy a raster band.
Definition: rt_band.c:242
uint16_t height
Definition: librtcore.h:2253
#define CHECK_BINPTR_POSITION(ptr, end, size, pos)
Definition: rt_serialize.h:65
uint16_t read_uint16(const uint8_t **from, uint8_t littleEndian)
Definition: rt_serialize.c:229
void rtwarn(const char *fmt,...)
Definition: rt_context.c:224
uint16_t width
Definition: librtcore.h:2252
double skewX
Definition: librtcore.h:2248
#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
rt_band * bands
Definition: librtcore.h:2254
double ipX
Definition: librtcore.h:2246
int32_t read_int32(const uint8_t **from, uint8_t littleEndian)
Definition: rt_serialize.c:333
double read_float64(const uint8_t **from, uint8_t littleEndian)
Definition: rt_serialize.c:389
double scaleX
Definition: librtcore.h:2244
unsigned char uint8_t
Definition: uthash.h:79
double scaleY
Definition: librtcore.h:2245
Here is the call graph for this function:
Here is the caller graph for this function: