summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--third_party/qcms/README.chromium6
-rw-r--r--third_party/qcms/google.patch688
-rw-r--r--third_party/qcms/src/iccread.c9
-rw-r--r--third_party/qcms/src/qcms.h7
-rw-r--r--third_party/qcms/src/qcmsint.h19
-rw-r--r--third_party/qcms/src/qcmstypes.h5
-rw-r--r--third_party/qcms/src/transform-sse1.c34
-rw-r--r--third_party/qcms/src/transform-sse2.c34
-rw-r--r--third_party/qcms/src/transform.c201
9 files changed, 906 insertions, 97 deletions
diff --git a/third_party/qcms/README.chromium b/third_party/qcms/README.chromium
index f073143..910adae 100644
--- a/third_party/qcms/README.chromium
+++ b/third_party/qcms/README.chromium
@@ -12,4 +12,8 @@ originally based on tinycms, re-written by Mozilla for better security and
performance. This copy is a source-drop from Mozilla on March 13, 2012.
Local Modifications:
-Some files only have license headers in the master branch. Added the same license headers to the versions brought down from the 'v4' branch.
+Some files only have license headers in the master branch.
+ - Added the same license headers to the versions brought down from the 'v4'
+ branch src URL qcms/tree/v4
+google.patch
+ - Add bgra output support. Apply with patch -p1 < google.patch
diff --git a/third_party/qcms/google.patch b/third_party/qcms/google.patch
new file mode 100644
index 0000000..84a1235
--- /dev/null
+++ b/third_party/qcms/google.patch
@@ -0,0 +1,688 @@
+diff --git a/src/iccread.c b/src/iccread.c
+index 36b7011..2454924 100644
+--- a/src/iccread.c
++++ b/src/iccread.c
+@@ -297,6 +297,11 @@ qcms_bool qcms_profile_is_bogus(qcms_profile *profile)
+ sum[1] = rY + gY + bY;
+ sum[2] = rZ + gZ + bZ;
+
++#if defined (_MSC_VER)
++#pragma warning(push)
++/* Disable double to float truncation warning 4305 */
++#pragma warning(disable:4305)
++#endif
+ // Build our target vector (see mozilla bug 460629)
+ target[0] = 0.96420;
+ target[1] = 1.00000;
+@@ -310,6 +315,10 @@ qcms_bool qcms_profile_is_bogus(qcms_profile *profile)
+ tolerance[1] = 0.02;
+ tolerance[2] = 0.04;
+
++#if defined (_MSC_VER)
++/* Restore warnings */
++#pragma warning(pop)
++#endif
+ // Compare with our tolerance
+ for (i = 0; i < 3; ++i) {
+ if (!(((sum[i] - tolerance[i]) <= target[i]) &&
+diff --git a/src/qcms.h b/src/qcms.h
+index 7d83623..1e3e125 100644
+--- a/src/qcms.h
++++ b/src/qcms.h
+@@ -102,6 +102,12 @@ typedef enum {
+ QCMS_DATA_GRAYA_8
+ } qcms_data_type;
+
++/* Format of the output data for qcms_transform_data_type() */
++typedef enum {
++ QCMS_OUTPUT_RGBX,
++ QCMS_OUTPUT_BGRX
++} qcms_output_type;
++
+ /* the names for the following two types are sort of ugly */
+ typedef struct
+ {
+@@ -146,6 +152,7 @@ qcms_transform* qcms_transform_create(
+ void qcms_transform_release(qcms_transform *);
+
+ void qcms_transform_data(qcms_transform *transform, void *src, void *dest, size_t length);
++void qcms_transform_data_type(qcms_transform *transform, void *src, void *dest, size_t length, qcms_output_type type);
+
+ void qcms_enable_iccv4();
+
+diff --git a/src/qcmsint.h b/src/qcmsint.h
+index 53a3420..63905de 100644
+--- a/src/qcmsint.h
++++ b/src/qcmsint.h
+@@ -45,6 +45,11 @@ struct precache_output
+ #define ALIGN __attribute__(( aligned (16) ))
+ #endif
+
++typedef struct _qcms_format_type {
++ int r;
++ int b;
++} qcms_format_type;
++
+ struct _qcms_transform {
+ float ALIGN matrix[3][4];
+ float *input_gamma_table_r;
+@@ -88,7 +93,7 @@ struct _qcms_transform {
+ struct precache_output *output_table_g;
+ struct precache_output *output_table_b;
+
+- void (*transform_fn)(struct _qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length);
++ void (*transform_fn)(struct _qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, struct _qcms_format_type output_format);
+ };
+
+ struct matrix {
+@@ -280,18 +285,22 @@ qcms_bool set_rgb_colorants(qcms_profile *profile, qcms_CIE_xyY white_point, qcm
+ void qcms_transform_data_rgb_out_lut_sse2(qcms_transform *transform,
+ unsigned char *src,
+ unsigned char *dest,
+- size_t length);
++ size_t length,
++ qcms_format_type output_format);
+ void qcms_transform_data_rgba_out_lut_sse2(qcms_transform *transform,
+ unsigned char *src,
+ unsigned char *dest,
+- size_t length);
++ size_t length,
++ qcms_format_type output_format);
+ void qcms_transform_data_rgb_out_lut_sse1(qcms_transform *transform,
+ unsigned char *src,
+ unsigned char *dest,
+- size_t length);
++ size_t length,
++ qcms_format_type output_format);
+ void qcms_transform_data_rgba_out_lut_sse1(qcms_transform *transform,
+ unsigned char *src,
+ unsigned char *dest,
+- size_t length);
++ size_t length,
++ qcms_format_type output_format);
+
+ extern qcms_bool qcms_supports_iccv4;
+diff --git a/src/qcmstypes.h b/src/qcmstypes.h
+index 56d8de3..9a9b197 100644
+--- a/src/qcmstypes.h
++++ b/src/qcmstypes.h
+@@ -87,7 +87,12 @@ typedef unsigned __int64 uint64_t;
+ #ifdef _WIN64
+ typedef unsigned __int64 uintptr_t;
+ #else
++#pragma warning(push)
++/* Disable benign redefinition of type warning 4142 */
++#pragma warning(disable:4142)
+ typedef unsigned long uintptr_t;
++/* Restore warnings */
++#pragma warning(pop)
+ #endif
+
+ #elif defined (_AIX)
+diff --git a/src/transform-sse1.c b/src/transform-sse1.c
+index 2f34db5..aaee1bf 100644
+--- a/src/transform-sse1.c
++++ b/src/transform-sse1.c
+@@ -34,7 +34,8 @@ static const ALIGN float clampMaxValueX4[4] =
+ void qcms_transform_data_rgb_out_lut_sse1(qcms_transform *transform,
+ unsigned char *src,
+ unsigned char *dest,
+- size_t length)
++ size_t length,
++ qcms_format_type output_format)
+ {
+ unsigned int i;
+ float (*mat)[4] = transform->matrix;
+@@ -70,6 +71,8 @@ void qcms_transform_data_rgb_out_lut_sse1(qcms_transform *transform,
+
+ /* working variables */
+ __m128 vec_r, vec_g, vec_b, result;
++ const int r_out = output_format.r;
++ const int b_out = output_format.b;
+
+ /* CYA */
+ if (!length)
+@@ -116,9 +119,9 @@ void qcms_transform_data_rgb_out_lut_sse1(qcms_transform *transform,
+ src += 3;
+
+ /* use calc'd indices to output RGB values */
+- dest[0] = otdata_r[output[0]];
+- dest[1] = otdata_g[output[1]];
+- dest[2] = otdata_b[output[2]];
++ dest[r_out] = otdata_r[output[0]];
++ dest[1] = otdata_g[output[1]];
++ dest[b_out] = otdata_b[output[2]];
+ dest += 3;
+ }
+
+@@ -141,9 +144,9 @@ void qcms_transform_data_rgb_out_lut_sse1(qcms_transform *transform,
+ result = _mm_movehl_ps(result, result);
+ *((__m64 *)&output[2]) = _mm_cvtps_pi32(result);
+
+- dest[0] = otdata_r[output[0]];
+- dest[1] = otdata_g[output[1]];
+- dest[2] = otdata_b[output[2]];
++ dest[r_out] = otdata_r[output[0]];
++ dest[1] = otdata_g[output[1]];
++ dest[b_out] = otdata_b[output[2]];
+
+ _mm_empty();
+ }
+@@ -151,7 +154,8 @@ void qcms_transform_data_rgb_out_lut_sse1(qcms_transform *transform,
+ void qcms_transform_data_rgba_out_lut_sse1(qcms_transform *transform,
+ unsigned char *src,
+ unsigned char *dest,
+- size_t length)
++ size_t length,
++ qcms_format_type output_format)
+ {
+ unsigned int i;
+ float (*mat)[4] = transform->matrix;
+@@ -187,6 +191,8 @@ void qcms_transform_data_rgba_out_lut_sse1(qcms_transform *transform,
+
+ /* working variables */
+ __m128 vec_r, vec_g, vec_b, result;
++ const int r_out = output_format.r;
++ const int b_out = output_format.b;
+ unsigned char alpha;
+
+ /* CYA */
+@@ -239,9 +245,9 @@ void qcms_transform_data_rgba_out_lut_sse1(qcms_transform *transform,
+ src += 4;
+
+ /* use calc'd indices to output RGB values */
+- dest[0] = otdata_r[output[0]];
+- dest[1] = otdata_g[output[1]];
+- dest[2] = otdata_b[output[2]];
++ dest[r_out] = otdata_r[output[0]];
++ dest[1] = otdata_g[output[1]];
++ dest[b_out] = otdata_b[output[2]];
+ dest += 4;
+ }
+
+@@ -266,9 +272,9 @@ void qcms_transform_data_rgba_out_lut_sse1(qcms_transform *transform,
+ result = _mm_movehl_ps(result, result);
+ *((__m64 *)&output[2]) = _mm_cvtps_pi32(result);
+
+- dest[0] = otdata_r[output[0]];
+- dest[1] = otdata_g[output[1]];
+- dest[2] = otdata_b[output[2]];
++ dest[r_out] = otdata_r[output[0]];
++ dest[1] = otdata_g[output[1]];
++ dest[b_out] = otdata_b[output[2]];
+
+ _mm_empty();
+ }
+diff --git a/src/transform-sse2.c b/src/transform-sse2.c
+index 6a5faf9..fa7f2d1 100644
+--- a/src/transform-sse2.c
++++ b/src/transform-sse2.c
+@@ -34,7 +34,8 @@ static const ALIGN float clampMaxValueX4[4] =
+ void qcms_transform_data_rgb_out_lut_sse2(qcms_transform *transform,
+ unsigned char *src,
+ unsigned char *dest,
+- size_t length)
++ size_t length,
++ qcms_format_type output_format)
+ {
+ unsigned int i;
+ float (*mat)[4] = transform->matrix;
+@@ -70,6 +71,8 @@ void qcms_transform_data_rgb_out_lut_sse2(qcms_transform *transform,
+
+ /* working variables */
+ __m128 vec_r, vec_g, vec_b, result;
++ const int r_out = output_format.r;
++ const int b_out = output_format.b;
+
+ /* CYA */
+ if (!length)
+@@ -114,9 +117,9 @@ void qcms_transform_data_rgb_out_lut_sse2(qcms_transform *transform,
+ src += 3;
+
+ /* use calc'd indices to output RGB values */
+- dest[0] = otdata_r[output[0]];
+- dest[1] = otdata_g[output[1]];
+- dest[2] = otdata_b[output[2]];
++ dest[r_out] = otdata_r[output[0]];
++ dest[1] = otdata_g[output[1]];
++ dest[b_out] = otdata_b[output[2]];
+ dest += 3;
+ }
+
+@@ -137,15 +140,16 @@ void qcms_transform_data_rgb_out_lut_sse2(qcms_transform *transform,
+
+ _mm_store_si128((__m128i*)output, _mm_cvtps_epi32(result));
+
+- dest[0] = otdata_r[output[0]];
+- dest[1] = otdata_g[output[1]];
+- dest[2] = otdata_b[output[2]];
++ dest[r_out] = otdata_r[output[0]];
++ dest[1] = otdata_g[output[1]];
++ dest[b_out] = otdata_b[output[2]];
+ }
+
+ void qcms_transform_data_rgba_out_lut_sse2(qcms_transform *transform,
+ unsigned char *src,
+ unsigned char *dest,
+- size_t length)
++ size_t length,
++ qcms_format_type output_format)
+ {
+ unsigned int i;
+ float (*mat)[4] = transform->matrix;
+@@ -181,6 +185,8 @@ void qcms_transform_data_rgba_out_lut_sse2(qcms_transform *transform,
+
+ /* working variables */
+ __m128 vec_r, vec_g, vec_b, result;
++ const int r_out = output_format.r;
++ const int b_out = output_format.b;
+ unsigned char alpha;
+
+ /* CYA */
+@@ -231,9 +237,9 @@ void qcms_transform_data_rgba_out_lut_sse2(qcms_transform *transform,
+ src += 4;
+
+ /* use calc'd indices to output RGB values */
+- dest[0] = otdata_r[output[0]];
+- dest[1] = otdata_g[output[1]];
+- dest[2] = otdata_b[output[2]];
++ dest[r_out] = otdata_r[output[0]];
++ dest[1] = otdata_g[output[1]];
++ dest[b_out] = otdata_b[output[2]];
+ dest += 4;
+ }
+
+@@ -256,7 +262,7 @@ void qcms_transform_data_rgba_out_lut_sse2(qcms_transform *transform,
+
+ _mm_store_si128((__m128i*)output, _mm_cvtps_epi32(result));
+
+- dest[0] = otdata_r[output[0]];
+- dest[1] = otdata_g[output[1]];
+- dest[2] = otdata_b[output[2]];
++ dest[r_out] = otdata_r[output[0]];
++ dest[1] = otdata_g[output[1]];
++ dest[b_out] = otdata_b[output[2]];
+ }
+diff --git a/src/transform.c b/src/transform.c
+index 9a6562b..ae3f628 100644
+--- a/src/transform.c
++++ b/src/transform.c
+@@ -181,11 +181,20 @@ compute_chromatic_adaption(struct CIE_XYZ source_white_point,
+ static struct matrix
+ adaption_matrix(struct CIE_XYZ source_illumination, struct CIE_XYZ target_illumination)
+ {
++#if defined (_MSC_VER)
++#pragma warning(push)
++/* Disable double to float truncation warning 4305 */
++#pragma warning(disable:4305)
++#endif
+ struct matrix lam_rigg = {{ // Bradford matrix
+ { 0.8951, 0.2664, -0.1614 },
+ { -0.7502, 1.7135, 0.0367 },
+ { 0.0389, -0.0685, 1.0296 }
+ }};
++#if defined (_MSC_VER)
++/* Restore warnings */
++#pragma warning(pop)
++#endif
+ return compute_chromatic_adaption(source_illumination, target_illumination, lam_rigg);
+ }
+
+@@ -230,8 +239,11 @@ qcms_bool set_rgb_colorants(qcms_profile *profile, qcms_CIE_xyY white_point, qcm
+ }
+
+ #if 0
+-static void qcms_transform_data_rgb_out_pow(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
++static void qcms_transform_data_rgb_out_pow(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
+ {
++ const int r_out = output_format.r;
++ const int b_out = output_format.b;
++
+ int i;
+ float (*mat)[4] = transform->matrix;
+ for (i=0; i<length; i++) {
+@@ -251,15 +263,19 @@ static void qcms_transform_data_rgb_out_pow(qcms_transform *transform, unsigned
+ float out_device_g = pow(out_linear_g, transform->out_gamma_g);
+ float out_device_b = pow(out_linear_b, transform->out_gamma_b);
+
+- *dest++ = clamp_u8(255*out_device_r);
+- *dest++ = clamp_u8(255*out_device_g);
+- *dest++ = clamp_u8(255*out_device_b);
++ dest[r_out] = clamp_u8(out_device_r*255);
++ dest[1] = clamp_u8(out_device_g*255);
++ dest[b_out] = clamp_u8(out_device_b*255);
++ dest += 3;
+ }
+ }
+ #endif
+
+-static void qcms_transform_data_gray_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
++static void qcms_transform_data_gray_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
+ {
++ const int r_out = output_format.r;
++ const int b_out = output_format.b;
++
+ unsigned int i;
+ for (i = 0; i < length; i++) {
+ float out_device_r, out_device_g, out_device_b;
+@@ -267,13 +283,14 @@ static void qcms_transform_data_gray_out_lut(qcms_transform *transform, unsigned
+
+ float linear = transform->input_gamma_table_gray[device];
+
+- out_device_r = lut_interp_linear(linear, transform->output_gamma_lut_r, transform->output_gamma_lut_r_length);
++ out_device_r = lut_interp_linear(linear, transform->output_gamma_lut_r, transform->output_gamma_lut_r_length);
+ out_device_g = lut_interp_linear(linear, transform->output_gamma_lut_g, transform->output_gamma_lut_g_length);
+ out_device_b = lut_interp_linear(linear, transform->output_gamma_lut_b, transform->output_gamma_lut_b_length);
+
+- *dest++ = clamp_u8(out_device_r*255);
+- *dest++ = clamp_u8(out_device_g*255);
+- *dest++ = clamp_u8(out_device_b*255);
++ dest[r_out] = clamp_u8(out_device_r*255);
++ dest[1] = clamp_u8(out_device_g*255);
++ dest[b_out] = clamp_u8(out_device_b*255);
++ dest += 3;
+ }
+ }
+
+@@ -283,8 +300,11 @@ static void qcms_transform_data_gray_out_lut(qcms_transform *transform, unsigned
+ See: ftp://ftp.alvyray.com/Acrobat/17_Nonln.pdf
+ */
+
+-static void qcms_transform_data_graya_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
++static void qcms_transform_data_graya_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
+ {
++ const int r_out = output_format.r;
++ const int b_out = output_format.b;
++
+ unsigned int i;
+ for (i = 0; i < length; i++) {
+ float out_device_r, out_device_g, out_device_b;
+@@ -293,20 +313,24 @@ static void qcms_transform_data_graya_out_lut(qcms_transform *transform, unsigne
+
+ float linear = transform->input_gamma_table_gray[device];
+
+- out_device_r = lut_interp_linear(linear, transform->output_gamma_lut_r, transform->output_gamma_lut_r_length);
++ out_device_r = lut_interp_linear(linear, transform->output_gamma_lut_r, transform->output_gamma_lut_r_length);
+ out_device_g = lut_interp_linear(linear, transform->output_gamma_lut_g, transform->output_gamma_lut_g_length);
+ out_device_b = lut_interp_linear(linear, transform->output_gamma_lut_b, transform->output_gamma_lut_b_length);
+
+- *dest++ = clamp_u8(out_device_r*255);
+- *dest++ = clamp_u8(out_device_g*255);
+- *dest++ = clamp_u8(out_device_b*255);
+- *dest++ = alpha;
++ dest[r_out] = clamp_u8(out_device_r*255);
++ dest[1] = clamp_u8(out_device_g*255);
++ dest[b_out] = clamp_u8(out_device_b*255);
++ dest[3] = alpha;
++ dest += 4;
+ }
+ }
+
+
+-static void qcms_transform_data_gray_out_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
++static void qcms_transform_data_gray_out_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
+ {
++ const int r_out = output_format.r;
++ const int b_out = output_format.b;
++
+ unsigned int i;
+ for (i = 0; i < length; i++) {
+ unsigned char device = *src++;
+@@ -317,14 +341,19 @@ static void qcms_transform_data_gray_out_precache(qcms_transform *transform, uns
+ /* we could round here... */
+ gray = linear * PRECACHE_OUTPUT_MAX;
+
+- *dest++ = transform->output_table_r->data[gray];
+- *dest++ = transform->output_table_g->data[gray];
+- *dest++ = transform->output_table_b->data[gray];
++ dest[r_out] = transform->output_table_r->data[gray];
++ dest[1] = transform->output_table_g->data[gray];
++ dest[b_out] = transform->output_table_b->data[gray];
++ dest += 3;
+ }
+ }
+
+-static void qcms_transform_data_graya_out_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
++
++static void qcms_transform_data_graya_out_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
+ {
++ const int r_out = output_format.r;
++ const int b_out = output_format.b;
++
+ unsigned int i;
+ for (i = 0; i < length; i++) {
+ unsigned char device = *src++;
+@@ -336,15 +365,19 @@ static void qcms_transform_data_graya_out_precache(qcms_transform *transform, un
+ /* we could round here... */
+ gray = linear * PRECACHE_OUTPUT_MAX;
+
+- *dest++ = transform->output_table_r->data[gray];
+- *dest++ = transform->output_table_g->data[gray];
+- *dest++ = transform->output_table_b->data[gray];
+- *dest++ = alpha;
++ dest[r_out] = transform->output_table_r->data[gray];
++ dest[1] = transform->output_table_g->data[gray];
++ dest[b_out] = transform->output_table_b->data[gray];
++ dest[3] = alpha;
++ dest += 4;
+ }
+ }
+
+-static void qcms_transform_data_rgb_out_lut_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
++static void qcms_transform_data_rgb_out_lut_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
+ {
++ const int r_out = output_format.r;
++ const int b_out = output_format.b;
++
+ unsigned int i;
+ float (*mat)[4] = transform->matrix;
+ for (i = 0; i < length; i++) {
+@@ -370,14 +403,18 @@ static void qcms_transform_data_rgb_out_lut_precache(qcms_transform *transform,
+ g = out_linear_g * PRECACHE_OUTPUT_MAX;
+ b = out_linear_b * PRECACHE_OUTPUT_MAX;
+
+- *dest++ = transform->output_table_r->data[r];
+- *dest++ = transform->output_table_g->data[g];
+- *dest++ = transform->output_table_b->data[b];
++ dest[r_out] = transform->output_table_r->data[r];
++ dest[1] = transform->output_table_g->data[g];
++ dest[b_out] = transform->output_table_b->data[b];
++ dest += 3;
+ }
+ }
+
+-static void qcms_transform_data_rgba_out_lut_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
++static void qcms_transform_data_rgba_out_lut_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
+ {
++ const int r_out = output_format.r;
++ const int b_out = output_format.b;
++
+ unsigned int i;
+ float (*mat)[4] = transform->matrix;
+ for (i = 0; i < length; i++) {
+@@ -404,16 +441,21 @@ static void qcms_transform_data_rgba_out_lut_precache(qcms_transform *transform,
+ g = out_linear_g * PRECACHE_OUTPUT_MAX;
+ b = out_linear_b * PRECACHE_OUTPUT_MAX;
+
+- *dest++ = transform->output_table_r->data[r];
+- *dest++ = transform->output_table_g->data[g];
+- *dest++ = transform->output_table_b->data[b];
+- *dest++ = alpha;
++ dest[r_out] = transform->output_table_r->data[r];
++ dest[1] = transform->output_table_g->data[g];
++ dest[b_out] = transform->output_table_b->data[b];
++ dest[3] = alpha;
++ dest += 4;
+ }
+ }
+
+ // Not used
+ /*
+-static void qcms_transform_data_clut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) {
++static void qcms_transform_data_clut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
++{
++ const int r_out = output_format.r;
++ const int b_out = output_format.b;
++
+ unsigned int i;
+ int xy_len = 1;
+ int x_len = transform->grid_size;
+@@ -462,15 +504,20 @@ static void qcms_transform_data_clut(qcms_transform *transform, unsigned char *s
+ float b_y2 = lerp(b_x3, b_x4, y_d);
+ float clut_b = lerp(b_y1, b_y2, z_d);
+
+- *dest++ = clamp_u8(clut_r*255.0f);
+- *dest++ = clamp_u8(clut_g*255.0f);
+- *dest++ = clamp_u8(clut_b*255.0f);
+- }
++ dest[r_out] = clamp_u8(clut_r*255.0f);
++ dest[1] = clamp_u8(clut_g*255.0f);
++ dest[b_out] = clamp_u8(clut_b*255.0f);
++ dest += 3;
++ }
+ }
+ */
+
+ // Using lcms' tetra interpolation algorithm.
+-static void qcms_transform_data_tetra_clut_rgba(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) {
++static void qcms_transform_data_tetra_clut_rgba(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
++{
++ const int r_out = output_format.r;
++ const int b_out = output_format.b;
++
+ unsigned int i;
+ int xy_len = 1;
+ int x_len = transform->grid_size;
+@@ -577,15 +624,20 @@ static void qcms_transform_data_tetra_clut_rgba(qcms_transform *transform, unsig
+ clut_g = c0_g + c1_g*rx + c2_g*ry + c3_g*rz;
+ clut_b = c0_b + c1_b*rx + c2_b*ry + c3_b*rz;
+
+- *dest++ = clamp_u8(clut_r*255.0f);
+- *dest++ = clamp_u8(clut_g*255.0f);
+- *dest++ = clamp_u8(clut_b*255.0f);
+- *dest++ = in_a;
+- }
++ dest[r_out] = clamp_u8(clut_r*255.0f);
++ dest[1] = clamp_u8(clut_g*255.0f);
++ dest[b_out] = clamp_u8(clut_b*255.0f);
++ dest[3] = in_a;
++ dest += 4;
++ }
+ }
+
+ // Using lcms' tetra interpolation code.
+-static void qcms_transform_data_tetra_clut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) {
++static void qcms_transform_data_tetra_clut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
++{
++ const int r_out = output_format.r;
++ const int b_out = output_format.b;
++
+ unsigned int i;
+ int xy_len = 1;
+ int x_len = transform->grid_size;
+@@ -691,14 +743,18 @@ static void qcms_transform_data_tetra_clut(qcms_transform *transform, unsigned c
+ clut_g = c0_g + c1_g*rx + c2_g*ry + c3_g*rz;
+ clut_b = c0_b + c1_b*rx + c2_b*ry + c3_b*rz;
+
+- *dest++ = clamp_u8(clut_r*255.0f);
+- *dest++ = clamp_u8(clut_g*255.0f);
+- *dest++ = clamp_u8(clut_b*255.0f);
+- }
++ dest[r_out] = clamp_u8(clut_r*255.0f);
++ dest[1] = clamp_u8(clut_g*255.0f);
++ dest[b_out] = clamp_u8(clut_b*255.0f);
++ dest += 3;
++ }
+ }
+
+-static void qcms_transform_data_rgb_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
++static void qcms_transform_data_rgb_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
+ {
++ const int r_out = output_format.r;
++ const int b_out = output_format.b;
++
+ unsigned int i;
+ float (*mat)[4] = transform->matrix;
+ for (i = 0; i < length; i++) {
+@@ -726,14 +782,18 @@ static void qcms_transform_data_rgb_out_lut(qcms_transform *transform, unsigned
+ out_device_b = lut_interp_linear(out_linear_b,
+ transform->output_gamma_lut_b, transform->output_gamma_lut_b_length);
+
+- *dest++ = clamp_u8(out_device_r*255);
+- *dest++ = clamp_u8(out_device_g*255);
+- *dest++ = clamp_u8(out_device_b*255);
++ dest[r_out] = clamp_u8(out_device_r*255);
++ dest[1] = clamp_u8(out_device_g*255);
++ dest[b_out] = clamp_u8(out_device_b*255);
++ dest += 3;
+ }
+ }
+
+-static void qcms_transform_data_rgba_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
++static void qcms_transform_data_rgba_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
+ {
++ const int r_out = output_format.r;
++ const int b_out = output_format.b;
++
+ unsigned int i;
+ float (*mat)[4] = transform->matrix;
+ for (i = 0; i < length; i++) {
+@@ -762,16 +822,20 @@ static void qcms_transform_data_rgba_out_lut(qcms_transform *transform, unsigned
+ out_device_b = lut_interp_linear(out_linear_b,
+ transform->output_gamma_lut_b, transform->output_gamma_lut_b_length);
+
+- *dest++ = clamp_u8(out_device_r*255);
+- *dest++ = clamp_u8(out_device_g*255);
+- *dest++ = clamp_u8(out_device_b*255);
+- *dest++ = alpha;
++ dest[r_out] = clamp_u8(out_device_r*255);
++ dest[1] = clamp_u8(out_device_g*255);
++ dest[b_out] = clamp_u8(out_device_b*255);
++ dest[3] = alpha;
++ dest += 4;
+ }
+ }
+
+ #if 0
+-static void qcms_transform_data_rgb_out_linear(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
++static void qcms_transform_data_rgb_out_linear(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
+ {
++ const int r_out = output_format.r;
++ const int b_out = output_format.b;
++
+ int i;
+ float (*mat)[4] = transform->matrix;
+ for (i = 0; i < length; i++) {
+@@ -787,9 +851,10 @@ static void qcms_transform_data_rgb_out_linear(qcms_transform *transform, unsign
+ float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + mat[2][1]*linear_b;
+ float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + mat[2][2]*linear_b;
+
+- *dest++ = clamp_u8(out_linear_r*255);
+- *dest++ = clamp_u8(out_linear_g*255);
+- *dest++ = clamp_u8(out_linear_b*255);
++ dest[r_out] = clamp_u8(out_linear_r*255);
++ dest[1] = clamp_u8(out_linear_g*255);
++ dest[b_out] = clamp_u8(out_linear_b*255);
++ dest += 3;
+ }
+ }
+ #endif
+@@ -1262,7 +1327,17 @@ __attribute__((__force_align_arg_pointer__))
+ #endif
+ void qcms_transform_data(qcms_transform *transform, void *src, void *dest, size_t length)
+ {
+- transform->transform_fn(transform, src, dest, length);
++ static const struct _qcms_format_type output_rgbx = { 0, 2 };
++
++ transform->transform_fn(transform, src, dest, length, output_rgbx);
++}
++
++void qcms_transform_data_type(qcms_transform *transform, void *src, void *dest, size_t length, qcms_output_type type)
++{
++ static const struct _qcms_format_type output_rgbx = { 0, 2 };
++ static const struct _qcms_format_type output_bgrx = { 2, 0 };
++
++ transform->transform_fn(transform, src, dest, length, type == QCMS_OUTPUT_BGRX ? output_bgrx : output_rgbx);
+ }
+
+ qcms_bool qcms_supports_iccv4;
diff --git a/third_party/qcms/src/iccread.c b/third_party/qcms/src/iccread.c
index 36b7011..2454924 100644
--- a/third_party/qcms/src/iccread.c
+++ b/third_party/qcms/src/iccread.c
@@ -297,6 +297,11 @@ qcms_bool qcms_profile_is_bogus(qcms_profile *profile)
sum[1] = rY + gY + bY;
sum[2] = rZ + gZ + bZ;
+#if defined (_MSC_VER)
+#pragma warning(push)
+/* Disable double to float truncation warning 4305 */
+#pragma warning(disable:4305)
+#endif
// Build our target vector (see mozilla bug 460629)
target[0] = 0.96420;
target[1] = 1.00000;
@@ -310,6 +315,10 @@ qcms_bool qcms_profile_is_bogus(qcms_profile *profile)
tolerance[1] = 0.02;
tolerance[2] = 0.04;
+#if defined (_MSC_VER)
+/* Restore warnings */
+#pragma warning(pop)
+#endif
// Compare with our tolerance
for (i = 0; i < 3; ++i) {
if (!(((sum[i] - tolerance[i]) <= target[i]) &&
diff --git a/third_party/qcms/src/qcms.h b/third_party/qcms/src/qcms.h
index 7d83623..1e3e125b 100644
--- a/third_party/qcms/src/qcms.h
+++ b/third_party/qcms/src/qcms.h
@@ -102,6 +102,12 @@ typedef enum {
QCMS_DATA_GRAYA_8
} qcms_data_type;
+/* Format of the output data for qcms_transform_data_type() */
+typedef enum {
+ QCMS_OUTPUT_RGBX,
+ QCMS_OUTPUT_BGRX
+} qcms_output_type;
+
/* the names for the following two types are sort of ugly */
typedef struct
{
@@ -146,6 +152,7 @@ qcms_transform* qcms_transform_create(
void qcms_transform_release(qcms_transform *);
void qcms_transform_data(qcms_transform *transform, void *src, void *dest, size_t length);
+void qcms_transform_data_type(qcms_transform *transform, void *src, void *dest, size_t length, qcms_output_type type);
void qcms_enable_iccv4();
diff --git a/third_party/qcms/src/qcmsint.h b/third_party/qcms/src/qcmsint.h
index 53a3420..63905de 100644
--- a/third_party/qcms/src/qcmsint.h
+++ b/third_party/qcms/src/qcmsint.h
@@ -45,6 +45,11 @@ struct precache_output
#define ALIGN __attribute__(( aligned (16) ))
#endif
+typedef struct _qcms_format_type {
+ int r;
+ int b;
+} qcms_format_type;
+
struct _qcms_transform {
float ALIGN matrix[3][4];
float *input_gamma_table_r;
@@ -88,7 +93,7 @@ struct _qcms_transform {
struct precache_output *output_table_g;
struct precache_output *output_table_b;
- void (*transform_fn)(struct _qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length);
+ void (*transform_fn)(struct _qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, struct _qcms_format_type output_format);
};
struct matrix {
@@ -280,18 +285,22 @@ qcms_bool set_rgb_colorants(qcms_profile *profile, qcms_CIE_xyY white_point, qcm
void qcms_transform_data_rgb_out_lut_sse2(qcms_transform *transform,
unsigned char *src,
unsigned char *dest,
- size_t length);
+ size_t length,
+ qcms_format_type output_format);
void qcms_transform_data_rgba_out_lut_sse2(qcms_transform *transform,
unsigned char *src,
unsigned char *dest,
- size_t length);
+ size_t length,
+ qcms_format_type output_format);
void qcms_transform_data_rgb_out_lut_sse1(qcms_transform *transform,
unsigned char *src,
unsigned char *dest,
- size_t length);
+ size_t length,
+ qcms_format_type output_format);
void qcms_transform_data_rgba_out_lut_sse1(qcms_transform *transform,
unsigned char *src,
unsigned char *dest,
- size_t length);
+ size_t length,
+ qcms_format_type output_format);
extern qcms_bool qcms_supports_iccv4;
diff --git a/third_party/qcms/src/qcmstypes.h b/third_party/qcms/src/qcmstypes.h
index 56d8de3..9a9b197 100644
--- a/third_party/qcms/src/qcmstypes.h
+++ b/third_party/qcms/src/qcmstypes.h
@@ -87,7 +87,12 @@ typedef unsigned __int64 uint64_t;
#ifdef _WIN64
typedef unsigned __int64 uintptr_t;
#else
+#pragma warning(push)
+/* Disable benign redefinition of type warning 4142 */
+#pragma warning(disable:4142)
typedef unsigned long uintptr_t;
+/* Restore warnings */
+#pragma warning(pop)
#endif
#elif defined (_AIX)
diff --git a/third_party/qcms/src/transform-sse1.c b/third_party/qcms/src/transform-sse1.c
index 2f34db5..aaee1bf 100644
--- a/third_party/qcms/src/transform-sse1.c
+++ b/third_party/qcms/src/transform-sse1.c
@@ -34,7 +34,8 @@ static const ALIGN float clampMaxValueX4[4] =
void qcms_transform_data_rgb_out_lut_sse1(qcms_transform *transform,
unsigned char *src,
unsigned char *dest,
- size_t length)
+ size_t length,
+ qcms_format_type output_format)
{
unsigned int i;
float (*mat)[4] = transform->matrix;
@@ -70,6 +71,8 @@ void qcms_transform_data_rgb_out_lut_sse1(qcms_transform *transform,
/* working variables */
__m128 vec_r, vec_g, vec_b, result;
+ const int r_out = output_format.r;
+ const int b_out = output_format.b;
/* CYA */
if (!length)
@@ -116,9 +119,9 @@ void qcms_transform_data_rgb_out_lut_sse1(qcms_transform *transform,
src += 3;
/* use calc'd indices to output RGB values */
- dest[0] = otdata_r[output[0]];
- dest[1] = otdata_g[output[1]];
- dest[2] = otdata_b[output[2]];
+ dest[r_out] = otdata_r[output[0]];
+ dest[1] = otdata_g[output[1]];
+ dest[b_out] = otdata_b[output[2]];
dest += 3;
}
@@ -141,9 +144,9 @@ void qcms_transform_data_rgb_out_lut_sse1(qcms_transform *transform,
result = _mm_movehl_ps(result, result);
*((__m64 *)&output[2]) = _mm_cvtps_pi32(result);
- dest[0] = otdata_r[output[0]];
- dest[1] = otdata_g[output[1]];
- dest[2] = otdata_b[output[2]];
+ dest[r_out] = otdata_r[output[0]];
+ dest[1] = otdata_g[output[1]];
+ dest[b_out] = otdata_b[output[2]];
_mm_empty();
}
@@ -151,7 +154,8 @@ void qcms_transform_data_rgb_out_lut_sse1(qcms_transform *transform,
void qcms_transform_data_rgba_out_lut_sse1(qcms_transform *transform,
unsigned char *src,
unsigned char *dest,
- size_t length)
+ size_t length,
+ qcms_format_type output_format)
{
unsigned int i;
float (*mat)[4] = transform->matrix;
@@ -187,6 +191,8 @@ void qcms_transform_data_rgba_out_lut_sse1(qcms_transform *transform,
/* working variables */
__m128 vec_r, vec_g, vec_b, result;
+ const int r_out = output_format.r;
+ const int b_out = output_format.b;
unsigned char alpha;
/* CYA */
@@ -239,9 +245,9 @@ void qcms_transform_data_rgba_out_lut_sse1(qcms_transform *transform,
src += 4;
/* use calc'd indices to output RGB values */
- dest[0] = otdata_r[output[0]];
- dest[1] = otdata_g[output[1]];
- dest[2] = otdata_b[output[2]];
+ dest[r_out] = otdata_r[output[0]];
+ dest[1] = otdata_g[output[1]];
+ dest[b_out] = otdata_b[output[2]];
dest += 4;
}
@@ -266,9 +272,9 @@ void qcms_transform_data_rgba_out_lut_sse1(qcms_transform *transform,
result = _mm_movehl_ps(result, result);
*((__m64 *)&output[2]) = _mm_cvtps_pi32(result);
- dest[0] = otdata_r[output[0]];
- dest[1] = otdata_g[output[1]];
- dest[2] = otdata_b[output[2]];
+ dest[r_out] = otdata_r[output[0]];
+ dest[1] = otdata_g[output[1]];
+ dest[b_out] = otdata_b[output[2]];
_mm_empty();
}
diff --git a/third_party/qcms/src/transform-sse2.c b/third_party/qcms/src/transform-sse2.c
index 6a5faf9..fa7f2d1 100644
--- a/third_party/qcms/src/transform-sse2.c
+++ b/third_party/qcms/src/transform-sse2.c
@@ -34,7 +34,8 @@ static const ALIGN float clampMaxValueX4[4] =
void qcms_transform_data_rgb_out_lut_sse2(qcms_transform *transform,
unsigned char *src,
unsigned char *dest,
- size_t length)
+ size_t length,
+ qcms_format_type output_format)
{
unsigned int i;
float (*mat)[4] = transform->matrix;
@@ -70,6 +71,8 @@ void qcms_transform_data_rgb_out_lut_sse2(qcms_transform *transform,
/* working variables */
__m128 vec_r, vec_g, vec_b, result;
+ const int r_out = output_format.r;
+ const int b_out = output_format.b;
/* CYA */
if (!length)
@@ -114,9 +117,9 @@ void qcms_transform_data_rgb_out_lut_sse2(qcms_transform *transform,
src += 3;
/* use calc'd indices to output RGB values */
- dest[0] = otdata_r[output[0]];
- dest[1] = otdata_g[output[1]];
- dest[2] = otdata_b[output[2]];
+ dest[r_out] = otdata_r[output[0]];
+ dest[1] = otdata_g[output[1]];
+ dest[b_out] = otdata_b[output[2]];
dest += 3;
}
@@ -137,15 +140,16 @@ void qcms_transform_data_rgb_out_lut_sse2(qcms_transform *transform,
_mm_store_si128((__m128i*)output, _mm_cvtps_epi32(result));
- dest[0] = otdata_r[output[0]];
- dest[1] = otdata_g[output[1]];
- dest[2] = otdata_b[output[2]];
+ dest[r_out] = otdata_r[output[0]];
+ dest[1] = otdata_g[output[1]];
+ dest[b_out] = otdata_b[output[2]];
}
void qcms_transform_data_rgba_out_lut_sse2(qcms_transform *transform,
unsigned char *src,
unsigned char *dest,
- size_t length)
+ size_t length,
+ qcms_format_type output_format)
{
unsigned int i;
float (*mat)[4] = transform->matrix;
@@ -181,6 +185,8 @@ void qcms_transform_data_rgba_out_lut_sse2(qcms_transform *transform,
/* working variables */
__m128 vec_r, vec_g, vec_b, result;
+ const int r_out = output_format.r;
+ const int b_out = output_format.b;
unsigned char alpha;
/* CYA */
@@ -231,9 +237,9 @@ void qcms_transform_data_rgba_out_lut_sse2(qcms_transform *transform,
src += 4;
/* use calc'd indices to output RGB values */
- dest[0] = otdata_r[output[0]];
- dest[1] = otdata_g[output[1]];
- dest[2] = otdata_b[output[2]];
+ dest[r_out] = otdata_r[output[0]];
+ dest[1] = otdata_g[output[1]];
+ dest[b_out] = otdata_b[output[2]];
dest += 4;
}
@@ -256,7 +262,7 @@ void qcms_transform_data_rgba_out_lut_sse2(qcms_transform *transform,
_mm_store_si128((__m128i*)output, _mm_cvtps_epi32(result));
- dest[0] = otdata_r[output[0]];
- dest[1] = otdata_g[output[1]];
- dest[2] = otdata_b[output[2]];
+ dest[r_out] = otdata_r[output[0]];
+ dest[1] = otdata_g[output[1]];
+ dest[b_out] = otdata_b[output[2]];
}
diff --git a/third_party/qcms/src/transform.c b/third_party/qcms/src/transform.c
index 9a6562b..ae3f628 100644
--- a/third_party/qcms/src/transform.c
+++ b/third_party/qcms/src/transform.c
@@ -181,11 +181,20 @@ compute_chromatic_adaption(struct CIE_XYZ source_white_point,
static struct matrix
adaption_matrix(struct CIE_XYZ source_illumination, struct CIE_XYZ target_illumination)
{
+#if defined (_MSC_VER)
+#pragma warning(push)
+/* Disable double to float truncation warning 4305 */
+#pragma warning(disable:4305)
+#endif
struct matrix lam_rigg = {{ // Bradford matrix
{ 0.8951, 0.2664, -0.1614 },
{ -0.7502, 1.7135, 0.0367 },
{ 0.0389, -0.0685, 1.0296 }
}};
+#if defined (_MSC_VER)
+/* Restore warnings */
+#pragma warning(pop)
+#endif
return compute_chromatic_adaption(source_illumination, target_illumination, lam_rigg);
}
@@ -230,8 +239,11 @@ qcms_bool set_rgb_colorants(qcms_profile *profile, qcms_CIE_xyY white_point, qcm
}
#if 0
-static void qcms_transform_data_rgb_out_pow(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
+static void qcms_transform_data_rgb_out_pow(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
{
+ const int r_out = output_format.r;
+ const int b_out = output_format.b;
+
int i;
float (*mat)[4] = transform->matrix;
for (i=0; i<length; i++) {
@@ -251,15 +263,19 @@ static void qcms_transform_data_rgb_out_pow(qcms_transform *transform, unsigned
float out_device_g = pow(out_linear_g, transform->out_gamma_g);
float out_device_b = pow(out_linear_b, transform->out_gamma_b);
- *dest++ = clamp_u8(255*out_device_r);
- *dest++ = clamp_u8(255*out_device_g);
- *dest++ = clamp_u8(255*out_device_b);
+ dest[r_out] = clamp_u8(out_device_r*255);
+ dest[1] = clamp_u8(out_device_g*255);
+ dest[b_out] = clamp_u8(out_device_b*255);
+ dest += 3;
}
}
#endif
-static void qcms_transform_data_gray_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
+static void qcms_transform_data_gray_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
{
+ const int r_out = output_format.r;
+ const int b_out = output_format.b;
+
unsigned int i;
for (i = 0; i < length; i++) {
float out_device_r, out_device_g, out_device_b;
@@ -267,13 +283,14 @@ static void qcms_transform_data_gray_out_lut(qcms_transform *transform, unsigned
float linear = transform->input_gamma_table_gray[device];
- out_device_r = lut_interp_linear(linear, transform->output_gamma_lut_r, transform->output_gamma_lut_r_length);
+ out_device_r = lut_interp_linear(linear, transform->output_gamma_lut_r, transform->output_gamma_lut_r_length);
out_device_g = lut_interp_linear(linear, transform->output_gamma_lut_g, transform->output_gamma_lut_g_length);
out_device_b = lut_interp_linear(linear, transform->output_gamma_lut_b, transform->output_gamma_lut_b_length);
- *dest++ = clamp_u8(out_device_r*255);
- *dest++ = clamp_u8(out_device_g*255);
- *dest++ = clamp_u8(out_device_b*255);
+ dest[r_out] = clamp_u8(out_device_r*255);
+ dest[1] = clamp_u8(out_device_g*255);
+ dest[b_out] = clamp_u8(out_device_b*255);
+ dest += 3;
}
}
@@ -283,8 +300,11 @@ static void qcms_transform_data_gray_out_lut(qcms_transform *transform, unsigned
See: ftp://ftp.alvyray.com/Acrobat/17_Nonln.pdf
*/
-static void qcms_transform_data_graya_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
+static void qcms_transform_data_graya_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
{
+ const int r_out = output_format.r;
+ const int b_out = output_format.b;
+
unsigned int i;
for (i = 0; i < length; i++) {
float out_device_r, out_device_g, out_device_b;
@@ -293,20 +313,24 @@ static void qcms_transform_data_graya_out_lut(qcms_transform *transform, unsigne
float linear = transform->input_gamma_table_gray[device];
- out_device_r = lut_interp_linear(linear, transform->output_gamma_lut_r, transform->output_gamma_lut_r_length);
+ out_device_r = lut_interp_linear(linear, transform->output_gamma_lut_r, transform->output_gamma_lut_r_length);
out_device_g = lut_interp_linear(linear, transform->output_gamma_lut_g, transform->output_gamma_lut_g_length);
out_device_b = lut_interp_linear(linear, transform->output_gamma_lut_b, transform->output_gamma_lut_b_length);
- *dest++ = clamp_u8(out_device_r*255);
- *dest++ = clamp_u8(out_device_g*255);
- *dest++ = clamp_u8(out_device_b*255);
- *dest++ = alpha;
+ dest[r_out] = clamp_u8(out_device_r*255);
+ dest[1] = clamp_u8(out_device_g*255);
+ dest[b_out] = clamp_u8(out_device_b*255);
+ dest[3] = alpha;
+ dest += 4;
}
}
-static void qcms_transform_data_gray_out_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
+static void qcms_transform_data_gray_out_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
{
+ const int r_out = output_format.r;
+ const int b_out = output_format.b;
+
unsigned int i;
for (i = 0; i < length; i++) {
unsigned char device = *src++;
@@ -317,14 +341,19 @@ static void qcms_transform_data_gray_out_precache(qcms_transform *transform, uns
/* we could round here... */
gray = linear * PRECACHE_OUTPUT_MAX;
- *dest++ = transform->output_table_r->data[gray];
- *dest++ = transform->output_table_g->data[gray];
- *dest++ = transform->output_table_b->data[gray];
+ dest[r_out] = transform->output_table_r->data[gray];
+ dest[1] = transform->output_table_g->data[gray];
+ dest[b_out] = transform->output_table_b->data[gray];
+ dest += 3;
}
}
-static void qcms_transform_data_graya_out_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
+
+static void qcms_transform_data_graya_out_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
{
+ const int r_out = output_format.r;
+ const int b_out = output_format.b;
+
unsigned int i;
for (i = 0; i < length; i++) {
unsigned char device = *src++;
@@ -336,15 +365,19 @@ static void qcms_transform_data_graya_out_precache(qcms_transform *transform, un
/* we could round here... */
gray = linear * PRECACHE_OUTPUT_MAX;
- *dest++ = transform->output_table_r->data[gray];
- *dest++ = transform->output_table_g->data[gray];
- *dest++ = transform->output_table_b->data[gray];
- *dest++ = alpha;
+ dest[r_out] = transform->output_table_r->data[gray];
+ dest[1] = transform->output_table_g->data[gray];
+ dest[b_out] = transform->output_table_b->data[gray];
+ dest[3] = alpha;
+ dest += 4;
}
}
-static void qcms_transform_data_rgb_out_lut_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
+static void qcms_transform_data_rgb_out_lut_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
{
+ const int r_out = output_format.r;
+ const int b_out = output_format.b;
+
unsigned int i;
float (*mat)[4] = transform->matrix;
for (i = 0; i < length; i++) {
@@ -370,14 +403,18 @@ static void qcms_transform_data_rgb_out_lut_precache(qcms_transform *transform,
g = out_linear_g * PRECACHE_OUTPUT_MAX;
b = out_linear_b * PRECACHE_OUTPUT_MAX;
- *dest++ = transform->output_table_r->data[r];
- *dest++ = transform->output_table_g->data[g];
- *dest++ = transform->output_table_b->data[b];
+ dest[r_out] = transform->output_table_r->data[r];
+ dest[1] = transform->output_table_g->data[g];
+ dest[b_out] = transform->output_table_b->data[b];
+ dest += 3;
}
}
-static void qcms_transform_data_rgba_out_lut_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
+static void qcms_transform_data_rgba_out_lut_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
{
+ const int r_out = output_format.r;
+ const int b_out = output_format.b;
+
unsigned int i;
float (*mat)[4] = transform->matrix;
for (i = 0; i < length; i++) {
@@ -404,16 +441,21 @@ static void qcms_transform_data_rgba_out_lut_precache(qcms_transform *transform,
g = out_linear_g * PRECACHE_OUTPUT_MAX;
b = out_linear_b * PRECACHE_OUTPUT_MAX;
- *dest++ = transform->output_table_r->data[r];
- *dest++ = transform->output_table_g->data[g];
- *dest++ = transform->output_table_b->data[b];
- *dest++ = alpha;
+ dest[r_out] = transform->output_table_r->data[r];
+ dest[1] = transform->output_table_g->data[g];
+ dest[b_out] = transform->output_table_b->data[b];
+ dest[3] = alpha;
+ dest += 4;
}
}
// Not used
/*
-static void qcms_transform_data_clut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) {
+static void qcms_transform_data_clut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
+{
+ const int r_out = output_format.r;
+ const int b_out = output_format.b;
+
unsigned int i;
int xy_len = 1;
int x_len = transform->grid_size;
@@ -462,15 +504,20 @@ static void qcms_transform_data_clut(qcms_transform *transform, unsigned char *s
float b_y2 = lerp(b_x3, b_x4, y_d);
float clut_b = lerp(b_y1, b_y2, z_d);
- *dest++ = clamp_u8(clut_r*255.0f);
- *dest++ = clamp_u8(clut_g*255.0f);
- *dest++ = clamp_u8(clut_b*255.0f);
- }
+ dest[r_out] = clamp_u8(clut_r*255.0f);
+ dest[1] = clamp_u8(clut_g*255.0f);
+ dest[b_out] = clamp_u8(clut_b*255.0f);
+ dest += 3;
+ }
}
*/
// Using lcms' tetra interpolation algorithm.
-static void qcms_transform_data_tetra_clut_rgba(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) {
+static void qcms_transform_data_tetra_clut_rgba(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
+{
+ const int r_out = output_format.r;
+ const int b_out = output_format.b;
+
unsigned int i;
int xy_len = 1;
int x_len = transform->grid_size;
@@ -577,15 +624,20 @@ static void qcms_transform_data_tetra_clut_rgba(qcms_transform *transform, unsig
clut_g = c0_g + c1_g*rx + c2_g*ry + c3_g*rz;
clut_b = c0_b + c1_b*rx + c2_b*ry + c3_b*rz;
- *dest++ = clamp_u8(clut_r*255.0f);
- *dest++ = clamp_u8(clut_g*255.0f);
- *dest++ = clamp_u8(clut_b*255.0f);
- *dest++ = in_a;
- }
+ dest[r_out] = clamp_u8(clut_r*255.0f);
+ dest[1] = clamp_u8(clut_g*255.0f);
+ dest[b_out] = clamp_u8(clut_b*255.0f);
+ dest[3] = in_a;
+ dest += 4;
+ }
}
// Using lcms' tetra interpolation code.
-static void qcms_transform_data_tetra_clut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) {
+static void qcms_transform_data_tetra_clut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
+{
+ const int r_out = output_format.r;
+ const int b_out = output_format.b;
+
unsigned int i;
int xy_len = 1;
int x_len = transform->grid_size;
@@ -691,14 +743,18 @@ static void qcms_transform_data_tetra_clut(qcms_transform *transform, unsigned c
clut_g = c0_g + c1_g*rx + c2_g*ry + c3_g*rz;
clut_b = c0_b + c1_b*rx + c2_b*ry + c3_b*rz;
- *dest++ = clamp_u8(clut_r*255.0f);
- *dest++ = clamp_u8(clut_g*255.0f);
- *dest++ = clamp_u8(clut_b*255.0f);
- }
+ dest[r_out] = clamp_u8(clut_r*255.0f);
+ dest[1] = clamp_u8(clut_g*255.0f);
+ dest[b_out] = clamp_u8(clut_b*255.0f);
+ dest += 3;
+ }
}
-static void qcms_transform_data_rgb_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
+static void qcms_transform_data_rgb_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
{
+ const int r_out = output_format.r;
+ const int b_out = output_format.b;
+
unsigned int i;
float (*mat)[4] = transform->matrix;
for (i = 0; i < length; i++) {
@@ -726,14 +782,18 @@ static void qcms_transform_data_rgb_out_lut(qcms_transform *transform, unsigned
out_device_b = lut_interp_linear(out_linear_b,
transform->output_gamma_lut_b, transform->output_gamma_lut_b_length);
- *dest++ = clamp_u8(out_device_r*255);
- *dest++ = clamp_u8(out_device_g*255);
- *dest++ = clamp_u8(out_device_b*255);
+ dest[r_out] = clamp_u8(out_device_r*255);
+ dest[1] = clamp_u8(out_device_g*255);
+ dest[b_out] = clamp_u8(out_device_b*255);
+ dest += 3;
}
}
-static void qcms_transform_data_rgba_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
+static void qcms_transform_data_rgba_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
{
+ const int r_out = output_format.r;
+ const int b_out = output_format.b;
+
unsigned int i;
float (*mat)[4] = transform->matrix;
for (i = 0; i < length; i++) {
@@ -762,16 +822,20 @@ static void qcms_transform_data_rgba_out_lut(qcms_transform *transform, unsigned
out_device_b = lut_interp_linear(out_linear_b,
transform->output_gamma_lut_b, transform->output_gamma_lut_b_length);
- *dest++ = clamp_u8(out_device_r*255);
- *dest++ = clamp_u8(out_device_g*255);
- *dest++ = clamp_u8(out_device_b*255);
- *dest++ = alpha;
+ dest[r_out] = clamp_u8(out_device_r*255);
+ dest[1] = clamp_u8(out_device_g*255);
+ dest[b_out] = clamp_u8(out_device_b*255);
+ dest[3] = alpha;
+ dest += 4;
}
}
#if 0
-static void qcms_transform_data_rgb_out_linear(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
+static void qcms_transform_data_rgb_out_linear(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
{
+ const int r_out = output_format.r;
+ const int b_out = output_format.b;
+
int i;
float (*mat)[4] = transform->matrix;
for (i = 0; i < length; i++) {
@@ -787,9 +851,10 @@ static void qcms_transform_data_rgb_out_linear(qcms_transform *transform, unsign
float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + mat[2][1]*linear_b;
float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + mat[2][2]*linear_b;
- *dest++ = clamp_u8(out_linear_r*255);
- *dest++ = clamp_u8(out_linear_g*255);
- *dest++ = clamp_u8(out_linear_b*255);
+ dest[r_out] = clamp_u8(out_linear_r*255);
+ dest[1] = clamp_u8(out_linear_g*255);
+ dest[b_out] = clamp_u8(out_linear_b*255);
+ dest += 3;
}
}
#endif
@@ -1262,7 +1327,17 @@ __attribute__((__force_align_arg_pointer__))
#endif
void qcms_transform_data(qcms_transform *transform, void *src, void *dest, size_t length)
{
- transform->transform_fn(transform, src, dest, length);
+ static const struct _qcms_format_type output_rgbx = { 0, 2 };
+
+ transform->transform_fn(transform, src, dest, length, output_rgbx);
+}
+
+void qcms_transform_data_type(qcms_transform *transform, void *src, void *dest, size_t length, qcms_output_type type)
+{
+ static const struct _qcms_format_type output_rgbx = { 0, 2 };
+ static const struct _qcms_format_type output_bgrx = { 2, 0 };
+
+ transform->transform_fn(transform, src, dest, length, type == QCMS_OUTPUT_BGRX ? output_bgrx : output_rgbx);
}
qcms_bool qcms_supports_iccv4;