[gimp/gimp-2-10] plug-ins: fix #6766 TIFF B/W image opened as grayscale and not index map



commit 95f0822fc3d76121ecbd17d220674e48a5ca3c60
Author: Jacob Boerema <jgboerema gmail com>
Date:   Tue Jun 7 19:11:54 2022 -0400

    plug-ins: fix #6766 TIFF B/W image opened as grayscale and not index map
    
    In a previous commit 1, 2 and 4-bit B/W images were converted to grayscale.
    However, it seems that there is more of a use case for these images to be
    handled as indexed, even though technically they can be considered
    grayscale.
    Also, the only way to export these images again in the same format, is to
    have them as indexed.
    
    So, let's change this back, so that these kind of images will be opened
    as indexed. With a reminder that in the future we could add an option
    at loading time where the user can choose whether they prefer it to be
    loaded as indexed or grayscale.
    
    We use grayscale mappings, that we moved in the previous commit, to
    add a palette to these grayscale images.
    
    (cherry picked from commit 3e6237030c8a7d7a91b7163db19b1d158d1b5161)

 plug-ins/file-tiff/file-tiff-load.c | 168 +++++++++++++++++++++++++++---------
 1 file changed, 125 insertions(+), 43 deletions(-)
---
diff --git a/plug-ins/file-tiff/file-tiff-load.c b/plug-ins/file-tiff/file-tiff-load.c
index 8e976ff8a1..c88e9a2ea0 100644
--- a/plug-ins/file-tiff/file-tiff-load.c
+++ b/plug-ins/file-tiff/file-tiff-load.c
@@ -829,26 +829,54 @@ load_image (GFile        *file,
 
       switch (photomet)
         {
+        case PHOTOMETRIC_PALETTE:
         case PHOTOMETRIC_MINISBLACK:
         case PHOTOMETRIC_MINISWHITE:
-          if (photomet == PHOTOMETRIC_MINISWHITE)
-            tiff_mode = GIMP_TIFF_GRAY_MINISWHITE;
+          if (bps < 8)
+            {
+              if (photomet == PHOTOMETRIC_PALETTE)
+                tiff_mode = GIMP_TIFF_INDEXED;
+              else if (photomet == PHOTOMETRIC_MINISBLACK)
+                tiff_mode = GIMP_TIFF_GRAY;
+              else if (photomet == PHOTOMETRIC_MINISWHITE)
+                tiff_mode = GIMP_TIFF_GRAY_MINISWHITE;
+
+              /* FIXME: It should be a user choice whether this should be
+               * interpreted as indexed or grayscale. For now we will
+               * use indexed (see issue #6766). */
+              image_type = GIMP_INDEXED;
+              layer_type = alpha ? GIMP_INDEXEDA_IMAGE : GIMP_INDEXED_IMAGE;
+
+              if ((bps == 1 || bps == 2 || bps == 4) && ! alpha && spp == 1)
+                {
+                  if (bps == 1)
+                    fill_bit2byte (tiff_mode);
+                  else if (bps == 2)
+                    fill_2bit2byte (tiff_mode);
+                  else if (bps == 4)
+                    fill_4bit2byte (tiff_mode);
+                }
+            }
           else
-            tiff_mode = GIMP_TIFF_GRAY;
-
-          if ((bps == 1 || bps == 2 || bps == 4) && ! alpha && spp == 1)
             {
-              if (bps == 1)
-                fill_bit2byte (tiff_mode);
-              else if (bps == 2)
-                fill_2bit2byte (tiff_mode);
-              else if (bps == 4)
-                fill_4bit2byte (tiff_mode);
+              if (photomet == PHOTOMETRIC_PALETTE)
+                {
+                  image_type = GIMP_INDEXED;
+                  layer_type = alpha ? GIMP_INDEXEDA_IMAGE : GIMP_INDEXED_IMAGE;
+                }
+              else
+                {
+                  image_type = GIMP_GRAY;
+                  layer_type = alpha ? GIMP_GRAYA_IMAGE : GIMP_GRAY_IMAGE;
+                }
             }
-          image_type = GIMP_GRAY;
-          layer_type = alpha ? GIMP_GRAYA_IMAGE : GIMP_GRAY_IMAGE;
 
-          if (alpha)
+          if (photomet == PHOTOMETRIC_PALETTE)
+            {
+              /* Do nothing here, handled later.
+               * Didn't want more indenting in the next part. */
+            }
+          else if (alpha)
             {
               if (tsvals.save_transp_pixels)
                 {
@@ -984,21 +1012,6 @@ load_image (GFile        *file,
             }
           break;
 
-        case PHOTOMETRIC_PALETTE:
-          image_type = GIMP_INDEXED;
-          layer_type = alpha ? GIMP_INDEXEDA_IMAGE : GIMP_INDEXED_IMAGE;
-
-          if (bps < 8)
-            tiff_mode = GIMP_TIFF_INDEXED; /* Only bps < 8 needs special handling. */
-
-          if (bps == 1)
-            fill_bit2byte (tiff_mode);
-          else if (bps == 2)
-            fill_2bit2byte (tiff_mode);
-          else if (bps == 4)
-            fill_4bit2byte (tiff_mode);
-          break;
-
         case PHOTOMETRIC_SEPARATED:
           layer_type = alpha ? GIMP_RGBA_IMAGE : GIMP_RGB_IMAGE;
           /* It's possible that a CMYK image might not have an
@@ -1361,25 +1374,94 @@ load_image (GFile        *file,
       if (image_type == GIMP_INDEXED)
         {
           guchar   cmap[768];
-          gushort *redmap;
-          gushort *greenmap;
-          gushort *bluemap;
-          gint     i, j;
 
-          if (! TIFFGetField (tif, TIFFTAG_COLORMAP,
-                              &redmap, &greenmap, &bluemap))
+          if (photomet == PHOTOMETRIC_PALETTE)
             {
-              TIFFClose (tif);
-              g_message (_("Could not get colormaps from '%s'"),
-                         gimp_file_get_utf8_name (file));
-              return GIMP_PDB_EXECUTION_ERROR;
+              gushort *redmap;
+              gushort *greenmap;
+              gushort *bluemap;
+              gint     i, j;
+
+              if (! TIFFGetField (tif, TIFFTAG_COLORMAP,
+                                  &redmap, &greenmap, &bluemap))
+                {
+                  TIFFClose (tif);
+                  g_message (_("Could not get colormaps from '%s'"),
+                             gimp_file_get_utf8_name (file));
+                  return GIMP_PDB_EXECUTION_ERROR;
+                }
+
+              for (i = 0, j = 0; i < (1 << bps); i++)
+                {
+                  cmap[j++] = redmap[i] >> 8;
+                  cmap[j++] = greenmap[i] >> 8;
+                  cmap[j++] = bluemap[i] >> 8;
+                }
+
             }
+          else if (photomet == PHOTOMETRIC_MINISBLACK)
+            {
+              gint i, j;
 
-          for (i = 0, j = 0; i < (1 << bps); i++)
+              if (bps == 1)
+                {
+                  for (i = 0, j = 0; i < (1 << bps); i++)
+                    {
+                      cmap[j++] = _1_to_8_bitmap[i];
+                      cmap[j++] = _1_to_8_bitmap[i];
+                      cmap[j++] = _1_to_8_bitmap[i];
+                    }
+                }
+              else if (bps == 2)
+                {
+                  for (i = 0, j = 0; i < (1 << bps); i++)
+                    {
+                      cmap[j++] = _2_to_8_bitmap[i];
+                      cmap[j++] = _2_to_8_bitmap[i];
+                      cmap[j++] = _2_to_8_bitmap[i];
+                    }
+                }
+              else if (bps == 4)
+                {
+                  for (i = 0, j = 0; i < (1 << bps); i++)
+                    {
+                      cmap[j++] = _4_to_8_bitmap[i];
+                      cmap[j++] = _4_to_8_bitmap[i];
+                      cmap[j++] = _4_to_8_bitmap[i];
+                    }
+                }
+            }
+          else if (photomet == PHOTOMETRIC_MINISWHITE)
             {
-              cmap[j++] = redmap[i] >> 8;
-              cmap[j++] = greenmap[i] >> 8;
-              cmap[j++] = bluemap[i] >> 8;
+              gint i, j;
+
+              if (bps == 1)
+                {
+                  for (i = 0, j = 0; i < (1 << bps); i++)
+                    {
+                      cmap[j++] = _1_to_8_bitmap_rev[i];
+                      cmap[j++] = _1_to_8_bitmap_rev[i];
+                      cmap[j++] = _1_to_8_bitmap_rev[i];
+                    }
+                }
+              else if (bps == 2)
+                {
+                  for (i = 0, j = 0; i < (1 << bps); i++)
+                    {
+                      cmap[j++] = _2_to_8_bitmap_rev[i];
+                      cmap[j++] = _2_to_8_bitmap_rev[i];
+                      cmap[j++] = _2_to_8_bitmap_rev[i];
+                    }
+                }
+              else if (bps == 4)
+                {
+                  for (i = 0, j = 0; i < (1 << bps); i++)
+                    {
+                      cmap[j++] = _4_to_8_bitmap_rev[i];
+                      cmap[j++] = _4_to_8_bitmap_rev[i];
+                      cmap[j++] = _4_to_8_bitmap_rev[i];
+                    }
+                }
             }
 
           gimp_image_set_colormap (*image, cmap, (1 << bps));


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