chromium/third_party/qcms/src/chain.c

/* vim: set ts=8 sw=8 noexpandtab: */
//  qcms
//  Copyright (C) 2009 Mozilla Corporation
//  Copyright (C) 1998-2007 Marti Maria
//
// Permission is hereby granted, free of charge, to any person obtaining 
// a copy of this software and associated documentation files (the "Software"), 
// to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, 
// and/or sell copies of the Software, and to permit persons to whom the Software 
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in 
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include <string.h> //memcpy
#include "qcmsint.h"
#include "transform_util.h"
#include "matrix.h"

#ifdef USE_LIBFUZZER
#define ASSERT
#else
#define ASSERT(x)
#endif

static struct matrix build_lut_matrix(struct lutType *lut)
{}

static struct matrix build_mAB_matrix(struct lutmABType *lut)
{}

//Based on lcms cmsLab2XYZ
#define f(t)
#define f_1(t)
static void qcms_transform_module_LAB_to_XYZ(struct qcms_modular_transform *transform, float *src, float *dest, size_t length)
{}

//Based on lcms cmsXYZ2Lab
static void qcms_transform_module_XYZ_to_LAB(struct qcms_modular_transform *transform, float *src, float *dest, size_t length)
{}

static void qcms_transform_module_clut_only(struct qcms_modular_transform *transform, float *src, float *dest, size_t length)
{}

static void qcms_transform_module_clut(struct qcms_modular_transform *transform, float *src, float *dest, size_t length)
{}

/* NOT USED
static void qcms_transform_module_tetra_clut(struct qcms_modular_transform *transform, float *src, float *dest, size_t length)
{
	size_t 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;
	float pcs_r, pcs_g, pcs_b;
	for (i = 0; i < length; i++) {
		float device_r = *src++;
		float device_g = *src++;
		float device_b = *src++;
		float linear_r = lut_interp_linear_float(device_r,
				transform->input_clut_table_r, transform->input_clut_table_length);
		float linear_g = lut_interp_linear_float(device_g,
				transform->input_clut_table_g, transform->input_clut_table_length);
		float linear_b = lut_interp_linear_float(device_b,
				transform->input_clut_table_b, transform->input_clut_table_length);

		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_n, 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_n, 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_n, 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) - 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_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_n, y_n, z_n) - CLU(g_table, x_n, 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_n, y_n, z_n) - CLU(b_table, x_n, y_n, z);
				}
			}
		}

		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;

		pcs_r = lut_interp_linear_float(clut_r,
				transform->output_clut_table_r, transform->output_clut_table_length);
		pcs_g = lut_interp_linear_float(clut_g,
				transform->output_clut_table_g, transform->output_clut_table_length);
		pcs_b = lut_interp_linear_float(clut_b,
				transform->output_clut_table_b, transform->output_clut_table_length);
		*dest++ = clamp_float(pcs_r);
		*dest++ = clamp_float(pcs_g);
		*dest++ = clamp_float(pcs_b);
	}
}
*/

static void qcms_transform_module_gamma_table(struct qcms_modular_transform *transform, float *src, float *dest, size_t length)
{}

static void qcms_transform_module_gamma_lut(struct qcms_modular_transform *transform, float *src, float *dest, size_t length)
{}

static void qcms_transform_module_matrix_translate(struct qcms_modular_transform *transform, float *src, float *dest, size_t length)
{}

static void qcms_transform_module_matrix(struct qcms_modular_transform *transform, float *src, float *dest, size_t length)
{}

static struct qcms_modular_transform* qcms_modular_transform_alloc() {}

static void qcms_modular_transform_release(struct qcms_modular_transform *transform)
{}

/* Set transform to be the next element in the linked list. */
static void append_transform(struct qcms_modular_transform *transform, struct qcms_modular_transform ***next_transform)
{}

/* reverse the transformation list (used by mBA) */
static struct qcms_modular_transform* reverse_transform(struct qcms_modular_transform *transform) 
{}

#define EMPTY_TRANSFORM_LIST
static struct qcms_modular_transform* qcms_modular_transform_create_mAB(struct lutmABType *lut)
{}

static struct qcms_modular_transform* qcms_modular_transform_create_lut(struct lutType *lut)
{}

struct qcms_modular_transform* qcms_modular_transform_create_input(qcms_profile *in)
{}
static struct qcms_modular_transform* qcms_modular_transform_create_output(qcms_profile *out)
{}

/* Not Completed
// Simplify the transformation chain to an equivalent transformation chain
static struct qcms_modular_transform* qcms_modular_transform_reduce(struct qcms_modular_transform *transform)
{
	struct qcms_modular_transform *first_transform = NULL;
	struct qcms_modular_transform *curr_trans = transform;
	struct qcms_modular_transform *prev_trans = NULL;
	while (curr_trans) {
		struct qcms_modular_transform *next_trans = curr_trans->next_transform;
		if (curr_trans->transform_module_fn == qcms_transform_module_matrix) {
			if (next_trans && next_trans->transform_module_fn == qcms_transform_module_matrix) {
				curr_trans->matrix = matrix_multiply(curr_trans->matrix, next_trans->matrix);
				goto remove_next;	
			}
		}
		if (curr_trans->transform_module_fn == qcms_transform_module_gamma_table) {
			bool isLinear = true;
			uint16_t i;
			for (i = 0; isLinear && i < 256; i++) {
				isLinear &= (int)(curr_trans->input_clut_table_r[i] * 255) == i;
				isLinear &= (int)(curr_trans->input_clut_table_g[i] * 255) == i;
				isLinear &= (int)(curr_trans->input_clut_table_b[i] * 255) == i;
			}
			goto remove_current;
		}
		
next_transform:
		if (!next_trans) break;
		prev_trans = curr_trans;
		curr_trans = next_trans;
		continue;
remove_current:
		if (curr_trans == transform) {
			//Update head
			transform = next_trans;
		} else {
			prev_trans->next_transform = next_trans;
		}
		curr_trans->next_transform = NULL;
		qcms_modular_transform_release(curr_trans);
		//return transform;
		return qcms_modular_transform_reduce(transform);
remove_next:
		curr_trans->next_transform = next_trans->next_transform;
		next_trans->next_transform = NULL;
		qcms_modular_transform_release(next_trans);
		continue;
	}
	return transform;
}
*/

static struct qcms_modular_transform* qcms_modular_transform_create(qcms_profile *in, qcms_profile *out)
{}

static float* qcms_modular_transform_data(struct qcms_modular_transform *transform, float *src, float *dest, size_t len)
{}

float* qcms_chain_transform(qcms_profile *in, qcms_profile *out, float *src, float *dest, size_t lutSize)
{}

qcms_bool qcms_profile_white_transform(qcms_profile *profile, float XYZ[3])
{}