2
* * Copyright (C) 2006-2011 Anders Brander <anders@brander.dk>,
3
* * Anders Kvist <akv@lnxbx.dk> and Klaus Post <klauspost@gmail.com>
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
/* Color space tmpl version 1 */
22
#include <math.h> /* pow() */
23
#include <rawstudio.h>
27
#define RS_TYPE_SRGB (rs_srgb_type)
28
#define RS_SRGB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RS_TYPE_SRGB, RSSrgb))
29
#define RS_SRGB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RS_TYPE_SRGB, RSSrgbClass))
30
#define RS_IS_SRGB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RS_TYPE_SRGB))
31
#define RS_SRGB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RS_TYPE_SRGB, RSSrgbClass))
38
RSColorSpaceClass parent_class;
40
RSIccProfile *icc_profile;
41
RSIccProfile *icc_profile_linear;
44
RS_DEFINE_COLOR_SPACE(rs_srgb, RSSrgb)
46
static const RSIccProfile *get_icc_profile(const RSColorSpace *color_space, gboolean linear_profile);
47
static const RS1dFunction *get_gamma_function(const RSColorSpace *color_space);
50
rs_plugin_load(RSPlugin *plugin)
52
rs_srgb_get_type(G_TYPE_MODULE(plugin));
56
rs_srgb_class_init(RSSrgbClass *klass)
58
RSColorSpaceClass *colorclass = RS_COLOR_SPACE_CLASS(klass);
60
colorclass->name = "sRGB";
61
colorclass->description = "";
63
colorclass->get_icc_profile = get_icc_profile;
64
colorclass->get_gamma_function = get_gamma_function;
66
klass->icc_profile = rs_icc_profile_new_from_file(PACKAGE_DATA_DIR G_DIR_SEPARATOR_S PACKAGE G_DIR_SEPARATOR_S "profiles" G_DIR_SEPARATOR_S "sRGB.icc");
67
klass->icc_profile_linear = rs_icc_profile_new_from_file(PACKAGE_DATA_DIR G_DIR_SEPARATOR_S PACKAGE G_DIR_SEPARATOR_S "profiles" G_DIR_SEPARATOR_S "sRGB-linear.icc");
71
rs_srgb_init(RSSrgb *srgb)
73
/* Source: http://brucelindbloom.com/Eqn_RGB_XYZ_Matrix.html */
74
const static RS_MATRIX3 to_pcs = {{
75
{ 0.4360747, 0.3850649, 0.1430804 },
76
{ 0.2225045, 0.7168786, 0.0606169 },
77
{ 0.0139322, 0.0971045, 0.7141733 },
80
rs_color_space_set_matrix_to_pcs(RS_COLOR_SPACE(srgb), &to_pcs);
83
static const RSIccProfile *
84
get_icc_profile(const RSColorSpace *color_space, gboolean linear_profile)
86
RSSrgb *srgb = RS_SRGB(color_space);
89
return RS_SRGB_GET_CLASS(srgb)->icc_profile_linear;
91
return RS_SRGB_GET_CLASS(srgb)->icc_profile;
96
static gdouble evaluate(const RS1dFunction *func, const gdouble x);
97
static gdouble evaluate_inverse(const RS1dFunction *func, const gdouble y);
99
#define RS_TYPE_SRGB_GAMMA rs_srgb_gamma_get_type()
100
#define RS_SRGB_GAMMA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RS_TYPE_SRGB_GAMMA, RSSrgbGamma))
101
#define RS_SRGB_GAMMA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RS_TYPE_SRGB_GAMMA, RSSrgbGammaClass))
102
#define RS_IS_SRGB_GAMMA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RS_TYPE_SRGB_GAMMA))
109
RS1dFunctionClass parent_class;
112
GType rs_srgb_gamma_get_type(void);
114
RS1dFunction *rs_srgb_gamma_new(void);
116
G_DEFINE_TYPE (RSSrgbGamma, rs_srgb_gamma, RS_TYPE_1D_FUNCTION)
119
rs_srgb_gamma_class_init(RSSrgbGammaClass *klass)
121
RS1dFunctionClass *fclass = RS_1D_FUNCTION_CLASS(klass);
123
fclass->evaluate = evaluate;
124
fclass->evaluate_inverse = evaluate_inverse;
128
rs_srgb_gamma_init(RSSrgbGamma *gamma)
133
rs_srgb_gamma_new(void)
135
return RS_1D_FUNCTION(g_object_new(RS_TYPE_SRGB_GAMMA, NULL));
138
static const RS1dFunction *
139
get_gamma_function(const RSColorSpace *color_space)
141
static GStaticMutex lock = G_STATIC_MUTEX_INIT;
142
static RS1dFunction *func = NULL;
144
g_static_mutex_lock(&lock);
146
func = rs_srgb_gamma_new();
147
g_static_mutex_unlock(&lock);
153
evaluate(const RS1dFunction *func, const gdouble x)
155
const gdouble junction = 0.0031308;
160
return 1.055 * pow(x, 1.0/2.4) - 0.055;
164
evaluate_inverse(const RS1dFunction *func, const gdouble y)
166
const gdouble junction = 0.04045;
171
return pow((y+0.055)/1.055, 2.4);