Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(276)

Unified Diff: third_party/qcms/src/transform.c

Issue 10384114: Added BGRA support to qcms. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/qcms/src/qcmsint.h ('k') | third_party/qcms/src/transform-sse1.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/qcms/src/transform.c
diff --git a/third_party/qcms/src/transform.c b/third_party/qcms/src/transform.c
index 9a6562bf2712db51bfdef01a6b3f751c31e54d39..8d49e5ce6dd96fbdd3ad01d591ad38e61c0edffa 100644
--- a/third_party/qcms/src/transform.c
+++ b/third_party/qcms/src/transform.c
@@ -411,6 +411,41 @@ static void qcms_transform_data_rgba_out_lut_precache(qcms_transform *transform,
}
}
+static void qcms_transform_data_bgra_out_lut_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
+{
+ unsigned int i;
+ float (*mat)[4] = transform->matrix;
+ for (i = 0; i < length; i++) {
+ unsigned char device_b = *src++;
+ unsigned char device_g = *src++;
+ unsigned char device_r = *src++;
+ unsigned char alpha = *src++;
+ uint16_t r, g, b;
+
+ float linear_r = transform->input_gamma_table_r[device_r];
+ float linear_g = transform->input_gamma_table_g[device_g];
+ float linear_b = transform->input_gamma_table_b[device_b];
+
+ float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + mat[2][0]*linear_b;
+ 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;
+
+ out_linear_r = clamp_float(out_linear_r);
+ out_linear_g = clamp_float(out_linear_g);
+ out_linear_b = clamp_float(out_linear_b);
+
+ /* we could round here... */
+ r = out_linear_r * PRECACHE_OUTPUT_MAX;
+ g = out_linear_g * PRECACHE_OUTPUT_MAX;
+ b = out_linear_b * PRECACHE_OUTPUT_MAX;
+
+ *dest++ = transform->output_table_b->data[b];
+ *dest++ = transform->output_table_g->data[g];
+ *dest++ = transform->output_table_r->data[r];
+ *dest++ = alpha;
+ }
+}
+
// Not used
/*
static void qcms_transform_data_clut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) {
@@ -584,6 +619,121 @@ static void qcms_transform_data_tetra_clut_rgba(qcms_transform *transform, unsig
}
}
+// Using lcms' tetra interpolation algorithm.
+static void qcms_transform_data_tetra_clut_bgra(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) {
+ unsigned int i;
+ int xy_len = 1;
+ int x_len = transform->grid_size;
+ int len = x_len * x_len;
+ float* r_table = transform->r_clut;
+ float* g_table = transform->g_clut;
+ float* b_table = transform->b_clut;
+ float c0_r, c1_r, c2_r, c3_r;
+ float c0_g, c1_g, c2_g, c3_g;
+ float c0_b, c1_b, c2_b, c3_b;
+ float clut_r, clut_g, clut_b;
+ for (i = 0; i < length; i++) {
+ unsigned char in_b = *src++;
+ unsigned char in_g = *src++;
+ unsigned char in_r = *src++;
+ unsigned char in_a = *src++;
+ float linear_r = in_r/255.0f, linear_g=in_g/255.0f, linear_b = in_b/255.0f;
+
+ int x = floor(linear_r * (transform->grid_size-1));
+ int y = floor(linear_g * (transform->grid_size-1));
+ int z = floor(linear_b * (transform->grid_size-1));
+ int x_n = ceil(linear_r * (transform->grid_size-1));
+ int y_n = ceil(linear_g * (transform->grid_size-1));
+ int z_n = ceil(linear_b * (transform->grid_size-1));
+ float rx = linear_r * (transform->grid_size-1) - x;
+ float ry = linear_g * (transform->grid_size-1) - y;
+ float rz = linear_b * (transform->grid_size-1) - z;
+
+ c0_r = CLU(r_table, x, y, z);
+ c0_g = CLU(g_table, x, y, z);
+ c0_b = CLU(b_table, x, y, z);
+
+ if( rx >= ry ) {
+ if (ry >= rz) { //rx >= ry && ry >= rz
+ c1_r = CLU(r_table, x_n, y, z) - c0_r;
+ c2_r = CLU(r_table, x_n, y_n, z) - CLU(r_table, x_n, y, z);
+ c3_r = CLU(r_table, x_n, y_n, z_n) - CLU(r_table, x_n, y_n, z);
+ c1_g = CLU(g_table, x_n, y, z) - c0_g;
+ c2_g = CLU(g_table, x_n, y_n, z) - CLU(g_table, x_n, y, z);
+ c3_g = CLU(g_table, x_n, y_n, z_n) - CLU(g_table, x_n, y_n, z);
+ c1_b = CLU(b_table, x_n, y, z) - c0_b;
+ c2_b = CLU(b_table, x_n, y_n, z) - CLU(b_table, x_n, y, z);
+ c3_b = CLU(b_table, x_n, y_n, z_n) - CLU(b_table, x_n, y_n, z);
+ } else {
+ if (rx >= rz) { //rx >= rz && rz >= ry
+ c1_r = CLU(r_table, x_n, y, z) - c0_r;
+ c2_r = CLU(r_table, x_n, y_n, z_n) - CLU(r_table, x_n, y, z_n);
+ c3_r = CLU(r_table, x_n, y, z_n) - CLU(r_table, x_n, y, z);
+ c1_g = CLU(g_table, x_n, y, z) - c0_g;
+ c2_g = CLU(g_table, x_n, y_n, z_n) - CLU(g_table, x_n, y, z_n);
+ c3_g = CLU(g_table, x_n, y, z_n) - CLU(g_table, x_n, y, z);
+ c1_b = CLU(b_table, x_n, y, z) - c0_b;
+ c2_b = CLU(b_table, x_n, y_n, z_n) - CLU(b_table, x_n, y, z_n);
+ c3_b = CLU(b_table, x_n, y, z_n) - CLU(b_table, x_n, y, z);
+ } else { //rz > rx && rx >= ry
+ c1_r = CLU(r_table, x_n, y, z_n) - CLU(r_table, x, y, z_n);
+ c2_r = CLU(r_table, x_n, y_n, z_n) - CLU(r_table, x_n, y, z_n);
+ c3_r = CLU(r_table, x, y, z_n) - c0_r;
+ c1_g = CLU(g_table, x_n, y, z_n) - CLU(g_table, x, y, z_n);
+ c2_g = CLU(g_table, x_n, y_n, z_n) - CLU(g_table, x_n, y, z_n);
+ c3_g = CLU(g_table, x, y, z_n) - c0_g;
+ c1_b = CLU(b_table, x_n, y, z_n) - CLU(b_table, x, y, z_n);
+ c2_b = CLU(b_table, x_n, y_n, z_n) - CLU(b_table, x_n, y, z_n);
+ c3_b = CLU(b_table, x, y, z_n) - c0_b;
+ }
+ }
+ } else {
+ if (rx >= rz) { //ry > rx && rx >= rz
+ c1_r = CLU(r_table, x_n, y_n, z) - CLU(r_table, x, y_n, z);
+ c2_r = CLU(r_table, x, y_n, z) - c0_r;
+ c3_r = CLU(r_table, x_n, y_n, z_n) - CLU(r_table, x_n, y_n, z);
+ c1_g = CLU(g_table, x_n, y_n, z) - CLU(g_table, x, y_n, z);
+ c2_g = CLU(g_table, x, y_n, z) - c0_g;
+ c3_g = CLU(g_table, x_n, y_n, z_n) - CLU(g_table, x_n, y_n, z);
+ c1_b = CLU(b_table, x_n, y_n, z) - CLU(b_table, x, y_n, z);
+ c2_b = CLU(b_table, x, y_n, z) - c0_b;
+ c3_b = CLU(b_table, x_n, y_n, z_n) - CLU(b_table, x_n, y_n, z);
+ } else {
+ if (ry >= rz) { //ry >= rz && rz > rx
+ c1_r = CLU(r_table, x_n, y_n, z_n) - CLU(r_table, x, y_n, z_n);
+ c2_r = CLU(r_table, x, y_n, z) - c0_r;
+ c3_r = CLU(r_table, x, y_n, z_n) - CLU(r_table, x, y_n, z);
+ c1_g = CLU(g_table, x_n, y_n, z_n) - CLU(g_table, x, y_n, z_n);
+ c2_g = CLU(g_table, x, y_n, z) - c0_g;
+ c3_g = CLU(g_table, x, y_n, z_n) - CLU(g_table, x, y_n, z);
+ c1_b = CLU(b_table, x_n, y_n, z_n) - CLU(b_table, x, y_n, z_n);
+ c2_b = CLU(b_table, x, y_n, z) - c0_b;
+ c3_b = CLU(b_table, x, y_n, z_n) - CLU(b_table, x, y_n, z);
+ } else { //rz > ry && ry > rx
+ c1_r = CLU(r_table, x_n, y_n, z_n) - CLU(r_table, x, y_n, z_n);
+ c2_r = CLU(r_table, x, y_n, z_n) - CLU(r_table, x, y, z_n);
+ c3_r = CLU(r_table, x, y, z_n) - c0_r;
+ c1_g = CLU(g_table, x_n, y_n, z_n) - CLU(g_table, x, y_n, z_n);
+ c2_g = CLU(g_table, x, y_n, z_n) - CLU(g_table, x, y, z_n);
+ c3_g = CLU(g_table, x, y, z_n) - c0_g;
+ c1_b = CLU(b_table, x_n, y_n, z_n) - CLU(b_table, x, y_n, z_n);
+ c2_b = CLU(b_table, x, y_n, z_n) - CLU(b_table, x, y, z_n);
+ c3_b = CLU(b_table, x, y, z_n) - c0_b;
+ }
+ }
+ }
+
+ clut_r = c0_r + c1_r*rx + c2_r*ry + c3_r*rz;
+ 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_b*255.0f);
+ *dest++ = clamp_u8(clut_g*255.0f);
+ *dest++ = clamp_u8(clut_r*255.0f);
+ *dest++ = in_a;
+ }
+}
+
// Using lcms' tetra interpolation code.
static void qcms_transform_data_tetra_clut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) {
unsigned int i;
@@ -769,6 +919,43 @@ static void qcms_transform_data_rgba_out_lut(qcms_transform *transform, unsigned
}
}
+static void qcms_transform_data_bgra_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
+{
+ unsigned int i;
+ float (*mat)[4] = transform->matrix;
+ for (i = 0; i < length; i++) {
+ unsigned char device_b = *src++;
+ unsigned char device_g = *src++;
+ unsigned char device_r = *src++;
+ unsigned char alpha = *src++;
+ float out_device_r, out_device_g, out_device_b;
+
+ float linear_r = transform->input_gamma_table_r[device_r];
+ float linear_g = transform->input_gamma_table_g[device_g];
+ float linear_b = transform->input_gamma_table_b[device_b];
+
+ float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + mat[2][0]*linear_b;
+ 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;
+
+ out_linear_r = clamp_float(out_linear_r);
+ out_linear_g = clamp_float(out_linear_g);
+ out_linear_b = clamp_float(out_linear_b);
+
+ out_device_r = lut_interp_linear(out_linear_r,
+ transform->output_gamma_lut_r, transform->output_gamma_lut_r_length);
+ out_device_g = lut_interp_linear(out_linear_g,
+ transform->output_gamma_lut_g, transform->output_gamma_lut_g_length);
+ 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_b*255);
+ *dest++ = clamp_u8(out_device_g*255);
+ *dest++ = clamp_u8(out_device_r*255);
+ *dest++ = alpha;
+ }
+}
+
#if 0
static void qcms_transform_data_rgb_out_linear(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
{
@@ -1068,6 +1255,8 @@ qcms_transform* qcms_transform_precacheLUT_float(qcms_transform *transform, qcms
transform->grid_size = samples;
if (in_type == QCMS_DATA_RGBA_8) {
transform->transform_fn = qcms_transform_data_tetra_clut_rgba;
+ } else if (in_type == QCMS_DATA_BGRA_8) {
+ transform->transform_fn = qcms_transform_data_tetra_clut_bgra;
} else {
transform->transform_fn = qcms_transform_data_tetra_clut;
}
@@ -1102,7 +1291,8 @@ qcms_transform* qcms_transform_create(
return NULL;
}
if (out_type != QCMS_DATA_RGB_8 &&
- out_type != QCMS_DATA_RGBA_8) {
+ out_type != QCMS_DATA_RGBA_8 &&
+ out_type != QCMS_DATA_BGRA_8) {
assert(0 && "output type");
transform_free(transform);
return NULL;
@@ -1151,7 +1341,8 @@ qcms_transform* qcms_transform_create(
struct matrix in_matrix, out_matrix, result;
if (in_type != QCMS_DATA_RGB_8 &&
- in_type != QCMS_DATA_RGBA_8){
+ in_type != QCMS_DATA_RGBA_8 &&
+ in_type != QCMS_DATA_BGRA_8){
assert(0 && "input type");
transform_free(transform);
return NULL;
@@ -1161,6 +1352,8 @@ qcms_transform* qcms_transform_create(
if (sse_version_available() >= 2) {
if (in_type == QCMS_DATA_RGB_8)
transform->transform_fn = qcms_transform_data_rgb_out_lut_sse2;
+ else if (in_type == QCMS_DATA_BGRA_8)
+ transform->transform_fn = qcms_transform_data_bgra_out_lut_sse2;
else
transform->transform_fn = qcms_transform_data_rgba_out_lut_sse2;
@@ -1171,6 +1364,8 @@ qcms_transform* qcms_transform_create(
if (sse_version_available() >= 1) {
if (in_type == QCMS_DATA_RGB_8)
transform->transform_fn = qcms_transform_data_rgb_out_lut_sse1;
+ else if (in_type == QCMS_DATA_BGRA_8)
+ transform->transform_fn = qcms_transform_data_bgra_out_lut_sse1;
else
transform->transform_fn = qcms_transform_data_rgba_out_lut_sse1;
#endif
@@ -1179,12 +1374,16 @@ qcms_transform* qcms_transform_create(
{
if (in_type == QCMS_DATA_RGB_8)
transform->transform_fn = qcms_transform_data_rgb_out_lut_precache;
+ else if (in_type == QCMS_DATA_BGRA_8)
+ transform->transform_fn = qcms_transform_data_bgra_out_lut_precache;
else
transform->transform_fn = qcms_transform_data_rgba_out_lut_precache;
}
} else {
if (in_type == QCMS_DATA_RGB_8)
transform->transform_fn = qcms_transform_data_rgb_out_lut;
+ else if (in_type == QCMS_DATA_BGRA_8)
+ transform->transform_fn = qcms_transform_data_bgra_out_lut;
else
transform->transform_fn = qcms_transform_data_rgba_out_lut;
}
« no previous file with comments | « third_party/qcms/src/qcmsint.h ('k') | third_party/qcms/src/transform-sse1.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698