FFmpeg
h274.c
Go to the documentation of this file.
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/imgutils.h"
30 
31 #include "h274.h"
32 
33 static const int8_t Gaussian_LUT[2048+4];
34 static const uint32_t Seed_LUT[256];
35 static const int8_t R64T[64][64];
36 
37 static void prng_shift(uint32_t *state)
38 {
39  // Primitive polynomial x^31 + x^3 + 1 (modulo 2)
40  uint32_t x = *state;
41  uint8_t feedback = 1u ^ (x >> 2) ^ (x >> 30);
42  *state = (x << 1) | (feedback & 1u);
43 }
44 
45 static void init_slice_c(int8_t out[64][64], uint8_t h, uint8_t v,
46  int16_t tmp[64][64])
47 {
48  static const uint8_t deblock_factors[13] = {
49  64, 71, 77, 84, 90, 96, 103, 109, 116, 122, 128, 128, 128
50  };
51 
52  const uint8_t deblock_coeff = deblock_factors[v];
53  const uint8_t freq_h = ((h + 3) << 2) - 1;
54  const uint8_t freq_v = ((v + 3) << 2) - 1;
55  uint32_t seed = Seed_LUT[h + v * 13];
56 
57  // Initialize with random gaussian values, using the output array as a
58  // temporary buffer for these intermediate values.
59  //
60  // Note: To make the subsequent matrix multiplication cache friendlier, we
61  // store each *column* of the starting image in a *row* of `out`
62  for (int l = 0; l <= freq_v; l++) {
63  for (int k = 0; k <= freq_h; k += 4) {
64  uint16_t offset = seed % 2048;
65  out[l][k + 0] = Gaussian_LUT[offset + 0];
66  out[l][k + 1] = Gaussian_LUT[offset + 1];
67  out[l][k + 2] = Gaussian_LUT[offset + 2];
68  out[l][k + 3] = Gaussian_LUT[offset + 3];
69  prng_shift(&seed);
70  }
71  }
72 
73  out[0][0] = 0;
74 
75  // 64x64 inverse integer transform
76  for (int y = 0; y < 64; y++) {
77  for (int x = 0; x <= freq_v; x++) {
78  int32_t sum = 0;
79  for (int p = 0; p <= freq_h; p++)
80  sum += R64T[y][p] * out[x][p];
81  tmp[y][x] = (sum + 128) >> 8;
82  }
83  }
84 
85  for (int y = 0; y < 64; y++) {
86  for (int x = 0; x < 64; x++) {
87  int32_t sum = 0;
88  for (int p = 0; p <= freq_v; p++)
89  sum += tmp[x][p] * R64T[y][p]; // R64T^T = R64
90  // Renormalize and clip to [-127, 127]
91  out[y][x] = av_clip((sum + 128) >> 8, -127, 127);
92  }
93  }
94 
95  // Deblock horizontal edges by simple attentuation of values
96  for (int y = 0; y < 64; y += 8) {
97  for (int x = 0; x < 64; x++) {
98  out[y + 0][x] = (out[y + 0][x] * deblock_coeff) >> 7;
99  out[y + 7][x] = (out[y + 7][x] * deblock_coeff) >> 7;
100  }
101  }
102 }
103 
104 static void init_slice(H274FilmGrainDatabase *database, uint8_t h, uint8_t v)
105 {
106  if (database->residency[h] & (1 << v))
107  return;
108 
109  database->residency[h] |= (1 << v);
110  init_slice_c(database->db[h][v], h, v, database->slice_tmp);
111 }
112 
113 // Computes the average of an 8x8 block
114 static uint16_t avg_8x8_c(const uint8_t *in, int in_stride)
115 {
116  uint16_t avg[8] = {0}; // summing over an array vectorizes better
117 
118  for (int y = 0; y < 8; y++) {
119  for (int x = 0; x < 8; x++)
120  avg[x] += in[x];
121  in += in_stride;
122  }
123 
124  return (avg[0] + avg[1] + avg[2] + avg[3] +
125  avg[4] + avg[5] + avg[6] + avg[7]) >> 6;
126 }
127 
128 // Synthesize an 8x8 block of film grain by copying the pattern from `db`
129 static void synth_grain_8x8_c(int8_t *out, const int out_stride,
130  const int16_t scale, const uint8_t shift,
131  const int8_t *db)
132 {
133  for (int y = 0; y < 8; y++) {
134  for (int x = 0; x < 8; x++)
135  out[x] = (scale * db[x]) >> shift;
136 
137  out += out_stride;
138  db += 64;
139  }
140 }
141 
142 // Deblock vertical edges of an 8x8 block, mixing with the previous block
143 static void deblock_8x8_c(int8_t *out, const int out_stride)
144 {
145  for (int y = 0; y < 8; y++) {
146  const int8_t l1 = out[-2], l0 = out[-1];
147  const int8_t r0 = out[0], r1 = out[1];
148  out[0] = (l0 + r0 * 2 + r1) >> 2;
149  out[-1] = (r0 + l0 * 2 + l1) >> 2;
150  out += out_stride;
151  }
152 }
153 
154 // Generates a single 8x8 block of grain, optionally also applying the
155 // deblocking step (note that this implies writing to the previous block).
156 static av_always_inline void generate(int8_t *out, int out_stride,
157  const uint8_t *in, int in_stride,
158  H274FilmGrainDatabase *database,
159  const AVFilmGrainH274Params *h274,
160  int c, int invert, int deblock,
161  int y_offset, int x_offset)
162 {
163  const uint8_t shift = h274->log2_scale_factor + 6;
164  const uint16_t avg = avg_8x8_c(in, in_stride);
165  int16_t scale;
166  uint8_t h, v;
167  int8_t s = -1;
168 
169  // FIXME: This logic only generates grain with a single
170  // intensity interval. Strictly speaking, the H.274 specification allows
171  // for overlapping intensity intervals, however SMPTE RDD 5-2006 (which
172  // concerns the implementation of H.274 for H.264) forbids this as it
173  // requires a nontrivial grain synthesis process (FFT).
174  //
175  // In principle, we should detect this possibility ahead of time and warn
176  // the user that the output is unlikely to be correct, or alternatively
177  // return an AVERROR_PATCHWELCOME.
178  for (int i = 0; i < h274->num_intensity_intervals[c]; i++) {
179  if (avg >= h274->intensity_interval_lower_bound[c][i] &&
180  avg <= h274->intensity_interval_upper_bound[c][i])
181  {
182  s = i;
183  break;
184  }
185  }
186 
187  if (s < 0) {
188  // No matching intensity interval, synthesize blank film grain
189  for (int y = 0; y < 8; y++)
190  memset(out + y * out_stride, 0, sizeof(int8_t[8]));
191  return;
192  }
193 
194  h = av_clip(h274->comp_model_value[c][s][1], 2, 14) - 2;
195  v = av_clip(h274->comp_model_value[c][s][2], 2, 14) - 2;
196  init_slice(database, h, v);
197 
198  scale = h274->comp_model_value[c][s][0];
199  if (invert)
200  scale = -scale;
201 
202  synth_grain_8x8_c(out, out_stride, scale, shift,
203  &database->db[h][v][y_offset][x_offset]);
204 
205  if (deblock)
206  deblock_8x8_c(out, out_stride);
207 }
208 
209 // Saturating 8-bit sum of a+b
210 static void add_8x8_clip_c(uint8_t *out, const uint8_t *a, const int8_t *b,
211  int n)
212 {
213  for (int i = 0; i < n; i++)
214  out[i] = av_clip_uint8(a[i] + b[i]);
215 }
216 
217 int ff_h274_apply_film_grain(AVFrame *out_frame, const AVFrame *in_frame,
218  H274FilmGrainDatabase *database,
219  const AVFilmGrainParams *params)
220 {
221  AVFilmGrainH274Params h274 = params->codec.h274;
223  if (h274.model_id != 0)
224  return AVERROR_PATCHWELCOME;
225 
226  av_assert1(out_frame->format == in_frame->format);
227  if (in_frame->format != AV_PIX_FMT_YUV420P)
228  return AVERROR_PATCHWELCOME;
229 
230  for (int c = 0; c < 3; c++) {
231  static const uint8_t color_offset[3] = { 0, 85, 170 };
232  uint32_t seed = Seed_LUT[(params->seed + color_offset[c]) % 256];
233  const int width = c > 0 ? AV_CEIL_RSHIFT(out_frame->width, 1) : out_frame->width;
234  const int height = c > 0 ? AV_CEIL_RSHIFT(out_frame->height, 1) : out_frame->height;
235 
236  uint8_t * const out = out_frame->data[c];
237  const int out_stride = out_frame->linesize[c];
238  int8_t * const grain = out_frame->data[c]; // re-use output buffer for grain
239  const int grain_stride = out_stride;
240  const uint8_t * const in = in_frame->data[c];
241  const int in_stride = in_frame->linesize[c];
242 
243  if (!h274.component_model_present[c]) {
244  av_image_copy_plane(out, out_stride, in, in_stride,
245  width * sizeof(uint8_t), height);
246  continue;
247  }
248 
249  if (c > 0) {
250  // Adaptation for 4:2:0 chroma subsampling
251  for (int i = 0; i < h274.num_intensity_intervals[c]; i++) {
252  h274.comp_model_value[c][i][0] >>= 1;
253  h274.comp_model_value[c][i][1] *= 2;
254  h274.comp_model_value[c][i][2] *= 2;
255  }
256  }
257 
258  // Film grain synthesis is done in 8x8 blocks, but the PRNG state is
259  // only advanced in 16x16 blocks, so use a nested loop
260  for (int y = 0; y < height; y += 16) {
261  for (int x = 0; x < width; x += 16) {
262  uint16_t x_offset = (seed >> 16) % 52;
263  uint16_t y_offset = (seed & 0xFFFF) % 56;
264  const int invert = (seed & 0x1);
265  x_offset &= 0xFFFC;
266  y_offset &= 0xFFF8;
267  prng_shift(&seed);
268 
269  for (int yy = 0; yy < 16 && y+yy < height; yy += 8) {
270  for (int xx = 0; xx < 16 && x+xx < width; xx += 8) {
271  generate(grain + (y+yy) * grain_stride + (x+xx), grain_stride,
272  in + (y+yy) * in_stride + (x+xx), in_stride,
273  database, &h274, c, invert, (x+xx) > 0,
274  y_offset + yy, x_offset + xx);
275  }
276  }
277  }
278  }
279 
280  // Final output blend pass, done after grain synthesis is complete
281  // because deblocking depends on previous grain values
282  for (int y = 0; y < height; y++) {
283  add_8x8_clip_c(out + y * out_stride, in + y * in_stride,
284  grain + y * grain_stride, width);
285  }
286  }
287 
288  return 0;
289 }
290 
291 // These tables are all taken from the SMPTE RDD 5-2006 specification
292 static const int8_t Gaussian_LUT[2048+4] = {
293  -11, 12, 103, -11, 42, -35, 12, 59, 77, 98, -87, 3, 65, -78, 45, 56, -51, 21,
294  13, -11, -20, -19, 33, -127, 17, -6, -105, 18, 19, 71, 48, -10, -38, 42,
295  -2, 75, -67, 52, -90, 33, -47, 21, -3, -56, 49, 1, -57, -42, -1, 120, -127,
296  -108, -49, 9, 14, 127, 122, 109, 52, 127, 2, 7, 114, 19, 30, 12, 77, 112,
297  82, -61, -127, 111, -52, -29, 2, -49, -24, 58, -29, -73, 12, 112, 67, 79,
298  -3, -114, -87, -6, -5, 40, 58, -81, 49, -27, -31, -34, -105, 50, 16, -24,
299  -35, -14, -15, -127, -55, -22, -55, -127, -112, 5, -26, -72, 127, 127, -2,
300  41, 87, -65, -16, 55, 19, 91, -81, -65, -64, 35, -7, -54, 99, -7, 88, 125,
301  -26, 91, 0, 63, 60, -14, -23, 113, -33, 116, 14, 26, 51, -16, 107, -8, 53,
302  38, -34, 17, -7, 4, -91, 6, 63, 63, -15, 39, -36, 19, 55, 17, -51, 40, 33,
303  -37, 126, -39, -118, 17, -30, 0, 19, 98, 60, 101, -12, -73, -17, -52, 98,
304  3, 3, 60, 33, -3, -2, 10, -42, -106, -38, 14, 127, 16, -127, -31, -86, -39,
305  -56, 46, -41, 75, 23, -19, -22, -70, 74, -54, -2, 32, -45, 17, -92, 59,
306  -64, -67, 56, -102, -29, -87, -34, -92, 68, 5, -74, -61, 93, -43, 14, -26,
307  -38, -126, -17, 16, -127, 64, 34, 31, 93, 17, -51, -59, 71, 77, 81, 127,
308  127, 61, 33, -106, -93, 0, 0, 75, -69, 71, 127, -19, -111, 30, 23, 15, 2,
309  39, 92, 5, 42, 2, -6, 38, 15, 114, -30, -37, 50, 44, 106, 27, 119, 7, -80,
310  25, -68, -21, 92, -11, -1, 18, 41, -50, 79, -127, -43, 127, 18, 11, -21,
311  32, -52, 27, -88, -90, -39, -19, -10, 24, -118, 72, -24, -44, 2, 12, 86,
312  -107, 39, -33, -127, 47, 51, -24, -22, 46, 0, 15, -35, -69, -2, -74, 24,
313  -6, 0, 29, -3, 45, 32, -32, 117, -45, 79, -24, -17, -109, -10, -70, 88,
314  -48, 24, -91, 120, -37, 50, -127, 58, 32, -82, -10, -17, -7, 46, -127, -15,
315  89, 127, 17, 98, -39, -33, 37, 42, -40, -32, -21, 105, -19, 19, 19, -59,
316  -9, 30, 0, -127, 34, 127, -84, 75, 24, -40, -49, -127, -107, -14, 45, -75,
317  1, 30, -20, 41, -68, -40, 12, 127, -3, 5, 20, -73, -59, -127, -3, -3, -53,
318  -6, -119, 93, 120, -80, -50, 0, 20, -46, 67, 78, -12, -22, -127, 36, -41,
319  56, 119, -5, -116, -22, 68, -14, -90, 24, -82, -44, -127, 107, -25, -37,
320  40, -7, -7, -82, 5, -87, 44, -34, 9, -127, 39, 70, 49, -63, 74, -49, 109,
321  -27, -89, -47, -39, 44, 49, -4, 60, -42, 80, 9, -127, -9, -56, -49, 125,
322  -66, 47, 36, 117, 15, -11, -96, 109, 94, -17, -56, 70, 8, -14, -5, 50, 37,
323  -45, 120, -30, -76, 40, -46, 6, 3, 69, 17, -78, 1, -79, 6, 127, 43, 26,
324  127, -127, 28, -55, -26, 55, 112, 48, 107, -1, -77, -1, 53, -9, -22, -43,
325  123, 108, 127, 102, 68, 46, 5, 1, 123, -13, -55, -34, -49, 89, 65, -105,
326  -5, 94, -53, 62, 45, 30, 46, 18, -35, 15, 41, 47, -98, -24, 94, -75, 127,
327  -114, 127, -68, 1, -17, 51, -95, 47, 12, 34, -45, -75, 89, -107, -9, -58,
328  -29, -109, -24, 127, -61, -13, 77, -45, 17, 19, 83, -24, 9, 127, -66, 54,
329  4, 26, 13, 111, 43, -113, -22, 10, -24, 83, 67, -14, 75, -123, 59, 127,
330  -12, 99, -19, 64, -38, 54, 9, 7, 61, -56, 3, -57, 113, -104, -59, 3, -9,
331  -47, 74, 85, -55, -34, 12, 118, 28, 93, -72, 13, -99, -72, -20, 30, 72,
332  -94, 19, -54, 64, -12, -63, -25, 65, 72, -10, 127, 0, -127, 103, -20, -73,
333  -112, -103, -6, 28, -42, -21, -59, -29, -26, 19, -4, -51, 94, -58, -95,
334  -37, 35, 20, -69, 127, -19, -127, -22, -120, -53, 37, 74, -127, -1, -12,
335  -119, -53, -28, 38, 69, 17, 16, -114, 89, 62, 24, 37, -23, 49, -101, -32,
336  -9, -95, -53, 5, 93, -23, -49, -8, 51, 3, -75, -90, -10, -39, 127, -86,
337  -22, 20, 20, 113, 75, 52, -31, 92, -63, 7, -12, 46, 36, 101, -43, -17, -53,
338  -7, -38, -76, -31, -21, 62, 31, 62, 20, -127, 31, 64, 36, 102, -85, -10,
339  77, 80, 58, -79, -8, 35, 8, 80, -24, -9, 3, -17, 72, 127, 83, -87, 55, 18,
340  -119, -123, 36, 10, 127, 56, -55, 113, 13, 26, 32, -13, -48, 22, -13, 5,
341  58, 27, 24, 26, -11, -36, 37, -92, 78, 81, 9, 51, 14, 67, -13, 0, 32, 45,
342  -76, 32, -39, -22, -49, -127, -27, 31, -9, 36, 14, 71, 13, 57, 12, -53,
343  -86, 53, -44, -35, 2, 127, 12, -66, -44, 46, -115, 3, 10, 56, -35, 119,
344  -19, -61, 52, -59, -127, -49, -23, 4, -5, 17, -82, -6, 127, 25, 79, 67, 64,
345  -25, 14, -64, -37, -127, -28, 21, -63, 66, -53, -41, 109, -62, 15, -22, 13,
346  29, -63, 20, 27, 95, -44, -59, -116, -10, 79, -49, 22, -43, -16, 46, -47,
347  -120, -36, -29, -52, -44, 29, 127, -13, 49, -9, -127, 75, -28, -23, 88, 59,
348  11, -95, 81, -59, 58, 60, -26, 40, -92, -3, -22, -58, -45, -59, -22, -53,
349  71, -29, 66, -32, -23, 14, -17, -66, -24, -28, -62, 47, 38, 17, 16, -37,
350  -24, -11, 8, -27, -19, 59, 45, -49, -47, -4, -22, -81, 30, -67, -127, 74,
351  102, 5, -18, 98, 34, -66, 42, -52, 7, -59, 24, -58, -19, -24, -118, -73,
352  91, 15, -16, 79, -32, -79, -127, -36, 41, 77, -83, 2, 56, 22, -75, 127,
353  -16, -21, 12, 31, 56, -113, -127, 90, 55, 61, 12, 55, -14, -113, -14, 32,
354  49, -67, -17, 91, -10, 1, 21, 69, -70, 99, -19, -112, 66, -90, -10, -9,
355  -71, 127, 50, -81, -49, 24, 61, -61, -111, 7, -41, 127, 88, -66, 108, -127,
356  -6, 36, -14, 41, -50, 14, 14, 73, -101, -28, 77, 127, -8, -100, 88, 38,
357  121, 88, -125, -60, 13, -94, -115, 20, -67, -87, -94, -119, 44, -28, -30,
358  18, 5, -53, -61, 20, -43, 11, -77, -60, 13, 29, 3, 6, -72, 38, -60, -11,
359  108, -53, 41, 66, -12, -127, -127, -49, 24, 29, 46, 36, 91, 34, -33, 116,
360  -51, -34, -52, 91, 7, -83, 73, -26, -103, 24, -10, 76, 84, 5, 68, -80, -13,
361  -17, -32, -48, 20, 50, 26, 10, 63, -104, -14, 37, 127, 114, 97, 35, 1, -33,
362  -55, 127, -124, -33, 61, -7, 119, -32, -127, -53, -42, 63, 3, -5, -26, 70,
363  -58, -33, -44, -43, 34, -56, -127, 127, 25, -35, -11, 16, -81, 29, -58, 40,
364  -127, -127, 20, -47, -11, -36, -63, -52, -32, -82, 78, -76, -73, 8, 27,
365  -72, -9, -74, -85, -86, -57, 25, 78, -10, -97, 35, -65, 8, -59, 14, 1, -42,
366  32, -88, -44, 17, -3, -9, 59, 40, 12, -108, -40, 24, 34, 18, -28, 2, 51,
367  -110, -4, 100, 1, 65, 22, 0, 127, 61, 45, 25, -31, 6, 9, -7, -48, 99, 16,
368  44, -2, -40, 32, -39, -52, 10, -110, -19, 56, -127, 69, 26, 51, 92, 40, 61,
369  -52, 45, -38, 13, 85, 122, 27, 66, 45, -111, -83, -3, 31, 37, 19, -36, 58,
370  71, 39, -78, -47, 58, -78, 8, -62, -36, -14, 61, 42, -127, 71, -4, 24, -54,
371  52, -127, 67, -4, -42, 30, -63, 59, -3, -1, -18, -46, -92, -81, -96, -14,
372  -53, -10, -11, -77, 13, 1, 8, -67, -127, 127, -28, 26, -14, 18, -13, -26,
373  2, 10, -46, -32, -15, 27, -31, -59, 59, 77, -121, 28, 40, -54, -62, -31,
374  -21, -37, -32, -6, -127, -25, -60, 70, -127, 112, -127, 127, 88, -7, 116,
375  110, 53, 87, -127, 3, 16, 23, 74, -106, -51, 3, 74, -82, -112, -74, 65, 81,
376  25, 53, 127, -45, -50, -103, -41, -65, -29, 79, -67, 64, -33, -30, -8, 127,
377  0, -13, -51, 67, -14, 5, -92, 29, -35, -8, -90, -57, -3, 36, 43, 44, -31,
378  -69, -7, 36, 39, -51, 43, -81, 58, 6, 127, 12, 57, 66, 46, 59, -43, -42,
379  41, -15, -120, 24, 3, -11, 19, -13, 51, 28, 3, 55, -48, -12, -1, 2, 97,
380  -19, 29, 42, 13, 43, 78, -44, 56, -108, -43, -19, 127, 15, -11, -18, -81,
381  83, -37, 77, -109, 15, 65, -50, 43, 12, 13, 27, 28, 61, 57, 30, 26, 106,
382  -18, 56, 13, 97, 4, -8, -62, -103, 94, 108, -44, 52, 27, -47, -9, 105, -53,
383  46, 89, 103, -33, 38, -34, 55, 51, 70, -94, -35, -87, -107, -19, -31, 9,
384  -19, 79, -14, 77, 5, -19, -107, 85, 21, -45, -39, -42, 9, -29, 74, 47, -75,
385  60, -127, 120, -112, -57, -32, 41, 7, 79, 76, 66, 57, 41, -25, 31, 37, -47,
386  -36, 43, -73, -37, 63, 127, -69, -52, 90, -33, -61, 60, -55, 44, 15, 4,
387  -67, 13, -92, 64, 29, -39, -3, 83, -2, -38, -85, -86, 58, 35, -69, -61, 29,
388  -37, -95, -78, 4, 30, -4, -32, -80, -22, -9, -77, 46, 7, -93, -71, 65, 9,
389  -50, 127, -70, 26, -12, -39, -114, 63, -127, -100, 4, -32, 111, 22, -60,
390  65, -101, 26, -42, 21, -59, -27, -74, 2, -94, 6, 126, 5, 76, -88, -9, -43,
391  -101, 127, 1, 125, 92, -63, 52, 56, 4, 81, -127, 127, 80, 127, -29, 30,
392  116, -74, -17, -57, 105, 48, 45, 25, -72, 48, -38, -108, 31, -34, 4, -11,
393  41, -127, 52, -104, -43, -37, 52, 2, 47, 87, -9, 77, 27, -41, -25, 90, 86,
394  -56, 75, 10, 33, 78, 58, 127, 127, -7, -73, 49, -33, -106, -35, 38, 57, 53,
395  -17, -4, 83, 52, -108, 54, -125, 28, 23, 56, -43, -88, -17, -6, 47, 23, -9,
396  0, -13, 111, 75, 27, -52, -38, -34, 39, 30, 66, 39, 38, -64, 38, 3, 21,
397  -32, -51, -28, 54, -38, -87, 20, 52, 115, 18, -81, -70, 0, -14, -46, -46,
398  -3, 125, 16, -14, 23, -82, -84, -69, -20, -65, -127, 9, 81, -49, 61, 7,
399  -36, -45, -42, 57, -26, 47, 20, -85, 46, -13, 41, -37, -75, -60, 86, -78,
400  -127, 12, 50, 2, -3, 13, 47, 5, 19, -78, -55, -27, 65, -71, 12, -108, 20,
401  -16, 11, -31, 63, -55, 37, 75, -17, 127, -73, -33, -28, -120, 105, 68, 106,
402  -103, -106, 71, 61, 2, 23, -3, 33, -5, -15, -67, -15, -23, -54, 15, -63,
403  76, 58, -110, 1, 83, -27, 22, 75, -39, -17, -11, 64, -17, -127, -54, -66,
404  31, 96, 116, 3, -114, -7, -108, -63, 97, 9, 50, 8, 75, -28, 72, 112, -36,
405  -112, 95, -50, 23, -13, -19, 55, 21, 23, 92, 91, 22, -49, 16, -75, 23, 9,
406  -49, -97, -37, 49, -36, 36, -127, -86, 43, 127, -24, -24, 84, 83, -35, -34,
407  -12, 109, 102, -38, 51, -68, 34, 19, -22, 49, -32, 127, 40, 24, -93, -4,
408  -3, 105, 3, -58, -18, 8, 127, -18, 125, 68, 69, -62, 30, -36, 54, -57, -24,
409  17, 43, -36, -27, -57, -67, -21, -10, -49, 68, 12, 65, 4, 48, 55, 127, -75,
410  44, 89, -66, -13, -78, -82, -91, 22, 30, 33, -40, -87, -34, 96, -91, 39,
411  10, -64, -3, -12, 127, -50, -37, -56, 23, -35, -36, -54, 90, -91, 2, 50,
412  77, -6, -127, 16, 46, -5, -73, 0, -56, -18, -72, 28, 93, 60, 49, 20, 18,
413  111, -111, 32, -83, 47, 47, -10, 35, -88, 43, 57, -98, 127, -17, 0, 1, -39,
414  -127, -2, 0, 63, 93, 0, 36, -66, -61, -19, 39, -127, 58, 50, -17, 127, 88,
415  -43, -108, -51, -16, 7, -36, 68, 46, -14, 107, 40, 57, 7, 19, 8, 3, 88,
416  -90, -92, -18, -21, -24, 13, 7, -4, -78, -91, -4, 8, -35, -5, 19, 2, -111,
417  4, -66, -81, 122, -20, -34, -37, -84, 127, 68, 46, 17, 47,
418 
419  // Repeat the beginning of the array to allow wrapping reads
420  -11, 12, 103, -11,
421 };
422 
423 static const uint32_t Seed_LUT[256] = {
424  747538460, 1088979410, 1744950180, 1767011913, 1403382928,
425  521866116, 1060417601, 2110622736, 1557184770, 105289385, 585624216,
426  1827676546, 1191843873, 1018104344, 1123590530, 663361569, 2023850500,
427  76561770, 1226763489, 80325252, 1992581442, 502705249, 740409860,
428  516219202, 557974537, 1883843076, 720112066, 1640137737, 1820967556,
429  40667586, 155354121, 1820967557, 1115949072, 1631803309, 98284748,
430  287433856, 2119719977, 988742797, 1827432592, 579378475, 1017745956,
431  1309377032, 1316535465, 2074315269, 1923385360, 209722667, 1546228260,
432  168102420, 135274561, 355958469, 248291472, 2127839491, 146920100,
433  585982612, 1611702337, 696506029, 1386498192, 1258072451, 1212240548,
434  1043171860, 1217404993, 1090770605, 1386498193, 169093201, 541098240,
435  1468005469, 456510673, 1578687785, 1838217424, 2010752065, 2089828354,
436  1362717428, 970073673, 854129835, 714793201, 1266069081, 1047060864,
437  1991471829, 1098097741, 913883585, 1669598224, 1337918685, 1219264706,
438  1799741108, 1834116681, 683417731, 1120274457, 1073098457, 1648396544,
439  176642749, 31171789, 718317889, 1266977808, 1400892508, 549749008,
440  1808010512, 67112961, 1005669825, 903663673, 1771104465, 1277749632,
441  1229754427, 950632997, 1979371465, 2074373264, 305357524, 1049387408,
442  1171033360, 1686114305, 2147468765, 1941195985, 117709841, 809550080,
443  991480851, 1816248997, 1561503561, 329575568, 780651196, 1659144592,
444  1910793616, 604016641, 1665084765, 1530186961, 1870928913, 809550081,
445  2079346113, 71307521, 876663040, 1073807360, 832356664, 1573927377,
446  204073344, 2026918147, 1702476788, 2043881033, 57949587, 2001393952,
447  1197426649, 1186508931, 332056865, 950043140, 890043474, 349099312,
448  148914948, 236204097, 2022643605, 1441981517, 498130129, 1443421481,
449  924216797, 1817491777, 1913146664, 1411989632, 929068432, 495735097,
450  1684636033, 1284520017, 432816184, 1344884865, 210843729, 676364544,
451  234449232, 12112337, 1350619139, 1753272996, 2037118872, 1408560528,
452  533334916, 1043640385, 357326099, 201376421, 110375493, 541106497,
453  416159637, 242512193, 777294080, 1614872576, 1535546636, 870600145,
454  910810409, 1821440209, 1605432464, 1145147393, 951695441, 1758494976,
455  1506656568, 1557150160, 608221521, 1073840384, 217672017, 684818688,
456  1750138880, 16777217, 677990609, 953274371, 1770050213, 1359128393,
457  1797602707, 1984616737, 1865815816, 2120835200, 2051677060, 1772234061,
458  1579794881, 1652821009, 1742099468, 1887260865, 46468113, 1011925248,
459  1134107920, 881643832, 1354774993, 472508800, 1892499769, 1752793472,
460  1962502272, 687898625, 883538000, 1354355153, 1761673473, 944820481,
461  2020102353, 22020353, 961597696, 1342242816, 964808962, 1355809701,
462  17016649, 1386540177, 647682692, 1849012289, 751668241, 1557184768,
463  127374604, 1927564752, 1045744913, 1614921984, 43588881, 1016185088,
464  1544617984, 1090519041, 136122424, 215038417, 1563027841, 2026918145,
465  1688778833, 701530369, 1372639488, 1342242817, 2036945104, 953274369,
466  1750192384, 16842753, 964808960, 1359020032, 1358954497
467 };
468 
469 // Note: This is pre-transposed, i.e. stored column-major order
470 static const int8_t R64T[64][64] = {
471  {
472  32, 45, 45, 45, 45, 45, 45, 45, 44, 44, 44, 44, 43, 43, 43, 42,
473  42, 41, 41, 40, 40, 39, 39, 38, 38, 37, 36, 36, 35, 34, 34, 33,
474  32, 31, 30, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18,
475  17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 4, 3, 2, 1,
476  }, {
477  32, 45, 45, 44, 43, 42, 41, 39, 38, 36, 34, 31, 29, 26, 23, 20,
478  17, 14, 11, 8, 4, 1, -2, -6, -9, -12, -15, -18, -21, -24, -27, -30,
479  -32, -34, -36, -38, -40, -41, -43, -44, -44, -45, -45, -45, -45, -45, -44, -43,
480  -42, -40, -39, -37, -35, -33, -30, -28, -25, -22, -19, -16, -13, -10, -7, -3,
481  }, {
482  32, 45, 44, 42, 40, 37, 34, 30, 25, 20, 15, 10, 4, -1, -7, -12,
483  -17, -22, -27, -31, -35, -38, -41, -43, -44, -45, -45, -45, -43, -41, -39, -36,
484  -32, -28, -23, -18, -13, -8, -2, 3, 9, 14, 19, 24, 29, 33, 36, 39,
485  42, 44, 45, 45, 45, 44, 43, 40, 38, 34, 30, 26, 21, 16, 11, 6,
486  }, {
487  32, 45, 43, 39, 35, 30, 23, 16, 9, 1, -7, -14, -21, -28, -34, -38,
488  -42, -44, -45, -45, -43, -40, -36, -31, -25, -18, -11, -3, 4, 12, 19, 26,
489  32, 37, 41, 44, 45, 45, 44, 41, 38, 33, 27, 20, 13, 6, -2, -10,
490  -17, -24, -30, -36, -40, -43, -45, -45, -44, -42, -39, -34, -29, -22, -15, -8,
491  }, {
492  32, 44, 41, 36, 29, 20, 11, 1, -9, -18, -27, -34, -40, -44, -45, -45,
493  -42, -37, -30, -22, -13, -3, 7, 16, 25, 33, 39, 43, 45, 45, 43, 38,
494  32, 24, 15, 6, -4, -14, -23, -31, -38, -42, -45, -45, -43, -39, -34, -26,
495  -17, -8, 2, 12, 21, 30, 36, 41, 44, 45, 44, 40, 35, 28, 19, 10,
496  }, {
497  32, 44, 39, 31, 21, 10, -2, -14, -25, -34, -41, -45, -45, -42, -36, -28,
498  -17, -6, 7, 18, 29, 37, 43, 45, 44, 40, 34, 24, 13, 1, -11, -22,
499  -32, -39, -44, -45, -43, -38, -30, -20, -9, 3, 15, 26, 35, 41, 45, 45,
500  42, 36, 27, 16, 4, -8, -19, -30, -38, -43, -45, -44, -40, -33, -23, -12,
501  }, {
502  32, 43, 36, 26, 13, -1, -15, -28, -38, -44, -45, -42, -35, -24, -11, 3,
503  17, 30, 39, 44, 45, 41, 34, 22, 9, -6, -19, -31, -40, -45, -45, -40,
504  -32, -20, -7, 8, 21, 33, 41, 45, 44, 39, 30, 18, 4, -10, -23, -34,
505  -42, -45, -44, -38, -29, -16, -2, 12, 25, 36, 43, 45, 43, 37, 27, 14,
506  }, {
507  32, 42, 34, 20, 4, -12, -27, -38, -44, -45, -39, -28, -13, 3, 19, 33,
508  42, 45, 43, 34, 21, 6, -11, -26, -38, -44, -45, -39, -29, -14, 2, 18,
509  32, 41, 45, 43, 35, 22, 7, -10, -25, -37, -44, -45, -40, -30, -15, 1,
510  17, 31, 41, 45, 43, 36, 23, 8, -9, -24, -36, -44, -45, -40, -30, -16,
511  }, {
512  32, 41, 30, 14, -4, -22, -36, -44, -44, -37, -23, -6, 13, 30, 41, 45,
513  42, 31, 15, -3, -21, -36, -44, -45, -38, -24, -7, 12, 29, 40, 45, 42,
514  32, 16, -2, -20, -35, -44, -45, -38, -25, -8, 11, 28, 40, 45, 43, 33,
515  17, -1, -19, -34, -43, -45, -39, -26, -9, 10, 27, 39, 45, 43, 34, 18,
516  }, {
517  32, 40, 27, 8, -13, -31, -43, -45, -38, -22, -2, 18, 35, 44, 44, 34,
518  17, -3, -23, -38, -45, -42, -30, -12, 9, 28, 41, 45, 40, 26, 7, -14,
519  -32, -43, -45, -37, -21, -1, 19, 36, 44, 44, 34, 16, -4, -24, -39, -45,
520  -42, -30, -11, 10, 29, 41, 45, 39, 25, 6, -15, -33, -43, -45, -36, -20,
521  }, {
522  32, 39, 23, 1, -21, -38, -45, -40, -25, -3, 19, 37, 45, 41, 27, 6,
523  -17, -36, -45, -42, -29, -8, 15, 34, 44, 43, 30, 10, -13, -33, -44, -44,
524  -32, -12, 11, 31, 43, 44, 34, 14, -9, -30, -43, -45, -35, -16, 7, 28,
525  42, 45, 36, 18, -4, -26, -41, -45, -38, -20, 2, 24, 40, 45, 39, 22,
526  }, {
527  32, 38, 19, -6, -29, -43, -44, -31, -9, 16, 36, 45, 40, 22, -2, -26,
528  -42, -45, -34, -12, 13, 34, 45, 41, 25, 1, -23, -40, -45, -36, -15, 10,
529  32, 44, 43, 28, 4, -20, -39, -45, -38, -18, 7, 30, 43, 44, 30, 8,
530  -17, -37, -45, -39, -21, 3, 27, 42, 44, 33, 11, -14, -35, -45, -41, -24,
531  }, {
532  32, 37, 15, -12, -35, -45, -39, -18, 9, 33, 45, 40, 21, -6, -30, -44,
533  -42, -24, 2, 28, 43, 43, 27, 1, -25, -42, -44, -30, -4, 22, 41, 45,
534  32, 8, -19, -39, -45, -34, -11, 16, 38, 45, 36, 14, -13, -36, -45, -38,
535  -17, 10, 34, 45, 40, 20, -7, -31, -44, -41, -23, 3, 29, 44, 43, 26,
536  }, {
537  32, 36, 11, -18, -40, -45, -30, -3, 25, 43, 43, 24, -4, -31, -45, -39,
538  -17, 12, 36, 45, 35, 10, -19, -40, -44, -30, -2, 26, 43, 42, 23, -6,
539  -32, -45, -39, -16, 13, 37, 45, 34, 9, -20, -41, -44, -29, -1, 27, 44,
540  42, 22, -7, -33, -45, -38, -15, 14, 38, 45, 34, 8, -21, -41, -44, -28,
541  }, {
542  32, 34, 7, -24, -43, -41, -19, 12, 38, 45, 30, 1, -29, -45, -39, -14,
543  17, 40, 44, 26, -4, -33, -45, -36, -9, 22, 43, 42, 21, -10, -36, -45,
544  -32, -3, 27, 44, 40, 16, -15, -39, -44, -28, 2, 31, 45, 37, 11, -20,
545  -42, -43, -23, 8, 35, 45, 34, 6, -25, -44, -41, -18, 13, 38, 45, 30,
546  }, {
547  32, 33, 2, -30, -45, -36, -7, 26, 44, 38, 11, -22, -43, -40, -15, 18,
548  42, 42, 19, -14, -40, -44, -23, 10, 38, 45, 27, -6, -35, -45, -30, 1,
549  32, 45, 34, 3, -29, -45, -36, -8, 25, 44, 39, 12, -21, -43, -41, -16,
550  17, 41, 43, 20, -13, -39, -44, -24, 9, 37, 45, 28, -4, -34, -45, -31,
551  }, {
552  32, 31, -2, -34, -45, -28, 7, 37, 44, 24, -11, -39, -43, -20, 15, 41,
553  42, 16, -19, -43, -40, -12, 23, 44, 38, 8, -27, -45, -35, -3, 30, 45,
554  32, -1, -34, -45, -29, 6, 36, 45, 25, -10, -39, -44, -21, 14, 41, 42,
555  17, -18, -43, -40, -13, 22, 44, 38, 9, -26, -45, -36, -4, 30, 45, 33,
556  }, {
557  32, 30, -7, -38, -43, -18, 19, 44, 38, 6, -30, -45, -29, 8, 39, 43,
558  17, -20, -44, -37, -4, 31, 45, 28, -9, -39, -43, -16, 21, 44, 36, 3,
559  -32, -45, -27, 10, 40, 42, 15, -22, -44, -36, -2, 33, 45, 26, -11, -40,
560  -42, -14, 23, 45, 35, 1, -34, -45, -25, 12, 41, 41, 13, -24, -45, -34,
561  }, {
562  32, 28, -11, -41, -40, -8, 30, 45, 25, -14, -43, -38, -4, 33, 45, 22,
563  -17, -44, -36, -1, 35, 44, 19, -20, -44, -34, 2, 37, 43, 16, -23, -45,
564  -32, 6, 39, 42, 13, -26, -45, -30, 9, 40, 41, 10, -29, -45, -27, 12,
565  42, 39, 7, -31, -45, -24, 15, 43, 38, 3, -34, -45, -21, 18, 44, 36,
566  }, {
567  32, 26, -15, -44, -35, 3, 39, 41, 9, -31, -45, -20, 21, 45, 30, -10,
568  -42, -38, -2, 36, 43, 14, -27, -45, -25, 16, 44, 34, -4, -39, -41, -8,
569  32, 45, 19, -22, -45, -30, 11, 42, 38, 1, -36, -43, -13, 28, 45, 24,
570  -17, -44, -34, 6, 40, 40, 7, -33, -44, -18, 23, 45, 29, -12, -43, -37,
571  }, {
572  32, 24, -19, -45, -29, 14, 44, 33, -9, -42, -36, 3, 40, 39, 2, -37,
573  -42, -8, 34, 44, 13, -30, -45, -18, 25, 45, 23, -20, -45, -28, 15, 44,
574  32, -10, -43, -36, 4, 40, 39, 1, -38, -41, -7, 34, 43, 12, -30, -45,
575  -17, 26, 45, 22, -21, -45, -27, 16, 44, 31, -11, -43, -35, 6, 41, 38,
576  }, {
577  32, 22, -23, -45, -21, 24, 45, 20, -25, -45, -19, 26, 45, 18, -27, -45,
578  -17, 28, 45, 16, -29, -45, -15, 30, 44, 14, -30, -44, -13, 31, 44, 12,
579  -32, -44, -11, 33, 43, 10, -34, -43, -9, 34, 43, 8, -35, -42, -7, 36,
580  42, 6, -36, -41, -4, 37, 41, 3, -38, -40, -2, 38, 40, 1, -39, -39,
581  }, {
582  32, 20, -27, -45, -13, 33, 43, 6, -38, -39, 2, 41, 35, -10, -44, -30,
583  17, 45, 23, -24, -45, -16, 30, 44, 9, -36, -41, -1, 40, 37, -7, -43,
584  -32, 14, 45, 26, -21, -45, -19, 28, 44, 12, -34, -42, -4, 38, 39, -3,
585  -42, -34, 11, 44, 29, -18, -45, -22, 25, 45, 15, -31, -43, -8, 36, 40,
586  }, {
587  32, 18, -30, -43, -4, 39, 36, -10, -44, -26, 23, 45, 13, -34, -41, 1,
588  42, 33, -15, -45, -21, 28, 44, 8, -38, -38, 7, 44, 29, -20, -45, -16,
589  32, 42, 2, -40, -35, 12, 45, 24, -25, -45, -11, 36, 40, -3, -43, -31,
590  17, 45, 19, -30, -43, -6, 39, 37, -9, -44, -27, 22, 45, 14, -34, -41,
591  }, {
592  32, 16, -34, -40, 4, 44, 27, -24, -44, -8, 39, 36, -13, -45, -19, 31,
593  42, -1, -43, -30, 21, 45, 11, -37, -38, 10, 45, 22, -29, -43, -2, 41,
594  32, -18, -45, -14, 35, 39, -7, -44, -25, 26, 44, 6, -40, -34, 15, 45,
595  17, -33, -41, 3, 43, 28, -23, -45, -9, 38, 36, -12, -45, -20, 30, 42,
596  }, {
597  32, 14, -36, -37, 13, 45, 15, -36, -38, 12, 45, 16, -35, -38, 11, 45,
598  17, -34, -39, 10, 45, 18, -34, -39, 9, 45, 19, -33, -40, 8, 45, 20,
599  -32, -40, 7, 45, 21, -31, -41, 6, 44, 22, -30, -41, 4, 44, 23, -30,
600  -42, 3, 44, 24, -29, -42, 2, 44, 25, -28, -43, 1, 43, 26, -27, -43,
601  }, {
602  32, 12, -39, -33, 21, 44, 2, -43, -25, 30, 41, -8, -45, -16, 36, 36,
603  -17, -45, -7, 41, 29, -26, -43, 3, 44, 20, -34, -38, 13, 45, 11, -39,
604  -32, 22, 44, 1, -43, -24, 30, 40, -9, -45, -15, 37, 35, -18, -45, -6,
605  42, 28, -27, -42, 4, 45, 19, -34, -38, 14, 45, 10, -40, -31, 23, 44,
606  }, {
607  32, 10, -41, -28, 29, 40, -11, -45, -9, 41, 27, -30, -40, 12, 45, 8,
608  -42, -26, 30, 39, -13, -45, -7, 42, 25, -31, -39, 14, 45, 6, -43, -24,
609  32, 38, -15, -45, -4, 43, 23, -33, -38, 16, 45, 3, -43, -22, 34, 37,
610  -17, -45, -2, 44, 21, -34, -36, 18, 44, 1, -44, -20, 35, 36, -19, -44,
611  }, {
612  32, 8, -43, -22, 35, 34, -23, -42, 9, 45, 7, -43, -21, 36, 34, -24,
613  -42, 10, 45, 6, -43, -20, 36, 33, -25, -41, 11, 45, 4, -44, -19, 37,
614  32, -26, -41, 12, 45, 3, -44, -18, 38, 31, -27, -40, 13, 45, 2, -44,
615  -17, 38, 30, -28, -40, 14, 45, 1, -44, -16, 39, 30, -29, -39, 15, 45,
616  }, {
617  32, 6, -44, -16, 40, 26, -34, -34, 25, 40, -15, -44, 4, 45, 7, -44,
618  -17, 39, 27, -33, -35, 24, 41, -14, -44, 3, 45, 8, -43, -18, 39, 28,
619  -32, -36, 23, 41, -13, -45, 2, 45, 9, -43, -19, 38, 29, -31, -36, 22,
620  42, -12, -45, 1, 45, 10, -43, -20, 38, 30, -30, -37, 21, 42, -11, -45,
621  }, {
622  32, 3, -45, -10, 43, 16, -41, -22, 38, 28, -34, -33, 29, 37, -23, -40,
623  17, 43, -11, -45, 4, 45, 2, -45, -9, 44, 15, -41, -21, 38, 27, -34,
624  -32, 30, 36, -24, -40, 18, 43, -12, -44, 6, 45, 1, -45, -8, 44, 14,
625  -42, -20, 39, 26, -35, -31, 30, 36, -25, -39, 19, 42, -13, -44, 7, 45,
626  }, {
627  32, 1, -45, -3, 45, 6, -45, -8, 44, 10, -44, -12, 43, 14, -43, -16,
628  42, 18, -41, -20, 40, 22, -39, -24, 38, 26, -36, -28, 35, 30, -34, -31,
629  32, 33, -30, -34, 29, 36, -27, -37, 25, 38, -23, -39, 21, 40, -19, -41,
630  17, 42, -15, -43, 13, 44, -11, -44, 9, 45, -7, -45, 4, 45, -2, -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, -3, -45, 10, 43, -16, -41, 22, 38, -28, -34, 33, 29, -37, -23, 40,
638  17, -43, -11, 45, 4, -45, 2, 45, -9, -44, 15, 41, -21, -38, 27, 34,
639  -32, -30, 36, 24, -40, -18, 43, 12, -44, -6, 45, -1, -45, 8, 44, -14,
640  -42, 20, 39, -26, -35, 31, 30, -36, -25, 39, 19, -42, -13, 44, 7, -45,
641  }, {
642  32, -6, -44, 16, 40, -26, -34, 34, 25, -40, -15, 44, 4, -45, 7, 44,
643  -17, -39, 27, 33, -35, -24, 41, 14, -44, -3, 45, -8, -43, 18, 39, -28,
644  -32, 36, 23, -41, -13, 45, 2, -45, 9, 43, -19, -38, 29, 31, -36, -22,
645  42, 12, -45, -1, 45, -10, -43, 20, 38, -30, -30, 37, 21, -42, -11, 45,
646  }, {
647  32, -8, -43, 22, 35, -34, -23, 42, 9, -45, 7, 43, -21, -36, 34, 24,
648  -42, -10, 45, -6, -43, 20, 36, -33, -25, 41, 11, -45, 4, 44, -19, -37,
649  32, 26, -41, -12, 45, -3, -44, 18, 38, -31, -27, 40, 13, -45, 2, 44,
650  -17, -38, 30, 28, -40, -14, 45, -1, -44, 16, 39, -30, -29, 39, 15, -45,
651  }, {
652  32, -10, -41, 28, 29, -40, -11, 45, -9, -41, 27, 30, -40, -12, 45, -8,
653  -42, 26, 30, -39, -13, 45, -7, -42, 25, 31, -39, -14, 45, -6, -43, 24,
654  32, -38, -15, 45, -4, -43, 23, 33, -38, -16, 45, -3, -43, 22, 34, -37,
655  -17, 45, -2, -44, 21, 34, -36, -18, 44, -1, -44, 20, 35, -36, -19, 44,
656  }, {
657  32, -12, -39, 33, 21, -44, 2, 43, -25, -30, 41, 8, -45, 16, 36, -36,
658  -17, 45, -7, -41, 29, 26, -43, -3, 44, -20, -34, 38, 13, -45, 11, 39,
659  -32, -22, 44, -1, -43, 24, 30, -40, -9, 45, -15, -37, 35, 18, -45, 6,
660  42, -28, -27, 42, 4, -45, 19, 34, -38, -14, 45, -10, -40, 31, 23, -44,
661  }, {
662  32, -14, -36, 37, 13, -45, 15, 36, -38, -12, 45, -16, -35, 38, 11, -45,
663  17, 34, -39, -10, 45, -18, -34, 39, 9, -45, 19, 33, -40, -8, 45, -20,
664  -32, 40, 7, -45, 21, 31, -41, -6, 44, -22, -30, 41, 4, -44, 23, 30,
665  -42, -3, 44, -24, -29, 42, 2, -44, 25, 28, -43, -1, 43, -26, -27, 43,
666  }, {
667  32, -16, -34, 40, 4, -44, 27, 24, -44, 8, 39, -36, -13, 45, -19, -31,
668  42, 1, -43, 30, 21, -45, 11, 37, -38, -10, 45, -22, -29, 43, -2, -41,
669  32, 18, -45, 14, 35, -39, -7, 44, -25, -26, 44, -6, -40, 34, 15, -45,
670  17, 33, -41, -3, 43, -28, -23, 45, -9, -38, 36, 12, -45, 20, 30, -42,
671  }, {
672  32, -18, -30, 43, -4, -39, 36, 10, -44, 26, 23, -45, 13, 34, -41, -1,
673  42, -33, -15, 45, -21, -28, 44, -8, -38, 38, 7, -44, 29, 20, -45, 16,
674  32, -42, 2, 40, -35, -12, 45, -24, -25, 45, -11, -36, 40, 3, -43, 31,
675  17, -45, 19, 30, -43, 6, 39, -37, -9, 44, -27, -22, 45, -14, -34, 41,
676  }, {
677  32, -20, -27, 45, -13, -33, 43, -6, -38, 39, 2, -41, 35, 10, -44, 30,
678  17, -45, 23, 24, -45, 16, 30, -44, 9, 36, -41, 1, 40, -37, -7, 43,
679  -32, -14, 45, -26, -21, 45, -19, -28, 44, -12, -34, 42, -4, -38, 39, 3,
680  -42, 34, 11, -44, 29, 18, -45, 22, 25, -45, 15, 31, -43, 8, 36, -40,
681  }, {
682  32, -22, -23, 45, -21, -24, 45, -20, -25, 45, -19, -26, 45, -18, -27, 45,
683  -17, -28, 45, -16, -29, 45, -15, -30, 44, -14, -30, 44, -13, -31, 44, -12,
684  -32, 44, -11, -33, 43, -10, -34, 43, -9, -34, 43, -8, -35, 42, -7, -36,
685  42, -6, -36, 41, -4, -37, 41, -3, -38, 40, -2, -38, 40, -1, -39, 39,
686  }, {
687  32, -24, -19, 45, -29, -14, 44, -33, -9, 42, -36, -3, 40, -39, 2, 37,
688  -42, 8, 34, -44, 13, 30, -45, 18, 25, -45, 23, 20, -45, 28, 15, -44,
689  32, 10, -43, 36, 4, -40, 39, -1, -38, 41, -7, -34, 43, -12, -30, 45,
690  -17, -26, 45, -22, -21, 45, -27, -16, 44, -31, -11, 43, -35, -6, 41, -38,
691  }, {
692  32, -26, -15, 44, -35, -3, 39, -41, 9, 31, -45, 20, 21, -45, 30, 10,
693  -42, 38, -2, -36, 43, -14, -27, 45, -25, -16, 44, -34, -4, 39, -41, 8,
694  32, -45, 19, 22, -45, 30, 11, -42, 38, -1, -36, 43, -13, -28, 45, -24,
695  -17, 44, -34, -6, 40, -40, 7, 33, -44, 18, 23, -45, 29, 12, -43, 37,
696  }, {
697  32, -28, -11, 41, -40, 8, 30, -45, 25, 14, -43, 38, -4, -33, 45, -22,
698  -17, 44, -36, 1, 35, -44, 19, 20, -44, 34, 2, -37, 43, -16, -23, 45,
699  -32, -6, 39, -42, 13, 26, -45, 30, 9, -40, 41, -10, -29, 45, -27, -12,
700  42, -39, 7, 31, -45, 24, 15, -43, 38, -3, -34, 45, -21, -18, 44, -36,
701  }, {
702  32, -30, -7, 38, -43, 18, 19, -44, 38, -6, -30, 45, -29, -8, 39, -43,
703  17, 20, -44, 37, -4, -31, 45, -28, -9, 39, -43, 16, 21, -44, 36, -3,
704  -32, 45, -27, -10, 40, -42, 15, 22, -44, 36, -2, -33, 45, -26, -11, 40,
705  -42, 14, 23, -45, 35, -1, -34, 45, -25, -12, 41, -41, 13, 24, -45, 34,
706  }, {
707  32, -31, -2, 34, -45, 28, 7, -37, 44, -24, -11, 39, -43, 20, 15, -41,
708  42, -16, -19, 43, -40, 12, 23, -44, 38, -8, -27, 45, -35, 3, 30, -45,
709  32, 1, -34, 45, -29, -6, 36, -45, 25, 10, -39, 44, -21, -14, 41, -42,
710  17, 18, -43, 40, -13, -22, 44, -38, 9, 26, -45, 36, -4, -30, 45, -33,
711  }, {
712  32, -33, 2, 30, -45, 36, -7, -26, 44, -38, 11, 22, -43, 40, -15, -18,
713  42, -42, 19, 14, -40, 44, -23, -10, 38, -45, 27, 6, -35, 45, -30, -1,
714  32, -45, 34, -3, -29, 45, -36, 8, 25, -44, 39, -12, -21, 43, -41, 16,
715  17, -41, 43, -20, -13, 39, -44, 24, 9, -37, 45, -28, -4, 34, -45, 31,
716  }, {
717  32, -34, 7, 24, -43, 41, -19, -12, 38, -45, 30, -1, -29, 45, -39, 14,
718  17, -40, 44, -26, -4, 33, -45, 36, -9, -22, 43, -42, 21, 10, -36, 45,
719  -32, 3, 27, -44, 40, -16, -15, 39, -44, 28, 2, -31, 45, -37, 11, 20,
720  -42, 43, -23, -8, 35, -45, 34, -6, -25, 44, -41, 18, 13, -38, 45, -30,
721  }, {
722  32, -36, 11, 18, -40, 45, -30, 3, 25, -43, 43, -24, -4, 31, -45, 39,
723  -17, -12, 36, -45, 35, -10, -19, 40, -44, 30, -2, -26, 43, -42, 23, 6,
724  -32, 45, -39, 16, 13, -37, 45, -34, 9, 20, -41, 44, -29, 1, 27, -44,
725  42, -22, -7, 33, -45, 38, -15, -14, 38, -45, 34, -8, -21, 41, -44, 28,
726  }, {
727  32, -37, 15, 12, -35, 45, -39, 18, 9, -33, 45, -40, 21, 6, -30, 44,
728  -42, 24, 2, -28, 43, -43, 27, -1, -25, 42, -44, 30, -4, -22, 41, -45,
729  32, -8, -19, 39, -45, 34, -11, -16, 38, -45, 36, -14, -13, 36, -45, 38,
730  -17, -10, 34, -45, 40, -20, -7, 31, -44, 41, -23, -3, 29, -44, 43, -26,
731  }, {
732  32, -38, 19, 6, -29, 43, -44, 31, -9, -16, 36, -45, 40, -22, -2, 26,
733  -42, 45, -34, 12, 13, -34, 45, -41, 25, -1, -23, 40, -45, 36, -15, -10,
734  32, -44, 43, -28, 4, 20, -39, 45, -38, 18, 7, -30, 43, -44, 30, -8,
735  -17, 37, -45, 39, -21, -3, 27, -42, 44, -33, 11, 14, -35, 45, -41, 24,
736  }, {
737  32, -39, 23, -1, -21, 38, -45, 40, -25, 3, 19, -37, 45, -41, 27, -6,
738  -17, 36, -45, 42, -29, 8, 15, -34, 44, -43, 30, -10, -13, 33, -44, 44,
739  -32, 12, 11, -31, 43, -44, 34, -14, -9, 30, -43, 45, -35, 16, 7, -28,
740  42, -45, 36, -18, -4, 26, -41, 45, -38, 20, 2, -24, 40, -45, 39, -22,
741  }, {
742  32, -40, 27, -8, -13, 31, -43, 45, -38, 22, -2, -18, 35, -44, 44, -34,
743  17, 3, -23, 38, -45, 42, -30, 12, 9, -28, 41, -45, 40, -26, 7, 14,
744  -32, 43, -45, 37, -21, 1, 19, -36, 44, -44, 34, -16, -4, 24, -39, 45,
745  -42, 30, -11, -10, 29, -41, 45, -39, 25, -6, -15, 33, -43, 45, -36, 20,
746  }, {
747  32, -41, 30, -14, -4, 22, -36, 44, -44, 37, -23, 6, 13, -30, 41, -45,
748  42, -31, 15, 3, -21, 36, -44, 45, -38, 24, -7, -12, 29, -40, 45, -42,
749  32, -16, -2, 20, -35, 44, -45, 38, -25, 8, 11, -28, 40, -45, 43, -33,
750  17, 1, -19, 34, -43, 45, -39, 26, -9, -10, 27, -39, 45, -43, 34, -18,
751  }, {
752  32, -42, 34, -20, 4, 12, -27, 38, -44, 45, -39, 28, -13, -3, 19, -33,
753  42, -45, 43, -34, 21, -6, -11, 26, -38, 44, -45, 39, -29, 14, 2, -18,
754  32, -41, 45, -43, 35, -22, 7, 10, -25, 37, -44, 45, -40, 30, -15, -1,
755  17, -31, 41, -45, 43, -36, 23, -8, -9, 24, -36, 44, -45, 40, -30, 16,
756  }, {
757  32, -43, 36, -26, 13, 1, -15, 28, -38, 44, -45, 42, -35, 24, -11, -3,
758  17, -30, 39, -44, 45, -41, 34, -22, 9, 6, -19, 31, -40, 45, -45, 40,
759  -32, 20, -7, -8, 21, -33, 41, -45, 44, -39, 30, -18, 4, 10, -23, 34,
760  -42, 45, -44, 38, -29, 16, -2, -12, 25, -36, 43, -45, 43, -37, 27, -14,
761  }, {
762  32, -44, 39, -31, 21, -10, -2, 14, -25, 34, -41, 45, -45, 42, -36, 28,
763  -17, 6, 7, -18, 29, -37, 43, -45, 44, -40, 34, -24, 13, -1, -11, 22,
764  -32, 39, -44, 45, -43, 38, -30, 20, -9, -3, 15, -26, 35, -41, 45, -45,
765  42, -36, 27, -16, 4, 8, -19, 30, -38, 43, -45, 44, -40, 33, -23, 12,
766  }, {
767  32, -44, 41, -36, 29, -20, 11, -1, -9, 18, -27, 34, -40, 44, -45, 45,
768  -42, 37, -30, 22, -13, 3, 7, -16, 25, -33, 39, -43, 45, -45, 43, -38,
769  32, -24, 15, -6, -4, 14, -23, 31, -38, 42, -45, 45, -43, 39, -34, 26,
770  -17, 8, 2, -12, 21, -30, 36, -41, 44, -45, 44, -40, 35, -28, 19, -10,
771  }, {
772  32, -45, 43, -39, 35, -30, 23, -16, 9, -1, -7, 14, -21, 28, -34, 38,
773  -42, 44, -45, 45, -43, 40, -36, 31, -25, 18, -11, 3, 4, -12, 19, -26,
774  32, -37, 41, -44, 45, -45, 44, -41, 38, -33, 27, -20, 13, -6, -2, 10,
775  -17, 24, -30, 36, -40, 43, -45, 45, -44, 42, -39, 34, -29, 22, -15, 8,
776  }, {
777  32, -45, 44, -42, 40, -37, 34, -30, 25, -20, 15, -10, 4, 1, -7, 12,
778  -17, 22, -27, 31, -35, 38, -41, 43, -44, 45, -45, 45, -43, 41, -39, 36,
779  -32, 28, -23, 18, -13, 8, -2, -3, 9, -14, 19, -24, 29, -33, 36, -39,
780  42, -44, 45, -45, 45, -44, 43, -40, 38, -34, 30, -26, 21, -16, 11, -6,
781  }, {
782  32, -45, 45, -44, 43, -42, 41, -39, 38, -36, 34, -31, 29, -26, 23, -20,
783  17, -14, 11, -8, 4, -1, -2, 6, -9, 12, -15, 18, -21, 24, -27, 30,
784  -32, 34, -36, 38, -40, 41, -43, 44, -44, 45, -45, 45, -45, 45, -44, 43,
785  -42, 40, -39, 37, -35, 33, -30, 28, -25, 22, -19, 16, -13, 10, -7, 3,
786  }, {
787  32, -45, 45, -45, 45, -45, 45, -45, 44, -44, 44, -44, 43, -43, 43, -42,
788  42, -41, 41, -40, 40, -39, 39, -38, 38, -37, 36, -36, 35, -34, 34, -33,
789  32, -31, 30, -30, 29, -28, 27, -26, 25, -24, 23, -22, 21, -20, 19, -18,
790  17, -16, 15, -14, 13, -12, 11, -10, 9, -8, 7, -6, 4, -3, 2, -1,
791  }
792 };
generate
static av_always_inline void generate(int8_t *out, int out_stride, const uint8_t *in, int in_stride, H274FilmGrainDatabase *database, const AVFilmGrainH274Params *h274, int c, int invert, int deblock, int y_offset, int x_offset)
Definition: h274.c:156
av_clip
#define av_clip
Definition: common.h:100
out
FILE * out
Definition: movenc.c:55
deblock
static void deblock(const RV60Context *s, AVFrame *frame, int xpos, int ypos, int size, int dpos)
Definition: rv60dec.c:2141
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:251
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:389
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
AVFrame::width
int width
Definition: frame.h:461
b
#define b
Definition: input.c:41
init_slice_c
static void init_slice_c(int8_t out[64][64], uint8_t h, uint8_t v, int16_t tmp[64][64])
Definition: h274.c:45
AVFilmGrainParams::seed
uint64_t seed
Seed to use for the synthesis process, if the codec allows for it.
Definition: film_grain_params.h:250
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:410
av_image_copy_plane
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
Definition: imgutils.c:374
avassert.h
H274FilmGrainDatabase::slice_tmp
int16_t slice_tmp[64][64]
Definition: h274.h:40
Gaussian_LUT
static const int8_t Gaussian_LUT[2048+4]
Definition: h274.c:33
s
#define s(width, name)
Definition: cbs_vp9.c:198
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:60
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
AVFilmGrainH274Params::comp_model_value
int16_t comp_model_value[3][256][6]
Specifies the model values for the component for each intensity interval.
Definition: film_grain_params.h:227
AVFilmGrainH274Params::model_id
int model_id
Specifies the film grain simulation mode.
Definition: film_grain_params.h:137
H274FilmGrainDatabase::db
int8_t db[13][13][64][64]
Definition: h274.h:36
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
state
static struct @466 state
Seed_LUT
static const uint32_t Seed_LUT[256]
Definition: h274.c:34
h274.h
init_slice
static void init_slice(H274FilmGrainDatabase *database, uint8_t h, uint8_t v)
Definition: h274.c:104
seed
static unsigned int seed
Definition: videogen.c:78
H274FilmGrainDatabase::residency
uint16_t residency[13]
Definition: h274.h:37
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
synth_grain_8x8_c
static void synth_grain_8x8_c(int8_t *out, const int out_stride, const int16_t scale, const uint8_t shift, const int8_t *db)
Definition: h274.c:129
H274FilmGrainDatabase
Definition: h274.h:34
height
#define height
Definition: dsp.h:85
AVFilmGrainH274Params::component_model_present
int component_model_present[3]
Indicates if the modelling of film grain for a given component is present.
Definition: film_grain_params.h:192
shift
static int shift(int a, int b)
Definition: bonk.c:261
R64T
static const int8_t R64T[64][64]
Definition: h274.c:35
AVFilmGrainParams
This structure describes how to handle film grain synthesis in video for specific codecs.
Definition: film_grain_params.h:238
avg
#define avg(a, b, c, d)
Definition: colorspacedsp_template.c:28
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:476
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
avg_8x8_c
static uint16_t avg_8x8_c(const uint8_t *in, int in_stride)
Definition: h274.c:114
AVFilmGrainParams::h274
AVFilmGrainH274Params h274
Definition: film_grain_params.h:261
ff_h274_apply_film_grain
int ff_h274_apply_film_grain(AVFrame *out_frame, const AVFrame *in_frame, H274FilmGrainDatabase *database, const AVFilmGrainParams *params)
Definition: h274.c:217
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVFilmGrainH274Params
This structure describes how to handle film grain synthesis for codecs using the ITU-T H....
Definition: film_grain_params.h:132
invert
static void invert(float *h, int n)
Definition: asrc_sinc.c:186
AVFilmGrainH274Params::num_intensity_intervals
uint16_t num_intensity_intervals[3]
Specifies the number of intensity intervals for which a specific set of model values has been estimat...
Definition: film_grain_params.h:198
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:56
av_always_inline
#define av_always_inline
Definition: attributes.h:49
AVFilmGrainH274Params::intensity_interval_lower_bound
uint8_t intensity_interval_lower_bound[3][256]
Specifies the lower ounds of each intensity interval for whichthe set of model values applies for the...
Definition: film_grain_params.h:210
AVFilmGrainParams::codec
union AVFilmGrainParams::@435 codec
Additional fields may be added both here and in any structure included.
AVFrame::height
int height
Definition: frame.h:461
AV_FILM_GRAIN_PARAMS_H274
@ AV_FILM_GRAIN_PARAMS_H274
The union is valid when interpreted as AVFilmGrainH274Params (codec.h274)
Definition: film_grain_params.h:35
add_8x8_clip_c
static void add_8x8_clip_c(uint8_t *out, const uint8_t *a, const int8_t *b, int n)
Definition: h274.c:210
AVFilmGrainH274Params::log2_scale_factor
int log2_scale_factor
Specifies a scale factor used in the film grain characterization equations.
Definition: film_grain_params.h:187
av_clip_uint8
#define av_clip_uint8
Definition: common.h:106
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:291
prng_shift
static void prng_shift(uint32_t *state)
Definition: h274.c:37
int32_t
int32_t
Definition: audioconvert.c:56
imgutils.h
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:434
deblock_8x8_c
static void deblock_8x8_c(int8_t *out, const int out_stride)
Definition: h274.c:143
h
h
Definition: vp9dsp_template.c:2070
width
#define width
Definition: dsp.h:85
AVFilmGrainParams::type
enum AVFilmGrainParamsType type
Specifies the codec for which this structure is valid.
Definition: film_grain_params.h:242