Google
  Web www.spinics.net

Re: Portable pixmap patch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


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]