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",