2 * Misc image convertion routines
3 * Copyright (c) 2001, 2002 Fabrice Bellard.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "fastmemcpy.h"
29 /* XXX: totally non optimized */
31 static void yuv422_to_yuv420p(UINT8
*lum
, UINT8
*cb
, UINT8
*cr
,
32 UINT8
*src
, int width
, int height
)
37 for(y
=0;y
<height
;y
+=2) {
38 for(x
=0;x
<width
;x
+=2) {
48 for(x
=0;x
<width
;x
+=2) {
58 #define ONE_HALF (1 << (SCALEBITS - 1))
59 #define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5))
61 static void rgb24_to_yuv420p(UINT8
*lum
, UINT8
*cb
, UINT8
*cr
,
62 UINT8
*src
, int width
, int height
)
64 int wrap
, wrap3
, x
, y
;
65 int r
, g
, b
, r1
, g1
, b1
;
71 for(y
=0;y
<height
;y
+=2) {
72 for(x
=0;x
<width
;x
+=2) {
79 lum
[0] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
80 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
87 lum
[1] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
88 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
98 lum
[0] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
99 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
106 lum
[1] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
107 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
109 cb
[0] = ((- FIX(0.16874) * r1
- FIX(0.33126) * g1
+
110 FIX(0.50000) * b1
+ 4 * ONE_HALF
- 1) >> (SCALEBITS
+ 2)) + 128;
111 cr
[0] = ((FIX(0.50000) * r1
- FIX(0.41869) * g1
-
112 FIX(0.08131) * b1
+ 4 * ONE_HALF
- 1) >> (SCALEBITS
+ 2)) + 128;
124 static void rgba32_to_yuv420p(UINT8
*lum
, UINT8
*cb
, UINT8
*cr
,
125 UINT8
*src
, int width
, int height
)
127 int wrap
, wrap4
, x
, y
;
128 int r
, g
, b
, r1
, g1
, b1
;
134 for(y
=0;y
<height
;y
+=2) {
135 for(x
=0;x
<width
;x
+=2) {
142 lum
[0] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
143 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
150 lum
[1] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
151 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
161 lum
[0] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
162 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
169 lum
[1] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
170 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
172 cb
[0] = ((- FIX(0.16874) * r1
- FIX(0.33126) * g1
+
173 FIX(0.50000) * b1
+ 4 * ONE_HALF
- 1) >> (SCALEBITS
+ 2)) + 128;
174 cr
[0] = ((FIX(0.50000) * r1
- FIX(0.41869) * g1
-
175 FIX(0.08131) * b1
+ 4 * ONE_HALF
- 1) >> (SCALEBITS
+ 2)) + 128;
187 #define rgb565_to_yuv420p(lum,cb,cr,src,width,height) rgbmisc_to_yuv420p((lum),(cb),(cr),(src),(width),(height),0x0800,31, 0x0020,63,0x0001,31)
188 #define rgb555_to_yuv420p(lum,cb,cr,src,width,height) rgbmisc_to_yuv420p((lum),(cb),(cr),(src),(width),(height),0x0400,31, 0x0020,31,0x0001,31)
189 #define rgb5551_to_yuv420p(lum,cb,cr,src,width,height) rgbmisc_to_yuv420p((lum),(cb),(cr),(src),(width),(height),0x0800,31, 0x0040,31,0x0002,31)
190 #define bgr565_to_yuv420p(lum,cb,cr,src,width,height) rgbmisc_to_yuv420p((lum),(cb),(cr),(src),(width),(height),0x0001,31, 0x0020,63,0x0800,31)
191 #define bgr555_to_yuv420p(lum,cb,cr,src,width,height) rgbmisc_to_yuv420p((lum),(cb),(cr),(src),(width),(height),0x0001,31, 0x0020,31,0x0400,31)
192 #define gbr565_to_yuv420p(lum,cb,cr,src,width,height) rgbmisc_to_yuv420p((lum),(cb),(cr),(src),(width),(height),0x0001,31, 0x0800,31,0x0040,63)
193 #define gbr555_to_yuv420p(lum,cb,cr,src,width,height) rgbmisc_to_yuv420p((lum),(cb),(cr),(src),(width),(height),0x0001,31, 0x0400,31,0x0020,31)
195 static void rgbmisc_to_yuv420p
196 (UINT8
*lum
, UINT8
*cb
, UINT8
*cr
,
197 UINT8
*src
, int width
, int height
,
199 UINT16 R_LOWMASK
, UINT16 R_MAX
,
200 UINT16 G_LOWMASK
, UINT16 G_MAX
,
201 UINT16 B_LOWMASK
, UINT16 B_MAX
204 int wrap
, wrap2
, x
, y
;
205 int r
, g
, b
, r1
, g1
, b1
;
212 for(y
=0;y
<height
;y
+=2) {
213 for(x
=0;x
<width
;x
+=2) {
214 pixel
= p
[0] | (p
[1]<<8);
215 r
= (((pixel
/R_LOWMASK
) & R_MAX
) * (0x100 / (R_MAX
+1)));
216 g
= (((pixel
/G_LOWMASK
) & G_MAX
) * (0x100 / (G_MAX
+1)));
217 b
= (((pixel
/B_LOWMASK
) & B_MAX
) * (0x100 / (B_MAX
+1)));
221 lum
[0] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
222 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
224 pixel
= p
[2] | (p
[3]<<8);
225 r
= (((pixel
/R_LOWMASK
) & R_MAX
) * (0x100 / (R_MAX
+1)));
226 g
= (((pixel
/G_LOWMASK
) & G_MAX
) * (0x100 / (G_MAX
+1)));
227 b
= (((pixel
/B_LOWMASK
) & B_MAX
) * (0x100 / (B_MAX
+1)));
231 lum
[1] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
232 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
236 pixel
= p
[0] | (p
[1]<<8);
237 r
= (((pixel
/R_LOWMASK
) & R_MAX
) * (0x100 / (R_MAX
+1)));
238 g
= (((pixel
/G_LOWMASK
) & G_MAX
) * (0x100 / (G_MAX
+1)));
239 b
= (((pixel
/B_LOWMASK
) & B_MAX
) * (0x100 / (B_MAX
+1)));
243 lum
[0] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
244 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
245 pixel
= p
[2] | (p
[3]<<8);
246 r
= (((pixel
/R_LOWMASK
) & R_MAX
) * (0x100 / (R_MAX
+1)));
247 g
= (((pixel
/G_LOWMASK
) & G_MAX
) * (0x100 / (G_MAX
+1)));
248 b
= (((pixel
/B_LOWMASK
) & B_MAX
) * (0x100 / (B_MAX
+1)));
252 lum
[1] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
253 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
255 cb
[0] = ((- FIX(0.16874) * r1
- FIX(0.33126) * g1
+
256 FIX(0.50000) * b1
+ 4 * ONE_HALF
- 1) >> (SCALEBITS
+ 2)) + 128;
257 cr
[0] = ((FIX(0.50000) * r1
- FIX(0.41869) * g1
-
258 FIX(0.08131) * b1
+ 4 * ONE_HALF
- 1) >> (SCALEBITS
+ 2)) + 128;
271 static void bgr24_to_yuv420p(UINT8
*lum
, UINT8
*cb
, UINT8
*cr
,
272 UINT8
*src
, int width
, int height
)
274 int wrap
, wrap3
, x
, y
;
275 int r
, g
, b
, r1
, g1
, b1
;
281 for(y
=0;y
<height
;y
+=2) {
282 for(x
=0;x
<width
;x
+=2) {
289 lum
[0] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
290 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
297 lum
[1] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
298 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
308 lum
[0] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
309 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
316 lum
[1] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
317 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
319 cb
[0] = ((- FIX(0.16874) * r1
- FIX(0.33126) * g1
+
320 FIX(0.50000) * b1
+ 4 * ONE_HALF
- 1) >> (SCALEBITS
+ 2)) + 128;
321 cr
[0] = ((FIX(0.50000) * r1
- FIX(0.41869) * g1
-
322 FIX(0.08131) * b1
+ 4 * ONE_HALF
- 1) >> (SCALEBITS
+ 2)) + 128;
334 static void bgra32_to_yuv420p(UINT8
*lum
, UINT8
*cb
, UINT8
*cr
,
335 UINT8
*src
, int width
, int height
)
337 int wrap
, wrap4
, x
, y
;
338 int r
, g
, b
, r1
, g1
, b1
;
344 for(y
=0;y
<height
;y
+=2) {
345 for(x
=0;x
<width
;x
+=2) {
352 lum
[0] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
353 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
360 lum
[1] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
361 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
371 lum
[0] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
372 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
379 lum
[1] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
380 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
382 cb
[0] = ((- FIX(0.16874) * r1
- FIX(0.33126) * g1
+
383 FIX(0.50000) * b1
+ 4 * ONE_HALF
- 1) >> (SCALEBITS
+ 2)) + 128;
384 cr
[0] = ((FIX(0.50000) * r1
- FIX(0.41869) * g1
-
385 FIX(0.08131) * b1
+ 4 * ONE_HALF
- 1) >> (SCALEBITS
+ 2)) + 128;
397 /* XXX: use generic filter ? */
399 static void shrink2(UINT8
*dst
, int dst_wrap
,
400 UINT8
*src
, int src_wrap
,
401 int width
, int height
)
406 for(;height
> 0; height
--) {
410 for(w
= width
;w
>= 4; w
-=4) {
411 d
[0] = (s1
[0] + s2
[0]) >> 1;
412 d
[1] = (s1
[1] + s2
[1]) >> 1;
413 d
[2] = (s1
[2] + s2
[2]) >> 1;
414 d
[3] = (s1
[3] + s2
[3]) >> 1;
420 d
[0] = (s1
[0] + s2
[0]) >> 1;
431 static void shrink22(UINT8
*dst
, int dst_wrap
,
432 UINT8
*src
, int src_wrap
,
433 int width
, int height
)
438 for(;height
> 0; height
--) {
442 for(w
= width
;w
>= 4; w
-=4) {
443 d
[0] = (s1
[0] + s1
[1] + s2
[0] + s2
[1] + 2) >> 1;
444 d
[1] = (s1
[2] + s1
[3] + s2
[2] + s2
[3] + 2) >> 1;
445 d
[2] = (s1
[4] + s1
[5] + s2
[4] + s2
[5] + 2) >> 1;
446 d
[3] = (s1
[6] + s1
[7] + s2
[6] + s2
[7] + 2) >> 1;
452 d
[0] = (s1
[0] + s1
[1] + s2
[0] + s2
[1] + 2) >> 1;
463 static void grow22(UINT8
*dst
, int dst_wrap
,
464 UINT8
*src
, int src_wrap
,
465 int width
, int height
)
470 for(;height
> 0; height
--) {
473 for(w
= width
;w
>= 4; w
-=4) {
490 /* 1x2 -> 2x1. width and height are given for the source picture */
491 static void conv411(UINT8
*dst
, int dst_wrap
,
492 UINT8
*src
, int src_wrap
,
493 int width
, int height
)
498 for(;height
> 0; height
-= 2) {
502 for(w
= width
;w
> 0; w
--) {
503 c
= (s1
[0] + s2
[0]) >> 1;
515 static void img_copy(UINT8
*dst
, int dst_wrap
,
516 UINT8
*src
, int src_wrap
,
517 int width
, int height
)
519 for(;height
> 0; height
--) {
520 memcpy(dst
, src
, width
);
526 #define SCALE_BITS 10
528 #define C_Y (76309 >> (16 - SCALE_BITS))
529 #define C_RV (117504 >> (16 - SCALE_BITS))
530 #define C_BU (138453 >> (16 - SCALE_BITS))
531 #define C_GU (13954 >> (16 - SCALE_BITS))
532 #define C_GV (34903 >> (16 - SCALE_BITS))
534 #define RGBOUT(r, g, b, y1)\
536 y = (y1 - 16) * C_Y;\
537 r = cm[(y + r_add) >> SCALE_BITS];\
538 g = cm[(y + g_add) >> SCALE_BITS];\
539 b = cm[(y + b_add) >> SCALE_BITS];\
542 /* XXX: no chroma interpolating is done */
543 static void yuv420p_to_bgra32(AVPicture
*dst
, AVPicture
*src
,
544 int width
, int height
)
546 UINT8
*y1_ptr
, *y2_ptr
, *cb_ptr
, *cr_ptr
, *d
, *d1
, *d2
;
547 int w
, y
, cb
, cr
, r_add
, g_add
, b_add
, width2
;
548 UINT8
*cm
= cropTbl
+ MAX_NEG_CROP
;
551 y1_ptr
= src
->data
[0];
552 cb_ptr
= src
->data
[1];
553 cr_ptr
= src
->data
[2];
555 for(;height
> 0; height
-= 2) {
557 d2
= d
+ dst
->linesize
[0];
558 y2_ptr
= y1_ptr
+ src
->linesize
[0];
559 for(w
= width2
; w
> 0; w
--) {
560 cb
= cb_ptr
[0] - 128;
561 cr
= cr_ptr
[0] - 128;
562 r_add
= C_RV
* cr
+ (1 << (SCALE_BITS
- 1));
563 g_add
= - C_GU
* cb
- C_GV
* cr
+ (1 << (SCALE_BITS
- 1));
564 b_add
= C_BU
* cb
+ (1 << (SCALE_BITS
- 1));
566 /* output 4 pixels */
567 RGBOUT(d1
[2], d1
[1], d1
[0], y1_ptr
[0]);
568 RGBOUT(d1
[6], d1
[5], d1
[4], y1_ptr
[1]);
569 RGBOUT(d2
[2], d2
[1], d2
[0], y2_ptr
[0]);
570 RGBOUT(d2
[6], d2
[5], d2
[4], y2_ptr
[1]);
572 d1
[3] = d1
[7] = d2
[3] = d2
[7] = 255;
581 d
+= 2 * dst
->linesize
[0];
582 y1_ptr
+= 2 * src
->linesize
[0] - width
;
583 cb_ptr
+= src
->linesize
[1] - width2
;
584 cr_ptr
+= src
->linesize
[2] - width2
;
588 /* XXX: no chroma interpolating is done */
589 static void yuv420p_to_rgba32(AVPicture
*dst
, AVPicture
*src
,
590 int width
, int height
)
592 UINT8
*y1_ptr
, *y2_ptr
, *cb_ptr
, *cr_ptr
, *d
, *d1
, *d2
;
593 int w
, y
, cb
, cr
, r_add
, g_add
, b_add
, width2
;
594 UINT8
*cm
= cropTbl
+ MAX_NEG_CROP
;
597 y1_ptr
= src
->data
[0];
598 cb_ptr
= src
->data
[1];
599 cr_ptr
= src
->data
[2];
601 for(;height
> 0; height
-= 2) {
603 d2
= d
+ dst
->linesize
[0];
604 y2_ptr
= y1_ptr
+ src
->linesize
[0];
605 for(w
= width2
; w
> 0; w
--) {
606 cb
= cb_ptr
[0] - 128;
607 cr
= cr_ptr
[0] - 128;
608 r_add
= C_RV
* cr
+ (1 << (SCALE_BITS
- 1));
609 g_add
= - C_GU
* cb
- C_GV
* cr
+ (1 << (SCALE_BITS
- 1));
610 b_add
= C_BU
* cb
+ (1 << (SCALE_BITS
- 1));
612 /* output 4 pixels */
613 RGBOUT(d1
[0], d1
[1], d1
[2], y1_ptr
[0]);
614 RGBOUT(d1
[4], d1
[5], d1
[6], y1_ptr
[1]);
615 RGBOUT(d2
[0], d2
[1], d2
[2], y2_ptr
[0]);
616 RGBOUT(d2
[4], d2
[5], d2
[6], y2_ptr
[1]);
618 d1
[3] = d1
[7] = d2
[3] = d2
[7] = 255;
627 d
+= 2 * dst
->linesize
[0];
628 y1_ptr
+= 2 * src
->linesize
[0] - width
;
629 cb_ptr
+= src
->linesize
[1] - width2
;
630 cr_ptr
+= src
->linesize
[2] - width2
;
634 /* XXX: no chroma interpolating is done */
635 static void yuv420p_to_rgb24(AVPicture
*dst
, AVPicture
*src
,
636 int width
, int height
)
638 UINT8
*y1_ptr
, *y2_ptr
, *cb_ptr
, *cr_ptr
, *d
, *d1
, *d2
;
639 int w
, y
, cb
, cr
, r_add
, g_add
, b_add
, width2
;
640 UINT8
*cm
= cropTbl
+ MAX_NEG_CROP
;
643 y1_ptr
= src
->data
[0];
644 cb_ptr
= src
->data
[1];
645 cr_ptr
= src
->data
[2];
647 for(;height
> 0; height
-= 2) {
649 d2
= d
+ dst
->linesize
[0];
650 y2_ptr
= y1_ptr
+ src
->linesize
[0];
651 for(w
= width2
; w
> 0; w
--) {
652 cb
= cb_ptr
[0] - 128;
653 cr
= cr_ptr
[0] - 128;
654 r_add
= C_RV
* cr
+ (1 << (SCALE_BITS
- 1));
655 g_add
= - C_GU
* cb
- C_GV
* cr
+ (1 << (SCALE_BITS
- 1));
656 b_add
= C_BU
* cb
+ (1 << (SCALE_BITS
- 1));
658 /* output 4 pixels */
659 RGBOUT(d1
[0], d1
[1], d1
[2], y1_ptr
[0]);
660 RGBOUT(d1
[3], d1
[4], d1
[5], y1_ptr
[1]);
661 RGBOUT(d2
[0], d2
[1], d2
[2], y2_ptr
[0]);
662 RGBOUT(d2
[3], d2
[4], d2
[5], y2_ptr
[1]);
671 d
+= 2 * dst
->linesize
[0];
672 y1_ptr
+= 2 * src
->linesize
[0] - width
;
673 cb_ptr
+= src
->linesize
[1] - width2
;
674 cr_ptr
+= src
->linesize
[2] - width2
;
678 /* XXX: no chroma interpolating is done */
679 static void yuv422p_to_rgb24(AVPicture
*dst
, AVPicture
*src
,
680 int width
, int height
)
682 UINT8
*y1_ptr
, *cb_ptr
, *cr_ptr
, *d
, *d1
;
683 int w
, y
, cb
, cr
, r_add
, g_add
, b_add
, width2
;
684 UINT8
*cm
= cropTbl
+ MAX_NEG_CROP
;
687 y1_ptr
= src
->data
[0];
688 cb_ptr
= src
->data
[1];
689 cr_ptr
= src
->data
[2];
691 for(;height
> 0; height
--) {
693 for(w
= width2
; w
> 0; w
--) {
694 cb
= cb_ptr
[0] - 128;
695 cr
= cr_ptr
[0] - 128;
696 r_add
= C_RV
* cr
+ (1 << (SCALE_BITS
- 1));
697 g_add
= - C_GU
* cb
- C_GV
* cr
+ (1 << (SCALE_BITS
- 1));
698 b_add
= C_BU
* cb
+ (1 << (SCALE_BITS
- 1));
700 /* output 2 pixels */
701 RGBOUT(d1
[0], d1
[1], d1
[2], y1_ptr
[0]);
702 RGBOUT(d1
[3], d1
[4], d1
[5], y1_ptr
[1]);
709 d
+= dst
->linesize
[0];
710 y1_ptr
+= src
->linesize
[0] - width
;
711 cb_ptr
+= src
->linesize
[1] - width2
;
712 cr_ptr
+= src
->linesize
[2] - width2
;
716 /* XXX: always use linesize. Return -1 if not supported */
717 int img_convert(AVPicture
*dst
, int dst_pix_fmt
,
718 AVPicture
*src
, int pix_fmt
,
719 int width
, int height
)
723 assert(pix_fmt
!= PIX_FMT_ANY
&& dst_pix_fmt
!= PIX_FMT_ANY
);
725 if (dst_pix_fmt
== pix_fmt
) {
727 case PIX_FMT_YUV420P
:
733 img_copy(dst
->data
[i
], dst
->linesize
[i
],
734 src
->data
[i
], src
->linesize
[i
],
741 } else if (dst_pix_fmt
== PIX_FMT_YUV420P
) {
744 case PIX_FMT_YUV411P
:
745 img_copy(dst
->data
[0], dst
->linesize
[0],
746 src
->data
[0], src
->linesize
[0],
748 conv411(dst
->data
[1], dst
->linesize
[1],
749 src
->data
[1], src
->linesize
[1],
751 conv411(dst
->data
[2], dst
->linesize
[2],
752 src
->data
[2], src
->linesize
[2],
755 case PIX_FMT_YUV410P
:
756 img_copy(dst
->data
[0], dst
->linesize
[0],
757 src
->data
[0], src
->linesize
[0],
759 grow22(dst
->data
[1], dst
->linesize
[1],
760 src
->data
[1], src
->linesize
[1],
762 grow22(dst
->data
[2], dst
->linesize
[2],
763 src
->data
[2], src
->linesize
[2],
766 case PIX_FMT_YUV420P
:
768 img_copy(dst
->data
[i
], dst
->linesize
[i
],
769 src
->data
[i
], src
->linesize
[i
],
773 case PIX_FMT_YUV422P
:
774 img_copy(dst
->data
[0], dst
->linesize
[0],
775 src
->data
[0], src
->linesize
[0],
780 shrink2(dst
->data
[i
], dst
->linesize
[i
],
781 src
->data
[i
], src
->linesize
[i
],
785 case PIX_FMT_YUV444P
:
786 img_copy(dst
->data
[0], dst
->linesize
[0],
787 src
->data
[0], src
->linesize
[0],
792 shrink22(dst
->data
[i
], dst
->linesize
[i
],
793 src
->data
[i
], src
->linesize
[i
],
798 yuv422_to_yuv420p(dst
->data
[0], dst
->data
[1], dst
->data
[2],
799 src
->data
[0], width
, height
);
802 rgb24_to_yuv420p(dst
->data
[0], dst
->data
[1], dst
->data
[2],
803 src
->data
[0], width
, height
);
806 rgba32_to_yuv420p(dst
->data
[0], dst
->data
[1], dst
->data
[2],
807 src
->data
[0], width
, height
);
810 bgr24_to_yuv420p(dst
->data
[0], dst
->data
[1], dst
->data
[2],
811 src
->data
[0], width
, height
);
814 bgra32_to_yuv420p(dst
->data
[0], dst
->data
[1], dst
->data
[2],
815 src
->data
[0], width
, height
);
818 rgb565_to_yuv420p(dst
->data
[0], dst
->data
[1], dst
->data
[2],
819 src
->data
[0], width
, height
);
822 rgb555_to_yuv420p(dst
->data
[0], dst
->data
[1], dst
->data
[2],
823 src
->data
[0], width
, height
);
825 /* case PIX_FMT_RGB5551:
826 rgb5551_to_yuv420p(dst->data[0], dst->data[1], dst->data[2],
827 src->data[0], width, height);
830 bgr565_to_yuv420p(dst
->data
[0], dst
->data
[1], dst
->data
[2],
831 src
->data
[0], width
, height
);
834 bgr555_to_yuv420p(dst
->data
[0], dst
->data
[1], dst
->data
[2],
835 src
->data
[0], width
, height
);
837 /* case PIX_FMT_GBR565:
838 gbr565_to_yuv420p(dst->data[0], dst->data[1], dst->data[2],
839 src->data[0], width, height);
842 gbr555_to_yuv420p(dst->data[0], dst->data[1], dst->data[2],
843 src->data[0], width, height);
848 } else if (dst_pix_fmt
== PIX_FMT_RGB24
) {
850 case PIX_FMT_YUV420P
:
851 yuv420p_to_rgb24(dst
, src
, width
, height
);
853 case PIX_FMT_YUV422P
:
854 yuv422p_to_rgb24(dst
, src
, width
, height
);
859 } else if (dst_pix_fmt
== PIX_FMT_RGBA32
) {
861 case PIX_FMT_YUV420P
:
862 yuv420p_to_rgba32(dst
, src
, width
, height
);
867 } else if (dst_pix_fmt
== PIX_FMT_BGRA32
) {
869 case PIX_FMT_YUV420P
:
870 yuv420p_to_bgra32(dst
, src
, width
, height
);
883 #define DEINT_INPLACE_LINE_LUM \
884 movd_m2r(lum_m4[0],mm0);\
885 movd_m2r(lum_m3[0],mm1);\
886 movd_m2r(lum_m2[0],mm2);\
887 movd_m2r(lum_m1[0],mm3);\
888 movd_m2r(lum[0],mm4);\
889 punpcklbw_r2r(mm7,mm0);\
890 movd_r2m(mm2,lum_m4[0]);\
891 punpcklbw_r2r(mm7,mm1);\
892 punpcklbw_r2r(mm7,mm2);\
893 punpcklbw_r2r(mm7,mm3);\
894 punpcklbw_r2r(mm7,mm4);\
901 psubusw_r2r(mm0,mm1);\
903 packuswb_r2r(mm7,mm1);\
904 movd_r2m(mm1,lum_m2[0]);
906 #define DEINT_LINE_LUM \
907 movd_m2r(lum_m4[0],mm0);\
908 movd_m2r(lum_m3[0],mm1);\
909 movd_m2r(lum_m2[0],mm2);\
910 movd_m2r(lum_m1[0],mm3);\
911 movd_m2r(lum[0],mm4);\
912 punpcklbw_r2r(mm7,mm0);\
913 punpcklbw_r2r(mm7,mm1);\
914 punpcklbw_r2r(mm7,mm2);\
915 punpcklbw_r2r(mm7,mm3);\
916 punpcklbw_r2r(mm7,mm4);\
923 psubusw_r2r(mm0,mm1);\
925 packuswb_r2r(mm7,mm1);\
926 movd_r2m(mm1,dst[0]);
929 /* filter parameters: [-1 4 2 4 -1] // 8 */
930 static void deinterlace_line(UINT8
*dst
, UINT8
*lum_m4
, UINT8
*lum_m3
, UINT8
*lum_m2
, UINT8
*lum_m1
, UINT8
*lum
,
934 UINT8
*cm
= cropTbl
+ MAX_NEG_CROP
;
937 for(;size
> 0;size
--) {
939 sum
+= lum_m3
[0] << 2;
940 sum
+= lum_m2
[0] << 1;
941 sum
+= lum_m1
[0] << 2;
943 dst
[0] = cm
[(sum
+ 4) >> 3];
953 for (;size
> 3; size
-=4) {
964 static void deinterlace_line_inplace(UINT8
*lum_m4
, UINT8
*lum_m3
, UINT8
*lum_m2
, UINT8
*lum_m1
, UINT8
*lum
,
968 UINT8
*cm
= cropTbl
+ MAX_NEG_CROP
;
971 for(;size
> 0;size
--) {
973 sum
+= lum_m3
[0] << 2;
974 sum
+= lum_m2
[0] << 1;
976 sum
+= lum_m1
[0] << 2;
978 lum_m2
[0] = cm
[(sum
+ 4) >> 3];
987 for (;size
> 3; size
-=4) {
988 DEINT_INPLACE_LINE_LUM
998 /* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
999 top field is copied as is, but the bottom field is deinterlaced
1000 against the top field. */
1001 static void deinterlace_bottom_field(UINT8
*dst
, int dst_wrap
,
1002 UINT8
*src1
, int src_wrap
,
1003 int width
, int height
)
1005 UINT8
*src_m2
, *src_m1
, *src_0
, *src_p1
, *src_p2
;
1010 src_0
=&src_m1
[src_wrap
];
1011 src_p1
=&src_0
[src_wrap
];
1012 src_p2
=&src_p1
[src_wrap
];
1013 for(y
=0;y
<(height
-2);y
+=2) {
1014 memcpy(dst
,src_m1
,width
);
1016 deinterlace_line(dst
,src_m2
,src_m1
,src_0
,src_p1
,src_p2
,width
);
1020 src_p1
+= 2*src_wrap
;
1021 src_p2
+= 2*src_wrap
;
1024 memcpy(dst
,src_m1
,width
);
1027 deinterlace_line(dst
,src_m2
,src_m1
,src_0
,src_0
,src_0
,width
);
1030 static void deinterlace_bottom_field_inplace(UINT8
*src1
, int src_wrap
,
1031 int width
, int height
)
1033 UINT8
*src_m1
, *src_0
, *src_p1
, *src_p2
;
1036 buf
= (UINT8
*)av_malloc(width
);
1039 memcpy(buf
,src_m1
,width
);
1040 src_0
=&src_m1
[src_wrap
];
1041 src_p1
=&src_0
[src_wrap
];
1042 src_p2
=&src_p1
[src_wrap
];
1043 for(y
=0;y
<(height
-2);y
+=2) {
1044 deinterlace_line_inplace(buf
,src_m1
,src_0
,src_p1
,src_p2
,width
);
1047 src_p1
+= 2*src_wrap
;
1048 src_p2
+= 2*src_wrap
;
1051 deinterlace_line_inplace(buf
,src_m1
,src_0
,src_0
,src_0
,width
);
1056 /* deinterlace - if not supported return -1 */
1057 int avpicture_deinterlace(AVPicture
*dst
, AVPicture
*src
,
1058 int pix_fmt
, int width
, int height
)
1062 if (pix_fmt
!= PIX_FMT_YUV420P
&&
1063 pix_fmt
!= PIX_FMT_YUV422P
&&
1064 pix_fmt
!= PIX_FMT_YUV444P
)
1066 if ((width
& 3) != 0 || (height
& 3) != 0)
1077 movq_m2r(rounder
,mm6
);
1085 case PIX_FMT_YUV420P
:
1089 case PIX_FMT_YUV422P
:
1097 deinterlace_bottom_field_inplace(src
->data
[i
], src
->linesize
[i
],
1100 deinterlace_bottom_field(dst
->data
[i
],dst
->linesize
[i
],
1101 src
->data
[i
], src
->linesize
[i
],