Nettoyage des YUV.
Ne marche qu'en -g pour le moment, le reste arrive.
# Target architecture and optimization
#ARCH=
-ARCH=MMX
+#ARCH=MMX
#ARCH=PPC
# Decoder choice - ?? old decoder will be removed soon
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 \
/* 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
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 */
* 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 */
#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;
/*******************************************************************************
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 );
--- /dev/null
+/*******************************************************************************
+ * 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 );
+
* 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
*******************************************************************************/
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 );
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
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 );
* 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 */
{
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",
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:
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
{
/* 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 ) )
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;
* 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;
}
}
*/
if( p_vout->b_gamma_change )
{
+ //??
p_vout->b_gamma_change = 0;
- BuildTables( p_vout );
+ vout_ResetTables( p_vout ); // ?? test return value
}
/*
}
/* Destroy translation tables */
- free( p_vout->p_trans_base );
+ vout_EndTables( p_vout );
/* Destroy thread structures allocated by InitThread */
vout_SysEnd( 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
*******************************************************************************
* 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
#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 );
#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
--- /dev/null
+/*******************************************************************************
+ * 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 */
+
+++ /dev/null
-/*******************************************************************************
- * 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 */
-