[gimp/goat-invasion] first shot at PNG loading with GEGL
- From: Simon Budig <simon src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/goat-invasion] first shot at PNG loading with GEGL
- Date: Thu, 26 Apr 2012 02:22:40 +0000 (UTC)
commit 91ffada18ea567c8ef20dc38f9631cbc19fcf419
Author: Simon Budig <simon budig de>
Date: Thu Apr 26 03:16:19 2012 +0200
first shot at PNG loading with GEGL
Doesn't work yet for 16bit PNGs, there is a weird crash in libgimp
but I didn't do anything...
This closely follows the old pixel region based code, which might
be suboptimal for gegl, but has the advantage of keeping metadata intact.
Indexed currently is disabled, needs resurrecting.
plug-ins/common/Makefile.am | 1 +
plug-ins/common/file-png.c | 79 ++++++++++++++++++----------------------
plug-ins/common/plugin-defs.pl | 2 +-
3 files changed, 37 insertions(+), 45 deletions(-)
---
diff --git a/plug-ins/common/Makefile.am b/plug-ins/common/Makefile.am
index cf3dd2e..d5d7712 100644
--- a/plug-ins/common/Makefile.am
+++ b/plug-ins/common/Makefile.am
@@ -1330,6 +1330,7 @@ file_png_LDADD = \
$(libgimpcolor) \
$(libgimpbase) \
$(GTK_LIBS) \
+ $(GEGL_LIBS) \
$(PNG_LIBS) \
$(RT_LIBS) \
$(INTLLIBS) \
diff --git a/plug-ins/common/file-png.c b/plug-ins/common/file-png.c
index 4e590a9..3ee6733 100644
--- a/plug-ins/common/file-png.c
+++ b/plug-ins/common/file-png.c
@@ -411,6 +411,8 @@ run (const gchar *name,
*nreturn_vals = 1;
*return_vals = values;
+ gegl_init (NULL, NULL);
+
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
@@ -621,9 +623,9 @@ run (const gchar *name,
struct read_error_data
{
- GimpPixelRgn *pixel_rgn; /* Pixel region for layer */
guchar *pixel; /* Pixel data */
- GimpDrawable *drawable; /* Drawable for layer */
+ GeglBuffer *buffer; /* GEGL buffer for layer */
+ const Babl *file_format;
guint32 width; /* png_infop->width */
guint32 height; /* png_infop->height */
gint bpp; /* Bytes per pixel */
@@ -645,9 +647,7 @@ on_read_error (png_structp png_ptr, png_const_charp error_msg)
/* Flush the current half-read row of tiles */
- gimp_pixel_rgn_set_rect (error_data->pixel_rgn, error_data->pixel, 0,
- error_data->begin, error_data->drawable->width,
- error_data->num);
+ gegl_buffer_set (error_data->buffer, GEGL_RECTANGLE (0, error_data->begin, gegl_buffer_get_width (error_data->buffer), error_data->num), 0, error_data->file_format, error_data->pixel, GEGL_AUTO_ROWSTRIDE);
/* Fill the rest of the rows of tiles with 0s */
@@ -664,9 +664,7 @@ on_read_error (png_structp png_ptr, png_const_charp error_msg)
num = end - begin;
- gimp_pixel_rgn_set_rect (error_data->pixel_rgn, error_data->pixel, 0,
- begin,
- error_data->drawable->width, num);
+ gegl_buffer_set (error_data->buffer, GEGL_RECTANGLE (0, begin, gegl_buffer_get_width (error_data->buffer), num), 0, error_data->file_format, error_data->pixel, GEGL_AUTO_ROWSTRIDE);
}
longjmp (png_jmpbuf (png_ptr), 1);
@@ -696,6 +694,7 @@ load_image (const gchar *filename,
int i, /* Looping var */
trns, /* Transparency present */
bpp, /* Bytes per pixel */
+ have_u16 = 0, /* 16bit values? */
image_type, /* Type of image */
layer_type, /* Type of drawable/layer */
empty, /* Number of fully transparent indices */
@@ -708,8 +707,8 @@ load_image (const gchar *filename,
FILE *fp; /* File pointer */
volatile gint32 image = -1; /* Image -- preserved against setjmp() */
gint32 layer; /* Layer */
- GimpDrawable *drawable; /* Drawable for layer */
- GimpPixelRgn pixel_rgn; /* Pixel region for layer */
+ GeglBuffer *buffer; /* GEGL buffer for layer */
+ const Babl *file_format; /* BABL format for layer */
png_structp pp; /* PNG read pointer */
png_infop info; /* PNG info pointers */
guchar **pixels, /* Pixel rows */
@@ -775,7 +774,8 @@ load_image (const gchar *filename,
if (png_get_bit_depth (pp, info) == 16)
{
- png_set_strip_16 (pp);
+ png_set_swap (pp);
+ have_u16 = 1;
}
if (png_get_color_type (pp, info) == PNG_COLOR_TYPE_GRAY &&
@@ -837,34 +837,41 @@ load_image (const gchar *filename,
switch (png_get_color_type (pp, info))
{
case PNG_COLOR_TYPE_RGB: /* RGB */
- bpp = 3;
image_type = GIMP_RGB;
layer_type = GIMP_RGB_IMAGE;
+ bpp = have_u16 ? 6 : 3;
+ file_format = babl_format (have_u16 ? "R'G'B' u16" : "R'G'B' u8");
break;
case PNG_COLOR_TYPE_RGB_ALPHA: /* RGBA */
- bpp = 4;
image_type = GIMP_RGB;
layer_type = GIMP_RGBA_IMAGE;
+ bpp = have_u16 ? 8 : 4;
+ file_format = babl_format (have_u16 ? "R'G'B'A u16" : "R'G'B'A u8");
break;
case PNG_COLOR_TYPE_GRAY: /* Grayscale */
- bpp = 1;
image_type = GIMP_GRAY;
layer_type = GIMP_GRAY_IMAGE;
+ bpp = have_u16 ? 2 : 1;
+ file_format = babl_format (have_u16 ? "Y' u16" : "Y' u8");
break;
case PNG_COLOR_TYPE_GRAY_ALPHA: /* Grayscale + alpha */
- bpp = 2;
image_type = GIMP_GRAY;
layer_type = GIMP_GRAYA_IMAGE;
+ bpp = have_u16 ? 4 : 2;
+ file_format = babl_format (have_u16 ? "Y'A u16" : "Y'A u8");
break;
+#warning port PNG indexed format
+#if 0
case PNG_COLOR_TYPE_PALETTE: /* Indexed */
bpp = 1;
image_type = GIMP_INDEXED;
layer_type = GIMP_INDEXED_IMAGE;
break;
+#endif
default: /* Aie! Unknown type */
g_set_error (error, 0, 0,
@@ -873,9 +880,10 @@ load_image (const gchar *filename,
return -1;
}
- image = gimp_image_new (png_get_image_width (pp, info),
- png_get_image_height (pp, info),
- image_type);
+ image = gimp_image_new_with_precision (png_get_image_width (pp, info),
+ png_get_image_height (pp, info),
+ image_type,
+ have_u16 ? GIMP_PRECISION_U16 : GIMP_PRECISION_U8);
if (image == -1)
{
g_set_error (error, 0, 0,
@@ -1010,14 +1018,7 @@ load_image (const gchar *filename,
}
}
- /*
- * Get the drawable and set the pixel region for our load...
- */
-
- drawable = gimp_drawable_get (layer);
-
- gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width,
- drawable->height, TRUE, FALSE);
+ buffer = gimp_drawable_get_buffer (layer);
/*
* Temporary buffer...
@@ -1028,17 +1029,16 @@ load_image (const gchar *filename,
pixels = g_new (guchar *, tile_height);
for (i = 0; i < tile_height; i++)
- pixels[i] = pixel + png_get_image_width (pp, info) *
- png_get_channels (pp, info) * i;
+ pixels[i] = pixel + png_get_image_width (pp, info) * bpp * i;
/* Install our own error handler to handle incomplete PNG files better */
- error_data.drawable = drawable;
+ error_data.buffer = buffer;
error_data.pixel = pixel;
+ error_data.file_format = file_format;
error_data.tile_height = tile_height;
error_data.width = png_get_image_width (pp, info);
error_data.height = png_get_image_height (pp, info);
error_data.bpp = bpp;
- error_data.pixel_rgn = &pixel_rgn;
png_set_error_fn (pp, &error_data, on_read_error, NULL);
@@ -1058,8 +1058,7 @@ load_image (const gchar *filename,
num = end - begin;
if (pass != 0) /* to handle interlaced PiNGs */
- gimp_pixel_rgn_get_rect (&pixel_rgn, pixel, 0, begin,
- drawable->width, num);
+ gegl_buffer_get (buffer, GEGL_RECTANGLE (0, begin, png_get_image_width (pp, info), num), 1.0, file_format, pixel, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
error_data.begin = begin;
error_data.end = end;
@@ -1067,11 +1066,7 @@ load_image (const gchar *filename,
png_read_rows (pp, pixels, NULL, num);
- gimp_pixel_rgn_set_rect (&pixel_rgn, pixel, 0, begin,
- drawable->width, num);
-
- memset (pixel, 0,
- tile_height * png_get_image_width (pp, info) * bpp);
+ gegl_buffer_set (buffer, GEGL_RECTANGLE (0, begin, png_get_image_width (pp, info), num), 0, file_format, pixel, GEGL_AUTO_ROWSTRIDE);
gimp_progress_update
(((gdouble) pass +
@@ -1172,11 +1167,13 @@ load_image (const gchar *filename,
g_free (pixel);
g_free (pixels);
+ g_object_unref (buffer);
free (pp);
free (info);
fclose (fp);
+#if 0
if (trns)
{
gimp_layer_add_alpha (layer);
@@ -1208,13 +1205,7 @@ load_image (const gchar *filename,
g_free (pixel);
}
-
- /*
- * Update the display...
- */
-
- gimp_drawable_flush (drawable);
- gimp_drawable_detach (drawable);
+#endif
return image;
}
diff --git a/plug-ins/common/plugin-defs.pl b/plug-ins/common/plugin-defs.pl
index 3d842aa..b40a8a6 100644
--- a/plug-ins/common/plugin-defs.pl
+++ b/plug-ins/common/plugin-defs.pl
@@ -62,7 +62,7 @@
'file-pat' => { ui => 1, gegl => 1 },
'file-pcx' => { ui => 1 },
'file-pix' => { ui => 1 },
- 'file-png' => { ui => 1, optional => 1, libs => 'PNG_LIBS', cflags => 'PNG_CFLAGS' },
+ 'file-png' => { ui => 1, gegl => 1, optional => 1, libs => 'PNG_LIBS', cflags => 'PNG_CFLAGS' },
'file-pnm' => { ui => 1 },
'file-pdf-load' => { ui => 1, optional => 1, libs => 'POPPLER_LIBS', cflags => 'POPPLER_CFLAGS' },
'file-pdf-save' => { ui => 1, optional => 1, libs => 'CAIRO_PDF_LIBS', cflags => 'CAIRO_PDF_CFLAGS' },
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]