/*------------------------------------------------------------------------
*
* 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;
}