diff options
author | Matthias Clasen <mclasen@redhat.com> | 2022-05-08 10:25:39 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2022-09-30 14:42:03 -0400 |
commit | 3214e5a703e870adb9a13623ebc6ae09373ec303 (patch) | |
tree | 82d07d06b1d8f0f9c229e3a5377032a6dc6e9409 | |
parent | 9ceaf3445ddf6c1b98903cb9d13719595c77577a (diff) | |
download | gtk+-3214e5a703e870adb9a13623ebc6ae09373ec303.tar.gz |
tiff: Add color space support
Apply an embedded icc profile when loading tiff
images, and save associated icc profile information
when saving tiff images.
-rw-r--r-- | gdk/loaders/gdktiff.c | 65 |
1 files changed, 57 insertions, 8 deletions
diff --git a/gdk/loaders/gdktiff.c b/gdk/loaders/gdktiff.c index aea9f2f073..3b7ef21283 100644 --- a/gdk/loaders/gdktiff.c +++ b/gdk/loaders/gdktiff.c @@ -221,6 +221,44 @@ tiff_open_write (GBytes **result) } /* }}} */ +/* {{{ Color profile handling */ + +static GdkColorSpace * +gdk_tiff_get_color_space (TIFF *tiff) +{ + const char *icc_data; + guint icc_len; + + if (TIFFGetField (tiff, TIFFTAG_ICCPROFILE, &icc_len, &icc_data)) + { + GBytes *icc_bytes; + GdkColorSpace *color_space; + + icc_bytes = g_bytes_new (icc_data, icc_len); + color_space = gdk_color_space_new_from_icc_profile (icc_bytes, NULL); + g_bytes_unref (icc_bytes); + + if (color_space) + return color_space; + } + + return g_object_ref (gdk_color_space_get_srgb ()); +} + +static void +gdk_tiff_set_color_space (TIFF *tiff, + GdkColorSpace *color_space) +{ + GBytes *bytes = gdk_color_space_save_to_icc_profile (color_space, NULL); + + TIFFSetField (tiff, TIFFTAG_ICCPROFILE, + g_bytes_get_size (bytes), + g_bytes_get_data (bytes, NULL)); + + g_bytes_unref (bytes); +} + +/* }}} */ /* {{{ Public API */ typedef struct _FormatData FormatData; @@ -266,6 +304,7 @@ gdk_save_tiff (GdkTexture *texture) GBytes *result = NULL; GdkMemoryTexture *memtex; GdkMemoryFormat format; + GdkColorSpace *color_space; const FormatData *fdata = NULL; tif = tiff_open_write (&result); @@ -273,6 +312,7 @@ gdk_save_tiff (GdkTexture *texture) width = gdk_texture_get_width (texture); height = gdk_texture_get_height (texture); format = gdk_texture_get_format (texture); + color_space = gdk_texture_get_color_space (texture); fdata = &format_data[format]; if (fdata == NULL) @@ -292,7 +332,9 @@ gdk_save_tiff (GdkTexture *texture) TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); TIFFSetField (tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); - memtex = gdk_memory_texture_from_texture (texture, fdata->format, gdk_color_space_get_srgb ()); + gdk_tiff_set_color_space (tif, color_space); + + memtex = gdk_memory_texture_from_texture (texture, fdata->format, color_space); data = gdk_memory_texture_get_data (memtex); stride = gdk_memory_texture_get_stride (memtex); @@ -326,6 +368,7 @@ load_fallback (TIFF *tif, int width, height; guchar *data; GBytes *bytes; + GdkColorSpace *color_space; GdkTexture *texture; TIFFGetField (tif, TIFFTAG_IMAGEWIDTH, &width); @@ -342,12 +385,15 @@ load_fallback (TIFF *tif, return NULL; } + color_space = gdk_tiff_get_color_space (tif); + bytes = g_bytes_new_take (data, width * height * 4); - texture = gdk_memory_texture_new (width, height, - GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, - bytes, - width * 4); + texture = gdk_memory_texture_new_with_color_space (width, height, + GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, + color_space, + bytes, + width * 4); g_bytes_unref (bytes); @@ -372,6 +418,7 @@ gdk_load_tiff (GBytes *input_bytes, gsize stride; int bpp; GBytes *bytes; + GdkColorSpace *color_space; GdkTexture *texture; G_GNUC_UNUSED gint64 before = GDK_PROFILER_CURRENT_TIME; @@ -471,12 +518,14 @@ gdk_load_tiff (GBytes *input_bytes, line += stride; } + color_space = gdk_tiff_get_color_space (tif); + bpp = gdk_memory_format_bytes_per_pixel (format); bytes = g_bytes_new_take (data, width * height * bpp); - texture = gdk_memory_texture_new (width, height, - format, - bytes, width * bpp); + texture = gdk_memory_texture_new_with_color_space (width, height, + format, color_space, + bytes, width * bpp); g_bytes_unref (bytes); TIFFClose (tif); |