[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 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