home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / anim / players / mpeg_src.lha / amiga / main.c < prev    next >
C/C++ Source or Header  |  1993-02-11  |  14KB  |  656 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 "proto.h"
  23. #include <sys/types.h>
  24. #include <signal.h>
  25.  
  26. #ifndef AMIGA
  27. #ifndef MIPS
  28. #include <netinet/in.h>
  29. #else
  30. #include <bsd/netinet/in.h>
  31. #endif
  32. #endif
  33.  
  34. #include "util.h"
  35. #include "dither.h"
  36.  
  37. /* Define buffer length. */
  38.  
  39. #define BUF_LENGTH 80000
  40.  
  41. /* Function return type declarations */
  42. void usage();
  43.  
  44. /* External declaration of main decoding call. */
  45.  
  46. extern VidStream *mpegVidRsrc();
  47. extern VidStream *NewVidStream();
  48.  
  49. /* Declaration of global variable to hold dither info. */
  50.  
  51. int ditherType;
  52.  
  53. /* Global file pointer to incoming data. */
  54. FILE *input;
  55.  
  56. /* End of File flag. */
  57. static int EOF_flag = 0;
  58.  
  59. /* Loop flag. */
  60. int loopFlag = 0;
  61.  
  62. /* Shared memory flag. */
  63. int shmemFlag = 0;
  64.  
  65. #ifdef AMIGA
  66. extern char *amiga_option;
  67. extern char *saveiff_option;
  68. #endif
  69.  
  70. /* Quiet flag. */
  71. int quietFlag = 0;
  72.  
  73. /* Display image on screen? */
  74. int noDisplayFlag = 0;
  75.  
  76. /* Setjmp/Longjmp env. */
  77. jmp_buf env;
  78.  
  79.  
  80. /*
  81.  *--------------------------------------------------------------
  82.  *
  83.  * get_more_data --
  84.  *
  85.  *    Called by correct_underflow in bit parsing utilities to
  86.  *      read in more data.
  87.  *
  88.  * Results:
  89.  *    Input buffer updated, buffer length updated.
  90.  *      Returns 1 if data read, 0 if EOF, -1 if error.
  91.  *
  92.  * Side effects:
  93.  *      None.
  94.  *
  95.  *--------------------------------------------------------------
  96.  */
  97.  
  98. int 
  99. get_more_data(buf_start, max_length, length_ptr, buf_ptr)
  100.      unsigned int *buf_start;
  101.      int max_length;
  102.      int *length_ptr;
  103.      unsigned int **buf_ptr;
  104. {
  105.   
  106.   int length, num_read, i, request;
  107.   unsigned char *buffer, *mark;
  108.   unsigned int *lmark;
  109.  
  110.   if (EOF_flag) return 0;
  111.  
  112.   length = *length_ptr;
  113.   buffer = (unsigned char *) *buf_ptr;
  114.  
  115.   if (length > 0) {
  116.     memcpy((unsigned char *) buf_start, buffer, (length*4));
  117.     mark = ((unsigned char *) (buf_start + length));
  118.   }
  119.   else {
  120.     mark = (unsigned char *) buf_start;
  121.     length = 0;
  122.   }
  123.  
  124.   request = (max_length-length)*4;
  125.   
  126.   num_read = fread( mark, 1, request, input);
  127.  
  128.   /* Paulo Villegas - 26/1/1993: Correction for 4-byte alignment */
  129.   {
  130.     int num_read_rounded;
  131.     unsigned char *index;
  132.  
  133.     num_read_rounded = 4*(num_read/4);
  134.  
  135.     /* this can happen only if num_read<request; i.e. end of file reached */
  136.     if( num_read_rounded < num_read )
  137.       { 
  138.      num_read_rounded = 4*( num_read/4+1 );
  139.      /* fill in with zeros */
  140.      for( index=mark+num_read; index<mark+num_read_rounded; *(index++)=0 );
  141.      /* advance to the next 4-byte boundary */
  142.      num_read = num_read_rounded;
  143.       }
  144.   }
  145.   
  146.   if   (num_read < 0) {
  147.     return -1;
  148.   }
  149.   else if (num_read == 0) {
  150.     *buf_ptr = buf_start;
  151.     
  152.     /* Make 32 bits after end equal to 0 and 32
  153.        bits after that equal to seq end code
  154.        in order to prevent messy data from infinite
  155.        recursion.
  156.     */
  157.  
  158.     *(buf_start + length) = 0x0;
  159.     *(buf_start + length+1) = SEQ_END_CODE;
  160.  
  161.     EOF_flag = 1;
  162.     return 0;
  163.   }
  164.  
  165.   lmark = (unsigned int *) mark;
  166.  
  167.   num_read = num_read/4;
  168.  
  169. #ifndef AMIGA
  170.   for (i=0; i<num_read; i++) {
  171.     *lmark = htonl(*lmark);
  172.     lmark++;
  173.   }
  174. #endif
  175.  
  176.   *buf_ptr = buf_start;
  177.   *length_ptr = length + num_read;
  178.  
  179.   return 1;
  180. }
  181.  
  182. /*
  183.  *--------------------------------------------------------------
  184.  *
  185.  * int_handler --
  186.  *
  187.  *    Handles Cntl-C interupts..
  188.  *
  189.  * Results:
  190.  *    None.
  191.  *
  192.  * Side effects:
  193.  *    None.
  194.  *
  195.  *--------------------------------------------------------------
  196.  */
  197. void
  198. int_handler()
  199. {
  200.   if (!quietFlag) {
  201.     fprintf(stderr, "Interrupted!\n");
  202.   }
  203.   if (curVidStream != NULL)
  204.     DestroyVidStream(curVidStream);
  205.   exit(1);
  206. }
  207.  
  208.  
  209. /*
  210.  *--------------------------------------------------------------
  211.  *
  212.  * main --
  213.  *
  214.  *    Parses command line, starts decoding and displaying.
  215.  *
  216.  * Results:
  217.  *    None.
  218.  *
  219.  * Side effects:
  220.  *    None.
  221.  *
  222.  *--------------------------------------------------------------
  223.  */
  224.  
  225. void
  226. main(argc, argv)
  227.      int argc;
  228.      char **argv;
  229. {
  230.  
  231.   char *name;
  232.   static VidStream *theStream;
  233.   int mark;
  234.   int i;
  235.  
  236.   mark = 1;
  237.   argc--;
  238.  
  239.   name = "";
  240.   input = stdin;
  241.   ditherType = ORDERED2_DITHER;
  242.   LUM_RANGE = 8;
  243.   CR_RANGE = CB_RANGE = 4;
  244.   noDisplayFlag = 0;
  245.  
  246. #ifdef SH_MEM
  247.   shmemFlag = 1;
  248. #endif
  249.  
  250.   while (argc) {
  251.     if (strcmp(argv[mark], "-nop") == 0) {
  252.       TogglePFlag();
  253.       argc--; mark++;
  254.     } else if (strcmp(argv[mark], "-nob") == 0) {
  255.       ToggleBFlag();
  256.       argc--; mark++;
  257.     } else if (strcmp(argv[mark], "-display") == 0) {
  258.       name = argv[++mark];
  259.       argc -= 2; mark++;
  260.     } else if (strcmp(argv[mark], "-dither") == 0) {
  261.       argc--; mark++;
  262.       if (argc < 1) {
  263.     perror("Must specify dither option after -dither flag");
  264.     usage(argv[0]);
  265.       }
  266.       if (strcmp(argv[mark], "hybrid") == 0) {
  267.     argc--; mark++;
  268.     ditherType = HYBRID_DITHER;
  269.       } else if (strcmp(argv[mark], "hybrid2") == 0) {
  270.     argc--; mark++;
  271.     ditherType = HYBRID2_DITHER;
  272.       } else if (strcmp(argv[mark], "fs4") == 0) {
  273.     argc--; mark++;
  274.     ditherType = FS4_DITHER;
  275.       } else if (strcmp(argv[mark], "fs2") == 0) {
  276.     argc--; mark++;
  277.     ditherType = FS2_DITHER;
  278.       } else if (strcmp(argv[mark], "fs2fast") == 0) {
  279.     argc--; mark++;
  280.     ditherType = FS2FAST_DITHER;
  281.       } else if (strcmp(argv[mark], "hybrid2") == 0) {
  282.     argc--; mark++;
  283.     ditherType = HYBRID2_DITHER;
  284.       } else if (strcmp(argv[mark], "2x2") == 0) {
  285.     argc--; mark++;
  286.     ditherType = Twox2_DITHER;
  287.       } else if (strcmp(argv[mark], "gray") == 0) {
  288.     argc--; mark++;
  289.     ditherType = GRAY_DITHER;
  290.       } else if (strcmp(argv[mark], "color") == 0) {
  291.     argc--; mark++;
  292.     ditherType = FULL_COLOR_DITHER;
  293.       } else if (strcmp(argv[mark], "none") == 0) {
  294.     argc--; mark++;
  295.     ditherType = NO_DITHER;
  296.       } else if (strcmp(argv[mark], "ordered") == 0) {
  297.     argc--; mark++;
  298.     ditherType = ORDERED_DITHER;
  299.       } else if (strcmp(argv[mark], "ordered2") == 0) {
  300.     argc--; mark++;
  301.     ditherType = ORDERED2_DITHER;
  302.       } else if (strcmp(argv[mark], "mbordered") == 0) {
  303.     argc--; mark++;
  304.     ditherType = MBORDERED_DITHER;
  305.       } else if (strcmp(argv[mark], "mono") == 0) {
  306.     argc--; mark++;
  307.     ditherType = MONO_DITHER;
  308.       } else if (strcmp(argv[mark], "threshold") == 0) {
  309.     argc--; mark++;
  310.     ditherType = MONO_THRESHOLD;
  311.       } else {
  312.     perror("Illegal dither option.");
  313.     usage(argv[0]);
  314.       }
  315.     } 
  316.     else if (strcmp(argv[mark], "-eachstat") == 0) {
  317.       argc--; mark++;
  318. #ifdef ANALYSIS
  319.       showEachFlag = 1;
  320. #else
  321.       fprintf(stderr, "To use -eachstat, recompile with -DANALYSIS in CFLAGS\n");
  322.       exit(1);
  323. #endif
  324.     }
  325.     else if (strcmp(argv[mark], "-shmem_off") == 0) {
  326.       argc--; mark++;
  327.       shmemFlag = 0;
  328.     }
  329.     else if (strcmp(argv[mark], "-quiet") == 0) {
  330.       argc--; mark++;
  331.       quietFlag = 1;
  332.     }
  333.     else if (strcmp(argv[mark], "-loop") == 0) {
  334.       argc--; mark++;
  335.       loopFlag = 1;
  336.     }
  337. #ifdef AMIGA
  338.     else if (strcmp(argv[mark], "-amiga") == 0) {
  339.       argc--; mark++;
  340.       if( argc )
  341.       {
  342.         amiga_option = argv[mark];
  343.         argc--; mark++;
  344.       }
  345.     }
  346.     else if (strcmp(argv[mark], "-saveiff") == 0) {
  347.       argc--; mark++;
  348.       if( argc )
  349.       {
  350.         saveiff_option = argv[mark];
  351.         argc--; mark++;
  352.       }
  353.     }
  354. #endif
  355.     else if (strcmp(argv[mark], "-no_display") == 0) {
  356.       argc--; mark++;
  357.       noDisplayFlag = 1;
  358.     }
  359.     else if (strcmp(argv[mark], "-l_range") == 0) {
  360.       argc--; mark++;
  361.       LUM_RANGE = atoi(argv[mark]);
  362.       if (LUM_RANGE < 1) {
  363.     fprintf(stderr, "Illegal luminance range value: %d\n", LUM_RANGE);
  364.     exit(1);
  365.       }
  366.       argc--; mark++;
  367.     }
  368.     else if (strcmp(argv[mark], "-cr_range") == 0) {
  369.       argc--; mark++;
  370.       CR_RANGE = atoi(argv[mark]);
  371.       if (CR_RANGE < 1) {
  372.     fprintf(stderr, "Illegal cr range value: %d\n", CR_RANGE);
  373.     exit(1);
  374.       }
  375.       argc--; mark++;
  376.     }
  377.     else if (strcmp(argv[mark], "-cb_range") == 0) {
  378.       argc--; mark++;
  379.       CB_RANGE = atoi(argv[mark]);
  380.       if (CB_RANGE < 1) {
  381.     fprintf(stderr, "Illegal cb range value: %d\n", CB_RANGE);
  382.     exit(1);
  383.       }
  384.       argc--; mark++;
  385.     }
  386.     else if (argv[mark][0] == '-') {
  387.       fprintf(stderr, "Un-recognized flag %s\n",argv[mark]);
  388.       usage(argv[0]);
  389.     }
  390.     else {
  391.       input = fopen(argv[mark], "r");
  392.       if (input == NULL) {
  393.     fprintf(stderr, "Could not open file %s\n", argv[mark]);
  394.     usage(argv[0]);
  395.       }
  396.       argc--; mark++;
  397.     }
  398.   }
  399.  
  400.   lum_values = (int *) malloc(LUM_RANGE*sizeof(int));
  401.   cr_values = (int *) malloc(CR_RANGE*sizeof(int));
  402.   cb_values = (int *) malloc(CB_RANGE*sizeof(int));
  403.  
  404.   signal(SIGINT, int_handler);
  405.  
  406.   init_tables();
  407.   
  408.   switch (ditherType) {
  409.     
  410.   case HYBRID_DITHER:
  411.     
  412.     InitColor();
  413.     InitHybridDither();
  414.     InitDisplay(name);
  415.     break;
  416.     
  417.     case HYBRID2_DITHER:
  418.     InitColor();
  419.     InitHybridErrorDither();
  420.     InitDisplay(name);
  421.     break;
  422.     
  423.   case FS4_DITHER:
  424.     InitColor();
  425.     InitFS4Dither();
  426.       InitDisplay(name);
  427.     break;
  428.     
  429.   case FS2_DITHER:
  430.     InitColor();
  431.     InitFS2Dither();
  432.     InitDisplay(name);
  433.     break;
  434.     
  435.   case FS2FAST_DITHER:
  436.     InitColor();
  437.     InitFS2FastDither();
  438.     InitDisplay(name);
  439.     break;
  440.     
  441.   case Twox2_DITHER:
  442.     InitColor();
  443.     Init2x2Dither();
  444.     InitDisplay(name);
  445.     PostInit2x2Dither();
  446.     break;
  447.  
  448.   case GRAY_DITHER:
  449.     InitGrayDisplay(name);
  450.     break;
  451.  
  452.   case FULL_COLOR_DITHER:
  453.     InitColorDither();
  454.     InitColorDisplay(name);
  455.     break;
  456.  
  457.   case NO_DITHER:
  458.     shmemFlag = 0;
  459.     break;
  460.  
  461.   case ORDERED_DITHER:
  462.     InitColor();
  463.     InitOrderedDither();
  464.     InitDisplay(name);
  465.     break;
  466.  
  467.   case MONO_DITHER:
  468.   case MONO_THRESHOLD:
  469.     InitMonoDisplay(name);
  470.     break;
  471.  
  472.   case ORDERED2_DITHER:
  473.     InitColor();
  474.     InitDisplay(name);
  475.     InitOrdered2Dither();
  476.     break;
  477.  
  478.   case MBORDERED_DITHER:
  479.     InitColor();
  480.     InitDisplay(name);
  481.     InitMBOrderedDither();
  482.     break;
  483.  
  484.   }
  485.  
  486. #ifdef SH_MEM
  487.     if (shmemFlag && (display != NULL)) {
  488.       if (!XShmQueryExtension(display)) {
  489.     shmemFlag = 0;
  490.     if (!quietFlag) {
  491.       fprintf(stderr, "Shared memory not supported\n");
  492.       fprintf(stderr, "Reverting to normal Xlib.\n");
  493.     }
  494.       }
  495.     }
  496. #endif
  497.  
  498.   if (setjmp(env) != 0) {
  499.  
  500.     DestroyVidStream(theStream);
  501.  
  502.     rewind(input);
  503.  
  504.     EOF_flag = 0;
  505.     curBits = 0;
  506.     bitOffset = 0;
  507.     bufLength = 0;
  508.     bitBuffer = NULL;
  509.     totNumFrames = 0;
  510. #ifdef ANALYSIS 
  511.     init_stats();
  512. #endif
  513.  
  514.   }
  515.  
  516.   theStream = NewVidStream(BUF_LENGTH);
  517.  
  518.   mpegVidRsrc(0, theStream);
  519.  
  520.   if (ditherType == Twox2_DITHER) i = 2;
  521.   else i = 1;  
  522.  
  523.   ResizeDisplay(curVidStream->h_size*i, curVidStream->v_size*i);
  524.  
  525.   realTimeStart = ReadSysClock();
  526.  
  527.   while (1) mpegVidRsrc(0, theStream);
  528. }
  529.  
  530.  
  531. /*
  532.  *--------------------------------------------------------------
  533.  *
  534.  * usage --
  535.  *
  536.  *    Print mpeg_play usage
  537.  *
  538.  * Results:
  539.  *    None.
  540.  *
  541.  * Side effects:
  542.  *    exits with a return value -1
  543.  *
  544.  *--------------------------------------------------------------
  545.  */
  546.  
  547. void
  548. usage(s)
  549. char *s;    /* program name */
  550. {
  551.     fprintf(stderr, "Usage:\n");
  552.     fprintf(stderr, "mpeg_play\n");
  553.     fprintf(stderr, "          [-nob]\n");
  554.     fprintf(stderr, "          [-nop]\n");
  555.     fprintf(stderr, "          [-dither {ordered|ordered2|mbordered|fs4|fs2|fs2fast|hybrid|\n");
  556.     fprintf(stderr, "                    hybrid2|2x2|gray|color|none|mono|threshold}]\n");
  557.     fprintf(stderr, "          [-loop]\n");
  558.     fprintf(stderr, "          [-eachstat]\n");
  559.     fprintf(stderr, "          [-no_display]\n");
  560.     fprintf(stderr, "          [-shmem_off]\n");
  561.     fprintf(stderr, "          [-l_range num]\n");
  562.     fprintf(stderr, "          [-cr_range num]\n");
  563.     fprintf(stderr, "          [-cb_range num]\n");
  564.     fprintf(stderr, "          [-quiet]\n");
  565. #ifdef AMIGA
  566.     fprintf(stderr, "          [-amiga window]\n");
  567.     fprintf(stderr, "          [-amiga screen[:id[/depth[/width[/height]]]]]\n");
  568.     fprintf(stderr, "          [-saveiff framename_%%04d.iff]\n");
  569. #endif
  570.     fprintf(stderr, "          file_name\n");
  571.     exit (-1);
  572. }
  573.  
  574.  
  575.  
  576. /*
  577.  *--------------------------------------------------------------
  578.  *
  579.  * DoDitherImage --
  580.  *
  581.  *    Called when image needs to be dithered. Selects correct
  582.  *      dither routine based on info in ditherType.
  583.  *
  584.  * Results:
  585.  *    None.
  586.  *
  587.  * Side effects:
  588.  *    None.
  589.  *
  590.  *--------------------------------------------------------------
  591.  */
  592.  
  593. void
  594. DoDitherImage(l, Cr, Cb, disp, h, w) 
  595. unsigned char *l, *Cr, *Cb, *disp;
  596. int h,w;
  597. {
  598.  
  599.   switch(ditherType) {
  600.   case HYBRID_DITHER:
  601.     HybridDitherImage(l, Cr, Cb, disp, h, w);
  602.     break;
  603.  
  604.   case HYBRID2_DITHER:
  605.     HybridErrorDitherImage(l, Cr, Cb, disp, h, w);
  606.     break;
  607.  
  608.   case FS2FAST_DITHER:
  609.     FS2FastDitherImage(l, Cr, Cb, disp, h, w);
  610.     break;
  611.  
  612.   case FS2_DITHER:
  613.     FS2DitherImage(l, Cr, Cb, disp, h, w);
  614.     break;
  615.  
  616.   case FS4_DITHER:
  617.     FS4DitherImage(l, Cr, Cb, disp, h, w);
  618.     break;
  619.  
  620.   case Twox2_DITHER:
  621.     Twox2DitherImage(l, Cr, Cb, disp, h, w);
  622.     break;
  623.  
  624.   case FULL_COLOR_DITHER:
  625.     ColorDitherImage(l, Cr, Cb, disp, h, w);
  626.     break;
  627.  
  628.   case GRAY_DITHER:
  629.     GrayDitherImage(l, Cr, Cb, disp, h, w);
  630.     break;
  631.  
  632.   case NO_DITHER:
  633.     break;
  634.  
  635.   case ORDERED_DITHER:
  636.     OrderedDitherImage(l, Cr, Cb, disp, h, w);
  637.     break;
  638.  
  639.   case MONO_DITHER:
  640.     MonoDitherImage(l, Cr, Cb, disp, h, w);
  641.     break;
  642.  
  643.   case MONO_THRESHOLD:
  644.     MonoThresholdImage(l, Cr, Cb, disp, h, w);
  645.     break;
  646.  
  647.   case ORDERED2_DITHER:
  648.     Ordered2DitherImage(l, Cr, Cb, disp, h, w);
  649.     break;
  650.  
  651.   case MBORDERED_DITHER:
  652.     MBOrderedDitherImage(l, Cr, Cb, disp, h, w);
  653.     break;
  654.   }
  655. }
  656.