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
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.