Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * H.274 film grain synthesis | ||
3 | * Copyright (c) 2021 Niklas Haas <ffmpeg@haasn.xyz> | ||
4 | * | ||
5 | * This file is part of FFmpeg. | ||
6 | * | ||
7 | * FFmpeg is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * FFmpeg is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with FFmpeg; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | */ | ||
21 | |||
22 | /** | ||
23 | * @file | ||
24 | * H.274 film grain synthesis. | ||
25 | * @author Niklas Haas <ffmpeg@haasn.xyz> | ||
26 | */ | ||
27 | |||
28 | #include "libavutil/avassert.h" | ||
29 | #include "libavutil/bswap.h" | ||
30 | #include "libavcodec/bswapdsp.h" | ||
31 | #include "libavutil/crc.h" | ||
32 | #include "libavutil/imgutils.h" | ||
33 | #include "libavutil/md5.h" | ||
34 | #include "libavutil/mem.h" | ||
35 | |||
36 | #include "h274.h" | ||
37 | |||
38 | static const int8_t Gaussian_LUT[2048+4]; | ||
39 | static const uint32_t Seed_LUT[256]; | ||
40 | static const int8_t R64T[64][64]; | ||
41 | |||
42 | ✗ | static void prng_shift(uint32_t *state) | |
43 | { | ||
44 | // Primitive polynomial x^31 + x^3 + 1 (modulo 2) | ||
45 | ✗ | uint32_t x = *state; | |
46 | ✗ | uint8_t feedback = 1u ^ (x >> 2) ^ (x >> 30); | |
47 | ✗ | *state = (x << 1) | (feedback & 1u); | |
48 | ✗ | } | |
49 | |||
50 | ✗ | static void init_slice_c(int8_t out[64][64], uint8_t h, uint8_t v, | |
51 | int16_t tmp[64][64]) | ||
52 | { | ||
53 | static const uint8_t deblock_factors[13] = { | ||
54 | 64, 71, 77, 84, 90, 96, 103, 109, 116, 122, 128, 128, 128 | ||
55 | }; | ||
56 | |||
57 | ✗ | const uint8_t deblock_coeff = deblock_factors[v]; | |
58 | ✗ | const uint8_t freq_h = ((h + 3) << 2) - 1; | |
59 | ✗ | const uint8_t freq_v = ((v + 3) << 2) - 1; | |
60 | ✗ | uint32_t seed = Seed_LUT[h + v * 13]; | |
61 | |||
62 | // Initialize with random gaussian values, using the output array as a | ||
63 | // temporary buffer for these intermediate values. | ||
64 | // | ||
65 | // Note: To make the subsequent matrix multiplication cache friendlier, we | ||
66 | // store each *column* of the starting image in a *row* of `out` | ||
67 | ✗ | for (int l = 0; l <= freq_v; l++) { | |
68 | ✗ | for (int k = 0; k <= freq_h; k += 4) { | |
69 | ✗ | uint16_t offset = seed % 2048; | |
70 | ✗ | out[l][k + 0] = Gaussian_LUT[offset + 0]; | |
71 | ✗ | out[l][k + 1] = Gaussian_LUT[offset + 1]; | |
72 | ✗ | out[l][k + 2] = Gaussian_LUT[offset + 2]; | |
73 | ✗ | out[l][k + 3] = Gaussian_LUT[offset + 3]; | |
74 | ✗ | prng_shift(&seed); | |
75 | } | ||
76 | } | ||
77 | |||
78 | ✗ | out[0][0] = 0; | |
79 | |||
80 | // 64x64 inverse integer transform | ||
81 | ✗ | for (int y = 0; y < 64; y++) { | |
82 | ✗ | for (int x = 0; x <= freq_v; x++) { | |
83 | ✗ | int32_t sum = 0; | |
84 | ✗ | for (int p = 0; p <= freq_h; p++) | |
85 | ✗ | sum += R64T[y][p] * out[x][p]; | |
86 | ✗ | tmp[y][x] = (sum + 128) >> 8; | |
87 | } | ||
88 | } | ||
89 | |||
90 | ✗ | for (int y = 0; y < 64; y++) { | |
91 | ✗ | for (int x = 0; x < 64; x++) { | |
92 | ✗ | int32_t sum = 0; | |
93 | ✗ | for (int p = 0; p <= freq_v; p++) | |
94 | ✗ | sum += tmp[x][p] * R64T[y][p]; // R64T^T = R64 | |
95 | // Renormalize and clip to [-127, 127] | ||
96 | ✗ | out[y][x] = av_clip((sum + 128) >> 8, -127, 127); | |
97 | } | ||
98 | } | ||
99 | |||
100 | // Deblock horizontal edges by simple attenuation of values | ||
101 | ✗ | for (int y = 0; y < 64; y += 8) { | |
102 | ✗ | for (int x = 0; x < 64; x++) { | |
103 | ✗ | out[y + 0][x] = (out[y + 0][x] * deblock_coeff) >> 7; | |
104 | ✗ | out[y + 7][x] = (out[y + 7][x] * deblock_coeff) >> 7; | |
105 | } | ||
106 | } | ||
107 | ✗ | } | |
108 | |||
109 | ✗ | static void init_slice(H274FilmGrainDatabase *database, uint8_t h, uint8_t v) | |
110 | { | ||
111 | ✗ | if (database->residency[h] & (1 << v)) | |
112 | ✗ | return; | |
113 | |||
114 | ✗ | database->residency[h] |= (1 << v); | |
115 | ✗ | init_slice_c(database->db[h][v], h, v, database->slice_tmp); | |
116 | } | ||
117 | |||
118 | // Computes the average of an 8x8 block | ||
119 | ✗ | static uint16_t avg_8x8_c(const uint8_t *in, int in_stride) | |
120 | { | ||
121 | ✗ | uint16_t avg[8] = {0}; // summing over an array vectorizes better | |
122 | |||
123 | ✗ | for (int y = 0; y < 8; y++) { | |
124 | ✗ | for (int x = 0; x < 8; x++) | |
125 | ✗ | avg[x] += in[x]; | |
126 | ✗ | in += in_stride; | |
127 | } | ||
128 | |||
129 | ✗ | return (avg[0] + avg[1] + avg[2] + avg[3] + | |
130 | ✗ | avg[4] + avg[5] + avg[6] + avg[7]) >> 6; | |
131 | } | ||
132 | |||
133 | // Synthesize an 8x8 block of film grain by copying the pattern from `db` | ||
134 | ✗ | static void synth_grain_8x8_c(int8_t *out, const int out_stride, | |
135 | const int16_t scale, const uint8_t shift, | ||
136 | const int8_t *db) | ||
137 | { | ||
138 | ✗ | for (int y = 0; y < 8; y++) { | |
139 | ✗ | for (int x = 0; x < 8; x++) | |
140 | ✗ | out[x] = (scale * db[x]) >> shift; | |
141 | |||
142 | ✗ | out += out_stride; | |
143 | ✗ | db += 64; | |
144 | } | ||
145 | ✗ | } | |
146 | |||
147 | // Deblock vertical edges of an 8x8 block, mixing with the previous block | ||
148 | ✗ | static void deblock_8x8_c(int8_t *out, const int out_stride) | |
149 | { | ||
150 | ✗ | for (int y = 0; y < 8; y++) { | |
151 | ✗ | const int8_t l1 = out[-2], l0 = out[-1]; | |
152 | ✗ | const int8_t r0 = out[0], r1 = out[1]; | |
153 | ✗ | out[0] = (l0 + r0 * 2 + r1) >> 2; | |
154 | ✗ | out[-1] = (r0 + l0 * 2 + l1) >> 2; | |
155 | ✗ | out += out_stride; | |
156 | } | ||
157 | ✗ | } | |
158 | |||
159 | // Generates a single 8x8 block of grain, optionally also applying the | ||
160 | // deblocking step (note that this implies writing to the previous block). | ||
161 | ✗ | static av_always_inline void generate(int8_t *out, int out_stride, | |
162 | const uint8_t *in, int in_stride, | ||
163 | H274FilmGrainDatabase *database, | ||
164 | const AVFilmGrainH274Params *h274, | ||
165 | int c, int invert, int deblock, | ||
166 | int y_offset, int x_offset) | ||
167 | { | ||
168 | ✗ | const uint8_t shift = h274->log2_scale_factor + 6; | |
169 | ✗ | const uint16_t avg = avg_8x8_c(in, in_stride); | |
170 | int16_t scale; | ||
171 | uint8_t h, v; | ||
172 | ✗ | int8_t s = -1; | |
173 | |||
174 | // FIXME: This logic only generates grain with a single | ||
175 | // intensity interval. Strictly speaking, the H.274 specification allows | ||
176 | // for overlapping intensity intervals, however SMPTE RDD 5-2006 (which | ||
177 | // concerns the implementation of H.274 for H.264) forbids this as it | ||
178 | // requires a nontrivial grain synthesis process (FFT). | ||
179 | // | ||
180 | // In principle, we should detect this possibility ahead of time and warn | ||
181 | // the user that the output is unlikely to be correct, or alternatively | ||
182 | // return an AVERROR_PATCHWELCOME. | ||
183 | ✗ | for (int i = 0; i < h274->num_intensity_intervals[c]; i++) { | |
184 | ✗ | if (avg >= h274->intensity_interval_lower_bound[c][i] && | |
185 | ✗ | avg <= h274->intensity_interval_upper_bound[c][i]) | |
186 | { | ||
187 | ✗ | s = i; | |
188 | ✗ | break; | |
189 | } | ||
190 | } | ||
191 | |||
192 | ✗ | if (s < 0) { | |
193 | // No matching intensity interval, synthesize blank film grain | ||
194 | ✗ | for (int y = 0; y < 8; y++) | |
195 | ✗ | memset(out + y * out_stride, 0, sizeof(int8_t[8])); | |
196 | ✗ | return; | |
197 | } | ||
198 | |||
199 | ✗ | h = av_clip(h274->comp_model_value[c][s][1], 2, 14) - 2; | |
200 | ✗ | v = av_clip(h274->comp_model_value[c][s][2], 2, 14) - 2; | |
201 | ✗ | init_slice(database, h, v); | |
202 | |||
203 | ✗ | scale = h274->comp_model_value[c][s][0]; | |
204 | ✗ | if (invert) | |
205 | ✗ | scale = -scale; | |
206 | |||
207 | ✗ | synth_grain_8x8_c(out, out_stride, scale, shift, | |
208 | ✗ | &database->db[h][v][y_offset][x_offset]); | |
209 | |||
210 | ✗ | if (deblock) | |
211 | ✗ | deblock_8x8_c(out, out_stride); | |
212 | } | ||
213 | |||
214 | // Saturating 8-bit sum of a+b | ||
215 | ✗ | static void add_8x8_clip_c(uint8_t *out, const uint8_t *a, const int8_t *b, | |
216 | int n) | ||
217 | { | ||
218 | ✗ | for (int i = 0; i < n; i++) | |
219 | ✗ | out[i] = av_clip_uint8(a[i] + b[i]); | |
220 | ✗ | } | |
221 | |||
222 | ✗ | int ff_h274_apply_film_grain(AVFrame *out_frame, const AVFrame *in_frame, | |
223 | H274FilmGrainDatabase *database, | ||
224 | const AVFilmGrainParams *params) | ||
225 | { | ||
226 | ✗ | AVFilmGrainH274Params h274 = params->codec.h274; | |
227 | av_assert1(params->type == AV_FILM_GRAIN_PARAMS_H274); | ||
228 | ✗ | if (h274.model_id != 0) | |
229 | ✗ | return AVERROR_PATCHWELCOME; | |
230 | |||
231 | av_assert1(out_frame->format == in_frame->format); | ||
232 | ✗ | if (in_frame->format != AV_PIX_FMT_YUV420P) | |
233 | ✗ | return AVERROR_PATCHWELCOME; | |
234 | |||
235 | ✗ | for (int c = 0; c < 3; c++) { | |
236 | static const uint8_t color_offset[3] = { 0, 85, 170 }; | ||
237 | ✗ | uint32_t seed = Seed_LUT[(params->seed + color_offset[c]) % 256]; | |
238 | ✗ | const int width = c > 0 ? AV_CEIL_RSHIFT(out_frame->width, 1) : out_frame->width; | |
239 | ✗ | const int height = c > 0 ? AV_CEIL_RSHIFT(out_frame->height, 1) : out_frame->height; | |
240 | |||
241 | ✗ | uint8_t * const out = out_frame->data[c]; | |
242 | ✗ | const int out_stride = out_frame->linesize[c]; | |
243 | ✗ | int8_t * const grain = out_frame->data[c]; // reuse output buffer for grain | |
244 | ✗ | const int grain_stride = out_stride; | |
245 | ✗ | const uint8_t * const in = in_frame->data[c]; | |
246 | ✗ | const int in_stride = in_frame->linesize[c]; | |
247 | |||
248 | ✗ | if (!h274.component_model_present[c]) { | |
249 | ✗ | av_image_copy_plane(out, out_stride, in, in_stride, | |
250 | width * sizeof(uint8_t), height); | ||
251 | ✗ | continue; | |
252 | } | ||
253 | |||
254 | ✗ | if (c > 0) { | |
255 | // Adaptation for 4:2:0 chroma subsampling | ||
256 | ✗ | for (int i = 0; i < h274.num_intensity_intervals[c]; i++) { | |
257 | ✗ | h274.comp_model_value[c][i][0] >>= 1; | |
258 | ✗ | h274.comp_model_value[c][i][1] *= 2; | |
259 | ✗ | h274.comp_model_value[c][i][2] *= 2; | |
260 | } | ||
261 | } | ||
262 | |||
263 | // Film grain synthesis is done in 8x8 blocks, but the PRNG state is | ||
264 | // only advanced in 16x16 blocks, so use a nested loop | ||
265 | ✗ | for (int y = 0; y < height; y += 16) { | |
266 | ✗ | for (int x = 0; x < width; x += 16) { | |
267 | ✗ | uint16_t x_offset = (seed >> 16) % 52; | |
268 | ✗ | uint16_t y_offset = (seed & 0xFFFF) % 56; | |
269 | ✗ | const int invert = (seed & 0x1); | |
270 | ✗ | x_offset &= 0xFFFC; | |
271 | ✗ | y_offset &= 0xFFF8; | |
272 | ✗ | prng_shift(&seed); | |
273 | |||
274 | ✗ | for (int yy = 0; yy < 16 && y+yy < height; yy += 8) { | |
275 | ✗ | for (int xx = 0; xx < 16 && x+xx < width; xx += 8) { | |
276 | ✗ | generate(grain + (y+yy) * grain_stride + (x+xx), grain_stride, | |
277 | ✗ | in + (y+yy) * in_stride + (x+xx), in_stride, | |
278 | ✗ | database, &h274, c, invert, (x+xx) > 0, | |
279 | y_offset + yy, x_offset + xx); | ||
280 | } | ||
281 | } | ||
282 | } | ||
283 | } | ||
284 | |||
285 | // Final output blend pass, done after grain synthesis is complete | ||
286 | // because deblocking depends on previous grain values | ||
287 | ✗ | for (int y = 0; y < height; y++) { | |
288 | ✗ | add_8x8_clip_c(out + y * out_stride, in + y * in_stride, | |
289 | ✗ | grain + y * grain_stride, width); | |
290 | } | ||
291 | } | ||
292 | |||
293 | ✗ | return 0; | |
294 | } | ||
295 | |||
296 | // These tables are all taken from the SMPTE RDD 5-2006 specification | ||
297 | static const int8_t Gaussian_LUT[2048+4] = { | ||
298 | -11, 12, 103, -11, 42, -35, 12, 59, 77, 98, -87, 3, 65, -78, 45, 56, -51, 21, | ||
299 | 13, -11, -20, -19, 33, -127, 17, -6, -105, 18, 19, 71, 48, -10, -38, 42, | ||
300 | -2, 75, -67, 52, -90, 33, -47, 21, -3, -56, 49, 1, -57, -42, -1, 120, -127, | ||
301 | -108, -49, 9, 14, 127, 122, 109, 52, 127, 2, 7, 114, 19, 30, 12, 77, 112, | ||
302 | 82, -61, -127, 111, -52, -29, 2, -49, -24, 58, -29, -73, 12, 112, 67, 79, | ||
303 | -3, -114, -87, -6, -5, 40, 58, -81, 49, -27, -31, -34, -105, 50, 16, -24, | ||
304 | -35, -14, -15, -127, -55, -22, -55, -127, -112, 5, -26, -72, 127, 127, -2, | ||
305 | 41, 87, -65, -16, 55, 19, 91, -81, -65, -64, 35, -7, -54, 99, -7, 88, 125, | ||
306 | -26, 91, 0, 63, 60, -14, -23, 113, -33, 116, 14, 26, 51, -16, 107, -8, 53, | ||
307 | 38, -34, 17, -7, 4, -91, 6, 63, 63, -15, 39, -36, 19, 55, 17, -51, 40, 33, | ||
308 | -37, 126, -39, -118, 17, -30, 0, 19, 98, 60, 101, -12, -73, -17, -52, 98, | ||
309 | 3, 3, 60, 33, -3, -2, 10, -42, -106, -38, 14, 127, 16, -127, -31, -86, -39, | ||
310 | -56, 46, -41, 75, 23, -19, -22, -70, 74, -54, -2, 32, -45, 17, -92, 59, | ||
311 | -64, -67, 56, -102, -29, -87, -34, -92, 68, 5, -74, -61, 93, -43, 14, -26, | ||
312 | -38, -126, -17, 16, -127, 64, 34, 31, 93, 17, -51, -59, 71, 77, 81, 127, | ||
313 | 127, 61, 33, -106, -93, 0, 0, 75, -69, 71, 127, -19, -111, 30, 23, 15, 2, | ||
314 | 39, 92, 5, 42, 2, -6, 38, 15, 114, -30, -37, 50, 44, 106, 27, 119, 7, -80, | ||
315 | 25, -68, -21, 92, -11, -1, 18, 41, -50, 79, -127, -43, 127, 18, 11, -21, | ||
316 | 32, -52, 27, -88, -90, -39, -19, -10, 24, -118, 72, -24, -44, 2, 12, 86, | ||
317 | -107, 39, -33, -127, 47, 51, -24, -22, 46, 0, 15, -35, -69, -2, -74, 24, | ||
318 | -6, 0, 29, -3, 45, 32, -32, 117, -45, 79, -24, -17, -109, -10, -70, 88, | ||
319 | -48, 24, -91, 120, -37, 50, -127, 58, 32, -82, -10, -17, -7, 46, -127, -15, | ||
320 | 89, 127, 17, 98, -39, -33, 37, 42, -40, -32, -21, 105, -19, 19, 19, -59, | ||
321 | -9, 30, 0, -127, 34, 127, -84, 75, 24, -40, -49, -127, -107, -14, 45, -75, | ||
322 | 1, 30, -20, 41, -68, -40, 12, 127, -3, 5, 20, -73, -59, -127, -3, -3, -53, | ||
323 | -6, -119, 93, 120, -80, -50, 0, 20, -46, 67, 78, -12, -22, -127, 36, -41, | ||
324 | 56, 119, -5, -116, -22, 68, -14, -90, 24, -82, -44, -127, 107, -25, -37, | ||
325 | 40, -7, -7, -82, 5, -87, 44, -34, 9, -127, 39, 70, 49, -63, 74, -49, 109, | ||
326 | -27, -89, -47, -39, 44, 49, -4, 60, -42, 80, 9, -127, -9, -56, -49, 125, | ||
327 | -66, 47, 36, 117, 15, -11, -96, 109, 94, -17, -56, 70, 8, -14, -5, 50, 37, | ||
328 | -45, 120, -30, -76, 40, -46, 6, 3, 69, 17, -78, 1, -79, 6, 127, 43, 26, | ||
329 | 127, -127, 28, -55, -26, 55, 112, 48, 107, -1, -77, -1, 53, -9, -22, -43, | ||
330 | 123, 108, 127, 102, 68, 46, 5, 1, 123, -13, -55, -34, -49, 89, 65, -105, | ||
331 | -5, 94, -53, 62, 45, 30, 46, 18, -35, 15, 41, 47, -98, -24, 94, -75, 127, | ||
332 | -114, 127, -68, 1, -17, 51, -95, 47, 12, 34, -45, -75, 89, -107, -9, -58, | ||
333 | -29, -109, -24, 127, -61, -13, 77, -45, 17, 19, 83, -24, 9, 127, -66, 54, | ||
334 | 4, 26, 13, 111, 43, -113, -22, 10, -24, 83, 67, -14, 75, -123, 59, 127, | ||
335 | -12, 99, -19, 64, -38, 54, 9, 7, 61, -56, 3, -57, 113, -104, -59, 3, -9, | ||
336 | -47, 74, 85, -55, -34, 12, 118, 28, 93, -72, 13, -99, -72, -20, 30, 72, | ||
337 | -94, 19, -54, 64, -12, -63, -25, 65, 72, -10, 127, 0, -127, 103, -20, -73, | ||
338 | -112, -103, -6, 28, -42, -21, -59, -29, -26, 19, -4, -51, 94, -58, -95, | ||
339 | -37, 35, 20, -69, 127, -19, -127, -22, -120, -53, 37, 74, -127, -1, -12, | ||
340 | -119, -53, -28, 38, 69, 17, 16, -114, 89, 62, 24, 37, -23, 49, -101, -32, | ||
341 | -9, -95, -53, 5, 93, -23, -49, -8, 51, 3, -75, -90, -10, -39, 127, -86, | ||
342 | -22, 20, 20, 113, 75, 52, -31, 92, -63, 7, -12, 46, 36, 101, -43, -17, -53, | ||
343 | -7, -38, -76, -31, -21, 62, 31, 62, 20, -127, 31, 64, 36, 102, -85, -10, | ||
344 | 77, 80, 58, -79, -8, 35, 8, 80, -24, -9, 3, -17, 72, 127, 83, -87, 55, 18, | ||
345 | -119, -123, 36, 10, 127, 56, -55, 113, 13, 26, 32, -13, -48, 22, -13, 5, | ||
346 | 58, 27, 24, 26, -11, -36, 37, -92, 78, 81, 9, 51, 14, 67, -13, 0, 32, 45, | ||
347 | -76, 32, -39, -22, -49, -127, -27, 31, -9, 36, 14, 71, 13, 57, 12, -53, | ||
348 | -86, 53, -44, -35, 2, 127, 12, -66, -44, 46, -115, 3, 10, 56, -35, 119, | ||
349 | -19, -61, 52, -59, -127, -49, -23, 4, -5, 17, -82, -6, 127, 25, 79, 67, 64, | ||
350 | -25, 14, -64, -37, -127, -28, 21, -63, 66, -53, -41, 109, -62, 15, -22, 13, | ||
351 | 29, -63, 20, 27, 95, -44, -59, -116, -10, 79, -49, 22, -43, -16, 46, -47, | ||
352 | -120, -36, -29, -52, -44, 29, 127, -13, 49, -9, -127, 75, -28, -23, 88, 59, | ||
353 | 11, -95, 81, -59, 58, 60, -26, 40, -92, -3, -22, -58, -45, -59, -22, -53, | ||
354 | 71, -29, 66, -32, -23, 14, -17, -66, -24, -28, -62, 47, 38, 17, 16, -37, | ||
355 | -24, -11, 8, -27, -19, 59, 45, -49, -47, -4, -22, -81, 30, -67, -127, 74, | ||
356 | 102, 5, -18, 98, 34, -66, 42, -52, 7, -59, 24, -58, -19, -24, -118, -73, | ||
357 | 91, 15, -16, 79, -32, -79, -127, -36, 41, 77, -83, 2, 56, 22, -75, 127, | ||
358 | -16, -21, 12, 31, 56, -113, -127, 90, 55, 61, 12, 55, -14, -113, -14, 32, | ||
359 | 49, -67, -17, 91, -10, 1, 21, 69, -70, 99, -19, -112, 66, -90, -10, -9, | ||
360 | -71, 127, 50, -81, -49, 24, 61, -61, -111, 7, -41, 127, 88, -66, 108, -127, | ||
361 | -6, 36, -14, 41, -50, 14, 14, 73, -101, -28, 77, 127, -8, -100, 88, 38, | ||
362 | 121, 88, -125, -60, 13, -94, -115, 20, -67, -87, -94, -119, 44, -28, -30, | ||
363 | 18, 5, -53, -61, 20, -43, 11, -77, -60, 13, 29, 3, 6, -72, 38, -60, -11, | ||
364 | 108, -53, 41, 66, -12, -127, -127, -49, 24, 29, 46, 36, 91, 34, -33, 116, | ||
365 | -51, -34, -52, 91, 7, -83, 73, -26, -103, 24, -10, 76, 84, 5, 68, -80, -13, | ||
366 | -17, -32, -48, 20, 50, 26, 10, 63, -104, -14, 37, 127, 114, 97, 35, 1, -33, | ||
367 | -55, 127, -124, -33, 61, -7, 119, -32, -127, -53, -42, 63, 3, -5, -26, 70, | ||
368 | -58, -33, -44, -43, 34, -56, -127, 127, 25, -35, -11, 16, -81, 29, -58, 40, | ||
369 | -127, -127, 20, -47, -11, -36, -63, -52, -32, -82, 78, -76, -73, 8, 27, | ||
370 | -72, -9, -74, -85, -86, -57, 25, 78, -10, -97, 35, -65, 8, -59, 14, 1, -42, | ||
371 | 32, -88, -44, 17, -3, -9, 59, 40, 12, -108, -40, 24, 34, 18, -28, 2, 51, | ||
372 | -110, -4, 100, 1, 65, 22, 0, 127, 61, 45, 25, -31, 6, 9, -7, -48, 99, 16, | ||
373 | 44, -2, -40, 32, -39, -52, 10, -110, -19, 56, -127, 69, 26, 51, 92, 40, 61, | ||
374 | -52, 45, -38, 13, 85, 122, 27, 66, 45, -111, -83, -3, 31, 37, 19, -36, 58, | ||
375 | 71, 39, -78, -47, 58, -78, 8, -62, -36, -14, 61, 42, -127, 71, -4, 24, -54, | ||
376 | 52, -127, 67, -4, -42, 30, -63, 59, -3, -1, -18, -46, -92, -81, -96, -14, | ||
377 | -53, -10, -11, -77, 13, 1, 8, -67, -127, 127, -28, 26, -14, 18, -13, -26, | ||
378 | 2, 10, -46, -32, -15, 27, -31, -59, 59, 77, -121, 28, 40, -54, -62, -31, | ||
379 | -21, -37, -32, -6, -127, -25, -60, 70, -127, 112, -127, 127, 88, -7, 116, | ||
380 | 110, 53, 87, -127, 3, 16, 23, 74, -106, -51, 3, 74, -82, -112, -74, 65, 81, | ||
381 | 25, 53, 127, -45, -50, -103, -41, -65, -29, 79, -67, 64, -33, -30, -8, 127, | ||
382 | 0, -13, -51, 67, -14, 5, -92, 29, -35, -8, -90, -57, -3, 36, 43, 44, -31, | ||
383 | -69, -7, 36, 39, -51, 43, -81, 58, 6, 127, 12, 57, 66, 46, 59, -43, -42, | ||
384 | 41, -15, -120, 24, 3, -11, 19, -13, 51, 28, 3, 55, -48, -12, -1, 2, 97, | ||
385 | -19, 29, 42, 13, 43, 78, -44, 56, -108, -43, -19, 127, 15, -11, -18, -81, | ||
386 | 83, -37, 77, -109, 15, 65, -50, 43, 12, 13, 27, 28, 61, 57, 30, 26, 106, | ||
387 | -18, 56, 13, 97, 4, -8, -62, -103, 94, 108, -44, 52, 27, -47, -9, 105, -53, | ||
388 | 46, 89, 103, -33, 38, -34, 55, 51, 70, -94, -35, -87, -107, -19, -31, 9, | ||
389 | -19, 79, -14, 77, 5, -19, -107, 85, 21, -45, -39, -42, 9, -29, 74, 47, -75, | ||
390 | 60, -127, 120, -112, -57, -32, 41, 7, 79, 76, 66, 57, 41, -25, 31, 37, -47, | ||
391 | -36, 43, -73, -37, 63, 127, -69, -52, 90, -33, -61, 60, -55, 44, 15, 4, | ||
392 | -67, 13, -92, 64, 29, -39, -3, 83, -2, -38, -85, -86, 58, 35, -69, -61, 29, | ||
393 | -37, -95, -78, 4, 30, -4, -32, -80, -22, -9, -77, 46, 7, -93, -71, 65, 9, | ||
394 | -50, 127, -70, 26, -12, -39, -114, 63, -127, -100, 4, -32, 111, 22, -60, | ||
395 | 65, -101, 26, -42, 21, -59, -27, -74, 2, -94, 6, 126, 5, 76, -88, -9, -43, | ||
396 | -101, 127, 1, 125, 92, -63, 52, 56, 4, 81, -127, 127, 80, 127, -29, 30, | ||
397 | 116, -74, -17, -57, 105, 48, 45, 25, -72, 48, -38, -108, 31, -34, 4, -11, | ||
398 | 41, -127, 52, -104, -43, -37, 52, 2, 47, 87, -9, 77, 27, -41, -25, 90, 86, | ||
399 | -56, 75, 10, 33, 78, 58, 127, 127, -7, -73, 49, -33, -106, -35, 38, 57, 53, | ||
400 | -17, -4, 83, 52, -108, 54, -125, 28, 23, 56, -43, -88, -17, -6, 47, 23, -9, | ||
401 | 0, -13, 111, 75, 27, -52, -38, -34, 39, 30, 66, 39, 38, -64, 38, 3, 21, | ||
402 | -32, -51, -28, 54, -38, -87, 20, 52, 115, 18, -81, -70, 0, -14, -46, -46, | ||
403 | -3, 125, 16, -14, 23, -82, -84, -69, -20, -65, -127, 9, 81, -49, 61, 7, | ||
404 | -36, -45, -42, 57, -26, 47, 20, -85, 46, -13, 41, -37, -75, -60, 86, -78, | ||
405 | -127, 12, 50, 2, -3, 13, 47, 5, 19, -78, -55, -27, 65, -71, 12, -108, 20, | ||
406 | -16, 11, -31, 63, -55, 37, 75, -17, 127, -73, -33, -28, -120, 105, 68, 106, | ||
407 | -103, -106, 71, 61, 2, 23, -3, 33, -5, -15, -67, -15, -23, -54, 15, -63, | ||
408 | 76, 58, -110, 1, 83, -27, 22, 75, -39, -17, -11, 64, -17, -127, -54, -66, | ||
409 | 31, 96, 116, 3, -114, -7, -108, -63, 97, 9, 50, 8, 75, -28, 72, 112, -36, | ||
410 | -112, 95, -50, 23, -13, -19, 55, 21, 23, 92, 91, 22, -49, 16, -75, 23, 9, | ||
411 | -49, -97, -37, 49, -36, 36, -127, -86, 43, 127, -24, -24, 84, 83, -35, -34, | ||
412 | -12, 109, 102, -38, 51, -68, 34, 19, -22, 49, -32, 127, 40, 24, -93, -4, | ||
413 | -3, 105, 3, -58, -18, 8, 127, -18, 125, 68, 69, -62, 30, -36, 54, -57, -24, | ||
414 | 17, 43, -36, -27, -57, -67, -21, -10, -49, 68, 12, 65, 4, 48, 55, 127, -75, | ||
415 | 44, 89, -66, -13, -78, -82, -91, 22, 30, 33, -40, -87, -34, 96, -91, 39, | ||
416 | 10, -64, -3, -12, 127, -50, -37, -56, 23, -35, -36, -54, 90, -91, 2, 50, | ||
417 | 77, -6, -127, 16, 46, -5, -73, 0, -56, -18, -72, 28, 93, 60, 49, 20, 18, | ||
418 | 111, -111, 32, -83, 47, 47, -10, 35, -88, 43, 57, -98, 127, -17, 0, 1, -39, | ||
419 | -127, -2, 0, 63, 93, 0, 36, -66, -61, -19, 39, -127, 58, 50, -17, 127, 88, | ||
420 | -43, -108, -51, -16, 7, -36, 68, 46, -14, 107, 40, 57, 7, 19, 8, 3, 88, | ||
421 | -90, -92, -18, -21, -24, 13, 7, -4, -78, -91, -4, 8, -35, -5, 19, 2, -111, | ||
422 | 4, -66, -81, 122, -20, -34, -37, -84, 127, 68, 46, 17, 47, | ||
423 | |||
424 | // Repeat the beginning of the array to allow wrapping reads | ||
425 | -11, 12, 103, -11, | ||
426 | }; | ||
427 | |||
428 | static const uint32_t Seed_LUT[256] = { | ||
429 | 747538460, 1088979410, 1744950180, 1767011913, 1403382928, | ||
430 | 521866116, 1060417601, 2110622736, 1557184770, 105289385, 585624216, | ||
431 | 1827676546, 1191843873, 1018104344, 1123590530, 663361569, 2023850500, | ||
432 | 76561770, 1226763489, 80325252, 1992581442, 502705249, 740409860, | ||
433 | 516219202, 557974537, 1883843076, 720112066, 1640137737, 1820967556, | ||
434 | 40667586, 155354121, 1820967557, 1115949072, 1631803309, 98284748, | ||
435 | 287433856, 2119719977, 988742797, 1827432592, 579378475, 1017745956, | ||
436 | 1309377032, 1316535465, 2074315269, 1923385360, 209722667, 1546228260, | ||
437 | 168102420, 135274561, 355958469, 248291472, 2127839491, 146920100, | ||
438 | 585982612, 1611702337, 696506029, 1386498192, 1258072451, 1212240548, | ||
439 | 1043171860, 1217404993, 1090770605, 1386498193, 169093201, 541098240, | ||
440 | 1468005469, 456510673, 1578687785, 1838217424, 2010752065, 2089828354, | ||
441 | 1362717428, 970073673, 854129835, 714793201, 1266069081, 1047060864, | ||
442 | 1991471829, 1098097741, 913883585, 1669598224, 1337918685, 1219264706, | ||
443 | 1799741108, 1834116681, 683417731, 1120274457, 1073098457, 1648396544, | ||
444 | 176642749, 31171789, 718317889, 1266977808, 1400892508, 549749008, | ||
445 | 1808010512, 67112961, 1005669825, 903663673, 1771104465, 1277749632, | ||
446 | 1229754427, 950632997, 1979371465, 2074373264, 305357524, 1049387408, | ||
447 | 1171033360, 1686114305, 2147468765, 1941195985, 117709841, 809550080, | ||
448 | 991480851, 1816248997, 1561503561, 329575568, 780651196, 1659144592, | ||
449 | 1910793616, 604016641, 1665084765, 1530186961, 1870928913, 809550081, | ||
450 | 2079346113, 71307521, 876663040, 1073807360, 832356664, 1573927377, | ||
451 | 204073344, 2026918147, 1702476788, 2043881033, 57949587, 2001393952, | ||
452 | 1197426649, 1186508931, 332056865, 950043140, 890043474, 349099312, | ||
453 | 148914948, 236204097, 2022643605, 1441981517, 498130129, 1443421481, | ||
454 | 924216797, 1817491777, 1913146664, 1411989632, 929068432, 495735097, | ||
455 | 1684636033, 1284520017, 432816184, 1344884865, 210843729, 676364544, | ||
456 | 234449232, 12112337, 1350619139, 1753272996, 2037118872, 1408560528, | ||
457 | 533334916, 1043640385, 357326099, 201376421, 110375493, 541106497, | ||
458 | 416159637, 242512193, 777294080, 1614872576, 1535546636, 870600145, | ||
459 | 910810409, 1821440209, 1605432464, 1145147393, 951695441, 1758494976, | ||
460 | 1506656568, 1557150160, 608221521, 1073840384, 217672017, 684818688, | ||
461 | 1750138880, 16777217, 677990609, 953274371, 1770050213, 1359128393, | ||
462 | 1797602707, 1984616737, 1865815816, 2120835200, 2051677060, 1772234061, | ||
463 | 1579794881, 1652821009, 1742099468, 1887260865, 46468113, 1011925248, | ||
464 | 1134107920, 881643832, 1354774993, 472508800, 1892499769, 1752793472, | ||
465 | 1962502272, 687898625, 883538000, 1354355153, 1761673473, 944820481, | ||
466 | 2020102353, 22020353, 961597696, 1342242816, 964808962, 1355809701, | ||
467 | 17016649, 1386540177, 647682692, 1849012289, 751668241, 1557184768, | ||
468 | 127374604, 1927564752, 1045744913, 1614921984, 43588881, 1016185088, | ||
469 | 1544617984, 1090519041, 136122424, 215038417, 1563027841, 2026918145, | ||
470 | 1688778833, 701530369, 1372639488, 1342242817, 2036945104, 953274369, | ||
471 | 1750192384, 16842753, 964808960, 1359020032, 1358954497 | ||
472 | }; | ||
473 | |||
474 | // Note: This is pre-transposed, i.e. stored column-major order | ||
475 | static const int8_t R64T[64][64] = { | ||
476 | { | ||
477 | 32, 45, 45, 45, 45, 45, 45, 45, 44, 44, 44, 44, 43, 43, 43, 42, | ||
478 | 42, 41, 41, 40, 40, 39, 39, 38, 38, 37, 36, 36, 35, 34, 34, 33, | ||
479 | 32, 31, 30, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, | ||
480 | 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 4, 3, 2, 1, | ||
481 | }, { | ||
482 | 32, 45, 45, 44, 43, 42, 41, 39, 38, 36, 34, 31, 29, 26, 23, 20, | ||
483 | 17, 14, 11, 8, 4, 1, -2, -6, -9, -12, -15, -18, -21, -24, -27, -30, | ||
484 | -32, -34, -36, -38, -40, -41, -43, -44, -44, -45, -45, -45, -45, -45, -44, -43, | ||
485 | -42, -40, -39, -37, -35, -33, -30, -28, -25, -22, -19, -16, -13, -10, -7, -3, | ||
486 | }, { | ||
487 | 32, 45, 44, 42, 40, 37, 34, 30, 25, 20, 15, 10, 4, -1, -7, -12, | ||
488 | -17, -22, -27, -31, -35, -38, -41, -43, -44, -45, -45, -45, -43, -41, -39, -36, | ||
489 | -32, -28, -23, -18, -13, -8, -2, 3, 9, 14, 19, 24, 29, 33, 36, 39, | ||
490 | 42, 44, 45, 45, 45, 44, 43, 40, 38, 34, 30, 26, 21, 16, 11, 6, | ||
491 | }, { | ||
492 | 32, 45, 43, 39, 35, 30, 23, 16, 9, 1, -7, -14, -21, -28, -34, -38, | ||
493 | -42, -44, -45, -45, -43, -40, -36, -31, -25, -18, -11, -3, 4, 12, 19, 26, | ||
494 | 32, 37, 41, 44, 45, 45, 44, 41, 38, 33, 27, 20, 13, 6, -2, -10, | ||
495 | -17, -24, -30, -36, -40, -43, -45, -45, -44, -42, -39, -34, -29, -22, -15, -8, | ||
496 | }, { | ||
497 | 32, 44, 41, 36, 29, 20, 11, 1, -9, -18, -27, -34, -40, -44, -45, -45, | ||
498 | -42, -37, -30, -22, -13, -3, 7, 16, 25, 33, 39, 43, 45, 45, 43, 38, | ||
499 | 32, 24, 15, 6, -4, -14, -23, -31, -38, -42, -45, -45, -43, -39, -34, -26, | ||
500 | -17, -8, 2, 12, 21, 30, 36, 41, 44, 45, 44, 40, 35, 28, 19, 10, | ||
501 | }, { | ||
502 | 32, 44, 39, 31, 21, 10, -2, -14, -25, -34, -41, -45, -45, -42, -36, -28, | ||
503 | -17, -6, 7, 18, 29, 37, 43, 45, 44, 40, 34, 24, 13, 1, -11, -22, | ||
504 | -32, -39, -44, -45, -43, -38, -30, -20, -9, 3, 15, 26, 35, 41, 45, 45, | ||
505 | 42, 36, 27, 16, 4, -8, -19, -30, -38, -43, -45, -44, -40, -33, -23, -12, | ||
506 | }, { | ||
507 | 32, 43, 36, 26, 13, -1, -15, -28, -38, -44, -45, -42, -35, -24, -11, 3, | ||
508 | 17, 30, 39, 44, 45, 41, 34, 22, 9, -6, -19, -31, -40, -45, -45, -40, | ||
509 | -32, -20, -7, 8, 21, 33, 41, 45, 44, 39, 30, 18, 4, -10, -23, -34, | ||
510 | -42, -45, -44, -38, -29, -16, -2, 12, 25, 36, 43, 45, 43, 37, 27, 14, | ||
511 | }, { | ||
512 | 32, 42, 34, 20, 4, -12, -27, -38, -44, -45, -39, -28, -13, 3, 19, 33, | ||
513 | 42, 45, 43, 34, 21, 6, -11, -26, -38, -44, -45, -39, -29, -14, 2, 18, | ||
514 | 32, 41, 45, 43, 35, 22, 7, -10, -25, -37, -44, -45, -40, -30, -15, 1, | ||
515 | 17, 31, 41, 45, 43, 36, 23, 8, -9, -24, -36, -44, -45, -40, -30, -16, | ||
516 | }, { | ||
517 | 32, 41, 30, 14, -4, -22, -36, -44, -44, -37, -23, -6, 13, 30, 41, 45, | ||
518 | 42, 31, 15, -3, -21, -36, -44, -45, -38, -24, -7, 12, 29, 40, 45, 42, | ||
519 | 32, 16, -2, -20, -35, -44, -45, -38, -25, -8, 11, 28, 40, 45, 43, 33, | ||
520 | 17, -1, -19, -34, -43, -45, -39, -26, -9, 10, 27, 39, 45, 43, 34, 18, | ||
521 | }, { | ||
522 | 32, 40, 27, 8, -13, -31, -43, -45, -38, -22, -2, 18, 35, 44, 44, 34, | ||
523 | 17, -3, -23, -38, -45, -42, -30, -12, 9, 28, 41, 45, 40, 26, 7, -14, | ||
524 | -32, -43, -45, -37, -21, -1, 19, 36, 44, 44, 34, 16, -4, -24, -39, -45, | ||
525 | -42, -30, -11, 10, 29, 41, 45, 39, 25, 6, -15, -33, -43, -45, -36, -20, | ||
526 | }, { | ||
527 | 32, 39, 23, 1, -21, -38, -45, -40, -25, -3, 19, 37, 45, 41, 27, 6, | ||
528 | -17, -36, -45, -42, -29, -8, 15, 34, 44, 43, 30, 10, -13, -33, -44, -44, | ||
529 | -32, -12, 11, 31, 43, 44, 34, 14, -9, -30, -43, -45, -35, -16, 7, 28, | ||
530 | 42, 45, 36, 18, -4, -26, -41, -45, -38, -20, 2, 24, 40, 45, 39, 22, | ||
531 | }, { | ||
532 | 32, 38, 19, -6, -29, -43, -44, -31, -9, 16, 36, 45, 40, 22, -2, -26, | ||
533 | -42, -45, -34, -12, 13, 34, 45, 41, 25, 1, -23, -40, -45, -36, -15, 10, | ||
534 | 32, 44, 43, 28, 4, -20, -39, -45, -38, -18, 7, 30, 43, 44, 30, 8, | ||
535 | -17, -37, -45, -39, -21, 3, 27, 42, 44, 33, 11, -14, -35, -45, -41, -24, | ||
536 | }, { | ||
537 | 32, 37, 15, -12, -35, -45, -39, -18, 9, 33, 45, 40, 21, -6, -30, -44, | ||
538 | -42, -24, 2, 28, 43, 43, 27, 1, -25, -42, -44, -30, -4, 22, 41, 45, | ||
539 | 32, 8, -19, -39, -45, -34, -11, 16, 38, 45, 36, 14, -13, -36, -45, -38, | ||
540 | -17, 10, 34, 45, 40, 20, -7, -31, -44, -41, -23, 3, 29, 44, 43, 26, | ||
541 | }, { | ||
542 | 32, 36, 11, -18, -40, -45, -30, -3, 25, 43, 43, 24, -4, -31, -45, -39, | ||
543 | -17, 12, 36, 45, 35, 10, -19, -40, -44, -30, -2, 26, 43, 42, 23, -6, | ||
544 | -32, -45, -39, -16, 13, 37, 45, 34, 9, -20, -41, -44, -29, -1, 27, 44, | ||
545 | 42, 22, -7, -33, -45, -38, -15, 14, 38, 45, 34, 8, -21, -41, -44, -28, | ||
546 | }, { | ||
547 | 32, 34, 7, -24, -43, -41, -19, 12, 38, 45, 30, 1, -29, -45, -39, -14, | ||
548 | 17, 40, 44, 26, -4, -33, -45, -36, -9, 22, 43, 42, 21, -10, -36, -45, | ||
549 | -32, -3, 27, 44, 40, 16, -15, -39, -44, -28, 2, 31, 45, 37, 11, -20, | ||
550 | -42, -43, -23, 8, 35, 45, 34, 6, -25, -44, -41, -18, 13, 38, 45, 30, | ||
551 | }, { | ||
552 | 32, 33, 2, -30, -45, -36, -7, 26, 44, 38, 11, -22, -43, -40, -15, 18, | ||
553 | 42, 42, 19, -14, -40, -44, -23, 10, 38, 45, 27, -6, -35, -45, -30, 1, | ||
554 | 32, 45, 34, 3, -29, -45, -36, -8, 25, 44, 39, 12, -21, -43, -41, -16, | ||
555 | 17, 41, 43, 20, -13, -39, -44, -24, 9, 37, 45, 28, -4, -34, -45, -31, | ||
556 | }, { | ||
557 | 32, 31, -2, -34, -45, -28, 7, 37, 44, 24, -11, -39, -43, -20, 15, 41, | ||
558 | 42, 16, -19, -43, -40, -12, 23, 44, 38, 8, -27, -45, -35, -3, 30, 45, | ||
559 | 32, -1, -34, -45, -29, 6, 36, 45, 25, -10, -39, -44, -21, 14, 41, 42, | ||
560 | 17, -18, -43, -40, -13, 22, 44, 38, 9, -26, -45, -36, -4, 30, 45, 33, | ||
561 | }, { | ||
562 | 32, 30, -7, -38, -43, -18, 19, 44, 38, 6, -30, -45, -29, 8, 39, 43, | ||
563 | 17, -20, -44, -37, -4, 31, 45, 28, -9, -39, -43, -16, 21, 44, 36, 3, | ||
564 | -32, -45, -27, 10, 40, 42, 15, -22, -44, -36, -2, 33, 45, 26, -11, -40, | ||
565 | -42, -14, 23, 45, 35, 1, -34, -45, -25, 12, 41, 41, 13, -24, -45, -34, | ||
566 | }, { | ||
567 | 32, 28, -11, -41, -40, -8, 30, 45, 25, -14, -43, -38, -4, 33, 45, 22, | ||
568 | -17, -44, -36, -1, 35, 44, 19, -20, -44, -34, 2, 37, 43, 16, -23, -45, | ||
569 | -32, 6, 39, 42, 13, -26, -45, -30, 9, 40, 41, 10, -29, -45, -27, 12, | ||
570 | 42, 39, 7, -31, -45, -24, 15, 43, 38, 3, -34, -45, -21, 18, 44, 36, | ||
571 | }, { | ||
572 | 32, 26, -15, -44, -35, 3, 39, 41, 9, -31, -45, -20, 21, 45, 30, -10, | ||
573 | -42, -38, -2, 36, 43, 14, -27, -45, -25, 16, 44, 34, -4, -39, -41, -8, | ||
574 | 32, 45, 19, -22, -45, -30, 11, 42, 38, 1, -36, -43, -13, 28, 45, 24, | ||
575 | -17, -44, -34, 6, 40, 40, 7, -33, -44, -18, 23, 45, 29, -12, -43, -37, | ||
576 | }, { | ||
577 | 32, 24, -19, -45, -29, 14, 44, 33, -9, -42, -36, 3, 40, 39, 2, -37, | ||
578 | -42, -8, 34, 44, 13, -30, -45, -18, 25, 45, 23, -20, -45, -28, 15, 44, | ||
579 | 32, -10, -43, -36, 4, 40, 39, 1, -38, -41, -7, 34, 43, 12, -30, -45, | ||
580 | -17, 26, 45, 22, -21, -45, -27, 16, 44, 31, -11, -43, -35, 6, 41, 38, | ||
581 | }, { | ||
582 | 32, 22, -23, -45, -21, 24, 45, 20, -25, -45, -19, 26, 45, 18, -27, -45, | ||
583 | -17, 28, 45, 16, -29, -45, -15, 30, 44, 14, -30, -44, -13, 31, 44, 12, | ||
584 | -32, -44, -11, 33, 43, 10, -34, -43, -9, 34, 43, 8, -35, -42, -7, 36, | ||
585 | 42, 6, -36, -41, -4, 37, 41, 3, -38, -40, -2, 38, 40, 1, -39, -39, | ||
586 | }, { | ||
587 | 32, 20, -27, -45, -13, 33, 43, 6, -38, -39, 2, 41, 35, -10, -44, -30, | ||
588 | 17, 45, 23, -24, -45, -16, 30, 44, 9, -36, -41, -1, 40, 37, -7, -43, | ||
589 | -32, 14, 45, 26, -21, -45, -19, 28, 44, 12, -34, -42, -4, 38, 39, -3, | ||
590 | -42, -34, 11, 44, 29, -18, -45, -22, 25, 45, 15, -31, -43, -8, 36, 40, | ||
591 | }, { | ||
592 | 32, 18, -30, -43, -4, 39, 36, -10, -44, -26, 23, 45, 13, -34, -41, 1, | ||
593 | 42, 33, -15, -45, -21, 28, 44, 8, -38, -38, 7, 44, 29, -20, -45, -16, | ||
594 | 32, 42, 2, -40, -35, 12, 45, 24, -25, -45, -11, 36, 40, -3, -43, -31, | ||
595 | 17, 45, 19, -30, -43, -6, 39, 37, -9, -44, -27, 22, 45, 14, -34, -41, | ||
596 | }, { | ||
597 | 32, 16, -34, -40, 4, 44, 27, -24, -44, -8, 39, 36, -13, -45, -19, 31, | ||
598 | 42, -1, -43, -30, 21, 45, 11, -37, -38, 10, 45, 22, -29, -43, -2, 41, | ||
599 | 32, -18, -45, -14, 35, 39, -7, -44, -25, 26, 44, 6, -40, -34, 15, 45, | ||
600 | 17, -33, -41, 3, 43, 28, -23, -45, -9, 38, 36, -12, -45, -20, 30, 42, | ||
601 | }, { | ||
602 | 32, 14, -36, -37, 13, 45, 15, -36, -38, 12, 45, 16, -35, -38, 11, 45, | ||
603 | 17, -34, -39, 10, 45, 18, -34, -39, 9, 45, 19, -33, -40, 8, 45, 20, | ||
604 | -32, -40, 7, 45, 21, -31, -41, 6, 44, 22, -30, -41, 4, 44, 23, -30, | ||
605 | -42, 3, 44, 24, -29, -42, 2, 44, 25, -28, -43, 1, 43, 26, -27, -43, | ||
606 | }, { | ||
607 | 32, 12, -39, -33, 21, 44, 2, -43, -25, 30, 41, -8, -45, -16, 36, 36, | ||
608 | -17, -45, -7, 41, 29, -26, -43, 3, 44, 20, -34, -38, 13, 45, 11, -39, | ||
609 | -32, 22, 44, 1, -43, -24, 30, 40, -9, -45, -15, 37, 35, -18, -45, -6, | ||
610 | 42, 28, -27, -42, 4, 45, 19, -34, -38, 14, 45, 10, -40, -31, 23, 44, | ||
611 | }, { | ||
612 | 32, 10, -41, -28, 29, 40, -11, -45, -9, 41, 27, -30, -40, 12, 45, 8, | ||
613 | -42, -26, 30, 39, -13, -45, -7, 42, 25, -31, -39, 14, 45, 6, -43, -24, | ||
614 | 32, 38, -15, -45, -4, 43, 23, -33, -38, 16, 45, 3, -43, -22, 34, 37, | ||
615 | -17, -45, -2, 44, 21, -34, -36, 18, 44, 1, -44, -20, 35, 36, -19, -44, | ||
616 | }, { | ||
617 | 32, 8, -43, -22, 35, 34, -23, -42, 9, 45, 7, -43, -21, 36, 34, -24, | ||
618 | -42, 10, 45, 6, -43, -20, 36, 33, -25, -41, 11, 45, 4, -44, -19, 37, | ||
619 | 32, -26, -41, 12, 45, 3, -44, -18, 38, 31, -27, -40, 13, 45, 2, -44, | ||
620 | -17, 38, 30, -28, -40, 14, 45, 1, -44, -16, 39, 30, -29, -39, 15, 45, | ||
621 | }, { | ||
622 | 32, 6, -44, -16, 40, 26, -34, -34, 25, 40, -15, -44, 4, 45, 7, -44, | ||
623 | -17, 39, 27, -33, -35, 24, 41, -14, -44, 3, 45, 8, -43, -18, 39, 28, | ||
624 | -32, -36, 23, 41, -13, -45, 2, 45, 9, -43, -19, 38, 29, -31, -36, 22, | ||
625 | 42, -12, -45, 1, 45, 10, -43, -20, 38, 30, -30, -37, 21, 42, -11, -45, | ||
626 | }, { | ||
627 | 32, 3, -45, -10, 43, 16, -41, -22, 38, 28, -34, -33, 29, 37, -23, -40, | ||
628 | 17, 43, -11, -45, 4, 45, 2, -45, -9, 44, 15, -41, -21, 38, 27, -34, | ||
629 | -32, 30, 36, -24, -40, 18, 43, -12, -44, 6, 45, 1, -45, -8, 44, 14, | ||
630 | -42, -20, 39, 26, -35, -31, 30, 36, -25, -39, 19, 42, -13, -44, 7, 45, | ||
631 | }, { | ||
632 | 32, 1, -45, -3, 45, 6, -45, -8, 44, 10, -44, -12, 43, 14, -43, -16, | ||
633 | 42, 18, -41, -20, 40, 22, -39, -24, 38, 26, -36, -28, 35, 30, -34, -31, | ||
634 | 32, 33, -30, -34, 29, 36, -27, -37, 25, 38, -23, -39, 21, 40, -19, -41, | ||
635 | 17, 42, -15, -43, 13, 44, -11, -44, 9, 45, -7, -45, 4, 45, -2, -45, | ||
636 | }, { | ||
637 | 32, -1, -45, 3, 45, -6, -45, 8, 44, -10, -44, 12, 43, -14, -43, 16, | ||
638 | 42, -18, -41, 20, 40, -22, -39, 24, 38, -26, -36, 28, 35, -30, -34, 31, | ||
639 | 32, -33, -30, 34, 29, -36, -27, 37, 25, -38, -23, 39, 21, -40, -19, 41, | ||
640 | 17, -42, -15, 43, 13, -44, -11, 44, 9, -45, -7, 45, 4, -45, -2, 45, | ||
641 | }, { | ||
642 | 32, -3, -45, 10, 43, -16, -41, 22, 38, -28, -34, 33, 29, -37, -23, 40, | ||
643 | 17, -43, -11, 45, 4, -45, 2, 45, -9, -44, 15, 41, -21, -38, 27, 34, | ||
644 | -32, -30, 36, 24, -40, -18, 43, 12, -44, -6, 45, -1, -45, 8, 44, -14, | ||
645 | -42, 20, 39, -26, -35, 31, 30, -36, -25, 39, 19, -42, -13, 44, 7, -45, | ||
646 | }, { | ||
647 | 32, -6, -44, 16, 40, -26, -34, 34, 25, -40, -15, 44, 4, -45, 7, 44, | ||
648 | -17, -39, 27, 33, -35, -24, 41, 14, -44, -3, 45, -8, -43, 18, 39, -28, | ||
649 | -32, 36, 23, -41, -13, 45, 2, -45, 9, 43, -19, -38, 29, 31, -36, -22, | ||
650 | 42, 12, -45, -1, 45, -10, -43, 20, 38, -30, -30, 37, 21, -42, -11, 45, | ||
651 | }, { | ||
652 | 32, -8, -43, 22, 35, -34, -23, 42, 9, -45, 7, 43, -21, -36, 34, 24, | ||
653 | -42, -10, 45, -6, -43, 20, 36, -33, -25, 41, 11, -45, 4, 44, -19, -37, | ||
654 | 32, 26, -41, -12, 45, -3, -44, 18, 38, -31, -27, 40, 13, -45, 2, 44, | ||
655 | -17, -38, 30, 28, -40, -14, 45, -1, -44, 16, 39, -30, -29, 39, 15, -45, | ||
656 | }, { | ||
657 | 32, -10, -41, 28, 29, -40, -11, 45, -9, -41, 27, 30, -40, -12, 45, -8, | ||
658 | -42, 26, 30, -39, -13, 45, -7, -42, 25, 31, -39, -14, 45, -6, -43, 24, | ||
659 | 32, -38, -15, 45, -4, -43, 23, 33, -38, -16, 45, -3, -43, 22, 34, -37, | ||
660 | -17, 45, -2, -44, 21, 34, -36, -18, 44, -1, -44, 20, 35, -36, -19, 44, | ||
661 | }, { | ||
662 | 32, -12, -39, 33, 21, -44, 2, 43, -25, -30, 41, 8, -45, 16, 36, -36, | ||
663 | -17, 45, -7, -41, 29, 26, -43, -3, 44, -20, -34, 38, 13, -45, 11, 39, | ||
664 | -32, -22, 44, -1, -43, 24, 30, -40, -9, 45, -15, -37, 35, 18, -45, 6, | ||
665 | 42, -28, -27, 42, 4, -45, 19, 34, -38, -14, 45, -10, -40, 31, 23, -44, | ||
666 | }, { | ||
667 | 32, -14, -36, 37, 13, -45, 15, 36, -38, -12, 45, -16, -35, 38, 11, -45, | ||
668 | 17, 34, -39, -10, 45, -18, -34, 39, 9, -45, 19, 33, -40, -8, 45, -20, | ||
669 | -32, 40, 7, -45, 21, 31, -41, -6, 44, -22, -30, 41, 4, -44, 23, 30, | ||
670 | -42, -3, 44, -24, -29, 42, 2, -44, 25, 28, -43, -1, 43, -26, -27, 43, | ||
671 | }, { | ||
672 | 32, -16, -34, 40, 4, -44, 27, 24, -44, 8, 39, -36, -13, 45, -19, -31, | ||
673 | 42, 1, -43, 30, 21, -45, 11, 37, -38, -10, 45, -22, -29, 43, -2, -41, | ||
674 | 32, 18, -45, 14, 35, -39, -7, 44, -25, -26, 44, -6, -40, 34, 15, -45, | ||
675 | 17, 33, -41, -3, 43, -28, -23, 45, -9, -38, 36, 12, -45, 20, 30, -42, | ||
676 | }, { | ||
677 | 32, -18, -30, 43, -4, -39, 36, 10, -44, 26, 23, -45, 13, 34, -41, -1, | ||
678 | 42, -33, -15, 45, -21, -28, 44, -8, -38, 38, 7, -44, 29, 20, -45, 16, | ||
679 | 32, -42, 2, 40, -35, -12, 45, -24, -25, 45, -11, -36, 40, 3, -43, 31, | ||
680 | 17, -45, 19, 30, -43, 6, 39, -37, -9, 44, -27, -22, 45, -14, -34, 41, | ||
681 | }, { | ||
682 | 32, -20, -27, 45, -13, -33, 43, -6, -38, 39, 2, -41, 35, 10, -44, 30, | ||
683 | 17, -45, 23, 24, -45, 16, 30, -44, 9, 36, -41, 1, 40, -37, -7, 43, | ||
684 | -32, -14, 45, -26, -21, 45, -19, -28, 44, -12, -34, 42, -4, -38, 39, 3, | ||
685 | -42, 34, 11, -44, 29, 18, -45, 22, 25, -45, 15, 31, -43, 8, 36, -40, | ||
686 | }, { | ||
687 | 32, -22, -23, 45, -21, -24, 45, -20, -25, 45, -19, -26, 45, -18, -27, 45, | ||
688 | -17, -28, 45, -16, -29, 45, -15, -30, 44, -14, -30, 44, -13, -31, 44, -12, | ||
689 | -32, 44, -11, -33, 43, -10, -34, 43, -9, -34, 43, -8, -35, 42, -7, -36, | ||
690 | 42, -6, -36, 41, -4, -37, 41, -3, -38, 40, -2, -38, 40, -1, -39, 39, | ||
691 | }, { | ||
692 | 32, -24, -19, 45, -29, -14, 44, -33, -9, 42, -36, -3, 40, -39, 2, 37, | ||
693 | -42, 8, 34, -44, 13, 30, -45, 18, 25, -45, 23, 20, -45, 28, 15, -44, | ||
694 | 32, 10, -43, 36, 4, -40, 39, -1, -38, 41, -7, -34, 43, -12, -30, 45, | ||
695 | -17, -26, 45, -22, -21, 45, -27, -16, 44, -31, -11, 43, -35, -6, 41, -38, | ||
696 | }, { | ||
697 | 32, -26, -15, 44, -35, -3, 39, -41, 9, 31, -45, 20, 21, -45, 30, 10, | ||
698 | -42, 38, -2, -36, 43, -14, -27, 45, -25, -16, 44, -34, -4, 39, -41, 8, | ||
699 | 32, -45, 19, 22, -45, 30, 11, -42, 38, -1, -36, 43, -13, -28, 45, -24, | ||
700 | -17, 44, -34, -6, 40, -40, 7, 33, -44, 18, 23, -45, 29, 12, -43, 37, | ||
701 | }, { | ||
702 | 32, -28, -11, 41, -40, 8, 30, -45, 25, 14, -43, 38, -4, -33, 45, -22, | ||
703 | -17, 44, -36, 1, 35, -44, 19, 20, -44, 34, 2, -37, 43, -16, -23, 45, | ||
704 | -32, -6, 39, -42, 13, 26, -45, 30, 9, -40, 41, -10, -29, 45, -27, -12, | ||
705 | 42, -39, 7, 31, -45, 24, 15, -43, 38, -3, -34, 45, -21, -18, 44, -36, | ||
706 | }, { | ||
707 | 32, -30, -7, 38, -43, 18, 19, -44, 38, -6, -30, 45, -29, -8, 39, -43, | ||
708 | 17, 20, -44, 37, -4, -31, 45, -28, -9, 39, -43, 16, 21, -44, 36, -3, | ||
709 | -32, 45, -27, -10, 40, -42, 15, 22, -44, 36, -2, -33, 45, -26, -11, 40, | ||
710 | -42, 14, 23, -45, 35, -1, -34, 45, -25, -12, 41, -41, 13, 24, -45, 34, | ||
711 | }, { | ||
712 | 32, -31, -2, 34, -45, 28, 7, -37, 44, -24, -11, 39, -43, 20, 15, -41, | ||
713 | 42, -16, -19, 43, -40, 12, 23, -44, 38, -8, -27, 45, -35, 3, 30, -45, | ||
714 | 32, 1, -34, 45, -29, -6, 36, -45, 25, 10, -39, 44, -21, -14, 41, -42, | ||
715 | 17, 18, -43, 40, -13, -22, 44, -38, 9, 26, -45, 36, -4, -30, 45, -33, | ||
716 | }, { | ||
717 | 32, -33, 2, 30, -45, 36, -7, -26, 44, -38, 11, 22, -43, 40, -15, -18, | ||
718 | 42, -42, 19, 14, -40, 44, -23, -10, 38, -45, 27, 6, -35, 45, -30, -1, | ||
719 | 32, -45, 34, -3, -29, 45, -36, 8, 25, -44, 39, -12, -21, 43, -41, 16, | ||
720 | 17, -41, 43, -20, -13, 39, -44, 24, 9, -37, 45, -28, -4, 34, -45, 31, | ||
721 | }, { | ||
722 | 32, -34, 7, 24, -43, 41, -19, -12, 38, -45, 30, -1, -29, 45, -39, 14, | ||
723 | 17, -40, 44, -26, -4, 33, -45, 36, -9, -22, 43, -42, 21, 10, -36, 45, | ||
724 | -32, 3, 27, -44, 40, -16, -15, 39, -44, 28, 2, -31, 45, -37, 11, 20, | ||
725 | -42, 43, -23, -8, 35, -45, 34, -6, -25, 44, -41, 18, 13, -38, 45, -30, | ||
726 | }, { | ||
727 | 32, -36, 11, 18, -40, 45, -30, 3, 25, -43, 43, -24, -4, 31, -45, 39, | ||
728 | -17, -12, 36, -45, 35, -10, -19, 40, -44, 30, -2, -26, 43, -42, 23, 6, | ||
729 | -32, 45, -39, 16, 13, -37, 45, -34, 9, 20, -41, 44, -29, 1, 27, -44, | ||
730 | 42, -22, -7, 33, -45, 38, -15, -14, 38, -45, 34, -8, -21, 41, -44, 28, | ||
731 | }, { | ||
732 | 32, -37, 15, 12, -35, 45, -39, 18, 9, -33, 45, -40, 21, 6, -30, 44, | ||
733 | -42, 24, 2, -28, 43, -43, 27, -1, -25, 42, -44, 30, -4, -22, 41, -45, | ||
734 | 32, -8, -19, 39, -45, 34, -11, -16, 38, -45, 36, -14, -13, 36, -45, 38, | ||
735 | -17, -10, 34, -45, 40, -20, -7, 31, -44, 41, -23, -3, 29, -44, 43, -26, | ||
736 | }, { | ||
737 | 32, -38, 19, 6, -29, 43, -44, 31, -9, -16, 36, -45, 40, -22, -2, 26, | ||
738 | -42, 45, -34, 12, 13, -34, 45, -41, 25, -1, -23, 40, -45, 36, -15, -10, | ||
739 | 32, -44, 43, -28, 4, 20, -39, 45, -38, 18, 7, -30, 43, -44, 30, -8, | ||
740 | -17, 37, -45, 39, -21, -3, 27, -42, 44, -33, 11, 14, -35, 45, -41, 24, | ||
741 | }, { | ||
742 | 32, -39, 23, -1, -21, 38, -45, 40, -25, 3, 19, -37, 45, -41, 27, -6, | ||
743 | -17, 36, -45, 42, -29, 8, 15, -34, 44, -43, 30, -10, -13, 33, -44, 44, | ||
744 | -32, 12, 11, -31, 43, -44, 34, -14, -9, 30, -43, 45, -35, 16, 7, -28, | ||
745 | 42, -45, 36, -18, -4, 26, -41, 45, -38, 20, 2, -24, 40, -45, 39, -22, | ||
746 | }, { | ||
747 | 32, -40, 27, -8, -13, 31, -43, 45, -38, 22, -2, -18, 35, -44, 44, -34, | ||
748 | 17, 3, -23, 38, -45, 42, -30, 12, 9, -28, 41, -45, 40, -26, 7, 14, | ||
749 | -32, 43, -45, 37, -21, 1, 19, -36, 44, -44, 34, -16, -4, 24, -39, 45, | ||
750 | -42, 30, -11, -10, 29, -41, 45, -39, 25, -6, -15, 33, -43, 45, -36, 20, | ||
751 | }, { | ||
752 | 32, -41, 30, -14, -4, 22, -36, 44, -44, 37, -23, 6, 13, -30, 41, -45, | ||
753 | 42, -31, 15, 3, -21, 36, -44, 45, -38, 24, -7, -12, 29, -40, 45, -42, | ||
754 | 32, -16, -2, 20, -35, 44, -45, 38, -25, 8, 11, -28, 40, -45, 43, -33, | ||
755 | 17, 1, -19, 34, -43, 45, -39, 26, -9, -10, 27, -39, 45, -43, 34, -18, | ||
756 | }, { | ||
757 | 32, -42, 34, -20, 4, 12, -27, 38, -44, 45, -39, 28, -13, -3, 19, -33, | ||
758 | 42, -45, 43, -34, 21, -6, -11, 26, -38, 44, -45, 39, -29, 14, 2, -18, | ||
759 | 32, -41, 45, -43, 35, -22, 7, 10, -25, 37, -44, 45, -40, 30, -15, -1, | ||
760 | 17, -31, 41, -45, 43, -36, 23, -8, -9, 24, -36, 44, -45, 40, -30, 16, | ||
761 | }, { | ||
762 | 32, -43, 36, -26, 13, 1, -15, 28, -38, 44, -45, 42, -35, 24, -11, -3, | ||
763 | 17, -30, 39, -44, 45, -41, 34, -22, 9, 6, -19, 31, -40, 45, -45, 40, | ||
764 | -32, 20, -7, -8, 21, -33, 41, -45, 44, -39, 30, -18, 4, 10, -23, 34, | ||
765 | -42, 45, -44, 38, -29, 16, -2, -12, 25, -36, 43, -45, 43, -37, 27, -14, | ||
766 | }, { | ||
767 | 32, -44, 39, -31, 21, -10, -2, 14, -25, 34, -41, 45, -45, 42, -36, 28, | ||
768 | -17, 6, 7, -18, 29, -37, 43, -45, 44, -40, 34, -24, 13, -1, -11, 22, | ||
769 | -32, 39, -44, 45, -43, 38, -30, 20, -9, -3, 15, -26, 35, -41, 45, -45, | ||
770 | 42, -36, 27, -16, 4, 8, -19, 30, -38, 43, -45, 44, -40, 33, -23, 12, | ||
771 | }, { | ||
772 | 32, -44, 41, -36, 29, -20, 11, -1, -9, 18, -27, 34, -40, 44, -45, 45, | ||
773 | -42, 37, -30, 22, -13, 3, 7, -16, 25, -33, 39, -43, 45, -45, 43, -38, | ||
774 | 32, -24, 15, -6, -4, 14, -23, 31, -38, 42, -45, 45, -43, 39, -34, 26, | ||
775 | -17, 8, 2, -12, 21, -30, 36, -41, 44, -45, 44, -40, 35, -28, 19, -10, | ||
776 | }, { | ||
777 | 32, -45, 43, -39, 35, -30, 23, -16, 9, -1, -7, 14, -21, 28, -34, 38, | ||
778 | -42, 44, -45, 45, -43, 40, -36, 31, -25, 18, -11, 3, 4, -12, 19, -26, | ||
779 | 32, -37, 41, -44, 45, -45, 44, -41, 38, -33, 27, -20, 13, -6, -2, 10, | ||
780 | -17, 24, -30, 36, -40, 43, -45, 45, -44, 42, -39, 34, -29, 22, -15, 8, | ||
781 | }, { | ||
782 | 32, -45, 44, -42, 40, -37, 34, -30, 25, -20, 15, -10, 4, 1, -7, 12, | ||
783 | -17, 22, -27, 31, -35, 38, -41, 43, -44, 45, -45, 45, -43, 41, -39, 36, | ||
784 | -32, 28, -23, 18, -13, 8, -2, -3, 9, -14, 19, -24, 29, -33, 36, -39, | ||
785 | 42, -44, 45, -45, 45, -44, 43, -40, 38, -34, 30, -26, 21, -16, 11, -6, | ||
786 | }, { | ||
787 | 32, -45, 45, -44, 43, -42, 41, -39, 38, -36, 34, -31, 29, -26, 23, -20, | ||
788 | 17, -14, 11, -8, 4, -1, -2, 6, -9, 12, -15, 18, -21, 24, -27, 30, | ||
789 | -32, 34, -36, 38, -40, 41, -43, 44, -44, 45, -45, 45, -45, 45, -44, 43, | ||
790 | -42, 40, -39, 37, -35, 33, -30, 28, -25, 22, -19, 16, -13, 10, -7, 3, | ||
791 | }, { | ||
792 | 32, -45, 45, -45, 45, -45, 45, -45, 44, -44, 44, -44, 43, -43, 43, -42, | ||
793 | 42, -41, 41, -40, 40, -39, 39, -38, 38, -37, 36, -36, 35, -34, 34, -33, | ||
794 | 32, -31, 30, -30, 29, -28, 27, -26, 25, -24, 23, -22, 21, -20, 19, -18, | ||
795 | 17, -16, 15, -14, 13, -12, 11, -10, 9, -8, 7, -6, 4, -3, 2, -1, | ||
796 | } | ||
797 | }; | ||
798 | |||
799 | struct H274HashContext { | ||
800 | int type; | ||
801 | struct AVMD5 *ctx; | ||
802 | |||
803 | #if HAVE_BIGENDIAN | ||
804 | BswapDSPContext bdsp; | ||
805 | uint8_t *buf; | ||
806 | int buf_size; | ||
807 | #endif | ||
808 | }; | ||
809 | |||
810 | ✗ | static av_always_inline void bswap16_buf_if_be(H274HashContext *s, const int ps, const uint8_t **src, const int w) | |
811 | { | ||
812 | #if HAVE_BIGENDIAN | ||
813 | if (ps) { | ||
814 | s->bdsp.bswap16_buf((uint16_t *)s->buf, | ||
815 | (const uint16_t *)*src, w); | ||
816 | *src = s->buf; | ||
817 | } | ||
818 | #endif | ||
819 | ✗ | } | |
820 | |||
821 | ✗ | static int verify_plane_md5(H274HashContext *s, | |
822 | const uint8_t *_src, const int w, const int h, const int stride, | ||
823 | const int ps, const uint8_t *expected) | ||
824 | { | ||
825 | #define MD5_SIZE 16 | ||
826 | ✗ | struct AVMD5 *ctx = s->ctx; | |
827 | uint8_t md5[MD5_SIZE]; | ||
828 | |||
829 | ✗ | av_md5_init(ctx); | |
830 | ✗ | for (int j = 0; j < h; j++) { | |
831 | ✗ | const uint8_t *src = &_src[j * stride]; | |
832 | ✗ | bswap16_buf_if_be(s, ps, &src, w); | |
833 | ✗ | av_md5_update(ctx, src, w << ps); | |
834 | ✗ | src += stride; | |
835 | } | ||
836 | ✗ | av_md5_final(ctx, md5); | |
837 | |||
838 | ✗ | if (memcmp(md5, expected, MD5_SIZE)) | |
839 | ✗ | return AVERROR_INVALIDDATA; | |
840 | |||
841 | ✗ | return 0; | |
842 | } | ||
843 | |||
844 | ✗ | static int verify_plane_crc(H274HashContext *s, const uint8_t *_src, const int w, const int h, const int stride, | |
845 | const int ps, uint16_t expected) | ||
846 | { | ||
847 | ✗ | uint32_t crc = 0x0F1D; // CRC-16-CCITT-AUG | |
848 | ✗ | const AVCRC *ctx = av_crc_get_table(AV_CRC_16_CCITT); | |
849 | |||
850 | ✗ | for (int j = 0; j < h; j++) { | |
851 | ✗ | const uint8_t *src = &_src[j * stride]; | |
852 | ✗ | bswap16_buf_if_be(s, ps, &src, w); | |
853 | ✗ | crc = av_crc(ctx, crc, src, w << ps); | |
854 | ✗ | src += stride; | |
855 | } | ||
856 | ✗ | crc = av_bswap16(crc); | |
857 | |||
858 | ✗ | if (crc != expected) | |
859 | ✗ | return AVERROR_INVALIDDATA; | |
860 | |||
861 | ✗ | return 0; | |
862 | } | ||
863 | |||
864 | #define CAL_CHECKSUM(pixel) ((pixel) ^ xor_mask) | ||
865 | ✗ | static int verify_plane_checksum(const uint8_t *src, const int w, const int h, const int stride, const int ps, | |
866 | uint32_t expected) | ||
867 | { | ||
868 | ✗ | uint32_t checksum = 0; | |
869 | ✗ | expected = av_le2ne32(expected); | |
870 | |||
871 | ✗ | for (int y = 0; y < h; y++) { | |
872 | ✗ | for (int x = 0; x < w; x++) { | |
873 | ✗ | const int xor_mask = (x & 0xFF) ^ (y & 0xFF) ^ (x >> 8) ^ (y >> 8); | |
874 | ✗ | checksum += CAL_CHECKSUM(src[x << ps]); | |
875 | ✗ | if (ps) | |
876 | ✗ | checksum += CAL_CHECKSUM(src[(x << ps) + 1]); | |
877 | } | ||
878 | ✗ | src += stride; | |
879 | } | ||
880 | |||
881 | ✗ | if (checksum != expected) | |
882 | ✗ | return AVERROR_INVALIDDATA; | |
883 | |||
884 | ✗ | return 0; | |
885 | } | ||
886 | |||
887 | enum { | ||
888 | HASH_MD5SUM, | ||
889 | HASH_CRC, | ||
890 | HASH_CHECKSUM, | ||
891 | HASH_LAST = HASH_CHECKSUM, | ||
892 | }; | ||
893 | |||
894 | 94 | void ff_h274_hash_freep(H274HashContext **ctx) | |
895 | { | ||
896 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
|
94 | if (*ctx) { |
897 | ✗ | H274HashContext *c = *ctx; | |
898 | ✗ | if (c->ctx) | |
899 | ✗ | av_free(c->ctx); | |
900 | ✗ | av_freep(ctx); | |
901 | #if HAVE_BIGENDIAN | ||
902 | av_freep(&c->buf); | ||
903 | #endif | ||
904 | } | ||
905 | 94 | } | |
906 | |||
907 | ✗ | int ff_h274_hash_init(H274HashContext **ctx, const int type) | |
908 | { | ||
909 | H274HashContext *c; | ||
910 | |||
911 | ✗ | if (type > HASH_LAST || !ctx) | |
912 | ✗ | return AVERROR(EINVAL); | |
913 | |||
914 | ✗ | c = *ctx; | |
915 | ✗ | if (c) { | |
916 | ✗ | if (c->type != type) { | |
917 | ✗ | if (c->type == HASH_MD5SUM) | |
918 | ✗ | av_freep(&c->ctx); | |
919 | ✗ | c->type = type; | |
920 | } | ||
921 | } else { | ||
922 | ✗ | c = av_mallocz(sizeof(H274HashContext)); | |
923 | ✗ | if (!c) | |
924 | ✗ | return AVERROR(ENOMEM); | |
925 | ✗ | c->type = type; | |
926 | ✗ | *ctx = c; | |
927 | } | ||
928 | |||
929 | ✗ | if (type == HASH_MD5SUM && !c->ctx) { | |
930 | ✗ | c->ctx = av_md5_alloc(); | |
931 | ✗ | if (!c->ctx) | |
932 | ✗ | return AVERROR(ENOMEM); | |
933 | } | ||
934 | |||
935 | #if HAVE_BIGENDIAN | ||
936 | ff_bswapdsp_init(&c->bdsp); | ||
937 | #endif | ||
938 | |||
939 | ✗ | return 0; | |
940 | } | ||
941 | |||
942 | ✗ | int ff_h274_hash_verify(H274HashContext *c, const H274SEIPictureHash *hash, | |
943 | const AVFrame *frame, const int coded_width, const int coded_height) | ||
944 | { | ||
945 | const AVPixFmtDescriptor *desc; | ||
946 | ✗ | int err = 0; | |
947 | |||
948 | ✗ | if (!c || !hash || !frame) | |
949 | ✗ | return AVERROR(EINVAL); | |
950 | |||
951 | ✗ | if (c->type != hash->hash_type) | |
952 | ✗ | return AVERROR(EINVAL); | |
953 | |||
954 | ✗ | desc = av_pix_fmt_desc_get(frame->format); | |
955 | ✗ | if (!desc) | |
956 | ✗ | return AVERROR(EINVAL); | |
957 | |||
958 | ✗ | for (int i = 0; i < desc->nb_components; i++) { | |
959 | ✗ | const int w = i ? (coded_width >> desc->log2_chroma_w) : coded_width; | |
960 | ✗ | const int h = i ? (coded_height >> desc->log2_chroma_h) : coded_height; | |
961 | ✗ | const int ps = desc->comp[i].step - 1; | |
962 | ✗ | const uint8_t *src = frame->data[i]; | |
963 | ✗ | const int stride = frame->linesize[i]; | |
964 | |||
965 | #if HAVE_BIGENDIAN | ||
966 | if (c->type != HASH_CHECKSUM) { | ||
967 | if (ps) { | ||
968 | av_fast_malloc(&c->buf, &c->buf_size, | ||
969 | FFMAX3(frame->linesize[0], frame->linesize[1], | ||
970 | frame->linesize[2])); | ||
971 | if (!c->buf) | ||
972 | return AVERROR(ENOMEM); | ||
973 | } | ||
974 | } | ||
975 | #endif | ||
976 | |||
977 | ✗ | if (c->type == HASH_MD5SUM) | |
978 | ✗ | err = verify_plane_md5(c, src, w, h, stride, ps, hash->md5[i]); | |
979 | ✗ | else if (c->type == HASH_CRC) | |
980 | ✗ | err = verify_plane_crc(c, src, w, h, stride, ps, hash->crc[i]); | |
981 | ✗ | else if (c->type == HASH_CHECKSUM) | |
982 | ✗ | err = verify_plane_checksum(src, w, h, stride, ps, hash->checksum[i]); | |
983 | ✗ | if (err < 0) | |
984 | ✗ | goto fail; | |
985 | } | ||
986 | |||
987 | ✗ | fail: | |
988 | ✗ | return err; | |
989 | } | ||
990 |