]> git.sesse.net Git - vlc/commitdiff
Nettoyage, ajout du gamma, pr�paration de la yuv walken.
authorVincent Seguin <seguin@videolan.org>
Mon, 17 Jan 2000 16:43:04 +0000 (16:43 +0000)
committerVincent Seguin <seguin@videolan.org>
Mon, 17 Jan 2000 16:43:04 +0000 (16:43 +0000)
Makefile
include/config.h
include/video.h
include/video_output.h
include/video_sys.h
src/video_output/video_ggi.c
src/video_output/video_output.c
src/video_output/video_x11.c
src/video_output/video_yuv_c.c [new file with mode: 0644]
src/video_output/video_yuv_mmx.S [moved from src/video_output/yuv_mmx.S with 99% similarity]

index 0164579c242d32f7ee3a2ab8ac22feab791f5485..ea5907f08f365a3557e5118aeaa5c21f3d4ed688 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
@@ -64,6 +64,7 @@ endif
 # Libraries
 #
 LIB += -lpthread
+LIB += -lm
 
 ifeq ($(VIDEO),X11)
 LIB += -L/usr/X11R6/lib
@@ -211,7 +212,7 @@ misc_obj =                  misc/mtime.o \
 
 ifeq ($(ARCH),MMX)
 ASM_OBJ =                      video_decoder_ref/idctmmx.o \
-                                               video_output/yuv_mmx.o
+                                               video_output/video_yuv_mmx.o
 endif
 
 C_OBJ = $(interface_obj) \
index 7160bbd0892ec23e737d94ef6160f4f633e36b02..5779c166a7e03104efa6d5e1775587dd05219133 100644 (file)
 /* Base delay in micro second for interface sleeps */
 #define INTF_IDLE_SLEEP                 100000
 
+/* Factor for changing gamma, and minimum and maximum values */
+#define INTF_GAMMA_FACTOR               1.1
+#define INTF_GAMMA_MIN                  0.1
+#define INTF_GAMMA_MAX                  10
+
 /*
  * X11 settings
  */
 #define VOUT_GRAYSCALE_VAR              "vlc_grayscale"
 #define VOUT_GRAYSCALE_DEFAULT          0
 
+/* Default gamma */
+#define VOUT_GAMMA                      1.
+
 /*
  * Time settings
  */
index e1cdc88116815694de2b486ca6dbfac6f48dde33..7e056168dd79dcceba0088ab84669a212eaed85b 100644 (file)
@@ -57,7 +57,7 @@ typedef struct
      * (the pointer) should NEVER be modified. In YUV format, the p_y, p_u and
      * p_v data pointers refers to different areas of p_data, and should not
      * be freed */   
-    byte_t *        p_data;                                    /* picture data */
+    void *          p_data;                                    /* picture data */
     yuv_data_t *    p_y;          /* pointer to beginning of Y image in p_data */
     yuv_data_t *    p_u;          /* pointer to beginning of U image in p_data */
     yuv_data_t *    p_v;          /* pointer to beginning of V image in p_data */
index 1599ef75c2c99c86d381c12e1e71f24b2da219ff..e01c4cbde01ffd3405da6a912dd3aab1cbbbdd46 100644 (file)
@@ -34,9 +34,11 @@ typedef struct vout_thread_s
     int                 i_bytes_per_pixel;                /* real screen depth */
     float               f_x_ratio;                 /* horizontal display ratio */
     float               f_y_ratio;                   /* vertical display ratio */
+    float               f_gamma;                                      /* gamma */    
 
-    /* New size for resizeable windows - they may be ignored or handled by
-     * vout_SysManage */
+    /* Changed properties values - some of them are treated directly by the
+     * thread, the over may be ignored or handled by vout_SysManage */
+    boolean_t           b_gamma_change;              /* gamma change indicator */    
     int                 i_new_width;                              /* new width */    
     int                 i_new_height;                            /* new height */    
 
@@ -59,15 +61,16 @@ typedef struct vout_thread_s
     /* Video heap */
     picture_t           p_picture[VOUT_MAX_PICTURES];              /* pictures */
 
-    /* YUV translation tables, for 15,16 and 24/32 bpp displays. 16 bits and 32
-     * bits pointers points on the same data.
-     * CAUTION: these tables are translated: their origin is -384 */
-    u16 *               pi_trans16_red;
-    u16 *               pi_trans16_green;
-    u16 *               pi_trans16_blue;
-    u32 *               pi_trans32_red;
-    u32 *               pi_trans32_green;
-    u32 *               pi_trans32_blue;          
+    /* 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;
+    void *              p_trans_green;
+    void *              p_trans_blue;
+    void *              p_trans_gray;    
+
+    /* YUV translation tables, for optimized C YUV transform ?? */
 } vout_thread_t;
 
 /*******************************************************************************
index 090390c7d0a523359b75f98a3659fbd47e459123..1807f5c20fb4cb3540445380c7b840cde50f9177 100644 (file)
@@ -16,7 +16,7 @@ void         vout_SysEnd        ( p_vout_thread_t p_vout );
 void         vout_SysDestroy    ( p_vout_thread_t p_vout );
 int          vout_SysManage     ( p_vout_thread_t p_vout );
 void         vout_SysDisplay    ( p_vout_thread_t p_vout );
-byte_t *     vout_SysGetPicture ( p_vout_thread_t p_vout );
+void *       vout_SysGetPicture ( p_vout_thread_t p_vout );
 void         vout_SysPrint      ( p_vout_thread_t p_vout, int i_x, int i_y, 
                                   int i_halign, int i_valign,  
                                   unsigned char *psz_text );
index e4205b4a8d399ad755ad4806cfe14eb175364167..2f90586e560920cd7d1975b67976c783f9482963 100644 (file)
@@ -166,7 +166,7 @@ void vout_SysDisplay( vout_thread_t *p_vout )
  *******************************************************************************
  * This function returns the address of the current display buffer.
  *******************************************************************************/
-byte_t * vout_SysGetPicture( vout_thread_t *p_vout )
+void * vout_SysGetPicture( vout_thread_t *p_vout )
 {    
     return( p_vout->p_sys->p_buffer[ p_vout->p_sys->i_buffer_index ]->write );        
 }
index 6e37473173853c3b2c0d236d7042d1043827e61b..95562ff30c12b3beb3f7d55a7296608e29051bef 100644 (file)
@@ -10,7 +10,8 @@
 /*******************************************************************************
  * Preamble
  *******************************************************************************/
-#include <errno.h> 
+#include <errno.h>
+#include <math.h> 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
  * 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_RED, TRANS_GREEN, TRANS_BLUE, P_PIC )      \
+#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++)                 \
+    for (i_pic_x=0; i_pic_x< p_pic->i_width; i_pic_x+=16)               \
     {                                                                   \
-        i_y = *p_y++;                                                   \
-        *P_PIC++ = TRANS_RED[i_y] | TRANS_GREEN[i_y] | TRANS_BLUE[i_y]; \
+        /* 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;                                              \
@@ -66,7 +82,7 @@ for (i_pic_y=0; i_pic_y < p_pic->i_height ; i_pic_y++)                  \
 /* 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               \
+    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;                                 \
@@ -123,7 +139,7 @@ const int MATRIX_COEFFICIENTS_TABLE[8][4] =
  *      i_width, i_height:      frames dimensions (pixels)
  *      i_ypitch, i_vpitch:     Y and V lines sizes (bytes)
  *      i_aspect:               vertical aspect factor
- *      pi_pic:                 RGB frame
+ *      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)
@@ -131,7 +147,7 @@ const int MATRIX_COEFFICIENTS_TABLE[8][4] =
 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 *pi_pic, 
+                         unsigned int i_aspect, u8 *p_pic, 
                          u32 i_dci_offset, u32 i_offset_to_line_0,
                          int CCOPitch, int i_colortype );
 #endif
@@ -143,6 +159,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 );
@@ -192,6 +209,7 @@ vout_thread_t * vout_CreateThread               (
     p_vout->i_bytes_per_pixel   = 2;
     p_vout->f_x_ratio           = 1;
     p_vout->f_y_ratio           = 1;
+    p_vout->f_gamma             = VOUT_GAMMA;    
     intf_DbgMsg("wished configuration: %dx%d,%d (%d bytes/pixel, %d bytes/line), ratio %.2f:%.2f, gray=%d\n",
                 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,
@@ -224,6 +242,9 @@ vout_thread_t * vout_CreateThread               (
     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 );
@@ -516,7 +537,6 @@ void vout_UnlinkPicture( vout_thread_t *p_vout, picture_t *p_pic )
 static int InitThread( vout_thread_t *p_vout )
 {
     int     i_index;                                          /* generic index */    
-    int     i_pixel_size;     /* pixel size, in bytes, for translations tables */    
 
     /* Update status */
     *p_vout->pi_status = THREAD_START;    
@@ -536,94 +556,19 @@ static int InitThread( vout_thread_t *p_vout )
     } 
 
     /* Allocate translation tables */
-    switch( p_vout->i_bytes_per_pixel )
+    p_vout->p_trans_base = malloc( 4 * 1024 * p_vout->i_bytes_per_pixel );
+    if( p_vout->p_trans_base == NULL )
     {
-    case 2:                   /* 15 or 16 bpp, use 16 bits translations tables */        
-        i_pixel_size = sizeof( u16 );        
-        break;                
-    case 3:                   /* 24 or 32 bpp, use 32 bits translations tables */        
-    case 4:
-#ifndef DEBUG
-    default:        
-#endif
-        i_pixel_size = sizeof( u32 );
-        break;
-#ifdef DEBUG
-    default:
-        intf_DbgMsg("error: invalid bytes_per_pixel %d\n", p_vout->i_bytes_per_pixel );
-        i_pixel_size = sizeof( u32 );        
-        break;              
-#endif
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+        return( 1 );                
     }
-    p_vout->pi_trans32_red =   (u32 *)p_vout->pi_trans16_red =   
-        (u16 *)malloc( 1024 * i_pixel_size );
-    p_vout->pi_trans32_green = (u32 *)p_vout->pi_trans16_green = 
-        (u16 *)malloc( 1024 * i_pixel_size );
-    p_vout->pi_trans32_blue =  (u32 *)p_vout->pi_trans16_blue =  
-        (u16 *)malloc( 1024 * i_pixel_size );
-    if( (p_vout->pi_trans16_red == NULL) || 
-        (p_vout->pi_trans16_green == NULL ) ||
-        (p_vout->pi_trans16_blue == NULL ) )
-    {
-        intf_ErrMsg("error: %s\n", strerror(ENOMEM) );
-        *p_vout->pi_status = THREAD_ERROR;   
-        if( p_vout->pi_trans16_red != NULL )
-        {
-            free( p_vout->pi_trans16_red );
-        }
-        if( p_vout->pi_trans16_green != NULL )
-        {
-            free( p_vout->pi_trans16_green );
-        }
-        if( p_vout->pi_trans16_blue != NULL )
-        {
-            free( p_vout->pi_trans16_blue );
-        }
-        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;
     
-    /* Translate translation tables */
-    p_vout->pi_trans16_red      += 384;
-    p_vout->pi_trans16_green    += 384;
-    p_vout->pi_trans16_blue     += 384;
-    p_vout->pi_trans32_red      += 384;
-    p_vout->pi_trans32_green    += 384;
-    p_vout->pi_trans32_blue     += 384;
-
     /* Build translation tables */
-    switch( p_vout->i_screen_depth )
-    {
-    case 15:
-        for( i_index = -384; i_index < 640; i_index++) 
-        {
-            p_vout->pi_trans16_red[i_index]     = (CLIP_BYTE( i_index ) & 0xf8)<<7;
-            p_vout->pi_trans16_green[i_index]   = (CLIP_BYTE( i_index ) & 0xf8)<<2;
-            p_vout->pi_trans16_blue[i_index]    =  CLIP_BYTE( i_index ) >> 3;
-        }
-        break;        
-    case 16:
-        for( i_index = -384; i_index < 640; i_index++) 
-        {
-            p_vout->pi_trans16_red[i_index]     = (CLIP_BYTE( i_index ) & 0xf8)<<8;
-            p_vout->pi_trans16_green[i_index]   = (CLIP_BYTE( i_index ) & 0xfc)<<3;
-            p_vout->pi_trans16_blue[i_index]    =  CLIP_BYTE( i_index ) >> 3;
-        }
-        break;        
-    case 24:
-    case 32:        
-        for( i_index = -384; i_index < 640; i_index++) 
-        {
-            p_vout->pi_trans32_red[i_index]     =  CLIP_BYTE( i_index ) <<16;
-            p_vout->pi_trans32_green[i_index]   =  CLIP_BYTE( i_index ) <<8;
-            p_vout->pi_trans32_blue[i_index]    =  CLIP_BYTE( i_index ) ;
-        }
-        break;        
-#ifdef DEBUG
-    default:
-        intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
-        break;      
-#endif
-    }
+    BuildTables( p_vout );
     
     /* Mark thread as running and return */
     p_vout->b_active =          1;    
@@ -725,6 +670,15 @@ static void RunThread( vout_thread_t *p_vout)
            }
         }
 
+        /* 
+         * Rebuild tables if gamma has changed
+         */
+        if( p_vout->b_gamma_change )
+        {
+            p_vout->b_gamma_change = 0;            
+            BuildTables( p_vout );            
+        }        
+
         /*
          * Check events, sleep and display picture
         */
@@ -844,10 +798,8 @@ static void EndThread( vout_thread_t *p_vout )
         }
     }
 
-    /* Destroy translation tables - remeber these tables are translated */    
-    free( p_vout->pi_trans16_red - 384 );
-    free( p_vout->pi_trans16_green - 384 );
-    free( p_vout->pi_trans16_blue - 384 );
+    /* Destroy translation tables */
+    free( p_vout->p_trans_base );
     
     /* Destroy thread structures allocated by InitThread */
     vout_SysEnd( p_vout );
@@ -858,6 +810,72 @@ 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
+    } 
+}
+
 /*******************************************************************************
  * RenderPicture: render a picture
  *******************************************************************************
@@ -890,7 +908,7 @@ static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
         {
             RenderYUV16Picture( p_vout, p_pic );        
         }
-        else                                             /* color 24 or 32 bpp */
+        else if( p_vout->i_bytes_per_pixel == 4 )              /* color 32 bpp */
         {
             RenderYUV32Picture( p_vout, p_pic );            
         }
@@ -909,7 +927,7 @@ static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
 }
 
 /*******************************************************************************
- * RenderYUVGrayPicture: render a 15, 16, 24 or 32 bpp YUV picture in grayscale
+ * 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.
@@ -920,15 +938,10 @@ static void RenderYUVGrayPicture( vout_thread_t *p_vout, picture_t *p_pic )
     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 */
-    yuv_data_t  i_y;                                               /* Y sample */
-    u16 *       pi_pic16;                 /* destination picture, 15 or 16 bpp */
-    u32 *       pi_pic32;                 /* destination picture, 24 or 32 bpp */
-    u16 *       pi_trans16_red;                    /* red transformation table */
-    u16 *       pi_trans16_green;                /* green transformation table */
-    u16 *       pi_trans16_blue;                  /* blue transformation table */
-    u32 *       pi_trans32_red;                    /* red transformation table */
-    u32 *       pi_trans32_green;                /* green transformation table */
-    u32 *       pi_trans32_blue;                  /* blue transformation table */
+    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;
@@ -942,23 +955,14 @@ static void RenderYUVGrayPicture( vout_thread_t *p_vout, picture_t *p_pic )
     {
     case 15:
     case 16:
-        pi_trans16_red =      p_vout->pi_trans16_red;
-        pi_trans16_green =    p_vout->pi_trans16_green;
-        pi_trans16_blue =     p_vout->pi_trans16_blue;        
-        pi_pic16 = (u16 *) vout_SysGetPicture( p_vout );
-
-        YUV_GRAYSCALE( pi_trans16_red, pi_trans16_green, pi_trans16_blue,
-                       pi_pic16 );
+        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 24:        
     case 32:
-        pi_trans32_red =      p_vout->pi_trans32_red;
-        pi_trans32_green =    p_vout->pi_trans32_green;
-        pi_trans32_blue =     p_vout->pi_trans32_blue;    
-        pi_pic32 = (u32 *) vout_SysGetPicture( p_vout );
-
-        YUV_GRAYSCALE( pi_trans32_red, pi_trans32_green, pi_trans32_blue,
-                       pi_pic32 );
+        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:
@@ -986,10 +990,10 @@ static void RenderYUV16Picture( vout_thread_t *p_vout, picture_t *p_pic )
     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 *       pi_pic;                 /* base adress for destination picture */
-    u16 *       pi_trans_red;                      /* red transformation table */
-    u16 *       pi_trans_green;                  /* green transformation table */
-    u16 *       pi_trans_blue;                    /* blue transformation table */
+    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];
@@ -997,10 +1001,11 @@ static void RenderYUV16Picture( vout_thread_t *p_vout, picture_t *p_pic )
     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 */
-    pi_trans_red =      p_vout->pi_trans16_red;
-    pi_trans_green =    p_vout->pi_trans16_green;
-    pi_trans_blue =     p_vout->pi_trans16_blue;    
+    /* 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;
@@ -1011,9 +1016,6 @@ static void RenderYUV16Picture( vout_thread_t *p_vout, picture_t *p_pic )
     i_chroma_width =    i_width / 2;
     i_eol_offset =      p_vout->i_bytes_per_line / 2 - i_width;    
         
-    /* Get base adress for destination image */
-    pi_pic = (u16 *)vout_SysGetPicture( p_vout );
-
     /* Do YUV transformation - the loops are repeated for optimization */
     switch( p_pic->i_type )
     {
@@ -1022,36 +1024,36 @@ static void RenderYUV16Picture( vout_thread_t *p_vout, picture_t *p_pic )
         vout_YUV420_16_MMX( p_y, p_u, p_v, 
                             i_width, i_height, 
                             i_width, i_chroma_width,
-                            0, (u8 *) pi_pic
+                            0, p_data
                             0, 0, p_vout->i_bytes_per_line, 
                             p_vout->i_screen_depth == 15 );
 #else
         YUV_TRANSFORM( 420,
-                       pi_trans_red, 
-                       pi_trans_green, 
-                       pi_trans_blue,
-                       pi_pic );            
+                       p_trans_red, 
+                       p_trans_green, 
+                       p_trans_blue,
+                       p_data );            
 #endif
         break;
     case YUV_422_PICTURE:                   /* 15 or 16 bpp 422 transformation */
         YUV_TRANSFORM( 422,
-                       pi_trans_red, 
-                       pi_trans_green, 
-                       pi_trans_blue,
-                       pi_pic );            
+                       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,
-                       pi_trans_red, 
-                       pi_trans_green, 
-                       pi_trans_blue,
-                       pi_pic );            
+                       p_trans_red, 
+                       p_trans_green, 
+                       p_trans_blue,
+                       p_data );            
         break;                 
     }
 }
 
 /*******************************************************************************
- * RenderYUV32Picture: render a 24 or 32 bpp YUV picture
+ * 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.
@@ -1067,10 +1069,10 @@ static void RenderYUV32Picture( vout_thread_t *p_vout, picture_t *p_pic )
     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 *       pi_pic;                 /* base adress for destination picture */
-    u32 *       pi_trans_red;                      /* red transformation table */
-    u32 *       pi_trans_green;                  /* green transformation table */
-    u32 *       pi_trans_blue;                    /* blue transformation table */
+    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];
@@ -1078,10 +1080,11 @@ static void RenderYUV32Picture( vout_thread_t *p_vout, picture_t *p_pic )
     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 */
-    pi_trans_red =      p_vout->pi_trans32_red;
-    pi_trans_green =    p_vout->pi_trans32_green;
-    pi_trans_blue =     p_vout->pi_trans32_blue;    
+    /* 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;
@@ -1092,32 +1095,29 @@ static void RenderYUV32Picture( vout_thread_t *p_vout, picture_t *p_pic )
     i_chroma_width =    i_width / 2;
     i_eol_offset =      p_vout->i_bytes_per_line / p_vout->i_bytes_per_pixel - i_width;
         
-    /* Get base adress for destination image */
-    pi_pic = (u32 *)vout_SysGetPicture( p_vout );
-
     /* Do YUV transformation - the loops are repeated for optimization */
     switch( p_pic->i_type )
     {
-    case YUV_420_PICTURE:                   /* 24 or 32 bpp 420 transformation */
+    case YUV_420_PICTURE:                         /* 32 bpp 420 transformation */
         YUV_TRANSFORM( 420,
-                       pi_trans_red, 
-                       pi_trans_green, 
-                       pi_trans_blue,
-                       pi_pic );            
+                       p_trans_red, 
+                       p_trans_green, 
+                       p_trans_blue,
+                       p_data );            
         break;
-    case YUV_422_PICTURE:                   /* 24 or 32 bpp 422 transformation */
+    case YUV_422_PICTURE:                         /* 32 bpp 422 transformation */
         YUV_TRANSFORM( 422,
-                       pi_trans_red, 
-                       pi_trans_green, 
-                       pi_trans_blue,
-                       pi_pic );            
+                       p_trans_red, 
+                       p_trans_green, 
+                       p_trans_blue,
+                       p_data );            
         break;
-    case YUV_444_PICTURE:                   /* 24 or 32 bpp 444 transformation */
+    case YUV_444_PICTURE:                         /* 32 bpp 444 transformation */
         YUV_TRANSFORM( 444,
-                       pi_trans_red, 
-                       pi_trans_green, 
-                       pi_trans_blue,
-                       pi_pic );            
+                       p_trans_red, 
+                       p_trans_green, 
+                       p_trans_blue,
+                       p_data );            
         break;                 
     }
 }
@@ -1147,8 +1147,8 @@ static void RenderInfo( vout_thread_t *p_vout )
     }
 
     /* Print statistics in upper left corner */
-    sprintf( psz_buffer, "%ld frames (%.1f %% idle)", p_vout->c_fps_samples,
-             p_vout->c_loops ? 
+    sprintf( psz_buffer, "gamma=%.2f   %ld frames (%.1f %% idle)", 
+             p_vout->f_gamma, p_vout->c_fps_samples, p_vout->c_loops ? 
              (double ) p_vout->c_idle_loops * 100 / p_vout->c_loops : 100. );    
     vout_SysPrint( p_vout, 0, 0, -1, -1, psz_buffer );    
 #endif
index 7415cb3fb1bed6fa2a2e5fb79efb65748ce06dea..b406e0a9e28bad6457b59588fc15846e992ac3bd 100644 (file)
@@ -275,7 +275,7 @@ void vout_SysDisplay( vout_thread_t *p_vout )
  *******************************************************************************
  * This function returns the address of the current display buffer.
  *******************************************************************************/
-byte_t * vout_SysGetPicture( vout_thread_t *p_vout )
+void * vout_SysGetPicture( vout_thread_t *p_vout )
 {
     return( p_vout->p_sys->p_ximage[ p_vout->p_sys->i_buffer_index ]->data );        
 }
@@ -407,10 +407,6 @@ static int X11OpenDisplay( vout_thread_t *p_vout, char *psz_display, Window root
         return( 1 );
     }
 
-    /* Store additionnal vout informations */
-    p_vout->i_new_width =       p_vout->i_width;
-    p_vout->i_new_height =      p_vout->i_height;    
-
     /* Get font information */
     if( X11GetFont( p_vout ) )
     {
diff --git a/src/video_output/video_yuv_c.c b/src/video_output/video_yuv_c.c
new file mode 100644 (file)
index 0000000..3573b36
--- /dev/null
@@ -0,0 +1,837 @@
+/*******************************************************************************
+ * 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.
+ */
+
+static 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))
+
+static 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 */
+
+int convertGrey (CONVERTER * convert, DISPLAY * disp)
+{
+    if ((convert == NULL) || (disp == NULL))
+       return 1;
+
+    if (greyRgbTable (disp))
+       return 1;
+
+    switch (disp->bytesPerPixel) {
+    case 2:
+       convert->convert = &greyToRgb16;
+       break;
+    case 3:
+       convert->convert = &greyToRgb24;
+       break;
+    case 4:
+       convert->convert = &greyToRgb32;
+       break;
+    default:
+       return 1;
+    }
+    convert->table = disp->greyRgbTable;
+    return 0;
+}
+
+static void * greyRgbTable (DISP_COLORS * colors, unsigned char gamma[256])
+{
+    /* FIXME could avoid recalculating the same table */
+    void * table;
+
+       for (i = 0; i < 16; i++)
+           gamma[i] = 0;
+#define Y_COEF ((int)(1.164 * 65536))
+       for (; i <= 235; i++)
+           gamma[i] = (Y_COEF * i - Y_COEF * 16) >> 16;
+#undef Y_COEF
+       for (; i < 256; i++)
+           gamma[i] = 255;
+    }
+
+    switch (colors->bytesPerPixel) {
+    case 2:
+       table = malloc (256 * sizeof (short));
+       if (table == NULL)
+           break;
+       if (greyRgb16Table (table,
+                           colors->redMask,
+                           colors->greenMask,
+                           colors->blueMask,
+                           gamma))
+           goto error;
+       return table;
+    case 3:
+    case 4:
+       table = malloc (256 * sizeof (int));
+       if (table == NULL)
+           break;
+       if (greyRgb32Table (table,
+                           colors->redMask,
+                           colors->greenMask,
+                           colors->blueMask,
+                           gamma))
+           goto error;
+       return table;
+    error:
+       free (table);
+    }
+
+    return NULL;
+}
+
+static void * rgbTable (DISP_COLORS * colors, unsigned char gamma[256])
+{
+    /* FIXME could avoid recalculating the same table */
+    void * table;
+
+    switch (colors->bytesPerPixel) {
+    case 2:
+       table = malloc (1935 * sizeof (short));
+       if (table == NULL)
+           break;
+       if (rgbTable16 (table,
+                       colors->redMask, colors->greenMask, colors->blueMask,
+                       gamma))
+           goto error;
+       return table;
+    case 3:
+    case 4:
+       table = malloc (1935 * sizeof (int));
+       if (table == NULL)
+           break;
+       if (rgbTable32 (table,
+                       colors->redMask, colors->greenMask, colors->blueMask,
+                       gamma))
+           goto error;
+       return table;
+    error:
+       free (table);
+    }
+
+    return NULL;
+}
similarity index 99%
rename from src/video_output/yuv_mmx.S
rename to src/video_output/video_yuv_mmx.S
index 9b855153f468ba2516332be9034f279c529d4f60..0b3c9db7af3ec96dd684f95a79756621a0e890fa 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * yuv_mmx.S: YUV transformation, optimized for MMX processors
+ * video_yuv_mmx.S: YUV transformation, optimized for MMX processors
  * (c)1999 VideoLAN
  *******************************************************************************
  * Following functions are defined: