~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Open Mash Cross Reference
mash/codec/tmndec/display.c

Component: ~ [ mash ] ~ [ apps ] ~ [ gsm ] ~ [ lib ] ~ [ otcl ] ~ [ srm ] ~ [ tcl8.3 ] ~ [ tclcl ] ~ [ tk8.3 ] ~ [ tutorials ] ~

  1 /************************************************************************
  2  *
  3  *  display.c, X11 interface for tmndecode (H.263 decoder)
  4  *  Copyright (C) 1995, 1996  Telenor R&D, Norway
  5  *
  6  *  Contacts:
  7  *  Robert Danielsen                  <Robert.Danielsen@nta.no>
  8  *
  9  *  Telenor Research and Development  http://www.nta.no/brukere/DVC/
 10  *  P.O.Box 83                        tel.:   +47 63 84 84 00
 11  *  N-2007 Kjeller, Norway            fax.:   +47 63 81 00 76
 12  *
 13  *  Copyright (C) 1997  University of BC, Canada
 14  *  Modified by: Michael Gallant <mikeg@ee.ubc.ca>
 15  *               Guy Cote <guyc@ee.ubc.ca>
 16  *               Berna Erol <bernae@ee.ubc.ca>
 17  *               
 18  *  Contacts:
 19  *  Michael Gallant                   <mikeg@ee.ubc.ca>
 20  *
 21  *  UBC Image Processing Laboratory   http://www.ee.ubc.ca/image
 22  *  2356 Main Mall                    tel.: +1 604 822 4051
 23  *  Vancouver BC Canada V6T1Z4        fax.: +1 604 822 5949
 24  *
 25  ************************************************************************/
 26 
 27 /* Disclaimer of Warranty
 28  * 
 29  * These software programs are available to the user without any license fee
 30  * or royalty on an "as is" basis. The University of British Columbia
 31  * disclaims any and all warranties, whether express, implied, or
 32  * statuary, including any implied warranties or merchantability or of
 33  * fitness for a particular purpose.  In no event shall the
 34  * copyright-holder be liable for any incidental, punitive, or
 35  * consequential damages of any kind whatsoever arising from the use of
 36  * these programs.
 37  * 
 38  * This disclaimer of warranty extends to the user of these programs and
 39  * user's customers, employees, agents, transferees, successors, and
 40  * assigns.
 41  * 
 42  * The University of British Columbia does not represent or warrant that the
 43  * programs furnished hereunder are free of infringement of any
 44  * third-party patents.
 45  * 
 46  * Commercial implementations of H.263, including shareware, are subject to
 47  * royalty fees to patent holders.  Many of these patents are general
 48  * enough such that they are unavoidable regardless of implementation
 49  * design.
 50  * 
 51  */
 52 
 53 
 54 /* based on mpeg2decode, (C) 1994, MPEG Software Simulation Group and
 55  * mpeg2play, (C) 1994 Stefan Eckart <stefan@lis.e-technik.tu-muenchen.de>
 56  * 
 57  */
 58 
 59 /* the Xlib interface is closely modeled after mpeg_play 2.0 by the
 60  * Berkeley Plateau Research Group */
 61 
 62 #ifdef DISPLAY
 63 
 64 #include <stdio.h>
 65 #include <stdlib.h>
 66 
 67 #include <X11/Xlib.h>
 68 #include <X11/Xutil.h>
 69 
 70 #include "config.h"
 71 #include "tmndec.h"
 72 #include "global.h"
 73 
 74 /* private prototypes */
 75 static void display_image _ANSI_ARGS_ ((XImage * ximage, unsigned char *dithered_image));
 76 
 77 /* display related data */
 78 unsigned long wpixel[3];
 79 static unsigned char *dithered_image;
 80 
 81 /* X11 related variables */
 82 static Display *display;
 83 static Window window;
 84 static GC gc;
 85 static int dpy_depth;
 86 
 87 XImage *ximage;
 88 
 89 unsigned char pixel[256];
 90 
 91 #ifdef SH_MEM
 92 
 93 #include <sys/ipc.h>
 94 #include <sys/shm.h>
 95 #include <X11/extensions/XShm.h>
 96 
 97 extern int XShmQueryExtension _ANSI_ARGS_ ((Display * dpy));
 98 extern int XShmGetEventBase _ANSI_ARGS_ ((Display * dpy));
 99 
100 static int HandleXError _ANSI_ARGS_ ((Display * dpy, XErrorEvent * event));
101 static void InstallXErrorHandler _ANSI_ARGS_ ((void));
102 static void DeInstallXErrorHandler _ANSI_ARGS_ ((void));
103 
104 static int shmem_flag;
105 static XShmSegmentInfo shminfo1, shminfo2;
106 static int gXErrorFlag;
107 static int CompletionType = -1;
108 
109 static int HandleXError (dpy, event)
110   Display *dpy;
111   XErrorEvent *event;
112 {
113   gXErrorFlag = 1;
114 
115   return 0;
116 }
117 
118 static void InstallXErrorHandler ()
119 {
120   XSetErrorHandler (HandleXError);
121   XFlush (display);
122 }
123 
124 static void DeInstallXErrorHandler ()
125 {
126   XSetErrorHandler (NULL);
127   XFlush (display);
128 }
129 
130 #endif
131 
132 /* connect to server, create and map window, allocate colors and (shared)
133  * memory */
134 void init_display (name)
135   char *name;
136 {
137   int crv, cbu, cgu, cgv;
138   int y, u, v, r, g, b;
139   int i;
140   char dummy;
141   int screen;
142   Visual *visual;
143   int dpy_class;
144   Colormap cmap;
145   int private;
146   XColor xcolor;
147   unsigned int fg, bg;
148   char *hello = "H.263 Display";
149   XSizeHints hint;
150   XEvent xev;
151   XSetWindowAttributes xswa;
152   unsigned long tmp_pixel;
153   unsigned int mask;
154 
155   display = XOpenDisplay (name);
156 
157   if (display == NULL)
158     error ("Can not open display\n");
159 
160   screen = DefaultScreen (display);
161 
162   visual = DefaultVisual (display, screen);
163   dpy_depth = DefaultDepth (display, screen);
164   dpy_class = visual->class;
165 
166   if (!((dpy_class == TrueColor && dpy_depth == 32)
167         || (dpy_class == TrueColor && dpy_depth == 24)
168         || (dpy_class == TrueColor && dpy_depth == 16)
169         || (dpy_class == PseudoColor && dpy_depth == 8)))
170     error ("requires 8 bit PseudoColor or 16/24/32 bit TrueColor display\n");
171 
172   if (dpy_class == TrueColor && dpy_depth == 32)
173     printf ("TrueColor : 32 bit colordepth\n");
174   if (dpy_class == TrueColor && dpy_depth == 24)
175     printf ("TrueColor : 24 bit colordepth\n");
176   if (dpy_class == TrueColor && dpy_depth == 16)
177     printf ("TrueColor : 16 bit colordepth\n");
178   if (dpy_class == PseudoColor && dpy_depth == 8)
179     printf ("PseudoColor : 8 bit colordepth, 4x4 ordered dither\n");
180 
181   /* width and height of the display window */
182   if (expand)
183   {
184     hint.min_width = hint.max_width = hint.width = 2 * horizontal_size;
185     hint.min_height = hint.max_height = hint.height = 2 * vertical_size;
186   } else
187   {
188     hint.min_width = hint.max_width = hint.width = horizontal_size;
189     hint.min_height = hint.max_height = hint.height = vertical_size;
190   }
191 
192   hint.flags = PSize | PMinSize | PMaxSize;
193 
194   /* Get some colors */
195 
196   bg = WhitePixel (display, screen);
197   fg = BlackPixel (display, screen);
198 
199   /* Make the window */
200   mask = CWBackPixel | CWBorderPixel;
201   if (dpy_depth == 32 || dpy_depth == 24 || dpy_depth == 16)
202   {
203     mask |= CWColormap;
204     xswa.colormap = XCreateColormap (display, DefaultRootWindow (display),
205                                      visual, AllocNone);
206   }
207   xswa.background_pixel = bg;
208   xswa.border_pixel = fg;
209   window = XCreateWindow (display, DefaultRootWindow (display),
210                           hint.x, hint.y, hint.width, hint.height,
211                           1, dpy_depth, InputOutput, visual, mask, &xswa);
212 
213 
214   XSelectInput (display, window, StructureNotifyMask);
215 
216   /* Tell other applications about this window */
217 
218   XSetStandardProperties (display, window, hello, hello, None, NULL, 0, &hint);
219 
220   /* Map window. */
221 
222   XMapWindow (display, window);
223 
224   /* Wait for map. */
225   do
226   {
227     XNextEvent (display, &xev);
228   }
229   while (xev.type != MapNotify || xev.xmap.event != window);
230 
231   XSelectInput (display, window, NoEventMask);
232 
233   /* allocate colors */
234 
235   gc = DefaultGC (display, screen);
236 
237   if (dpy_depth == 8)
238   {
239     XWindowAttributes xwa;
240 
241     cmap = DefaultColormap (display, screen);
242     private = 0;
243 
244     /* matrix coefficients */
245     crv = convmat[matrix_coefficients][0];
246     cbu = convmat[matrix_coefficients][1];
247     cgu = convmat[matrix_coefficients][2];
248     cgv = convmat[matrix_coefficients][3];
249 
250     /* color allocation: i is the (internal) 8 bit color number, it
251      * consists of separate bit fields for Y, U and V: i = (yyyyuuvv), we
252      * don't use yyyy=0000 yyyy=0001 and yyyy=1111, this leaves 48 colors
253      * for other applications
254      * 
255      * the allocated colors correspond to the following Y, U and V values: Y:
256      * 40, 56, 72, 88, 104, 120, 136, 152, 168, 184, 200, 216, 232 U,V:
257      * -48, -16, 16, 48
258      * 
259      * U and V values span only about half the color space; this gives
260      * usually much better quality, although highly saturated colors can
261      * not be displayed properly
262      * 
263      * translation to R,G,B is implicitly done by the color look-up table */
264     for (i = 32; i < 240; i++)
265     {
266       /* color space conversion */
267       y = 16 * ((i >> 4) & 15) + 8;
268       u = 32 * ((i >> 2) & 3) - 48;
269       v = 32 * (i & 3) - 48;
270 
271       y = 76309 * (y - 16);     /* (255/219)*65536 */
272 
273       r = clp[(y + crv * v + 32768) >> 16];
274       g = clp[(y - cgu * u - cgv * v + 32768) >> 16];
275       b = clp[(y + cbu * u + 32786) >> 16];
276 
277       /* X11 colors are 16 bit */
278       xcolor.red = r << 8;
279       xcolor.green = g << 8;
280       xcolor.blue = b << 8;
281 
282       if (XAllocColor (display, cmap, &xcolor) != 0)
283         pixel[i] = xcolor.pixel;
284       else
285       {
286         /* allocation failed, have to use a private colormap */
287 
288         if (private)
289           error ("Couldn't allocate private colormap");
290 
291         private = 1;
292 
293         if (!quiet)
294           fprintf (stderr, "Using private colormap (%d colors were "
295                    "available).\n", i - 32);
296 
297         /* Free colors. */
298         while (--i >= 32)
299         {
300           tmp_pixel = pixel[i]; /* because XFreeColors expects unsigned
301                                  * long */
302           XFreeColors (display, cmap, &tmp_pixel, 1, 0);
303         }
304 
305         /* i is now 31, this restarts the outer loop */
306 
307         /* create private colormap */
308 
309         XGetWindowAttributes (display, window, &xwa);
310         cmap = XCreateColormap (display, window, xwa.visual, AllocNone);
311         XSetWindowColormap (display, window, cmap);
312       }
313     }
314   }
315 #ifdef SH_MEM
316   if (XShmQueryExtension (display))
317     shmem_flag = 1;
318   else
319   {
320     shmem_flag = 0;
321     if (!quiet)
322       fprintf (stderr, "Shared memory not supported\nReverting to normal "
323                "Xlib\n");
324   }
325 
326   if (shmem_flag)
327     CompletionType = XShmGetEventBase (display) + ShmCompletion;
328 
329   InstallXErrorHandler ();
330 
331   if (shmem_flag)
332   {
333 
334     if (expand)
335       ximage = XShmCreateImage (display, visual, dpy_depth, ZPixmap, NULL,
336                                 &shminfo1,
337                       2 * coded_picture_width, 2 * coded_picture_height);
338     else
339       ximage = XShmCreateImage (display, visual, dpy_depth, ZPixmap, NULL,
340                                 &shminfo1,
341                               coded_picture_width, coded_picture_height);
342 
343 
344     /* If no go, then revert to normal Xlib calls. */
345 
346     if (ximage == NULL)
347     {
348       if (ximage != NULL)
349         XDestroyImage (ximage);
350       if (!quiet)
351         fprintf (stderr, "Shared memory error, disabling (Ximage error)\n");
352       goto shmemerror;
353     }
354     /* Success here, continue. */
355 
356     shminfo1.shmid = shmget (IPC_PRIVATE,
357                              ximage->bytes_per_line * ximage->height,
358                              IPC_CREAT | 0777);
359 
360     if (shminfo1.shmid < 0)
361     {
362       XDestroyImage (ximage);
363       if (!quiet)
364         fprintf (stderr, "Shared memory error, disabling (seg id error)\n");
365       goto shmemerror;
366     }
367     shminfo1.shmaddr = (char *) shmat (shminfo1.shmid, 0, 0);
368     shminfo2.shmaddr = (char *) shmat (shminfo2.shmid, 0, 0);
369 
370     if (shminfo1.shmaddr == ((char *) -1))
371     {
372       XDestroyImage (ximage);
373       if (shminfo1.shmaddr != ((char *) -1))
374         shmdt (shminfo1.shmaddr);
375       if (!quiet)
376       {
377         fprintf (stderr, "Shared memory error, disabling (address error)\n");
378       }
379       goto shmemerror;
380     }
381     ximage->data = shminfo1.shmaddr;
382     dithered_image = (unsigned char *) ximage->data;
383     shminfo1.readOnly = False;
384     XShmAttach (display, &shminfo1);
385 
386     XSync (display, False);
387 
388     if (gXErrorFlag)
389     {
390       /* Ultimate failure here. */
391       XDestroyImage (ximage);
392       shmdt (shminfo1.shmaddr);
393       if (!quiet)
394         fprintf (stderr, "Shared memory error, disabling.\n");
395       gXErrorFlag = 0;
396       goto shmemerror;
397     } else
398     {
399       shmctl (shminfo1.shmid, IPC_RMID, 0);
400     }
401 
402     if (!quiet)
403     {
404       fprintf (stderr, "Sharing memory.\n");
405     }
406   } else
407   {
408 shmemerror:
409     shmem_flag = 0;
410 #endif
411 
412 
413     if (expand)
414     {
415       ximage = XCreateImage (display, visual, dpy_depth, ZPixmap, 0, &dummy,
416                 2 * coded_picture_width, 2 * coded_picture_height, 8, 0);
417       if (!(dithered_image =
418             (unsigned char *) malloc (coded_picture_width * coded_picture_height *
419                                       (dpy_depth > 8 ? sizeof (int) * 4 :
420                                        sizeof (unsigned char)) * 4)))
421         error ("malloc failed");
422     } else
423     {
424       ximage = XCreateImage (display, visual, dpy_depth, ZPixmap, 0, &dummy,
425                         coded_picture_width, coded_picture_height, 8, 0);
426       if (!(dithered_image =
427             (unsigned char *) malloc (coded_picture_width * coded_picture_height *
428                                       (dpy_depth > 8 ? sizeof (int) :
429                                        sizeof (unsigned char)))))
430         error ("malloc failed");
431     }
432 
433 #ifdef SH_MEM
434   }
435 
436   DeInstallXErrorHandler ();
437 #endif
438 
439 
440   if (dpy_depth == 32 || dpy_depth == 24 || dpy_depth == 16)
441   {
442     XWindowAttributes xwa;
443 
444     XGetWindowAttributes (display, window, &xwa);
445 
446 
447     wpixel[0] = xwa.visual->red_mask;
448     wpixel[1] = xwa.visual->green_mask;
449     wpixel[2] = xwa.visual->blue_mask;
450 
451     /* If the colors in 16/24/32-bit mode are wrong, try this instead of
452      * the above three lines */
453     /* wpixel[2] = xwa.visual->red_mask; wpixel[1] =
454      * xwa.visual->green_mask; wpixel[0] = xwa.visual->blue_mask; */
455 
456     InitColorDither (dpy_depth == 24 || dpy_depth == 32);
457   } else
458   {
459     ord4x4_dither_init ();
460   }
461 }
462 
463 void exit_display ()
464 {
465 #ifdef SH_MEM
466   if (shmem_flag)
467   {
468     XShmDetach (display, &shminfo1);
469     XDestroyImage (ximage);
470     shmdt (shminfo1.shmaddr);
471   }
472 #endif
473 }
474 
475 static void display_image (ximage, dithered_image)
476   XImage *ximage;
477   unsigned char *dithered_image;
478 {
479   int t = 1;
480 
481   /* Always work in native bit and byte order. This tells Xlib to reverse
482    * bit and byte order if necessary when crossing a network. Frankly,
483    * this part of XImages is somewhat underdocumented, so this may not be
484    * exactly correct.  */
485 
486   if (*(char *) &t == 1)
487   {
488     ximage->byte_order = LSBFirst;
489     ximage->bitmap_bit_order = LSBFirst;
490   } else
491   {
492     ximage->byte_order = MSBFirst;
493     ximage->bitmap_bit_order = MSBFirst;
494   }
495 
496   /* display dithered image */
497 #ifdef SH_MEM
498   if (shmem_flag)
499   {
500     XShmPutImage (display, window, gc, ximage,
501                   0, 0, 0, 0, ximage->width, ximage->height, True);
502     XFlush (display);
503 
504     while (1)
505     {
506       XEvent xev;
507 
508       XNextEvent (display, &xev);
509       if (xev.type == CompletionType)
510         break;
511     }
512   } else
513 #endif
514   {
515     ximage->data = (char *) dithered_image;
516     XPutImage (display, window, gc, ximage, 0, 0, 0, 0, ximage->width, ximage->height);
517   }
518 }
519 
520 
521 void dither (src)
522   unsigned char *src[];
523 {
524   if (dpy_depth == 24 || dpy_depth == 32)
525   {
526     if (ximage->bits_per_pixel == 24)
527       ConvertYUVtoRGB (src[0], src[1], src[2], dithered_image,
528                        coded_picture_width,
529                        coded_picture_height);
530     else
531       Color32DitherImage (src, dithered_image);
532   } else if (dpy_depth == 16)
533   {
534     Color16DitherImage (src, dithered_image);
535   } else
536   {
537     ord4x4_dither_frame (src, dithered_image);
538   }
539 
540   display_image (ximage, dithered_image);
541 }
542 
543 #endif
544 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.