PostGIS 3.6.2dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
rt_pixel.c
Go to the documentation of this file.
1/*
2 *
3 * WKTRaster - Raster Types for PostGIS
4 * http://trac.osgeo.org/postgis/wiki/WKTRaster
5 *
6 * Copyright (C) 2011-2013 Regents of the University of California
7 * <bkpark@ucdavis.edu>
8 * Copyright (C) 2010-2011 Jorge Arevalo <jorge.arevalo@deimos-space.com>
9 * Copyright (C) 2010-2011 David Zwarg <dzwarg@azavea.com>
10 * Copyright (C) 2009-2011 Pierre Racine <pierre.racine@sbf.ulaval.ca>
11 * Copyright (C) 2009-2011 Mateusz Loskot <mateusz@loskot.net>
12 * Copyright (C) 2008-2009 Sandro Santilli <strk@kbt.io>
13 * Copyright (C) 2013 Nathaniel Hunter Clay <clay.nathaniel@gmail.com>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software Foundation,
27 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
28 *
29 */
30
31#include "librtcore.h"
32#include "librtcore_internal.h"
33
34/******************************************************************************
35* rt_pixeltype
36******************************************************************************/
37
38int
40 int pixbytes = -1;
41
42 switch (pixtype) {
43 case PT_1BB:
44 case PT_2BUI:
45 case PT_4BUI:
46 case PT_8BSI:
47 case PT_8BUI:
48 pixbytes = 1;
49 break;
50 case PT_16BSI:
51 case PT_16BUI:
52 pixbytes = 2;
53 break;
54 case PT_32BSI:
55 case PT_32BUI:
56 case PT_32BF:
57 pixbytes = 4;
58 break;
59 case PT_64BF:
60 pixbytes = 8;
61 break;
62 default:
63 rterror("rt_pixtype_size: Unknown pixeltype %d", pixtype);
64 pixbytes = -1;
65 break;
66 }
67
68 RASTER_DEBUGF(3, "Pixel type = %s and size = %d bytes",
69 rt_pixtype_name(pixtype), pixbytes);
70
71 return pixbytes;
72}
73
74int
76 return rt_pixtype_size(pixtype);
77}
78
80rt_pixtype_index_from_name(const char* pixname) {
81 assert(pixname);
82
83 if (strcmp(pixname, "1BB") == 0)
84 return PT_1BB;
85 else if (strcmp(pixname, "2BUI") == 0)
86 return PT_2BUI;
87 else if (strcmp(pixname, "4BUI") == 0)
88 return PT_4BUI;
89 else if (strcmp(pixname, "8BSI") == 0)
90 return PT_8BSI;
91 else if (strcmp(pixname, "8BUI") == 0)
92 return PT_8BUI;
93 else if (strcmp(pixname, "16BSI") == 0)
94 return PT_16BSI;
95 else if (strcmp(pixname, "16BUI") == 0)
96 return PT_16BUI;
97 else if (strcmp(pixname, "32BSI") == 0)
98 return PT_32BSI;
99 else if (strcmp(pixname, "32BUI") == 0)
100 return PT_32BUI;
101 else if (strcmp(pixname, "32BF") == 0)
102 return PT_32BF;
103 else if (strcmp(pixname, "64BF") == 0)
104 return PT_64BF;
105
106 return PT_END;
107}
108
109const char*
111
112
113 switch (pixtype) {
114 case PT_1BB:
115 return "1BB";
116 case PT_2BUI:
117 return "2BUI";
118 case PT_4BUI:
119 return "4BUI";
120 case PT_8BSI:
121 return "8BSI";
122 case PT_8BUI:
123 return "8BUI";
124 case PT_16BSI:
125 return "16BSI";
126 case PT_16BUI:
127 return "16BUI";
128 case PT_32BSI:
129 return "32BSI";
130 case PT_32BUI:
131 return "32BUI";
132 case PT_32BF:
133 return "32BF";
134 case PT_64BF:
135 return "64BF";
136 default:
137 rterror("rt_pixtype_name: Unknown pixeltype %d", pixtype);
138 return "Unknown";
139 }
140}
141
149double
151 switch (pixtype) {
152 case PT_1BB: {
153 return (double) rt_util_clamp_to_1BB((double) CHAR_MIN);
154 }
155 case PT_2BUI: {
156 return 0;
157 }
158 case PT_4BUI: {
159 return 0;
160 }
161 case PT_8BUI: {
162 return 0;
163 }
164 case PT_8BSI: {
165 return (double) rt_util_clamp_to_8BSI((double) SCHAR_MIN);
166 }
167 case PT_16BSI: {
168 return (double) rt_util_clamp_to_16BSI((double) SHRT_MIN);
169 }
170 case PT_16BUI: {
171 return 0;
172 }
173 case PT_32BSI: {
174 return (double) rt_util_clamp_to_32BSI((double) INT_MIN);
175 }
176 case PT_32BUI: {
177 return 0;
178 }
179 case PT_32BF: {
180 return (double) -FLT_MAX;
181 }
182 case PT_64BF: {
183 return (double) -DBL_MAX;
184 }
185 default: {
186 rterror("rt_pixtype_get_min_value: Unknown pixeltype %d", pixtype);
187 return (double) rt_util_clamp_to_8BUI((double) CHAR_MIN);
188 }
189 }
190}
191
203 rt_pixtype pixtype,
204 double val, double refval,
205 int *isequal
206) {
207 assert(isequal != NULL);
208 *isequal = 0;
209
210 switch (pixtype) {
211 case PT_1BB:
212 if (rt_util_clamp_to_1BB(val) == rt_util_clamp_to_1BB(refval))
213 *isequal = 1;
214 break;
215 case PT_2BUI:
217 *isequal = 1;
218 break;
219 case PT_4BUI:
221 *isequal = 1;
222 break;
223 case PT_8BSI:
225 *isequal = 1;
226 break;
227 case PT_8BUI:
229 *isequal = 1;
230 break;
231 case PT_16BSI:
233 *isequal = 1;
234 break;
235 case PT_16BUI:
237 *isequal = 1;
238 break;
239 case PT_32BSI:
241 *isequal = 1;
242 break;
243 case PT_32BUI:
245 *isequal = 1;
246 break;
247 case PT_32BF:
249 *isequal = 1;
250 break;
251 case PT_64BF:
252 if (FLT_EQ(val, refval))
253 *isequal = 1;
254 break;
255 default:
256 rterror("rt_pixtype_compare_clamped_values: Unknown pixeltype %d", pixtype);
257 return ES_ERROR;
258 }
259
260 return ES_NONE;
261}
262
263/******************************************************************************
264* rt_pixel
265******************************************************************************/
266
267/*
268 * Convert an array of rt_pixel objects to two 2D arrays of value and NODATA.
269 * The dimensions of the returned 2D array are [Y][X], going by row Y and
270 * then column X.
271 *
272 * @param npixel : array of rt_pixel objects
273 * @param count : number of elements in npixel
274 * @param mask : mask to be respected when returning array
275 * @param x : the column of the center pixel (0-based)
276 * @param y : the line of the center pixel (0-based)
277 * @param distancex : the number of pixels around the specified pixel
278 * along the X axis
279 * @param distancey : the number of pixels around the specified pixel
280 * along the Y axis
281 * @param value : pointer to pointer for 2D value array
282 * @param nodata : pointer to pointer for 2D NODATA array
283 * @param dimx : size of value and nodata along the X axis
284 * @param dimy : size of value and nodata along the Y axis
285 *
286 * @return ES_NONE on success, ES_ERROR on error
287 */
289 rt_pixel npixel, uint32_t count, rt_mask mask,
290 int x, int y,
291 uint16_t distancex, uint16_t distancey,
292 double ***value,
293 int ***nodata,
294 int *dimx, int *dimy
295) {
296 uint32_t i;
297 uint32_t j;
298 uint32_t dim[2] = {0};
299 double **values = NULL;
300 int **nodatas = NULL;
301 int zero[2] = {0};
302 int _x;
303 int _y;
304
305 assert(npixel != NULL && count > 0);
306 assert(value != NULL);
307 assert(nodata != NULL);
308
309 /* dimensions */
310 dim[0] = distancex * 2 + 1;
311 dim[1] = distancey * 2 + 1;
312 RASTER_DEBUGF(4, "dimensions = %d x %d", dim[0], dim[1]);
313
314 /* make sure that the dimx and dimy match mask */
315 if (mask != NULL) {
316 if (dim[0] != mask->dimx || dim[1] != mask->dimy) {
317 rterror("rt_pixel_set_array: mask dimensions %d x %d do not match given dims %d x %d", mask->dimx, mask->dimy, dim[0], dim[1]);
318 return ES_ERROR;
319 }
320
321 if (mask->values == NULL || mask->nodata == NULL) {
322 rterror("rt_pixel_set_array: Invalid mask");
323 return ES_ERROR;
324 }
325
326 }
327
328 /* establish 2D arrays (Y axis) */
329 values = rtalloc(sizeof(double *) * dim[1]);
330 nodatas = rtalloc(sizeof(int *) * dim[1]);
331
332 if (values == NULL || nodatas == NULL) {
333 rterror("rt_pixel_set_to_array: Could not allocate memory for 2D array");
334 return ES_ERROR;
335 }
336
337 /* initialize X axis */
338 for (i = 0; i < dim[1]; i++) {
339 values[i] = rtalloc(sizeof(double) * dim[0]);
340 nodatas[i] = rtalloc(sizeof(int) * dim[0]);
341
342 if (values[i] == NULL || nodatas[i] == NULL) {
343 rterror("rt_pixel_set_to_array: Could not allocate memory for dimension of 2D array");
344
345 if (values[i] == NULL) {
346 for (j = 0; j < i; j++) {
347 rtdealloc(values[j]);
348 rtdealloc(nodatas[j]);
349 }
350 }
351 else {
352 for (j = 0; j <= i; j++) {
353 rtdealloc(values[j]);
354 if (j < i)
355 rtdealloc(nodatas[j]);
356 }
357 }
358
359 rtdealloc(values);
360 rtdealloc(nodatas);
361
362 return ES_ERROR;
363 }
364
365 /* set values to 0 */
366 memset(values[i], 0, sizeof(double) * dim[0]);
367
368 /* set nodatas to 1 */
369 for (j = 0; j < dim[0]; j++)
370 nodatas[i][j] = 1;
371 }
372
373 /* get 0,0 of grid */
374 zero[0] = x - distancex;
375 zero[1] = y - distancey;
376
377 /* populate 2D arrays */
378 for (i = 0; i < count; i++) {
379 if (npixel[i].nodata)
380 continue;
381
382 _x = npixel[i].x - zero[0];
383 _y = npixel[i].y - zero[1];
384
385 RASTER_DEBUGF(4, "absolute x,y: %d x %d", npixel[i].x, npixel[i].y);
386 RASTER_DEBUGF(4, "relative x,y: %d x %d", _x, _y);
387
388 /* no mask */
389 if (mask == NULL) {
390 values[_y][_x] = npixel[i].value;
391 nodatas[_y][_x] = 0;
392 }
393 /* mask */
394 else {
395 /* unweighted (boolean) mask */
396 if (mask->weighted == 0) {
397 /* pixel is set to zero or nodata */
398 if (FLT_EQ(mask->values[_y][_x], 0.0) || mask->nodata[_y][_x] == 1)
399 {
400 values[_y][_x] = 0;
401 nodatas[_y][_x] = 1;
402 }
403 /* use pixel */
404 else {
405 values[_y][_x] = npixel[i].value;
406 nodatas[_y][_x] = 0;
407 }
408 }
409 /* weighted mask */
410 else {
411 /* nodata */
412 if(mask->nodata[_y][_x] == 1) {
413 values[_y][_x] = 0;
414 nodatas[_y][_x] = 1;
415 }
416 /* apply weight to pixel value */
417 else {
418 values[_y][_x] = npixel[i].value * mask->values[_y][_x];
419 nodatas[_y][_x] = 0;
420 }
421 }
422 }
423
424 RASTER_DEBUGF(4, "(x, y, nodata, value) = (%d, %d, %d, %f)", _x, _y, nodatas[_y][_x], values[_y][_x]);
425 }
426
427 *value = &(*values);
428 *nodata = &(*nodatas);
429 if (dimx != NULL)
430 *dimx = dim[0];
431 if (dimy != NULL)
432 *dimy = dim[1];
433
434 return ES_NONE;
435}
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
int8_t rt_util_clamp_to_8BSI(double value)
Definition rt_util.c:50
uint8_t rt_util_clamp_to_1BB(double value)
Definition rt_util.c:35
int32_t rt_util_clamp_to_32BSI(double value)
Definition rt_util.c:70
rt_pixtype
Definition librtcore.h:187
@ 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
#define FLT_EQ(x, y)
Definition librtcore.h:2424
uint8_t rt_util_clamp_to_2BUI(double value)
Definition rt_util.c:40
uint8_t rt_util_clamp_to_8BUI(double value)
Definition rt_util.c:55
rt_errorstate
Enum definitions.
Definition librtcore.h:181
@ ES_NONE
Definition librtcore.h:182
@ ES_ERROR
Definition librtcore.h:183
int16_t rt_util_clamp_to_16BSI(double value)
Definition rt_util.c:60
uint8_t rt_util_clamp_to_4BUI(double value)
Definition rt_util.c:45
void rtdealloc(void *mem)
Definition rt_context.c:206
uint16_t rt_util_clamp_to_16BUI(double value)
Definition rt_util.c:65
uint32_t rt_util_clamp_to_32BUI(double value)
Definition rt_util.c:75
float rt_util_clamp_to_32F(double value)
Definition rt_util.c:80
This library is the generic raster handling section of PostGIS.
rt_pixtype rt_pixtype_index_from_name(const char *pixname)
Definition rt_pixel.c:80
double rt_pixtype_get_min_value(rt_pixtype pixtype)
Return minimum value possible for pixel type.
Definition rt_pixel.c:150
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition rt_pixel.c:110
int rt_pixtype_alignment(rt_pixtype pixtype)
Return alignment requirements for data in the given pixel type.
Definition rt_pixel.c:75
rt_errorstate rt_pixtype_compare_clamped_values(rt_pixtype pixtype, double val, double refval, int *isequal)
Returns 1 if clamped values are equal, 0 if not equal, -1 if error.
Definition rt_pixel.c:202
rt_errorstate rt_pixel_set_to_array(rt_pixel npixel, uint32_t count, rt_mask mask, int x, int y, uint16_t distancex, uint16_t distancey, double ***value, int ***nodata, int *dimx, int *dimy)
Definition rt_pixel.c:288
int rt_pixtype_size(rt_pixtype pixtype)
Return size in bytes of a value in the given pixtype.
Definition rt_pixel.c:39
double ** values
Definition librtcore.h:2536
uint16_t dimy
Definition librtcore.h:2535
uint16_t dimx
Definition librtcore.h:2534
int ** nodata
Definition librtcore.h:2537
double value
Definition librtcore.h:2528