[gdk-pixbuf] Add TIFF image density metadata support
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gdk-pixbuf] Add TIFF image density metadata support
- Date: Thu, 30 Oct 2014 20:33:05 +0000 (UTC)
commit d5c1910154219fca19fae2ac1d3b8f7d416630c5
Author: Robert Ancell <robert ancell canonical com>
Date: Wed Oct 22 13:38:06 2014 -0400
Add TIFF image density metadata support
https://bugzilla.gnome.org/show_bug.cgi?id=498721
gdk-pixbuf/gdk-pixbuf-private.h | 1 +
gdk-pixbuf/io-tiff.c | 70 +++++++++++++++++++++++++++++++++++++++
tests/Makefile.am | 5 ++-
tests/dpi.tiff | Bin 0 -> 2805 bytes
tests/pixbuf-dpi.c | 23 +++++++-----
tests/test-common.c | 2 +-
6 files changed, 88 insertions(+), 13 deletions(-)
---
diff --git a/gdk-pixbuf/gdk-pixbuf-private.h b/gdk-pixbuf/gdk-pixbuf-private.h
index d41dd3a..552e084 100644
--- a/gdk-pixbuf/gdk-pixbuf-private.h
+++ b/gdk-pixbuf/gdk-pixbuf-private.h
@@ -26,6 +26,7 @@
#define GDK_PIXBUF_PRIVATE_H
#include <stdio.h>
+#include <math.h>
#include <glib-object.h>
#include <glib/gi18n.h>
diff --git a/gdk-pixbuf/io-tiff.c b/gdk-pixbuf/io-tiff.c
index 67c300c..5f753fd 100644
--- a/gdk-pixbuf/io-tiff.c
+++ b/gdk-pixbuf/io-tiff.c
@@ -94,6 +94,8 @@ tiff_image_parse (TIFF *tiff, TiffContext *context, GError **error)
gchar *icc_profile_base64;
const gchar *icc_profile;
guint icc_profile_size;
+ uint16 resolution_unit;
+ gchar *density_str;
gint retval;
/* We're called with the lock held. */
@@ -236,6 +238,33 @@ tiff_image_parse (TIFF *tiff, TiffContext *context, GError **error)
g_free (icc_profile_base64);
}
+ retval = TIFFGetField (tiff, TIFFTAG_RESOLUTIONUNIT, &resolution_unit);
+ if (retval == 1) {
+ float x_resolution = 0, y_resolution = 0;
+
+ TIFFGetField (tiff, TIFFTAG_XRESOLUTION, &x_resolution);
+ TIFFGetField (tiff, TIFFTAG_YRESOLUTION, &y_resolution);
+
+ switch (resolution_unit) {
+ case RESUNIT_INCH:
+ density_str = g_strdup_printf ("%d", (int) round (x_resolution));
+ gdk_pixbuf_set_option (pixbuf, "x-dpi", density_str);
+ g_free (density_str);
+ density_str = g_strdup_printf ("%d", (int) round (y_resolution));
+ gdk_pixbuf_set_option (pixbuf, "y-dpi", density_str);
+ g_free (density_str);
+ break;
+ case RESUNIT_CENTIMETER:
+ density_str = g_strdup_printf ("%d", DPCM_TO_DPI (x_resolution));
+ gdk_pixbuf_set_option (pixbuf, "x-dpi", density_str);
+ g_free (density_str);
+ density_str = g_strdup_printf ("%d", DPCM_TO_DPI (y_resolution));
+ gdk_pixbuf_set_option (pixbuf, "y-dpi", density_str);
+ g_free (density_str);
+ break;
+ }
+ }
+
if (context && context->prepare_func)
(* context->prepare_func) (pixbuf, NULL, context->user_data);
@@ -661,6 +690,8 @@ gdk_pixbuf__tiff_image_save_to_callback (GdkPixbufSaveFunc save_func,
TiffSaveContext *context;
gboolean retval;
const gchar *icc_profile = NULL;
+ const gchar *x_dpi = NULL;
+ const gchar *y_dpi = NULL;
tiff_set_handlers ();
@@ -703,6 +734,10 @@ gdk_pixbuf__tiff_image_save_to_callback (GdkPixbufSaveFunc save_func,
compression = values[i];
else if (g_str_equal (keys[i], "icc-profile"))
icc_profile = values[i];
+ else if (g_str_equal (keys[i], "x-dpi"))
+ x_dpi = values[i];
+ else if (g_str_equal (keys[i], "y-dpi"))
+ y_dpi = values[i];
i++;
}
}
@@ -859,6 +894,41 @@ gdk_pixbuf__tiff_image_save_to_callback (GdkPixbufSaveFunc save_func,
goto cleanup;
}
+ if (x_dpi != NULL && y_dpi != NULL) {
+ char *endptr = NULL;
+ uint16 resolution_unit = RESUNIT_INCH;
+ float x_dpi_value, y_dpi_value;
+
+ x_dpi_value = strtol (x_dpi, &endptr, 10);
+ if (x_dpi[0] != '\0' && *endptr != '\0')
+ x_dpi_value = -1;
+ if (x_dpi_value <= 0) {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_BAD_OPTION,
+ _("TIFF x-dpi must be greater than zero; value '%s' is not allowed."),
+ x_dpi);
+ retval = FALSE;
+ goto cleanup;
+ }
+ y_dpi_value = strtol (y_dpi, &endptr, 10);
+ if (y_dpi[0] != '\0' && *endptr != '\0')
+ y_dpi_value = -1;
+ if (y_dpi_value <= 0) {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_BAD_OPTION,
+ _("TIFF y-dpi must be greater than zero; value '%s' is not allowed."),
+ y_dpi);
+ retval = FALSE;
+ goto cleanup;
+ }
+
+ TIFFSetField (tiff, TIFFTAG_RESOLUTIONUNIT, resolution_unit);
+ TIFFSetField (tiff, TIFFTAG_XRESOLUTION, x_dpi_value);
+ TIFFSetField (tiff, TIFFTAG_YRESOLUTION, y_dpi_value);
+ }
+
TIFFClose (tiff);
/* Now call the callback */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 99238c3..bf1ec82 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -43,8 +43,9 @@ dist_installed_test_data = \
test-animation.ani \
icc-profile.jpeg \
icc-profile.png \
- dpi.jpeg \
- dpi.png \
+ dpi.jpeg \
+ dpi.png \
+ dpi.tiff \
$(wildcard $(srcdir)/test-images/*)
pixbuf_icc_SOURCES = \
diff --git a/tests/dpi.tiff b/tests/dpi.tiff
new file mode 100644
index 0000000..0a8971f
Binary files /dev/null and b/tests/dpi.tiff differ
diff --git a/tests/pixbuf-dpi.c b/tests/pixbuf-dpi.c
index 51613e0..7d5495e 100644
--- a/tests/pixbuf-dpi.c
+++ b/tests/pixbuf-dpi.c
@@ -54,12 +54,13 @@ test_incremental (gconstpointer data)
g_assert_no_error (error);
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+ g_assert_nonnull (pixbuf);
x_dpi = gdk_pixbuf_get_option (pixbuf, "x-dpi");
y_dpi = gdk_pixbuf_get_option (pixbuf, "y-dpi");
- g_assert (x_dpi != NULL);
- g_assert (y_dpi != NULL);
- g_assert (strcmp (x_dpi, "300") == 0);
- g_assert (strcmp (y_dpi, "600") == 0);
+ g_assert_nonnull (x_dpi);
+ g_assert_nonnull (y_dpi);
+ g_assert_cmpstr (x_dpi, ==, "300");
+ g_assert_cmpstr (y_dpi, ==, "600");
g_object_unref (loader);
g_free (contents);
@@ -84,10 +85,10 @@ test_nonincremental (gconstpointer data)
x_dpi = gdk_pixbuf_get_option (pixbuf, "x-dpi");
y_dpi = gdk_pixbuf_get_option (pixbuf, "y-dpi");
- g_assert (x_dpi != NULL);
- g_assert (y_dpi != NULL);
- g_assert (strcmp (x_dpi, "300") == 0);
- g_assert (strcmp (y_dpi, "600") == 0);
+ g_assert_nonnull (x_dpi);
+ g_assert_nonnull (y_dpi);
+ g_assert_cmpstr (x_dpi, ==, "300");
+ g_assert_cmpstr (y_dpi, ==, "600");
g_object_unref (pixbuf);
}
@@ -98,9 +99,11 @@ main (int argc, char **argv)
g_test_init (&argc, &argv, NULL);
g_test_add_data_func ("/pixbuf/dpi/png", "dpi.png", test_nonincremental);
+ g_test_add_data_func ("/pixbuf/dpi/png-incremental", "dpi.png", test_incremental);
g_test_add_data_func ("/pixbuf/dpi/jpeg", "dpi.jpeg", test_nonincremental);
- g_test_add_data_func ("/pixbuf/dpi/png/incremental", "dpi.png", test_incremental);
- g_test_add_data_func ("/pixbuf/dpi/jpeg/incremental", "dpi.jpeg", test_incremental);
+ g_test_add_data_func ("/pixbuf/dpi/jpeg-incremental", "dpi.jpeg", test_incremental);
+ g_test_add_data_func ("/pixbuf/dpi/tiff", "dpi.tiff", test_nonincremental);
+ g_test_add_data_func ("/pixbuf/dpi/tiff-incremental", "dpi.tiff", test_incremental);
return g_test_run ();
}
diff --git a/tests/test-common.c b/tests/test-common.c
index a7107a1..b7ff926 100644
--- a/tests/test-common.c
+++ b/tests/test-common.c
@@ -33,7 +33,7 @@ format_supported (const gchar *filename)
GSList *formats, *l;
gboolean retval;
const gchar *names[] = { "png", "jpeg", "bmp", "gif", "ras",
- "tga", "xpm", "xbm", "ico" };
+ "tga", "xpm", "xbm", "ico", "tiff" };
gint i;
for (i = 0; i < G_N_ELEMENTS (names); i++)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]