home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource1 / mpegplay / main.c < prev    next >
C/C++ Source or Header  |  1994-02-16  |  15KB  |  642 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. #if defined(OS2)
  26. #include "xstub.h"
  27. #elif defined(MIPS)
  28. #include <bsd/netinet/in.h>
  29. #else
  30. #include <netinet/in.h>
  31. #endif
  32.  
  33. #include "util.h"
  34. #include "dither.h"
  35.  
  36. /* Define buffer length. */
  37.  
  38. #define BUF_LENGTH 80000
  39.  
  40. /* Function return type declarations */
  41. void usage();
  42.  
  43. /* External declaration of main decoding call. */
  44.  
  45. extern VidStream *mpegVidRsrc();
  46. extern VidStream *NewVidStream();
  47.  
  48. /* Declaration of global variable to hold dither info. */
  49.  
  50. int ditherType;
  51.  
  52. /* Global file pointer to incoming data. */
  53. FILE *input;
  54.  
  55. /* End of File flag. */
  56. static int EOF_flag = 0;
  57.  
  58. /* Loop flag. */
  59. int loopFlag = 0;
  60.  
  61. /* Shared memory flag. */
  62. int shmemFlag = 0;
  63.  
  64. /* Quiet flag. */
  65. int quietFlag = 0;
  66.  
  67. /* Display image on screen? */
  68. int noDisplayFlag = 0;
  69.  
  70. /* Setjmp/Longjmp env. */
  71. jmp_buf env;
  72.  
  73.  
  74. /*
  75.  *--------------------------------------------------------------
  76.  *
  77.  * get_more_data --
  78.  *
  79.  *    Called by correct_underflow in bit parsing utilities to
  80.  *      read in more data.
  81.  *
  82.  * Results:
  83.  *    Input buffer updated, buffer length updated.
  84.  *      Returns 1 if data read, 0 if EOF, -1 if error.
  85.  *
  86.  * Side effects:
  87.  *      None.
  88.  *
  89.  *--------------------------------------------------------------
  90.  */
  91.  
  92. int 
  93. get_more_data(buf_start, max_length, length_ptr, buf_ptr)
  94.      unsigned int *buf_start;
  95.      int max_length;
  96.      int *length_ptr;
  97.      unsigned int **buf_ptr;
  98. {
  99.   
  100.   int length, num_read, i, request;
  101.   unsigned char *buffer, *mark;
  102.   unsigned int *lmark;
  103.  
  104.   if (EOF_flag) return 0;
  105.  
  106.   length = *length_ptr;
  107.   buffer = (unsigned char *) *buf_ptr;
  108.  
  109.   if (length > 0) {
  110.     memcpy((unsigned char *) buf_start, buffer, (length*4));
  111.     mark = ((unsigned char *) (buf_start + length));
  112.   }
  113.   else {
  114.     mark = (unsigned char *) buf_start;
  115.     length = 0;
  116.   }
  117.  
  118.   request = (max_length-length)*4;
  119.   
  120.   num_read = fread( mark, 1, request, input);
  121.  
  122.   /* Paulo Villegas - 26/1/1993: Correction for 4-byte alignment */
  123.   {
  124.     int num_read_rounded;
  125.     unsigned char *index;
  126.  
  127.     num_read_rounded = 4*(num_read/4);
  128.  
  129.     /* this can happen only if num_read<request; i.e. end of file reached */
  130.     if( num_read_rounded < num_read )
  131.       { 
  132.      num_read_rounded = 4*( num_read/4+1 );
  133.      /* fill in with zeros */
  134.      for( index=mark+num_read; index<mark+num_read_rounded; *(index++)=0 );
  135.      /* advance to the next 4-byte boundary */
  136.      num_read = num_read_rounded;
  137.       }
  138.   }
  139.   
  140.   if   (num_read < 0) {
  141.     return -1;
  142.   }
  143.   else if (num_read == 0) {
  144.     *buf_ptr = buf_start;
  145.     
  146.     /* Make 32 bits after end equal to 0 and 32
  147.        bits after that equal to seq end code
  148.        in order to prevent messy data from infinite
  149.        recursion.
  150.     */
  151.  
  152.     *(buf_start + length) = 0x0;
  153.     *(buf_start + length+1) = SEQ_END_CODE;
  154.  
  155.     EOF_flag = 1;
  156.     return 0;
  157.   }
  158.  
  159.   lmark = (unsigned int *) mark;
  160.  
  161.   num_read = num_read/4;
  162.  
  163.   for (i=0; i<num_read; i++) {
  164.     *lmark = htonl(*lmark);
  165.     lmark++;
  166.   }
  167.  
  168.   *buf_ptr = buf_start;
  169.   *length_ptr = length + num_read;
  170.  
  171.   return 1;
  172. }
  173.  
  174. /*
  175.  *--------------------------------------------------------------
  176.  *
  177.  * int_handler --
  178.  *
  179.  *    Handles Cntl-C interupts..
  180.  *
  181.  * Results:
  182.  *    None.
  183.  *
  184.  * Side effects:
  185.  *    None.
  186.  *
  187.  *--------------------------------------------------------------
  188.  */
  189.  
  190. void
  191. /* @@@ AK, Should properly do prototype for OS/2 signal handlers */
  192. #if defined(OS2)
  193. int_handler(int x)
  194. #else
  195. int_handler()
  196. #endif
  197. {
  198.   if (!quietFlag) {
  199.     fprintf(stderr, "Interrupted!\n");
  200.   }
  201.   if (curVidStream != NULL)
  202.     DestroyVidStream(curVidStream);
  203.   exit(1);
  204. }
  205.  
  206.  
  207. /*
  208.  *--------------------------------------------------------------
  209.  *
  210.  * main --
  211.  *
  212.  *    Parses command line, starts decoding and displaying.
  213.  *
  214.  * Results:
  215.  *    None.
  216.  *
  217.  * Side effects:
  218.  *    None.
  219.  *
  220.  *--------------------------------------------------------------
  221.  */
  222.  
  223. void
  224. main(argc, argv)
  225.      int argc;
  226.      char **argv;
  227. {
  228.  
  229.   char *name;
  230.   static VidStream *theStream;
  231.   int mark;
  232.   int i;
  233.  
  234.   mark = 1;
  235.   argc--;
  236.  
  237.   name = "";
  238.   input = stdin;
  239.   ditherType = ORDERED2_DITHER;
  240.   LUM_RANGE = 8;
  241.   CR_RANGE = CB_RANGE = 4;
  242.   noDisplayFlag = 0;
  243.  
  244. #ifdef SH_MEM
  245.   shmemFlag = 1;
  246. #endif
  247.  
  248.   while (argc) {
  249.     if (strcmp(argv[mark], "-nop") == 0) {
  250.       TogglePFlag();
  251.       argc--; mark++;
  252.     } else if (strcmp(argv[mark], "-nob") == 0) {
  253.       ToggleBFlag();
  254.       argc--; mark++;
  255.     } else if (strcmp(argv[mark], "-display") == 0) {
  256.       name = argv[++mark];
  257.       argc -= 2; mark++;
  258.     } else if (strcmp(argv[mark], "-dither") == 0) {
  259.       argc--; mark++;
  260.       if (argc < 1) {
  261.     perror("Must specify dither option after -dither flag");
  262.     usage(argv[0]);
  263.       }
  264.       if (strcmp(argv[mark], "hybrid") == 0) {
  265.     argc--; mark++;
  266.     ditherType = HYBRID_DITHER;
  267.       } else if (strcmp(argv[mark], "hybrid2") == 0) {
  268.     argc--; mark++;
  269.     ditherType = HYBRID2_DITHER;
  270.       } else if (strcmp(argv[mark], "fs4") == 0) {
  271.     argc--; mark++;
  272.     ditherType = FS4_DITHER;
  273.       } else if (strcmp(argv[mark], "fs2") == 0) {
  274.     argc--; mark++;
  275.     ditherType = FS2_DITHER;
  276.       } else if (strcmp(argv[mark], "fs2fast") == 0) {
  277.     argc--; mark++;
  278.     ditherType = FS2FAST_DITHER;
  279.       } else if (strcmp(argv[mark], "hybrid2") == 0) {
  280.     argc--; mark++;
  281.     ditherType = HYBRID2_DITHER;
  282.       } else if (strcmp(argv[mark], "2x2") == 0) {
  283.     argc--; mark++;
  284.     ditherType = Twox2_DITHER;
  285.       } else if (strcmp(argv[mark], "gray") == 0) {
  286.     argc--; mark++;
  287.     ditherType = GRAY_DITHER;
  288.       } else if (strcmp(argv[mark], "color") == 0) {
  289.     argc--; mark++;
  290.     ditherType = FULL_COLOR_DITHER;
  291.       } else if (strcmp(argv[mark], "none") == 0) {
  292.     argc--; mark++;
  293.     ditherType = NO_DITHER;
  294.       } else if (strcmp(argv[mark], "ordered") == 0) {
  295.     argc--; mark++;
  296.     ditherType = ORDERED_DITHER;
  297.       } else if (strcmp(argv[mark], "ordered2") == 0) {
  298.     argc--; mark++;
  299.     ditherType = ORDERED2_DITHER;
  300.       } else if (strcmp(argv[mark], "mbordered") == 0) {
  301.     argc--; mark++;
  302.     ditherType = MBORDERED_DITHER;
  303.       } else if (strcmp(argv[mark], "mono") == 0) {
  304.     argc--; mark++;
  305.     ditherType = MONO_DITHER;
  306.       } else if (strcmp(argv[mark], "threshold") == 0) {
  307.     argc--; mark++;
  308.     ditherType = MONO_THRESHOLD;
  309.       } else {
  310.     perror("Illegal dither option.");
  311.     usage(argv[0]);
  312.       }
  313.     } 
  314.     else if (strcmp(argv[mark], "-eachstat") == 0) {
  315.       argc--; mark++;
  316. #ifdef ANALYSIS
  317.       showEachFlag = 1;
  318. #else
  319.       fprintf(stderr, "To use -eachstat, recompile with -DANALYSIS in CFLAGS\n");
  320.       exit(1);
  321. #endif
  322.     }
  323.     else if (strcmp(argv[mark], "-shmem_off") == 0) {
  324.       argc--; mark++;
  325.       shmemFlag = 0;
  326.     }
  327.     else if (strcmp(argv[mark], "-quiet") == 0) {
  328.       argc--; mark++;
  329.       quietFlag = 1;
  330.     }
  331.     else if (strcmp(argv[mark], "-loop") == 0) {
  332.       argc--; mark++;
  333.       loopFlag = 1;
  334.     }
  335.     else if (strcmp(argv[mark], "-no_displ