Author: post Date: 2011-02-20 00:39:49 +0100 (Sun, 20 Feb 2011) New Revision: 3823
Added: trunk/plugins/load-gdk/exiv2-colorspace.cpp trunk/plugins/load-gdk/exiv2-colorspace.h Modified: trunk/plugins/load-gdk/Makefile.am trunk/plugins/load-gdk/load-gdk.c Log: Add better ICC/Colorspace support when inputting non-raw images. Modified: trunk/plugins/load-gdk/Makefile.am =================================================================== --- trunk/plugins/load-gdk/Makefile.am 2011-02-19 19:58:21 UTC (rev 3822) +++ trunk/plugins/load-gdk/Makefile.am 2011-02-19 23:39:49 UTC (rev 3823) @@ -19,4 +19,4 @@ load_gdk_la_LIBADD = @PACKAGE_LIBS@ load_gdk_la_LDFLAGS = -module -avoid-version -load_gdk_la_SOURCES = load-gdk.c +load_gdk_la_SOURCES = load-gdk.c exiv2-colorspace.cpp Added: trunk/plugins/load-gdk/exiv2-colorspace.cpp =================================================================== --- trunk/plugins/load-gdk/exiv2-colorspace.cpp (rev 0) +++ trunk/plugins/load-gdk/exiv2-colorspace.cpp 2011-02-19 23:39:49 UTC (rev 3823) @@ -0,0 +1,154 @@ +/* + * * Copyright (C) 2006-2011 Anders Brander <[email protected]>, + * * Anders Kvist <[email protected]> and Klaus Post <[email protected]> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <gtk/gtk.h> +#include <iostream> +#include <iomanip> +#include <exiv2/image.hpp> +#include <exiv2/exif.hpp> +#include <exiv2/easyaccess.hpp> +#include <assert.h> +#include "exiv2-colorspace.h" +#include <math.h> +#include <png.h> + +#ifndef EXIV2_TEST_VERSION +# define EXIV2_TEST_VERSION(major,minor,patch) \ + ( EXIV2_VERSION >= EXIV2_MAKE_VERSION((major),(minor),(patch)) ) +#endif + +#if EXIV2_TEST_VERSION(0,17,0) +#include <exiv2/convert.hpp> +#endif + +extern "C" { + +/** INTERFACE **/ + +using namespace Exiv2; + +RSColorSpace* +exiv2_get_colorspace(const gchar *filename, gboolean *linear_guess) +{ +#ifdef PNG_iCCP_SUPPORTED + if (1) + { + *linear_guess = FALSE; + RSColorSpace* profile = NULL; + const gchar *icc_profile_title; + const gchar *icc_profile; + guint icc_profile_size; + png_structp png_ptr = png_create_read_struct( + PNG_LIBPNG_VER_STRING, + NULL, + NULL, + NULL); + FILE* fp = fopen(filename, "rb"); + if (fp) + { + png_byte sig[8]; + + if (fread(sig, 1, 8, fp) && 0 == fseek(fp,0,SEEK_SET) && png_check_sig(sig, 8)) + { + png_init_io(png_ptr, fp); + png_infop info_ptr = png_create_info_struct(png_ptr); + if (info_ptr) + { + png_read_info( png_ptr, info_ptr ); + + int compression_type; + /* Extract embedded ICC profile */ + if (info_ptr->valid & PNG_INFO_iCCP) + { + png_uint_32 retval = png_get_iCCP (png_ptr, info_ptr, + (png_charpp) &icc_profile_title, &compression_type, + (png_charpp) &icc_profile, (png_uint_32*) &icc_profile_size); + if (retval != 0) + { + 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; + } + } + png_destroy_read_struct (&png_ptr, &info_ptr, NULL); + } + fclose(fp); + } + if (profile) + return profile; + } +#endif + + try { + Image::AutoPtr img = ImageFactory::open(filename); + img->readMetadata(); + ExifData &exifData = img->exifData(); + *linear_guess = FALSE; + + if (exifData.empty() && !img->xmpData().empty()) + { + copyXmpToExif(img->xmpData(), exifData); + } + + /* Parse Exif Data */ + if (!exifData.empty()) + { + ExifData::const_iterator i; + i = exifData.findKey(ExifKey("Exif.Image.BitsPerSample")); + if (i != exifData.end()) + if (i->toLong() == 16) + *linear_guess = TRUE; + + i = exifData.findKey(ExifKey("Exif.Photo.ColorSpace")); + if (i != exifData.end()) + { + if (i->toLong() == 1) + return rs_color_space_new_singleton("RSSrgb"); + } + + /* Attempt to find ICC profile */ + i = exifData.findKey(ExifKey("Exif.Image.InterColorProfile")); + if (i != exifData.end()) + { + DataBuf buf(i->size()); + i->copy(buf.pData_, Exiv2::invalidByteOrder); + if (buf.pData_ && buf.size_) + { + RSIccProfile *icc = rs_icc_profile_new_from_memory((gchar*)buf.pData_, buf.size_, TRUE); + return rs_color_space_icc_new_from_icc(icc); + } + } + + i = exifData.findKey(ExifKey("Exif.Iop.InteroperabilityIndex")); + if (i != exifData.end()) + if (0 == i->toString().compare("R03")) + return rs_color_space_new_singleton("RSAdobeRGB"); + } + } catch (Exiv2::Error& e) { + g_debug("Exiv2 ColorSpace Loader:'%s", e.what()); + } + g_debug("Exiv2 ColorSpace Loader: Could not determine colorspace, assume sRGB."); + return rs_color_space_new_singleton("RSSrgb"); +} +/** END INTERFACE **/ +} // extern "C" Added: trunk/plugins/load-gdk/exiv2-colorspace.h =================================================================== --- trunk/plugins/load-gdk/exiv2-colorspace.h (rev 0) +++ trunk/plugins/load-gdk/exiv2-colorspace.h 2011-02-19 23:39:49 UTC (rev 3823) @@ -0,0 +1,44 @@ +/* + * * Copyright (C) 2006-2011 Anders Brander <[email protected]>, + * * Anders Kvist <[email protected]> and Klaus Post <[email protected]> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef exiv2_colorspace_h__ +#define exiv2_colorspace_h__ +#include <rawstudio.h> + +#ifdef _unix_ +G_BEGIN_DECLS +#endif + +#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */ +extern "C" { +#endif + +extern RSColorSpace* +exiv2_get_colorspace(const gchar *filename, gboolean *linear_guess); + + +#ifdef _unix_ +G_END_DECLS +#endif +#ifdef __cplusplus /* If this is a C++ compiler, end C linkage */ +} +#endif + + +#endif // exiv2_colorspace_h__ Modified: trunk/plugins/load-gdk/load-gdk.c =================================================================== --- trunk/plugins/load-gdk/load-gdk.c 2011-02-19 19:58:21 UTC (rev 3822) +++ trunk/plugins/load-gdk/load-gdk.c 2011-02-19 23:39:49 UTC (rev 3823) @@ -19,8 +19,8 @@ #include <rawstudio.h> #include <math.h> /* pow() */ +#include "exiv2-colorspace.h" -static gushort gammatable[256]; /** * Open an image using the GDK-engine @@ -30,6 +30,7 @@ static RSFilterResponse* load_gdk(const gchar *filename) { + gushort gammatable[256]; RS_IMAGE16 *image = NULL; GdkPixbuf *pixbuf; guchar *pixels; @@ -37,6 +38,19 @@ gint width, height; gint row,col, src, dest; gint alpha=0; + gint n; + gdouble nd, res; + gboolean linear_guess = FALSE; + + RSColorSpace *input_space = exiv2_get_colorspace(filename, &linear_guess); + 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); + _CLAMP65535(res); + gammatable[n] = res; + } + if ((pixbuf = gdk_pixbuf_new_from_file(filename, NULL))) { rowstride = gdk_pixbuf_get_rowstride(pixbuf); @@ -69,7 +83,6 @@ rs_filter_response_set_width(response, image->w); rs_filter_response_set_height(response, image->h); g_object_unref(image); - RSColorSpace *input_space = rs_color_space_new_singleton("RSSrgb"); rs_filter_param_set_object(RS_FILTER_PARAM(response), "embedded-colorspace", input_space); } return response; @@ -86,17 +99,6 @@ G_MODULE_EXPORT void rs_plugin_load(RSPlugin *plugin) { - gint n, res; - gdouble nd; - - for(n=0;n<256;n++) - { - nd = ((gdouble) n) / 255.0; - res = (gint) (pow(nd, GAMMA) * 65535.0); - _CLAMP65535(res); - gammatable[n] = res; - } - rs_filetype_register_loader(".jpg", "JPEG", load_gdk, 10, RS_LOADER_FLAGS_8BIT); rs_filetype_register_loader(".jpeg", "JPEG", load_gdk, 10, RS_LOADER_FLAGS_8BIT); rs_filetype_register_loader(".png", "JPEG", load_gdk, 10, RS_LOADER_FLAGS_8BIT); _______________________________________________ Rawstudio-commit mailing list [email protected] http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit
