From 749ec4ad5ec7d49addeaffec4241cabc3c6f2833 Mon Sep 17 00:00:00 2001 From: paul Date: Sat, 29 Oct 2011 16:35:04 +0000 Subject: [PATCH 1/1] initial commit svn path=/trunk/; revision=2 --- Makefile | 13 ++++ anaglyph.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++ stereofy.sh | 58 ++++++++++++++++++ 3 files changed, 238 insertions(+) create mode 100644 Makefile create mode 100644 anaglyph.c create mode 100755 stereofy.sh diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a608ae8 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +CC = gcc +CCFLAGS = -Wall +BINDIR = ~/.bin + +anaglyph: anaglyph.c + ${CC} ${CCFLAGS} -oanaglyph anaglyph.c + +install: anaglyph stereofy.sh + cp anaglyph ${BINDIR} + cp stereofy.sh ${BINDIR}/stereofy + +clean: + rm anaglyph diff --git a/anaglyph.c b/anaglyph.c new file mode 100644 index 0000000..3a325be --- /dev/null +++ b/anaglyph.c @@ -0,0 +1,167 @@ +#include +#include +#include + +int error(int code); +int mm(int v, int min, int max); +int anaglyph(FILE *in1, FILE *in2, FILE *out, char *alg); +unsigned char* colorize(unsigned char *out, const unsigned char *left, const unsigned char *right, const char *alg); +unsigned char* full_gm(unsigned char *out, const unsigned char *l, const unsigned char *r); +unsigned char* half_gm(unsigned char *out, const unsigned char *l, const unsigned char *r); +unsigned char* dubois_gm(unsigned char *out, const unsigned char *l, const unsigned char *r); +unsigned char* full_rc(unsigned char *out, const unsigned char *l, const unsigned char *r); +unsigned char* half_rc(unsigned char *out, const unsigned char *l, const unsigned char *r); +unsigned char* dubois_rc(unsigned char *out, const unsigned char *l, const unsigned char *r); +unsigned char* full_mc(unsigned char *out, const unsigned char *l, const unsigned char *r); +unsigned char* dubois_mc(unsigned char *out, const unsigned char *l, const unsigned char *r); +unsigned char* dubois_ab(unsigned char *out, const unsigned char *l, const unsigned char *r); + +int main(int argc, char *argv[]){ + FILE *in1, *in2, *out; int cnt; char *alg = malloc(5); + in1 = in2 = out = NULL; alg = strcpy(alg, "-dgm"); + + if (argc < 4 || argc > 5) return error(1); + for (cnt = 1; cnt < argc; cnt++) { + if (argv[cnt][0] == '-') alg = strcpy(alg, argv[cnt]); + else if (!in1){ if ((in1 = fopen(argv[cnt], "r")) == NULL) return error(2);} + else if (!in2){ if ((in2 = fopen(argv[cnt], "r")) == NULL) return error(2);} + else if (!out){ if ((out = fopen(argv[cnt], "w")) == NULL) return error(3);} + } + return anaglyph(in1, in2, out, alg); +} + +int error(int code){ + char *msg = "Unknown Error\n"; + switch (code) { + case 1: msg = "Usage: anaglyph [ -[fhd]gm | -[fhd]rc | -fmc | -dab ] left.rgb right.rgb output.rgb\n"; + case 2: msg = "Could not open input file for reading\n"; + case 3: msg = "Could not open output file for writing\n"; + case 4: msg = "Unexpected end of file\n"; + case 5: msg = "Cannot write to output file\n"; + } + fprintf(stderr, msg); return code; +} + +// min-max to prevent overflowing in Dubois calculations +int mm(int v, int min, int max){ + if (v < min) return min; + else if (v > max) return max; + else return v; +} + +//green-magenta full-color +unsigned char* full_gm(unsigned char *out, const unsigned char *l, const unsigned char *r){ + out[0] = r[0]; + out[1] = l[1]; + out[2] = r[2]; + return out; +} + +//green-magenta half-color +unsigned char* half_gm(unsigned char *out, const unsigned char *l, const unsigned char *r){ + out[0] = r[0]; + //green channel is derived from chroma value of left image + out[1] = (unsigned char)(int)((299*(int)l[0] + 587*(int)l[1] + 114*(int)l[2]) / 1000); + out[2] = r[2]; + + return out; +} + +//green-magenta Dubois +unsigned char* dubois_gm(unsigned char *out, const unsigned char *l, const unsigned char *r){ + out[0] = (unsigned char)mm((-62*(int)l[0] + -158*(int)l[1] + -39*(int)l[2] + + 529*(int)r[0] + 705*(int)r[1] + 24*(int)r[2]) / 1000, 0, 255); + out[1] = (unsigned char)mm((284*(int)l[0] + 668*(int)l[1] + 143*(int)l[2] + + -16*(int)r[0] + -15*(int)r[1] + -65*(int)r[2]) / 1000, 0, 255); + out[2] = (unsigned char)mm((-15*(int)l[0] + -27*(int)l[1] + 21*(int)l[2] + + 9*(int)r[0] + 75*(int)r[1] + 937*(int)r[2]) / 1000, 0, 255); + return out; +} + +//red-cyan full-color +unsigned char* full_rc(unsigned char *out, const unsigned char *l, const unsigned char *r){ + out[0] = l[0]; + out[1] = r[1]; + out[2] = r[2]; + return out; +} + +//red-cyan half-color +unsigned char* half_rc(unsigned char *out, const unsigned char *l, const unsigned char *r){ + //red channel is derived from chroma value of left image + out[0] = (unsigned char)(int)((299*(int)l[0] + 587*(int)l[1] + 114*(int)l[2]) / 1000); + out[1] = r[1]; + out[2] = r[2]; + + return out; +} + +//red-cyan Dubois +unsigned char* dubois_rc(unsigned char *out, const unsigned char *l, const unsigned char *r){ + out[0] = (unsigned char)mm((456*(int)l[0] + 500*(int)l[1] + 176*(int)l[2] + + -43*(int)r[0] + -88*(int)r[1] + -2*(int)r[2]) / 1000, 0, 255); + out[1] = (unsigned char)mm((-40*(int)l[0] + -38*(int)l[1] + -16*(int)l[2] + + 378*(int)r[0] + 734*(int)r[1] + -18*(int)r[2]) / 1000, 0, 255); + out[2] = (unsigned char)mm((-15*(int)l[0] + -21*(int)l[1] + -5*(int)l[2] + + -72*(int)r[0] +-113*(int)r[1] + 1226*(int)r[2]) / 1000, 0, 255); + return out; +} + +//magenta-cyan full-color +unsigned char* full_mc(unsigned char *out, const unsigned char *l, const unsigned char *r){ + out[0] = l[0]; + out[1] = r[1]; + out[2] = (unsigned char)(((int)r[2] + (int)l[2]) / 2); + return out; +} + +//magenta-cyan "Dubois" +unsigned char* dubois_mc(unsigned char *out, const unsigned char *l, const unsigned char *r){ + out[0] = (unsigned char)mm((529*(int)l[0] + 705*(int)l[1] + 24*(int)l[2] + + -62*(int)r[0] +-158*(int)r[1] + -39*(int)r[2]) / 1000, 0, 255); + out[1] = (unsigned char)mm((-40*(int)l[0] + -38*(int)l[1] + -16*(int)l[2] + + 378*(int)r[0] + 734*(int)r[1] + -18*(int)r[2]) / 1000, 0, 255); + out[2] = (unsigned char)mm((-15*(int)l[0] + -24*(int)l[1] + 8*(int)l[2] + + -32*(int)r[0] + -19*(int)r[1] + 1081*(int)r[2]) / 1000, 0, 255); + +// out[2] = (unsigned char)mm((-15*(int)l[0] + -27*(int)l[1] + 21*(int)l[2] + gm +// 9*(int)r[0] + 75*(int)r[1] + 937*(int)r[2]) / 1000, 0, 255); +// out[2] = (unsigned char)mm((-15*(int)l[0] + -21*(int)l[1] + -5*(int)l[2] + rc +// -72*(int)r[0] +-113*(int)r[1] + 1226*(int)r[2]) / 1000, 0, 255); + return out; +} + +//amber-blue Dubois +unsigned char* dubois_ab(unsigned char *out, const unsigned char *l, const unsigned char *r){ + out[0] = (unsigned char)mm((1062*(int)l[0] + -205*(int)l[1] +299*(int)l[2] + + -16*(int)r[0] +-123*(int)r[1] + -17*(int)r[2]) / 1000, 0, 255); + out[1] = (unsigned char)mm((-26*(int)l[0] + 908*(int)l[1] + 68*(int)l[2] + + 6*(int)r[0] + 62*(int)r[1] + -17*(int)r[2]) / 1000, 0, 255); + out[2] = (unsigned char)mm((-38*(int)l[0] + -173*(int)l[1] + 22*(int)l[2] + + 94*(int)r[0] + 185*(int)r[1] + 911*(int)r[2]) / 1000, 0, 255); + return out; +} + +unsigned char* colorize(unsigned char *out, const unsigned char *left, const unsigned char *right, const char *alg){ + if (!strcmp(alg, "-fgm")) return full_gm(out, left, right); + if (!strcmp(alg, "-hgm")) return half_gm(out, left, right); + if (!strcmp(alg, "-dgm")) return dubois_gm(out, left, right); + + if (!strcmp(alg, "-frc")) return full_rc(out, left, right); + if (!strcmp(alg, "-hrc")) return half_rc(out, left, right); + if (!strcmp(alg, "-drc")) return dubois_rc(out, left, right); + + if (!strcmp(alg, "-fmc")) return full_mc(out, left, right); + if (!strcmp(alg, "-dmc")) return dubois_mc(out, left, right); + if (!strcmp(alg, "-dab")) return dubois_ab(out, left, right); + exit(error(1)); return out; +} + +int anaglyph(FILE *in1, FILE *in2, FILE *out, char *alg){ + unsigned char *i1 = malloc(3), *i2 = malloc(3), *o = malloc(3); + + while (fread( i1, 1, 3, in1) && fread( i2, 1, 3, in2)){ + if (!fwrite(colorize( o, i1, i2, alg), 1, 3, out)) return error(5); + } + return 0; +} diff --git a/stereofy.sh b/stereofy.sh new file mode 100755 index 0000000..919c2a8 --- /dev/null +++ b/stereofy.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +algo="d" #algorythm, Dubois by default +model="gm" #color model, green-magenta by default +param="" #leave blank, will be -$algo$model +left='' +right='' +stereo='' + +while [ -n "$1" ]; do + case "$1" in + -d|--dubois]) algo="d" + ;; + -f|--full|--full-color]) algo="f" + ;; + -h|--half|--half-color]) algo="d" + ;; + -rc|--rc|--red-cyan) model="rc" + ;; + -mc|--mc|--magenta-cyan) model="mc" + ;; + -gm|--gm|--green-magenta) model="gm" + ;; + -ab|--ab|--amber-blue|yellow-blue) model="ab" + ;; + -[dfh]rc|-[dfh]gm|-[fd]mc|-dab) param="$1" + ;; + *) if [ -z "$left" ]; then + left="$1" + elif [ -z "$right" ]; then + right="$1" + elif [ -z "$stereo" ]; then + stereo="$1" + fi + ;; + esac + shift 1; +done + +[ -z "$param" ] && param="-$algo$model" +[ -z "$stereo" ] && stereo="${left}_stereo.jpg" + +geom=$(identify "$left" |sed -rn 's:^.* ([0-9]+x[0-9]+) .*$:\1:gp') + +echo -n bitmapping... +stream "$left" "$left.bts" +stream "$right" "$right.bts" + +echo -n anaglyphing... +anaglyph "$param" "$left.bts" "$right.bts" "$stereo.bts" + +if [ $? = 0 ]; then + echo -n converting... + convert -depth 8 -size "$geom" "rgb:$stereo.bts" "$stereo" +fi + +echo cleaning... +rm "$left.bts" "$right.bts" "$stereo.bts" 2>/dev/null -- 2.39.2