From 871796a126b24dc3cb412bbbf514915eaa0e4c8b Mon Sep 17 00:00:00 2001 From: Jehan Date: Fri, 11 Mar 2022 10:50:44 +0100 Subject: [PATCH] Issue #7956: Add full BigTiff open/export support to GIMP. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Recent libtiff supports loading BigTiff automatically so we didn't have anything to do there (as long as a recent libtiff was used). For creating a BigTIFF though, we simply needed to add a "8" flag to TIFFOpen/TIFFClientOpen when creating a new image (i.e. using "w8" mode) as explained here in the "Implementation Strategy" section: http://www.simplesystems.org/libtiff/BigTIFFProposal.html What this commit does: - Explicitly bump our libtiff requirement to version 4.0.0 or higher (which is where BigTiff support appeared). libtiff 4.0.0 was apparently released on 2011-12-22 and is available on all current distributions, so it's probably not a problem. - Switch to detect libtiff with a pkg-config test (added in libtiff commit faf5f3eb before 4.0.0 release, so it's fine) instead of function checks. (Note: meson was already detecting for libtiff-4 with pkg-config, which was obviously wrong since it should have mimicked autotools, but well… then changes were minimal on meson) - Add a new "bigtiff" boolean argument to the "file-tiff-save" PDB procedure, FALSE by default. I set this as the first argument as I figure that choosing the format you want is quite a major choice. Unless I misunderstood something, since BigTIFF is really designed to be an evolution of TIFF with a "minimum change strategy", i.e. mostly using 64-bit instead of 32-bit offsets, everything which is possible in TIFF will be in BigTIFF (and oppositely as well, except of course having huge files) so there is no need to have 2 separate procedures. - Adding this new argument to the GUI dialog as a checkbox. - Tweak the load and export procedures' documentation strings to make clear we support both TIFF and BigTIFF. Note: interestingly there doesn't seem to be a separate mimetype for BigTIFF so nothing to update on this side. - Tweak the procedure labels too to mention BigTIFF. Since BigTIFF is still a different format (though very closely resembling) from TIFF, unlike some others which are just extensions embedded in a TIFF file (like GeoTIFF we recently added), I figure it deserves to be explicitly cited. --- INSTALL.in | 2 +- configure.ac | 29 +++++------------------------ meson.build | 4 +++- plug-ins/file-tiff/file-tiff-io.c | 2 +- plug-ins/file-tiff/file-tiff-save.c | 5 ++++- plug-ins/file-tiff/file-tiff.c | 26 ++++++++++++++++---------- 6 files changed, 30 insertions(+), 38 deletions(-) diff --git a/INSTALL.in b/INSTALL.in index a086bcc810..297ff2aed1 100644 --- a/INSTALL.in +++ b/INSTALL.in @@ -212,7 +212,7 @@ header files installed. libpng @LIBPNG_REQUIRED_VERSION@ libpoppler-glib @POPPLER_REQUIRED_VERSION@ librsvg @RSVG_REQUIRED_VERSION@ - libtiff + libtiff @LIBTIFF_REQUIRED_VERSION@ Little CMS @LCMS_REQUIRED_VERSION@ mypaint-brushes-1.0 pangocairo @PANGOCAIRO_REQUIRED_VERSION@ diff --git a/configure.ac b/configure.ac index 8daa0564b5..45f5614810 100644 --- a/configure.ac +++ b/configure.ac @@ -79,6 +79,7 @@ m4_define([libjxl_required_version], [0.6.1]) m4_define([liblzma_required_version], [5.0.0]) m4_define([libmypaint_required_version], [1.3.0]) m4_define([libpng_required_version], [1.6.25]) +m4_define([libtiff_required_version], [4.0.0]) m4_define([libunwind_required_version], [1.1.0]) m4_define([openexr_required_version], [1.6.1]) m4_define([openjpeg_required_version], [2.1.0]) @@ -181,6 +182,7 @@ LIBJXL_REQUIRED_VERSION=libjxl_required_version LIBLZMA_REQUIRED_VERSION=liblzma_required_version LIBMYPAINT_REQUIRED_VERSION=libmypaint_required_version LIBPNG_REQUIRED_VERSION=libpng_required_version +LIBTIFF_REQUIRED_VERSION=libtiff_required_version OPENEXR_REQUIRED_VERSION=openexr_required_version OPENJPEG_REQUIRED_VERSION=openjpeg_required_version PANGOCAIRO_REQUIRED_VERSION=pangocairo_required_version @@ -217,6 +219,7 @@ AC_SUBST(LIBJXL_REQUIRED_VERSION) AC_SUBST(LIBLZMA_REQUIRED_VERSION) AC_SUBST(LIBMYPAINT_REQUIRED_VERSION) AC_SUBST(LIBPNG_REQUIRED_VERSION) +AC_SUBST(LIBTIFF_REQUIRED_VERSION) AC_SUBST(OPENEXR_REQUIRED_VERSION) AC_SUBST(OPENJPEG_REQUIRED_VERSION) AC_SUBST(PANGOCAIRO_REQUIRED_VERSION) @@ -1489,32 +1492,10 @@ AC_MSG_RESULT([$enable_relocatable_bundle]) # Check for libtiff ################### -libtiff_error= -if test -z "$TIFF_LIBS"; then - AC_CHECK_LIB(tiff, TIFFReadScanline, - [AC_CHECK_HEADER(tiffio.h, - FILE_TIFF_LOAD='file-tiff-load$(EXEEXT)'; FILE_TIFF_SAVE='file-tiff-save$(EXEEXT)'; TIFF_LIBS='-ltiff', - [libtiff_error="TIFF header files not found"])], - [AC_CHECK_LIB(tiff, TIFFWriteScanline, - [AC_CHECK_HEADER(tiffio.h, - FILE_TIFF_LOAD='file-tiff-load$(EXEEXT)'; FILE_TIFF_SAVE='file-tiff-save$(EXEEXT)'; TIFF_LIBS='-ltiff -ljpeg -lz', - [libtiff_error="TIFF header files not found"])], - [AC_CHECK_LIB(tiff34, TIFFFlushData, - [AC_CHECK_HEADER(tiffio.h, - FILE_TIFF_LOAD='file-tiff-load$(EXEEXT)'; FILE_TIFF_SAVE='file-tiff-save$(EXEEXT)'; TIFF_LIBS='-ltiff34 -ljpeg -lz', - [libtiff_error="TIFF header files not found"])], - [libtiff_error="TIFF library not found"], -ljpeg -lz -lm)], -ljpeg -lz -lm)], -lm) -fi - -if test -z "$TIFF_LIBS"; then - add_deps_error([libtiff], [Checks for TIFF library failed: $libtiff_error]) -fi - +PKG_CHECK_MODULES(TIFF, [libtiff-4 >= libtiff_required_version],, + [add_deps_error([libtiff-4 >= libtiff_required_version])]) MIME_TYPES="$MIME_TYPES;image/tiff" -AC_SUBST(TIFF_LIBS) - - ################### # Check for libjpeg ################### diff --git a/meson.build b/meson.build index 65eca12315..60289db23b 100644 --- a/meson.build +++ b/meson.build @@ -629,7 +629,8 @@ MIMEtypes = [ -libtiff = dependency('libtiff-4') +libtiff_minver = '4.0.0' +libtiff = dependency('libtiff-4', version: '>=' + libtiff_minver) MIMEtypes += 'image/tiff' @@ -1540,6 +1541,7 @@ install_conf.set('INTLTOOL_REQUIRED_VERSION', '0.40.1') install_conf.set('LCMS_REQUIRED_VERSION', lcms_minver) install_conf.set('LIBHEIF_REQUIRED_VERSION', libheif_minver) install_conf.set('LIBLZMA_REQUIRED_VERSION', liblzma_minver) +install_conf.set('LIBTIFF_REQUIRED_VERSION', libtiff_minver) install_conf.set('LIBMYPAINT_REQUIRED_VERSION', libmypaint_minver) install_conf.set('LIBPNG_REQUIRED_VERSION', libpng_minver) install_conf.set('OPENEXR_REQUIRED_VERSION', openexr_minver) diff --git a/plug-ins/file-tiff/file-tiff-io.c b/plug-ins/file-tiff/file-tiff-io.c index ca1a434dcb..eba1dc22ad 100644 --- a/plug-ins/file-tiff/file-tiff-io.c +++ b/plug-ins/file-tiff/file-tiff-io.c @@ -107,7 +107,7 @@ tiff_open (GFile *file, tiff_io.stream = G_OBJECT (tiff_io.input); } - else if(! strcmp (mode, "w")) + else if(! strcmp (mode, "w") || ! strcmp (mode, "w8")) { tiff_io.output = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE, diff --git a/plug-ins/file-tiff/file-tiff-save.c b/plug-ins/file-tiff/file-tiff-save.c index 8b6fa266b9..fb78042866 100644 --- a/plug-ins/file-tiff/file-tiff-save.c +++ b/plug-ins/file-tiff/file-tiff-save.c @@ -997,10 +997,12 @@ save_image (GFile *file, gint origin_x = 0; gint origin_y = 0; gint saved_bpp; + gboolean bigtiff; gboolean config_save_profile; gboolean config_save_thumbnail; g_object_get (config, + "bigtiff", &bigtiff, "save-color-profile", &config_save_profile, "save-thumbnail", &config_save_thumbnail, NULL); @@ -1013,7 +1015,7 @@ save_image (GFile *file, gimp_file_get_utf8_name (file)); /* Open file and write some global data */ - tif = tiff_open (file, "w", error); + tif = tiff_open (file, (bigtiff ? "w8" : "w"), error); if (! tif) { @@ -1267,6 +1269,7 @@ save_dialog (GimpImage *image, gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog), "compression", + "bigtiff", "layers-frame", "save-transparent-pixels", NULL); diff --git a/plug-ins/file-tiff/file-tiff.c b/plug-ins/file-tiff/file-tiff.c index d79345c311..d5b2245f49 100644 --- a/plug-ins/file-tiff/file-tiff.c +++ b/plug-ins/file-tiff/file-tiff.c @@ -57,7 +57,6 @@ #define SAVE_PROC "file-tiff-save" -#define SAVE2_PROC "file-tiff-save2" #define PLUG_IN_BINARY "file-tiff" @@ -144,11 +143,12 @@ tiff_create_procedure (GimpPlugIn *plug_in, GIMP_PDB_PROC_TYPE_PLUGIN, tiff_load, NULL, NULL); - gimp_procedure_set_menu_label (procedure, N_("TIFF image")); + gimp_procedure_set_menu_label (procedure, N_("TIFF or BigTIFF image")); gimp_procedure_set_documentation (procedure, - "loads files of the tiff file format", - "FIXME: write help for tiff_load", + "Loads files of the TIFF and BigTIFF file formats", + "Loads files of the Tag Image File Format (TIFF) and " + "its 64-bit offsets variant (BigTIFF)", name); gimp_procedure_set_attribution (procedure, "Spencer Kimball, Peter Mattis & Nick Lamb", @@ -172,14 +172,13 @@ tiff_create_procedure (GimpPlugIn *plug_in, gimp_procedure_set_image_types (procedure, "*"); - gimp_procedure_set_menu_label (procedure, N_("TIFF image")); + gimp_procedure_set_menu_label (procedure, N_("TIFF or BigTIFF image")); gimp_procedure_set_documentation (procedure, - "Saves files in the tiff file format", - "Saves files in the Tagged Image File " - "Format. The value for the saved " - "comment is taken from the " - "'gimp-comment' parasite", + "Exports files in the TIFF or BigTIFF file formats", + "Exports files in the Tag Image File Format (TIFF) or " + "its 64-bit offsets variant (BigTIFF) able to support " + "much bigger file sizes", name); gimp_procedure_set_attribution (procedure, "Spencer Kimball & Peter Mattis", @@ -195,6 +194,13 @@ tiff_create_procedure (GimpPlugIn *plug_in, gimp_file_procedure_set_extensions (GIMP_FILE_PROCEDURE (procedure), "tif,tiff"); + GIMP_PROC_ARG_BOOLEAN (procedure, "bigtiff", + "Export in BigTIFF variant file format", + "The BigTIFF variant file format uses 64-bit offsets, " + "hence supporting over 4GiB files and bigger", + FALSE, + G_PARAM_READWRITE); + GIMP_PROC_ARG_INT (procedure, "compression", "Co_mpression", "Compression type: { NONE (0), LZW (1), PACKBITS (2), "