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