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