1 /* display.c, X11 interface                                                 */
2 
3 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
4 
5 /*
6  * Disclaimer of Warranty
7  *
8  * These software programs are available to the user without any license fee or
9  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
10  * any and all warranties, whether express, implied, or statuary, including any
11  * implied warranties or merchantability or of fitness for a particular
12  * purpose.  In no event shall the copyright-holder be liable for any
13  * incidental, punitive, or consequential damages of any kind whatsoever
14  * arising from the use of these programs.
15  *
16  * This disclaimer of warranty extends to the user of these programs and user's
17  * customers, employees, agents, transferees, successors, and assigns.
18  *
19  * The MPEG Software Simulation Group does not represent or warrant that the
20  * programs furnished hereunder are free of infringement of any third-party
21  * patents.
22  *
23  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
24  * are subject to royalty fees to patent holders.  Many of these patents are
25  * general enough such that they are unavoidable regardless of implementation
26  * design.
27  *
28  */
29 
30 #ifdef DISPLAY
31 
32  /* the Xlib interface is closely modeled after
33   * mpeg_play 2.0 by the Berkeley Plateau Research Group
34   */
35 
36 #include <stdio.h>
37 #include <stdlib.h>
38 
39 #include <X11/Xlib.h>
40 #include <X11/Xutil.h>
41 
42 #include "config.h"
43 #include "global.h"
44 
45 /* private prototypes */
46 static void Display_Image _ANSI_ARGS_((XImage *Ximage_Ptr, unsigned char *Dithered_Image));
47 static void Dither_Frame _ANSI_ARGS_((unsigned char *src[]));
48 static void Dither_Top_Field _ANSI_ARGS_((unsigned char *src[], unsigned char *dst));
49 static void Dither_Bottom_Field _ANSI_ARGS_((unsigned char *src[], unsigned char *dst));
50 static void Dither_Top_Field420 _ANSI_ARGS_((unsigned char *src[],
51                                       unsigned char *dst));
52 static void Dither_Bottom_Field420 _ANSI_ARGS_((unsigned char *src[],
53                                       unsigned char *dst));
54 
55 /* local data */
56 static unsigned char *Dithered_Image, *Dithered_Image2;
57 
58 static unsigned char Y_Table[256+16];
59 static unsigned char Cb_Table[128+16];
60 static unsigned char Cr_Table[128+16];
61 
62 /* X11 related variables */
63 static Display *Display_Ptr;
64 static Window Window_Instance;
65 static GC GC_Instance;
66 static XImage *Ximage_Ptr, *Ximage_Ptr2;
67 static unsigned char Pixel[256];
68 
69 #ifdef SH_MEM
70 
71 #include <sys/ipc.h>
72 #include <sys/shm.h>
73 #include <X11/extensions/XShm.h>
74 
75 static int HandleXError _ANSI_ARGS_((Display *dpy, XErrorEvent *event));
76 static void InstallXErrorHandler _ANSI_ARGS_((void));
77 static void DeInstallXErrorHandler _ANSI_ARGS_((void));
78 
79 static int Shmem_Flag;
80 static XShmSegmentInfo Shminfo1, Shminfo2;
81 static int gXErrorFlag;
82 static int CompletionType = -1;
83 
HandleXError(Dpy,Event)84 static int HandleXError(Dpy, Event)
85 Display *Dpy;
86 XErrorEvent *Event;
87 {
88   gXErrorFlag = 1;
89 
90   return 0;
91 }
92 
InstallXErrorHandler()93 static void InstallXErrorHandler()
94 {
95   XSetErrorHandler(HandleXError);
96   XFlush(Display_Ptr);
97 }
98 
DeInstallXErrorHandler()99 static void DeInstallXErrorHandler()
100 {
101   XSetErrorHandler(NULL);
102   XFlush(Display_Ptr);
103 }
104 
105 #endif
106 
107 /* connect to server, create and map window,
108  * allocate colors and (shared) memory
109  */
Initialize_Display_Process(name)110 void Initialize_Display_Process(name)
111 char *name;
112 {
113   int crv, cbu, cgu, cgv;
114   int Y, Cb, Cr, R, G, B;
115   int i;
116   char dummy;
117   int screen;
118   Colormap cmap;
119   int private;
120   XColor xcolor;
121   unsigned int fg, bg;
122   char *hello = "MPEG-2 Display";
123   XSizeHints hint;
124   XVisualInfo vinfo;
125   XEvent xev;
126   unsigned long tmp_pixel;
127   XWindowAttributes xwa;
128 
129   Display_Ptr = XOpenDisplay(name);
130 
131   if (Display_Ptr == NULL)
132     Error("Can not open display\n");
133 
134   screen = DefaultScreen(Display_Ptr);
135 
136   hint.x = 200;
137   hint.y = 200;
138   hint.width = horizontal_size;
139   hint.height = vertical_size;
140   hint.flags = PPosition | PSize;
141 
142   /* Get some colors */
143 
144   bg = WhitePixel (Display_Ptr, screen);
145   fg = BlackPixel (Display_Ptr, screen);
146 
147   /* Make the window */
148 
149   if (!XMatchVisualInfo(Display_Ptr, screen, 8, PseudoColor, &vinfo))
150   {
151     if (!XMatchVisualInfo(Display_Ptr, screen, 8, GrayScale, &vinfo))
152       Error("requires 8 bit display\n");
153   }
154 
155   Window_Instance = XCreateSimpleWindow (Display_Ptr, DefaultRootWindow (Display_Ptr),
156              hint.x, hint.y, hint.width, hint.height, 4, fg, bg);
157 
158   XSelectInput(Display_Ptr, Window_Instance, StructureNotifyMask);
159 
160   /* Tell other applications about this window */
161 
162   XSetStandardProperties (Display_Ptr, Window_Instance, hello, hello, None, NULL, 0, &hint);
163 
164   /* Map window. */
165 
166   XMapWindow(Display_Ptr, Window_Instance);
167 
168   /* Wait for map. */
169   do
170   {
171     XNextEvent(Display_Ptr, &xev);
172   }
173   while (xev.type != MapNotify || xev.xmap.event != Window_Instance);
174 
175   XSelectInput(Display_Ptr, Window_Instance, NoEventMask);
176 
177   /* matrix coefficients */
178   crv = Inverse_Table_6_9[matrix_coefficients][0];
179   cbu = Inverse_Table_6_9[matrix_coefficients][1];
180   cgu = Inverse_Table_6_9[matrix_coefficients][2];
181   cgv = Inverse_Table_6_9[matrix_coefficients][3];
182 
183   /* allocate colors */
184 
185   GC_Instance = DefaultGC(Display_Ptr, screen);
186   cmap = DefaultColormap(Display_Ptr, screen);
187   private = 0;
188 
189   /* color allocation:
190    * i is the (internal) 8 bit color number, it consists of separate
191    * bit fields for Y, U and V: i = (yyyyuuvv), we don't use yyyy=0000
192    * and yyyy=1111, this leaves 32 colors for other applications
193    *
194    * the allocated colors correspond to the following Y, U and V values:
195    * Y:   24, 40, 56, 72, 88, 104, 120, 136, 152, 168, 184, 200, 216, 232
196    * U,V: -48, -16, 16, 48
197    *
198    * U and V values span only about half the color space; this gives
199    * usually much better quality, although highly saturated colors can
200    * not be displayed properly
201    *
202    * translation to R,G,B is implicitly done by the color look-up table
203    */
204   for (i=16; i<240; i++)
205   {
206     /* color space conversion */
207     Y  = 16*((i>>4)&15) + 8;
208     Cb = 32*((i>>2)&3)  - 48;
209     Cr = 32*(i&3)       - 48;
210 
211     Y = 76309 * (Y - 16); /* (255/219)*65536 */
212 
213     R = Clip[(Y + crv*Cr + 32768)>>16];
214     G = Clip[(Y - cgu*Cb - cgv*Cr + 32768)>>16];
215     B = Clip[(Y + cbu*Cb + 32786)>>16];
216 
217     /* X11 colors are 16 bit */
218     xcolor.red   = R << 8;
219     xcolor.green = G << 8;
220     xcolor.blue  = B << 8;
221 
222     if (XAllocColor(Display_Ptr, cmap, &xcolor) != 0)
223       Pixel[i] = xcolor.pixel;
224     else
225     {
226       /* allocation failed, have to use a private colormap */
227 
228       if (private)
229         Error("Couldn't allocate private colormap");
230 
231       private = 1;
232 
233       if (!Quiet_Flag)
234         fprintf(stderr, "Using private colormap (%d colors were available).\n",
235           i-16);
236 
237       /* Free colors. */
238       while (--i >= 16)
239       {
240         tmp_pixel = Pixel[i]; /* because XFreeColors expects unsigned long */
241         XFreeColors(Display_Ptr, cmap, &tmp_pixel, 1, 0);
242       }
243 
244       /* i is now 15, this restarts the outer loop */
245 
246       /* create private colormap */
247 
248       XGetWindowAttributes(Display_Ptr, Window_Instance, &xwa);
249       cmap = XCreateColormap(Display_Ptr, Window_Instance, xwa.visual, AllocNone);
250       XSetWindowColormap(Display_Ptr, Window_Instance, cmap);
251     }
252   }
253 
254 #ifdef SH_MEM
255   if (XShmQueryExtension(Display_Ptr))
256     Shmem_Flag = 1;
257   else
258   {
259     Shmem_Flag = 0;
260     if (!Quiet_Flag)
261       fprintf(stderr, "Shared memory not supported\nReverting to normal Xlib\n");
262   }
263 
264   if (Shmem_Flag)
265     CompletionType = XShmGetEventBase(Display_Ptr) + ShmCompletion;
266 
267   InstallXErrorHandler();
268 
269   if (Shmem_Flag)
270   {
271 
272     Ximage_Ptr = XShmCreateImage(Display_Ptr, None, 8, ZPixmap, NULL,
273                              &Shminfo1,
274                              Coded_Picture_Width, Coded_Picture_Height);
275 
276     if (!progressive_sequence)
277       Ximage_Ptr2 = XShmCreateImage(Display_Ptr, None, 8, ZPixmap, NULL,
278                                 &Shminfo2,
279                                 Coded_Picture_Width, Coded_Picture_Height);
280 
281     /* If no go, then revert to normal Xlib calls. */
282 
283     if (Ximage_Ptr==NULL || (!progressive_sequence && Ximage_Ptr2==NULL))
284     {
285       if (Ximage_Ptr!=NULL)
286         XDestroyImage(Ximage_Ptr);
287       if (!progressive_sequence && Ximage_Ptr2!=NULL)
288         XDestroyImage(Ximage_Ptr2);
289       if (!Quiet_Flag)
290         fprintf(stderr, "Shared memory error, disabling (Ximage error)\n");
291       goto shmemerror;
292     }
293 
294     /* Success here, continue. */
295 
296     Shminfo1.shmid = shmget(IPC_PRIVATE,
297                             Ximage_Ptr->bytes_per_line * Ximage_Ptr->height,
298                             IPC_CREAT | 0777);
299     if (!progressive_sequence)
300       Shminfo2.shmid = shmget(IPC_PRIVATE,
301                               Ximage_Ptr2->bytes_per_line * Ximage_Ptr2->height,
302                               IPC_CREAT | 0777);
303 
304     if (Shminfo1.shmid<0 || (!progressive_sequence && Shminfo2.shmid<0))
305     {
306       XDestroyImage(Ximage_Ptr);
307       if (!progressive_sequence)
308         XDestroyImage(Ximage_Ptr2);
309       if (!Quiet_Flag)
310         fprintf(stderr, "Shared memory error, disabling (seg id error)\n");
311       goto shmemerror;
312     }
313 
314     Shminfo1.shmaddr = (char *) shmat(Shminfo1.shmid, 0, 0);
315     Shminfo2.shmaddr = (char *) shmat(Shminfo2.shmid, 0, 0);
316 
317     if (Shminfo1.shmaddr==((char *) -1) ||
318         (!progressive_sequence && Shminfo2.shmaddr==((char *) -1)))
319     {
320       XDestroyImage(Ximage_Ptr);
321       if (Shminfo1.shmaddr!=((char *) -1))
322         shmdt(Shminfo1.shmaddr);
323       if (!progressive_sequence)
324       {
325         XDestroyImage(Ximage_Ptr2);
326         if (Shminfo2.shmaddr!=((char *) -1))
327           shmdt(Shminfo2.shmaddr);
328       }
329       if (!Quiet_Flag)
330       {
331         fprintf(stderr, "Shared memory error, disabling (address error)\n");
332       }
333       goto shmemerror;
334     }
335 
336     Ximage_Ptr->data = Shminfo1.shmaddr;
337     Dithered_Image = (unsigned char *)Ximage_Ptr->data;
338     Shminfo1.readOnly = False;
339     XShmAttach(Display_Ptr, &Shminfo1);
340     if (!progressive_sequence)
341     {
342       Ximage_Ptr2->data = Shminfo2.shmaddr;
343       Dithered_Image2 = (unsigned char *)Ximage_Ptr2->data;
344       Shminfo2.readOnly = False;
345       XShmAttach(Display_Ptr, &Shminfo2);
346     }
347 
348     XSync(Display_Ptr, False);
349 
350     if (gXErrorFlag)
351     {
352       /* Ultimate failure here. */
353       XDestroyImage(Ximage_Ptr);
354       shmdt(Shminfo1.shmaddr);
355       if (!progressive_sequence)
356       {
357         XDestroyImage(Ximage_Ptr2);
358         shmdt(Shminfo2.shmaddr);
359       }
360       if (!Quiet_Flag)
361         fprintf(stderr, "Shared memory error, disabling.\n");
362       gXErrorFlag = 0;
363       goto shmemerror;
364     }
365     else
366     {
367       shmctl(Shminfo1.shmid, IPC_RMID, 0);
368       if (!progressive_sequence)
369         shmctl(Shminfo2.shmid, IPC_RMID, 0);
370     }
371 
372     if (!Quiet_Flag)
373     {
374       fprintf(stderr, "Sharing memory.\n");
375     }
376   }
377   else
378   {
379 shmemerror:
380     Shmem_Flag = 0;
381 #endif
382 
383     Ximage_Ptr = XCreateImage(Display_Ptr,None,8,ZPixmap,0,&dummy,
384                           Coded_Picture_Width,Coded_Picture_Height,8,0);
385 
386     if (!(Dithered_Image = (unsigned char *)malloc(Coded_Picture_Width*
387                                                    Coded_Picture_Height)))
388       Error("malloc failed");
389 
390     if (!progressive_sequence)
391     {
392       Ximage_Ptr2 = XCreateImage(Display_Ptr,None,8,ZPixmap,0,&dummy,
393                              Coded_Picture_Width,Coded_Picture_Height,8,0);
394 
395       if (!(Dithered_Image2 = (unsigned char *)malloc(Coded_Picture_Width*
396                                                       Coded_Picture_Height)))
397         Error("malloc failed");
398     }
399 
400 #ifdef SH_MEM
401   }
402 
403   DeInstallXErrorHandler();
404 #endif
405 }
406 
Terminate_Display_Process()407 void Terminate_Display_Process()
408 {
409 #ifdef SH_MEM
410   if (Shmem_Flag)
411   {
412     XShmDetach(Display_Ptr, &Shminfo1);
413     XDestroyImage(Ximage_Ptr);
414     shmdt(Shminfo1.shmaddr);
415     if (!progressive_sequence)
416     {
417       XShmDetach(Display_Ptr, &Shminfo2);
418       XDestroyImage(Ximage_Ptr2);
419       shmdt(Shminfo2.shmaddr);
420     }
421   }
422 #endif
423 }
424 
Display_Image(Ximage_Ptr,Dithered_Image)425 static void Display_Image(Ximage_Ptr,Dithered_Image)
426 XImage *Ximage_Ptr;
427 unsigned char *Dithered_Image;
428 {
429   /* display dithered image */
430 #ifdef SH_MEM
431   if (Shmem_Flag)
432   {
433     XShmPutImage(Display_Ptr, Window_Instance, GC_Instance, Ximage_Ptr,
434        	         0, 0, 0, 0, Ximage_Ptr->width, Ximage_Ptr->height, True);
435     XFlush(Display_Ptr);
436 
437     while (1)
438     {
439       XEvent xev;
440 
441       XNextEvent(Display_Ptr, &xev);
442       if (xev.type == CompletionType)
443         break;
444     }
445   }
446   else
447 #endif
448   {
449     Ximage_Ptr->data = (char *) Dithered_Image;
450     XPutImage(Display_Ptr, Window_Instance, GC_Instance, Ximage_Ptr, 0, 0, 0, 0, Ximage_Ptr->width, Ximage_Ptr->height);
451   }
452 }
453 
Display_Second_Field()454 void Display_Second_Field()
455 {
456   Display_Image(Ximage_Ptr2,Dithered_Image2);
457 }
458 
459 /* 4x4 ordered dither
460  *
461  * threshold pattern:
462  *   0  8  2 10
463  *  12  4 14  6
464  *   3 11  1  9
465  *  15  7 13  5
466  */
467 
Initialize_Dither_Matrix()468 void Initialize_Dither_Matrix()
469 {
470   int i, v;
471 
472   for (i=-8; i<256+8; i++)
473   {
474     v = i>>4;
475     if (v<1)
476       v = 1;
477     else if (v>14)
478       v = 14;
479     Y_Table[i+8] = v<<4;
480   }
481 
482   for (i=0; i<128+16; i++)
483   {
484     v = (i-40)>>4;
485     if (v<0)
486       v = 0;
487     else if (v>3)
488       v = 3;
489     Cb_Table[i] = v<<2;
490     Cr_Table[i] = v;
491   }
492 }
493 
dither(src)494 void dither(src)
495 unsigned char *src[];
496 {
497   /* should this test only the display flag, not progressive_sequence ? --CF */
498   /* CHANGE 95/05/13: progressive_sequence -> progressive_frame */
499 
500   if( progressive_frame || Display_Progressive_Flag)
501     Dither_Frame(src);
502   else
503   {
504     if ((picture_structure==FRAME_PICTURE && top_field_first) || picture_structure==BOTTOM_FIELD)
505     {
506       /* top field first */
507       if (chroma_format==CHROMA420 && hiQdither)
508       {
509         Dither_Top_Field420(src,Dithered_Image);
510         Dither_Bottom_Field420(src,Dithered_Image2);
511       }
512       else
513       {
514         Dither_Top_Field(src,Dithered_Image);
515         Dither_Bottom_Field(src,Dithered_Image2);
516       }
517     }
518     else
519     {
520       /* bottom field first */
521       if (chroma_format==CHROMA420 && hiQdither)
522       {
523         Dither_Bottom_Field420(src,Dithered_Image);
524         Dither_Top_Field420(src,Dithered_Image2);
525       }
526       else
527       {
528         Dither_Bottom_Field(src,Dithered_Image);
529         Dither_Top_Field(src,Dithered_Image2);
530       }
531     }
532   }
533 
534   Display_Image(Ximage_Ptr,Dithered_Image);
535 }
536 
Dither_Frame(src)537 static void Dither_Frame(src)
538 unsigned char *src[];
539 {
540   int i,j;
541   int y,u,v;
542   unsigned char *py,*pu,*pv,*dst;
543 
544   py = src[0];
545   pu = src[1];
546   pv = src[2];
547   dst = Dithered_Image;
548 
549   for (j=0; j<Coded_Picture_Height; j+=4)
550   {
551     /* line j + 0 */
552     for (i=0; i<Coded_Picture_Width; i+=4)
553     {
554       y = *py++;
555       u = *pu++ >> 1;
556       v = *pv++ >> 1;
557       *dst++ = Pixel[Y_Table[y]|Cb_Table[u]|Cr_Table[v]];
558       y = *py++;
559       if (chroma_format==CHROMA444)
560       {
561         u = *pu++ >> 1;
562         v = *pv++ >> 1;
563       }
564       *dst++ = Pixel[Y_Table[y+8]|Cb_Table[u+8]|Cr_Table[v+8]];
565       y = *py++;
566       u = *pu++ >> 1;
567       v = *pv++ >> 1;
568       *dst++ = Pixel[Y_Table[y+2]|Cb_Table[u+2]|Cr_Table[v+2]];
569       y = *py++;
570       if (chroma_format==CHROMA444)
571       {
572         u = *pu++ >> 1;
573         v = *pv++ >> 1;
574       }
575       *dst++ = Pixel[Y_Table[y+10]|Cb_Table[u+10]|Cr_Table[v+10]];
576     }
577 
578     if (chroma_format==CHROMA420)
579     {
580       pu -= Chroma_Width;
581       pv -= Chroma_Width;
582     }
583 
584     /* line j + 1 */
585     for (i=0; i<Coded_Picture_Width; i+=4)
586     {
587       y = *py++;
588       u = *pu++ >> 1;
589       v = *pv++ >> 1;
590       *dst++ = Pixel[Y_Table[y+12]|Cb_Table[u+12]|Cr_Table[v+12]];
591       y = *py++;
592       if (chroma_format==CHROMA444)
593       {
594         u = *pu++ >> 1;
595         v = *pv++ >> 1;
596       }
597       *dst++ = Pixel[Y_Table[y+4]|Cb_Table[u+4]|Cr_Table[v+4]];
598       y = *py++;
599       u = *pu++ >> 1;
600       v = *pv++ >> 1;
601       *dst++ = Pixel[Y_Table[y+14]|Cb_Table[u+14]|Cr_Table[v+14]];
602       y = *py++;
603       if (chroma_format==CHROMA444)
604       {
605         u = *pu++ >> 1;
606         v = *pv++ >> 1;
607       }
608       *dst++ = Pixel[Y_Table[y+6]|Cb_Table[u+6]|Cr_Table[v+6]];
609     }
610 
611     /* line j + 2 */
612     for (i=0; i<Coded_Picture_Width; i+=4)
613     {
614       y = *py++;
615       u = *pu++ >> 1;
616       v = *pv++ >> 1;
617       *dst++ = Pixel[Y_Table[y+3]|Cb_Table[u+3]|Cr_Table[v+3]];
618       y = *py++;
619       if (chroma_format==CHROMA444)
620       {
621         u = *pu++ >> 1;
622         v = *pv++ >> 1;
623       }
624       *dst++ = Pixel[Y_Table[y+11]|Cb_Table[u+11]|Cr_Table[v+11]];
625       y = *py++;
626       u = *pu++ >> 1;
627       v = *pv++ >> 1;
628       *dst++ = Pixel[Y_Table[y+1]|Cb_Table[u+1]|Cr_Table[v+1]];
629       y = *py++;
630       if (chroma_format==CHROMA444)
631       {
632         u = *pu++ >> 1;
633         v = *pv++ >> 1;
634       }
635       *dst++ = Pixel[Y_Table[y+9]|Cb_Table[u+9]|Cr_Table[v+9]];
636     }
637 
638     if (chroma_format==CHROMA420)
639     {
640       pu -= Chroma_Width;
641       pv -= Chroma_Width;
642     }
643 
644     /* line j + 3 */
645     for (i=0; i<Coded_Picture_Width; i+=4)
646     {
647       y = *py++;
648       u = *pu++ >> 1;
649       v = *pv++ >> 1;
650       *dst++ = Pixel[Y_Table[y+15]|Cb_Table[u+15]|Cr_Table[v+15]];
651       y = *py++;
652       if (chroma_format==CHROMA444)
653       {
654         u = *pu++ >> 1;
655         v = *pv++ >> 1;
656       }
657       *dst++ = Pixel[Y_Table[y+7]|Cb_Table[u+7]|Cr_Table[v+7]];
658       y = *py++;
659       u = *pu++ >> 1;
660       v = *pv++ >> 1;
661       *dst++ = Pixel[Y_Table[y+13]|Cb_Table[u+13]|Cr_Table[v+13]];
662       y = *py++;
663       if (chroma_format==CHROMA444)
664       {
665         u = *pu++ >> 1;
666         v = *pv++ >> 1;
667       }
668       *dst++ = Pixel[Y_Table[y+5]|Cb_Table[u+5]|Cr_Table[v+5]];
669     }
670   }
671 
672 }
673 
Dither_Top_Field(src,dst)674 static void Dither_Top_Field(src,dst)
675 unsigned char *src[];
676 unsigned char *dst;
677 {
678   int i,j;
679   int y,Y2,u,v;
680   unsigned char *py,*Y2_ptr,*pu,*pv,*dst2;
681 
682   py = src[0];
683   Y2_ptr = src[0] + (Coded_Picture_Width<<1);
684   pu = src[1];
685   pv = src[2];
686   dst2 = dst + Coded_Picture_Width;
687 
688   for (j=0; j<Coded_Picture_Height; j+=4)
689   {
690     /* line j + 0, j + 1 */
691     for (i=0; i<Coded_Picture_Width; i+=4)
692     {
693       y = *py++;
694       Y2 = *Y2_ptr++;
695       u = *pu++ >> 1;
696       v = *pv++ >> 1;
697       *dst++  = Pixel[Y_Table[y]|Cb_Table[u]|Cr_Table[v]];
698       *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+12]|Cb_Table[u+12]|Cr_Table[v+12]];
699 
700       y = *py++;
701       Y2 = *Y2_ptr++;
702       if (chroma_format==CHROMA444)
703       {
704         u = *pu++ >> 1;
705         v = *pv++ >> 1;
706       }
707       *dst++  = Pixel[Y_Table[y+8]|Cb_Table[u+8]|Cr_Table[v+8]];
708       *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+4]|Cb_Table[u+4]|Cr_Table[v+4]];
709 
710       y = *py++;
711       Y2 = *Y2_ptr++;
712       u = *pu++ >> 1;
713       v = *pv++ >> 1;
714       *dst++  = Pixel[Y_Table[y+2]|Cb_Table[u+2]|Cr_Table[v+2]];
715       *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+14]|Cb_Table[u+14]|Cr_Table[v+14]];
716 
717       y = *py++;
718       Y2 = *Y2_ptr++;
719       if (chroma_format==CHROMA444)
720       {
721         u = *pu++ >> 1;
722         v = *pv++ >> 1;
723       }
724       *dst++  = Pixel[Y_Table[y+10]|Cb_Table[u+10]|Cr_Table[v+10]];
725       *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+6]|Cb_Table[u+6]|Cr_Table[v+6]];
726     }
727 
728     py += Coded_Picture_Width;
729 
730     if (j!=(Coded_Picture_Height-4))
731       Y2_ptr += Coded_Picture_Width;
732     else
733       Y2_ptr -= Coded_Picture_Width;
734 
735     dst += Coded_Picture_Width;
736     dst2 += Coded_Picture_Width;
737 
738     if (chroma_format==CHROMA420)
739     {
740       pu -= Chroma_Width;
741       pv -= Chroma_Width;
742     }
743     else
744     {
745       pu += Chroma_Width;
746       pv += Chroma_Width;
747     }
748 
749     /* line j + 2, j + 3 */
750     for (i=0; i<Coded_Picture_Width; i+=4)
751     {
752       y = *py++;
753       Y2 = *Y2_ptr++;
754       u = *pu++ >> 1;
755       v = *pv++ >> 1;
756       *dst++  = Pixel[Y_Table[y+3]|Cb_Table[u+3]|Cr_Table[v+3]];
757       *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+15]|Cb_Table[u+15]|Cr_Table[v+15]];
758 
759       y = *py++;
760       Y2 = *Y2_ptr++;
761       if (chroma_format==CHROMA444)
762       {
763         u = *pu++ >> 1;
764         v = *pv++ >> 1;
765       }
766       *dst++  = Pixel[Y_Table[y+11]|Cb_Table[u+11]|Cr_Table[v+11]];
767       *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+7]|Cb_Table[u+7]|Cr_Table[v+7]];
768 
769       y = *py++;
770       Y2 = *Y2_ptr++;
771       u = *pu++ >> 1;
772       v = *pv++ >> 1;
773       *dst++  = Pixel[Y_Table[y+1]|Cb_Table[u+1]|Cr_Table[v+1]];
774       *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+13]|Cb_Table[u+13]|Cr_Table[v+13]];
775 
776       y = *py++;
777       Y2 = *Y2_ptr++;
778       if (chroma_format==CHROMA444)
779       {
780         u = *pu++ >> 1;
781         v = *pv++ >> 1;
782       }
783       *dst++  = Pixel[Y_Table[y+9]|Cb_Table[u+9]|Cr_Table[v+9]];
784       *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+5]|Cb_Table[u+5]|Cr_Table[v+5]];
785     }
786 
787     py += Coded_Picture_Width;
788     Y2_ptr += Coded_Picture_Width;
789     dst += Coded_Picture_Width;
790     dst2 += Coded_Picture_Width;
791     pu += Chroma_Width;
792     pv += Chroma_Width;
793   }
794 }
795 
Dither_Bottom_Field(src,dst)796 static void Dither_Bottom_Field(src,dst)
797 unsigned char *src[];
798 unsigned char *dst;
799 {
800   int i,j;
801   int y,Y2,u,v;
802   unsigned char *py,*Y2_ptr,*pu,*pv,*dst2;
803 
804   py = src[0] + Coded_Picture_Width;
805   Y2_ptr = py;
806   pu = src[1] + Chroma_Width;
807   pv = src[2] + Chroma_Width;
808   dst2 = dst + Coded_Picture_Width;
809 
810   for (j=0; j<Coded_Picture_Height; j+=4)
811   {
812     /* line j + 0, j + 1 */
813     for (i=0; i<Coded_Picture_Width; i+=4)
814     {
815       y = *py++;
816       Y2 = *Y2_ptr++;
817       u = *pu++ >> 1;
818       v = *pv++ >> 1;
819       *dst++  = Pixel[Y_Table[((y+Y2)>>1)]|Cb_Table[u]|Cr_Table[v]];
820       *dst2++ = Pixel[Y_Table[Y2+12]|Cb_Table[u+12]|Cr_Table[v+12]];
821 
822       y = *py++;
823       Y2 = *Y2_ptr++;
824       if (chroma_format==CHROMA444)
825       {
826         u = *pu++ >> 1;
827         v = *pv++ >> 1;
828       }
829       *dst++  = Pixel[Y_Table[((y+Y2)>>1)+8]|Cb_Table[u+8]|Cr_Table[v+8]];
830       *dst2++ = Pixel[Y_Table[Y2+4]|Cb_Table[u+4]|Cr_Table[v+4]];
831 
832       y = *py++;
833       Y2 = *Y2_ptr++;
834       u = *pu++ >> 1;
835       v = *pv++ >> 1;
836       *dst++  = Pixel[Y_Table[((y+Y2)>>1)+2]|Cb_Table[u+2]|Cr_Table[v+2]];
837       *dst2++ = Pixel[Y_Table[Y2+14]|Cb_Table[u+14]|Cr_Table[v+14]];
838 
839       y = *py++;
840       Y2 = *Y2_ptr++;
841       if (chroma_format==CHROMA444)
842       {
843         u = *pu++ >> 1;
844         v = *pv++ >> 1;
845       }
846       *dst++  = Pixel[Y_Table[((y+Y2)>>1)+10]|Cb_Table[u+10]|Cr_Table[v+10]];
847       *dst2++ = Pixel[Y_Table[Y2+6]|Cb_Table[u+6]|Cr_Table[v+6]];
848     }
849 
850     if (j==0)
851       py -= Coded_Picture_Width;
852     else
853       py += Coded_Picture_Width;
854 
855     Y2_ptr += Coded_Picture_Width;
856     dst += Coded_Picture_Width;
857     dst2 += Coded_Picture_Width;
858 
859     if (chroma_format==CHROMA420)
860     {
861       pu -= Chroma_Width;
862       pv -= Chroma_Width;
863     }
864     else
865     {
866       pu += Chroma_Width;
867       pv += Chroma_Width;
868     }
869 
870     /* line j + 2. j + 3 */
871     for (i=0; i<Coded_Picture_Width; i+=4)
872     {
873       y = *py++;
874       Y2 = *Y2_ptr++;
875       u = *pu++ >> 1;
876       v = *pv++ >> 1;
877       *dst++  = Pixel[Y_Table[((y+Y2)>>1)+3]|Cb_Table[u+3]|Cr_Table[v+3]];
878       *dst2++ = Pixel[Y_Table[Y2+15]|Cb_Table[u+15]|Cr_Table[v+15]];
879 
880       y = *py++;
881       Y2 = *Y2_ptr++;
882       if (chroma_format==CHROMA444)
883       {
884         u = *pu++ >> 1;
885         v = *pv++ >> 1;
886       }
887       *dst++  = Pixel[Y_Table[((y+Y2)>>1)+11]|Cb_Table[u+11]|Cr_Table[v+11]];
888       *dst2++ = Pixel[Y_Table[Y2+7]|Cb_Table[u+7]|Cr_Table[v+7]];
889 
890       y = *py++;
891       Y2 = *Y2_ptr++;
892       u = *pu++ >> 1;
893       v = *pv++ >> 1;
894       *dst++  = Pixel[Y_Table[((y+Y2)>>1)+1]|Cb_Table[u+1]|Cr_Table[v+1]];
895       *dst2++ = Pixel[Y_Table[Y2+13]|Cb_Table[u+13]|Cr_Table[v+13]];
896 
897       y = *py++;
898       Y2 = *Y2_ptr++;
899       if (chroma_format==CHROMA444)
900       {
901         u = *pu++ >> 1;
902         v = *pv++ >> 1;
903       }
904       *dst++  = Pixel[Y_Table[((y+Y2)>>1)+9]|Cb_Table[u+9]|Cr_Table[v+9]];
905       *dst2++ = Pixel[Y_Table[Y2+5]|Cb_Table[u+5]|Cr_Table[v+5]];
906     }
907 
908     py += Coded_Picture_Width;
909     Y2_ptr += Coded_Picture_Width;
910     dst += Coded_Picture_Width;
911     dst2 += Coded_Picture_Width;
912     pu += Chroma_Width;
913     pv += Chroma_Width;
914   }
915 }
916 
Dither_Top_Field420(src,dst)917 static void Dither_Top_Field420(src,dst)
918 unsigned char *src[];
919 unsigned char *dst;
920 {
921   int i,j;
922   int Y1,Cb1,Cr1,Y2,Cb2,Cr2;
923   unsigned char *Y1_ptr,*Cb1_ptr,*Cr1_ptr,*Y2_ptr,*Cb2_ptr,*Cr2_ptr,*dst2;
924 
925   Y1_ptr = src[0];
926   Cb1_ptr = src[1];
927   Cr1_ptr = src[2];
928 
929   Y2_ptr = Y1_ptr + (Coded_Picture_Width<<1);
930   Cb2_ptr = Cb1_ptr + (Chroma_Width<<1);
931   Cr2_ptr = Cr1_ptr + (Chroma_Width<<1);
932 
933   dst2 = dst + Coded_Picture_Width;
934 
935   for (j=0; j<Coded_Picture_Height; j+=4)
936   {
937     /* line j + 0, j + 1 */
938     for (i=0; i<Coded_Picture_Width; i+=4)
939     {
940       Y1 = *Y1_ptr++;
941       Y2 = *Y2_ptr++;
942       Cb1 = *Cb1_ptr++ >> 1;
943       Cr1 = *Cr1_ptr++ >> 1;
944       Cb2 = *Cb2_ptr++ >> 1;
945       Cr2 = *Cr2_ptr++ >> 1;
946       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)]|Cb_Table[Cb1]|Cr_Table[Cr1]];
947       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+12]|Cb_Table[((3*Cb1+Cb2)>>2)+12]
948                                              |Cr_Table[((3*Cr1+Cr2)>>2)+12]];
949 
950       Y1 = *Y1_ptr++;
951       Y2 = *Y2_ptr++;
952       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+8]|Cb_Table[Cb1+8]|Cr_Table[Cr1+8]];
953       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+4]|Cb_Table[((3*Cb1+Cb2)>>2)+4]
954                                             |Cr_Table[((3*Cr1+Cr2)>>2)+4]];
955 
956       Y1 = *Y1_ptr++;
957       Y2 = *Y2_ptr++;
958       Cb1 = *Cb1_ptr++ >> 1;
959       Cr1 = *Cr1_ptr++ >> 1;
960       Cb2 = *Cb2_ptr++ >> 1;
961       Cr2 = *Cr2_ptr++ >> 1;
962       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+2]|Cb_Table[Cb1+2]|Cr_Table[Cr1+2]];
963       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+14]|Cb_Table[((3*Cb1+Cb2)>>2)+14]
964                                              |Cr_Table[((3*Cr1+Cr2)>>2)+14]];
965 
966       Y1 = *Y1_ptr++;
967       Y2 = *Y2_ptr++;
968       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+10]|Cb_Table[Cb1+10]|Cr_Table[Cr1+10]];
969       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+6]|Cb_Table[((3*Cb1+Cb2)>>2)+6]
970                                             |Cr_Table[((3*Cr1+Cr2)>>2)+6]];
971     }
972 
973     Y1_ptr += Coded_Picture_Width;
974 
975     if (j!=(Coded_Picture_Height-4))
976       Y2_ptr += Coded_Picture_Width;
977     else
978       Y2_ptr -= Coded_Picture_Width;
979 
980     Cb1_ptr -= Chroma_Width;
981     Cr1_ptr -= Chroma_Width;
982     Cb2_ptr -= Chroma_Width;
983     Cr2_ptr -= Chroma_Width;
984 
985     dst  += Coded_Picture_Width;
986     dst2 += Coded_Picture_Width;
987 
988     /* line j + 2, j + 3 */
989     for (i=0; i<Coded_Picture_Width; i+=4)
990     {
991       Y1 = *Y1_ptr++;
992       Y2 = *Y2_ptr++;
993       Cb1 = *Cb1_ptr++ >> 1;
994       Cr1 = *Cr1_ptr++ >> 1;
995       Cb2 = *Cb2_ptr++ >> 1;
996       Cr2 = *Cr2_ptr++ >> 1;
997       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+3]|Cb_Table[((Cb1+Cb2)>>1)+3]
998                                             |Cr_Table[((Cr1+Cr2)>>1)+3]];
999       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+15]|Cb_Table[((Cb1+3*Cb2)>>2)+15]
1000                                              |Cr_Table[((Cr1+3*Cr2)>>2)+15]];
1001 
1002       Y1 = *Y1_ptr++;
1003       Y2 = *Y2_ptr++;
1004       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+11]|Cb_Table[((Cb1+Cb2)>>1)+11]
1005                                              |Cr_Table[((Cr1+Cr2)>>1)+11]];
1006       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+7]|Cb_Table[((Cb1+3*Cb2)>>2)+7]
1007                                             |Cr_Table[((Cr1+3*Cr2)>>2)+7]];
1008 
1009       Y1 = *Y1_ptr++;
1010       Y2 = *Y2_ptr++;
1011       Cb1 = *Cb1_ptr++ >> 1;
1012       Cr1 = *Cr1_ptr++ >> 1;
1013       Cb2 = *Cb2_ptr++ >> 1;
1014       Cr2 = *Cr2_ptr++ >> 1;
1015       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+1]|Cb_Table[((Cb1+Cb2)>>1)+1]
1016                                             |Cr_Table[((Cr1+Cr2)>>1)+1]];
1017       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+13]|Cb_Table[((Cb1+3*Cb2)>>2)+13]
1018                                              |Cr_Table[((Cr1+3*Cr2)>>2)+13]];
1019 
1020       Y1 = *Y1_ptr++;
1021       Y2 = *Y2_ptr++;
1022       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+9]|Cb_Table[((Cb1+Cb2)>>1)+9]
1023                                             |Cr_Table[((Cr1+Cr2)>>1)+9]];
1024       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+5]|Cb_Table[((Cb1+3*Cb2)>>2)+5]
1025                                             |Cr_Table[((Cr1+3*Cr2)>>2)+5]];
1026     }
1027 
1028     Y1_ptr += Coded_Picture_Width;
1029     Y2_ptr += Coded_Picture_Width;
1030     Cb1_ptr += Chroma_Width;
1031     Cr1_ptr += Chroma_Width;
1032     if (j!=(Coded_Picture_Height-8))
1033     {
1034       Cb2_ptr += Chroma_Width;
1035       Cr2_ptr += Chroma_Width;
1036     }
1037     else
1038     {
1039       Cb2_ptr -= Chroma_Width;
1040       Cr2_ptr -= Chroma_Width;
1041     }
1042     dst += Coded_Picture_Width;
1043     dst2+= Coded_Picture_Width;
1044   }
1045 }
1046 
Dither_Bottom_Field420(src,dst)1047 static void Dither_Bottom_Field420(src,dst)
1048 unsigned char *src[];
1049 unsigned char *dst;
1050 {
1051   int i,j;
1052   int Y1,Cb1,Cr1,Y2,Cb2,Cr2;
1053   unsigned char *Y1_ptr,*Cb1_ptr,*Cr1_ptr,*Y2_ptr,*Cb2_ptr,*Cr2_ptr,*dst2;
1054 
1055   Y2_ptr = Y1_ptr = src[0] + Coded_Picture_Width;
1056   Cb2_ptr = Cb1_ptr = src[1] + Chroma_Width;
1057   Cr2_ptr = Cr1_ptr = src[2] + Chroma_Width;
1058 
1059   dst2 = dst;
1060 
1061   for (j=0; j<Coded_Picture_Height; j+=4)
1062   {
1063     /* line j + 0, j + 1 */
1064     for (i=0; i<Coded_Picture_Width; i+=4)
1065     {
1066       Y1 = *Y1_ptr++;
1067       Y2 = *Y2_ptr++;
1068       Cb1 = *Cb1_ptr++ >> 1;
1069       Cr1 = *Cr1_ptr++ >> 1;
1070       Cb2 = *Cb2_ptr++ >> 1;
1071       Cr2 = *Cr2_ptr++ >> 1;
1072       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+15]|Cb_Table[((3*Cb1+Cb2)>>2)+15]
1073                                              |Cr_Table[((3*Cr1+Cr2)>>2)+15]];
1074       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)]|Cb_Table[((Cb1+Cb2)>>1)]
1075                                           |Cr_Table[((Cr1+Cr2)>>1)]];
1076 
1077       Y1 = *Y1_ptr++;
1078       Y2 = *Y2_ptr++;
1079       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+7]|Cb_Table[((3*Cb1+Cb2)>>2)+7]
1080                                             |Cr_Table[((3*Cr1+Cr2)>>2)+7]];
1081       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+8]|Cb_Table[((Cb1+Cb2)>>1)+8]
1082                                             |Cr_Table[((Cr1+Cr2)>>1)+8]];
1083 
1084       Y1 = *Y1_ptr++;
1085       Y2 = *Y2_ptr++;
1086       Cb1 = *Cb1_ptr++ >> 1;
1087       Cr1 = *Cr1_ptr++ >> 1;
1088       Cb2 = *Cb2_ptr++ >> 1;
1089       Cr2 = *Cr2_ptr++ >> 1;
1090       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+13]|Cb_Table[((3*Cb1+Cb2)>>2)+13]
1091                                              |Cr_Table[((3*Cr1+Cr2)>>2)+13]];
1092       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+2]|Cb_Table[((Cb1+Cb2)>>1)+2]
1093                                             |Cr_Table[((Cr1+Cr2)>>1)+2]];
1094 
1095       Y1 = *Y1_ptr++;
1096       Y2 = *Y2_ptr++;
1097       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+5]|Cb_Table[((3*Cb1+Cb2)>>2)+5]
1098                                             |Cr_Table[((3*Cr1+Cr2)>>2)+5]];
1099       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+10]|Cb_Table[((Cb1+Cb2)>>1)+10]
1100                                              |Cr_Table[((Cr1+Cr2)>>1)+10]];
1101     }
1102 
1103     if (j!=0)
1104       Y1_ptr += Coded_Picture_Width;
1105     else
1106       Y1_ptr -= Coded_Picture_Width;
1107 
1108     Y2_ptr += Coded_Picture_Width;
1109 
1110     Cb1_ptr -= Chroma_Width;
1111     Cr1_ptr -= Chroma_Width;
1112     Cb2_ptr -= Chroma_Width;
1113     Cr2_ptr -= Chroma_Width;
1114 
1115     if (j!=0)
1116       dst  += Coded_Picture_Width;
1117 
1118     dst2 += Coded_Picture_Width;
1119 
1120     /* line j + 2, j + 3 */
1121     for (i=0; i<Coded_Picture_Width; i+=4)
1122     {
1123       Y1 = *Y1_ptr++;
1124       Y2 = *Y2_ptr++;
1125       Cb1 = *Cb1_ptr++ >> 1;
1126       Cr1 = *Cr1_ptr++ >> 1;
1127       Cb2 = *Cb2_ptr++ >> 1;
1128       Cr2 = *Cr2_ptr++ >> 1;
1129       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+12]|Cb_Table[((Cb1+3*Cb2)>>2)+12]
1130                                              |Cr_Table[((Cr1+3*Cr2)>>2)+12]];
1131       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+3]|Cb_Table[Cb2+3]
1132                                             |Cr_Table[Cr2+3]];
1133 
1134       Y1 = *Y1_ptr++;
1135       Y2 = *Y2_ptr++;
1136       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+4]|Cb_Table[((Cb1+3*Cb2)>>2)+4]
1137                                             |Cr_Table[((Cr1+3*Cr2)>>2)+4]];
1138       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+11]|Cb_Table[Cb2+11]
1139                                              |Cr_Table[Cr2+11]];
1140 
1141       Y1 = *Y1_ptr++;
1142       Y2 = *Y2_ptr++;
1143       Cb1 = *Cb1_ptr++ >> 1;
1144       Cr1 = *Cr1_ptr++ >> 1;
1145       Cb2 = *Cb2_ptr++ >> 1;
1146       Cr2 = *Cr2_ptr++ >> 1;
1147       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+14]|Cb_Table[((Cb1+3*Cb2)>>2)+14]
1148                                              |Cr_Table[((Cr1+3*Cr2)>>2)+14]];
1149       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+1]|Cb_Table[Cb2+1]
1150                                             |Cr_Table[Cr2+1]];
1151 
1152       Y1 = *Y1_ptr++;
1153       Y2 = *Y2_ptr++;
1154       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+6]|Cb_Table[((Cb1+3*Cb2)>>2)+6]
1155                                             |Cr_Table[((Cr1+3*Cr2)>>2)+6]];
1156       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+9]|Cb_Table[Cb2+9]
1157                                             |Cr_Table[Cr2+9]];
1158     }
1159 
1160     Y1_ptr += Coded_Picture_Width;
1161     Y2_ptr += Coded_Picture_Width;
1162 
1163     if (j!=0)
1164     {
1165       Cb1_ptr += Chroma_Width;
1166       Cr1_ptr += Chroma_Width;
1167     }
1168     else
1169     {
1170       Cb1_ptr -= Chroma_Width;
1171       Cr1_ptr -= Chroma_Width;
1172     }
1173 
1174     Cb2_ptr += Chroma_Width;
1175     Cr2_ptr += Chroma_Width;
1176 
1177     dst += Coded_Picture_Width;
1178     dst2+= Coded_Picture_Width;
1179   }
1180 
1181   Y2_ptr -= (Coded_Picture_Width<<1);
1182   Cb2_ptr -= (Chroma_Width<<1);
1183   Cr2_ptr -= (Chroma_Width<<1);
1184 
1185   /* dither last line */
1186   for (i=0; i<Coded_Picture_Width; i+=4)
1187   {
1188     Y1 = *Y1_ptr++;
1189     Y2 = *Y2_ptr++;
1190     Cb1 = *Cb1_ptr++ >> 1;
1191     Cr1 = *Cr1_ptr++ >> 1;
1192     Cb2 = *Cb2_ptr++ >> 1;
1193     Cr2 = *Cr2_ptr++ >> 1;
1194     *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+15]|Cb_Table[((3*Cb1+Cb2)>>2)+15]
1195                                            |Cr_Table[((3*Cr1+Cr2)>>2)+15]];
1196 
1197     Y1 = *Y1_ptr++;
1198     Y2 = *Y2_ptr++;
1199     *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+7]|Cb_Table[((3*Cb1+Cb2)>>2)+7]
1200                                           |Cr_Table[((3*Cr1+Cr2)>>2)+7]];
1201 
1202     Y1 = *Y1_ptr++;
1203     Y2 = *Y2_ptr++;
1204     Cb1 = *Cb1_ptr++ >> 1;
1205     Cr1 = *Cr1_ptr++ >> 1;
1206     Cb2 = *Cb2_ptr++ >> 1;
1207     Cr2 = *Cr2_ptr++ >> 1;
1208     *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+13]|Cb_Table[((3*Cb1+Cb2)>>2)+13]
1209                                            |Cr_Table[((3*Cr1+Cr2)>>2)+13]];
1210 
1211     Y1 = *Y1_ptr++;
1212     Y2 = *Y2_ptr++;
1213     *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+5]|Cb_Table[((3*Cb1+Cb2)>>2)+5]
1214                                           |Cr_Table[((3*Cr1+Cr2)>>2)+5]];
1215     }
1216 
1217 }
1218 #endif
1219