[gimp] Issue #3253: exporting to webp from 32-bit float linear image...



commit 7a4b313b12b8bdea4cbd8003719fc6b255a707ff
Author: Jehan <jehan girinstud io>
Date:   Sun Apr 14 22:18:36 2019 +0200

    Issue #3253: exporting to webp from 32-bit float linear image...
    
    ... produces incorrect result.
    Similar to previous fixes to JPEG and PNG exporters. Here WebP always
    export 8-bit per channel colors, so let's always keep it non-linear.
    Simply when the original data was linear, if we save the profile,
    convert it to sRGB before exporting.

 plug-ins/file-webp/file-webp-save.c | 34 ++++++++++++++++++++++++++++++----
 1 file changed, 30 insertions(+), 4 deletions(-)
---
diff --git a/plug-ins/file-webp/file-webp-save.c b/plug-ins/file-webp/file-webp-save.c
index 50325f0601..270016ddfd 100644
--- a/plug-ins/file-webp/file-webp-save.c
+++ b/plug-ins/file-webp/file-webp-save.c
@@ -162,6 +162,20 @@ save_layer (const gchar    *filename,
   WebPData          chunk;
   int               res;
 
+  profile = gimp_image_get_color_profile (image_ID);
+  if (profile && gimp_color_profile_is_linear (profile))
+    {
+      /* We always save as sRGB data, especially since WebP is
+       * apparently 8-bit max (at least how we export it). If original
+       * data was linear, let's convert the profile.
+       */
+      GimpColorProfile *saved_profile;
+
+      saved_profile = gimp_color_profile_new_srgb_trc_from_color_profile (profile);
+      g_object_unref (profile);
+      profile = saved_profile;
+    }
+
   /* The do...while() loop is a neat little trick that makes it easier
    * to jump to error handling code while still ensuring proper
    * cleanup
@@ -294,7 +308,6 @@ save_layer (const gchar    *filename,
               gboolean saved = FALSE;
 
               /* Save ICC data */
-              profile = gimp_image_get_color_profile (image_ID);
               if (profile)
                 {
                   const guint8 *icc_data;
@@ -307,7 +320,6 @@ save_layer (const gchar    *filename,
                   chunk.bytes = icc_data;
                   chunk.size = icc_data_size;
                   WebPMuxSetChunk(mux, "ICCP", &chunk, 1);
-                  g_object_unref (profile);
                 }
 
               if (saved == TRUE)
@@ -341,6 +353,7 @@ save_layer (const gchar    *filename,
     fclose (outfile);
 
   WebPPictureFree (&picture);
+  g_clear_object (&profile);
 
   return status;
 }
@@ -496,6 +509,20 @@ save_animation (const gchar    *filename,
   if (nLayers < 1)
     return FALSE;
 
+  profile = gimp_image_get_color_profile (image_ID);
+  if (profile && gimp_color_profile_is_linear (profile))
+    {
+      /* We always save as sRGB data, especially since WebP is
+       * apparently 8-bit max (at least how we export it). If original
+       * data was linear, let's convert the profile.
+       */
+      GimpColorProfile *saved_profile;
+
+      saved_profile = gimp_color_profile_new_srgb_trc_from_color_profile (profile);
+      g_object_unref (profile);
+      profile = saved_profile;
+    }
+
   gimp_image_undo_freeze (image_ID);
 
   WebPDataInit (&webp_data);
@@ -687,7 +714,6 @@ save_animation (const gchar    *filename,
         }
 
       /* Create a mux object if profile is present */
-      profile = gimp_image_get_color_profile (image_ID);
       if (profile)
         {
           WebPMux      *mux;
@@ -708,7 +734,6 @@ save_animation (const gchar    *filename,
           chunk.bytes = icc_data;
           chunk.size  = icc_data_size;
           WebPMuxSetChunk (mux, "ICCP", &chunk, 1);
-          g_object_unref (profile);
 
           WebPDataClear (&webp_data);
           if (WebPMuxAssemble (mux, &webp_data) != WEBP_MUX_OK)
@@ -726,6 +751,7 @@ save_animation (const gchar    *filename,
   /* Free any resources */
   WebPDataClear (&webp_data);
   WebPAnimEncoderDelete (enc);
+  g_clear_object (&profile);
 
   if (prev_frame != NULL)
     {


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