[GRASS-SVN] r43926 - grass/trunk/raster/r.in.png
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Oct 15 05:59:25 EDT 2010
Author: glynn
Date: 2010-10-15 02:59:25 -0700 (Fri, 15 Oct 2010)
New Revision: 43926
Added:
grass/trunk/raster/r.in.png/main.c
Removed:
grass/trunk/raster/r.in.png/r.in.png.c
Log:
Use functions rather than direct acess to the info struct
Cleanup
Copied: grass/trunk/raster/r.in.png/main.c (from rev 43923, grass/trunk/raster/r.in.png/r.in.png.c)
===================================================================
--- grass/trunk/raster/r.in.png/main.c (rev 0)
+++ grass/trunk/raster/r.in.png/main.c 2010-10-15 09:59:25 UTC (rev 43926)
@@ -0,0 +1,569 @@
+/*
+ * $Id: r.in.png.c,v 1.11 2002/05/08 10:42:01 glynn Exp $
+ *
+ ****************************************************************************
+ *
+ * MODULE: r.in.png
+ * AUTHOR(S): Michael Shapiro - CERL
+ * Alex Shevlakov - sixote at yahoo.com
+ * Glynn Clements
+ * PURPOSE: Import non-georeferenced Images in PNG format.
+ * COPYRIGHT: (C) 2000-2002,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
+ * for details.
+ *
+ *****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <png.h>
+
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/glocale.h>
+
+typedef struct
+{
+ const char suffix[4];
+ int active;
+ int fd;
+ CELL *buf;
+ FCELL *fbuf;
+ CELL maxval;
+ char name[256];
+} channel;
+
+#define C_Y 0
+#define C_P 1
+#define C_R 2
+#define C_G 3
+#define C_B 4
+#define C_A 5
+
+static channel channels[6] = {
+ {""},
+ {""},
+ {".r"},
+ {".g"},
+ {".b"},
+ {".a"}
+};
+
+static int Header;
+static int Float;
+
+static char *input, *output, *title;
+static double f_gamma, d_gamma, alpha, t_gamma;
+static int ialpha;
+
+static png_structp png_ptr;
+static png_infop info_ptr;
+
+static png_uint_32 width, height;
+static int bit_depth, color_type, interlace_type, compression_type, filter_type;
+
+static double gamma_correct(double k)
+{
+ return pow(k, 1.0 / t_gamma);
+}
+
+static int intensity(double k)
+{
+ return (int) (gamma_correct(k) * 255 + 0.5);
+}
+
+static int get_byte(png_bytep *pp)
+{
+ return *(*pp)++;
+}
+
+static int get_png_val(png_bytep *pp, int bit_depth)
+{
+ return (bit_depth == 16)
+ ? (get_byte(pp) << 8) | get_byte(pp)
+ : get_byte(pp);
+}
+
+static void init_channel(channel *c)
+{
+ sprintf(c->name, "%s%s", output, c->suffix);
+
+ if (Float)
+ {
+ c->fd = Rast_open_fp_new(c->name);
+ c->fbuf = Rast_allocate_f_buf();
+ }
+ else
+ {
+ c->fd = Rast_open_c_new(c->name);
+ c->buf = Rast_allocate_c_buf();
+ }
+
+ c->active = 1;
+}
+
+static void write_row_int(png_bytep p)
+{
+ int x, c;
+ channel *ch;
+
+ for (x = 0; x < width; x++)
+ for (c = 0; c < 6; c++)
+ {
+ ch = &channels[c];
+ if (ch->active)
+ ch->buf[x] = (CELL) get_png_val(&p, bit_depth);
+ }
+
+ if (channels[C_A].active && ialpha > 0)
+ for (c = 0; c < 6; c++)
+ {
+ ch = &channels[c];
+ if (c != C_A && ch->active)
+ for (x = 0; x < width; x++)
+ if (channels[C_A].buf[x] <= ialpha)
+ Rast_set_c_null_value(&ch->buf[x], 1);
+ }
+
+ for (c = 0; c < 6; c++)
+ {
+ ch = &channels[c];
+ if (ch->active)
+ Rast_put_c_row(ch->fd, ch->buf);
+ }
+}
+
+static void write_row_float(png_bytep p)
+{
+ int x, c;
+ channel *ch;
+
+ for (x = 0; x < width; x++)
+ for (c = 0; c < 6; c++)
+ {
+ ch = &channels[c];
+ if (ch->active)
+ ch->fbuf[x] = (FCELL) get_png_val(&p, bit_depth)
+ / ch->maxval;
+ }
+
+ if (t_gamma != 1.0)
+ for (c = 0; c < 6; c++)
+ {
+ ch = &channels[c];
+ if (c != C_A && ch->active)
+ for (x = 0; x < width; x++)
+ ch->fbuf[x] = gamma_correct(ch->fbuf[x]);
+ }
+
+ if (channels[C_A].active && ialpha > 0)
+ for (c = 0; c < 6; c++)
+ {
+ ch = &channels[c];
+ if (c != C_A && ch->active)
+ for (x = 0; x < width; x++)
+ if (channels[C_A].fbuf[x] <= alpha)
+ Rast_set_f_null_value(&ch->fbuf[x], 1);
+ }
+
+ for (c = 0; c < 6; c++)
+ {
+ ch = &channels[c];
+ if (ch->active)
+ Rast_put_f_row(ch->fd, ch->fbuf);
+ }
+}
+
+static void write_colors_int(int c)
+{
+ channel *ch = &channels[c];
+ CELL i0 = 0;
+ CELL i1 = ch->maxval;
+ struct Colors colors;
+ int i;
+
+ Rast_init_colors(&colors);
+
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_colorp palette;
+ int num_palette;
+
+ png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
+
+ for (i = 0; i < num_palette; i++)
+ {
+ png_colorp col = &palette[i];
+ Rast_set_c_color((CELL) i, col->red, col->green, col->blue, &colors);
+ }
+ }
+ else if (c == C_A || t_gamma == 1.0)
+ Rast_add_c_color_rule(&i0, 0, 0, 0,
+ &i1, 255, 255, 255,
+ &colors);
+ else
+ for (i = 0; i <= i1; i++)
+ {
+ int v = intensity((double) i / i1);
+ Rast_set_c_color((CELL) i, v, v, v, &colors);
+ }
+
+ Rast_write_colors(ch->name, G_mapset(), &colors);
+}
+
+static void write_colors_float(int c)
+{
+ channel *ch = &channels[c];
+ FCELL i0 = 0.0;
+ FCELL i1 = 1.0;
+ struct Colors colors;
+
+ Rast_init_colors(&colors);
+
+ Rast_add_f_color_rule(&i0, 0, 0, 0,
+ &i1, 255, 255, 255,
+ &colors);
+
+ Rast_write_colors(ch->name, G_mapset(), &colors);
+}
+
+static void print_header(void)
+{
+ char gamma_string[80] = "";
+ const char *type_string = "";
+ const char *alpha_string = "";
+
+ switch (color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ type_string = "gray";
+ alpha_string = "";
+ break;
+
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ type_string = "gray";
+ alpha_string = "+alpha";
+ break;
+
+ case PNG_COLOR_TYPE_PALETTE:
+ type_string = "palette";
+ alpha_string = "";
+ break;
+
+ case PNG_COLOR_TYPE_RGB:
+ type_string = "truecolor";
+ alpha_string = "";
+ break;
+
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ type_string = "truecolor";
+ alpha_string = "+alpha";
+ break;
+ }
+
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+ alpha_string = "+transparency";
+
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA))
+ sprintf(gamma_string, ", image gamma = %4.2f", f_gamma);
+
+ fprintf(stderr, "%lu x %lu image, %d bit%s %s%s%s%s\n",
+ (unsigned long) width, (unsigned long) height,
+ bit_depth, bit_depth > 1 ? "s" : "",
+ type_string, alpha_string,
+ gamma_string,
+ interlace_type ? ", Adam7 interlaced" : "");
+}
+
+static void read_png(void)
+{
+ unsigned char sig_buf[8];
+ png_bytep png_buffer;
+ png_bytep *png_rows;
+ int linesize;
+ struct Cell_head cellhd;
+ int y, c;
+ png_color_8p sig_bit;
+ int sbit, interlace;
+ FILE *ifp;
+
+ /* initialize input stream and PNG library */
+
+ ifp = fopen(input, "rb");
+ if (!ifp)
+ G_fatal_error("unable to open PNG file %s", input);
+
+ if (fread(sig_buf, sizeof(sig_buf), 1, ifp) != 1)
+ G_fatal_error("input file empty or too short");
+
+ if (png_sig_cmp(sig_buf, 0, sizeof(sig_buf)) != 0)
+ G_fatal_error("input file not a PNG file");
+
+ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!png_ptr)
+ G_fatal_error("cannot allocate PNG structure");
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr)
+ G_fatal_error("cannot allocate PNG structures");
+
+ if (setjmp(png_jmpbuf(png_ptr)))
+ G_fatal_error("PNG error");
+
+ png_init_io(png_ptr, ifp);
+ png_set_sig_bytes(png_ptr, sizeof(sig_buf));
+
+ png_read_info(png_ptr, info_ptr);
+
+ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth,
+ &color_type, &interlace_type, &compression_type, &filter_type);
+
+ if (Header || G_verbose() == G_verbose_max())
+ print_header();
+
+ if (Header)
+ {
+ fclose(ifp);
+ exit(0);
+ }
+
+ /* read image parameters and set up data conversions */
+
+ if (png_get_bit_depth(png_ptr, info_ptr) < 8)
+ png_set_packing(png_ptr);
+
+ sbit = png_get_sBIT(png_ptr, info_ptr, &sig_bit);
+ if (sbit)
+ png_set_shift(png_ptr, sig_bit);
+
+ if (!png_get_gAMA(png_ptr, info_ptr, &f_gamma))
+ f_gamma = 0.0;
+
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+ png_set_tRNS_to_alpha(png_ptr);
+
+ if (Float && color_type == PNG_COLOR_TYPE_PALETTE)
+ png_set_palette_to_rgb(png_ptr);
+
+ png_read_update_info(png_ptr, info_ptr);
+
+ interlace = (interlace_type != PNG_INTERLACE_NONE);
+
+ ialpha = (int) (alpha * channels[C_A].maxval);
+
+ t_gamma = (f_gamma != 0.0 && d_gamma != 0.0)
+ ? f_gamma * d_gamma
+ : 1.0;
+
+ /* allocate input buffer */
+
+ linesize = png_get_rowbytes(png_ptr, info_ptr);
+
+ png_buffer = G_malloc(interlace
+ ? height * linesize
+ : linesize);
+
+ if (interlace)
+ {
+ png_rows = G_malloc(height * sizeof(png_bytep));
+ for (y = 0; y < height; y++)
+ png_rows[y] = png_buffer + y * linesize;
+ }
+
+ /* initialize cell header */
+
+ Rast_get_window(&cellhd);
+
+ cellhd.rows = height;
+ cellhd.cols = width;
+ cellhd.north = cellhd.rows;
+ cellhd.south = 0.0;
+ cellhd.east = cellhd.cols;
+ cellhd.west = 0.0;
+ cellhd.ns_res = 1;
+ cellhd.ew_res = 1;
+
+ Rast_set_window(&cellhd);
+
+ /* initialize channel information */
+
+ switch (color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ init_channel(&channels[C_Y]);
+ break;
+
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ init_channel(&channels[C_Y]);
+ init_channel(&channels[C_A]);
+ break;
+
+ case PNG_COLOR_TYPE_PALETTE:
+ init_channel(&channels[C_P]);
+ break;
+
+ case PNG_COLOR_TYPE_RGB:
+ init_channel(&channels[C_R]);
+ init_channel(&channels[C_G]);
+ init_channel(&channels[C_B]);
+ break;
+
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ init_channel(&channels[C_R]);
+ init_channel(&channels[C_G]);
+ init_channel(&channels[C_B]);
+ init_channel(&channels[C_A]);
+ break;
+ }
+
+ if (sbit)
+ {
+ channels[C_R].maxval = (1 << sig_bit->red ) - 1;
+ channels[C_G].maxval = (1 << sig_bit->green) - 1;
+ channels[C_B].maxval = (1 << sig_bit->blue ) - 1;
+ channels[C_Y].maxval = (1 << sig_bit->gray ) - 1;
+ channels[C_A].maxval = (1 << sig_bit->alpha) - 1;
+ }
+ else
+ {
+ channels[C_R].maxval = (1 << bit_depth) - 1;
+ channels[C_G].maxval = (1 << bit_depth) - 1;
+ channels[C_B].maxval = (1 << bit_depth) - 1;
+ channels[C_Y].maxval = (1 << bit_depth) - 1;
+ channels[C_A].maxval = (1 << bit_depth) - 1;
+ }
+
+ /* read image and write raster layers */
+
+ if (interlace)
+ png_read_image(png_ptr, png_rows);
+
+ for (y = 0; y < height; y++)
+ {
+ png_bytep p;
+
+ if (interlace)
+ p = png_rows[y];
+ else
+ {
+ png_read_row(png_ptr, png_buffer, NULL);
+ p = png_buffer;
+ }
+
+ if (Float)
+ write_row_float(p);
+ else
+ write_row_int(p);
+ }
+
+ png_read_end(png_ptr, NULL);
+
+ fclose(ifp);
+
+ /* close output files */
+
+ for (c = 0; c < 6; c++)
+ {
+ channel *ch = &channels[c];
+
+ if (!ch->active)
+ continue;
+
+ Rast_close(ch->fd);
+
+ if (Float)
+ G_free(ch->fbuf);
+ else
+ G_free(ch->buf);
+ }
+
+ /* write title and color table */
+
+ G_verbose_message(_("Creating support files for <%s>"), output);
+
+ for (c = 0; c < 6; c++)
+ {
+ channel *ch = &channels[c];
+
+ if (!ch->active)
+ continue;
+
+ if (title && *title)
+ Rast_put_cell_title(ch->name, title);
+
+ if (Float)
+ write_colors_float(c);
+ else
+ write_colors_int(c);
+ }
+
+ G_free(png_buffer);
+ if (interlace)
+ G_free(png_rows);
+
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+}
+
+int main(int argc, char *argv[])
+{
+ struct Option *inopt, *outopt, *titleopt, *gammaopt, *alphaopt;
+ struct Flag *fflag, *hflag;
+ struct GModule *module;
+
+ G_gisinit(argv[0]);
+
+ module = G_define_module();
+ module->description = "Import non-georeferenced PNG format image.";
+
+ inopt = G_define_standard_option(G_OPT_F_INPUT);
+
+ outopt = G_define_standard_option(G_OPT_R_OUTPUT);
+
+ titleopt = G_define_option();
+ titleopt->key = "title";
+ titleopt->type = TYPE_STRING;
+ titleopt->required = NO;
+ titleopt->description = _("Title for new raster file.");
+
+ gammaopt = G_define_option();
+ gammaopt->key = "gamma";
+ gammaopt->type = TYPE_DOUBLE;
+ gammaopt->required = NO;
+ gammaopt->description = _("Display gamma.");
+
+ alphaopt = G_define_option();
+ alphaopt->key = "alpha";
+ alphaopt->type = TYPE_DOUBLE;
+ alphaopt->required = NO;
+ alphaopt->description = _("Alpha threshold.");
+
+ fflag = G_define_flag();
+ fflag->key = 'f';
+ fflag->description = _("Create floating-point maps (0.0 - 1.0).");
+
+ hflag = G_define_flag();
+ hflag->key = 'h';
+ hflag->description = _("Output image file header only.");
+
+ if(G_parser(argc, argv))
+ exit(1);
+
+ input = inopt->answer;
+ output = outopt->answer;
+ title = titleopt->answer;
+ d_gamma = gammaopt->answer ? atof(gammaopt->answer) : 0.0;
+ alpha = alphaopt->answer ? atof(alphaopt->answer) : -1.0;
+
+ Float = fflag->answer;
+ Header = hflag->answer;
+
+ read_png();
+
+ return 0;
+}
+
Deleted: grass/trunk/raster/r.in.png/r.in.png.c
===================================================================
--- grass/trunk/raster/r.in.png/r.in.png.c 2010-10-15 09:49:51 UTC (rev 43925)
+++ grass/trunk/raster/r.in.png/r.in.png.c 2010-10-15 09:59:25 UTC (rev 43926)
@@ -1,559 +0,0 @@
-/*
- * $Id: r.in.png.c,v 1.11 2002/05/08 10:42:01 glynn Exp $
- *
- ****************************************************************************
- *
- * MODULE: r.in.png
- * AUTHOR(S): Michael Shapiro - CERL
- * Alex Shevlakov - sixote at yahoo.com
- * Glynn Clements
- * PURPOSE: Import non-georeferenced Images in PNG format.
- * COPYRIGHT: (C) 2000-2002,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
- * for details.
- *
- *****************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#include <png.h>
-
-#include <grass/gis.h>
-#include <grass/raster.h>
-#include <grass/glocale.h>
-
-typedef struct
-{
- const char suffix[4];
- int active;
- int fd;
- CELL *buf;
- FCELL *fbuf;
- CELL maxval;
- char name[256];
-} channel;
-
-#define C_Y 0
-#define C_P 1
-#define C_R 2
-#define C_G 3
-#define C_B 4
-#define C_A 5
-
-static channel channels[6] = {
- {""},
- {""},
- {".r"},
- {".g"},
- {".b"},
- {".a"}
-};
-
-static int Header;
-static int Float;
-
-static char *input, *output, *title;
-static double d_gamma, alpha, t_gamma;
-static int ialpha;
-
-static png_structp png_ptr;
-static png_infop info_ptr;
-
-static double gamma_correct(double k)
-{
- return pow(k, 1.0 / t_gamma);
-}
-
-static int intensity(double k)
-{
- return (int) (gamma_correct(k) * 255 + 0.5);
-}
-
-static int get_byte(png_bytep *pp)
-{
- return *(*pp)++;
-}
-
-static int get_png_val(png_bytep *pp, int bit_depth)
-{
- return (bit_depth == 16)
- ? (get_byte(pp) << 8) | get_byte(pp)
- : get_byte(pp);
-}
-
-static void init_channel(channel *c)
-{
- sprintf(c->name, "%s%s", output, c->suffix);
-
- if (Float)
- {
- c->fd = Rast_open_fp_new(c->name);
- c->fbuf = Rast_allocate_f_buf();
- }
- else
- {
- c->fd = Rast_open_c_new(c->name);
- c->buf = Rast_allocate_c_buf();
- }
-
- c->active = 1;
-}
-
-static void write_row_int(png_bytep p)
-{
- int x, c;
- channel *ch;
-
- for (x = 0; x < info_ptr->width; x++)
- for (c = 0; c < 6; c++)
- {
- ch = &channels[c];
- if (ch->active)
- ch->buf[x] = (CELL) get_png_val(&p, info_ptr->bit_depth);
- }
-
- if (channels[C_A].active && ialpha > 0)
- for (c = 0; c < 6; c++)
- {
- ch = &channels[c];
- if (c != C_A && ch->active)
- for (x = 0; x < info_ptr->width; x++)
- if (channels[C_A].buf[x] <= ialpha)
- Rast_set_c_null_value(&ch->buf[x], 1);
- }
-
- for (c = 0; c < 6; c++)
- {
- ch = &channels[c];
- if (ch->active)
- Rast_put_c_row(ch->fd, ch->buf);
- }
-}
-
-static void write_row_float(png_bytep p)
-{
- int x, c;
- channel *ch;
-
- for (x = 0; x < info_ptr->width; x++)
- for (c = 0; c < 6; c++)
- {
- ch = &channels[c];
- if (ch->active)
- ch->fbuf[x] = (FCELL) get_png_val(&p, info_ptr->bit_depth)
- / ch->maxval;
- }
-
- if (t_gamma != 1.0)
- for (c = 0; c < 6; c++)
- {
- ch = &channels[c];
- if (c != C_A && ch->active)
- for (x = 0; x < info_ptr->width; x++)
- ch->fbuf[x] = gamma_correct(ch->fbuf[x]);
- }
-
- if (channels[C_A].active && ialpha > 0)
- for (c = 0; c < 6; c++)
- {
- ch = &channels[c];
- if (c != C_A && ch->active)
- for (x = 0; x < info_ptr->width; x++)
- if (channels[C_A].fbuf[x] <= alpha)
- Rast_set_f_null_value(&ch->fbuf[x], 1);
- }
-
- for (c = 0; c < 6; c++)
- {
- ch = &channels[c];
- if (ch->active)
- Rast_put_f_row(ch->fd, ch->fbuf);
- }
-}
-
-static void write_colors_int(int c)
-{
- channel *ch = &channels[c];
- CELL i0 = 0;
- CELL i1 = ch->maxval;
- struct Colors colors;
- int i;
-
- Rast_init_colors(&colors);
-
- if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- for (i = 0; i < info_ptr->num_palette; i++)
- {
- png_colorp col = &info_ptr->palette[i];
- Rast_set_c_color((CELL) i, col->red, col->green, col->blue, &colors);
- }
- }
- else if (c == C_A || t_gamma == 1.0)
- Rast_add_c_color_rule(&i0, 0, 0, 0,
- &i1, 255, 255, 255,
- &colors);
- else
- for (i = 0; i <= i1; i++)
- {
- int v = intensity((double) i / i1);
- Rast_set_c_color((CELL) i, v, v, v, &colors);
- }
-
- Rast_write_colors(ch->name, G_mapset(), &colors);
-}
-
-static void write_colors_float(int c)
-{
- channel *ch = &channels[c];
- FCELL i0 = 0.0;
- FCELL i1 = 1.0;
- struct Colors colors;
-
- Rast_init_colors(&colors);
-
- Rast_add_f_color_rule(&i0, 0, 0, 0,
- &i1, 255, 255, 255,
- &colors);
-
- Rast_write_colors(ch->name, G_mapset(), &colors);
-}
-
-static void print_header(void)
-{
- char gamma_string[80] = "";
- const char *type_string = "";
- const char *alpha_string = "";
-
- switch (info_ptr->color_type)
- {
- case PNG_COLOR_TYPE_GRAY:
- type_string = "gray";
- alpha_string = "";
- break;
-
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- type_string = "gray";
- alpha_string = "+alpha";
- break;
-
- case PNG_COLOR_TYPE_PALETTE:
- type_string = "palette";
- alpha_string = "";
- break;
-
- case PNG_COLOR_TYPE_RGB:
- type_string = "truecolor";
- alpha_string = "";
- break;
-
- case PNG_COLOR_TYPE_RGB_ALPHA:
- type_string = "truecolor";
- alpha_string = "+alpha";
- break;
- }
-
- if (info_ptr->valid & PNG_INFO_tRNS)
- alpha_string = "+transparency";
-
- if (info_ptr->valid & PNG_INFO_gAMA)
- sprintf(gamma_string, ", image gamma = %4.2f", info_ptr->gamma);
-
- fprintf(stderr, "%ld x %ld image, %d bit%s %s%s%s%s\n",
- info_ptr->width, info_ptr->height,
- info_ptr->bit_depth, info_ptr->bit_depth > 1 ? "s" : "",
- type_string, alpha_string,
- gamma_string,
- info_ptr->interlace_type ? ", Adam7 interlaced" : "");
-}
-
-static void read_png(void)
-{
- char sig_buf[8];
- png_bytep png_buffer;
- png_bytep *png_rows;
- int linesize;
- struct Cell_head cellhd;
- int y, c;
- png_color_8p sig_bit;
- int sbit, interlace;
- double f_gamma;
- FILE *ifp;
-
- /* initialize input stream and PNG library */
-
- ifp = fopen(input, "rb");
- if (!ifp)
- G_fatal_error("unable to open PNG file %s", input);
-
- if (fread(sig_buf, sizeof(sig_buf), 1, ifp) != 1)
- G_fatal_error("input file empty or too short");
-
- if (png_sig_cmp(sig_buf, 0, sizeof(sig_buf)) != 0)
- G_fatal_error("input file not a PNG file");
-
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- if (!png_ptr)
- G_fatal_error("cannot allocate PNG structure");
-
- info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr)
- G_fatal_error("cannot allocate PNG structures");
-
- if (setjmp(png_jmpbuf(png_ptr)))
- G_fatal_error("PNG error");
-
- png_init_io(png_ptr, ifp);
- png_set_sig_bytes(png_ptr, sizeof(sig_buf));
-
- png_read_info(png_ptr, info_ptr);
-
- if (Header || G_verbose() == G_verbose_max())
- print_header();
-
- if (Header)
- {
- fclose(ifp);
- exit(0);
- }
-
- /* read image parameters and set up data conversions */
-
- if (png_get_bit_depth(png_ptr, info_ptr) < 8)
- png_set_packing(png_ptr);
-
- sbit = png_get_sBIT(png_ptr, info_ptr, &sig_bit);
- if (sbit)
- png_set_shift(png_ptr, sig_bit);
-
- if (!png_get_gAMA(png_ptr, info_ptr, &f_gamma))
- f_gamma = 0.0;
-
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
- png_set_tRNS_to_alpha(png_ptr);
-
- if (Float && info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- png_set_palette_to_rgb(png_ptr);
-
- png_read_update_info(png_ptr, info_ptr);
-
- interlace = (info_ptr->interlace_type != PNG_INTERLACE_NONE);
-
- ialpha = (int) (alpha * channels[C_A].maxval);
-
- t_gamma = (f_gamma != 0.0 && d_gamma != 0.0)
- ? f_gamma * d_gamma
- : 1.0;
-
- /* allocate input buffer */
-
- linesize = png_get_rowbytes(png_ptr, info_ptr);
-
- png_buffer = G_malloc(interlace
- ? info_ptr->height * linesize
- : linesize);
-
- if (interlace)
- {
- png_rows = G_malloc(info_ptr->height * sizeof(png_bytep));
- for (y = 0; y < info_ptr->height; y++)
- png_rows[y] = png_buffer + y * linesize;
- }
-
- /* initialize cell header */
-
- Rast_get_window(&cellhd);
-
- cellhd.rows = info_ptr->height;
- cellhd.cols = info_ptr->width;
- cellhd.north = cellhd.rows;
- cellhd.south = 0.0;
- cellhd.east = cellhd.cols;
- cellhd.west = 0.0;
- cellhd.ns_res = 1;
- cellhd.ew_res = 1;
-
- Rast_set_window(&cellhd);
-
- /* initialize channel information */
-
- switch (info_ptr->color_type)
- {
- case PNG_COLOR_TYPE_GRAY:
- init_channel(&channels[C_Y]);
- break;
-
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- init_channel(&channels[C_Y]);
- init_channel(&channels[C_A]);
- break;
-
- case PNG_COLOR_TYPE_PALETTE:
- init_channel(&channels[C_P]);
- break;
-
- case PNG_COLOR_TYPE_RGB:
- init_channel(&channels[C_R]);
- init_channel(&channels[C_G]);
- init_channel(&channels[C_B]);
- break;
-
- case PNG_COLOR_TYPE_RGB_ALPHA:
- init_channel(&channels[C_R]);
- init_channel(&channels[C_G]);
- init_channel(&channels[C_B]);
- init_channel(&channels[C_A]);
- break;
- }
-
- if (sbit)
- {
- channels[C_R].maxval = (1 << sig_bit->red ) - 1;
- channels[C_G].maxval = (1 << sig_bit->green) - 1;
- channels[C_B].maxval = (1 << sig_bit->blue ) - 1;
- channels[C_Y].maxval = (1 << sig_bit->gray ) - 1;
- channels[C_A].maxval = (1 << sig_bit->alpha) - 1;
- }
- else
- {
- channels[C_R].maxval = (1 << info_ptr->bit_depth) - 1;
- channels[C_G].maxval = (1 << info_ptr->bit_depth) - 1;
- channels[C_B].maxval = (1 << info_ptr->bit_depth) - 1;
- channels[C_Y].maxval = (1 << info_ptr->bit_depth) - 1;
- channels[C_A].maxval = (1 << info_ptr->bit_depth) - 1;
- }
-
- /* read image and write raster layers */
-
- if (interlace)
- png_read_image(png_ptr, png_rows);
-
- for (y = 0; y < info_ptr->height; y++)
- {
- png_bytep p;
-
- if (interlace)
- p = png_rows[y];
- else
- {
- png_read_row(png_ptr, png_buffer, NULL);
- p = png_buffer;
- }
-
- if (Float)
- write_row_float(p);
- else
- write_row_int(p);
- }
-
- png_read_end(png_ptr, NULL);
-
- fclose(ifp);
-
- /* close output files */
-
- for (c = 0; c < 6; c++)
- {
- channel *ch = &channels[c];
-
- if (!ch->active)
- continue;
-
- Rast_close(ch->fd);
-
- if (Float)
- G_free(ch->fbuf);
- else
- G_free(ch->buf);
- }
-
- /* write title and color table */
-
- G_verbose_message(_("Creating support files for <%s>"), output);
-
- for (c = 0; c < 6; c++)
- {
- channel *ch = &channels[c];
-
- if (!ch->active)
- continue;
-
- if (title && *title)
- Rast_put_cell_title(ch->name, title);
-
- if (Float)
- write_colors_float(c);
- else
- write_colors_int(c);
- }
-
- G_free(png_buffer);
- if (interlace)
- G_free(png_rows);
-
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
-}
-
-int main(int argc, char *argv[])
-{
- struct Option *inopt, *outopt, *titleopt, *gammaopt, *alphaopt;
- struct Flag *fflag, *hflag;
- struct GModule *module;
-
- G_gisinit(argv[0]);
-
- module = G_define_module();
- module->description = "Import non-georeferenced PNG format image.";
-
- inopt = G_define_standard_option(G_OPT_F_INPUT);
-
- outopt = G_define_standard_option(G_OPT_R_OUTPUT);
-
- titleopt = G_define_option();
- titleopt->key = "title";
- titleopt->type = TYPE_STRING;
- titleopt->required = NO;
- titleopt->description = _("Title for new raster file.");
-
- gammaopt = G_define_option();
- gammaopt->key = "gamma";
- gammaopt->type = TYPE_DOUBLE;
- gammaopt->required = NO;
- gammaopt->description = _("Display gamma.");
-
- alphaopt = G_define_option();
- alphaopt->key = "alpha";
- alphaopt->type = TYPE_DOUBLE;
- alphaopt->required = NO;
- alphaopt->description = _("Alpha threshold.");
-
- fflag = G_define_flag();
- fflag->key = 'f';
- fflag->description = _("Create floating-point maps (0.0 - 1.0).");
-
- hflag = G_define_flag();
- hflag->key = 'h';
- hflag->description = _("Output image file header only.");
-
- if(G_parser(argc, argv))
- exit(1);
-
- input = inopt->answer;
- output = outopt->answer;
- title = titleopt->answer;
- d_gamma = gammaopt->answer ? atof(gammaopt->answer) : 0.0;
- alpha = alphaopt->answer ? atof(alphaopt->answer) : -1.0;
-
- Float = fflag->answer;
- Header = hflag->answer;
-
- read_png();
-
- return 0;
-}
-
More information about the grass-commit
mailing list