[GRASS-SVN] r40957 - in grass/trunk/general: . g.pnmcat

svn_grass at osgeo.org svn_grass at osgeo.org
Fri Feb 12 23:39:05 EST 2010


Author: glynn
Date: 2010-02-12 23:39:05 -0500 (Fri, 12 Feb 2010)
New Revision: 40957

Added:
   grass/trunk/general/g.pnmcat/
   grass/trunk/general/g.pnmcat/Makefile
   grass/trunk/general/g.pnmcat/g.pnmcat.html
   grass/trunk/general/g.pnmcat/main.c
Log:
Add g.pnmcat module (for use by NVIZ)



Property changes on: grass/trunk/general/g.pnmcat
___________________________________________________________________
Added: svn:ignore
   + OBJ.*


Added: grass/trunk/general/g.pnmcat/Makefile
===================================================================
--- grass/trunk/general/g.pnmcat/Makefile	                        (rev 0)
+++ grass/trunk/general/g.pnmcat/Makefile	2010-02-13 04:39:05 UTC (rev 40957)
@@ -0,0 +1,10 @@
+
+MODULE_TOPDIR = ../..
+
+PGM = g.pnmcat
+LIBES = $(GISLIB)
+DEPENDENCIES = $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd

Added: grass/trunk/general/g.pnmcat/g.pnmcat.html
===================================================================
--- grass/trunk/general/g.pnmcat/g.pnmcat.html	                        (rev 0)
+++ grass/trunk/general/g.pnmcat/g.pnmcat.html	2010-02-13 04:39:05 UTC (rev 40957)
@@ -0,0 +1,24 @@
+<H2>DESCRIPTION</H2>
+<p>
+Concatenate PNM tiles into a single image.
+<p>
+This module is for use by NVIZ' "Maximum resolution PPM" option.
+<p>
+It concatenates a grid of &lt;rows&gt; x &lt;cols&gt; binary PPM
+images into a single image. The images must all be named
+&lt;base&gt;_&lt;row&gt;_&lt;col&gt;.ppm, where &lt;row&gt; and
+&lt;col&gt; start from one, with row one being the bottom row, and
+where &lt;base&gt; is the value of the <em>base=</em> option.
+<p>
+All images within a row must have the same height, and the widths must
+sum to the value of the <em>width=</em> option. The heights of the individual
+rows must sum to the value of the <em>height=</em> option. All images must be
+in "P6" (binary PPM) format.
+
+<h2>SEE ALSO</h2>
+<em><a href="nviz.html">NVIZ</a></em>
+
+<H2>AUTHOR</H2>
+Glynn Clements
+
+<p><i>Last changed: $Date: 2008-08-15 07:16:42 +0100 (Fri, 15 Aug 2008) $</i>

Added: grass/trunk/general/g.pnmcat/main.c
===================================================================
--- grass/trunk/general/g.pnmcat/main.c	                        (rev 0)
+++ grass/trunk/general/g.pnmcat/main.c	2010-02-13 04:39:05 UTC (rev 40957)
@@ -0,0 +1,220 @@
+/*
+ * MODULE:       g.pnmcat
+ * AUTHOR(S):    Glynn Clements
+ * PURPOSE:      Concatenate PNM tiles into a single image, for use by NVIZ'
+ *               "Max. Resolution PPM" option.
+ * COPYRIGHT:    (C) 2010 by Glynn Clements
+ *
+ *               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 <stdarg.h>
+#include <string.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+struct infile {
+    FILE *fp;
+    int width;
+};
+
+static void read_line(char *buf, int size, FILE *fp)
+{
+    for (;;) {
+	if (!fgets(buf, size, fp))
+	    G_fatal_error(_("Error reading PPM file"));
+
+	if (buf[0] != '#')
+	    return;
+    }
+}
+
+static void read_header(FILE *fp, int *width, int *height)
+{
+    char buf[80];
+    char magic;
+    int maxval;
+
+    read_line(buf, sizeof(buf), fp);
+
+    if (sscanf(buf, "P%c", &magic) != 1)
+	G_fatal_error(_("Invalid PPM file"));
+
+    if (magic != '6')
+	G_fatal_error(_("Unsupported PPM file (format = P6 required)"));
+
+    read_line(buf, sizeof(buf), fp);
+
+    if (sscanf(buf, "%d %d", width, height) != 2)
+	G_fatal_error(_("Invalid PPM file"));
+
+    read_line(buf, sizeof(buf), fp);
+
+    if (sscanf(buf, "%d", &maxval) != 1)
+	G_fatal_error(_("Invalid PPM file"));
+
+    if (maxval != 255)
+	G_fatal_error(_("Unsupported PPM file (maxval = 255 required)"));
+}
+
+static void open_files(const char *base, struct infile *infiles,
+		       int row, int cols,
+		       int *p_width, int *p_height)
+{
+    int r_width = 0;
+    int r_height;
+    int col;
+
+    for (col = 0; col < cols; col++) {
+	struct infile *infile = &infiles[col];
+	char path[GPATH_MAX];
+	int c_width, c_height;
+	FILE *fp;
+
+	sprintf(path, "%s_%d_%d.ppm",  base, row + 1, col + 1);
+
+	fp = fopen(path, "rb");
+	if (!fp)
+	    G_fatal_error(_("File <%s> not found"), path);
+
+	read_header(fp, &c_width, &c_height);
+
+	r_width += c_width;
+
+	if (col == 0)
+	    r_height = c_height;
+	else
+	    if (c_height != r_height)
+		G_fatal_error(_("File <%s> has wrong height (expected %d, got %d"),
+			      path, r_height, c_height);
+
+	infile->fp = fp;
+	infile->width = c_width;
+    }
+
+    *p_width = r_width;
+    *p_height = r_height;
+}
+
+int main(int argc, char *argv[])
+{
+    struct GModule *module;
+    struct
+    {
+	struct Option *base, *out, *rows, *cols, *width, *height;
+    } opt;
+    int rows, cols, width, height;
+    int row, col;
+    int t_height = 0;
+    FILE *out_fp;
+    struct infile *infiles;
+    char *buf;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    G_add_keyword(_("general"));
+    module->description = "Concatenates multiple PPM image files";
+
+    opt.base = G_define_option();
+    opt.base->key = "base";
+    opt.base->type = TYPE_STRING;
+    opt.base->required = YES;
+    opt.base->description = _("Base name of input files");
+
+    opt.out = G_define_option();
+    opt.out->key = "output";
+    opt.out->type = TYPE_STRING;
+    opt.out->required = YES;
+    opt.out->description = _("Name of output file");
+    opt.out->gisprompt = "new_file,file,output";
+
+    opt.rows = G_define_option();
+    opt.rows->key = "rows";
+    opt.rows->type = TYPE_INTEGER;
+    opt.rows->required = YES;
+    opt.rows->description = _("Number of rows");
+
+    opt.cols = G_define_option();
+    opt.cols->key = "cols";
+    opt.cols->type = TYPE_INTEGER;
+    opt.cols->required = YES;
+    opt.cols->description = _("Number of columns");
+
+    opt.width = G_define_option();
+    opt.width->key = "width";
+    opt.width->type = TYPE_INTEGER;
+    opt.width->required = YES;
+    opt.width->description = _("Image width");
+
+    opt.height = G_define_option();
+    opt.height->key = "height";
+    opt.height->type = TYPE_INTEGER;
+    opt.height->required = YES;
+    opt.height->description = _("Image height");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    rows = atoi(opt.rows->answer);
+    cols = atoi(opt.cols->answer);
+    width = atoi(opt.width->answer);
+    height = atoi(opt.height->answer);
+
+    infiles = G_malloc(cols * sizeof(struct infile));
+    buf = G_malloc(width * 3);
+
+    out_fp = fopen(opt.out->answer, "wb");
+    if (!out_fp)
+	G_fatal_error(_("Unable to open output file <%s>"), opt.out->answer);
+
+    fprintf(out_fp, "P6\n%d %d\n255\n", width, height);
+
+    for (row = 0; row < rows; row++) {
+	int r_width = 0, r_height;
+	int i;
+
+	open_files(opt.base->answer, infiles, rows - 1 - row, cols, &r_width, &r_height);
+
+	if (r_width != width)
+	    G_fatal_error(_("Row <%d> has wrong width (expected %d, got %d"),
+			  row, width, r_width);
+
+	t_height += r_height;
+	if (t_height > height)
+	    G_fatal_error(_("Invalid height (expected %d, got %d"),
+			  height, t_height);
+
+	for (i = 0; i < r_height; i++) {
+	    char *p = buf;
+	    for (col = 0; col < cols; col++) {
+		struct infile *infile = &infiles[col];
+		if (fread(p, 3, infile->width, infile->fp) != infile->width)
+		    G_fatal_error(_("Error reading PPM file for tile <%d,%d> at row <%d>"),
+				  row, col, i);
+		p += 3 * infile->width;
+	    }
+
+	    if (fwrite(buf, 3, width, out_fp) != width)
+		G_fatal_error(_("Error writing PPM file for tile row <%d> at row <%d>"),
+			      row, i);
+	}
+
+	for (col = 0; col < cols; col++)
+	    fclose(infiles[col].fp);
+    }
+
+    if (t_height != height)
+	G_fatal_error(_("Incorrect height (expected %d, got %d"),
+		      height, t_height);
+
+    fclose(out_fp);
+
+    return 0;
+}
+



More information about the grass-commit mailing list