[svn] / branches / dev-api-3 / xvidcore / src / image / colorspace.c Repository:
ViewVC logotype

Annotation of /branches/dev-api-3/xvidcore/src/image/colorspace.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 582 - (view) (download)

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

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4