/*------------------------------------------------------------------------ * * Copyright (c) 1997-1998 by Cornell University. * * See the file "license.txt" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * mpgtoppm.c * * Wei Tsang Ooi weitsang@cs.cornell.edu * * Usage : mpgtoppm inputMPG * * Decodes an MPEG video into a series of PPM files. * *------------------------------------------------------------------------ */ #include <sys/types.h> #include <sys/stat.h> #include "dvmbasic.h" #include "dvmavi.h" #include "dvmpnm.h" /* * This procedure encode 3 byte image into a bitstream bs, * using bitparser bp, and output it to a tcl channel called * name. Assumes that the header is already encoded in the * bitstream. (This is an improvement over the routines in pnmlib.tcl * since it reuse the same header and bitstream) */ void WritePPM (r, g, b, bs, bp, name) ByteImage *r; ByteImage *g; ByteImage *b; BitStream *bs; BitParser *bp; char *name; { FILE *chan; int curr; chan = fopen(name, "wb"); if (chan == NULL) { fprintf(stderr, "unable to open %s for reading.\n", name); exit(1); } curr = BitParserTell(bp); PpmEncode(r, g, b, bp); BitStreamFileWrite(bs, chan, 0); BitParserSeek(bp, curr); fclose(chan); } int main(int argc, char *argv[]) { BitParser *outbp; BitStream *outbs; ByteImage *r, *g, *b; PnmHdr *pnmhdr; AviFile *aviFile; AviStream *aviStream; int seqw, seqh; int i, len; char outname[100]; /* * Check arguments, open file, and initialize BitStream. */ if (argc < 1) { fprintf(stderr, "usage : %s input\n", argv[0]); exit(1); } AVIFileInit(); if (AviFileOpen(argv[1], &aviFile)) { fprintf(stderr, "unable to open %s as an avi file for reading.\n", argv[1]); exit(1); } if (AviStreamOpen(aviFile, 0, &aviStream)) { fprintf(stderr, "unable to open stream 0.\n", argv[1]); exit(1); } seqw = ((AviVideoStream *)aviStream->data)->width; seqh = ((AviVideoStream *)aviStream->data)->height; len = aviStream->length; r = ByteNew (seqw, seqh); g = ByteNew (seqw, seqh); b = ByteNew (seqw, seqh); /* * Create a new PnmHdr and encode it to the BitStream. We only do * this once, since all frames have the same header. */ pnmhdr = PnmHdrNew(); PnmHdrSetType(pnmhdr, PPM_BIN); PnmHdrSetWidth(pnmhdr, seqw); PnmHdrSetHeight(pnmhdr, seqh); PnmHdrSetMaxVal(pnmhdr, 255); outbs = BitStreamNew(3*seqw*seqh + 20); outbp = BitParserNew(); BitParserWrap(outbp, outbs); PnmHdrEncode(pnmhdr, outbp); PnmHdrFree(pnmhdr); AviStreamStartDecode(aviStream); for (i=0; i<len; i++) { AviVideoFrameRead(aviStream, r, g, b); sprintf(outname, "%03di.ppm", i); WritePPM(r, g, b, outbs, outbp, outname); fprintf(stderr, "Frame %d\n", i); } /* * Clean up the stuff. */ ByteFree(r); ByteFree(g); ByteFree(b); AviStreamClose(aviStream); AviFileClose(aviFile); return 0; }