initial commit
authorpaul <paul@plutz.net>
Sat, 29 Oct 2011 16:35:04 +0000 (16:35 +0000)
committerpaul <paul@plutz.net>
Sat, 29 Oct 2011 16:35:04 +0000 (16:35 +0000)
svn path=/trunk/; revision=2

Makefile [new file with mode: 0644]
anaglyph.c [new file with mode: 0644]
stereofy.sh [new file with mode: 0755]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
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 (file)
index 0000000..3a325be
--- /dev/null
@@ -0,0 +1,167 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+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 (executable)
index 0000000..919c2a8
--- /dev/null
@@ -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