Based on this discussion I made the following changes to ppm-load.c based on ff-load.c. Is it ok to commit?Â
I also changed gaussian blur so that it negotiates the format. Unfortunately I seem to have introduced some bug that broke its functionality that I have yet to solve. But that's for some other night.
diff --git a/operations/external/ppm-load.c b/operations/external/ppm-load.c
index 82041e2..d518eab 100644
--- a/operations/external/ppm-load.c
+++ b/operations/external/ppm-load.c
@@ -54,11 +54,11 @@ typedef struct {
  gsize    channels;Â
  gsize    bpc;     /* bytes per channel */
  guchar   *data;
-} pnm_struct;
+} Priv;
Â
 static gboolean
 ppm_load_read_header(FILE    *fp,
- Â Â Â Â Â Â Â Â Â Â pnm_struct *img)
+           Priv    *img)
 {
  /* PPM Headers Variable Declaration */
  gchar *ptr;
@@ -160,8 +160,65 @@ ppm_load_read_header(FILE Â Â Â *fp,
 }
Â
 static void
+init (GeglChantO *o)
+{
+  Priv    *p = (Priv*)o->chant_data;
+
+ Â if (p==NULL)
+ Â Â {
+ Â Â Â p = g_new0 (Priv, 1);
+ Â Â Â o->chant_data = (void*) p;
+ Â Â }
+}
+
+static void
+prepare (GeglOperation *operation)
+{
+ Â GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
+ Â Priv *p = (Priv*)o->chant_data;
+ Â FILE *fp;
+
+ Â if (p == NULL)
+ Â Â {
+ Â Â Â init (o);
+ Â Â Â p = (Priv*)o->chant_data;
+ Â Â }
+
+ Â g_assert (o->chant_data != NULL);
+
+ Â fp = (!strcmp (o->path, "-") ? stdin : fopen (o->path,"rb") );
+ Â if (!ppm_load_read_header (fp, p))
+ Â Â goto out;
+
+ Â if (p->bpc == 1)
+ Â Â {
+ Â Â Â if (p->channels == 3)
+ Â Â Â Â gegl_operation_set_format (operation, "output",
+ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â babl_format ("R'G'B' u8"));
+ Â Â Â else
+ Â Â Â Â gegl_operation_set_format (operation, "output",
+ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â babl_format ("Y u8"));
+ Â Â }
+ Â else if (p->bpc == 2)
+ Â Â {
+ Â Â Â if (p->channels == 3)
+ Â Â Â Â gegl_operation_set_format (operation, "output",
+ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â babl_format ("R'G'B' u16"));
+ Â Â Â else
+ Â Â Â Â gegl_operation_set_format (operation, "output",
+ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â babl_format ("Y' u16"));
+ Â Â }
+ Â else
+ Â Â g_warning ("%s: Programmer stupidity error", G_STRLOC);
+
+ out:
+ Â if (stdin != fp)
+ Â Â fclose (fp);
+}
+
+static void
 ppm_load_read_image(FILE    *fp,
- Â Â Â Â Â Â Â Â Â Â pnm_struct *img)
+ Â Â Â Â Â Â Â Â Â Â Priv *img)
 {
  guint  i;
Â
@@ -219,44 +276,12 @@ 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;
-
- Â if (!ppm_load_read_header (fp, &img))
- Â Â goto out;
-
- Â if (img.bpc == 1)
- Â Â {
- Â Â Â if (img.channels == 3)
- Â Â Â Â gegl_operation_set_format (operation, "output",
- Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â babl_format ("R'G'B' u8"));
- Â Â Â else
- Â Â Â Â gegl_operation_set_format (operation, "output",
- Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â babl_format ("Y' u8"));
- Â Â }
- Â else if (img.bpc == 2)
- Â Â {
- Â Â Â if (img.channels == 3)
- Â Â Â Â gegl_operation_set_format (operation, "output",
- Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â babl_format ("R'G'B' u16"));
- Â Â Â else
- Â Â Â Â gegl_operation_set_format (operation, "output",
- Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â babl_format ("Y' u16"));
- Â Â }
- Â else
- Â Â g_warning ("%s: Programmer stupidity error", G_STRLOC);
+  Priv  *p = (Priv*)o->chant_data;
Â
- Â result.width = img.width;
- Â result.height = img.height;
+ Â g_assert (o->chant_data != NULL);
Â
- out:
- Â if (stdin != fp)
- Â Â fclose (fp);
+ Â result.width = p->width;
+ Â result.height = p->height;
Â
  return result;
 }
@@ -269,16 +294,19 @@ process (GeglOperation    *operation,
 {
  GeglChantO  *o = GEGL_CHANT_PROPERTIES (operation);
  FILE     *fp;
-  pnm_struct   img;
  GeglRectangle rect = {0,0,0,0};
  gboolean    ret = FALSE;
+  Priv  *p = (Priv*)o->chant_data;
+  const Babl     *format = gegl_operation_get_format (operation, "output");
+
+ Â g_assert (o->chant_data != NULL);
Â
  fp = (!strcmp (o->path, "-") ? stdin : fopen (o->path,"rb"));
Â
  if (!fp)
   return FALSE;
Â
- Â if (!ppm_load_read_header (fp, &img))
+ Â if (!ppm_load_read_header (fp, p))
   goto out;
Â
  /* Allocating Array Size */
@@ -287,63 +315,24 @@ process (GeglOperation    *operation,
  * error signalled by returning FALSE isn't properly acted upon. Therefore
  * g_malloc() is used here which aborts if the requested memory size can't be
  * allocated causing a controlled crash. */
- Â img.data = "" g_malloc (img.numsamples * img.bpc);
+ Â p->data = "" g_malloc (p->numsamples * p->bpc);
Â
  /* No-op without g_try_malloc(), see above. */
- Â if (! img.data)
+ Â if (! p->data)
   {
- Â Â Â g_warning ("Couldn't allocate %" G_GSIZE_FORMAT " bytes, giving up.", ((gsize)img.numsamples * img.bpc));
+ Â Â Â g_warning ("Couldn't allocate %" G_GSIZE_FORMAT " bytes, giving up.", ((gsize)p->numsamples * p->bpc));
    goto out;
   }
Â
- Â rect.height = img.height;
- Â rect.width = img.width;
+ Â rect.height = p->height;
+ Â rect.width = p->width;
Â
- Â if (img.bpc == 1)
- Â Â {
- Â Â Â if (img.channels == 3)
- Â Â Â Â gegl_buffer_get (output, &rect, 1.0, babl_format ("R'G'B' u8"), img.data,
- Â Â Â Â Â Â Â Â Â Â Â Â GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
- Â Â Â else
- Â Â Â Â gegl_buffer_get (output, &rect, 1.0, babl_format ("Y' u8"), img.data,
- Â Â Â Â Â Â Â Â Â Â Â Â GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
- Â Â }
- Â else if (img.bpc == 2)
- Â Â {
- Â Â Â if (img.channels == 3)
- Â Â Â Â gegl_buffer_get (output, &rect, 1.0, babl_format ("R'G'B' u16"), img.data,
- Â Â Â Â Â Â Â Â Â Â Â Â GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
- Â Â Â else
- Â Â Â Â gegl_buffer_get (output, &rect, 1.0, babl_format ("Y' u16"), img.data,
- Â Â Â Â Â Â Â Â Â Â Â Â GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
- Â Â }
- Â else
- Â Â g_warning ("%s: Programmer stupidity error", G_STRLOC);
-
- Â ppm_load_read_image (fp, &img);
+ Â ppm_load_read_image (fp, p);
Â
- Â if (img.bpc == 1)
- Â Â {
- Â Â Â if (img.channels == 3)
- Â Â Â Â gegl_buffer_set (output, &rect, 0, babl_format ("R'G'B' u8"), img.data,
- Â Â Â Â Â Â Â Â Â Â Â Â GEGL_AUTO_ROWSTRIDE);
- Â Â Â else
- Â Â Â Â gegl_buffer_set (output, &rect, 0, babl_format ("Y' u8"), img.data,
+ Â gegl_buffer_set (output, &rect, 0, format, p->data,
          GEGL_AUTO_ROWSTRIDE);
- Â Â }
- Â else if (img.bpc == 2)
- Â Â {
- Â Â Â if (img.channels == 3)
- Â Â Â Â gegl_buffer_set (output, &rect, 0, babl_format ("R'G'B' u16"), img.data,
- Â Â Â Â Â Â Â Â Â Â Â Â GEGL_AUTO_ROWSTRIDE);
- Â Â Â else
- Â Â Â Â gegl_buffer_set (output, &rect, 0, babl_format ("Y' u16"), img.data,
- Â Â Â Â Â Â Â Â Â Â Â Â GEGL_AUTO_ROWSTRIDE);
- Â Â }
- Â else
- Â Â g_warning ("%s: Programmer stupidity error", G_STRLOC);
-
- Â g_free (img.data);
+ Â g_free (p->data);
+ Â p->data = "">
Â
  ret = TRUE;
Â
@@ -354,6 +343,24 @@ process (GeglOperation    *operation,
  return ret;
 }
Â
+static void
+finalize (GObject *object)
+{
+ Â GeglChantO *o = GEGL_CHANT_PROPERTIES (object);
+
+ Â if (o->chant_data)
+ Â Â {
+ Â Â Â Priv *p = (Priv*)o->chant_data;
+ Â Â Â if (p->data)
+ Â Â Â Â g_free(p->data);
+
+ Â Â Â g_free (o->chant_data);
+ Â Â Â o->chant_data = NULL;
+ Â Â }
+
+ Â G_OBJECT_CLASS (gegl_chant_parent_class)->finalize (object);
+}
+
 static GeglRectangle
 get_cached_region (GeglOperation    *operation,
          const GeglRectangle *roi)
@@ -370,9 +377,11 @@ gegl_chant_class_init (GeglChantClass *klass)
  operation_class = GEGL_OPERATION_CLASS (klass);
  source_class   = GEGL_OPERATION_SOURCE_CLASS (klass);
Â
+ Â G_OBJECT_CLASS (klass)->finalize = finalize;
  source_class->process = process;
  operation_class->get_bounding_box = get_bounding_box;
  operation_class->get_cached_region = get_cached_region;
+ Â operation_class->prepare = prepare;
Â
  gegl_operation_class_set_keys (operation_class,
                 "name"     , "gegl:ppm-load",