Author: post
Date: 2009-11-23 22:18:48 +0100 (Mon, 23 Nov 2009)
New Revision: 2758
Modified:
trunk/plugins/dcp/dcp.c
Log:
DCP: Apply tone curve.
Modified: trunk/plugins/dcp/dcp.c
===================================================================
--- trunk/plugins/dcp/dcp.c 2009-11-22 16:43:32 UTC (rev 2757)
+++ trunk/plugins/dcp/dcp.c 2009-11-23 21:18:48 UTC (rev 2758)
@@ -65,8 +65,8 @@
gfloat temp1;
gfloat temp2;
- RSSpline *baseline_exposure;
- gfloat *baseline_exposure_lut;
+ RSSpline *tone_curve;
+ gfloat *tone_curve_lut;
gboolean has_color_matrix1;
gboolean has_color_matrix2;
@@ -1092,107 +1092,74 @@
gfloat r = *_r;
gfloat g = *_g;
gfloat b = *_b;
- gfloat rr;
- gfloat gg;
- gfloat bb;
+ gfloat rr;
+ gfloat gg;
+ gfloat bb;
- #define RGBTone(r, g, b, rr, gg, bb)\
- {\
- \
-/* DNG_ASSERT (r >= g && g >= b && r > b, "Logic Error
RGBTone");*/\
- \
- rr = tone_lut[_S(r)];\
- bb = tone_lut[_S(b)];\
- \
- gg = bb + ((rr - bb) * (g - b) / (r - b));\
- \
- }
+ #define RGBTone(lg, md, sm, LG, MD, SM)\
+ {\
+ LG = tone_lut[_S(lg)];\
+ SM = tone_lut[_S(sm)];\
+ \
+ MD = SM + ((LG - SM) * (md - sm) / (lg - sm));\
+ \
+ }
+ /* Tone curve is:
+ 1. Lookup smallest and largest of R,G,B
+ 2. Middle value is calculated as (CAPS is curve corrected)
+ MD = SM + ((LG - SM) * (md - sm) / (lg - sm))
+ 3. Store.
+ */
+ if (r >= g)
+ {
- if (r >= g)
- {
-
- if (g > b)
- {
-
- // Case 1: r >= g > b
-
- RGBTone (r, g, b, rr, gg, bb);
-
- }
-
- else if (b > r)
- {
-
- // Case 2: b > r >= g
-
- RGBTone (b, r, g, bb, rr, gg);
-
- }
-
- else if (b > g)
- {
-
- // Case 3: r >= b > g
-
- RGBTone (r, b, g, rr, bb, gg);
-
- }
-
- else
- {
-
- // Case 4: r >= g == b
-
-// DNG_ASSERT (r >= g && g == b, "Logic Error 2");
-
- rr = tone_lut[_S(r)];
- gg = tone_lut[_S(b)];
-// rr = table.Interpolate (r);
-// gg = table.Interpolate (g);
- bb = gg;
-
- }
-
- }
-
+ if (g > b)
+ {
+ // Case 1: r >= g > b; hue = 0-1
+ RGBTone (r, g, b, rr, gg, bb);
+ }
+ else if (b > r)
+ {
+ // Case 2: b > r >= g; hue = 4-5
+ RGBTone (b, r, g, bb, rr, gg);
+ }
+ else if (b > g)
+ {
+ // Case 3: r >= b > g; hue = 5-6
+ RGBTone (r, b, g, rr, bb, gg);
+ }
else
- {
+ {
+ // Case 4: r >= g == b; s = 0;
+ rr = tone_lut[_S(r)];
+ gg = tone_lut[_S(b)];
+ bb = gg;
+ }
+ }
+ else // g > r
+ {
+ if (r >= b)
+ {
+ // Case 5: g > r >= b; hue = 1-2
+ RGBTone (g, r, b, gg, rr, bb);
+ }
+ else if (b > g)
+ {
+ // Case 6: b > g > r; hue = 3-4
+ RGBTone (b, g, r, bb, gg, rr);
+ }
+ else
+ {
+ // Case 7: g >= b > r; hue = 2-3
+ RGBTone (g, b, r, gg, bb, rr);
+ }
+ }
- if (r >= b)
- {
+ #undef RGBTone
+ *_r = rr;
+ *_g = gg;
+ *_b = bb;
- // Case 5: g > r >= b
-
- RGBTone (g, r, b, gg, rr, bb);
-
- }
-
- else if (b > g)
- {
-
- // Case 6: b > g > r
-
- RGBTone (b, g, r, bb, gg, rr);
-
- }
-
- else
- {
-
- // Case 7: g >= b > r
-
- RGBTone (g, b, r, gg, bb, rr);
-
- }
-
- }
-
- #undef RGBTone
-
- *_r = rr;
- *_g = gg;
- *_b = bb;
-
}
#if defined (__SSE2__)
@@ -1225,6 +1192,7 @@
RS_IMAGE16 *image = t->tmp;
RSDcp *dcp = t->dcp;
gint x, y;
+ gint i;
__m128 h, s, v;
__m128i p1,p2;
__m128 p1f, p2f, p3f, p4f;
@@ -1232,6 +1200,7 @@
__m128i zero = _mm_load_si128((__m128i*)_15_bit_epi32);
int xfer[4] __attribute__ ((aligned (16)));
+ float xfer_ps[12] __attribute__ ((aligned (16)));
const gfloat exposure_comp = pow(2.0, dcp->exposure);
__m128 exp = _mm_set_ps(exposure_comp, exposure_comp, exposure_comp,
exposure_comp);
@@ -1370,13 +1339,29 @@
six_masked_lt = _mm_and_ps(six_ps, h_mask_lt);
h = _mm_sub_ps(h, six_masked_gt);
h = _mm_add_ps(h, six_masked_lt);
-
- /* s always slightly > 0 */
- s = _mm_max_ps(s, min_val);
+ /* s always slightly > 0 when converting to RGB */
+ s = _mm_max_ps(s, min_val);
+
HSVtoRGB_SSE(&h, &s, &v);
r = h; g = s; b = v;
+ /* Apply Tone Curve in RGB space*/
+ if (dcp->tone_curve_lut)
+ {
+ _mm_store_ps(&xfer_ps[0], r);
+ _mm_store_ps(&xfer_ps[4], g);
+ _mm_store_ps(&xfer_ps[8], b);
+
+ for( i = 0 ; i < 4 ; i++ )
+ rgb_tone(&xfer_ps[i], &xfer_ps[4+i],
&xfer_ps[8+i],dcp->tone_curve_lut);
+
+ r = _mm_load_ps(&xfer_ps[0]);
+ g = _mm_load_ps(&xfer_ps[4]);
+ b = _mm_load_ps(&xfer_ps[8]);
+ }
+
+ /* Convert to 16 bit */
__m128 rgb_mul = _mm_load_ps(_16_bit_ps);
r = _mm_mul_ps(r, rgb_mul);
g = _mm_mul_ps(g, rgb_mul);
@@ -1486,6 +1471,10 @@
/* Back to RGB */
HSVtoRGB(h, s, v, &r, &g, &b);
+ /* Apply tone curve */
+ if (dcp->tone_curve_lut)
+ rgb_tone(&r, &g, &b, dcp->tone_curve_lut);
+
/* Save as gushort */
pixel[R] = _S(r);
pixel[G] = _S(g);
@@ -1626,9 +1615,9 @@
dcp->temp2 = rs_dcp_file_get_illuminant2(dcp_file);
/* ProfileToneCurve */
- dcp->baseline_exposure = rs_dcp_file_get_tonecurve(dcp_file);
- if (dcp->baseline_exposure)
- dcp->baseline_exposure_lut =
rs_spline_sample(dcp->baseline_exposure, NULL, 65536);
+ dcp->tone_curve = rs_dcp_file_get_tonecurve(dcp_file);
+ if (dcp->tone_curve)
+ dcp->tone_curve_lut = rs_spline_sample(dcp->tone_curve, NULL,
65536);
/* FIXME: Free these at some point! */
/* ForwardMatrix */
_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit