6 int mm(int v, int min, int max);
7 int anaglyph(FILE *in1, FILE *in2, FILE *out,
8 unsigned char* (*alg)(unsigned char*, const unsigned char*, const unsigned char*) );
9 unsigned char* (*parse_func(const char *arg))(unsigned char*, const unsigned char*, const unsigned char*);
11 unsigned char* full_gm(unsigned char *out, const unsigned char *l, const unsigned char *r);
12 unsigned char* half_gm(unsigned char *out, const unsigned char *l, const unsigned char *r);
13 unsigned char* dubois_gm(unsigned char *out, const unsigned char *l, const unsigned char *r);
14 unsigned char* full_rc(unsigned char *out, const unsigned char *l, const unsigned char *r);
15 unsigned char* half_rc(unsigned char *out, const unsigned char *l, const unsigned char *r);
16 unsigned char* dubois_rc(unsigned char *out, const unsigned char *l, const unsigned char *r);
17 unsigned char* full_mc(unsigned char *out, const unsigned char *l, const unsigned char *r);
18 unsigned char* dubois_mc(unsigned char *out, const unsigned char *l, const unsigned char *r);
19 unsigned char* dubois_ab(unsigned char *out, const unsigned char *l, const unsigned char *r);
21 int main(int argc, char *argv[]){
22 FILE *in1, *in2, *out; int cnt; in1 = in2 = out = NULL;
23 unsigned char* (*alg)(unsigned char[], const unsigned char[], const unsigned char[]) = &dubois_rc;
25 if (argc < 4 || argc > 5) return error(1);
26 for (cnt = 1; cnt < argc; cnt++) {
27 if (argv[cnt][0] == '-') alg = parse_func(argv[cnt]);
28 else if (!in1){ if ((in1 = fopen(argv[cnt], "r")) == NULL) return error(2);}
29 else if (!in2){ if ((in2 = fopen(argv[cnt], "r")) == NULL) return error(2);}
30 else if (!out){ if ((out = fopen(argv[cnt], "w")) == NULL) return error(3);}
32 return anaglyph(in1, in2, out, alg);
36 char *msg = "Unknown Error\n";
38 case 1: msg = "Usage: anaglyph [ -[fhd]gm | -[fhd]rc | -fmc | -dab ] left.rgb right.rgb output.rgb\n";
39 case 2: msg = "Could not open input file for reading\n";
40 case 3: msg = "Could not open output file for writing\n";
41 case 4: msg = "Unexpected end of file\n";
42 case 5: msg = "Cannot write to output file\n";
44 fprintf(stderr, msg); return code;
47 // min-max to prevent overflowing in Dubois calculations
48 int mm(int v, int min, int max){
49 if (v < min) return min;
50 else if (v > max) return max;
54 //green-magenta full-color
55 unsigned char* full_gm(unsigned char *out, const unsigned char *l, const unsigned char *r){
62 //green-magenta half-color
63 unsigned char* half_gm(unsigned char *out, const unsigned char *l, const unsigned char *r){
65 //green channel is derived from chroma value of left image
66 out[1] = (unsigned char)(int)((299*(int)l[0] + 587*(int)l[1] + 114*(int)l[2]) / 1000);
72 //green-magenta Dubois
73 unsigned char* dubois_gm(unsigned char *out, const unsigned char *l, const unsigned char *r){
74 out[0] = (unsigned char)mm((-62*(int)l[0] + -158*(int)l[1] + -39*(int)l[2] +
75 529*(int)r[0] + 705*(int)r[1] + 24*(int)r[2]) / 1000, 0, 255);
76 out[1] = (unsigned char)mm((284*(int)l[0] + 668*(int)l[1] + 143*(int)l[2] +
77 -16*(int)r[0] + -15*(int)r[1] + -65*(int)r[2]) / 1000, 0, 255);
78 out[2] = (unsigned char)mm((-15*(int)l[0] + -27*(int)l[1] + 21*(int)l[2] +
79 9*(int)r[0] + 75*(int)r[1] + 937*(int)r[2]) / 1000, 0, 255);
84 unsigned char* full_rc(unsigned char *out, const unsigned char *l, const unsigned char *r){
92 unsigned char* half_rc(unsigned char *out, const unsigned char *l, const unsigned char *r){
93 //red channel is derived from chroma value of left image
94 out[0] = (unsigned char)(int)((299*(int)l[0] + 587*(int)l[1] + 114*(int)l[2]) / 1000);
102 unsigned char* dubois_rc(unsigned char *out, const unsigned char *l, const unsigned char *r){
103 out[0] = (unsigned char) mm((456*(int)l[0] + 500*(int)l[1] + 176*(int)l[2] +
104 -43*(int)r[0] + -88*(int)r[1] + -2*(int)r[2]) / 1000, 0, 255);
105 out[1] = (unsigned char) mm((-40*(int)l[0] + -38*(int)l[1] + -16*(int)l[2] +
106 378*(int)r[0] + 734*(int)r[1] + -18*(int)r[2]) / 1000, 0, 255);
107 out[2] = (unsigned char) mm((-15*(int)l[0] + -21*(int)l[1] + -5*(int)l[2] +
108 -72*(int)r[0] +-113*(int)r[1] + 1226*(int)r[2]) / 1000, 0, 255);
112 //magenta-cyan full-color
113 unsigned char* full_mc(unsigned char *out, const unsigned char *l, const unsigned char *r){
116 out[2] = (unsigned char)(((int)r[2] + (int)l[2]) / 2);
120 //magenta-cyan experimental
121 unsigned char* experimental_mc(unsigned char *out, const unsigned char *l, const unsigned char *r){
122 out[0] = (unsigned char) mm((556*(int)l[0] + 400*(int)l[1] + 176*(int)l[2] +
123 -43*(int)r[0] + -88*(int)r[1] + -2*(int)r[2]) / 950, 0, 255);
124 out[1] = (unsigned char) mm((-40*(int)l[0] + -38*(int)l[1] + -16*(int)l[2] +
125 278*(int)r[0] + 734*(int)r[1] + -18*(int)r[2]) / 1100, 0, 255);
126 out[2] = (unsigned char) mm((-15*(int)l[0] + -21*(int)l[1] + 600*(int)l[2] +
127 -72*(int)r[0] +-113*(int)r[1] + 621*(int)r[2]) / 950, 0, 255);
132 unsigned char* dubois_ab(unsigned char *out, const unsigned char *l, const unsigned char *r){
133 out[0] = (unsigned char)mm((1062*(int)l[0] + -205*(int)l[1] +299*(int)l[2] +
134 -16*(int)r[0] +-123*(int)r[1] + -17*(int)r[2]) / 1000, 0, 255);
135 out[1] = (unsigned char)mm((-26*(int)l[0] + 908*(int)l[1] + 68*(int)l[2] +
136 6*(int)r[0] + 62*(int)r[1] + -17*(int)r[2]) / 1000, 0, 255);
137 out[2] = (unsigned char)mm((-38*(int)l[0] + -173*(int)l[1] + 22*(int)l[2] +
138 94*(int)r[0] + 185*(int)r[1] + 911*(int)r[2]) / 1000, 0, 255);
142 unsigned char* (*parse_func(const char *arg))(unsigned char*, const unsigned char*, const unsigned char*){
143 if (!strcmp(arg, "-fgm")) return &full_gm;
144 if (!strcmp(arg, "-hgm")) return &half_gm;
145 if (!strcmp(arg, "-dgm")) return &dubois_gm;
147 if (!strcmp(arg, "-frc")) return &full_rc;
148 if (!strcmp(arg, "-hrc")) return &half_rc;
149 if (!strcmp(arg, "-drc")) return &dubois_rc;
151 if (!strcmp(arg, "-fmc")) return &full_mc;
152 if (!strcmp(arg, "-dab")) return &dubois_ab;
153 if (!strcmp(arg, "-emc")) return &experimental_mc;
154 exit(error(1)); return &dubois_rc;
157 int anaglyph(FILE *in1, FILE *in2, FILE *out,
158 unsigned char* (*alg)(unsigned char*, const unsigned char*, const unsigned char*) ){
159 unsigned char *i1 = malloc(3), *i2 = malloc(3), *o = malloc(3);
161 while (fread( i1, 1, 3, in1) && fread( i2, 1, 3, in2)){
162 if (!fwrite(alg( o, i1, i2), 1, 3, out)) return error(5);