FFmpeg  4.4.8
alphablend.c
Go to the documentation of this file.
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 
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  const int lum_w = c->srcW;
29  const int lum_h = c->srcH;
30  int nb_components = desc->nb_components;
31  int plane, x, ysrc;
32  int plane_count = isGray(c->srcFormat) ? 1 : 3;
33  int sixteen_bits = desc->comp[0].depth >= 9;
34  unsigned off = 1<<(desc->comp[0].depth - 1);
35  unsigned shift = desc->comp[0].depth;
36  unsigned max = (1<<shift) - 1;
37  int target_table[2][3];
38 
39  for (plane = 0; plane < plane_count; plane++) {
40  int a = 0, b = 0;
41  if (c->alphablend == SWS_ALPHA_BLEND_CHECKERBOARD) {
42  a = (1<<(desc->comp[0].depth - 1))/2;
43  b = 3*(1<<(desc->comp[0].depth-1))/2;
44  }
45  target_table[0][plane] = plane && !(desc->flags & AV_PIX_FMT_FLAG_RGB) ? 1<<(desc->comp[0].depth - 1) : a;
46  target_table[1][plane] = plane && !(desc->flags & AV_PIX_FMT_FLAG_RGB) ? 1<<(desc->comp[0].depth - 1) : b;
47  }
48 
49  av_assert0(plane_count == nb_components - 1);
50  if (desc->flags & AV_PIX_FMT_FLAG_PLANAR) {
51  for (plane = 0; plane < plane_count; plane++) {
52  int w = plane ? c->chrSrcW : c->srcW;
53  int x_subsample = plane ? desc->log2_chroma_w: 0;
54  int y_subsample = plane ? desc->log2_chroma_h: 0;
55  for (ysrc = 0; ysrc < AV_CEIL_RSHIFT(srcSliceH, y_subsample); ysrc++) {
56  int y = ysrc + (srcSliceY >> y_subsample);
57  int subsample_row = y_subsample && (y << y_subsample) + 1 < lum_h;
58  if (x_subsample || subsample_row) {
59  int alpha;
60  unsigned u;
61  if (sixteen_bits) {
62  ptrdiff_t alpha_step = srcStride[plane_count] >> 1;
63  const uint16_t *s = (const uint16_t *)(src[plane ] + srcStride[plane ] * ysrc);
64  const uint16_t *a = (const uint16_t *)(src[plane_count] + (srcStride[plane_count] * ysrc << y_subsample));
65  uint16_t *d = ( uint16_t *)(dst[plane ] + dstStride[plane ] * y);
66  if ((!isBE(c->srcFormat)) == !HAVE_BIGENDIAN) {
67  for (x = 0; x < w; x++) {
68  const int xnext = FFMIN(2*x + 1, lum_w - 1);
69  if (subsample_row) {
70  alpha = (a[2*x] + a[xnext] + 2 +
71  a[2*x + alpha_step] + a[xnext + alpha_step]) >> 2;
72  } else
73  alpha = (a[2*x] + a[xnext]) >> 1;
74  u = s[x]*alpha + target_table[((x^y)>>5)&1][plane]*(max-alpha) + off;
75  d[x] = av_clip((u + (u >> shift)) >> shift, 0, max);
76  }
77  } else {
78  for (x = 0; x < w; x++) {
79  const int xnext = FFMIN(2*x + 1, lum_w - 1);
80  if (subsample_row) {
81  alpha = (av_bswap16(a[2*x]) + av_bswap16(a[xnext]) + 2 +
82  av_bswap16(a[2*x + alpha_step]) + av_bswap16(a[xnext + alpha_step])) >> 2;
83  } else
84  alpha = (av_bswap16(a[2*x]) + av_bswap16(a[xnext])) >> 1;
85  u = av_bswap16(s[x])*alpha + target_table[((x^y)>>5)&1][plane]*(max-alpha) + off;
86  d[x] = av_clip((u + (u >> shift)) >> shift, 0, max);
87  }
88  }
89  } else {
90  ptrdiff_t alpha_step = srcStride[plane_count];
91  const uint8_t *s = src[plane ] + srcStride[plane] * ysrc;
92  const uint8_t *a = src[plane_count] + (srcStride[plane_count] * ysrc << y_subsample);
93  uint8_t *d = dst[plane ] + dstStride[plane] * y;
94  for (x = 0; x < w; x++) {
95  const int xnext = FFMIN(2*x + 1, lum_w - 1);
96  if (subsample_row) {
97  alpha = (a[2*x] + a[xnext] + 2 +
98  a[2*x + alpha_step] + a[xnext + alpha_step]) >> 2;
99  } else
100  alpha = (a[2*x] + a[xnext]) >> 1;
101  u = s[x]*alpha + target_table[((x^y)>>5)&1][plane]*(255-alpha) + 128;
102  d[x] = (257*u) >> 16;
103  }
104  }
105  } else {
106  if (sixteen_bits) {
107  const uint16_t *s = (const uint16_t *)(src[plane ] + srcStride[plane ] * ysrc);
108  const uint16_t *a = (const uint16_t *)(src[plane_count] + srcStride[plane_count] * ysrc);
109  uint16_t *d = ( uint16_t *)(dst[plane ] + dstStride[plane ] * y);
110  if ((!isBE(c->srcFormat)) == !HAVE_BIGENDIAN) {
111  for (x = 0; x < w; x++) {
112  unsigned u = s[x]*a[x] + target_table[((x^y)>>5)&1][plane]*(max-a[x]) + off;
113  d[x] = av_clip((u + (u >> shift)) >> shift, 0, max);
114  }
115  } else {
116  for (x = 0; x < w; x++) {
117  unsigned aswap =av_bswap16(a[x]);
118  unsigned u = av_bswap16(s[x])*aswap + target_table[((x^y)>>5)&1][plane]*(max-aswap) + off;
119  d[x] = av_clip((u + (u >> shift)) >> shift, 0, max);
120  }
121  }
122  } else {
123  const uint8_t *s = src[plane ] + srcStride[plane] * ysrc;
124  const uint8_t *a = src[plane_count] + srcStride[plane_count] * ysrc;
125  uint8_t *d = dst[plane ] + dstStride[plane] * y;
126  for (x = 0; x < w; x++) {
127  unsigned u = s[x]*a[x] + target_table[((x^y)>>5)&1][plane]*(255-a[x]) + 128;
128  d[x] = (257*u) >> 16;
129  }
130  }
131  }
132  }
133  }
134  } else {
135  int alpha_pos = desc->comp[plane_count].offset;
136  int w = c->srcW;
137  for (ysrc = 0; ysrc < srcSliceH; ysrc++) {
138  int y = ysrc + srcSliceY;
139  if (sixteen_bits) {
140  const uint16_t *s = (const uint16_t *)(src[0] + srcStride[0] * ysrc + 2*!alpha_pos);
141  const uint16_t *a = (const uint16_t *)(src[0] + srcStride[0] * ysrc + alpha_pos);
142  uint16_t *d = ( uint16_t *)(dst[0] + dstStride[0] * y);
143  if ((!isBE(c->srcFormat)) == !HAVE_BIGENDIAN) {
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 u = s[x_index + plane]*a[x_index] + target_table[((x^y)>>5)&1][plane]*(max-a[x_index]) + off;
148  d[plane_count*x + plane] = av_clip((u + (u >> shift)) >> shift, 0, max);
149  }
150  }
151  } else {
152  for (x = 0; x < w; x++) {
153  for (plane = 0; plane < plane_count; plane++) {
154  int x_index = (plane_count + 1) * x;
155  unsigned aswap =av_bswap16(a[x_index]);
156  unsigned u = av_bswap16(s[x_index + plane])*aswap + target_table[((x^y)>>5)&1][plane]*(max-aswap) + off;
157  d[plane_count*x + plane] = av_clip((u + (u >> shift)) >> shift, 0, max);
158  }
159  }
160  }
161  } else {
162  const uint8_t *s = src[0] + srcStride[0] * ysrc + !alpha_pos;
163  const uint8_t *a = src[0] + srcStride[0] * ysrc + alpha_pos;
164  uint8_t *d = dst[0] + dstStride[0] * y;
165  for (x = 0; x < w; x++) {
166  for (plane = 0; plane < plane_count; plane++) {
167  int x_index = (plane_count + 1) * x;
168  unsigned u = s[x_index + plane]*a[x_index] + target_table[((x^y)>>5)&1][plane]*(255-a[x_index]) + 128;
169  d[plane_count*x + plane] = (257*u) >> 16;
170  }
171  }
172  }
173  }
174  }
175 
176  return 0;
177 }
int ff_sws_alphablendaway(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
Definition: alphablend.c:23
uint8_t
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:264
#define s(width, name)
Definition: cbs_vp9.c:257
#define FFMIN(a, b)
Definition: common.h:105
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
#define av_clip
Definition: common.h:122
#define HAVE_BIGENDIAN
Definition: config.h:203
#define max(a, b)
Definition: cuda_runtime.h:33
static const int16_t alpha[]
Definition: ilbcdata.h:55
const char * desc
Definition: libsvtav1.c:79
uint8_t w
Definition: llviddspenc.c:39
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2573
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
Definition: pixdesc.h:148
#define AV_PIX_FMT_FLAG_PLANAR
At least one pixel component is not in the first data plane.
Definition: pixdesc.h:144
#define av_bswap16
Definition: bswap.h:31
static int shift(int a, int b)
Definition: sonic.c:82
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
@ SWS_ALPHA_BLEND_CHECKERBOARD
static av_always_inline int isBE(enum AVPixelFormat pix_fmt)
#define src
Definition: vp8dsp.c:255
#define isGray(x)
Definition: swscale.c:40
const char * b
Definition: vf_curves.c:119
static double c[64]
EMMS_IF_MMX return srcSliceH