/* * process -- find and crop out frames from * a scan of a strip of 8mm movie film * * Copyright 2005 Shay Mozes * Adapted from tiffcine.c by Richard J Kinch */ #include #include #include #include "tiffio.h" /* Grayscale value for a given RGB raster word */ #define grayscale(v) ((TIFFGetR(v)+TIFFGetG(v)+TIFFGetB(v))/3) #define threshold(v) ((grayscale(v)>382)) #define grayscale_white 255*3 #define grayscale_black 0 //parameters for 8mm film #define FRAME_HEIGHT 1100 #define FRAME_WIDTH 800 #define BLACK_THRESHOLD 50 #define WHITE_THRESHOLD 240 #define WHITE_THRESHOLD2 200 #define FILM_INCREMENT 8000 #define MINIMAL_GAP 580 #define FRAME_TOL 10 #define HOLE_WIDTH 175 /* Number of text columns to use to plot grayscale values */ #define PLOT_COLUMNS 75 void crop(uint32 *raster,uint32 w,uint32 h, float xres, float yres, uint16 resunits, uint32 x0, uint32 y0, uint32 xN, uint32 yN, char *fname, int rotate) { /* Given an input RGB raster of dimensions (w,h), write a new TIFF */ /* file named fname, the new image being cropped from the input */ /* raster starting at (x0,y0) and having size (xN,yN). If "rotate" */ /* we apply a 90 degree clockwise rotation to the output file. */ TIFF *out; unsigned char *buf, *p; uint32 *q; uint32 row, i; uint32 cw, ch; /* Cropped width/height after rotation */ tsize_t scanlinesize; if (w==0 || h==0) return; if (x0>=w || y0>=h || (x0+xN)>w || (y0+yN)>h) return; if (fopen(fname,"rb")) { fprintf(stderr,"File \"%s\" already exists\n",fname); return; } out = TIFFOpen(fname,"w"); if (out==NULL) return; if (rotate) { cw = yN ; ch = xN ; } else { cw = xN ; ch = yN ; } TIFFSetField(out,TIFFTAG_IMAGEWIDTH,cw); TIFFSetField(out,TIFFTAG_IMAGELENGTH,ch); TIFFSetField(out,TIFFTAG_PHOTOMETRIC,((uint16)PHOTOMETRIC_RGB)); TIFFSetField(out,TIFFTAG_COMPRESSION,((uint16)COMPRESSION_NONE)); TIFFSetField(out,TIFFTAG_SAMPLESPERPIXEL,((uint16)3)); TIFFSetField(out,TIFFTAG_PLANARCONFIG,((uint16)PLANARCONFIG_CONTIG)); TIFFSetField(out,TIFFTAG_BITSPERSAMPLE,((uint16)8)); TIFFSetField(out,TIFFTAG_RESOLUTIONUNIT,(uint16)resunits); TIFFSetField(out,TIFFTAG_XRESOLUTION,(float)xres); TIFFSetField(out,TIFFTAG_YRESOLUTION,(float)yres); scanlinesize = TIFFScanlineSize(out); if (scanlinesize<=0) return; buf = (unsigned char *) _TIFFmalloc(scanlinesize); if (buf==NULL) return; if (rotate) for (row=0; row \n",argv[0]); return(-1); } path[0] = '\0'; strcat(path,"/cygdrive/c/8mm/"); strcat(path,argv[3]); for (fileno=atoi(argv[1]); fileno BLACK_THRESHOLD); start_row = i; // printf("after white lines\n"); /* refine black-threshold */ black = 0; for (i=start_row*w; i<(start_row+10)*w; i++) black += grayscale(raster[i]); black /= 10*w; black += 10; // printf("black point is: %d\n", black); // black = BLACK_THRESHOLD; /* find horizontal beginning of frames*/ /* i=start_row; do { i++; rstats[i] = 0; for(j=0;jh) { printf("could not find frams!!!\n"); // exit(0); } ymax = i + FRAME_HEIGHT; ymin = i; printf("frame Y position: %d - %d.\n", ymin, ymax); */ //find horizontal end of frames by identifying sprocket holes white = WHITE_THRESHOLD; for (i=(w-10)*h-1;i>w*(h-500);i--){ if (grayscale(raster[i]) > white) { i-=FRAME_WIDTH; for (j=0;jw*(h-500)) for(;grayscale(raster[i])>white&&grayscale(raster[i-15*w])>white||grayscale(raster[i+40])>white;i-=w); ymax = i/w-15; ymin = ymax - FRAME_HEIGHT; // printf("frame Y position: %d - %d.\n", ymin, ymax); for(j=0;j= h) tmpmax = h; for(i=tmpmin;i0) { printf("%d, ",xmin[i]-xmax[i-1]); // // if (xmin[i]-xmax[i-1] > FRAME_WIDTH + FRAME_TOL) break; // if (xmin[i]-xmax[i-1] < FRAME_WIDTH - FRAME_TOL) { // cont = 0; //failure... // break; // } numframes++; } // printf("%d -> ",j); } else if(minmax==1) { // printf("%d , ",mstats[j]); if (mstats[j] > black){ xmax[i] = j; minmax = 0; // printf("-> %d (%d)\n",j,xmax[i]-xmin[i]); i++; } } } printf(" - number of frames is %d\n",numframes); } printf("number of frames is %d\n",numframes); */ /* identifiy frames by finding sprocket holes */ numframes = 0; cont = 1; i=0; minmax=0; for(j=10;j white && (j+50>w ||cstats[j+50] > white) ) { xmin[i] = j; minmax = 1; if (i>0) { if (xmin[i]-xmax[i-1] < MINIMAL_GAP) { printf("*%d*", xmin[i]-xmax[i-1]); minmax = 0; j+= 15; continue; } seps[i-1] = (xmin[i]+xmax[i-1])/2; // printf("%d, ",xmin[i]-xmax[i-1]); // printf("seps[%d] = %d , ",i-1,seps[i-1]); numframes++; } // printf("%d -> ",j); } else if(minmax==1) { // printf("%d , ",cstats[j]); if (cstats[j] < white){ if (i>0 && j-xmin[i] < HOLE_WIDTH) { printf("@%d@", j-xmin[i]); j+=25; continue; } xmax[i] = j; minmax = 0; // printf("-> %d (%d)\n",j,xmax[i]-xmin[i]); i++; } } } numframes--; // find additional frames if (seps[0] > FRAME_WIDTH) { for (i=numframes;i>=0;i--) seps[i+1] = seps[i]; seps[0] = seps[1] - (seps[2]-seps[1]); numframes++; } if (seps[numframes] + FRAME_WIDTH < w){ seps[numframes+1] = seps[numframes] + (seps[numframes]-seps[numframes-1]); numframes++; } printf(" - number of frames is %d. ",numframes); imin = discard = 0; //discard frame in case there are\were 11 frames in file. if (numframes == 11 || lastnum == 11) imin++; printf("%d\n",imin); tmpfilename[0] = '\0'; strcat(tmpfilename,path); strcat(tmpfilename,"video/"); strcat(tmpfilename,prefix); sprintf(number,"%03d_",fileno); strcat(tmpfilename,number); for (i=imin;i