# HG changeset patch
# User Edouard Gomez <[EMAIL PROTECTED]>
# Date 1187904914 -7200
# Node ID c08eac5446299e71a965adf68a0861aa1db56e4b
# Parent 46d39ed470f675b7426169ee931a3c88feafbf96
Use the curve as a luminance curve only
diff --git a/src/rs-color-transform.c b/src/rs-color-transform.c
--- a/src/rs-color-transform.c
+++ b/src/rs-color-transform.c
@@ -25,6 +25,13 @@ static void make_tables(RS_COLOR_TRANSFO
static void make_tables(RS_COLOR_TRANSFORM *rct);
static gboolean select_render(RS_COLOR_TRANSFORM *rct);
+#define LUM_PRECISION 15
+#define RLUMF ((gint)(0.212671f*(1<<LUM_PRECISION)))
+#define GLUMF ((gint)(0.715160f*(1<<LUM_PRECISION)))
+#define BLUMF ((gint)(0.072169f*(1<<LUM_PRECISION)))
+#define HALFF (1<<(LUM_PRECISION-1))
+#define LUM_FIXED(a) ((guint)((a)*(1<<LUM_PRECISION)))
+
/* Function pointers - initialized by arch binders */
COLOR_TRANSFORM(*transform_nocms8);
COLOR_TRANSFORM(*transform_cms8);
@@ -50,6 +57,7 @@ struct _RS_COLOR_TRANSFORM_PRIVATE {
gint nknots;
gfloat *knots;
gfloat curve_samples[65536];
+ guint luminance[65536];
void *transform;
};
@@ -308,8 +316,39 @@ make_tables(RS_COLOR_TRANSFORM *rct)
nd = ((gdouble) n) * rec65535;
nd = pow(nd, gammavalue);
- if (likely(rct->priv->curve_samples))
- nd = (gdouble) rct->priv->curve_samples[((gint)
(nd*65535.0f))];
+ if (likely(rct->priv->curve_samples)) {
+ n = (n>0) ? n : 1;
+
+ /* The idea is to use the curve to boost/dcrease
+ * luminance only.
+ * So we have to compute Y, map it to its new value
+ * and then compute a factor that would keep this
+ * new luminance if applied to the RGB triplet.
+ *
+ * Quite straight forward; let's do it quick...
+ * Y = a.R + b.G + c.B
+ *
+ * We map Y to Y' according to the curve:
+ * Y' = curve(Y)
+ *
+ * let's compute a real 'd' such that:
+ * Y' = d.Y
+ *
+ * Then we have
+ * Y' = d.(a.R + b.G + c.B)
+ * or written a bit differently:
+ * Y' = a.(d.R) + b.(d.G) + c.(d.B)
+ *
+ * So the RGB triplet we are looking for is (d.R, d.G,
d.B)
+ *
+ * The luminance LUT stores curve(Y)/Y as a fixed point
+ * value so that it becomes very easy to compute
d.(R,G,B)
+ * even on SIMD CPUs
+ *
+ * NB: luminance curve is applied in linear space before
+ * any gamma */
+ rct->priv->luminance[n] =
LUM_FIXED(rct->priv->curve_samples[n]*65535.f/(float)n);
+ }
nd = nd*contrast+postadd;
@@ -901,6 +940,8 @@ COLOR_TRANSFORM(transform_cms_c)
srcoffset = y * in_rowstride;
for(x=0 ; x<width ; x++)
{
+ guint Y;
+
rr = (in[srcoffset+R]*pre_muli[R])>>7;
gg = (in[srcoffset+G]*pre_muli[G])>>7;
bb = (in[srcoffset+B]*pre_muli[B])>>7;
@@ -915,6 +956,20 @@ COLOR_TRANSFORM(transform_cms_c)
+ gg*mati.coeff[2][1]
+ bb*mati.coeff[2][2])>>MATRIX_RESOLUTION;
_CLAMP65535_TRIPLET(r,g,b);
+
+ // Compute luminance
+ Y = (RLUMF*r + GLUMF*g + BLUMF*b +
HALFF)>>LUM_PRECISION;
+
+ // Find the factor to apply to the RGB triplet
+ Y = rct->priv->luminance[Y];
+
+ // Multiplythe RGB triplet using fixed point arithmetic
+ r = (r*Y)>>LUM_PRECISION;
+ g = (g*Y)>>LUM_PRECISION;
+ b = (b*Y)>>LUM_PRECISION;
+
+ _CLAMP65535_TRIPLET(r,g,b);
+
buffer[destoffset++] = rct->priv->table16[r];
buffer[destoffset++] = rct->priv->table16[g];
buffer[destoffset++] = rct->priv->table16[b];
@@ -945,6 +1000,8 @@ COLOR_TRANSFORM(transform_nocms_c)
srcoffset = y * in_rowstride;
for(x=0 ; x<width ; x++)
{
+ guint Y;
+
rr = (in[srcoffset+R]*pre_muli[R]+64)>>7;
gg = (in[srcoffset+G]*pre_muli[G]+64)>>7;
bb = (in[srcoffset+B]*pre_muli[B]+64)>>7;
@@ -959,6 +1016,20 @@ COLOR_TRANSFORM(transform_nocms_c)
+ gg*mati.coeff[2][1]
+ bb*mati.coeff[2][2])>>MATRIX_RESOLUTION;
_CLAMP65535_TRIPLET(r,g,b);
+
+ // Compute luminance
+ Y = (RLUMF*r + GLUMF*g + BLUMF*b +
HALFF)>>LUM_PRECISION;
+
+ // Find the factor to apply to the RGB triplet
+ Y = rct->priv->luminance[Y];
+
+ // Multiplythe RGB triplet using fixed point arithmetic
+ r = (r*Y)>>LUM_PRECISION;
+ g = (g*Y)>>LUM_PRECISION;
+ b = (b*Y)>>LUM_PRECISION;
+
+ _CLAMP65535_TRIPLET(r,g,b);
+
d[destoffset++] = rct->priv->table8[r];
d[destoffset++] = rct->priv->table8[g];
d[destoffset++] = rct->priv->table8[b];
_______________________________________________
Rawstudio-dev mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-dev