PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
rt_util.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) 2025 Darafei Praliaskouski <me@komzpa.net>
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#include "optionlist.h"
34
35uint8_t
36rt_util_clamp_to_1BB(double value) {
37 return (uint8_t)fmin(fmax((value), 0), POSTGIS_RT_1BBMAX);
38}
39
40uint8_t
41rt_util_clamp_to_2BUI(double value) {
42 return (uint8_t)fmin(fmax((value), 0), POSTGIS_RT_2BUIMAX);
43}
44
45uint8_t
46rt_util_clamp_to_4BUI(double value) {
47 return (uint8_t)fmin(fmax((value), 0), POSTGIS_RT_4BUIMAX);
48}
49
50int8_t
51rt_util_clamp_to_8BSI(double value) {
52 return (int8_t)fmin(fmax((value), SCHAR_MIN), SCHAR_MAX);
53}
54
55uint8_t
56rt_util_clamp_to_8BUI(double value) {
57 return (uint8_t)fmin(fmax((value), 0), UCHAR_MAX);
58}
59
60int16_t
62 return (int16_t)fmin(fmax((value), SHRT_MIN), SHRT_MAX);
63}
64
65uint16_t
67 return (uint16_t)fmin(fmax((value), 0), USHRT_MAX);
68}
69
70int32_t
72 return (int32_t)fmin(fmax((value), INT_MIN), INT_MAX);
73}
74
75uint32_t
77 return (uint32_t)fmin(fmax((value), 0), UINT_MAX);
78}
79
80float
81rt_util_clamp_to_32F(double value) {
82 if (isnan(value))
83 return value;
84 return (float)fmin(fmax((value), -FLT_MAX), FLT_MAX);
85}
86
87float
89{
90 /*
91 * GDAL exposes Float16 samples as raw 16-bit words, so we clamp to the
92 * representable range before packing them manually rather than
93 * depending on a runtime helper.
94 */
95 if (isnan(value))
96 return (float)value;
97 return (float)fmin(fmax((value), -POSTGIS_RT_16F_MAX), POSTGIS_RT_16F_MAX);
98}
99
100uint16_t
102{
103 /*
104 * Manual half-float conversion keeps raster I/O independent of GDAL's
105 * optional Float16 helpers while preserving IEEE semantics.
106 */
107 union {
108 float f;
109 uint32_t u;
110 } v;
111
112 v.f = value;
113
114 uint32_t sign = (v.u >> 16) & 0x8000U;
115 uint32_t mantissa = v.u & 0x7fffffU;
116 int32_t exponent = ((int32_t)((v.u >> 23) & 0xffU)) - 127 + 15;
117
118 if (exponent <= 0)
119 {
120 if (exponent < -10)
121 return (uint16_t)sign;
122
123 mantissa = (mantissa | 0x800000U) >> (uint32_t)(1 - exponent);
124 return (uint16_t)(sign | ((mantissa + 0x1000U) >> 13));
125 }
126
127 if (exponent >= 31)
128 return (uint16_t)(sign | 0x7c00U | (mantissa ? 0x200U : 0));
129
130 return (uint16_t)(sign | ((uint32_t)exponent << 10) | ((mantissa + 0x1000U) >> 13));
131}
132
133float
135{
136 union {
137 uint32_t u;
138 float f;
139 } v;
140
141 uint32_t sign = (uint32_t)(value & 0x8000U) << 16;
142 uint32_t exponent = (value >> 10) & 0x1fU;
143 uint32_t mantissa = value & 0x3ffU;
144
145 if (exponent == 0)
146 {
147 if (mantissa == 0)
148 {
149 v.u = sign;
150 }
151 else
152 {
153 exponent = 1;
154 while ((mantissa & 0x400U) == 0)
155 {
156 mantissa <<= 1;
157 exponent--;
158 }
159 mantissa &= 0x3ffU;
160 v.u = sign | ((exponent + 127 - 15) << 23) | (mantissa << 13);
161 }
162 }
163 else if (exponent == 31)
164 {
165 v.u = sign | 0x7f800000U | (mantissa << 13);
166 }
167 else
168 {
169 v.u = sign | ((exponent + 127 - 15) << 23) | (mantissa << 13);
170 }
171
172 return v.f;
173}
174
182GDALResampleAlg
183rt_util_gdal_resample_alg(const char *algname) {
184 assert(algname != NULL && strlen(algname) > 0);
185
186 if (strcmp(algname, "NEARESTNEIGHBOUR") == 0)
187 return GRA_NearestNeighbour;
188 else if (strcmp(algname, "NEARESTNEIGHBOR") == 0)
189 return GRA_NearestNeighbour;
190 else if (strcmp(algname, "BILINEAR") == 0)
191 return GRA_Bilinear;
192 else if (strcmp(algname, "CUBICSPLINE") == 0)
193 return GRA_CubicSpline;
194 else if (strcmp(algname, "CUBIC") == 0)
195 return GRA_Cubic;
196 else if (strcmp(algname, "LANCZOS") == 0)
197 return GRA_Lanczos;
198 else if (strcmp(algname, "MAX") == 0)
199 return GRA_Max;
200 else if (strcmp(algname, "MIN") == 0)
201 return GRA_Min;
202 return GRA_NearestNeighbour;
203}
204
212GDALDataType
214 switch (pt) {
215 case PT_1BB:
216 case PT_2BUI:
217 case PT_4BUI:
218 case PT_8BUI:
219 return GDT_Byte;
220 case PT_8BSI:
221#if POSTGIS_GDAL_VERSION >= 30700
222 return GDT_Int8;
223#endif
224 case PT_16BSI:
225 return GDT_Int16;
226 case PT_16BUI:
227 return GDT_UInt16;
228 case PT_32BSI:
229 return GDT_Int32;
230 case PT_32BUI:
231 return GDT_UInt32;
232#if POSTGIS_GDAL_VERSION >= 31100 && defined(GDT_Float16)
233 case PT_16BF:
234 return GDT_Float16;
235#endif
236 case PT_32BF:
237 return GDT_Float32;
238 case PT_64BF:
239 return GDT_Float64;
240 default:
241 return GDT_Unknown;
242 }
243
244 return GDT_Unknown;
245}
246
256 switch (gdt) {
257 case GDT_Byte:
258 return PT_8BUI;
259#if POSTGIS_GDAL_VERSION >= 30700
260 case GDT_Int8:
261 return PT_8BSI;
262#endif
263 case GDT_UInt16:
264 return PT_16BUI;
265 case GDT_Int16:
266 return PT_16BSI;
267 case GDT_UInt32:
268 return PT_32BUI;
269 case GDT_Int32:
270 return PT_32BSI;
271 case GDT_Float32:
272 return PT_32BF;
273 case GDT_Float64:
274 return PT_64BF;
275#if POSTGIS_GDAL_VERSION >= 31100 && defined(GDT_Float16)
276 case GDT_Float16:
277 return PT_16BF;
278#endif
279 default:
280 return PT_END;
281 }
282
283 return PT_END;
284}
285
286/*
287 get GDAL runtime version information
288*/
289const char*
290rt_util_gdal_version(const char *request) {
291 if (NULL == request || !strlen(request))
292 return GDALVersionInfo("RELEASE_NAME");
293 else
294 return GDALVersionInfo(request);
295}
296
297/*
298 computed extent type
299*/
301rt_util_extent_type(const char *name) {
302 assert(name != NULL && strlen(name) > 0);
303
304 if (strcmp(name, "UNION") == 0)
305 return ET_UNION;
306 else if (strcmp(name, "FIRST") == 0)
307 return ET_FIRST;
308 else if (strcmp(name, "SECOND") == 0)
309 return ET_SECOND;
310 else if (strcmp(name, "LAST") == 0)
311 return ET_LAST;
312 else if (strcmp(name, "CUSTOM") == 0)
313 return ET_CUSTOM;
314 else
315 return ET_INTERSECTION;
316}
317
318/*
319 convert the spatial reference string from a GDAL recognized format to either WKT or Proj4
320*/
321char*
322rt_util_gdal_convert_sr(const char *srs, int proj4) {
323 OGRSpatialReferenceH hsrs;
324 char *rtn = NULL;
325
326 assert(srs != NULL);
327
328 hsrs = OSRNewSpatialReference(NULL);
329 if (OSRSetFromUserInput(hsrs, srs) == OGRERR_NONE) {
330 if (proj4)
331 OSRExportToProj4(hsrs, &rtn);
332 else
333 OSRExportToWkt(hsrs, &rtn);
334 }
335 else {
336 rterror("rt_util_gdal_convert_sr: Could not process the provided srs: %s", srs);
337 return NULL;
338 }
339
340 OSRDestroySpatialReference(hsrs);
341 if (rtn == NULL) {
342 rterror("rt_util_gdal_convert_sr: Could not process the provided srs: %s", srs);
343 return NULL;
344 }
345
346 return rtn;
347}
348
349/*
350 is the spatial reference string supported by GDAL
351*/
352int
354 OGRSpatialReferenceH hsrs;
355 OGRErr rtn = OGRERR_NONE;
356
357 assert(srs != NULL);
358
359 hsrs = OSRNewSpatialReference(NULL);
360 rtn = OSRSetFromUserInput(hsrs, srs);
361 OSRDestroySpatialReference(hsrs);
362
363 if (rtn == OGRERR_NONE)
364 return 1;
365 else
366 return 0;
367}
368
380rt_util_gdal_sr_auth_info(GDALDatasetH hds, char **authname, char **authcode) {
381 const char *srs = NULL;
382
383 assert(authname != NULL);
384 assert(authcode != NULL);
385
386 *authname = NULL;
387 *authcode = NULL;
388
389 srs = GDALGetProjectionRef(hds);
390 if (srs != NULL && srs[0] != '\0') {
391 OGRSpatialReferenceH hSRS = OSRNewSpatialReference(NULL);
392
393 if (OSRSetFromUserInput(hSRS, srs) == OGRERR_NONE) {
394 const char* pszAuthorityName = OSRGetAuthorityName(hSRS, NULL);
395 const char* pszAuthorityCode = OSRGetAuthorityCode(hSRS, NULL);
396
397 if (pszAuthorityName != NULL && pszAuthorityCode != NULL) {
398 size_t authorityName_len = strlen(pszAuthorityName) +1;
399 size_t authorityCode_len = strlen(pszAuthorityCode) + 1;
400 *authname = rtalloc(sizeof(char) * authorityName_len);
401 *authcode = rtalloc(sizeof(char) * authorityCode_len);
402
403 if (*authname == NULL || *authcode == NULL) {
404 rterror("rt_util_gdal_sr_auth_info: Could not allocate memory for auth name and code");
405 if (*authname != NULL) rtdealloc(*authname);
406 if (*authcode != NULL) rtdealloc(*authcode);
407 OSRDestroySpatialReference(hSRS);
408 return ES_ERROR;
409 }
410
411 strncpy(*authname, pszAuthorityName, authorityName_len);
412 strncpy(*authcode, pszAuthorityCode, authorityCode_len);
413 }
414 }
415
416 OSRDestroySpatialReference(hSRS);
417 }
418
419 return ES_NONE;
420}
421
422/*
423 is GDAL configured correctly?
424*/
426
427 /* set of EPSG codes */
428 if (!rt_util_gdal_supported_sr("EPSG:4326"))
429 return 0;
430 if (!rt_util_gdal_supported_sr("EPSG:4269"))
431 return 0;
432 if (!rt_util_gdal_supported_sr("EPSG:4267"))
433 return 0;
434 if (!rt_util_gdal_supported_sr("EPSG:3310"))
435 return 0;
436
437 return 1;
438}
439
440/*
441 register all GDAL drivers
442*/
443int
444rt_util_gdal_register_all(int force_register_all) {
445 static int registered = 0;
446
447 if (registered && !force_register_all) {
448 RASTER_DEBUG(3, "Already called once... not calling GDALAllRegister");
449 return 0;
450 }
451
452 RASTER_DEBUG(3, "Calling GDALAllRegister");
453 GDALAllRegister();
454 registered = 1;
455
456 return 1;
457}
458
459/*
460 is the driver registered?
461*/
462int
464 int count = GDALGetDriverCount();
465 int i = 0;
466 GDALDriverH hdrv = NULL;
467
468 if (drv == NULL || !strlen(drv) || count < 1)
469 return 0;
470
471 for (i = 0; i < count; i++) {
472 hdrv = GDALGetDriver(i);
473 if (hdrv == NULL) continue;
474
475 if (strcmp(drv, GDALGetDriverShortName(hdrv)) == 0)
476 return 1;
477 }
478
479 return 0;
480}
481
482/* variable for PostgreSQL GUC: postgis.gdal_enabled_drivers */
484
485
486
487/*
488 wrapper for GDALOpen and GDALOpenShared
489*/
490GDALDatasetH
492 const char *fn,
493 GDALAccess fn_access,
494 int shared
495) {
496 char *vsi_options_str = rtoptions("gdal_vsi_options");
497
498 /* Parse vsi options string */
499 if (vsi_options_str && strlen(vsi_options_str) > 0) {
500 size_t sz;
501 char *olist[OPTION_LIST_SIZE];
502 rtinfo("postgis.gdal_vsi_options is set");
503 memset(olist, 0, sizeof(olist));
504 option_list_parse(vsi_options_str, olist);
505 sz = option_list_length(olist);
506 if (sz % 2 == 0) {
507 size_t i;
508 for (i = 0; i < sz; i += 2)
509 {
510 char *key = olist[i];
511 char *val = olist[i+1];
512 /* GDAL_SKIP is where the disallowed drivers are set */
513 /* We cannot allow user-level over-ride of that config option */
514 if (strcmp(key, "gdal_skip") == 0) {
515 rtwarn("Unable to set GDAL_SKIP config option");
516 continue;
517 }
518 rtinfo("CPLSetConfigOption(%s)", key);
519 CPLSetConfigOption(key, val);
520 }
521 }
522 }
523
524 unsigned int open_flags;
525 assert(NULL != fn);
526
527 if (gdal_enabled_drivers != NULL) {
528 if (strstr(gdal_enabled_drivers, GDAL_DISABLE_ALL) != NULL) {
529 rterror("rt_util_gdal_open: Cannot open file. All GDAL drivers disabled");
530 return NULL;
531 }
532 else if (strstr(gdal_enabled_drivers, GDAL_ENABLE_ALL) != NULL) {
533 /* do nothing */
534 }
535 else if (
536 (strstr(fn, "/vsi") != NULL) &&
537 (strstr(fn, "/vsimem") == NULL) &&
538 (strstr(gdal_enabled_drivers, GDAL_VSICURL) == NULL)
539 ) {
540 rterror("rt_util_gdal_open: Cannot open %s file. %s disabled", GDAL_VSICURL, GDAL_VSICURL);
541 return NULL;
542 }
543 }
544
545 open_flags = GDAL_OF_RASTER
546 | GDAL_OF_VERBOSE_ERROR
547 | (fn_access == GA_Update ? GDAL_OF_UPDATE : 0)
548 | (shared ? GDAL_OF_SHARED : 0);
549
550 return GDALOpenEx(fn /* filename */,
551 open_flags,
552 NULL, /* allowed drivers */
553 NULL, /* open options */
554 NULL /* sibling files */
555 );
556}
557
558void
560 OGREnvelope env,
561 rt_envelope *ext
562) {
563 assert(ext != NULL);
564
565 ext->MinX = env.MinX;
566 ext->MaxX = env.MaxX;
567 ext->MinY = env.MinY;
568 ext->MaxY = env.MaxY;
569
570 ext->UpperLeftX = env.MinX;
571 ext->UpperLeftY = env.MaxY;
572}
573
574void
576 rt_envelope ext,
577 OGREnvelope *env
578) {
579 assert(env != NULL);
580
581 env->MinX = ext.MinX;
582 env->MaxX = ext.MaxX;
583 env->MinY = ext.MinY;
584 env->MaxY = ext.MaxY;
585}
586
587LWPOLY *
589 rt_envelope env
590) {
591 LWPOLY *npoly = NULL;
592 POINTARRAY **rings = NULL;
593 POINTARRAY *pts = NULL;
594 POINT4D p4d;
595
596 rings = (POINTARRAY **) rtalloc(sizeof (POINTARRAY*));
597 if (!rings) {
598 rterror("rt_util_envelope_to_lwpoly: Out of memory building envelope's geometry");
599 return NULL;
600 }
601 rings[0] = ptarray_construct(0, 0, 5);
602 if (!rings[0]) {
603 rterror("rt_util_envelope_to_lwpoly: Out of memory building envelope's geometry ring");
604 return NULL;
605 }
606
607 pts = rings[0];
608
609 /* Upper-left corner (first and last points) */
610 p4d.x = env.MinX;
611 p4d.y = env.MaxY;
612 ptarray_set_point4d(pts, 0, &p4d);
613 ptarray_set_point4d(pts, 4, &p4d);
614
615 /* Upper-right corner (we go clockwise) */
616 p4d.x = env.MaxX;
617 p4d.y = env.MaxY;
618 ptarray_set_point4d(pts, 1, &p4d);
619
620 /* Lower-right corner */
621 p4d.x = env.MaxX;
622 p4d.y = env.MinY;
623 ptarray_set_point4d(pts, 2, &p4d);
624
625 /* Lower-left corner */
626 p4d.x = env.MinX;
627 p4d.y = env.MinY;
628 ptarray_set_point4d(pts, 3, &p4d);
629
630 npoly = lwpoly_construct(SRID_UNKNOWN, 0, 1, rings);
631 if (npoly == NULL) {
632 rterror("rt_util_envelope_to_lwpoly: Could not build envelope's geometry");
633 return NULL;
634 }
635
636 return npoly;
637}
638
639int
640rt_util_same_geotransform_matrix(double *gt1, double *gt2) {
641 int k = 0;
642
643 if (gt1 == NULL || gt2 == NULL)
644 return FALSE;
645
646 for (k = 0; k < 6; k++) {
647 if (FLT_NEQ(gt1[k], gt2[k]))
648 return FALSE;
649 }
650
651 return TRUE;
652}
653
654/* coordinates in RGB and HSV are floating point values between 0 and 1 */
656rt_util_rgb_to_hsv(double rgb[3], double hsv[3]) {
657 int i;
658
659 double minc;
660 double maxc;
661
662 double h = 0.;
663 double s = 0.;
664 double v = 0.;
665
666 minc = rgb[0];
667 maxc = rgb[0];
668
669 /* get min and max values from RGB */
670 for (i = 1; i < 3; i++) {
671 if (rgb[i] > maxc)
672 maxc = rgb[i];
673 if (rgb[i] < minc)
674 minc = rgb[i];
675 }
676 v = maxc;
677
678 if (maxc != minc) {
679 double diff = 0.;
680 double rc = 0.;
681 double gc = 0.;
682 double bc = 0.;
683 double junk = 0.;
684
685 diff = maxc - minc;
686 s = diff / maxc;
687 rc = (maxc - rgb[0]) / diff;
688 gc = (maxc - rgb[1]) / diff;
689 bc = (maxc - rgb[2]) / diff;
690
691 if (DBL_EQ(rgb[0], maxc))
692 h = bc - gc;
693 else if (DBL_EQ(rgb[1], maxc))
694 h = 2.0 + rc - bc;
695 else
696 h = 4.0 + gc - rc;
697
698 h = modf((h / 6.0), &junk);
699 }
700
701 hsv[0] = h;
702 hsv[1] = s;
703 hsv[2] = v;
704
705 return ES_NONE;
706}
707
708/* coordinates in RGB and HSV are floating point values between 0 and 1 */
710rt_util_hsv_to_rgb(double hsv[3], double rgb[3]) {
711 double r = 0;
712 double g = 0;
713 double b = 0;
714 double v = hsv[2];
715
716 if (DBL_EQ(hsv[1], 0.))
717 r = g = b = v;
718 else {
719 double i;
720 double f;
721 double p;
722 double q;
723 double t;
724
725 int a;
726
727 i = floor(hsv[0] * 6.);
728 f = (hsv[0] * 6.0) - i;
729 p = v * (1. - hsv[1]);
730 q = v * (1. - hsv[1] * f);
731 t = v * (1. - hsv[1] * (1. - f));
732
733 a = (int) i;
734 switch (a) {
735 case 1:
736 r = q;
737 g = v;
738 b = p;
739 break;
740 case 2:
741 r = p;
742 g = v;
743 b = t;
744 break;
745 case 3:
746 r = p;
747 g = q;
748 b = v;
749 break;
750 case 4:
751 r = t;
752 g = p;
753 b = v;
754 break;
755 case 5:
756 r = v;
757 g = p;
758 b = q;
759 break;
760 case 0:
761 case 6:
762 default:
763 r = v;
764 g = t;
765 b = p;
766 break;
767 }
768 }
769
770 rgb[0] = r;
771 rgb[1] = g;
772 rgb[2] = b;
773
774 return ES_NONE;
775}
776
777int
779 double initialvalue,
780 int32_t checkvalint, uint32_t checkvaluint,
781 float checkvalfloat, double checkvaldouble,
782 rt_pixtype pixtype
783) {
784 int result = 0;
785
786 switch (pixtype) {
787 case PT_1BB:
788 case PT_2BUI:
789 case PT_4BUI:
790 case PT_8BSI:
791 case PT_8BUI:
792 case PT_16BSI:
793 case PT_16BUI:
794 case PT_32BSI: {
795 if (fabs(checkvalint - initialvalue) >= 1) {
796#if POSTGIS_RASTER_WARN_ON_TRUNCATION > 0
797 rtwarn("Value set for %s band got clamped from %f to %d",
798 rt_pixtype_name(pixtype),
799 initialvalue, checkvalint
800 );
801#endif
802 result = 1;
803 }
804 else if (checkvalint != initialvalue)
805 {
806#if POSTGIS_RASTER_WARN_ON_TRUNCATION > 0
807 rtwarn("Value set for %s band got truncated from %f to %d",
808 rt_pixtype_name(pixtype),
809 initialvalue, checkvalint
810 );
811#endif
812 result = 1;
813 }
814 break;
815 }
816 case PT_32BUI: {
817 if (fabs(checkvaluint - initialvalue) >= 1)
818 {
819#if POSTGIS_RASTER_WARN_ON_TRUNCATION > 0
820 rtwarn("Value set for %s band got clamped from %f to %u",
821 rt_pixtype_name(pixtype),
822 initialvalue,
823 checkvaluint);
824#endif
825 result = 1;
826 }
827 else if (checkvaluint != initialvalue)
828 {
829#if POSTGIS_RASTER_WARN_ON_TRUNCATION > 0
830 rtwarn("Value set for %s band got truncated from %f to %u",
831 rt_pixtype_name(pixtype),
832 initialvalue, checkvaluint
833 );
834#endif
835 result = 1;
836 }
837 break;
838 }
839 case PT_16BF:
840 case PT_32BF: {
841 /*
842 For float, because the initial value is a double,
843 there is very often a difference between the desired value and the obtained one
844 */
845 if (FLT_NEQ(checkvalfloat, initialvalue)) {
846#if POSTGIS_RASTER_WARN_ON_TRUNCATION > 0
847 rtwarn("Value set for %s band got converted from %f to %f",
848 rt_pixtype_name(pixtype),
849 initialvalue, checkvalfloat
850 );
851#endif
852 result = 1;
853 }
854 break;
855 }
856 case PT_64BF: {
857 if (FLT_NEQ(checkvaldouble, initialvalue)) {
858#if POSTGIS_RASTER_WARN_ON_TRUNCATION > 0
859 rtwarn("Value set for %s band got converted from %f to %f",
860 rt_pixtype_name(pixtype),
861 initialvalue, checkvaldouble
862 );
863#endif
864 result = 1;
865 }
866 break;
867 }
868 case PT_END:
869 break;
870 }
871
872 return result;
873}
874
char * s
Definition cu_in_wkt.c:23
char * r
Definition cu_in_wkt.c:24
char result[OUT_DOUBLE_BUFFER_SIZE]
Definition cu_print.c:267
#define TRUE
Definition dbfopen.c:73
#define FALSE
Definition dbfopen.c:72
LWPOLY * lwpoly_construct(int32_t srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
Definition lwpoly.c:43
#define SRID_UNKNOWN
Unknown SRID value.
Definition liblwgeom.h:215
void ptarray_set_point4d(POINTARRAY *pa, uint32_t n, const POINT4D *p4d)
Definition lwgeom_api.c:369
POINTARRAY * ptarray_construct(char hasz, char hasm, uint32_t npoints)
Construct an empty pointarray, allocating storage and setting the npoints, but not filling in any inf...
Definition ptarray.c:51
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 FLT_NEQ(x, y)
Definition librtcore.h:2435
#define RASTER_DEBUG(level, msg)
Definition librtcore.h:304
void void rtinfo(const char *fmt,...) __attribute__((format(printf
void void void rtwarn(const char *fmt,...) __attribute__((format(printf
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 POSTGIS_RT_4BUIMAX
Definition librtcore.h:2253
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition rt_pixel.c:114
void void void char * rtoptions(const char *varname)
Wrappers used for options.
Definition rt_context.c:256
rt_errorstate
Enum definitions.
Definition librtcore.h:181
@ ES_NONE
Definition librtcore.h:182
@ ES_ERROR
Definition librtcore.h:183
#define DBL_EQ(x, y)
Definition librtcore.h:2438
#define GDAL_ENABLE_ALL
Definition librtcore.h:2239
#define GDAL_DISABLE_ALL
Definition librtcore.h:2240
#define GDAL_VSICURL
Definition librtcore.h:2241
rt_extenttype
Definition librtcore.h:204
@ ET_CUSTOM
Definition librtcore.h:210
@ ET_LAST
Definition librtcore.h:209
@ ET_INTERSECTION
Definition librtcore.h:205
@ ET_UNION
Definition librtcore.h:206
@ ET_SECOND
Definition librtcore.h:208
@ ET_FIRST
Definition librtcore.h:207
#define POSTGIS_RT_16F_MAX
Definition librtcore.h:2254
#define POSTGIS_RT_2BUIMAX
Definition librtcore.h:2252
#define POSTGIS_RT_1BBMAX
Definition librtcore.h:2251
void rtdealloc(void *mem)
Definition rt_context.c:206
This library is the generic raster handling section of PostGIS.
size_t option_list_length(char **olist)
Returns the total number of keys and values in the list.
Definition optionlist.c:73
void option_list_parse(char *input, char **olist)
option_list is a null-terminated list of strings, where every odd string is a key and every even stri...
Definition optionlist.c:86
#define OPTION_LIST_SIZE
Definition optionlist.h:31
rt_pixtype rt_util_gdal_datatype_to_pixtype(GDALDataType gdt)
Convert GDALDataType to rt_pixtype.
Definition rt_util.c:255
rt_errorstate rt_util_rgb_to_hsv(double rgb[3], double hsv[3])
Definition rt_util.c:656
int rt_util_gdal_register_all(int force_register_all)
Definition rt_util.c:444
int rt_util_gdal_configured(void)
Definition rt_util.c:425
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
uint16_t rt_util_float_to_float16(float value)
Definition rt_util.c:101
float rt_util_float16_to_float(uint16_t value)
Definition rt_util.c:134
char * rt_util_gdal_convert_sr(const char *srs, int proj4)
Definition rt_util.c:322
rt_extenttype rt_util_extent_type(const char *name)
Definition rt_util.c:301
int rt_util_dbl_trunc_warning(double initialvalue, int32_t checkvalint, uint32_t checkvaluint, float checkvalfloat, double checkvaldouble, rt_pixtype pixtype)
Definition rt_util.c:778
GDALDataType rt_util_pixtype_to_gdal_datatype(rt_pixtype pt)
Convert rt_pixtype to GDALDataType.
Definition rt_util.c:213
uint8_t rt_util_clamp_to_2BUI(double value)
Definition rt_util.c:41
const char * rt_util_gdal_version(const char *request)
Definition rt_util.c:290
uint8_t rt_util_clamp_to_8BUI(double value)
Definition rt_util.c:56
GDALDatasetH rt_util_gdal_open(const char *fn, GDALAccess fn_access, int shared)
Definition rt_util.c:491
int rt_util_gdal_supported_sr(const char *srs)
Definition rt_util.c:353
int16_t rt_util_clamp_to_16BSI(double value)
Definition rt_util.c:61
GDALResampleAlg rt_util_gdal_resample_alg(const char *algname)
Convert cstring name to GDAL Resample Algorithm.
Definition rt_util.c:183
int rt_util_gdal_driver_registered(const char *drv)
Definition rt_util.c:463
uint8_t rt_util_clamp_to_4BUI(double value)
Definition rt_util.c:46
rt_errorstate rt_util_hsv_to_rgb(double hsv[3], double rgb[3])
Definition rt_util.c:710
void rt_util_to_ogr_envelope(rt_envelope ext, OGREnvelope *env)
Definition rt_util.c:575
LWPOLY * rt_util_envelope_to_lwpoly(rt_envelope env)
Definition rt_util.c:588
rt_errorstate rt_util_gdal_sr_auth_info(GDALDatasetH hds, char **authname, char **authcode)
Get auth name and code.
Definition rt_util.c:380
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
char * gdal_enabled_drivers
Definition rt_util.c:483
int rt_util_same_geotransform_matrix(double *gt1, double *gt2)
Definition rt_util.c:640
float rt_util_clamp_to_32F(double value)
Definition rt_util.c:81
void rt_util_from_ogr_envelope(OGREnvelope env, rt_envelope *ext)
Definition rt_util.c:559
double x
Definition liblwgeom.h:414
double y
Definition liblwgeom.h:414
double MinX
Definition librtcore.h:167
double UpperLeftY
Definition librtcore.h:173
double UpperLeftX
Definition librtcore.h:172
double MaxX
Definition librtcore.h:168
double MinY
Definition librtcore.h:169
double MaxY
Definition librtcore.h:170