Parent Directory | Revision Log
Revision 433 - (view) (download)
1 : | chl | 433 | /***************************************************************************** |
2 : | edgomez | 195 | * |
3 : | chl | 433 | * XVID MPEG-4 VIDEO CODEC |
4 : | * - colorspace conversion module - | ||
5 : | edgomez | 195 | * |
6 : | chl | 433 | * Copyright(C) 2002 Peter Ross <pross@xvid.org> |
7 : | edgomez | 195 | * |
8 : | chl | 433 | * This program is an implementation of a part of one or more MPEG-4 |
9 : | * Video tools as specified in ISO/IEC 14496-2 standard. Those intending | ||
10 : | * to use this software module in hardware or software products are | ||
11 : | * advised that its use may infringe existing patents or copyrights, and | ||
12 : | * any such use would be at such party's own risk. The original | ||
13 : | * developer of this software module and his/her company, and subsequent | ||
14 : | * editors and their companies, will have no liability for use of this | ||
15 : | * software or modifications or derivatives thereof. | ||
16 : | edgomez | 195 | * |
17 : | chl | 433 | * This program is free software; you can redistribute it and/or modify |
18 : | * it under the terms of the GNU General Public License as published by | ||
19 : | * the Free Software Foundation; either version 2 of the License, or | ||
20 : | * (at your option) any later version. | ||
21 : | edgomez | 195 | * |
22 : | chl | 433 | * This program is distributed in the hope that it will be useful, |
23 : | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
24 : | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
25 : | * GNU General Public License for more details. | ||
26 : | edgomez | 195 | * |
27 : | chl | 433 | * You should have received a copy of the GNU General Public License |
28 : | * along with this program; if not, write to the Free Software | ||
29 : | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
30 : | edgomez | 195 | * |
31 : | chl | 433 | ****************************************************************************/ |
32 : | edgomez | 195 | |
33 : | #include <string.h> // memcpy | ||
34 : | |||
35 : | #include "colorspace.h" | ||
36 : | #include "../divx4.h" // DEC_PICTURE | ||
37 : | |||
38 : | // function pointers | ||
39 : | |||
40 : | /* input */ | ||
41 : | color_inputFuncPtr rgb555_to_yv12; | ||
42 : | color_inputFuncPtr rgb565_to_yv12; | ||
43 : | color_inputFuncPtr rgb24_to_yv12; | ||
44 : | color_inputFuncPtr rgb32_to_yv12; | ||
45 : | color_inputFuncPtr yuv_to_yv12; | ||
46 : | color_inputFuncPtr yuyv_to_yv12; | ||
47 : | color_inputFuncPtr uyvy_to_yv12; | ||
48 : | |||
49 : | /* output */ | ||
50 : | color_outputFuncPtr yv12_to_rgb555; | ||
51 : | color_outputFuncPtr yv12_to_rgb565; | ||
52 : | color_outputFuncPtr yv12_to_rgb24; | ||
53 : | color_outputFuncPtr yv12_to_rgb32; | ||
54 : | color_outputFuncPtr yv12_to_yuv; | ||
55 : | color_outputFuncPtr yv12_to_yuyv; | ||
56 : | color_outputFuncPtr yv12_to_uyvy; | ||
57 : | |||
58 : | #define MIN(A,B) ((A)<(B)?(A):(B)) | ||
59 : | #define MAX(A,B) ((A)>(B)?(A):(B)) | ||
60 : | |||
61 : | /* rgb -> yuv def's | ||
62 : | |||
63 : | this following constants are "official spec" | ||
64 : | Video Demystified" (ISBN 1-878707-09-4) | ||
65 : | |||
66 : | rgb<->yuv _is_ lossy, since most programs do the conversion differently | ||
67 : | |||
68 : | SCALEBITS/FIX taken from ffmpeg | ||
69 : | */ | ||
70 : | |||
71 : | #define Y_R_IN 0.257 | ||
72 : | #define Y_G_IN 0.504 | ||
73 : | #define Y_B_IN 0.098 | ||
74 : | #define Y_ADD_IN 16 | ||
75 : | |||
76 : | #define U_R_IN 0.148 | ||
77 : | #define U_G_IN 0.291 | ||
78 : | #define U_B_IN 0.439 | ||
79 : | #define U_ADD_IN 128 | ||
80 : | |||
81 : | #define V_R_IN 0.439 | ||
82 : | #define V_G_IN 0.368 | ||
83 : | #define V_B_IN 0.071 | ||
84 : | #define V_ADD_IN 128 | ||
85 : | |||
86 : | #define SCALEBITS_IN 8 | ||
87 : | #define FIX_IN(x) ((uint16_t) ((x) * (1L<<SCALEBITS_IN) + 0.5)) | ||
88 : | |||
89 : | |||
90 : | int32_t RGB_Y_tab[256]; | ||
91 : | int32_t B_U_tab[256]; | ||
92 : | int32_t G_U_tab[256]; | ||
93 : | int32_t G_V_tab[256]; | ||
94 : | int32_t R_V_tab[256]; | ||
95 : | |||
96 : | |||
97 : | /* rgb555 -> yuv 4:2:0 planar */ | ||
98 : | void | ||
99 : | rgb555_to_yv12_c(uint8_t * y_out, | ||
100 : | uint8_t * u_out, | ||
101 : | uint8_t * v_out, | ||
102 : | uint8_t * src, | ||
103 : | int width, | ||
104 : | int height, | ||
105 : | int y_stride) | ||
106 : | { | ||
107 : | int32_t src_stride = width * 2; | ||
108 : | uint32_t y_dif = y_stride - width; | ||
109 : | uint32_t uv_dif = (y_stride - width) / 2; | ||
110 : | uint32_t x, y; | ||
111 : | |||
112 : | if (height < 0) { | ||
113 : | height = -height; | ||
114 : | src += (height - 1) * src_stride; | ||
115 : | src_stride = -src_stride; | ||
116 : | } | ||
117 : | |||
118 : | |||
119 : | for (y = height / 2; y; y--) { | ||
120 : | // process one 2x2 block per iteration | ||
121 : | for (x = 0; x < (uint32_t) width; x += 2) { | ||
122 : | int rgb, r, g, b, r4, g4, b4; | ||
123 : | |||
124 : | rgb = *(uint16_t *) (src + x * 2); | ||
125 : | b4 = b = (rgb << 3) & 0xf8; | ||
126 : | g4 = g = (rgb >> 2) & 0xf8; | ||
127 : | r4 = r = (rgb >> 7) & 0xf8; | ||
128 : | y_out[0] = | ||
129 : | (uint8_t) ((FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + | ||
130 : | FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; | ||
131 : | |||
132 : | rgb = *(uint16_t *) (src + x * 2 + src_stride); | ||
133 : | b4 += b = (rgb << 3) & 0xf8; | ||
134 : | g4 += g = (rgb >> 2) & 0xf8; | ||
135 : | r4 += r = (rgb >> 7) & 0xf8; | ||
136 : | y_out[y_stride] = | ||
137 : | (uint8_t) ((FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + | ||
138 : | FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; | ||
139 : | |||
140 : | rgb = *(uint16_t *) (src + x * 2 + 2); | ||
141 : | b4 += b = (rgb << 3) & 0xf8; | ||
142 : | g4 += g = (rgb >> 2) & 0xf8; | ||
143 : | r4 += r = (rgb >> 7) & 0xf8; | ||
144 : | y_out[1] = | ||
145 : | (uint8_t) ((FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + | ||
146 : | FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; | ||
147 : | |||
148 : | rgb = *(uint16_t *) (src + x * 2 + src_stride + 2); | ||
149 : | b4 += b = (rgb << 3) & 0xf8; | ||
150 : | g4 += g = (rgb >> 2) & 0xf8; | ||
151 : | r4 += r = (rgb >> 7) & 0xf8; | ||
152 : | y_out[y_stride + 1] = | ||
153 : | (uint8_t) ((FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + | ||
154 : | FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; | ||
155 : | |||
156 : | *u_out++ = | ||
157 : | (uint8_t) ((-FIX_IN(U_R_IN) * r4 - FIX_IN(U_G_IN) * g4 + | ||
158 : | FIX_IN(U_B_IN) * b4) >> (SCALEBITS_IN + 2)) + | ||
159 : | U_ADD_IN; | ||
160 : | |||
161 : | |||
162 : | *v_out++ = | ||
163 : | (uint8_t) ((FIX_IN(V_R_IN) * r4 - FIX_IN(V_G_IN) * g4 - | ||
164 : | FIX_IN(V_B_IN) * b4) >> (SCALEBITS_IN + 2)) + | ||
165 : | V_ADD_IN; | ||
166 : | |||
167 : | y_out += 2; | ||
168 : | } | ||
169 : | src += src_stride * 2; | ||
170 : | y_out += y_dif + y_stride; | ||
171 : | u_out += uv_dif; | ||
172 : | v_out += uv_dif; | ||
173 : | } | ||
174 : | } | ||
175 : | |||
176 : | |||
177 : | |||
178 : | /* rgb565_to_yuv_c | ||
179 : | NOTE: identical to rgb555 except for shift/mask | ||
180 : | not tested */ | ||
181 : | |||
182 : | void | ||
183 : | rgb565_to_yv12_c(uint8_t * y_out, | ||
184 : | uint8_t * u_out, | ||
185 : | uint8_t * v_out, | ||
186 : | uint8_t * src, | ||
187 : | int width, | ||
188 : | int height, | ||
189 : | int y_stride) | ||
190 : | { | ||
191 : | int32_t src_stride = width * 2; | ||
192 : | |||
193 : | uint32_t y_dif = y_stride - width; | ||
194 : | uint32_t uv_dif = (y_stride - width) / 2; | ||
195 : | uint32_t x, y; | ||
196 : | |||
197 : | if (height < 0) { | ||
198 : | height = -height; | ||
199 : | src += (height - 1) * src_stride; | ||
200 : | src_stride = -src_stride; | ||
201 : | } | ||
202 : | |||
203 : | |||
204 : | for (y = height / 2; y; y--) { | ||
205 : | // process one 2x2 block per iteration | ||
206 : | for (x = 0; x < (uint32_t) width; x += 2) { | ||
207 : | int rgb, r, g, b, r4, g4, b4; | ||
208 : | |||
209 : | rgb = *(uint16_t *) (src + x * 2); | ||
210 : | b4 = b = (rgb << 3) & 0xf8; | ||
211 : | g4 = g = (rgb >> 3) & 0xfc; | ||
212 : | r4 = r = (rgb >> 8) & 0xf8; | ||
213 : | y_out[0] = | ||
214 : | (uint8_t) ((FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + | ||
215 : | FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; | ||
216 : | |||
217 : | rgb = *(uint16_t *) (src + x * 2 + src_stride); | ||
218 : | b4 += b = (rgb << 3) & 0xf8; | ||
219 : | g4 += g = (rgb >> 3) & 0xfc; | ||
220 : | r4 += r = (rgb >> 8) & 0xf8; | ||
221 : | y_out[y_stride] = | ||
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 : | |||
225 : | rgb = *(uint16_t *) (src + x * 2 + 2); | ||
226 : | b4 += b = (rgb << 3) & 0xf8; | ||
227 : | g4 += g = (rgb >> 3) & 0xfc; | ||
228 : | r4 += r = (rgb >> 8) & 0xf8; | ||
229 : | y_out[1] = | ||
230 : | (uint8_t) ((FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + | ||
231 : | FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; | ||
232 : | |||
233 : | rgb = *(uint16_t *) (src + x * 2 + src_stride + 2); | ||
234 : | b4 += b = (rgb << 3) & 0xf8; | ||
235 : | g4 += g = (rgb >> 3) & 0xfc; | ||
236 : | r4 += r = (rgb >> 8) & 0xf8; | ||
237 : | y_out[y_stride + 1] = | ||
238 : | (uint8_t) ((FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + | ||
239 : | FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; | ||
240 : | |||
241 : | *u_out++ = | ||
242 : | (uint8_t) ((-FIX_IN(U_R_IN) * r4 - FIX_IN(U_G_IN) * g4 + | ||
243 : | FIX_IN(U_B_IN) * b4) >> (SCALEBITS_IN + 2)) + | ||
244 : | U_ADD_IN; | ||
245 : | |||
246 : | |||
247 : | *v_out++ = | ||
248 : | (uint8_t) ((FIX_IN(V_R_IN) * r4 - FIX_IN(V_G_IN) * g4 - | ||
249 : | FIX_IN(V_B_IN) * b4) >> (SCALEBITS_IN + 2)) + | ||
250 : | V_ADD_IN; | ||
251 : | |||
252 : | y_out += 2; | ||
253 : | } | ||
254 : | src += src_stride * 2; | ||
255 : | y_out += y_dif + y_stride; | ||
256 : | u_out += uv_dif; | ||
257 : | v_out += uv_dif; | ||
258 : | } | ||
259 : | } | ||
260 : | |||
261 : | |||
262 : | |||
263 : | |||
264 : | /* rgb24 -> yuv 4:2:0 planar | ||
265 : | |||
266 : | NOTE: always flips. | ||
267 : | */ | ||
268 : | |||
269 : | void | ||
270 : | rgb24_to_yv12_c(uint8_t * y_out, | ||
271 : | uint8_t * u_out, | ||
272 : | uint8_t * v_out, | ||
273 : | uint8_t * src, | ||
274 : | int width, | ||
275 : | int height, | ||
276 : | int stride) | ||
277 : | { | ||
278 : | uint32_t width3 = (width << 1) + width; /* width * 3 */ | ||
279 : | uint32_t src_dif = (width << 3) + width; /* width3 * 3 */ | ||
280 : | uint32_t y_dif = (stride << 1) - width; | ||
281 : | uint32_t uv_dif = (stride - width) >> 1; | ||
282 : | uint32_t x, y; | ||
283 : | |||
284 : | src += (height - 2) * width3; | ||
285 : | |||
286 : | |||
287 : | for (y = height >> 1; y; y--) { | ||
288 : | for (x = width >> 1; x; x--) { | ||
289 : | uint32_t r, g, b, r4, g4, b4; | ||
290 : | |||
291 : | b4 = b = src[0]; | ||
292 : | g4 = g = src[1]; | ||
293 : | r4 = r = src[2]; | ||
294 : | y_out[stride + 0] = | ||
295 : | (uint8_t) ((FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + | ||
296 : | FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; | ||
297 : | |||
298 : | b4 += (b = src[3]); | ||
299 : | g4 += (g = src[4]); | ||
300 : | r4 += (r = src[5]); | ||
301 : | y_out[stride + 1] = | ||
302 : | (uint8_t) ((FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + | ||
303 : | FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; | ||
304 : | |||
305 : | b4 += (b = src[width3 + 0]); | ||
306 : | g4 += (g = src[width3 + 1]); | ||
307 : | r4 += (r = src[width3 + 2]); | ||
308 : | y_out[0] = | ||
309 : | (uint8_t) ((FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + | ||
310 : | FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; | ||
311 : | |||
312 : | b4 += (b = src[width3 + 3]); | ||
313 : | g4 += (g = src[width3 + 4]); | ||
314 : | r4 += (r = src[width3 + 5]); | ||
315 : | y_out[1] = | ||
316 : | (uint8_t) ((FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + | ||
317 : | FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; | ||
318 : | |||
319 : | *u_out++ = | ||
320 : | (uint8_t) ((-FIX_IN(U_R_IN) * r4 - FIX_IN(U_G_IN) * g4 + | ||
321 : | FIX_IN(U_B_IN) * b4) >> (SCALEBITS_IN + 2)) + | ||
322 : | U_ADD_IN; | ||
323 : | |||
324 : | |||
325 : | *v_out++ = | ||
326 : | (uint8_t) ((FIX_IN(V_R_IN) * r4 - FIX_IN(V_G_IN) * g4 - | ||
327 : | FIX_IN(V_B_IN) * b4) >> (SCALEBITS_IN + 2)) + | ||
328 : | V_ADD_IN; | ||
329 : | |||
330 : | |||
331 : | src += 6; | ||
332 : | y_out += 2; | ||
333 : | } | ||
334 : | src -= src_dif; | ||
335 : | y_out += y_dif; | ||
336 : | u_out += uv_dif; | ||
337 : | v_out += uv_dif; | ||
338 : | } | ||
339 : | } | ||
340 : | |||
341 : | |||
342 : | /* rgb32 -> yuv 4:2:0 planar | ||
343 : | |||
344 : | NOTE: always flips | ||
345 : | */ | ||
346 : | |||
347 : | void | ||
348 : | rgb32_to_yv12_c(uint8_t * y_out, | ||
349 : | uint8_t * u_out, | ||
350 : | uint8_t * v_out, | ||
351 : | uint8_t * src, | ||
352 : | int width, | ||
353 : | int height, | ||
354 : | int stride) | ||
355 : | { | ||
356 : | uint32_t width4 = (width << 2); /* width * 4 */ | ||
357 : | uint32_t src_dif = 3 * width4; | ||
358 : | uint32_t y_dif = (stride << 1) - width; | ||
359 : | uint32_t uv_dif = (stride - width) >> 1; | ||
360 : | uint32_t x, y; | ||
361 : | |||
362 : | src += (height - 2) * width4; | ||
363 : | |||
364 : | for (y = height >> 1; y; y--) { | ||
365 : | for (x = width >> 1; x; x--) { | ||
366 : | uint32_t r, g, b, r4, g4, b4; | ||
367 : | |||
368 : | b4 = b = src[0]; | ||
369 : | g4 = g = src[1]; | ||
370 : | r4 = r = src[2]; | ||
371 : | y_out[stride + 0] = | ||
372 : | (uint8_t) ((FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + | ||
373 : | FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; | ||
374 : | |||
375 : | b4 += (b = src[4]); | ||
376 : | g4 += (g = src[5]); | ||
377 : | r4 += (r = src[6]); | ||
378 : | y_out[stride + 1] = | ||
379 : | (uint8_t) ((FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + | ||
380 : | FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; | ||
381 : | |||
382 : | b4 += (b = src[width4 + 0]); | ||
383 : | g4 += (g = src[width4 + 1]); | ||
384 : | r4 += (r = src[width4 + 2]); | ||
385 : | |||
386 : | y_out[0] = | ||
387 : | (uint8_t) ((FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + | ||
388 : | FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; | ||
389 : | |||
390 : | b4 += (b = src[width4 + 4]); | ||
391 : | g4 += (g = src[width4 + 5]); | ||
392 : | r4 += (r = src[width4 + 6]); | ||
393 : | y_out[1] = | ||
394 : | (uint8_t) ((FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + | ||
395 : | FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; | ||
396 : | |||
397 : | *u_out++ = | ||
398 : | (uint8_t) ((-FIX_IN(U_R_IN) * r4 - FIX_IN(U_G_IN) * g4 + | ||
399 : | FIX_IN(U_B_IN) * b4) >> (SCALEBITS_IN + 2)) + | ||
400 : | U_ADD_IN; | ||
401 : | |||
402 : | *v_out++ = | ||
403 : | (uint8_t) ((FIX_IN(V_R_IN) * r4 - FIX_IN(V_G_IN) * g4 - | ||
404 : | FIX_IN(V_B_IN) * b4) >> (SCALEBITS_IN + 2)) + | ||
405 : | V_ADD_IN; | ||
406 : | |||
407 : | src += 8; | ||
408 : | y_out += 2; | ||
409 : | } | ||
410 : | src -= src_dif; | ||
411 : | y_out += y_dif; | ||
412 : | u_out += uv_dif; | ||
413 : | v_out += uv_dif; | ||
414 : | } | ||
415 : | } | ||
416 : | |||
417 : | /* yuv planar -> yuv 4:2:0 planar | ||
418 : | |||
419 : | NOTE: does not flip */ | ||
420 : | |||
421 : | void | ||
422 : | yuv_to_yv12_c(uint8_t * y_out, | ||
423 : | uint8_t * u_out, | ||
424 : | uint8_t * v_out, | ||
425 : | uint8_t * src, | ||
426 : | int width, | ||
427 : | int height, | ||
428 : | int stride) | ||
429 : | { | ||
430 : | uint32_t stride2 = stride >> 1; | ||
431 : | uint32_t width2 = width >> 1; | ||
432 : | uint32_t y; | ||
433 : | |||
434 : | for (y = height; y; y--) { | ||
435 : | memcpy(y_out, src, width); | ||
436 : | src += width; | ||
437 : | y_out += stride; | ||
438 : | } | ||
439 : | |||
440 : | for (y = height >> 1; y; y--) { | ||
441 : | memcpy(u_out, src, width2); | ||
442 : | src += width2; | ||
443 : | u_out += stride2; | ||
444 : | } | ||
445 : | |||
446 : | for (y = height >> 1; y; y--) { | ||
447 : | memcpy(v_out, src, width2); | ||
448 : | src += width2; | ||
449 : | v_out += stride2; | ||
450 : | } | ||
451 : | } | ||
452 : | |||
453 : | |||
454 : | |||
455 : | /* yuyv (yuv2) packed -> yuv 4:2:0 planar | ||
456 : | |||
457 : | NOTE: does not flip */ | ||
458 : | |||
459 : | void | ||
460 : | yuyv_to_yv12_c(uint8_t * y_out, | ||
461 : | uint8_t * u_out, | ||
462 : | uint8_t * v_out, | ||
463 : | uint8_t * src, | ||
464 : | int width, | ||
465 : | int height, | ||
466 : | int stride) | ||
467 : | { | ||
468 : | uint32_t width2 = width + width; | ||
469 : | uint32_t y_dif = stride - width; | ||
470 : | uint32_t uv_dif = y_dif >> 1; | ||
471 : | uint32_t x, y; | ||
472 : | |||
473 : | for (y = height >> 1; y; y--) { | ||
474 : | |||
475 : | for (x = width >> 1; x; x--) { | ||
476 : | *y_out++ = *src++; | ||
477 : | //*u_out++ = *src++; | ||
478 : | *u_out++ = (*(src + width2) + *src) >> 1; | ||
479 : | src++; | ||
480 : | *y_out++ = *src++; | ||
481 : | //*v_out++ = *src++; | ||
482 : | *v_out++ = (*(src + width2) + *src) >> 1; | ||
483 : | src++; | ||
484 : | |||
485 : | } | ||
486 : | |||
487 : | y_out += y_dif; | ||
488 : | u_out += uv_dif; | ||
489 : | v_out += uv_dif; | ||
490 : | |||
491 : | for (x = width >> 1; x; x--) { | ||
492 : | *y_out++ = *src++; | ||
493 : | src++; | ||
494 : | *y_out++ = *src++; | ||
495 : | src++; | ||
496 : | } | ||
497 : | |||
498 : | y_out += y_dif; | ||
499 : | |||
500 : | } | ||
501 : | |||
502 : | } | ||
503 : | |||
504 : | |||
505 : | |||
506 : | /* uyvy packed -> yuv 4:2:0 planar | ||
507 : | |||
508 : | NOTE: does not flip */ | ||
509 : | |||
510 : | |||
511 : | void | ||
512 : | uyvy_to_yv12_c(uint8_t * y_out, | ||
513 : | uint8_t * u_out, | ||
514 : | uint8_t * v_out, | ||
515 : | uint8_t * src, | ||
516 : | int width, | ||
517 : | int height, | ||
518 : | int stride) | ||
519 : | { | ||
520 : | uint32_t width2 = width + width; | ||
521 : | uint32_t y_dif = stride - width; | ||
522 : | uint32_t uv_dif = y_dif >> 1; | ||
523 : | uint32_t x, y; | ||
524 : | |||
525 : | for (y = height >> 1; y; y--) { | ||
526 : | |||
527 : | for (x = width >> 1; x; x--) { | ||
528 : | *u_out++ = *src++; | ||
529 : | // *u_out++ = (*(src+width2) + *src++) >> 1; | ||
530 : | *y_out++ = *src++; | ||
531 : | //*v_out++ = *src++; | ||
532 : | *v_out++ = (*(src + width2) + *src) >> 1; | ||
533 : | src++; | ||
534 : | *y_out++ = *src++; | ||
535 : | } | ||
536 : | |||
537 : | y_out += y_dif; | ||
538 : | u_out += uv_dif;; | ||
539 : | v_out += uv_dif;; | ||
540 : | |||
541 : | for (x = width >> 1; x; x--) { | ||
542 : | src++; | ||
543 : | *y_out++ = *src++; | ||
544 : | src++; | ||
545 : | *y_out++ = *src++; | ||
546 : | } | ||
547 : | |||
548 : | y_out += y_dif; | ||
549 : | } | ||
550 : | } | ||
551 : | |||
552 : | |||
553 : | /* yuv -> rgb def's */ | ||
554 : | |||
555 : | #define RGB_Y_OUT 1.164 | ||
556 : | #define B_U_OUT 2.018 | ||
557 : | #define Y_ADD_OUT 16 | ||
558 : | |||
559 : | #define G_U_OUT 0.391 | ||
560 : | #define G_V_OUT 0.813 | ||
561 : | #define U_ADD_OUT 128 | ||
562 : | |||
563 : | #define R_V_OUT 1.596 | ||
564 : | #define V_ADD_OUT 128 | ||
565 : | |||
566 : | |||
567 : | #define SCALEBITS_OUT 13 | ||
568 : | #define FIX_OUT(x) ((uint16_t) ((x) * (1L<<SCALEBITS_OUT) + 0.5)) | ||
569 : | |||
570 : | |||
571 : | /* initialize rgb lookup tables */ | ||
572 : | |||
573 : | void | ||
574 : | colorspace_init(void) | ||
575 : | { | ||
576 : | int32_t i; | ||
577 : | |||
578 : | for (i = 0; i < 256; i++) { | ||
579 : | RGB_Y_tab[i] = FIX_OUT(RGB_Y_OUT) * (i - Y_ADD_OUT); | ||
580 : | B_U_tab[i] = FIX_OUT(B_U_OUT) * (i - U_ADD_OUT); | ||
581 : | G_U_tab[i] = FIX_OUT(G_U_OUT) * (i - U_ADD_OUT); | ||
582 : | G_V_tab[i] = FIX_OUT(G_V_OUT) * (i - V_ADD_OUT); | ||
583 : | R_V_tab[i] = FIX_OUT(R_V_OUT) * (i - V_ADD_OUT); | ||
584 : | } | ||
585 : | } | ||
586 : | |||
587 : | /* yuv 4:2:0 planar -> rgb555 + very simple error diffusion | ||
588 : | */ | ||
589 : | |||
590 : | #define MK_RGB555(R,G,B) ((MAX(0,MIN(255, R)) << 7) & 0x7c00) | \ | ||
591 : | ((MAX(0,MIN(255, G)) << 2) & 0x03e0) | \ | ||
592 : | ((MAX(0,MIN(255, B)) >> 3) & 0x001f) | ||
593 : | |||
594 : | |||
595 : | void | ||
596 : | yv12_to_rgb555_c(uint8_t * dst, | ||
597 : | int dst_stride, | ||
598 : | uint8_t * y_src, | ||
599 : | uint8_t * u_src, | ||
600 : | uint8_t * v_src, | ||
601 : | int y_stride, | ||
602 : | int uv_stride, | ||
603 : | int width, | ||
604 : | int height) | ||
605 : | { | ||
606 : | const uint32_t dst_dif = 4 * dst_stride - 2 * width; | ||
607 : | int32_t y_dif = 2 * y_stride - width; | ||
608 : | |||
609 : | uint8_t *dst2 = dst + 2 * dst_stride; | ||
610 : | uint8_t *y_src2 = y_src + y_stride; | ||
611 : | uint32_t x, y; | ||
612 : | |||
613 : | if (height < 0) { | ||
614 : | height = -height; | ||
615 : | y_src += (height - 1) * y_stride; | ||
616 : | y_src2 = y_src - y_stride; | ||
617 : | u_src += (height / 2 - 1) * uv_stride; | ||
618 : | v_src += (height / 2 - 1) * uv_stride; | ||
619 : | y_dif = -width - 2 * y_stride; | ||
620 : | uv_stride = -uv_stride; | ||
621 : | } | ||
622 : | |||
623 : | for (y = height / 2; y; y--) { | ||
624 : | int r, g, b; | ||
625 : | int r2, g2, b2; | ||
626 : | |||
627 : | r = g = b = 0; | ||
628 : | r2 = g2 = b2 = 0; | ||
629 : | |||
630 : | // process one 2x2 block per iteration | ||
631 : | for (x = 0; x < (uint32_t) width / 2; x++) { | ||
632 : | int u, v; | ||
633 : | int b_u, g_uv, r_v, rgb_y; | ||
634 : | |||
635 : | u = u_src[x]; | ||
636 : | v = v_src[x]; | ||
637 : | |||
638 : | b_u = B_U_tab[u]; | ||
639 : | g_uv = G_U_tab[u] + G_V_tab[v]; | ||
640 : | r_v = R_V_tab[v]; | ||
641 : | |||
642 : | rgb_y = RGB_Y_tab[*y_src]; | ||
643 : | b = (b & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); | ||
644 : | g = (g & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); | ||
645 : | r = (r & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); | ||
646 : | *(uint16_t *) dst = MK_RGB555(r, g, b); | ||
647 : | |||
648 : | y_src++; | ||
649 : | rgb_y = RGB_Y_tab[*y_src]; | ||
650 : | b = (b & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); | ||
651 : | g = (g & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); | ||
652 : | r = (r & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); | ||
653 : | *(uint16_t *) (dst + 2) = MK_RGB555(r, g, b); | ||
654 : | y_src++; | ||
655 : | |||
656 : | rgb_y = RGB_Y_tab[*y_src2]; | ||
657 : | b2 = (b2 & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); | ||
658 : | g2 = (g2 & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); | ||
659 : | r2 = (r2 & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); | ||
660 : | *(uint16_t *) (dst2) = MK_RGB555(r2, g2, b2); | ||
661 : | y_src2++; | ||
662 : | |||
663 : | rgb_y = RGB_Y_tab[*y_src2]; | ||
664 : | b2 = (b2 & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); | ||
665 : | g2 = (g2 & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); | ||
666 : | r2 = (r2 & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); | ||
667 : | *(uint16_t *) (dst2 + 2) = MK_RGB555(r2, g2, b2); | ||
668 : | y_src2++; | ||
669 : | |||
670 : | dst += 4; | ||
671 : | dst2 += 4; | ||
672 : | } | ||
673 : | |||
674 : | dst += dst_dif; | ||
675 : | dst2 += dst_dif; | ||
676 : | |||
677 : | y_src += y_dif; | ||
678 : | y_src2 += y_dif; | ||
679 : | |||
680 : | u_src += uv_stride; | ||
681 : | v_src += uv_stride; | ||
682 : | } | ||
683 : | } | ||
684 : | |||
685 : | |||
686 : | /* yuv 4:2:0 planar -> rgb565 + very simple error diffusion | ||
687 : | NOTE: identical to rgb555 except for shift/mask */ | ||
688 : | |||
689 : | |||
690 : | #define MK_RGB565(R,G,B) ((MAX(0,MIN(255, R)) << 8) & 0xf800) | \ | ||
691 : | ((MAX(0,MIN(255, G)) << 3) & 0x07e0) | \ | ||
692 : | ((MAX(0,MIN(255, B)) >> 3) & 0x001f) | ||
693 : | |||
694 : | void | ||
695 : | yv12_to_rgb565_c(uint8_t * dst, | ||
696 : | int dst_stride, | ||
697 : | uint8_t * y_src, | ||
698 : | uint8_t * u_src, | ||
699 : | uint8_t * v_src, | ||
700 : | int y_stride, | ||
701 : | int uv_stride, | ||
702 : | int width, | ||
703 : | int height) | ||
704 : | { | ||
705 : | const uint32_t dst_dif = 4 * dst_stride - 2 * width; | ||
706 : | int32_t y_dif = 2 * y_stride - width; | ||
707 : | |||
708 : | uint8_t *dst2 = dst + 2 * dst_stride; | ||
709 : | uint8_t *y_src2 = y_src + y_stride; | ||
710 : | uint32_t x, y; | ||
711 : | |||
712 : | if (height < 0) { // flip image? | ||
713 : | height = -height; | ||
714 : | y_src += (height - 1) * y_stride; | ||
715 : | y_src2 = y_src - y_stride; | ||
716 : | u_src += (height / 2 - 1) * uv_stride; | ||
717 : | v_src += (height / 2 - 1) * uv_stride; | ||
718 : | y_dif = -width - 2 * y_stride; | ||
719 : | uv_stride = -uv_stride; | ||
720 : | } | ||
721 : | |||
722 : | for (y = height / 2; y; y--) { | ||
723 : | int r, g, b; | ||
724 : | int r2, g2, b2; | ||
725 : | |||
726 : | r = g = b = 0; | ||
727 : | r2 = g2 = b2 = 0; | ||
728 : | |||
729 : | // process one 2x2 block per iteration | ||
730 : | for (x = 0; x < (uint32_t) width / 2; x++) { | ||
731 : | int u, v; | ||
732 : | int b_u, g_uv, r_v, rgb_y; | ||
733 : | |||
734 : | u = u_src[x]; | ||
735 : | v = v_src[x]; | ||
736 : | |||
737 : | b_u = B_U_tab[u]; | ||
738 : | g_uv = G_U_tab[u] + G_V_tab[v]; | ||
739 : | r_v = R_V_tab[v]; | ||
740 : | |||
741 : | rgb_y = RGB_Y_tab[*y_src]; | ||
742 : | b = (b & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); | ||
743 : | g = (g & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); | ||
744 : | r = (r & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); | ||
745 : | *(uint16_t *) dst = MK_RGB565(r, g, b); | ||
746 : | |||
747 : | y_src++; | ||
748 : | rgb_y = RGB_Y_tab[*y_src]; | ||
749 : | b = (b & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); | ||
750 : | g = (g & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); | ||
751 : | r = (r & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); | ||
752 : | *(uint16_t *) (dst + 2) = MK_RGB565(r, g, b); | ||
753 : | y_src++; | ||
754 : | |||
755 : | rgb_y = RGB_Y_tab[*y_src2]; | ||
756 : | b2 = (b2 & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); | ||
757 : | g2 = (g2 & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); | ||
758 : | r2 = (r2 & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); | ||
759 : | *(uint16_t *) (dst2) = MK_RGB565(r2, g2, b2); | ||
760 : | y_src2++; | ||
761 : | |||
762 : | rgb_y = RGB_Y_tab[*y_src2]; | ||
763 : | b2 = (b2 & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); | ||
764 : | g2 = (g2 & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); | ||
765 : | r2 = (r2 & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); | ||
766 : | *(uint16_t *) (dst2 + 2) = MK_RGB565(r2, g2, b2); | ||
767 : | y_src2++; | ||
768 : | |||
769 : | dst += 4; | ||
770 : | dst2 += 4; | ||
771 : | } | ||
772 : | |||
773 : | dst += dst_dif; | ||
774 : | dst2 += dst_dif; | ||
775 : | |||
776 : | y_src += y_dif; | ||
777 : | y_src2 += y_dif; | ||
778 : | |||
779 : | u_src += uv_stride; | ||
780 : | v_src += uv_stride; | ||
781 : | } | ||
782 : | } | ||
783 : | |||
784 : | |||
785 : | |||
786 : | /* yuv 4:2:0 planar -> rgb24 */ | ||
787 : | |||
788 : | void | ||
789 : | yv12_to_rgb24_c(uint8_t * dst, | ||
790 : | int dst_stride, | ||
791 : | uint8_t * y_src, | ||
792 : | uint8_t * u_src, | ||
793 : | uint8_t * v_src, | ||
794 : | int y_stride, | ||
795 : | int uv_stride, | ||
796 : | int width, | ||
797 : | int height) | ||
798 : | { | ||
799 : | const uint32_t dst_dif = 6 * dst_stride - 3 * width; | ||
800 : | int32_t y_dif = 2 * y_stride - width; | ||
801 : | |||
802 : | uint8_t *dst2 = dst + 3 * dst_stride; | ||
803 : | uint8_t *y_src2 = y_src + y_stride; | ||
804 : | uint32_t x, y; | ||
805 : | |||
806 : | if (height < 0) { // flip image? | ||
807 : | height = -height; | ||
808 : | y_src += (height - 1) * y_stride; | ||
809 : | y_src2 = y_src - y_stride; | ||
810 : | u_src += (height / 2 - 1) * uv_stride; | ||
811 : | v_src += (height / 2 - 1) * uv_stride; | ||
812 : | y_dif = -width - 2 * y_stride; | ||
813 : | uv_stride = -uv_stride; | ||
814 : | } | ||
815 : | |||
816 : | for (y = height / 2; y; y--) { | ||
817 : | // process one 2x2 block per iteration | ||
818 : | for (x = 0; x < (uint32_t) width / 2; x++) { | ||
819 : | int u, v; | ||
820 : | int b_u, g_uv, r_v, rgb_y; | ||
821 : | int r, g, b; | ||
822 : | |||
823 : | u = u_src[x]; | ||
824 : | v = v_src[x]; | ||
825 : | |||
826 : | b_u = B_U_tab[u]; | ||
827 : | g_uv = G_U_tab[u] + G_V_tab[v]; | ||
828 : | r_v = R_V_tab[v]; | ||
829 : | |||
830 : | rgb_y = RGB_Y_tab[*y_src]; | ||
831 : | b = (rgb_y + b_u) >> SCALEBITS_OUT; | ||
832 : | g = (rgb_y - g_uv) >> SCALEBITS_OUT; | ||
833 : | r = (rgb_y + r_v) >> SCALEBITS_OUT; | ||
834 : | dst[0] = MAX(0, MIN(255, b)); | ||
835 : | dst[1] = MAX(0, MIN(255, g)); | ||
836 : | dst[2] = MAX(0, MIN(255, r)); | ||
837 : | |||
838 : | y_src++; | ||
839 : | rgb_y = RGB_Y_tab[*y_src]; | ||
840 : | b = (rgb_y + b_u) >> SCALEBITS_OUT; | ||
841 : | g = (rgb_y - g_uv) >> SCALEBITS_OUT; | ||
842 : | r = (rgb_y + r_v) >> SCALEBITS_OUT; | ||
843 : | dst[3] = MAX(0, MIN(255, b)); | ||
844 : | dst[4] = MAX(0, MIN(255, g)); | ||
845 : | dst[5] = MAX(0, MIN(255, r)); | ||
846 : | y_src++; | ||
847 : | |||
848 : | rgb_y = RGB_Y_tab[*y_src2]; | ||
849 : | b = (rgb_y + b_u) >> SCALEBITS_OUT; | ||
850 : | g = (rgb_y - g_uv) >> SCALEBITS_OUT; | ||
851 : | r = (rgb_y + r_v) >> SCALEBITS_OUT; | ||
852 : | dst2[0] = MAX(0, MIN(255, b)); | ||
853 : | dst2[1] = MAX(0, MIN(255, g)); | ||
854 : | dst2[2] = MAX(0, MIN(255, r)); | ||
855 : | y_src2++; | ||
856 : | |||
857 : | rgb_y = RGB_Y_tab[*y_src2]; | ||
858 : | b = (rgb_y + b_u) >> SCALEBITS_OUT; | ||
859 : | g = (rgb_y - g_uv) >> SCALEBITS_OUT; | ||
860 : | r = (rgb_y + r_v) >> SCALEBITS_OUT; | ||
861 : | dst2[3] = MAX(0, MIN(255, b)); | ||
862 : | dst2[4] = MAX(0, MIN(255, g)); | ||
863 : | dst2[5] = MAX(0, MIN(255, r)); | ||
864 : | y_src2++; | ||
865 : | |||
866 : | dst += 6; | ||
867 : | dst2 += 6; | ||
868 : | } | ||
869 : | |||
870 : | dst += dst_dif; | ||
871 : | dst2 += dst_dif; | ||
872 : | |||
873 : | y_src += y_dif; | ||
874 : | y_src2 += y_dif; | ||
875 : | |||
876 : | u_src += uv_stride; | ||
877 : | v_src += uv_stride; | ||
878 : | } | ||
879 : | } | ||
880 : | |||
881 : | |||
882 : | |||
883 : | /* yuv 4:2:0 planar -> rgb32 */ | ||
884 : | |||
885 : | void | ||
886 : | yv12_to_rgb32_c(uint8_t * dst, | ||
887 : | int dst_stride, | ||
888 : | uint8_t * y_src, | ||
889 : | uint8_t * v_src, | ||
890 : | uint8_t * u_src, | ||
891 : | int y_stride, | ||
892 : | int uv_stride, | ||
893 : | int width, | ||
894 : | int height) | ||
895 : | { | ||
896 : | const uint32_t dst_dif = 8 * dst_stride - 4 * width; | ||
897 : | int32_t y_dif = 2 * y_stride - width; | ||
898 : | |||
899 : | uint8_t *dst2 = dst + 4 * dst_stride; | ||
900 : | uint8_t *y_src2 = y_src + y_stride; | ||
901 : | uint32_t x, y; | ||
902 : | |||
903 : | if (height < 0) { // flip image? | ||
904 : | height = -height; | ||
905 : | y_src += (height - 1) * y_stride; | ||
906 : | y_src2 = y_src - y_stride; | ||
907 : | u_src += (height / 2 - 1) * uv_stride; | ||
908 : | v_src += (height / 2 - 1) * uv_stride; | ||
909 : | y_dif = -width - 2 * y_stride; | ||
910 : | uv_stride = -uv_stride; | ||
911 : | } | ||
912 : | |||
913 : | for (y = height / 2; y; y--) { | ||
914 : | // process one 2x2 block per iteration | ||
915 : | for (x = 0; x < (uint32_t) width / 2; x++) { | ||
916 : | int u, v; | ||
917 : | int b_u, g_uv, r_v, rgb_y; | ||
918 : | int r, g, b; | ||
919 : | |||
920 : | u = u_src[x]; | ||
921 : | v = v_src[x]; | ||
922 : | |||
923 : | b_u = B_U_tab[u]; | ||
924 : | g_uv = G_U_tab[u] + G_V_tab[v]; | ||
925 : | r_v = R_V_tab[v]; | ||
926 : | |||
927 : | rgb_y = RGB_Y_tab[*y_src]; | ||
928 : | b = (rgb_y + b_u) >> SCALEBITS_OUT; | ||
929 : | g = (rgb_y - g_uv) >> SCALEBITS_OUT; | ||
930 : | r = (rgb_y + r_v) >> SCALEBITS_OUT; | ||
931 : | dst[0] = MAX(0, MIN(255, r)); | ||
932 : | dst[1] = MAX(0, MIN(255, g)); | ||
933 : | dst[2] = MAX(0, MIN(255, b)); | ||
934 : | dst[3] = 0; | ||
935 : | |||
936 : | y_src++; | ||
937 : | rgb_y = RGB_Y_tab[*y_src]; | ||
938 : | b = (rgb_y + b_u) >> SCALEBITS_OUT; | ||
939 : | g = (rgb_y - g_uv) >> SCALEBITS_OUT; | ||
940 : | r = (rgb_y + r_v) >> SCALEBITS_OUT; | ||
941 : | dst[4] = MAX(0, MIN(255, r)); | ||
942 : | dst[5] = MAX(0, MIN(255, g)); | ||
943 : | dst[6] = MAX(0, MIN(255, b)); | ||
944 : | dst[7] = 0; | ||
945 : | y_src++; | ||
946 : | |||
947 : | rgb_y = RGB_Y_tab[*y_src2]; | ||
948 : | b = (rgb_y + b_u) >> SCALEBITS_OUT; | ||
949 : | g = (rgb_y - g_uv) >> SCALEBITS_OUT; | ||
950 : | r = (rgb_y + r_v) >> SCALEBITS_OUT; | ||
951 : | dst2[0] = MAX(0, MIN(255, r)); | ||
952 : | dst2[1] = MAX(0, MIN(255, g)); | ||
953 : | dst2[2] = MAX(0, MIN(255, b)); | ||
954 : | dst2[3] = 0; | ||
955 : | y_src2++; | ||
956 : | |||
957 : | rgb_y = RGB_Y_tab[*y_src2]; | ||
958 : | b = (rgb_y + b_u) >> SCALEBITS_OUT; | ||
959 : | g = (rgb_y - g_uv) >> SCALEBITS_OUT; | ||
960 : | r = (rgb_y + r_v) >> SCALEBITS_OUT; | ||
961 : | dst2[4] = MAX(0, MIN(255, r)); | ||
962 : | dst2[5] = MAX(0, MIN(255, g)); | ||
963 : | dst2[6] = MAX(0, MIN(255, b)); | ||
964 : | dst2[7] = 0; | ||
965 : | y_src2++; | ||
966 : | |||
967 : | dst += 8; | ||
968 : | dst2 += 8; | ||
969 : | } | ||
970 : | |||
971 : | dst += dst_dif; | ||
972 : | dst2 += dst_dif; | ||
973 : | |||
974 : | y_src += y_dif; | ||
975 : | y_src2 += y_dif; | ||
976 : | |||
977 : | u_src += uv_stride; | ||
978 : | v_src += uv_stride; | ||
979 : | } | ||
980 : | } | ||
981 : | |||
982 : | |||
983 : | |||
984 : | /* yuv 4:2:0 planar -> yuv planar */ | ||
985 : | |||
986 : | void | ||
987 : | yv12_to_yuv_c(uint8_t * dst, | ||
988 : | int dst_stride, | ||
989 : | uint8_t * y_src, | ||
990 : | uint8_t * u_src, | ||
991 : | uint8_t * v_src, | ||
992 : | int y_stride, | ||
993 : | int uv_stride, | ||
994 : | int width, | ||
995 : | int height) | ||
996 : | { | ||
997 : | uint32_t dst_stride2 = dst_stride >> 1; | ||
998 : | uint32_t width2 = width >> 1; | ||
999 : | uint32_t y; | ||
1000 : | |||
1001 : | if (height < 0) { | ||
1002 : | height = -height; | ||
1003 : | y_src += (height - 1) * y_stride; | ||
1004 : | u_src += (height / 2 - 1) * uv_stride; | ||
1005 : | v_src += (height / 2 - 1) * uv_stride; | ||
1006 : | y_stride = -y_stride; | ||
1007 : | uv_stride = -uv_stride; | ||
1008 : | } | ||
1009 : | |||
1010 : | for (y = height; y; y--) { | ||
1011 : | memcpy(dst, y_src, width); | ||
1012 : | dst += dst_stride; | ||
1013 : | y_src += y_stride; | ||
1014 : | } | ||
1015 : | |||
1016 : | for (y = height >> 1; y; y--) { | ||
1017 : | memcpy(dst, u_src, width2); | ||
1018 : | dst += dst_stride2; | ||
1019 : | u_src += uv_stride; | ||
1020 : | } | ||
1021 : | |||
1022 : | for (y = height >> 1; y; y--) { | ||
1023 : | memcpy(dst, v_src, width2); | ||
1024 : | dst += dst_stride2; | ||
1025 : | v_src += uv_stride; | ||
1026 : | } | ||
1027 : | } | ||
1028 : | |||
1029 : | |||
1030 : | |||
1031 : | |||
1032 : | /* yuv 4:2:0 planar -> yuyv (yuv2) packed */ | ||
1033 : | |||
1034 : | void | ||
1035 : | yv12_to_yuyv_c(uint8_t * dst, | ||
1036 : | int dst_stride, | ||
1037 : | uint8_t * y_src, | ||
1038 : | uint8_t * u_src, | ||
1039 : | uint8_t * v_src, | ||
1040 : | int y_stride, | ||
1041 : | int uv_stride, | ||
1042 : | int width, | ||
1043 : | int height) | ||
1044 : | { | ||
1045 : | const uint32_t dst_dif = 2 * (dst_stride - width); | ||
1046 : | uint32_t x, y; | ||
1047 : | |||
1048 : | if (height < 0) { | ||
1049 : | height = -height; | ||
1050 : | y_src += (height - 1) * y_stride; | ||
1051 : | u_src += (height / 2 - 1) * uv_stride; | ||
1052 : | v_src += (height / 2 - 1) * uv_stride; | ||
1053 : | y_stride = -y_stride; | ||
1054 : | uv_stride = -uv_stride; | ||
1055 : | } | ||
1056 : | |||
1057 : | for (y = 0; y < (uint32_t) height; y++) { | ||
1058 : | for (x = 0; x < (uint32_t) width / 2; x++) { | ||
1059 : | dst[0] = y_src[2 * x]; | ||
1060 : | dst[1] = u_src[x]; | ||
1061 : | dst[2] = y_src[2 * x + 1]; | ||
1062 : | dst[3] = v_src[x]; | ||
1063 : | dst += 4; | ||
1064 : | } | ||
1065 : | dst += dst_dif; | ||
1066 : | y_src += y_stride; | ||
1067 : | if (y & 1) { | ||
1068 : | u_src += uv_stride; | ||
1069 : | v_src += uv_stride; | ||
1070 : | } | ||
1071 : | } | ||
1072 : | } | ||
1073 : | |||
1074 : | |||
1075 : | |||
1076 : | /* yuv 4:2:0 planar -> uyvy packed */ | ||
1077 : | |||
1078 : | void | ||
1079 : | yv12_to_uyvy_c(uint8_t * dst, | ||
1080 : | int dst_stride, | ||
1081 : | uint8_t * y_src, | ||
1082 : | uint8_t * u_src, | ||
1083 : | uint8_t * v_src, | ||
1084 : | int y_stride, | ||
1085 : | int uv_stride, | ||
1086 : | int width, | ||
1087 : | int height) | ||
1088 : | { | ||
1089 : | const uint32_t dst_dif = 2 * (dst_stride - width); | ||
1090 : | uint32_t x, y; | ||
1091 : | |||
1092 : | if (height < 0) { | ||
1093 : | height = -height; | ||
1094 : | y_src += (height - 1) * y_stride; | ||
1095 : | u_src += (height / 2 - 1) * uv_stride; | ||
1096 : | v_src += (height / 2 - 1) * uv_stride; | ||
1097 : | y_stride = -y_stride; | ||
1098 : | uv_stride = -uv_stride; | ||
1099 : | } | ||
1100 : | |||
1101 : | for (y = 0; y < (uint32_t) height; y++) { | ||
1102 : | for (x = 0; x < (uint32_t) width / 2; x++) { | ||
1103 : | dst[0] = u_src[x]; | ||
1104 : | dst[1] = y_src[2 * x]; | ||
1105 : | dst[2] = v_src[x]; | ||
1106 : | dst[3] = y_src[2 * x + 1]; | ||
1107 : | dst += 4; | ||
1108 : | } | ||
1109 : | dst += dst_dif; | ||
1110 : | y_src += y_stride; | ||
1111 : | if (y & 1) { | ||
1112 : | u_src += uv_stride; | ||
1113 : | v_src += uv_stride; | ||
1114 : | } | ||
1115 : | } | ||
1116 : | } | ||
1117 : | |||
1118 : | |||
1119 : | /* user yuv planar -> yuv 4:2:0 planar | ||
1120 : | |||
1121 : | NOTE: does not flip */ | ||
1122 : | |||
1123 : | void | ||
1124 : | user_to_yuv_c(uint8_t * y_out, | ||
1125 : | uint8_t * u_out, | ||
1126 : | uint8_t * v_out, | ||
1127 : | int stride, | ||
1128 : | DEC_PICTURE * picture, | ||
1129 : | int width, | ||
1130 : | int height) | ||
1131 : | { | ||
1132 : | uint32_t stride2 = stride >> 1; | ||
1133 : | uint32_t width2 = width >> 1; | ||
1134 : | uint32_t y; | ||
1135 : | uint8_t *src; | ||
1136 : | |||
1137 : | src = picture->y; | ||
1138 : | for (y = height; y; y--) { | ||
1139 : | memcpy(y_out, src, width); | ||
1140 : | src += picture->stride_y; | ||
1141 : | y_out += stride; | ||
1142 : | } | ||
1143 : | |||
1144 : | src = picture->u; | ||
1145 : | for (y = height >> 1; y; y--) { | ||
1146 : | memcpy(u_out, src, width2); | ||
1147 : | src += picture->stride_uv; | ||
1148 : | u_out += stride2; | ||
1149 : | } | ||
1150 : | |||
1151 : | src = picture->v; | ||
1152 : | for (y = height >> 1; y; y--) { | ||
1153 : | memcpy(v_out, src, width2); | ||
1154 : | src += picture->stride_uv; | ||
1155 : | v_out += stride2; | ||
1156 : | } | ||
1157 : | } |
No admin address has been configured | ViewVC Help |
Powered by ViewVC 1.0.4 |