2436 lines
36 KiB
C
2436 lines
36 KiB
C
/* display.c, X11 interface */
|
|
|
|
|
|
|
|
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Disclaimer of Warranty
|
|
|
|
*
|
|
|
|
* These software programs are available to the user without any license fee or
|
|
|
|
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims
|
|
|
|
* any and all warranties, whether express, implied, or statuary, including any
|
|
|
|
* implied warranties or merchantability or of fitness for a particular
|
|
|
|
* purpose. In no event shall the copyright-holder be liable for any
|
|
|
|
* incidental, punitive, or consequential damages of any kind whatsoever
|
|
|
|
* arising from the use of these programs.
|
|
|
|
*
|
|
|
|
* This disclaimer of warranty extends to the user of these programs and user's
|
|
|
|
* customers, employees, agents, transferees, successors, and assigns.
|
|
|
|
*
|
|
|
|
* The MPEG Software Simulation Group does not represent or warrant that the
|
|
|
|
* programs furnished hereunder are free of infringement of any third-party
|
|
|
|
* patents.
|
|
|
|
*
|
|
|
|
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
|
|
|
|
* are subject to royalty fees to patent holders. Many of these patents are
|
|
|
|
* general enough such that they are unavoidable regardless of implementation
|
|
|
|
* design.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef DISPLAY
|
|
|
|
|
|
|
|
/* the Xlib interface is closely modeled after
|
|
|
|
* mpeg_play 2.0 by the Berkeley Plateau Research Group
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <X11/Xutil.h>
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
#include "global.h"
|
|
|
|
|
|
|
|
/* private prototypes */
|
|
|
|
static void Display_Image _ANSI_ARGS_((XImage *Ximage_Ptr, unsigned char *Dithered_Image));
|
|
|
|
static void Dither_Frame _ANSI_ARGS_((unsigned char *src[]));
|
|
|
|
static void Dither_Top_Field _ANSI_ARGS_((unsigned char *src[], unsigned char *dst));
|
|
|
|
static void Dither_Bottom_Field _ANSI_ARGS_((unsigned char *src[], unsigned char *dst));
|
|
|
|
static void Dither_Top_Field420 _ANSI_ARGS_((unsigned char *src[],
|
|
|
|
unsigned char *dst));
|
|
|
|
static void Dither_Bottom_Field420 _ANSI_ARGS_((unsigned char *src[],
|
|
|
|
unsigned char *dst));
|
|
|
|
|
|
|
|
/* local data */
|
|
|
|
static unsigned char *Dithered_Image, *Dithered_Image2;
|
|
|
|
|
|
|
|
static unsigned char Y_Table[256+16];
|
|
|
|
static unsigned char Cb_Table[128+16];
|
|
|
|
static unsigned char Cr_Table[128+16];
|
|
|
|
|
|
|
|
/* X11 related variables */
|
|
|
|
static Display *Display_Ptr;
|
|
|
|
static Window Window_Instance;
|
|
|
|
static GC GC_Instance;
|
|
|
|
static XImage *Ximage_Ptr, *Ximage_Ptr2;
|
|
|
|
static unsigned char Pixel[256];
|
|
|
|
|
|
|
|
#ifdef SH_MEM
|
|
|
|
|
|
|
|
#include <sys/ipc.h>
|
|
|
|
#include <sys/shm.h>
|
|
|
|
#include <X11/extensions/XShm.h>
|
|
|
|
|
|
|
|
static int HandleXError _ANSI_ARGS_((Display *dpy, XErrorEvent *event));
|
|
|
|
static void InstallXErrorHandler _ANSI_ARGS_((void));
|
|
|
|
static void DeInstallXErrorHandler _ANSI_ARGS_((void));
|
|
|
|
|
|
|
|
static int Shmem_Flag;
|
|
|
|
static XShmSegmentInfo Shminfo1, Shminfo2;
|
|
|
|
static int gXErrorFlag;
|
|
|
|
static int CompletionType = -1;
|
|
|
|
|
|
|
|
static int HandleXError(Dpy, Event)
|
|
|
|
Display *Dpy;
|
|
|
|
XErrorEvent *Event;
|
|
|
|
{
|
|
|
|
gXErrorFlag = 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void InstallXErrorHandler()
|
|
|
|
{
|
|
|
|
XSetErrorHandler(HandleXError);
|
|
|
|
XFlush(Display_Ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DeInstallXErrorHandler()
|
|
|
|
{
|
|
|
|
XSetErrorHandler(NULL);
|
|
|
|
XFlush(Display_Ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* connect to server, create and map window,
|
|
|
|
* allocate colors and (shared) memory
|
|
|
|
*/
|
|
|
|
void Initialize_Display_Process(name)
|
|
|
|
char *name;
|
|
|
|
{
|
|
|
|
int crv, cbu, cgu, cgv;
|
|
|
|
int Y, Cb, Cr, R, G, B;
|
|
|
|
int i;
|
|
|
|
char dummy;
|
|
|
|
int screen;
|
|
|
|
Colormap cmap;
|
|
|
|
int private;
|
|
|
|
XColor xcolor;
|
|
|
|
unsigned int fg, bg;
|
|
|
|
char *hello = "MPEG-2 Display";
|
|
|
|
XSizeHints hint;
|
|
|
|
XVisualInfo vinfo;
|
|
|
|
XEvent xev;
|
|
|
|
unsigned long tmp_pixel;
|
|
|
|
XWindowAttributes xwa;
|
|
|
|
|
|
|
|
Display_Ptr = XOpenDisplay(name);
|
|
|
|
|
|
|
|
if (Display_Ptr == NULL)
|
|
|
|
Error("Can not open display\n");
|
|
|
|
|
|
|
|
screen = DefaultScreen(Display_Ptr);
|
|
|
|
|
|
|
|
hint.x = 200;
|
|
|
|
hint.y = 200;
|
|
|
|
hint.width = horizontal_size;
|
|
|
|
hint.height = vertical_size;
|
|
|
|
hint.flags = PPosition | PSize;
|
|
|
|
|
|
|
|
/* Get some colors */
|
|
|
|
|
|
|
|
bg = WhitePixel (Display_Ptr, screen);
|
|
|
|
fg = BlackPixel (Display_Ptr, screen);
|
|
|
|
|
|
|
|
/* Make the window */
|
|
|
|
|
|
|
|
if (!XMatchVisualInfo(Display_Ptr, screen, 8, PseudoColor, &vinfo))
|
|
|
|
{
|
|
|
|
if (!XMatchVisualInfo(Display_Ptr, screen, 8, GrayScale, &vinfo))
|
|
|
|
Error("requires 8 bit display\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
Window_Instance = XCreateSimpleWindow (Display_Ptr, DefaultRootWindow (Display_Ptr),
|
|
|
|
hint.x, hint.y, hint.width, hint.height, 4, fg, bg);
|
|
|
|
|
|
|
|
XSelectInput(Display_Ptr, Window_Instance, StructureNotifyMask);
|
|
|
|
|
|
|
|
/* Tell other applications about this window */
|
|
|
|
|
|
|
|
XSetStandardProperties (Display_Ptr, Window_Instance, hello, hello, None, NULL, 0, &hint);
|
|
|
|
|
|
|
|
/* Map window. */
|
|
|
|
|
|
|
|
XMapWindow(Display_Ptr, Window_Instance);
|
|
|
|
|
|
|
|
/* Wait for map. */
|
|
|
|
do
|
|
|
|
{
|
|
|
|
XNextEvent(Display_Ptr, &xev);
|
|
|
|
}
|
|
|
|
while (xev.type != MapNotify || xev.xmap.event != Window_Instance);
|
|
|
|
|
|
|
|
XSelectInput(Display_Ptr, Window_Instance, NoEventMask);
|
|
|
|
|
|
|
|
/* matrix coefficients */
|
|
|
|
crv = Inverse_Table_6_9[matrix_coefficients][0];
|
|
|
|
cbu = Inverse_Table_6_9[matrix_coefficients][1];
|
|
|
|
cgu = Inverse_Table_6_9[matrix_coefficients][2];
|
|
|
|
cgv = Inverse_Table_6_9[matrix_coefficients][3];
|
|
|
|
|
|
|
|
/* allocate colors */
|
|
|
|
|
|
|
|
GC_Instance = DefaultGC(Display_Ptr, screen);
|
|
|
|
cmap = DefaultColormap(Display_Ptr, screen);
|
|
|
|
private = 0;
|
|
|
|
|
|
|
|
/* color allocation:
|
|
|
|
* i is the (internal) 8 bit color number, it consists of separate
|
|
|
|
* bit fields for Y, U and V: i = (yyyyuuvv), we don't use yyyy=0000
|
|
|
|
* and yyyy=1111, this leaves 32 colors for other applications
|
|
|
|
*
|
|
|
|
* the allocated colors correspond to the following Y, U and V values:
|
|
|
|
* Y: 24, 40, 56, 72, 88, 104, 120, 136, 152, 168, 184, 200, 216, 232
|
|
|
|
* U,V: -48, -16, 16, 48
|
|
|
|
*
|
|
|
|
* U and V values span only about half the color space; this gives
|
|
|
|
* usually much better quality, although highly saturated colors can
|
|
|
|
* not be displayed properly
|
|
|
|
*
|
|
|
|
* translation to R,G,B is implicitly done by the color look-up table
|
|
|
|
*/
|
|
|
|
for (i=16; i<240; i++)
|
|
|
|
{
|
|
|
|
/* color space conversion */
|
|
|
|
Y = 16*((i>>4)&15) + 8;
|
|
|
|
Cb = 32*((i>>2)&3) - 48;
|
|
|
|
Cr = 32*(i&3) - 48;
|
|
|
|
|
|
|
|
Y = 76309 * (Y - 16); /* (255/219)*65536 */
|
|
|
|
|
|
|
|
R = Clip[(Y + crv*Cr + 32768)>>16];
|
|
|
|
G = Clip[(Y - cgu*Cb - cgv*Cr + 32768)>>16];
|
|
|
|
B = Clip[(Y + cbu*Cb + 32786)>>16];
|
|
|
|
|
|
|
|
/* X11 colors are 16 bit */
|
|
|
|
xcolor.red = R << 8;
|
|
|
|
xcolor.green = G << 8;
|
|
|
|
xcolor.blue = B << 8;
|
|
|
|
|
|
|
|
if (XAllocColor(Display_Ptr, cmap, &xcolor) != 0)
|
|
|
|
Pixel[i] = xcolor.pixel;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* allocation failed, have to use a private colormap */
|
|
|
|
|
|
|
|
if (private)
|
|
|
|
Error("Couldn't allocate private colormap");
|
|
|
|
|
|
|
|
private = 1;
|
|
|
|
|
|
|
|
if (!Quiet_Flag)
|
|
|
|
fprintf(stderr, "Using private colormap (%d colors were available).\n",
|
|
|
|
i-16);
|
|
|
|
|
|
|
|
/* Free colors. */
|
|
|
|
while (--i >= 16)
|
|
|
|
{
|
|
|
|
tmp_pixel = Pixel[i]; /* because XFreeColors expects unsigned long */
|
|
|
|
XFreeColors(Display_Ptr, cmap, &tmp_pixel, 1, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* i is now 15, this restarts the outer loop */
|
|
|
|
|
|
|
|
/* create private colormap */
|
|
|
|
|
|
|
|
XGetWindowAttributes(Display_Ptr, Window_Instance, &xwa);
|
|
|
|
cmap = XCreateColormap(Display_Ptr, Window_Instance, xwa.visual, AllocNone);
|
|
|
|
XSetWindowColormap(Display_Ptr, Window_Instance, cmap);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef SH_MEM
|
|
|
|
if (XShmQueryExtension(Display_Ptr))
|
|
|
|
Shmem_Flag = 1;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Shmem_Flag = 0;
|
|
|
|
if (!Quiet_Flag)
|
|
|
|
fprintf(stderr, "Shared memory not supported\nReverting to normal Xlib\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Shmem_Flag)
|
|
|
|
CompletionType = XShmGetEventBase(Display_Ptr) + ShmCompletion;
|
|
|
|
|
|
|
|
InstallXErrorHandler();
|
|
|
|
|
|
|
|
if (Shmem_Flag)
|
|
|
|
{
|
|
|
|
|
|
|
|
Ximage_Ptr = XShmCreateImage(Display_Ptr, None, 8, ZPixmap, NULL,
|
|
|
|
&Shminfo1,
|
|
|
|
Coded_Picture_Width, Coded_Picture_Height);
|
|
|
|
|
|
|
|
if (!progressive_sequence)
|
|
|
|
Ximage_Ptr2 = XShmCreateImage(Display_Ptr, None, 8, ZPixmap, NULL,
|
|
|
|
&Shminfo2,
|
|
|
|
Coded_Picture_Width, Coded_Picture_Height);
|
|
|
|
|
|
|
|
/* If no go, then revert to normal Xlib calls. */
|
|
|
|
|
|
|
|
if (Ximage_Ptr==NULL || (!progressive_sequence && Ximage_Ptr2==NULL))
|
|
|
|
{
|
|
|
|
if (Ximage_Ptr!=NULL)
|
|
|
|
XDestroyImage(Ximage_Ptr);
|
|
|
|
if (!progressive_sequence && Ximage_Ptr2!=NULL)
|
|
|
|
XDestroyImage(Ximage_Ptr2);
|
|
|
|
if (!Quiet_Flag)
|
|
|
|
fprintf(stderr, "Shared memory error, disabling (Ximage error)\n");
|
|
|
|
goto shmemerror;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Success here, continue. */
|
|
|
|
|
|
|
|
Shminfo1.shmid = shmget(IPC_PRIVATE,
|
|
|
|
Ximage_Ptr->bytes_per_line * Ximage_Ptr->height,
|
|
|
|
IPC_CREAT | 0777);
|
|
|
|
if (!progressive_sequence)
|
|
|
|
Shminfo2.shmid = shmget(IPC_PRIVATE,
|
|
|
|
Ximage_Ptr2->bytes_per_line * Ximage_Ptr2->height,
|
|
|
|
IPC_CREAT | 0777);
|
|
|
|
|
|
|
|
if (Shminfo1.shmid<0 || (!progressive_sequence && Shminfo2.shmid<0))
|
|
|
|
{
|
|
|
|
XDestroyImage(Ximage_Ptr);
|
|
|
|
if (!progressive_sequence)
|
|
|
|
XDestroyImage(Ximage_Ptr2);
|
|
|
|
if (!Quiet_Flag)
|
|
|
|
fprintf(stderr, "Shared memory error, disabling (seg id error)\n");
|
|
|
|
goto shmemerror;
|
|
|
|
}
|
|
|
|
|
|
|
|
Shminfo1.shmaddr = (char *) shmat(Shminfo1.shmid, 0, 0);
|
|
|
|
Shminfo2.shmaddr = (char *) shmat(Shminfo2.shmid, 0, 0);
|
|
|
|
|
|
|
|
if (Shminfo1.shmaddr==((char *) -1) ||
|
|
|
|
(!progressive_sequence && Shminfo2.shmaddr==((char *) -1)))
|
|
|
|
{
|
|
|
|
XDestroyImage(Ximage_Ptr);
|
|
|
|
if (Shminfo1.shmaddr!=((char *) -1))
|
|
|
|
shmdt(Shminfo1.shmaddr);
|
|
|
|
if (!progressive_sequence)
|
|
|
|
{
|
|
|
|
XDestroyImage(Ximage_Ptr2);
|
|
|
|
if (Shminfo2.shmaddr!=((char *) -1))
|
|
|
|
shmdt(Shminfo2.shmaddr);
|
|
|
|
}
|
|
|
|
if (!Quiet_Flag)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "Shared memory error, disabling (address error)\n");
|
|
|
|
}
|
|
|
|
goto shmemerror;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ximage_Ptr->data = Shminfo1.shmaddr;
|
|
|
|
Dithered_Image = (unsigned char *)Ximage_Ptr->data;
|
|
|
|
Shminfo1.readOnly = False;
|
|
|
|
XShmAttach(Display_Ptr, &Shminfo1);
|
|
|
|
if (!progressive_sequence)
|
|
|
|
{
|
|
|
|
Ximage_Ptr2->data = Shminfo2.shmaddr;
|
|
|
|
Dithered_Image2 = (unsigned char *)Ximage_Ptr2->data;
|
|
|
|
Shminfo2.readOnly = False;
|
|
|
|
XShmAttach(Display_Ptr, &Shminfo2);
|
|
|
|
}
|
|
|
|
|
|
|
|
XSync(Display_Ptr, False);
|
|
|
|
|
|
|
|
if (gXErrorFlag)
|
|
|
|
{
|
|
|
|
/* Ultimate failure here. */
|
|
|
|
XDestroyImage(Ximage_Ptr);
|
|
|
|
shmdt(Shminfo1.shmaddr);
|
|
|
|
if (!progressive_sequence)
|
|
|
|
{
|
|
|
|
XDestroyImage(Ximage_Ptr2);
|
|
|
|
shmdt(Shminfo2.shmaddr);
|
|
|
|
}
|
|
|
|
if (!Quiet_Flag)
|
|
|
|
fprintf(stderr, "Shared memory error, disabling.\n");
|
|
|
|
gXErrorFlag = 0;
|
|
|
|
goto shmemerror;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
shmctl(Shminfo1.shmid, IPC_RMID, 0);
|
|
|
|
if (!progressive_sequence)
|
|
|
|
shmctl(Shminfo2.shmid, IPC_RMID, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Quiet_Flag)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "Sharing memory.\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
shmemerror:
|
|
|
|
Shmem_Flag = 0;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
Ximage_Ptr = XCreateImage(Display_Ptr,None,8,ZPixmap,0,&dummy,
|
|
|
|
Coded_Picture_Width,Coded_Picture_Height,8,0);
|
|
|
|
|
|
|
|
if (!(Dithered_Image = (unsigned char *)malloc(Coded_Picture_Width*
|
|
|
|
Coded_Picture_Height)))
|
|
|
|
Error("malloc failed");
|
|
|
|
|
|
|
|
if (!progressive_sequence)
|
|
|
|
{
|
|
|
|
Ximage_Ptr2 = XCreateImage(Display_Ptr,None,8,ZPixmap,0,&dummy,
|
|
|
|
Coded_Picture_Width,Coded_Picture_Height,8,0);
|
|
|
|
|
|
|
|
if (!(Dithered_Image2 = (unsigned char *)malloc(Coded_Picture_Width*
|
|
|
|
Coded_Picture_Height)))
|
|
|
|
Error("malloc failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef SH_MEM
|
|
|
|
}
|
|
|
|
|
|
|
|
DeInstallXErrorHandler();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void Terminate_Display_Process()
|
|
|
|
{
|
|
|
|
#ifdef SH_MEM
|
|
|
|
if (Shmem_Flag)
|
|
|
|
{
|
|
|
|
XShmDetach(Display_Ptr, &Shminfo1);
|
|
|
|
XDestroyImage(Ximage_Ptr);
|
|
|
|
shmdt(Shminfo1.shmaddr);
|
|
|
|
if (!progressive_sequence)
|
|
|
|
{
|
|
|
|
XShmDetach(Display_Ptr, &Shminfo2);
|
|
|
|
XDestroyImage(Ximage_Ptr2);
|
|
|
|
shmdt(Shminfo2.shmaddr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Display_Image(Ximage_Ptr,Dithered_Image)
|
|
|
|
XImage *Ximage_Ptr;
|
|
|
|
unsigned char *Dithered_Image;
|
|
|
|
{
|
|
|
|
/* display dithered image */
|
|
|
|
#ifdef SH_MEM
|
|
|
|
if (Shmem_Flag)
|
|
|
|
{
|
|
|
|
XShmPutImage(Display_Ptr, Window_Instance, GC_Instance, Ximage_Ptr,
|
|
|
|
0, 0, 0, 0, Ximage_Ptr->width, Ximage_Ptr->height, True);
|
|
|
|
XFlush(Display_Ptr);
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
XEvent xev;
|
|
|
|
|
|
|
|
XNextEvent(Display_Ptr, &xev);
|
|
|
|
if (xev.type == CompletionType)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
Ximage_Ptr->data = (char *) Dithered_Image;
|
|
|
|
XPutImage(Display_Ptr, Window_Instance, GC_Instance, Ximage_Ptr, 0, 0, 0, 0, Ximage_Ptr->width, Ximage_Ptr->height);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Display_Second_Field()
|
|
|
|
{
|
|
|
|
Display_Image(Ximage_Ptr2,Dithered_Image2);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 4x4 ordered dither
|
|
|
|
*
|
|
|
|
* threshold pattern:
|
|
|
|
* 0 8 2 10
|
|
|
|
* 12 4 14 6
|
|
|
|
* 3 11 1 9
|
|
|
|
* 15 7 13 5
|
|
|
|
*/
|
|
|
|
|
|
|
|
void Initialize_Dither_Matrix()
|
|
|
|
{
|
|
|
|
int i, v;
|
|
|
|
|
|
|
|
for (i=-8; i<256+8; i++)
|
|
|
|
{
|
|
|
|
v = i>>4;
|
|
|
|
if (v<1)
|
|
|
|
v = 1;
|
|
|
|
else if (v>14)
|
|
|
|
v = 14;
|
|
|
|
Y_Table[i+8] = v<<4;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i=0; i<128+16; i++)
|
|
|
|
{
|
|
|
|
v = (i-40)>>4;
|
|
|
|
if (v<0)
|
|
|
|
v = 0;
|
|
|
|
else if (v>3)
|
|
|
|
v = 3;
|
|
|
|
Cb_Table[i] = v<<2;
|
|
|
|
Cr_Table[i] = v;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void dither(src)
|
|
|
|
unsigned char *src[];
|
|
|
|
{
|
|
|
|
/* should this test only the display flag, not progressive_sequence ? --CF */
|
|
|
|
/* CHANGE 95/05/13: progressive_sequence -> progressive_frame */
|
|
|
|
|
|
|
|
if( progressive_frame || Display_Progressive_Flag)
|
|
|
|
Dither_Frame(src);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((picture_structure==FRAME_PICTURE && top_field_first) || picture_structure==BOTTOM_FIELD)
|
|
|
|
{
|
|
|
|
/* top field first */
|
|
|
|
if (chroma_format==CHROMA420 && hiQdither)
|
|
|
|
{
|
|
|
|
Dither_Top_Field420(src,Dithered_Image);
|
|
|
|
Dither_Bottom_Field420(src,Dithered_Image2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Dither_Top_Field(src,Dithered_Image);
|
|
|
|
Dither_Bottom_Field(src,Dithered_Image2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* bottom field first */
|
|
|
|
if (chroma_format==CHROMA420 && hiQdither)
|
|
|
|
{
|
|
|
|
Dither_Bottom_Field420(src,Dithered_Image);
|
|
|
|
Dither_Top_Field420(src,Dithered_Image2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Dither_Bottom_Field(src,Dithered_Image);
|
|
|
|
Dither_Top_Field(src,Dithered_Image2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Display_Image(Ximage_Ptr,Dithered_Image);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Dither_Frame(src)
|
|
|
|
unsigned char *src[];
|
|
|
|
{
|
|
|
|
int i,j;
|
|
|
|
int y,u,v;
|
|
|
|
unsigned char *py,*pu,*pv,*dst;
|
|
|
|
|
|
|
|
py = src[0];
|
|
|
|
pu = src[1];
|
|
|
|
pv = src[2];
|
|
|
|
dst = Dithered_Image;
|
|
|
|
|
|
|
|
for (j=0; j<Coded_Picture_Height; j+=4)
|
|
|
|
{
|
|
|
|
/* line j + 0 */
|
|
|
|
for (i=0; i<Coded_Picture_Width; i+=4)
|
|
|
|
{
|
|
|
|
y = *py++;
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[y]|Cb_Table[u]|Cr_Table[v]];
|
|
|
|
y = *py++;
|
|
|
|
if (chroma_format==CHROMA444)
|
|
|
|
{
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
}
|
|
|
|
*dst++ = Pixel[Y_Table[y+8]|Cb_Table[u+8]|Cr_Table[v+8]];
|
|
|
|
y = *py++;
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[y+2]|Cb_Table[u+2]|Cr_Table[v+2]];
|
|
|
|
y = *py++;
|
|
|
|
if (chroma_format==CHROMA444)
|
|
|
|
{
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
}
|
|
|
|
*dst++ = Pixel[Y_Table[y+10]|Cb_Table[u+10]|Cr_Table[v+10]];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (chroma_format==CHROMA420)
|
|
|
|
{
|
|
|
|
pu -= Chroma_Width;
|
|
|
|
pv -= Chroma_Width;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* line j + 1 */
|
|
|
|
for (i=0; i<Coded_Picture_Width; i+=4)
|
|
|
|
{
|
|
|
|
y = *py++;
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[y+12]|Cb_Table[u+12]|Cr_Table[v+12]];
|
|
|
|
y = *py++;
|
|
|
|
if (chroma_format==CHROMA444)
|
|
|
|
{
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
}
|
|
|
|
*dst++ = Pixel[Y_Table[y+4]|Cb_Table[u+4]|Cr_Table[v+4]];
|
|
|
|
y = *py++;
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[y+14]|Cb_Table[u+14]|Cr_Table[v+14]];
|
|
|
|
y = *py++;
|
|
|
|
if (chroma_format==CHROMA444)
|
|
|
|
{
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
}
|
|
|
|
*dst++ = Pixel[Y_Table[y+6]|Cb_Table[u+6]|Cr_Table[v+6]];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* line j + 2 */
|
|
|
|
for (i=0; i<Coded_Picture_Width; i+=4)
|
|
|
|
{
|
|
|
|
y = *py++;
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[y+3]|Cb_Table[u+3]|Cr_Table[v+3]];
|
|
|
|
y = *py++;
|
|
|
|
if (chroma_format==CHROMA444)
|
|
|
|
{
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
}
|
|
|
|
*dst++ = Pixel[Y_Table[y+11]|Cb_Table[u+11]|Cr_Table[v+11]];
|
|
|
|
y = *py++;
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[y+1]|Cb_Table[u+1]|Cr_Table[v+1]];
|
|
|
|
y = *py++;
|
|
|
|
if (chroma_format==CHROMA444)
|
|
|
|
{
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
}
|
|
|
|
*dst++ = Pixel[Y_Table[y+9]|Cb_Table[u+9]|Cr_Table[v+9]];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (chroma_format==CHROMA420)
|
|
|
|
{
|
|
|
|
pu -= Chroma_Width;
|
|
|
|
pv -= Chroma_Width;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* line j + 3 */
|
|
|
|
for (i=0; i<Coded_Picture_Width; i+=4)
|
|
|
|
{
|
|
|
|
y = *py++;
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[y+15]|Cb_Table[u+15]|Cr_Table[v+15]];
|
|
|
|
y = *py++;
|
|
|
|
if (chroma_format==CHROMA444)
|
|
|
|
{
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
}
|
|
|
|
*dst++ = Pixel[Y_Table[y+7]|Cb_Table[u+7]|Cr_Table[v+7]];
|
|
|
|
y = *py++;
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[y+13]|Cb_Table[u+13]|Cr_Table[v+13]];
|
|
|
|
y = *py++;
|
|
|
|
if (chroma_format==CHROMA444)
|
|
|
|
{
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
}
|
|
|
|
*dst++ = Pixel[Y_Table[y+5]|Cb_Table[u+5]|Cr_Table[v+5]];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Dither_Top_Field(src,dst)
|
|
|
|
unsigned char *src[];
|
|
|
|
unsigned char *dst;
|
|
|
|
{
|
|
|
|
int i,j;
|
|
|
|
int y,Y2,u,v;
|
|
|
|
unsigned char *py,*Y2_ptr,*pu,*pv,*dst2;
|
|
|
|
|
|
|
|
py = src[0];
|
|
|
|
Y2_ptr = src[0] + (Coded_Picture_Width<<1);
|
|
|
|
pu = src[1];
|
|
|
|
pv = src[2];
|
|
|
|
dst2 = dst + Coded_Picture_Width;
|
|
|
|
|
|
|
|
for (j=0; j<Coded_Picture_Height; j+=4)
|
|
|
|
{
|
|
|
|
/* line j + 0, j + 1 */
|
|
|
|
for (i=0; i<Coded_Picture_Width; i+=4)
|
|
|
|
{
|
|
|
|
y = *py++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[y]|Cb_Table[u]|Cr_Table[v]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((y+Y2)>>1)+12]|Cb_Table[u+12]|Cr_Table[v+12]];
|
|
|
|
|
|
|
|
y = *py++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
if (chroma_format==CHROMA444)
|
|
|
|
{
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
}
|
|
|
|
*dst++ = Pixel[Y_Table[y+8]|Cb_Table[u+8]|Cr_Table[v+8]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((y+Y2)>>1)+4]|Cb_Table[u+4]|Cr_Table[v+4]];
|
|
|
|
|
|
|
|
y = *py++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[y+2]|Cb_Table[u+2]|Cr_Table[v+2]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((y+Y2)>>1)+14]|Cb_Table[u+14]|Cr_Table[v+14]];
|
|
|
|
|
|
|
|
y = *py++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
if (chroma_format==CHROMA444)
|
|
|
|
{
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
}
|
|
|
|
*dst++ = Pixel[Y_Table[y+10]|Cb_Table[u+10]|Cr_Table[v+10]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((y+Y2)>>1)+6]|Cb_Table[u+6]|Cr_Table[v+6]];
|
|
|
|
}
|
|
|
|
|
|
|
|
py += Coded_Picture_Width;
|
|
|
|
|
|
|
|
if (j!=(Coded_Picture_Height-4))
|
|
|
|
Y2_ptr += Coded_Picture_Width;
|
|
|
|
else
|
|
|
|
Y2_ptr -= Coded_Picture_Width;
|
|
|
|
|
|
|
|
dst += Coded_Picture_Width;
|
|
|
|
dst2 += Coded_Picture_Width;
|
|
|
|
|
|
|
|
if (chroma_format==CHROMA420)
|
|
|
|
{
|
|
|
|
pu -= Chroma_Width;
|
|
|
|
pv -= Chroma_Width;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pu += Chroma_Width;
|
|
|
|
pv += Chroma_Width;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* line j + 2, j + 3 */
|
|
|
|
for (i=0; i<Coded_Picture_Width; i+=4)
|
|
|
|
{
|
|
|
|
y = *py++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[y+3]|Cb_Table[u+3]|Cr_Table[v+3]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((y+Y2)>>1)+15]|Cb_Table[u+15]|Cr_Table[v+15]];
|
|
|
|
|
|
|
|
y = *py++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
if (chroma_format==CHROMA444)
|
|
|
|
{
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
}
|
|
|
|
*dst++ = Pixel[Y_Table[y+11]|Cb_Table[u+11]|Cr_Table[v+11]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((y+Y2)>>1)+7]|Cb_Table[u+7]|Cr_Table[v+7]];
|
|
|
|
|
|
|
|
y = *py++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[y+1]|Cb_Table[u+1]|Cr_Table[v+1]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((y+Y2)>>1)+13]|Cb_Table[u+13]|Cr_Table[v+13]];
|
|
|
|
|
|
|
|
y = *py++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
if (chroma_format==CHROMA444)
|
|
|
|
{
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
}
|
|
|
|
*dst++ = Pixel[Y_Table[y+9]|Cb_Table[u+9]|Cr_Table[v+9]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((y+Y2)>>1)+5]|Cb_Table[u+5]|Cr_Table[v+5]];
|
|
|
|
}
|
|
|
|
|
|
|
|
py += Coded_Picture_Width;
|
|
|
|
Y2_ptr += Coded_Picture_Width;
|
|
|
|
dst += Coded_Picture_Width;
|
|
|
|
dst2 += Coded_Picture_Width;
|
|
|
|
pu += Chroma_Width;
|
|
|
|
pv += Chroma_Width;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Dither_Bottom_Field(src,dst)
|
|
|
|
unsigned char *src[];
|
|
|
|
unsigned char *dst;
|
|
|
|
{
|
|
|
|
int i,j;
|
|
|
|
int y,Y2,u,v;
|
|
|
|
unsigned char *py,*Y2_ptr,*pu,*pv,*dst2;
|
|
|
|
|
|
|
|
py = src[0] + Coded_Picture_Width;
|
|
|
|
Y2_ptr = py;
|
|
|
|
pu = src[1] + Chroma_Width;
|
|
|
|
pv = src[2] + Chroma_Width;
|
|
|
|
dst2 = dst + Coded_Picture_Width;
|
|
|
|
|
|
|
|
for (j=0; j<Coded_Picture_Height; j+=4)
|
|
|
|
{
|
|
|
|
/* line j + 0, j + 1 */
|
|
|
|
for (i=0; i<Coded_Picture_Width; i+=4)
|
|
|
|
{
|
|
|
|
y = *py++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[((y+Y2)>>1)]|Cb_Table[u]|Cr_Table[v]];
|
|
|
|
*dst2++ = Pixel[Y_Table[Y2+12]|Cb_Table[u+12]|Cr_Table[v+12]];
|
|
|
|
|
|
|
|
y = *py++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
if (chroma_format==CHROMA444)
|
|
|
|
{
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
}
|
|
|
|
*dst++ = Pixel[Y_Table[((y+Y2)>>1)+8]|Cb_Table[u+8]|Cr_Table[v+8]];
|
|
|
|
*dst2++ = Pixel[Y_Table[Y2+4]|Cb_Table[u+4]|Cr_Table[v+4]];
|
|
|
|
|
|
|
|
y = *py++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[((y+Y2)>>1)+2]|Cb_Table[u+2]|Cr_Table[v+2]];
|
|
|
|
*dst2++ = Pixel[Y_Table[Y2+14]|Cb_Table[u+14]|Cr_Table[v+14]];
|
|
|
|
|
|
|
|
y = *py++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
if (chroma_format==CHROMA444)
|
|
|
|
{
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
}
|
|
|
|
*dst++ = Pixel[Y_Table[((y+Y2)>>1)+10]|Cb_Table[u+10]|Cr_Table[v+10]];
|
|
|
|
*dst2++ = Pixel[Y_Table[Y2+6]|Cb_Table[u+6]|Cr_Table[v+6]];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (j==0)
|
|
|
|
py -= Coded_Picture_Width;
|
|
|
|
else
|
|
|
|
py += Coded_Picture_Width;
|
|
|
|
|
|
|
|
Y2_ptr += Coded_Picture_Width;
|
|
|
|
dst += Coded_Picture_Width;
|
|
|
|
dst2 += Coded_Picture_Width;
|
|
|
|
|
|
|
|
if (chroma_format==CHROMA420)
|
|
|
|
{
|
|
|
|
pu -= Chroma_Width;
|
|
|
|
pv -= Chroma_Width;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pu += Chroma_Width;
|
|
|
|
pv += Chroma_Width;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* line j + 2. j + 3 */
|
|
|
|
for (i=0; i<Coded_Picture_Width; i+=4)
|
|
|
|
{
|
|
|
|
y = *py++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[((y+Y2)>>1)+3]|Cb_Table[u+3]|Cr_Table[v+3]];
|
|
|
|
*dst2++ = Pixel[Y_Table[Y2+15]|Cb_Table[u+15]|Cr_Table[v+15]];
|
|
|
|
|
|
|
|
y = *py++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
if (chroma_format==CHROMA444)
|
|
|
|
{
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
}
|
|
|
|
*dst++ = Pixel[Y_Table[((y+Y2)>>1)+11]|Cb_Table[u+11]|Cr_Table[v+11]];
|
|
|
|
*dst2++ = Pixel[Y_Table[Y2+7]|Cb_Table[u+7]|Cr_Table[v+7]];
|
|
|
|
|
|
|
|
y = *py++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[((y+Y2)>>1)+1]|Cb_Table[u+1]|Cr_Table[v+1]];
|
|
|
|
*dst2++ = Pixel[Y_Table[Y2+13]|Cb_Table[u+13]|Cr_Table[v+13]];
|
|
|
|
|
|
|
|
y = *py++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
if (chroma_format==CHROMA444)
|
|
|
|
{
|
|
|
|
u = *pu++ >> 1;
|
|
|
|
v = *pv++ >> 1;
|
|
|
|
}
|
|
|
|
*dst++ = Pixel[Y_Table[((y+Y2)>>1)+9]|Cb_Table[u+9]|Cr_Table[v+9]];
|
|
|
|
*dst2++ = Pixel[Y_Table[Y2+5]|Cb_Table[u+5]|Cr_Table[v+5]];
|
|
|
|
}
|
|
|
|
|
|
|
|
py += Coded_Picture_Width;
|
|
|
|
Y2_ptr += Coded_Picture_Width;
|
|
|
|
dst += Coded_Picture_Width;
|
|
|
|
dst2 += Coded_Picture_Width;
|
|
|
|
pu += Chroma_Width;
|
|
|
|
pv += Chroma_Width;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Dither_Top_Field420(src,dst)
|
|
|
|
unsigned char *src[];
|
|
|
|
unsigned char *dst;
|
|
|
|
{
|
|
|
|
int i,j;
|
|
|
|
int Y1,Cb1,Cr1,Y2,Cb2,Cr2;
|
|
|
|
unsigned char *Y1_ptr,*Cb1_ptr,*Cr1_ptr,*Y2_ptr,*Cb2_ptr,*Cr2_ptr,*dst2;
|
|
|
|
|
|
|
|
Y1_ptr = src[0];
|
|
|
|
Cb1_ptr = src[1];
|
|
|
|
Cr1_ptr = src[2];
|
|
|
|
|
|
|
|
Y2_ptr = Y1_ptr + (Coded_Picture_Width<<1);
|
|
|
|
Cb2_ptr = Cb1_ptr + (Chroma_Width<<1);
|
|
|
|
Cr2_ptr = Cr1_ptr + (Chroma_Width<<1);
|
|
|
|
|
|
|
|
dst2 = dst + Coded_Picture_Width;
|
|
|
|
|
|
|
|
for (j=0; j<Coded_Picture_Height; j+=4)
|
|
|
|
{
|
|
|
|
/* line j + 0, j + 1 */
|
|
|
|
for (i=0; i<Coded_Picture_Width; i+=4)
|
|
|
|
{
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
Cb1 = *Cb1_ptr++ >> 1;
|
|
|
|
Cr1 = *Cr1_ptr++ >> 1;
|
|
|
|
Cb2 = *Cb2_ptr++ >> 1;
|
|
|
|
Cr2 = *Cr2_ptr++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)]|Cb_Table[Cb1]|Cr_Table[Cr1]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+12]|Cb_Table[((3*Cb1+Cb2)>>2)+12]
|
|
|
|
|Cr_Table[((3*Cr1+Cr2)>>2)+12]];
|
|
|
|
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+8]|Cb_Table[Cb1+8]|Cr_Table[Cr1+8]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+4]|Cb_Table[((3*Cb1+Cb2)>>2)+4]
|
|
|
|
|Cr_Table[((3*Cr1+Cr2)>>2)+4]];
|
|
|
|
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
Cb1 = *Cb1_ptr++ >> 1;
|
|
|
|
Cr1 = *Cr1_ptr++ >> 1;
|
|
|
|
Cb2 = *Cb2_ptr++ >> 1;
|
|
|
|
Cr2 = *Cr2_ptr++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+2]|Cb_Table[Cb1+2]|Cr_Table[Cr1+2]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+14]|Cb_Table[((3*Cb1+Cb2)>>2)+14]
|
|
|
|
|Cr_Table[((3*Cr1+Cr2)>>2)+14]];
|
|
|
|
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+10]|Cb_Table[Cb1+10]|Cr_Table[Cr1+10]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+6]|Cb_Table[((3*Cb1+Cb2)>>2)+6]
|
|
|
|
|Cr_Table[((3*Cr1+Cr2)>>2)+6]];
|
|
|
|
}
|
|
|
|
|
|
|
|
Y1_ptr += Coded_Picture_Width;
|
|
|
|
|
|
|
|
if (j!=(Coded_Picture_Height-4))
|
|
|
|
Y2_ptr += Coded_Picture_Width;
|
|
|
|
else
|
|
|
|
Y2_ptr -= Coded_Picture_Width;
|
|
|
|
|
|
|
|
Cb1_ptr -= Chroma_Width;
|
|
|
|
Cr1_ptr -= Chroma_Width;
|
|
|
|
Cb2_ptr -= Chroma_Width;
|
|
|
|
Cr2_ptr -= Chroma_Width;
|
|
|
|
|
|
|
|
dst += Coded_Picture_Width;
|
|
|
|
dst2 += Coded_Picture_Width;
|
|
|
|
|
|
|
|
/* line j + 2, j + 3 */
|
|
|
|
for (i=0; i<Coded_Picture_Width; i+=4)
|
|
|
|
{
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
Cb1 = *Cb1_ptr++ >> 1;
|
|
|
|
Cr1 = *Cr1_ptr++ >> 1;
|
|
|
|
Cb2 = *Cb2_ptr++ >> 1;
|
|
|
|
Cr2 = *Cr2_ptr++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+3]|Cb_Table[((Cb1+Cb2)>>1)+3]
|
|
|
|
|Cr_Table[((Cr1+Cr2)>>1)+3]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+15]|Cb_Table[((Cb1+3*Cb2)>>2)+15]
|
|
|
|
|Cr_Table[((Cr1+3*Cr2)>>2)+15]];
|
|
|
|
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+11]|Cb_Table[((Cb1+Cb2)>>1)+11]
|
|
|
|
|Cr_Table[((Cr1+Cr2)>>1)+11]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+7]|Cb_Table[((Cb1+3*Cb2)>>2)+7]
|
|
|
|
|Cr_Table[((Cr1+3*Cr2)>>2)+7]];
|
|
|
|
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
Cb1 = *Cb1_ptr++ >> 1;
|
|
|
|
Cr1 = *Cr1_ptr++ >> 1;
|
|
|
|
Cb2 = *Cb2_ptr++ >> 1;
|
|
|
|
Cr2 = *Cr2_ptr++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+1]|Cb_Table[((Cb1+Cb2)>>1)+1]
|
|
|
|
|Cr_Table[((Cr1+Cr2)>>1)+1]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+13]|Cb_Table[((Cb1+3*Cb2)>>2)+13]
|
|
|
|
|Cr_Table[((Cr1+3*Cr2)>>2)+13]];
|
|
|
|
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+9]|Cb_Table[((Cb1+Cb2)>>1)+9]
|
|
|
|
|Cr_Table[((Cr1+Cr2)>>1)+9]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+5]|Cb_Table[((Cb1+3*Cb2)>>2)+5]
|
|
|
|
|Cr_Table[((Cr1+3*Cr2)>>2)+5]];
|
|
|
|
}
|
|
|
|
|
|
|
|
Y1_ptr += Coded_Picture_Width;
|
|
|
|
Y2_ptr += Coded_Picture_Width;
|
|
|
|
Cb1_ptr += Chroma_Width;
|
|
|
|
Cr1_ptr += Chroma_Width;
|
|
|
|
if (j!=(Coded_Picture_Height-8))
|
|
|
|
{
|
|
|
|
Cb2_ptr += Chroma_Width;
|
|
|
|
Cr2_ptr += Chroma_Width;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Cb2_ptr -= Chroma_Width;
|
|
|
|
Cr2_ptr -= Chroma_Width;
|
|
|
|
}
|
|
|
|
dst += Coded_Picture_Width;
|
|
|
|
dst2+= Coded_Picture_Width;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Dither_Bottom_Field420(src,dst)
|
|
|
|
unsigned char *src[];
|
|
|
|
unsigned char *dst;
|
|
|
|
{
|
|
|
|
int i,j;
|
|
|
|
int Y1,Cb1,Cr1,Y2,Cb2,Cr2;
|
|
|
|
unsigned char *Y1_ptr,*Cb1_ptr,*Cr1_ptr,*Y2_ptr,*Cb2_ptr,*Cr2_ptr,*dst2;
|
|
|
|
|
|
|
|
Y2_ptr = Y1_ptr = src[0] + Coded_Picture_Width;
|
|
|
|
Cb2_ptr = Cb1_ptr = src[1] + Chroma_Width;
|
|
|
|
Cr2_ptr = Cr1_ptr = src[2] + Chroma_Width;
|
|
|
|
|
|
|
|
dst2 = dst;
|
|
|
|
|
|
|
|
for (j=0; j<Coded_Picture_Height; j+=4)
|
|
|
|
{
|
|
|
|
/* line j + 0, j + 1 */
|
|
|
|
for (i=0; i<Coded_Picture_Width; i+=4)
|
|
|
|
{
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
Cb1 = *Cb1_ptr++ >> 1;
|
|
|
|
Cr1 = *Cr1_ptr++ >> 1;
|
|
|
|
Cb2 = *Cb2_ptr++ >> 1;
|
|
|
|
Cr2 = *Cr2_ptr++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+15]|Cb_Table[((3*Cb1+Cb2)>>2)+15]
|
|
|
|
|Cr_Table[((3*Cr1+Cr2)>>2)+15]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)]|Cb_Table[((Cb1+Cb2)>>1)]
|
|
|
|
|Cr_Table[((Cr1+Cr2)>>1)]];
|
|
|
|
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+7]|Cb_Table[((3*Cb1+Cb2)>>2)+7]
|
|
|
|
|Cr_Table[((3*Cr1+Cr2)>>2)+7]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+8]|Cb_Table[((Cb1+Cb2)>>1)+8]
|
|
|
|
|Cr_Table[((Cr1+Cr2)>>1)+8]];
|
|
|
|
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
Cb1 = *Cb1_ptr++ >> 1;
|
|
|
|
Cr1 = *Cr1_ptr++ >> 1;
|
|
|
|
Cb2 = *Cb2_ptr++ >> 1;
|
|
|
|
Cr2 = *Cr2_ptr++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+13]|Cb_Table[((3*Cb1+Cb2)>>2)+13]
|
|
|
|
|Cr_Table[((3*Cr1+Cr2)>>2)+13]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+2]|Cb_Table[((Cb1+Cb2)>>1)+2]
|
|
|
|
|Cr_Table[((Cr1+Cr2)>>1)+2]];
|
|
|
|
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+5]|Cb_Table[((3*Cb1+Cb2)>>2)+5]
|
|
|
|
|Cr_Table[((3*Cr1+Cr2)>>2)+5]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+10]|Cb_Table[((Cb1+Cb2)>>1)+10]
|
|
|
|
|Cr_Table[((Cr1+Cr2)>>1)+10]];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (j!=0)
|
|
|
|
Y1_ptr += Coded_Picture_Width;
|
|
|
|
else
|
|
|
|
Y1_ptr -= Coded_Picture_Width;
|
|
|
|
|
|
|
|
Y2_ptr += Coded_Picture_Width;
|
|
|
|
|
|
|
|
Cb1_ptr -= Chroma_Width;
|
|
|
|
Cr1_ptr -= Chroma_Width;
|
|
|
|
Cb2_ptr -= Chroma_Width;
|
|
|
|
Cr2_ptr -= Chroma_Width;
|
|
|
|
|
|
|
|
if (j!=0)
|
|
|
|
dst += Coded_Picture_Width;
|
|
|
|
|
|
|
|
dst2 += Coded_Picture_Width;
|
|
|
|
|
|
|
|
/* line j + 2, j + 3 */
|
|
|
|
for (i=0; i<Coded_Picture_Width; i+=4)
|
|
|
|
{
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
Cb1 = *Cb1_ptr++ >> 1;
|
|
|
|
Cr1 = *Cr1_ptr++ >> 1;
|
|
|
|
Cb2 = *Cb2_ptr++ >> 1;
|
|
|
|
Cr2 = *Cr2_ptr++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+12]|Cb_Table[((Cb1+3*Cb2)>>2)+12]
|
|
|
|
|Cr_Table[((Cr1+3*Cr2)>>2)+12]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+3]|Cb_Table[Cb2+3]
|
|
|
|
|Cr_Table[Cr2+3]];
|
|
|
|
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+4]|Cb_Table[((Cb1+3*Cb2)>>2)+4]
|
|
|
|
|Cr_Table[((Cr1+3*Cr2)>>2)+4]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+11]|Cb_Table[Cb2+11]
|
|
|
|
|Cr_Table[Cr2+11]];
|
|
|
|
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
Cb1 = *Cb1_ptr++ >> 1;
|
|
|
|
Cr1 = *Cr1_ptr++ >> 1;
|
|
|
|
Cb2 = *Cb2_ptr++ >> 1;
|
|
|
|
Cr2 = *Cr2_ptr++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+14]|Cb_Table[((Cb1+3*Cb2)>>2)+14]
|
|
|
|
|Cr_Table[((Cr1+3*Cr2)>>2)+14]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+1]|Cb_Table[Cb2+1]
|
|
|
|
|Cr_Table[Cr2+1]];
|
|
|
|
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+6]|Cb_Table[((Cb1+3*Cb2)>>2)+6]
|
|
|
|
|Cr_Table[((Cr1+3*Cr2)>>2)+6]];
|
|
|
|
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+9]|Cb_Table[Cb2+9]
|
|
|
|
|Cr_Table[Cr2+9]];
|
|
|
|
}
|
|
|
|
|
|
|
|
Y1_ptr += Coded_Picture_Width;
|
|
|
|
Y2_ptr += Coded_Picture_Width;
|
|
|
|
|
|
|
|
if (j!=0)
|
|
|
|
{
|
|
|
|
Cb1_ptr += Chroma_Width;
|
|
|
|
Cr1_ptr += Chroma_Width;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Cb1_ptr -= Chroma_Width;
|
|
|
|
Cr1_ptr -= Chroma_Width;
|
|
|
|
}
|
|
|
|
|
|
|
|
Cb2_ptr += Chroma_Width;
|
|
|
|
Cr2_ptr += Chroma_Width;
|
|
|
|
|
|
|
|
dst += Coded_Picture_Width;
|
|
|
|
dst2+= Coded_Picture_Width;
|
|
|
|
}
|
|
|
|
|
|
|
|
Y2_ptr -= (Coded_Picture_Width<<1);
|
|
|
|
Cb2_ptr -= (Chroma_Width<<1);
|
|
|
|
Cr2_ptr -= (Chroma_Width<<1);
|
|
|
|
|
|
|
|
/* dither last line */
|
|
|
|
for (i=0; i<Coded_Picture_Width; i+=4)
|
|
|
|
{
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
Cb1 = *Cb1_ptr++ >> 1;
|
|
|
|
Cr1 = *Cr1_ptr++ >> 1;
|
|
|
|
Cb2 = *Cb2_ptr++ >> 1;
|
|
|
|
Cr2 = *Cr2_ptr++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+15]|Cb_Table[((3*Cb1+Cb2)>>2)+15]
|
|
|
|
|Cr_Table[((3*Cr1+Cr2)>>2)+15]];
|
|
|
|
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+7]|Cb_Table[((3*Cb1+Cb2)>>2)+7]
|
|
|
|
|Cr_Table[((3*Cr1+Cr2)>>2)+7]];
|
|
|
|
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
Cb1 = *Cb1_ptr++ >> 1;
|
|
|
|
Cr1 = *Cr1_ptr++ >> 1;
|
|
|
|
Cb2 = *Cb2_ptr++ >> 1;
|
|
|
|
Cr2 = *Cr2_ptr++ >> 1;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+13]|Cb_Table[((3*Cb1+Cb2)>>2)+13]
|
|
|
|
|Cr_Table[((3*Cr1+Cr2)>>2)+13]];
|
|
|
|
|
|
|
|
Y1 = *Y1_ptr++;
|
|
|
|
Y2 = *Y2_ptr++;
|
|
|
|
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+5]|Cb_Table[((3*Cb1+Cb2)>>2)+5]
|
|
|
|
|Cr_Table[((3*Cr1+Cr2)>>2)+5]];
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
#endif
|
|
|