diff options
-rw-r--r-- | third_party/qcms/README.chromium | 6 | ||||
-rw-r--r-- | third_party/qcms/google.patch | 688 | ||||
-rw-r--r-- | third_party/qcms/src/iccread.c | 9 | ||||
-rw-r--r-- | third_party/qcms/src/qcms.h | 7 | ||||
-rw-r--r-- | third_party/qcms/src/qcmsint.h | 19 | ||||
-rw-r--r-- | third_party/qcms/src/qcmstypes.h | 5 | ||||
-rw-r--r-- | third_party/qcms/src/transform-sse1.c | 34 | ||||
-rw-r--r-- | third_party/qcms/src/transform-sse2.c | 34 | ||||
-rw-r--r-- | third_party/qcms/src/transform.c | 201 |
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; |