⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 display.c

📁 文件内包含H.263视频编码算法和解码算法2个文件
💻 C
字号:
/************************************************************************
 *
 *  display.c, X11 interface for tmndecode (H.263 decoder)
 
*/

 /* 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 + -