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