From 3df41bb1ec5b2a757d9df4ff1bcacbfcfb2373b9 Mon Sep 17 00:00:00 2001 From: Bborie Park Date: Mon, 16 May 2011 19:50:38 +0000 Subject: [PATCH] Add ST_AsTIFF function - add SQL functions for ST_AsTIFF - add regression tests Associated ticket is #341 git-svn-id: http://svn.osgeo.org/postgis/trunk@7156 b70326c6-7e19-0410-871a-916f4a2858ee --- raster/rt_pg/rtpostgis.sql.in.c | 161 +++++++++++++++++++++++++ raster/test/regress/Makefile.in | 1 + raster/test/regress/rt_astiff.sql | 91 ++++++++++++++ raster/test/regress/rt_astiff_expected | 10 ++ 4 files changed, 263 insertions(+) create mode 100644 raster/test/regress/rt_astiff.sql create mode 100644 raster/test/regress/rt_astiff_expected diff --git a/raster/rt_pg/rtpostgis.sql.in.c b/raster/rt_pg/rtpostgis.sql.in.c index 35cf6373d..52abfe38d 100644 --- a/raster/rt_pg/rtpostgis.sql.in.c +++ b/raster/rt_pg/rtpostgis.sql.in.c @@ -1081,6 +1081,167 @@ CREATE OR REPLACE FUNCTION st_asgdalraster(rast raster, format text) AS $$ SELECT st_asgdalraster($1, $2, NULL, st_srtext($1)) $$ LANGUAGE 'SQL' IMMUTABLE STRICT; +----------------------------------------------------------------------- +-- ST_AsTIFF +----------------------------------------------------------------------- +-- Cannot be strict as "options" and "srs" can be NULL +CREATE OR REPLACE FUNCTION st_astiff(rast raster, options text[], srs text) + RETURNS bytea + AS $$ + DECLARE + i int; + num_bands int; + nodata int; + last_nodata int; + BEGIN + num_bands := st_numbands($1); + + -- TIFF only allows one NODATA value for ALL bands + FOR i IN 1..num_bands LOOP + nodata := st_bandnodatavalue($1, i); + IF last_nodata IS NULL THEN + last_nodata := nodata; + ELSEIF nodata != last_nodata THEN + RAISE NOTICE 'The TIFF format only permits one NODATA value for all bands. The value used will be the last band with a NODATA value.'; + END IF; + END LOOP; + + RETURN st_asgdalraster($1, 'GTiff', $2, $3); + END; + $$ LANGUAGE 'plpgsql' IMMUTABLE; + +CREATE OR REPLACE FUNCTION st_astiff(rast raster, options text[]) + RETURNS bytea + AS $$ SELECT st_astiff($1, $2, st_srtext($1)) $$ + LANGUAGE 'SQL' IMMUTABLE STRICT; + +CREATE OR REPLACE FUNCTION st_astiff(rast raster) + RETURNS bytea + AS $$ SELECT st_astiff($1, NULL::text[], st_srtext($1)) $$ + LANGUAGE 'SQL' IMMUTABLE STRICT; + +CREATE OR REPLACE FUNCTION st_astiff(rast raster, nbands int[], options text[], srs text) + RETURNS bytea + AS $$ SELECT st_astiff(st_band($1, $2), $3, $4) $$ + LANGUAGE 'SQL' IMMUTABLE STRICT; + +CREATE OR REPLACE FUNCTION st_astiff(rast raster, nbands int[], options text[]) + RETURNS bytea + AS $$ + BEGIN + rast := st_band($1, $2); + RETURN st_astiff(rast, $3, st_srtext(rast)); + END; + $$ LANGUAGE 'plpgsql' IMMUTABLE STRICT; + +CREATE OR REPLACE FUNCTION st_astiff(rast raster, nbands int[]) + RETURNS bytea + AS $$ + BEGIN + rast := st_band($1, $2); + RETURN st_astiff(rast, NULL::text[], st_srtext(rast)); + END; + $$ LANGUAGE 'plpgsql' IMMUTABLE STRICT; + +-- Cannot be strict as "srs" can be NULL +CREATE OR REPLACE FUNCTION st_astiff(rast raster, compression text, srs text) + RETURNS bytea + AS $$ + DECLARE + c_type text; + c_level int; + i int; + num_bands int; + options text[]; + BEGIN + compression := trim(both from upper(compression)); + + IF length(compression) > 0 THEN + -- JPEG + IF position('JPEG' in compression) != 0 THEN + c_type := 'JPEG'; + c_level := substring(compression from '[0-9]+$'); + + IF c_level IS NOT NULL THEN + IF c_level > 100 THEN + c_level := 100; + ELSEIF c_level < 1 THEN + c_level := 1; + END IF; + + options := array_append(options, 'JPEG_QUALITY=' || c_level); + END IF; + + -- per band pixel type check + num_bands := st_numbands($1); + FOR i IN 1..num_bands LOOP + IF st_bandpixeltype($1, i) != '8BUI' THEN + RAISE EXCEPTION 'The pixel type of band % in the raster is not 8BUI. JPEG compression can only be used with the 8BUI pixel type.', i; + END IF; + END LOOP; + + -- DEFLATE + ELSEIF position('DEFLATE' in compression) != 0 THEN + c_type := 'DEFLATE'; + c_level := substring(compression from '[0-9]+$'); + + IF c_level IS NOT NULL THEN + IF c_level > 9 THEN + c_level := 9; + ELSEIF c_level < 1 THEN + c_level := 1; + END IF; + + options := array_append(options, 'ZLEVEL=' || c_level); + END IF; + + ELSE + c_type := compression; + + -- CCITT + IF position('CCITT' in compression) THEN + -- per band pixel type check + num_bands := st_numbands($1); + FOR i IN 1..num_bands LOOP + IF st_bandpixeltype($1, i) != '1BB' THEN + RAISE EXCEPTION 'The pixel type of band % in the raster is not 1BB. CCITT compression can only be used with the 1BB pixel type.', i; + END IF; + END LOOP; + END IF; + + END IF; + + -- compression type check + IF ARRAY[c_type] <@ ARRAY['JPEG', 'LZW', 'PACKBITS', 'DEFLATE', 'CCITTRLE', 'CCITTFAX3', 'CCITTFAX4', 'NONE'] THEN + options := array_append(options, 'COMPRESS=' || c_type); + ELSE + RAISE NOTICE 'Unknown compression type: %. The outputted TIFF will not be COMPRESSED.', c_type; + END IF; + END IF; + + RETURN st_astiff($1, options, $4); + END; + $$ LANGUAGE 'plpgsql' IMMUTABLE; + +CREATE OR REPLACE FUNCTION st_astiff(rast raster, compression text) + RETURNS bytea + AS $$ SELECT st_astiff($1, $2, st_srtext($1)) $$ + LANGUAGE 'SQL' IMMUTABLE STRICT; + +CREATE OR REPLACE FUNCTION st_astiff(rast raster, nbands int[], compression text, srs text) + RETURNS bytea + AS $$ SELECT st_astiff(st_band($1, $2), $3, $4) $$ + LANGUAGE 'SQL' IMMUTABLE STRICT; + +CREATE OR REPLACE FUNCTION st_astiff(rast raster, nbands int[], compression text) + RETURNS bytea + AS $$ + BEGIN + rast := st_band($1, $2); + RETURN st_astiff(rast, $3, NULL::text[], st_srtext(rast)); + END; + $$ LANGUAGE 'plpgsql' IMMUTABLE STRICT; + ----------------------------------------------------------------------- -- MapAlgebra ----------------------------------------------------------------------- diff --git a/raster/test/regress/Makefile.in b/raster/test/regress/Makefile.in index dcfd840c5..51843861c 100644 --- a/raster/test/regress/Makefile.in +++ b/raster/test/regress/Makefile.in @@ -43,6 +43,7 @@ TEST_FUNC = \ rt_addband.sql \ rt_band.sql \ rt_asgdalraster.sql \ + rt_astiff.sql \ $(NULL) TEST_PROPS = \ diff --git a/raster/test/regress/rt_astiff.sql b/raster/test/regress/rt_astiff.sql new file mode 100644 index 000000000..6f9a1c733 --- /dev/null +++ b/raster/test/regress/rt_astiff.sql @@ -0,0 +1,91 @@ +SELECT md5( + ST_AsTIFF( + ST_AddBand(ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1), 1, '64BF', 123.4567, NULL) + ) +); +SELECT md5( + ST_AsTIFF( + ST_AddBand( + ST_AddBand( + ST_AddBand( + ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0,-1) + , 1, '64BF', 1234.5678, NULL + ) + , '64BF', 987.654321, NULL + ) + , '64BF', 9876.54321, NULL + ) + ) +); +SELECT md5( + ST_AsTIFF( + ST_AddBand( + ST_AddBand( + ST_AddBand( + ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1) + , 1, '64BF', 1234.5678, -9999 + ) + , '64BF', 987.654321, -9999 + ) + , '64BF', 9876.54321, -9999 + ) + ) +); +SELECT md5( + ST_AsTIFF( + ST_AddBand( + ST_AddBand( + ST_AddBand( + ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1) + , 1, '64BF', 1234.5678, -9999 + ) + , '64BF', 987.654321, -9999 + ) + , '64BF', 9876.54321, -9999 + ) + , ARRAY[3] + ) +); +SELECT md5( + ST_AsTIFF( + ST_AddBand( + ST_AddBand( + ST_AddBand( + ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1) + , 1, '64BF', 1234.5678, -9999 + ) + , '64BF', 987.654321, -9999 + ) + , '64BF', 9876.54321, -1 + ) + ) +); +SELECT md5( + ST_AsTIFF( + ST_AddBand( + ST_AddBand( + ST_AddBand( + ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1) + , 1, '64BF', 1234.5678, -1 + ) + , '64BF', 987.654321, -9999 + ) + , '64BF', 9876.54321, -9999 + ) + ) +); +SELECT md5( + ST_AsTIFF( + ST_AddBand( + ST_AddBand( + ST_AddBand( + ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1) + , 1, '64BF', 1234.5678, -9999 + ) + , '64BF', 987.654321, -9999 + ) + , '64BF', 9876.54321, -1 + ) + , 'JPEG90' + ) +); diff --git a/raster/test/regress/rt_astiff_expected b/raster/test/regress/rt_astiff_expected new file mode 100644 index 000000000..f046c10a0 --- /dev/null +++ b/raster/test/regress/rt_astiff_expected @@ -0,0 +1,10 @@ +2fd5de5f94416f2999fc24fbc3974a4b +4af1ca04adf045690fb60764cc93de75 +81de10108dd8eede75ef47c8f6f09bc5 +915b9a5f0b1baea454eef06a2431891b +NOTICE: The TIFF format only permits one NODATA value for all bands. The value used will be the last band with a NODATA value. +81de10108dd8eede75ef47c8f6f09bc5 +NOTICE: The TIFF format only permits one NODATA value for all bands. The value used will be the last band with a NODATA value. +NOTICE: The TIFF format only permits one NODATA value for all bands. The value used will be the last band with a NODATA value. +8f6e8ae14b92e32d4cf70c85ef67252e +ERROR: The pixel type of band 1 in the raster is not 8BUI. JPEG compression can only be used with the 8BUI pixel type. -- 2.50.1