Coverage Report

Created: 2025-06-13 06:48

/src/libwebp/src/dsp/alpha_processing.c
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2013 Google Inc. All Rights Reserved.
2
//
3
// Use of this source code is governed by a BSD-style license
4
// that can be found in the COPYING file in the root of the source
5
// tree. An additional intellectual property rights grant can be found
6
// in the file PATENTS. All contributing project authors may
7
// be found in the AUTHORS file in the root of the source tree.
8
// -----------------------------------------------------------------------------
9
//
10
// Utilities for processing transparent channel.
11
//
12
// Author: Skal (pascal.massimino@gmail.com)
13
14
#include <assert.h>
15
#include <stddef.h>
16
17
#include "src/dsp/cpu.h"
18
#include "src/dsp/dsp.h"
19
#include "src/webp/types.h"
20
21
// Tables can be faster on some platform but incur some extra binary size (~2k).
22
#if !defined(USE_TABLES_FOR_ALPHA_MULT)
23
#define USE_TABLES_FOR_ALPHA_MULT 0   // ALTERNATE_CODE
24
#endif
25
26
27
// -----------------------------------------------------------------------------
28
29
0
#define MFIX 24    // 24bit fixed-point arithmetic
30
0
#define HALF ((1u << MFIX) >> 1)
31
0
#define KINV_255 ((1u << MFIX) / 255u)
32
33
0
static uint32_t Mult(uint8_t x, uint32_t mult) {
34
0
  const uint32_t v = (x * mult + HALF) >> MFIX;
35
0
  assert(v <= 255);  // <- 24bit precision is enough to ensure that.
36
0
  return v;
37
0
}
38
39
#if (USE_TABLES_FOR_ALPHA_MULT == 1)
40
41
static const uint32_t kMultTables[2][256] = {
42
  {    // (255u << MFIX) / alpha
43
    0x00000000, 0xff000000, 0x7f800000, 0x55000000, 0x3fc00000, 0x33000000,
44
    0x2a800000, 0x246db6db, 0x1fe00000, 0x1c555555, 0x19800000, 0x172e8ba2,
45
    0x15400000, 0x139d89d8, 0x1236db6d, 0x11000000, 0x0ff00000, 0x0f000000,
46
    0x0e2aaaaa, 0x0d6bca1a, 0x0cc00000, 0x0c249249, 0x0b9745d1, 0x0b1642c8,
47
    0x0aa00000, 0x0a333333, 0x09cec4ec, 0x0971c71c, 0x091b6db6, 0x08cb08d3,
48
    0x08800000, 0x0839ce73, 0x07f80000, 0x07ba2e8b, 0x07800000, 0x07492492,
49
    0x07155555, 0x06e45306, 0x06b5e50d, 0x0689d89d, 0x06600000, 0x063831f3,
50
    0x06124924, 0x05ee23b8, 0x05cba2e8, 0x05aaaaaa, 0x058b2164, 0x056cefa8,
51
    0x05500000, 0x05343eb1, 0x05199999, 0x05000000, 0x04e76276, 0x04cfb2b7,
52
    0x04b8e38e, 0x04a2e8ba, 0x048db6db, 0x0479435e, 0x04658469, 0x045270d0,
53
    0x04400000, 0x042e29f7, 0x041ce739, 0x040c30c3, 0x03fc0000, 0x03ec4ec4,
54
    0x03dd1745, 0x03ce540f, 0x03c00000, 0x03b21642, 0x03a49249, 0x03976fc6,
55
    0x038aaaaa, 0x037e3f1f, 0x03722983, 0x03666666, 0x035af286, 0x034fcace,
56
    0x0344ec4e, 0x033a5440, 0x03300000, 0x0325ed09, 0x031c18f9, 0x0312818a,
57
    0x03092492, 0x03000000, 0x02f711dc, 0x02ee5846, 0x02e5d174, 0x02dd7baf,
58
    0x02d55555, 0x02cd5cd5, 0x02c590b2, 0x02bdef7b, 0x02b677d4, 0x02af286b,
59
    0x02a80000, 0x02a0fd5c, 0x029a1f58, 0x029364d9, 0x028ccccc, 0x0286562d,
60
    0x02800000, 0x0279c952, 0x0273b13b, 0x026db6db, 0x0267d95b, 0x026217ec,
61
    0x025c71c7, 0x0256e62a, 0x0251745d, 0x024c1bac, 0x0246db6d, 0x0241b2f9,
62
    0x023ca1af, 0x0237a6f4, 0x0232c234, 0x022df2df, 0x02293868, 0x02249249,
63
    0x02200000, 0x021b810e, 0x021714fb, 0x0212bb51, 0x020e739c, 0x020a3d70,
64
    0x02061861, 0x02020408, 0x01fe0000, 0x01fa0be8, 0x01f62762, 0x01f25213,
65
    0x01ee8ba2, 0x01ead3ba, 0x01e72a07, 0x01e38e38, 0x01e00000, 0x01dc7f10,
66
    0x01d90b21, 0x01d5a3e9, 0x01d24924, 0x01cefa8d, 0x01cbb7e3, 0x01c880e5,
67
    0x01c55555, 0x01c234f7, 0x01bf1f8f, 0x01bc14e5, 0x01b914c1, 0x01b61eed,
68
    0x01b33333, 0x01b05160, 0x01ad7943, 0x01aaaaaa, 0x01a7e567, 0x01a5294a,
69
    0x01a27627, 0x019fcbd2, 0x019d2a20, 0x019a90e7, 0x01980000, 0x01957741,
70
    0x0192f684, 0x01907da4, 0x018e0c7c, 0x018ba2e8, 0x018940c5, 0x0186e5f0,
71
    0x01849249, 0x018245ae, 0x01800000, 0x017dc11f, 0x017b88ee, 0x0179574e,
72
    0x01772c23, 0x01750750, 0x0172e8ba, 0x0170d045, 0x016ebdd7, 0x016cb157,
73
    0x016aaaaa, 0x0168a9b9, 0x0166ae6a, 0x0164b8a7, 0x0162c859, 0x0160dd67,
74
    0x015ef7bd, 0x015d1745, 0x015b3bea, 0x01596596, 0x01579435, 0x0155c7b4,
75
    0x01540000, 0x01523d03, 0x01507eae, 0x014ec4ec, 0x014d0fac, 0x014b5edc,
76
    0x0149b26c, 0x01480a4a, 0x01466666, 0x0144c6af, 0x01432b16, 0x0141938b,
77
    0x01400000, 0x013e7063, 0x013ce4a9, 0x013b5cc0, 0x0139d89d, 0x01385830,
78
    0x0136db6d, 0x01356246, 0x0133ecad, 0x01327a97, 0x01310bf6, 0x012fa0be,
79
    0x012e38e3, 0x012cd459, 0x012b7315, 0x012a150a, 0x0128ba2e, 0x01276276,
80
    0x01260dd6, 0x0124bc44, 0x01236db6, 0x01222222, 0x0120d97c, 0x011f93bc,
81
    0x011e50d7, 0x011d10c4, 0x011bd37a, 0x011a98ef, 0x0119611a, 0x01182bf2,
82
    0x0116f96f, 0x0115c988, 0x01149c34, 0x0113716a, 0x01124924, 0x01112358,
83
    0x01100000, 0x010edf12, 0x010dc087, 0x010ca458, 0x010b8a7d, 0x010a72f0,
84
    0x01095da8, 0x01084a9f, 0x010739ce, 0x01062b2e, 0x01051eb8, 0x01041465,
85
    0x01030c30, 0x01020612, 0x01010204, 0x01000000 },
86
  {   // alpha * KINV_255
87
    0x00000000, 0x00010101, 0x00020202, 0x00030303, 0x00040404, 0x00050505,
88
    0x00060606, 0x00070707, 0x00080808, 0x00090909, 0x000a0a0a, 0x000b0b0b,
89
    0x000c0c0c, 0x000d0d0d, 0x000e0e0e, 0x000f0f0f, 0x00101010, 0x00111111,
90
    0x00121212, 0x00131313, 0x00141414, 0x00151515, 0x00161616, 0x00171717,
91
    0x00181818, 0x00191919, 0x001a1a1a, 0x001b1b1b, 0x001c1c1c, 0x001d1d1d,
92
    0x001e1e1e, 0x001f1f1f, 0x00202020, 0x00212121, 0x00222222, 0x00232323,
93
    0x00242424, 0x00252525, 0x00262626, 0x00272727, 0x00282828, 0x00292929,
94
    0x002a2a2a, 0x002b2b2b, 0x002c2c2c, 0x002d2d2d, 0x002e2e2e, 0x002f2f2f,
95
    0x00303030, 0x00313131, 0x00323232, 0x00333333, 0x00343434, 0x00353535,
96
    0x00363636, 0x00373737, 0x00383838, 0x00393939, 0x003a3a3a, 0x003b3b3b,
97
    0x003c3c3c, 0x003d3d3d, 0x003e3e3e, 0x003f3f3f, 0x00404040, 0x00414141,
98
    0x00424242, 0x00434343, 0x00444444, 0x00454545, 0x00464646, 0x00474747,
99
    0x00484848, 0x00494949, 0x004a4a4a, 0x004b4b4b, 0x004c4c4c, 0x004d4d4d,
100
    0x004e4e4e, 0x004f4f4f, 0x00505050, 0x00515151, 0x00525252, 0x00535353,
101
    0x00545454, 0x00555555, 0x00565656, 0x00575757, 0x00585858, 0x00595959,
102
    0x005a5a5a, 0x005b5b5b, 0x005c5c5c, 0x005d5d5d, 0x005e5e5e, 0x005f5f5f,
103
    0x00606060, 0x00616161, 0x00626262, 0x00636363, 0x00646464, 0x00656565,
104
    0x00666666, 0x00676767, 0x00686868, 0x00696969, 0x006a6a6a, 0x006b6b6b,
105
    0x006c6c6c, 0x006d6d6d, 0x006e6e6e, 0x006f6f6f, 0x00707070, 0x00717171,
106
    0x00727272, 0x00737373, 0x00747474, 0x00757575, 0x00767676, 0x00777777,
107
    0x00787878, 0x00797979, 0x007a7a7a, 0x007b7b7b, 0x007c7c7c, 0x007d7d7d,
108
    0x007e7e7e, 0x007f7f7f, 0x00808080, 0x00818181, 0x00828282, 0x00838383,
109
    0x00848484, 0x00858585, 0x00868686, 0x00878787, 0x00888888, 0x00898989,
110
    0x008a8a8a, 0x008b8b8b, 0x008c8c8c, 0x008d8d8d, 0x008e8e8e, 0x008f8f8f,
111
    0x00909090, 0x00919191, 0x00929292, 0x00939393, 0x00949494, 0x00959595,
112
    0x00969696, 0x00979797, 0x00989898, 0x00999999, 0x009a9a9a, 0x009b9b9b,
113
    0x009c9c9c, 0x009d9d9d, 0x009e9e9e, 0x009f9f9f, 0x00a0a0a0, 0x00a1a1a1,
114
    0x00a2a2a2, 0x00a3a3a3, 0x00a4a4a4, 0x00a5a5a5, 0x00a6a6a6, 0x00a7a7a7,
115
    0x00a8a8a8, 0x00a9a9a9, 0x00aaaaaa, 0x00ababab, 0x00acacac, 0x00adadad,
116
    0x00aeaeae, 0x00afafaf, 0x00b0b0b0, 0x00b1b1b1, 0x00b2b2b2, 0x00b3b3b3,
117
    0x00b4b4b4, 0x00b5b5b5, 0x00b6b6b6, 0x00b7b7b7, 0x00b8b8b8, 0x00b9b9b9,
118
    0x00bababa, 0x00bbbbbb, 0x00bcbcbc, 0x00bdbdbd, 0x00bebebe, 0x00bfbfbf,
119
    0x00c0c0c0, 0x00c1c1c1, 0x00c2c2c2, 0x00c3c3c3, 0x00c4c4c4, 0x00c5c5c5,
120
    0x00c6c6c6, 0x00c7c7c7, 0x00c8c8c8, 0x00c9c9c9, 0x00cacaca, 0x00cbcbcb,
121
    0x00cccccc, 0x00cdcdcd, 0x00cecece, 0x00cfcfcf, 0x00d0d0d0, 0x00d1d1d1,
122
    0x00d2d2d2, 0x00d3d3d3, 0x00d4d4d4, 0x00d5d5d5, 0x00d6d6d6, 0x00d7d7d7,
123
    0x00d8d8d8, 0x00d9d9d9, 0x00dadada, 0x00dbdbdb, 0x00dcdcdc, 0x00dddddd,
124
    0x00dedede, 0x00dfdfdf, 0x00e0e0e0, 0x00e1e1e1, 0x00e2e2e2, 0x00e3e3e3,
125
    0x00e4e4e4, 0x00e5e5e5, 0x00e6e6e6, 0x00e7e7e7, 0x00e8e8e8, 0x00e9e9e9,
126
    0x00eaeaea, 0x00ebebeb, 0x00ececec, 0x00ededed, 0x00eeeeee, 0x00efefef,
127
    0x00f0f0f0, 0x00f1f1f1, 0x00f2f2f2, 0x00f3f3f3, 0x00f4f4f4, 0x00f5f5f5,
128
    0x00f6f6f6, 0x00f7f7f7, 0x00f8f8f8, 0x00f9f9f9, 0x00fafafa, 0x00fbfbfb,
129
    0x00fcfcfc, 0x00fdfdfd, 0x00fefefe, 0x00ffffff }
130
};
131
132
static WEBP_INLINE uint32_t GetScale(uint32_t a, int inverse) {
133
  return kMultTables[!inverse][a];
134
}
135
136
#else
137
138
0
static WEBP_INLINE uint32_t GetScale(uint32_t a, int inverse) {
139
0
  return inverse ? (255u << MFIX) / a : a * KINV_255;
140
0
}
141
142
#endif  // USE_TABLES_FOR_ALPHA_MULT
143
144
0
void WebPMultARGBRow_C(uint32_t* const ptr, int width, int inverse) {
145
0
  int x;
146
0
  for (x = 0; x < width; ++x) {
147
0
    const uint32_t argb = ptr[x];
148
0
    if (argb < 0xff000000u) {      // alpha < 255
149
0
      if (argb <= 0x00ffffffu) {   // alpha == 0
150
0
        ptr[x] = 0;
151
0
      } else {
152
0
        const uint32_t alpha = (argb >> 24) & 0xff;
153
0
        const uint32_t scale = GetScale(alpha, inverse);
154
0
        uint32_t out = argb & 0xff000000u;
155
0
        out |= Mult(argb >>  0, scale) <<  0;
156
0
        out |= Mult(argb >>  8, scale) <<  8;
157
0
        out |= Mult(argb >> 16, scale) << 16;
158
0
        ptr[x] = out;
159
0
      }
160
0
    }
161
0
  }
162
0
}
163
164
void WebPMultRow_C(uint8_t* WEBP_RESTRICT const ptr,
165
                   const uint8_t* WEBP_RESTRICT const alpha,
166
0
                   int width, int inverse) {
167
0
  int x;
168
0
  for (x = 0; x < width; ++x) {
169
0
    const uint32_t a = alpha[x];
170
0
    if (a != 255) {
171
0
      if (a == 0) {
172
0
        ptr[x] = 0;
173
0
      } else {
174
0
        const uint32_t scale = GetScale(a, inverse);
175
0
        ptr[x] = Mult(ptr[x], scale);
176
0
      }
177
0
    }
178
0
  }
179
0
}
180
181
#undef KINV_255
182
#undef HALF
183
#undef MFIX
184
185
void (*WebPMultARGBRow)(uint32_t* const ptr, int width, int inverse);
186
void (*WebPMultRow)(uint8_t* WEBP_RESTRICT const ptr,
187
                    const uint8_t* WEBP_RESTRICT const alpha,
188
                    int width, int inverse);
189
190
//------------------------------------------------------------------------------
191
// Generic per-plane calls
192
193
void WebPMultARGBRows(uint8_t* ptr, int stride, int width, int num_rows,
194
0
                      int inverse) {
195
0
  int n;
196
0
  for (n = 0; n < num_rows; ++n) {
197
0
    WebPMultARGBRow((uint32_t*)ptr, width, inverse);
198
0
    ptr += stride;
199
0
  }
200
0
}
201
202
void WebPMultRows(uint8_t* WEBP_RESTRICT ptr, int stride,
203
                  const uint8_t* WEBP_RESTRICT alpha, int alpha_stride,
204
0
                  int width, int num_rows, int inverse) {
205
0
  int n;
206
0
  for (n = 0; n < num_rows; ++n) {
207
0
    WebPMultRow(ptr, alpha, width, inverse);
208
0
    ptr += stride;
209
0
    alpha += alpha_stride;
210
0
  }
211
0
}
212
213
//------------------------------------------------------------------------------
214
// Premultiplied modes
215
216
// non dithered-modes
217
218
// (x * a * 32897) >> 23 is bit-wise equivalent to (int)(x * a / 255.)
219
// for all 8bit x or a. For bit-wise equivalence to (int)(x * a / 255. + .5),
220
// one can use instead: (x * a * 65793 + (1 << 23)) >> 24
221
#if 1     // (int)(x * a / 255.)
222
0
#define MULTIPLIER(a)   ((a) * 32897U)
223
0
#define PREMULTIPLY(x, m) (((x) * (m)) >> 23)
224
#else     // (int)(x * a / 255. + .5)
225
#define MULTIPLIER(a) ((a) * 65793U)
226
#define PREMULTIPLY(x, m) (((x) * (m) + (1U << 23)) >> 24)
227
#endif
228
229
#if !WEBP_NEON_OMIT_C_CODE
230
static void ApplyAlphaMultiply_C(uint8_t* rgba, int alpha_first,
231
0
                                 int w, int h, int stride) {
232
0
  while (h-- > 0) {
233
0
    uint8_t* const rgb = rgba + (alpha_first ? 1 : 0);
234
0
    const uint8_t* const alpha = rgba + (alpha_first ? 0 : 3);
235
0
    int i;
236
0
    for (i = 0; i < w; ++i) {
237
0
      const uint32_t a = alpha[4 * i];
238
0
      if (a != 0xff) {
239
0
        const uint32_t mult = MULTIPLIER(a);
240
0
        rgb[4 * i + 0] = PREMULTIPLY(rgb[4 * i + 0], mult);
241
0
        rgb[4 * i + 1] = PREMULTIPLY(rgb[4 * i + 1], mult);
242
0
        rgb[4 * i + 2] = PREMULTIPLY(rgb[4 * i + 2], mult);
243
0
      }
244
0
    }
245
0
    rgba += stride;
246
0
  }
247
0
}
248
#endif  // !WEBP_NEON_OMIT_C_CODE
249
#undef MULTIPLIER
250
#undef PREMULTIPLY
251
252
// rgbA4444
253
254
0
#define MULTIPLIER(a)  ((a) * 0x1111)    // 0x1111 ~= (1 << 16) / 15
255
256
0
static WEBP_INLINE uint8_t dither_hi(uint8_t x) {
257
0
  return (x & 0xf0) | (x >> 4);
258
0
}
259
260
0
static WEBP_INLINE uint8_t dither_lo(uint8_t x) {
261
0
  return (x & 0x0f) | (x << 4);
262
0
}
263
264
0
static WEBP_INLINE uint8_t multiply(uint8_t x, uint32_t m) {
265
0
  return (x * m) >> 16;
266
0
}
267
268
static WEBP_INLINE void ApplyAlphaMultiply4444_C(uint8_t* rgba4444,
269
                                                 int w, int h, int stride,
270
0
                                                 int rg_byte_pos /* 0 or 1 */) {
271
0
  while (h-- > 0) {
272
0
    int i;
273
0
    for (i = 0; i < w; ++i) {
274
0
      const uint32_t rg = rgba4444[2 * i + rg_byte_pos];
275
0
      const uint32_t ba = rgba4444[2 * i + (rg_byte_pos ^ 1)];
276
0
      const uint8_t a = ba & 0x0f;
277
0
      const uint32_t mult = MULTIPLIER(a);
278
0
      const uint8_t r = multiply(dither_hi(rg), mult);
279
0
      const uint8_t g = multiply(dither_lo(rg), mult);
280
0
      const uint8_t b = multiply(dither_hi(ba), mult);
281
0
      rgba4444[2 * i + rg_byte_pos] = (r & 0xf0) | ((g >> 4) & 0x0f);
282
0
      rgba4444[2 * i + (rg_byte_pos ^ 1)] = (b & 0xf0) | a;
283
0
    }
284
0
    rgba4444 += stride;
285
0
  }
286
0
}
287
#undef MULTIPLIER
288
289
static void ApplyAlphaMultiply_16b_C(uint8_t* rgba4444,
290
0
                                     int w, int h, int stride) {
291
#if (WEBP_SWAP_16BIT_CSP == 1)
292
  ApplyAlphaMultiply4444_C(rgba4444, w, h, stride, 1);
293
#else
294
0
  ApplyAlphaMultiply4444_C(rgba4444, w, h, stride, 0);
295
0
#endif
296
0
}
297
298
#if !WEBP_NEON_OMIT_C_CODE
299
static int DispatchAlpha_C(const uint8_t* WEBP_RESTRICT alpha, int alpha_stride,
300
                           int width, int height,
301
0
                           uint8_t* WEBP_RESTRICT dst, int dst_stride) {
302
0
  uint32_t alpha_mask = 0xff;
303
0
  int i, j;
304
305
0
  for (j = 0; j < height; ++j) {
306
0
    for (i = 0; i < width; ++i) {
307
0
      const uint32_t alpha_value = alpha[i];
308
0
      dst[4 * i] = alpha_value;
309
0
      alpha_mask &= alpha_value;
310
0
    }
311
0
    alpha += alpha_stride;
312
0
    dst += dst_stride;
313
0
  }
314
315
0
  return (alpha_mask != 0xff);
316
0
}
317
318
static void DispatchAlphaToGreen_C(const uint8_t* WEBP_RESTRICT alpha,
319
                                   int alpha_stride, int width, int height,
320
                                   uint32_t* WEBP_RESTRICT dst,
321
0
                                   int dst_stride) {
322
0
  int i, j;
323
0
  for (j = 0; j < height; ++j) {
324
0
    for (i = 0; i < width; ++i) {
325
0
      dst[i] = alpha[i] << 8;  // leave A/R/B channels zero'd.
326
0
    }
327
0
    alpha += alpha_stride;
328
0
    dst += dst_stride;
329
0
  }
330
0
}
331
332
static int ExtractAlpha_C(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
333
                          int width, int height,
334
0
                          uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
335
0
  uint8_t alpha_mask = 0xff;
336
0
  int i, j;
337
338
0
  for (j = 0; j < height; ++j) {
339
0
    for (i = 0; i < width; ++i) {
340
0
      const uint8_t alpha_value = argb[4 * i];
341
0
      alpha[i] = alpha_value;
342
0
      alpha_mask &= alpha_value;
343
0
    }
344
0
    argb += argb_stride;
345
0
    alpha += alpha_stride;
346
0
  }
347
0
  return (alpha_mask == 0xff);
348
0
}
349
350
static void ExtractGreen_C(const uint32_t* WEBP_RESTRICT argb,
351
0
                           uint8_t* WEBP_RESTRICT alpha, int size) {
352
0
  int i;
353
0
  for (i = 0; i < size; ++i) alpha[i] = argb[i] >> 8;
354
0
}
355
#endif  // !WEBP_NEON_OMIT_C_CODE
356
357
//------------------------------------------------------------------------------
358
359
0
static int HasAlpha8b_C(const uint8_t* src, int length) {
360
0
  while (length-- > 0) if (*src++ != 0xff) return 1;
361
0
  return 0;
362
0
}
363
364
0
static int HasAlpha32b_C(const uint8_t* src, int length) {
365
0
  int x;
366
0
  for (x = 0; length-- > 0; x += 4) if (src[x] != 0xff) return 1;
367
0
  return 0;
368
0
}
369
370
0
static void AlphaReplace_C(uint32_t* src, int length, uint32_t color) {
371
0
  int x;
372
0
  for (x = 0; x < length; ++x) if ((src[x] >> 24) == 0) src[x] = color;
373
0
}
374
375
//------------------------------------------------------------------------------
376
// Simple channel manipulations.
377
378
0
static WEBP_INLINE uint32_t MakeARGB32(int a, int r, int g, int b) {
379
0
  return (((uint32_t)a << 24) | (r << 16) | (g << 8) | b);
380
0
}
381
382
#ifdef WORDS_BIGENDIAN
383
static void PackARGB_C(const uint8_t* WEBP_RESTRICT a,
384
                       const uint8_t* WEBP_RESTRICT r,
385
                       const uint8_t* WEBP_RESTRICT g,
386
                       const uint8_t* WEBP_RESTRICT b,
387
                       int len, uint32_t* WEBP_RESTRICT out) {
388
  int i;
389
  for (i = 0; i < len; ++i) {
390
    out[i] = MakeARGB32(a[4 * i], r[4 * i], g[4 * i], b[4 * i]);
391
  }
392
}
393
#endif
394
395
static void PackRGB_C(const uint8_t* WEBP_RESTRICT r,
396
                      const uint8_t* WEBP_RESTRICT g,
397
                      const uint8_t* WEBP_RESTRICT b,
398
0
                      int len, int step, uint32_t* WEBP_RESTRICT out) {
399
0
  int i, offset = 0;
400
0
  for (i = 0; i < len; ++i) {
401
0
    out[i] = MakeARGB32(0xff, r[offset], g[offset], b[offset]);
402
0
    offset += step;
403
0
  }
404
0
}
405
406
void (*WebPApplyAlphaMultiply)(uint8_t*, int, int, int, int);
407
void (*WebPApplyAlphaMultiply4444)(uint8_t*, int, int, int);
408
int (*WebPDispatchAlpha)(const uint8_t* WEBP_RESTRICT, int, int, int,
409
                         uint8_t* WEBP_RESTRICT, int);
410
void (*WebPDispatchAlphaToGreen)(const uint8_t* WEBP_RESTRICT, int, int, int,
411
                                 uint32_t* WEBP_RESTRICT, int);
412
int (*WebPExtractAlpha)(const uint8_t* WEBP_RESTRICT, int, int, int,
413
                        uint8_t* WEBP_RESTRICT, int);
414
void (*WebPExtractGreen)(const uint32_t* WEBP_RESTRICT argb,
415
                         uint8_t* WEBP_RESTRICT alpha, int size);
416
#ifdef WORDS_BIGENDIAN
417
void (*WebPPackARGB)(const uint8_t* a, const uint8_t* r, const uint8_t* g,
418
                     const uint8_t* b, int, uint32_t*);
419
#endif
420
void (*WebPPackRGB)(const uint8_t* WEBP_RESTRICT r,
421
                    const uint8_t* WEBP_RESTRICT g,
422
                    const uint8_t* WEBP_RESTRICT b,
423
                    int len, int step, uint32_t* WEBP_RESTRICT out);
424
425
int (*WebPHasAlpha8b)(const uint8_t* src, int length);
426
int (*WebPHasAlpha32b)(const uint8_t* src, int length);
427
void (*WebPAlphaReplace)(uint32_t* src, int length, uint32_t color);
428
429
//------------------------------------------------------------------------------
430
// Init function
431
432
extern VP8CPUInfo VP8GetCPUInfo;
433
extern void WebPInitAlphaProcessingMIPSdspR2(void);
434
extern void WebPInitAlphaProcessingSSE2(void);
435
extern void WebPInitAlphaProcessingSSE41(void);
436
extern void WebPInitAlphaProcessingNEON(void);
437
438
0
WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) {
439
0
  WebPMultARGBRow = WebPMultARGBRow_C;
440
0
  WebPMultRow = WebPMultRow_C;
441
0
  WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply_16b_C;
442
443
#ifdef WORDS_BIGENDIAN
444
  WebPPackARGB = PackARGB_C;
445
#endif
446
0
  WebPPackRGB = PackRGB_C;
447
0
#if !WEBP_NEON_OMIT_C_CODE
448
0
  WebPApplyAlphaMultiply = ApplyAlphaMultiply_C;
449
0
  WebPDispatchAlpha = DispatchAlpha_C;
450
0
  WebPDispatchAlphaToGreen = DispatchAlphaToGreen_C;
451
0
  WebPExtractAlpha = ExtractAlpha_C;
452
0
  WebPExtractGreen = ExtractGreen_C;
453
0
#endif
454
455
0
  WebPHasAlpha8b = HasAlpha8b_C;
456
0
  WebPHasAlpha32b = HasAlpha32b_C;
457
0
  WebPAlphaReplace = AlphaReplace_C;
458
459
  // If defined, use CPUInfo() to overwrite some pointers with faster versions.
460
0
  if (VP8GetCPUInfo != NULL) {
461
0
#if defined(WEBP_HAVE_SSE2)
462
0
    if (VP8GetCPUInfo(kSSE2)) {
463
0
      WebPInitAlphaProcessingSSE2();
464
0
#if defined(WEBP_HAVE_SSE41)
465
0
      if (VP8GetCPUInfo(kSSE4_1)) {
466
0
        WebPInitAlphaProcessingSSE41();
467
0
      }
468
0
#endif
469
0
    }
470
0
#endif
471
#if defined(WEBP_USE_MIPS_DSP_R2)
472
    if (VP8GetCPUInfo(kMIPSdspR2)) {
473
      WebPInitAlphaProcessingMIPSdspR2();
474
    }
475
#endif
476
0
  }
477
478
#if defined(WEBP_HAVE_NEON)
479
  if (WEBP_NEON_OMIT_C_CODE ||
480
      (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
481
    WebPInitAlphaProcessingNEON();
482
  }
483
#endif
484
485
0
  assert(WebPMultARGBRow != NULL);
486
0
  assert(WebPMultRow != NULL);
487
0
  assert(WebPApplyAlphaMultiply != NULL);
488
0
  assert(WebPApplyAlphaMultiply4444 != NULL);
489
0
  assert(WebPDispatchAlpha != NULL);
490
0
  assert(WebPDispatchAlphaToGreen != NULL);
491
0
  assert(WebPExtractAlpha != NULL);
492
0
  assert(WebPExtractGreen != NULL);
493
#ifdef WORDS_BIGENDIAN
494
  assert(WebPPackARGB != NULL);
495
#endif
496
0
  assert(WebPPackRGB != NULL);
497
0
  assert(WebPHasAlpha8b != NULL);
498
0
  assert(WebPHasAlpha32b != NULL);
499
0
  assert(WebPAlphaReplace != NULL);
500
0
}