/* anaglyphe.c superimpose 2 sets of images, left in red and right in green, to make anaglyphs. For viewing, can use Lee filters 106 (primary red) and 139 (primary green) Usage: anaglyphe infileleft infileright outfile [-b n] [-d n] [-l n] [-k] [-z] Flags- -b : begin at frame "n" (default: 1). -d : set debug parameter to "n" (default: 1). -l : do "n" images (default: all). -k : keep intermediate directory and files. -z : do not compress final files 20 Apr 1998 put red on the left! 14 Apr 1997 begin at optional frame number 17 Jun 1996 use ppm format input and output image files 21 Apr 1996 written (Don Herbison-Evans) File format (ppm) - 4 lines of format data - P3 width height maxcols then three integers per pixel of width*height values. subroutines - main - organises things getpar - get invoked parameters getfile - get the image files tryfile - try various file types isfile - find full name of image file checkhead - check header of image file doframe - load line buffer and print it exec - execute a system command getout - exit gracefully combine - print combined image line out openout - open output file */ #include #include #define BMAX 256 /* size of string buffers */ #define CMAX 256 /* number of values of each colour */ #define PMAX 1000 /* max number of frames */ #define XMAX 1024 /* max width of image */ #define TRUE 1 #define FALSE 0 int cmax; int cmaxl; int cmaxr; char blank; /* blanks to separate images */ char bgr,bgl; /* backgrounds of images */ char buf[BMAX]; /* input string buffer */ char cmnd[BMAX]; /* shell command string buffer */ char err[BMAX]; /* error message string buffer */ char filelname[BMAX]; /* original left image file name */ char filername[BMAX]; /* original right image file name */ char finame[BMAX]; /* current input file name */ char fliname[BMAX]; /* root+image type left file name stem */ char friname[BMAX]; /* root+image type right file name stem */ char flname[BMAX]; /* root name of left image file names */ char frname[BMAX]; /* root name of right image file names */ char foname[BMAX]; /* root name of output files */ char home[BMAX] = "/rose/don"; char infile[BMAX]; /* current input image file name */ char outfile[BMAX]; /* output image file name */ int black; int count; /* output file line counter */ int debug; /* <= 0 for debugging info to be printed */ int f; /* current frame number */ int frno; /* frame number read from image file */ int flheight; /* height of the left image */ int frheight; /* height of the right image */ int first = TRUE; /* true when doing first frame */ int fwidth,fheight; /* size of current image */ int flwidth; /* width of the left image */ int frwidth; /* width of the right image */ int height; /* height of output image */ int keep; /* true if intermediate files to be kept */ int length; /* number of frames to be processed */ int line[XMAX]; /* output line buffer */ int nfr; /* number of current frame */ int ok; /* true if image file obtained */ int pack; /* true if final files to be compressed */ int start; /* number of first frame file */ int step; /* increment between frame numbers */ int stop; /* number of last frame file */ int white; int width; /* width of output image */ FILE *INFILE; FILE *INFILEL; FILE *INFILER; FILE *OUTFILE; /************************************************/ main(argc,argv) int argc; char *argv[]; /* calls getpar, getfiles, getout. */ { black = 0; white = 255; keep = FALSE; pack = TRUE; getpar(argc,argv); getfiles(); getout(0); } /* main */ /************************************************/ getpar(argc,argv) int argc; char *argv[]; /* get the parameters called by main. calls getout. */ { int p; int x; int value; debug = 1; start = 0; step = 1; length = PMAX; stop = length; blank = 255; if (argc < 4) { sprintf(cmnd,"more %s/src.nudes/anaglyphe.c\n",home); exec(cmnd); exit(0); } else { for ( p = 1; p < argc; ++ p) { sprintf(buf,"%s",argv[p]); if (debug <= 0) printf("getpara %d %s %c\n", p,argv[p],buf[0]); if (buf[0] != '-') { if (p == 1) sprintf(flname,"%s",argv[p]); else if (p == 2) sprintf(frname,"%s",argv[p]); else if (p == 3) sprintf(foname,"%s",argv[p]); else { sprintf(err,"anaglyphe: funny %dth parameter:%s",p,argv[p]); getout(1); } } /* buf0 != - */ else if (buf[1] == 'b') { ++p; sscanf(argv[p],"%d",&start); } else if (buf[1] == 'd') { ++p; sscanf(argv[p],"%d",&debug); } else if (buf[1] == 'k') keep = TRUE; else if (buf[1] == 'l') { ++p; sscanf(argv[p],"%d",&length); } else if (buf[1] == 'z') pack = FALSE; else { sprintf(err,"unrecognized flag: %s",argv[p]); getout(1); } } } if (length == PMAX) { length = (length-1)*step+1; if (step != 1) printf( "max length changed to %d\n",length); } stop = start + step*length ; if (debug <= 0) { printf("left file %s\n",flname); printf("right file %s\n",frname); } } /* getpar */ /************************************************/ getfiles() /* run through files called by main. calls isfile, tryfile, doframe, getout. */ { int nextl,nextr; int tryfile(); int isfile(); if (debug <= 0) printf("getfilesa %s %s %d\n",flname,frname,start); f = 0; first = TRUE; sprintf(fliname,"%s",flname); sprintf(friname,"%s",frname); if (start < 0) start = 0; if (start == 0) { if ((tryfile(start,flname,fliname) == FALSE) || (tryfile(start,frname,friname) == FALSE)) start = 1; } stop = start+step*length; if (debug <= 0) printf("getfilesb %d %d\n",start,stop); for ( nfr = start; nfr < stop; nfr += step) { if (debug <= 0) printf("getfilesc %d\n",nfr); nextl = tryfile(nfr,flname,fliname); nextr = tryfile(nfr,frname,friname); if (debug <= 0) printf("getfilesd %d\n",nfr); nextl = isfile(fliname,nfr); if (nextl == FALSE) break; checkhead(); if (debug < 0) printf("getfilese %d %d %d\n",fwidth,fheight,cmax); INFILEL = INFILE; bgl = 255; flwidth = fwidth; flheight = fheight; cmaxl = cmax; nextr = isfile(friname,nfr); if (nextr == FALSE) break; checkhead(); if (debug < 0) printf("getfilesf %d %d %d\n",fwidth,fheight,cmax); INFILER = INFILE; bgr = 255; frwidth = fwidth; frheight = fheight; cmaxr = cmax; if (debug <= 0) printf("getfilesg %d %d\n",flwidth,frwidth); if ((nextl == TRUE) && (nextr == TRUE)) { openout(nfr); if (flwidth > frwidth) width = flwidth; else width = frwidth; if (flheight > frheight) height = flheight; else height = frheight; if (cmaxl > cmaxr) cmax = cmaxl; else cmax = cmaxr; fprintf(OUTFILE,"P3\n"); fprintf(OUTFILE," %d\n",width); fprintf(OUTFILE," %d\n",height); fprintf(OUTFILE," %d\n",cmax); doframe(); if (count > 0) fprintf(OUTFILE,"\n"); fclose(OUTFILE); sprintf(cmnd,"chmod 775 %s\n",outfile); exec(cmnd); sprintf(cmnd,"rm %s.Z 2>/usr/tmp/mess\n",outfile); exec(cmnd); sprintf(cmnd,"compress %s\n",outfile); --debug; if (pack == TRUE) exec(cmnd); ++debug; } /* next true */ else { if (nfr == start) { sprintf(err, "can't open file like %s or %s for reading", fliname,friname); sprintf(cmnd,"rm -rf /tmp/%s.*\n",fliname); if (keep == FALSE) exec(cmnd); sprintf(cmnd,"rm -rf /tmp/%s.*\n",friname); if (keep == FALSE) exec(cmnd); getout(1); } /* nfr = start */ else { sprintf(cmnd,"rm -rf /tmp/%s.*\n",fliname); if (keep == FALSE) exec(cmnd); sprintf(cmnd,"rm -rf /tmp/%s.*\n",friname); if (keep == FALSE) exec(cmnd); goto dis; } /* nfr = start */ } /* next false */ sprintf(cmnd,"rm -rf /tmp/%s*\n",fliname); if (keep == FALSE) exec(cmnd); sprintf(cmnd,"rm -rf /tmp/%s*\n",friname); if (keep == FALSE) exec(cmnd); if (f > length) { printf("more than %d frames\n",length); ok = FALSE; goto dis; } /* f > length */ ++ f; } /* nfr */ dis: if (f != 1) printf("%d frames written\n",f); else printf("%d frame written\n",f); sprintf(cmnd,"rm -rf /tmp/%s*\n",fliname); if (keep == FALSE) exec(cmnd); sprintf(cmnd,"rm -rf /tmp/%s*\n",friname); if (keep == FALSE) exec(cmnd); if (debug <= 0) printf("getfilesh %d %d\n",start,stop); } /* getfiles */ /***********************************************/ int tryfile(nfr,fname,finame) int nfr; char fname[CMAX]; char finame[CMAX]; /* try various types of files for same root name 'fname' and frame number 'nfr', leaving name in 'finame' if ok. called by getfiles. calls isfile. */ { int k; if (debug < 0) printf("tryfilea %d %s\n",nfr,fname); sprintf(finame,"%s",fname); if (isfile(finame,nfr) == TRUE) goto gotit; sprintf(finame,"%s.ppm",fname); if (isfile(finame,nfr) == TRUE) goto gotit; return(FALSE); gotit: fclose(INFILE); if (debug <= 0) printf("tryfileb %s %d %d %d %d\n", fname,nfr,flwidth,flheight,frwidth,frheight); return(TRUE); } /* tryfile */ /*************************************************/ int isfile(ftmp1,nfr) char ftmp1[BMAX]; int nfr; /* check whether there is a file for nfr'th frame. called by getfiles, tryfile. calls getout. */ { int comprd; /* true if current frame is compressed */ int ok; char filename[BMAX]; char ftmp2[BMAX]; char ftmp3[BMAX]; char ftmpz[BMAX]; ok = FALSE; sprintf(ftmp2,"ftmp2"); sprintf(ftmp3,"ftmp3"); sprintf(ftmpz,"ftmpz"); sprintf(filename,"filename"); comprd = FALSE; if (first == TRUE) { sprintf(filename,"%s",ftmp1); if (debug < 0) printf("isfilea trying %s\n",ftmp1); if( NULL != (INFILE=fopen(ftmp1,"r")) ) { sprintf(infile,"%s",ftmp1); length = 1; ok = TRUE; } else { sprintf(ftmpz,"%s.Z",ftmp1); sprintf(filename,"%s",ftmpz); if (debug < 0) printf("isfileb trying %s\n",ftmpz); if (NULL != (INFILE=fopen(ftmpz,"r")) ) { sprintf(cmnd,"zcat %s >/tmp/%s\n",ftmpz,ftmp1); exec(cmnd); sprintf(ftmp2,"/tmp/%s",ftmp1); if (debug < 0) printf("isfilec trying %s\n",ftmp2); if( NULL == (INFILE=fopen(ftmp2,"r")) ) { sprintf(err, "can't open %s (uncompressed %s)",ftmp2,ftmpz); getout(1); } comprd = TRUE; length = 1; ok = TRUE; sprintf(infile,"%s",ftmpz); } } } if (ok == FALSE) { if ((nfr >= 0 ) && (nfr <= 9 )) sprintf(ftmp2,"%s.000%d.ppm",ftmp1,nfr); if ((nfr >= 10) && (nfr <= 99)) sprintf(ftmp2,"%s.00%d.ppm",ftmp1,nfr); if ((nfr >= 100) && (nfr <= 999)) sprintf(ftmp2,"%s.0%d.ppm",ftmp1,nfr); if (nfr >= 1000) sprintf(ftmp2,"%s.%d.ppm",ftmp1,nfr); sprintf(filename,"%s",ftmp2); if (debug < 0) printf("isfiled trying %s\n",ftmp2); if( NULL == (INFILE=fopen(ftmp2,"r")) ) { sprintf(ftmpz,"%s.Z",ftmp2); sprintf(filename,"%s",ftmpz); if (debug < 0) printf("isfilee trying %s\n",ftmpz); if( NULL != (INFILE=fopen(ftmpz,"r")) ) { fclose(INFILE); comprd = TRUE; sprintf(cmnd,"zcat %s >/tmp/%s\n",ftmpz,ftmp2); exec(cmnd); sprintf(ftmp3,"/tmp/%s",ftmp2); if (debug < 0) printf("isfilef trying %s\n",ftmp3); if( NULL == (INFILE=fopen(ftmp3,"r")) ) { sprintf(err, "cannot open %s (uncompressed %s)",ftmp3,ftmpz); getout(1); } sprintf(infile,"%s",ftmpz); ok = TRUE; } } else { sprintf(infile,"%s",ftmp2); ok = TRUE; } } if (debug <= 0) printf("isfileg %d %d %d %s %s %s %s %s %s %s\n", ok,TRUE,nfr,fliname,friname,ftmp1,ftmp2,ftmp3,ftmpz,filename); return(ok); } /* isfile */ /****************************************************/ checkhead() /* check the heading of an image file called by isfile. calls getout. */ { char buf1[BMAX]; int k; int temp; if (debug <= 0) printf("checkheada\n"); for (k = 0; k < 4; ++k) { fscanf(INFILE,"%s\n",buf1); if (debug <= 0) printf("checkheadb %s\n",buf1); if (k != 0) { sscanf(buf1,"%d",&temp); if (k == 1) fwidth = temp; else if (k == 2) fheight = temp; else if (k == 3) cmax = temp; else { sprintf(err, "input header funny, frame %d\n%s\n", nfr,buf1); getout(1); } } } if (debug <= 0) printf("checkheadc %d %d %d\n", nfr,fheight,fwidth); } /* checkhead */ /******************************************/ doframe() /* load line buffer from image files and print it out. called by getfiles. calls getout. */ { int x; int y; int rl,gl,bl; int rr,gr,br; int greyl[XMAX],greyr[XMAX]; if (debug <= 0) printf("doframea %d %d %d %d %d\n", flwidth,CMAX,TRUE,frwidth,width); for (y = 0; y < height; ++y) { for ( x = 0; x < width; ++ x) { if ((x < flwidth) && (y < flheight)) fscanf(INFILEL,"%d %d %d",&rl,&gl,&bl); else { rl = black; gl = black; bl = black; } greyl[x] = (rl + gl + bl)/3; if ((x < frwidth) && (y < frheight)) fscanf(INFILER,"%d %d %d",&rr,&gr,&br); else { rr = black; gr = black; br = black; } greyr[x] = (rr + gr + br)/3; } /* x */ combine(y,width,greyl,greyr); } /* y */ fclose(INFILEL); fclose(INFILER); if (debug <= 0) printf("doframed %d %d\n",width,height); } /* doframe */ /**********************************/ exec(cmnd) char cmnd[BMAX]; /* execute a system command with optional echo called by isfile, getout, getpar, getfiles. */ { if (debug <= 0) printf("%s",cmnd); system(cmnd); } /* exec */ /******************************************/ getout(v) int v; /* exit gracefully called by main, getpar, doframe, checkhead, isfile, getframes, openout. */ { int j; if (v != 0) printf("anaglyphe: %s\n",err); sprintf(cmnd,"rm -rf /tmp/%s*\n",fliname); if (keep == FALSE) exec(cmnd); sprintf(cmnd,"rm -rf /tmp/%s*\n",friname); if (keep == FALSE) exec(cmnd); exit(v); } /* getout */ /*******************************************/ combine(y,width,greyl,greyr) int y,width; int greyl[XMAX],greyr[XMAX]; /* write line out called by doframe. */ { int x; int r,g,b; if (debug < 0) printf("combinea %d\n",width); for (x = 0; x < width; ++x) { r = greyl[x]; g = greyr[x]; b = black; fprintf(OUTFILE,"%3d %3d %3d ",r,g,b); count += 12; if (count > 57) { count = 0; fprintf(OUTFILE,"\n"); } } if (debug < 0) printf("combineb %d\n",y); } /* combine */ /************************************************/ openout(nfr) int nfr; /* open output file called by getfiles. calls getout. */ { if (debug <= 0) printf("openouta %d %s\n",nfr,foname); if ((nfr >= 0 ) && (nfr <= 9 )) sprintf(outfile,"%s.000%d.ppm",foname,nfr); if ((nfr >= 10) && (nfr <= 99)) sprintf(outfile,"%s.00%d.ppm",foname,nfr); if ((nfr >= 100) && (nfr <= 999)) sprintf(outfile,"%s.0%d.ppm",foname,nfr); if (nfr >= 1000) sprintf(outfile,"%s.%d.ppm",foname,nfr); if( NULL == (OUTFILE=fopen(outfile,"w+")) ) { sprintf(err,"cannot open output file %s\n",outfile); getout(1); } count = 0; } /* openout */ /************************************************/ int random() /* return a random integer in the range 0 to 255. note : that a=123465,b=54321,c0=34567 gives a regular grid called by combine. */ { int ans; static unsigned int a=1234589,b=3432,c=4567; c = (b*c)%a; ans = 256*c/a; if (debug < -1) fprintf(stderr,"random %d %d %d %d\n",a,b,c,ans); return(ans); } /* random */ /***************************************************/