mirror of https://github.com/GNOME/gimp.git
plug-ins: propose exporting as BigTIFF once if TIFF export fails…
… because we reached max TIFF size. We detect the specific TIFF error (by string comparison so it's a bit weak IMO yet it doesn't seem like libtiff provides anything better; let's trust they don't change their error strings), then we reopen the export dialog, pre-checking the BigTIFF checkbox newly created (and making it insensitive). We still fail with error if an error happens the second time (even for the same error).
This commit is contained in:
parent
871796a126
commit
6e71478cd4
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
#include "file-tiff-io.h"
|
#include "file-tiff-io.h"
|
||||||
|
|
||||||
|
static gboolean tiff_file_size_error = FALSE;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -150,6 +151,18 @@ tiff_open (GFile *file,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
tiff_got_file_size_error (void)
|
||||||
|
{
|
||||||
|
return tiff_file_size_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tiff_reset_file_size_error (void)
|
||||||
|
{
|
||||||
|
tiff_file_size_error = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tiff_io_warning (const gchar *module,
|
tiff_io_warning (const gchar *module,
|
||||||
const gchar *fmt,
|
const gchar *fmt,
|
||||||
|
@ -247,6 +260,22 @@ tiff_io_error (const gchar *module,
|
||||||
if (! strcmp (fmt, "Compression algorithm does not support random access"))
|
if (! strcmp (fmt, "Compression algorithm does not support random access"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (g_strcmp0 (fmt, "Maximum TIFF file size exceeded") == 0)
|
||||||
|
{
|
||||||
|
/* @module in my tests were "TIFFAppendToStrip" but I wonder if
|
||||||
|
* this same error could not happen with other "modules".
|
||||||
|
*/
|
||||||
|
tiff_file_size_error = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gchar *msg = g_strdup_vprintf (fmt, ap);
|
||||||
|
|
||||||
|
/* Easier for debugging to at least print messages on stderr. */
|
||||||
|
g_printerr ("LibTiff error: [%s] %s\n", module, msg);
|
||||||
|
g_free (msg);
|
||||||
|
}
|
||||||
|
|
||||||
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, ap);
|
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,8 @@ static const TIFFFieldInfo geotifftags_fieldinfo[] = {
|
||||||
TIFF * tiff_open (GFile *file,
|
TIFF * tiff_open (GFile *file,
|
||||||
const gchar *mode,
|
const gchar *mode,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
gboolean tiff_got_file_size_error (void);
|
||||||
|
void tiff_reset_file_size_error (void);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __FILE_TIFF_IO_H__ */
|
#endif /* __FILE_TIFF_IO_H__ */
|
||||||
|
|
|
@ -805,7 +805,8 @@ save_layer (TIFF *tif,
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
g_message (_("Failed a scanline write on row %d"), row);
|
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||||
|
_("Failed a scanline write on row %d"), row);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1144,6 +1145,7 @@ out:
|
||||||
gimp_progress_update (1.0);
|
gimp_progress_update (1.0);
|
||||||
|
|
||||||
g_list_free (layers);
|
g_list_free (layers);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1196,7 +1198,8 @@ save_dialog (GimpImage *image,
|
||||||
gboolean has_alpha,
|
gboolean has_alpha,
|
||||||
gboolean is_monochrome,
|
gboolean is_monochrome,
|
||||||
gboolean is_indexed,
|
gboolean is_indexed,
|
||||||
gboolean is_multi_layer)
|
gboolean is_multi_layer,
|
||||||
|
gboolean classic_tiff_failed)
|
||||||
{
|
{
|
||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
GtkListStore *store;
|
GtkListStore *store;
|
||||||
|
@ -1222,6 +1225,21 @@ save_dialog (GimpImage *image,
|
||||||
GIMP_PROCEDURE_CONFIG (config),
|
GIMP_PROCEDURE_CONFIG (config),
|
||||||
image);
|
image);
|
||||||
|
|
||||||
|
if (classic_tiff_failed)
|
||||||
|
{
|
||||||
|
GtkWidget *bigtiff_checkbox;
|
||||||
|
|
||||||
|
gimp_procedure_dialog_get_label (GIMP_PROCEDURE_DIALOG (dialog),
|
||||||
|
"big-tif-warning",
|
||||||
|
"\xe2\x9a\xa0 Warning: maximum TIFF file size exceeded. "
|
||||||
|
"Retry as BigTIFF or cancel.");
|
||||||
|
g_object_set (config, "bigtiff", TRUE, NULL);
|
||||||
|
bigtiff_checkbox = gimp_procedure_dialog_get_widget (GIMP_PROCEDURE_DIALOG (dialog),
|
||||||
|
"bigtiff",
|
||||||
|
G_TYPE_NONE);
|
||||||
|
gtk_widget_set_sensitive (bigtiff_checkbox, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
store =
|
store =
|
||||||
gimp_int_store_new (_("None"), GIMP_COMPRESSION_NONE,
|
gimp_int_store_new (_("None"), GIMP_COMPRESSION_NONE,
|
||||||
_("LZW"), GIMP_COMPRESSION_LZW,
|
_("LZW"), GIMP_COMPRESSION_LZW,
|
||||||
|
@ -1267,6 +1285,15 @@ save_dialog (GimpImage *image,
|
||||||
"save-geotiff",
|
"save-geotiff",
|
||||||
has_geotiff, NULL, NULL, FALSE);
|
has_geotiff, NULL, NULL, FALSE);
|
||||||
|
|
||||||
|
if (classic_tiff_failed)
|
||||||
|
gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog),
|
||||||
|
"compression",
|
||||||
|
"big-tif-warning",
|
||||||
|
"bigtiff",
|
||||||
|
"layers-frame",
|
||||||
|
"save-transparent-pixels",
|
||||||
|
NULL);
|
||||||
|
else
|
||||||
gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog),
|
gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog),
|
||||||
"compression",
|
"compression",
|
||||||
"bigtiff",
|
"bigtiff",
|
||||||
|
|
|
@ -36,7 +36,8 @@ gboolean save_dialog (GimpImage *image,
|
||||||
gboolean has_alpha,
|
gboolean has_alpha,
|
||||||
gboolean is_monochrome,
|
gboolean is_monochrome,
|
||||||
gboolean is_indexed,
|
gboolean is_indexed,
|
||||||
gboolean is_multi_layer);
|
gboolean is_multi_layer,
|
||||||
|
gboolean classic_tiff_failed);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __FILE_TIFF_SAVE_H__ */
|
#endif /* __FILE_TIFF_SAVE_H__ */
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
#include <libgimp/gimpui.h>
|
#include <libgimp/gimpui.h>
|
||||||
|
|
||||||
#include "file-tiff.h"
|
#include "file-tiff.h"
|
||||||
|
#include "file-tiff-io.h"
|
||||||
#include "file-tiff-load.h"
|
#include "file-tiff-load.h"
|
||||||
#include "file-tiff-save.h"
|
#include "file-tiff-save.h"
|
||||||
|
|
||||||
|
@ -96,6 +97,16 @@ static GimpValueArray * tiff_save (GimpProcedure *procedure,
|
||||||
GFile *file,
|
GFile *file,
|
||||||
const GimpValueArray *args,
|
const GimpValueArray *args,
|
||||||
gpointer run_data);
|
gpointer run_data);
|
||||||
|
static GimpPDBStatusType tiff_save_rec (GimpProcedure *procedure,
|
||||||
|
GimpRunMode run_mode,
|
||||||
|
GimpImage *orig_image,
|
||||||
|
gint n_orig_drawables,
|
||||||
|
GimpDrawable **orig_drawables,
|
||||||
|
GFile *file,
|
||||||
|
GimpProcedureConfig *config,
|
||||||
|
GimpMetadata *metadata,
|
||||||
|
gboolean retried,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
static gboolean image_is_monochrome (GimpImage *image);
|
static gboolean image_is_monochrome (GimpImage *image);
|
||||||
static gboolean image_is_multi_layer (GimpImage *image);
|
static gboolean image_is_multi_layer (GimpImage *image);
|
||||||
|
@ -316,11 +327,9 @@ tiff_save (GimpProcedure *procedure,
|
||||||
gpointer run_data)
|
gpointer run_data)
|
||||||
{
|
{
|
||||||
GimpProcedureConfig *config;
|
GimpProcedureConfig *config;
|
||||||
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
|
|
||||||
GimpExportReturn export = GIMP_EXPORT_CANCEL;
|
|
||||||
GimpMetadata *metadata;
|
GimpMetadata *metadata;
|
||||||
GimpImage *orig_image;
|
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
|
||||||
|
|
||||||
INIT_I18N ();
|
INIT_I18N ();
|
||||||
gegl_init (NULL, NULL);
|
gegl_init (NULL, NULL);
|
||||||
|
@ -329,8 +338,6 @@ tiff_save (GimpProcedure *procedure,
|
||||||
metadata = gimp_procedure_config_begin_export (config, image, run_mode,
|
metadata = gimp_procedure_config_begin_export (config, image, run_mode,
|
||||||
args, "image/tiff");
|
args, "image/tiff");
|
||||||
|
|
||||||
orig_image = image;
|
|
||||||
|
|
||||||
switch (run_mode)
|
switch (run_mode)
|
||||||
{
|
{
|
||||||
case GIMP_RUN_INTERACTIVE:
|
case GIMP_RUN_INTERACTIVE:
|
||||||
|
@ -341,16 +348,45 @@ tiff_save (GimpProcedure *procedure,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = tiff_save_rec (procedure, run_mode, image,
|
||||||
|
n_drawables, drawables,
|
||||||
|
file, config, metadata, FALSE, &error);
|
||||||
|
|
||||||
|
gimp_procedure_config_end_export (config, image, file, status);
|
||||||
|
g_object_unref (config);
|
||||||
|
|
||||||
|
return gimp_procedure_new_return_values (procedure, status, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GimpPDBStatusType
|
||||||
|
tiff_save_rec (GimpProcedure *procedure,
|
||||||
|
GimpRunMode run_mode,
|
||||||
|
GimpImage *orig_image,
|
||||||
|
gint n_orig_drawables,
|
||||||
|
GimpDrawable **orig_drawables,
|
||||||
|
GFile *file,
|
||||||
|
GimpProcedureConfig *config,
|
||||||
|
GimpMetadata *metadata,
|
||||||
|
gboolean retried,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GimpImage *image = orig_image;
|
||||||
|
GimpDrawable **drawables = orig_drawables;
|
||||||
|
gint n_drawables = n_orig_drawables;
|
||||||
|
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
|
||||||
|
GimpExportReturn export = GIMP_EXPORT_CANCEL;
|
||||||
|
gboolean bigtiff = FALSE;
|
||||||
|
|
||||||
if (run_mode == GIMP_RUN_INTERACTIVE)
|
if (run_mode == GIMP_RUN_INTERACTIVE)
|
||||||
{
|
{
|
||||||
if (! save_dialog (orig_image, procedure, G_OBJECT (config),
|
if (! save_dialog (orig_image, procedure, G_OBJECT (config),
|
||||||
n_drawables == 1 ? gimp_drawable_has_alpha (drawables[0]) : TRUE,
|
n_drawables == 1 ? gimp_drawable_has_alpha (drawables[0]) : TRUE,
|
||||||
image_is_monochrome (image),
|
image_is_monochrome (orig_image),
|
||||||
gimp_image_get_base_type (image) == GIMP_INDEXED,
|
gimp_image_get_base_type (orig_image) == GIMP_INDEXED,
|
||||||
image_is_multi_layer (image)))
|
image_is_multi_layer (orig_image),
|
||||||
|
retried))
|
||||||
{
|
{
|
||||||
return gimp_procedure_new_return_values (procedure, GIMP_PDB_CANCEL,
|
return GIMP_PDB_CANCEL;
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,6 +401,7 @@ tiff_save (GimpProcedure *procedure,
|
||||||
gboolean crop_layers;
|
gboolean crop_layers;
|
||||||
|
|
||||||
g_object_get (config,
|
g_object_get (config,
|
||||||
|
"bigtiff", &bigtiff,
|
||||||
"compression", &compression,
|
"compression", &compression,
|
||||||
"save-layers", &save_layers,
|
"save-layers", &save_layers,
|
||||||
"crop-layers", &crop_layers,
|
"crop-layers", &crop_layers,
|
||||||
|
@ -386,7 +423,7 @@ tiff_save (GimpProcedure *procedure,
|
||||||
GIMP_EXPORT_CAN_HANDLE_ALPHA);
|
GIMP_EXPORT_CAN_HANDLE_ALPHA);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (save_layers && image_is_multi_layer (image))
|
if (save_layers && image_is_multi_layer (orig_image))
|
||||||
{
|
{
|
||||||
capabilities |= GIMP_EXPORT_CAN_HANDLE_LAYERS;
|
capabilities |= GIMP_EXPORT_CAN_HANDLE_LAYERS;
|
||||||
|
|
||||||
|
@ -398,8 +435,7 @@ tiff_save (GimpProcedure *procedure,
|
||||||
capabilities);
|
capabilities);
|
||||||
|
|
||||||
if (export == GIMP_EXPORT_CANCEL)
|
if (export == GIMP_EXPORT_CANCEL)
|
||||||
return gimp_procedure_new_return_values (procedure, GIMP_PDB_CANCEL,
|
return GIMP_PDB_CANCEL;
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -420,15 +456,10 @@ tiff_save (GimpProcedure *procedure,
|
||||||
|
|
||||||
if (status == GIMP_PDB_SUCCESS)
|
if (status == GIMP_PDB_SUCCESS)
|
||||||
{
|
{
|
||||||
if (! save_image (file, image, orig_image, G_OBJECT (config), metadata,
|
if (! save_image (file, image, orig_image, G_OBJECT (config),
|
||||||
&error))
|
metadata, error))
|
||||||
{
|
|
||||||
status = GIMP_PDB_EXECUTION_ERROR;
|
status = GIMP_PDB_EXECUTION_ERROR;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
gimp_procedure_config_end_export (config, image, file, status);
|
|
||||||
g_object_unref (config);
|
|
||||||
|
|
||||||
if (export == GIMP_EXPORT_EXPORT)
|
if (export == GIMP_EXPORT_EXPORT)
|
||||||
{
|
{
|
||||||
|
@ -436,7 +467,21 @@ tiff_save (GimpProcedure *procedure,
|
||||||
g_free (drawables);
|
g_free (drawables);
|
||||||
}
|
}
|
||||||
|
|
||||||
return gimp_procedure_new_return_values (procedure, status, error);
|
if (status == GIMP_PDB_EXECUTION_ERROR &&
|
||||||
|
run_mode == GIMP_RUN_INTERACTIVE &&
|
||||||
|
! retried && ! bigtiff && tiff_got_file_size_error ())
|
||||||
|
{
|
||||||
|
/* Retrying but just once, when the save failed because we exceeded
|
||||||
|
* TIFF max size, to propose BigTIFF instead. */
|
||||||
|
tiff_reset_file_size_error ();
|
||||||
|
g_clear_error (error);
|
||||||
|
|
||||||
|
return tiff_save_rec (procedure, run_mode,
|
||||||
|
orig_image, n_orig_drawables, orig_drawables,
|
||||||
|
file, config, metadata, TRUE, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
Loading…
Reference in New Issue