]> git.sesse.net Git - ffmpeg/blob - libswscale/alphablend.c
Merge commit 'fab8156b2f30666adabe227b3d7712fd193873b1'
[ffmpeg] / 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, y;
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 (y = srcSliceY >> y_subsample; y < AV_CEIL_RSHIFT(srcSliceH, y_subsample); y++) {
54                 if (x_subsample || y_subsample) {
55                     int alpha;
56                     unsigned u;
57                     if (sixteen_bits) {
58                         ptrdiff_t alpha_step = srcStride[plane_count] >> 1;
59                         const uint16_t *s = (const uint16_t *)(src[plane      ] +  srcStride[plane      ] * y);
60                         const uint16_t *a = (const uint16_t *)(src[plane_count] + (srcStride[plane_count] * y << y_subsample));
61                               uint16_t *d = (      uint16_t *)(dst[plane      ] +  dstStride[plane      ] * y);
62                         if ((!isBE(c->srcFormat)) == !HAVE_BIGENDIAN) {
63                             for (x = 0; x < w; x++) {
64                                 if (y_subsample) {
65                                     alpha = (a[2*x]              + a[2*x + 1] + 2 +
66                                              a[2*x + alpha_step] + a[2*x + alpha_step + 1]) >> 2;
67                                 } else
68                                     alpha = (a[2*x] + a[2*x + 1]) >> 1;
69                                 u = s[x]*alpha + target_table[((x^y)>>5)&1][plane]*(max-alpha) + off;
70                                 d[x] = av_clip((u + (u >> shift)) >> shift, 0, max);
71                             }
72                         } else {
73                             for (x = 0; x < w; x++) {
74                                 if (y_subsample) {
75                                     alpha = (av_bswap16(a[2*x])              + av_bswap16(a[2*x + 1]) + 2 +
76                                              av_bswap16(a[2*x + alpha_step]) + av_bswap16(a[2*x + alpha_step + 1])) >> 2;
77                                 } else
78                                     alpha = (av_bswap16(a[2*x]) + av_bswap16(a[2*x + 1])) >> 1;
79                                 u = av_bswap16(s[x])*alpha + target_table[((x^y)>>5)&1][plane]*(max-alpha) + off;
80                                 d[x] = av_clip((u + (u >> shift)) >> shift, 0, max);
81                             }
82                         }
83                     } else {
84                         ptrdiff_t alpha_step = srcStride[plane_count];
85                         const uint8_t *s = src[plane      ] + srcStride[plane] * y;
86                         const uint8_t *a = src[plane_count] + (srcStride[plane_count] * y << y_subsample);
87                               uint8_t *d = dst[plane      ] + dstStride[plane] * y;
88                         for (x = 0; x < w; x++) {
89                             if (y_subsample) {
90                                 alpha = (a[2*x]              + a[2*x + 1] + 2 +
91                                          a[2*x + alpha_step] + a[2*x + alpha_step + 1]) >> 2;
92                             } else
93                                 alpha = (a[2*x] + a[2*x + 1]) >> 1;
94                             u = s[x]*alpha + target_table[((x^y)>>5)&1][plane]*(255-alpha) + 128;
95                             d[x] = (257*u) >> 16;
96                         }
97                     }
98                 } else {
99                 if (sixteen_bits) {
100                     const uint16_t *s = (const uint16_t *)(src[plane      ] + srcStride[plane      ] * y);
101                     const uint16_t *a = (const uint16_t *)(src[plane_count] + srcStride[plane_count] * y);
102                           uint16_t *d = (      uint16_t *)(dst[plane      ] + dstStride[plane      ] * y);
103                     if ((!isBE(c->srcFormat)) == !HAVE_BIGENDIAN) {
104                         for (x = 0; x < w; x++) {
105                             unsigned u = s[x]*a[x] + target_table[((x^y)>>5)&1][plane]*(max-a[x]) + off;
106                             d[x] = av_clip((u + (u >> shift)) >> shift, 0, max);
107                         }
108                     } else {
109                         for (x = 0; x < w; x++) {
110                             unsigned aswap =av_bswap16(a[x]);
111                             unsigned u = av_bswap16(s[x])*aswap + target_table[((x^y)>>5)&1][plane]*(max-aswap) + off;
112                             d[x] = av_clip((u + (u >> shift)) >> shift, 0, max);
113                         }
114                     }
115                 } else {
116                     const uint8_t *s = src[plane      ] + srcStride[plane] * y;
117                     const uint8_t *a = src[plane_count] + srcStride[plane_count] * y;
118                           uint8_t *d = dst[plane      ] + dstStride[plane] * y;
119                     for (x = 0; x < w; x++) {
120                         unsigned u = s[x]*a[x] + target_table[((x^y)>>5)&1][plane]*(255-a[x]) + 128;
121                         d[x] = (257*u) >> 16;
122                     }
123                 }
124                 }
125             }
126         }
127     } else {
128         int alpha_pos = desc->comp[plane_count].offset;
129         int w = c->srcW;
130         for (y = srcSliceY; y < srcSliceH; y++) {
131             if (sixteen_bits) {
132                 const uint16_t *s = (const uint16_t *)(src[0] + srcStride[0] * y + 2*!alpha_pos);
133                 const uint16_t *a = (const uint16_t *)(src[0] + srcStride[0] * y +    alpha_pos);
134                       uint16_t *d = (      uint16_t *)(dst[0] + dstStride[0] * y);
135                 if ((!isBE(c->srcFormat)) == !HAVE_BIGENDIAN) {
136                     for (x = 0; x < w; x++) {
137                         for (plane = 0; plane < plane_count; plane++) {
138                             int x_index = (plane_count + 1) * x;
139                             unsigned u = s[x_index + plane]*a[x_index] + target_table[((x^y)>>5)&1][plane]*(max-a[x_index]) + off;
140                             d[plane_count*x + plane] = av_clip((u + (u >> shift)) >> shift, 0, max);
141                         }
142                     }
143                 } else {
144                     for (x = 0; x < w; x++) {
145                         for (plane = 0; plane < plane_count; plane++) {
146                             int x_index = (plane_count + 1) * x;
147                             unsigned aswap =av_bswap16(a[x_index]);
148                             unsigned u = av_bswap16(s[x_index + plane])*aswap + target_table[((x^y)>>5)&1][plane]*(max-aswap) + off;
149                             d[plane_count*x + plane] = av_clip((u + (u >> shift)) >> shift, 0, max);
150                         }
151                     }
152                 }
153             } else {
154                 const uint8_t *s = src[0] + srcStride[0] * y + !alpha_pos;
155                 const uint8_t *a = src[0] + srcStride[0] * y + alpha_pos;
156                       uint8_t *d = dst[0] + dstStride[0] * y;
157                 for (x = 0; x < w; x++) {
158                     for (plane = 0; plane < plane_count; plane++) {
159                         int x_index = (plane_count + 1) * x;
160                         unsigned u = s[x_index + plane]*a[x_index] + target_table[((x^y)>>5)&1][plane]*(255-a[x_index]) + 128;
161                         d[plane_count*x + plane] = (257*u) >> 16;
162                     }
163                 }
164             }
165         }
166     }
167
168     return 0;
169 }