Update to patch (removed some unused code and an incorrect comment).
2009/4/13 Henrik Akesson <h.m.akesson@xxxxxxxxx>:
> Hi,
>
> I've done a patch for reading and writing ppm images. This is mainly
> meant for debugging and testing purposes, as (when using ascii format)
> images can easily be diffed.
>
> [ppm.diff]
>
> Patch from Henrik Akesson that adds a portable pixmap loader and saver
> that can read/write both the ascii and the binary formats.
>
> * operations/external/Makefile.am
> * operations/external/ppm-load.c
> * operations/external/ppm-save.c
>
>
> /Henrik
>
Index: operations/external/ppm-load.c
===================================================================
--- operations/external/ppm-load.c (revision 0)
+++ operations/external/ppm-load.c (revision 0)
@@ -0,0 +1,219 @@
+/* This file is an image processing operation for GEGL
+ *
+ * GEGL is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * GEGL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright 2009 Henrik Akesson <h.m.akesson (a) gmail.com>
+ */
+
+#include "config.h"
+#include <glib/gi18n-lib.h>
+
+
+#ifdef GEGL_CHANT_PROPERTIES
+
+gegl_chant_file_path (path, _("File"), "", _("Path of file to load."))
+
+#else
+
+#define GEGL_CHANT_TYPE_SOURCE
+#define GEGL_CHANT_C_FILE "ppm-load.c"
+
+#define MAX_CHARS_IN_ROW 500
+#define CHANNEL_COUNT 3
+#define ASCII_P 80
+
+#include "gegl-chant.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef enum {
+ PIXMAP_ASCII = 51,
+ PIXMAP_RAW = 54,
+} map_type;
+
+typedef struct {
+ map_type type;
+ gint width;
+ gint height;
+ gint size;
+ gint maxval;
+ guchar *data;
+} pnm_struct;
+
+void
+ppm_load_read_header(FILE *fp,
+ pnm_struct *img);
+void
+ppm_load_read_image(FILE *fp,
+ pnm_struct *img);
+
+void
+ppm_load_read_header(FILE *fp,
+ pnm_struct *img)
+ {
+ /* PPM Headers Variable Declaration */
+ gchar *ptr;
+ gchar *retval;
+ gchar header[MAX_CHARS_IN_ROW];
+
+ /* Check the PPM file Type P2 or P5 */
+ retval = fgets (header,MAX_CHARS_IN_ROW,fp);
+
+ if (header[0] != ASCII_P ||
+ (header[1] != PIXMAP_ASCII &&
+ header[1] != PIXMAP_RAW
+ )
+ )
+ printf ("Image is not a portable pixmap\n");
+
+ img->type = header[1];
+
+ /* Check the Comments */
+ retval = fgets (header,MAX_CHARS_IN_ROW,fp);
+ while(header[0] == '#')
+ {
+ retval = fgets (header,MAX_CHARS_IN_ROW,fp);
+ }
+
+ /* Get Width and Height */
+ img->width = strtol (header,&ptr,0);
+ img->height = atoi (ptr);
+
+ img->size = img->width * img->height * sizeof (guchar) * CHANNEL_COUNT;
+
+ retval = fgets (header,100,fp);
+ /* Maxval is not used */
+ img->maxval = (int) strtol (header,&ptr,0);
+ }
+
+void
+ppm_load_read_image(FILE *fp,
+ pnm_struct *img)
+ {
+ gint i;
+ gint retval;
+ guchar *ptr;
+
+ if (img->type == PIXMAP_RAW)
+ {
+ /* Pixel Extraction */
+ retval = fread (img->data, 1, img->size, fp);
+ }
+ else
+ {
+ ptr = img->data;
+
+ for (i=0; i<img->size; i++)
+ retval = fscanf (fp, " %d", (int *) ptr++);
+ }
+ }
+
+static GeglRectangle
+get_bounding_box (GeglOperation *operation)
+{
+ GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
+ GeglRectangle result = {0,0,0,0};
+ pnm_struct img;
+ FILE *fp;
+
+ fp = (!strcmp (o->path, "-") ? stdin : fopen (o->path,"rb") );
+
+ if (!fp)
+ {
+ return result;
+ }
+ ppm_load_read_header (fp, &img);
+
+ if (stdin != fp)
+ {
+ fclose (fp);
+ }
+
+ gegl_operation_set_format (operation, "output", babl_format ("R'G'B' u8"));
+
+ result.width = img.width;
+ result.height = img.height;
+
+ return result;
+}
+
+static gboolean
+process (GeglOperation *operation,
+ GeglBuffer *output,
+ const GeglRectangle *result)
+{
+ GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
+ FILE *fp;
+ pnm_struct img;
+ GeglRectangle rect = {0,0,0,0};
+
+ fp = (!strcmp (o->path, "-") ? stdin : fopen (o->path,"rb"));
+
+ if (!fp)
+ {
+ return FALSE;
+ }
+
+ ppm_load_read_header (fp, &img);
+ rect.height = img.height;
+ rect.width = img.width;
+
+ /* Allocating Array Size */
+ img.data = (guchar*) g_malloc0 (img.size);
+
+ gegl_buffer_get (output, 1.0, &rect, babl_format ("R'G'B' u8"), img.data,
+ GEGL_AUTO_ROWSTRIDE);
+
+ ppm_load_read_image (fp, &img);
+
+ gegl_buffer_set (output, &rect, babl_format ("R'G'B' u8"), img.data,
+ GEGL_AUTO_ROWSTRIDE);
+
+ g_free (img.data);
+ if (stdin != fp)
+ {
+ fclose (fp);
+ }
+ return TRUE;
+}
+
+static GeglRectangle
+get_cached_region (GeglOperation *operation,
+ const GeglRectangle *roi)
+{
+ return get_bounding_box (operation);
+}
+
+static void
+gegl_chant_class_init (GeglChantClass *klass)
+{
+ GeglOperationClass *operation_class;
+ GeglOperationSourceClass *source_class;
+
+ operation_class = GEGL_OPERATION_CLASS (klass);
+ source_class = GEGL_OPERATION_SOURCE_CLASS (klass);
+
+ source_class->process = process;
+ operation_class->get_bounding_box = get_bounding_box;
+ operation_class->get_cached_region = get_cached_region;
+
+ operation_class->name = "gegl:ppm-load";
+ operation_class->categories = "hidden";
+ operation_class->description = _("PPM image loader.");
+
+ gegl_extension_handler_register (".ppm", "gegl:ppm-load");
+ gegl_extension_handler_register (".PPM", "gegl:ppm-load");
+}
+
+#endif
Index: operations/external/ppm-save.c
===================================================================
--- operations/external/ppm-save.c (revision 0)
+++ operations/external/ppm-save.c (revision 0)
@@ -0,0 +1,141 @@
+/* This file is an image processing operation for GEGL
+ *
+ * GEGL is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * GEGL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright 2009 Henrik Akesson <h.m.akesson (a) gmail.com>
+ */
+
+#include "config.h"
+#include <glib/gi18n-lib.h>
+
+
+#ifdef GEGL_CHANT_PROPERTIES
+
+gegl_chant_string (path, _("File"), "",
+ _("Target path and filename, use '-' for stdout."))
+gegl_chant_boolean (rawformat, _("Raw format"), FALSE, _("Raw format"))
+
+#else
+
+#define GEGL_CHANT_TYPE_SINK
+#define GEGL_CHANT_C_FILE "ppm-save.c"
+
+#define CHANNEL_COUNT 3
+
+#include "gegl-chant.h"
+#include <stdio.h>
+
+typedef enum {
+ PIXMAP_ASCII = 51,
+ PIXMAP_RAW = 54,
+} map_type;
+
+void
+ppm_save_write(FILE *fp,
+ gint width,
+ gint height,
+ guchar *pixels,
+ map_type type);
+
+void
+ppm_save_write(FILE *fp,
+ gint width,
+ gint height,
+ guchar *pixels,
+ map_type type)
+{
+ gint i, size, written;
+ guchar * ptr;
+
+ /* Write the header */
+ fprintf (fp, "P%c\n%d %d\n", type, width, height );
+ /* For the moment only 8 bit channels are supported */
+ fprintf (fp, "%d\n", 255);
+
+ size = width * height * sizeof (guchar) * CHANNEL_COUNT;
+
+ /* Raw images writes the data in binary form */
+ if (type == PIXMAP_RAW)
+ {
+ written = fwrite (pixels, 1, size, fp);
+ }
+ /* Otherwise a plain ascii format is used */
+ else
+ {
+ ptr = pixels;
+
+ for (i=0; i<size; i++)
+ {
+ fprintf (fp, "%3d ", (int) *ptr++);
+ if ((i + 1) % (width * CHANNEL_COUNT) == 0)
+ fprintf (fp, "\n");
+ }
+ }
+}
+
+static gboolean
+process (GeglOperation *operation,
+ GeglBuffer *input,
+ const GeglRectangle *rect)
+{
+ GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
+
+ FILE *fp;
+ guchar *pixels;
+ map_type type;
+
+ fp = (!strcmp (o->path, "-") ? stdout : fopen(o->path, "wb") );
+ if (!fp)
+ {
+ return FALSE;
+ }
+
+ pixels = g_malloc0 (rect->width * rect->height * 3);
+ gegl_buffer_get (input, 1.0, rect, babl_format ("R'G'B' u8"), pixels,
+ GEGL_AUTO_ROWSTRIDE);
+
+ type = (o->rawformat ? PIXMAP_RAW : PIXMAP_ASCII);
+
+ ppm_save_write (fp, rect->width, rect->height, pixels, type);
+
+ g_free (pixels);
+ if (fp != stdout)
+ {
+ fclose( fp );
+ }
+
+ return TRUE;
+}
+
+
+static void
+gegl_chant_class_init (GeglChantClass *klass)
+{
+ GeglOperationClass *operation_class;
+ GeglOperationSinkClass *sink_class;
+
+ operation_class = GEGL_OPERATION_CLASS (klass);
+ sink_class = GEGL_OPERATION_SINK_CLASS (klass);
+
+ sink_class->process = process;
+ sink_class->needs_full = TRUE;
+
+ operation_class->name = "gegl:ppm-save";
+ operation_class->categories = "output";
+ operation_class->description =
+ _("PPM image saver (Portable pixmap saver.)");
+
+}
+
+#endif
Index: operations/external/Makefile.am
===================================================================
--- operations/external/Makefile.am (revision 3053)
+++ operations/external/Makefile.am (working copy)
@@ -2,7 +2,7 @@
# start out with no ops, each if/endif block contains all the bits relevant
# for a specific dependency.
-ops =
+ops = ppm-load.la ppm-save.la
if HAVE_PANGOCAIRO
ops += text.la
_______________________________________________
Gegl-developer mailing list
Gegl-developer@xxxxxxxxxxxxxxxxxxxxxx
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer
[Video For Linux]
[Photo]
[Yosemite News]
[Yosemite Photos]
[gtk]
[GIMP Users]
[KDE]
[Scanner]
[Gimp's Home]
[Gimp on Windows]
[Steve's Art]
[Webcams]