display.cc
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:38k
源码类别:

DVD

开发平台:

Unix_Linux

  1. /*
  2.    File: display.cc
  3.    By: Alex de Jong (original by MSSG)
  4.    Created: March 1996
  5.    
  6.    Description:
  7.    Multi-Threaded display class. Displays class is able to 
  8.    synchronize frames with a synchronoization object, which
  9.    in turn is updates by a decoder timer.
  10. */
  11. #ifdef __GNUG__
  12. #pragma implementation
  13. #endif
  14. #include "athread.hh"
  15. #include <stdio.h>
  16. #include <fstream.h>
  17. #include <sys/time.h>
  18. #include "error.hh"
  19. #include "debug.hh"
  20. #include "util.hh"
  21. #include "videoconst.hh"
  22. #include "sync.hh"
  23. #include "display.hh"
  24. #include "ditherer_lk16.hh"
  25. #include "ditherer_lkbw.hh"
  26. #include "ditherer_mmx16.hh"
  27. extern int quiet;
  28. //extern int coded_picture_width; use horizontal_size attribute
  29. //extern int coded_picture_height;  use horizontal_size attribute
  30. extern int prog_seq;
  31. extern int chroma_format;
  32. extern int chrom_width;
  33. extern int pict_struct, topfirst;
  34. extern int convmat[8][4];
  35. extern int matrix_coefficients;
  36. extern int playedlastframe;
  37. // #define USE_DGA 1               /* enable this to use DGA extention */
  38. #ifdef SH_MEM
  39. // Dummies to get rid of warnings
  40. extern "C" {
  41. int XShmQueryExtension(Display*);
  42. int XShmGetEventBase(Display*);
  43. }
  44. #ifdef USE_DGA
  45. #include <X11/extensions/xf86dga.h>
  46. #include <X11/extensions/xf86vmode.h>
  47. #endif
  48. #endif
  49. #ifdef SOLARIS_SDK_XIL
  50. Xil_boolean error_handler(XilError error){
  51.   xil_call_next_error_handler(error);
  52.   error("XIL received an error: exiting!");
  53.   exit(1);
  54.   return True;
  55. }
  56. #endif // SOLARIS_SDK_XIL
  57. DisplayX11::DisplayX11(const char* title, Synchronization* s){
  58.   TRACER("DisplayX11::DisplayX11(const char* title, Synchronization* s)");
  59.   int crv, cbu, cgu, cgv;
  60.   int y, u, v, r, g, b;
  61.   int i, j;
  62.   Colormap cmap;
  63.   XColor xcolor;
  64.   unsigned int fg, bg;
  65.   XSizeHints hint;
  66.   unsigned long tmp_pixel;
  67.   XWindowAttributes xwa;
  68.   int screen;
  69.   
  70.   // init to avoid invalid destroy in destructor
  71.   ximage=0;
  72.   ximage2=0;
  73.   // Synchronization with decoder clock
  74.   sync=s;
  75.   // Init display lock/condition to prevent threads to pass eachother
  76.   source=0;
  77. #ifdef SOLARIS_SDK_XIL
  78.   resized=0;  // window has not been resized
  79.   horizontal_size=100;
  80.   vertical_size=100;
  81.   horizontal_factor=1.0;
  82.   vertical_factor=1.0;
  83. #else
  84. #ifdef SH_MEM
  85.   CompletionType = -1;
  86. #endif
  87. #endif
  88.   // create clipping table
  89.   clp=new unsigned char[1024];  // clip table
  90.   clp += 384;
  91.   for (i=-384; i<640; i++) 
  92.     clp[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
  93.   if (!(display=XOpenDisplay(0))){
  94.     error("Can not open displayn");
  95.     athr_exit(0);
  96.   }
  97. #ifdef TRACE
  98.   XSynchronize(display, 1);
  99. #endif
  100.     
  101.   screen = DefaultScreen(display);
  102.   // find best display
  103.   if (XMatchVisualInfo(display, screen, 24, TrueColor, &vinfo)){
  104.   } else
  105.   if (XMatchVisualInfo(display, screen, 16, TrueColor, &vinfo)){
  106.   } else
  107.   if (XMatchVisualInfo(display, screen, 15, TrueColor, &vinfo)){
  108.   } else
  109.   if (XMatchVisualInfo(display, screen, 8, PseudoColor, &vinfo)){
  110.   }
  111.   else if (XMatchVisualInfo(display, screen, 8, GrayScale, &vinfo)){
  112.   }
  113.   else if (XMatchVisualInfo(display, screen, 8, StaticGray, &vinfo)){
  114.   }
  115.   else if (XMatchVisualInfo(display, screen, 1, StaticGray, &vinfo)) {
  116.   }
  117. #ifdef LINUX
  118.   else error("requires 16 bit displayn");
  119. #else
  120.   else error("requires 8 bit or 24 bit displayn");
  121. #endif
  122.   // Make the window
  123.   hint.x = 1;
  124.   hint.y = 1;
  125.   hint.width = 400 ;//horizontal_size;
  126.   hint.height= 300;//vertical_size;
  127.   hint.flags = PPosition | PSize;
  128.   bpp = vinfo.depth;
  129.   if (vinfo.red_mask == 0x7c00)
  130.     rgb_mode = 1; // RGB555    for more modes see yuv12-rgb.s
  131.   else
  132.     rgb_mode = 0; // RGB565
  133.   if (vinfo.c_class==TrueColor && bpp == 24 ){
  134. #ifdef SOLARIS_SDK_XIL
  135.     bands=3;
  136. #endif
  137.     cmap=XCreateColormap(display, DefaultRootWindow(display), vinfo.visual, AllocNone);
  138.     
  139.     XSetWindowAttributes xswa;
  140.     xswa.colormap = cmap;
  141.     xswa.event_mask = StructureNotifyMask;
  142.     xswa.border_pixel = BlackPixel(display, screen);
  143.     
  144.     window=XCreateWindow(display, DefaultRootWindow(display),
  145.                            hint.x, hint.y, hint.width, hint.height,
  146.                            0,
  147.                            vinfo.depth, InputOutput, vinfo.visual,
  148.                            CWBorderPixel | CWColormap | CWEventMask, &xswa);
  149.   }
  150.   else {
  151. #ifdef SOLARIS_SDK_XIL
  152.      bands=1;
  153. #endif
  154.     // Get some colors
  155.     bg = WhitePixel(display, screen);
  156.     fg = BlackPixel(display, screen);
  157.     window=XCreateSimpleWindow(display, DefaultRootWindow (display),
  158.                                hint.x, hint.y, hint.width, hint.height, 4, fg, bg);
  159.   }
  160.   // Tell other applications about this window
  161.   XSetStandardProperties(display, window, title, title, None, NULL, 0, &hint);
  162.   XSelectInput(display, window, StructureNotifyMask);
  163.   // Map window
  164.   XMapWindow(display, window);
  165.   // Wait for map.
  166.   do {
  167.     XNextEvent(display, &event);
  168.   }
  169.   while (event.type != MapNotify || event.xmap.event != window);
  170.   XSelectInput(display, window, NoEventMask);
  171.   if (vinfo.c_class==PseudoColor){     // Do dithering before display
  172.     int privte=0;
  173.     
  174.     // allocate colors
  175.     gc = DefaultGC(display, screen);
  176.     cmap = DefaultColormap(display, screen);
  177.     // matrix coefficients
  178.     crv = convmat[matrix_coefficients][0];
  179.     cbu = convmat[matrix_coefficients][1];
  180.     cgu = convmat[matrix_coefficients][2];
  181.     cgv = convmat[matrix_coefficients][3];
  182.     
  183.     /* color allocation:
  184.      * i is the (internal) 8 bit color number, it consists of separate
  185.      * bit fields for Y, U and V: i = (yyyyuuvv), we don't use yyyy=0000
  186.      * yyyy=0001 and yyyy=1111, this leaves 48 colors for other applications
  187.      *
  188.      * the allocated colors correspond to the following Y, U and V values:
  189.      * Y:   40, 56, 72, 88, 104, 120, 136, 152, 168, 184, 200, 216, 232
  190.      * U,V: -48, -16, 16, 48
  191.      *
  192.      * U and V values span only about half the color space; this gives
  193.      * usually much better quality, although highly saturated colors can
  194.      * not be displayed properly
  195.      *
  196.      * translation to R,G,B is implicitly done by the color look-up table
  197.      */
  198.     // THIS IS REALLY SLOW on a 24 Bit display. Please drop me a line if
  199.     // you know how to do this faster (alex.dejong@nist.gov)
  200.     // DON'T ALLOCATE 240 COLORS!! Just 215 will do and stops Solaris
  201.     // from colors blinking when moving the cursor
  202. #if (defined(SOLARIS))
  203.     int number_of_colors=215;
  204. #endif
  205. #if (defined(IRIX)|| defined(LINUX))
  206.     int number_of_colors=240;
  207. #endif
  208.     for (i=32; i<number_of_colors; i++){
  209.       /* color space conversion */
  210.       y = 16*((i>>4)&15) + 8;
  211.       u = 32*((i>>2)&3)  - 48;
  212.       v = 32*(i&3)       - 48;
  213.       
  214.       y = 76309 * (y - 16); /* (255/219)*65536 */
  215.       
  216.       r = clp[(y + crv*v + 32768)>>16];
  217.       g = clp[(y - cgu*u -cgv*v + 32768)>>16];
  218.       b = clp[(y + cbu*u + 32786)>>16];
  219.       
  220.       /* X11 colors are 16 bit */
  221.       xcolor.red   = r << 8;
  222.       xcolor.green = g << 8;
  223.       xcolor.blue  = b << 8;
  224.       
  225.       if (XAllocColor(display, cmap, &xcolor) != 0) pixel[i] = xcolor.pixel;
  226.       else {
  227.         /* allocation failed, have to use a private colormap */
  228.         
  229.         if (privte) error("Couldn't allocate private colormap");
  230.         
  231.         privte = 1;
  232.         
  233.         if (!quiet)
  234.           fprintf(stderr, "Using private colormap (%d colors were available)n",
  235.                   i-32);
  236.         
  237.         /* Free colors. */
  238.         while (--i >= 32){
  239.           tmp_pixel = pixel[i]; /* because XFreeColors expects unsigned long */
  240.           XFreeColors(display, cmap, &tmp_pixel, 1, 0);
  241.         }
  242.          /* i is now 31, this restarts the outer loop */
  243.         
  244.         /* create private colormap */
  245.         
  246.         XGetWindowAttributes(display, window, &xwa);
  247.         cmap = XCreateColormap(display, window, xwa.visual, AllocNone);
  248.         XSetWindowColormap(display, window, cmap);
  249.       }
  250.     }
  251.   }
  252.   else
  253.     gc = DefaultGC(display, screen);
  254. /*
  255.    Init dither
  256.    4x4 ordered dither
  257.    threshold pattern:
  258.     0  8  2 10
  259.    12  4 14  6
  260.     3 11  1  9
  261.    15  7 13  5
  262. */
  263.   unsigned char ctab[256+32];
  264.   
  265.   for (i=0; i<256+16; i++){
  266.     v = (i-8)>>4;
  267.     if (v<2) v=2;
  268.     else if (v>14) v=14;
  269.     for (j=0; j<16; j++) 
  270.       ytab[16*i+j] = pixel[(v<<4)+j];
  271.   }
  272.   for (i=0; i<256+32; i++){
  273.     v = (i+48-128)>>5;
  274.     if (v<0) v=0;
  275.     else if (v>3) v=3;
  276.     ctab[i]=v;
  277.   }
  278.   for (i=0; i<255+15; i++)
  279.     for (j=0; j<255+15; j++)
  280.       uvtab[256*i+j]=(ctab[i+16]<<6)|(ctab[j+16]<<4)|(ctab[i]<<2)|ctab[j];
  281. }
  282. DisplayX11::~DisplayX11(){ 
  283.   TRACER("DisplayX11::~DisplayX11()");
  284.   display_lock.lock();
  285.   if (!terminated) athr_join(thread_id);
  286.   exit_display();
  287.   delete clp; // delete clipping table
  288.   display_lock.unlock();
  289. }
  290. void* DisplayX11::dither_thread(DisplayX11* d){
  291.   d->display_lock.lock();
  292.   d->terminated=0;
  293.   d->dither_image(d->source);
  294.   d->display_image(d->ximage, d->dithered_image); 
  295.   d->source=0;
  296.   d->display_cond.signal();
  297.   d->terminated=1;
  298.   d->display_lock.unlock(); 
  299. #if !defined(IRIX) && !defined(SOLARIS_SDK_XIL) && !defined(LINUX)
  300.   athr_exit(0);
  301. #endif
  302.   return 0;
  303. }
  304. void* DisplayX11::display_thread(DisplayX11* d){
  305. #ifndef LINUX
  306.   d->display_lock.lock();
  307.   d->terminated=0;
  308.   d->display_image(d->ximage2, d->dithered_image2); 
  309.   d->terminated=1;
  310.   d->display_lock.unlock();
  311. #if !defined(IRIX) && !defined(SOLARIS_SDK_XIL) && !defined(LINUX)
  312.   athr_exit(0);
  313. #endif
  314. #endif
  315.   return 0;
  316. }
  317. int DisplayX11::init(int h_size, int v_size,int sx_div_h=1,int sx_div_l=1,
  318.                      int sy_div_h=1,int sy_div_l=1,
  319.                      int clip_y_l=0, int clip_y_h=0) {
  320.   
  321.   screenx_div_h=sx_div_h;
  322.   screenx_div_l=sx_div_l;
  323.   screeny_div_h=sy_div_h;
  324.   screeny_div_l=sy_div_l;
  325.   TRACER("void DisplayX11::init(int h_size, int v_size)");
  326.   display_lock.lock();  // lock the display from others access for now
  327.   // resize window
  328.   if (clip_y_l != 0 && clip_y_h != 0) {
  329.      clipping_y_l=clip_y_l;
  330.      clipping_y_h=clip_y_h;
  331.   } else {
  332.      clipping_y_l=0;
  333.      clipping_y_h=v_size;
  334.   }
  335.   
  336.   horizontal_size=h_size*screenx_div_h/screenx_div_l;
  337.   vertical_size=/*v_size*/(clipping_y_h-clipping_y_l)*screeny_div_h/screeny_div_l;
  338.   original_horizontal_size=h_size;
  339.   original_vertical_size=(clipping_y_h-clipping_y_l);
  340.   XResizeWindow(display, window, horizontal_size, vertical_size);
  341. #ifdef SOLARIS_SDK_XIL
  342.   if ((State = xil_open()) == NULL)
  343.     exit(1);   // XIL sends an error message to stderr if xil_open fails 
  344.   // Install error handler
  345.   if (xil_install_error_handler(State, error_handler) == XIL_FAILURE)
  346.     error("unable to install error handler for XIL");
  347.   if (!(displayimage=xil_create_from_window(State, display, window)))
  348.     exit(1); // XIL sends error message to stderr if xil_create_from_window fails
  349.   ximage=xil_create(State, horizontal_size, vertical_size, bands, XIL_BYTE);
  350.   ximage2=xil_create(State, horizontal_size, vertical_size, bands, XIL_BYTE);
  351.   resized_image=xil_create(State, horizontal_size, vertical_size, bands, XIL_BYTE);
  352. /*
  353.   // Only when using XIL colorspace conversion; this seems rather slow
  354.   if (bands==3){
  355.     XilColorspace cspace=xil_colorspace_get_by_name(State, "ycc601");
  356.     xil_set_colorspace(ximage, cspace);
  357.     cspace=xil_colorspace_get_by_name(State, "ycc601");
  358.     xil_set_colorspace(resized_image, cspace);
  359.     cspace=xil_colorspace_get_by_name(State, "rgb709");
  360.     xil_set_colorspace(displayimage, cspace);
  361.   }
  362. */
  363.   XSelectInput(display, window, StructureNotifyMask);
  364. #else
  365. #ifdef SH_MEM
  366.   char dummy;
  367.   shmem_flag = 0;
  368. #ifdef USE_DGA             /* enable this if you want to have DGA support */
  369.   int EventBase, ErrorBase, flags,vp_width,vp_height,bank,ram;
  370.   if (XF86DGAQueryExtension (display, &EventBase, &ErrorBase)) {
  371.       XF86DGAQueryDirectVideo (display, XDefaultScreen (display), &flags);
  372.       if ((flags & XF86DGADirectPresent) == 0) {
  373.           if (!quiet) message ("dga: no direct present");
  374.       }
  375.       else {
  376.           shmem_flag = 2;
  377.           if (!quiet) message ("using DGA ");
  378.       }
  379.       XF86DGAGetVideo (display, XDefaultScreen (display), (char **) &dithered_image,
  380.                         &xwidth, &bank, &ram);
  381.       dithered_image2 = dithered_image;
  382.       XF86DGAGetViewPortSize (display, XDefaultScreen (display),
  383.                         &vp_width, &vp_height);
  384.       if (vp_height < v_size || vp_width < h_size) {
  385.         if (!quiet) message("View Port too small for DGA");
  386.         shmem_flag = 0;
  387.       }
  388.       else {
  389.         XF86DGASetViewPort (display, XDefaultScreen (display), 0, 0);
  390.         XF86DGADirectVideo (display, XDefaultScreen (display),XF86DGADirectGraphics );
  391.       }
  392.   }
  393. #endif
  394.   if (!shmem_flag) 
  395.     if (XShmQueryExtension(display)) shmem_flag = 1;
  396.     else {
  397.       shmem_flag = 0;
  398.       if (!quiet){
  399.         message("Shared memory not supported");
  400.         message("Reverting to normal Xlib");
  401.       }
  402.     }
  403.   if (shmem_flag==1) CompletionType = XShmGetEventBase(display) + ShmCompletion;
  404.   InstallXErrorHandler();
  405.   if (shmem_flag==1){
  406.     ximage = XShmCreateImage(display, None, bpp, ZPixmap, NULL,
  407.                              &shminfo1,
  408.                              horizontal_size, vertical_size);
  409.     if (!prog_seq)
  410.       ximage2 = XShmCreateImage(display, None, bpp, ZPixmap, NULL,
  411.                                 &shminfo2,
  412.                                 horizontal_size, vertical_size);
  413.     /* If no go, then revert to normal Xlib calls. */
  414.     if (ximage==NULL || (!prog_seq && ximage2==NULL)){
  415.       if (ximage!=NULL) XDestroyImage(ximage);
  416.       if (!prog_seq && ximage2!=NULL) XDestroyImage(ximage2);
  417.       if (!quiet)
  418.         fprintf(stderr, "Shared memory error, disabling (Ximage error)n");
  419.       goto shmemerror;
  420.     }
  421.     /* Success here, continue. */
  422.     shminfo1.shmid = shmget(IPC_PRIVATE, 
  423.                             ximage->bytes_per_line * ximage->height,
  424.                             IPC_CREAT | 0777);
  425.     if (!prog_seq)
  426.       shminfo2.shmid = shmget(IPC_PRIVATE, 
  427.                               ximage2->bytes_per_line * ximage2->height,
  428.                               IPC_CREAT | 0777);
  429.     if (shminfo1.shmid<0 || (!prog_seq && shminfo2.shmid<0)){
  430.       XDestroyImage(ximage);
  431.       if (!prog_seq) XDestroyImage(ximage2);
  432.       if (!quiet)
  433.         fprintf(stderr, "Shared memory error, disabling (seg id error)n");
  434.       goto shmemerror;
  435.     }
  436.     shminfo1.shmaddr = (char *) shmat(shminfo1.shmid, 0, 0);
  437.     shminfo2.shmaddr = (char *) shmat(shminfo2.shmid, 0, 0);
  438.     if (shminfo1.shmaddr==((char *) -1) ||
  439.         (!prog_seq && shminfo2.shmaddr==((char *) -1))){
  440.       XDestroyImage(ximage);
  441.       if (shminfo1.shmaddr!=((char *) -1)) shmdt(shminfo1.shmaddr);
  442.       if (!prog_seq){
  443.         XDestroyImage(ximage2);
  444.         if (shminfo2.shmaddr!=((char *) -1))
  445.           shmdt(shminfo2.shmaddr);
  446.       }
  447.       if (!quiet)
  448.       {
  449.         fprintf(stderr, "Shared memory error, disabling (address error)n");
  450.       }
  451.       goto shmemerror;
  452.     }
  453.     ximage->data = shminfo1.shmaddr;
  454.     dithered_image = (unsigned char *)ximage->data;
  455.     shminfo1.readOnly = False;
  456.     XShmAttach(display, &shminfo1);
  457.     if (!prog_seq){
  458.       ximage2->data = shminfo2.shmaddr;
  459.       dithered_image2 = (unsigned char *)ximage2->data;
  460.       shminfo2.readOnly = False;
  461.       XShmAttach(display, &shminfo2);
  462.     }
  463.     XSync(display, False);
  464.     if (gXErrorFlag){
  465.       /* Ultimate failure here. */
  466.       XDestroyImage(ximage);
  467.       shmdt(shminfo1.shmaddr);
  468.       if (!prog_seq){
  469.         XDestroyImage(ximage2);
  470.         shmdt(shminfo2.shmaddr);
  471.       }
  472.       if (!quiet)
  473.         fprintf(stderr, "Shared memory error, disabling.n");
  474.       gXErrorFlag = 0;
  475.       goto shmemerror;
  476.     }
  477.     else {
  478.       shmctl(shminfo1.shmid, IPC_RMID, 0);
  479.       if (!prog_seq)
  480.         shmctl(shminfo2.shmid, IPC_RMID, 0);
  481.     }
  482.     if (!quiet){
  483.       fprintf(stderr, "Sharing memory.n");
  484.     }
  485.   }
  486.   else if (shmem_flag != 2) {
  487. shmemerror:
  488.     shmem_flag = 0;
  489. #endif
  490.     ximage = XCreateImage(display,None,bpp,ZPixmap,0,&dummy,
  491.                           horizontal_size,vertical_size,8,0);
  492.     if (!(dithered_image = new unsigned char[horizontal_size*
  493.                                                    vertical_size]))
  494.       error("new failed");
  495.     if (!prog_seq){
  496.       ximage2 = XCreateImage(display,None,bpp,ZPixmap,0,&dummy,
  497.                              horizontal_size,vertical_size,8,0);
  498.       if (!(dithered_image2 = new unsigned char[horizontal_size*
  499.                                                       vertical_size]))
  500.         error("new failed");
  501.     }
  502. #ifdef SH_MEM
  503.   }
  504.   DeInstallXErrorHandler();
  505. #endif
  506. #endif // SOLARIS_SDK_XIL
  507.   display_lock.unlock();
  508.   return 1;
  509. }
  510. void DisplayX11::exit_display(){
  511. #ifdef SOLARIS_SDK_XIL
  512.   xil_destroy(displayimage);
  513.   xil_destroy(resized_image);
  514.   if (ximage) xil_destroy(ximage);
  515.   if (ximage2) xil_destroy(ximage2);
  516.   xil_close(State);
  517.   XCloseDisplay(display);
  518. #else
  519. #ifdef SH_MEM
  520. #ifdef USE_DGA
  521.   if (shmem_flag==2)
  522.     XF86DGADirectVideo (display, XDefaultScreen (display), 0);
  523. #endif
  524.   if (shmem_flag==1){
  525.     XShmDetach(display, &shminfo1);
  526.     shmdt(shminfo1.shmaddr);
  527.     if (!prog_seq){
  528.       XShmDetach(display, &shminfo2);
  529.       XDestroyImage(ximage2);
  530.       shmdt(shminfo2.shmaddr);
  531.     }
  532.   }
  533. #else
  534.   XDestroyImage(ximage);
  535. #endif
  536. #endif
  537. }
  538. #ifdef SOLARIS_SDK_XIL
  539. void DisplayX11::display_image(XilImage ximg, unsigned char *dithered_img){
  540. #else
  541. void DisplayX11::display_image(XImage *ximg, unsigned char *dithered_img){
  542. #endif
  543.   DEBUGGER("void DisplayX11::display_image(ximage, unsigned char *dithered_image)");
  544.   playedlastframe=1;  // indicate that frame is displayed
  545.   if (sync)  {
  546.     sync->wait(1);    // wait for presentation time stamp (PTS), id=1
  547.   }
  548. #ifdef SH_MEM                            // display dithered image
  549.   if (shmem_flag==2)
  550.     return;
  551. #endif
  552. #ifdef SOLARIS_SDK_XIL
  553.   xil_import(ximg, TRUE);
  554.   if (resized){
  555.     // , general and linear are Ok (These is no good for this: bilinear, bicubic)
  556.     xil_scale(ximage, resized_image, "general", horizontal_factor, vertical_factor);
  557.     // if (bands==1)   // Use XIL for color conversion
  558.     xil_copy(resized_image, displayimage);
  559.     // else 
  560.     //   xil_color_convert(resized_image, displayimage);
  561.   }
  562.   else {
  563.     // if (bands==1)   // Use XIL for color conversion
  564.     xil_copy(ximg, displayimage);
  565.     // else 
  566.     //   xil_color_convert(ximg, displayimage);
  567.   }
  568.   // check for geometry changes
  569.   if (XCheckWindowEvent(display, window, StructureNotifyMask, &event))  resize();
  570. #else
  571. #ifdef SH_MEM                            // display dithered image
  572.   if (shmem_flag==1){
  573.     XShmPutImage(display, window, gc, ximg, 0,0,0,0,ximg->width,ximg->height,True);
  574.     XFlush(display);
  575.   }
  576.   else 
  577. #endif // SH_MEM
  578.   {
  579.     ximg->data=(char*) dithered_img;
  580.     XPutImage(display, window, gc, ximg, 0, 0, 0, 0, ximg->width, ximg->height);
  581.   }
  582. #endif // SOLARIS_SDK_XIL
  583. }
  584. #ifdef SOLARIS_SDK_XIL
  585. int DisplayX11::dither_image_rgb24(unsigned char* src[], unsigned char* dithered_img){
  586.   register int h=0, w=-1;
  587.   register unsigned char *Y, *Cb, *Cr;  
  588.   Y=src[0];
  589.   Cb=src[1];
  590.   Cr=src[2];
  591.   register Xil_unsigned8* data;
  592.   data=dithered_img;
  593.   
  594.   //  map data in XIL image  
  595.   for (h=0; h<vertical_size; h++){
  596.     for (w=0; w<horizontal_size; w++){
  597.       *data++ = clp[(int)(*Y + 1.371*(*Cr-128))];  
  598.       *data++ = clp[(int)(*Y - 0.698*(*Cr-128) - 0.336*(*Cr-128))]; 
  599.       *data++ = clp[(int)(*Y++ + 1.732*(*Cb-128))];
  600.       if ((w % 4)==0){
  601.         Cr++;
  602.         Cb++;
  603.       }
  604.     }
  605.   }
  606.   return 0;
  607. };
  608. #endif
  609. #if defined(LINUX)
  610. //extern "C" void yuv_2_rgb(void *,void *,void *,int,int,int,int,int,void *,int,int,int,int);
  611. /* Need to have access to the memory after
  612. */
  613. int DisplayX11::dither_image_rgb16(unsigned char* src[], unsigned char* dithered_img){
  614.   int height,width,display_width;
  615. #ifdef HAVE_MMX
  616.   static Ditherer * dither_module=Ditherer::allocModule("mmx16b");
  617. #else
  618.   static Ditherer * dither_module=Ditherer::allocModule("lk16");
  619. #endif
  620.   
  621.   height=vertical_size;
  622.   width=horizontal_size;
  623.   
  624.   if (shmem_flag == 2)
  625.     display_width = xwidth;
  626.   else
  627.     display_width=horizontal_size;
  628.   
  629.   dither_module->setBpp(bpp);
  630.   dither_module->dither(src[0],src[1],src[2],dithered_img,
  631.                         original_horizontal_size, original_vertical_size,
  632.                         horizontal_size,vertical_size,
  633.                         display_width);
  634.   
  635.   return 0;
  636. }
  637.  
  638. #if 0
  639. int DisplayX11::dither_image_rgb24(unsigned char* src[], unsigned char* dithered_img){
  640.   int height,width,display_width;
  641.   height=vertical_size;
  642.   if (shmem_flag == 2)
  643.     display_width = xwidth;
  644.   else
  645.     display_width=horizontal_size;
  646.   width=horizontal_size;
  647.   if (rgb_mode == 0)
  648.     Color16DitherImageMod(src[0], src[2], src[1], dithered_img, height, width,display_width -width);
  649.   else
  650.     yuv_2_rgb(src[0],src[1],src[2],width,height,width,width/2,0,dithered_img,0,0,display_width*2,rgb_mode);
  651.   return 0;
  652. }
  653. #endif
  654. #endif
  655. void DisplayX11::dither_image(unsigned char *src[]){
  656. #ifdef SOLARIS_SDK_XIL
  657.   dithered_image=getImage1Data();
  658. #endif
  659.   if (prog_seq){
  660.     if (chroma_format!=CHROMA444){
  661. #if defined(LINUX)
  662.       if (vinfo.c_class==TrueColor && vinfo.depth==24){
  663.          //dither_image_rgb24(src, dithered_image);
  664.          cerr<<" 24 bpp display not supported (only 16bpp)"<<endl;
  665.          exit(1);
  666.          return;
  667.       }
  668.       dither_image_rgb16(src, dithered_image);
  669.       return;
  670. #endif
  671.       ditherframe(src);
  672.     }
  673.     else
  674.       ditherframe444(src);
  675.   }
  676.   else {
  677. #ifdef SOLARIS_SDK_XIL
  678.     dithered_image2=getImage2Data();
  679. #endif
  680. #if defined(LINUX) 
  681.     dither_image_rgb16(src, dithered_image);
  682.         return;
  683. #endif
  684.     if ((pict_struct==FRAME_PICTURE && topfirst) || pict_struct==BOTTOM_FIELD){
  685.       /* top field first */
  686.       if (chroma_format!=CHROMA444){
  687.         dithertop(src,dithered_image);
  688.         ditherbot(src,dithered_image2);
  689.       }
  690.       else {
  691.         dithertop444(src,dithered_image);
  692.         ditherbot444(src,dithered_image2);
  693.       }
  694.     }
  695.     else {
  696.       /* bottom field first */
  697.       if (chroma_format!=CHROMA444){
  698.         ditherbot(src,dithered_image);
  699.         dithertop(src,dithered_image2);
  700.       }
  701.       else {
  702.         ditherbot444(src,dithered_image);
  703.         dithertop444(src,dithered_image2);
  704.       }
  705.     }
  706.   }
  707. }
  708. /* only for 4:2:0 and 4:2:2! */
  709. void DisplayX11::ditherframe(unsigned char *src[]){
  710.   int i;
  711.   register unsigned int uv;
  712.   register unsigned char *py,*pu,*pv,*dst;
  713.   py = src[0];
  714.   pu = src[1];
  715.   pv = src[2];
  716.   dst = dithered_image;
  717.   for (int j=0; j<vertical_size; j+=4){
  718.     /* line j + 0 */
  719.     for (i=0; i<horizontal_size; i+=8){
  720.       uv = uvtab[(*pu++<<8)|*pv++];
  721.       *dst++ = ytab[((*py++)<<4)|(uv&15)];
  722.       *dst++ = ytab[((*py++ +8)<<4)|(uv>>4)];
  723.       uv = uvtab[((*pu++<<8)|*pv++)+1028];
  724.       *dst++ = ytab[((*py++ +2)<<4)|(uv&15)];
  725.       *dst++ = ytab[((*py++ +10)<<4)|(uv>>4)];
  726.       uv = uvtab[(*pu++<<8)|*pv++];
  727.       *dst++ = ytab[((*py++)<<4)|(uv&15)];
  728.       *dst++ = ytab[((*py++ +8)<<4)|(uv>>4)];
  729.       uv = uvtab[((*pu++<<8)|*pv++)+1028];
  730.       *dst++ = ytab[((*py++ +2)<<4)|(uv&15)];
  731.       *dst++ = ytab[((*py++ +10)<<4)|(uv>>4)];
  732.     }
  733.     if (chroma_format==CHROMA420){
  734.       pu -= chrom_width;
  735.       pv -= chrom_width;
  736.     }
  737.     /* line j + 1 */
  738.     for (i=0; i<horizontal_size; i+=8){
  739.       uv = uvtab[((*pu++<<8)|*pv++)+2056];
  740.       *dst++ = ytab[((*py++ +12)<<4)|(uv>>4)];
  741.       *dst++ = ytab[((*py++ +4)<<4)|(uv&15)];
  742.       uv = uvtab[((*pu++<<8)|*pv++)+3084];
  743.       *dst++ = ytab[((*py++ +14)<<4)|(uv>>4)];
  744.       *dst++ = ytab[((*py++ +6)<<4)|(uv&15)];
  745.       uv = uvtab[((*pu++<<8)|*pv++)+2056];
  746.       *dst++ = ytab[((*py++ +12)<<4)|(uv>>4)];
  747.       *dst++ = ytab[((*py++ +4)<<4)|(uv&15)];
  748.       uv = uvtab[((*pu++<<8)|*pv++)+3084];
  749.       *dst++ = ytab[((*py++ +14)<<4)|(uv>>4)];
  750.       *dst++ = ytab[((*py++ +6)<<4)|(uv&15)];
  751.     }
  752.     /* line j + 2 */
  753.     for (i=0; i<horizontal_size; i+=8){
  754.       uv = uvtab[((*pu++<<8)|*pv++)+1542];
  755.       *dst++ = ytab[((*py++ +3)<<4)|(uv&15)];
  756.       *dst++ = ytab[((*py++ +11)<<4)|(uv>>4)];
  757.       uv = uvtab[((*pu++<<8)|*pv++)+514];
  758.       *dst++ = ytab[((*py++ +1)<<4)|(uv&15)];
  759.       *dst++ = ytab[((*py++ +9)<<4)|(uv>>4)];
  760.       uv = uvtab[((*pu++<<8)|*pv++)+1542];
  761.       *dst++ = ytab[((*py++ +3)<<4)|(uv&15)];
  762.       *dst++ = ytab[((*py++ +11)<<4)|(uv>>4)];
  763.       uv = uvtab[((*pu++<<8)|*pv++)+514];
  764.       *dst++ = ytab[((*py++ +1)<<4)|(uv&15)];
  765.       *dst++ = ytab[((*py++ +9)<<4)|(uv>>4)];
  766.     }
  767.     if (chroma_format==CHROMA420){
  768.       pu -= chrom_width;
  769.       pv -= chrom_width;
  770.     }
  771.     /* line j + 3 */
  772.     for (i=0; i<horizontal_size; i+=8){
  773.       uv = uvtab[((*pu++<<8)|*pv++)+3598];
  774.       *dst++ = ytab[((*py++ +15)<<4)|(uv>>4)];
  775.       *dst++ = ytab[((*py++ +7)<<4)|(uv&15)];
  776.       uv = uvtab[((*pu++<<8)|*pv++)+2570];
  777.       *dst++ = ytab[((*py++ +13)<<4)|(uv>>4)];
  778.       *dst++ = ytab[((*py++ +5)<<4)|(uv&15)];
  779.       uv = uvtab[((*pu++<<8)|*pv++)+3598];
  780.       *dst++ = ytab[((*py++ +15)<<4)|(uv>>4)];
  781.       *dst++ = ytab[((*py++ +7)<<4)|(uv&15)];
  782.       uv = uvtab[((*pu++<<8)|*pv++)+2570];
  783.       *dst++ = ytab[((*py++ +13)<<4)|(uv>>4)];
  784.       *dst++ = ytab[((*py++ +5)<<4)|(uv&15)];
  785.     }
  786.   }
  787. }
  788. void DisplayX11::dithertop(unsigned char *src[], unsigned char *dst){
  789.   int i;
  790.   unsigned int y,uv1,uv2;
  791.   unsigned char *py,*py2,*pu,*pv,*dst2;
  792.   py = src[0];
  793.   py2 = src[0] + (horizontal_size<<1);
  794.   pu = src[1];
  795.   pv = src[2];
  796.   dst2 = dst + horizontal_size;
  797.   for (int j=0; j<vertical_size; j+=4){
  798.     /* line j + 0, j + 1 */
  799.     for (i=0; i<horizontal_size; i+=4){
  800.       y = *py++;
  801.       uv2 = (*pu++<<8)|*pv++;
  802.       uv1 = uvtab[uv2];
  803.       uv2 = uvtab[uv2+2056];
  804.       *dst++  = ytab[((y)<<4)|(uv1&15)];
  805.       *dst2++ = ytab[((((y + *py2++)>>1)+12)<<4)|(uv2>>4)];
  806.       y = *py++;
  807.       *dst++  = ytab[((y+8)<<4)|(uv1>>4)];
  808.       *dst2++ = ytab[((((y + *py2++)>>1)+4)<<4)|(uv2&15)];
  809.       y = *py++;
  810.       uv2 = (*pu++<<8)|*pv++;
  811.       uv1 = uvtab[uv2+1028];
  812.       uv2 = uvtab[uv2+3072];
  813.       *dst++  = ytab[((y+2)<<4)|(uv1&15)];
  814.       *dst2++ = ytab[((((y + *py2++)>>1)+14)<<4)|(uv2>>4)];
  815.       y = *py++;
  816.       *dst++  = ytab[((y+10)<<4)|(uv1>>4)];
  817.       *dst2++ = ytab[((((y + *py2++)>>1)+6)<<4)|(uv2&15)];
  818.     }
  819.     py += horizontal_size;
  820.     if (j!=(vertical_size-4)) py2 += horizontal_size;
  821.     else                             py2 -= horizontal_size;
  822.     dst += horizontal_size;
  823.     dst2 += horizontal_size;
  824.     if (chroma_format==CHROMA420){
  825.       pu -= chrom_width;
  826.       pv -= chrom_width;
  827.     }
  828.     else {
  829.       pu += chrom_width;
  830.       pv += chrom_width;
  831.     }
  832.     /* line j + 2, j + 3 */
  833.     for (i=0; i<horizontal_size; i+=4){
  834.       y = *py++;
  835.       uv2 = (*pu++<<8)|*pv++;
  836.       uv1 = uvtab[uv2+1542];
  837.       uv2 = uvtab[uv2+3598];
  838.       *dst++  = ytab[((y+3)<<4)|(uv1&15)];
  839.       *dst2++ = ytab[((((y + *py2++)>>1)+15)<<4)|(uv2>>4)];
  840.       y = *py++;
  841.       *dst++  = ytab[((y+11)<<4)|(uv1>>4)];
  842.       *dst2++ = ytab[((((y + *py2++)>>1)+7)<<4)|(uv2&15)];
  843.       y = *py++;
  844.       uv2 = (*pu++<<8)|*pv++;
  845.       uv1 = uvtab[uv2+514];
  846.       uv2 = uvtab[uv2+2570];
  847.       *dst++  = ytab[((y+1)<<4)|(uv1&15)];
  848.       *dst2++ = ytab[((((y + *py2++)>>1)+13)<<4)|(uv2>>4)];
  849.       y = *py++;
  850.       *dst++  = ytab[((y+9)<<4)|(uv1>>4)];
  851.       *dst2++ = ytab[((((y + *py2++)>>1)+5)<<4)|(uv2&15)];
  852.     }
  853.     py += horizontal_size;
  854.     py2 += horizontal_size;
  855.     dst += horizontal_size;
  856.     dst2 += horizontal_size;
  857.     pu += chrom_width;
  858.     pv += chrom_width;
  859.   }
  860. }
  861. void DisplayX11::ditherbot(unsigned char *src[], unsigned char *dst){
  862.   int i;
  863.   unsigned int y2,uv1,uv2;
  864.   unsigned char *py,*py2,*pu,*pv,*dst2;
  865.   py = src[0] + horizontal_size;
  866.   py2 = py;
  867.   pu = src[1] + chrom_width;
  868.   pv = src[2] + chrom_width;
  869.   dst2 = dst + horizontal_size;
  870.   for (int j=0; j<vertical_size; j+=4){
  871.     /* line j + 0, j + 1 */
  872.     for (i=0; i<horizontal_size; i+=4){
  873.       y2 = *py2++;
  874.       uv2 = (*pu++<<8)|*pv++;
  875.       uv1 = uvtab[uv2];
  876.       uv2 = uvtab[uv2+2056];
  877.       *dst++  = ytab[((((*py++ + y2)>>1))<<4)|(uv1&15)];
  878.       *dst2++ = ytab[((y2+12)<<4)|(uv2>>4)];
  879.       y2 = *py2++;
  880.       *dst++  = ytab[((((*py++ + y2)>>1)+8)<<4)|(uv1>>4)];
  881.       *dst2++ = ytab[((y2+4)<<4)|(uv2&15)];
  882.       y2 = *py2++;
  883.       uv2 = (*pu++<<8)|*pv++;
  884.       uv1 = uvtab[uv2+1028];
  885.       uv2 = uvtab[uv2+3072];
  886.       *dst++  = ytab[((((*py++ + y2)>>1)+2)<<4)|(uv1&15)];
  887.       *dst2++ = ytab[((y2+14)<<4)|(uv2>>4)];
  888.       y2 = *py2++;
  889.       *dst++  = ytab[((((*py++ + y2)>>1)+10)<<4)|(uv1>>4)];
  890.       *dst2++ = ytab[((y2+6)<<4)|(uv2&15)];
  891.     }
  892.     if (j==0) py -= horizontal_size;
  893.     else      py += horizontal_size;
  894.     py2 += horizontal_size;
  895.     dst += horizontal_size;
  896.     dst2 += horizontal_size;
  897.     if (chroma_format==CHROMA420){
  898.       pu -= chrom_width;
  899.       pv -= chrom_width;
  900.     }
  901.     else {
  902.       pu += chrom_width;
  903.       pv += chrom_width;
  904.     }
  905.     /* line j + 2, j + 3 */
  906.     for (i=0; i<horizontal_size; i+=4){
  907.       y2 = *py2++;
  908.       uv2 = (*pu++<<8)|*pv++;
  909.       uv1 = uvtab[uv2+1542];
  910.       uv2 = uvtab[uv2+3598];
  911.       *dst++  = ytab[((((*py++ + y2)>>1)+3)<<4)|(uv1&15)];
  912.       *dst2++ = ytab[((y2+15)<<4)|(uv2>>4)];
  913.       y2 = *py2++;
  914.       *dst++  = ytab[((((*py++ + y2)>>1)+11)<<4)|(uv1>>4)];
  915.       *dst2++ = ytab[((y2+7)<<4)|(uv2&15)];
  916.       y2 = *py2++;
  917.       uv2 = (*pu++<<8)|*pv++;
  918.       uv1 = uvtab[uv2+514];
  919.       uv2 = uvtab[uv2+2570];
  920.       *dst++  = ytab[((((*py++ + y2)>>1)+1)<<4)|(uv1&15)];
  921.       *dst2++ = ytab[((y2+13)<<4)|(uv2>>4)];
  922.       y2 = *py2++;
  923.       *dst++  = ytab[((((*py++ + y2)>>1)+9)<<4)|(uv1>>4)];
  924.       *dst2++ = ytab[((y2+5)<<4)|(uv2&15)];
  925.     }
  926.     py += horizontal_size;
  927.     py2 += horizontal_size;
  928.     dst += horizontal_size;
  929.     dst2 += horizontal_size;
  930.     pu += chrom_width;
  931.     pv += chrom_width;
  932.   }
  933. }
  934. /* only for 4:4:4 */
  935. void DisplayX11::ditherframe444(unsigned char *src[]){
  936.   int i;
  937.   unsigned char *py=src[0], *pu=src[1], *pv=src[2], *dst=dithered_image;
  938.   for (int j=0; j<vertical_size; j+=4){
  939.     /* line j + 0 */
  940.     for (i=0; i<horizontal_size; i+=8){
  941.       *dst++ = ytab[((*py++)<<4)|(uvtab[(*pu++<<8)|*pv++]&15)];
  942.       *dst++ = ytab[((*py++ +8)<<4)|(uvtab[(*pu++<<8)|*pv++]>>4)];
  943.       *dst++ = ytab[((*py++ +2)<<4)|(uvtab[((*pu++<<8)|*pv++)+1028]&15)];
  944.       *dst++ = ytab[((*py++ +10)<<4)|(uvtab[((*pu++<<8)|*pv++)+1028]>>4)];
  945.       *dst++ = ytab[((*py++)<<4)|(uvtab[(*pu++<<8)|*pv++]&15)];
  946.       *dst++ = ytab[((*py++ +8)<<4)|(uvtab[(*pu++<<8)|*pv++]>>4)];
  947.       *dst++ = ytab[((*py++ +2)<<4)|(uvtab[((*pu++<<8)|*pv++)+1028]&15)];
  948.       *dst++ = ytab[((*py++ +10)<<4)|(uvtab[((*pu++<<8)|*pv++)+1028]>>4)];
  949.     }
  950.     /* line j + 1 */
  951.     for (i=0; i<horizontal_size; i+=8){
  952.       *dst++ = ytab[((*py++ +12)<<4)|(uvtab[((*pu++<<8)|*pv++)+2056]>>4)];
  953.       *dst++ = ytab[((*py++ +4)<<4)|(uvtab[((*pu++<<8)|*pv++)+2056]&15)];
  954.       *dst++ = ytab[((*py++ +14)<<4)|(uvtab[((*pu++<<8)|*pv++)+3084]>>4)];
  955.       *dst++ = ytab[((*py++ +6)<<4)|(uvtab[((*pu++<<8)|*pv++)+3084]&15)];
  956.       *dst++ = ytab[((*py++ +12)<<4)|(uvtab[((*pu++<<8)|*pv++)+2056]>>4)];
  957.       *dst++ = ytab[((*py++ +4)<<4)|(uvtab[((*pu++<<8)|*pv++)+2056]&15)];
  958.       *dst++ = ytab[((*py++ +14)<<4)|(uvtab[((*pu++<<8)|*pv++)+3084]>>4)];
  959.       *dst++ = ytab[((*py++ +6)<<4)|(uvtab[((*pu++<<8)|*pv++)+3084]&15)];
  960.     }
  961.     /* line j + 2 */
  962.     for (i=0; i<horizontal_size; i+=8){
  963.       *dst++ = ytab[((*py++ +3)<<4)|(uvtab[((*pu++<<8)|*pv++)+1542]&15)];
  964.       *dst++ = ytab[((*py++ +11)<<4)|(uvtab[((*pu++<<8)|*pv++)+1542]>>4)];
  965.       *dst++ = ytab[((*py++ +1)<<4)|(uvtab[((*pu++<<8)|*pv++)+514]&15)];
  966.       *dst++ = ytab[((*py++ +9)<<4)|(uvtab[((*pu++<<8)|*pv++)+514]>>4)];
  967.       *dst++ = ytab[((*py++ +3)<<4)|(uvtab[((*pu++<<8)|*pv++)+1542]&15)];
  968.       *dst++ = ytab[((*py++ +11)<<4)|(uvtab[((*pu++<<8)|*pv++)+1542]>>4)];
  969.       *dst++ = ytab[((*py++ +1)<<4)|(uvtab[((*pu++<<8)|*pv++)+514]&15)];
  970.       *dst++ = ytab[((*py++ +9)<<4)|(uvtab[((*pu++<<8)|*pv++)+514]>>4)];
  971.     }
  972.     /* line j + 3 */
  973.     for (i=0; i<horizontal_size; i+=8){
  974.       *dst++ = ytab[((*py++ +15)<<4)|(uvtab[((*pu++<<8)|*pv++)+3598]>>4)];
  975.       *dst++ = ytab[((*py++ +7)<<4)|(uvtab[((*pu++<<8)|*pv++)+3598]&15)];
  976.       *dst++ = ytab[((*py++ +13)<<4)|(uvtab[((*pu++<<8)|*pv++)+2570]>>4)];
  977.       *dst++ = ytab[((*py++ +5)<<4)|(uvtab[((*pu++<<8)|*pv++)+2570]&15)];
  978.       *dst++ = ytab[((*py++ +15)<<4)|(uvtab[((*pu++<<8)|*pv++)+3598]>>4)];
  979.       *dst++ = ytab[((*py++ +7)<<4)|(uvtab[((*pu++<<8)|*pv++)+3598]&15)];
  980.       *dst++ = ytab[((*py++ +13)<<4)|(uvtab[((*pu++<<8)|*pv++)+2570]>>4)];
  981.       *dst++ = ytab[((*py++ +5)<<4)|(uvtab[((*pu++<<8)|*pv++)+2570]&15)];
  982.     }
  983.   }
  984. }
  985. void DisplayX11::dithertop444(unsigned char *src[], unsigned char *dst){
  986.   int i;
  987.   unsigned int y,uv;
  988.   unsigned char *py,*py2,*pu,*pv,*dst2;
  989.   py = src[0];
  990.   py2 = src[0] + (horizontal_size<<1);
  991.   pu = src[1];
  992.   pv = src[2];
  993.   dst2 = dst + horizontal_size;
  994.   for (int j=0; j<vertical_size; j+=4){
  995.     /* line j + 0, j + 1 */
  996.     for (i=0; i<horizontal_size; i+=4){
  997.       y = *py++;
  998.       uv = (*pu++<<8)|*pv++;
  999.       *dst++  = ytab[((y)<<4)|(uvtab[uv]&15)];
  1000.       *dst2++ = ytab[((((y + *py2++)>>1)+12)<<4)|(uvtab[uv+2056]>>4)];
  1001.       y = *py++;
  1002.       uv = (*pu++<<8)|*pv++;
  1003.       *dst++  = ytab[((y+8)<<4)|(uvtab[uv]>>4)];
  1004.       *dst2++ = ytab[((((y + *py2++)>>1)+4)<<4)|(uvtab[uv+2056]&15)];
  1005.       y = *py++;
  1006.       uv = (*pu++<<8)|*pv++;
  1007.       *dst++  = ytab[((y+2)<<4)|(uvtab[uv+1028]&15)];
  1008.       *dst2++ = ytab[((((y + *py2++)>>1)+14)<<4)|(uvtab[uv+3072]>>4)];
  1009.       y = *py++;
  1010.       uv = (*pu++<<8)|*pv++;
  1011.       *dst++  = ytab[((y+10)<<4)|(uvtab[uv+1028]>>4)];
  1012.       *dst2++ = ytab[((((y + *py2++)>>1)+6)<<4)|(uvtab[uv+3072]&15)];
  1013.     }
  1014.     py += horizontal_size;
  1015.     if (j!=(vertical_size-4))
  1016.       py2 += horizontal_size;
  1017.     else
  1018.       py2 -= horizontal_size;
  1019.     dst += horizontal_size;
  1020.     dst2 += horizontal_size;
  1021.     pu += chrom_width;
  1022.     pv += chrom_width;
  1023.     /* line j + 2, j + 3 */
  1024.     for (i=0; i<horizontal_size; i+=4){
  1025.       y = *py++;
  1026.       uv = (*pu++<<8)|*pv++;
  1027.       *dst++  = ytab[((y+3)<<4)|(uvtab[uv+1542]&15)];
  1028.       *dst2++ = ytab[((((y + *py2++)>>1)+15)<<4)|(uvtab[uv+3598]>>4)];
  1029.       y = *py++;
  1030.       uv = (*pu++<<8)|*pv++;
  1031.       *dst++  = ytab[((y+11)<<4)|(uvtab[uv+1542]>>4)];
  1032.       *dst2++ = ytab[((((y + *py2++)>>1)+7)<<4)|(uvtab[uv+3598]&15)];
  1033.       y = *py++;
  1034.       uv = (*pu++<<8)|*pv++;
  1035.       *dst++  = ytab[((y+1)<<4)|(uvtab[uv+514]&15)];
  1036.       *dst2++ = ytab[((((y + *py2++)>>1)+13)<<4)|(uvtab[uv+2570]>>4)];
  1037.       y = *py++;
  1038.       uv = (*pu++<<8)|*pv++;
  1039.       *dst++  = ytab[((y+9)<<4)|(uvtab[uv+514]>>4)];
  1040.       *dst2++ = ytab[((((y + *py2++)>>1)+5)<<4)|(uvtab[uv+2570]&15)];
  1041.     }
  1042.     py += horizontal_size;
  1043.     py2 += horizontal_size;
  1044.     dst += horizontal_size;
  1045.     dst2 += horizontal_size;
  1046.     pu += chrom_width;
  1047.     pv += chrom_width;
  1048.   }
  1049. }
  1050. void DisplayX11::ditherbot444(unsigned char *src[], unsigned char *dst){
  1051.   int i;
  1052.   unsigned int y2,uv;
  1053.   unsigned char *py,*py2,*pu,*pv,*dst2;
  1054.   py = src[0] + horizontal_size;
  1055.   py2 = py;
  1056.   pu = src[1] + chrom_width;
  1057.   pv = src[2] + chrom_width;
  1058.   dst2 = dst + horizontal_size;
  1059.   for (int j=0; j<vertical_size; j+=4){
  1060.     /* line j + 0, j + 1 */
  1061.     for (i=0; i<horizontal_size; i+=4){
  1062.       y2 = *py2++;
  1063.       uv = (*pu++<<8)|*pv++;
  1064.       *dst++  = ytab[((((*py++ + y2)>>1))<<4)|(uvtab[uv]&15)];
  1065.       *dst2++ = ytab[((y2+12)<<4)|(uvtab[uv+2056]>>4)];
  1066.       y2 = *py2++;
  1067.       uv = (*pu++<<8)|*pv++;
  1068.       *dst++  = ytab[((((*py++ + y2)>>1)+8)<<4)|(uvtab[uv]>>4)];
  1069.       *dst2++ = ytab[((y2+4)<<4)|(uvtab[uv+2056]&15)];
  1070.       y2 = *py2++;
  1071.       uv = (*pu++<<8)|*pv++;
  1072.       *dst++  = ytab[((((*py++ + y2)>>1)+2)<<4)|(uvtab[uv+1028]&15)];
  1073.       *dst2++ = ytab[((y2+14)<<4)|(uvtab[uv+3072]>>4)];
  1074.       y2 = *py2++;
  1075.       uv = (*pu++<<8)|*pv++;
  1076.       *dst++  = ytab[((((*py++ + y2)>>1)+10)<<4)|(uvtab[uv+1028]>>4)];
  1077.       *dst2++ = ytab[((y2+6)<<4)|(uvtab[uv+3072]&15)];
  1078.     }
  1079.     if (j==0)
  1080.       py -= horizontal_size;
  1081.     else
  1082.       py += horizontal_size;
  1083.     py2 += horizontal_size;
  1084.     dst += horizontal_size;
  1085.     dst2 += horizontal_size;
  1086.     pu += chrom_width;
  1087.     pv += chrom_width;
  1088.     /* line j + 2, j + 3 */
  1089.     for (i=0; i<horizontal_size; i+=4){
  1090.       y2 = *py2++;
  1091.       uv = (*pu++<<8)|*pv++;
  1092.       *dst++  = ytab[((((*py++ + y2)>>1)+3)<<4)|(uvtab[uv+1542]&15)];
  1093.       *dst2++ = ytab[((y2+15)<<4)|(uvtab[uv+3598]>>4)];
  1094.       y2 = *py2++;
  1095.       uv = (*pu++<<8)|*pv++;
  1096.       *dst++  = ytab[((((*py++ + y2)>>1)+11)<<4)|(uvtab[uv+1542]>>4)];
  1097.       *dst2++ = ytab[((y2+7)<<4)|(uvtab[uv+3598]&15)];
  1098.       y2 = *py2++;
  1099.       uv = (*pu++<<8)|*pv++;
  1100.       *dst++  = ytab[((((*py++ + y2)>>1)+1)<<4)|(uvtab[uv+514]&15)];
  1101.       *dst2++ = ytab[((y2+13)<<4)|(uvtab[uv+2570]>>4)];
  1102.       y2 = *py2++;
  1103.       uv = (*pu++<<8)|*pv++;
  1104.       *dst++  = ytab[((((*py++ + y2)>>1)+9)<<4)|(uvtab[uv+514]>>4)];
  1105.       *dst2++ = ytab[((y2+5)<<4)|(uvtab[uv+2570]&15)];
  1106.     }
  1107.     py += horizontal_size;
  1108.     py2 += horizontal_size;
  1109.     dst += horizontal_size;
  1110.     dst2 += horizontal_size;
  1111.     pu += chrom_width;
  1112.     pv += chrom_width;
  1113.   }
  1114. }
  1115. #ifdef SOLARIS_SDK_XIL
  1116. int DisplayX11::resize(){
  1117.   TRACER("int DisplayX11::resize()");
  1118.   Window root;
  1119.   int x, y;
  1120.   unsigned int w, h, b, d;
  1121.   XGetGeometry(display, window, &root, &x, &y, &w, &h, &b, &d);
  1122.   // indicate resize
  1123.   resized=1;
  1124.   horizontal_factor=((float) w)/horizontal_size;
  1125.   vertical_factor=((float) h)/vertical_size;
  1126.   // to avoid new events for the time being
  1127.   XSelectInput(display, window, NoEventMask);
  1128.   
  1129.   // Create new image with new geometry
  1130.   xil_destroy(displayimage);
  1131.   displayimage=xil_create_from_window(State, display, window);
  1132.   xil_destroy(resized_image);
  1133.   resized_image=xil_create(State, w, h, bands, XIL_BYTE);
  1134. /*
  1135.   if (bands==3){
  1136.     XilColorspace cspace=xil_colorspace_get_by_name(State, "ycc601");
  1137.     xil_set_colorspace(resized_image, cspace);
  1138.     cspace=xil_colorspace_get_by_name(State, "rgb709");
  1139.     xil_set_colorspace(displayimage, cspace);
  1140.   }
  1141. */
  1142.   XSelectInput(display, window, StructureNotifyMask);
  1143.   return 1;
  1144. }
  1145. #endif // SOLARIS_SDK_XIL
  1146. void  DisplayX11::dither_bw_rgb16(unsigned char * src,
  1147.                                   unsigned short * dithered_img,
  1148.                                   int height,
  1149.                                   int width,
  1150.                                   int display_width,
  1151.                                   int step) {
  1152.    int i,j,k,l=0;
  1153.    static unsigned short * look_up_table=NULL;
  1154.    if (look_up_table==NULL) {
  1155.       look_up_table=new unsigned short[256];
  1156.       for (i=0;i<256;++i) {
  1157.          look_up_table[i]=(i>>3)|((i>>2)<<5)|((i>>3)<<11);
  1158.          //fprintf(stdout,"%d=%02x ",i, look_up_table[i]);
  1159.       }
  1160.    }
  1161.    for (j=0;j<height;j+=step) {
  1162.       k=display_width*l++;
  1163.       for (i=0;i<width;i+=step) {
  1164.          dithered_img[k++]= look_up_table[src[j*width+i]];
  1165.       }
  1166.    }
  1167. }