1 /*****************************************************************************
2 * yv12_rgb16.c : YUV to paletted RGB16 conversion module for vlc
3 *****************************************************************************
4 * Copyright (C) 2000 VideoLAN
5 * $Id: yv12_rgb16.c,v 1.1 2001/12/30 07:09:54 sam Exp $
7 * Authors: Samuel Hocevar <sam@zoy.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include <math.h> /* exp(), pow() */
28 #include <errno.h> /* ENOMEM */
29 #include <string.h> /* strerror() */
30 #include <stdlib.h> /* malloc(), free() */
32 #include <videolan/vlc.h>
35 #include "video_output.h"
37 #include "chroma_common.h"
38 #include "transforms.h"
40 /*****************************************************************************
41 * chroma_sys_t: chroma method descriptor
42 *****************************************************************************
43 * This structure is part of the chroma transformation descriptor, it
44 * describes the yuv2rgb16 specific properties.
45 *****************************************************************************/
46 typedef struct chroma_sys_s
53 /*****************************************************************************
54 * Local and extern prototypes.
55 *****************************************************************************/
56 static void chroma_getfunctions ( function_list_t * p_function_list );
58 static int chroma_Probe ( probedata_t *p_data );
59 static int chroma_Init ( vout_thread_t *p_vout );
60 static void chroma_End ( vout_thread_t *p_vout );
62 static void ConvertYUV420RGB16 ( vout_thread_t *, picture_t *, picture_t * );
64 /*****************************************************************************
65 * Build configuration tree.
66 *****************************************************************************/
71 SET_DESCRIPTION( "YV12 to RGB16 conversion module" )
72 ADD_CAPABILITY( CHROMA, 80 )
76 _M( chroma_getfunctions )( &p_module->p_functions->chroma );
79 MODULE_DEACTIVATE_START
80 MODULE_DEACTIVATE_STOP
82 /*****************************************************************************
84 *****************************************************************************/
85 /*****************************************************************************
86 * Functions exported as capabilities. They are declared as static so that
87 * we don't pollute the namespace too much.
88 *****************************************************************************/
89 void _M( chroma_getfunctions )( function_list_t * p_function_list )
91 p_function_list->pf_probe = chroma_Probe;
92 p_function_list->functions.chroma.pf_init = chroma_Init;
93 p_function_list->functions.chroma.pf_end = chroma_End;
96 /*****************************************************************************
97 * chroma_Probe: return a score
98 *****************************************************************************
99 * This function checks that we can handle the required data
100 *****************************************************************************/
101 static int chroma_Probe( probedata_t *p_data )
103 if( p_data->chroma.p_render->i_chroma != YUV_420_PICTURE
104 || p_data->chroma.p_output->i_chroma != RGB_16BPP_PICTURE )
112 /*****************************************************************************
113 * chroma_Init: allocate a chroma function
114 *****************************************************************************
115 * This function allocates and initializes a chroma function
116 *****************************************************************************/
117 static int chroma_Init( vout_thread_t *p_vout )
119 if( p_vout->render.i_chroma != YUV_420_PICTURE
120 || p_vout->output.i_chroma != RGB_16BPP_PICTURE )
126 p_vout->chroma.p_sys = malloc( sizeof( chroma_sys_t ) );
127 if( p_vout->chroma.p_sys == NULL )
133 /* FIXME: this is really suboptimal ! */
134 p_vout->chroma.pf_convert = ConvertYUV420RGB16;
139 /*****************************************************************************
140 * chroma_End: free the chroma function
141 *****************************************************************************
142 * This function frees the previously allocated chroma function
143 *****************************************************************************/
144 static void chroma_End( vout_thread_t *p_vout )
147 free( p_vout->chroma.p_sys );
153 /* Following functions are local */
155 /*****************************************************************************
156 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 8 bpp
157 *****************************************************************************/
158 static void ConvertYUV420RGB16( vout_thread_t *p_vout, picture_t *p_source,
161 /**********************************************************************
162 * XXX XXX FIXME FIXME XXX XXX XXX *
163 * XXX XXX XXX TODO TODO XXX XXX XXX TODO *
164 * XXX XXX XXX XXX XXX XXX XXX XXX *
165 * XXX FIXME XXX FIXME XXX FIXME XXX *
166 * XXX XXX XXX XXX XXX XXX XXX XXX *
167 * XXX XXX XXX XXX TODO XXX XXX XXX *
168 * XXX XXX XXX XXX FIXME XXX XXX XXX *
169 **********************************************************************/
171 pixel_data_t *p_in, *p_in_end, *p_out, *p_out_end;
173 p_in = p_source->planes[ Y_PLANE ].p_data;
174 p_in_end = p_in + p_source->planes[ Y_PLANE ].i_bytes;
176 p_out = p_dest->planes[ RGB_PLANE ].p_data;
177 p_out_end = p_out + p_dest->planes[ RGB_PLANE ].i_bytes;
179 while( p_in < p_in_end && p_out < p_out_end )
181 int i_src = p_source->planes[ Y_PLANE ].i_line_bytes;
182 int i_dst = p_dest->planes[ RGB_PLANE ].i_line_bytes / 2;
184 /* Masks: 0xf800 0x07e0 0x001f */
185 #define RED ((u16*)p_out)[i_dst--] = (u16)(p_in[i_src--]>>3) << 11;
186 #define GREEN ((u16*)p_out)[i_dst--] = (u16)(p_in[i_src--]>>2) << 5;
187 #define BLUE ((u16*)p_out)[i_dst--] = (u16)(p_in[i_src--]>>3) << 0;
188 #define WHITE ((u16*)p_out)[i_dst--] = ((u16)(p_in[i_src]>>3) << 11) | ((u16)(p_in[i_src]>>2) << 5) | ((u16)(p_in[i_src]>>3) << 0); i_src--;
189 #define BLACK ((u16*)p_out)[i_dst--] = 0; i_src--;
191 while( i_src && i_dst )
193 BLACK; BLUE; GREEN; RED; GREEN; BLUE; WHITE; RED;
194 GREEN; BLUE; WHITE; RED; BLACK; BLUE; GREEN; RED;
197 p_in += p_source->planes[ Y_PLANE ].i_line_bytes;
198 p_out += p_dest->planes[ RGB_PLANE ].i_line_bytes;
200 i_src = p_source->planes[ Y_PLANE ].i_line_bytes;
201 i_dst = p_dest->planes[ RGB_PLANE ].i_line_bytes / 2;
203 while( i_src && i_dst )
205 GREEN; RED; WHITE; BLUE; BLACK; RED; GREEN; BLUE;
206 BLACK; RED; GREEN; BLUE; GREEN; RED; WHITE; BLUE;
209 p_in += p_source->planes[ Y_PLANE ].i_line_bytes;
210 p_out += p_dest->planes[ RGB_PLANE ].i_line_bytes;
213 /**********************************************************************
214 * XXX XXX XXX XXX FIXME XXX XXX XXX *
215 * XXX XXX XXX XXX TODO XXX XXX XXX TODO *
216 * XXX XXX XXX XXX XXX XXX XXX XXX *
217 * TODO XXX XXX XXX FIXME XXX *
218 * TODO XXX XXX XXX XXX XXX XXX *
219 * XXX TODO XXX TODO XXX XXX XXX *
220 * XXX FIXME FIXME XXX XXX XXX *
221 **********************************************************************/