~paparazzi-uav/paparazzi/v5.0-manual

« back to all changes in this revision

Viewing changes to sw/ext/opencv_bebop/opencv/3rdparty/libwebp/dsp/dec.c

  • Committer: Paparazzi buildbot
  • Date: 2016-05-18 15:00:29 UTC
  • Revision ID: felix.ruess+docbot@gmail.com-20160518150029-e8lgzi5kvb4p7un9
Manual import commit 4b8bbb730080dac23cf816b98908dacfabe2a8ec from v5.0 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2010 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
// Speed-critical decoding functions.
 
11
//
 
12
// Author: Skal (pascal.massimino@gmail.com)
 
13
 
 
14
#include "./dsp.h"
 
15
#include "../dec/vp8i.h"
 
16
 
 
17
#if defined(__cplusplus) || defined(c_plusplus)
 
18
extern "C" {
 
19
#endif
 
20
 
 
21
//------------------------------------------------------------------------------
 
22
// run-time tables (~4k)
 
23
 
 
24
static uint8_t abs0[255 + 255 + 1];     // abs(i)
 
25
static uint8_t abs1[255 + 255 + 1];     // abs(i)>>1
 
26
static int8_t sclip1[1020 + 1020 + 1];  // clips [-1020, 1020] to [-128, 127]
 
27
static int8_t sclip2[112 + 112 + 1];    // clips [-112, 112] to [-16, 15]
 
28
static uint8_t clip1[255 + 510 + 1];    // clips [-255,510] to [0,255]
 
29
 
 
30
// We declare this variable 'volatile' to prevent instruction reordering
 
31
// and make sure it's set to true _last_ (so as to be thread-safe)
 
32
static volatile int tables_ok = 0;
 
33
 
 
34
static void DspInitTables(void) {
 
35
  if (!tables_ok) {
 
36
    int i;
 
37
    for (i = -255; i <= 255; ++i) {
 
38
      abs0[255 + i] = (i < 0) ? -i : i;
 
39
      abs1[255 + i] = abs0[255 + i] >> 1;
 
40
    }
 
41
    for (i = -1020; i <= 1020; ++i) {
 
42
      sclip1[1020 + i] = (i < -128) ? -128 : (i > 127) ? 127 : i;
 
43
    }
 
44
    for (i = -112; i <= 112; ++i) {
 
45
      sclip2[112 + i] = (i < -16) ? -16 : (i > 15) ? 15 : i;
 
46
    }
 
47
    for (i = -255; i <= 255 + 255; ++i) {
 
48
      clip1[255 + i] = (i < 0) ? 0 : (i > 255) ? 255 : i;
 
49
    }
 
50
    tables_ok = 1;
 
51
  }
 
52
}
 
53
 
 
54
static WEBP_INLINE uint8_t clip_8b(int v) {
 
55
  return (!(v & ~0xff)) ? v : (v < 0) ? 0 : 255;
 
56
}
 
57
 
 
58
//------------------------------------------------------------------------------
 
59
// Transforms (Paragraph 14.4)
 
60
 
 
61
#define STORE(x, y, v) \
 
62
  dst[x + y * BPS] = clip_8b(dst[x + y * BPS] + ((v) >> 3))
 
63
 
 
64
static const int kC1 = 20091 + (1 << 16);
 
65
static const int kC2 = 35468;
 
66
#define MUL(a, b) (((a) * (b)) >> 16)
 
67
 
 
68
static void TransformOne(const int16_t* in, uint8_t* dst) {
 
69
  int C[4 * 4], *tmp;
 
70
  int i;
 
71
  tmp = C;
 
72
  for (i = 0; i < 4; ++i) {    // vertical pass
 
73
    const int a = in[0] + in[8];    // [-4096, 4094]
 
74
    const int b = in[0] - in[8];    // [-4095, 4095]
 
75
    const int c = MUL(in[4], kC2) - MUL(in[12], kC1);   // [-3783, 3783]
 
76
    const int d = MUL(in[4], kC1) + MUL(in[12], kC2);   // [-3785, 3781]
 
77
    tmp[0] = a + d;   // [-7881, 7875]
 
78
    tmp[1] = b + c;   // [-7878, 7878]
 
79
    tmp[2] = b - c;   // [-7878, 7878]
 
80
    tmp[3] = a - d;   // [-7877, 7879]
 
81
    tmp += 4;
 
82
    in++;
 
83
  }
 
84
  // Each pass is expanding the dynamic range by ~3.85 (upper bound).
 
85
  // The exact value is (2. + (kC1 + kC2) / 65536).
 
86
  // After the second pass, maximum interval is [-3794, 3794], assuming
 
87
  // an input in [-2048, 2047] interval. We then need to add a dst value
 
88
  // in the [0, 255] range.
 
89
  // In the worst case scenario, the input to clip_8b() can be as large as
 
90
  // [-60713, 60968].
 
91
  tmp = C;
 
92
  for (i = 0; i < 4; ++i) {    // horizontal pass
 
93
    const int dc = tmp[0] + 4;
 
94
    const int a =  dc +  tmp[8];
 
95
    const int b =  dc -  tmp[8];
 
96
    const int c = MUL(tmp[4], kC2) - MUL(tmp[12], kC1);
 
97
    const int d = MUL(tmp[4], kC1) + MUL(tmp[12], kC2);
 
98
    STORE(0, 0, a + d);
 
99
    STORE(1, 0, b + c);
 
100
    STORE(2, 0, b - c);
 
101
    STORE(3, 0, a - d);
 
102
    tmp++;
 
103
    dst += BPS;
 
104
  }
 
105
}
 
106
#undef MUL
 
107
 
 
108
static void TransformTwo(const int16_t* in, uint8_t* dst, int do_two) {
 
109
  TransformOne(in, dst);
 
110
  if (do_two) {
 
111
    TransformOne(in + 16, dst + 4);
 
112
  }
 
113
}
 
114
 
 
115
static void TransformUV(const int16_t* in, uint8_t* dst) {
 
116
  VP8Transform(in + 0 * 16, dst, 1);
 
117
  VP8Transform(in + 2 * 16, dst + 4 * BPS, 1);
 
118
}
 
119
 
 
120
static void TransformDC(const int16_t *in, uint8_t* dst) {
 
121
  const int DC = in[0] + 4;
 
122
  int i, j;
 
123
  for (j = 0; j < 4; ++j) {
 
124
    for (i = 0; i < 4; ++i) {
 
125
      STORE(i, j, DC);
 
126
    }
 
127
  }
 
128
}
 
129
 
 
130
static void TransformDCUV(const int16_t* in, uint8_t* dst) {
 
131
  if (in[0 * 16]) TransformDC(in + 0 * 16, dst);
 
132
  if (in[1 * 16]) TransformDC(in + 1 * 16, dst + 4);
 
133
  if (in[2 * 16]) TransformDC(in + 2 * 16, dst + 4 * BPS);
 
134
  if (in[3 * 16]) TransformDC(in + 3 * 16, dst + 4 * BPS + 4);
 
135
}
 
136
 
 
137
#undef STORE
 
138
 
 
139
//------------------------------------------------------------------------------
 
140
// Paragraph 14.3
 
141
 
 
142
static void TransformWHT(const int16_t* in, int16_t* out) {
 
143
  int tmp[16];
 
144
  int i;
 
145
  for (i = 0; i < 4; ++i) {
 
146
    const int a0 = in[0 + i] + in[12 + i];
 
147
    const int a1 = in[4 + i] + in[ 8 + i];
 
148
    const int a2 = in[4 + i] - in[ 8 + i];
 
149
    const int a3 = in[0 + i] - in[12 + i];
 
150
    tmp[0  + i] = a0 + a1;
 
151
    tmp[8  + i] = a0 - a1;
 
152
    tmp[4  + i] = a3 + a2;
 
153
    tmp[12 + i] = a3 - a2;
 
154
  }
 
155
  for (i = 0; i < 4; ++i) {
 
156
    const int dc = tmp[0 + i * 4] + 3;    // w/ rounder
 
157
    const int a0 = dc             + tmp[3 + i * 4];
 
158
    const int a1 = tmp[1 + i * 4] + tmp[2 + i * 4];
 
159
    const int a2 = tmp[1 + i * 4] - tmp[2 + i * 4];
 
160
    const int a3 = dc             - tmp[3 + i * 4];
 
161
    out[ 0] = (a0 + a1) >> 3;
 
162
    out[16] = (a3 + a2) >> 3;
 
163
    out[32] = (a0 - a1) >> 3;
 
164
    out[48] = (a3 - a2) >> 3;
 
165
    out += 64;
 
166
  }
 
167
}
 
168
 
 
169
void (*VP8TransformWHT)(const int16_t* in, int16_t* out) = TransformWHT;
 
170
 
 
171
//------------------------------------------------------------------------------
 
172
// Intra predictions
 
173
 
 
174
#define DST(x, y) dst[(x) + (y) * BPS]
 
175
 
 
176
static WEBP_INLINE void TrueMotion(uint8_t *dst, int size) {
 
177
  const uint8_t* top = dst - BPS;
 
178
  const uint8_t* const clip0 = clip1 + 255 - top[-1];
 
179
  int y;
 
180
  for (y = 0; y < size; ++y) {
 
181
    const uint8_t* const clip = clip0 + dst[-1];
 
182
    int x;
 
183
    for (x = 0; x < size; ++x) {
 
184
      dst[x] = clip[top[x]];
 
185
    }
 
186
    dst += BPS;
 
187
  }
 
188
}
 
189
static void TM4(uint8_t *dst)   { TrueMotion(dst, 4); }
 
190
static void TM8uv(uint8_t *dst) { TrueMotion(dst, 8); }
 
191
static void TM16(uint8_t *dst)  { TrueMotion(dst, 16); }
 
192
 
 
193
//------------------------------------------------------------------------------
 
194
// 16x16
 
195
 
 
196
static void VE16(uint8_t *dst) {     // vertical
 
197
  int j;
 
198
  for (j = 0; j < 16; ++j) {
 
199
    memcpy(dst + j * BPS, dst - BPS, 16);
 
200
  }
 
201
}
 
202
 
 
203
static void HE16(uint8_t *dst) {     // horizontal
 
204
  int j;
 
205
  for (j = 16; j > 0; --j) {
 
206
    memset(dst, dst[-1], 16);
 
207
    dst += BPS;
 
208
  }
 
209
}
 
210
 
 
211
static WEBP_INLINE void Put16(int v, uint8_t* dst) {
 
212
  int j;
 
213
  for (j = 0; j < 16; ++j) {
 
214
    memset(dst + j * BPS, v, 16);
 
215
  }
 
216
}
 
217
 
 
218
static void DC16(uint8_t *dst) {    // DC
 
219
  int DC = 16;
 
220
  int j;
 
221
  for (j = 0; j < 16; ++j) {
 
222
    DC += dst[-1 + j * BPS] + dst[j - BPS];
 
223
  }
 
224
  Put16(DC >> 5, dst);
 
225
}
 
226
 
 
227
static void DC16NoTop(uint8_t *dst) {   // DC with top samples not available
 
228
  int DC = 8;
 
229
  int j;
 
230
  for (j = 0; j < 16; ++j) {
 
231
    DC += dst[-1 + j * BPS];
 
232
  }
 
233
  Put16(DC >> 4, dst);
 
234
}
 
235
 
 
236
static void DC16NoLeft(uint8_t *dst) {  // DC with left samples not available
 
237
  int DC = 8;
 
238
  int i;
 
239
  for (i = 0; i < 16; ++i) {
 
240
    DC += dst[i - BPS];
 
241
  }
 
242
  Put16(DC >> 4, dst);
 
243
}
 
244
 
 
245
static void DC16NoTopLeft(uint8_t *dst) {  // DC with no top and left samples
 
246
  Put16(0x80, dst);
 
247
}
 
248
 
 
249
//------------------------------------------------------------------------------
 
250
// 4x4
 
251
 
 
252
#define AVG3(a, b, c) (((a) + 2 * (b) + (c) + 2) >> 2)
 
253
#define AVG2(a, b) (((a) + (b) + 1) >> 1)
 
254
 
 
255
static void VE4(uint8_t *dst) {    // vertical
 
256
  const uint8_t* top = dst - BPS;
 
257
  const uint8_t vals[4] = {
 
258
    AVG3(top[-1], top[0], top[1]),
 
259
    AVG3(top[ 0], top[1], top[2]),
 
260
    AVG3(top[ 1], top[2], top[3]),
 
261
    AVG3(top[ 2], top[3], top[4])
 
262
  };
 
263
  int i;
 
264
  for (i = 0; i < 4; ++i) {
 
265
    memcpy(dst + i * BPS, vals, sizeof(vals));
 
266
  }
 
267
}
 
268
 
 
269
static void HE4(uint8_t *dst) {    // horizontal
 
270
  const int A = dst[-1 - BPS];
 
271
  const int B = dst[-1];
 
272
  const int C = dst[-1 + BPS];
 
273
  const int D = dst[-1 + 2 * BPS];
 
274
  const int E = dst[-1 + 3 * BPS];
 
275
  *(uint32_t*)(dst + 0 * BPS) = 0x01010101U * AVG3(A, B, C);
 
276
  *(uint32_t*)(dst + 1 * BPS) = 0x01010101U * AVG3(B, C, D);
 
277
  *(uint32_t*)(dst + 2 * BPS) = 0x01010101U * AVG3(C, D, E);
 
278
  *(uint32_t*)(dst + 3 * BPS) = 0x01010101U * AVG3(D, E, E);
 
279
}
 
280
 
 
281
static void DC4(uint8_t *dst) {   // DC
 
282
  uint32_t dc = 4;
 
283
  int i;
 
284
  for (i = 0; i < 4; ++i) dc += dst[i - BPS] + dst[-1 + i * BPS];
 
285
  dc >>= 3;
 
286
  for (i = 0; i < 4; ++i) memset(dst + i * BPS, dc, 4);
 
287
}
 
288
 
 
289
static void RD4(uint8_t *dst) {   // Down-right
 
290
  const int I = dst[-1 + 0 * BPS];
 
291
  const int J = dst[-1 + 1 * BPS];
 
292
  const int K = dst[-1 + 2 * BPS];
 
293
  const int L = dst[-1 + 3 * BPS];
 
294
  const int X = dst[-1 - BPS];
 
295
  const int A = dst[0 - BPS];
 
296
  const int B = dst[1 - BPS];
 
297
  const int C = dst[2 - BPS];
 
298
  const int D = dst[3 - BPS];
 
299
  DST(0, 3)                                     = AVG3(J, K, L);
 
300
  DST(0, 2) = DST(1, 3)                         = AVG3(I, J, K);
 
301
  DST(0, 1) = DST(1, 2) = DST(2, 3)             = AVG3(X, I, J);
 
302
  DST(0, 0) = DST(1, 1) = DST(2, 2) = DST(3, 3) = AVG3(A, X, I);
 
303
  DST(1, 0) = DST(2, 1) = DST(3, 2)             = AVG3(B, A, X);
 
304
  DST(2, 0) = DST(3, 1)                         = AVG3(C, B, A);
 
305
  DST(3, 0)                                     = AVG3(D, C, B);
 
306
}
 
307
 
 
308
static void LD4(uint8_t *dst) {   // Down-Left
 
309
  const int A = dst[0 - BPS];
 
310
  const int B = dst[1 - BPS];
 
311
  const int C = dst[2 - BPS];
 
312
  const int D = dst[3 - BPS];
 
313
  const int E = dst[4 - BPS];
 
314
  const int F = dst[5 - BPS];
 
315
  const int G = dst[6 - BPS];
 
316
  const int H = dst[7 - BPS];
 
317
  DST(0, 0)                                     = AVG3(A, B, C);
 
318
  DST(1, 0) = DST(0, 1)                         = AVG3(B, C, D);
 
319
  DST(2, 0) = DST(1, 1) = DST(0, 2)             = AVG3(C, D, E);
 
320
  DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F);
 
321
  DST(3, 1) = DST(2, 2) = DST(1, 3)             = AVG3(E, F, G);
 
322
  DST(3, 2) = DST(2, 3)                         = AVG3(F, G, H);
 
323
  DST(3, 3)                                     = AVG3(G, H, H);
 
324
}
 
325
 
 
326
static void VR4(uint8_t *dst) {   // Vertical-Right
 
327
  const int I = dst[-1 + 0 * BPS];
 
328
  const int J = dst[-1 + 1 * BPS];
 
329
  const int K = dst[-1 + 2 * BPS];
 
330
  const int X = dst[-1 - BPS];
 
331
  const int A = dst[0 - BPS];
 
332
  const int B = dst[1 - BPS];
 
333
  const int C = dst[2 - BPS];
 
334
  const int D = dst[3 - BPS];
 
335
  DST(0, 0) = DST(1, 2) = AVG2(X, A);
 
336
  DST(1, 0) = DST(2, 2) = AVG2(A, B);
 
337
  DST(2, 0) = DST(3, 2) = AVG2(B, C);
 
338
  DST(3, 0)             = AVG2(C, D);
 
339
 
 
340
  DST(0, 3) =             AVG3(K, J, I);
 
341
  DST(0, 2) =             AVG3(J, I, X);
 
342
  DST(0, 1) = DST(1, 3) = AVG3(I, X, A);
 
343
  DST(1, 1) = DST(2, 3) = AVG3(X, A, B);
 
344
  DST(2, 1) = DST(3, 3) = AVG3(A, B, C);
 
345
  DST(3, 1) =             AVG3(B, C, D);
 
346
}
 
347
 
 
348
static void VL4(uint8_t *dst) {   // Vertical-Left
 
349
  const int A = dst[0 - BPS];
 
350
  const int B = dst[1 - BPS];
 
351
  const int C = dst[2 - BPS];
 
352
  const int D = dst[3 - BPS];
 
353
  const int E = dst[4 - BPS];
 
354
  const int F = dst[5 - BPS];
 
355
  const int G = dst[6 - BPS];
 
356
  const int H = dst[7 - BPS];
 
357
  DST(0, 0) =             AVG2(A, B);
 
358
  DST(1, 0) = DST(0, 2) = AVG2(B, C);
 
359
  DST(2, 0) = DST(1, 2) = AVG2(C, D);
 
360
  DST(3, 0) = DST(2, 2) = AVG2(D, E);
 
361
 
 
362
  DST(0, 1) =             AVG3(A, B, C);
 
363
  DST(1, 1) = DST(0, 3) = AVG3(B, C, D);
 
364
  DST(2, 1) = DST(1, 3) = AVG3(C, D, E);
 
365
  DST(3, 1) = DST(2, 3) = AVG3(D, E, F);
 
366
              DST(3, 2) = AVG3(E, F, G);
 
367
              DST(3, 3) = AVG3(F, G, H);
 
368
}
 
369
 
 
370
static void HU4(uint8_t *dst) {   // Horizontal-Up
 
371
  const int I = dst[-1 + 0 * BPS];
 
372
  const int J = dst[-1 + 1 * BPS];
 
373
  const int K = dst[-1 + 2 * BPS];
 
374
  const int L = dst[-1 + 3 * BPS];
 
375
  DST(0, 0) =             AVG2(I, J);
 
376
  DST(2, 0) = DST(0, 1) = AVG2(J, K);
 
377
  DST(2, 1) = DST(0, 2) = AVG2(K, L);
 
378
  DST(1, 0) =             AVG3(I, J, K);
 
379
  DST(3, 0) = DST(1, 1) = AVG3(J, K, L);
 
380
  DST(3, 1) = DST(1, 2) = AVG3(K, L, L);
 
381
  DST(3, 2) = DST(2, 2) =
 
382
    DST(0, 3) = DST(1, 3) = DST(2, 3) = DST(3, 3) = L;
 
383
}
 
384
 
 
385
static void HD4(uint8_t *dst) {  // Horizontal-Down
 
386
  const int I = dst[-1 + 0 * BPS];
 
387
  const int J = dst[-1 + 1 * BPS];
 
388
  const int K = dst[-1 + 2 * BPS];
 
389
  const int L = dst[-1 + 3 * BPS];
 
390
  const int X = dst[-1 - BPS];
 
391
  const int A = dst[0 - BPS];
 
392
  const int B = dst[1 - BPS];
 
393
  const int C = dst[2 - BPS];
 
394
 
 
395
  DST(0, 0) = DST(2, 1) = AVG2(I, X);
 
396
  DST(0, 1) = DST(2, 2) = AVG2(J, I);
 
397
  DST(0, 2) = DST(2, 3) = AVG2(K, J);
 
398
  DST(0, 3)             = AVG2(L, K);
 
399
 
 
400
  DST(3, 0)             = AVG3(A, B, C);
 
401
  DST(2, 0)             = AVG3(X, A, B);
 
402
  DST(1, 0) = DST(3, 1) = AVG3(I, X, A);
 
403
  DST(1, 1) = DST(3, 2) = AVG3(J, I, X);
 
404
  DST(1, 2) = DST(3, 3) = AVG3(K, J, I);
 
405
  DST(1, 3)             = AVG3(L, K, J);
 
406
}
 
407
 
 
408
#undef DST
 
409
#undef AVG3
 
410
#undef AVG2
 
411
 
 
412
//------------------------------------------------------------------------------
 
413
// Chroma
 
414
 
 
415
static void VE8uv(uint8_t *dst) {    // vertical
 
416
  int j;
 
417
  for (j = 0; j < 8; ++j) {
 
418
    memcpy(dst + j * BPS, dst - BPS, 8);
 
419
  }
 
420
}
 
421
 
 
422
static void HE8uv(uint8_t *dst) {    // horizontal
 
423
  int j;
 
424
  for (j = 0; j < 8; ++j) {
 
425
    memset(dst, dst[-1], 8);
 
426
    dst += BPS;
 
427
  }
 
428
}
 
429
 
 
430
// helper for chroma-DC predictions
 
431
static WEBP_INLINE void Put8x8uv(uint8_t value, uint8_t* dst) {
 
432
  int j;
 
433
#ifndef WEBP_REFERENCE_IMPLEMENTATION
 
434
  const uint64_t v = (uint64_t)value * 0x0101010101010101ULL;
 
435
  for (j = 0; j < 8; ++j) {
 
436
    *(uint64_t*)(dst + j * BPS) = v;
 
437
  }
 
438
#else
 
439
  for (j = 0; j < 8; ++j) memset(dst + j * BPS, value, 8);
 
440
#endif
 
441
}
 
442
 
 
443
static void DC8uv(uint8_t *dst) {     // DC
 
444
  int dc0 = 8;
 
445
  int i;
 
446
  for (i = 0; i < 8; ++i) {
 
447
    dc0 += dst[i - BPS] + dst[-1 + i * BPS];
 
448
  }
 
449
  Put8x8uv(dc0 >> 4, dst);
 
450
}
 
451
 
 
452
static void DC8uvNoLeft(uint8_t *dst) {   // DC with no left samples
 
453
  int dc0 = 4;
 
454
  int i;
 
455
  for (i = 0; i < 8; ++i) {
 
456
    dc0 += dst[i - BPS];
 
457
  }
 
458
  Put8x8uv(dc0 >> 3, dst);
 
459
}
 
460
 
 
461
static void DC8uvNoTop(uint8_t *dst) {  // DC with no top samples
 
462
  int dc0 = 4;
 
463
  int i;
 
464
  for (i = 0; i < 8; ++i) {
 
465
    dc0 += dst[-1 + i * BPS];
 
466
  }
 
467
  Put8x8uv(dc0 >> 3, dst);
 
468
}
 
469
 
 
470
static void DC8uvNoTopLeft(uint8_t *dst) {    // DC with nothing
 
471
  Put8x8uv(0x80, dst);
 
472
}
 
473
 
 
474
//------------------------------------------------------------------------------
 
475
// default C implementations
 
476
 
 
477
const VP8PredFunc VP8PredLuma4[NUM_BMODES] = {
 
478
  DC4, TM4, VE4, HE4, RD4, VR4, LD4, VL4, HD4, HU4
 
479
};
 
480
 
 
481
const VP8PredFunc VP8PredLuma16[NUM_B_DC_MODES] = {
 
482
  DC16, TM16, VE16, HE16,
 
483
  DC16NoTop, DC16NoLeft, DC16NoTopLeft
 
484
};
 
485
 
 
486
const VP8PredFunc VP8PredChroma8[NUM_B_DC_MODES] = {
 
487
  DC8uv, TM8uv, VE8uv, HE8uv,
 
488
  DC8uvNoTop, DC8uvNoLeft, DC8uvNoTopLeft
 
489
};
 
490
 
 
491
//------------------------------------------------------------------------------
 
492
// Edge filtering functions
 
493
 
 
494
// 4 pixels in, 2 pixels out
 
495
static WEBP_INLINE void do_filter2(uint8_t* p, int step) {
 
496
  const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
 
497
  const int a = 3 * (q0 - p0) + sclip1[1020 + p1 - q1];
 
498
  const int a1 = sclip2[112 + ((a + 4) >> 3)];
 
499
  const int a2 = sclip2[112 + ((a + 3) >> 3)];
 
500
  p[-step] = clip1[255 + p0 + a2];
 
501
  p[    0] = clip1[255 + q0 - a1];
 
502
}
 
503
 
 
504
// 4 pixels in, 4 pixels out
 
505
static WEBP_INLINE void do_filter4(uint8_t* p, int step) {
 
506
  const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
 
507
  const int a = 3 * (q0 - p0);
 
508
  const int a1 = sclip2[112 + ((a + 4) >> 3)];
 
509
  const int a2 = sclip2[112 + ((a + 3) >> 3)];
 
510
  const int a3 = (a1 + 1) >> 1;
 
511
  p[-2*step] = clip1[255 + p1 + a3];
 
512
  p[-  step] = clip1[255 + p0 + a2];
 
513
  p[      0] = clip1[255 + q0 - a1];
 
514
  p[   step] = clip1[255 + q1 - a3];
 
515
}
 
516
 
 
517
// 6 pixels in, 6 pixels out
 
518
static WEBP_INLINE void do_filter6(uint8_t* p, int step) {
 
519
  const int p2 = p[-3*step], p1 = p[-2*step], p0 = p[-step];
 
520
  const int q0 = p[0], q1 = p[step], q2 = p[2*step];
 
521
  const int a = sclip1[1020 + 3 * (q0 - p0) + sclip1[1020 + p1 - q1]];
 
522
  const int a1 = (27 * a + 63) >> 7;  // eq. to ((3 * a + 7) * 9) >> 7
 
523
  const int a2 = (18 * a + 63) >> 7;  // eq. to ((2 * a + 7) * 9) >> 7
 
524
  const int a3 = (9  * a + 63) >> 7;  // eq. to ((1 * a + 7) * 9) >> 7
 
525
  p[-3*step] = clip1[255 + p2 + a3];
 
526
  p[-2*step] = clip1[255 + p1 + a2];
 
527
  p[-  step] = clip1[255 + p0 + a1];
 
528
  p[      0] = clip1[255 + q0 - a1];
 
529
  p[   step] = clip1[255 + q1 - a2];
 
530
  p[ 2*step] = clip1[255 + q2 - a3];
 
531
}
 
532
 
 
533
static WEBP_INLINE int hev(const uint8_t* p, int step, int thresh) {
 
534
  const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
 
535
  return (abs0[255 + p1 - p0] > thresh) || (abs0[255 + q1 - q0] > thresh);
 
536
}
 
537
 
 
538
static WEBP_INLINE int needs_filter(const uint8_t* p, int step, int thresh) {
 
539
  const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
 
540
  return (2 * abs0[255 + p0 - q0] + abs1[255 + p1 - q1]) <= thresh;
 
541
}
 
542
 
 
543
static WEBP_INLINE int needs_filter2(const uint8_t* p,
 
544
                                     int step, int t, int it) {
 
545
  const int p3 = p[-4*step], p2 = p[-3*step], p1 = p[-2*step], p0 = p[-step];
 
546
  const int q0 = p[0], q1 = p[step], q2 = p[2*step], q3 = p[3*step];
 
547
  if ((2 * abs0[255 + p0 - q0] + abs1[255 + p1 - q1]) > t)
 
548
    return 0;
 
549
  return abs0[255 + p3 - p2] <= it && abs0[255 + p2 - p1] <= it &&
 
550
         abs0[255 + p1 - p0] <= it && abs0[255 + q3 - q2] <= it &&
 
551
         abs0[255 + q2 - q1] <= it && abs0[255 + q1 - q0] <= it;
 
552
}
 
553
 
 
554
//------------------------------------------------------------------------------
 
555
// Simple In-loop filtering (Paragraph 15.2)
 
556
 
 
557
static void SimpleVFilter16(uint8_t* p, int stride, int thresh) {
 
558
  int i;
 
559
  for (i = 0; i < 16; ++i) {
 
560
    if (needs_filter(p + i, stride, thresh)) {
 
561
      do_filter2(p + i, stride);
 
562
    }
 
563
  }
 
564
}
 
565
 
 
566
static void SimpleHFilter16(uint8_t* p, int stride, int thresh) {
 
567
  int i;
 
568
  for (i = 0; i < 16; ++i) {
 
569
    if (needs_filter(p + i * stride, 1, thresh)) {
 
570
      do_filter2(p + i * stride, 1);
 
571
    }
 
572
  }
 
573
}
 
574
 
 
575
static void SimpleVFilter16i(uint8_t* p, int stride, int thresh) {
 
576
  int k;
 
577
  for (k = 3; k > 0; --k) {
 
578
    p += 4 * stride;
 
579
    SimpleVFilter16(p, stride, thresh);
 
580
  }
 
581
}
 
582
 
 
583
static void SimpleHFilter16i(uint8_t* p, int stride, int thresh) {
 
584
  int k;
 
585
  for (k = 3; k > 0; --k) {
 
586
    p += 4;
 
587
    SimpleHFilter16(p, stride, thresh);
 
588
  }
 
589
}
 
590
 
 
591
//------------------------------------------------------------------------------
 
592
// Complex In-loop filtering (Paragraph 15.3)
 
593
 
 
594
static WEBP_INLINE void FilterLoop26(uint8_t* p,
 
595
                                     int hstride, int vstride, int size,
 
596
                                     int thresh, int ithresh, int hev_thresh) {
 
597
  while (size-- > 0) {
 
598
    if (needs_filter2(p, hstride, thresh, ithresh)) {
 
599
      if (hev(p, hstride, hev_thresh)) {
 
600
        do_filter2(p, hstride);
 
601
      } else {
 
602
        do_filter6(p, hstride);
 
603
      }
 
604
    }
 
605
    p += vstride;
 
606
  }
 
607
}
 
608
 
 
609
static WEBP_INLINE void FilterLoop24(uint8_t* p,
 
610
                                     int hstride, int vstride, int size,
 
611
                                     int thresh, int ithresh, int hev_thresh) {
 
612
  while (size-- > 0) {
 
613
    if (needs_filter2(p, hstride, thresh, ithresh)) {
 
614
      if (hev(p, hstride, hev_thresh)) {
 
615
        do_filter2(p, hstride);
 
616
      } else {
 
617
        do_filter4(p, hstride);
 
618
      }
 
619
    }
 
620
    p += vstride;
 
621
  }
 
622
}
 
623
 
 
624
// on macroblock edges
 
625
static void VFilter16(uint8_t* p, int stride,
 
626
                      int thresh, int ithresh, int hev_thresh) {
 
627
  FilterLoop26(p, stride, 1, 16, thresh, ithresh, hev_thresh);
 
628
}
 
629
 
 
630
static void HFilter16(uint8_t* p, int stride,
 
631
                      int thresh, int ithresh, int hev_thresh) {
 
632
  FilterLoop26(p, 1, stride, 16, thresh, ithresh, hev_thresh);
 
633
}
 
634
 
 
635
// on three inner edges
 
636
static void VFilter16i(uint8_t* p, int stride,
 
637
                       int thresh, int ithresh, int hev_thresh) {
 
638
  int k;
 
639
  for (k = 3; k > 0; --k) {
 
640
    p += 4 * stride;
 
641
    FilterLoop24(p, stride, 1, 16, thresh, ithresh, hev_thresh);
 
642
  }
 
643
}
 
644
 
 
645
static void HFilter16i(uint8_t* p, int stride,
 
646
                       int thresh, int ithresh, int hev_thresh) {
 
647
  int k;
 
648
  for (k = 3; k > 0; --k) {
 
649
    p += 4;
 
650
    FilterLoop24(p, 1, stride, 16, thresh, ithresh, hev_thresh);
 
651
  }
 
652
}
 
653
 
 
654
// 8-pixels wide variant, for chroma filtering
 
655
static void VFilter8(uint8_t* u, uint8_t* v, int stride,
 
656
                     int thresh, int ithresh, int hev_thresh) {
 
657
  FilterLoop26(u, stride, 1, 8, thresh, ithresh, hev_thresh);
 
658
  FilterLoop26(v, stride, 1, 8, thresh, ithresh, hev_thresh);
 
659
}
 
660
 
 
661
static void HFilter8(uint8_t* u, uint8_t* v, int stride,
 
662
                     int thresh, int ithresh, int hev_thresh) {
 
663
  FilterLoop26(u, 1, stride, 8, thresh, ithresh, hev_thresh);
 
664
  FilterLoop26(v, 1, stride, 8, thresh, ithresh, hev_thresh);
 
665
}
 
666
 
 
667
static void VFilter8i(uint8_t* u, uint8_t* v, int stride,
 
668
                      int thresh, int ithresh, int hev_thresh) {
 
669
  FilterLoop24(u + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
 
670
  FilterLoop24(v + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
 
671
}
 
672
 
 
673
static void HFilter8i(uint8_t* u, uint8_t* v, int stride,
 
674
                      int thresh, int ithresh, int hev_thresh) {
 
675
  FilterLoop24(u + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
 
676
  FilterLoop24(v + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
 
677
}
 
678
 
 
679
//------------------------------------------------------------------------------
 
680
 
 
681
VP8DecIdct2 VP8Transform;
 
682
VP8DecIdct VP8TransformUV;
 
683
VP8DecIdct VP8TransformDC;
 
684
VP8DecIdct VP8TransformDCUV;
 
685
 
 
686
VP8LumaFilterFunc VP8VFilter16;
 
687
VP8LumaFilterFunc VP8HFilter16;
 
688
VP8ChromaFilterFunc VP8VFilter8;
 
689
VP8ChromaFilterFunc VP8HFilter8;
 
690
VP8LumaFilterFunc VP8VFilter16i;
 
691
VP8LumaFilterFunc VP8HFilter16i;
 
692
VP8ChromaFilterFunc VP8VFilter8i;
 
693
VP8ChromaFilterFunc VP8HFilter8i;
 
694
VP8SimpleFilterFunc VP8SimpleVFilter16;
 
695
VP8SimpleFilterFunc VP8SimpleHFilter16;
 
696
VP8SimpleFilterFunc VP8SimpleVFilter16i;
 
697
VP8SimpleFilterFunc VP8SimpleHFilter16i;
 
698
 
 
699
extern void VP8DspInitSSE2(void);
 
700
extern void VP8DspInitNEON(void);
 
701
 
 
702
void VP8DspInit(void) {
 
703
  DspInitTables();
 
704
 
 
705
  VP8Transform = TransformTwo;
 
706
  VP8TransformUV = TransformUV;
 
707
  VP8TransformDC = TransformDC;
 
708
  VP8TransformDCUV = TransformDCUV;
 
709
 
 
710
  VP8VFilter16 = VFilter16;
 
711
  VP8HFilter16 = HFilter16;
 
712
  VP8VFilter8 = VFilter8;
 
713
  VP8HFilter8 = HFilter8;
 
714
  VP8VFilter16i = VFilter16i;
 
715
  VP8HFilter16i = HFilter16i;
 
716
  VP8VFilter8i = VFilter8i;
 
717
  VP8HFilter8i = HFilter8i;
 
718
  VP8SimpleVFilter16 = SimpleVFilter16;
 
719
  VP8SimpleHFilter16 = SimpleHFilter16;
 
720
  VP8SimpleVFilter16i = SimpleVFilter16i;
 
721
  VP8SimpleHFilter16i = SimpleHFilter16i;
 
722
 
 
723
  // If defined, use CPUInfo() to overwrite some pointers with faster versions.
 
724
  if (VP8GetCPUInfo) {
 
725
#if defined(WEBP_USE_SSE2)
 
726
    if (VP8GetCPUInfo(kSSE2)) {
 
727
      VP8DspInitSSE2();
 
728
    }
 
729
#elif defined(WEBP_USE_NEON)
 
730
    if (VP8GetCPUInfo(kNEON)) {
 
731
      VP8DspInitNEON();
 
732
    }
 
733
#endif
 
734
  }
 
735
}
 
736
 
 
737
#if defined(__cplusplus) || defined(c_plusplus)
 
738
}    // extern "C"
 
739
#endif