Return GDAL dataset using GDAL MEM driver from raster.
1828 {
1829 GDALDriverH drv = NULL;
1830 GDALDatasetH
ds = NULL;
1831 double gt[6] = {0.0};
1832 CPLErr cplerr;
1833 GDALDataType gdal_pt = GDT_Unknown;
1834 GDALRasterBandH
band;
1835 void *pVoid;
1836 char *pszDataPointer;
1837 char szGDALOption[50];
1838 char *apszOptions[4];
1839 double nodata = 0.0;
1840 int allocBandNums = 0;
1841 int allocNodataValues = 0;
1842
1843 int i;
1844 uint32_t numBands;
1845 uint32_t width = 0;
1846 uint32_t height = 0;
1849
1850 assert(NULL != raster);
1851 assert(NULL != rtn_drv);
1852 assert(NULL != destroy_rtn_drv);
1853
1854 *destroy_rtn_drv = 0;
1855
1856
1859 GDALRegister_MEM();
1860 *destroy_rtn_drv = 1;
1861 }
1862 drv = GDALGetDriverByName("MEM");
1863 if (NULL == drv) {
1864 rterror(
"rt_raster_to_gdal_mem: Could not load the MEM GDAL driver");
1865 return 0;
1866 }
1867 *rtn_drv = drv;
1868
1869
1870 if (*destroy_rtn_drv) {
1872 GDALDeregisterDriver(drv);
1873 }
1874
1878 drv, "",
1879 width, height,
1880 0, GDT_Byte, NULL
1881 );
1882 if (NULL == ds) {
1883 rterror(
"rt_raster_to_gdal_mem: Could not create a GDALDataset to convert into");
1884 return 0;
1885 }
1886
1887
1889 cplerr = GDALSetGeoTransform(ds, gt);
1890 if (cplerr != CE_None) {
1891 rterror(
"rt_raster_to_gdal_mem: Could not set geotransformation");
1892 GDALClose(ds);
1893 return 0;
1894 }
1895
1896
1897 if (NULL != srs && strlen(srs)) {
1899 if (_srs == NULL) {
1900 rterror(
"rt_raster_to_gdal_mem: Could not convert srs to GDAL accepted format");
1901 GDALClose(ds);
1902 return 0;
1903 }
1904
1905 cplerr = GDALSetProjection(ds, _srs);
1906 CPLFree(_srs);
1907 if (cplerr != CE_None) {
1908 rterror(
"rt_raster_to_gdal_mem: Could not set projection");
1909 GDALClose(ds);
1910 return 0;
1911 }
1912 RASTER_DEBUGF(3,
"Projection set to: %s", GDALGetProjectionRef(ds));
1913 }
1914
1915
1917 if (NULL != bandNums && count > 0) {
1918 for (i = 0; i <
count; i++) {
1919 if (bandNums[i] >= numBands) {
1920 rterror(
"rt_raster_to_gdal_mem: The band index %d is invalid", bandNums[i]);
1921 GDALClose(ds);
1922 return 0;
1923 }
1924 }
1925 }
1926 else {
1928 bandNums = (uint32_t *)
rtalloc(
sizeof(uint32_t) *
count);
1929 if (NULL == bandNums) {
1930 rterror(
"rt_raster_to_gdal_mem: Could not allocate memory for band indices");
1931 GDALClose(ds);
1932 return 0;
1933 }
1934 allocBandNums = 1;
1935 for (i = 0; i <
count; i++) bandNums[i] = i;
1936 }
1937
1938
1939 if (NULL == excludeNodataValues) {
1940 excludeNodataValues = (
int *)
rtalloc(
sizeof(
int) *
count);
1941 if (NULL == excludeNodataValues) {
1942 rterror(
"rt_raster_to_gdal_mem: Could not allocate memory for NODATA flags");
1943 GDALClose(ds);
1944 return 0;
1945 }
1946 allocNodataValues = 1;
1947 for (i = 0; i <
count; i++) excludeNodataValues[i] = 1;
1948 }
1949
1950
1951 for (i = 0; i <
count; i++) {
1953 if (NULL == rtband) {
1954 rterror(
"rt_raster_to_gdal_mem: Could not get requested band index %d", bandNums[i]);
1956 if (allocNodataValues)
rtdealloc(excludeNodataValues);
1957 GDALClose(ds);
1958 return 0;
1959 }
1960
1963 if (gdal_pt == GDT_Unknown)
1964 rtwarn(
"rt_raster_to_gdal_mem: Unknown pixel type for band");
1965
1966
1967
1968
1972
1973 pszDataPointer = (
char *)
rtalloc(20 *
sizeof (
char));
1974 sprintf(pszDataPointer, "%p", pVoid);
1975 RASTER_DEBUGF(4,
"rt_raster_to_gdal_mem: szDatapointer is %p",
1976 pszDataPointer);
1977
1978 if (strncasecmp(pszDataPointer, "0x", 2) == 0)
1979 sprintf(szGDALOption, "DATAPOINTER=%s", pszDataPointer);
1980 else
1981 sprintf(szGDALOption, "DATAPOINTER=0x%s", pszDataPointer);
1982
1983 RASTER_DEBUG(3,
"Storing info for GDAL MEM raster band");
1984
1985 apszOptions[0] = szGDALOption;
1986 apszOptions[1] = NULL;
1987 apszOptions[2] = NULL;
1988 apszOptions[3] = NULL;
1989
1990
1992
1993
1994 if (GDALAddBand(ds, gdal_pt, apszOptions) == CE_Failure) {
1995 rterror(
"rt_raster_to_gdal_mem: Could not add GDAL raster band");
1997 GDALClose(ds);
1998 return 0;
1999 }
2000 }
2001
2002
2003
2004
2005 else {
2006
2007 if (GDALAddBand(ds, gdal_pt, NULL) == CE_Failure) {
2008 rterror(
"rt_raster_to_gdal_mem: Could not add GDAL raster band");
2010 if (allocNodataValues)
rtdealloc(excludeNodataValues);
2011 GDALClose(ds);
2012 return 0;
2013 }
2014 }
2015
2016
2017 if (GDALGetRasterCount(ds) != i + 1) {
2018 rterror(
"rt_raster_to_gdal_mem: Error creating GDAL MEM raster band");
2020 if (allocNodataValues)
rtdealloc(excludeNodataValues);
2021 GDALClose(ds);
2022 return 0;
2023 }
2024
2025
2027 band = GDALGetRasterBand(ds, i + 1);
2028 if (NULL == band) {
2029 rterror(
"rt_raster_to_gdal_mem: Could not get GDAL band for additional processing");
2031 if (allocNodataValues)
rtdealloc(excludeNodataValues);
2032 GDALClose(ds);
2033 return 0;
2034 }
2035
2036
2038 uint32_t nXBlocks, nYBlocks;
2039 int nXBlockSize, nYBlockSize;
2040 uint32_t iXBlock, iYBlock;
2041 int nXValid, nYValid;
2042 int iX, iY;
2043 int iXMax, iYMax;
2044
2046 uint32_t valueslen = 0;
2047 int16_t *values = NULL;
2049
2050
2051 GDALGetBlockSize(band, &nXBlockSize, &nYBlockSize);
2052 nXBlocks = (width + nXBlockSize - 1) / nXBlockSize;
2053 nYBlocks = (height + nYBlockSize - 1) / nYBlockSize;
2054 RASTER_DEBUGF(4,
"(nXBlockSize, nYBlockSize) = (%d, %d)", nXBlockSize, nYBlockSize);
2055 RASTER_DEBUGF(4,
"(nXBlocks, nYBlocks) = (%d, %d)", nXBlocks, nYBlocks);
2056
2057
2060 if (NULL == values) {
2061 rterror(
"rt_raster_to_gdal_mem: Could not allocate memory for GDAL band pixel values");
2063 if (allocNodataValues)
rtdealloc(excludeNodataValues);
2064 GDALClose(ds);
2065 return 0;
2066 }
2067
2068 for (iYBlock = 0; iYBlock < nYBlocks; iYBlock++) {
2069 for (iXBlock = 0; iXBlock < nXBlocks; iXBlock++) {
2070 memset(values, 0, valueslen);
2071
2072 x = iXBlock * nXBlockSize;
2073 y = iYBlock * nYBlockSize;
2074 RASTER_DEBUGF(4,
"(iXBlock, iYBlock) = (%d, %d)", iXBlock, iYBlock);
2076
2077
2078 if ((iXBlock + 1) * nXBlockSize > width)
2079 nXValid = width - (iXBlock * nXBlockSize);
2080 else
2081 nXValid = nXBlockSize;
2082
2083
2084 if ((iYBlock + 1) * nYBlockSize > height)
2085 nYValid = height - (iYBlock * nYBlockSize);
2086 else
2087 nYValid = nYBlockSize;
2088
2089 RASTER_DEBUGF(4,
"(nXValid, nYValid) = (%d, %d)", nXValid, nYValid);
2090
2091
2092 z = 0;
2093 iYMax =
y + nYValid;
2094 iXMax =
x + nXValid;
2095 for (iY = y; iY < iYMax; iY++) {
2096 for (iX = x; iX < iXMax; iX++) {
2098 rterror(
"rt_raster_to_gdal_mem: Could not get pixel value to convert from 8BSI to 16BSI");
2101 if (allocNodataValues)
rtdealloc(excludeNodataValues);
2102 GDALClose(ds);
2103 return 0;
2104 }
2105
2107 }
2108 }
2109
2110
2111 if (GDALRasterIO(
2112 band, GF_Write,
2113 x, y,
2114 nXValid, nYValid,
2115 values, nXValid, nYValid,
2116 gdal_pt,
2117 0, 0
2118 ) != CE_None) {
2119 rterror(
"rt_raster_to_gdal_mem: Could not write converted 8BSI to 16BSI values to GDAL band");
2122 if (allocNodataValues)
rtdealloc(excludeNodataValues);
2123 GDALClose(ds);
2124 return 0;
2125 }
2126 }
2127 }
2128
2130 }
2131
2132
2135 if (GDALSetRasterNoDataValue(band, nodata) != CE_None)
2136 rtwarn(
"rt_raster_to_gdal_mem: Could not set nodata value for band");
2137 RASTER_DEBUGF(3,
"nodata value set to %f", GDALGetRasterNoDataValue(band, NULL));
2138 }
2139
2140#if POSTGIS_DEBUG_LEVEL > 3
2141 {
2142 GDALRasterBandH _grb = NULL;
2143 double _min;
2144 double _max;
2145 double _mean;
2146 double _stddev;
2147
2148 _grb = GDALGetRasterBand(ds, i + 1);
2149 GDALComputeRasterStatistics(_grb,
FALSE, &_min, &_max, &_mean, &_stddev, NULL, NULL);
2150 RASTER_DEBUGF(4,
"GDAL Band %d stats: %f, %f, %f, %f", i + 1, _min, _max, _mean, _stddev);
2151 }
2152#endif
2153
2154 }
2155
2156
2157 GDALFlushCache(ds);
2158
2160 if (allocNodataValues)
rtdealloc(excludeNodataValues);
2161
2163}
void rterror(const char *fmt,...)
Wrappers used for reporting errors and info.
void * rtalloc(size_t size)
Wrappers used for managing memory.
#define RASTER_DEBUG(level, msg)
#define RASTER_DEBUGF(level, msg,...)
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
void * rt_band_get_data(rt_band band)
Get pointer to raster band data.
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
char * rt_util_gdal_convert_sr(const char *srs, int proj4)
GDALDataType rt_util_pixtype_to_gdal_datatype(rt_pixtype pt)
Convert rt_pixtype to GDALDataType.
void rtwarn(const char *fmt,...)
int16_t rt_util_clamp_to_16BSI(double value)
int rt_util_gdal_driver_registered(const char *drv)
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
void rtdealloc(void *mem)
int rt_pixtype_size(rt_pixtype pixtype)
Return size in bytes of a value in the given pixtype.
uint16_t rt_raster_get_num_bands(rt_raster raster)
uint16_t rt_raster_get_height(rt_raster raster)
rt_band rt_raster_get_band(rt_raster raster, int n)
Return Nth band, or NULL if unavailable.
uint16_t rt_raster_get_width(rt_raster raster)
void rt_raster_get_geotransform_matrix(rt_raster raster, double *gt)
Get 6-element array of raster geotransform matrix.