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.5 2001/04/15 04:19:58 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"
53 /*****************************************************************************
54 * ConvertY4Gray8: grayscale YUV 4:x:x to RGB 8 bpp
55 *****************************************************************************/
56 void _M( ConvertY4Gray8 )( YUV_ARGS_8BPP )
58 intf_ErrMsg( "yuvmmx error: unhandled function, grayscale, bpp = 8" );
61 /*****************************************************************************
62 * ConvertYUV420RGB8: color YUV 4:2:0 to RGB 8 bpp
63 *****************************************************************************/
64 void _M( ConvertYUV420RGB8 )( YUV_ARGS_8BPP )
66 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, bpp = 8" );
69 /*****************************************************************************
70 * ConvertYUV422RGB8: color YUV 4:2:2 to RGB 8 bpp
71 *****************************************************************************/
72 void _M( ConvertYUV422RGB8 )( YUV_ARGS_8BPP )
74 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, bpp = 8" );
77 /*****************************************************************************
78 * ConvertYUV444RGB8: color YUV 4:4:4 to RGB 8 bpp
79 *****************************************************************************/
80 void _M( ConvertYUV444RGB8 )( YUV_ARGS_8BPP )
82 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, bpp = 8" );
85 /*****************************************************************************
86 * ConvertY4Gray16: color YUV 4:4:4 to RGB 2 Bpp
87 *****************************************************************************/
88 void _M( ConvertY4Gray16 )( YUV_ARGS_16BPP )
90 boolean_t b_horizontal_scaling; /* horizontal scaling type */
91 int i_vertical_scaling; /* vertical scaling type */
92 int i_x, i_y; /* horizontal and vertical indexes */
93 int i_scale_count; /* scale modulo counter */
94 int i_chroma_width; /* chroma width */
95 u16 * p_pic_start; /* beginning of the current line for copy */
96 u16 * p_buffer_start; /* conversion buffer start */
97 u16 * p_buffer; /* conversion buffer pointer */
98 int * p_offset_start; /* offset array start */
99 int * p_offset; /* offset array pointer */
102 * Initialize some values - i_pic_line_width will store the line skip
104 i_pic_line_width -= i_pic_width;
105 i_chroma_width = i_width / 2;
106 p_buffer_start = p_vout->yuv.p_buffer;
107 p_offset_start = p_vout->yuv.p_offset;
108 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
109 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
114 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
115 for( i_y = 0; i_y < i_height; i_y++ )
117 /* Mark beginnning of line for possible later line copy, and initialize
120 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
122 for ( i_x = i_width / 8; i_x--; )
124 __asm__( MMX_INIT_16_GRAY
125 : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
130 : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
139 SCALE_HEIGHT( 420, 2 );
143 /*****************************************************************************
144 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 2 Bpp
145 *****************************************************************************/
146 void _M( ConvertYUV420RGB16 )( YUV_ARGS_16BPP )
148 boolean_t b_horizontal_scaling; /* horizontal scaling type */
149 int i_vertical_scaling; /* vertical scaling type */
150 int i_x, i_y; /* horizontal and vertical indexes */
151 int i_scale_count; /* scale modulo counter */
152 int i_chroma_width; /* chroma width */
153 u16 * p_pic_start; /* beginning of the current line for copy */
154 u16 * p_buffer_start; /* conversion buffer start */
155 u16 * p_buffer; /* conversion buffer pointer */
156 int * p_offset_start; /* offset array start */
157 int * p_offset; /* offset array pointer */
160 * Initialize some values - i_pic_line_width will store the line skip
162 i_pic_line_width -= i_pic_width;
163 i_chroma_width = i_width / 2;
164 p_buffer_start = p_vout->yuv.p_buffer;
165 p_offset_start = p_vout->yuv.p_offset;
166 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
167 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
172 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
173 for( i_y = 0; i_y < i_height; i_y++ )
176 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
178 for ( i_x = i_width / 8; i_x--; )
181 : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
187 : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
195 SCALE_HEIGHT( 420, 2 );
199 /*****************************************************************************
200 * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 2 Bpp
201 *****************************************************************************/
202 void _M( ConvertYUV422RGB16 )( YUV_ARGS_16BPP )
204 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, bpp = 16" );
207 /*****************************************************************************
208 * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 2 Bpp
209 *****************************************************************************/
210 void _M( ConvertYUV444RGB16 )( YUV_ARGS_16BPP )
212 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, bpp = 16" );
215 /*****************************************************************************
216 * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 2 Bpp
217 *****************************************************************************/
218 void _M( ConvertY4Gray24 )( YUV_ARGS_24BPP )
220 intf_ErrMsg( "yuvmmx error: unhandled function, grayscale, bpp = 24" );
223 /*****************************************************************************
224 * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 2 Bpp
225 *****************************************************************************/
226 void _M( ConvertYUV420RGB24 )( YUV_ARGS_24BPP )
228 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, bpp = 24" );
231 /*****************************************************************************
232 * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 2 Bpp
233 *****************************************************************************/
234 void _M( ConvertYUV422RGB24 )( YUV_ARGS_24BPP )
236 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, bpp = 24" );
239 /*****************************************************************************
240 * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 2 Bpp
241 *****************************************************************************/
242 void _M( ConvertYUV444RGB24 )( YUV_ARGS_24BPP )
244 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, bpp = 24" );
247 /*****************************************************************************
248 * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 4 Bpp
249 *****************************************************************************/
250 void _M( ConvertY4Gray32 )( YUV_ARGS_32BPP )
252 intf_ErrMsg( "yuvmmx error: unhandled function, grayscale, bpp = 32" );
255 /*****************************************************************************
256 * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 4 Bpp
257 *****************************************************************************/
258 void _M( ConvertYUV420RGB32 )( YUV_ARGS_32BPP )
260 boolean_t b_horizontal_scaling; /* horizontal scaling type */
261 int i_vertical_scaling; /* vertical scaling type */
262 int i_x, i_y; /* horizontal and vertical indexes */
263 int i_scale_count; /* scale modulo counter */
264 int i_chroma_width; /* chroma width */
265 u32 * p_pic_start; /* beginning of the current line for copy */
266 u32 * p_buffer_start; /* conversion buffer start */
267 u32 * p_buffer; /* conversion buffer pointer */
268 int * p_offset_start; /* offset array start */
269 int * p_offset; /* offset array pointer */
272 * Initialize some values - i_pic_line_width will store the line skip
274 i_pic_line_width -= i_pic_width;
275 i_chroma_width = i_width / 2;
276 p_buffer_start = p_vout->yuv.p_buffer;
277 p_offset_start = p_vout->yuv.p_offset;
278 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
279 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
281 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
282 for( i_y = 0; i_y < i_height; i_y++ )
285 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
287 for ( i_x = i_width / 8; i_x--; )
291 : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
297 : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
306 SCALE_HEIGHT( 420, 4 );
311 /*****************************************************************************
312 * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 4 Bpp
313 *****************************************************************************/
314 void _M( ConvertYUV422RGB32 )( YUV_ARGS_32BPP )
316 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 32" );
319 /*****************************************************************************
320 * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 4 Bpp
321 *****************************************************************************/
322 void _M( ConvertYUV444RGB32 )( YUV_ARGS_32BPP )
324 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 32" );
327 /*****************************************************************************
328 * ConvertYUV420YCbr8: color YUV 4:2:0 to YCbr 8 Bpp
329 *****************************************************************************/
330 void _M( ConvertYUV420YCbr8 )( YUV_ARGS_8BPP )
332 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, YCbr = 8" );
335 /*****************************************************************************
336 * ConvertYUV422YCbr8: color YUV 4:2:2 to YCbr 8 Bpp
337 *****************************************************************************/
338 void _M( ConvertYUV422YCbr8 )( YUV_ARGS_8BPP )
340 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, YCbr = 8" );
344 /*****************************************************************************
345 * ConvertYUV444YCbr8: color YUV 4:4:4 to YCbr 8 Bpp
346 *****************************************************************************/
347 void _M( ConvertYUV444YCbr8 )( YUV_ARGS_8BPP )
349 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, YCbr = 8" );
353 /*****************************************************************************
354 * ConvertYUV420YCbr16: color YUV 4:2:0 to YCbr 16 Bpp
355 *****************************************************************************/
356 void _M( ConvertYUV420YCbr16 )( YUV_ARGS_16BPP )
358 boolean_t b_horizontal_scaling; /* horizontal scaling type */
359 int i_vertical_scaling; /* vertical scaling type */
360 int i_x, i_y; /* horizontal and vertical indexes */
361 int i_scale_count; /* scale modulo counter */
362 int i_chroma_width; /* chroma width */
363 u16 * p_pic_start; /* beginning of the current line for copy */
364 u16 * p_buffer_start; /* conversion buffer start */
365 u16 * p_buffer; /* conversion buffer pointer */
366 int * p_offset_start; /* offset array start */
367 int * p_offset; /* offset array pointer */
369 i_pic_line_width -= i_pic_width;
370 i_chroma_width = i_width / 2;
371 p_buffer_start = p_vout->yuv.p_buffer;
372 p_offset_start = p_vout->yuv.p_offset;
373 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
374 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
376 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
377 for( i_y = 0; i_y < i_height; i_y++ )
380 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
382 for ( i_x = i_width / 8; i_x--; )
385 : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
389 : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
397 SCALE_HEIGHT( 420, 2 );
403 /*****************************************************************************
404 * ConvertYUV422YCbr8: color YUV 4:2:2 to YCbr 16 Bpp
405 *****************************************************************************/
406 void _M( ConvertYUV422YCbr16 )( YUV_ARGS_16BPP )
408 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, YCbr = 16" );
412 /*****************************************************************************
413 * ConvertYUV424YCbr8: color YUV 4:4:4 to YCbr 16 Bpp
414 *****************************************************************************/
415 void _M( ConvertYUV444YCbr16 )( YUV_ARGS_16BPP )
417 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, YCbr = 16" );
421 /*****************************************************************************
422 * ConvertYUV420YCbr24: color YUV 4:2:0 to YCbr 24 Bpp
423 *****************************************************************************/
424 void _M( ConvertYUV420YCbr24 )( YUV_ARGS_24BPP )
426 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, YCbr = 24" );
430 /*****************************************************************************
431 * ConvertYUV422YCbr24: color YUV 4:2:2 to YCbr 24 Bpp
432 *****************************************************************************/
433 void _M( ConvertYUV422YCbr24 )( YUV_ARGS_24BPP )
435 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, YCbr = 24" );
439 /*****************************************************************************
440 * ConvertYUV444YCbr24: color YUV 4:4:4 to YCbr 24 Bpp
441 *****************************************************************************/
442 void _M( ConvertYUV444YCbr24 )( YUV_ARGS_24BPP )
444 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, YCbr = 24" );
448 /*****************************************************************************
449 * ConvertYUV420YCbr32: color YUV 4:2:0 to YCbr 32 Bpp
450 *****************************************************************************/
451 void _M( ConvertYUV420YCbr32 )( YUV_ARGS_32BPP )
453 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, YCbr = 32" );
457 /*****************************************************************************
458 * ConvertYUV422YCbr32: color YUV 4:2:2 to YCbr 32 Bpp
459 *****************************************************************************/
460 void _M( ConvertYUV422YCbr32 )( YUV_ARGS_32BPP )
462 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, YCbr = 32" );
466 /*****************************************************************************
467 * ConvertYUV444YCbr32: color YUV 4:4:4 to YCbr 32 Bpp
468 *****************************************************************************/
469 void _M( ConvertYUV444YCbr32 )( YUV_ARGS_32BPP )
471 intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, YCbr = 32" );