📄 display.c
字号:
/************************************************************************ * * display.c, X11 interface for tmndecode (H.263 decoder) * Copyright (C) 1995, 1996 Telenor R&D, Norway * * Contacts: * Robert Danielsen <Robert.Danielsen@nta.no> * * Telenor Research and Development http://www.nta.no/brukere/DVC/ * P.O.Box 83 tel.: +47 63 84 84 00 * N-2007 Kjeller, Norway fax.: +47 63 81 00 76 * * Copyright (C) 1997 University of BC, Canada * Modified by: Michael Gallant <mikeg@ee.ubc.ca> * Guy Cote <guyc@ee.ubc.ca> * Berna Erol <bernae@ee.ubc.ca> * * Contacts: * Michael Gallant <mikeg@ee.ubc.ca> * * UBC Image Processing Laboratory http://www.ee.ubc.ca/image * 2356 Main Mall tel.: +1 604 822 4051 * Vancouver BC Canada V6T1Z4 fax.: +1 604 822 5949 * ************************************************************************//* Disclaimer of Warranty * * These software programs are available to the user without any license fee * or royalty on an "as is" basis. The University of British Columbia * disclaims any and all warranties, whether express, implied, or * statuary, including any implied warranties or merchantability or of * fitness for a particular purpose. In no event shall the * copyright-holder be liable for any incidental, punitive, or * consequential damages of any kind whatsoever arising from the use of * these programs. * * This disclaimer of warranty extends to the user of these programs and * user's customers, employees, agents, transferees, successors, and * assigns. * * The University of British Columbia does not represent or warrant that the * programs furnished hereunder are free of infringement of any * third-party patents. * * Commercial implementations of H.263, including shareware, are subject to * royalty fees to patent holders. Many of these patents are general * enough such that they are unavoidable regardless of implementation * design. * *//* based on mpeg2decode, (C) 1994, MPEG Software Simulation Group and * mpeg2play, (C) 1994 Stefan Eckart <stefan@lis.e-technik.tu-muenchen.de> * *//* the Xlib interface is closely modeled after mpeg_play 2.0 by the * Berkeley Plateau Research Group */#ifdef DISPLAY#include <stdio.h>#include <stdlib.h>#include <X11/Xlib.h>#include <X11/Xutil.h>#include "config.h"#include "tmndec.h"#include "global.h"/* private prototypes */static void display_image _ANSI_ARGS_ ((XImage * ximage, unsigned char *dithered_image));/* display related data */unsigned long wpixel[3];static unsigned char *dithered_image;/* X11 related variables */static Display *display;static Window window;static GC gc;static int dpy_depth;XImage *ximage;unsigned char pixel[256];#ifdef SH_MEM#include <sys/ipc.h>#include <sys/shm.h>#include <X11/extensions/XShm.h>extern int XShmQueryExtension _ANSI_ARGS_ ((Display * dpy));extern int XShmGetEventBase _ANSI_ARGS_ ((Display * dpy));static int HandleXError _ANSI_ARGS_ ((Display * dpy, XErrorEvent * event));static void InstallXErrorHandler _ANSI_ARGS_ ((void));static void DeInstallXErrorHandler _ANSI_ARGS_ ((void));static int shmem_flag;static XShmSegmentInfo shminfo1, shminfo2;static int gXErrorFlag;static int CompletionType = -1;static int HandleXError (dpy, event) Display *dpy; XErrorEvent *event;{ gXErrorFlag = 1; return 0;}static void InstallXErrorHandler (){ XSetErrorHandler (HandleXError); XFlush (display);}static void DeInstallXErrorHandler (){ XSetErrorHandler (NULL); XFlush (display);}#endif/* connect to server, create and map window, allocate colors and (shared) * memory */void init_display (name) char *name;{ int crv, cbu, cgu, cgv; int y, u, v, r, g, b; int i; char dummy; int screen; Visual *visual; int dpy_class; Colormap cmap; int private; XColor xcolor; unsigned int fg, bg; char *hello = "H.263 Display"; XSizeHints hint; XEvent xev; XSetWindowAttributes xswa; unsigned long tmp_pixel; unsigned int mask; display = XOpenDisplay (name); if (display == NULL) error ("Can not open display\n"); screen = DefaultScreen (display); visual = DefaultVisual (display, screen); dpy_depth = DefaultDepth (display, screen); dpy_class = visual->class; if (!((dpy_class == TrueColor && dpy_depth == 32) || (dpy_class == TrueColor && dpy_depth == 24) || (dpy_class == TrueColor && dpy_depth == 16) || (dpy_class == PseudoColor && dpy_depth == 8))) error ("requires 8 bit PseudoColor or 16/24/32 bit TrueColor display\n"); if (dpy_class == TrueColor && dpy_depth == 32) printf ("TrueColor : 32 bit colordepth\n"); if (dpy_class == TrueColor && dpy_depth == 24) printf ("TrueColor : 24 bit colordepth\n"); if (dpy_class == TrueColor && dpy_depth == 16) printf ("TrueColor : 16 bit colordepth\n"); if (dpy_class == PseudoColor && dpy_depth == 8) printf ("PseudoColor : 8 bit colordepth, 4x4 ordered dither\n"); /* width and height of the display window */ if (expand) { hint.min_width = hint.max_width = hint.width = 2 * horizontal_size; hint.min_height = hint.max_height = hint.height = 2 * vertical_size; } else { hint.min_width = hint.max_width = hint.width = horizontal_size; hint.min_height = hint.max_height = hint.height = vertical_size; } hint.flags = PSize | PMinSize | PMaxSize; /* Get some colors */ bg = WhitePixel (display, screen); fg = BlackPixel (display, screen); /* Make the window */ mask = CWBackPixel | CWBorderPixel; if (dpy_depth == 32 || dpy_depth == 24 || dpy_depth == 16) { mask |= CWColormap; xswa.colormap = XCreateColormap (display, DefaultRootWindow (display), visual, AllocNone); } xswa.background_pixel = bg; xswa.border_pixel = fg; window = XCreateWindow (display, DefaultRootWindow (display), hint.x, hint.y, hint.width, hint.height, 1, dpy_depth, InputOutput, visual, mask, &xswa); XSelectInput (display, window, StructureNotifyMask); /* Tell other applications about this window */ XSetStandardProperties (display, window, hello, hello, None, NULL, 0, &hint); /* Map window. */ XMapWindow (display, window); /* Wait for map. */ do { XNextEvent (display, &xev); } while (xev.type != MapNotify || xev.xmap.event != window); XSelectInput (display, window, NoEventMask); /* allocate colors */ gc = DefaultGC (display, screen); if (dpy_depth == 8) { XWindowAttributes xwa; cmap = DefaultColormap (display, screen); private = 0; /* matrix coefficients */ crv = convmat[matrix_coefficients][0]; cbu = convmat[matrix_coefficients][1]; cgu = convmat[matrix_coefficients][2]; cgv = convmat[matrix_coefficients][3]; /* color allocation: i is the (internal) 8 bit color number, it * consists of separate bit fields for Y, U and V: i = (yyyyuuvv), we * don't use yyyy=0000 yyyy=0001 and yyyy=1111, this leaves 48 colors * for other applications * * the allocated colors correspond to the following Y, U and V values: Y: * 40, 56, 72, 88, 104, 120, 136, 152, 168, 184, 200, 216, 232 U,V: * -48, -16, 16, 48 * * U and V values span only about half the color space; this gives * usually much better quality, although highly saturated colors can * not be displayed properly * * translation to R,G,B is implicitly done by the color look-up table */ for (i = 32; i < 240; i++) { /* color space conversion */ y = 16 * ((i >> 4) & 15) + 8; u = 32 * ((i >> 2) & 3) - 48; v = 32 * (i & 3) - 48; y = 76309 * (y - 16); /* (255/219)*65536 */ r = clp[(y + crv * v + 32768) >> 16]; g = clp[(y - cgu * u - cgv * v + 32768) >> 16]; b = clp[(y + cbu * u + 32786) >> 16]; /* X11 colors are 16 bit */ xcolor.red = r << 8; xcolor.green = g << 8; xcolor.blue = b << 8; if (XAllocColor (display, cmap, &xcolor) != 0) pixel[i] = xcolor.pixel; else { /* allocation failed, have to use a private colormap */ if (private) error ("Couldn't allocate private colormap"); private = 1; if (!quiet) fprintf (stderr, "Using private colormap (%d colors were " "available).\n", i - 32); /* Free colors. */ while (--i >= 32) { tmp_pixel = pixel[i]; /* because XFreeColors expects unsigned * long */ XFreeColors (display, cmap, &tmp_pixel, 1, 0); } /* i is now 31, this restarts the outer loop */ /* create private colormap */ XGetWindowAttributes (display, window, &xwa); cmap = XCreateColormap (display, window, xwa.visual, AllocNone); XSetWindowColormap (display, window, cmap); } } }#ifdef SH_MEM if (XShmQueryExtension (display)) shmem_flag = 1; else { shmem_flag = 0; if (!quiet) fprintf (stderr, "Shared memory not supported\nReverting to normal " "Xlib\n"); } if (shmem_flag) CompletionType = XShmGetEventBase (display) + ShmCompletion; InstallXErrorHandler (); if (shmem_flag) { if (expand) ximage = XShmCreateImage (display, visual, dpy_depth, ZPixmap, NULL, &shminfo1, 2 * coded_picture_width, 2 * coded_picture_height); else ximage = XShmCreateImage (display, visual, dpy_depth, ZPixmap, NULL, &shminfo1, coded_picture_width, coded_picture_height); /* If no go, then revert to normal Xlib calls. */ if (ximage == NULL) { if (ximage != NULL) XDestroyImage (ximage); if (!quiet) fprintf (stderr, "Shared memory error, disabling (Ximage error)\n"); goto shmemerror; } /* Success here, continue. */ shminfo1.shmid = shmget (IPC_PRIVATE, ximage->bytes_per_line * ximage->height, IPC_CREAT | 0777); if (shminfo1.shmid < 0) { XDestroyImage (ximage); if (!quiet) fprintf (stderr, "Shared memory error, disabling (seg id error)\n"); goto shmemerror; } shminfo1.shmaddr = (char *) shmat (shminfo1.shmid, 0, 0); shminfo2.shmaddr = (char *) shmat (shminfo2.shmid, 0, 0); if (shminfo1.shmaddr == ((char *) -1)) { XDestroyImage (ximage); if (shminfo1.shmaddr != ((char *) -1)) shmdt (shminfo1.shmaddr); if (!quiet) { fprintf (stderr, "Shared memory error, disabling (address error)\n"); } goto shmemerror; } ximage->data = shminfo1.shmaddr; dithered_image = (unsigned char *) ximage->data; shminfo1.readOnly = False; XShmAttach (display, &shminfo1); XSync (display, False); if (gXErrorFlag) { /* Ultimate failure here. */ XDestroyImage (ximage); shmdt (shminfo1.shmaddr); if (!quiet) fprintf (stderr, "Shared memory error, disabling.\n"); gXErrorFlag = 0; goto shmemerror; } else { shmctl (shminfo1.shmid, IPC_RMID, 0); } if (!quiet) { fprintf (stderr, "Sharing memory.\n"); } } else {shmemerror: shmem_flag = 0;#endif if (expand) { ximage = XCreateImage (display, visual, dpy_depth, ZPixmap, 0, &dummy, 2 * coded_picture_width, 2 * coded_picture_height, 8, 0); if (!(dithered_image = (unsigned char *) malloc (coded_picture_width * coded_picture_height * (dpy_depth > 8 ? sizeof (int) * 4 : sizeof (unsigned char)) * 4))) error ("malloc failed"); } else { ximage = XCreateImage (display, visual, dpy_depth, ZPixmap, 0, &dummy, coded_picture_width, coded_picture_height, 8, 0); if (!(dithered_image = (unsigned char *) malloc (coded_picture_width * coded_picture_height * (dpy_depth > 8 ? sizeof (int) : sizeof (unsigned char))))) error ("malloc failed"); }#ifdef SH_MEM } DeInstallXErrorHandler ();#endif if (dpy_depth == 32 || dpy_depth == 24 || dpy_depth == 16) { XWindowAttributes xwa; XGetWindowAttributes (display, window, &xwa); wpixel[0] = xwa.visual->red_mask; wpixel[1] = xwa.visual->green_mask; wpixel[2] = xwa.visual->blue_mask; /* If the colors in 16/24/32-bit mode are wrong, try this instead of * the above three lines */ /* wpixel[2] = xwa.visual->red_mask; wpixel[1] = * xwa.visual->green_mask; wpixel[0] = xwa.visual->blue_mask; */ InitColorDither (dpy_depth == 24 || dpy_depth == 32); } else { ord4x4_dither_init (); }}void exit_display (){#ifdef SH_MEM if (shmem_flag) { XShmDetach (display, &shminfo1); XDestroyImage (ximage); shmdt (shminfo1.shmaddr); }#endif}static void display_image (ximage, dithered_image) XImage *ximage; unsigned char *dithered_image;{ int t = 1; /* Always work in native bit and byte order. This tells Xlib to reverse * bit and byte order if necessary when crossing a network. Frankly, * this part of XImages is somewhat underdocumented, so this may not be * exactly correct. */ if (*(char *) &t == 1) { ximage->byte_order = LSBFirst; ximage->bitmap_bit_order = LSBFirst; } else { ximage->byte_order = MSBFirst; ximage->bitmap_bit_order = MSBFirst; } /* display dithered image */#ifdef SH_MEM if (shmem_flag) { XShmPutImage (display, window, gc, ximage, 0, 0, 0, 0, ximage->width, ximage->height, True); XFlush (display); while (1) { XEvent xev; XNextEvent (display, &xev); if (xev.type == CompletionType) break; } } else#endif { ximage->data = (char *) dithered_image; XPutImage (display, window, gc, ximage, 0, 0, 0, 0, ximage->width, ximage->height); }}void dither (src) unsigned char *src[];{ if (dpy_depth == 24 || dpy_depth == 32) { if (ximage->bits_per_pixel == 24) ConvertYUVtoRGB (src[0], src[1], src[2], dithered_image, coded_picture_width, coded_picture_height); else Color32DitherImage (src, dithered_image); } else if (dpy_depth == 16) { Color16DitherImage (src, dithered_image); } else { ord4x4_dither_frame (src, dithered_image); } display_image (ximage, dithered_image);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -