Exemplo n.º 1
0
void test_distance_layout(){
	int l = 5, k = 4;
	int radius = 5, width=1;
	graph_t *g = new_ravasz_barabasi(l, k);
	int n = graph_num_vertices(g);
	
	int *distance = malloc(n * sizeof(*distance));
	graph_geodesic_vertex(g, 0, distance);
	
	coord_t *p = malloc(n * sizeof(*p));
	graph_layout_shell(g, width+radius, distance, false, false, p);
	
	color_t solid_red = {255, 0, 0, 255};
	color_t black     = {0,   0, 0, 255};
	
	circle_style_t point_style;
	point_style.radius = radius;
	point_style.width = width;
	color_copy(point_style.fill, solid_red);
	color_copy(point_style.stroke, black);
	
	path_style_t edge_style;
	edge_style.width = width;
	color_copy(edge_style.color, black);
	
	graph_print_svg_one_style("test/test_distance_layout.svg", 0, 0, g, p, 
	                          point_style, edge_style);
	
	free(p);
	delete_graph(g);
}
Exemplo n.º 2
0
void test_degree_layout(){
	int n = 64, k = 4;
	int radius = 5, width=1;
	graph_t *g = new_barabasi_albert(n, k);
	
	coord_t *p = malloc(n * sizeof(*p));
	graph_layout_degree_shell(g, width+radius, true, p);
	
	color_t solid_red = {255, 0, 0, 255};
	color_t black     = {0,   0, 0, 255};
	
	circle_style_t point_style;
	point_style.radius = radius;
	point_style.width = width;
	color_copy(point_style.fill, solid_red);
	color_copy(point_style.stroke, black);
	
	path_style_t edge_style;
	edge_style.width = width;
	color_copy(edge_style.color, black);
	
	graph_print_svg_one_style("test/test_degree_layout.svg", 0, 0, g, p, 
	                          point_style, edge_style);
	
	free(p);
	delete_graph(g);
}
Exemplo n.º 3
0
void test_core_layout(){
	int radius = 5, width=1;
	graph_t *g = load_graph("datasets/email/edges.txt", false);
	int n = graph_num_vertices(g);
	
	coord_t *p = malloc(n * sizeof(*p));
	graph_layout_core_shell(g, width+radius, true, p);
	
	color_t solid_red = {255, 0, 0, 255};
	color_t black     = {0,   0, 0, 255};
	
	circle_style_t point_style;
	point_style.radius = radius;
	point_style.width = width;
	color_copy(point_style.fill, solid_red);
	color_copy(point_style.stroke, black);
	
	path_style_t edge_style;
	edge_style.width = width;
	color_copy(edge_style.color, black);
	
	graph_print_svg_one_style("test/test_core_layout.svg", 0, 0, g, p, 
	                          point_style, edge_style);
	
	free(p);
	delete_graph(g);
}
Exemplo n.º 4
0
void test_random_layout(){
	int n = 64, k = 4;
	int radius = 5, width=1;
	graph_t *g = new_erdos_renyi(n, (double)k);
	
	coord_t *p = malloc(n * sizeof(*p));
	graph_layout_random_wout_overlap(width+radius, 0.5, p, n);
	
	color_t solid_red = {255, 0, 0, 255};
	color_t black     = {0,   0, 0, 255};
	
	circle_style_t point_style;
	point_style.radius = radius;
	point_style.width = width;
	color_copy(point_style.fill, solid_red);
	color_copy(point_style.stroke, black);
	
	path_style_t edge_style;
	edge_style.width = width;
	color_copy(edge_style.color, black);
	
	graph_print_svg_one_style("test/test_random_layout.svg", 0, 0, g, p, 
	                          point_style, edge_style);
	
	free(p);
	delete_graph(g);
}
Exemplo n.º 5
0
void test_circle_layout(){
	int n = 64, k = 4;
	int radius = 5, width=1;
	graph_t *g = new_watts_strogatz(n, k, 0.25);
	
	color_t solid_red = {255, 0, 0, 255};
	color_t black     = {0,   0, 0, 255};
	
	coord_t *p = malloc(n * sizeof(*p));
	double size = graph_layout_circle(width+radius, p, n);
	
	int m = graph_num_edges(g);
	int *es = malloc(m * sizeof(*es));
	path_style_t edge_style[2];
	
	graph_layout_circle_edges(g, size, width, black, es, &edge_style[0]);
	
	int *ps = malloc(n * sizeof(*ps));
	memset(ps, 0, n*sizeof(*ps));
	
	circle_style_t point_style;
	point_style.radius = radius;
	point_style.width = width;
	color_copy(point_style.fill, solid_red);
	color_copy(point_style.stroke, black);
	
	graph_print_svg_some_styles("test/test_circle_layout.svg", 0, 0, g, p, 
	                            ps, &point_style, 1, 
	                            es, edge_style, 2);
	free(ps); free(es);
	free(p);
	delete_graph(g);
}
Exemplo n.º 6
0
float *
get_image_chunk(texture_info * tex, int xmin, int ymin, int xmax, int ymax)
{
    int xbound;
    int ybound;
    float * image_buf = NULL;

    constrain_boundaries(&xmin, &ymin, &xmax, &ymax, tex->width, tex->height);

    xbound = xmax - xmin + 1;
    ybound = ymax - ymin + 1;

    image_buf = allocate_texture(xbound, ybound);

    for(int y = 0; y < ybound; y++)
        for(int x = 0; x < xbound; x++) {
            int buf_index = 4 * (x + y * xbound);

            int offset = calc_pixel_offset(tex, x + xmin, y + ymin);

            color_copy(tex->td_array + offset, image_buf + buf_index);
        }

    return image_buf;
}
Exemplo n.º 7
0
static void
cb_palette_color_selected(void *data, Evas_Object *obj, void *event_info)
{
  Elicit *el = data;
  Color *c = event_info;

  color_copy(c, el->color);
}
Exemplo n.º 8
0
static inline void fill_color(xyStackArray* stack, const T* replace_color, const T* target_color, T* r, T* g, T* b, int width, int x, int y, T tol)
{
  int offset = y * width + x;
  if (!color_equal(replace_color, r[offset], g[offset], b[offset]) && color_is_similar(target_color, r[offset], g[offset], b[offset], tol))
  {
    xyStackArrayPush(stack, x, y);
    color_copy(replace_color, r[offset], g[offset], b[offset]);
  }
}
Exemplo n.º 9
0
design_defaults_s *design_defaults_copy(design_defaults_s *d)
{
  design_defaults_s *nd;

    // Sanity check parameters.
  assert(d);

  nd = design_defaults_create();
  memcpy(nd, d, sizeof(design_defaults_s));

  if (d->line_style) nd->line_style = strdup(d->line_style);
  if (d->fill_style) nd->fill_style = strdup(d->fill_style);

  if (d->background_color) nd->background_color = color_copy(d->background_color);
  if (d->element_color) nd->element_color = color_copy(d->element_color);

    // Return RETVAL
  return nd;
}
Exemplo n.º 10
0
Image *image_deepcopy(const Image *a, Image *out) {
  int wi, hi;

  image_ctor(out, a->width, a->height, a->channels);

  for (hi = 0; hi < a->height; ++hi)
    for (wi = 0; wi < a->width; ++wi)
      color_copy(a->channels, sample(a,wi,hi), sample(out,wi,hi));

  return out;
}
Exemplo n.º 11
0
void test_animation(){
	int n = 64, k = 4;
	int radius = 5, width=1;
	int seed = 42;
	unsigned int state = seed;
	graph_t *g = new_barabasi_albert_r(n, k, &state);
	
	coord_t *p = malloc(n * sizeof(*p));
	double size = graph_layout_degree_shell(g, width+radius, true, p);
	delete_graph(g);
	
	color_t solid_red = {255, 0, 0, 255};
	color_t black     = {0,   0, 0, 255};
	
	circle_style_t point_style;
	point_style.radius = radius;
	point_style.width = width;
	color_copy(point_style.fill, solid_red);
	color_copy(point_style.stroke, black);
	
	path_style_t edge_style;
	edge_style.width = width;
	color_copy(edge_style.color, black);
	
	int i;
	for (i=k+1; i <= n; i++){
		state = seed;
		g = new_barabasi_albert_r(i, k, &state);
		
		char filename[256];
		sprintf(filename, "test/anim_ba/frame%03d.svg", i-k-1);
		graph_print_svg_one_style(filename, (int)size, (int)size, g, p, 
		                          point_style, edge_style);
		
		delete_graph(g);
	}
	
	free(p);
}
Exemplo n.º 12
0
/*
 * Allocate an Element and store a duplicate of the data pointed to by 
 * obj in the Element. Modules do not get duplicated. The function needs
 * to handle each type of object separately in a case statement.
 */
Element *element_init(ObjectType type, void *obj){
	Element *e = malloc(sizeof(Element));
	if(!e){
		printf("malloc failed in element_init\n");
		return NULL;
	}
	e->type = type;
	e->next = NULL;
	switch (e->type) {
		case ObjNone:
			printf("ObjNone not implemented in element_init\n");
			break;
		case ObjLine:
			line_copy(&(e->obj.line), (Line*)obj);
			break;
		case ObjPoint:
			point_copy(&(e->obj.point), (Point*)obj);
			break;
		case ObjPolyline:
  			polyline_init(&(e->obj.polyline));
			polyline_copy(&(e->obj.polyline), (Polyline*)obj);
			break;
		case ObjPolygon:
  			polygon_init(&(e->obj.polygon));
			polygon_copy(&(e->obj.polygon), (Polygon*)obj);
			break;
		case ObjIdentity:
			break;
		case ObjMatrix:
			matrix_copy(&(e->obj.matrix), (Matrix*)obj);
			break;
		case ObjColor:
		case ObjBodyColor:
		case ObjSurfaceColor:
			color_copy(&(e->obj.color), (Color*)obj);
			break;
		case ObjSurfaceCoeff:
			e->obj.coeff = *(float*)obj;
			break;
		case ObjLight:
			printf("ObjLight not implemented in element_init\n");
			break;
		case ObjModule:
			e->obj.module = obj;
			break;
		default:
			printf("ObjectType %d is not handled in element_init\n",type);
	}
	return e;
}
Exemplo n.º 13
0
static void DoRenderFloodFillRGB(T** data, int width, int height, int start_x, int start_y, float* replace_data, float tolerance)
{
  T *r = data[0], *g = data[1], *b = data[2];
  int offset, x, y;
  T target_color[3];
  T replace_color[3];
  T tol = (T)tolerance;

  replace_color[0] = (T)replace_data[0];
  replace_color[1] = (T)replace_data[1];
  replace_color[2] = (T)replace_data[2];

  offset = start_y * width + start_x;
  if (color_equal(replace_color, r[offset], g[offset], b[offset]))
    return;

  color_init(target_color, r[offset], g[offset], b[offset]);

  /* very simple 4 neighbors stack based flood fill */

  xyStackArray* stack = xyStackArrayCreate();

  /* a color in the xy_stack is always similar to the target color,
  and it was already replaced */
  xyStackArrayPush(stack, start_x, start_y);
  color_copy(replace_color, r[offset], g[offset], b[offset]);

  while (xyStackArrayHasData(stack))
  {
    xyStackArrayPop(stack, x, y);

    /* right */
    if (x < width - 1)
      fill_color(stack, replace_color, target_color, r, g, b, width, x + 1, y, tol);

    /* left */
    if (x > 0)
      fill_color(stack, replace_color, target_color, r, g, b, width, x - 1, y, tol);

    /* top */
    if (y < height - 1)
      fill_color(stack, replace_color, target_color, r, g, b, width, x, y + 1, tol);

    /* bottom */
    if (y > 0)
      fill_color(stack, replace_color, target_color, r, g, b, width, x, y - 1, tol);
  }

  xyStackArrayDestroy(stack);
}
Exemplo n.º 14
0
void test_some_styles(){
	graph_t *g = make_a_graph(true);
	
	int width = 1, radius = 6;
	coord_t *p = make_a_position(width, radius);
	
	int num_edge_style = 3;
	int es[] = {0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2};
	path_style_t edge_style[3];
	
	color_t solid_red   = {255, 0, 0, 255};
	color_t solid_green = {0, 255, 0, 255};
	color_t solid_blue  = {0, 0, 255, 255};
	color_t black       = {0, 0, 0,   255};
	
	// Edges within community 0 in blue
	edge_style[0].type = GRAPH_STRAIGHT;
	edge_style[0].width = 1;
	color_copy(edge_style[0].color, solid_blue);
	
	// Edges between communities 0 and 1 in red
	edge_style[1].type = GRAPH_STRAIGHT;
	edge_style[1].width = 1;
	color_copy(edge_style[1].color, solid_red);
	
	// Edges within community 1 in green
	edge_style[2].type = GRAPH_STRAIGHT;
	edge_style[2].width = 1;
	color_copy(edge_style[2].color, solid_green);
	
	int num_point_style = 2;
	int ps[] = {0, 0, 0, 1, 1, 1, 1, 1};
	circle_style_t point_style[2];
	
	// Vertices in community 0 are blue
	point_style[0].radius = radius;
	point_style[0].width = width;
	color_copy(point_style[0].fill, solid_blue);
	color_copy(point_style[0].stroke, black);
	
	// Vertices in community 1 are green
	point_style[1].radius = radius;
	point_style[1].width = width;
	color_copy(point_style[1].fill, solid_green);
	color_copy(point_style[1].stroke, black);
	
	graph_print_svg_some_styles("test/test_some_styles.svg", 0, 0, g, p, 
	                            ps, point_style, num_point_style,
	                            es, edge_style, num_edge_style);
	delete_graph(g);
	free(p);
}
Exemplo n.º 15
0
void Chain::apply(const Color *input, Color *output)
{
	if (!enabled) {
		color_copy(input, output);
		return;
	}
	Color tmp[2];
	Color *tmp_p[3];

	color_copy(input, &tmp[0]);

	tmp_p[0] = &tmp[0];
	tmp_p[1] = &tmp[1];
	for (TransformationList::iterator i = transformation_chain.begin(); i != transformation_chain.end(); i++){

		(*i)->apply(tmp_p[0], tmp_p[1]);

		tmp_p[2] = tmp_p[0];
		tmp_p[0] = tmp_p[1];
		tmp_p[1] = tmp_p[2];
	}

	color_copy(tmp_p[0], output);
}
Exemplo n.º 16
0
paper_s *paper_copy(paper_s *p)
{
  paper_s *np;

    // Sanity check parameters.
  assert(p);

  np = paper_create();
  memcpy(np, p, sizeof(paper_s));

  if (p->margins) np->margins = margins_copy(p->margins);
  if (p->color) np->color = color_copy(p->color);

    // Return RETVAL
  return np;
}
Exemplo n.º 17
0
static Module * genWood(float x, float y, float z, int fill){
	// set up fields
	Module *wood, *outline, *woodpile;
	Color brown0, brown1, dkBrown0, dkBrown1, final, outlineC;
	int thickness, gen;
	// set up different brown colors for wood
	color_set(&brown0, (float)(123/255.0), (float)(63/255.0), 
		0.0);
	color_set(&brown1, (float)(112/255.0), (float)(66/255.0), 
		(float)(20/255.0));
	color_set(&dkBrown0, (float)(101/255.0), (float)(67/255.0), 
		(float)(33/255.0));
	color_set(&dkBrown1, (float)(72/255.0), (float)(60/255.0), 
		(float)(50/255.0));
	color_set(&final, 0, 0, 0);

	// randomly generate a number between 0 and 4 inclusive
	gen = (int)(rand() % 4);
	// select outline color and fill color depending on gen
	if (gen == 0){
		color_copy(&final, &brown0);
		color_copy(&outlineC, &dkBrown0);
	}
Exemplo n.º 18
0
void Transformation::apply(Color *input, Color *output)
{
	color_copy(input, output);
}
Exemplo n.º 19
0
void apply_tmQ_portable(spincolor *out,quad_su3 *conf,double kappa,double mu,spincolor *in)
{
  if(!check_borders_valid(conf)) communicate_lx_quad_su3_borders(conf);
  if(!check_borders_valid(in)) communicate_lx_spincolor_borders(in);
  
  double kcf=1/(2*kappa);
  
  NISSA_LOC_VOL_LOOP(X)
    {
      int Xup,Xdw;
      color temp_c0,temp_c1,temp_c2,temp_c3;
      
      //Forward 0 - backward scatter
      Xup=loclx_neighup[X][0];
      color_summ(temp_c0,in[Xup][0],in[Xup][2]);
      color_summ(temp_c1,in[Xup][1],in[Xup][3]);
      unsafe_su3_prod_color(out[X][0],conf[X][0],temp_c0);
      unsafe_su3_prod_color(out[X][1],conf[X][0],temp_c1);
      color_copy(out[X][2],out[X][0]);
      color_copy(out[X][3],out[X][1]);
      
      //Backward 0
      Xdw=loclx_neighdw[X][0];
      color_subt(temp_c0,in[Xdw][0],in[Xdw][2]);
      color_subt(temp_c1,in[Xdw][1],in[Xdw][3]);
      unsafe_su3_dag_prod_color(temp_c2,conf[Xdw][0],temp_c0);
      unsafe_su3_dag_prod_color(temp_c3,conf[Xdw][0],temp_c1);
      color_summassign(out[X][0],temp_c2);
      color_summassign(out[X][1],temp_c3);
      color_subtassign(out[X][2],temp_c2);
      color_subtassign(out[X][3],temp_c3);
      
      //Forward 1
      Xup=loclx_neighup[X][1];
      color_isumm(temp_c0,in[Xup][0],in[Xup][3]);
      color_isumm(temp_c1,in[Xup][1],in[Xup][2]);
      unsafe_su3_prod_color(temp_c2,conf[X][1],temp_c0);
      unsafe_su3_prod_color(temp_c3,conf[X][1],temp_c1);
      color_summassign(out[X][0],temp_c2);
      color_summassign(out[X][1],temp_c3);
      color_isubtassign(out[X][2],temp_c3);
      color_isubtassign(out[X][3],temp_c2);
      
      //Backward 1
      Xdw=loclx_neighdw[X][1];
      color_isubt(temp_c0,in[Xdw][0],in[Xdw][3]);
      color_isubt(temp_c1,in[Xdw][1],in[Xdw][2]);
      unsafe_su3_dag_prod_color(temp_c2,conf[Xdw][1],temp_c0);
      unsafe_su3_dag_prod_color(temp_c3,conf[Xdw][1],temp_c1);
      color_summassign(out[X][0],temp_c2);
      color_summassign(out[X][1],temp_c3);
      color_isummassign(out[X][2],temp_c3);
      color_isummassign(out[X][3],temp_c2);
      
      //Forward 2
      Xup=loclx_neighup[X][2];
      color_summ(temp_c0,in[Xup][0],in[Xup][3]);
      color_subt(temp_c1,in[Xup][1],in[Xup][2]);
      unsafe_su3_prod_color(temp_c2,conf[X][2],temp_c0);
      unsafe_su3_prod_color(temp_c3,conf[X][2],temp_c1);
      color_summassign(out[X][0],temp_c2);
      color_summassign(out[X][1],temp_c3);
      color_subtassign(out[X][2],temp_c3);
      color_summassign(out[X][3],temp_c2);

      //Backward 2
      Xdw=loclx_neighdw[X][2];
      color_subt(temp_c0,in[Xdw][0],in[Xdw][3]);
      color_summ(temp_c1,in[Xdw][1],in[Xdw][2]);
      unsafe_su3_dag_prod_color(temp_c2,conf[Xdw][2],temp_c0);
      unsafe_su3_dag_prod_color(temp_c3,conf[Xdw][2],temp_c1);
      color_summassign(out[X][0],temp_c2);
      color_summassign(out[X][1],temp_c3);
      color_summassign(out[X][2],temp_c3);
      color_subtassign(out[X][3],temp_c2);

      //Forward 3
      Xup=loclx_neighup[X][3];
      color_isumm(temp_c0,in[Xup][0],in[Xup][2]);
      color_isubt(temp_c1,in[Xup][1],in[Xup][3]);
      unsafe_su3_prod_color(temp_c2,conf[X][3],temp_c0);
      unsafe_su3_prod_color(temp_c3,conf[X][3],temp_c1);
      color_summassign(out[X][0],temp_c2);
      color_summassign(out[X][1],temp_c3);
      color_isubtassign(out[X][2],temp_c2);
      color_isummassign(out[X][3],temp_c3);
      
      //Backward 3
      Xdw=loclx_neighdw[X][3];
      color_isubt(temp_c0,in[Xdw][0],in[Xdw][2]);
      color_isumm(temp_c1,in[Xdw][1],in[Xdw][3]);
      unsafe_su3_dag_prod_color(temp_c2,conf[Xdw][3],temp_c0);
      unsafe_su3_dag_prod_color(temp_c3,conf[Xdw][3],temp_c1);
      color_summassign(out[X][0],temp_c2);
      color_summassign(out[X][1],temp_c3);
      color_isummassign(out[X][2],temp_c2);
      color_isubtassign(out[X][3],temp_c3);
  
      //Put the -1/2 factor on derivative, the gamma5, and the imu
      //ok this is horrible, but fast
      double fac=0.5;
      for(int c=0;c<3;c++)
        {
          out[X][0][c][0]=-fac*out[X][0][c][0]+kcf*in[X][0][c][0]-mu*in[X][0][c][1];
          out[X][0][c][1]=-fac*out[X][0][c][1]+kcf*in[X][0][c][1]+mu*in[X][0][c][0];
          out[X][1][c][0]=-fac*out[X][1][c][0]+kcf*in[X][1][c][0]-mu*in[X][1][c][1];
          out[X][1][c][1]=-fac*out[X][1][c][1]+kcf*in[X][1][c][1]+mu*in[X][1][c][0];
          out[X][2][c][0]=+fac*out[X][2][c][0]-kcf*in[X][2][c][0]-mu*in[X][2][c][1];
          out[X][2][c][1]=+fac*out[X][2][c][1]-kcf*in[X][2][c][1]+mu*in[X][2][c][0];
          out[X][3][c][0]=+fac*out[X][3][c][0]-kcf*in[X][3][c][0]-mu*in[X][3][c][1];
          out[X][3][c][1]=+fac*out[X][3][c][1]-kcf*in[X][3][c][1]+mu*in[X][3][c][0];
        }
    }

}
Exemplo n.º 20
0
void ColorVisionDeficiency::apply(Color *input, Color *output)
{
	Color linear_input, linear_output;
	color_rgb_get_linear(input, &linear_input);
	vector3 vi, vo1, vo2;
	load_vector(&linear_input, &vi);
	matrix3x3 matrix1, matrix2;
	int index = floor(strength * 10);
	int index_secondary = std::min(index + 1, 10);
	float interpolation_factor = 1 - ((strength * 10) - index);

	vector3 lms;
	if ((type == PROTANOPIA) || (type == DEUTERANOPIA) || (type == TRITANOPIA)){
		load_matrix(rgb_to_lms, &matrix1);
		load_matrix(lms_to_rgb, &matrix2);
		vector3_multiply_matrix3x3(&vi, &matrix1, &lms);
	}

	switch (type){
		case PROTANOMALY:
			load_matrix(protanomaly[index], &matrix1);
			load_matrix(protanomaly[index_secondary], &matrix2);
			vector3_multiply_matrix3x3(&vi, &matrix1, &vo1);
			vector3_multiply_matrix3x3(&vi, &matrix2, &vo2);
			break;
		case DEUTERANOMALY:
			load_matrix(deuteranomaly[index], &matrix1);
			load_matrix(deuteranomaly[index_secondary], &matrix2);
			vector3_multiply_matrix3x3(&vi, &matrix1, &vo1);
			vector3_multiply_matrix3x3(&vi, &matrix2, &vo2);
			break;
		case TRITANOMALY:
			load_matrix(tritanomaly[index], &matrix1);
			load_matrix(tritanomaly[index_secondary], &matrix2);
			vector3_multiply_matrix3x3(&vi, &matrix1, &vo1);
			vector3_multiply_matrix3x3(&vi, &matrix2, &vo2);
			break;
		case PROTANOPIA:
			if (lms.z / lms.y < rgb_anchor[2] / rgb_anchor[1]){
				lms.x = -(protanopia_abc[0].y * lms.y + protanopia_abc[0].z * lms.z) / protanopia_abc[0].x;
			}else{
				lms.x = -(protanopia_abc[1].y * lms.y + protanopia_abc[1].z * lms.z) / protanopia_abc[1].x;
			}
			vector3_multiply_matrix3x3(&lms, &matrix2, &vo1);
			load_vector(&linear_input, &vo2);
			interpolation_factor = strength;
			break;
		case DEUTERANOPIA:
			if (lms.z / lms.x < rgb_anchor[2] / rgb_anchor[0]){
				lms.y = -(deuteranopia_abc[0].x * lms.x + deuteranopia_abc[0].z * lms.z) / deuteranopia_abc[0].y;
			}else{
				lms.y = -(deuteranopia_abc[1].x * lms.x + deuteranopia_abc[1].z * lms.z) / deuteranopia_abc[1].y;
			}
			vector3_multiply_matrix3x3(&lms, &matrix2, &vo1);
			load_vector(&linear_input, &vo2);
			interpolation_factor = strength;
			break;
		case TRITANOPIA:
			if (lms.y / lms.x < rgb_anchor[1] / rgb_anchor[0]){
				lms.z = -(tritanopia_abc[0].x * lms.x + tritanopia_abc[0].y * lms.y) / tritanopia_abc[0].z;
			}else{
				lms.z = -(tritanopia_abc[1].x * lms.x + tritanopia_abc[1].y * lms.y) / tritanopia_abc[1].z;
			}
			vector3_multiply_matrix3x3(&lms, &matrix2, &vo1);
			load_vector(&linear_input, &vo2);
			interpolation_factor = strength;
			break;
		default:
			color_copy(input, output);
			return;
	}

	linear_output.rgb.red = vo1.x * interpolation_factor + vo2.x * (1 - interpolation_factor);
	linear_output.rgb.green = vo1.y * interpolation_factor + vo2.y * (1 - interpolation_factor);
	linear_output.rgb.blue = vo1.z * interpolation_factor + vo2.z * (1 - interpolation_factor);
	color_linear_get_rgb(&linear_output, output);
	color_rgb_normalize(output);
}