|
@@ -4,8 +4,9 @@
|
|
|
* MODULE: r.out.png
|
|
|
* AUTHOR(S): Bill Brown - USA-CERL
|
|
|
* Alex Shevlakov - sixote@yahoo.com
|
|
|
+ * Hamish Bowman
|
|
|
* PURPOSE: Export GRASS raster as non-georeferenced PNG image.
|
|
|
- * COPYRIGHT: (C) 2000 by the GRASS Development Team
|
|
|
+ * COPYRIGHT: (C) 2000-2010 by the GRASS Development Team
|
|
|
*
|
|
|
* This program is free software under the GNU General Public
|
|
|
* License (>=v2). Read the file COPYING that comes with GRASS
|
|
@@ -14,16 +15,13 @@
|
|
|
*****************************************************************************/
|
|
|
|
|
|
/*
|
|
|
+ * Alex Shevlakov, sixote@yahoo.com, 03/2000
|
|
|
* based on r.out.ppm by
|
|
|
* Written by Bill Brown, USA-CERL March 21, 1994
|
|
|
*
|
|
|
- */
|
|
|
-
|
|
|
-/* Use to convert grass raster map to PNG
|
|
|
+ * Use to convert grass raster map to PNG
|
|
|
* uses currently selected region
|
|
|
- */
|
|
|
-
|
|
|
-/* Alex Shevlakov, sixote@yahoo.com, 03/2000
|
|
|
+ *
|
|
|
*/
|
|
|
|
|
|
#include <string.h>
|
|
@@ -38,48 +36,50 @@
|
|
|
|
|
|
#include <grass/gis.h>
|
|
|
#include <grass/raster.h>
|
|
|
+#include <grass/colors.h>
|
|
|
#include <grass/glocale.h>
|
|
|
|
|
|
-#define DEF_RED 255
|
|
|
-#define DEF_GRN 255
|
|
|
-#define DEF_BLU 255
|
|
|
|
|
|
typedef int FILEDESC;
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
{
|
|
|
struct GModule *module;
|
|
|
- struct Option *rast, *png_file;
|
|
|
+ struct Option *rast, *png_file, *compr; /* , *bgcolor; */
|
|
|
+ struct Flag *alpha;
|
|
|
char *rastermap;
|
|
|
char *basename = NULL, *ofile;
|
|
|
unsigned char *set, *ored, *ogrn, *oblu;
|
|
|
+ int def_red, def_grn, def_blu;
|
|
|
CELL *cell_buf;
|
|
|
FCELL *fcell_buf;
|
|
|
DCELL *dcell_buf;
|
|
|
void *voidc;
|
|
|
int rtype, row, col, do_stdout = 0;
|
|
|
+ size_t rsize;
|
|
|
+ int png_compr, ret, do_alpha;
|
|
|
struct Cell_head w;
|
|
|
FILEDESC cellfile = 0;
|
|
|
FILE *fp;
|
|
|
|
|
|
/* now goes from pnmtopng.c* -A.Sh */
|
|
|
/*
|
|
|
- * ** pnmtopng.c -
|
|
|
- * ** read a portable anymap and produce a Portable Network Graphics file
|
|
|
- * **
|
|
|
- * ** derived from pnmtorast.c (c) 1990,1991 by Jef Poskanzer and some
|
|
|
- * ** parts derived from ppmtogif.c by Marcel Wijkstra <wijkstra@fwi.uva.nl>
|
|
|
- * ** thanks to Greg Roelofs <newt@pobox.com> for contributions and bug-fixes
|
|
|
- * **
|
|
|
- * ** Copyright (C) 1995-1998 by Alexander Lehmann <alex@hal.rhein-main.de>
|
|
|
- * ** and Willem van Schaik <willem@schaik.com>
|
|
|
- * **
|
|
|
- * ** Permission to use, copy, modify, and distribute this software and its
|
|
|
- * ** documentation for any purpose and without fee is hereby granted, provided
|
|
|
- * ** that the above copyright notice appear in all copies and that both that
|
|
|
- * ** copyright notice and this permission notice appear in supporting
|
|
|
- * ** documentation. This software is provided "as is" without express or
|
|
|
- * ** implied warranty.
|
|
|
+ * * pnmtopng.c -
|
|
|
+ * * read a portable anymap and produce a Portable Network Graphics file
|
|
|
+ * *
|
|
|
+ * * derived from pnmtorast.c (c) 1990,1991 by Jef Poskanzer and some
|
|
|
+ * * parts derived from ppmtogif.c by Marcel Wijkstra <wijkstra@fwi.uva.nl>
|
|
|
+ * * thanks to Greg Roelofs <newt@pobox.com> for contributions and bug-fixes
|
|
|
+ * *
|
|
|
+ * * Copyright (C) 1995-1998 by Alexander Lehmann <alex@hal.rhein-main.de>
|
|
|
+ * * and Willem van Schaik <willem@schaik.com>
|
|
|
+ * *
|
|
|
+ * * Permission to use, copy, modify, and distribute this software and its
|
|
|
+ * * documentation for any purpose and without fee is hereby granted, provided
|
|
|
+ * * that the above copyright notice appear in all copies and that both that
|
|
|
+ * * copyright notice and this permission notice appear in supporting
|
|
|
+ * * documentation. This software is provided "as is" without express or
|
|
|
+ * * implied warranty.
|
|
|
*/
|
|
|
|
|
|
png_struct *png_ptr;
|
|
@@ -103,42 +103,53 @@ int main(int argc, char *argv[])
|
|
|
|
|
|
G_gisinit(argv[0]);
|
|
|
|
|
|
- rast = G_define_option();
|
|
|
- rast->key = "input";
|
|
|
- rast->type = TYPE_STRING;
|
|
|
- rast->required = YES;
|
|
|
- rast->multiple = NO;
|
|
|
- rast->gisprompt = "old,cell,Raster";
|
|
|
- rast->description = _("Raster file to be converted.");
|
|
|
-
|
|
|
- png_file = G_define_option();
|
|
|
- png_file->key = "output";
|
|
|
- png_file->type = TYPE_STRING;
|
|
|
+ module = G_define_module();
|
|
|
+ G_add_keyword(_("raster"));
|
|
|
+ G_add_keyword(_("export"));
|
|
|
+ G_add_keyword("PNG");
|
|
|
+ module->description =
|
|
|
+ _("Export a GRASS raster map as a non-georeferenced PNG image.");
|
|
|
+
|
|
|
+ rast = G_define_standard_option(G_OPT_R_INPUT);
|
|
|
+
|
|
|
+ png_file = G_define_standard_option(G_OPT_F_OUTPUT);
|
|
|
png_file->required = YES;
|
|
|
- png_file->multiple = NO;
|
|
|
- png_file->description = _("Name for new PNG file. (use out=- for stdout)");
|
|
|
+ png_file->description = _("Name for new PNG file (use out=- for stdout)");
|
|
|
+
|
|
|
+ compr = G_define_option();
|
|
|
+ compr->key = "compression";
|
|
|
+ compr->type = TYPE_INTEGER;
|
|
|
+ compr->required = NO;
|
|
|
+ compr->multiple = NO;
|
|
|
+ compr->options = "0-9";
|
|
|
+ compr->label = _("Compression level of PNG file");
|
|
|
+ compr->description = _("(0 = none, 1 = fastest, 9 = best)");
|
|
|
+ compr->answer = "6";
|
|
|
+
|
|
|
+/* bgcolor = G_define_standard_option(G_OPT_C_BG); */
|
|
|
+
|
|
|
+ alpha = G_define_flag();
|
|
|
+ alpha->key = 't';
|
|
|
+ alpha->description = _("Make NULL cells transparent");
|
|
|
|
|
|
/* see what can be done to convert'em -A.Sh.
|
|
|
* gscale = G_define_flag ();
|
|
|
- * gscale->key = 'G';
|
|
|
+ * gscale->key = 'g';
|
|
|
* gscale->description = "Output greyscale instead of color";
|
|
|
*/
|
|
|
|
|
|
- module = G_define_module();
|
|
|
- G_add_keyword(_("raster"));
|
|
|
- G_add_keyword(_("export"));
|
|
|
- module->description =
|
|
|
- _("Export a GRASS raster map as non-georeferenced PNG image format.");
|
|
|
-
|
|
|
if (G_parser(argc, argv))
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
|
+
|
|
|
rastermap = rast->answer;
|
|
|
|
|
|
+ do_alpha = alpha->answer ? TRUE : FALSE;
|
|
|
+
|
|
|
if (strcmp(png_file->answer, "-") != 0)
|
|
|
basename = G_store(png_file->answer);
|
|
|
else
|
|
|
- do_stdout = 1;
|
|
|
+ do_stdout = TRUE;
|
|
|
|
|
|
if (basename) {
|
|
|
G_basename(basename, "png");
|
|
@@ -147,10 +158,25 @@ int main(int argc, char *argv[])
|
|
|
G_free(basename);
|
|
|
}
|
|
|
|
|
|
+ png_compr = atoi(compr->answer);
|
|
|
+
|
|
|
+#ifdef MAYBE_LATER
|
|
|
+ /* ... if at all */
|
|
|
+ ret = G_str_to_color(bgcolor->answer, &def_red, &def_grn, &def_blu);
|
|
|
+ if (ret == 0)
|
|
|
+ G_fatal_error(_("[%s]: No such color"), bgcolor->answer);
|
|
|
+ else if (ret == 2) { /* (ret==2) is "none" */
|
|
|
+ if(!do_alpha)
|
|
|
+ do_alpha = TRUE;
|
|
|
+ }
|
|
|
+#else
|
|
|
+ ret = G_str_to_color(DEFAULT_BG_COLOR, &def_red, &def_grn, &def_blu);
|
|
|
+#endif
|
|
|
+
|
|
|
/*G_get_set_window (&w); *//* 10/99 MN: check for current region */
|
|
|
G_get_window(&w);
|
|
|
|
|
|
- G_message(_("rows = %d, cols = %d"), w.rows, w.cols);
|
|
|
+ G_debug(1, "rows = %d, cols = %d", w.rows, w.cols);
|
|
|
|
|
|
/* open raster map for reading */
|
|
|
cellfile = Rast_open_old(rast->answer, "");
|
|
@@ -169,7 +195,7 @@ int main(int argc, char *argv[])
|
|
|
if (do_stdout)
|
|
|
fp = stdout;
|
|
|
else if (NULL == (fp = fopen(ofile, "w")))
|
|
|
- G_fatal_error("Not able to open file for [%s]", ofile);
|
|
|
+ G_fatal_error(_("Unable to open output file <%s>"), ofile);
|
|
|
else
|
|
|
G_free(ofile);
|
|
|
}
|
|
@@ -211,13 +237,17 @@ int main(int argc, char *argv[])
|
|
|
png_set_filter(png_ptr, 0, filter);
|
|
|
}
|
|
|
|
|
|
- /* zlib compression-level (or none) required */
|
|
|
- /* ((compression >= -1) && (compression <= 9)) */
|
|
|
- /* { */
|
|
|
- png_set_compression_level(png_ptr, Z_DEFAULT_COMPRESSION);
|
|
|
- /* } */
|
|
|
+ png_set_compression_level(png_ptr, png_compr);
|
|
|
|
|
|
- G_message(_("Converting %s..."), rast->answer);
|
|
|
+/* FIXME: this should be set
|
|
|
+ if(do_alpha) {
|
|
|
+ png_color_16p bgcolor *background_color;
|
|
|
+ png_set_background(png_ptr, png_color_16p background_color,
|
|
|
+ PNG_BACKGROUND_GAMMA_FILE, int need_expand, double background_gamma);
|
|
|
+ }
|
|
|
+*/
|
|
|
+
|
|
|
+ G_verbose_message(_("Converting <%s>..."), rast->answer);
|
|
|
|
|
|
{
|
|
|
struct Colors colors;
|
|
@@ -232,13 +262,17 @@ int main(int argc, char *argv[])
|
|
|
else if (rtype == DCELL_TYPE)
|
|
|
voidc = (DCELL *) dcell_buf;
|
|
|
else
|
|
|
- exit(EXIT_FAILURE);
|
|
|
+ G_fatal_error(_("Raster <%s> type mismatch"), rast->answer);
|
|
|
|
|
|
- /*if(!gscale->answer){ *//* 24BIT COLOR IMAGE */
|
|
|
+ rsize = Rast_cell_size(rtype);
|
|
|
|
|
|
- if (1) {
|
|
|
+ /*if(!gscale->answer){ *//* 24BIT COLOR IMAGE */
|
|
|
|
|
|
- info_ptr->color_type = PNG_COLOR_TYPE_RGB;
|
|
|
+ if (TRUE) {
|
|
|
+ if (do_alpha)
|
|
|
+ info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
|
|
|
+ else
|
|
|
+ info_ptr->color_type = PNG_COLOR_TYPE_RGB;
|
|
|
|
|
|
/* write the png-info struct */
|
|
|
png_write_info(png_ptr, info_ptr);
|
|
@@ -264,20 +298,33 @@ int main(int argc, char *argv[])
|
|
|
*pp++ = ored[col];
|
|
|
*pp++ = ogrn[col];
|
|
|
*pp++ = oblu[col];
|
|
|
+ if (do_alpha) {
|
|
|
+ if (Rast_is_null_value(
|
|
|
+ G_incr_void_ptr(voidc, col * rsize), rtype))
|
|
|
+ *pp++ = 0;
|
|
|
+ else
|
|
|
+ *pp++ = 255;
|
|
|
+ }
|
|
|
}
|
|
|
else {
|
|
|
- *pp++ = DEF_RED;
|
|
|
- *pp++ = DEF_GRN;
|
|
|
- *pp++ = DEF_BLU;
|
|
|
+ if (do_alpha) {
|
|
|
+ *pp++ = ored[col];
|
|
|
+ *pp++ = ogrn[col];
|
|
|
+ *pp++ = oblu[col];
|
|
|
+ *pp++ = 0;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ *pp++ = (unsigned char)def_red;
|
|
|
+ *pp++ = (unsigned char)def_grn;
|
|
|
+ *pp++ = (unsigned char)def_blu;
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
|
|
|
png_write_row(png_ptr, line);
|
|
|
|
|
|
}
|
|
|
-
|
|
|
+ G_percent(row, w.rows, 5); /* finish it off */
|
|
|
}
|
|
|
else { /* GREYSCALE IMAGE */
|
|
|
|
|
@@ -288,7 +335,7 @@ int main(int argc, char *argv[])
|
|
|
|
|
|
|
|
|
/* pm_message ("don't know yet how to write grey - yumm!!"); */
|
|
|
- G_warning("don't know how to write grey scale!\n");
|
|
|
+ G_warning("don't know how to write grey scale!");
|
|
|
}
|
|
|
|
|
|
Rast_free_colors(&colors);
|
|
@@ -304,7 +351,6 @@ int main(int argc, char *argv[])
|
|
|
Rast_close(cellfile);
|
|
|
|
|
|
|
|
|
-
|
|
|
png_write_end(png_ptr, info_ptr);
|
|
|
/* png_write_destroy (png_ptr); this is no longer supported with libpng, al 11/2000 */
|
|
|
/* flush first because G_free (png_ptr) can segfault due to jmpbuf problems
|
|
@@ -317,9 +363,10 @@ int main(int argc, char *argv[])
|
|
|
|
|
|
fclose(fp);
|
|
|
|
|
|
- return (0);
|
|
|
+ exit(EXIT_SUCCESS);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
#ifdef __STDC__
|
|
|
static void pnmtopng_error_handler(png_structp png_ptr, png_const_charp msg)
|
|
|
#else
|
|
@@ -339,7 +386,7 @@ static void pnmtopng_error_handler(png_ptr, msg)
|
|
|
* regardless of whether _BSD_SOURCE or anything else has (or has not)
|
|
|
* been defined. */
|
|
|
|
|
|
- G_warning("pnmtopng: fatal libpng error: %s", msg);
|
|
|
+ G_warning("pnmtopng: fatal libpng error: [%s]", msg);
|
|
|
|
|
|
jmpbuf_ptr = png_get_error_ptr(png_ptr);
|
|
|
if (jmpbuf_ptr == NULL) { /* we are completely hosed now */
|