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:
committed by
Havoc Pennington
parent
a7e20093e9
commit
6b9f907270
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user