[gtk/image-loading] Add code to save jpegs
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/image-loading] Add code to save jpegs
- Date: Tue, 14 Sep 2021 21:46:40 +0000 (UTC)
commit a284a964fb52327fff43a1e1970e30fa9e3d1cef
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Sep 14 17:40:29 2021 -0400
Add code to save jpegs
gdk/loaders/gdkjpeg.c | 98 +++++++++++++++++++++++++++++++++++++++++++-
gdk/loaders/gdkjpegprivate.h | 2 +
2 files changed, 99 insertions(+), 1 deletion(-)
---
diff --git a/gdk/loaders/gdkjpeg.c b/gdk/loaders/gdkjpeg.c
index 74a1c9623a..8966514948 100644
--- a/gdk/loaders/gdkjpeg.c
+++ b/gdk/loaders/gdkjpeg.c
@@ -70,7 +70,42 @@ output_message_handler (j_common_ptr cinfo)
}
/* }}} */
- /* {{{ Public API */
+/* {{{ Format conversion */
+
+static void
+convert_to_rgb (guchar *data,
+ int width,
+ int height,
+ int stride)
+{
+ gsize x, y;
+ guchar *src, *dest;
+
+ for (y = 0; y < height; y++)
+ {
+ src = data;
+ dest = data;
+
+ for (x = 0; x < width; x++)
+ {
+ guint32 pixel;
+
+ memcpy (&pixel, src, sizeof (guint32));
+
+ dest[0] = (pixel & 0x00ff0000) >> 16;
+ dest[1] = (pixel & 0x0000ff00) >> 8;
+ dest[2] = (pixel & 0x000000ff) >> 0;
+
+ dest += 3;
+ src += 4;
+ }
+
+ data += stride;
+ }
+}
+
+/* }}} */
+/* {{{ Public API */
GdkTexture *
gdk_load_jpeg (GBytes *input_bytes,
@@ -141,6 +176,67 @@ gdk_load_jpeg (GBytes *input_bytes,
return texture;
}
+GBytes *
+gdk_save_jpeg (GdkTexture *texture)
+{
+ struct jpeg_compress_struct info;
+ struct error_handler_data jerr;
+ struct jpeg_error_mgr err;
+ guchar *data = NULL;
+ gulong size = 0;
+ guchar *input = NULL;
+ guchar *row;
+ int width, height, stride;
+
+ width = gdk_texture_get_width (texture);
+ height = gdk_texture_get_height (texture);
+
+ info.err = jpeg_std_error (&jerr.pub);
+ jerr.pub.error_exit = fatal_error_handler;
+ jerr.pub.output_message = output_message_handler;
+ jerr.error = NULL;
+
+ if (sigsetjmp (jerr.setjmp_buffer, 1))
+ {
+ free (data);
+ g_free (input);
+ jpeg_destroy_compress (&info);
+ return NULL;
+ }
+
+ info.err = jpeg_std_error (&err);
+ jpeg_create_compress (&info);
+ info.image_width = width;
+ info.image_height = height;
+ info.input_components = 3;
+ info.in_color_space = JCS_RGB;
+
+ jpeg_set_defaults (&info);
+ jpeg_set_quality (&info, 75, TRUE);
+
+ jpeg_mem_dest (&info, &data, &size);
+
+ stride = width * 4;
+ input = g_malloc (stride * height);
+ gdk_texture_download (texture, input, stride);
+ convert_to_rgb (data, width, height, stride);
+
+ jpeg_start_compress (&info, TRUE);
+
+ while (info.next_scanline < info.image_height)
+ {
+ row = &input[info.next_scanline * stride];
+ jpeg_write_scanlines (&info, &row, 1);
+ }
+
+ jpeg_finish_compress (&info);
+
+ g_free (input);
+ jpeg_destroy_compress (&info);
+
+ return g_bytes_new_with_free_func (data, size, (GDestroyNotify) free, NULL);
+}
+
/* }}} */
/* vim:set foldmethod=marker expandtab: */
diff --git a/gdk/loaders/gdkjpegprivate.h b/gdk/loaders/gdkjpegprivate.h
index 4dcccbaf8d..28e7b90f28 100644
--- a/gdk/loaders/gdkjpegprivate.h
+++ b/gdk/loaders/gdkjpegprivate.h
@@ -26,6 +26,8 @@
GdkTexture *gdk_load_jpeg (GBytes *bytes,
GError **error);
+GBytes *gdk_save_jpeg (GdkTexture *texture);
+
static inline gboolean
gdk_is_jpeg (GBytes *bytes)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]