/* * This is the main part */ #include "video.h" #include "proto.h" #include <sys/types.h> #include <signal.h> #include "util.h" /* Define buffer length. */ #define BUF_LENGTH 65536 char animname[1024]; /* Declaration of global variable to hold dither info. */ int ditherType; /* Global file pointer to incoming data. */ FILE *input; /* End of File flag. */ static int EOF_flag = 0; /* Loop flag. */ int loopFlag = 0; /* Quiet flag. */ int quietFlag = 0; /* Display image on screen? */ int noDisplayFlag = 0; /* Setjmp/Longjmp env. */ jmp_buf env; /* HAM6 rendering / HAM hires flag */ extern int ham6, lores; /* modeid of CyberGraphX screen */ unsigned long modeid = 0xffffffff; /* Method of picture conversion */ void (*DoDitherImage)(unsigned char *l, unsigned char *Cr, unsigned char *Cb, unsigned char *disp, int h, int w); static char version[]="$VER: aMiPEG 0.5 (compiled on " __DATE__ ", " __TIME__ ")\n"; /* *-------------------------------------------------------------- * * get_more_data -- * * Called by correct_underflow in bit parsing utilities to * read in more data. * * Results: * Input buffer updated, buffer length updated. * Returns 1 if data read, 0 if EOF, -1 if error. * * Side effects: * None. * *-------------------------------------------------------------- */ int get_more_data(unsigned int *buf_start, int max_length, int *length_ptr, unsigned int **buf_ptr) { int length, num_read, request; unsigned char *buffer, *mark; if (EOF_flag) return 0; length = *length_ptr; buffer = (unsigned char *) *buf_ptr; if (length > 0) { memcpy((unsigned char *) buf_start, buffer, (length*4)); mark = ((unsigned char *) (buf_start + length)); } else { mark = (unsigned char *) buf_start; length = 0; } request = (max_length-length)*4; num_read = fread( mark, 1, request, input); /* Paulo Villegas - 26/1/1993: Correction for 4-byte alignment */ { int num_read_rounded; unsigned char *index; num_read_rounded = num_read & 0xfffffffc; /* this can happen only if num_read<request; i.e. end of file reached */ if( num_read_rounded < num_read ) { num_read_rounded+=4; /* fill in with zeros */ for( index=mark+num_read; index<mark+num_read_rounded; *(index++)=0 ); /* advance to the next 4-byte boundary */ num_read = num_read_rounded; } } if (num_read < 0) { return -1; } else if (num_read == 0) { *buf_ptr = buf_start; /* Make 32 bits after end equal to 0 and 32 bits after that equal to seq end code in order to prevent messy data from infinite recursion. */ *(buf_start + length) = 0x0; *(buf_start + length+1) = SEQ_END_CODE; EOF_flag = 1; return 0; } num_read >>= 2; *buf_ptr = buf_start; *length_ptr = length + num_read; return 1; } /* *-------------------------------------------------------------- * * int_handler -- * * Handles Cntl-C interupts.. * * Results: * None. * * Side effects: * None. * *-------------------------------------------------------------- */ void int_handler(int dummy) { if (!quietFlag) fprintf(stderr, "Interrupted!\n"); if (curVidStream) DestroyVidStream(curVidStream); exit(1); } /* *-------------------------------------------------------------- * * main -- * * Parses command line, starts decoding and displaying. * * Results: * None. * * Side effects: * None. * *-------------------------------------------------------------- */ void main(int argc, char **argv) { char *name; static VidStream *theStream; int mark; extern int lores; mark = 1; argc--; name = ""; input = stdin; ditherType = FULL_COLOR_DITHER; noDisplayFlag = 0; while (argc) { if (strcmp(argv[mark], "-nop") == 0) { TogglePFlag(); argc--; mark++; } else if (strcmp(argv[mark], "-nob") == 0) { ToggleBFlag(); argc--; mark++; } else if (strcmp(argv[mark], "-display") == 0) { name = argv[++mark]; argc -= 2; mark++; } else if (strcmp(argv[mark], "-dither") == 0) { argc--; mark++; if (argc < 1) { perror("Must specify dither option after -dither flag"); usage(argv[0]); } if (strcmp(argv[mark], "gray") == 0) { argc--; mark++; ditherType = GRAY_DITHER; } else if (strcmp(argv[mark], "color") == 0) { argc--; mark++; ditherType = FULL_COLOR_DITHER; } else if (strcmp(argv[mark], "hiresham") == 0) { argc--; mark++; ditherType = FULL_COLOR_DITHER; lores = FALSE; } else if (strcmp(argv[mark], "ham6") == 0) { argc--; mark++; ditherType = FULL_COLOR_DITHER; ham6 = TRUE; } else if (strcmp(argv[mark], "cybergfx") == 0) { argc--; mark++; ditherType = CYBERGFX_DITHER; } else if (strcmp(argv[mark], "cybergfxgray") == 0) { argc--; mark++; ditherType = CYBERGFXGRAY_DITHER; } else if (strcmp(argv[mark], "none") == 0) { argc--; mark++; ditherType = NO_DITHER; } else { perror("Illegal dither option."); usage(argv[0]); } } else if (strcmp(argv[mark], "-eachstat") == 0) { argc--; mark++; #ifdef ANALYSIS showEachFlag = 1; #else fprintf(stderr, "To use -eachstat, recompile with -DANALYSIS in CFLAGS\n"); exit(1); #endif } else if (strcmp(argv[mark], "-quiet") == 0) { argc--; mark++; quietFlag = 1; } else if (strcmp(argv[mark], "-loop") == 0) { argc--; mark++; loopFlag = 1; } else if (strcmp(argv[mark], "-no_display") == 0) { argc--; mark++; noDisplayFlag = 1; } else if (strcmp(argv[mark], "-modeid") == 0) { argc--; mark++; if(sscanf(argv[mark], "%x", &modeid) != 1) { fprintf(stderr, "ModeID not given.\n",argv[mark]); usage(argv[0]); } argc--; mark++; } else if (argv[mark][0] == '-') { fprintf(stderr, "Unrecognized flag %s\n",argv[mark]); usage(argv[0]); } else { input = fopen(argv[mark], "r"); if (input == NULL) { fprintf(stderr, "Could not open file %s\n", argv[mark]); usage(argv[0]); } strcpy(animname, argv[mark]); argc--; mark++; } } signal(SIGINT, int_handler); init_tables(); switch (ditherType) { case CYBERGFX_DITHER: InitColorDither(); modeid = InitCyberGfxDisplay(modeid); HAM8_draw = (void (*)(void *, int, int)) DrawCyberGfxImage; DoDitherImage = ColorDitherImage_RGB; break; case CYBERGFXGRAY_DITHER: InitColorDither(); modeid = InitCyberGfxDisplay(modeid); HAM8_draw = (void (*)(void *, int, int)) DrawCyberGfxImage; DoDitherImage = NoDitherImage; break; case GRAY_DITHER: InitGrayDisplay(name); break; case FULL_COLOR_DITHER: InitColorDither(); InitColorDisplay(name); break; case NO_DITHER: HAM8_draw = (void (*)(void *, int, int)) NoDitherImage; // method casting ... argh! DoDitherImage = NoDitherImage; break; } /* * The new restart handling has not been checked out very closely with changing * (non)intra scale matrices! */ theStream = NewVidStream(BUF_LENGTH); if (setjmp(env) != 0) { mpegInitVidRsrc(); /* fix bug in static first in mpegVidRsrc */ rewind(input); EOF_flag = 0; theStream->bit_offset = 0; theStream->buf_length = 0; theStream->buffer = NULL; totNumFrames = 0; #ifdef ANALYSIS init_stats(); #endif } realTimeStart = ReadSysClock(); while (mpegVidRsrc(0, theStream)); } /* *-------------------------------------------------------------- * * usage -- * * Print mpeg_play usage * * Results: * None. * * Side effects: * exits with a return value -1 * *-------------------------------------------------------------- */ void usage(char *s) /* program name */ { fprintf(stderr, "Usage:\n"); fprintf(stderr, "mpeg_play\n"); fprintf(stderr, " [-nob]\n"); fprintf(stderr, " [-nop]\n"); fprintf(stderr, " [-dither {gray|color|ham6|hiresham|cybergfx|cybergfxmono|none}]\n"); fprintf(stderr, " [-modeid nnnnnnnn]\n"); fprintf(stderr, " [-loop]\n"); fprintf(stderr, " [-eachstat]\n"); fprintf(stderr, " [-no_display]\n"); fprintf(stderr, " [-quiet]\n"); fprintf(stderr, " file_name\n"); exit (-1); } /* * Dummy display method * */ void NoDitherImage(unsigned char *l, unsigned char *Cr, unsigned char *Cb, unsigned char *disp, int h, int w) {}