diff options
author | Matthias Clasen <maclas@gmx.de> | 2004-01-07 01:57:42 +0000 |
---|---|---|
committer | Matthias Clasen <matthiasc@src.gnome.org> | 2004-01-07 01:57:42 +0000 |
commit | 03376d79faf862ada7fca924aed681156398d574 (patch) | |
tree | 914249bd1d2864773bec4eadf2f3f533f9523fac /gdk-pixbuf/io-jpeg.c | |
parent | 5b26e695a1fc70c99b58f2e9c4c922412fbd1a08 (diff) | |
download | gtk+-03376d79faf862ada7fca924aed681156398d574.tar.gz |
New public API to save pixbufs to non-file locations. (#82203, Tim Evans)
Wed Jan 7 02:41:14 2004 Matthias Clasen <maclas@gmx.de>
* gdk-pixbuf-io.c (gdk_pixbuf_save_to_bufferv):
* gdk-pixbuf-io.c (gdk_pixbuf_save_to_buffer):
* gdk-pixbuf-io.c (gdk_pixbuf_save_to_callbackv):
* gdk-pixbuf-io.c (gdk_pixbuf_save_to_callback): New public API
to save pixbufs to non-file locations. (#82203, Tim Evans)
* gdk-pixbuf.h:
* gdk_pixbuf.def: Declare the new public API.
* gdk-pixbuf-io.h: Add save_to_callback to the module interface.
* io-jpeg.c:
* io-png.c: Implement save_to_callback.
* gdk-pixbuf-io.c (gdk_pixbuf_savev):
* gdk-pixbuf-io.c (gdk_pixbuf_save): Update documentation.
* gdk-pixbuf-io.c (gdk_pixbuf_real_save): Support saving via
image_module->save_to_callback.
* gdk-pixbuf-io.c (gdk_pixbuf_real_save_to_callback): New generic
save_to_callback function which falls back to image_module->save
on a temp file.
Diffstat (limited to 'gdk-pixbuf/io-jpeg.c')
-rw-r--r-- | gdk-pixbuf/io-jpeg.c | 138 |
1 files changed, 131 insertions, 7 deletions
diff --git a/gdk-pixbuf/io-jpeg.c b/gdk-pixbuf/io-jpeg.c index 85d75dfe60..4dd5f8f2a5 100644 --- a/gdk-pixbuf/io-jpeg.c +++ b/gdk-pixbuf/io-jpeg.c @@ -780,12 +780,85 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer data, return TRUE; } +/* Save */ + +#define TO_FUNCTION_BUF_SIZE 4096 + +typedef struct { + struct jpeg_destination_mgr pub; + JOCTET *buffer; + GdkPixbufSaveFunc save_func; + gpointer user_data; + GError **error; +} ToFunctionDestinationManager; + +void +to_callback_init (j_compress_ptr cinfo) +{ + ToFunctionDestinationManager *destmgr; + + destmgr = (ToFunctionDestinationManager*) cinfo->dest; + destmgr->pub.next_output_byte = destmgr->buffer; + destmgr->pub.free_in_buffer = TO_FUNCTION_BUF_SIZE; +} + +static void +to_callback_do_write (j_compress_ptr cinfo, gsize length) +{ + ToFunctionDestinationManager *destmgr; + + destmgr = (ToFunctionDestinationManager*) cinfo->dest; + if (!destmgr->save_func (destmgr->buffer, + length, + destmgr->error, + destmgr->user_data)) { + struct error_handler_data *errmgr; + + errmgr = (struct error_handler_data *) cinfo->err; + /* Use a default error message if the callback didn't set one, + * which it should have. + */ + if (errmgr->error && *errmgr->error == NULL) { + g_set_error (errmgr->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + "write function failed"); + } + siglongjmp (errmgr->setjmp_buffer, 1); + g_assert_not_reached (); + } +} + +static guchar +to_callback_empty_output_buffer (j_compress_ptr cinfo) +{ + ToFunctionDestinationManager *destmgr; + + destmgr = (ToFunctionDestinationManager*) cinfo->dest; + to_callback_do_write (cinfo, TO_FUNCTION_BUF_SIZE); + destmgr->pub.next_output_byte = destmgr->buffer; + destmgr->pub.free_in_buffer = TO_FUNCTION_BUF_SIZE; + return TRUE; +} + +void +to_callback_terminate (j_compress_ptr cinfo) +{ + ToFunctionDestinationManager *destmgr; + + destmgr = (ToFunctionDestinationManager*) cinfo->dest; + to_callback_do_write (cinfo, TO_FUNCTION_BUF_SIZE - destmgr->pub.free_in_buffer); +} + static gboolean -gdk_pixbuf__jpeg_image_save (FILE *f, - GdkPixbuf *pixbuf, - gchar **keys, - gchar **values, - GError **error) +real_save_jpeg (GdkPixbuf *pixbuf, + gchar **keys, + gchar **values, + GError **error, + gboolean to_callback, + FILE *f, + GdkPixbufSaveFunc save_func, + gpointer user_data) { /* FIXME error handling is broken */ @@ -800,6 +873,9 @@ gdk_pixbuf__jpeg_image_save (FILE *f, int w, h = 0; int rowstride = 0; struct error_handler_data jerr; + ToFunctionDestinationManager to_callback_destmgr; + + to_callback_destmgr.buffer = NULL; if (keys && *keys) { gchar **kiter = keys; @@ -854,7 +930,9 @@ gdk_pixbuf__jpeg_image_save (FILE *f, pixels = gdk_pixbuf_get_pixels (pixbuf); g_return_val_if_fail (pixels != NULL, FALSE); - /* allocate a small buffer to convert image data */ + /* Allocate a small buffer to convert image data, + * and a larger buffer if doing to_callback save. + */ buf = g_try_malloc (w * 3 * sizeof (guchar)); if (!buf) { g_set_error (error, @@ -863,6 +941,16 @@ gdk_pixbuf__jpeg_image_save (FILE *f, _("Couldn't allocate memory for loading JPEG file")); return FALSE; } + if (to_callback) { + to_callback_destmgr.buffer = g_try_malloc (TO_FUNCTION_BUF_SIZE); + if (!to_callback_destmgr.buffer) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, + _("Couldn't allocate memory for loading JPEG file")); + return FALSE; + } + } /* set up error handling */ jerr.pub.error_exit = fatal_error_handler; @@ -873,12 +961,23 @@ gdk_pixbuf__jpeg_image_save (FILE *f, if (sigsetjmp (jerr.setjmp_buffer, 1)) { jpeg_destroy_compress (&cinfo); g_free (buf); + g_free (to_callback_destmgr.buffer); return FALSE; } /* setup compress params */ jpeg_create_compress (&cinfo); - jpeg_stdio_dest (&cinfo, f); + if (to_callback) { + to_callback_destmgr.pub.init_destination = to_callback_init; + to_callback_destmgr.pub.empty_output_buffer = to_callback_empty_output_buffer; + to_callback_destmgr.pub.term_destination = to_callback_terminate; + to_callback_destmgr.error = error; + to_callback_destmgr.save_func = save_func; + to_callback_destmgr.user_data = user_data; + cinfo.dest = (struct jpeg_destination_mgr*) &to_callback_destmgr; + } else { + jpeg_stdio_dest (&cinfo, f); + } cinfo.image_width = w; cinfo.image_height = h; cinfo.input_components = 3; @@ -909,9 +1008,33 @@ gdk_pixbuf__jpeg_image_save (FILE *f, jpeg_finish_compress (&cinfo); jpeg_destroy_compress(&cinfo); g_free (buf); + g_free (to_callback_destmgr.buffer); return TRUE; } +static gboolean +gdk_pixbuf__jpeg_image_save (FILE *f, + GdkPixbuf *pixbuf, + gchar **keys, + gchar **values, + GError **error) +{ + return real_save_jpeg (pixbuf, keys, values, error, + FALSE, f, NULL, NULL); +} + +static gboolean +gdk_pixbuf__jpeg_image_save_to_callback (GdkPixbufSaveFunc save_func, + gpointer user_data, + GdkPixbuf *pixbuf, + gchar **keys, + gchar **values, + GError **error) +{ + return real_save_jpeg (pixbuf, keys, values, error, + TRUE, NULL, save_func, user_data); +} + void MODULE_ENTRY (jpeg, fill_vtable) (GdkPixbufModule *module) { @@ -920,6 +1043,7 @@ MODULE_ENTRY (jpeg, fill_vtable) (GdkPixbufModule *module) module->stop_load = gdk_pixbuf__jpeg_image_stop_load; module->load_increment = gdk_pixbuf__jpeg_image_load_increment; module->save = gdk_pixbuf__jpeg_image_save; + module->save_to_callback = gdk_pixbuf__jpeg_image_save_to_callback; } void |