gdk: Support gray/alpha in TIFF loader
authorSophie Herold <sophie@hemio.de>
Fri, 26 May 2023 12:57:32 +0000 (14:57 +0200)
committerMatthias Clasen <mclasen@redhat.com>
Tue, 30 May 2023 18:41:01 +0000 (14:41 -0400)
Use PHOTOMETRIC_MINISBLACK for grayscale image

gdk/loaders/gdktiff.c

index d112ff1626415e713dd4772e42da2d003652525f..674211898a15ca86057008900a7fbaaa3587b76f 100644 (file)
@@ -229,27 +229,36 @@ struct _FormatData {
   guint16 samples_per_pixel;
   guint16 sample_format;
   guint16 alpha_samples;
+  guint16 photometric;
 };
 
 static const FormatData format_data[] = {
-  [GDK_MEMORY_B8G8R8A8_PREMULTIPLIED]           = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,            8, 4, SAMPLEFORMAT_UINT,   EXTRASAMPLE_ASSOCALPHA },
-  [GDK_MEMORY_A8R8G8B8_PREMULTIPLIED]           = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,            8, 4, SAMPLEFORMAT_UINT,   EXTRASAMPLE_ASSOCALPHA },
-  [GDK_MEMORY_R8G8B8A8_PREMULTIPLIED]           = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,            8, 4, SAMPLEFORMAT_UINT,   EXTRASAMPLE_ASSOCALPHA },
-  [GDK_MEMORY_B8G8R8A8]                         = { GDK_MEMORY_R8G8B8A8,                          8, 4, SAMPLEFORMAT_UINT,   EXTRASAMPLE_UNASSALPHA },
-  [GDK_MEMORY_A8R8G8B8]                         = { GDK_MEMORY_R8G8B8A8,                          8, 4, SAMPLEFORMAT_UINT,   EXTRASAMPLE_UNASSALPHA },
-  [GDK_MEMORY_R8G8B8A8]                         = { GDK_MEMORY_R8G8B8A8,                          8, 4, SAMPLEFORMAT_UINT,   EXTRASAMPLE_UNASSALPHA },
-  [GDK_MEMORY_A8B8G8R8]                         = { GDK_MEMORY_R8G8B8A8,                          8, 4, SAMPLEFORMAT_UINT,   EXTRASAMPLE_UNASSALPHA },
-  [GDK_MEMORY_R8G8B8]                           = { GDK_MEMORY_R8G8B8,                            8, 3, SAMPLEFORMAT_UINT,   0                      },
-  [GDK_MEMORY_B8G8R8]                           = { GDK_MEMORY_R8G8B8,                            8, 3, SAMPLEFORMAT_UINT,   0                      },
-  [GDK_MEMORY_R16G16B16]                        = { GDK_MEMORY_R16G16B16,                        16, 3, SAMPLEFORMAT_UINT,   0                      },
-  [GDK_MEMORY_R16G16B16A16_PREMULTIPLIED]       = { GDK_MEMORY_R16G16B16A16_PREMULTIPLIED,       16, 4, SAMPLEFORMAT_UINT,   EXTRASAMPLE_ASSOCALPHA },
-  [GDK_MEMORY_R16G16B16A16]                     = { GDK_MEMORY_R16G16B16A16,                     16, 4, SAMPLEFORMAT_UINT,   EXTRASAMPLE_UNASSALPHA },
-  [GDK_MEMORY_R16G16B16_FLOAT]                  = { GDK_MEMORY_R16G16B16_FLOAT,                  16, 3, SAMPLEFORMAT_IEEEFP, 0                      },
-  [GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] = { GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED, 16, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_ASSOCALPHA },
-  [GDK_MEMORY_R16G16B16A16_FLOAT]               = { GDK_MEMORY_R16G16B16A16_FLOAT,               16, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_UNASSALPHA },
-  [GDK_MEMORY_R32G32B32_FLOAT]                  = { GDK_MEMORY_R32G32B32_FLOAT,                  32, 3, SAMPLEFORMAT_IEEEFP, 0                      },
-  [GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] = { GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED, 32, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_ASSOCALPHA },
-  [GDK_MEMORY_R32G32B32A32_FLOAT]               = { GDK_MEMORY_R32G32B32A32_FLOAT,               32, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_UNASSALPHA },
+  [GDK_MEMORY_B8G8R8A8_PREMULTIPLIED]           = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,            8, 4, SAMPLEFORMAT_UINT,   EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
+  [GDK_MEMORY_A8R8G8B8_PREMULTIPLIED]           = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,            8, 4, SAMPLEFORMAT_UINT,   EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
+  [GDK_MEMORY_R8G8B8A8_PREMULTIPLIED]           = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,            8, 4, SAMPLEFORMAT_UINT,   EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
+  [GDK_MEMORY_B8G8R8A8]                         = { GDK_MEMORY_R8G8B8A8,                          8, 4, SAMPLEFORMAT_UINT,   EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
+  [GDK_MEMORY_A8R8G8B8]                         = { GDK_MEMORY_R8G8B8A8,                          8, 4, SAMPLEFORMAT_UINT,   EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
+  [GDK_MEMORY_R8G8B8A8]                         = { GDK_MEMORY_R8G8B8A8,                          8, 4, SAMPLEFORMAT_UINT,   EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
+  [GDK_MEMORY_A8B8G8R8]                         = { GDK_MEMORY_R8G8B8A8,                          8, 4, SAMPLEFORMAT_UINT,   EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
+  [GDK_MEMORY_R8G8B8]                           = { GDK_MEMORY_R8G8B8,                            8, 3, SAMPLEFORMAT_UINT,   0,                      PHOTOMETRIC_RGB },
+  [GDK_MEMORY_B8G8R8]                           = { GDK_MEMORY_R8G8B8,                            8, 3, SAMPLEFORMAT_UINT,   0,                      PHOTOMETRIC_RGB },
+  [GDK_MEMORY_R16G16B16]                        = { GDK_MEMORY_R16G16B16,                        16, 3, SAMPLEFORMAT_UINT,   0,                      PHOTOMETRIC_RGB },
+  [GDK_MEMORY_R16G16B16A16_PREMULTIPLIED]       = { GDK_MEMORY_R16G16B16A16_PREMULTIPLIED,       16, 4, SAMPLEFORMAT_UINT,   EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
+  [GDK_MEMORY_R16G16B16A16]                     = { GDK_MEMORY_R16G16B16A16,                     16, 4, SAMPLEFORMAT_UINT,   EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
+  [GDK_MEMORY_R16G16B16_FLOAT]                  = { GDK_MEMORY_R16G16B16_FLOAT,                  16, 3, SAMPLEFORMAT_IEEEFP, 0,                      PHOTOMETRIC_RGB },
+  [GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] = { GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED, 16, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
+  [GDK_MEMORY_R16G16B16A16_FLOAT]               = { GDK_MEMORY_R16G16B16A16_FLOAT,               16, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
+  [GDK_MEMORY_R32G32B32_FLOAT]                  = { GDK_MEMORY_R32G32B32_FLOAT,                  32, 3, SAMPLEFORMAT_IEEEFP, 0,                      PHOTOMETRIC_RGB },
+  [GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] = { GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED, 32, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
+  [GDK_MEMORY_R32G32B32A32_FLOAT]               = { GDK_MEMORY_R32G32B32A32_FLOAT,               32, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
+  [GDK_MEMORY_G8A8_PREMULTIPLIED]               = { GDK_MEMORY_G8A8_PREMULTIPLIED,                8, 2, SAMPLEFORMAT_UINT,   EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_MINISBLACK },
+  [GDK_MEMORY_G8A8]                             = { GDK_MEMORY_G8A8,                              8, 2, SAMPLEFORMAT_UINT,   EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_MINISBLACK },
+  [GDK_MEMORY_G8]                               = { GDK_MEMORY_G8,                                8, 1, SAMPLEFORMAT_UINT,   0,                      PHOTOMETRIC_MINISBLACK },
+  [GDK_MEMORY_G16A16_PREMULTIPLIED]             = { GDK_MEMORY_G16A16_PREMULTIPLIED,             16, 2, SAMPLEFORMAT_UINT,   EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_MINISBLACK },
+  [GDK_MEMORY_G16A16]                           = { GDK_MEMORY_G16A16,                           16, 2, SAMPLEFORMAT_UINT,   EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_MINISBLACK },
+  [GDK_MEMORY_G16]                              = { GDK_MEMORY_G16,                              16, 1, SAMPLEFORMAT_UINT,   0,                      PHOTOMETRIC_MINISBLACK },
+  [GDK_MEMORY_A8]                               = { GDK_MEMORY_G8A8,                              8, 2, SAMPLEFORMAT_UINT,   EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_MINISBLACK },
+  [GDK_MEMORY_A16]                              = { GDK_MEMORY_G16A16,                           16, 2, SAMPLEFORMAT_UINT,   EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_MINISBLACK },
 };
 
 /* if this fails, somebody forgot to add formats above */
@@ -289,7 +298,7 @@ gdk_save_tiff (GdkTexture *texture)
   if (fdata->alpha_samples)
     TIFFSetField (tif, TIFFTAG_EXTRASAMPLES, 1, &fdata->alpha_samples);
 
-  TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+  TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, fdata->photometric);
   TIFFSetField (tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
 
   gdk_texture_downloader_init (&downloader, texture);
@@ -397,7 +406,7 @@ gdk_load_tiff (GBytes  *input_bytes,
   TIFFGetFieldDefaulted (tif, TIFFTAG_IMAGEWIDTH, &width);
   TIFFGetFieldDefaulted (tif, TIFFTAG_IMAGELENGTH, &height);
 
-  if (samples_per_pixel == 4)
+  if (samples_per_pixel == 2 || samples_per_pixel == 4)
     {
       guint16 extra;
       guint16 *extra_types;
@@ -426,14 +435,15 @@ gdk_load_tiff (GBytes  *input_bytes,
       if (format_data[format].sample_format == sample_format &&
           format_data[format].bits_per_sample == bits_per_sample &&
           format_data[format].samples_per_pixel == samples_per_pixel &&
-          format_data[format].alpha_samples == alpha_samples)
+          format_data[format].alpha_samples == alpha_samples &&
+          format_data[format].photometric == photometric)
         {
           break;
         }
     }
 
   if (format == G_N_ELEMENTS(format_data) ||
-      photometric != PHOTOMETRIC_RGB ||
+      (photometric != PHOTOMETRIC_RGB && photometric != PHOTOMETRIC_MINISBLACK) ||
       planarconfig != PLANARCONFIG_CONTIG ||
       TIFFIsTiled (tif) ||
       orientation != ORIENTATION_TOPLEFT)