home *** CD-ROM | disk | FTP | other *** search
/ Graphics 16,000 / graphics-16000.iso / amiga / mpeg / mpgplyr1.lha / src / main.c < prev    next >
C/C++ Source or Header  |  1992-12-08  |  11KB  |  517 lines

  1. /*
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.
  4.  * 
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  * 
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  * 
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21. #include "video.h"
  22. #include <sys/types.h>
  23. #include <signal.h>
  24. #ifndef MIPS
  25. #include <netinet/in.h>
  26. #else
  27. #include <bsd/netinet/in.h>
  28. #endif
  29.  
  30. #include "util.h"
  31.  
  32. /* Define buffer length. */
  33.  
  34. #define BUF_LENGTH 80000
  35.  
  36. /* Function return type declarations */
  37. void usage();
  38.  
  39. /* External declaration of main decoding call. */
  40.  
  41. extern VidStream *mpegVidRsrc();
  42. extern VidStream *NewVidStream();
  43.  
  44. /* Declaration of global variable to hold dither info. */
  45.  
  46. int ditherType;
  47.  
  48. /* Global file pointer to incoming data. */
  49. FILE *input;
  50.  
  51. /* End of File flag. */
  52. static int EOF_flag = 0;
  53.  
  54. /* Loop flag. */
  55. int loopFlag = 0;
  56.  
  57. /* Shared memory flag. */
  58. int shmemFlag = 0;
  59.  
  60. /* Setjmp/Longjmp env. */
  61. jmp_buf env;
  62.  
  63.  
  64. /*
  65.  *--------------------------------------------------------------
  66.  *
  67.  * get_more_data --
  68.  *
  69.  *    Called by correct_underflow in bit parsing utilities to
  70.  *      read in more data.
  71.  *
  72.  * Results:
  73.  *    Input buffer updated, buffer length updated.
  74.  *      Returns 1 if data read, 0 if EOF, -1 if error.
  75.  *
  76.  * Side effects:
  77.  *      None.
  78.  *
  79.  *--------------------------------------------------------------
  80.  */
  81.  
  82. int 
  83. get_more_data(buf_start, max_length, length_ptr, buf_ptr)
  84.      unsigned int *buf_start;
  85.      int max_length;
  86.      int *length_ptr;
  87.      unsigned int **buf_ptr;
  88. {
  89.   
  90.   int length, num_read, i, request;
  91.   unsigned char *buffer, *mark;
  92.   unsigned int *lmark;
  93.  
  94.   if (EOF_flag) return 0;
  95.  
  96.   length = *length_ptr;
  97.   buffer = (unsigned char *) *buf_ptr;
  98.  
  99.   if (length > 0) {
  100.     memcpy((unsigned char *) buf_start, buffer, (length*4));
  101.     mark = ((unsigned char *) (buf_start + length));
  102.   }
  103.   else {
  104.     mark = (unsigned char *) buf_start;
  105.     length = 0;
  106.   }
  107.  
  108.   request = (max_length-length)*4;
  109.   
  110.   num_read = fread( mark, 1, request, input);
  111.  
  112.   if (num_read < 0) {
  113.     return -1;
  114.   }
  115.   else if (num_read == 0) {
  116.     *buf_ptr = buf_start;
  117.     
  118.     /* Make 32 bits after end equal to 0 and 32
  119.        bits after that equal to seq end code
  120.        in order to prevent messy data from infinite
  121.        recursion.
  122.     */
  123.  
  124.     *(buf_start + length) = 0x0;
  125.     *(buf_start + length+1) = SEQ_END_CODE;
  126.  
  127.     EOF_flag = 1;
  128.     return 0;
  129.   }
  130.  
  131.   lmark = (unsigned int *) mark;
  132.  
  133.   num_read = num_read/4;
  134.  
  135.   for (i=0; i<num_read; i++) {
  136.     *lmark = htonl(*lmark);
  137.     lmark++;
  138.   }
  139.  
  140.   *buf_ptr = buf_start;
  141.   *length_ptr = length + num_read;
  142.  
  143.   return 1;
  144. }
  145.  
  146. /*
  147.  *--------------------------------------------------------------
  148.  *
  149.  * int_handler --
  150.  *
  151.  *    Handles Cntl-C interupts..
  152.  *
  153.  * Results:
  154.  *    None.
  155.  *
  156.  * Side effects:
  157.  *    None.
  158.  *
  159.  *--------------------------------------------------------------
  160.  */
  161. void
  162. int_handler()
  163. {
  164.   fprintf(stderr, "Interrupted!\n");
  165.   if (curVidStream != NULL)
  166.     DestroyVidStream(curVidStream);
  167.   exit(1);
  168. }
  169.  
  170.  
  171. /*
  172.  *--------------------------------------------------------------
  173.  *
  174.  * main --
  175.  *
  176.  *    Parses command line, starts decoding and displaying.
  177.  *
  178.  * Results:
  179.  *    None.
  180.  *
  181.  * Side effects:
  182.  *    None.
  183.  *
  184.  *--------------------------------------------------------------
  185.  */
  186.  
  187. void
  188. main(argc, argv)
  189.      int argc;
  190.      char **argv;
  191. {
  192.  
  193.   static VidStream *theStream;
  194.   int mark;
  195.   int i;
  196.  
  197.   mark = 1;
  198.   argc--;
  199.  
  200.   input = stdin;
  201.   ditherType = ORDERED_DITHER;
  202.  
  203. #ifdef SH_MEM
  204.   shmemFlag = 1;
  205. #endif
  206.  
  207.   while (argc) {
  208.     if (strcmp(argv[mark], "-nop") == 0) {
  209.       TogglePFlag();
  210.       argc--; mark++;
  211.     } else if (strcmp(argv[mark], "-nob") == 0) {
  212.       ToggleBFlag();
  213.       argc--; mark++;
  214.     } else if (strcmp(argv[mark], "-dither") == 0) {
  215.       argc--; mark++;
  216.       if (argc < 1) {
  217.     perror("Must specify dither option after -dither flag");
  218.     usage(argv[0]);
  219.       }
  220.       if (strcmp(argv[mark], "hybrid") == 0) {
  221.     argc--; mark++;
  222.     ditherType = HYBRID_DITHER;
  223.       } else if (strcmp(argv[mark], "hybrid2") == 0) {
  224.     argc--; mark++;
  225.     ditherType = HYBRID2_DITHER;
  226.       } else if (strcmp(argv[mark], "fs4") == 0) {
  227.     argc--; mark++;
  228.     ditherType = FS4_DITHER;
  229.       } else if (strcmp(argv[mark], "fs2") == 0) {
  230.     argc--; mark++;
  231.     ditherType = FS2_DITHER;
  232.       } else if (strcmp(argv[mark], "fs2fast") == 0) {
  233.     argc--; mark++;
  234.     ditherType = FS2FAST_DITHER;
  235.       } else if (strcmp(argv[mark], "hybrid2") == 0) {
  236.     argc--; mark++;
  237.     ditherType = HYBRID2_DITHER;
  238.       } else if (strcmp(argv[mark], "2x2") == 0) {
  239.     argc--; mark++;
  240.     ditherType = Twox2_DITHER;
  241.       } else if (strcmp(argv[mark], "gray") == 0) {
  242.     argc--; mark++;
  243.     ditherType = GRAY_DITHER;
  244.       } else if (strcmp(argv[mark], "color") == 0) {
  245.     argc--; mark++;
  246.     ditherType = FULL_COLOR_DITHER;
  247.       } else if (strcmp(argv[mark], "none") == 0) {
  248.     argc--; mark++;
  249.     ditherType = NO_DITHER;
  250.       } else if (strcmp(argv[mark], "ordered") == 0) {
  251.     argc--; mark++;
  252.     ditherType = ORDERED_DITHER;
  253.       } else if (strcmp(argv[mark], "mono") == 0) {
  254.     argc--; mark++;
  255.     ditherType = MONO_DITHER;
  256.       } else if (strcmp(argv[mark], "threshold") == 0) {
  257.     argc--; mark++;
  258.     ditherType = MONO_THRESHOLD;
  259.       } else {
  260.     perror("Illegal dither option.");
  261.     usage(argv[0]);
  262.       }
  263.     } 
  264.     else if (strcmp(argv[mark], "-eachstat") == 0) {
  265.       argc--; mark++;
  266. #ifdef ANALYSIS
  267.       showEachFlag = 1;
  268. #else
  269.       fprintf(stderr, "To use -eachstat, recompile with -DANALYSIS in CFLAGS\n");
  270.       exit(1);
  271. #endif
  272.     }
  273.     else if (strcmp(argv[mark], "-shmem_off") == 0) {
  274.       argc--; mark++;
  275.       shmemFlag = 0;
  276.     }
  277.     else if (strcmp(argv[mark], "-loop") == 0) {
  278.       argc--; mark++;
  279.       loopFlag = 1;
  280.     }
  281.     else if (argv[mark][0] == '-') {
  282.       fprintf(stderr, "Un-recognized flag %s\n",argv[mark]);
  283.       usage(argv[0]);
  284.     }
  285.     else {
  286.       input = fopen(argv[mark], "r");
  287.       if (input == NULL) {
  288.     fprintf(stderr, "Could not open file %s\n", argv[mark]);
  289.     usage(argv[0]);
  290.       }
  291.       argc--; mark++;
  292.     }
  293.   }
  294.  
  295.   signal(SIGINT, int_handler);
  296.  
  297.   init_tables();
  298.   
  299.   switch (ditherType) {
  300.     
  301.   case HYBRID_DITHER:
  302.     
  303.     InitColor();
  304.     InitHybridDither();
  305.     InitDisplay();
  306.     break;
  307.     
  308.     case HYBRID2_DITHER:
  309.     InitColor();
  310.     InitHybridErrorDither();
  311.     InitDisplay();
  312.     break;
  313.     
  314.   case FS4_DITHER:
  315.     InitColor();
  316.     InitFS4Dither();
  317.       InitDisplay();
  318.     break;
  319.     
  320.   case FS2_DITHER:
  321.     InitColor();
  322.     InitFS2Dither();
  323.     InitDisplay();
  324.     break;
  325.     
  326.   case FS2FAST_DITHER:
  327.     InitColor();
  328.     InitFS2FastDither();
  329.     InitDisplay();
  330.     break;
  331.     
  332.   case Twox2_DITHER:
  333.     InitColor();
  334.     Init2x2Dither();
  335.     InitDisplay();
  336.     PostInit2x2Dither();
  337.     break;
  338.  
  339.   case GRAY_DITHER:
  340.     InitGrayDisplay();
  341.     break;
  342.  
  343.   case FULL_COLOR_DITHER:
  344.     InitColorDither();
  345.     InitColorDisplay();
  346.     break;
  347.  
  348.   case NO_DITHER:
  349.     shmemFlag = 0;
  350.     break;
  351.  
  352.   case ORDERED_DITHER:
  353.     InitColor();
  354.     InitOrderedDither();
  355.     InitDisplay();
  356.     break;
  357.  
  358.   case MONO_DITHER:
  359.   case MONO_THRESHOLD:
  360.     InitMonoDisplay();
  361.     break;
  362.   }
  363.  
  364. #ifdef SH_MEM
  365.     if (shmemFlag && (display != NULL)) {
  366.       if (!XShmQueryExtension(display)) {
  367.     shmemFlag = 0;
  368.     fprintf(stderr, "Shared memory not supported\n");
  369.     fprintf(stderr, "Reverting to normal Xlib.\n");
  370.       }
  371.     }
  372. #endif
  373.  
  374.   if (setjmp(env) != 0) {
  375.  
  376.     DestroyVidStream(theStream);
  377.  
  378.     rewind(input);
  379.  
  380.     EOF_flag = 0;
  381.     curBits = 0;
  382.     bitOffset = 0;
  383.     bufLength = 0;
  384.     bitBuffer = NULL;
  385.     totNumFrames = 0;
  386. #ifdef ANALYSIS 
  387.     init_stats();
  388. #endif
  389.  
  390.   }
  391.  
  392.   theStream = NewVidStream(BUF_LENGTH);
  393.  
  394.  
  395.   mpegVidRsrc(0, theStream);
  396.  
  397.   if (ditherType == Twox2_DITHER) i = 2;
  398.   else i = 1;  
  399.  
  400.   ResizeDisplay(curVidStream->h_size*i, curVidStream->v_size*i);
  401.  
  402.   realTimeStart = ReadSysClock();
  403.  
  404.   while (1) mpegVidRsrc(0, theStream);
  405. }
  406.  
  407.  
  408. /*
  409.  *--------------------------------------------------------------
  410.  *
  411.  * usage --
  412.  *
  413.  *    Print mpeg_play usage
  414.  *
  415.  * Results:
  416.  *    None.
  417.  *
  418.  * Side effects:
  419.  *    exits with a return value -1
  420.  *
  421.  *--------------------------------------------------------------
  422.  */
  423.  
  424. void
  425. usage(s)
  426. char *s;    /* program name */
  427. {
  428.     fprintf(stderr, "Usage:\n");
  429.     fprintf(stderr, "mpeg_play\n");
  430.     fprintf(stderr, "          [-nob]\n");
  431.     fprintf(stderr, "          [-nop]\n");
  432.     fprintf(stderr, "          [-dither {ordered|fs4|fs2|fs2fast|hybrid|hybrid2|2x2|gray|color|none|mono|threshold}]\n");
  433.     fprintf(stderr, "          [-loop]\n");
  434.     fprintf(stderr, "          [-eachstat]\n");
  435.     fprintf(stderr, "          file_name\n");
  436.     exit (-1);
  437. }
  438.  
  439.  
  440.  
  441. /*
  442.  *--------------------------------------------------------------
  443.  *
  444.  * DoDitherImage --
  445.  *
  446.  *    Called when image needs to be dithered. Selects correct
  447.  *      dither routine based on info in ditherType.
  448.  *
  449.  * Results:
  450.  *    None.
  451.  *
  452.  * Side effects:
  453.  *    None.
  454.  *
  455.  *--------------------------------------------------------------
  456.  */
  457.  
  458. void
  459. DoDitherImage(l, Cr, Cb, disp, h, w) 
  460. unsigned char *l, *Cr, *Cb, *disp;
  461. int h,w;
  462. {
  463.  
  464.   switch(ditherType) {
  465.   case HYBRID_DITHER:
  466.     HybridDitherImage(l, Cr, Cb, disp, h, w);
  467.     break;
  468.  
  469.   case HYBRID2_DITHER:
  470.     HybridErrorDitherImage(l, Cr, Cb, disp, h, w);
  471.     break;
  472.  
  473.   case FS2FAST_DITHER:
  474.     FS2FastDitherImage(l, Cr, Cb, disp, h, w);
  475.     break;
  476.  
  477.   case FS2_DITHER:
  478.     FS2DitherImage(l, Cr, Cb, disp, h, w);
  479.     break;
  480.  
  481.   case FS4_DITHER:
  482.     FS4DitherImage(l, Cr, Cb, disp, h, w);
  483.     break;
  484.  
  485.   case Twox2_DITHER:
  486.     Twox2DitherImage(l, Cr, Cb, disp, h, w);
  487.     break;
  488.  
  489.   case FULL_COLOR_DITHER:
  490.     ColorDitherImage(l, Cr, Cb, disp, h, w);
  491.     break;
  492.  
  493.   case GRAY_DITHER:
  494.     GrayDitherImage(l, Cr, Cb, disp, h, w);
  495.     break;
  496.  
  497.   case NO_DITHER:
  498.     break;
  499.  
  500.   case ORDERED_DITHER:
  501.     OrderedDitherImage(l, Cr, Cb, disp, h, w);
  502.     break;
  503.  
  504.   case MONO_DITHER:
  505.     MonoDitherImage(l, Cr, Cb, disp, h, w);
  506.     break;
  507.  
  508.   case MONO_THRESHOLD:
  509.     MonoThresholdImage(l, Cr, Cb, disp, h, w);
  510.     break;
  511.   }
  512. }
  513.  
  514.  
  515.  
  516.  
  517.