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 );
79 i_scale_count = i_pic_height;
80 for( i_y = 0; i_y < i_height; i_y++ )
82 /* Mark beginnning of line for possible later line copy, and initialize
85 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
87 /* Do YUV conversion to buffer - YUV picture is always formed of 16
88 * pixels wide blocks */
89 for( i_x = i_width / 16; i_x--; )
91 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
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++ ];
101 /* Do horizontal and vertical scaling */
103 SCALE_HEIGHT(400, 2);
107 /*****************************************************************************
108 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 2 Bpp
109 *****************************************************************************/
110 void ConvertYUV420RGB16( YUV_ARGS_16BPP )
112 boolean_t b_horizontal_scaling; /* horizontal scaling type */
113 int i_vertical_scaling; /* vertical scaling type */
114 int i_x, i_y; /* horizontal and vertical indexes */
115 int i_scale_count; /* scale modulo counter */
116 int i_uval, i_vval; /* U and V samples */
117 int i_red, i_green, i_blue; /* U and V modified samples */
118 int i_chroma_width; /* chroma width */
119 u16 * p_yuv; /* base conversion table */
120 u16 * p_ybase; /* Y dependant conversion table */
121 u16 * p_pic_start; /* beginning of the current line for copy */
122 u16 * p_buffer_start; /* conversion buffer start */
123 u16 * p_buffer; /* conversion buffer pointer */
124 int * p_offset_start; /* offset array start */
125 int * p_offset; /* offset array pointer */
128 * Initialize some values - i_pic_line_width will store the line skip
130 i_pic_line_width -= i_pic_width;
131 i_chroma_width = i_width / 2;
132 p_yuv = p_vout->yuv.yuv.p_rgb16;
133 p_buffer_start = p_vout->yuv.p_buffer;
134 p_offset_start = p_vout->yuv.p_offset;
135 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
136 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
141 i_scale_count = i_pic_height;
142 for( i_y = 0; i_y < i_height; i_y++ )
144 /* Mark beginnning of line for possible later line copy, and initialize
147 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
149 /* Do YUV conversion to buffer - YUV picture is always formed of 16
150 * pixels wide blocks */
151 for( i_x = i_width / 16; i_x--; )
153 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
154 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
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);
163 /* Do horizontal and vertical scaling */
165 SCALE_HEIGHT(420, 2);
169 /*****************************************************************************
170 * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 2 Bpp
171 *****************************************************************************/
172 void ConvertYUV422RGB16( YUV_ARGS_16BPP )
174 boolean_t b_horizontal_scaling; /* horizontal scaling type */
175 int i_vertical_scaling; /* vertical scaling type */
176 int i_x, i_y; /* horizontal and vertical indexes */
177 int i_scale_count; /* scale modulo counter */
178 int i_uval, i_vval; /* U and V samples */
179 int i_red, i_green, i_blue; /* U and V modified samples */
180 int i_chroma_width; /* chroma width */
181 u16 * p_yuv; /* base conversion table */
182 u16 * p_ybase; /* Y dependant conversion table */
183 u16 * p_pic_start; /* beginning of the current line for copy */
184 u16 * p_buffer_start; /* conversion buffer start */
185 u16 * p_buffer; /* conversion buffer pointer */
186 int * p_offset_start; /* offset array start */
187 int * p_offset; /* offset array pointer */
190 * Initialize some values - i_pic_line_width will store the line skip
192 i_pic_line_width -= i_pic_width;
193 i_chroma_width = i_width / 2;
194 p_yuv = p_vout->yuv.yuv.p_rgb16;
195 p_buffer_start = p_vout->yuv.p_buffer;
196 p_offset_start = p_vout->yuv.p_offset;
197 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
198 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
203 i_scale_count = i_pic_height;
204 for( i_y = 0; i_y < i_height; i_y++ )
206 /* Mark beginnning of line for possible later line copy, and initialize
209 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
211 /* Do YUV conversion to buffer - YUV picture is always formed of 16
212 * pixels wide blocks */
213 for( i_x = i_width / 16; i_x--; )
215 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
216 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
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);
225 /* Do horizontal and vertical scaling */
227 SCALE_HEIGHT(422, 2);
231 /*****************************************************************************
232 * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 2 Bpp
233 *****************************************************************************/
234 void ConvertYUV444RGB16( YUV_ARGS_16BPP )
236 boolean_t b_horizontal_scaling; /* horizontal scaling type */
237 int i_vertical_scaling; /* vertical scaling type */
238 int i_x, i_y; /* horizontal and vertical indexes */
239 int i_scale_count; /* scale modulo counter */
240 int i_uval, i_vval; /* U and V samples */
241 int i_red, i_green, i_blue; /* U and V modified samples */
242 int i_chroma_width; /* chroma width, not used */
243 u16 * p_yuv; /* base conversion table */
244 u16 * p_ybase; /* Y dependant conversion table */
245 u16 * p_pic_start; /* beginning of the current line for copy */
246 u16 * p_buffer_start; /* conversion buffer start */
247 u16 * p_buffer; /* conversion buffer pointer */
248 int * p_offset_start; /* offset array start */
249 int * p_offset; /* offset array pointer */
252 * Initialize some values - i_pic_line_width will store the line skip
254 i_pic_line_width -= i_pic_width;
255 p_yuv = p_vout->yuv.yuv.p_rgb16;
256 p_buffer_start = p_vout->yuv.p_buffer;
257 p_offset_start = p_vout->yuv.p_offset;
258 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
259 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
264 i_scale_count = i_pic_height;
265 for( i_y = 0; i_y < i_height; i_y++ )
267 /* Mark beginnning of line for possible later line copy, and initialize
270 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
272 /* Do YUV conversion to buffer - YUV picture is always formed of 16
273 * pixels wide blocks */
274 for( i_x = i_width / 16; i_x--; )
276 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
277 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
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);
286 /* Do horizontal and vertical scaling */
288 SCALE_HEIGHT(444, 2);