PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ rt_band_from_wkb()

static rt_band rt_band_from_wkb ( uint16_t  width,
uint16_t  height,
const uint8_t **  ptr,
const uint8_t *  end,
uint8_t  littleEndian 
)
static

Definition at line 38 of file rt_wkb.c.

42  {
43  rt_band band = NULL;
44  int pixbytes = 0;
45  uint8_t type = 0;
46  size_t sz = 0;
47  size_t v = 0;
48 
49  assert(NULL != ptr);
50  assert(NULL != end);
51 
52  band = rtalloc(sizeof (struct rt_band_t));
53  if (!band) {
54  rterror("rt_band_from_wkb: Out of memory allocating rt_band during WKB parsing");
55  return NULL;
56  }
57  band->ownsdata = 0; /* assume we don't own data */
58 
59  if (end - *ptr < 1) {
60  rterror("rt_band_from_wkb: Premature end of WKB on band reading (%s:%d)",
61  __FILE__, __LINE__);
63  return NULL;
64  }
65  type = read_uint8(ptr);
66 
67  if ((type & BANDTYPE_PIXTYPE_MASK) >= PT_END) {
68  rterror("rt_band_from_wkb: Invalid pixtype %d", type & BANDTYPE_PIXTYPE_MASK);
70  return NULL;
71  }
72 
73  band->pixtype = type & BANDTYPE_PIXTYPE_MASK;
74  band->offline = BANDTYPE_IS_OFFDB(type) ? 1 : 0;
75  band->hasnodata = BANDTYPE_HAS_NODATA(type) ? 1 : 0;
76  band->isnodata = band->hasnodata ? (BANDTYPE_IS_NODATA(type) ? 1 : 0) : 0;
77  band->width = width;
78  band->height = height;
79 
80  RASTER_DEBUGF(3, " Band pixtype:%s, offline:%d, hasnodata:%d",
81  rt_pixtype_name(band->pixtype),
82  band->offline,
83  band->hasnodata
84  );
85 
86  /* Check there's enough bytes to read nodata value */
87  pixbytes = rt_pixtype_size(band->pixtype);
88  if (((*ptr) + pixbytes) >= end) {
89  rterror("rt_band_from_wkb: Premature end of WKB on band novalue reading");
91  return NULL;
92  }
93 
94  /* Read nodata value */
95  switch (band->pixtype) {
96  case PT_1BB: {
97  band->nodataval = ((int) read_uint8(ptr)) & 0x01;
98  break;
99  }
100  case PT_2BUI: {
101  band->nodataval = ((int) read_uint8(ptr)) & 0x03;
102  break;
103  }
104  case PT_4BUI: {
105  band->nodataval = ((int) read_uint8(ptr)) & 0x0F;
106  break;
107  }
108  case PT_8BSI: {
109  band->nodataval = read_int8(ptr);
110  break;
111  }
112  case PT_8BUI: {
113  band->nodataval = read_uint8(ptr);
114  break;
115  }
116  case PT_16BSI: {
117  band->nodataval = read_int16(ptr, littleEndian);
118  break;
119  }
120  case PT_16BUI: {
121  band->nodataval = read_uint16(ptr, littleEndian);
122  break;
123  }
124  case PT_32BSI: {
125  band->nodataval = read_int32(ptr, littleEndian);
126  break;
127  }
128  case PT_32BUI: {
129  band->nodataval = read_uint32(ptr, littleEndian);
130  break;
131  }
132  case PT_32BF: {
133  band->nodataval = read_float32(ptr, littleEndian);
134  break;
135  }
136  case PT_64BF: {
137  band->nodataval = read_float64(ptr, littleEndian);
138  break;
139  }
140  default: {
141  rterror("rt_band_from_wkb: Unknown pixeltype %d", band->pixtype);
143  return NULL;
144  }
145  }
146 
147  RASTER_DEBUGF(3, " Nodata value: %g, pixbytes: %d, ptr @ %p, end @ %p",
148  band->nodataval, pixbytes, *ptr, end);
149 
150  if (band->offline) {
151  if (((*ptr) + 1) >= end) {
152  rterror("rt_band_from_wkb: Premature end of WKB on offline "
153  "band data bandNum reading (%s:%d)",
154  __FILE__, __LINE__
155  );
157  return NULL;
158  }
159 
160  band->data.offline.bandNum = read_int8(ptr);
161  band->data.offline.mem = NULL;
162 
163  {
164  /* check we have a NULL-termination */
165  sz = 0;
166  while ((*ptr)[sz] && &((*ptr)[sz]) < end) ++sz;
167  if (&((*ptr)[sz]) >= end) {
168  rterror("rt_band_from_wkb: Premature end of WKB on band offline path reading");
170  return NULL;
171  }
172 
173  /* we never own offline band data */
174  band->ownsdata = 0;
175 
176  band->data.offline.path = rtalloc(sz + 1);
177  if (band->data.offline.path == NULL) {
178  rterror("rt_band_from_wkb: Out of memory allocating for offline path of band");
180  return NULL;
181  }
182 
183  memcpy(band->data.offline.path, *ptr, sz);
184  band->data.offline.path[sz] = '\0';
185 
186  RASTER_DEBUGF(3, "OFFDB band path is %s (size is %zu)",
187  band->data.offline.path, sz);
188 
189  *ptr += sz + 1;
190 
191  /* TODO: How could we know if the offline band is a nodata band? */
192  /* trust in the force */
193  /*band->isnodata = FALSE;*/
194  }
195 
196  return band;
197  }
198 
199  /* This is an on-disk band */
200  sz = (size_t)width * height * pixbytes;
201  if (((*ptr) + sz) > end) {
202  rterror("rt_band_from_wkb: Premature end of WKB on band data reading (%s:%d)",
203  __FILE__, __LINE__);
205  return NULL;
206  }
207 
208  band->data.mem = rtalloc(sz);
209  if (!band->data.mem) {
210  rterror("rt_band_from_wkb: Out of memory during band creation in WKB parser");
212  return NULL;
213  }
214 
215  band->ownsdata = 1; /* we DO own this data!!! */
216  memcpy(band->data.mem, *ptr, sz);
217  *ptr += sz;
218 
219  /* Should now flip values if > 8bit and
220  * littleEndian != isMachineLittleEndian */
221  if (pixbytes > 1) {
222  if (isMachineLittleEndian() != littleEndian) {
223  void (*flipper)(uint8_t*) = 0;
224  uint8_t *flipme = NULL;
225 
226  if (pixbytes == 2)
227  flipper = flip_endian_16;
228  else if (pixbytes == 4)
229  flipper = flip_endian_32;
230  else if (pixbytes == 8)
231  flipper = flip_endian_64;
232  else {
233  rterror("rt_band_from_wkb: Unexpected pix bytes %d", pixbytes);
235  return NULL;
236  }
237 
238  flipme = band->data.mem;
239  sz = (size_t)width * height;
240  for (v = 0; v < sz; ++v) {
241  flipper(flipme);
242  flipme += pixbytes;
243  }
244  }
245  }
246  /* And should check for invalid values for < 8bit types */
247  else if (
248  band->pixtype == PT_1BB ||
249  band->pixtype == PT_2BUI ||
250  band->pixtype == PT_4BUI
251  ) {
252  uint8_t maxVal = band->pixtype == PT_1BB ? 1 : (band->pixtype == PT_2BUI ? 3 : 15);
253  uint8_t val;
254 
255  sz = (size_t)width*height;
256  for (v = 0; v < sz; ++v) {
257  val = ((uint8_t*) band->data.mem)[v];
258  if (val > maxVal) {
259  rterror("rt_band_from_wkb: Invalid value %d for pixel of type %s",
260  val, rt_pixtype_name(band->pixtype));
262  return NULL;
263  }
264  }
265  }
266 
267  /* And we should check if the band is a nodata band */
268  /* TODO: No!! This is too slow */
269  /*rt_band_check_is_nodata(band);*/
270 
271  return band;
272 }
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
@ PT_32BUI
Definition: librtcore.h:196
@ PT_2BUI
Definition: librtcore.h:189
@ PT_32BSI
Definition: librtcore.h:195
@ PT_END
Definition: librtcore.h:199
@ PT_4BUI
Definition: librtcore.h:190
@ PT_32BF
Definition: librtcore.h:197
@ PT_1BB
Definition: librtcore.h:188
@ PT_16BUI
Definition: librtcore.h:194
@ PT_8BSI
Definition: librtcore.h:191
@ PT_16BSI
Definition: librtcore.h:193
@ PT_64BF
Definition: librtcore.h:198
@ PT_8BUI
Definition: librtcore.h:192
void rt_band_destroy(rt_band band)
Destroy a raster band.
Definition: rt_band.c:491
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition: rt_pixel.c:110
int rt_pixtype_size(rt_pixtype pixtype)
Return size in bytes of a value in the given pixtype.
Definition: rt_pixel.c:39
band
Definition: ovdump.py:58
type
Definition: ovdump.py:42
uint8_t isMachineLittleEndian(void)
Definition: rt_serialize.c:190
void flip_endian_32(uint8_t *d)
Definition: rt_serialize.c:172
void flip_endian_16(uint8_t *d)
Definition: rt_serialize.c:165
uint8_t read_uint8(const uint8_t **from)
Definition: rt_serialize.c:197
double read_float64(const uint8_t **from, uint8_t littleEndian)
Definition: rt_serialize.c:389
float read_float32(const uint8_t **from, uint8_t littleEndian)
Definition: rt_serialize.c:363
void flip_endian_64(uint8_t *d)
Definition: rt_serialize.c:180
int8_t read_int8(const uint8_t **from)
Definition: rt_serialize.c:213
int16_t read_int16(const uint8_t **from, uint8_t littleEndian)
Definition: rt_serialize.c:261
int32_t read_int32(const uint8_t **from, uint8_t littleEndian)
Definition: rt_serialize.c:333
uint32_t read_uint32(const uint8_t **from, uint8_t littleEndian)
Definition: rt_serialize.c:287
uint16_t read_uint16(const uint8_t **from, uint8_t littleEndian)
Definition: rt_serialize.c:229
#define BANDTYPE_HAS_NODATA(x)
Definition: rt_serialize.h:44
#define BANDTYPE_IS_OFFDB(x)
Definition: rt_serialize.h:43
#define BANDTYPE_IS_NODATA(x)
Definition: rt_serialize.h:45
#define BANDTYPE_PIXTYPE_MASK
Definition: rt_serialize.h:36

References ovdump::band, BANDTYPE_HAS_NODATA, BANDTYPE_IS_NODATA, BANDTYPE_IS_OFFDB, BANDTYPE_PIXTYPE_MASK, flip_endian_16(), flip_endian_32(), flip_endian_64(), isMachineLittleEndian(), PT_16BSI, PT_16BUI, PT_1BB, PT_2BUI, PT_32BF, PT_32BSI, PT_32BUI, PT_4BUI, PT_64BF, PT_8BSI, PT_8BUI, PT_END, RASTER_DEBUGF, read_float32(), read_float64(), read_int16(), read_int32(), read_int8(), read_uint16(), read_uint32(), read_uint8(), rt_band_destroy(), rt_pixtype_name(), rt_pixtype_size(), rtalloc(), rterror(), and ovdump::type.

Referenced by rt_raster_from_wkb().

Here is the call graph for this function:
Here is the caller graph for this function: