1 /*****************************************************************************
2 * video_yuv8.c: YUV transformation functions for 8bpp
3 * Provides functions to perform the YUV conversion. The functions provided here
4 * are a complete and portable C implementation, and may be replaced in certain
5 * case by optimized functions.
6 *****************************************************************************
7 * Copyright (C) 1999, 2000 VideoLAN
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
21 * You should have received a copy of the GNU General Public
22 * License along with this program; if not, write to the
23 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 * Boston, MA 02111-1307, USA.
25 *****************************************************************************/
27 /*****************************************************************************
29 *****************************************************************************/
32 #include <math.h> /* exp(), pow() */
33 #include <errno.h> /* ENOMEM */
34 #include <stdlib.h> /* free() */
35 #include <string.h> /* strerror() */
43 #include "video_output.h"
44 #include "video_yuv.h"
45 #include "video_yuv_macros.h"
46 #include "video_yuv_macros_8bpp.h"
50 /*****************************************************************************
51 * ConvertY4Gray8: grayscale YUV 4:x:x to RGB 8 bpp
52 *****************************************************************************/
53 void ConvertY4Gray8( YUV_ARGS_8BPP )
55 boolean_t b_horizontal_scaling; /* horizontal scaling type */
56 int i_vertical_scaling; /* vertical scaling type */
57 int i_x, i_y; /* horizontal and vertical indexes */
58 int i_scale_count; /* scale modulo counter */
59 int i_chroma_width; /* chroma width, not used */
60 u8 * p_gray; /* base conversion table */
61 u8 * p_pic_start; /* beginning of the current line for copy */
62 u8 * p_buffer_start; /* conversion buffer start */
63 u8 * p_buffer; /* conversion buffer pointer */
64 int * p_offset_start; /* offset array start */
65 int * p_offset; /* offset array pointer */
68 * Initialize some values - i_pic_line_width will store the line skip
70 i_pic_line_width -= i_pic_width;
71 p_gray = p_vout->yuv.yuv.p_gray8;
72 p_buffer_start = p_vout->yuv.p_buffer;
73 p_offset_start = p_vout->yuv.p_offset;
74 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
75 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
80 i_scale_count = i_pic_height;
81 for( i_y = 0; i_y < i_height; i_y++ )
83 /* Mark beginnning of line for possible later line copy, and initialize
86 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
88 /* Do YUV conversion to buffer - YUV picture is always formed of 16
89 * pixels wide blocks */
90 for( i_x = i_width / 16; i_x--; )
92 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
93 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
94 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
95 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
96 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
97 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
98 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
99 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
102 /* Do horizontal and vertical scaling */
104 SCALE_HEIGHT(400, 1);
108 /*****************************************************************************
109 * ConvertYUV420RGB8: color YUV 4:2:0 to RGB 8 bpp
110 *****************************************************************************/
111 void ConvertYUV420RGB8( YUV_ARGS_8BPP )
113 boolean_t b_horizontal_scaling; /* horizontal scaling type */
114 int i_vertical_scaling; /* vertical scaling type */
115 int i_x, i_y; /* horizontal and vertical indexes */
116 int i_scale_count; /* scale modulo counter */
117 int b_jump_uv; /* should we jump u and v ? */
118 int i_real_y; /* y % 4 */
119 u8 * p_lookup; /* lookup table */
120 int i_chroma_width; /* chroma width */
121 int * p_offset_start; /* offset array start */
122 int * p_offset; /* offset array pointer */
125 * The dither matrices
127 int dither10[4] = { 0x0, 0x8, 0x2, 0xa };
128 int dither11[4] = { 0xc, 0x4, 0xe, 0x6 };
129 int dither12[4] = { 0x3, 0xb, 0x1, 0x9 };
130 int dither13[4] = { 0xf, 0x7, 0xd, 0x5 };
132 int dither20[4] = { 0x0, 0x10, 0x4, 0x14 };
133 int dither21[4] = { 0x18, 0x8, 0x1c, 0xc };
134 int dither22[4] = { 0x6, 0x16, 0x2, 0x12 };
135 int dither23[4] = { 0x1e, 0xe, 0x1a, 0xa };
138 * Initialize some values - i_pic_line_width will store the line skip
140 i_pic_line_width -= i_pic_width;
141 i_chroma_width = i_width / 2;
142 p_offset_start = p_vout->yuv.p_offset;
143 p_lookup = p_vout->yuv.p_base;
144 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
145 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
150 i_scale_count = i_pic_height;
152 for( i_y = 0; i_y < i_height; i_y++ )
154 /* Do horizontal and vertical scaling */
155 SCALE_WIDTH_DITHER( 420 );
156 SCALE_HEIGHT_DITHER( 420 );
160 /*****************************************************************************
161 * ConvertYUV422RGB8: color YUV 4:2:2 to RGB 8 bpp
162 *****************************************************************************/
163 void ConvertYUV422RGB8( YUV_ARGS_8BPP )
165 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 8\n" );
168 /*****************************************************************************
169 * ConvertYUV444RGB8: color YUV 4:4:4 to RGB 8 bpp
170 *****************************************************************************/
171 void ConvertYUV444RGB8( YUV_ARGS_8BPP )
173 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 8\n" );