Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/libwebp/src/dsp/alpha_processing.c
20852 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 <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
#define MFIX 24 // 24bit fixed-point arithmetic
30
#define HALF ((1u << MFIX) >> 1)
31
#define KINV_255 ((1u << MFIX) / 255u)
32
33
static uint32_t Mult(uint8_t x, uint32_t mult) {
34
const uint32_t v = (x * mult + HALF) >> MFIX;
35
assert(v <= 255); // <- 24bit precision is enough to ensure that.
36
return v;
37
}
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
static WEBP_INLINE uint32_t GetScale(uint32_t a, int inverse) {
139
return inverse ? (255u << MFIX) / a : a * KINV_255;
140
}
141
142
#endif // USE_TABLES_FOR_ALPHA_MULT
143
144
void WebPMultARGBRow_C(uint32_t* const ptr, int width, int inverse) {
145
int x;
146
for (x = 0; x < width; ++x) {
147
const uint32_t argb = ptr[x];
148
if (argb < 0xff000000u) { // alpha < 255
149
if (argb <= 0x00ffffffu) { // alpha == 0
150
ptr[x] = 0;
151
} else {
152
const uint32_t alpha = (argb >> 24) & 0xff;
153
const uint32_t scale = GetScale(alpha, inverse);
154
uint32_t out = argb & 0xff000000u;
155
out |= Mult(argb >> 0, scale) << 0;
156
out |= Mult(argb >> 8, scale) << 8;
157
out |= Mult(argb >> 16, scale) << 16;
158
ptr[x] = out;
159
}
160
}
161
}
162
}
163
164
void WebPMultRow_C(uint8_t* WEBP_RESTRICT const ptr,
165
const uint8_t* WEBP_RESTRICT const alpha,
166
int width, int inverse) {
167
int x;
168
for (x = 0; x < width; ++x) {
169
const uint32_t a = alpha[x];
170
if (a != 255) {
171
if (a == 0) {
172
ptr[x] = 0;
173
} else {
174
const uint32_t scale = GetScale(a, inverse);
175
ptr[x] = Mult(ptr[x], scale);
176
}
177
}
178
}
179
}
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
int inverse) {
195
int n;
196
for (n = 0; n < num_rows; ++n) {
197
WebPMultARGBRow((uint32_t*)ptr, width, inverse);
198
ptr += stride;
199
}
200
}
201
202
void WebPMultRows(uint8_t* WEBP_RESTRICT ptr, int stride,
203
const uint8_t* WEBP_RESTRICT alpha, int alpha_stride,
204
int width, int num_rows, int inverse) {
205
int n;
206
for (n = 0; n < num_rows; ++n) {
207
WebPMultRow(ptr, alpha, width, inverse);
208
ptr += stride;
209
alpha += alpha_stride;
210
}
211
}
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
#define MULTIPLIER(a) ((a) * 32897U)
223
#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
int w, int h, int stride) {
232
while (h-- > 0) {
233
uint8_t* const rgb = rgba + (alpha_first ? 1 : 0);
234
const uint8_t* const alpha = rgba + (alpha_first ? 0 : 3);
235
int i;
236
for (i = 0; i < w; ++i) {
237
const uint32_t a = alpha[4 * i];
238
if (a != 0xff) {
239
const uint32_t mult = MULTIPLIER(a);
240
rgb[4 * i + 0] = PREMULTIPLY(rgb[4 * i + 0], mult);
241
rgb[4 * i + 1] = PREMULTIPLY(rgb[4 * i + 1], mult);
242
rgb[4 * i + 2] = PREMULTIPLY(rgb[4 * i + 2], mult);
243
}
244
}
245
rgba += stride;
246
}
247
}
248
#endif // !WEBP_NEON_OMIT_C_CODE
249
#undef MULTIPLIER
250
#undef PREMULTIPLY
251
252
// rgbA4444
253
254
#define MULTIPLIER(a) ((a) * 0x1111) // 0x1111 ~= (1 << 16) / 15
255
256
static WEBP_INLINE uint8_t dither_hi(uint8_t x) {
257
return (x & 0xf0) | (x >> 4);
258
}
259
260
static WEBP_INLINE uint8_t dither_lo(uint8_t x) {
261
return (x & 0x0f) | (x << 4);
262
}
263
264
static WEBP_INLINE uint8_t multiply(uint8_t x, uint32_t m) {
265
return (x * m) >> 16;
266
}
267
268
static WEBP_INLINE void ApplyAlphaMultiply4444_C(uint8_t* rgba4444,
269
int w, int h, int stride,
270
int rg_byte_pos /* 0 or 1 */) {
271
while (h-- > 0) {
272
int i;
273
for (i = 0; i < w; ++i) {
274
const uint32_t rg = rgba4444[2 * i + rg_byte_pos];
275
const uint32_t ba = rgba4444[2 * i + (rg_byte_pos ^ 1)];
276
const uint8_t a = ba & 0x0f;
277
const uint32_t mult = MULTIPLIER(a);
278
const uint8_t r = multiply(dither_hi(rg), mult);
279
const uint8_t g = multiply(dither_lo(rg), mult);
280
const uint8_t b = multiply(dither_hi(ba), mult);
281
rgba4444[2 * i + rg_byte_pos] = (r & 0xf0) | ((g >> 4) & 0x0f);
282
rgba4444[2 * i + (rg_byte_pos ^ 1)] = (b & 0xf0) | a;
283
}
284
rgba4444 += stride;
285
}
286
}
287
#undef MULTIPLIER
288
289
static void ApplyAlphaMultiply_16b_C(uint8_t* rgba4444,
290
int w, int h, int stride) {
291
#if (WEBP_SWAP_16BIT_CSP == 1)
292
ApplyAlphaMultiply4444_C(rgba4444, w, h, stride, 1);
293
#else
294
ApplyAlphaMultiply4444_C(rgba4444, w, h, stride, 0);
295
#endif
296
}
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
uint8_t* WEBP_RESTRICT dst, int dst_stride) {
302
uint32_t alpha_mask = 0xff;
303
int i, j;
304
305
for (j = 0; j < height; ++j) {
306
for (i = 0; i < width; ++i) {
307
const uint32_t alpha_value = alpha[i];
308
dst[4 * i] = alpha_value;
309
alpha_mask &= alpha_value;
310
}
311
alpha += alpha_stride;
312
dst += dst_stride;
313
}
314
315
return (alpha_mask != 0xff);
316
}
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
int dst_stride) {
322
int i, j;
323
for (j = 0; j < height; ++j) {
324
for (i = 0; i < width; ++i) {
325
dst[i] = alpha[i] << 8; // leave A/R/B channels zero'd.
326
}
327
alpha += alpha_stride;
328
dst += dst_stride;
329
}
330
}
331
332
static int ExtractAlpha_C(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
333
int width, int height,
334
uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
335
uint8_t alpha_mask = 0xff;
336
int i, j;
337
338
for (j = 0; j < height; ++j) {
339
for (i = 0; i < width; ++i) {
340
const uint8_t alpha_value = argb[4 * i];
341
alpha[i] = alpha_value;
342
alpha_mask &= alpha_value;
343
}
344
argb += argb_stride;
345
alpha += alpha_stride;
346
}
347
return (alpha_mask == 0xff);
348
}
349
350
static void ExtractGreen_C(const uint32_t* WEBP_RESTRICT argb,
351
uint8_t* WEBP_RESTRICT alpha, int size) {
352
int i;
353
for (i = 0; i < size; ++i) alpha[i] = argb[i] >> 8;
354
}
355
#endif // !WEBP_NEON_OMIT_C_CODE
356
357
//------------------------------------------------------------------------------
358
359
static int HasAlpha8b_C(const uint8_t* src, int length) {
360
while (length-- > 0) if (*src++ != 0xff) return 1;
361
return 0;
362
}
363
364
static int HasAlpha32b_C(const uint8_t* src, int length) {
365
int x;
366
for (x = 0; length-- > 0; x += 4) if (src[x] != 0xff) return 1;
367
return 0;
368
}
369
370
static void AlphaReplace_C(uint32_t* src, int length, uint32_t color) {
371
int x;
372
for (x = 0; x < length; ++x) if ((src[x] >> 24) == 0) src[x] = color;
373
}
374
375
//------------------------------------------------------------------------------
376
// Simple channel manipulations.
377
378
static WEBP_INLINE uint32_t MakeARGB32(int a, int r, int g, int b) {
379
return (((uint32_t)a << 24) | (r << 16) | (g << 8) | b);
380
}
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
int len, int step, uint32_t* WEBP_RESTRICT out) {
399
int i, offset = 0;
400
for (i = 0; i < len; ++i) {
401
out[i] = MakeARGB32(0xff, r[offset], g[offset], b[offset]);
402
offset += step;
403
}
404
}
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
WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) {
439
WebPMultARGBRow = WebPMultARGBRow_C;
440
WebPMultRow = WebPMultRow_C;
441
WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply_16b_C;
442
443
#ifdef WORDS_BIGENDIAN
444
WebPPackARGB = PackARGB_C;
445
#endif
446
WebPPackRGB = PackRGB_C;
447
#if !WEBP_NEON_OMIT_C_CODE
448
WebPApplyAlphaMultiply = ApplyAlphaMultiply_C;
449
WebPDispatchAlpha = DispatchAlpha_C;
450
WebPDispatchAlphaToGreen = DispatchAlphaToGreen_C;
451
WebPExtractAlpha = ExtractAlpha_C;
452
WebPExtractGreen = ExtractGreen_C;
453
#endif
454
455
WebPHasAlpha8b = HasAlpha8b_C;
456
WebPHasAlpha32b = HasAlpha32b_C;
457
WebPAlphaReplace = AlphaReplace_C;
458
459
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
460
if (VP8GetCPUInfo != NULL) {
461
#if defined(WEBP_HAVE_SSE2)
462
if (VP8GetCPUInfo(kSSE2)) {
463
WebPInitAlphaProcessingSSE2();
464
#if defined(WEBP_HAVE_SSE41)
465
if (VP8GetCPUInfo(kSSE4_1)) {
466
WebPInitAlphaProcessingSSE41();
467
}
468
#endif
469
}
470
#endif
471
#if defined(WEBP_USE_MIPS_DSP_R2)
472
if (VP8GetCPUInfo(kMIPSdspR2)) {
473
WebPInitAlphaProcessingMIPSdspR2();
474
}
475
#endif
476
}
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
assert(WebPMultARGBRow != NULL);
486
assert(WebPMultRow != NULL);
487
assert(WebPApplyAlphaMultiply != NULL);
488
assert(WebPApplyAlphaMultiply4444 != NULL);
489
assert(WebPDispatchAlpha != NULL);
490
assert(WebPDispatchAlphaToGreen != NULL);
491
assert(WebPExtractAlpha != NULL);
492
assert(WebPExtractGreen != NULL);
493
#ifdef WORDS_BIGENDIAN
494
assert(WebPPackARGB != NULL);
495
#endif
496
assert(WebPPackRGB != NULL);
497
assert(WebPHasAlpha8b != NULL);
498
assert(WebPHasAlpha32b != NULL);
499
assert(WebPAlphaReplace != NULL);
500
}
501
502