Bug fix of wrong mp4, m4a duration
[platform/upstream/ffmpeg.git] / libswscale / alphablend.c
1 /*
2  * Copyright (C) 2015 Michael Niedermayer <michaelni@gmx.at>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 #include "swscale_internal.h"
22
23 int ff_sws_alphablendaway(SwsContext *c, const uint8_t *src[],
24                           int srcStride[], int srcSliceY, int srcSliceH,
25                           uint8_t *dst[], int dstStride[])
26 {
27     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
28     int nb_components = desc->nb_components;
29     int plane, x, ysrc;
30     int plane_count = isGray(c->srcFormat) ? 1 : 3;
31     int sixteen_bits = desc->comp[0].depth >= 9;
32     unsigned off    = 1<<(desc->comp[0].depth - 1);
33     unsigned shift  = desc->comp[0].depth;
34     unsigned max    = (1<<shift) - 1;
35     int target_table[2][3];
36
37     for (plane = 0; plane < plane_count; plane++) {
38         int a = 0, b = 0;
39         if (c->alphablend == SWS_ALPHA_BLEND_CHECKERBOARD) {
40             a = (1<<(desc->comp[0].depth - 1))/2;
41             b = 3*(1<<(desc->comp[0].depth-1))/2;
42         }
43         target_table[0][plane] = plane && !(desc->flags & AV_PIX_FMT_FLAG_RGB) ? 1<<(desc->comp[0].depth - 1) : a;
44         target_table[1][plane] = plane && !(desc->flags & AV_PIX_FMT_FLAG_RGB) ? 1<<(desc->comp[0].depth - 1) : b;
45     }
46
47     av_assert0(plane_count == nb_components - 1);
48     if (desc->flags & AV_PIX_FMT_FLAG_PLANAR) {
49         for (plane = 0; plane < plane_count; plane++) {
50             int w = plane ? c->chrSrcW : c->srcW;
51             int x_subsample = plane ? desc->log2_chroma_w: 0;
52             int y_subsample = plane ? desc->log2_chroma_h: 0;
53             for (ysrc = 0; ysrc < AV_CEIL_RSHIFT(srcSliceH, y_subsample); ysrc++) {
54                 int y = ysrc + (srcSliceY >> y_subsample);
55                 if (x_subsample || y_subsample) {
56                     int alpha;
57                     unsigned u;
58                     if (sixteen_bits) {
59                         ptrdiff_t alpha_step = srcStride[plane_count] >> 1;
60                         const uint16_t *s = (const uint16_t *)(src[plane      ] +  srcStride[plane      ] * ysrc);
61                         const uint16_t *a = (const uint16_t *)(src[plane_count] + (srcStride[plane_count] * ysrc << y_subsample));
62                               uint16_t *d = (      uint16_t *)(dst[plane      ] +  dstStride[plane      ] * y);
63                         if ((!isBE(c->srcFormat)) == !HAVE_BIGENDIAN) {
64                             for (x = 0; x < w; x++) {
65                                 if (y_subsample) {
66                                     alpha = (a[2*x]              + a[2*x + 1] + 2 +
67                                              a[2*x + alpha_step] + a[2*x + alpha_step + 1]) >> 2;
68                                 } else
69                                     alpha = (a[2*x] + a[2*x + 1]) >> 1;
70                                 u = s[x]*alpha + target_table[((x^y)>>5)&1][plane]*(max-alpha) + off;
71                                 d[x] = av_clip((u + (u >> shift)) >> shift, 0, max);
72                             }
73                         } else {
74                             for (x = 0; x < w; x++) {
75                                 if (y_subsample) {
76                                     alpha = (av_bswap16(a[2*x])              + av_bswap16(a[2*x + 1]) + 2 +
77                                              av_bswap16(a[2*x + alpha_step]) + av_bswap16(a[2*x + alpha_step + 1])) >> 2;
78                                 } else
79                                     alpha = (av_bswap16(a[2*x]) + av_bswap16(a[2*x + 1])) >> 1;
80                                 u = av_bswap16(s[x])*alpha + target_table[((x^y)>>5)&1][plane]*(max-alpha) + off;
81                                 d[x] = av_clip((u + (u >> shift)) >> shift, 0, max);
82                             }
83                         }
84                     } else {
85                         ptrdiff_t alpha_step = srcStride[plane_count];
86                         const uint8_t *s = src[plane      ] + srcStride[plane] * ysrc;
87                         const uint8_t *a = src[plane_count] + (srcStride[plane_count] * ysrc << y_subsample);
88                               uint8_t *d = dst[plane      ] + dstStride[plane] * y;
89                         for (x = 0; x < w; x++) {
90                             if (y_subsample) {
91                                 alpha = (a[2*x]              + a[2*x + 1] + 2 +
92                                          a[2*x + alpha_step] + a[2*x + alpha_step + 1]) >> 2;
93                             } else
94                                 alpha = (a[2*x] + a[2*x + 1]) >> 1;
95                             u = s[x]*alpha + target_table[((x^y)>>5)&1][plane]*(255-alpha) + 128;
96                             d[x] = (257*u) >> 16;
97                         }
98                     }
99                 } else {
100                 if (sixteen_bits) {
101                     const uint16_t *s = (const uint16_t *)(src[plane      ] + srcStride[plane      ] * ysrc);
102                     const uint16_t *a = (const uint16_t *)(src[plane_count] + srcStride[plane_count] * ysrc);
103                           uint16_t *d = (      uint16_t *)(dst[plane      ] + dstStride[plane      ] * y);
104                     if ((!isBE(c->srcFormat)) == !HAVE_BIGENDIAN) {
105                         for (x = 0; x < w; x++) {
106                             unsigned u = s[x]*a[x] + target_table[((x^y)>>5)&1][plane]*(max-a[x]) + off;
107                             d[x] = av_clip((u + (u >> shift)) >> shift, 0, max);
108                         }
109                     } else {
110                         for (x = 0; x < w; x++) {
111                             unsigned aswap =av_bswap16(a[x]);
112                             unsigned u = av_bswap16(s[x])*aswap + target_table[((x^y)>>5)&1][plane]*(max-aswap) + off;
113                             d[x] = av_clip((u + (u >> shift)) >> shift, 0, max);
114                         }
115                     }
116                 } else {
117                     const uint8_t *s = src[plane      ] + srcStride[plane] * ysrc;
118                     const uint8_t *a = src[plane_count] + srcStride[plane_count] * ysrc;
119                           uint8_t *d = dst[plane      ] + dstStride[plane] * y;
120                     for (x = 0; x < w; x++) {
121                         unsigned u = s[x]*a[x] + target_table[((x^y)>>5)&1][plane]*(255-a[x]) + 128;
122                         d[x] = (257*u) >> 16;
123                     }
124                 }
125                 }
126             }
127         }
128     } else {
129         int alpha_pos = desc->comp[plane_count].offset;
130         int w = c->srcW;
131         for (ysrc = 0; ysrc < srcSliceH; ysrc++) {
132             int y = ysrc + srcSliceY;
133             if (sixteen_bits) {
134                 const uint16_t *s = (const uint16_t *)(src[0] + srcStride[0] * ysrc + 2*!alpha_pos);
135                 const uint16_t *a = (const uint16_t *)(src[0] + srcStride[0] * ysrc +    alpha_pos);
136                       uint16_t *d = (      uint16_t *)(dst[0] + dstStride[0] * y);
137                 if ((!isBE(c->srcFormat)) == !HAVE_BIGENDIAN) {
138                     for (x = 0; x < w; x++) {
139                         for (plane = 0; plane < plane_count; plane++) {
140                             int x_index = (plane_count + 1) * x;
141                             unsigned u = s[x_index + plane]*a[x_index] + target_table[((x^y)>>5)&1][plane]*(max-a[x_index]) + off;
142                             d[plane_count*x + plane] = av_clip((u + (u >> shift)) >> shift, 0, max);
143                         }
144                     }
145                 } else {
146                     for (x = 0; x < w; x++) {
147                         for (plane = 0; plane < plane_count; plane++) {
148                             int x_index = (plane_count + 1) * x;
149                             unsigned aswap =av_bswap16(a[x_index]);
150                             unsigned u = av_bswap16(s[x_index + plane])*aswap + target_table[((x^y)>>5)&1][plane]*(max-aswap) + off;
151                             d[plane_count*x + plane] = av_clip((u + (u >> shift)) >> shift, 0, max);
152                         }
153                     }
154                 }
155             } else {
156                 const uint8_t *s = src[0] + srcStride[0] * ysrc + !alpha_pos;
157                 const uint8_t *a = src[0] + srcStride[0] * ysrc + alpha_pos;
158                       uint8_t *d = dst[0] + dstStride[0] * y;
159                 for (x = 0; x < w; x++) {
160                     for (plane = 0; plane < plane_count; plane++) {
161                         int x_index = (plane_count + 1) * x;
162                         unsigned u = s[x_index + plane]*a[x_index] + target_table[((x^y)>>5)&1][plane]*(255-a[x_index]) + 128;
163                         d[plane_count*x + plane] = (257*u) >> 16;
164                     }
165                 }
166             }
167         }
168     }
169
170     return 0;
171 }