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