]> granicus.if.org Git - postgis/commitdiff
Fix division by zero in ST_ApproxSummaryStats and the situation where
authorBborie Park <bkpark at ucdavis.edu>
Mon, 18 Jun 2012 22:47:34 +0000 (22:47 +0000)
committerBborie Park <bkpark at ucdavis.edu>
Mon, 18 Jun 2012 22:47:34 +0000 (22:47 +0000)
band is empty.  Added regression tests for both situations.
Ticket is #1872

git-svn-id: http://svn.osgeo.org/postgis/trunk@9940 b70326c6-7e19-0410-871a-916f4a2858ee

NEWS
raster/rt_core/rt_api.c
raster/test/regress/rt_summarystats.sql
raster/test/regress/rt_summarystats_expected

diff --git a/NEWS b/NEWS
index dab40dbb8267cdfe1b6d040ae3a5d89b6248e2f4..b1eb7b1cf461dbf75004cb4749ef0e1d3295676e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,7 @@ PostGIS 2.1.0
 
   - #1839, handling of subdatasets in GeoTIFF in raster2pgsql.
   - #1840, fix logic of when to compute # of tiles in raster2pgsql.
+  - #1872, fix ST_ApproxSummarystats to prevent division by zero.
 
 PostGIS 2.0.1
 2012/06/DD
index d08c0a23081af0f77e1e509e513f7413b693e14e..3538e617c8512c0549807f61e6f517f6ecccb2e3 100644 (file)
@@ -2683,8 +2683,11 @@ rt_band_corrected_clamped_value(rt_band band, double val, double *newval) {
  * @return the summary statistics for a band
  */
 rt_bandstats
-rt_band_get_summary_stats(rt_band band, int exclude_nodata_value, double sample,
-       int inc_vals, uint64_t *cK, double *cM, double *cQ) {
+rt_band_get_summary_stats(
+       rt_band band,
+       int exclude_nodata_value, double sample, int inc_vals,
+       uint64_t *cK, double *cM, double *cQ
+) {
        uint8_t *data = NULL;
        uint32_t x = 0;
        uint32_t y = 0;
@@ -2721,6 +2724,28 @@ rt_band_get_summary_stats(rt_band band, int exclude_nodata_value, double sample,
 
        assert(NULL != band);
 
+       /* band is empty (width < 1 || height < 1) */
+       if (band->width < 1 || band->height < 1) {
+               stats = (rt_bandstats) rtalloc(sizeof(struct rt_bandstats_t));
+               if (NULL == stats) {
+                       rterror("rt_band_get_summary_stats: Unable to allocate memory for stats");
+                       return NULL;
+               }
+
+               rtwarn("Band is empty as width and/or height is 0");
+
+               stats->sample = 1;
+               stats->sorted = 0;
+               stats->values = NULL;
+               stats->count = 0;
+               stats->min = stats->max = 0;
+               stats->sum = 0;
+               stats->mean = 0;
+               stats->stddev = -1;
+
+               return stats;
+       }
+
        data = rt_band_get_data(band);
        if (data == NULL) {
                rterror("rt_band_get_summary_stats: Cannot get band data");
@@ -2794,6 +2819,8 @@ rt_band_get_summary_stats(rt_band band, int exclude_nodata_value, double sample,
        else {
                sample_size = round((band->width * band->height) * sample);
                sample_per = round(sample_size / band->width);
+               if (sample_per < 1)
+                       sample_per = 1;
                sample_int = round(band->height / sample_per);
                srand(time(NULL));
        }
index 12d043709a68297692be0ff5240807d6a5c040b8..8d75d5a369babf13e1fea4910efce61c7fa1052c 100644 (file)
@@ -101,6 +101,22 @@ SELECT round(mean::numeric, 3), round(stddev::numeric, 3) FROM ST_SummaryStats(
        )
        , 2
 );
+SELECT ST_ApproxSummaryStats(
+       ST_Clip(
+               ST_AddBand(
+                       ST_MakeEmptyRaster(10, 10, 0, 0, 1, 1, 0, 0, 0)
+                       , '16BSI'::text, 0, 0
+               )
+               , ST_MakeEnvelope(0, 0, 10, 5, 0)
+       )
+       , 1, true, 0.1
+);
+SELECT ST_SummaryStats(
+       ST_AddBand(
+               ST_MakeEmptyRaster(10, 0, 0, 0, 1, -1, 0, 0, 0)
+               , '8BUI'::text, 1, 0
+       )
+);
 BEGIN;
 CREATE TEMP TABLE test_summarystats
        ON COMMIT DROP AS
index bdfd8ce763f1f3cfd3a27ca3cf9bb5214db19930..339f3dd92429b42717bc2989aaac44d9131637c1 100644 (file)
@@ -5,6 +5,9 @@
 -0.069|1.046
 NOTICE:  Invalid band index (must use 1-based). Returning NULL
 |
+(0,0,0,-1,0,0)
+NOTICE:  Band is empty as width and/or height is 0
+(0,0,0,-1,0,0)
 BEGIN
 20|-68.584|-3.429|6.571|-10.000|3.142
 1000|-68.584|-0.069|1.046|-10.000|3.142