1 /*****************************************************************************
2 * video_yuv16.c: YUV transformation functions for 16bpp
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"
49 /*****************************************************************************
50 * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 2 Bpp
51 *****************************************************************************/
52 void ConvertY4Gray16( YUV_ARGS_16BPP )
54 boolean_t b_horizontal_scaling; /* horizontal scaling type */
55 int i_vertical_scaling; /* vertical scaling type */
56 int i_x, i_y; /* horizontal and vertical indexes */
57 int i_scale_count; /* scale modulo counter */
58 int i_chroma_width; /* chroma width, not used */
59 u16 * p_gray; /* base conversion table */
60 u16 * p_pic_start; /* beginning of the current line for copy */
61 u16 * p_buffer_start; /* conversion buffer start */
62 u16 * p_buffer; /* conversion buffer pointer */
63 int * p_offset_start; /* offset array start */
64 int * p_offset; /* offset array pointer */
67 * Initialize some values - i_pic_line_width will store the line skip
69 i_pic_line_width -= i_pic_width;
70 p_gray = p_vout->yuv.yuv.p_gray16;
71 p_buffer_start = p_vout->yuv.p_buffer;
72 p_offset_start = p_vout->yuv.p_offset;
73 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
74 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
81 i_scale_count = i_pic_height;
82 for( i_y = 0; i_y < i_height; i_y++ )
84 /* Mark beginnning of line for possible later line copy, and initialize
87 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
89 /* Do YUV conversion to buffer - YUV picture is always formed of 16
90 * pixels wide blocks */
91 for( i_x = i_width / 16; i_x--; )
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++ ];
100 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
103 /* Do horizontal and vertical scaling */
105 SCALE_HEIGHT(400, 2);
109 /*****************************************************************************
110 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 2 Bpp
111 *****************************************************************************/
112 void ConvertYUV420RGB16( YUV_ARGS_16BPP )
114 boolean_t b_horizontal_scaling; /* horizontal scaling type */
115 int i_vertical_scaling; /* vertical scaling type */
116 int i_x, i_y; /* horizontal and vertical indexes */
117 int i_scale_count; /* scale modulo counter */
118 int i_uval, i_vval; /* U and V samples */
119 int i_red, i_green, i_blue; /* U and V modified samples */
120 int i_chroma_width; /* chroma width */
121 u16 * p_yuv; /* base conversion table */
122 u16 * p_ybase; /* Y dependant conversion table */
123 u16 * p_pic_start; /* beginning of the current line for copy */
124 u16 * p_buffer_start; /* conversion buffer start */
125 u16 * p_buffer; /* conversion buffer pointer */
126 int * p_offset_start; /* offset array start */
127 int * p_offset; /* offset array pointer */
130 * Initialize some values - i_pic_line_width will store the line skip
132 i_pic_line_width -= i_pic_width;
133 i_chroma_width = i_width / 2;
134 p_yuv = p_vout->yuv.yuv.p_rgb16;
135 p_buffer_start = p_vout->yuv.p_buffer;
136 p_offset_start = p_vout->yuv.p_offset;
137 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
138 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
143 i_scale_count = i_pic_height;
144 for( i_y = 0; i_y < i_height; i_y++ )
146 /* Mark beginnning of line for possible later line copy, and initialize
149 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
151 /* Do YUV conversion to buffer - YUV picture is always formed of 16
152 * pixels wide blocks */
153 for( i_x = i_width / 16; i_x--; )
155 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
156 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
157 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
158 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
159 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
160 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
161 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
162 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
165 /* Do horizontal and vertical scaling */
167 SCALE_HEIGHT(420, 2);
171 /*****************************************************************************
172 * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 2 Bpp
173 *****************************************************************************/
174 void ConvertYUV422RGB16( YUV_ARGS_16BPP )
176 boolean_t b_horizontal_scaling; /* horizontal scaling type */
177 int i_vertical_scaling; /* vertical scaling type */
178 int i_x, i_y; /* horizontal and vertical indexes */
179 int i_scale_count; /* scale modulo counter */
180 int i_uval, i_vval; /* U and V samples */
181 int i_red, i_green, i_blue; /* U and V modified samples */
182 int i_chroma_width; /* chroma width */
183 u16 * p_yuv; /* base conversion table */
184 u16 * p_ybase; /* Y dependant conversion table */
185 u16 * p_pic_start; /* beginning of the current line for copy */
186 u16 * p_buffer_start; /* conversion buffer start */
187 u16 * p_buffer; /* conversion buffer pointer */
188 int * p_offset_start; /* offset array start */
189 int * p_offset; /* offset array pointer */
192 * Initialize some values - i_pic_line_width will store the line skip
194 i_pic_line_width -= i_pic_width;
195 i_chroma_width = i_width / 2;
196 p_yuv = p_vout->yuv.yuv.p_rgb16;
197 p_buffer_start = p_vout->yuv.p_buffer;
198 p_offset_start = p_vout->yuv.p_offset;
199 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
200 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
205 i_scale_count = i_pic_height;
206 for( i_y = 0; i_y < i_height; i_y++ )
208 /* Mark beginnning of line for possible later line copy, and initialize
211 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
213 /* Do YUV conversion to buffer - YUV picture is always formed of 16
214 * pixels wide blocks */
215 for( i_x = i_width / 16; i_x--; )
217 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
218 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
219 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
220 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
221 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
222 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
223 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
224 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
227 /* Do horizontal and vertical scaling */
229 SCALE_HEIGHT(422, 2);
233 /*****************************************************************************
234 * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 2 Bpp
235 *****************************************************************************/
236 void ConvertYUV444RGB16( YUV_ARGS_16BPP )
238 boolean_t b_horizontal_scaling; /* horizontal scaling type */
239 int i_vertical_scaling; /* vertical scaling type */
240 int i_x, i_y; /* horizontal and vertical indexes */
241 int i_scale_count; /* scale modulo counter */
242 int i_uval, i_vval; /* U and V samples */
243 int i_red, i_green, i_blue; /* U and V modified samples */
244 int i_chroma_width; /* chroma width, not used */
245 u16 * p_yuv; /* base conversion table */
246 u16 * p_ybase; /* Y dependant conversion table */
247 u16 * p_pic_start; /* beginning of the current line for copy */
248 u16 * p_buffer_start; /* conversion buffer start */
249 u16 * p_buffer; /* conversion buffer pointer */
250 int * p_offset_start; /* offset array start */
251 int * p_offset; /* offset array pointer */
254 * Initialize some values - i_pic_line_width will store the line skip
256 i_pic_line_width -= i_pic_width;
257 p_yuv = p_vout->yuv.yuv.p_rgb16;
258 p_buffer_start = p_vout->yuv.p_buffer;
259 p_offset_start = p_vout->yuv.p_offset;
260 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
261 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
266 i_scale_count = i_pic_height;
267 for( i_y = 0; i_y < i_height; i_y++ )
269 /* Mark beginnning of line for possible later line copy, and initialize
272 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
274 /* Do YUV conversion to buffer - YUV picture is always formed of 16
275 * pixels wide blocks */
276 for( i_x = i_width / 16; i_x--; )
278 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
279 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
280 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
281 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
282 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
283 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
284 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
285 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
288 /* Do horizontal and vertical scaling */
290 SCALE_HEIGHT(444, 2);