//takes avi file (given on command line as only arg) and converts to pgms int startframe,endframe; #include #include #include "avitopgms.h" // function prototypes void usage(void); unsigned int pixsz,frame; unsigned char *lpColor,*clp; unsigned int palletized; unsigned int bpscanl, dib_offset,x,y; char basename[100],tailname[100],filename[100]; FILE *fp; float R, G, B; unsigned char fr,fg,fb; // globals int main(int argc, char **argv) { int i=0,j=0, err=0; char avifilename[100] = ""; AVIFILEINFO thisPfi; float fps; int sys_bit_specd = 0, sys_byte_specd = 0; PAVISTREAM pVideoStream; time_t current_time, el_time; if(argc < 2) { usage(); } // parse for paramters here strcpy(avifilename, argv[1]); // initialize AVI subsystem AVIFileInit(); // open avi file and validate file parameters hResult = AVIFileOpen(&pfile, avifilename, OF_READ, 0L); if(hResult) { fprintf(stderr, "\ncould not open filename %s!\n", avifilename); exit(7); } // get info structure on file hResult = AVIFileInfo(pfile, &thisPfi, sizeof(AVIFILEINFO)); if(hResult) { fprintf(stderr, "\n%s does not appear to be an AVI file!\n", avifilename); exit(8); } // open a stream hResult = AVIFileGetStream(pfile, &pVideoStream, streamtypeVIDEO, 0); if(hResult) { fprintf(stderr, "\ncould not retrieve video stream from %s!\n", avifilename); exit(31); } // prepare to decompress frames pget = AVIStreamGetFrameOpen(pVideoStream, NULL); // print details on input file fps = (float)thisPfi.dwRate/(float)thisPfi.dwScale; fprintf(stderr, "%s file details:\nWidth = %u, Height = %u, FPS = %4.2f", avifilename, thisPfi.dwWidth, thisPfi.dwHeight, fps); // now retrieve a video frame so we can identify details // get pointer to bitmap lpbi = AVIStreamGetFrame(pget, 0); if(!lpbi) { fprintf(stderr, "\ncould not retrieve video details for %s!",avifilename); fprintf(stderr, "\nyou probably do not have a codec for this compression scheme!"); fprintf(stderr, "\nor avi file may be corrupt!\n"); exit(9); } // we only handle non-palletized video pixsz = lpbi->biBitCount; if(pixsz!=8) { fprintf(stderr, "\ncan only handle 8 bit video!,"); fprintf(stderr, "\nthis file is %i bits!\n", pixsz); exit(10); } fprintf(stderr, ", Bits per pixel = %u", pixsz); if(thisPfi.dwWidth>4095) { fprintf(stderr, "\nHorizontal width must < 4096!"); err = 1; } if(thisPfi.dwHeight>4095) { fprintf(stderr, "\nVerical height must be < 4096!"); err = 1; } if(err) exit(11); fprintf(stderr, "\nTotal Video Frames = %u, ", thisPfi.dwLength); fprintf(stderr, "Length = %u sec.", (unsigned int)thisPfi.dwLength/(int)(fps+.5)); if (lpbi->biCompression != BI_RGB) { fprintf(stderr, "\ncan not handle compressed DIBs from codec!\n"); err = 1; } // locate color table - should there be one??? lpColor = (unsigned char *)lpbi + lpbi->biSize; fprintf(stderr,"pixel size (bits) %d\n",pixsz); // next, actual DIB if(pixsz==8) palletized=1; else palletized=0; if(palletized) dib_offset = sizeof(BITMAPINFOHEADER) + lpbi->biClrUsed * 4; else dib_offset = sizeof(BITMAPINFOHEADER); // offset past bitmap header lpbitmp = (unsigned char *)lpbi + dib_offset; // pointer to actual bitmap fprintf(stderr,"dib offset %d\n",dib_offset); switch(pixsz) { case 8: bpscanl = (unsigned int)(((lpbi->biWidth + 3)>>2)<<2); break; default: fprintf(stderr, "\ninternal error: illegal pixsz value\n"); exit(28); // should never occur } // convert RGB DIB to YUV (4:2:0) // lpframeY = (unsigned char *)frame[0]; // lpframeU = (unsigned char *)frame[1]; // lpframeV = (unsigned char *)frame[2]; printf("basename - output will be in format basename.number.pgm\n"); scanf("%s",basename); printf("startframe number? (numbering from 0)\n"); scanf("%d",&startframe); printf("endframe number?\n"); scanf("%d",&endframe); if ((startframe<0)||(endframe>thisPfi.dwLength)||(endframebiWidth,lpbi->biHeight); lpbi = AVIStreamGetFrame(pget, frame); for(y = 0; y < (lpbi->biHeight); y++) for(x = 0; x < (lpbi->biWidth); x++) { switch(pixsz) { case 8: lpcurpix = (unsigned char *)(lpbitmp + (lpbi->biHeight - 1 -y) * bpscanl+x) ; break; default: fprintf(stderr, "\ninternal error: illegal pixsz value\n"); exit(29); // should never occur }//case // *lpframeY++ = (int)(RY*R + GY*G + BY*B); // Ubuffer[(hblank/2)+x + (topblank+y)*width] = (int)(RU*R + GU*G + BU*B + 128); // Vbuffer[(hblank/2)+x + (topblank+y)*width] = (int)(RV*R + GV*G + BV*B + 128); fwrite(lpcurpix,1,1,fp); }//for //read in rest of frames fclose(fp); }//end frame loop //clean up AVIStreamGetFrameClose(pget); AVIFileRelease(pfile); AVIFileExit(); return(0); } void usage() { fprintf(stderr,"give avifilename on commandline\n"); exit(0); } // now do FIR chroma subsampling //conv444to422(Ubuffer, Ubuffer422); //conv444to422(Vbuffer, Vbuffer422); //conv422to420(Ubuffer422, frame[1]); //conv422to420(Vbuffer422, frame[2]); // horizontal filter and 2:1 subsampling static void conv444to422(src,dst) unsigned char *src, *dst; { int i, j, im5, im4, im3, im2, im1, ip1, ip2, ip3, ip4, ip5, ip6; for (j=0; j>1] = clp[(int)(228*(src[i]+src[ip1]) +70*(src[im1]+src[ip2]) -37*(src[im2]+src[ip3]) -21*(src[im3]+src[ip4]) +11*(src[im4]+src[ip5]) + 5*(src[im5]+src[ip6])+256)>>9]; } src+= width; dst+= width>>1; } } // vertical filter and 2:1 subsampling static void conv422to420(src,dst) unsigned char *src, *dst; { int w, i, j, jm5, jm4, jm3, jm2, jm1; int jp1, jp2, jp3, jp4, jp5, jp6; w = width>>1; for (i=0; i>1)] = clp[(int)(228*(src[w*j]+src[w*jp1]) +70*(src[w*jm1]+src[w*jp2]) -37*(src[w*jm2]+src[w*jp3]) -21*(src[w*jm3]+src[w*jp4]) +11*(src[w*jm4]+src[w*jp5]) + 5*(src[w*jm5]+src[w*jp6])+256)>>9]; } src++; dst++; } }