]> git.sesse.net Git - vlc/commitdiff
Changement de l'API de vout (chroma_width)
authorVincent Seguin <seguin@videolan.org>
Tue, 18 Jan 2000 21:50:53 +0000 (21:50 +0000)
committerVincent Seguin <seguin@videolan.org>
Tue, 18 Jan 2000 21:50:53 +0000 (21:50 +0000)
Nettoyage des YUV.

Ne marche qu'en -g pour le moment, le reste arrive.

Makefile
include/config.h
include/video.h
include/video_output.h
include/video_yuv.h [new file with mode: 0644]
src/video_output/video_output.c
src/video_output/video_yuv.c [new file with mode: 0644]
src/video_output/video_yuv_c.c [deleted file]

index 50e8121f729b7f346cf6b12b9196684247d451e5..f2a4673dba9fbd09831498f1615d5e9f816d99c6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -22,7 +22,7 @@ VIDEO=X11
 
 # Target architecture and optimization
 #ARCH=
-ARCH=MMX
+#ARCH=MMX
 #ARCH=PPC
 
 # Decoder choice - ?? old decoder will be removed soon
@@ -174,7 +174,7 @@ audio_output_obj =          audio_output/audio_output.o \
 
 video_output_obj =             video_output/video_output.o \
                                                video_output/video_$(video).o \
-                                               video_output/video_yuv_c.o
+                                               video_output/video_yuv.o
 
 ac3_decoder_obj =              ac3_decoder/ac3_decoder.o \
                                                ac3_decoder/ac3_parse.o \
index d6b4da8ff1fe699cf94072c8121a18bd82408ea3..df44dd93aa44daef7946dfa82943a94a9e1ef921 100644 (file)
 /* Define to enable messages queues - disabling messages queue can be usefull
  * when debugging, since it allows messages which would not otherwise be printed,
  * due to a crash, to be printed anyway */
-#define INTF_MSG_QUEUE
+//#define INTF_MSG_QUEUE
 
 /* Format of the header for debug messages. The arguments following this header
  * are the file (char *), the function (char *) and the line (int) in which the
index 5288b626b8c5d432873e991377dd3af09651dfbb..2116df8dbd40b74a02d4024dcbf4fd749fdc4eb7 100644 (file)
@@ -32,11 +32,10 @@ typedef struct
     int             i_matrix_coefficients;       /* in YUV type, encoding type */    
     
     /* Picture static properties - those properties are fixed at initialization
-     * and should NOT be modified. Note that for YUV pictures, i_bytes_per_line
-     * has no signification and is replaced by i_width */
+     * and should NOT be modified */
     int             i_width;                                  /* picture width */
     int             i_height;                                /* picture height */
-    int             i_bytes_per_line;        /* total number of bytes per line */
+    int             i_chroma_width;                            /* chroma width */
 
     /* Picture dynamic properties - those properties can be changed by the 
      * decoder */
index ed833ea7517c7fc89d17c1c38133bbd656df68a7..c14da37f3a4f01ca94ec8b05c49334ddb6d03570 100644 (file)
@@ -7,6 +7,70 @@
  * thread, and destroy a previously oppenned video output thread.
  *******************************************************************************/
 
+/*******************************************************************************
+ * vout_tables_t: pre-calculated convertion tables
+ *******************************************************************************
+ * These tables are used by convertion and scaling functions.
+ *******************************************************************************/
+typedef struct vout_tables_s
+{
+    void *              p_base;             /* base for all translation tables */    
+    union 
+    {        
+        struct { u16 *p_red, *p_green, *p_blue; } rgb16;   /* color 15, 16 bpp */
+        struct { u32 *p_red, *p_green, *p_blue; } rgb32;   /* color 24, 32 bpp */
+        struct { u16 *p_gray; }                   gray16;   /* gray 15, 16 bpp */
+        struct { u32 *p_gray; }                   gray32;   /* gray 24, 32 bpp */
+    } yuv;    
+    void *              p_trans_optimized;     /* optimized (all colors) */      
+} vout_tables_t;
+
+/*******************************************************************************
+ * vout_convert_t: convertion function
+ *******************************************************************************
+ * This is the prototype common to all convertion functions. The type of p_pic
+ * will change depending of the screen depth treated.
+ * Parameters:
+ *      p_vout                  video output thread
+ *      p_pic                   picture address (start address in picture)
+ *      p_y, p_u, p_v           Y,U,V samples addresses
+ *      i_width                 Y samples width
+ *      i_height                Y samples height
+ *      i_eol                   number of Y samples to reach the next line 
+ *      i_pic_eol               number or pixels to reach the next line
+ *      i_scale                 if non 0, vertical scaling is 1 - 1/i_scale
+ * Conditions:
+ *      start x + i_width                        <  picture width
+ *      start y + i_height * (scaling factor)    <  picture height
+ *      i_width % 16                             == 0
+ *******************************************************************************/
+typedef void (vout_convert_t)( p_vout_thread_t p_vout, void *p_pic,
+                               yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                               int i_width, int i_height, int i_eol, int i_pic_eol,
+                               int i_scale );
+
+/*******************************************************************************
+ * vout_scale_t: scaling function
+ *******************************************************************************
+ * When a picture can't be scaled unsing the fast i_y_scale parameter of a
+ * transformation, it is rendered in a temporary buffer then scaled using a
+ * totally accurate (but also very slow) method.
+ * This is the prototype common to all scaling functions. The types of p_buffer
+ * and p_pic will change depending of the screen depth treated.
+ * Parameters:
+ *      p_vout                  video output thread
+ *      p_pic                   picture address (start address in picture)
+ *      p_buffer                source picture
+ *      i_width                 buffer width
+ *      i_height                buffer height
+ *      i_eol                   number of pixels to reach next buffer line
+ *      i_pic_eol               number of pixels to reach next picture line
+ *      f_alpha, f_beta         horizontal and vertical scaling factors
+ *******************************************************************************/
+typedef void (vout_scale_t)( p_vout_thread_t p_vout, void *p_pic, void *p_buffer, 
+                             int i_width, int i_height, int i_eol, int i_pic_eol,
+                             float f_alpha, float f_beta );
+
 /*******************************************************************************
  * vout_thread_t: video output thread descriptor
  *******************************************************************************
  *******************************************************************************/
 typedef struct vout_thread_s
 {
-    /* Thread properties and locks */
+    /* Thread properties and lock */
     boolean_t           b_die;                                   /* `die' flag */
     boolean_t           b_error;                               /* `error' flag */
     boolean_t           b_active;                             /* `active' flag */
     pthread_t           thread_id;                 /* id for pthread functions */
     pthread_mutex_t     lock;                                   /* thread lock */
     int *               pi_status;                    /* temporary status flag */
+    p_vout_sys_t        p_sys;                         /* system output method */
 
-    /* Common display properties */
+    /* Current display properties */
     boolean_t           b_info;              /* print additionnal informations */    
     boolean_t           b_grayscale;             /* color or grayscale display */    
     int                 i_width;                /* current output method width */
     int                 i_height;              /* current output method height */
     int                 i_bytes_per_line;/* bytes per line (including virtual) */    
-    int                 i_screen_depth;                      /* bits per pixel */
-    int                 i_bytes_per_pixel;                /* real screen depth */
+    int                 i_screen_depth;              /* bits per pixel - FIXED */
+    int                 i_bytes_per_pixel;        /* real screen depth - FIXED */
     float               f_x_ratio;                 /* horizontal display ratio */
     float               f_y_ratio;                   /* vertical display ratio */
     float               f_gamma;                                      /* gamma */    
 
     /* Changed properties values - some of them are treated directly by the
      * thread, the over may be ignored or handled by vout_SysManage */
+    //?? info, grayscale, width, height, bytes per line, x ratio, y ratio, gamma
     boolean_t           b_gamma_change;              /* gamma change indicator */    
     int                 i_new_width;                              /* new width */    
     int                 i_new_height;                            /* new height */    
 
 #ifdef STATS    
-    /* Statistics - these numbers are not supposed to be accurate */
+    /* Statistics - these numbers are not supposed to be accurate, but are a
+     * good indication of the thread status */
     count_t             c_loops;                            /* number of loops */
     count_t             c_idle_loops;                  /* number of idle loops */
     count_t             c_fps_samples;                       /* picture counts */    
@@ -51,25 +118,17 @@ typedef struct vout_thread_s
 #endif
 
 #ifdef DEBUG_VIDEO
-    /* Video debugging informations */
+    /* Additionnal video debugging informations */
     mtime_t             picture_render_time;    /* last picture rendering time */
 #endif
-
-    /* Output method */
-    p_vout_sys_t        p_sys;                         /* system output method */
-
-    /* Video heap */
+    /* Video heap and translation tables */
     picture_t           p_picture[VOUT_MAX_PICTURES];              /* pictures */
-
-    /* YUV translation tables - they have to be casted to the appropriate width 
-     * on use. All tables are allocated in the same memory block, based at
-     * p_trans_base, and shifted depending of the output thread configuration */
-    byte_t *            p_trans_base;       /* base for all translation tables */    
-    void *              p_trans_red;                            /* regular red */
-    void *              p_trans_green;                        /* regular green */
-    void *              p_trans_blue;                          /* regular blue */
-    void *              p_trans_gray;                          /* regular gray */
-    void *              p_trans_optimized;           /* optimized (all colors) */
+    vout_tables_t       tables;                          /* translation tables */
+    vout_convert_t *    p_ConvertYUV420;                /* YUV 4:2:0 converter */
+    vout_convert_t *    p_ConvertYUV422;                /* YUV 4:2:2 converter */
+    vout_convert_t *    p_ConvertYUV444;                /* YUV 4:4:4 converter */
+    vout_scale_t *      p_Scale;                                     /* scaler */
 } vout_thread_t;
 
 /*******************************************************************************
@@ -85,7 +144,7 @@ vout_thread_t * vout_CreateThread               (
 void            vout_DestroyThread              ( vout_thread_t *p_vout, int *pi_status );
 
 picture_t *     vout_CreatePicture              ( vout_thread_t *p_vout, int i_type, 
-                                                 int i_width, int i_height, int i_bytes_per_line );
+                                                 int i_width, int i_height );
 void            vout_DestroyPicture             ( vout_thread_t *p_vout, picture_t *p_pic );
 void            vout_DisplayPicture             ( vout_thread_t *p_vout, picture_t *p_pic );
 void            vout_LinkPicture                ( vout_thread_t *p_vout, picture_t *p_pic );
diff --git a/include/video_yuv.h b/include/video_yuv.h
new file mode 100644 (file)
index 0000000..4a80108
--- /dev/null
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * video_yuv.h: YUV transformation functions
+ * (c)1999 VideoLAN
+ *******************************************************************************
+ * Provides functions prototypes to perform the YUV conversion. The functions
+ * may be implemented in one of the video_yuv_* files.
+ *******************************************************************************/
+
+/*******************************************************************************
+ * Prototypes
+ *******************************************************************************/
+int             vout_InitTables      ( vout_thread_t *p_vout );
+int             vout_ResetTables     ( vout_thread_t *p_vout );
+void            vout_EndTables       ( vout_thread_t *p_vout );
+
index 5f586d9f404606943206c0cd84f5eba6555029e6..16ee39ea5d6496e5975076fa1fcb762c658523ea 100644 (file)
@@ -11,7 +11,6 @@
  * Preamble
  *******************************************************************************/
 #include <errno.h>
-#include <math.h> 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include "video.h"
 #include "video_output.h"
 #include "video_sys.h"
+#include "video_yuv.h"
 #include "intf_msg.h"
 #include "main.h"
 
-/*******************************************************************************
- * Macros
- *******************************************************************************/
-
-/* CLIP_BYTE: return value if between 0 and 255, else return nearest boundary 
- * (0 or 255), used to build translations tables */
-#define CLIP_BYTE( i_val ) ( (i_val < 0) ? 0 : ((i_val > 255) ? 255 : i_val) )
-
-/* YUV_GRAYSCALE: parametric macro for YUV grayscale transformation.
- * Due to the high performance need of this loop, all possible conditions 
- * evaluations are made outside the transformation loop. However, the code does 
- * not change much for two different loops. This macro allows to change slightly
- * the content of the loop without having to copy and paste code. It is used in 
- * RenderYUVPicture function. */
-#define YUV_GRAYSCALE( TRANS_GRAY, P_PIC )                              \
-/* Main loop */                                                         \
-for (i_pic_y=0; i_pic_y < p_pic->i_height ; i_pic_y++)                  \
-{                                                                       \
-    for (i_pic_x=0; i_pic_x< p_pic->i_width; i_pic_x+=16)               \
-    {                                                                   \
-        /* Convert 16 pixels (width is always multiple of 16 */         \
-        *P_PIC++ = TRANS_GRAY[ *p_y++ ];                                \
-        *P_PIC++ = TRANS_GRAY[ *p_y++ ];                                \
-        *P_PIC++ = TRANS_GRAY[ *p_y++ ];                                \
-        *P_PIC++ = TRANS_GRAY[ *p_y++ ];                                \
-        *P_PIC++ = TRANS_GRAY[ *p_y++ ];                                \
-        *P_PIC++ = TRANS_GRAY[ *p_y++ ];                                \
-        *P_PIC++ = TRANS_GRAY[ *p_y++ ];                                \
-        *P_PIC++ = TRANS_GRAY[ *p_y++ ];                                \
-        *P_PIC++ = TRANS_GRAY[ *p_y++ ];                                \
-        *P_PIC++ = TRANS_GRAY[ *p_y++ ];                                \
-        *P_PIC++ = TRANS_GRAY[ *p_y++ ];                                \
-        *P_PIC++ = TRANS_GRAY[ *p_y++ ];                                \
-        *P_PIC++ = TRANS_GRAY[ *p_y++ ];                                \
-        *P_PIC++ = TRANS_GRAY[ *p_y++ ];                                \
-        *P_PIC++ = TRANS_GRAY[ *p_y++ ];                                \
-        *P_PIC++ = TRANS_GRAY[ *p_y++ ];                                \
-    }                                                                   \
-    /* Skip until beginning of next line */                             \
-    P_PIC += i_eol_offset;                                              \
-}                                                                       
-
-/* YUV_TRANSFORM: parametric macro for YUV transformation.
- * Due to the high performance need of this loop, all possible conditions 
- * evaluations are made outside the transformation loop. However, the code does 
- * not change much for two different loops. This macro allows to change slightly
- * the content of the loop without having to copy and paste code. It is used in 
- * RenderYUVPicture function. */
-#define YUV_TRANSFORM( CHROMA, TRANS_RED, TRANS_GREEN, TRANS_BLUE, P_PIC ) \
-/* Main loop */                                                         \
-for (i_pic_y=0; i_pic_y < p_pic->i_height ; i_pic_y++)                  \
-{                                                                       \
-    for (i_pic_x=0; i_pic_x< p_pic->i_width; i_pic_x+=2 )               \
-    {                                                                   \
-        /* First sample (complete) */                                   \
-        i_y = 76309 * *p_y++ - 1188177;                                 \
-        i_u = *p_u++ - 128;                                             \
-        i_v = *p_v++ - 128;                                             \
-        *P_PIC++ =                                                      \
-            TRANS_RED   [(i_y+i_crv*i_v)                >>16] |         \
-            TRANS_GREEN [(i_y-i_cgu*i_u-i_cgv*i_v)      >>16] |         \
-            TRANS_BLUE  [(i_y+i_cbu*i_u)                >>16];          \
-        i_y = 76309 * *p_y++ - 1188177;                                 \
-        /* Second sample (partial) */                                   \
-        if( CHROMA == 444 )                                             \
-        {                                                               \
-            i_u = *p_u++ - 128;                                         \
-            i_v = *p_v++ - 128;                                         \
-        }                                                               \
-        *P_PIC++ =                                                      \
-            TRANS_RED   [(i_y+i_crv*i_v)                >>16] |         \
-            TRANS_GREEN [(i_y-i_cgu*i_u-i_cgv*i_v)      >>16] |         \
-            TRANS_BLUE  [(i_y+i_cbu*i_u)                >>16];          \
-    }                                                                   \
-    if( (CHROMA == 420) && !(i_pic_y & 0x1) )                           \
-    {                                                                   \
-        p_u -= i_chroma_width;                                          \
-        p_v -= i_chroma_width;                                          \
-    }                                                                   \
-    /* Skip until beginning of next line */                             \
-    P_PIC += i_eol_offset;                                              \
-}
-
-/*******************************************************************************
- * Constants
- *******************************************************************************/
-
-/* RGB/YUV inversion matrix (ISO/IEC 13818-2 section 6.3.6, table 6.9) */
-const int MATRIX_COEFFICIENTS_TABLE[8][4] =
-{
-  {117504, 138453, 13954, 34903},       /* no sequence_display_extension */
-  {117504, 138453, 13954, 34903},       /* ITU-R Rec. 709 (1990) */
-  {104597, 132201, 25675, 53279},       /* unspecified */
-  {104597, 132201, 25675, 53279},       /* reserved */
-  {104448, 132798, 24759, 53109},       /* FCC */
-  {104597, 132201, 25675, 53279},       /* ITU-R Rec. 624-4 System B, G */
-  {104597, 132201, 25675, 53279},       /* SMPTE 170M */
-  {117579, 136230, 16907, 35559}        /* SMPTE 240M (1987) */
-};
-
-/*******************************************************************************
- * External prototypes
- *******************************************************************************/
-#ifdef HAVE_MMX
-/* YUV transformations for MMX - in video_yuv_mmx.S 
- *      p_y, p_u, p_v:          Y U and V planes
- *      i_width, i_height:      frames dimensions (pixels)
- *      i_ypitch, i_vpitch:     Y and V lines sizes (bytes)
- *      i_aspect:               vertical aspect factor
- *      p_pic:                  RGB frame
- *      i_dci_offset:           ?? x offset for left image border
- *      i_offset_to_line_0:     ?? x offset for left image border
- *      i_pitch:                RGB line size (bytes)
- *      i_colortype:            0 for 565, 1 for 555 */
-void vout_YUV420_16_MMX( u8* p_y, u8* p_u, u8 *p_v, 
-                         unsigned int i_width, unsigned int i_height,
-                         unsigned int i_ypitch, unsigned int i_vpitch,
-                         unsigned int i_aspect, u8 *p_pic, 
-                         u32 i_dci_offset, u32 i_offset_to_line_0,
-                         int CCOPitch, int i_colortype );
-#endif
-
-/* Optimized YUV functions: translations and tables building - in video_yuv_c.c
- * ??? looks efficient, but does not work well - ask walken */
-void yuvToRgb16 ( unsigned char * Y,
-                       unsigned char * U, unsigned char * V,
-                  short * dest, short table[1935], int width);
-int rgbTable16 (short table [1935],
-                int redMask, int greenMask, int blueMask,
-                unsigned char gamma[256]);
-
-
 /*******************************************************************************
  * Local prototypes
  *******************************************************************************/
@@ -169,11 +37,7 @@ static int      InitThread              ( vout_thread_t *p_vout );
 static void     RunThread               ( vout_thread_t *p_vout );
 static void     ErrorThread             ( vout_thread_t *p_vout );
 static void     EndThread               ( vout_thread_t *p_vout );
-static void     BuildTables             ( vout_thread_t *p_vout );
 static void     RenderPicture           ( vout_thread_t *p_vout, picture_t *p_pic );
-static void     RenderYUVGrayPicture    ( vout_thread_t *p_vout, picture_t *p_pic );
-static void     RenderYUV16Picture      ( vout_thread_t *p_vout, picture_t *p_pic );
-static void     RenderYUV32Picture      ( vout_thread_t *p_vout, picture_t *p_pic );
 static void     RenderPictureInfo       ( vout_thread_t *p_vout, picture_t *p_pic );
 static int      RenderIdle              ( vout_thread_t *p_vout, int i_level );
 
@@ -203,8 +67,15 @@ vout_thread_t * vout_CreateThread               (
         return( NULL );
     }
 
+    /* Initialize thread properties */
+    p_vout->b_die               = 0;
+    p_vout->b_error             = 0;    
+    p_vout->b_active            = 0;
+    p_vout->pi_status           = (pi_status != NULL) ? pi_status : &i_status;
+    *p_vout->pi_status          = THREAD_CREATE;    
+
     /* Initialize some fields used by the system-dependant method - these fields will
-     * probably be modified by the method */
+     * probably be modified by the method, and are only preferences */
 #ifdef DEBUG
     p_vout->b_info              = 1;    
 #else
@@ -240,21 +111,18 @@ vout_thread_t * vout_CreateThread               (
                 p_vout->i_width, p_vout->i_height, p_vout->i_screen_depth,
                 p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line,
                 p_vout->f_x_ratio, p_vout->f_y_ratio, p_vout->b_grayscale );
-  
-    /* Terminate the initialization */
-    p_vout->b_die               = 0;
-    p_vout->b_error             = 0;    
-    p_vout->b_active            = 0;
-    p_vout->pi_status           = (pi_status != NULL) ? pi_status : &i_status;
-    *p_vout->pi_status          = THREAD_CREATE;    
+
+    /* Initialize changement properties */
+    p_vout->b_gamma_change      = 0;
+    p_vout->i_new_width         = p_vout->i_width;
+    p_vout->i_new_height        = p_vout->i_height; 
+
 #ifdef STATS
+    /* Initialize statistics fields */
     p_vout->c_loops             = 0;
     p_vout->c_idle_loops        = 0;
     p_vout->c_fps_samples       = 0;
 #endif      
-    p_vout->b_gamma_change      = 0;
-    p_vout->i_new_width         = p_vout->i_width;
-    p_vout->i_new_height        = p_vout->i_height;    
 
     /* Create thread and set locks */
     vlc_mutex_init( &p_vout->lock );
@@ -353,12 +221,13 @@ void  vout_DisplayPicture( vout_thread_t *p_vout, picture_t *p_pic )
  * This function create a reserved image in the video output heap. 
  * A null pointer is returned if the function fails. This method provides an
  * already allocated zone of memory in the picture data fields. It needs locking
- * since several pictures can be created by several producers threads.
+ * since several pictures can be created by several producers threads. 
  *******************************************************************************/
 picture_t *vout_CreatePicture( vout_thread_t *p_vout, int i_type, 
-                              int i_width, int i_height, int i_bytes_per_line )
+                              int i_width, int i_height )
 {
     int         i_picture;                                    /* picture index */
+    int         i_chroma_width;                                /* chroma width */    
     picture_t * p_free_picture = NULL;                   /* first free picture */    
     picture_t * p_destroyed_picture = NULL;         /* first destroyed picture */    
 
@@ -374,15 +243,16 @@ picture_t *vout_CreatePicture( vout_thread_t *p_vout, int i_type,
     {
        if( p_vout->p_picture[i_picture].i_status == DESTROYED_PICTURE )
        {
-           /* Picture is marked for destruction, but is still allocated */
+           /* Picture is marked for destruction, but is still allocated - note
+             * that if width and type are the same for two pictures, chroma_width 
+             * should also be the same */
            if( (p_vout->p_picture[i_picture].i_type           == i_type)   &&
                (p_vout->p_picture[i_picture].i_height         == i_height) &&
-               (p_vout->p_picture[i_picture].i_bytes_per_line == i_bytes_per_line) )
+               (p_vout->p_picture[i_picture].i_width          == i_width) )
            {
                /* Memory size do match : memory will not be reallocated, and function
                  * can end immediately - this is the best possible case, since no
                  * memory allocation needs to be done */
-               p_vout->p_picture[i_picture].i_width  = i_width;
                p_vout->p_picture[i_picture].i_status = RESERVED_PICTURE;
 #ifdef DEBUG_VIDEO
                 intf_DbgMsg("picture %p (in destroyed picture slot)\n", 
@@ -424,22 +294,25 @@ picture_t *vout_CreatePicture( vout_thread_t *p_vout, int i_type,
         switch( i_type )
         {
         case YUV_420_PICTURE:          /* YUV 420: 1,1/4,1/4 samples per pixel */
-            p_free_picture->p_data = malloc( i_height * i_bytes_per_line * 3 / 2 );
-            p_free_picture->p_y = (yuv_data_t *) p_free_picture->p_data;
-            p_free_picture->p_u = (yuv_data_t *)(p_free_picture->p_data + i_height * i_bytes_per_line);
-            p_free_picture->p_v = (yuv_data_t *)(p_free_picture->p_data + i_height * i_bytes_per_line * 5 / 4);
+            i_chroma_width = i_width / 4;            
+            p_free_picture->p_data = malloc( i_height * i_chroma_width * 6 * sizeof( yuv_data_t ) );
+            p_free_picture->p_y = (yuv_data_t *)p_free_picture->p_data;
+            p_free_picture->p_u = (yuv_data_t *)p_free_picture->p_data + i_height * i_chroma_width * 4;
+            p_free_picture->p_v = (yuv_data_t *)p_free_picture->p_data + i_height * i_chroma_width * 5;
             break;
         case YUV_422_PICTURE:          /* YUV 422: 1,1/2,1/2 samples per pixel */
-            p_free_picture->p_data = malloc( 2 * i_height * i_bytes_per_line );
-            p_free_picture->p_y = (yuv_data_t *) p_free_picture->p_data;
-            p_free_picture->p_u = (yuv_data_t *)(p_free_picture->p_data + i_height * i_bytes_per_line);
-            p_free_picture->p_v = (yuv_data_t *)(p_free_picture->p_data + i_height * i_bytes_per_line * 3 / 2);
+            i_chroma_width = i_width / 2;            
+            p_free_picture->p_data = malloc( i_height * i_chroma_width * 4 * sizeof( yuv_data_t ) );
+            p_free_picture->p_y = (yuv_data_t *)p_free_picture->p_data;
+            p_free_picture->p_u = (yuv_data_t *)p_free_picture->p_data + i_height * i_chroma_width * 2;
+            p_free_picture->p_v = (yuv_data_t *)p_free_picture->p_data + i_height * i_chroma_width * 3;
             break;
         case YUV_444_PICTURE:              /* YUV 444: 1,1,1 samples per pixel */
-            p_free_picture->p_data = malloc( 3 * i_height * i_bytes_per_line );                
-            p_free_picture->p_y = (yuv_data_t *) p_free_picture->p_data;
-            p_free_picture->p_u = (yuv_data_t *)(p_free_picture->p_data + i_height * i_bytes_per_line);
-            p_free_picture->p_v = (yuv_data_t *)(p_free_picture->p_data + i_height * i_bytes_per_line * 2);
+            i_chroma_width = i_width;            
+            p_free_picture->p_data = malloc( i_height * i_chroma_width * 3 * sizeof( yuv_data_t ) );
+            p_free_picture->p_y = (yuv_data_t *)p_free_picture->p_data;
+            p_free_picture->p_u = (yuv_data_t *)p_free_picture->p_data + i_height * i_chroma_width;
+            p_free_picture->p_v = (yuv_data_t *)p_free_picture->p_data + i_height * i_chroma_width * 2;
             break;                
 #ifdef DEBUG
         default:
@@ -451,14 +324,19 @@ picture_t *vout_CreatePicture( vout_thread_t *p_vout, int i_type,
 
         if( p_free_picture->p_data != NULL )
         {        
-            /* Copy picture informations */
+            /* Copy picture informations, set some default values */
             p_free_picture->i_type                      = i_type;
             p_free_picture->i_status                    = RESERVED_PICTURE;
+            p_free_picture->i_matrix_coefficients       = 1; 
             p_free_picture->i_width                     = i_width;
             p_free_picture->i_height                    = i_height;
-            p_free_picture->i_bytes_per_line            = i_bytes_per_line;
+            p_free_picture->i_chroma_width              = i_chroma_width;            
+            p_free_picture->i_display_horizontal_offset = 0;
+            p_free_picture->i_display_vertical_offset   = 0;            
+            p_free_picture->i_display_width             = i_width;
+            p_free_picture->i_display_height            = i_height;
+            p_free_picture->i_aspect_ratio              = AR_SQUARE_PICTURE;            
             p_free_picture->i_refcount                  = 0;            
-            p_free_picture->i_matrix_coefficients       = 1; 
         }
         else
         {
@@ -560,13 +438,6 @@ static int InitThread( vout_thread_t *p_vout )
 
     /* Update status */
     *p_vout->pi_status = THREAD_START;    
-    
-    /* Initialize pictures */    
-    for( i_index = 0; i_index < VOUT_MAX_PICTURES; i_index++)
-    {
-        p_vout->p_picture[i_index].i_type  = EMPTY_PICTURE;
-        p_vout->p_picture[i_index].i_status= FREE_PICTURE;
-    }
 
     /* Initialize output method - this function issues its own error messages */
     if( vout_SysInit( p_vout ) )
@@ -575,21 +446,19 @@ static int InitThread( vout_thread_t *p_vout )
         return( 1 );
     } 
 
-    /* Allocate translation tables */
-    p_vout->p_trans_base = malloc( ( 4 * 1024 + 1935 ) * p_vout->i_bytes_per_pixel );
-    if( p_vout->p_trans_base == NULL )
+    /* Initialize pictures */    
+    for( i_index = 0; i_index < VOUT_MAX_PICTURES; i_index++)
     {
-        intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+        p_vout->p_picture[i_index].i_type  = EMPTY_PICTURE;
+        p_vout->p_picture[i_index].i_status= FREE_PICTURE;
+    }
+
+    /* Initialize convertion tables and functions */
+    if( vout_InitTables( p_vout ) )
+    {
+        intf_ErrMsg("error: can't allocate translation tables\n");
         return( 1 );                
     }
-    p_vout->p_trans_red =       p_vout->p_trans_base +           384 *p_vout->i_bytes_per_pixel;
-    p_vout->p_trans_green =     p_vout->p_trans_base + (  1024 + 384)*p_vout->i_bytes_per_pixel;
-    p_vout->p_trans_blue =      p_vout->p_trans_base + (2*1024 + 384)*p_vout->i_bytes_per_pixel;
-    p_vout->p_trans_gray =      p_vout->p_trans_base + (3*1024 + 384)*p_vout->i_bytes_per_pixel;
-    p_vout->p_trans_optimized = p_vout->p_trans_base + (4*1024      )*p_vout->i_bytes_per_pixel;    
-    
-    /* Build translation tables */
-    BuildTables( p_vout );
     
     /* Mark thread as running and return */
     p_vout->b_active =          1;    
@@ -631,19 +500,19 @@ static void RunThread( vout_thread_t *p_vout)
      * initialization
      */
     while( (!p_vout->b_die) && (!p_vout->b_error) )
-    {
+    {            
         /* 
         * Find the picture to display - this operation does not need lock,
          * since only READY_PICTURES are handled 
          */
         p_pic = NULL;         
-       for( i_picture = 0; i_picture < VOUT_MAX_PICTURES; i_picture++ )
+        for( i_picture = 0; i_picture < VOUT_MAX_PICTURES; i_picture++ )
        {
            if( (p_vout->p_picture[i_picture].i_status == READY_PICTURE) &&
                ( (p_pic == NULL) || 
                  (p_vout->p_picture[i_picture].date < pic_date) ) )
            {
-               p_pic = &p_vout->p_picture[i_picture];
+                p_pic = &p_vout->p_picture[i_picture];
                 pic_date = p_pic->date;                
            }
        }
@@ -700,8 +569,9 @@ static void RunThread( vout_thread_t *p_vout)
          */
         if( p_vout->b_gamma_change )
         {
+            //??
             p_vout->b_gamma_change = 0;            
-            BuildTables( p_vout );            
+            vout_ResetTables( p_vout );            // ?? test return value
         }        
 
         /*
@@ -818,7 +688,7 @@ static void EndThread( vout_thread_t *p_vout )
     }
 
     /* Destroy translation tables */
-    free( p_vout->p_trans_base );
+    vout_EndTables( p_vout );
     
     /* Destroy thread structures allocated by InitThread */
     vout_SysEnd( p_vout );
@@ -829,81 +699,6 @@ static void EndThread( vout_thread_t *p_vout )
     *pi_status = THREAD_OVER;    
 }
 
-/*******************************************************************************
- * BuildTables: build YUV translation tables
- *******************************************************************************
- * This function will build translations tables according to pixel width and
- * gamma.
- *******************************************************************************/  
-static void BuildTables( vout_thread_t *p_vout )
-{
-    u16 *       p_trans16_red =         (u16 *) p_vout->p_trans_red;
-    u16 *       p_trans16_green =       (u16 *) p_vout->p_trans_green;
-    u16 *       p_trans16_blue =        (u16 *) p_vout->p_trans_blue;
-    u16 *       p_trans16_gray =        (u16 *) p_vout->p_trans_gray;
-    u32 *       p_trans32_red =         (u32 *) p_vout->p_trans_red;
-    u32 *       p_trans32_green =       (u32 *) p_vout->p_trans_green;
-    u32 *       p_trans32_blue =        (u32 *) p_vout->p_trans_blue;
-    u32 *       p_trans32_gray =        (u32 *) p_vout->p_trans_gray;          
-    u8          i_gamma[256];                                   /* gamma table */    
-    int         i_index;                                    /* index in tables */
-    
-    /* Build gamma table */     
-    for( i_index = 0; i_index < 256; i_index++ )
-    {
-        i_gamma[i_index] = 255. * pow( (double)i_index / 255., p_vout->f_gamma );        
-    }
-        
-    /* Build red, green, blue and gray tables */
-    switch( p_vout->i_screen_depth )
-    {
-    case 15:
-        for( i_index = -384; i_index < 640; i_index++) 
-        {
-            p_trans16_red[i_index]     = (i_gamma[CLIP_BYTE( i_index )] & 0xf8)<<7;
-            p_trans16_green[i_index]   = (i_gamma[CLIP_BYTE( i_index )] & 0xf8)<<2;
-            p_trans16_blue[i_index]    =  i_gamma[CLIP_BYTE( i_index )] >> 3;
-            p_trans16_gray[i_index]    = p_trans16_red[i_index] | 
-                p_trans16_green[i_index] | p_trans16_blue[i_index];            
-        }
-        break;        
-    case 16:
-        for( i_index = -384; i_index < 640; i_index++) 
-        {
-            p_trans16_red[i_index]     = (i_gamma[CLIP_BYTE( i_index )] & 0xf8)<<8;
-            p_trans16_green[i_index]   = (i_gamma[CLIP_BYTE( i_index )] & 0xfc)<<3;
-            p_trans16_blue[i_index]    =  i_gamma[CLIP_BYTE( i_index )] >> 3;
-            p_trans16_gray[i_index]    = p_trans16_red[i_index] |
-                p_trans16_green[i_index] | p_trans16_blue[i_index];
-        }        
-        break;        
-    case 32:        
-        for( i_index = -384; i_index < 640; i_index++) 
-        {
-            p_trans32_red[i_index]     = i_gamma[CLIP_BYTE( i_index )] <<16;
-            p_trans32_green[i_index]   = i_gamma[CLIP_BYTE( i_index )] <<8;
-            p_trans32_blue[i_index]    = i_gamma[CLIP_BYTE( i_index )] ;
-            p_trans32_gray[i_index]    = p_trans32_red[i_index] |
-                p_trans32_green[i_index] | p_trans32_blue[i_index];
-        }
-        break;        
-#ifdef DEBUG
-    default:
-        intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
-        break;      
-#endif
-    } 
-
-    /* Build red, green and blue tables for optimized transformation */
-    //????
-    switch( p_vout->i_screen_depth )
-    {
-    case 16:
-        rgbTable16( (short *) p_vout->p_trans_optimized, 0xf800, 0x07e0, 0x01f, i_gamma );
-        break;        
-    }    
-}
-
 /*******************************************************************************
  * RenderPicture: render a picture
  *******************************************************************************
@@ -911,19 +706,18 @@ static void BuildTables( vout_thread_t *p_vout )
  * and copy it to the current rendering buffer. No lock is required, since the
  * rendered picture has been determined as existant, and will only be destroyed
  * by the vout thread later.
- * ???? 24 and 32 bpp should probably be separated
  *******************************************************************************/
 static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
 {
 #ifdef DEBUG_VIDEO
-    /* Send picture informations */
+    /* Send picture informations and store rendering start date */
     intf_DbgMsg("picture %p\n", p_pic );
-
-    /* Store rendering start date */
     p_vout->picture_render_time = mdate();    
 #endif
 
-    /* Change aspect ratio or resize frame to fit frame */
+    /* 
+     * Prepare scaling 
+     */
     if( (p_pic->i_width > p_vout->i_width) || (p_pic->i_height > p_vout->i_height) )
     {
 #ifdef VIDEO_X11
@@ -940,25 +734,33 @@ static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
 #endif
     }    
 
-    /* Choose appropriate rendering function */
+    /*
+     * Choose appropriate rendering function and render picture
+     */
     switch( p_pic->i_type )
     {
-    case YUV_420_PICTURE:                   /* YUV picture: YUV transformation */        
+    case YUV_420_PICTURE:
+        p_vout->p_ConvertYUV420( p_vout, vout_SysGetPicture( p_vout ),
+                                 p_pic->p_y, p_pic->p_u, p_pic->p_v,
+                                 p_pic->i_width, p_pic->i_height, 0, 0,
+                                 4 );
+        break;        
     case YUV_422_PICTURE:
+/*     ???   p_vout->p_convert_yuv_420( p_vout, 
+                                   p_pic->p_y, p_pic->p_u, p_pic->p_v,
+                                   i_chroma_width, i_chroma_height,
+                                   p_vout->i_width / 2, p_vout->i_height,
+                                   p_vout->i_bytes_per_line,
+                                   0, 0, 0 );
+  */      break;        
     case YUV_444_PICTURE:
-        if( p_vout->b_grayscale )                                 /* grayscale */
-        {
-            RenderYUVGrayPicture( p_vout, p_pic );            
-        }
-        else if( p_vout->i_bytes_per_pixel == 2 )        /* color 15 or 16 bpp */
-        {
-            RenderYUV16Picture( p_vout, p_pic );        
-        }
-        else if( p_vout->i_bytes_per_pixel == 4 )              /* color 32 bpp */
-        {
-            RenderYUV32Picture( p_vout, p_pic );            
-        }
-        break;        
+/*  ???      p_vout->p_convert_yuv_420( p_vout, 
+                                   p_pic->p_y, p_pic->p_u, p_pic->p_v,
+                                   i_chroma_width, i_chroma_height,
+                                   p_vout->i_width, p_vout->i_height,
+                                   p_vout->i_bytes_per_line,
+                                   0, 0, 0 );
+  */      break;                
 #ifdef DEBUG
     default:        
         intf_DbgMsg("error: unknown picture type %d\n", p_pic->i_type );
@@ -966,208 +768,18 @@ static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
 #endif
     }
 
+    /* 
+     * Terminate scaling 
+     */
+    //??
+
 #ifdef DEBUG_VIDEO
     /* Computes rendering time */
     p_vout->picture_render_time = mdate() - p_vout->picture_render_time;    
 #endif
 }
 
-/*******************************************************************************
- * RenderYUVGrayPicture: render YUV picture in grayscale
- *******************************************************************************
- * Performs the YUV convertion. The picture sent to this function should only
- * have YUV_420, YUV_422 or YUV_444 types.
- *******************************************************************************/
-static void RenderYUVGrayPicture( vout_thread_t *p_vout, picture_t *p_pic )
-{
-    int         i_pic_x, i_pic_y;                /* x,y coordinates in picture */
-    int         i_width, i_height;                             /* picture size */
-    int         i_eol_offset;          /* pixels from end of line to next line */   
-    yuv_data_t *p_y;                                     /* Y data base adress */
-    u16 *       p_pic16;                  /* destination picture, 15 or 16 bpp */
-    u32 *       p_pic32;                        /* destination picture, 32 bpp */
-    u16 *       p_trans16_gray;          /* transformation table, 15 or 16 bpp */
-    u32 *       p_trans32_gray;                /* transformation table, 32 bpp */
-    /* Set the base pointers and transformation parameters */
-    p_y =               p_pic->p_y;
-    i_width =           p_pic->i_width;
-    i_height =          p_pic->i_height;
-    i_eol_offset =      p_vout->i_bytes_per_line / p_vout->i_bytes_per_pixel - i_width;
-
-    /* Get base adress for destination image and translation tables, then
-     * transform image */
-    switch( p_vout->i_screen_depth )
-    {
-    case 15:
-    case 16:
-        p_trans16_gray =       (u16 *) p_vout->p_trans_gray;
-        p_pic16 =              (u16 *) vout_SysGetPicture( p_vout );
-        YUV_GRAYSCALE( p_trans16_gray, p_pic16 );
-        break;        
-    case 32:
-        p_trans32_gray =       (u32 *) p_vout->p_trans_gray;
-        p_pic32 =              (u32 *) vout_SysGetPicture( p_vout );
-        YUV_GRAYSCALE( p_trans32_gray, p_pic32 );
-        break;        
-#ifdef DEBUG
-    default:
-        intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
-        break;    
-#endif      
-    }
-}
-
-
-/*******************************************************************************
- * RenderYUV16Picture: render a 15 or 16 bpp YUV picture
- *******************************************************************************
- * Performs the YUV convertion. The picture sent to this function should only
- * have YUV_420, YUV_422 or YUV_444 types.
- *******************************************************************************/
-static void RenderYUV16Picture( vout_thread_t *p_vout, picture_t *p_pic )
-{
-    int         i_crv, i_cbu, i_cgu, i_cgv;     /* transformation coefficients */
-    int         i_pic_x, i_pic_y;                /* x,y coordinates in picture */
-    int         i_y, i_u, i_v;                           /* Y, U and V samples */
-    int         i_width, i_height;                             /* picture size */
-    int         i_chroma_width;                                /* chroma width */    
-    int         i_eol_offset;          /* pixels from end of line to next line */
-    yuv_data_t *p_y;                                     /* Y data base adress */
-    yuv_data_t *p_u;                                     /* U data base adress */
-    yuv_data_t *p_v;                                     /* V data base adress */
-    u16 *       p_data;                 /* base adress for destination picture */
-    u16 *       p_trans_red;                       /* red transformation table */
-    u16 *       p_trans_green;                   /* green transformation table */
-    u16 *       p_trans_blue;                     /* blue transformation table */
-    /* Choose transformation matrix coefficients */
-    i_crv = MATRIX_COEFFICIENTS_TABLE[p_pic->i_matrix_coefficients][0];
-    i_cbu = MATRIX_COEFFICIENTS_TABLE[p_pic->i_matrix_coefficients][1];
-    i_cgu = MATRIX_COEFFICIENTS_TABLE[p_pic->i_matrix_coefficients][2];
-    i_cgv = MATRIX_COEFFICIENTS_TABLE[p_pic->i_matrix_coefficients][3];
-
-    /* Choose the conversions tables and picture address */
-    p_trans_red =       (u16 *) p_vout->p_trans_red;
-    p_trans_green =     (u16 *) p_vout->p_trans_green;
-    p_trans_blue =      (u16 *) p_vout->p_trans_blue;    
-    p_data =            (u16 *) vout_SysGetPicture( p_vout );
-
-    /* Set the base pointers and transformation parameters */
-    p_y =               p_pic->p_y;
-    p_u =               p_pic->p_u;
-    p_v =               p_pic->p_v;
-    i_width =           p_pic->i_width;
-    i_height =          p_pic->i_height;
-    i_chroma_width =    i_width / 2;
-    i_eol_offset =      p_vout->i_bytes_per_line / 2 - i_width;    
-        
-    /* Do YUV transformation - the loops are repeated for optimization */
-    switch( p_pic->i_type )
-    {
-    case YUV_420_PICTURE:                   /* 15 or 16 bpp 420 transformation */
-#ifdef HAVE_MMX
-        vout_YUV420_16_MMX( p_y, p_u, p_v, 
-                            i_width, i_height, 
-                            i_width, i_chroma_width,
-                            0, p_data, 
-                            0, 0, p_vout->i_bytes_per_line, 
-                            p_vout->i_screen_depth == 15 );
-#else
-        YUV_TRANSFORM( 420,
-                       p_trans_red, 
-                       p_trans_green, 
-                       p_trans_blue,
-                       p_data );            
-  //???      yuvToRgb16( p_y, p_u, p_v, p_data, p_vout->p_trans_optimized, i_width*i_height );
-#endif
-        break;
-    case YUV_422_PICTURE:                   /* 15 or 16 bpp 422 transformation */
-        YUV_TRANSFORM( 422,
-                       p_trans_red, 
-                       p_trans_green, 
-                       p_trans_blue,
-                       p_data );            
-        break;
-    case YUV_444_PICTURE:                   /* 15 or 16 bpp 444 transformation */
-        YUV_TRANSFORM( 444,
-                       p_trans_red, 
-                       p_trans_green, 
-                       p_trans_blue,
-                       p_data );            
-        break;                 
-    }
-}
 
-/*******************************************************************************
- * RenderYUV32Picture: render a 32 bpp YUV picture
- *******************************************************************************
- * Performs the YUV convertion. The picture sent to this function should only
- * have YUV_420, YUV_422 or YUV_444 types.
- *******************************************************************************/
-static void RenderYUV32Picture( vout_thread_t *p_vout, picture_t *p_pic )
-{
-    int         i_crv, i_cbu, i_cgu, i_cgv;     /* transformation coefficients */
-    int         i_pic_x, i_pic_y;                /* x,y coordinates in picture */
-    int         i_y, i_u, i_v;                           /* Y, U and V samples */
-    int         i_width, i_height;                             /* picture size */
-    int         i_chroma_width;                                /* chroma width */    
-    int         i_eol_offset;          /* pixels from end of line to next line */
-    yuv_data_t *p_y;                                     /* Y data base adress */
-    yuv_data_t *p_u;                                     /* U data base adress */
-    yuv_data_t *p_v;                                     /* V data base adress */
-    u32 *       p_data;                 /* base adress for destination picture */
-    u32 *       p_trans_red;                       /* red transformation table */
-    u32 *       p_trans_green;                   /* green transformation table */
-    u32 *       p_trans_blue;                     /* blue transformation table */
-    /* Choose transformation matrix coefficients */
-    i_crv = MATRIX_COEFFICIENTS_TABLE[p_pic->i_matrix_coefficients][0];
-    i_cbu = MATRIX_COEFFICIENTS_TABLE[p_pic->i_matrix_coefficients][1];
-    i_cgu = MATRIX_COEFFICIENTS_TABLE[p_pic->i_matrix_coefficients][2];
-    i_cgv = MATRIX_COEFFICIENTS_TABLE[p_pic->i_matrix_coefficients][3];
-
-    /* Choose the conversions tables and picture address */
-    p_trans_red =       (u32 *) p_vout->p_trans_red;
-    p_trans_green =     (u32 *) p_vout->p_trans_green;
-    p_trans_blue =      (u32 *) p_vout->p_trans_blue;    
-    p_data =            (u32 *) vout_SysGetPicture( p_vout );
-
-    /* Set the base pointers and transformation parameters */
-    p_y =               p_pic->p_y;
-    p_u =               p_pic->p_u;
-    p_v =               p_pic->p_v;
-    i_width =           p_pic->i_width;
-    i_height =          p_pic->i_height;
-    i_chroma_width =    i_width / 2;
-    i_eol_offset =      p_vout->i_bytes_per_line / p_vout->i_bytes_per_pixel - i_width;
-        
-    /* Do YUV transformation - the loops are repeated for optimization */
-    switch( p_pic->i_type )
-    {
-    case YUV_420_PICTURE:                         /* 32 bpp 420 transformation */
-        YUV_TRANSFORM( 420,
-                       p_trans_red, 
-                       p_trans_green, 
-                       p_trans_blue,
-                       p_data );            
-        break;
-    case YUV_422_PICTURE:                         /* 32 bpp 422 transformation */
-        YUV_TRANSFORM( 422,
-                       p_trans_red, 
-                       p_trans_green, 
-                       p_trans_blue,
-                       p_data );            
-        break;
-    case YUV_444_PICTURE:                         /* 32 bpp 444 transformation */
-        YUV_TRANSFORM( 444,
-                       p_trans_red, 
-                       p_trans_green, 
-                       p_trans_blue,
-                       p_data );            
-        break;                 
-    }
-}
 
 /*******************************************************************************
  * RenderPictureInfo: print additionnal informations on a picture
diff --git a/src/video_output/video_yuv.c b/src/video_output/video_yuv.c
new file mode 100644 (file)
index 0000000..f620f65
--- /dev/null
@@ -0,0 +1,1455 @@
+/*******************************************************************************
+ * video_yuv.c: YUV transformation functions
+ * (c)1999 VideoLAN
+ *******************************************************************************
+ * Provides functions to perform the YUV conversion. The functions provided here
+ * are a complete and portable C implementation, and may be replaced in certain
+ * case by optimized functions.
+ *******************************************************************************/
+
+/*******************************************************************************
+ * Preamble
+ *******************************************************************************/
+#include <errno.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef VIDEO_X11
+#include <X11/Xlib.h>                           /* for video_sys.h in X11 mode */
+#endif
+
+#include "common.h"
+#include "config.h"
+#include "mtime.h"
+#include "vlc_thread.h"
+#include "video.h"
+#include "video_output.h"
+#include "intf_msg.h"
+
+/*******************************************************************************
+ * Constants
+ *******************************************************************************/
+
+/* RGB/YUV inversion matrix (ISO/IEC 13818-2 section 6.3.6, table 6.9) */
+const int MATRIX_COEFFICIENTS_TABLE[8][4] =
+{
+  {117504, 138453, 13954, 34903},       /* no sequence_display_extension */
+  {117504, 138453, 13954, 34903},       /* ITU-R Rec. 709 (1990) */
+  {104597, 132201, 25675, 53279},       /* unspecified */
+  {104597, 132201, 25675, 53279},       /* reserved */
+  {104448, 132798, 24759, 53109},       /* FCC */
+  {104597, 132201, 25675, 53279},       /* ITU-R Rec. 624-4 System B, G */
+  {104597, 132201, 25675, 53279},       /* SMPTE 170M */
+  {117579, 136230, 16907, 35559}        /* SMPTE 240M (1987) */
+};
+
+/*******************************************************************************
+ * Local prototypes
+ *******************************************************************************/
+static int      BinaryLog         ( u32 i );
+static void     MaskToShift       ( int *pi_right, int *pi_left, u32 i_mask );
+static void     SetTables         ( vout_thread_t *p_vout );
+
+static void     ConvertY4Gray16   ( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                    int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale );
+static void     ConvertY4Gray24   ( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                    int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale );
+static void     ConvertY4Gray32   ( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                    int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale );
+static void     ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                    int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale );
+static void     ConvertYUV422RGB16( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                    int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale );
+static void     ConvertYUV444RGB16( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                    int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale );
+static void     ConvertYUV420RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                    int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale );
+static void     ConvertYUV422RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                    int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale );
+static void     ConvertYUV444RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                    int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale );
+static void     ConvertYUV420RGB32( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                    int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale );
+static void     ConvertYUV422RGB32( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                    int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale );
+static void     ConvertYUV444RGB32( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                    int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale );
+static void     Scale16           ( p_vout_thread_t p_vout, void *p_pic, void *p_buffer, 
+                                    int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta );
+static void     Scale24           ( p_vout_thread_t p_vout, void *p_pic, void *p_buffer, 
+                                    int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta );
+static void     Scale32           ( p_vout_thread_t p_vout, void *p_pic, void *p_buffer, 
+                                    int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta );
+
+/*******************************************************************************
+ * CLIP_BYTE macro: boundary detection
+ *******************************************************************************
+ * Return parameter if between 0 and 255, else return nearest boundary (0 or 
+ * 255). This macro is used to build translations tables.
+ *******************************************************************************/
+#define CLIP_BYTE( i_val ) ( (i_val < 0) ? 0 : ((i_val > 255) ? 255 : i_val) )
+
+/*******************************************************************************
+ * LINE_COPY macro: memcopy using 16 pixels blocks
+ *******************************************************************************
+ * Variables:
+ *      p_pic                   destination pointer
+ *      p_pic_src               source pointer
+ *      i_width                 width
+ *      i_x                     index
+ *******************************************************************************/
+#define LINE_COPY                                                       \
+for( i_x = 0; i_x < i_width; i_x+=16 )                                  \
+{                                                                       \
+    *p_pic++ = *p_pic_src++;                                            \
+    *p_pic++ = *p_pic_src++;                                            \
+    *p_pic++ = *p_pic_src++;                                            \
+    *p_pic++ = *p_pic_src++;                                            \
+    *p_pic++ = *p_pic_src++;                                            \
+    *p_pic++ = *p_pic_src++;                                            \
+    *p_pic++ = *p_pic_src++;                                            \
+    *p_pic++ = *p_pic_src++;                                            \
+    *p_pic++ = *p_pic_src++;                                            \
+    *p_pic++ = *p_pic_src++;                                            \
+    *p_pic++ = *p_pic_src++;                                            \
+    *p_pic++ = *p_pic_src++;                                            \
+    *p_pic++ = *p_pic_src++;                                            \
+    *p_pic++ = *p_pic_src++;                                            \
+    *p_pic++ = *p_pic_src++;                                            \
+    *p_pic++ = *p_pic_src++;                                            \
+}
+
+/*******************************************************************************
+ * CONVERT_YUV_GRAY macro: grayscale YUV convertion
+ *******************************************************************************
+ * Variables:
+ *      ...see vout_convert_t
+ *      i_x, i_y                coordinates
+ *      i_pic_copy              same type as p_pic
+ *      p_gray                  gray translation table
+ *******************************************************************************/
+#define CONVERT_YUV_GRAY                                                \
+/* Set scale factor to be ignored if it is 0 */                         \
+if( !i_scale )                                                          \
+{                                                                       \
+    i_scale = i_height;                                                 \
+}                                                                       \
+                                                                        \
+/* Main loop */                                                         \
+for (i_y = 0; i_y < i_height ; i_y++)                                   \
+{                                                                       \
+    for (i_x = 0; i_x < i_width; i_x += 16)                             \
+    {                                                                   \
+        /* Convert 16 pixels (width is always multiple of 16 */         \
+        *p_pic++ = p_gray[ *p_y++ ];                                    \
+        *p_pic++ = p_gray[ *p_y++ ];                                    \
+        *p_pic++ = p_gray[ *p_y++ ];                                    \
+        *p_pic++ = p_gray[ *p_y++ ];                                    \
+        *p_pic++ = p_gray[ *p_y++ ];                                    \
+        *p_pic++ = p_gray[ *p_y++ ];                                    \
+        *p_pic++ = p_gray[ *p_y++ ];                                    \
+        *p_pic++ = p_gray[ *p_y++ ];                                    \
+        *p_pic++ = p_gray[ *p_y++ ];                                    \
+        *p_pic++ = p_gray[ *p_y++ ];                                    \
+        *p_pic++ = p_gray[ *p_y++ ];                                    \
+        *p_pic++ = p_gray[ *p_y++ ];                                    \
+        *p_pic++ = p_gray[ *p_y++ ];                                    \
+        *p_pic++ = p_gray[ *p_y++ ];                                    \
+        *p_pic++ = p_gray[ *p_y++ ];                                    \
+        *p_pic++ = p_gray[ *p_y++ ];                                    \
+    }                                                                   \
+                                                                        \
+    /* Handle scale factor */                                           \
+    if( ! (i_y % i_scale) )                                             \
+    {                                                                   \
+        if( i_scale < 0 )                                               \
+        {                                                               \
+            /* Copy previous line */                                    \
+            p_pic_src = p_pic - i_width;                                \
+            p_pic += i_pic_eol;                                         \
+            LINE_COPY                                                   \
+        }                                                               \
+        else                                                            \
+        {                                                               \
+            /* Ignore next line */                                      \
+            p_y += i_eol + i_width;                                     \
+            i_y++;                                                      \
+        }                                                               \
+    }                                                                   \
+                                                                        \
+    /* Skip until beginning of next line */                             \
+    p_pic += i_pic_eol;                                                 \
+    p_y   += i_eol;                                                     \
+}
+
+/*******************************************************************************
+ * CONVERT_YUV_RGB: color YUV convertion
+ *******************************************************************************
+ * Parameters
+ *      CHROMA                  420, 422 or 444
+ * Variables:
+ *      ...see vout_convert_t
+ *      i_x, i_y                coordinates
+ *      i_uval, i_yval, i_vval  samples
+ *      p_pic_src               same type as p_pic
+ *      i_chroma_width          chroma width
+ *      i_chroma_eol            chroma eol
+ *      p_red                   red translation table
+ *      p_green                 green translation table
+ *      p_blue                  blue translation table
+ *******************************************************************************/
+#define CONVERT_YUV_RGB                                                 \
+/* Set scale factor to be ignored if it is 0 */                         \
+if( !i_scale )                                                          \
+{                                                                       \
+    i_scale = i_height;                                                 \
+}                                                                       \
+                                                                        \
+/* Main loop */                                                         \
+for (i_y = 0; i_y < i_height ; i_y++)                                   \
+{                                                                       \
+    for (i_x=0; i_x < i_width; i_x += 2 )                               \
+    {                                                                   \
+        /* First sample (complete) */                                   \
+        i_yval = 76309 * *p_y++ - 1188177;                              \
+        i_uval = *p_u++ - 128;                                          \
+        i_vval = *p_v++ - 128;                                          \
+        *p_pic++ =                                                      \
+            p_red  [(i_yval+i_crv*i_vval)                >>16] |        \
+            p_green[(i_yval-i_cgu*i_uval-i_cgv*i_vval)   >>16] |        \
+            p_blue [(i_yval+i_cbu*i_uval)                >>16];         \
+        i_yval = 76309 * *p_y++ - 1188177;                              \
+        /* Second sample (partial) */                                   \
+        if( CHROMA == 444 )                                             \
+        {                                                               \
+            i_uval = *p_u++ - 128;                                      \
+            i_vval = *p_v++ - 128;                                      \
+        }                                                               \
+        *p_pic++ =                                                      \
+            p_red  [(i_yval+i_crv*i_vval)                >>16] |        \
+            p_green[(i_yval-i_cgu*i_uval-i_cgv*i_vval)   >>16] |        \
+            p_blue [(i_yval+i_cbu*i_uval)                >>16];         \
+    }                                                                   \
+                                                                        \
+    /* Handle scale factor */                                           \
+    if( ! (i_y % i_scale) )                                             \
+    {                                                                   \
+        if( i_scale < 0 )                                               \
+        {                                                               \
+            /* Copy previous line */                                    \
+            p_pic_src = p_pic - i_width;                                \
+            p_pic += i_pic_eol;                                         \
+            LINE_COPY                                                   \
+        }                                                               \
+        else                                                            \
+        {                                                               \
+            /* Ignore next line, rewind if in 4:2:0 */                  \
+            p_y += i_eol + i_width;                                     \
+            if( (CHROMA == 420) && !(i_y & 0x1) )                       \
+            {                                                           \
+                p_u -= i_chroma_width;                                  \
+                p_v -= i_chroma_width;                                  \
+            }                                                           \
+            else                                                        \
+            {                                                           \
+                p_u += i_chroma_eol;                                    \
+                p_v += i_chroma_eol;                                    \
+            }                                                           \
+            i_y++;                                                      \
+        }                                                               \
+    }                                                                   \
+                                                                        \
+    /* Rewind u and v values in 4:2:0, or skip until next line */       \
+    if( (CHROMA == 420) && !(i_y & 0x1) )                               \
+    {                                                                   \
+        p_u -= i_chroma_width;                                          \
+        p_v -= i_chroma_width;                                          \
+    }                                                                   \
+    else                                                                \
+    {                                                                   \
+        p_u += i_chroma_eol;                                            \
+        p_v += i_chroma_eol;                                            \
+    }                                                                   \
+                                                                        \
+    /* Skip until beginning of next line */                             \
+    p_pic += i_pic_eol;                                                 \
+    p_y   += i_eol;                                                     \
+}
+
+/*******************************************************************************
+ * vout_InitTables: allocate and initialize translations tables
+ *******************************************************************************
+ * This function will allocate memory to store translation tables, depending
+ * of the screen depth.
+ *******************************************************************************/
+int vout_InitTables( vout_thread_t *p_vout )
+{
+    /* Allocate memory and set pointers */
+    p_vout->tables.p_base = malloc( ( 3 * 1024 ) *   
+                                    ( p_vout->i_bytes_per_pixel != 3 ? 
+                                      p_vout->i_bytes_per_pixel : 4 ));
+    if( p_vout->tables.p_base == NULL )
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+        return( 1 );                
+    }
+
+    /* Initialize tables */
+    SetTables( p_vout );    
+    return( 0 );    
+}
+
+/*******************************************************************************
+ * vout_ResetTables: re-initialize translations tables
+ *******************************************************************************
+ * This function will initialize the tables allocated by vout_CreateTables and
+ * set functions pointers.
+ *******************************************************************************/
+int vout_ResetTables( vout_thread_t *p_vout )
+{
+    // ?? realloc ?
+    SetTables( p_vout );
+    return( 0 );    
+}
+
+/*******************************************************************************
+ * vout_EndTables: destroy translations tables
+ *******************************************************************************
+ * Free memory allocated by vout_CreateTables.
+ *******************************************************************************/
+void vout_EndTables( vout_thread_t *p_vout )
+{
+    free( p_vout->tables.p_base );
+}
+
+/* following functions are local */
+
+/*******************************************************************************
+ * BinaryLog: computes the base 2 log of a binary value
+ *******************************************************************************
+ * This functions is used by MaskToShift during tables initialisation, to
+ * get a bit index from a binary value.
+ *******************************************************************************/
+static int BinaryLog(u32 i)
+{
+    int i_log;
+
+    i_log = 0;
+    if (i & 0xffff0000) 
+    {        
+        i_log = 16;
+    }    
+    if (i & 0xff00ff00) 
+    {        
+        i_log += 8;
+    }    
+    if (i & 0xf0f0f0f0) 
+    {        
+        i_log += 4;
+    }    
+    if (i & 0xcccccccc) 
+    {        
+        i_log += 2;
+    }    
+    if (i & 0xaaaaaaaa) 
+    {        
+        i_log++;
+    }    
+    if (i != ((u32)1 << i_log))
+    {        
+       intf_ErrMsg("internal error: binary log overflow\n");        
+    }    
+
+    return( i_log );
+}
+
+/*******************************************************************************
+ * MaskToShift: Transform a color mask into right and left shifts
+ *******************************************************************************
+ * This function is used during table initialisation. It can return a value
+ *******************************************************************************/
+static void MaskToShift (int *pi_right, int *pi_left, u32 i_mask)
+{
+    u32 i_low, i_high;                   /* lower hand higher bits of the mask */
+
+    /* Get bits */
+    i_low =  i_mask & (- i_mask);                     /* lower bit of the mask */
+    i_high = i_mask + i_low;                         /* higher bit of the mask */
+
+    /* Transform bits into an index */
+    i_low =  BinaryLog (i_low);
+    i_high = BinaryLog (i_high);
+
+    /* Update pointers and return */
+    *pi_left =   i_low;
+    *pi_right = (8 - i_high + i_low);
+}
+
+/*******************************************************************************
+ * SetTables: compute tables and set function pointers
+ *******************************************************************************/
+static void SetTables( vout_thread_t *p_vout )
+{
+    u8          i_gamma[256];                                   /* gamma table */    
+    int         i_index;                                    /* index in tables */
+    int         i_red_right, i_red_left;                         /* red shifts */
+    int         i_green_right, i_green_left;                   /* green shifts */
+    int         i_blue_right, i_blue_left;                      /* blue shifts */
+
+    /*
+     * Build gamma table 
+     */     
+    for( i_index = 0; i_index < 256; i_index++ )
+    {
+        i_gamma[i_index] = 255. * pow( (double)i_index / 255., p_vout->f_gamma );        
+    }
+
+    /*          
+     * Set color masks and shifts
+     */
+    switch( p_vout->i_screen_depth )
+    {
+    case 15:
+        MaskToShift( &i_red_right,   &i_red_left,   0xf800 );
+        MaskToShift( &i_green_right, &i_green_left, 0x03e0 );
+        MaskToShift( &i_blue_right,  &i_blue_left,  0x001f );        
+        break;        
+    case 16:
+        MaskToShift( &i_red_right,   &i_red_left,   0xf800 );
+        MaskToShift( &i_green_right, &i_green_left, 0x07e0 );
+        MaskToShift( &i_blue_right,  &i_blue_left,  0x001f );
+        break;        
+    case 24:
+    case 32:        
+        MaskToShift( &i_red_right,   &i_red_left,   0x00ff0000 );
+        MaskToShift( &i_green_right, &i_green_left, 0x0000ff00 );
+        MaskToShift( &i_blue_right,  &i_blue_left,  0x000000ff );
+        break;
+#ifdef DEBUG
+    default:
+        intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
+        break;        
+#endif      
+    }
+
+    /*
+     * Set pointers and build YUV tables
+     */        
+    if( p_vout->b_grayscale )
+    {
+        /* Grayscale: build gray table */
+        switch( p_vout->i_screen_depth )
+        {
+        case 15:
+        case 16:         
+            p_vout->tables.yuv.gray16.p_gray =  (u16 *)p_vout->tables.p_base + 384;
+            for( i_index = -384; i_index < 640; i_index++) 
+            {
+                p_vout->tables.yuv.gray16.p_gray[ i_index ] = 
+                    ((i_gamma[CLIP_BYTE( i_index )] >> i_red_right)   << i_red_left)   |
+                    ((i_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
+                    ((i_gamma[CLIP_BYTE( i_index )] >> i_blue_right)  << i_blue_left);                
+            }
+            break;        
+        case 24:
+        case 32:        
+            p_vout->tables.yuv.gray32.p_gray =  (u32 *)p_vout->tables.p_base + 384;
+            for( i_index = -384; i_index < 640; i_index++) 
+            {
+                p_vout->tables.yuv.gray32.p_gray[ i_index ] = 
+                    ((i_gamma[CLIP_BYTE( i_index )] >> i_red_right)   << i_red_left)   |
+                    ((i_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
+                    ((i_gamma[CLIP_BYTE( i_index )] >> i_blue_right)  << i_blue_left);                
+            }        
+            break;        
+        }
+    }
+    else
+    {
+        /* Color: build red, green and blue tables */
+        switch( p_vout->i_screen_depth )
+        {
+        case 15:
+        case 16:            
+            p_vout->tables.yuv.rgb16.p_red =    (u16 *)p_vout->tables.p_base +          384;
+            p_vout->tables.yuv.rgb16.p_green =  (u16 *)p_vout->tables.p_base +   1024 + 384;
+            p_vout->tables.yuv.rgb16.p_blue =   (u16 *)p_vout->tables.p_base + 2*1024 + 384;
+            for( i_index = -384; i_index < 640; i_index++) 
+            {
+                p_vout->tables.yuv.rgb16.p_red[i_index] =   (i_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
+                p_vout->tables.yuv.rgb16.p_green[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left;
+                p_vout->tables.yuv.rgb16.p_blue[i_index] =  (i_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left;
+            }
+            break;        
+        case 24:
+        case 32:
+            p_vout->tables.yuv.rgb32.p_red =    (u32 *)p_vout->tables.p_base +          384;
+            p_vout->tables.yuv.rgb32.p_green =  (u32 *)p_vout->tables.p_base +   1024 + 384;
+            p_vout->tables.yuv.rgb32.p_blue =   (u32 *)p_vout->tables.p_base + 2*1024 + 384;
+            for( i_index = -384; i_index < 640; i_index++) 
+            {
+                p_vout->tables.yuv.rgb32.p_red[i_index] =   (i_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
+                p_vout->tables.yuv.rgb32.p_green[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left;
+                p_vout->tables.yuv.rgb32.p_blue[i_index] =  (i_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left;
+            }
+            break;        
+        }
+    }    
+    
+    /*
+     * Set functions pointers
+     */
+    if( p_vout->b_grayscale )
+    {
+        /* Grayscale */
+        switch( p_vout->i_screen_depth )
+        {
+        case 15:
+        case 16:  
+            p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;        
+            p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;        
+            p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;        
+            p_vout->p_Scale =           (vout_scale_t *) Scale16;                    
+            break;        
+        case 24:
+            p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;        
+            p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;        
+            p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;        
+            p_vout->p_Scale =           (vout_scale_t *) Scale24;
+            break;        
+        case 32:        
+            p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;        
+            p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;        
+            p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;        
+            p_vout->p_Scale =           (vout_scale_t *) Scale32;                    
+            break;        
+        }        
+    }
+    else
+    {
+        /* Color */
+        switch( p_vout->i_screen_depth )
+        {
+        case 15:
+        case 16:  
+            p_vout->p_ConvertYUV420 =   (vout_convert_t *) ConvertYUV420RGB16;        
+            p_vout->p_ConvertYUV422 =   (vout_convert_t *) ConvertYUV422RGB16;        
+            p_vout->p_ConvertYUV444 =   (vout_convert_t *) ConvertYUV444RGB16;        
+            p_vout->p_Scale =           (vout_scale_t *)   Scale16;                    
+            break;        
+        case 24:
+            p_vout->p_ConvertYUV420 =   (vout_convert_t *) ConvertYUV420RGB24;        
+            p_vout->p_ConvertYUV422 =   (vout_convert_t *) ConvertYUV422RGB24;        
+            p_vout->p_ConvertYUV444 =   (vout_convert_t *) ConvertYUV444RGB24;        
+            p_vout->p_Scale =           (vout_scale_t *)   Scale24;                    
+            break;        
+        case 32:        
+            p_vout->p_ConvertYUV420 =   (vout_convert_t *) ConvertYUV420RGB32;        
+            p_vout->p_ConvertYUV422 =   (vout_convert_t *) ConvertYUV422RGB32;        
+            p_vout->p_ConvertYUV444 =   (vout_convert_t *) ConvertYUV444RGB32;        
+            p_vout->p_Scale =           (vout_scale_t *)   Scale32;                    
+            break;        
+        }
+    }        
+}
+
+/*******************************************************************************
+ * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 15 or 16 bpp
+ *******************************************************************************/
+static void ConvertY4Gray16( p_vout_thread_t p_vout, u16 *p_pic,
+                             yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                             int i_width, int i_height, int i_eol, int i_pic_eol,
+                             int i_scale )
+{
+    u16 *       p_pic_src;                   /* source pointer in case of copy */
+    u16 *       p_gray;                                          /* gray table */    
+    int         i_x, i_y;                               /* picture coordinates */
+    
+    p_gray = p_vout->tables.yuv.gray16.p_gray;
+    CONVERT_YUV_GRAY
+}
+
+/*******************************************************************************
+ * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 24 bpp
+ *******************************************************************************/
+static void ConvertY4Gray24( p_vout_thread_t p_vout, void *p_pic,
+                             yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                             int i_width, int i_height, int i_eol, int i_pic_eol,
+                             int i_scale )
+{
+    //??
+}
+
+/*******************************************************************************
+ * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 32 bpp
+ *******************************************************************************/
+static void ConvertY4Gray32( p_vout_thread_t p_vout, u32 *p_pic,
+                             yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                             int i_width, int i_height, int i_eol, int i_pic_eol,
+                             int i_scale )
+{
+    u32 *       p_pic_src;                   /* source pointer in case of copy */
+    u32 *       p_gray;                                          /* gray table */    
+    int         i_x, i_y;                               /* picture coordinates */
+    
+    p_gray = p_vout->tables.yuv.gray32.p_gray;
+    CONVERT_YUV_GRAY
+}
+
+/*******************************************************************************
+ * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 15 or 16 bpp
+ *******************************************************************************/
+static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic,
+                                yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                int i_width, int i_height, int i_eol, int i_pic_eol,
+                                int i_scale )
+{
+    u16 *       p_pic_src;                   /* source pointer in case of copy */
+    u16 *       p_red;                                            /* red table */
+    u16 *       p_green;                                        /* green table */
+    u16 *       p_blue;                                          /* blue table */
+    int         i_uval, i_yval, i_vval;                             /* samples */   
+    int         i_x, i_y;                               /* picture coordinates */
+    int         i_chroma_width, i_chroma_eol;      /* width and eol for chroma */
+    int         i_crv;
+    
+/*    p_red   = p_vout->tables.yuv.rgb16.p_red;
+    p_green = p_vout->tables.yuv.rgb16.p_green;
+    p_blue  = p_vout->tables.yuv.rgb16.p_blue;
+    i_chroma_width =    i_width / 4;
+    i_chroma_eol =      i_eol / 4;
+    CONVERT_YUV_RGB*/
+}
+
+/*******************************************************************************
+ * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 15 or 16 bpp
+ *******************************************************************************/
+static void ConvertYUV422RGB16( p_vout_thread_t p_vout, void *p_pic,
+                                yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                int i_width, int i_height, int i_eol, int i_pic_eol,
+                                int i_scale )
+{
+    //??
+}
+
+/*******************************************************************************
+ * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 15 or 16 bpp
+ *******************************************************************************/
+static void ConvertYUV444RGB16( p_vout_thread_t p_vout, void *p_pic,
+                                yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                int i_width, int i_height, int i_eol, int i_pic_eol,
+                                int i_scale )
+{
+    //??
+}
+
+/*******************************************************************************
+ * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 24 bpp
+ *******************************************************************************/
+static void ConvertYUV420RGB24( p_vout_thread_t p_vout, void *p_pic,
+                                yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                int i_width, int i_height, int i_eol, int i_pic_eol,
+                                int i_scale )
+{
+    //???
+}
+
+/*******************************************************************************
+ * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 24 bpp
+ *******************************************************************************/
+static void ConvertYUV422RGB24( p_vout_thread_t p_vout, void *p_pic,
+                                yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                int i_width, int i_height, int i_eol, int i_pic_eol,
+                                int i_scale )
+{
+    //???
+}
+
+/*******************************************************************************
+ * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 24 bpp
+ *******************************************************************************/
+static void ConvertYUV444RGB24( p_vout_thread_t p_vout, void *p_pic,
+                                yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                int i_width, int i_height, int i_eol, int i_pic_eol,
+                                int i_scale )
+{    
+    //???
+}
+
+/*******************************************************************************
+ * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 32 bpp
+ *******************************************************************************/
+static void ConvertYUV420RGB32( p_vout_thread_t p_vout, void *p_pic,
+                                yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                int i_width, int i_height, int i_eol, int i_pic_eol,
+                                int i_scale )
+{
+    //???
+}
+
+/*******************************************************************************
+ * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 32 bpp
+ *******************************************************************************/
+static void ConvertYUV422RGB32( p_vout_thread_t p_vout, void *p_pic,
+                                yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                int i_width, int i_height, int i_eol, int i_pic_eol,
+                                int i_scale )
+{
+    //???
+}
+
+/*******************************************************************************
+ * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 32 bpp
+ *******************************************************************************/
+static void ConvertYUV444RGB32( p_vout_thread_t p_vout, void *p_pic,
+                                yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
+                                int i_width, int i_height, int i_eol, int i_pic_eol,
+                                int i_scale )
+{
+    //???
+}
+
+/*******************************************************************************
+ * Scale16: 15 or 16 bpp picture scaling
+ *******************************************************************************/
+static void Scale16( p_vout_thread_t p_vout, void *p_pic, void *p_buffer, 
+                     int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta )
+{
+    //???
+}
+
+/*******************************************************************************
+ * Scale24: 24 bpp picture scaling
+ *******************************************************************************/
+static void Scale24( p_vout_thread_t p_vout, void *p_pic, void *p_buffer, 
+                     int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta )
+{
+    //???
+}
+
+/*******************************************************************************
+ * Scale32: 32 bpp picture scaling
+ *******************************************************************************/
+static void Scale32( p_vout_thread_t p_vout, void *p_pic, void *p_buffer, 
+                     int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta )
+{
+    //???
+}
+
+//-------------------------
+
+/*******************************************************************************
+ * External prototypes
+ *******************************************************************************/
+#ifdef HAVE_MMX
+/* YUV transformations for MMX - in video_yuv_mmx.S 
+ *      p_y, p_u, p_v:          Y U and V planes
+ *      i_width, i_height:      frames dimensions (pixels)
+ *      i_ypitch, i_vpitch:     Y and V lines sizes (bytes)
+ *      i_aspect:               vertical aspect factor
+ *      p_pic:                  RGB frame
+ *      i_dci_offset:           ?? x offset for left image border
+ *      i_offset_to_line_0:     ?? x offset for left image border
+ *      i_pitch:                RGB line size (bytes)
+ *      i_colortype:            0 for 565, 1 for 555 */
+static YUV420_16_MMX( u8* p_y, u8* p_u, u8 *p_v, 
+                         unsigned int i_width, unsigned int i_height,
+                         unsigned int i_ypitch, unsigned int i_vpitch,
+                         unsigned int i_aspect, u8 *p_pic, 
+                         u32 i_dci_offset, u32 i_offset_to_line_0,
+                         int CCOPitch, int i_colortype );
+#endif
+
+//-------------------- walken code follow --------------------------------
+
+
+
+
+/*
+ * YUV to RGB routines.
+ *
+ * these routines calculate r, g and b values from each pixel's y, u and v.
+ * these r, g an b values are then passed thru a table lookup to take the
+ * gamma curve into account and find the corresponding pixel value.
+ *
+ * the table must store more than 3*256 values because of the possibility
+ * of overflow in the yuv->rgb calculation. actually the calculated r,g,b
+ * values are in the following intervals :
+ * -176 to 255+176 for red
+ * -133 to 255+133 for green
+ * -222 to 255+222 for blue
+ *
+ * If the input y,u,v values are right, the r,g,b results are not expected
+ * to move out of the 0 to 255 interval but who knows what will happen in
+ * real use...
+ *
+ * the red, green and blue conversion tables are stored in a single 1935-entry
+ * array. The respective positions of each component in the array have been
+ * calculated to minimize the cache interactions of the 3 tables.
+ */
+
+int rgbTable16 (short table [1935],
+                      int redMask, int greenMask, int blueMask,
+                      unsigned char gamma[256])
+{
+    int redRight;
+    int redLeft;
+    int greenRight;
+    int greenLeft;
+    int blueRight;
+    int blueLeft;
+    short * redTable;
+    short * greenTable;
+    short * blueTable;
+    int i;
+    int y;
+
+    MaskToShift (&redRight, &redLeft, redMask);    
+    MaskToShift (&greenRight, &greenLeft, greenMask);    
+    MaskToShift (&blueRight, &blueLeft, blueMask);
+
+    /*
+     * green blue red +- 2 just to be sure
+     * green = 0-525 [151-370]
+     * blue = 594-1297 [834-1053] <834-29>
+     * red = 1323-1934 [1517-1736] <493-712>
+     */
+
+    redTable = table + 1501;
+    greenTable = table + 135;
+    blueTable = table + 818;
+
+    for (i = 0; i < 178; i++) {
+       redTable[i-178] = 0;
+       redTable[i+256] = redMask;
+    }
+    for (i = 0; i < 135; i++) {
+       greenTable[i-135] = 0;
+       greenTable[i+256] = greenMask;
+    }
+    for (i = 0; i < 224; i++) {
+       blueTable[i-224] = 0;
+       blueTable[i+256] = blueMask;
+    }
+
+    for (i = 0; i < 256; i++) {
+       y = gamma[i];
+       redTable[i] = ((y >> redRight) << redLeft);
+       greenTable[i] = ((y >> greenRight) << greenLeft);
+       blueTable[i] = ((y >> blueRight) << blueLeft);
+    }
+
+    return 0;
+}
+
+static int rgbTable32 (int table [1935],
+                      int redMask, int greenMask, int blueMask,
+                      unsigned char gamma[256])
+{
+    int redRight;
+    int redLeft;
+    int greenRight;
+    int greenLeft;
+    int blueRight;
+    int blueLeft;
+    int * redTable;
+    int * greenTable;
+    int * blueTable;
+    int i;
+    int y;
+
+    MaskToShift (&redRight, &redLeft, redMask);
+    MaskToShift (&greenRight, &greenLeft, greenMask);
+    MaskToShift (&blueRight, &blueLeft, blueMask);
+    
+
+    /*
+     * green blue red +- 2 just to be sure
+     * green = 0-525 [151-370]
+     * blue = 594-1297 [834-1053] <834-29>
+     * red = 1323-1934 [1517-1736] <493-712>
+     */
+
+    redTable = table + 1501;
+    greenTable = table + 135;
+    blueTable = table + 818;
+
+    for (i = 0; i < 178; i++) {
+       redTable[i-178] = 0;
+       redTable[i+256] = redMask;
+    }
+    for (i = 0; i < 135; i++) {
+       greenTable[i-135] = 0;
+       greenTable[i+256] = greenMask;
+    }
+    for (i = 0; i < 224; i++) {
+       blueTable[i-224] = 0;
+       blueTable[i+256] = blueMask;
+    }
+
+    for (i = 0; i < 256; i++) {
+       y = gamma[i];
+       redTable[i] = ((y >> redRight) << redLeft);
+       greenTable[i] = ((y >> greenRight) << greenLeft);
+       blueTable[i] = ((y >> blueRight) << blueLeft);
+    }
+
+    return 0;
+}
+
+#define SHIFT 20
+#define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164))
+#define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164))
+#define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
+#define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
+
+ void yuvToRgb16 (unsigned char * Y,
+                       unsigned char * U, unsigned char * V,
+                       short * dest, short table[1935], int width)
+{
+    int i;
+    int u;
+    int v;
+    int uvRed;
+    int uvGreen;
+    int uvBlue;
+    short * tableY;
+
+    i = width >> 4;
+    while (i--) {
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+    }
+
+    i = (width & 15) >> 1;
+    while (i--) {
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+    }
+
+    if (width & 1) {
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+    }
+}
+
+static void yuvToRgb24 (unsigned char * Y,
+                       unsigned char * U, unsigned char * V,
+                       char * dest, int table[1935], int width)
+{
+    int i;
+    int u;
+    int v;
+    int uvRed;
+    int uvGreen;
+    int uvBlue;
+    int * tableY;
+    int tmp24;
+
+    i = width >> 3;
+    while (i--) {
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                       uvGreen] |
+                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+       *(dest++) = tmp24;
+       *(dest++) = tmp24 >> 8;
+       *(dest++) = tmp24 >> 16;
+
+       tableY = table + *(Y++);
+       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                       uvGreen] |
+                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+       *(dest++) = tmp24;
+       *(dest++) = tmp24 >> 8;
+       *(dest++) = tmp24 >> 16;
+
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                       uvGreen] |
+                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+       *(dest++) = tmp24;
+       *(dest++) = tmp24 >> 8;
+       *(dest++) = tmp24 >> 16;
+
+       tableY = table + *(Y++);
+       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                       uvGreen] |
+                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+       *(dest++) = tmp24;
+       *(dest++) = tmp24 >> 8;
+       *(dest++) = tmp24 >> 16;
+
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                       uvGreen] |
+                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+       *(dest++) = tmp24;
+       *(dest++) = tmp24 >> 8;
+       *(dest++) = tmp24 >> 16;
+
+       tableY = table + *(Y++);
+       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                       uvGreen] |
+                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+       *(dest++) = tmp24;
+       *(dest++) = tmp24 >> 8;
+       *(dest++) = tmp24 >> 16;
+
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                       uvGreen] |
+                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+       *(dest++) = tmp24;
+       *(dest++) = tmp24 >> 8;
+       *(dest++) = tmp24 >> 16;
+
+       tableY = table + *(Y++);
+       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                       uvGreen] |
+                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+       *(dest++) = tmp24;
+       *(dest++) = tmp24 >> 8;
+       *(dest++) = tmp24 >> 16;
+    }
+
+    i = (width & 7) >> 1;
+    while (i--) {
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                       uvGreen] |
+                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+       *(dest++) = tmp24;
+       *(dest++) = tmp24 >> 8;
+       *(dest++) = tmp24 >> 16;
+
+       tableY = table + *(Y++);
+       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                       uvGreen] |
+                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+       *(dest++) = tmp24;
+       *(dest++) = tmp24 >> 8;
+       *(dest++) = tmp24 >> 16;
+    }
+
+    if (width & 1) {
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                       uvGreen] |
+                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+       *(dest++) = tmp24;
+       *(dest++) = tmp24 >> 8;
+       *(dest++) = tmp24 >> 16;
+    }
+}
+
+static void yuvToRgb32 (unsigned char * Y,
+                       unsigned char * U, unsigned char * V,
+                       int * dest, int table[1935], int width)
+{
+    int i;
+    int u;
+    int v;
+    int uvRed;
+    int uvGreen;
+    int uvBlue;
+    int * tableY;
+
+    i = width >> 4;
+    while (i--) {
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+    }
+
+    i = (width & 15) >> 1;
+    while (i--) {
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+    }
+
+    if (width & 1) {
+       u = *(U++);
+       v = *(V++);
+       uvRed = (V_RED_COEF*v) >> SHIFT;
+       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
+       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
+
+       tableY = table + *(Y++);
+       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
+                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
+                           uvGreen] |
+                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
+    }
+}
+
+/* API routines */
+
diff --git a/src/video_output/video_yuv_c.c b/src/video_output/video_yuv_c.c
deleted file mode 100644 (file)
index b49fcc2..0000000
+++ /dev/null
@@ -1,735 +0,0 @@
-/*******************************************************************************
- * video_yuv_c.c: YUV transformation, optimized 
- * (c)1999 VideoLAN
- *******************************************************************************
- * Provides optimized functions to perform the YUV conversion. 
- *******************************************************************************/
-
-#include <stdlib.h>    /* malloc */
-
-//#include "convert.h"
-
-static int binaryLog (int i)
-{
-    int log;
-
-    log = 0;
-    if (i & 0xffff0000) log = 16;
-    if (i & 0xff00ff00) log += 8;
-    if (i & 0xf0f0f0f0) log += 4;
-    if (i & 0xcccccccc) log += 2;
-    if (i & 0xaaaaaaaa) log++;
-    if (i != (1 << log))
-       return -1;
-
-    return log;
-}
-
-static int colorMaskToShift (int * right, int * left, int mask)
-{
-    int low;
-    int high;
-
-    low = mask & (- mask);     /* lower bit of the mask */
-    high = mask + low;         /* higher bit of the mask */
-
-    low = binaryLog (low);
-    high = binaryLog (high);
-    if ((low == -1) || (high == -1))
-       return 1;
-
-    *left = low;
-    *right = (8 - high + low);
-
-    return 0;
-}
-
-
-/*
- * YUV to RGB routines.
- *
- * these routines calculate r, g and b values from each pixel's y, u and v.
- * these r, g an b values are then passed thru a table lookup to take the
- * gamma curve into account and find the corresponding pixel value.
- *
- * the table must store more than 3*256 values because of the possibility
- * of overflow in the yuv->rgb calculation. actually the calculated r,g,b
- * values are in the following intervals :
- * -176 to 255+176 for red
- * -133 to 255+133 for green
- * -222 to 255+222 for blue
- *
- * If the input y,u,v values are right, the r,g,b results are not expected
- * to move out of the 0 to 255 interval but who knows what will happen in
- * real use...
- *
- * the red, green and blue conversion tables are stored in a single 1935-entry
- * array. The respective positions of each component in the array have been
- * calculated to minimize the cache interactions of the 3 tables.
- */
-
-int rgbTable16 (short table [1935],
-                      int redMask, int greenMask, int blueMask,
-                      unsigned char gamma[256])
-{
-    int redRight;
-    int redLeft;
-    int greenRight;
-    int greenLeft;
-    int blueRight;
-    int blueLeft;
-    short * redTable;
-    short * greenTable;
-    short * blueTable;
-    int i;
-    int y;
-
-    if (colorMaskToShift (&redRight, &redLeft, redMask) ||
-       colorMaskToShift (&greenRight, &greenLeft, greenMask) ||
-       colorMaskToShift (&blueRight, &blueLeft, blueMask))
-       return 1;
-
-    /*
-     * green blue red +- 2 just to be sure
-     * green = 0-525 [151-370]
-     * blue = 594-1297 [834-1053] <834-29>
-     * red = 1323-1934 [1517-1736] <493-712>
-     */
-
-    redTable = table + 1501;
-    greenTable = table + 135;
-    blueTable = table + 818;
-
-    for (i = 0; i < 178; i++) {
-       redTable[i-178] = 0;
-       redTable[i+256] = redMask;
-    }
-    for (i = 0; i < 135; i++) {
-       greenTable[i-135] = 0;
-       greenTable[i+256] = greenMask;
-    }
-    for (i = 0; i < 224; i++) {
-       blueTable[i-224] = 0;
-       blueTable[i+256] = blueMask;
-    }
-
-    for (i = 0; i < 256; i++) {
-       y = gamma[i];
-       redTable[i] = ((y >> redRight) << redLeft);
-       greenTable[i] = ((y >> greenRight) << greenLeft);
-       blueTable[i] = ((y >> blueRight) << blueLeft);
-    }
-
-    return 0;
-}
-
-static int rgbTable32 (int table [1935],
-                      int redMask, int greenMask, int blueMask,
-                      unsigned char gamma[256])
-{
-    int redRight;
-    int redLeft;
-    int greenRight;
-    int greenLeft;
-    int blueRight;
-    int blueLeft;
-    int * redTable;
-    int * greenTable;
-    int * blueTable;
-    int i;
-    int y;
-
-    if (colorMaskToShift (&redRight, &redLeft, redMask) ||
-       colorMaskToShift (&greenRight, &greenLeft, greenMask) ||
-       colorMaskToShift (&blueRight, &blueLeft, blueMask))
-       return 1;
-
-    /*
-     * green blue red +- 2 just to be sure
-     * green = 0-525 [151-370]
-     * blue = 594-1297 [834-1053] <834-29>
-     * red = 1323-1934 [1517-1736] <493-712>
-     */
-
-    redTable = table + 1501;
-    greenTable = table + 135;
-    blueTable = table + 818;
-
-    for (i = 0; i < 178; i++) {
-       redTable[i-178] = 0;
-       redTable[i+256] = redMask;
-    }
-    for (i = 0; i < 135; i++) {
-       greenTable[i-135] = 0;
-       greenTable[i+256] = greenMask;
-    }
-    for (i = 0; i < 224; i++) {
-       blueTable[i-224] = 0;
-       blueTable[i+256] = blueMask;
-    }
-
-    for (i = 0; i < 256; i++) {
-       y = gamma[i];
-       redTable[i] = ((y >> redRight) << redLeft);
-       greenTable[i] = ((y >> greenRight) << greenLeft);
-       blueTable[i] = ((y >> blueRight) << blueLeft);
-    }
-
-    return 0;
-}
-
-#define SHIFT 20
-#define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164))
-#define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164))
-#define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
-#define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
-
- void yuvToRgb16 (unsigned char * Y,
-                       unsigned char * U, unsigned char * V,
-                       short * dest, short table[1935], int width)
-{
-    int i;
-    int u;
-    int v;
-    int uvRed;
-    int uvGreen;
-    int uvBlue;
-    short * tableY;
-
-    i = width >> 4;
-    while (i--) {
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-    }
-
-    i = (width & 15) >> 1;
-    while (i--) {
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-    }
-
-    if (width & 1) {
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-    }
-}
-
-static void yuvToRgb24 (unsigned char * Y,
-                       unsigned char * U, unsigned char * V,
-                       char * dest, int table[1935], int width)
-{
-    int i;
-    int u;
-    int v;
-    int uvRed;
-    int uvGreen;
-    int uvBlue;
-    int * tableY;
-    int tmp24;
-
-    i = width >> 3;
-    while (i--) {
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                       uvGreen] |
-                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-       *(dest++) = tmp24;
-       *(dest++) = tmp24 >> 8;
-       *(dest++) = tmp24 >> 16;
-
-       tableY = table + *(Y++);
-       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                       uvGreen] |
-                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-       *(dest++) = tmp24;
-       *(dest++) = tmp24 >> 8;
-       *(dest++) = tmp24 >> 16;
-
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                       uvGreen] |
-                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-       *(dest++) = tmp24;
-       *(dest++) = tmp24 >> 8;
-       *(dest++) = tmp24 >> 16;
-
-       tableY = table + *(Y++);
-       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                       uvGreen] |
-                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-       *(dest++) = tmp24;
-       *(dest++) = tmp24 >> 8;
-       *(dest++) = tmp24 >> 16;
-
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                       uvGreen] |
-                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-       *(dest++) = tmp24;
-       *(dest++) = tmp24 >> 8;
-       *(dest++) = tmp24 >> 16;
-
-       tableY = table + *(Y++);
-       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                       uvGreen] |
-                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-       *(dest++) = tmp24;
-       *(dest++) = tmp24 >> 8;
-       *(dest++) = tmp24 >> 16;
-
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                       uvGreen] |
-                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-       *(dest++) = tmp24;
-       *(dest++) = tmp24 >> 8;
-       *(dest++) = tmp24 >> 16;
-
-       tableY = table + *(Y++);
-       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                       uvGreen] |
-                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-       *(dest++) = tmp24;
-       *(dest++) = tmp24 >> 8;
-       *(dest++) = tmp24 >> 16;
-    }
-
-    i = (width & 7) >> 1;
-    while (i--) {
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                       uvGreen] |
-                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-       *(dest++) = tmp24;
-       *(dest++) = tmp24 >> 8;
-       *(dest++) = tmp24 >> 16;
-
-       tableY = table + *(Y++);
-       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                       uvGreen] |
-                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-       *(dest++) = tmp24;
-       *(dest++) = tmp24 >> 8;
-       *(dest++) = tmp24 >> 16;
-    }
-
-    if (width & 1) {
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                       uvGreen] |
-                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-       *(dest++) = tmp24;
-       *(dest++) = tmp24 >> 8;
-       *(dest++) = tmp24 >> 16;
-    }
-}
-
-static void yuvToRgb32 (unsigned char * Y,
-                       unsigned char * U, unsigned char * V,
-                       int * dest, int table[1935], int width)
-{
-    int i;
-    int u;
-    int v;
-    int uvRed;
-    int uvGreen;
-    int uvBlue;
-    int * tableY;
-
-    i = width >> 4;
-    while (i--) {
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-    }
-
-    i = (width & 15) >> 1;
-    while (i--) {
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-    }
-
-    if (width & 1) {
-       u = *(U++);
-       v = *(V++);
-       uvRed = (V_RED_COEF*v) >> SHIFT;
-       uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
-       uvBlue = (U_BLUE_COEF*u) >> SHIFT;
-
-       tableY = table + *(Y++);
-       *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
-                    tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
-                           uvGreen] |
-                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
-    }
-}
-
-/* API routines */
-