Parent Directory
|
Revision Log
Revision 1290 - (view) (download)
1 : | edgomez | 1054 | /***************************************************************************** |
2 : | edgomez | 195 | * |
3 : | edgomez | 1054 | * XVID MPEG-4 VIDEO CODEC |
4 : | * - Colorspace conversion functions - | ||
5 : | edgomez | 195 | * |
6 : | edgomez | 1054 | * Copyright(C) 2001-2003 Peter Ross <pross@xvid.org> |
7 : | edgomez | 195 | * |
8 : | edgomez | 1054 | * This program is free software ; you can redistribute it and/or modify |
9 : | * it under the terms of the GNU General Public License as published by | ||
10 : | * the Free Software Foundation ; either version 2 of the License, or | ||
11 : | * (at your option) any later version. | ||
12 : | edgomez | 195 | * |
13 : | edgomez | 1054 | * This program is distributed in the hope that it will be useful, |
14 : | * but WITHOUT ANY WARRANTY ; without even the implied warranty of | ||
15 : | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 : | * GNU General Public License for more details. | ||
17 : | edgomez | 195 | * |
18 : | edgomez | 1054 | * You should have received a copy of the GNU General Public License |
19 : | * along with this program ; if not, write to the Free Software | ||
20 : | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 : | edgomez | 195 | * |
22 : | edgomez | 1290 | * $Id: colorspace.c,v 1.8.2.5 2003-12-20 22:20:54 edgomez Exp $ |
23 : | edgomez | 195 | * |
24 : | edgomez | 1054 | ****************************************************************************/ |
25 : | edgomez | 195 | |
26 : | edgomez | 1053 | #include <string.h> /* memcpy */ |
27 : | edgomez | 195 | |
28 : | edgomez | 851 | #include "../global.h" |
29 : | edgomez | 195 | #include "colorspace.h" |
30 : | |||
31 : | edgomez | 1053 | /* function pointers */ |
32 : | edgomez | 195 | |
33 : | /* input */ | ||
34 : | edgomez | 851 | packedFuncPtr rgb555_to_yv12; |
35 : | packedFuncPtr rgb565_to_yv12; | ||
36 : | packedFuncPtr bgr_to_yv12; | ||
37 : | packedFuncPtr bgra_to_yv12; | ||
38 : | packedFuncPtr abgr_to_yv12; | ||
39 : | packedFuncPtr rgba_to_yv12; | ||
40 : | edgomez | 1290 | packedFuncPtr argb_to_yv12; |
41 : | edgomez | 851 | packedFuncPtr yuv_to_yv12; |
42 : | packedFuncPtr yuyv_to_yv12; | ||
43 : | packedFuncPtr uyvy_to_yv12; | ||
44 : | edgomez | 195 | |
45 : | edgomez | 851 | packedFuncPtr rgb555i_to_yv12; |
46 : | packedFuncPtr rgb565i_to_yv12; | ||
47 : | packedFuncPtr bgri_to_yv12; | ||
48 : | packedFuncPtr bgrai_to_yv12; | ||
49 : | packedFuncPtr abgri_to_yv12; | ||
50 : | packedFuncPtr rgbai_to_yv12; | ||
51 : | edgomez | 1290 | packedFuncPtr argbi_to_yv12; |
52 : | edgomez | 851 | packedFuncPtr yuyvi_to_yv12; |
53 : | packedFuncPtr uyvyi_to_yv12; | ||
54 : | |||
55 : | edgomez | 195 | /* output */ |
56 : | edgomez | 851 | packedFuncPtr yv12_to_rgb555; |
57 : | packedFuncPtr yv12_to_rgb565; | ||
58 : | packedFuncPtr yv12_to_bgr; | ||
59 : | packedFuncPtr yv12_to_bgra; | ||
60 : | packedFuncPtr yv12_to_abgr; | ||
61 : | packedFuncPtr yv12_to_rgba; | ||
62 : | edgomez | 1290 | packedFuncPtr yv12_to_argb; |
63 : | edgomez | 851 | packedFuncPtr yv12_to_yuv; |
64 : | packedFuncPtr yv12_to_yuyv; | ||
65 : | packedFuncPtr yv12_to_uyvy; | ||
66 : | edgomez | 195 | |
67 : | edgomez | 851 | packedFuncPtr yv12_to_rgb555i; |
68 : | packedFuncPtr yv12_to_rgb565i; | ||
69 : | packedFuncPtr yv12_to_bgri; | ||
70 : | packedFuncPtr yv12_to_bgrai; | ||
71 : | packedFuncPtr yv12_to_abgri; | ||
72 : | packedFuncPtr yv12_to_rgbai; | ||
73 : | edgomez | 1290 | packedFuncPtr yv12_to_argbi; |
74 : | edgomez | 851 | packedFuncPtr yv12_to_yuyvi; |
75 : | packedFuncPtr yv12_to_uyvyi; | ||
76 : | edgomez | 195 | |
77 : | edgomez | 851 | planarFuncPtr yv12_to_yv12; |
78 : | |||
79 : | |||
80 : | int32_t RGB_Y_tab[256]; | ||
81 : | int32_t B_U_tab[256]; | ||
82 : | int32_t G_U_tab[256]; | ||
83 : | int32_t G_V_tab[256]; | ||
84 : | int32_t R_V_tab[256]; | ||
85 : | |||
86 : | |||
87 : | |||
88 : | /********** generic colorspace macro **********/ | ||
89 : | |||
90 : | |||
91 : | #define MAKE_COLORSPACE(NAME,SIZE,PIXELS,VPIXELS,FUNC,C1,C2,C3,C4) \ | ||
92 : | void \ | ||
93 : | NAME(uint8_t * x_ptr, int x_stride, \ | ||
94 : | uint8_t * y_ptr, uint8_t * u_ptr, uint8_t * v_ptr, \ | ||
95 : | int y_stride, int uv_stride, \ | ||
96 : | int width, int height, int vflip) \ | ||
97 : | { \ | ||
98 : | int fixed_width = (width + 1) & ~1; \ | ||
99 : | int x_dif = x_stride - (SIZE)*fixed_width; \ | ||
100 : | int y_dif = y_stride - fixed_width; \ | ||
101 : | int uv_dif = uv_stride - (fixed_width / 2); \ | ||
102 : | int x, y; \ | ||
103 : | if (vflip) { \ | ||
104 : | x_ptr += (height - 1) * x_stride; \ | ||
105 : | x_dif = -(SIZE)*fixed_width - x_stride; \ | ||
106 : | x_stride = -x_stride; \ | ||
107 : | } \ | ||
108 : | for (y = 0; y < height; y+=(VPIXELS)) { \ | ||
109 : | FUNC##_ROW(SIZE,C1,C2,C3,C4); \ | ||
110 : | for (x = 0; x < fixed_width; x+=(PIXELS)) { \ | ||
111 : | FUNC(SIZE,C1,C2,C3,C4); \ | ||
112 : | x_ptr += (PIXELS)*(SIZE); \ | ||
113 : | y_ptr += (PIXELS); \ | ||
114 : | u_ptr += (PIXELS)/2; \ | ||
115 : | v_ptr += (PIXELS)/2; \ | ||
116 : | } \ | ||
117 : | x_ptr += x_dif + (VPIXELS-1)*x_stride; \ | ||
118 : | y_ptr += y_dif + (VPIXELS-1)*y_stride; \ | ||
119 : | u_ptr += uv_dif + ((VPIXELS/2)-1)*uv_stride; \ | ||
120 : | v_ptr += uv_dif + ((VPIXELS/2)-1)*uv_stride; \ | ||
121 : | } \ | ||
122 : | } | ||
123 : | |||
124 : | |||
125 : | |||
126 : | /********** colorspace input (xxx_to_yv12) functions **********/ | ||
127 : | |||
128 : | edgomez | 195 | /* rgb -> yuv def's |
129 : | |||
130 : | this following constants are "official spec" | ||
131 : | Video Demystified" (ISBN 1-878707-09-4) | ||
132 : | |||
133 : | rgb<->yuv _is_ lossy, since most programs do the conversion differently | ||
134 : | edgomez | 1161 | |
135 : | edgomez | 195 | SCALEBITS/FIX taken from ffmpeg |
136 : | */ | ||
137 : | |||
138 : | #define Y_R_IN 0.257 | ||
139 : | #define Y_G_IN 0.504 | ||
140 : | #define Y_B_IN 0.098 | ||
141 : | #define Y_ADD_IN 16 | ||
142 : | |||
143 : | #define U_R_IN 0.148 | ||
144 : | #define U_G_IN 0.291 | ||
145 : | #define U_B_IN 0.439 | ||
146 : | #define U_ADD_IN 128 | ||
147 : | |||
148 : | #define V_R_IN 0.439 | ||
149 : | #define V_G_IN 0.368 | ||
150 : | #define V_B_IN 0.071 | ||
151 : | #define V_ADD_IN 128 | ||
152 : | |||
153 : | #define SCALEBITS_IN 8 | ||
154 : | #define FIX_IN(x) ((uint16_t) ((x) * (1L<<SCALEBITS_IN) + 0.5)) | ||
155 : | |||
156 : | |||
157 : | edgomez | 851 | /* rgb16/rgb16i input */ |
158 : | edgomez | 195 | |
159 : | edgomez | 851 | #define MK_RGB555_B(RGB) ((RGB) << 3) & 0xf8 |
160 : | #define MK_RGB555_G(RGB) ((RGB) >> 2) & 0xf8 | ||
161 : | #define MK_RGB555_R(RGB) ((RGB) >> 7) & 0xf8 | ||
162 : | edgomez | 195 | |
163 : | edgomez | 851 | #define MK_RGB565_B(RGB) ((RGB) << 3) & 0xf8 |
164 : | #define MK_RGB565_G(RGB) ((RGB) >> 3) & 0xfc | ||
165 : | #define MK_RGB565_R(RGB) ((RGB) >> 8) & 0xf8 | ||
166 : | edgomez | 195 | |
167 : | |||
168 : | edgomez | 851 | #define READ_RGB16_Y(ROW, UVID, C1,C2,C3,C4) \ |
169 : | rgb = *(uint16_t *) (x_ptr + ((ROW)*x_stride) + 0); \ | ||
170 : | b##UVID += b = C1##_B(rgb); \ | ||
171 : | g##UVID += g = C1##_G(rgb); \ | ||
172 : | r##UVID += r = C1##_R(rgb); \ | ||
173 : | y_ptr[(ROW)*y_stride+0] = \ | ||
174 : | (uint8_t) ((FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + \ | ||
175 : | FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; \ | ||
176 : | rgb = *(uint16_t *) (x_ptr + ((ROW)*x_stride) + 2); \ | ||
177 : | b##UVID += b = C1##_B(rgb); \ | ||
178 : | g##UVID += g = C1##_G(rgb); \ | ||
179 : | r##UVID += r = C1##_R(rgb); \ | ||
180 : | y_ptr[(ROW)*y_stride+1] = \ | ||
181 : | (uint8_t) ((FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + \ | ||
182 : | FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; | ||
183 : | edgomez | 195 | |
184 : | edgomez | 851 | #define READ_RGB16_UV(UV_ROW,UVID) \ |
185 : | u_ptr[(UV_ROW)*uv_stride] = \ | ||
186 : | (uint8_t) ((-FIX_IN(U_R_IN) * r##UVID - FIX_IN(U_G_IN) * g##UVID + \ | ||
187 : | FIX_IN(U_B_IN) * b##UVID) >> (SCALEBITS_IN + 2)) + U_ADD_IN; \ | ||
188 : | v_ptr[(UV_ROW)*uv_stride] = \ | ||
189 : | (uint8_t) ((FIX_IN(V_R_IN) * r##UVID - FIX_IN(V_G_IN) * g##UVID - \ | ||
190 : | FIX_IN(V_B_IN) * b##UVID) >> (SCALEBITS_IN + 2)) + V_ADD_IN; | ||
191 : | edgomez | 195 | |
192 : | edgomez | 851 | #define RGB16_TO_YV12_ROW(SIZE,C1,C2,C3,C4) \ |
193 : | /* nothing */ | ||
194 : | #define RGB16_TO_YV12(SIZE,C1,C2,C3,C4) \ | ||
195 : | uint32_t rgb, r, g, b, r0, g0, b0; \ | ||
196 : | r0 = g0 = b0 = 0; \ | ||
197 : | READ_RGB16_Y (0, 0, C1,C2,C3,C4) \ | ||
198 : | READ_RGB16_Y (1, 0, C1,C2,C3,C4) \ | ||
199 : | READ_RGB16_UV(0, 0) | ||
200 : | edgomez | 195 | |
201 : | |||
202 : | edgomez | 851 | #define RGB16I_TO_YV12_ROW(SIZE,C1,C2,C3,C4) \ |
203 : | /* nothing */ | ||
204 : | #define RGB16I_TO_YV12(SIZE,C1,C2,C3,C4) \ | ||
205 : | uint32_t rgb, r, g, b, r0, g0, b0, r1, g1, b1; \ | ||
206 : | r0 = g0 = b0 = r1 = g1 = b1 = 0; \ | ||
207 : | READ_RGB16_Y (0, 0, C1,C2,C3,C4) \ | ||
208 : | READ_RGB16_Y (1, 1, C1,C2,C3,C4) \ | ||
209 : | READ_RGB16_Y (2, 0, C1,C2,C3,C4) \ | ||
210 : | READ_RGB16_Y (3, 1, C1,C2,C3,C4) \ | ||
211 : | READ_RGB16_UV(0, 0) \ | ||
212 : | READ_RGB16_UV(1, 1) | ||
213 : | edgomez | 195 | |
214 : | |||
215 : | edgomez | 851 | /* rgb/rgbi input */ |
216 : | edgomez | 195 | |
217 : | edgomez | 851 | #define READ_RGB_Y(SIZE, ROW, UVID, C1,C2,C3,C4) \ |
218 : | r##UVID += r = x_ptr[(ROW)*x_stride+(C1)]; \ | ||
219 : | g##UVID += g = x_ptr[(ROW)*x_stride+(C2)]; \ | ||
220 : | b##UVID += b = x_ptr[(ROW)*x_stride+(C3)]; \ | ||
221 : | y_ptr[(ROW)*y_stride+0] = \ | ||
222 : | (uint8_t) ((FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + \ | ||
223 : | FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; \ | ||
224 : | r##UVID += r = x_ptr[(ROW)*x_stride+(SIZE)+(C1)]; \ | ||
225 : | g##UVID += g = x_ptr[(ROW)*x_stride+(SIZE)+(C2)]; \ | ||
226 : | b##UVID += b = x_ptr[(ROW)*x_stride+(SIZE)+(C3)]; \ | ||
227 : | y_ptr[(ROW)*y_stride+1] = \ | ||
228 : | (uint8_t) ((FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + \ | ||
229 : | edgomez | 1161 | FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; |
230 : | edgomez | 195 | |
231 : | edgomez | 851 | #define READ_RGB_UV(UV_ROW,UVID) \ |
232 : | u_ptr[(UV_ROW)*uv_stride] = \ | ||
233 : | (uint8_t) ((-FIX_IN(U_R_IN) * r##UVID - FIX_IN(U_G_IN) * g##UVID + \ | ||
234 : | FIX_IN(U_B_IN) * b##UVID) >> (SCALEBITS_IN + 2)) + U_ADD_IN; \ | ||
235 : | v_ptr[(UV_ROW)*uv_stride] = \ | ||
236 : | (uint8_t) ((FIX_IN(V_R_IN) * r##UVID - FIX_IN(V_G_IN) * g##UVID - \ | ||
237 : | FIX_IN(V_B_IN) * b##UVID) >> (SCALEBITS_IN + 2)) + V_ADD_IN; | ||
238 : | edgomez | 195 | |
239 : | |||
240 : | edgomez | 851 | #define RGB_TO_YV12_ROW(SIZE,C1,C2,C3,C4) \ |
241 : | /* nothing */ | ||
242 : | #define RGB_TO_YV12(SIZE,C1,C2,C3,C4) \ | ||
243 : | uint32_t r, g, b, r0, g0, b0; \ | ||
244 : | r0 = g0 = b0 = 0; \ | ||
245 : | READ_RGB_Y(SIZE, 0, 0, C1,C2,C3,C4) \ | ||
246 : | READ_RGB_Y(SIZE, 1, 0, C1,C2,C3,C4) \ | ||
247 : | READ_RGB_UV( 0, 0) | ||
248 : | edgomez | 195 | |
249 : | edgomez | 851 | #define RGBI_TO_YV12_ROW(SIZE,C1,C2,C3,C4) \ |
250 : | /* nothing */ | ||
251 : | #define RGBI_TO_YV12(SIZE,C1,C2,C3,C4) \ | ||
252 : | uint32_t r, g, b, r0, g0, b0, r1, g1, b1; \ | ||
253 : | r0 = g0 = b0 = r1 = g1 = b1 = 0; \ | ||
254 : | READ_RGB_Y(SIZE, 0, 0, C1,C2,C3,C4) \ | ||
255 : | READ_RGB_Y(SIZE, 1, 1, C1,C2,C3,C4) \ | ||
256 : | READ_RGB_Y(SIZE, 2, 0, C1,C2,C3,C4) \ | ||
257 : | READ_RGB_Y(SIZE, 3, 1, C1,C2,C3,C4) \ | ||
258 : | READ_RGB_UV( 0, 0) \ | ||
259 : | READ_RGB_UV( 1, 1) | ||
260 : | edgomez | 195 | |
261 : | |||
262 : | edgomez | 851 | /* yuyv/yuyvi input */ |
263 : | edgomez | 195 | |
264 : | edgomez | 851 | #define READ_YUYV_Y(ROW,C1,C2,C3,C4) \ |
265 : | y_ptr[(ROW)*y_stride+0] = x_ptr[(ROW)*x_stride+(C1)]; \ | ||
266 : | y_ptr[(ROW)*y_stride+1] = x_ptr[(ROW)*x_stride+(C3)]; | ||
267 : | #define READ_YUYV_UV(UV_ROW,ROW1,ROW2,C1,C2,C3,C4) \ | ||
268 : | u_ptr[(UV_ROW)*uv_stride] = (x_ptr[(ROW1)*x_stride+(C2)] + x_ptr[(ROW2)*x_stride+(C2)] + 1) / 2; \ | ||
269 : | v_ptr[(UV_ROW)*uv_stride] = (x_ptr[(ROW1)*x_stride+(C4)] + x_ptr[(ROW2)*x_stride+(C4)] + 1) / 2; | ||
270 : | edgomez | 195 | |
271 : | edgomez | 851 | #define YUYV_TO_YV12_ROW(SIZE,C1,C2,C3,C4) \ |
272 : | /* nothing */ | ||
273 : | #define YUYV_TO_YV12(SIZE,C1,C2,C3,C4) \ | ||
274 : | READ_YUYV_Y (0, C1,C2,C3,C4) \ | ||
275 : | READ_YUYV_Y (1, C1,C2,C3,C4) \ | ||
276 : | READ_YUYV_UV(0, 0,1, C1,C2,C3,C4) | ||
277 : | edgomez | 195 | |
278 : | edgomez | 851 | #define YUYVI_TO_YV12_ROW(SIZE,C1,C2,C3,C4) \ |
279 : | /* nothing */ | ||
280 : | #define YUYVI_TO_YV12(SIZE,C1,C2,C3,C4) \ | ||
281 : | READ_YUYV_Y (0, C1,C2,C3,C4) \ | ||
282 : | READ_YUYV_Y (1, C1,C2,C3,C4) \ | ||
283 : | READ_YUYV_Y (2, C1,C2,C3,C4) \ | ||
284 : | READ_YUYV_Y (3, C1,C2,C3,C4) \ | ||
285 : | READ_YUYV_UV(0, 0,2, C1,C2,C3,C4) \ | ||
286 : | READ_YUYV_UV(1, 1,3, C1,C2,C3,C4) | ||
287 : | edgomez | 195 | |
288 : | |||
289 : | edgomez | 851 | MAKE_COLORSPACE(rgb555_to_yv12_c, 2,2,2, RGB16_TO_YV12, MK_RGB555, 0,0,0) |
290 : | MAKE_COLORSPACE(rgb565_to_yv12_c, 2,2,2, RGB16_TO_YV12, MK_RGB565, 0,0,0) | ||
291 : | MAKE_COLORSPACE(bgr_to_yv12_c, 3,2,2, RGB_TO_YV12, 2,1,0, 0) | ||
292 : | MAKE_COLORSPACE(bgra_to_yv12_c, 4,2,2, RGB_TO_YV12, 2,1,0, 0) | ||
293 : | MAKE_COLORSPACE(abgr_to_yv12_c, 4,2,2, RGB_TO_YV12, 3,2,1, 0) | ||
294 : | MAKE_COLORSPACE(rgba_to_yv12_c, 4,2,2, RGB_TO_YV12, 0,1,2, 0) | ||
295 : | edgomez | 1290 | MAKE_COLORSPACE(argb_to_yv12_c, 4,2,2, RGB_TO_YV12, 1,2,3, 0) |
296 : | edgomez | 851 | MAKE_COLORSPACE(yuyv_to_yv12_c, 2,2,2, YUYV_TO_YV12, 0,1,2,3) |
297 : | MAKE_COLORSPACE(uyvy_to_yv12_c, 2,2,2, YUYV_TO_YV12, 1,0,3,2) | ||
298 : | edgomez | 195 | |
299 : | edgomez | 851 | MAKE_COLORSPACE(rgb555i_to_yv12_c, 2,2,4, RGB16I_TO_YV12, MK_RGB555, 0,0,0) |
300 : | MAKE_COLORSPACE(rgb565i_to_yv12_c, 2,2,4, RGB16I_TO_YV12, MK_RGB565, 0,0,0) | ||
301 : | MAKE_COLORSPACE(bgri_to_yv12_c, 3,2,4, RGBI_TO_YV12, 2,1,0, 0) | ||
302 : | MAKE_COLORSPACE(bgrai_to_yv12_c, 4,2,4, RGBI_TO_YV12, 2,1,0, 0) | ||
303 : | MAKE_COLORSPACE(abgri_to_yv12_c, 4,2,4, RGBI_TO_YV12, 3,2,1, 0) | ||
304 : | MAKE_COLORSPACE(rgbai_to_yv12_c, 4,2,4, RGBI_TO_YV12, 0,1,2, 0) | ||
305 : | edgomez | 1290 | MAKE_COLORSPACE(argbi_to_yv12_c, 4,2,4, RGBI_TO_YV12, 1,2,3, 0) |
306 : | edgomez | 851 | MAKE_COLORSPACE(yuyvi_to_yv12_c, 2,2,4, YUYVI_TO_YV12, 0,1,2,3) |
307 : | MAKE_COLORSPACE(uyvyi_to_yv12_c, 2,2,4, YUYVI_TO_YV12, 1,0,3,2) | ||
308 : | edgomez | 195 | |
309 : | |||
310 : | edgomez | 851 | /********** colorspace output (yv12_to_xxx) functions **********/ |
311 : | edgomez | 195 | |
312 : | edgomez | 851 | /* yuv -> rgb def's */ |
313 : | edgomez | 195 | |
314 : | #define RGB_Y_OUT 1.164 | ||
315 : | #define B_U_OUT 2.018 | ||
316 : | #define Y_ADD_OUT 16 | ||
317 : | |||
318 : | #define G_U_OUT 0.391 | ||
319 : | #define G_V_OUT 0.813 | ||
320 : | #define U_ADD_OUT 128 | ||
321 : | |||
322 : | #define R_V_OUT 1.596 | ||
323 : | #define V_ADD_OUT 128 | ||
324 : | |||
325 : | #define SCALEBITS_OUT 13 | ||
326 : | #define FIX_OUT(x) ((uint16_t) ((x) * (1L<<SCALEBITS_OUT) + 0.5)) | ||
327 : | |||
328 : | |||
329 : | edgomez | 851 | /* rgb16/rgb16i output */ |
330 : | edgomez | 195 | |
331 : | edgomez | 851 | #define MK_RGB555(R,G,B) \ |
332 : | ((MAX(0,MIN(255, R)) << 7) & 0x7c00) | \ | ||
333 : | ((MAX(0,MIN(255, G)) << 2) & 0x03e0) | \ | ||
334 : | ((MAX(0,MIN(255, B)) >> 3) & 0x001f) | ||
335 : | edgomez | 195 | |
336 : | edgomez | 851 | #define MK_RGB565(R,G,B) \ |
337 : | ((MAX(0,MIN(255, R)) << 8) & 0xf800) | \ | ||
338 : | ((MAX(0,MIN(255, G)) << 3) & 0x07e0) | \ | ||
339 : | ((MAX(0,MIN(255, B)) >> 3) & 0x001f) | ||
340 : | edgomez | 195 | |
341 : | edgomez | 851 | #define WRITE_RGB16(ROW,UV_ROW,C1) \ |
342 : | rgb_y = RGB_Y_tab[ y_ptr[y_stride + 0] ]; \ | ||
343 : | b[ROW] = (b[ROW] & 0x7) + ((rgb_y + b_u##UV_ROW) >> SCALEBITS_OUT); \ | ||
344 : | g[ROW] = (g[ROW] & 0x7) + ((rgb_y - g_uv##UV_ROW) >> SCALEBITS_OUT); \ | ||
345 : | r[ROW] = (r[ROW] & 0x7) + ((rgb_y + r_v##UV_ROW) >> SCALEBITS_OUT); \ | ||
346 : | *(uint16_t *) (x_ptr+((ROW)*x_stride)+0) = C1(r[ROW], g[ROW], b[ROW]); \ | ||
347 : | rgb_y = RGB_Y_tab[ y_ptr[y_stride + 1] ]; \ | ||
348 : | b[ROW] = (b[ROW] & 0x7) + ((rgb_y + b_u##UV_ROW) >> SCALEBITS_OUT); \ | ||
349 : | g[ROW] = (g[ROW] & 0x7) + ((rgb_y - g_uv##UV_ROW) >> SCALEBITS_OUT); \ | ||
350 : | r[ROW] = (r[ROW] & 0x7) + ((rgb_y + r_v##UV_ROW) >> SCALEBITS_OUT); \ | ||
351 : | *(uint16_t *) (x_ptr+((ROW)*x_stride)+2) = C1(r[ROW], g[ROW], b[ROW]); | ||
352 : | edgomez | 195 | |
353 : | edgomez | 851 | #define YV12_TO_RGB16_ROW(SIZE,C1,C2,C3,C4) \ |
354 : | int r[2], g[2], b[2]; \ | ||
355 : | r[0] = r[1] = g[0] = g[1] = b[0] = b[1] = 0; | ||
356 : | #define YV12_TO_RGB16(SIZE,C1,C2,C3,C4) \ | ||
357 : | int rgb_y; \ | ||
358 : | int b_u0 = B_U_tab[ u_ptr[0] ]; \ | ||
359 : | int g_uv0 = G_U_tab[ u_ptr[0] ] + G_V_tab[ v_ptr[0] ]; \ | ||
360 : | int r_v0 = R_V_tab[ v_ptr[0] ]; \ | ||
361 : | WRITE_RGB16(0, 0, C1) \ | ||
362 : | WRITE_RGB16(1, 0, C1) | ||
363 : | edgomez | 195 | |
364 : | edgomez | 851 | #define YV12_TO_RGB16I_ROW(SIZE,C1,C2,C3,C4) \ |
365 : | int r[4], g[4], b[4]; \ | ||
366 : | r[0] = r[1] = r[2] = r[3] = 0; \ | ||
367 : | g[0] = g[1] = g[2] = g[3] = 0; \ | ||
368 : | b[0] = b[1] = b[2] = b[3] = 0; | ||
369 : | #define YV12_TO_RGB16I(SIZE,C1,C2,C3,C4) \ | ||
370 : | int rgb_y; \ | ||
371 : | int b_u0 = B_U_tab[ u_ptr[0] ]; \ | ||
372 : | int g_uv0 = G_U_tab[ u_ptr[0] ] + G_V_tab[ v_ptr[0] ]; \ | ||
373 : | int r_v0 = R_V_tab[ v_ptr[0] ]; \ | ||
374 : | int b_u1 = B_U_tab[ u_ptr[uv_stride] ]; \ | ||
375 : | int g_uv1 = G_U_tab[ u_ptr[uv_stride] ] + G_V_tab[ v_ptr[uv_stride] ]; \ | ||
376 : | int r_v1 = R_V_tab[ v_ptr[uv_stride] ]; \ | ||
377 : | WRITE_RGB16(0, 0, C1) \ | ||
378 : | WRITE_RGB16(1, 1, C1) \ | ||
379 : | WRITE_RGB16(2, 0, C1) \ | ||
380 : | WRITE_RGB16(3, 1, C1) \ | ||
381 : | edgomez | 195 | |
382 : | edgomez | 1161 | |
383 : | edgomez | 851 | /* rgb/rgbi output */ |
384 : | edgomez | 195 | |
385 : | edgomez | 851 | #define WRITE_RGB(SIZE,ROW,UV_ROW,C1,C2,C3,C4) \ |
386 : | rgb_y = RGB_Y_tab[ y_ptr[(ROW)*y_stride + 0] ]; \ | ||
387 : | x_ptr[(ROW)*x_stride+(C3)] = MAX(0, MIN(255, (rgb_y + b_u##UV_ROW) >> SCALEBITS_OUT)); \ | ||
388 : | x_ptr[(ROW)*x_stride+(C2)] = MAX(0, MIN(255, (rgb_y - g_uv##UV_ROW) >> SCALEBITS_OUT)); \ | ||
389 : | x_ptr[(ROW)*x_stride+(C1)] = MAX(0, MIN(255, (rgb_y + r_v##UV_ROW) >> SCALEBITS_OUT)); \ | ||
390 : | if ((SIZE)>3) x_ptr[(ROW)*x_stride+(C4)] = 0; \ | ||
391 : | rgb_y = RGB_Y_tab[ y_ptr[(ROW)*y_stride + 1] ]; \ | ||
392 : | x_ptr[(ROW)*x_stride+(SIZE)+(C3)] = MAX(0, MIN(255, (rgb_y + b_u##UV_ROW) >> SCALEBITS_OUT)); \ | ||
393 : | x_ptr[(ROW)*x_stride+(SIZE)+(C2)] = MAX(0, MIN(255, (rgb_y - g_uv##UV_ROW) >> SCALEBITS_OUT)); \ | ||
394 : | x_ptr[(ROW)*x_stride+(SIZE)+(C1)] = MAX(0, MIN(255, (rgb_y + r_v##UV_ROW) >> SCALEBITS_OUT)); \ | ||
395 : | if ((SIZE)>3) x_ptr[(ROW)*x_stride+(SIZE)+(C4)] = 0; | ||
396 : | edgomez | 195 | |
397 : | |||
398 : | edgomez | 851 | #define YV12_TO_RGB_ROW(SIZE,C1,C2,C3,C4) /* nothing */ |
399 : | #define YV12_TO_RGB(SIZE,C1,C2,C3,C4) \ | ||
400 : | int rgb_y; \ | ||
401 : | int b_u0 = B_U_tab[ u_ptr[0] ]; \ | ||
402 : | int g_uv0 = G_U_tab[ u_ptr[0] ] + G_V_tab[ v_ptr[0] ]; \ | ||
403 : | int r_v0 = R_V_tab[ v_ptr[0] ]; \ | ||
404 : | WRITE_RGB(SIZE, 0, 0, C1,C2,C3,C4) \ | ||
405 : | WRITE_RGB(SIZE, 1, 0, C1,C2,C3,C4) | ||
406 : | edgomez | 195 | |
407 : | edgomez | 851 | #define YV12_TO_RGBI_ROW(SIZE,C1,C2,C3,C4) /* nothing */ |
408 : | #define YV12_TO_RGBI(SIZE,C1,C2,C3,C4) \ | ||
409 : | int rgb_y; \ | ||
410 : | int b_u0 = B_U_tab[ u_ptr[0] ]; \ | ||
411 : | int g_uv0 = G_U_tab[ u_ptr[0] ] + G_V_tab[ v_ptr[0] ]; \ | ||
412 : | int r_v0 = R_V_tab[ v_ptr[0] ]; \ | ||
413 : | int b_u1 = B_U_tab[ u_ptr[uv_stride] ]; \ | ||
414 : | int g_uv1 = G_U_tab[ u_ptr[uv_stride] ] + G_V_tab[ v_ptr[uv_stride] ]; \ | ||
415 : | int r_v1 = R_V_tab[ v_ptr[uv_stride] ]; \ | ||
416 : | WRITE_RGB(SIZE, 0, 0, C1,C2,C3,C4) \ | ||
417 : | WRITE_RGB(SIZE, 1, 1, C1,C2,C3,C4) \ | ||
418 : | WRITE_RGB(SIZE, 2, 0, C1,C2,C3,C4) \ | ||
419 : | WRITE_RGB(SIZE, 3, 1, C1,C2,C3,C4) | ||
420 : | edgomez | 195 | |
421 : | |||
422 : | edgomez | 851 | /* yuyv/yuyvi output */ |
423 : | edgomez | 195 | |
424 : | edgomez | 851 | #define WRITE_YUYV(ROW,UV_ROW,C1,C2,C3,C4) \ |
425 : | x_ptr[(ROW)*x_stride+(C1)] = y_ptr[ (ROW)*y_stride +0]; \ | ||
426 : | x_ptr[(ROW)*x_stride+(C2)] = u_ptr[(UV_ROW)*uv_stride+0]; \ | ||
427 : | x_ptr[(ROW)*x_stride+(C3)] = y_ptr[ (ROW)*y_stride +1]; \ | ||
428 : | x_ptr[(ROW)*x_stride+(C4)] = v_ptr[(UV_ROW)*uv_stride+0]; \ | ||
429 : | edgomez | 195 | |
430 : | edgomez | 851 | #define YV12_TO_YUYV_ROW(SIZE,C1,C2,C3,C4) /* nothing */ |
431 : | #define YV12_TO_YUYV(SIZE,C1,C2,C3,C4) \ | ||
432 : | WRITE_YUYV(0, 0, C1,C2,C3,C4) \ | ||
433 : | edgomez | 1161 | WRITE_YUYV(1, 0, C1,C2,C3,C4) |
434 : | edgomez | 195 | |
435 : | edgomez | 851 | #define YV12_TO_YUYVI_ROW(SIZE,C1,C2,C3,C4) /* nothing */ |
436 : | #define YV12_TO_YUYVI(SIZE,C1,C2,C3,C4) \ | ||
437 : | WRITE_YUYV(0, 0, C1,C2,C3,C4) \ | ||
438 : | WRITE_YUYV(1, 1, C1,C2,C3,C4) \ | ||
439 : | WRITE_YUYV(2, 0, C1,C2,C3,C4) \ | ||
440 : | WRITE_YUYV(3, 1, C1,C2,C3,C4) | ||
441 : | edgomez | 195 | |
442 : | |||
443 : | edgomez | 851 | MAKE_COLORSPACE(yv12_to_rgb555_c, 2,2,2, YV12_TO_RGB16, MK_RGB555, 0,0,0) |
444 : | MAKE_COLORSPACE(yv12_to_rgb565_c, 2,2,2, YV12_TO_RGB16, MK_RGB565, 0,0,0) | ||
445 : | MAKE_COLORSPACE(yv12_to_bgr_c, 3,2,2, YV12_TO_RGB, 2,1,0, 0) | ||
446 : | MAKE_COLORSPACE(yv12_to_bgra_c, 4,2,2, YV12_TO_RGB, 2,1,0,3) | ||
447 : | MAKE_COLORSPACE(yv12_to_abgr_c, 4,2,2, YV12_TO_RGB, 3,2,1,0) | ||
448 : | MAKE_COLORSPACE(yv12_to_rgba_c, 4,2,2, YV12_TO_RGB, 0,1,2,3) | ||
449 : | edgomez | 1290 | MAKE_COLORSPACE(yv12_to_argb_c, 4,2,2, YV12_TO_RGB, 1,2,3,0) |
450 : | edgomez | 851 | MAKE_COLORSPACE(yv12_to_yuyv_c, 2,2,2, YV12_TO_YUYV, 0,1,2,3) |
451 : | MAKE_COLORSPACE(yv12_to_uyvy_c, 2,2,2, YV12_TO_YUYV, 1,0,3,2) | ||
452 : | edgomez | 195 | |
453 : | edgomez | 851 | MAKE_COLORSPACE(yv12_to_rgb555i_c, 2,2,4, YV12_TO_RGB16I, MK_RGB555, 0,0,0) |
454 : | MAKE_COLORSPACE(yv12_to_rgb565i_c, 2,2,4, YV12_TO_RGB16I, MK_RGB565, 0,0,0) | ||
455 : | MAKE_COLORSPACE(yv12_to_bgri_c, 3,2,4, YV12_TO_RGBI, 2,1,0, 0) | ||
456 : | MAKE_COLORSPACE(yv12_to_bgrai_c, 4,2,4, YV12_TO_RGBI, 2,1,0,3) | ||
457 : | MAKE_COLORSPACE(yv12_to_abgri_c, 4,2,4, YV12_TO_RGBI, 3,2,1,0) | ||
458 : | MAKE_COLORSPACE(yv12_to_rgbai_c, 4,2,4, YV12_TO_RGBI, 0,1,2,3) | ||
459 : | edgomez | 1290 | MAKE_COLORSPACE(yv12_to_argbi_c, 4,2,4, YV12_TO_RGBI, 1,2,3,0) |
460 : | edgomez | 851 | MAKE_COLORSPACE(yv12_to_yuyvi_c, 2,2,4, YV12_TO_YUYVI, 0,1,2,3) |
461 : | MAKE_COLORSPACE(yv12_to_uyvyi_c, 2,2,4, YV12_TO_YUYVI, 1,0,3,2) | ||
462 : | edgomez | 195 | |
463 : | |||
464 : | |||
465 : | edgomez | 851 | /* yv12 to yv12 copy function */ |
466 : | edgomez | 195 | |
467 : | void | ||
468 : | edgomez | 1161 | yv12_to_yv12_c(uint8_t * y_dst, uint8_t * u_dst, uint8_t * v_dst, |
469 : | edgomez | 851 | int y_dst_stride, int uv_dst_stride, |
470 : | edgomez | 1161 | uint8_t * y_src, uint8_t * u_src, uint8_t * v_src, |
471 : | edgomez | 851 | int y_src_stride, int uv_src_stride, |
472 : | int width, int height, int vflip) | ||
473 : | edgomez | 195 | { |
474 : | edgomez | 851 | int width2 = width / 2; |
475 : | int height2 = height / 2; | ||
476 : | int y; | ||
477 : | edgomez | 195 | |
478 : | edgomez | 851 | if (vflip) { |
479 : | y_src += (height - 1) * y_src_stride; | ||
480 : | u_src += (height2 - 1) * uv_src_stride; | ||
481 : | v_src += (height2 - 1) * uv_src_stride; | ||
482 : | y_src_stride = -y_src_stride; | ||
483 : | uv_src_stride = -uv_src_stride; | ||
484 : | edgomez | 195 | } |
485 : | |||
486 : | for (y = height; y; y--) { | ||
487 : | edgomez | 851 | memcpy(y_dst, y_src, width); |
488 : | y_src += y_src_stride; | ||
489 : | y_dst += y_dst_stride; | ||
490 : | edgomez | 195 | } |
491 : | |||
492 : | edgomez | 851 | for (y = height2; y; y--) { |
493 : | memcpy(u_dst, u_src, width2); | ||
494 : | u_src += uv_src_stride; | ||
495 : | u_dst += uv_dst_stride; | ||
496 : | edgomez | 195 | } |
497 : | |||
498 : | edgomez | 851 | for (y = height2; y; y--) { |
499 : | memcpy(v_dst, v_src, width2); | ||
500 : | v_src += uv_src_stride; | ||
501 : | v_dst += uv_dst_stride; | ||
502 : | edgomez | 195 | } |
503 : | } | ||
504 : | |||
505 : | |||
506 : | |||
507 : | edgomez | 851 | /* initialize rgb lookup tables */ |
508 : | edgomez | 195 | |
509 : | void | ||
510 : | edgomez | 851 | colorspace_init(void) |
511 : | edgomez | 195 | { |
512 : | edgomez | 851 | int32_t i; |
513 : | edgomez | 195 | |
514 : | edgomez | 851 | for (i = 0; i < 256; i++) { |
515 : | RGB_Y_tab[i] = FIX_OUT(RGB_Y_OUT) * (i - Y_ADD_OUT); | ||
516 : | B_U_tab[i] = FIX_OUT(B_U_OUT) * (i - U_ADD_OUT); | ||
517 : | G_U_tab[i] = FIX_OUT(G_U_OUT) * (i - U_ADD_OUT); | ||
518 : | G_V_tab[i] = FIX_OUT(G_V_OUT) * (i - V_ADD_OUT); | ||
519 : | R_V_tab[i] = FIX_OUT(R_V_OUT) * (i - V_ADD_OUT); | ||
520 : | edgomez | 195 | } |
521 : | } |
No admin address has been configured | ViewVC Help |
Powered by ViewVC 1.0.4 |