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