|
@@ -0,0 +1,316 @@
|
|
|
+#include <grass/gis.h>
|
|
|
+#include <grass/raster.h>
|
|
|
+#include <grass/glocale.h>
|
|
|
+
|
|
|
+#include <gdal.h>
|
|
|
+
|
|
|
+/* -------------------------------------------------------------------- */
|
|
|
+/* Transfer colormap, if there is one. */
|
|
|
+/* prefer color rules over color tables, search: */
|
|
|
+/* 1. GRASS color rules in metadata */
|
|
|
+/* 2. Raster attribute table with color rules */
|
|
|
+/* 3. Raster color table */
|
|
|
+/* -------------------------------------------------------------------- */
|
|
|
+void transfer_colormap(GDALRasterBandH hBand, const char *output)
|
|
|
+{
|
|
|
+ int have_colors = 0;
|
|
|
+ int nrows, ncols;
|
|
|
+ int indx;
|
|
|
+ int complex = FALSE; /* TODO */
|
|
|
+
|
|
|
+ char **GDALmetadata;
|
|
|
+ GDALRasterAttributeTableH gdal_rat;
|
|
|
+
|
|
|
+ /* GRASS color rules in metadata? */
|
|
|
+ GDALmetadata = GDALGetMetadata(hBand, "");
|
|
|
+
|
|
|
+ if (GDALmetadata) {
|
|
|
+ struct Colors colors;
|
|
|
+ DCELL val1, val2;
|
|
|
+ int r1, g1, b1, r2, g2, b2;
|
|
|
+
|
|
|
+ Rast_init_colors(&colors);
|
|
|
+
|
|
|
+ while (GDALmetadata && GDALmetadata[0]) {
|
|
|
+ G_debug(2, "%s", GDALmetadata[0]);
|
|
|
+
|
|
|
+ if (!strncmp("COLOR_TABLE_RULE_RGB_", GDALmetadata[0], 21)) {
|
|
|
+ char *p;
|
|
|
+
|
|
|
+ for (p = GDALmetadata[0]; *p != '=' && *p != '\0'; p++);
|
|
|
+
|
|
|
+ if (*p == '=') {
|
|
|
+ p++;
|
|
|
+ }
|
|
|
+ if (p && *p != '\0') {
|
|
|
+ if (sscanf(p, "%lf %lf %d %d %d %d %d %d",
|
|
|
+ &val1, &val2, &r1, &g1, &b1, &r2, &g2, &b2) == 8) {
|
|
|
+
|
|
|
+ Rast_add_d_color_rule(&val1, r1, g1, b1,
|
|
|
+ &val2, r2, g2, b2,
|
|
|
+ &colors);
|
|
|
+ have_colors = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ GDALmetadata++;
|
|
|
+ }
|
|
|
+ if (have_colors)
|
|
|
+ Rast_write_colors((char *)output, G_mapset(), &colors);
|
|
|
+
|
|
|
+ Rast_free_colors(&colors);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* colors in raster attribute table? */
|
|
|
+ gdal_rat = GDALGetDefaultRAT(hBand);
|
|
|
+ if (!have_colors && gdal_rat != NULL) {
|
|
|
+ nrows = GDALRATGetRowCount(gdal_rat);
|
|
|
+ ncols = GDALRATGetColumnCount(gdal_rat);
|
|
|
+
|
|
|
+ if (nrows > 0 && ncols > 0) {
|
|
|
+ int minc, maxc, minmaxc;
|
|
|
+ int rc, gc, bc, rminc, rmaxc, gminc, gmaxc, bminc, bmaxc;
|
|
|
+ GDALRATFieldUsage field_use;
|
|
|
+ struct Colors colors;
|
|
|
+ DCELL val1, val2;
|
|
|
+ double r1, g1, b1, r2, g2, b2;
|
|
|
+ int cf;
|
|
|
+
|
|
|
+ Rast_init_colors(&colors);
|
|
|
+
|
|
|
+ minc = maxc = minmaxc = -1;
|
|
|
+ rc = gc = bc = rminc = rmaxc = gminc = gmaxc = bminc = bmaxc = -1;
|
|
|
+
|
|
|
+ for (indx = 0; indx < ncols; indx++) {
|
|
|
+ field_use = GDALRATGetUsageOfCol(gdal_rat, indx);
|
|
|
+
|
|
|
+ if (field_use == GFU_Min)
|
|
|
+ minc = indx;
|
|
|
+ else if (field_use == GFU_Max)
|
|
|
+ maxc = indx;
|
|
|
+ else if (field_use == GFU_MinMax)
|
|
|
+ minmaxc = indx;
|
|
|
+ else if (field_use == GFU_Red)
|
|
|
+ rc = indx;
|
|
|
+ else if (field_use == GFU_Green)
|
|
|
+ gc = indx;
|
|
|
+ else if (field_use == GFU_Blue)
|
|
|
+ bc = indx;
|
|
|
+ else if (field_use == GFU_RedMin)
|
|
|
+ rminc = indx;
|
|
|
+ else if (field_use == GFU_GreenMin)
|
|
|
+ gminc = indx;
|
|
|
+ else if (field_use == GFU_BlueMin)
|
|
|
+ bminc = indx;
|
|
|
+ else if (field_use == GFU_RedMax)
|
|
|
+ rmaxc = indx;
|
|
|
+ else if (field_use == GFU_GreenMax)
|
|
|
+ gmaxc = indx;
|
|
|
+ else if (field_use == GFU_BlueMax)
|
|
|
+ bmaxc = indx;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* guess color range 0, 1 or 0, 255 */
|
|
|
+
|
|
|
+ if (minc >= 0 && maxc >= 0 && rminc >= 0 && rmaxc >= 0 &&
|
|
|
+ gminc >= 0 && gmaxc >= 0 && bminc >= 0 && bmaxc >= 0) {
|
|
|
+
|
|
|
+ cf = 1;
|
|
|
+
|
|
|
+ /* analyze color rules */
|
|
|
+ for (indx = 0; indx < nrows; indx++) {
|
|
|
+ val1 = GDALRATGetValueAsDouble(gdal_rat, indx, minc);
|
|
|
+ val2 = GDALRATGetValueAsDouble(gdal_rat, indx, maxc);
|
|
|
+
|
|
|
+ r1 = GDALRATGetValueAsDouble(gdal_rat, indx, rminc);
|
|
|
+ g1 = GDALRATGetValueAsDouble(gdal_rat, indx, gminc);
|
|
|
+ b1 = GDALRATGetValueAsDouble(gdal_rat, indx, bminc);
|
|
|
+
|
|
|
+ r2 = GDALRATGetValueAsDouble(gdal_rat, indx, rmaxc);
|
|
|
+ g2 = GDALRATGetValueAsDouble(gdal_rat, indx, gmaxc);
|
|
|
+ b2 = GDALRATGetValueAsDouble(gdal_rat, indx, bmaxc);
|
|
|
+
|
|
|
+ if (r1 > 0.0 && r1 < 1.0)
|
|
|
+ cf = 255;
|
|
|
+ else if (cf == 255 && r1 > 1.0) {
|
|
|
+ cf = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (g1 > 0.0 && g1 < 1.0)
|
|
|
+ cf = 255;
|
|
|
+ else if (cf == 255 && g1 > 1.0) {
|
|
|
+ cf = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (b1 > 0.0 && b1 < 1.0)
|
|
|
+ cf = 255;
|
|
|
+ else if (cf == 255 && b1 > 1.0) {
|
|
|
+ cf = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (r2 > 0.0 && r2 < 1.0)
|
|
|
+ cf = 255;
|
|
|
+ else if (cf == 255 && r2 > 1.0) {
|
|
|
+ cf = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (g2 > 0.0 && g2 < 1.0)
|
|
|
+ cf = 255;
|
|
|
+ else if (cf == 255 && g2 > 1.0) {
|
|
|
+ cf = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (b2 > 0.0 && b2 < 1.0)
|
|
|
+ cf = 255;
|
|
|
+ else if (cf == 255 && b2 > 1.0) {
|
|
|
+ cf = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (cf == 0)
|
|
|
+ G_warning(_("Inconsistent color rules in RAT"));
|
|
|
+ else {
|
|
|
+ /* fetch color rules */
|
|
|
+ for (indx = 0; indx < nrows; indx++) {
|
|
|
+ val1 = GDALRATGetValueAsDouble(gdal_rat, indx, minc);
|
|
|
+ val2 = GDALRATGetValueAsDouble(gdal_rat, indx, maxc);
|
|
|
+
|
|
|
+ r1 = GDALRATGetValueAsDouble(gdal_rat, indx, rminc);
|
|
|
+ g1 = GDALRATGetValueAsDouble(gdal_rat, indx, gminc);
|
|
|
+ b1 = GDALRATGetValueAsDouble(gdal_rat, indx, bminc);
|
|
|
+
|
|
|
+ r2 = GDALRATGetValueAsDouble(gdal_rat, indx, rmaxc);
|
|
|
+ g2 = GDALRATGetValueAsDouble(gdal_rat, indx, gmaxc);
|
|
|
+ b2 = GDALRATGetValueAsDouble(gdal_rat, indx, bmaxc);
|
|
|
+
|
|
|
+ Rast_add_d_color_rule(&val1, r1 * cf, g1 * cf, b1 * cf,
|
|
|
+ &val2, r2 * cf, g2 * cf, b2 * cf,
|
|
|
+ &colors);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (minmaxc >= 0 && rc >= 0 && gc >= 0 && bc >= 0) {
|
|
|
+
|
|
|
+ cf = 1;
|
|
|
+
|
|
|
+ /* analyze color table */
|
|
|
+ for (indx = 0; indx < nrows; indx++) {
|
|
|
+ val1 = GDALRATGetValueAsDouble(gdal_rat, indx, minmaxc);
|
|
|
+
|
|
|
+ r1 = GDALRATGetValueAsDouble(gdal_rat, indx, rc);
|
|
|
+ g1 = GDALRATGetValueAsDouble(gdal_rat, indx, gc);
|
|
|
+ b1 = GDALRATGetValueAsDouble(gdal_rat, indx, bc);
|
|
|
+
|
|
|
+
|
|
|
+ if (r1 > 0.0 && r1 < 1.0)
|
|
|
+ cf = 255;
|
|
|
+ else if (cf == 255 && r1 > 1.0) {
|
|
|
+ cf = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (g1 > 0.0 && g1 < 1.0)
|
|
|
+ cf = 255;
|
|
|
+ else if (cf == 255 && g1 > 1.0) {
|
|
|
+ cf = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (b1 > 0.0 && b1 < 1.0)
|
|
|
+ cf = 255;
|
|
|
+ else if (cf == 255 && b1 > 1.0) {
|
|
|
+ cf = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (cf == 0)
|
|
|
+ G_warning(_("Inconsistent color rules in RAT"));
|
|
|
+ else {
|
|
|
+ /* fetch color table */
|
|
|
+ for (indx = 0; indx < nrows; indx++) {
|
|
|
+ val1 = GDALRATGetValueAsDouble(gdal_rat, indx, minmaxc);
|
|
|
+
|
|
|
+ r1 = GDALRATGetValueAsDouble(gdal_rat, indx, rc);
|
|
|
+ g1 = GDALRATGetValueAsDouble(gdal_rat, indx, gc);
|
|
|
+ b1 = GDALRATGetValueAsDouble(gdal_rat, indx, bc);
|
|
|
+
|
|
|
+ Rast_set_d_color(val1, r1 * cf, g1 * cf, b1 * cf, &colors);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ have_colors = Rast_colors_count(&colors) > 0;
|
|
|
+
|
|
|
+ if (have_colors)
|
|
|
+ Rast_write_colors((char *)output, G_mapset(), &colors);
|
|
|
+
|
|
|
+ Rast_free_colors(&colors);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* colors in raster color table? */
|
|
|
+
|
|
|
+ if (!have_colors && !complex && GDALGetRasterColorTable(hBand) != NULL) {
|
|
|
+ GDALColorTableH hCT;
|
|
|
+ struct Colors colors;
|
|
|
+ int iColor;
|
|
|
+
|
|
|
+ G_debug(1, "Copying color table for %s", output);
|
|
|
+
|
|
|
+ hCT = GDALGetRasterColorTable(hBand);
|
|
|
+
|
|
|
+ Rast_init_colors(&colors);
|
|
|
+ for (iColor = 0; iColor < GDALGetColorEntryCount(hCT); iColor++) {
|
|
|
+ GDALColorEntry sEntry;
|
|
|
+
|
|
|
+ GDALGetColorEntryAsRGB(hCT, iColor, &sEntry);
|
|
|
+ if (sEntry.c4 == 0)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ Rast_set_c_color(iColor, sEntry.c1, sEntry.c2, sEntry.c3, &colors);
|
|
|
+ }
|
|
|
+
|
|
|
+ Rast_write_colors((char *)output, G_mapset(), &colors);
|
|
|
+ Rast_free_colors(&colors);
|
|
|
+ have_colors = 1;
|
|
|
+ }
|
|
|
+ if (!have_colors) { /* no color table present */
|
|
|
+
|
|
|
+ /* types are defined in GDAL: ./core/gdal.h */
|
|
|
+ if ((GDALGetRasterDataType(hBand) == GDT_Byte)) {
|
|
|
+ /* found 0..255 data: we set to grey scale: */
|
|
|
+ struct Colors colors;
|
|
|
+
|
|
|
+ G_verbose_message(_("Setting grey color table for <%s> (8bit, full range)"),
|
|
|
+ output);
|
|
|
+
|
|
|
+ Rast_init_colors(&colors);
|
|
|
+ Rast_make_grey_scale_colors(&colors, 0, 255); /* full range */
|
|
|
+ Rast_write_colors((char *)output, G_mapset(), &colors);
|
|
|
+ Rast_free_colors(&colors);
|
|
|
+ }
|
|
|
+ if ((GDALGetRasterDataType(hBand) == GDT_UInt16)) {
|
|
|
+ /* found 0..65535 data: we set to grey scale: */
|
|
|
+ struct Colors colors;
|
|
|
+ struct Range range;
|
|
|
+ CELL min, max;
|
|
|
+
|
|
|
+ G_verbose_message(_("Setting grey color table for <%s> (16bit, image range)"),
|
|
|
+ output);
|
|
|
+ Rast_read_range((char *)output, G_mapset(), &range);
|
|
|
+ Rast_get_range_min_max(&range, &min, &max);
|
|
|
+
|
|
|
+ Rast_init_colors(&colors);
|
|
|
+ Rast_make_grey_scale_colors(&colors, min, max); /* image range */
|
|
|
+ Rast_write_colors((char *)output, G_mapset(), &colors);
|
|
|
+ Rast_free_colors(&colors);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|