Author: abrander Date: 2010-04-04 15:54:54 +0200 (Sun, 04 Apr 2010) New Revision: 3328
Added: attic/rs-cms.c Removed: trunk/src/rs-cms.c Log: Moved old cms code to attic. Copied: attic/rs-cms.c (from rev 3327, trunk/src/rs-cms.c) =================================================================== --- attic/rs-cms.c (rev 0) +++ attic/rs-cms.c 2010-04-04 13:54:54 UTC (rev 3328) @@ -0,0 +1,412 @@ +/* + * * Copyright (C) 2006-2010 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 <glib/gstdio.h> +#include <config.h> +#include "application.h" +#include "conf_interface.h" +#include "rs-cms.h" + +struct _RS_CMS { + gboolean enabled; + gint intent; + void *genericLoadProfile; + void *genericRGBProfile; + void *transforms[TRANSFORMS]; + void *profiles[CMS_PROFILES]; + gchar *profile_filenames[CMS_PROFILES]; +}; + +/* LCMS is not guaranteed to be thread-safe, we have to do this for now :( */ +GStaticMutex cms_spinlock = G_STATIC_MUTEX_INIT; +#define CMS_LOCK() g_static_mutex_lock(&cms_spinlock) +#define CMS_UNLOCK() g_static_mutex_unlock(&cms_spinlock) + +static gushort gammatable22[65536]; +static cmsHPROFILE genericLoadProfile = NULL; +static cmsHPROFILE genericRGBProfile = NULL; + +static void make_gammatable16(gushort *table, gdouble gamma); +static guchar *cms_pack_rgb_b(void *info, register WORD wOut[], register LPBYTE output); +static guchar *cms_pack_rgb_w(void *info, register WORD wOut[], register LPBYTE output); +static guchar *cms_unroll_rgb_w(void *info, register WORD wIn[], register LPBYTE accum); +static guchar *cms_unroll_rgb_w_gammatable22(void *info, register WORD wIn[], register LPBYTE accum); + +void +rs_cms_enable(RS_CMS *cms, gboolean enable) +{ + cms->enabled = enable; + rs_cms_prepare_transforms(cms); +} + +gboolean +rs_cms_is_profile_valid(const gchar *path, const CMS_PROFILE profile) +{ + gboolean ret = FALSE; + cmsHPROFILE lcms_profile; + + if (path) + { + CMS_LOCK(); + lcms_profile = cmsOpenProfileFromFile(path, "r"); + if (lcms_profile) + { + if (cmsGetColorSpace(lcms_profile) == 0x52474220) /* we only support RGB-profiles */ + { + /* Perceptual is the fall-back method of LittleCMS */ + if (profile == CMS_PROFILE_INPUT) + ret = cmsIsIntentSupported(lcms_profile, INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT); + else + ret = cmsIsIntentSupported(lcms_profile, INTENT_PERCEPTUAL, LCMS_USED_AS_OUTPUT); + } + cmsCloseProfile(lcms_profile); + } + CMS_UNLOCK(); + } + return(ret); +} + +void +rs_cms_set_profile(RS_CMS *cms, CMS_PROFILE profile, const gchar *filename) +{ + if (profile > (CMS_PROFILES-1)) return; + + CMS_LOCK(); + + /* free old filename */ + if (cms->profile_filenames[profile]) + g_free(cms->profile_filenames[profile]); + cms->profile_filenames[profile] = NULL; + + /* free old profile */ + if (cms->profiles[profile]) + cmsCloseProfile(cms->profiles[profile]); + cms->profiles[profile] = NULL; + + /* try to load new profile */ + if (filename) + cms->profiles[profile] = cmsOpenProfileFromFile(filename, "r"); + + /* if we could load it, save the filename */ + if (cms->profiles[profile]) + cms->profile_filenames[profile] = g_strdup(filename); + + CMS_UNLOCK(); + + /* update transforms */ + rs_cms_prepare_transforms(cms); + return; +} + +void +rs_cms_set_intent(RS_CMS *cms, gint intent) +{ + cms->intent = intent; + rs_cms_prepare_transforms(cms); + return; +} + +gint +rs_cms_get_intent(RS_CMS *cms) +{ + return(cms->intent); +} + +void * +rs_cms_get_transform(RS_CMS *cms, CMS_TRANSFORM transform) +{ + if (!cms->enabled) return NULL; + if (transform > (TRANSFORMS-1)) return(NULL); + return(cms->transforms[transform]); +} + +static gdouble +rs_cms_guess_gamma(void *transform) +{ + gushort buffer[27]; + gint n; + gint lin = 0; + gint g045 = 0; + gdouble gamma = 1.0; + + gushort table_lin[] = { + 6553, 6553, 6553, + 13107, 13107, 13107, + 19661, 19661, 19661, + 26214, 26214, 26214, + 32768, 32768, 32768, + 39321, 39321, 39321, + 45875, 45875, 45875, + 52428, 52428, 52428, + 58981, 58981, 58981 + }; + const gushort table_g045[] = { + 392, 392, 392, + 1833, 1833, 1833, + 4514, 4514, 4514, + 8554, 8554, 8554, + 14045, 14045, 14045, + 21061, 21061, 21061, + 29665, 29665, 29665, + 39913, 39913, 39913, + 51855, 51855, 51855 + }; + CMS_LOCK(); + cmsDoTransform(transform, table_lin, buffer, 9); + CMS_UNLOCK(); + for (n=0;n<9;n++) + { + lin += abs(buffer[n*3]-table_lin[n*3]); + lin += abs(buffer[n*3+1]-table_lin[n*3+1]); + lin += abs(buffer[n*3+2]-table_lin[n*3+2]); + g045 += abs(buffer[n*3]-table_g045[n*3]); + g045 += abs(buffer[n*3+1]-table_g045[n*3+1]); + g045 += abs(buffer[n*3+2]-table_g045[n*3+2]); + } + if (g045 < lin) + gamma = 2.2; + + return(gamma); +} + +void +rs_cms_prepare_transforms(RS_CMS *cms) +{ + gfloat gamma; + cmsHPROFILE in, di, ex; + cmsHTRANSFORM testtransform; + + if (cms->enabled) + { + if (cms->profiles[CMS_PROFILE_INPUT] && cmsIsIntentSupported(cms->profiles[CMS_PROFILE_INPUT], cms->intent, LCMS_USED_AS_INPUT)) + in = cms->profiles[CMS_PROFILE_INPUT]; + else + in = genericLoadProfile; + + if (cms->profiles[CMS_PROFILE_DISPLAY] && cmsIsIntentSupported(cms->profiles[CMS_PROFILE_DISPLAY], cms->intent, LCMS_USED_AS_OUTPUT)) + di = cms->profiles[CMS_PROFILE_DISPLAY]; + else + di = genericRGBProfile; + + if (cms->profiles[CMS_PROFILE_EXPORT] && cmsIsIntentSupported(cms->profiles[CMS_PROFILE_EXPORT], cms->intent, LCMS_USED_AS_OUTPUT)) + ex = cms->profiles[CMS_PROFILE_EXPORT]; + else + ex = genericRGBProfile; + + CMS_LOCK(); + if (cms->transforms[TRANSFORM_DISPLAY]) + cmsDeleteTransform(cms->transforms[TRANSFORM_DISPLAY]); + cms->transforms[TRANSFORM_DISPLAY] = cmsCreateTransform(in, TYPE_RGB_16, + di, TYPE_RGB_8, cms->intent, 0); + + if (cms->transforms[TRANSFORM_EXPORT]) + cmsDeleteTransform(cms->transforms[TRANSFORM_EXPORT]); + cms->transforms[TRANSFORM_EXPORT] = cmsCreateTransform(in, TYPE_RGB_16, + ex, TYPE_RGB_8, cms->intent, 0); + + if (cms->transforms[TRANSFORM_EXPORT16]) + cmsDeleteTransform(cms->transforms[TRANSFORM_EXPORT16]); + cms->transforms[TRANSFORM_EXPORT16] = cmsCreateTransform(in, TYPE_RGB_16, + ex, TYPE_RGB_16, cms->intent, 0); + + if (cms->transforms[TRANSFORM_SRGB]) + cmsDeleteTransform(cms->transforms[TRANSFORM_SRGB]); + cms->transforms[TRANSFORM_SRGB] = cmsCreateTransform(in, TYPE_RGB_16, + genericRGBProfile, TYPE_RGB_8, cms->intent, 0); + + testtransform = cmsCreateTransform(in, TYPE_RGB_16, + genericLoadProfile, TYPE_RGB_16, cms->intent, 0); + + cmsSetUserFormatters(testtransform, TYPE_RGB_16, cms_unroll_rgb_w, TYPE_RGB_16, cms_pack_rgb_w); + CMS_UNLOCK(); + gamma = rs_cms_guess_gamma(testtransform); + CMS_LOCK(); + cmsDeleteTransform(testtransform); + if (gamma != 1.0) + { + cmsSetUserFormatters(cms->transforms[TRANSFORM_DISPLAY], TYPE_RGB_16, cms_unroll_rgb_w_gammatable22, TYPE_RGB_8, cms_pack_rgb_b); + cmsSetUserFormatters(cms->transforms[TRANSFORM_EXPORT], TYPE_RGB_16, cms_unroll_rgb_w_gammatable22, TYPE_RGB_8, cms_pack_rgb_b); + cmsSetUserFormatters(cms->transforms[TRANSFORM_EXPORT16], TYPE_RGB_16, cms_unroll_rgb_w_gammatable22, TYPE_RGB_8, cms_pack_rgb_w); + cmsSetUserFormatters(cms->transforms[TRANSFORM_SRGB], TYPE_RGB_16, cms_unroll_rgb_w_gammatable22, TYPE_RGB_8, cms_pack_rgb_b); + } + else + { + cmsSetUserFormatters(cms->transforms[TRANSFORM_DISPLAY], TYPE_RGB_16, cms_unroll_rgb_w, TYPE_RGB_8, cms_pack_rgb_b); + cmsSetUserFormatters(cms->transforms[TRANSFORM_EXPORT], TYPE_RGB_16, cms_unroll_rgb_w, TYPE_RGB_8, cms_pack_rgb_b); + cmsSetUserFormatters(cms->transforms[TRANSFORM_EXPORT16], TYPE_RGB_16, cms_unroll_rgb_w, TYPE_RGB_8, cms_pack_rgb_w); + cmsSetUserFormatters(cms->transforms[TRANSFORM_SRGB], TYPE_RGB_16, cms_unroll_rgb_w, TYPE_RGB_8, cms_pack_rgb_b); + } + CMS_UNLOCK(); + } + return; +} + +void +rs_cms_do_transform(gpointer transform, gpointer input, gpointer output, guint size) +{ + if (transform && input && output && size) + cmsDoTransform((cmsHTRANSFORM) transform, input, output, size); +} + +RS_CMS * +rs_cms_init() +{ + RS_CMS *cms = g_new0(RS_CMS, 1); + gint n; + gchar *filename; + cmsCIExyY D65; + LPGAMMATABLE gamma[3]; + cmsCIExyYTRIPLE genericLoadPrimaries = { /* sRGB primaries */ + {0.64, 0.33, 0.212656}, + {0.115, 0.826, 0.724938}, + {0.157, 0.018, 0.016875}}; + + CMS_LOCK(); + cmsErrorAction(LCMS_ERROR_IGNORE); + cmsWhitePointFromTemp(6504, &D65); + gamma[0] = gamma[1] = gamma[2] = cmsBuildGamma(2,1.0); + + /* set up builtin profiles */ + if (!genericRGBProfile) + genericRGBProfile = cmsCreate_sRGBProfile(); + if (!genericLoadProfile) + genericLoadProfile = cmsCreateRGBProfile(&D65, &genericLoadPrimaries, gamma); + CMS_UNLOCK(); + + /* initialize arrays */ + for (n=0;n<TRANSFORMS;n++) + cms->transforms[n] = NULL; + for (n=0;n<CMS_PROFILES;n++) + { + cms->profiles[n] = NULL; + cms->profile_filenames[n] = NULL; + } + + filename = rs_conf_get_cms_profile(CMS_PROFILE_INPUT); + if (filename) + { + rs_cms_set_profile(cms, CMS_PROFILE_INPUT, filename); + g_free(filename); + } + + filename = rs_conf_get_cms_profile(CMS_PROFILE_DISPLAY); + if (filename) + { + rs_cms_set_profile(cms, CMS_PROFILE_DISPLAY, filename); + g_free(filename); + } + + filename = rs_conf_get_cms_profile(CMS_PROFILE_EXPORT); + if (filename) + { + rs_cms_set_profile(cms, CMS_PROFILE_EXPORT, filename); + g_free(filename); + } + + rs_cms_set_intent(cms, INTENT_PERCEPTUAL); /* default intent */ + rs_conf_get_cms_intent(CONF_CMS_INTENT, &cms->intent); + + cms->enabled = FALSE; + rs_conf_get_boolean(CONF_CMS_ENABLED, &cms->enabled); + rs_cms_prepare_transforms(cms); + make_gammatable16(gammatable22, 2.2); + return(cms); +} + +static void +make_gammatable16(gushort *table, gdouble gamma) +{ + gint n; + const gdouble gammavalue = (1.0/gamma); + gdouble nd; + gint res; + + for (n=0;n<0x10000;n++) + { + nd = ((gdouble) n) / 65535.0; + nd = pow(nd, gammavalue); + res = (gint) (nd*65535.0); + _CLAMP65535(res); + table[n] = res; + } + return; +} + +static guchar * +cms_pack_rgb_b(void *info, register WORD wOut[], register LPBYTE output) +{ + *output++ = RGB_16_TO_8(wOut[0]); + *output++ = RGB_16_TO_8(wOut[1]); + *output++ = RGB_16_TO_8(wOut[2]); + return(output); +} + +static guchar * +cms_pack_rgb_w(void *info, register WORD wOut[], register LPBYTE output) +{ + *(LPWORD) output = wOut[0]; output+= 2; + *(LPWORD) output = wOut[1]; output+= 2; + *(LPWORD) output = wOut[2]; output+= 2; + return(output); +} + +static guchar * +cms_unroll_rgb_w(void *info, register WORD wIn[], register LPBYTE accum) +{ + wIn[0] = *(LPWORD) accum; accum+= 2; + wIn[1] = *(LPWORD) accum; accum+= 2; + wIn[2] = *(LPWORD) accum; accum+= 2; + return(accum); +} + +static guchar * +cms_unroll_rgb_w_gammatable22(void *info, register WORD wIn[], register LPBYTE accum) +{ + wIn[0] = gammatable22[*(LPWORD) accum]; accum+= 2; + wIn[1] = gammatable22[*(LPWORD) accum]; accum+= 2; + wIn[2] = gammatable22[*(LPWORD) accum]; accum+= 2; + return(accum); +} + +gboolean +cms_get_profile_info_from_file(const gchar *filename, gchar **name, gchar **info, gchar **description) +{ + gboolean ret = FALSE; + cmsHPROFILE profile; + + g_assert(filename); + + CMS_LOCK(); + if ((profile = cmsOpenProfileFromFile(filename, "r"))) + { + if (name) + *name = g_strdup(cmsTakeProductName(profile)); + + if (info) + *info = g_strdup(cmsTakeProductInfo(profile)); + + if (description) + *description = g_strdup(cmsTakeProductDesc(profile)); + + ret = TRUE; + } + CMS_UNLOCK(); + + return ret; +} Deleted: trunk/src/rs-cms.c =================================================================== --- trunk/src/rs-cms.c 2010-04-03 06:09:06 UTC (rev 3327) +++ trunk/src/rs-cms.c 2010-04-04 13:54:54 UTC (rev 3328) @@ -1,412 +0,0 @@ -/* - * * Copyright (C) 2006-2010 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 <glib/gstdio.h> -#include <config.h> -#include "application.h" -#include "conf_interface.h" -#include "rs-cms.h" - -struct _RS_CMS { - gboolean enabled; - gint intent; - void *genericLoadProfile; - void *genericRGBProfile; - void *transforms[TRANSFORMS]; - void *profiles[CMS_PROFILES]; - gchar *profile_filenames[CMS_PROFILES]; -}; - -/* LCMS is not guaranteed to be thread-safe, we have to do this for now :( */ -GStaticMutex cms_spinlock = G_STATIC_MUTEX_INIT; -#define CMS_LOCK() g_static_mutex_lock(&cms_spinlock) -#define CMS_UNLOCK() g_static_mutex_unlock(&cms_spinlock) - -static gushort gammatable22[65536]; -static cmsHPROFILE genericLoadProfile = NULL; -static cmsHPROFILE genericRGBProfile = NULL; - -static void make_gammatable16(gushort *table, gdouble gamma); -static guchar *cms_pack_rgb_b(void *info, register WORD wOut[], register LPBYTE output); -static guchar *cms_pack_rgb_w(void *info, register WORD wOut[], register LPBYTE output); -static guchar *cms_unroll_rgb_w(void *info, register WORD wIn[], register LPBYTE accum); -static guchar *cms_unroll_rgb_w_gammatable22(void *info, register WORD wIn[], register LPBYTE accum); - -void -rs_cms_enable(RS_CMS *cms, gboolean enable) -{ - cms->enabled = enable; - rs_cms_prepare_transforms(cms); -} - -gboolean -rs_cms_is_profile_valid(const gchar *path, const CMS_PROFILE profile) -{ - gboolean ret = FALSE; - cmsHPROFILE lcms_profile; - - if (path) - { - CMS_LOCK(); - lcms_profile = cmsOpenProfileFromFile(path, "r"); - if (lcms_profile) - { - if (cmsGetColorSpace(lcms_profile) == 0x52474220) /* we only support RGB-profiles */ - { - /* Perceptual is the fall-back method of LittleCMS */ - if (profile == CMS_PROFILE_INPUT) - ret = cmsIsIntentSupported(lcms_profile, INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT); - else - ret = cmsIsIntentSupported(lcms_profile, INTENT_PERCEPTUAL, LCMS_USED_AS_OUTPUT); - } - cmsCloseProfile(lcms_profile); - } - CMS_UNLOCK(); - } - return(ret); -} - -void -rs_cms_set_profile(RS_CMS *cms, CMS_PROFILE profile, const gchar *filename) -{ - if (profile > (CMS_PROFILES-1)) return; - - CMS_LOCK(); - - /* free old filename */ - if (cms->profile_filenames[profile]) - g_free(cms->profile_filenames[profile]); - cms->profile_filenames[profile] = NULL; - - /* free old profile */ - if (cms->profiles[profile]) - cmsCloseProfile(cms->profiles[profile]); - cms->profiles[profile] = NULL; - - /* try to load new profile */ - if (filename) - cms->profiles[profile] = cmsOpenProfileFromFile(filename, "r"); - - /* if we could load it, save the filename */ - if (cms->profiles[profile]) - cms->profile_filenames[profile] = g_strdup(filename); - - CMS_UNLOCK(); - - /* update transforms */ - rs_cms_prepare_transforms(cms); - return; -} - -void -rs_cms_set_intent(RS_CMS *cms, gint intent) -{ - cms->intent = intent; - rs_cms_prepare_transforms(cms); - return; -} - -gint -rs_cms_get_intent(RS_CMS *cms) -{ - return(cms->intent); -} - -void * -rs_cms_get_transform(RS_CMS *cms, CMS_TRANSFORM transform) -{ - if (!cms->enabled) return NULL; - if (transform > (TRANSFORMS-1)) return(NULL); - return(cms->transforms[transform]); -} - -static gdouble -rs_cms_guess_gamma(void *transform) -{ - gushort buffer[27]; - gint n; - gint lin = 0; - gint g045 = 0; - gdouble gamma = 1.0; - - gushort table_lin[] = { - 6553, 6553, 6553, - 13107, 13107, 13107, - 19661, 19661, 19661, - 26214, 26214, 26214, - 32768, 32768, 32768, - 39321, 39321, 39321, - 45875, 45875, 45875, - 52428, 52428, 52428, - 58981, 58981, 58981 - }; - const gushort table_g045[] = { - 392, 392, 392, - 1833, 1833, 1833, - 4514, 4514, 4514, - 8554, 8554, 8554, - 14045, 14045, 14045, - 21061, 21061, 21061, - 29665, 29665, 29665, - 39913, 39913, 39913, - 51855, 51855, 51855 - }; - CMS_LOCK(); - cmsDoTransform(transform, table_lin, buffer, 9); - CMS_UNLOCK(); - for (n=0;n<9;n++) - { - lin += abs(buffer[n*3]-table_lin[n*3]); - lin += abs(buffer[n*3+1]-table_lin[n*3+1]); - lin += abs(buffer[n*3+2]-table_lin[n*3+2]); - g045 += abs(buffer[n*3]-table_g045[n*3]); - g045 += abs(buffer[n*3+1]-table_g045[n*3+1]); - g045 += abs(buffer[n*3+2]-table_g045[n*3+2]); - } - if (g045 < lin) - gamma = 2.2; - - return(gamma); -} - -void -rs_cms_prepare_transforms(RS_CMS *cms) -{ - gfloat gamma; - cmsHPROFILE in, di, ex; - cmsHTRANSFORM testtransform; - - if (cms->enabled) - { - if (cms->profiles[CMS_PROFILE_INPUT] && cmsIsIntentSupported(cms->profiles[CMS_PROFILE_INPUT], cms->intent, LCMS_USED_AS_INPUT)) - in = cms->profiles[CMS_PROFILE_INPUT]; - else - in = genericLoadProfile; - - if (cms->profiles[CMS_PROFILE_DISPLAY] && cmsIsIntentSupported(cms->profiles[CMS_PROFILE_DISPLAY], cms->intent, LCMS_USED_AS_OUTPUT)) - di = cms->profiles[CMS_PROFILE_DISPLAY]; - else - di = genericRGBProfile; - - if (cms->profiles[CMS_PROFILE_EXPORT] && cmsIsIntentSupported(cms->profiles[CMS_PROFILE_EXPORT], cms->intent, LCMS_USED_AS_OUTPUT)) - ex = cms->profiles[CMS_PROFILE_EXPORT]; - else - ex = genericRGBProfile; - - CMS_LOCK(); - if (cms->transforms[TRANSFORM_DISPLAY]) - cmsDeleteTransform(cms->transforms[TRANSFORM_DISPLAY]); - cms->transforms[TRANSFORM_DISPLAY] = cmsCreateTransform(in, TYPE_RGB_16, - di, TYPE_RGB_8, cms->intent, 0); - - if (cms->transforms[TRANSFORM_EXPORT]) - cmsDeleteTransform(cms->transforms[TRANSFORM_EXPORT]); - cms->transforms[TRANSFORM_EXPORT] = cmsCreateTransform(in, TYPE_RGB_16, - ex, TYPE_RGB_8, cms->intent, 0); - - if (cms->transforms[TRANSFORM_EXPORT16]) - cmsDeleteTransform(cms->transforms[TRANSFORM_EXPORT16]); - cms->transforms[TRANSFORM_EXPORT16] = cmsCreateTransform(in, TYPE_RGB_16, - ex, TYPE_RGB_16, cms->intent, 0); - - if (cms->transforms[TRANSFORM_SRGB]) - cmsDeleteTransform(cms->transforms[TRANSFORM_SRGB]); - cms->transforms[TRANSFORM_SRGB] = cmsCreateTransform(in, TYPE_RGB_16, - genericRGBProfile, TYPE_RGB_8, cms->intent, 0); - - testtransform = cmsCreateTransform(in, TYPE_RGB_16, - genericLoadProfile, TYPE_RGB_16, cms->intent, 0); - - cmsSetUserFormatters(testtransform, TYPE_RGB_16, cms_unroll_rgb_w, TYPE_RGB_16, cms_pack_rgb_w); - CMS_UNLOCK(); - gamma = rs_cms_guess_gamma(testtransform); - CMS_LOCK(); - cmsDeleteTransform(testtransform); - if (gamma != 1.0) - { - cmsSetUserFormatters(cms->transforms[TRANSFORM_DISPLAY], TYPE_RGB_16, cms_unroll_rgb_w_gammatable22, TYPE_RGB_8, cms_pack_rgb_b); - cmsSetUserFormatters(cms->transforms[TRANSFORM_EXPORT], TYPE_RGB_16, cms_unroll_rgb_w_gammatable22, TYPE_RGB_8, cms_pack_rgb_b); - cmsSetUserFormatters(cms->transforms[TRANSFORM_EXPORT16], TYPE_RGB_16, cms_unroll_rgb_w_gammatable22, TYPE_RGB_8, cms_pack_rgb_w); - cmsSetUserFormatters(cms->transforms[TRANSFORM_SRGB], TYPE_RGB_16, cms_unroll_rgb_w_gammatable22, TYPE_RGB_8, cms_pack_rgb_b); - } - else - { - cmsSetUserFormatters(cms->transforms[TRANSFORM_DISPLAY], TYPE_RGB_16, cms_unroll_rgb_w, TYPE_RGB_8, cms_pack_rgb_b); - cmsSetUserFormatters(cms->transforms[TRANSFORM_EXPORT], TYPE_RGB_16, cms_unroll_rgb_w, TYPE_RGB_8, cms_pack_rgb_b); - cmsSetUserFormatters(cms->transforms[TRANSFORM_EXPORT16], TYPE_RGB_16, cms_unroll_rgb_w, TYPE_RGB_8, cms_pack_rgb_w); - cmsSetUserFormatters(cms->transforms[TRANSFORM_SRGB], TYPE_RGB_16, cms_unroll_rgb_w, TYPE_RGB_8, cms_pack_rgb_b); - } - CMS_UNLOCK(); - } - return; -} - -void -rs_cms_do_transform(gpointer transform, gpointer input, gpointer output, guint size) -{ - if (transform && input && output && size) - cmsDoTransform((cmsHTRANSFORM) transform, input, output, size); -} - -RS_CMS * -rs_cms_init() -{ - RS_CMS *cms = g_new0(RS_CMS, 1); - gint n; - gchar *filename; - cmsCIExyY D65; - LPGAMMATABLE gamma[3]; - cmsCIExyYTRIPLE genericLoadPrimaries = { /* sRGB primaries */ - {0.64, 0.33, 0.212656}, - {0.115, 0.826, 0.724938}, - {0.157, 0.018, 0.016875}}; - - CMS_LOCK(); - cmsErrorAction(LCMS_ERROR_IGNORE); - cmsWhitePointFromTemp(6504, &D65); - gamma[0] = gamma[1] = gamma[2] = cmsBuildGamma(2,1.0); - - /* set up builtin profiles */ - if (!genericRGBProfile) - genericRGBProfile = cmsCreate_sRGBProfile(); - if (!genericLoadProfile) - genericLoadProfile = cmsCreateRGBProfile(&D65, &genericLoadPrimaries, gamma); - CMS_UNLOCK(); - - /* initialize arrays */ - for (n=0;n<TRANSFORMS;n++) - cms->transforms[n] = NULL; - for (n=0;n<CMS_PROFILES;n++) - { - cms->profiles[n] = NULL; - cms->profile_filenames[n] = NULL; - } - - filename = rs_conf_get_cms_profile(CMS_PROFILE_INPUT); - if (filename) - { - rs_cms_set_profile(cms, CMS_PROFILE_INPUT, filename); - g_free(filename); - } - - filename = rs_conf_get_cms_profile(CMS_PROFILE_DISPLAY); - if (filename) - { - rs_cms_set_profile(cms, CMS_PROFILE_DISPLAY, filename); - g_free(filename); - } - - filename = rs_conf_get_cms_profile(CMS_PROFILE_EXPORT); - if (filename) - { - rs_cms_set_profile(cms, CMS_PROFILE_EXPORT, filename); - g_free(filename); - } - - rs_cms_set_intent(cms, INTENT_PERCEPTUAL); /* default intent */ - rs_conf_get_cms_intent(CONF_CMS_INTENT, &cms->intent); - - cms->enabled = FALSE; - rs_conf_get_boolean(CONF_CMS_ENABLED, &cms->enabled); - rs_cms_prepare_transforms(cms); - make_gammatable16(gammatable22, 2.2); - return(cms); -} - -static void -make_gammatable16(gushort *table, gdouble gamma) -{ - gint n; - const gdouble gammavalue = (1.0/gamma); - gdouble nd; - gint res; - - for (n=0;n<0x10000;n++) - { - nd = ((gdouble) n) / 65535.0; - nd = pow(nd, gammavalue); - res = (gint) (nd*65535.0); - _CLAMP65535(res); - table[n] = res; - } - return; -} - -static guchar * -cms_pack_rgb_b(void *info, register WORD wOut[], register LPBYTE output) -{ - *output++ = RGB_16_TO_8(wOut[0]); - *output++ = RGB_16_TO_8(wOut[1]); - *output++ = RGB_16_TO_8(wOut[2]); - return(output); -} - -static guchar * -cms_pack_rgb_w(void *info, register WORD wOut[], register LPBYTE output) -{ - *(LPWORD) output = wOut[0]; output+= 2; - *(LPWORD) output = wOut[1]; output+= 2; - *(LPWORD) output = wOut[2]; output+= 2; - return(output); -} - -static guchar * -cms_unroll_rgb_w(void *info, register WORD wIn[], register LPBYTE accum) -{ - wIn[0] = *(LPWORD) accum; accum+= 2; - wIn[1] = *(LPWORD) accum; accum+= 2; - wIn[2] = *(LPWORD) accum; accum+= 2; - return(accum); -} - -static guchar * -cms_unroll_rgb_w_gammatable22(void *info, register WORD wIn[], register LPBYTE accum) -{ - wIn[0] = gammatable22[*(LPWORD) accum]; accum+= 2; - wIn[1] = gammatable22[*(LPWORD) accum]; accum+= 2; - wIn[2] = gammatable22[*(LPWORD) accum]; accum+= 2; - return(accum); -} - -gboolean -cms_get_profile_info_from_file(const gchar *filename, gchar **name, gchar **info, gchar **description) -{ - gboolean ret = FALSE; - cmsHPROFILE profile; - - g_assert(filename); - - CMS_LOCK(); - if ((profile = cmsOpenProfileFromFile(filename, "r"))) - { - if (name) - *name = g_strdup(cmsTakeProductName(profile)); - - if (info) - *info = g_strdup(cmsTakeProductInfo(profile)); - - if (description) - *description = g_strdup(cmsTakeProductDesc(profile)); - - ret = TRUE; - } - CMS_UNLOCK(); - - return ret; -} _______________________________________________ Rawstudio-commit mailing list [email protected] http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit
