[svn] / trunk / xvidcore / src / image / colorspace.c Repository:
ViewVC logotype

Annotation of /trunk/xvidcore/src/image/colorspace.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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