1*** gray.c	Tue Feb  2 23:58:35 1993
2--- mpegvga/gray.c	Sun Oct 17 17:19:39 1993
3***************
4*** 53,58 ****
5--- 53,59 ----
6    int i, max = w*h/16;
7
8    for (i=0; i<max; i++) {
9+ /*
10      out[0] = pixel[lum[0]];
11      out[1] = pixel[lum[1]];
12      out[2] = pixel[lum[2]];
13***************
14*** 69,74 ****
15--- 70,81 ----
16      out[13] = pixel[lum[13]];
17      out[14] = pixel[lum[14]];
18      out[15] = pixel[lum[15]];
19+   */
20+   /* For VGA, pixel[i] = i */
21+     *(unsigned *)(&out[0]) = *(unsigned *)(&lum[0]);
22+     *(unsigned *)(&out[4]) = *(unsigned *)(&lum[4]);
23+     *(unsigned *)(&out[8]) = *(unsigned *)(&lum[8]);
24+     *(unsigned *)(&out[12]) = *(unsigned *)(&lum[12]);
25      out += 16;
26      lum += 16;
27    }
28*** proto.h	Wed Feb  3 16:02:59 1993
29--- mpegvga/proto.h	Sun Oct 17 16:57:16 1993
30***************
31*** 49,55 ****
32--- 49,57 ----
33
34  /* gdith.c */
35  void InitColor P((void ));
36+ /*
37  int HandleXError P((Display *dpy , XErrorEvent *event ));
38+ */
39  void InstallXErrorHandler P((void ));
40  void DeInstallXErrorHandler P((void ));
41  void ResizeDisplay P((int w , int h ));
42***************
43*** 102,109 ****
44--- 104,113 ----
45  void ColorDitherImage P((unsigned char *lum , unsigned char *cr , unsigned char *cb , unsigned char *out , int rows , int cols ));
46
47  /* util32.c */
48+ /*
49  Visual *FindFullColorVisual P((Display *dpy , int *depth ));
50  Window CreateFullColorWindow P((Display *dpy , int x , int y , int w , int h ));
51+ */
52
53  /* ordered.c */
54  void InitOrderedDither P((void ));
55*** util.c	Tue Feb  2 23:58:38 1993
56--- mpegvga/util.c	Sun Oct 17 16:48:04 1993
57***************
58*** 20,25 ****
59--- 20,26 ----
60   */
61
62  #include <stdlib.h>
63+ #include <vga.h>
64  #include "video.h"
65  #include "proto.h"
66  #include "util.h"
67***************
68*** 104,109 ****
69--- 105,111 ----
70        fprintf (stderr, "\n");
71        perror("Unexpected read error.");
72      }
73+     vga_setmode(TEXT);
74      exit(1);
75    }
76    else if ((status == 0) && (bufLength < 1)) {
77***************
78*** 119,124 ****
79--- 121,127 ----
80
81      if (loopFlag) longjmp(env, 1);
82      DestroyVidStream(curVidStream);
83+     vga_setmode(TEXT);
84      exit(0);
85    }
86  #ifdef UTIL2
87*** video.c	Tue Feb  2 23:58:41 1993
88--- mpegvga/video.c	Sat Oct 23 14:04:06 1993
89***************
90*** 24,30 ****
91
92  #include <stdio.h>
93  #include <stdlib.h>
94! #include <assert.h>
95
96  #ifndef MIPS
97  #include <sys/time.h>
98--- 24,31 ----
99
100  #include <stdio.h>
101  #include <stdlib.h>
102! /* #include <assert.h> */
103! #define assert(c)
104
105  #ifndef MIPS
106  #include <sys/time.h>
107***************
108*** 32,37 ****
109--- 33,39 ----
110  #include <sys/types.h>
111  #include <sys/system.h>
112  #endif
113+ #include <vga.h>
114
115  #include "decoders.h"
116  #include "video.h"
117***************
118*** 985,990 ****
119--- 987,993 ----
120      if (data != SEQ_START_CODE) {
121        fprintf(stderr, "This is not an MPEG stream.");
122        DestroyVidStream(curVidStream);
123+       vga_setmode(TEXT);
124        exit(1);
125      }
126      first = 0;
127***************
128*** 1024,1029 ****
129--- 1027,1033 ----
130        longjmp(env, 1);
131
132      DestroyVidStream(curVidStream);
133+     vga_setmode(TEXT);
134      exit(0);
135      break;
136
137***************
138*** 1579,1584 ****
139--- 1583,1589 ----
140    while (vid_stream->ring[i]->locked != 0) {
141      if (++i >= RING_BUF_SIZE) {
142        perror("Fatal error. Ring buffer full.");
143+       vga_setmode(TEXT);
144        exit(1);
145      }
146    }
147*** video.h	Tue Feb  2 23:58:41 1993
148--- mpegvga/video.h	Sun Oct 17 16:56:44 1993
149***************
150*** 21,28 ****
151--- 21,30 ----
152  #include <stdio.h>
153  #include <setjmp.h>
154
155+ /*
156  #include <X11/Xlib.h>
157  #include <X11/Xutil.h>
158+ */
159
160  #ifdef SH_MEM
161  #include <sys/ipc.h>
162***************
163*** 244,250 ****
164  extern VidStream *curVidStream;
165
166  /* Declarataion of global display pointer. */
167! extern Display *display;
168
169  /* Shared memory flag. */
170  extern int shmemFlag;
171--- 246,252 ----
172  extern VidStream *curVidStream;
173
174  /* Declarataion of global display pointer. */
175! /* extern Display *display; */
176
177  /* Shared memory flag. */
178  extern int shmemFlag;
179*** README.linux	Sun Jan 15 16:44:10 1995
180--- mpegvga/README.linux	Sun Jan 15 16:06:09 1995
181***************
182*** 0 ****
183--- 1,49 ----
184+
185+ This is a port of the Berkeley MPEG Video Software Decoder v2.0 to Linux.
186+
187+ Two binaries are provided. They require the ld.so shared library loader.
188+
189+ mpeg_play
190+
191+ A binary compiled from the stock sources, using the XFree86-2.0 libraries.
192+ It was compiled with the flags: -O2 -fomit-frame-pointer -m486 (implicit)
193+ using gcc 2.5.4, with some debugging code left out. Uses the X shared memory
194+ extension that XFree86 v2.0 provides, which is a big win. The stock sources
195+ compile cleanly and trivially.
196+
197+ mpeg_vga
198+
199+ A non-X version that uses svgalib. It is slightly faster than the X version
200+ with shared memory and can use low resolution graphics modes. Also, with
201+ truecolor graphics cards that svgalib supports (Cirrus, ET4000), full color
202+ dithering can be used, which is very pretty. The graphics mode to be used can
203+ be set with the GSVGAMODE environment variable. Requires svgalib 0.91 or
204+ later installed.
205+
206+ For full color dithering (-dither color), 320x200x16M graphics mode is used
207+ if it is available and the picture is small enough; if not, 640x480x16M is
208+ used if available. 32K mode probed similarly.
209+
210+ For most other dithering methods, 320x200x256 standard VGA graphics mode is
211+ used if the picture is small enough; 640x480x256 otherwise.
212+
213+ For mono dithering, 640x480x2 VGA graphics mode is used.
214+
215+ [NOTE: The previously uploaded version contained patches for some hacked
216+ version of the stock sources; sorry for that.]
217+ Patches for the stock sources are included (mpegvga.patch). It removes X
218+ references, and uses svgalib instead. Also, the speed of gray dithering and
219+ full-color dithering has been improved. svgalib v0.91 or later is required to
220+ compile; it can be found on sunsite.unc.edu, directory /pub/Linux/libs.
221+ [Speed hack have been incorporated into the main source]
222+
223+ mpeg_play -h (or any other invalid flag) displays dithering and other options.
224+
225+ Note that with gray dithering, very little time is spent converting from the
226+ raw uncompressed data to a screen bitmap suitable for display, making it
227+ significantly faster than the other methods.
228+
229+ The v2.0 source is available on sunsite.unc.edu. For sample MPEG data,
230+ mm-ftp.cs.berkeley.edu, /pub/multimedia is one place to look.
231+
232+ hhanemaa@cs.ruu.nl
233*** gdith.c	Sun Jan 29 22:17:25 1995
234--- mpegvga/gdith.c	Sun Jan 29 22:44:59 1995
235***************
236*** 28,33 ****
237--- 28,35 ----
238   */
239
240  #include <math.h>
241+ #include <vga.h>
242+ #include <vgagl.h>
243  #include "video.h"
244  #include "proto.h"
245  #include "dither.h"
246***************
247*** 52,65 ****
248
249  extern int ditherType;
250
251! /* Structures used by the X server. */
252!
253! Display *display;
254!
255! static XImage *ximage = NULL;
256! static Colormap cmap;
257! static Window window;
258! static GC gc;
259
260  /* Frame Rate Info */
261  extern int framerate;
262--- 54,60 ----
263
264  extern int ditherType;
265
266! int vgamode = -1;
267
268  /* Frame Rate Info */
269  extern int framerate;
270***************
271*** 155,351 ****
272
273  }
274
275- #ifdef SH_MEM
276-
277- int gXErrorFlag = 0;
278-
279- int HandleXError(dpy, event)
280-      Display *dpy;
281-      XErrorEvent *event;
282- {
283-   gXErrorFlag = 1;
284-
285-   return 0;
286- }
287-
288- void InstallXErrorHandler()
289- {
290-   int HandleXError();
291-
292-   XSetErrorHandler(HandleXError);
293-   XFlush(display);
294- }
295
296- void DeInstallXErrorHandler()
297- {
298-   XSetErrorHandler(NULL);
299-   XFlush(display);
300- }
301- #endif
302
303-
304- /*
305-  *--------------------------------------------------------------
306-  *
307-  * ResizeDisplay --
308-  *
309-  *	Resizes display window.
310-  *
311-  * Results:
312-  *	None.
313-  *
314-  * Side effects:
315-  *      None.
316-  *
317-  *--------------------------------------------------------------
318-  */
319
320  void ResizeDisplay(w, h)
321       int w, h;
322  {
323!
324!   if (ditherType == NO_DITHER || ditherType == PPM_DITHER) return;
325!
326!   XResizeWindow(display, window, w, h);
327!   XFlush(display);
328  }
329
330-
331- /*
332-  *--------------------------------------------------------------
333-  *
334-  * MakeWindow --
335-  *
336-  *	Create X Window
337-  *
338-  * Results:
339-  *	Read the code.
340-  *
341-  * Side effects:
342-  *      None.
343-  *
344-  *--------------------------------------------------------------
345-  */
346
347! #ifdef SH_MEM
348! int CompletionType = -1;
349! #endif
350
351  static void
352  MakeWindow(name)
353  char *name;
354  {
355
356!   XSizeHints hint;
357!   unsigned int fg, bg;
358!   char *hello = "MPEG Play";
359!   int screen;
360!   Screen *screen_ptr;
361!   Window CreateFullColorWindow();
362!
363!   if (ditherType == NO_DITHER || ditherType == PPM_DITHER) return;
364!
365!   display = XOpenDisplay(name);
366!   if (display == NULL) {
367!     fprintf(stderr, "Can not open display\n");
368!     exit(-2);
369!   }
370
371! #ifdef SH_MEM
372!   if(shmemFlag)
373!     CompletionType = XShmGetEventBase(display) + ShmCompletion;
374! #endif
375
376!   screen = DefaultScreen (display);
377!   screen_ptr = XDefaultScreenOfDisplay(display);
378!
379!   /* Fill in hint structure */
380
381!   hint.x = 200;
382!   hint.y = 300;
383!   hint.width = 150;
384!   hint.height = 150;
385!   hint.flags = PPosition | PSize;
386!
387!   /* Get some colors */
388!
389!   bg = WhitePixel (display, screen);
390!   fg = BlackPixel (display, screen);
391!
392!   /* Make the window */
393
394!   if (ditherType == FULL_COLOR_DITHER || ditherType==FULL_COLOR2_DITHER) {
395!     window = CreateFullColorWindow (display, hint.x, hint.y, hint.width, hint.height);
396!     if (window == 0) {
397!       fprintf (stderr, "-color option only valid on full color display\n");
398!       exit (-1);
399!     }
400    } else if (ditherType == MONO_DITHER || ditherType == MONO_THRESHOLD) {
401!     window = XCreateSimpleWindow (display,
402! 				  DefaultRootWindow (display),
403! 				  hint.x, hint.y,
404! 				  hint.width, hint.height,
405! 				  4, fg, bg);
406    } else {
407!     XVisualInfo vinfo, *vinfo_ptr;
408!     Visual *vis;
409!     XSetWindowAttributes attrib;
410!     unsigned long attrib_flags=0;
411!
412!     if (!XMatchVisualInfo (display, screen, 8, PseudoColor,
413! 			   &vinfo)) {
414!       if (!XMatchVisualInfo(display, screen, 8, GrayScale,
415! 			    &vinfo)) {
416!         fprintf(stderr, "-requires 8 bit display\n");
417!         exit(-1);
418!       }
419!     }
420!
421!     vis=vinfo.visual;
422!     if (XDefaultDepthOfScreen(screen_ptr) != 8) {
423!       attrib_flags |= CWColormap;
424!       attrib.colormap = XCreateColormap(display, DefaultRootWindow(display),
425! 					vis, AllocNone);
426!       owncmFlag = TRUE;
427!     }
428!
429!     attrib.background_pixel = bg;
430!     attrib.border_pixel = fg;
431!     attrib.backing_store = NotUseful;
432!     attrib.save_under = False;
433!     attrib.background_pixel = bg;
434!     attrib.border_pixel = bg;
435!     attrib_flags |= CWBackPixel | CWBorderPixel | CWBackingStore | CWSaveUnder;
436!     window = XCreateWindow (display,
437! 			    DefaultRootWindow (display),
438! 			    hint.x, hint.y,
439! 			    hint.width, hint.height, 4,
440! 			    8, InputOutput, vis,
441! 			    attrib_flags, &attrib);
442!   }
443!
444!   XSelectInput(display, window, StructureNotifyMask);
445!
446!   /* Tell other applications about this window */
447!
448!   XSetStandardProperties (display, window, hello, hello, None, NULL, 0, &hint);
449!
450!   /* Map window. */
451!
452!   XMapWindow(display, window);
453!
454!   /* Wait for map. */
455!   while(1) {
456!     XEvent	xev;
457!
458!     XNextEvent(display, &xev);
459!     if(xev.type == MapNotify && xev.xmap.event == window)
460!       break;
461!   }
462!
463!   XSelectInput(display, window, NoEventMask);
464  }
465!
466
467  /*
468   *--------------------------------------------------------------
469--- 150,286 ----
470
471  }
472
473
474
475
476  void ResizeDisplay(w, h)
477       int w, h;
478  {
479!   vga_modeinfo *modeinfo;
480!   /* Check if current VGA mode is big enough. */
481!   modeinfo = vga_getmodeinfo(vgamode);
482!   if (w > modeinfo->width || h > modeinfo->height) {
483!     int fail = 0;
484!     if (w > 640 || h > 480)
485!       fail = 1;
486!     else
487!       if (modeinfo->width == 320) {
488!         fail = 1;
489!         switch (modeinfo->bytesperpixel) {
490!         case 1 :
491!   	  if (vga_hasmode(G640x480x256)) {
492!   	    Palette pal;
493!   	    gl_getpalette(&pal);
494!   	    vgamode = G640x480x256;
495! 	    vga_setmode(vgamode);
496! 	    gl_setpalette(&pal);
497! 	    gl_setcontextvga(vgamode);
498! 	    if (ditherType != GRAY_DITHER)
499! 		    gl_clearscreen(255);
500! 	    gl_enableclipping();
501! 	    fail = 0;
502! 	  }
503! 	  break;
504! 	case 2 :
505!   	  if (vga_hasmode(G640x480x32K)) {
506!   	    vgamode = G640x480x32K;
507! 	    vga_setmode(vgamode);
508! 	    gl_setcontextvga(vgamode);
509! 	    gl_enableclipping();
510! 	    fail = 0;
511! 	  }
512! 	  break;
513! 	case 3 :
514!   	  if (vga_hasmode(G640x480x16M)) {
515!   	    vgamode = G640x480x16M;
516! 	    vga_setmode(vgamode);
517! 	    gl_setcontextvga(vgamode);
518! 	    gl_enableclipping();
519! 	    fail = 0;
520! 	  }
521! 	  break;
522!         }
523!       }
524!       else
525!         fail = 1;
526!     if (fail) {
527!     	printf("MPEG screen size too big.\n");
528!     	vga_setmode(TEXT);
529!     	exit(-1);
530!     }
531!   }
532  }
533
534
535! void
536! restoretextmode() {
537!   vga_setmode(TEXT);
538! }
539
540  static void
541  MakeWindow(name)
542  char *name;
543  {
544
545!   if (ditherType == NO_DITHER) return;
546
547!   /* Make the window */
548
549!   vga_disabledriverreport();
550!   vga_init();
551
552!   #define FIRSTRES(c) G320x200x##c
553!   #define SECONDRES(c) G640x480x##c
554
555!   if (ditherType == FULL_COLOR_DITHER) {
556!     /* Look for hicolor/truecolor mode. */
557!     /* 640x480 resolution makes most animations very small. */
558!     /* 320x200 is more full-screen, but the distortions are very visible. */
559!     /* Check default svgalib mode. */
560!     vgamode = vga_getdefaultmode();
561!     if (vgamode != -1) {
562!        if (vga_getmodeinfo(vgamode)->bytesperpixel == 3)
563!          /* Default mode is a truecolor mode. */
564!          goto gotvgamode;
565!        if (vga_getmodeinfo(vgamode)->colors == 32768)
566!          goto gotvgamode;
567!     }
568!     if (vga_hasmode(FIRSTRES(16M)))
569!       vgamode = FIRSTRES(16M);
570!     else if (vga_hasmode(SECONDRES(16M)))
571!       vgamode = SECONDRES(16M);
572!     else if (vga_hasmode(FIRSTRES(32K)))
573!       vgamode = FIRSTRES(32K);
574!     else if (vga_hasmode(SECONDRES(32K)))
575!       vgamode = SECONDRES(32K);
576    } else if (ditherType == MONO_DITHER || ditherType == MONO_THRESHOLD) {
577!     /* set mode suitable for mono display if available */
578!     if (vga_hasmode(G640x480x2))
579!       vgamode = G640x480x2;
580    } else {
581!     /* set 256-color mode */
582!     /* Check default svgalib mode. */
583!     vgamode = vga_getdefaultmode();
584!     if (vgamode != -1)
585!        if (vga_getmodeinfo(vgamode)->bytesperpixel == 1)
586!          /* Default mode is a 256 color mode. */
587!          goto gotvgamode;
588!     if (vga_hasmode(FIRSTRES(256)))
589!       vgamode = FIRSTRES(256);
590!     else if (vga_hasmode(SECONDRES(256)))
591!       vgamode = SECONDRES(256);
592!   }
593!   if (vgamode == -1) {
594!   	printf("Cannot find suitable SVGA graphics mode for selected dithering.\n");
595!   	exit(-1);
596!   }
597! gotvgamode:
598!   printf("Using mode %s.\n", vga_getmodename(vgamode));
599!   vga_setmode(vgamode);
600!   gl_setcontextvga(vgamode);
601!   gl_enableclipping();
602  }
603!
604
605  /*
606   *--------------------------------------------------------------
607***************
608*** 366,429 ****
609  void InitDisplay(name)
610  char *name;
611  {
612
613    int ncolors = LUM_RANGE*CB_RANGE*CR_RANGE;
614-   XColor xcolor;
615    int i, lum_num, cr_num, cb_num;
616!   unsigned char r, g, b;
617!   Colormap dcmap;
618
619    if (ditherType == NO_DITHER) return;
620-   if (noDisplayFlag) return;
621
622    MakeWindow(name);
623
624!   gc = XCreateGC(display, window, 0, 0);
625!
626!   dcmap = cmap = XDefaultColormap(display, DefaultScreen(display));
627!
628!   xcolor.flags = DoRed | DoGreen | DoBlue;
629
630-   if (owncmFlag) goto create_map;
631-   retry_alloc_colors:
632    for (i=0; i<ncolors; i++) {
633
634      lum_num = (i / (CR_RANGE*CB_RANGE))%LUM_RANGE;
635      cr_num = (i / CB_RANGE)%CR_RANGE;
636      cb_num = i % CB_RANGE;
637
638      ConvertColor(lum_values[lum_num], cr_values[cr_num], cb_values[cb_num], &r, &g, &b);
639
640!     xcolor.red = r * 256;
641!     xcolor.green = g * 256;
642!     xcolor.blue = b * 256;
643!
644!     if (XAllocColor(display, cmap, &xcolor) == 0 && cmap == dcmap) {
645!       int j;
646!       unsigned long tmp_pixel;
647!       XWindowAttributes xwa;
648!
649!       if (!quietFlag) {
650!         fprintf(stderr, "Using private colormap.\n");
651!       }
652!
653!       /* Free colors. */
654!       for(j = 0; j < i; j ++) {
655!         tmp_pixel = pixel[j];
656!         XFreeColors(display, cmap, &tmp_pixel, 1, 0);
657!       }
658!
659!       create_map:
660!       XGetWindowAttributes(display, window, &xwa);
661!       cmap = XCreateColormap(display, window, xwa.visual, AllocNone);
662!       XSetWindowColormap(display, window, cmap);
663!
664!       goto retry_alloc_colors;
665      }
666!     pixel[i] = xcolor.pixel;
667    }
668-
669-   ximage = NULL;
670  }
671
672
673--- 301,336 ----
674  void InitDisplay(name)
675  char *name;
676  {
677+ /* For 256 color modes. */
678
679    int ncolors = LUM_RANGE*CB_RANGE*CR_RANGE;
680    int i, lum_num, cr_num, cb_num;
681!   int r, g, b;
682
683    if (ditherType == NO_DITHER) return;
684
685    MakeWindow(name);
686
687!   gl_setpalettecolor(255, 0, 0, 0);	/* black */
688!   gl_clearscreen(255);
689
690    for (i=0; i<ncolors; i++) {
691
692      lum_num = (i / (CR_RANGE*CB_RANGE))%LUM_RANGE;
693      cr_num = (i / CB_RANGE)%CR_RANGE;
694      cb_num = i % CB_RANGE;
695
696+     r = g = b = 0;
697      ConvertColor(lum_values[lum_num], cr_values[cr_num], cb_values[cb_num], &r, &g, &b);
698
699!     if (i > 256) {
700!       printf("mpeg_vga: not enough colors.\n");
701!       vga_setmode(TEXT);
702!       exit(-1);
703      }
704!     gl_setpalettecolor(i, r >> 2, g >> 2, b >> 2);
705!     pixel[i] = i;
706    }
707  }
708
709
710***************
711*** 443,572 ****
712   *--------------------------------------------------------------
713   */
714
715! void InitGrayDisplay(name)
716! char *name;
717! {
718!   int ncolors = 128;
719!   XColor xcolor;
720!   int i;
721!   Colormap dcmap;
722!
723!   MakeWindow(name);
724!
725!   gc = XCreateGC(display, window, 0, 0);
726!
727!   dcmap = cmap = XDefaultColormap(display, DefaultScreen(display));
728!
729!   xcolor.flags = DoRed | DoGreen | DoBlue;
730!
731!   if (owncmFlag) goto create_map;
732!   retry_alloc_grays:
733!   for (i=0; i<ncolors; i++) {
734!
735!     xcolor.red = (i*2) * 256;
736!     xcolor.green = (i*2) * 256;
737!     xcolor.blue = (i*2) * 256;
738!
739!     if(XAllocColor(display, cmap, &xcolor) == 0 && cmap == dcmap) {
740!       int j;
741!       unsigned long tmp_pixel;
742!       XWindowAttributes xwa;
743!
744!       if (!quietFlag) {
745!         fprintf(stderr, "Using private colormap.\n");
746!       }
747!
748!       /* Free colors. */
749!       for(j = 0; j < i; j ++) {
750!         tmp_pixel = pixel[j*2];
751!         XFreeColors(display, cmap, &tmp_pixel, 1, 0);
752!       }
753!
754!       create_map:
755!       XGetWindowAttributes(display, window, &xwa);
756!       cmap = XCreateColormap(display, window, xwa.visual, AllocNone);
757!       XSetWindowColormap(display, window, cmap);
758!
759!       goto retry_alloc_grays;
760!     }
761!     pixel[(i*2)] = xcolor.pixel;
762!     pixel[(i*2)+1] = xcolor.pixel;
763!   }
764
765!   ximage = NULL;
766! }
767!
768!
769! /*
770!  *--------------------------------------------------------------
771!  *
772!  * InitGray256Display --
773!  *
774!  *	Initialized display for gray scale dither with 256 levels
775!  *
776!  * Results:
777!  *      None.
778!  *
779!  * Side effects:
780!  *      None.
781!  *
782!  *--------------------------------------------------------------
783!  */
784!
785!
786! void InitGray256Display(name)
787  char *name;
788  {
789!   int ncolors = 256;
790!   XColor xcolor;
791    int i;
792-   Colormap dcmap;
793-   int result;
794-   XWindowAttributes xwa;
795
796    MakeWindow(name);
797
798-   gc = XCreateGC(display, window, 0, 0);
799-
800-   dcmap = cmap = XDefaultColormap(display, DefaultScreen(display));
801-
802-   xcolor.flags = DoRed | DoGreen | DoBlue;
803-
804-   if (owncmFlag) {
805-     XGetWindowAttributes(display, window, &xwa);
806-     cmap = XCreateColormap(display, window, xwa.visual, AllocNone);
807-     XSetWindowColormap(display, window, cmap);
808-   }
809-
810-   retry_alloc_grays:
811    for (i=0; i<ncolors; i++) {
812!     xcolor.red = i * 256;
813!     xcolor.green = i * 256;
814!     xcolor.blue = i * 256;
815!     if((result=XAllocColor(display, cmap, &xcolor)) == 0 && cmap == dcmap) {
816!       int j;
817!       unsigned long tmp_pixel;
818!
819!       if (!quietFlag) {
820!         fprintf(stderr, "Using private colormap.\n");
821!       }
822!
823!       /* Free colors. */
824!       for(j = 0; j < i; j ++) {
825!         tmp_pixel = pixel[j];
826!         XFreeColors(display, cmap, &tmp_pixel, 1, 0);
827!       }
828!
829!       XGetWindowAttributes(display, window, &xwa);
830!       cmap = XCreateColormap(display, window, xwa.visual, AllocNone);
831!       XSetWindowColormap(display, window, cmap);
832!
833!       goto retry_alloc_grays;
834!     }
835!     pixel[i] = xcolor.pixel;
836    }
837-
838-   ximage = NULL;
839  }
840
841
842--- 350,374 ----
843   *--------------------------------------------------------------
844   */
845
846! #define NUM_COLORS 256
847
848! void InitGrayDisplay(name)
849  char *name;
850  {
851!   int ncolors = NUM_COLORS;
852    int i;
853
854    MakeWindow(name);
855
856    for (i=0; i<ncolors; i++) {
857!     int r, g, b;
858!     r = i;
859!     g = i;
860!     b = i;
861!
862!     gl_setpalettecolor(i, r / 4, g / 4, b / 4);
863!     pixel[i] = i;
864    }
865  }
866
867
868***************
869*** 589,608 ****
870  void InitMonoDisplay(name)
871  char *name;
872  {
873-   XGCValues xgcv;
874
875    MakeWindow(name);
876
877-   xgcv.background = BlackPixel(display, DefaultScreen(display));
878-   xgcv.foreground = WhitePixel(display, DefaultScreen(display));
879-
880-   gc = XCreateGC(display, window, GCForeground | GCBackground, &xgcv);
881-
882-   ximage = NULL;
883  }
884
885
886-
887  /*
888   *--------------------------------------------------------------
889   *
890--- 391,402 ----
891***************
892*** 625,632 ****
893
894    MakeWindow(name);
895
896-   gc = XCreateGC(display, window, 0, 0);
897-   ximage = NULL;
898  }
899
900
901--- 419,424 ----
902***************
903*** 650,659 ****
904  ExecuteDisplay(vid_stream)
905       VidStream *vid_stream;
906  {
907-   char dummy;
908-   Visual *FindFullColorVisual();
909-   Visual *fc_visual;
910-   int depth;
911    static int rate_deal=-1, one_frame_time;
912    static struct timeval tftarget, tfnow;
913    int zero=0;
914--- 442,447 ----
915***************
916*** 664,669 ****
917--- 452,459 ----
918      fprintf (stderr, "%d\r", totNumFrames);
919    }
920
921+   if (ditherType == NO_DITHER) return;
922+
923    if (partialFlag)
924      if (!((totNumFrames>=startFrame) &&
925  	  ((endFrame==-1) || (totNumFrames<=endFrame))))
926***************
927*** 722,790 ****
928      while ((foo=getchar())!='\n');
929    }
930
931-   if (ditherType == NO_DITHER) return;
932    if (ditherType == PPM_DITHER) {
933      ExecutePPM(vid_stream);
934      return;
935    }
936
937!   if (ximage == NULL) {
938!
939!     if (ditherType == Twox2_DITHER) {
940!       ximage = XCreateImage(display, None, 8, ZPixmap, 0, &dummy,
941! 			    vid_stream->mb_width * 32,
942! 			    vid_stream->mb_height * 32, 8, 0);
943!     } else if (ditherType == FULL_COLOR_DITHER) {
944!       fc_visual = FindFullColorVisual(display, &depth);
945!       ximage = XCreateImage (display, fc_visual, depth, ZPixmap,
946! 			     0, &dummy, vid_stream->mb_width * 16,
947! 			     vid_stream->mb_height * 16, 32, 0);
948!     } else if (ditherType == FULL_COLOR2_DITHER) {
949!       fc_visual = FindFullColorVisual(display, &depth);
950!       ximage = XCreateImage (display, fc_visual, depth, ZPixmap,
951! 			     0, &dummy, vid_stream->mb_width * 32,
952! 			     vid_stream->mb_height * 32, 32, 0);
953!     } else if (ditherType == MONO_DITHER || ditherType == MONO_THRESHOLD) {
954!       ximage = XCreateImage (display, None, 1, XYBitmap, 0, &dummy,
955! 			     vid_stream->mb_width * 16,
956! 			     vid_stream->mb_height * 16, 8, 0);
957!       ximage->byte_order = MSBFirst;
958!       ximage->bitmap_bit_order = MSBFirst;
959!     } else {
960!       ximage = XCreateImage(display, None, 8, ZPixmap, 0, &dummy,
961! 			    vid_stream->mb_width * 16,
962! 			    vid_stream->mb_height * 16, 8, 0);
963!     }
964!   }
965!
966!   if (!noDisplayFlag) {
967! #ifdef SH_MEM
968!     if (shmemFlag) {
969!       XShmPutImage(display, window, gc, vid_stream->current->ximage,
970! 		   0, 0, 0, 0,
971! 		   vid_stream->current->ximage->width,
972! 		   vid_stream->current->ximage->height, True);
973!       XFlush(display);
974!
975!       while(1) {
976! 	XEvent xev;
977!
978! 	XNextEvent(display, &xev);
979! 	if(xev.type == CompletionType)
980! 	  break;
981!       }
982!     }
983!     else
984! #endif
985!
986        {
987! 	ximage->data = (char *) vid_stream->current->display;
988
989! 	XPutImage(display, window, gc, ximage, 0, 0, 0, 0, ximage->width, ximage->height);
990        }
991-   }
992  }
993-
994
995  extern char *inputName;
996  extern char *strrchr();
997--- 512,623 ----
998      while ((foo=getchar())!='\n');
999    }
1000
1001    if (ditherType == PPM_DITHER) {
1002      ExecutePPM(vid_stream);
1003      return;
1004    }
1005
1006!   if (!noDisplayFlag)
1007        {
1008! 	void *data = (char *) vid_stream->current->display;
1009
1010! 	if (ditherType == Twox2_DITHER) {
1011! 	  /* Twice the size; 256-color mode */
1012! 	  gl_putbox(0, 0, vid_stream->h_size * 2,
1013! 	    vid_stream->v_size * 2, data);
1014! 	} else if (ditherType == FULL_COLOR_DITHER && BYTESPERPIXEL == 3) {
1015! 	  /* Tricky conversion. */
1016! 	  /* The data is padded to 32 bits per pixel, we need 24 bits. */
1017! 	  int i, w;
1018! 	  unsigned int *datap;
1019! 	  void *box;
1020! 	  unsigned char *boxp;
1021! 	  datap = data;
1022! 	  w = vid_stream->h_size;
1023! 	  box = alloca(vid_stream->v_size * w * 3 + 3);
1024! 	  boxp = box;
1025! 	  for (i = 0; i < vid_stream->v_size; i++) {
1026! 	    int j = 0;
1027! 	    /* First byte is blue. */
1028! 	    /* Nasty overlapping memory writes, but it is fast. */
1029! 	    /* Note that boxp points to bytes, datap to words. */
1030!             while (j + 7 < w) {
1031!          	*(unsigned *)boxp = *datap;
1032!             	*(unsigned *)(boxp + 3) = *(datap + 1);
1033!             	*(unsigned *)(boxp + 6) = *(datap + 2);
1034!             	*(unsigned *)(boxp + 9) = *(datap + 3);
1035!             	*(unsigned *)(boxp + 12) = *(datap + 4);
1036!             	*(unsigned *)(boxp + 15) = *(datap + 5);
1037!             	*(unsigned *)(boxp + 18) = *(datap + 6);
1038!             	*(unsigned *)(boxp + 21) = *(datap + 7);
1039!             	j += 8;
1040!             	boxp += 24;
1041!             	datap += 8;
1042!             }
1043!             while (j < w) {
1044!               *(unsigned *)boxp = *datap;
1045!               j++;
1046!               boxp += 3;
1047!               datap++;
1048!             }
1049! 	  }
1050! 	  gl_putbox(0, 0, vid_stream->h_size, vid_stream->v_size, box);
1051! 	} else if (ditherType == FULL_COLOR_DITHER && BYTESPERPIXEL == 2) {
1052! 	  /* The data is 8-8-8 truecolor padded to 32 bits, we need */
1053! 	  /* 15-bit 5-5-5 truecolor. Pretty slow conversion. */
1054! 	  int i, w;
1055! 	  unsigned int *datap;
1056! 	  void *box;
1057! 	  unsigned char *boxp;
1058! 	  datap = data;
1059! 	  w = vid_stream->h_size;
1060! 	  box = alloca(vid_stream->v_size * w * 2 + 3);
1061! 	  boxp = box;
1062! 	  for (i = 0; i < vid_stream->v_size; i++) {
1063! 	    int j = 0;
1064! 	    /* First byte is blue. */
1065! 	    /* Note that boxp points to bytes, datap to words. */
1066!             while (j + 1 < w) {
1067!             	unsigned r, g, b;
1068!         	b = *((unsigned char *)datap);
1069!         	g = *((unsigned char *)datap + 1);
1070!         	r = *((unsigned char *)datap + 2);
1071!             	*(unsigned short *)boxp =
1072!             		((r & 0xf8) << 7) + ((g & 0xf8) << 2) + (b >> 3);
1073!         	b = *((unsigned char *)datap + 4);
1074!         	g = *((unsigned char *)datap + 5);
1075!         	r = *((unsigned char *)datap + 6);
1076!             	*(unsigned short *)(boxp + 2) =
1077!             		((r & 0xf8) << 7) + ((g & 0xf8) << 2) + (b >> 3);
1078!             	j += 2;
1079!             	boxp += 4;
1080!             	datap += 2;
1081!             }
1082!             while (j < w) {
1083!             	unsigned r, g, b;
1084!         	r = *((unsigned char *)datap);
1085!         	g = *((unsigned char *)datap + 1);
1086!         	g = *((unsigned char *)datap + 2);
1087!             	*(unsigned short *)boxp =
1088!             		((r & 0xf8) << 7) + ((g & 0xf8) << 2) + (b >> 3);
1089!             	j++;
1090!             	boxp += 2;
1091!             	datap++;
1092!             }
1093! 	  }
1094! 	  gl_putbox(0, 0, vid_stream->h_size, vid_stream->v_size, box);
1095!         } else if (ditherType == MONO_DITHER || ditherType == MONO_THRESHOLD) {
1096!           /* It's MSBFirst, which is what we need. */
1097!           int i;
1098!           for (i = 0; i < vid_stream->v_size; i++)
1099!             vga_drawscansegment(data + i * vid_stream->h_size / 8,
1100!               0, i, vid_stream->h_size / 8);
1101!         } else {
1102!           /* default 256-color dithering */
1103! 	  gl_putbox(0, 0, vid_stream->h_size, vid_stream->v_size, data);
1104! 	}
1105        }
1106  }
1107
1108  extern char *inputName;
1109  extern char *strrchr();
1110*** main.c	Sun Jan 29 22:17:25 1995
1111--- mpegvga/main.c	Sun Jan 29 22:48:49 1995
1112***************
1113*** 128,133 ****
1114--- 128,134 ----
1115    }
1116    if (curVidStream != NULL)
1117      DestroyVidStream(curVidStream);
1118+   restoretextmode();
1119    exit(1);
1120  }
1121  #else
1122***************
1123*** 140,145 ****
1124--- 141,147 ----
1125    }
1126    if (curVidStream != NULL)
1127      DestroyVidStream(curVidStream);
1128+   restoretextmode();
1129    exit(1);
1130  }
1131  #endif
1132***************
1133*** 307,324 ****
1134        exit(1);
1135  #endif
1136      }
1137-     else if (strcmp(argv[mark], "-shmem_off") == 0) {
1138-       argc--; mark++;
1139-       shmemFlag = 0;
1140-     }
1141      else if (strcmp(argv[mark], "-quiet") == 0) {
1142        argc--; mark++;
1143        quietFlag = 1;
1144      }
1145-     else if (strcmp(argv[mark], "-owncm") == 0) {
1146-       argc--; mark++;
1147-       owncmFlag = 1;
1148-     }
1149      else if (strcmp(argv[mark], "-step") == 0) {
1150        argc--; mark++;
1151        requireKeypressFlag = 1;
1152--- 309,318 ----
1153***************
1154*** 432,442 ****
1155      break;
1156
1157    case GRAY_DITHER:
1158-     InitGrayDisplay(name);
1159-     break;
1160-
1161    case GRAY256_DITHER:
1162!     InitGray256Display(name);
1163      break;
1164
1165    case FULL_COLOR_DITHER:
1166--- 426,433 ----
1167      break;
1168
1169    case GRAY_DITHER:
1170    case GRAY256_DITHER:
1171!     InitGrayDisplay(name);
1172      break;
1173
1174    case FULL_COLOR_DITHER:
1175***************
1176*** 483,500 ****
1177
1178    }
1179
1180- #ifdef SH_MEM
1181-     if (shmemFlag && (display != NULL)) {
1182-       if (!XShmQueryExtension(display)) {
1183- 	shmemFlag = 0;
1184- 	if (!quietFlag) {
1185- 	  fprintf(stderr, "Shared memory not supported\n");
1186- 	  fprintf(stderr, "Reverting to normal Xlib.\n");
1187- 	}
1188-       }
1189-     }
1190- #endif
1191-
1192    if (setjmp(env) != 0) {
1193
1194      DestroyVidStream(theStream);
1195--- 474,479 ----
1196***************
1197*** 568,575 ****
1198      fprintf(stderr, "      [-framerate num]\n");
1199      fprintf(stderr, "      [-no_display]\n");
1200      fprintf(stderr, "      [-quiet]\n");
1201-     fprintf(stderr, "      [-owncm]\n");
1202-     fprintf(stderr, "      [-shmem_off]\n");
1203  	fprintf(stderr, "      [-l_range num]\n");
1204  	fprintf(stderr, "      [-cr_range num]\n");
1205  	fprintf(stderr, "      [-cb_range num]\n");
1206--- 547,552 ----
1207