You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
161 lines
11 KiB
161 lines
11 KiB
/*****************************************************************************
|
|
* video_yuv_macros_truecolor.h: YUV transformation macros for truecolor
|
|
*****************************************************************************
|
|
* Copyright (C) 1999, 2000 VideoLAN
|
|
*
|
|
* Authors:
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public
|
|
* License along with this program; if not, write to the
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
* Boston, MA 02111-1307, USA.
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
* CONVERT_YUV_PIXEL, CONVERT_Y_PIXEL: pixel conversion blocks
|
|
*****************************************************************************
|
|
* These conversion routines are used by YUV conversion functions.
|
|
* conversion are made from p_y, p_u, p_v, which are modified, to p_buffer,
|
|
* which is also modified.
|
|
*****************************************************************************/
|
|
#define CONVERT_Y_PIXEL( BPP ) \
|
|
/* Only Y sample is present */ \
|
|
p_ybase = p_yuv + *p_y++; \
|
|
*p_buffer++ = p_ybase[RED_OFFSET-((V_RED_COEF*128)>>SHIFT) + i_red] | \
|
|
p_ybase[GREEN_OFFSET-(((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) \
|
|
+ i_green ] | p_ybase[BLUE_OFFSET-((U_BLUE_COEF*128)>>SHIFT) + i_blue];
|
|
|
|
#define CONVERT_YUV_PIXEL( BPP ) \
|
|
/* Y, U and V samples are present */ \
|
|
i_uval = *p_u++; \
|
|
i_vval = *p_v++; \
|
|
i_red = (V_RED_COEF * i_vval) >> SHIFT; \
|
|
i_green = (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT; \
|
|
i_blue = (U_BLUE_COEF * i_uval) >> SHIFT; \
|
|
CONVERT_Y_PIXEL( BPP ) \
|
|
|
|
/*****************************************************************************
|
|
* SCALE_WIDTH: scale a line horizontally
|
|
*****************************************************************************
|
|
* This macro scales a line using rendering buffer and offset array. It works
|
|
* for 1, 2 and 4 Bpp.
|
|
*****************************************************************************/
|
|
#define SCALE_WIDTH \
|
|
if( b_horizontal_scaling ) \
|
|
{ \
|
|
/* Horizontal scaling, conversion has been done to buffer. \
|
|
* Rewind buffer and offset, then copy and scale line */ \
|
|
p_buffer = p_buffer_start; \
|
|
p_offset = p_offset_start; \
|
|
for( i_x = i_pic_width / 16; i_x--; ) \
|
|
{ \
|
|
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
|
|
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
|
|
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
|
|
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
|
|
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
|
|
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
|
|
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
|
|
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
|
|
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
|
|
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
|
|
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
|
|
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
|
|
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
|
|
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
|
|
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
|
|
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
|
|
} \
|
|
p_pic += i_pic_line_width; \
|
|
} \
|
|
else \
|
|
{ \
|
|
/* No scaling, conversion has been done directly in picture memory. \
|
|
* Increment of picture pointer to end of line is still needed */ \
|
|
p_pic += i_pic_width + i_pic_line_width; \
|
|
} \
|
|
|
|
/*****************************************************************************
|
|
* SCALE_HEIGHT: handle vertical scaling
|
|
*****************************************************************************
|
|
* This macro handle vertical scaling for a picture. CHROMA may be 420, 422 or
|
|
* 444 for RGB conversion, or 400 for gray conversion. It works for 1, 2, 3
|
|
* and 4 Bpp.
|
|
*****************************************************************************/
|
|
#define SCALE_HEIGHT( CHROMA, BPP ) \
|
|
/* If line is odd, rewind 4:2:0 U and V samples */ \
|
|
if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
|
|
{ \
|
|
p_u -= i_chroma_width; \
|
|
p_v -= i_chroma_width; \
|
|
} \
|
|
\
|
|
/* \
|
|
* Handle vertical scaling. The current line can be copied or next one \
|
|
* can be ignored. \
|
|
*/ \
|
|
switch( i_vertical_scaling ) \
|
|
{ \
|
|
case -1: /* vertical scaling factor is < 1 */ \
|
|
while( (i_scale_count -= i_pic_height) > 0 ) \
|
|
{ \
|
|
/* Height reduction: skip next source line */ \
|
|
p_y += i_width; \
|
|
i_y++; \
|
|
if( (CHROMA == 420) || (CHROMA == 422) ) \
|
|
{ \
|
|
if( i_y & 0x1 ) \
|
|
{ \
|
|
p_u += i_chroma_width; \
|
|
p_v += i_chroma_width; \
|
|
} \
|
|
} \
|
|
else if( CHROMA == 444 ) \
|
|
{ \
|
|
p_u += i_width; \
|
|
p_v += i_width; \
|
|
} \
|
|
} \
|
|
i_scale_count += i_height; \
|
|
break; \
|
|
case 1: /* vertical scaling factor is > 1 */ \
|
|
while( (i_scale_count -= i_height) > 0 ) \
|
|
{ \
|
|
/* Height increment: copy previous picture line */ \
|
|
for( i_x = i_pic_width / 16; i_x--; ) \
|
|
{ \
|
|
*(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
|
|
*(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
|
|
if( BPP > 1 ) /* 2, 3, 4 Bpp */ \
|
|
{ \
|
|
*(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
|
|
*(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
|
|
} \
|
|
if( BPP > 2 ) /* 3, 4 Bpp */ \
|
|
{ \
|
|
*(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
|
|
*(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
|
|
} \
|
|
if( BPP > 3 ) /* 4 Bpp */ \
|
|
{ \
|
|
*(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
|
|
*(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
|
|
} \
|
|
} \
|
|
p_pic += i_pic_line_width; \
|
|
p_pic_start += i_pic_line_width; \
|
|
} \
|
|
i_scale_count += i_pic_height; \
|
|
break; \
|
|
} \
|
|
|
|
|