[SCM] PostGIS branch master updated. 3.6.0rc2-238-gef19e8fb4
git at osgeo.org
git at osgeo.org
Sun Nov 30 12:07:02 PST 2025
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "PostGIS".
The branch, master has been updated
via ef19e8fb446e05d42f54adc59d51ebdf2e88c5e0 (commit)
from eebec8c1cdf57805289c85ce9e155d386a860256 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit ef19e8fb446e05d42f54adc59d51ebdf2e88c5e0
Author: Darafei Praliaskouski <me at komzpa.net>
Date: Mon Dec 1 00:06:43 2025 +0400
[raster] Support GDT_Float16 pixel type
Closes #5941
diff --git a/NEWS b/NEWS
index 3401fe5f0..3d974e88c 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,7 @@ xxxx/xx/xx
(Sandro Santilli)
- #6001, support MultiLineString in ST_MakeLine (Paul Ramsey)
- #2858, ST_MMin and ST_MMax (Paul Ramsey)
+ - #5941, [raster] Support GDT_Float16 pixel type (Darafei Praliaskouski)
- #5992, Optimize GiST index for repeated edge subdivision in topology (Darafei Praliaskouski)
- #5702, Allow the compiler to detect the parallelism -flto=auto (Darafei Praliaskouski)
- #4798, ST_AsGeoJSON warns about duplicate property keys (Darafei Praliaskouski)
diff --git a/raster/doc/RFC1-SerializedFormat b/raster/doc/RFC1-SerializedFormat
index 8b143b5eb..519d2ac9b 100644
--- a/raster/doc/RFC1-SerializedFormat
+++ b/raster/doc/RFC1-SerializedFormat
@@ -114,7 +114,7 @@ will be of 7 bytes.
as part of the datum or is to be found on the server's
filesystem.
- There are currently 11 supported pixel value types, so 4
+ There are currently 12 supported pixel value types, so 4
bits are enough to account for all. We'll reserve
the upper 4 bits for generic flags and define upmost as
storage flag:
@@ -135,7 +135,7 @@ will be of 7 bytes.
- PT_1BB, PT_2BUI, PT_4BUI, PT_8BSI, PT_8BUI:
No alignment required, each value is 1 byte.
- - PT_16BSI, PT_16BUI:
+ - PT_16BSI, PT_16BUI, PT_16BF:
Data must be aligned to 2-bytes boundary.
- PT_32BSI, PT_32BUI, PT_32BF:
diff --git a/raster/rt_core/librtcore.h b/raster/rt_core/librtcore.h
index ded95f1c9..6847319cf 100644
--- a/raster/rt_core/librtcore.h
+++ b/raster/rt_core/librtcore.h
@@ -184,19 +184,21 @@ typedef enum {
} rt_errorstate;
/* Pixel types */
-typedef enum {
- PT_1BB=0, /* 1-bit boolean */
- PT_2BUI=1, /* 2-bit unsigned integer */
- PT_4BUI=2, /* 4-bit unsigned integer */
- PT_8BSI=3, /* 8-bit signed integer */
- PT_8BUI=4, /* 8-bit unsigned integer */
- PT_16BSI=5, /* 16-bit signed integer */
- PT_16BUI=6, /* 16-bit unsigned integer */
- PT_32BSI=7, /* 32-bit signed integer */
- PT_32BUI=8, /* 32-bit unsigned integer */
- PT_32BF=10, /* 32-bit float */
- PT_64BF=11, /* 64-bit float */
- PT_END=13
+typedef enum
+{
+ PT_1BB = 0, /* 1-bit boolean */
+ PT_2BUI = 1, /* 2-bit unsigned integer */
+ PT_4BUI = 2, /* 4-bit unsigned integer */
+ PT_8BSI = 3, /* 8-bit signed integer */
+ PT_8BUI = 4, /* 8-bit unsigned integer */
+ PT_16BSI = 5, /* 16-bit signed integer */
+ PT_16BUI = 6, /* 16-bit unsigned integer */
+ PT_32BSI = 7, /* 32-bit signed integer */
+ PT_32BUI = 8, /* 32-bit unsigned integer */
+ PT_16BF = 9, /* 16-bit float */
+ PT_32BF = 10, /* 32-bit float */
+ PT_64BF = 11, /* 64-bit float */
+ PT_END = 13
} rt_pixtype;
typedef enum {
@@ -2249,6 +2251,7 @@ extern void rtdealloc(void *mem);
#define POSTGIS_RT_1BBMAX 1
#define POSTGIS_RT_2BUIMAX 3
#define POSTGIS_RT_4BUIMAX 15
+#define POSTGIS_RT_16F_MAX 65504.0F
uint8_t
rt_util_clamp_to_1BB(double value);
@@ -2280,6 +2283,12 @@ rt_util_clamp_to_32BUI(double value);
float
rt_util_clamp_to_32F(double value);
+float rt_util_clamp_to_16F(double value);
+
+uint16_t rt_util_float_to_float16(float value);
+
+float rt_util_float16_to_float(uint16_t value);
+
int
rt_util_dbl_trunc_warning(
double initialvalue,
diff --git a/raster/rt_core/rt_band.c b/raster/rt_core/rt_band.c
index 4578609a2..2cbe92ead 100644
--- a/raster/rt_core/rt_band.c
+++ b/raster/rt_core/rt_band.c
@@ -11,6 +11,7 @@
* Copyright (C) 2009-2011 Pierre Racine <pierre.racine at sbf.ulaval.ca>
* Copyright (C) 2009-2011 Mateusz Loskot <mateusz at loskot.net>
* Copyright (C) 2008-2009 Sandro Santilli <strk at kbt.io>
+ * Copyright (C) 2025 Darafei Praliaskouski <me at komzpa.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -189,8 +190,7 @@ rt_band_init_value(
checkvalint = ptr[0];
break;
}
- case PT_16BUI:
- {
+ case PT_16BUI: {
uint16_t *ptr = mem;
uint16_t clamped_initval = rt_util_clamp_to_16BUI(initval);
for (uint32_t i = 0; i < numval; i++)
@@ -198,8 +198,16 @@ rt_band_init_value(
checkvalint = ptr[0];
break;
}
- case PT_32BSI:
- {
+ case PT_16BF: {
+ uint16_t *ptr = mem;
+ float clamped_initval = rt_util_clamp_to_16F(initval);
+ uint16_t packed = rt_util_float_to_float16(clamped_initval);
+ for (uint32_t i = 0; i < numval; i++)
+ ptr[i] = packed;
+ checkvalfloat = rt_util_float16_to_float(ptr[0]);
+ break;
+ }
+ case PT_32BSI: {
int32_t *ptr = mem;
int32_t clamped_initval = rt_util_clamp_to_32BSI(initval);
for (uint32_t i = 0; i < numval; i++)
@@ -944,6 +952,13 @@ rt_band_set_nodata(rt_band band, double val, int *converted) {
checkvaluint = band->nodataval;
break;
}
+ case PT_16BF: {
+ float half = rt_util_clamp_to_16F(val);
+ /* Persist the exact half-float encoding so nodata comparisons stay bitwise-stable. */
+ band->nodataval = rt_util_float16_to_float(rt_util_float_to_float16(half));
+ checkvalfloat = (float)band->nodataval;
+ break;
+ }
case PT_32BF: {
band->nodataval = rt_util_clamp_to_32F(val);
checkvalfloat = band->nodataval;
@@ -1178,12 +1193,13 @@ rt_band_set_pixel(
data = rt_band_get_data(band);
offset = x + (y * band->width);
- switch (pixtype) {
- case PT_1BB: {
- data[offset] = rt_util_clamp_to_1BB(val);
- checkvalint = data[offset];
- break;
- }
+ switch (pixtype)
+ {
+ case PT_1BB: {
+ data[offset] = rt_util_clamp_to_1BB(val);
+ checkvalint = data[offset];
+ break;
+ }
case PT_2BUI: {
data[offset] = rt_util_clamp_to_2BUI(val);
checkvalint = data[offset];
@@ -1223,13 +1239,21 @@ rt_band_set_pixel(
break;
}
case PT_32BUI: {
- uint32_t *ptr = (uint32_t*) data; /* we assume correct alignment */
+ uint32_t *ptr = (uint32_t *)data; /* we assume correct alignment */
ptr[offset] = rt_util_clamp_to_32BUI(val);
checkvaluint = ptr[offset];
break;
}
+ case PT_16BF: {
+ uint16_t *ptr = (uint16_t *)data; /* we assume correct alignment */
+ float clamped = rt_util_clamp_to_16F(val);
+ /* Pack via explicit converter to mirror GDAL's Float16 representation. */
+ ptr[offset] = rt_util_float_to_float16(clamped);
+ checkvalfloat = rt_util_float16_to_float(ptr[offset]);
+ break;
+ }
case PT_32BF: {
- float *ptr = (float*) data; /* we assume correct alignment */
+ float *ptr = (float *)data; /* we assume correct alignment */
ptr[offset] = rt_util_clamp_to_32F(val);
checkvalfloat = ptr[offset];
break;
@@ -1244,7 +1268,7 @@ rt_band_set_pixel(
rterror("rt_band_set_pixel: Unknown pixeltype %d", pixtype);
return ES_ERROR;
}
- }
+ }
/* If the stored value is not NODATA, reset the isnodata flag */
if (!rt_band_clamped_value_is_nodata(band, val)) {
@@ -1631,12 +1655,17 @@ rt_band_get_pixel(
break;
}
case PT_32BUI: {
- uint32_t *ptr = (uint32_t*) data; /* we assume correct alignment */
+ uint32_t *ptr = (uint32_t *)data; /* we assume correct alignment */
*value = ptr[offset];
break;
}
+ case PT_16BF: {
+ uint16_t *ptr = (uint16_t *)data; /* we assume correct alignment */
+ *value = rt_util_float16_to_float(ptr[offset]);
+ break;
+ }
case PT_32BF: {
- float *ptr = (float*) data; /* we assume correct alignment */
+ float *ptr = (float *)data; /* we assume correct alignment */
*value = ptr[offset];
break;
}
@@ -2213,6 +2242,12 @@ rt_band_corrected_clamped_value(
else
(*newval)--;
break;
+ case PT_16BF:
+ if (FLT_EQ(rt_util_clamp_to_16F(val), rt_util_clamp_to_16F(minval)))
+ *newval += FLT_EPSILON;
+ else
+ *newval -= FLT_EPSILON;
+ break;
case PT_32BF:
if (FLT_EQ(rt_util_clamp_to_32F(val), rt_util_clamp_to_32F(minval)))
*newval += FLT_EPSILON;
diff --git a/raster/rt_core/rt_pixel.c b/raster/rt_core/rt_pixel.c
index d35298fea..15793e82e 100644
--- a/raster/rt_core/rt_pixel.c
+++ b/raster/rt_core/rt_pixel.c
@@ -11,6 +11,7 @@
* Copyright (C) 2009-2011 Mateusz Loskot <mateusz at loskot.net>
* Copyright (C) 2008-2009 Sandro Santilli <strk at kbt.io>
* Copyright (C) 2013 Nathaniel Hunter Clay <clay.nathaniel at gmail.com>
+ * Copyright (C) 2025 Darafei Praliaskouski <me at komzpa.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -49,6 +50,7 @@ rt_pixtype_size(rt_pixtype pixtype) {
break;
case PT_16BSI:
case PT_16BUI:
+ case PT_16BF:
pixbytes = 2;
break;
case PT_32BSI:
@@ -94,6 +96,8 @@ rt_pixtype_index_from_name(const char* pixname) {
return PT_16BSI;
else if (strcmp(pixname, "16BUI") == 0)
return PT_16BUI;
+ else if (strcmp(pixname, "16BF") == 0)
+ return PT_16BF;
else if (strcmp(pixname, "32BSI") == 0)
return PT_32BSI;
else if (strcmp(pixname, "32BUI") == 0)
@@ -125,6 +129,8 @@ rt_pixtype_name(rt_pixtype pixtype) {
return "16BSI";
case PT_16BUI:
return "16BUI";
+ case PT_16BF:
+ return "16BF";
case PT_32BSI:
return "32BSI";
case PT_32BUI:
@@ -170,8 +176,11 @@ rt_pixtype_get_min_value(rt_pixtype pixtype) {
case PT_16BUI: {
return 0;
}
+ case PT_16BF: {
+ return (double)-POSTGIS_RT_16F_MAX;
+ }
case PT_32BSI: {
- return (double) rt_util_clamp_to_32BSI((double) INT_MIN);
+ return (double)rt_util_clamp_to_32BSI((double)INT_MIN);
}
case PT_32BUI: {
return 0;
@@ -236,6 +245,10 @@ rt_errorstate rt_pixtype_compare_clamped_values(
if (rt_util_clamp_to_16BUI(val) == rt_util_clamp_to_16BUI(refval))
*isequal = 1;
break;
+ case PT_16BF:
+ if (FLT_EQ(rt_util_clamp_to_16F(val), rt_util_clamp_to_16F(refval)))
+ *isequal = 1;
+ break;
case PT_32BSI:
if (rt_util_clamp_to_32BSI(val) == rt_util_clamp_to_32BSI(refval))
*isequal = 1;
diff --git a/raster/rt_core/rt_serialize.c b/raster/rt_core/rt_serialize.c
index 4673b3e0c..dbb7cd527 100644
--- a/raster/rt_core/rt_serialize.c
+++ b/raster/rt_core/rt_serialize.c
@@ -10,6 +10,7 @@
* Copyright (C) 2009-2011 Pierre Racine <pierre.racine at sbf.ulaval.ca>
* Copyright (C) 2009-2011 Mateusz Loskot <mateusz at loskot.net>
* Copyright (C) 2008-2009 Sandro Santilli <strk at kbt.io>
+ * Copyright (C) 2025 Darafei Praliaskouski <me at komzpa.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -653,6 +654,12 @@ rt_raster_serialize(rt_raster raster) {
ptr += 4;
break;
}
+ case PT_16BF: {
+ uint16_t v = rt_util_float_to_float16((float)band->nodataval);
+ memcpy(ptr, &v, 2);
+ ptr += 2;
+ break;
+ }
case PT_32BF: {
float v = band->nodataval;
memcpy(ptr, &v, 4);
@@ -849,6 +856,10 @@ rt_raster_deserialize(void* serialized, int header_only) {
band->nodataval = read_uint32(&ptr, littleEndian);
break;
}
+ case PT_16BF: {
+ band->nodataval = rt_util_float16_to_float(read_uint16(&ptr, littleEndian));
+ break;
+ }
case PT_32BF: {
band->nodataval = read_float32(&ptr, littleEndian);
break;
diff --git a/raster/rt_core/rt_statistics.c b/raster/rt_core/rt_statistics.c
index b5a6c7025..8be627161 100644
--- a/raster/rt_core/rt_statistics.c
+++ b/raster/rt_core/rt_statistics.c
@@ -10,6 +10,7 @@
* Copyright (C) 2009-2011 Pierre Racine <pierre.racine at sbf.ulaval.ca>
* Copyright (C) 2009-2011 Mateusz Loskot <mateusz at loskot.net>
* Copyright (C) 2008-2009 Sandro Santilli <strk at kbt.io>
+ * Copyright (C) 2025 Darafei Praliaskouski <me at komzpa.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -1683,11 +1684,14 @@ rt_band_get_value_count(
roundto = 0;
break;
/* floating points, check the rounding */
+ case PT_16BF:
case PT_32BF:
case PT_64BF:
- for (scale = 0; scale <= 20; scale++) {
+ for (scale = 0; scale <= 20; scale++)
+ {
tmpd = roundto * pow(10, scale);
- if (FLT_EQ((tmpd - ((int) tmpd)), 0.0)) break;
+ if (FLT_EQ((tmpd - ((int)tmpd)), 0.0))
+ break;
}
break;
case PT_END:
diff --git a/raster/rt_core/rt_util.c b/raster/rt_core/rt_util.c
index e3e1f5415..95f4eb8f3 100644
--- a/raster/rt_core/rt_util.c
+++ b/raster/rt_core/rt_util.c
@@ -10,6 +10,7 @@
* Copyright (C) 2009-2011 Pierre Racine <pierre.racine at sbf.ulaval.ca>
* Copyright (C) 2009-2011 Mateusz Loskot <mateusz at loskot.net>
* Copyright (C) 2008-2009 Sandro Santilli <strk at kbt.io>
+ * Copyright (C) 2025 Darafei Praliaskouski <me at komzpa.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -83,6 +84,94 @@ rt_util_clamp_to_32F(double value) {
return (float)fmin(fmax((value), -FLT_MAX), FLT_MAX);
}
+float
+rt_util_clamp_to_16F(double value)
+{
+ /*
+ * GDAL exposes Float16 samples as raw 16-bit words, so we clamp to the
+ * representable range before packing them manually rather than
+ * depending on a runtime helper.
+ */
+ if (isnan(value))
+ return (float)value;
+ return (float)fmin(fmax((value), -POSTGIS_RT_16F_MAX), POSTGIS_RT_16F_MAX);
+}
+
+uint16_t
+rt_util_float_to_float16(float value)
+{
+ /*
+ * Manual half-float conversion keeps raster I/O independent of GDAL's
+ * optional Float16 helpers while preserving IEEE semantics.
+ */
+ union {
+ float f;
+ uint32_t u;
+ } v;
+
+ v.f = value;
+
+ uint32_t sign = (v.u >> 16) & 0x8000U;
+ uint32_t mantissa = v.u & 0x7fffffU;
+ int32_t exponent = ((int32_t)((v.u >> 23) & 0xffU)) - 127 + 15;
+
+ if (exponent <= 0)
+ {
+ if (exponent < -10)
+ return (uint16_t)sign;
+
+ mantissa = (mantissa | 0x800000U) >> (uint32_t)(1 - exponent);
+ return (uint16_t)(sign | ((mantissa + 0x1000U) >> 13));
+ }
+
+ if (exponent >= 31)
+ return (uint16_t)(sign | 0x7c00U | (mantissa ? 0x200U : 0));
+
+ return (uint16_t)(sign | ((uint32_t)exponent << 10) | ((mantissa + 0x1000U) >> 13));
+}
+
+float
+rt_util_float16_to_float(uint16_t value)
+{
+ union {
+ uint32_t u;
+ float f;
+ } v;
+
+ uint32_t sign = (uint32_t)(value & 0x8000U) << 16;
+ uint32_t exponent = (value >> 10) & 0x1fU;
+ uint32_t mantissa = value & 0x3ffU;
+
+ if (exponent == 0)
+ {
+ if (mantissa == 0)
+ {
+ v.u = sign;
+ }
+ else
+ {
+ exponent = 1;
+ while ((mantissa & 0x400U) == 0)
+ {
+ mantissa <<= 1;
+ exponent--;
+ }
+ mantissa &= 0x3ffU;
+ v.u = sign | ((exponent + 127 - 15) << 23) | (mantissa << 13);
+ }
+ }
+ else if (exponent == 31)
+ {
+ v.u = sign | 0x7f800000U | (mantissa << 13);
+ }
+ else
+ {
+ v.u = sign | ((exponent + 127 - 15) << 23) | (mantissa << 13);
+ }
+
+ return v.f;
+}
+
/**
* Convert cstring name to GDAL Resample Algorithm
*
@@ -140,6 +229,10 @@ rt_util_pixtype_to_gdal_datatype(rt_pixtype pt) {
return GDT_Int32;
case PT_32BUI:
return GDT_UInt32;
+#if POSTGIS_GDAL_VERSION >= 31100 && defined(GDT_Float16)
+ case PT_16BF:
+ return GDT_Float16;
+#endif
case PT_32BF:
return GDT_Float32;
case PT_64BF:
@@ -179,11 +272,15 @@ rt_util_gdal_datatype_to_pixtype(GDALDataType gdt) {
return PT_32BF;
case GDT_Float64:
return PT_64BF;
+#if POSTGIS_GDAL_VERSION >= 31100 && defined(GDT_Float16)
+ case GDT_Float16:
+ return PT_16BF;
+#endif
default:
return PT_END;
- }
+ }
- return PT_END;
+ return PT_END;
}
/*
@@ -717,12 +814,13 @@ rt_util_dbl_trunc_warning(
break;
}
case PT_32BUI: {
- if (fabs(checkvaluint - initialvalue) >= 1) {
+ if (fabs(checkvaluint - initialvalue) >= 1)
+ {
#if POSTGIS_RASTER_WARN_ON_TRUNCATION > 0
rtwarn("Value set for %s band got clamped from %f to %u",
- rt_pixtype_name(pixtype),
- initialvalue, checkvaluint
- );
+ rt_pixtype_name(pixtype),
+ initialvalue,
+ checkvaluint);
#endif
result = 1;
}
@@ -738,6 +836,7 @@ rt_util_dbl_trunc_warning(
}
break;
}
+ case PT_16BF:
case PT_32BF: {
/*
For float, because the initial value is a double,
diff --git a/raster/rt_core/rt_wkb.c b/raster/rt_core/rt_wkb.c
index 88daa9665..86efe1e74 100644
--- a/raster/rt_core/rt_wkb.c
+++ b/raster/rt_core/rt_wkb.c
@@ -10,6 +10,7 @@
* Copyright (C) 2009-2011 Pierre Racine <pierre.racine at sbf.ulaval.ca>
* Copyright (C) 2009-2011 Mateusz Loskot <mateusz at loskot.net>
* Copyright (C) 2008-2009 Sandro Santilli <strk at kbt.io>
+ * Copyright (C) 2025 Darafei Praliaskouski <me at komzpa.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -129,6 +130,10 @@ rt_band_from_wkb(
band->nodataval = read_uint32(ptr, littleEndian);
break;
}
+ case PT_16BF: {
+ band->nodataval = rt_util_float16_to_float(read_uint16(ptr, littleEndian));
+ break;
+ }
case PT_32BF: {
band->nodataval = read_float32(ptr, littleEndian);
break;
@@ -619,6 +624,12 @@ rt_raster_to_wkb(rt_raster raster, int outasin, uint32_t *wkbsize) {
ptr += 4;
break;
}
+ case PT_16BF: {
+ uint16_t v = rt_util_float_to_float16((float)band->nodataval);
+ memcpy(ptr, &v, 2);
+ ptr += 2;
+ break;
+ }
case PT_32BF: {
float v = band->nodataval;
memcpy(ptr, &v, 4);
diff --git a/raster/scripts/python/pixval.py b/raster/scripts/python/pixval.py
index 644e1aec6..44c953cd0 100755
--- a/raster/scripts/python/pixval.py
+++ b/raster/scripts/python/pixval.py
@@ -39,6 +39,8 @@ def pt2fmt(pt):
gdalc.GDT_Float32: 'f',
gdalc.GDT_Float64: 'f'
}
+ if hasattr(gdalc, 'GDT_Float16'):
+ fmttypes[gdalc.GDT_Float16] = 'e'
return fmttypes.get(pt, 'x')
if len(sys.argv) < 5 or len(sys.argv) > 6:
diff --git a/raster/scripts/python/raster2pgsql.py b/raster/scripts/python/raster2pgsql.py
index c6401f925..7d227b413 100755
--- a/raster/scripts/python/raster2pgsql.py
+++ b/raster/scripts/python/raster2pgsql.py
@@ -222,6 +222,9 @@ def gdt2pt(gdt):
gdalc.GDT_Float32 : { 'name': 'PT_32BF', 'id': 10 },
gdalc.GDT_Float64 : { 'name': 'PT_64BF', 'id': 11 }
}
+
+ if hasattr(gdalc, 'GDT_Float16'):
+ pixtypes[gdalc.GDT_Float16] = { 'name': 'PT_16BF', 'id': 9 }
# XXX: Uncomment these logs to debug types translation
#logit('MSG: Input GDAL pixel type: %s (%d)\n' % (gdal.GetDataTypeName(gdt), gdt))
@@ -240,6 +243,8 @@ def pt2numpy(pt):
gdalc.GDT_Float32: numpy.float32,
gdalc.GDT_Float64: numpy.float64
}
+ if hasattr(gdalc, 'GDT_Float16'):
+ ptnumpy[gdalc.GDT_Float16] = numpy.float16
return ptnumpy.get(pt, numpy.uint8)
def pt2fmt(pt):
@@ -250,6 +255,7 @@ def pt2fmt(pt):
6: 'H', # PT_16BUI
7: 'i', # PT_32BSI
8: 'I', # PT_32BUI
+ 9: 'e', # PT_16BF
10: 'f', # PT_32BF
11: 'd' # PT_64BF
}
@@ -264,6 +270,7 @@ def fmt2printfmt(fmt):
'H': '%d', # PT_16BUI
'i': '%d', # PT_32BSI
'I': '%d', # PT_32BUI
+ 'e': '%.8f', # PT_16BF
'f': '%.15f', # PT_32BF
'd': '%.15f', # PT_64BF
's': '%s'
diff --git a/raster/scripts/python/rtrowdump.py b/raster/scripts/python/rtrowdump.py
index 8712db00d..d7a239182 100755
--- a/raster/scripts/python/rtrowdump.py
+++ b/raster/scripts/python/rtrowdump.py
@@ -47,6 +47,8 @@ def pt2gdt(pt):
'32BF' : osgeo.gdalconst.GDT_Float32,
'64BF' : osgeo.gdalconst.GDT_Float64
}
+ if hasattr(osgeo.gdalconst, 'GDT_Float16'):
+ pixtypes['16BF'] = osgeo.gdalconst.GDT_Float16
return pixtypes.get(pt, 'UNKNOWN')
def pt2numpy(pt):
@@ -60,6 +62,8 @@ def pt2numpy(pt):
'32BF' : numpy.float32,
'64BF' : numpy.float64
}
+ if hasattr(numpy, 'float16'):
+ numpytypes['16BF'] = numpy.float16
return numpytypes.get(pt, numpy.uint8)
###############################################################################
diff --git a/raster/test/cunit/cu_pixtype.c b/raster/test/cunit/cu_pixtype.c
index 45333a35e..b69db7b37 100644
--- a/raster/test/cunit/cu_pixtype.c
+++ b/raster/test/cunit/cu_pixtype.c
@@ -4,6 +4,7 @@
*
* Copyright (C) 2012 Regents of the University of California
* <bkpark at ucdavis.edu>
+ * Copyright (C) 2025 Darafei Praliaskouski <me at komzpa.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -32,6 +33,7 @@ static void test_pixtype_size() {
CU_ASSERT_EQUAL(rt_pixtype_size(PT_8BSI), 1);
CU_ASSERT_EQUAL(rt_pixtype_size(PT_16BUI), 2);
CU_ASSERT_EQUAL(rt_pixtype_size(PT_16BSI), 2);
+ CU_ASSERT_EQUAL(rt_pixtype_size(PT_16BF), 2);
CU_ASSERT_EQUAL(rt_pixtype_size(PT_32BUI), 4);
CU_ASSERT_EQUAL(rt_pixtype_size(PT_32BSI), 4);
CU_ASSERT_EQUAL(rt_pixtype_size(PT_32BF), 4);
@@ -52,6 +54,7 @@ static void test_pixtype_name() {
CU_ASSERT_STRING_EQUAL(rt_pixtype_name(PT_8BSI), "8BSI");
CU_ASSERT_STRING_EQUAL(rt_pixtype_name(PT_16BUI), "16BUI");
CU_ASSERT_STRING_EQUAL(rt_pixtype_name(PT_16BSI), "16BSI");
+ CU_ASSERT_STRING_EQUAL(rt_pixtype_name(PT_16BF), "16BF");
CU_ASSERT_STRING_EQUAL(rt_pixtype_name(PT_32BUI), "32BUI");
CU_ASSERT_STRING_EQUAL(rt_pixtype_name(PT_32BSI), "32BSI");
CU_ASSERT_STRING_EQUAL(rt_pixtype_name(PT_32BF), "32BF");
@@ -68,6 +71,7 @@ static void test_pixtype_index_from_name() {
CU_ASSERT_EQUAL(rt_pixtype_index_from_name("8BSI"), PT_8BSI);
CU_ASSERT_EQUAL(rt_pixtype_index_from_name("16BUI"), PT_16BUI);
CU_ASSERT_EQUAL(rt_pixtype_index_from_name("16BSI"), PT_16BSI);
+ CU_ASSERT_EQUAL(rt_pixtype_index_from_name("16BF"), PT_16BF);
CU_ASSERT_EQUAL(rt_pixtype_index_from_name("32BUI"), PT_32BUI);
CU_ASSERT_EQUAL(rt_pixtype_index_from_name("32BSI"), PT_32BSI);
CU_ASSERT_EQUAL(rt_pixtype_index_from_name("32BF"), PT_32BF);
@@ -84,11 +88,17 @@ static void test_pixtype_get_min_value() {
CU_ASSERT_DOUBLE_EQUAL(rt_pixtype_get_min_value(PT_2BUI), rt_util_clamp_to_2BUI((double) CHAR_MIN), DBL_EPSILON);
CU_ASSERT_DOUBLE_EQUAL(rt_pixtype_get_min_value(PT_4BUI), rt_util_clamp_to_4BUI((double) CHAR_MIN), DBL_EPSILON);
CU_ASSERT_DOUBLE_EQUAL(rt_pixtype_get_min_value(PT_8BUI), rt_util_clamp_to_8BUI((double) CHAR_MIN), DBL_EPSILON);
- CU_ASSERT_DOUBLE_EQUAL(rt_pixtype_get_min_value(PT_8BSI), rt_util_clamp_to_8BSI((double) SCHAR_MIN), DBL_EPSILON);
- CU_ASSERT_DOUBLE_EQUAL(rt_pixtype_get_min_value(PT_16BUI), rt_util_clamp_to_16BUI((double) SHRT_MIN), DBL_EPSILON);
- CU_ASSERT_DOUBLE_EQUAL(rt_pixtype_get_min_value(PT_16BSI), rt_util_clamp_to_16BSI((double) SHRT_MIN), DBL_EPSILON);
- CU_ASSERT_DOUBLE_EQUAL(rt_pixtype_get_min_value(PT_32BUI), rt_util_clamp_to_32BUI((double) INT_MIN), DBL_EPSILON);
- CU_ASSERT_DOUBLE_EQUAL(rt_pixtype_get_min_value(PT_32BSI), rt_util_clamp_to_32BSI((double) INT_MIN), DBL_EPSILON);
+ CU_ASSERT_DOUBLE_EQUAL(
+ rt_pixtype_get_min_value(PT_8BSI), rt_util_clamp_to_8BSI((double)SCHAR_MIN), DBL_EPSILON);
+ CU_ASSERT_DOUBLE_EQUAL(
+ rt_pixtype_get_min_value(PT_16BUI), rt_util_clamp_to_16BUI((double)SHRT_MIN), DBL_EPSILON);
+ CU_ASSERT_DOUBLE_EQUAL(
+ rt_pixtype_get_min_value(PT_16BSI), rt_util_clamp_to_16BSI((double)SHRT_MIN), DBL_EPSILON);
+ CU_ASSERT_DOUBLE_EQUAL(rt_pixtype_get_min_value(PT_16BF), -POSTGIS_RT_16F_MAX, DBL_EPSILON);
+ CU_ASSERT_DOUBLE_EQUAL(
+ rt_pixtype_get_min_value(PT_32BUI), rt_util_clamp_to_32BUI((double)INT_MIN), DBL_EPSILON);
+ CU_ASSERT_DOUBLE_EQUAL(
+ rt_pixtype_get_min_value(PT_32BSI), rt_util_clamp_to_32BSI((double)INT_MIN), DBL_EPSILON);
CU_ASSERT_DOUBLE_EQUAL(rt_pixtype_get_min_value(PT_32BF), -FLT_MAX, DBL_EPSILON);
CU_ASSERT_DOUBLE_EQUAL(rt_pixtype_get_min_value(PT_64BF), -DBL_MAX, DBL_EPSILON);
@@ -200,6 +210,14 @@ static void test_pixtype_compare_clamped_values() {
CU_ASSERT_EQUAL(rt_pixtype_compare_clamped_values(PT_16BSI, 32767, -32767, &isequal), ES_NONE);
CU_ASSERT(!isequal);
+ /* 16BF */
+ CU_ASSERT_EQUAL(rt_pixtype_compare_clamped_values(PT_16BF, 1.5, 1.5, &isequal), ES_NONE);
+ CU_ASSERT(isequal);
+ CU_ASSERT_EQUAL(rt_pixtype_compare_clamped_values(PT_16BF, 70000.0, 65504.0, &isequal), ES_NONE);
+ CU_ASSERT(isequal);
+ CU_ASSERT_EQUAL(rt_pixtype_compare_clamped_values(PT_16BF, -70000.0, 0.0, &isequal), ES_NONE);
+ CU_ASSERT(!isequal);
+
/* 32BUI */
CU_ASSERT_EQUAL(rt_pixtype_compare_clamped_values(PT_32BUI, 4294967295UL, 4294967295UL, &isequal), ES_NONE);
CU_ASSERT(isequal);
-----------------------------------------------------------------------
Summary of changes:
NEWS | 1 +
raster/doc/RFC1-SerializedFormat | 4 +-
raster/rt_core/librtcore.h | 35 +++++++----
raster/rt_core/rt_band.c | 65 +++++++++++++++-----
raster/rt_core/rt_pixel.c | 15 ++++-
raster/rt_core/rt_serialize.c | 11 ++++
raster/rt_core/rt_statistics.c | 8 ++-
raster/rt_core/rt_util.c | 111 ++++++++++++++++++++++++++++++++--
raster/rt_core/rt_wkb.c | 11 ++++
raster/scripts/python/pixval.py | 2 +
raster/scripts/python/raster2pgsql.py | 7 +++
raster/scripts/python/rtrowdump.py | 4 ++
raster/test/cunit/cu_pixtype.c | 28 +++++++--
13 files changed, 258 insertions(+), 44 deletions(-)
hooks/post-receive
--
PostGIS
More information about the postgis-tickets
mailing list