Author: post
Date: 2011-04-13 21:30:06 +0200 (Wed, 13 Apr 2011)
New Revision: 3987

Modified:
   trunk/plugins/load-gdk/exiv2-colorspace.cpp
   trunk/plugins/load-gdk/exiv2-colorspace.h
   trunk/plugins/load-gdk/load-gdk.c
Log:
Better guestimation of gamma when ICC profiles are the only information in 
images.

Modified: trunk/plugins/load-gdk/exiv2-colorspace.cpp
===================================================================
--- trunk/plugins/load-gdk/exiv2-colorspace.cpp 2011-04-13 13:29:47 UTC (rev 
3986)
+++ trunk/plugins/load-gdk/exiv2-colorspace.cpp 2011-04-13 19:30:06 UTC (rev 
3987)
@@ -60,7 +60,7 @@
 }
 
 RSColorSpace*
-exiv2_get_colorspace(const gchar *filename, gboolean *linear_guess)
+exiv2_get_colorspace(const gchar *filename, gfloat *gamma_guess)
 {
        struct jpeg_decompress_struct info;
        jpeg_create_decompress(&info);
@@ -100,7 +100,7 @@
 #ifdef PNG_iCCP_SUPPORTED
        if (1)
        {
-               *linear_guess = FALSE;
+               *gamma_guess = 2.2f;
                RSColorSpace* profile = NULL;
                const gchar *icc_profile_title;
                const gchar *icc_profile;
@@ -135,11 +135,10 @@
                                                        RSIccProfile *icc = 
rs_icc_profile_new_from_memory((gchar*)icc_profile, icc_profile_size, TRUE);
                                                        profile = 
rs_color_space_icc_new_from_icc(icc);
                                                }
-                                               gdouble gamma = 2.2;
-                                               png_get_gAMA(png_ptr, info_ptr, 
&gamma);
-                                               if (gamma < 1.1)
-                                                       *linear_guess = TRUE;
                                        }
+                                       gdouble gamma = 2.2;
+                                       if (png_get_gAMA(png_ptr, info_ptr, 
&gamma))
+                                               *gamma_guess = gamma;
                                }
                                png_destroy_read_struct (&png_ptr, &info_ptr, 
NULL);
                        }
@@ -154,7 +153,7 @@
                Image::AutoPtr img = ImageFactory::open(filename);
                img->readMetadata();
                ExifData &exifData = img->exifData();
-               *linear_guess = FALSE;
+               *gamma_guess = 2.2f;
 
 #if EXIV2_TEST_VERSION(0,17,0)
                if (exifData.empty() && !img->xmpData().empty())
@@ -170,7 +169,7 @@
                        i = 
exifData.findKey(ExifKey("Exif.Image.BitsPerSample"));
                        if (i != exifData.end())
                                if (i->toLong() == 16)
-                                       *linear_guess = TRUE;
+                                       *gamma_guess = 1.0f;
                        
                        i = exifData.findKey(ExifKey("Exif.Photo.ColorSpace"));
                        if (i != exifData.end())
@@ -195,7 +194,10 @@
                        i = 
exifData.findKey(ExifKey("Exif.Iop.InteroperabilityIndex"));
                        if (i != exifData.end())
                                if (0 == i->toString().compare("R03"))
+                               {
+                                       *gamma_guess = 2.2f;
                                        return 
rs_color_space_new_singleton("RSAdobeRGB");
+                               }
                }
        } catch (Exiv2::Error& e) {
                g_debug("Exiv2 ColorSpace Loader:'%s", e.what());

Modified: trunk/plugins/load-gdk/exiv2-colorspace.h
===================================================================
--- trunk/plugins/load-gdk/exiv2-colorspace.h   2011-04-13 13:29:47 UTC (rev 
3986)
+++ trunk/plugins/load-gdk/exiv2-colorspace.h   2011-04-13 19:30:06 UTC (rev 
3987)
@@ -30,7 +30,7 @@
 #endif
 
 extern RSColorSpace*
-exiv2_get_colorspace(const gchar *filename, gboolean *linear_guess);
+exiv2_get_colorspace(const gchar *filename, gfloat *gamma_guess);
 
 
 #ifdef _unix_

Modified: trunk/plugins/load-gdk/load-gdk.c
===================================================================
--- trunk/plugins/load-gdk/load-gdk.c   2011-04-13 13:29:47 UTC (rev 3986)
+++ trunk/plugins/load-gdk/load-gdk.c   2011-04-13 19:30:06 UTC (rev 3987)
@@ -20,6 +20,7 @@
 #include <rawstudio.h>
 #include <math.h> /* pow() */
 #include "exiv2-colorspace.h"
+#include <lcms.h>
 
 
 /**
@@ -40,13 +41,50 @@
        gint alpha=0;
        gint n;
        gdouble nd, res;
-       gboolean linear_guess = FALSE;
+       gfloat gamma_guess = 2.2f;
 
-       RSColorSpace *input_space = exiv2_get_colorspace(filename, 
&linear_guess);
+       RSColorSpace *input_space = exiv2_get_colorspace(filename, 
&gamma_guess);
+
+       if (G_OBJECT_TYPE(input_space) == RS_TYPE_COLOR_SPACE_ICC)
+       {
+               gchar *data;
+               gsize length;
+               RSIccProfile *profile = 
RS_COLOR_SPACE_ICC(input_space)->icc_profile;
+               
+               if (rs_icc_profile_get_data(profile, &data, &length))
+               {
+                       cmsHPROFILE *lcms_target = cmsOpenProfileFromMem(data, 
length);
+                       if (lcms_target)
+                       {
+                               LPGAMMATABLE curve = NULL;
+                               if (cmsIsTag(lcms_target, icSigGrayTRCTag))
+                                       curve = cmsReadICCGamma(lcms_target, 
icSigGrayTRCTag);
+
+                               if (NULL== curve && cmsIsTag(lcms_target, 
icSigRedTRCTag))
+                                       curve = cmsReadICCGamma(lcms_target, 
icSigRedTRCTag);
+                               if (curve)
+                               {
+                                       double gamma = cmsEstimateGamma(curve);
+                                       if (gamma>0.0)
+                                               gamma_guess = gamma;
+                               }
+                       }
+               }
+
+               /* This may seem very strange, but ICC profiles are basically 
treated as */
+               /* being either gamma 1.0 or gamma 2.2, this is then reversely 
applied to */
+               /* the profile, and therefore the actual gamma of the profile 
will be */
+               /* applied at that stage of the process. */
+               if (gamma_guess > 1.1)
+                       gamma_guess = 2.2;
+               else
+                       gamma_guess = 1.0;
+       }
+
        for(n=0;n<256;n++)
        {
                nd = ((gdouble) n) * (1.0/255.0);
-               res = (gint) (pow(nd, linear_guess ? 1.0 : 2.2) * 65535.0);
+               res = (gint) (pow(nd, 2.2) * 65535.0);
                _CLAMP65535(res);
                gammatable[n] = res;
        }


_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit

Reply via email to