[gimp] plug-ins: PNG export TRC chosen similarly to TIFF.



commit 24ed5870ade6e76ec828a752cf6b2a6d6c043f28
Author: Jehan <jehan girinstud io>
Date:   Fri Jun 7 18:18:33 2019 +0200

    plug-ins: PNG export TRC chosen similarly to TIFF.
    
    While we tend to default to sRGB for 8-bit max formats (such as JPEG or
    WebP) when no explicitly-assigned profile was set, there is no need to
    do so for PNG too. Indeed since we have the ability to export 16-bit
    PNG, let's consider this is ok to export 16-bit linear data when writing
    GIMP's default linear profile.
    
    Moreover let's follow the profile's (fallback to storage's) TRC also
    when exporting to a specific precision (as chosen manually in the
    dialog), not only when sticking to "Automatic", unless we are downsizing
    a high bit depth work image to 8-bit without a manually assigned profile
    (the only case we forcefully export as sRGB data, hence convert the
    profile if linear storage).

 plug-ins/common/file-png.c | 101 ++++++++++++++++++++++++++++++++-------------
 1 file changed, 73 insertions(+), 28 deletions(-)
---
diff --git a/plug-ins/common/file-png.c b/plug-ins/common/file-png.c
index d84b737eac..d60b9334b7 100644
--- a/plug-ins/common/file-png.c
+++ b/plug-ins/common/file-png.c
@@ -1494,27 +1494,47 @@ save_image (const gchar  *filename,
 
   out_linear = FALSE;
 #if defined(PNG_iCCP_SUPPORTED)
-  profile = gimp_image_get_color_profile (orig_image_ID);
+  /* If no profile is written: export as sRGB.
+   * If manually assigned profile written: follow its TRC.
+   * If default profile written:
+   *   - when export as auto or 16-bit: follow the storage TRC.
+   *   - when export from 8-bit storage: follow the storage TRC.
+   *   - when converting high bit depth to 8-bit: export as sRGB.
+   */
   if (pngvals.save_profile)
     {
-      if (profile && gimp_color_profile_is_linear (profile) &&
-          pngvals.export_format == PNG_FORMAT_AUTO)
-        out_linear = TRUE;
+      profile = gimp_image_get_color_profile (orig_image_ID);
+
+      if (profile                                     ||
+          pngvals.export_format == PNG_FORMAT_AUTO    ||
+          pngvals.export_format == PNG_FORMAT_RGB16   ||
+          pngvals.export_format == PNG_FORMAT_RGBA16  ||
+          pngvals.export_format == PNG_FORMAT_GRAY16  ||
+          pngvals.export_format == PNG_FORMAT_GRAYA16 ||
+          gimp_image_get_precision (image_ID) == GIMP_PRECISION_U8_LINEAR     ||
+          gimp_image_get_precision (image_ID) == GIMP_PRECISION_U8_NON_LINEAR ||
+          gimp_image_get_precision (image_ID) == GIMP_PRECISION_U8_PERCEPTUAL)
+        {
+          if (! profile)
+            profile = gimp_image_get_effective_color_profile (orig_image_ID);
+          out_linear = (gimp_color_profile_is_linear (profile));
+        }
+      else
+        {
+          /* When converting higher bit depth work image into 8-bit,
+           * with no manually assigned profile, make sure the result if
+           * sRGB. */
+          profile = gimp_image_get_effective_color_profile (orig_image_ID);
 
-      if (! profile)
-        profile = gimp_image_get_effective_color_profile (orig_image_ID);
+          if (gimp_color_profile_is_linear (profile))
+            {
+              GimpColorProfile *saved_profile;
 
-      if (! out_linear && gimp_color_profile_is_linear (profile))
-        {
-          /* This should happen only when using default linear profile
-           * (no profile explicitly set) or when not exporting to
-           * PNG_FORMAT_AUTO.
-           */
-          GimpColorProfile *saved_profile;
+              saved_profile = gimp_color_profile_new_srgb_trc_from_color_profile (profile);
+              g_object_unref (profile);
+              profile = saved_profile;
+            }
 
-          saved_profile = gimp_color_profile_new_srgb_trc_from_color_profile (profile);
-          g_object_unref (profile);
-          profile = saved_profile;
         }
     }
 #endif
@@ -1534,7 +1554,8 @@ save_image (const gchar  *filename,
 
     case GIMP_PRECISION_U8_NON_LINEAR:
     case GIMP_PRECISION_U8_PERCEPTUAL:
-      bit_depth = 8;
+      if (! out_linear)
+        bit_depth = 8;
       break;
 
     default:
@@ -1718,45 +1739,70 @@ save_image (const gchar  *filename,
       {
         case PNG_FORMAT_RGB8:
           color_type = PNG_COLOR_TYPE_RGB;
-          file_format = babl_format ("R'G'B' u8");
+          if (out_linear)
+            file_format = babl_format ("RGB u8");
+          else
+            file_format = babl_format ("R'G'B' u8");
           bit_depth = 8;
           break;
         case PNG_FORMAT_GRAY8:
           color_type = PNG_COLOR_TYPE_GRAY;
-          file_format = babl_format ("Y' u8");
+          if (out_linear)
+            file_format = babl_format ("Y u8");
+          else
+            file_format = babl_format ("Y' u8");
           bit_depth = 8;
           break;
-        case PNG_FORMAT_AUTO: // shut up gcc
         case PNG_FORMAT_RGBA8:
           color_type = PNG_COLOR_TYPE_RGB_ALPHA;
-          file_format = babl_format ("R'G'B'A u8");
+          if (out_linear)
+            file_format = babl_format ("RGBA u8");
+          else
+            file_format = babl_format ("R'G'B'A u8");
           bit_depth = 8;
           break;
         case PNG_FORMAT_GRAYA8:
           color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
-          file_format = babl_format ("Y'A u8");
+          if (out_linear)
+            file_format = babl_format ("YA u8");
+          else
+            file_format = babl_format ("Y'A u8");
           bit_depth = 8;
           break;
         case PNG_FORMAT_RGB16:
           color_type = PNG_COLOR_TYPE_RGB;
-          file_format = babl_format ("R'G'B' u16");
+          if (out_linear)
+            file_format = babl_format ("RGB u16");
+          else
+            file_format = babl_format ("R'G'B' u16");
           bit_depth = 16;
           break;
         case PNG_FORMAT_GRAY16:
           color_type = PNG_COLOR_TYPE_GRAY;
-          file_format = babl_format ("Y' u16");
+          if (out_linear)
+            file_format = babl_format ("Y u16");
+          else
+            file_format = babl_format ("Y' u16");
           bit_depth = 16;
           break;
         case PNG_FORMAT_RGBA16:
           color_type = PNG_COLOR_TYPE_RGB_ALPHA;
-          file_format = babl_format ("R'G'B'A u16");
+          if (out_linear)
+            file_format = babl_format ("RGBA u16");
+          else
+            file_format = babl_format ("R'G'B'A u16");
           bit_depth = 16;
           break;
         case PNG_FORMAT_GRAYA16:
           color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
-          file_format = babl_format ("Y'A u16");
+          if (out_linear)
+            file_format = babl_format ("YA u16");
+          else
+            file_format = babl_format ("Y'A u16");
           bit_depth = 16;
           break;
+        case PNG_FORMAT_AUTO:
+          g_return_val_if_reached (FALSE);
       }
     }
 
@@ -1868,9 +1914,8 @@ save_image (const gchar  *filename,
       g_free (profile_name);
 
       *profile_saved = TRUE;
+      g_object_unref (profile);
     }
-  if (profile)
-    g_object_unref (profile);
 #endif
 
 #ifdef PNG_zTXt_SUPPORTED


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