[gimp/wip/wormnest/windows-tiff-delete] Issue #3740 Impossible to delete multi page tiff with thumbnail




commit d0572df71c183a657594d0652d15fe5d2f62ed6a
Author: Jacob Boerema <jgboerema gmail com>
Date:   Mon Aug 16 13:34:36 2021 -0400

    Issue #3740 Impossible to delete multi page tiff with thumbnail
    
    WIP code - not cleaned up yet
    What more needs to be done if we decide to go through with this:
    - Remove specific thumbnail saving code
    - Revise specific metadata saving code if possible
    - Remove commented out parts and debugging statements
    - Decide whether we also want to check for Exif tag on loading when we
      see a possible thumbnail
    - Do we also want a loading option to include thumbnail pages (if yes,
      maybe better as a separate issue/commit since we currently also don't
      support this)
    + There's another issue we need to look at: if we start from a newly
      created image and don't use the metadata editor to write metadata first
      then saving metadata will always silently fail.

 libgimp/gimpimagemetadata-save.c    |   6 ++
 libgimp/gimpprocedureconfig.c       |   5 ++
 plug-ins/file-tiff/file-tiff-load.c | 109 +++++++++++++++++++++++++++++++++---
 plug-ins/file-tiff/file-tiff-load.h |   2 +
 plug-ins/file-tiff/file-tiff-save.c |  11 ++--
 5 files changed, 121 insertions(+), 12 deletions(-)
---
diff --git a/libgimp/gimpimagemetadata-save.c b/libgimp/gimpimagemetadata-save.c
index ff9ba52fab..de08825563 100644
--- a/libgimp/gimpimagemetadata-save.c
+++ b/libgimp/gimpimagemetadata-save.c
@@ -458,6 +458,8 @@ gimp_image_metadata_save_finish (GimpImage              *image,
                   GIMP_METADATA_SAVE_THUMBNAIL)))
     return TRUE;
 
+  g_printerr ("Save metadata finish...\n");
+
   /* read metadata from saved file */
   new_metadata = gimp_metadata_load_from_file (file, error);
   new_g2metadata = GEXIV2_METADATA (new_metadata);
@@ -587,6 +589,7 @@ gimp_image_metadata_save_finish (GimpImage              *image,
 
 #define EXIF_THUMBNAIL_SIZE 256
 
+      g_debug ("Saving Exif Thumbnail");
       image_width  = gimp_image_get_width  (image);
       image_height = gimp_image_get_height (image);
 
@@ -634,6 +637,9 @@ gimp_image_metadata_save_finish (GimpImage              *image,
           gexiv2_metadata_set_tag_string (new_g2metadata,
                                           "Exif.Thumbnail.PhotometricInterpretation",
                                           "6");
+          gexiv2_metadata_set_tag_string (new_g2metadata,
+                                          "Exif.Thumbnail.NewSubfileType",
+                                          "1");
 
           g_free (thumb_buffer);
         }
diff --git a/libgimp/gimpprocedureconfig.c b/libgimp/gimpprocedureconfig.c
index 0de75f6ed4..1c836a2c88 100644
--- a/libgimp/gimpprocedureconfig.c
+++ b/libgimp/gimpprocedureconfig.c
@@ -846,6 +846,11 @@ gimp_procedure_config_save_metadata (GimpProcedureConfig *config,
   g_return_if_fail (GIMP_IS_IMAGE (exported_image));
   g_return_if_fail (G_IS_FILE (file));
 
+  if (config->priv->metadata)
+    g_printerr ("Save metadata...\n");
+  else
+    g_printerr ("Metadata not initialized. Can't save!\n");
+
   if (config->priv->metadata && ! config->priv->metadata_saved)
     {
       GObjectClass *object_class = G_OBJECT_GET_CLASS (config);
diff --git a/plug-ins/file-tiff/file-tiff-load.c b/plug-ins/file-tiff/file-tiff-load.c
index f0abf7711c..c1c77f456a 100644
--- a/plug-ins/file-tiff/file-tiff-load.c
+++ b/plug-ins/file-tiff/file-tiff-load.c
@@ -300,6 +300,8 @@ load_image (GFile        *file,
     }
 
   pages.pages = NULL;
+  pages.n_filtered_pages = pages.n_pages;
+/*
   if (run_mode != GIMP_RUN_INTERACTIVE)
     {
       pages.pages = g_new (gint, pages.n_pages);
@@ -308,9 +310,14 @@ load_image (GFile        *file,
         pages.pages[li] = li;
     }
   else
+*/
     {
       const gchar *extra_message = NULL;
 
+      pages.filtered_pages  = g_new0 (gint, pages.n_pages);
+      for (li = 0; li < pages.n_pages; li++)
+        pages.filtered_pages[li] = li;
+
       if (pages.n_pages == 1)
         {
           pages.pages  = g_new0 (gint, pages.n_pages);
@@ -324,6 +331,8 @@ load_image (GFile        *file,
           gushort  photomet;
           gushort  extra;
           gushort *extra_types;
+          gushort  file_type = 0;
+          gboolean first_page_old_jpeg = FALSE;
 
           if (TIFFSetDirectory (tif, li) == 0)
             continue;
@@ -353,6 +362,60 @@ load_image (GFile        *file,
             }
           if (! TIFFGetField (tif, TIFFTAG_EXTRASAMPLES, &extra, &extra_types))
             extra = 0;
+          g_printerr ("Extra: %d, extra types[0]: %d\n", extra, extra_types[0]);
+
+
+          /* Try to detect if a TIFF page is a thumbnail.
+           * It is if subfiletype is set to FILETYPE_REDUCEDIMAGE.
+           * If no subfiletype is defined we have to try to figure
+           * it out ourselves. We will consider it a thumbnail if:
+           * - Compression is old style jpeg
+           * - PhotometricInterpretation is YCbCr
+           * - It's the second page
+           * - First page uses a different compression
+           *   or PhotometricInterpretation
+           *
+           * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+           * + TODO: Check if Exif tiff tag present since this will usually
+           *   be an exif thumbnail, without exif it might be uncertain...
+           */
+          if (li == 0)
+            {
+              guint16 compression;
+
+              if (TIFFGetField (tif, TIFFTAG_COMPRESSION, &compression) &&
+                  compression == COMPRESSION_OJPEG &&
+                  photomet    == PHOTOMETRIC_YCBCR)
+                first_page_old_jpeg = TRUE;
+            }
+
+          if (TIFFGetField (tif, TIFFTAG_SUBFILETYPE, &file_type))
+            {
+              if (file_type == FILETYPE_REDUCEDIMAGE)
+                {
+                  /* file_type is a mask but we will only filter out pages
+                   * that only have FILETYPE_REDUCEDIMAGE set */
+                  pages.filtered_pages[li] = -1;
+                  pages.n_filtered_pages--;
+                  g_printerr ("Page %d is a FILETYPE_REDUCEDIMAGE thumbnail.\n", li);
+                }
+            }
+          else
+            {
+              if (li == 1 && photomet == PHOTOMETRIC_YCBCR &&
+                  ! first_page_old_jpeg)
+                {
+                  guint16 compression;
+
+                  if (TIFFGetField (tif, TIFFTAG_COMPRESSION, &compression) &&
+                      compression == COMPRESSION_OJPEG)
+                    {
+                      pages.filtered_pages[li] = -1;
+                      pages.n_filtered_pages--;
+                      g_printerr ("Page %d is most likely a thumbnail.\n", li);
+                    }
+                }
+            }
 
           /* TODO: current code always assumes that the alpha channel
            * will be the first extra channel, though the TIFF spec does
@@ -382,7 +445,8 @@ load_image (GFile        *file,
         }
       TIFFSetDirectory (tif, 0);
 
-      if ((pages.n_pages > 1 || extra_message) &&
+      if (run_mode == GIMP_RUN_INTERACTIVE &&
+          (pages.n_pages > 1 || extra_message) &&
           ! load_dialog (tif, LOAD_PROC, &pages,
                          extra_message, &default_extra))
         {
@@ -391,6 +455,29 @@ load_image (GFile        *file,
 
           return GIMP_PDB_CANCEL;
         }
+      /* Adjust pages to take filtered out pages into account. */
+      if (pages.o_pages > pages.n_filtered_pages)
+        {
+          gint fi;
+          gint sel_index = 0;
+          gint sel_add   = 0;
+
+          for (fi = 0; fi < pages.o_pages && sel_index < pages.n_pages; fi++)
+            {
+              g_printerr ("Filtered %d: page %d\n", fi, pages.filtered_pages[fi]);
+              g_printerr ("Selected %d: page %d\n", sel_index, pages.pages[sel_index]);
+              if (pages.filtered_pages[fi] == -1)
+                {
+                  sel_add++;
+                }
+              if (pages.pages[sel_index] + sel_add == fi)
+                {
+                  pages.pages[sel_index] = fi;
+                  g_printerr ("New sel page %d, value %d\n", sel_index, pages.pages[sel_index]);
+                  sel_index++;
+                }
+            }
+        }
     }
 
   gimp_set_data (LOAD_PROC "-target",
@@ -2491,7 +2578,7 @@ load_dialog (TIFF              *tif,
 
   if (pages->n_pages > 1)
     {
-      gint i;
+      gint i, j;
 
       /* Page Selector */
       selector = gimp_page_selector_new ();
@@ -2499,16 +2586,22 @@ load_dialog (TIFF              *tif,
       gtk_box_pack_start (GTK_BOX (vbox), selector, TRUE, TRUE, 0);
 
       gimp_page_selector_set_n_pages (GIMP_PAGE_SELECTOR (selector),
-                                      pages->n_pages);
+                                      pages->n_filtered_pages);
       gimp_page_selector_set_target (GIMP_PAGE_SELECTOR (selector), pages->target);
 
-      for (i = 0; i < pages->n_pages; i++)
+      for (i = 0, j = 0; i < pages->n_pages && j < pages->n_filtered_pages; i++)
         {
-          const gchar *name = tiff_get_page_name (tif);
+          g_printerr ("i: %d, j: %d\n", i, j);
+          if (pages->filtered_pages[i] != -1)
+            {
+              const gchar *name = tiff_get_page_name (tif);
 
-          if (name)
-            gimp_page_selector_set_page_label (GIMP_PAGE_SELECTOR (selector),
-                                               i, name);
+              if (name)
+                gimp_page_selector_set_page_label (GIMP_PAGE_SELECTOR (selector),
+                                                  j, name);
+              g_printerr ("Name: %s\n", name);
+              j++;
+            }
 
           TIFFReadDirectory (tif);
         }
diff --git a/plug-ins/file-tiff/file-tiff-load.h b/plug-ins/file-tiff/file-tiff-load.h
index c94f881d79..394f0931db 100644
--- a/plug-ins/file-tiff/file-tiff-load.h
+++ b/plug-ins/file-tiff/file-tiff-load.h
@@ -29,6 +29,8 @@ typedef struct
   gint                    o_pages;
   gint                    n_pages;
   gint                   *pages;
+  gint                   *filtered_pages;   /* thumbnail is marked as -1 */
+  gint                    n_filtered_pages;
   GimpPageSelectorTarget  target;
   gboolean                keep_empty_space;
 } TiffSelectedPages;
diff --git a/plug-ins/file-tiff/file-tiff-save.c b/plug-ins/file-tiff/file-tiff-save.c
index daea3f8501..90249280ea 100644
--- a/plug-ins/file-tiff/file-tiff-save.c
+++ b/plug-ins/file-tiff/file-tiff-save.c
@@ -1053,11 +1053,14 @@ save_metadata (GFile        *file,
   g_object_get (config,
                 "save-thumbnail", &save_thumbnail,
                 NULL);
+  g_debug ("Save tiff thumbnail: %s", save_thumbnail? "TRUE" : "FALSE");
 
   /* never save metadata thumbnails for TIFF, see bug #729952 */
+  /*
   g_object_set (config,
                 "save-thumbnail", FALSE,
                 NULL);
+  */
 
   gimp_procedure_config_save_metadata (GIMP_PROCEDURE_CONFIG (config),
                                        image, file);
@@ -1145,8 +1148,8 @@ save_image (GFile         *file,
     }
 
   /* we put the whole file's thumbnail into the first IFD (i.e., page) */
-  if (config_save_thumbnail)
-    TIFFSetField (tif, TIFFTAG_SUBIFD, number_of_sub_IFDs, sub_IFDs_offsets);
+  //if (config_save_thumbnail)
+  //  TIFFSetField (tif, TIFFTAG_SUBIFD, number_of_sub_IFDs, sub_IFDs_offsets);
 
   /* calculate the top-left coordinates */
   for (iter = layers; iter; iter = g_list_next (iter))
@@ -1173,8 +1176,8 @@ save_image (GFile         *file,
   current_layer++;
 
   /* write thumbnail */
-  if (config_save_thumbnail)
-    save_thumbnail (image, tif);
+  //if (config_save_thumbnail)
+  //  save_thumbnail (image, tif);
 
   /* close file so we can safely let exiv2 work on it to write metadata.
    * this can be simplified once multi page TIFF is supported by exiv2


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]