Pixbuf saving, patch from David Welton.

2000-10-05  Havoc Pennington  <hp@redhat.com>

        Pixbuf saving, patch from David Welton.

	* Makefile.am (GDK_PIXBUF_LIBS): add INTLLIBS
	(libgdk_pixbuf_1_3_la_SOURCES): add gdk-pixbuf-i18n.h

	* gdk-pixbuf-i18n.h: Add _() to gdk-pixbuf

	* io-png.c (gdk_pixbuf__png_image_save): PNG save routine.

	* io-jpeg.c (gdk_pixbuf__jpeg_image_save): JPEG save routine.

	* gdk-pixbuf-io.c (gdk_pixbuf_save):
	(gdk_pixbuf_savev): Implement pixbuf saving routines

	* gdk-pixbuf.c (gdk_pixbuf_error_quark): pixbuf error quark
	function

	* gdk-pixbuf.h: Add public save routines; add pixbuf error
	types

	* gdk-pixbuf-io.h: Add save function to GdkPixbufModule

2000-10-05  Havoc Pennington  <hp@redhat.com>

        * demos/testpixbuf-save.c: add pixbuf save test

	* demos/Makefile.am: add testpixbuf-save.c
This commit is contained in:
Havoc Pennington
2000-10-06 18:19:18 +00:00
committed by Havoc Pennington
parent a7e20093e9
commit 6b9f907270
18 changed files with 743 additions and 13 deletions

View File

@ -537,5 +537,112 @@ png_warning_callback(png_structp png_read_ptr,
}
/* Save */
gboolean
gdk_pixbuf__png_image_save (FILE *f,
GdkPixbuf *pixbuf,
gchar **keys,
gchar **values,
GError **error)
{
/* FIXME error handling is broken */
png_structp png_ptr;
png_infop info_ptr;
guchar *ptr;
guchar *pixels;
int x, y, j;
png_bytep row_ptr, data = NULL;
png_color_8 sig_bit;
int w, h, rowstride;
int has_alpha;
int bpc;
if (keys && *keys) {
g_warning ("Bad option name '%s' passed to PNG saver",
*keys);
return FALSE;
#if 0
gchar **kiter = keys;
gchar **viter = values;
while (*kiter) {
++kiter;
++viter;
}
#endif
}
bpc = gdk_pixbuf_get_bits_per_sample (pixbuf);
w = gdk_pixbuf_get_width (pixbuf);
h = gdk_pixbuf_get_height (pixbuf);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
pixels = gdk_pixbuf_get_pixels (pixbuf);
png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL);
g_return_val_if_fail (png_ptr != NULL, FALSE);
info_ptr = png_create_info_struct (png_ptr);
if (info_ptr == NULL) {
png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
return FALSE;
}
if (setjmp (png_ptr->jmpbuf)) {
png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
return FALSE;
}
png_init_io (png_ptr, f);
if (has_alpha) {
png_set_IHDR (png_ptr, info_ptr, w, h, bpc,
PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
#ifdef WORDS_BIGENDIAN
png_set_swap_alpha (png_ptr);
#else
png_set_bgr (png_ptr);
#endif
} else {
png_set_IHDR (png_ptr, info_ptr, w, h, bpc,
PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
data = malloc (w * 3 * sizeof (char));
}
sig_bit.red = bpc;
sig_bit.green = bpc;
sig_bit.blue = bpc;
sig_bit.alpha = bpc;
png_set_sBIT (png_ptr, info_ptr, &sig_bit);
png_write_info (png_ptr, info_ptr);
png_set_shift (png_ptr, &sig_bit);
png_set_packing (png_ptr);
ptr = pixels;
for (y = 0; y < h; y++) {
if (has_alpha)
row_ptr = (png_bytep)ptr;
else {
for (j = 0, x = 0; x < w; x++)
memcpy (&(data[x*3]), &(ptr[x*3]), 3);
row_ptr = (png_bytep)data;
}
png_write_rows (png_ptr, &row_ptr, 1);
ptr += rowstride;
}
if (data)
free (data);
png_write_end (png_ptr, info_ptr);
png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
return TRUE;
}