PostGIS  2.1.10dev-r@@SVN_REVISION@@
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 7669 of file rt_api.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().

7669  {
7670  const uint8_t *ptr = wkb;
7671  const uint8_t *wkbend = NULL;
7672  rt_raster rast = NULL;
7673  uint8_t endian = 0;
7674  uint16_t version = 0;
7675  uint16_t i = 0;
7676  uint16_t j = 0;
7677 
7678  assert(NULL != ptr);
7679 
7680  /* Check that wkbsize is >= sizeof(rt_raster_serialized) */
7681  if (wkbsize < RT_WKB_HDR_SZ) {
7682  rterror("rt_raster_from_wkb: wkb size (%d) < min size (%d)",
7683  wkbsize, RT_WKB_HDR_SZ);
7684  return NULL;
7685  }
7686  wkbend = wkb + wkbsize;
7687 
7688  RASTER_DEBUGF(3, "Parsing header from wkb position %d (expected 0)",
7689  d_binptr_to_pos(ptr, wkbend, wkbsize));
7690 
7691  CHECK_BINPTR_POSITION(ptr, wkbend, wkbsize, 0);
7692 
7693  /* Read endianness */
7694  endian = *ptr;
7695  ptr += 1;
7696 
7697  /* Read version of protocol */
7698  version = read_uint16(&ptr, endian);
7699  if (version != 0) {
7700  rterror("rt_raster_from_wkb: WKB version %d unsupported", version);
7701  return NULL;
7702  }
7703 
7704  /* Read other components of raster header */
7705  rast = (rt_raster) rtalloc(sizeof (struct rt_raster_t));
7706  if (!rast) {
7707  rterror("rt_raster_from_wkb: Out of memory allocating raster for wkb input");
7708  return NULL;
7709  }
7710 
7711  rast->numBands = read_uint16(&ptr, endian);
7712  rast->scaleX = read_float64(&ptr, endian);
7713  rast->scaleY = read_float64(&ptr, endian);
7714  rast->ipX = read_float64(&ptr, endian);
7715  rast->ipY = read_float64(&ptr, endian);
7716  rast->skewX = read_float64(&ptr, endian);
7717  rast->skewY = read_float64(&ptr, endian);
7718  rast->srid = clamp_srid(read_int32(&ptr, endian));
7719  rast->width = read_uint16(&ptr, endian);
7720  rast->height = read_uint16(&ptr, endian);
7721 
7722  /* Consistency checking, should have been checked before */
7723  assert(ptr <= wkbend);
7724 
7725  RASTER_DEBUGF(3, "rt_raster_from_wkb: Raster numBands: %d",
7726  rast->numBands);
7727  RASTER_DEBUGF(3, "rt_raster_from_wkb: Raster scale: %gx%g",
7728  rast->scaleX, rast->scaleY);
7729  RASTER_DEBUGF(3, "rt_raster_from_wkb: Raster ip: %gx%g",
7730  rast->ipX, rast->ipY);
7731  RASTER_DEBUGF(3, "rt_raster_from_wkb: Raster skew: %gx%g",
7732  rast->skewX, rast->skewY);
7733  RASTER_DEBUGF(3, "rt_raster_from_wkb: Raster srid: %d",
7734  rast->srid);
7735  RASTER_DEBUGF(3, "rt_raster_from_wkb: Raster dims: %dx%d",
7736  rast->width, rast->height);
7737  RASTER_DEBUGF(3, "Parsing raster header finished at wkb position %d (expected 61)",
7738  d_binptr_to_pos(ptr, wkbend, wkbsize));
7739 
7740  CHECK_BINPTR_POSITION(ptr, wkbend, wkbsize, 61);
7741 
7742  /* Read all bands of raster */
7743  if (!rast->numBands) {
7744  /* Here ptr should have been left to right after last used byte */
7745  if (ptr < wkbend) {
7746  rtwarn("%d bytes of WKB remained unparsed", wkbend - ptr);
7747  }
7748  else if (ptr > wkbend) {
7749  /* Easier to get a segfault before I guess */
7750  rtwarn("We parsed %d bytes more then available!", ptr - wkbend);
7751  }
7752 
7753  rast->bands = NULL;
7754  return rast;
7755  }
7756 
7757  /* Now read the bands */
7758  rast->bands = (rt_band*) rtalloc(sizeof(rt_band) * rast->numBands);
7759  if (!rast->bands) {
7760  rterror("rt_raster_from_wkb: Out of memory allocating bands for WKB raster decoding");
7761  rt_raster_destroy(rast);
7762  return NULL;
7763  }
7764 
7765  /* ptr should now point to start of first band */
7766  /* we should have checked this before */
7767  assert(ptr <= wkbend);
7768 
7769  for (i = 0; i < rast->numBands; ++i) {
7770  RASTER_DEBUGF(3, "Parsing band %d from wkb position %d", i,
7771  d_binptr_to_pos(ptr, wkbend, wkbsize));
7772 
7773  rt_band band = rt_band_from_wkb(rast->width, rast->height,
7774  &ptr, wkbend, endian);
7775  if (!band) {
7776  rterror("rt_raster_from_wkb: Error reading WKB form of band %d", i);
7777  for (j = 0; j < i; j++) rt_band_destroy(rast->bands[j]);
7778  rt_raster_destroy(rast);
7779  return NULL;
7780  }
7781 
7782  band->raster = rast;
7783  rast->bands[i] = band;
7784  }
7785 
7786  /* Here ptr should have been left to right after last used byte */
7787  if (ptr < wkbend) {
7788  rtwarn("%d bytes of WKB remained unparsed", wkbend - ptr);
7789  }
7790  else if (ptr > wkbend) {
7791  /* Easier to get a segfault before I guess */
7792  rtwarn("We parsed %d bytes more then available!", ptr - wkbend);
7793  }
7794 
7795  return rast;
7796 }
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:326
double skewY
Definition: rt_api.h:2223
int32_t srid
Definition: rt_api.h:2225
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_api.c:5387
struct rt_raster_t * rt_raster
Types definitions.
Definition: rt_api.h:133
uint16_t numBands
Definition: rt_api.h:2215
rt_raster raster
Definition: rt_api.h:2249
#define CHECK_BINPTR_POSITION(ptr, end, size, pos)
Definition: rt_api.c:1090
static double read_float64(const uint8_t **from, uint8_t littleEndian)
Definition: rt_api.c:7342
tuple band
Definition: ovdump.py:57
tuple rast
Definition: rtpixdump.py:62
static int32_t read_int32(const uint8_t **from, uint8_t littleEndian)
Definition: rt_api.c:7284
double ipY
Definition: rt_api.h:2221
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_api.c:7429
uint16_t height
Definition: rt_api.h:2227
void rtwarn(const char *fmt,...)
Definition: rt_api.c:920
#define RASTER_DEBUGF(level, msg,...)
Definition: rt_api.h:285
uint16_t width
Definition: rt_api.h:2226
double skewX
Definition: rt_api.h:2222
void rt_band_destroy(rt_band band)
Destroy a raster band.
Definition: rt_api.c:1650
void * rtalloc(size_t size)
Raster core memory management functions.
Definition: rt_api.c:867
void rterror(const char *fmt,...)
Raster core error and info handlers.
Definition: rt_api.c:895
#define RT_WKB_HDR_SZ
Definition: rt_api.c:7666
rt_band * bands
Definition: rt_api.h:2228
double ipX
Definition: rt_api.h:2220
double scaleX
Definition: rt_api.h:2218
static uint16_t read_uint16(const uint8_t **from, uint8_t littleEndian)
Definition: rt_api.c:7178
double scaleY
Definition: rt_api.h:2219

Here is the call graph for this function:

Here is the caller graph for this function: