1 /*****************************************************************************
2 * transforms_yuvmmx.c: MMX YUV transformation functions
3 * Provides functions to perform the YUV conversion.
4 *****************************************************************************
5 * Copyright (C) 1999, 2000 VideoLAN
6 * $Id: transforms_yuvmmx.c,v 1.6 2001/06/03 12:47:21 sam Exp $
8 * Authors: Samuel Hocevar <sam@zoy.org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public
21 * License along with this program; if not, write to the
22 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 * Boston, MA 02111-1307, USA.
24 *****************************************************************************/
26 #define MODULE_NAME yuvmmx
27 #include "modules_inner.h"
29 /*****************************************************************************
31 *****************************************************************************/
34 #include <math.h> /* exp(), pow() */
35 #include <errno.h> /* ENOMEM */
36 #include <stdlib.h> /* free() */
37 #include <string.h> /* strerror() */
45 #include "video_output.h"
47 #include "video_common.h"
48 #include "transforms_common.h"
49 #include "transforms_yuvmmx.h"
54 #include "modules_export.h"
56 /*****************************************************************************
57 * ConvertY4Gray8: grayscale YUV 4:x:x to RGB 8 bpp
58 *****************************************************************************/
59 void _M( ConvertY4Gray8 )( YUV_ARGS_8BPP )
61 intf_ErrMsg( "yuvmmx error: unhandled function, grayscale, bpp = 8" );
64 /*****************************************************************************
65 * ConvertYUV420RGB8: color YUV 4:2:0 to RGB 8 bpp
66 *****************************************************************************/
67 void _M( ConvertYUV420RGB8 )( YUV_ARGS_8BPP )
69 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, bpp = 8" );
72 /*****************************************************************************
73 * ConvertYUV422RGB8: color YUV 4:2:2 to RGB 8 bpp
74 *****************************************************************************/
75 void _M( ConvertYUV422RGB8 )( YUV_ARGS_8BPP )
77 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, bpp = 8" );
80 /*****************************************************************************
81 * ConvertYUV444RGB8: color YUV 4:4:4 to RGB 8 bpp
82 *****************************************************************************/
83 void _M( ConvertYUV444RGB8 )( YUV_ARGS_8BPP )
85 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, bpp = 8" );
88 /*****************************************************************************
89 * ConvertY4Gray16: color YUV 4:4:4 to RGB 2 Bpp
90 *****************************************************************************/
91 void _M( ConvertY4Gray16 )( YUV_ARGS_16BPP )
93 boolean_t b_horizontal_scaling; /* horizontal scaling type */
94 int i_vertical_scaling; /* vertical scaling type */
95 int i_x, i_y; /* horizontal and vertical indexes */
96 int i_scale_count; /* scale modulo counter */
97 int i_chroma_width; /* chroma width */
98 u16 * p_pic_start; /* beginning of the current line for copy */
99 u16 * p_buffer_start; /* conversion buffer start */
100 u16 * p_buffer; /* conversion buffer pointer */
101 int * p_offset_start; /* offset array start */
102 int * p_offset; /* offset array pointer */
105 * Initialize some values - i_pic_line_width will store the line skip
107 i_pic_line_width -= i_pic_width;
108 i_chroma_width = i_width / 2;
109 p_buffer_start = p_vout->yuv.p_buffer;
110 p_offset_start = p_vout->yuv.p_offset;
111 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
112 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
117 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
118 for( i_y = 0; i_y < i_height; i_y++ )
120 /* Mark beginnning of line for possible later line copy, and initialize
123 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
125 for ( i_x = i_width / 8; i_x--; )
127 __asm__( MMX_INIT_16_GRAY
128 : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
133 : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
142 SCALE_HEIGHT( 420, 2 );
146 /*****************************************************************************
147 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 2 Bpp
148 *****************************************************************************/
149 void _M( ConvertYUV420RGB16 )( YUV_ARGS_16BPP )
151 boolean_t b_horizontal_scaling; /* horizontal scaling type */
152 int i_vertical_scaling; /* vertical scaling type */
153 int i_x, i_y; /* horizontal and vertical indexes */
154 int i_scale_count; /* scale modulo counter */
155 int i_chroma_width; /* chroma width */
156 u16 * p_pic_start; /* beginning of the current line for copy */
157 u16 * p_buffer_start; /* conversion buffer start */
158 u16 * p_buffer; /* conversion buffer pointer */
159 int * p_offset_start; /* offset array start */
160 int * p_offset; /* offset array pointer */
163 * Initialize some values - i_pic_line_width will store the line skip
165 i_pic_line_width -= i_pic_width;
166 i_chroma_width = i_width / 2;
167 p_buffer_start = p_vout->yuv.p_buffer;
168 p_offset_start = p_vout->yuv.p_offset;
169 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
170 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
175 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
176 for( i_y = 0; i_y < i_height; i_y++ )
179 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
181 for ( i_x = i_width / 8; i_x--; )
184 : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
190 : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
198 SCALE_HEIGHT( 420, 2 );
202 /*****************************************************************************
203 * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 2 Bpp
204 *****************************************************************************/
205 void _M( ConvertYUV422RGB16 )( YUV_ARGS_16BPP )
207 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, bpp = 16" );
210 /*****************************************************************************
211 * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 2 Bpp
212 *****************************************************************************/
213 void _M( ConvertYUV444RGB16 )( YUV_ARGS_16BPP )
215 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, bpp = 16" );
218 /*****************************************************************************
219 * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 2 Bpp
220 *****************************************************************************/
221 void _M( ConvertY4Gray24 )( YUV_ARGS_24BPP )
223 intf_ErrMsg( "yuvmmx error: unhandled function, grayscale, bpp = 24" );
226 /*****************************************************************************
227 * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 2 Bpp
228 *****************************************************************************/
229 void _M( ConvertYUV420RGB24 )( YUV_ARGS_24BPP )
231 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, bpp = 24" );
234 /*****************************************************************************
235 * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 2 Bpp
236 *****************************************************************************/
237 void _M( ConvertYUV422RGB24 )( YUV_ARGS_24BPP )
239 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, bpp = 24" );
242 /*****************************************************************************
243 * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 2 Bpp
244 *****************************************************************************/
245 void _M( ConvertYUV444RGB24 )( YUV_ARGS_24BPP )
247 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, bpp = 24" );
250 /*****************************************************************************
251 * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 4 Bpp
252 *****************************************************************************/
253 void _M( ConvertY4Gray32 )( YUV_ARGS_32BPP )
255 intf_ErrMsg( "yuvmmx error: unhandled function, grayscale, bpp = 32" );
258 /*****************************************************************************
259 * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 4 Bpp
260 *****************************************************************************/
261 void _M( ConvertYUV420RGB32 )( YUV_ARGS_32BPP )
263 boolean_t b_horizontal_scaling; /* horizontal scaling type */
264 int i_vertical_scaling; /* vertical scaling type */
265 int i_x, i_y; /* horizontal and vertical indexes */
266 int i_scale_count; /* scale modulo counter */
267 int i_chroma_width; /* chroma width */
268 u32 * p_pic_start; /* beginning of the current line for copy */
269 u32 * p_buffer_start; /* conversion buffer start */
270 u32 * p_buffer; /* conversion buffer pointer */
271 int * p_offset_start; /* offset array start */
272 int * p_offset; /* offset array pointer */
275 * Initialize some values - i_pic_line_width will store the line skip
277 i_pic_line_width -= i_pic_width;
278 i_chroma_width = i_width / 2;
279 p_buffer_start = p_vout->yuv.p_buffer;
280 p_offset_start = p_vout->yuv.p_offset;
281 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
282 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
284 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
285 for( i_y = 0; i_y < i_height; i_y++ )
288 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
290 for ( i_x = i_width / 8; i_x--; )
294 : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
300 : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
309 SCALE_HEIGHT( 420, 4 );
314 /*****************************************************************************
315 * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 4 Bpp
316 *****************************************************************************/
317 void _M( ConvertYUV422RGB32 )( YUV_ARGS_32BPP )
319 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 32" );
322 /*****************************************************************************
323 * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 4 Bpp
324 *****************************************************************************/
325 void _M( ConvertYUV444RGB32 )( YUV_ARGS_32BPP )
327 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 32" );
330 /*****************************************************************************
331 * ConvertYUV420YCbr8: color YUV 4:2:0 to YCbr 8 Bpp
332 *****************************************************************************/
333 void _M( ConvertYUV420YCbr8 )( YUV_ARGS_8BPP )
335 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, YCbr = 8" );
338 /*****************************************************************************
339 * ConvertYUV422YCbr8: color YUV 4:2:2 to YCbr 8 Bpp
340 *****************************************************************************/
341 void _M( ConvertYUV422YCbr8 )( YUV_ARGS_8BPP )
343 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, YCbr = 8" );
347 /*****************************************************************************
348 * ConvertYUV444YCbr8: color YUV 4:4:4 to YCbr 8 Bpp
349 *****************************************************************************/
350 void _M( ConvertYUV444YCbr8 )( YUV_ARGS_8BPP )
352 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, YCbr = 8" );
356 /*****************************************************************************
357 * ConvertYUV420YCbr16: color YUV 4:2:0 to YCbr 16 Bpp
358 *****************************************************************************/
359 void _M( ConvertYUV420YCbr16 )( YUV_ARGS_16BPP )
361 boolean_t b_horizontal_scaling; /* horizontal scaling type */
362 int i_vertical_scaling; /* vertical scaling type */
363 int i_x, i_y; /* horizontal and vertical indexes */
364 int i_scale_count; /* scale modulo counter */
365 int i_chroma_width; /* chroma width */
366 u16 * p_pic_start; /* beginning of the current line for copy */
367 u16 * p_buffer_start; /* conversion buffer start */
368 u16 * p_buffer; /* conversion buffer pointer */
369 int * p_offset_start; /* offset array start */
370 int * p_offset; /* offset array pointer */
372 i_pic_line_width -= i_pic_width;
373 i_chroma_width = i_width / 2;
374 p_buffer_start = p_vout->yuv.p_buffer;
375 p_offset_start = p_vout->yuv.p_offset;
376 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
377 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
379 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
380 for( i_y = 0; i_y < i_height; i_y++ )
383 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
385 for ( i_x = i_width / 8; i_x--; )
388 : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
392 : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
400 SCALE_HEIGHT( 420, 2 );
406 /*****************************************************************************
407 * ConvertYUV422YCbr8: color YUV 4:2:2 to YCbr 16 Bpp
408 *****************************************************************************/
409 void _M( ConvertYUV422YCbr16 )( YUV_ARGS_16BPP )
411 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, YCbr = 16" );
415 /*****************************************************************************
416 * ConvertYUV424YCbr8: color YUV 4:4:4 to YCbr 16 Bpp
417 *****************************************************************************/
418 void _M( ConvertYUV444YCbr16 )( YUV_ARGS_16BPP )
420 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, YCbr = 16" );
424 /*****************************************************************************
425 * ConvertYUV420YCbr24: color YUV 4:2:0 to YCbr 24 Bpp
426 *****************************************************************************/
427 void _M( ConvertYUV420YCbr24 )( YUV_ARGS_24BPP )
429 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, YCbr = 24" );
433 /*****************************************************************************
434 * ConvertYUV422YCbr24: color YUV 4:2:2 to YCbr 24 Bpp
435 *****************************************************************************/
436 void _M( ConvertYUV422YCbr24 )( YUV_ARGS_24BPP )
438 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, YCbr = 24" );
442 /*****************************************************************************
443 * ConvertYUV444YCbr24: color YUV 4:4:4 to YCbr 24 Bpp
444 *****************************************************************************/
445 void _M( ConvertYUV444YCbr24 )( YUV_ARGS_24BPP )
447 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, YCbr = 24" );
451 /*****************************************************************************
452 * ConvertYUV420YCbr32: color YUV 4:2:0 to YCbr 32 Bpp
453 *****************************************************************************/
454 void _M( ConvertYUV420YCbr32 )( YUV_ARGS_32BPP )
456 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, YCbr = 32" );
460 /*****************************************************************************
461 * ConvertYUV422YCbr32: color YUV 4:2:2 to YCbr 32 Bpp
462 *****************************************************************************/
463 void _M( ConvertYUV422YCbr32 )( YUV_ARGS_32BPP )
465 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, YCbr = 32" );
469 /*****************************************************************************
470 * ConvertYUV444YCbr32: color YUV 4:4:4 to YCbr 32 Bpp
471 *****************************************************************************/
472 void _M( ConvertYUV444YCbr32 )( YUV_ARGS_32BPP )
474 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, YCbr = 32" );