xref: /aosp_15_r20/external/libaom/av1/decoder/grain_synthesis.c (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker  * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker  *
4*77c1e3ccSAndroid Build Coastguard Worker  * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker  * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker  * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker  */
11*77c1e3ccSAndroid Build Coastguard Worker 
12*77c1e3ccSAndroid Build Coastguard Worker /*!\file
13*77c1e3ccSAndroid Build Coastguard Worker  * \brief Describes film grain parameters and film grain synthesis
14*77c1e3ccSAndroid Build Coastguard Worker  *
15*77c1e3ccSAndroid Build Coastguard Worker  */
16*77c1e3ccSAndroid Build Coastguard Worker 
17*77c1e3ccSAndroid Build Coastguard Worker #include <stdbool.h>
18*77c1e3ccSAndroid Build Coastguard Worker #include <stdio.h>
19*77c1e3ccSAndroid Build Coastguard Worker #include <string.h>
20*77c1e3ccSAndroid Build Coastguard Worker #include <stdlib.h>
21*77c1e3ccSAndroid Build Coastguard Worker #include <assert.h>
22*77c1e3ccSAndroid Build Coastguard Worker #include "aom_dsp/aom_dsp_common.h"
23*77c1e3ccSAndroid Build Coastguard Worker #include "aom_mem/aom_mem.h"
24*77c1e3ccSAndroid Build Coastguard Worker #include "av1/decoder/grain_synthesis.h"
25*77c1e3ccSAndroid Build Coastguard Worker 
26*77c1e3ccSAndroid Build Coastguard Worker // Samples with Gaussian distribution in the range of [-2048, 2047] (12 bits)
27*77c1e3ccSAndroid Build Coastguard Worker // with zero mean and standard deviation of about 512.
28*77c1e3ccSAndroid Build Coastguard Worker // should be divided by 4 for 10-bit range and 16 for 8-bit range.
29*77c1e3ccSAndroid Build Coastguard Worker static const int gaussian_sequence[2048] = {
30*77c1e3ccSAndroid Build Coastguard Worker   56,    568,   -180,  172,   124,   -84,   172,   -64,   -900,  24,   820,
31*77c1e3ccSAndroid Build Coastguard Worker   224,   1248,  996,   272,   -8,    -916,  -388,  -732,  -104,  -188, 800,
32*77c1e3ccSAndroid Build Coastguard Worker   112,   -652,  -320,  -376,  140,   -252,  492,   -168,  44,    -788, 588,
33*77c1e3ccSAndroid Build Coastguard Worker   -584,  500,   -228,  12,    680,   272,   -476,  972,   -100,  652,  368,
34*77c1e3ccSAndroid Build Coastguard Worker   432,   -196,  -720,  -192,  1000,  -332,  652,   -136,  -552,  -604, -4,
35*77c1e3ccSAndroid Build Coastguard Worker   192,   -220,  -136,  1000,  -52,   372,   -96,   -624,  124,   -24,  396,
36*77c1e3ccSAndroid Build Coastguard Worker   540,   -12,   -104,  640,   464,   244,   -208,  -84,   368,   -528, -740,
37*77c1e3ccSAndroid Build Coastguard Worker   248,   -968,  -848,  608,   376,   -60,   -292,  -40,   -156,  252,  -292,
38*77c1e3ccSAndroid Build Coastguard Worker   248,   224,   -280,  400,   -244,  244,   -60,   76,    -80,   212,  532,
39*77c1e3ccSAndroid Build Coastguard Worker   340,   128,   -36,   824,   -352,  -60,   -264,  -96,   -612,  416,  -704,
40*77c1e3ccSAndroid Build Coastguard Worker   220,   -204,  640,   -160,  1220,  -408,  900,   336,   20,    -336, -96,
41*77c1e3ccSAndroid Build Coastguard Worker   -792,  304,   48,    -28,   -1232, -1172, -448,  104,   -292,  -520, 244,
42*77c1e3ccSAndroid Build Coastguard Worker   60,    -948,  0,     -708,  268,   108,   356,   -548,  488,   -344, -136,
43*77c1e3ccSAndroid Build Coastguard Worker   488,   -196,  -224,  656,   -236,  -1128, 60,    4,     140,   276,  -676,
44*77c1e3ccSAndroid Build Coastguard Worker   -376,  168,   -108,  464,   8,     564,   64,    240,   308,   -300, -400,
45*77c1e3ccSAndroid Build Coastguard Worker   -456,  -136,  56,    120,   -408,  -116,  436,   504,   -232,  328,  844,
46*77c1e3ccSAndroid Build Coastguard Worker   -164,  -84,   784,   -168,  232,   -224,  348,   -376,  128,   568,  96,
47*77c1e3ccSAndroid Build Coastguard Worker   -1244, -288,  276,   848,   832,   -360,  656,   464,   -384,  -332, -356,
48*77c1e3ccSAndroid Build Coastguard Worker   728,   -388,  160,   -192,  468,   296,   224,   140,   -776,  -100, 280,
49*77c1e3ccSAndroid Build Coastguard Worker   4,     196,   44,    -36,   -648,  932,   16,    1428,  28,    528,  808,
50*77c1e3ccSAndroid Build Coastguard Worker   772,   20,    268,   88,    -332,  -284,  124,   -384,  -448,  208,  -228,
51*77c1e3ccSAndroid Build Coastguard Worker   -1044, -328,  660,   380,   -148,  -300,  588,   240,   540,   28,   136,
52*77c1e3ccSAndroid Build Coastguard Worker   -88,   -436,  256,   296,   -1000, 1400,  0,     -48,   1056,  -136, 264,
53*77c1e3ccSAndroid Build Coastguard Worker   -528,  -1108, 632,   -484,  -592,  -344,  796,   124,   -668,  -768, 388,
54*77c1e3ccSAndroid Build Coastguard Worker   1296,  -232,  -188,  -200,  -288,  -4,    308,   100,   -168,  256,  -500,
55*77c1e3ccSAndroid Build Coastguard Worker   204,   -508,  648,   -136,  372,   -272,  -120,  -1004, -552,  -548, -384,
56*77c1e3ccSAndroid Build Coastguard Worker   548,   -296,  428,   -108,  -8,    -912,  -324,  -224,  -88,   -112, -220,
57*77c1e3ccSAndroid Build Coastguard Worker   -100,  996,   -796,  548,   360,   -216,  180,   428,   -200,  -212, 148,
58*77c1e3ccSAndroid Build Coastguard Worker   96,    148,   284,   216,   -412,  -320,  120,   -300,  -384,  -604, -572,
59*77c1e3ccSAndroid Build Coastguard Worker   -332,  -8,    -180,  -176,  696,   116,   -88,   628,   76,    44,   -516,
60*77c1e3ccSAndroid Build Coastguard Worker   240,   -208,  -40,   100,   -592,  344,   -308,  -452,  -228,  20,   916,
61*77c1e3ccSAndroid Build Coastguard Worker   -1752, -136,  -340,  -804,  140,   40,    512,   340,   248,   184,  -492,
62*77c1e3ccSAndroid Build Coastguard Worker   896,   -156,  932,   -628,  328,   -688,  -448,  -616,  -752,  -100, 560,
63*77c1e3ccSAndroid Build Coastguard Worker   -1020, 180,   -800,  -64,   76,    576,   1068,  396,   660,   552,  -108,
64*77c1e3ccSAndroid Build Coastguard Worker   -28,   320,   -628,  312,   -92,   -92,   -472,  268,   16,    560,  516,
65*77c1e3ccSAndroid Build Coastguard Worker   -672,  -52,   492,   -100,  260,   384,   284,   292,   304,   -148, 88,
66*77c1e3ccSAndroid Build Coastguard Worker   -152,  1012,  1064,  -228,  164,   -376,  -684,  592,   -392,  156,  196,
67*77c1e3ccSAndroid Build Coastguard Worker   -524,  -64,   -884,  160,   -176,  636,   648,   404,   -396,  -436, 864,
68*77c1e3ccSAndroid Build Coastguard Worker   424,   -728,  988,   -604,  904,   -592,  296,   -224,  536,   -176, -920,
69*77c1e3ccSAndroid Build Coastguard Worker   436,   -48,   1176,  -884,  416,   -776,  -824,  -884,  524,   -548, -564,
70*77c1e3ccSAndroid Build Coastguard Worker   -68,   -164,  -96,   692,   364,   -692,  -1012, -68,   260,   -480, 876,
71*77c1e3ccSAndroid Build Coastguard Worker   -1116, 452,   -332,  -352,  892,   -1088, 1220,  -676,  12,    -292, 244,
72*77c1e3ccSAndroid Build Coastguard Worker   496,   372,   -32,   280,   200,   112,   -440,  -96,   24,    -644, -184,
73*77c1e3ccSAndroid Build Coastguard Worker   56,    -432,  224,   -980,  272,   -260,  144,   -436,  420,   356,  364,
74*77c1e3ccSAndroid Build Coastguard Worker   -528,  76,    172,   -744,  -368,  404,   -752,  -416,  684,   -688, 72,
75*77c1e3ccSAndroid Build Coastguard Worker   540,   416,   92,    444,   480,   -72,   -1416, 164,   -1172, -68,  24,
76*77c1e3ccSAndroid Build Coastguard Worker   424,   264,   1040,  128,   -912,  -524,  -356,  64,    876,   -12,  4,
77*77c1e3ccSAndroid Build Coastguard Worker   -88,   532,   272,   -524,  320,   276,   -508,  940,   24,    -400, -120,
78*77c1e3ccSAndroid Build Coastguard Worker   756,   60,    236,   -412,  100,   376,   -484,  400,   -100,  -740, -108,
79*77c1e3ccSAndroid Build Coastguard Worker   -260,  328,   -268,  224,   -200,  -416,  184,   -604,  -564,  -20,  296,
80*77c1e3ccSAndroid Build Coastguard Worker   60,    892,   -888,  60,    164,   68,    -760,  216,   -296,  904,  -336,
81*77c1e3ccSAndroid Build Coastguard Worker   -28,   404,   -356,  -568,  -208,  -1480, -512,  296,   328,   -360, -164,
82*77c1e3ccSAndroid Build Coastguard Worker   -1560, -776,  1156,  -428,  164,   -504,  -112,  120,   -216,  -148, -264,
83*77c1e3ccSAndroid Build Coastguard Worker   308,   32,    64,    -72,   72,    116,   176,   -64,   -272,  460,  -536,
84*77c1e3ccSAndroid Build Coastguard Worker   -784,  -280,  348,   108,   -752,  -132,  524,   -540,  -776,  116,  -296,
85*77c1e3ccSAndroid Build Coastguard Worker   -1196, -288,  -560,  1040,  -472,  116,   -848,  -1116, 116,   636,  696,
86*77c1e3ccSAndroid Build Coastguard Worker   284,   -176,  1016,  204,   -864,  -648,  -248,  356,   972,   -584, -204,
87*77c1e3ccSAndroid Build Coastguard Worker   264,   880,   528,   -24,   -184,  116,   448,   -144,  828,   524,  212,
88*77c1e3ccSAndroid Build Coastguard Worker   -212,  52,    12,    200,   268,   -488,  -404,  -880,  824,   -672, -40,
89*77c1e3ccSAndroid Build Coastguard Worker   908,   -248,  500,   716,   -576,  492,   -576,  16,    720,   -108, 384,
90*77c1e3ccSAndroid Build Coastguard Worker   124,   344,   280,   576,   -500,  252,   104,   -308,  196,   -188, -8,
91*77c1e3ccSAndroid Build Coastguard Worker   1268,  296,   1032,  -1196, 436,   316,   372,   -432,  -200,  -660, 704,
92*77c1e3ccSAndroid Build Coastguard Worker   -224,  596,   -132,  268,   32,    -452,  884,   104,   -1008, 424,  -1348,
93*77c1e3ccSAndroid Build Coastguard Worker   -280,  4,     -1168, 368,   476,   696,   300,   -8,    24,    180,  -592,
94*77c1e3ccSAndroid Build Coastguard Worker   -196,  388,   304,   500,   724,   -160,  244,   -84,   272,   -256, -420,
95*77c1e3ccSAndroid Build Coastguard Worker   320,   208,   -144,  -156,  156,   364,   452,   28,    540,   316,  220,
96*77c1e3ccSAndroid Build Coastguard Worker   -644,  -248,  464,   72,    360,   32,    -388,  496,   -680,  -48,  208,
97*77c1e3ccSAndroid Build Coastguard Worker   -116,  -408,  60,    -604,  -392,  548,   -840,  784,   -460,  656,  -544,
98*77c1e3ccSAndroid Build Coastguard Worker   -388,  -264,  908,   -800,  -628,  -612,  -568,  572,   -220,  164,  288,
99*77c1e3ccSAndroid Build Coastguard Worker   -16,   -308,  308,   -112,  -636,  -760,  280,   -668,  432,   364,  240,
100*77c1e3ccSAndroid Build Coastguard Worker   -196,  604,   340,   384,   196,   592,   -44,   -500,  432,   -580, -132,
101*77c1e3ccSAndroid Build Coastguard Worker   636,   -76,   392,   4,     -412,  540,   508,   328,   -356,  -36,  16,
102*77c1e3ccSAndroid Build Coastguard Worker   -220,  -64,   -248,  -60,   24,    -192,  368,   1040,  92,    -24,  -1044,
103*77c1e3ccSAndroid Build Coastguard Worker   -32,   40,    104,   148,   192,   -136,  -520,  56,    -816,  -224, 732,
104*77c1e3ccSAndroid Build Coastguard Worker   392,   356,   212,   -80,   -424,  -1008, -324,  588,   -1496, 576,  460,
105*77c1e3ccSAndroid Build Coastguard Worker   -816,  -848,  56,    -580,  -92,   -1372, -112,  -496,  200,   364,  52,
106*77c1e3ccSAndroid Build Coastguard Worker   -140,  48,    -48,   -60,   84,    72,    40,    132,   -356,  -268, -104,
107*77c1e3ccSAndroid Build Coastguard Worker   -284,  -404,  732,   -520,  164,   -304,  -540,  120,   328,   -76,  -460,
108*77c1e3ccSAndroid Build Coastguard Worker   756,   388,   588,   236,   -436,  -72,   -176,  -404,  -316,  -148, 716,
109*77c1e3ccSAndroid Build Coastguard Worker   -604,  404,   -72,   -88,   -888,  -68,   944,   88,    -220,  -344, 960,
110*77c1e3ccSAndroid Build Coastguard Worker   472,   460,   -232,  704,   120,   832,   -228,  692,   -508,  132,  -476,
111*77c1e3ccSAndroid Build Coastguard Worker   844,   -748,  -364,  -44,   1116,  -1104, -1056, 76,    428,   552,  -692,
112*77c1e3ccSAndroid Build Coastguard Worker   60,    356,   96,    -384,  -188,  -612,  -576,  736,   508,   892,  352,
113*77c1e3ccSAndroid Build Coastguard Worker   -1132, 504,   -24,   -352,  324,   332,   -600,  -312,  292,   508,  -144,
114*77c1e3ccSAndroid Build Coastguard Worker   -8,    484,   48,    284,   -260,  -240,  256,   -100,  -292,  -204, -44,
115*77c1e3ccSAndroid Build Coastguard Worker   472,   -204,  908,   -188,  -1000, -256,  92,    1164,  -392,  564,  356,
116*77c1e3ccSAndroid Build Coastguard Worker   652,   -28,   -884,  256,   484,   -192,  760,   -176,  376,   -524, -452,
117*77c1e3ccSAndroid Build Coastguard Worker   -436,  860,   -736,  212,   124,   504,   -476,  468,   76,    -472, 552,
118*77c1e3ccSAndroid Build Coastguard Worker   -692,  -944,  -620,  740,   -240,  400,   132,   20,    192,   -196, 264,
119*77c1e3ccSAndroid Build Coastguard Worker   -668,  -1012, -60,   296,   -316,  -828,  76,    -156,  284,   -768, -448,
120*77c1e3ccSAndroid Build Coastguard Worker   -832,  148,   248,   652,   616,   1236,  288,   -328,  -400,  -124, 588,
121*77c1e3ccSAndroid Build Coastguard Worker   220,   520,   -696,  1032,  768,   -740,  -92,   -272,  296,   448,  -464,
122*77c1e3ccSAndroid Build Coastguard Worker   412,   -200,  392,   440,   -200,  264,   -152,  -260,  320,   1032, 216,
123*77c1e3ccSAndroid Build Coastguard Worker   320,   -8,    -64,   156,   -1016, 1084,  1172,  536,   484,   -432, 132,
124*77c1e3ccSAndroid Build Coastguard Worker   372,   -52,   -256,  84,    116,   -352,  48,    116,   304,   -384, 412,
125*77c1e3ccSAndroid Build Coastguard Worker   924,   -300,  528,   628,   180,   648,   44,    -980,  -220,  1320, 48,
126*77c1e3ccSAndroid Build Coastguard Worker   332,   748,   524,   -268,  -720,  540,   -276,  564,   -344,  -208, -196,
127*77c1e3ccSAndroid Build Coastguard Worker   436,   896,   88,    -392,  132,   80,    -964,  -288,  568,   56,   -48,
128*77c1e3ccSAndroid Build Coastguard Worker   -456,  888,   8,     552,   -156,  -292,  948,   288,   128,   -716, -292,
129*77c1e3ccSAndroid Build Coastguard Worker   1192,  -152,  876,   352,   -600,  -260,  -812,  -468,  -28,   -120, -32,
130*77c1e3ccSAndroid Build Coastguard Worker   -44,   1284,  496,   192,   464,   312,   -76,   -516,  -380,  -456, -1012,
131*77c1e3ccSAndroid Build Coastguard Worker   -48,   308,   -156,  36,    492,   -156,  -808,  188,   1652,  68,   -120,
132*77c1e3ccSAndroid Build Coastguard Worker   -116,  316,   160,   -140,  352,   808,   -416,  592,   316,   -480, 56,
133*77c1e3ccSAndroid Build Coastguard Worker   528,   -204,  -568,  372,   -232,  752,   -344,  744,   -4,    324,  -416,
134*77c1e3ccSAndroid Build Coastguard Worker   -600,  768,   268,   -248,  -88,   -132,  -420,  -432,  80,    -288, 404,
135*77c1e3ccSAndroid Build Coastguard Worker   -316,  -1216, -588,  520,   -108,  92,    -320,  368,   -480,  -216, -92,
136*77c1e3ccSAndroid Build Coastguard Worker   1688,  -300,  180,   1020,  -176,  820,   -68,   -228,  -260,  436,  -904,
137*77c1e3ccSAndroid Build Coastguard Worker   20,    40,    -508,  440,   -736,  312,   332,   204,   760,   -372, 728,
138*77c1e3ccSAndroid Build Coastguard Worker   96,    -20,   -632,  -520,  -560,  336,   1076,  -64,   -532,  776,  584,
139*77c1e3ccSAndroid Build Coastguard Worker   192,   396,   -728,  -520,  276,   -188,  80,    -52,   -612,  -252, -48,
140*77c1e3ccSAndroid Build Coastguard Worker   648,   212,   -688,  228,   -52,   -260,  428,   -412,  -272,  -404, 180,
141*77c1e3ccSAndroid Build Coastguard Worker   816,   -796,  48,    152,   484,   -88,   -216,  988,   696,   188,  -528,
142*77c1e3ccSAndroid Build Coastguard Worker   648,   -116,  -180,  316,   476,   12,    -564,  96,    476,   -252, -364,
143*77c1e3ccSAndroid Build Coastguard Worker   -376,  -392,  556,   -256,  -576,  260,   -352,  120,   -16,   -136, -260,
144*77c1e3ccSAndroid Build Coastguard Worker   -492,  72,    556,   660,   580,   616,   772,   436,   424,   -32,  -324,
145*77c1e3ccSAndroid Build Coastguard Worker   -1268, 416,   -324,  -80,   920,   160,   228,   724,   32,    -516, 64,
146*77c1e3ccSAndroid Build Coastguard Worker   384,   68,    -128,  136,   240,   248,   -204,  -68,   252,   -932, -120,
147*77c1e3ccSAndroid Build Coastguard Worker   -480,  -628,  -84,   192,   852,   -404,  -288,  -132,  204,   100,  168,
148*77c1e3ccSAndroid Build Coastguard Worker   -68,   -196,  -868,  460,   1080,  380,   -80,   244,   0,     484,  -888,
149*77c1e3ccSAndroid Build Coastguard Worker   64,    184,   352,   600,   460,   164,   604,   -196,  320,   -64,  588,
150*77c1e3ccSAndroid Build Coastguard Worker   -184,  228,   12,    372,   48,    -848,  -344,  224,   208,   -200, 484,
151*77c1e3ccSAndroid Build Coastguard Worker   128,   -20,   272,   -468,  -840,  384,   256,   -720,  -520,  -464, -580,
152*77c1e3ccSAndroid Build Coastguard Worker   112,   -120,  644,   -356,  -208,  -608,  -528,  704,   560,   -424, 392,
153*77c1e3ccSAndroid Build Coastguard Worker   828,   40,    84,    200,   -152,  0,     -144,  584,   280,   -120, 80,
154*77c1e3ccSAndroid Build Coastguard Worker   -556,  -972,  -196,  -472,  724,   80,    168,   -32,   88,    160,  -688,
155*77c1e3ccSAndroid Build Coastguard Worker   0,     160,   356,   372,   -776,  740,   -128,  676,   -248,  -480, 4,
156*77c1e3ccSAndroid Build Coastguard Worker   -364,  96,    544,   232,   -1032, 956,   236,   356,   20,    -40,  300,
157*77c1e3ccSAndroid Build Coastguard Worker   24,    -676,  -596,  132,   1120,  -104,  532,   -1096, 568,   648,  444,
158*77c1e3ccSAndroid Build Coastguard Worker   508,   380,   188,   -376,  -604,  1488,  424,   24,    756,   -220, -192,
159*77c1e3ccSAndroid Build Coastguard Worker   716,   120,   920,   688,   168,   44,    -460,  568,   284,   1144, 1160,
160*77c1e3ccSAndroid Build Coastguard Worker   600,   424,   888,   656,   -356,  -320,  220,   316,   -176,  -724, -188,
161*77c1e3ccSAndroid Build Coastguard Worker   -816,  -628,  -348,  -228,  -380,  1012,  -452,  -660,  736,   928,  404,
162*77c1e3ccSAndroid Build Coastguard Worker   -696,  -72,   -268,  -892,  128,   184,   -344,  -780,  360,   336,  400,
163*77c1e3ccSAndroid Build Coastguard Worker   344,   428,   548,   -112,  136,   -228,  -216,  -820,  -516,  340,  92,
164*77c1e3ccSAndroid Build Coastguard Worker   -136,  116,   -300,  376,   -244,  100,   -316,  -520,  -284,  -12,  824,
165*77c1e3ccSAndroid Build Coastguard Worker   164,   -548,  -180,  -128,  116,   -924,  -828,  268,   -368,  -580, 620,
166*77c1e3ccSAndroid Build Coastguard Worker   192,   160,   0,     -1676, 1068,  424,   -56,   -360,  468,   -156, 720,
167*77c1e3ccSAndroid Build Coastguard Worker   288,   -528,  556,   -364,  548,   -148,  504,   316,   152,   -648, -620,
168*77c1e3ccSAndroid Build Coastguard Worker   -684,  -24,   -376,  -384,  -108,  -920,  -1032, 768,   180,   -264, -508,
169*77c1e3ccSAndroid Build Coastguard Worker   -1268, -260,  -60,   300,   -240,  988,   724,   -376,  -576,  -212, -736,
170*77c1e3ccSAndroid Build Coastguard Worker   556,   192,   1092,  -620,  -880,  376,   -56,   -4,    -216,  -32,  836,
171*77c1e3ccSAndroid Build Coastguard Worker   268,   396,   1332,  864,   -600,  100,   56,    -412,  -92,   356,  180,
172*77c1e3ccSAndroid Build Coastguard Worker   884,   -468,  -436,  292,   -388,  -804,  -704,  -840,  368,   -348, 140,
173*77c1e3ccSAndroid Build Coastguard Worker   -724,  1536,  940,   372,   112,   -372,  436,   -480,  1136,  296,  -32,
174*77c1e3ccSAndroid Build Coastguard Worker   -228,  132,   -48,   -220,  868,   -1016, -60,   -1044, -464,  328,  916,
175*77c1e3ccSAndroid Build Coastguard Worker   244,   12,    -736,  -296,  360,   468,   -376,  -108,  -92,   788,  368,
176*77c1e3ccSAndroid Build Coastguard Worker   -56,   544,   400,   -672,  -420,  728,   16,    320,   44,    -284, -380,
177*77c1e3ccSAndroid Build Coastguard Worker   -796,  488,   132,   204,   -596,  -372,  88,    -152,  -908,  -636, -572,
178*77c1e3ccSAndroid Build Coastguard Worker   -624,  -116,  -692,  -200,  -56,   276,   -88,   484,   -324,  948,  864,
179*77c1e3ccSAndroid Build Coastguard Worker   1000,  -456,  -184,  -276,  292,   -296,  156,   676,   320,   160,  908,
180*77c1e3ccSAndroid Build Coastguard Worker   -84,   -1236, -288,  -116,  260,   -372,  -644,  732,   -756,  -96,  84,
181*77c1e3ccSAndroid Build Coastguard Worker   344,   -520,  348,   -688,  240,   -84,   216,   -1044, -136,  -676, -396,
182*77c1e3ccSAndroid Build Coastguard Worker   -1500, 960,   -40,   176,   168,   1516,  420,   -504,  -344,  -364, -360,
183*77c1e3ccSAndroid Build Coastguard Worker   1216,  -940,  -380,  -212,  252,   -660,  -708,  484,   -444,  -152, 928,
184*77c1e3ccSAndroid Build Coastguard Worker   -120,  1112,  476,   -260,  560,   -148,  -344,  108,   -196,  228,  -288,
185*77c1e3ccSAndroid Build Coastguard Worker   504,   560,   -328,  -88,   288,   -1008, 460,   -228,  468,   -836, -196,
186*77c1e3ccSAndroid Build Coastguard Worker   76,    388,   232,   412,   -1168, -716,  -644,  756,   -172,  -356, -504,
187*77c1e3ccSAndroid Build Coastguard Worker   116,   432,   528,   48,    476,   -168,  -608,  448,   160,   -532, -272,
188*77c1e3ccSAndroid Build Coastguard Worker   28,    -676,  -12,   828,   980,   456,   520,   104,   -104,  256,  -344,
189*77c1e3ccSAndroid Build Coastguard Worker   -4,    -28,   -368,  -52,   -524,  -572,  -556,  -200,  768,   1124, -208,
190*77c1e3ccSAndroid Build Coastguard Worker   -512,  176,   232,   248,   -148,  -888,  604,   -600,  -304,  804,  -156,
191*77c1e3ccSAndroid Build Coastguard Worker   -212,  488,   -192,  -804,  -256,  368,   -360,  -916,  -328,  228,  -240,
192*77c1e3ccSAndroid Build Coastguard Worker   -448,  -472,  856,   -556,  -364,  572,   -12,   -156,  -368,  -340, 432,
193*77c1e3ccSAndroid Build Coastguard Worker   252,   -752,  -152,  288,   268,   -580,  -848,  -592,  108,   -76,  244,
194*77c1e3ccSAndroid Build Coastguard Worker   312,   -716,  592,   -80,   436,   360,   4,     -248,  160,   516,  584,
195*77c1e3ccSAndroid Build Coastguard Worker   732,   44,    -468,  -280,  -292,  -156,  -588,  28,    308,   912,  24,
196*77c1e3ccSAndroid Build Coastguard Worker   124,   156,   180,   -252,  944,   -924,  -772,  -520,  -428,  -624, 300,
197*77c1e3ccSAndroid Build Coastguard Worker   -212,  -1144, 32,    -724,  800,   -1128, -212,  -1288, -848,  180,  -416,
198*77c1e3ccSAndroid Build Coastguard Worker   440,   192,   -576,  -792,  -76,   -1080, 80,    -532,  -352,  -132, 380,
199*77c1e3ccSAndroid Build Coastguard Worker   -820,  148,   1112,  128,   164,   456,   700,   -924,  144,   -668, -384,
200*77c1e3ccSAndroid Build Coastguard Worker   648,   -832,  508,   552,   -52,   -100,  -656,  208,   -568,  748,  -88,
201*77c1e3ccSAndroid Build Coastguard Worker   680,   232,   300,   192,   -408,  -1012, -152,  -252,  -268,  272,  -876,
202*77c1e3ccSAndroid Build Coastguard Worker   -664,  -648,  -332,  -136,  16,    12,    1152,  -28,   332,   -536, 320,
203*77c1e3ccSAndroid Build Coastguard Worker   -672,  -460,  -316,  532,   -260,  228,   -40,   1052,  -816,  180,  88,
204*77c1e3ccSAndroid Build Coastguard Worker   -496,  -556,  -672,  -368,  428,   92,    356,   404,   -408,  252,  196,
205*77c1e3ccSAndroid Build Coastguard Worker   -176,  -556,  792,   268,   32,    372,   40,    96,    -332,  328,  120,
206*77c1e3ccSAndroid Build Coastguard Worker   372,   -900,  -40,   472,   -264,  -592,  952,   128,   656,   112,  664,
207*77c1e3ccSAndroid Build Coastguard Worker   -232,  420,   4,     -344,  -464,  556,   244,   -416,  -32,   252,  0,
208*77c1e3ccSAndroid Build Coastguard Worker   -412,  188,   -696,  508,   -476,  324,   -1096, 656,   -312,  560,  264,
209*77c1e3ccSAndroid Build Coastguard Worker   -136,  304,   160,   -64,   -580,  248,   336,   -720,  560,   -348, -288,
210*77c1e3ccSAndroid Build Coastguard Worker   -276,  -196,  -500,  852,   -544,  -236,  -1128, -992,  -776,  116,  56,
211*77c1e3ccSAndroid Build Coastguard Worker   52,    860,   884,   212,   -12,   168,   1020,  512,   -552,  924,  -148,
212*77c1e3ccSAndroid Build Coastguard Worker   716,   188,   164,   -340,  -520,  -184,  880,   -152,  -680,  -208, -1156,
213*77c1e3ccSAndroid Build Coastguard Worker   -300,  -528,  -472,  364,   100,   -744,  -1056, -32,   540,   280,  144,
214*77c1e3ccSAndroid Build Coastguard Worker   -676,  -32,   -232,  -280,  -224,  96,    568,   -76,   172,   148,  148,
215*77c1e3ccSAndroid Build Coastguard Worker   104,   32,    -296,  -32,   788,   -80,   32,    -16,   280,   288,  944,
216*77c1e3ccSAndroid Build Coastguard Worker   428,   -484
217*77c1e3ccSAndroid Build Coastguard Worker };
218*77c1e3ccSAndroid Build Coastguard Worker 
219*77c1e3ccSAndroid Build Coastguard Worker static const int gauss_bits = 11;
220*77c1e3ccSAndroid Build Coastguard Worker 
221*77c1e3ccSAndroid Build Coastguard Worker static int luma_subblock_size_y = 32;
222*77c1e3ccSAndroid Build Coastguard Worker static int luma_subblock_size_x = 32;
223*77c1e3ccSAndroid Build Coastguard Worker 
224*77c1e3ccSAndroid Build Coastguard Worker static int chroma_subblock_size_y = 16;
225*77c1e3ccSAndroid Build Coastguard Worker static int chroma_subblock_size_x = 16;
226*77c1e3ccSAndroid Build Coastguard Worker 
227*77c1e3ccSAndroid Build Coastguard Worker static const int min_luma_legal_range = 16;
228*77c1e3ccSAndroid Build Coastguard Worker static const int max_luma_legal_range = 235;
229*77c1e3ccSAndroid Build Coastguard Worker 
230*77c1e3ccSAndroid Build Coastguard Worker static const int min_chroma_legal_range = 16;
231*77c1e3ccSAndroid Build Coastguard Worker static const int max_chroma_legal_range = 240;
232*77c1e3ccSAndroid Build Coastguard Worker 
233*77c1e3ccSAndroid Build Coastguard Worker static int scaling_lut_y[256];
234*77c1e3ccSAndroid Build Coastguard Worker static int scaling_lut_cb[256];
235*77c1e3ccSAndroid Build Coastguard Worker static int scaling_lut_cr[256];
236*77c1e3ccSAndroid Build Coastguard Worker 
237*77c1e3ccSAndroid Build Coastguard Worker static int grain_min;
238*77c1e3ccSAndroid Build Coastguard Worker static int grain_max;
239*77c1e3ccSAndroid Build Coastguard Worker 
240*77c1e3ccSAndroid Build Coastguard Worker static uint16_t random_register = 0;  // random number generator register
241*77c1e3ccSAndroid Build Coastguard Worker 
dealloc_arrays(const aom_film_grain_t * params,int *** pred_pos_luma,int *** pred_pos_chroma,int ** luma_grain_block,int ** cb_grain_block,int ** cr_grain_block,int ** y_line_buf,int ** cb_line_buf,int ** cr_line_buf,int ** y_col_buf,int ** cb_col_buf,int ** cr_col_buf)242*77c1e3ccSAndroid Build Coastguard Worker static void dealloc_arrays(const aom_film_grain_t *params, int ***pred_pos_luma,
243*77c1e3ccSAndroid Build Coastguard Worker                            int ***pred_pos_chroma, int **luma_grain_block,
244*77c1e3ccSAndroid Build Coastguard Worker                            int **cb_grain_block, int **cr_grain_block,
245*77c1e3ccSAndroid Build Coastguard Worker                            int **y_line_buf, int **cb_line_buf,
246*77c1e3ccSAndroid Build Coastguard Worker                            int **cr_line_buf, int **y_col_buf, int **cb_col_buf,
247*77c1e3ccSAndroid Build Coastguard Worker                            int **cr_col_buf) {
248*77c1e3ccSAndroid Build Coastguard Worker   int num_pos_luma = 2 * params->ar_coeff_lag * (params->ar_coeff_lag + 1);
249*77c1e3ccSAndroid Build Coastguard Worker   int num_pos_chroma = num_pos_luma;
250*77c1e3ccSAndroid Build Coastguard Worker   if (params->num_y_points > 0) ++num_pos_chroma;
251*77c1e3ccSAndroid Build Coastguard Worker 
252*77c1e3ccSAndroid Build Coastguard Worker   if (*pred_pos_luma) {
253*77c1e3ccSAndroid Build Coastguard Worker     for (int row = 0; row < num_pos_luma; row++) {
254*77c1e3ccSAndroid Build Coastguard Worker       aom_free((*pred_pos_luma)[row]);
255*77c1e3ccSAndroid Build Coastguard Worker     }
256*77c1e3ccSAndroid Build Coastguard Worker     aom_free(*pred_pos_luma);
257*77c1e3ccSAndroid Build Coastguard Worker     *pred_pos_luma = NULL;
258*77c1e3ccSAndroid Build Coastguard Worker   }
259*77c1e3ccSAndroid Build Coastguard Worker 
260*77c1e3ccSAndroid Build Coastguard Worker   if (*pred_pos_chroma) {
261*77c1e3ccSAndroid Build Coastguard Worker     for (int row = 0; row < num_pos_chroma; row++) {
262*77c1e3ccSAndroid Build Coastguard Worker       aom_free((*pred_pos_chroma)[row]);
263*77c1e3ccSAndroid Build Coastguard Worker     }
264*77c1e3ccSAndroid Build Coastguard Worker     aom_free(*pred_pos_chroma);
265*77c1e3ccSAndroid Build Coastguard Worker     *pred_pos_chroma = NULL;
266*77c1e3ccSAndroid Build Coastguard Worker   }
267*77c1e3ccSAndroid Build Coastguard Worker 
268*77c1e3ccSAndroid Build Coastguard Worker   aom_free(*y_line_buf);
269*77c1e3ccSAndroid Build Coastguard Worker   *y_line_buf = NULL;
270*77c1e3ccSAndroid Build Coastguard Worker 
271*77c1e3ccSAndroid Build Coastguard Worker   aom_free(*cb_line_buf);
272*77c1e3ccSAndroid Build Coastguard Worker   *cb_line_buf = NULL;
273*77c1e3ccSAndroid Build Coastguard Worker 
274*77c1e3ccSAndroid Build Coastguard Worker   aom_free(*cr_line_buf);
275*77c1e3ccSAndroid Build Coastguard Worker   *cr_line_buf = NULL;
276*77c1e3ccSAndroid Build Coastguard Worker 
277*77c1e3ccSAndroid Build Coastguard Worker   aom_free(*y_col_buf);
278*77c1e3ccSAndroid Build Coastguard Worker   *y_col_buf = NULL;
279*77c1e3ccSAndroid Build Coastguard Worker 
280*77c1e3ccSAndroid Build Coastguard Worker   aom_free(*cb_col_buf);
281*77c1e3ccSAndroid Build Coastguard Worker   *cb_col_buf = NULL;
282*77c1e3ccSAndroid Build Coastguard Worker 
283*77c1e3ccSAndroid Build Coastguard Worker   aom_free(*cr_col_buf);
284*77c1e3ccSAndroid Build Coastguard Worker   *cr_col_buf = NULL;
285*77c1e3ccSAndroid Build Coastguard Worker 
286*77c1e3ccSAndroid Build Coastguard Worker   aom_free(*luma_grain_block);
287*77c1e3ccSAndroid Build Coastguard Worker   *luma_grain_block = NULL;
288*77c1e3ccSAndroid Build Coastguard Worker 
289*77c1e3ccSAndroid Build Coastguard Worker   aom_free(*cb_grain_block);
290*77c1e3ccSAndroid Build Coastguard Worker   *cb_grain_block = NULL;
291*77c1e3ccSAndroid Build Coastguard Worker 
292*77c1e3ccSAndroid Build Coastguard Worker   aom_free(*cr_grain_block);
293*77c1e3ccSAndroid Build Coastguard Worker   *cr_grain_block = NULL;
294*77c1e3ccSAndroid Build Coastguard Worker }
295*77c1e3ccSAndroid Build Coastguard Worker 
init_arrays(const aom_film_grain_t * params,int luma_stride,int chroma_stride,int *** pred_pos_luma_p,int *** pred_pos_chroma_p,int ** luma_grain_block,int ** cb_grain_block,int ** cr_grain_block,int ** y_line_buf,int ** cb_line_buf,int ** cr_line_buf,int ** y_col_buf,int ** cb_col_buf,int ** cr_col_buf,int luma_grain_samples,int chroma_grain_samples,int chroma_subsamp_y,int chroma_subsamp_x)296*77c1e3ccSAndroid Build Coastguard Worker static bool init_arrays(const aom_film_grain_t *params, int luma_stride,
297*77c1e3ccSAndroid Build Coastguard Worker                         int chroma_stride, int ***pred_pos_luma_p,
298*77c1e3ccSAndroid Build Coastguard Worker                         int ***pred_pos_chroma_p, int **luma_grain_block,
299*77c1e3ccSAndroid Build Coastguard Worker                         int **cb_grain_block, int **cr_grain_block,
300*77c1e3ccSAndroid Build Coastguard Worker                         int **y_line_buf, int **cb_line_buf, int **cr_line_buf,
301*77c1e3ccSAndroid Build Coastguard Worker                         int **y_col_buf, int **cb_col_buf, int **cr_col_buf,
302*77c1e3ccSAndroid Build Coastguard Worker                         int luma_grain_samples, int chroma_grain_samples,
303*77c1e3ccSAndroid Build Coastguard Worker                         int chroma_subsamp_y, int chroma_subsamp_x) {
304*77c1e3ccSAndroid Build Coastguard Worker   *pred_pos_luma_p = NULL;
305*77c1e3ccSAndroid Build Coastguard Worker   *pred_pos_chroma_p = NULL;
306*77c1e3ccSAndroid Build Coastguard Worker   *luma_grain_block = NULL;
307*77c1e3ccSAndroid Build Coastguard Worker   *cb_grain_block = NULL;
308*77c1e3ccSAndroid Build Coastguard Worker   *cr_grain_block = NULL;
309*77c1e3ccSAndroid Build Coastguard Worker   *y_line_buf = NULL;
310*77c1e3ccSAndroid Build Coastguard Worker   *cb_line_buf = NULL;
311*77c1e3ccSAndroid Build Coastguard Worker   *cr_line_buf = NULL;
312*77c1e3ccSAndroid Build Coastguard Worker   *y_col_buf = NULL;
313*77c1e3ccSAndroid Build Coastguard Worker   *cb_col_buf = NULL;
314*77c1e3ccSAndroid Build Coastguard Worker   *cr_col_buf = NULL;
315*77c1e3ccSAndroid Build Coastguard Worker 
316*77c1e3ccSAndroid Build Coastguard Worker   memset(scaling_lut_y, 0, sizeof(*scaling_lut_y) * 256);
317*77c1e3ccSAndroid Build Coastguard Worker   memset(scaling_lut_cb, 0, sizeof(*scaling_lut_cb) * 256);
318*77c1e3ccSAndroid Build Coastguard Worker   memset(scaling_lut_cr, 0, sizeof(*scaling_lut_cr) * 256);
319*77c1e3ccSAndroid Build Coastguard Worker 
320*77c1e3ccSAndroid Build Coastguard Worker   int num_pos_luma = 2 * params->ar_coeff_lag * (params->ar_coeff_lag + 1);
321*77c1e3ccSAndroid Build Coastguard Worker   int num_pos_chroma = num_pos_luma;
322*77c1e3ccSAndroid Build Coastguard Worker   if (params->num_y_points > 0) ++num_pos_chroma;
323*77c1e3ccSAndroid Build Coastguard Worker 
324*77c1e3ccSAndroid Build Coastguard Worker   int **pred_pos_luma;
325*77c1e3ccSAndroid Build Coastguard Worker   int **pred_pos_chroma;
326*77c1e3ccSAndroid Build Coastguard Worker 
327*77c1e3ccSAndroid Build Coastguard Worker   pred_pos_luma = (int **)aom_calloc(num_pos_luma, sizeof(*pred_pos_luma));
328*77c1e3ccSAndroid Build Coastguard Worker   if (!pred_pos_luma) return false;
329*77c1e3ccSAndroid Build Coastguard Worker 
330*77c1e3ccSAndroid Build Coastguard Worker   for (int row = 0; row < num_pos_luma; row++) {
331*77c1e3ccSAndroid Build Coastguard Worker     pred_pos_luma[row] = (int *)aom_malloc(sizeof(**pred_pos_luma) * 3);
332*77c1e3ccSAndroid Build Coastguard Worker     if (!pred_pos_luma[row]) {
333*77c1e3ccSAndroid Build Coastguard Worker       dealloc_arrays(params, pred_pos_luma_p, pred_pos_chroma_p,
334*77c1e3ccSAndroid Build Coastguard Worker                      luma_grain_block, cb_grain_block, cr_grain_block,
335*77c1e3ccSAndroid Build Coastguard Worker                      y_line_buf, cb_line_buf, cr_line_buf, y_col_buf,
336*77c1e3ccSAndroid Build Coastguard Worker                      cb_col_buf, cr_col_buf);
337*77c1e3ccSAndroid Build Coastguard Worker       return false;
338*77c1e3ccSAndroid Build Coastguard Worker     }
339*77c1e3ccSAndroid Build Coastguard Worker   }
340*77c1e3ccSAndroid Build Coastguard Worker 
341*77c1e3ccSAndroid Build Coastguard Worker   pred_pos_chroma =
342*77c1e3ccSAndroid Build Coastguard Worker       (int **)aom_calloc(num_pos_chroma, sizeof(*pred_pos_chroma));
343*77c1e3ccSAndroid Build Coastguard Worker   if (!pred_pos_chroma) {
344*77c1e3ccSAndroid Build Coastguard Worker     dealloc_arrays(params, pred_pos_luma_p, pred_pos_chroma_p, luma_grain_block,
345*77c1e3ccSAndroid Build Coastguard Worker                    cb_grain_block, cr_grain_block, y_line_buf, cb_line_buf,
346*77c1e3ccSAndroid Build Coastguard Worker                    cr_line_buf, y_col_buf, cb_col_buf, cr_col_buf);
347*77c1e3ccSAndroid Build Coastguard Worker     return false;
348*77c1e3ccSAndroid Build Coastguard Worker   }
349*77c1e3ccSAndroid Build Coastguard Worker 
350*77c1e3ccSAndroid Build Coastguard Worker   for (int row = 0; row < num_pos_chroma; row++) {
351*77c1e3ccSAndroid Build Coastguard Worker     pred_pos_chroma[row] = (int *)aom_malloc(sizeof(**pred_pos_chroma) * 3);
352*77c1e3ccSAndroid Build Coastguard Worker     if (!pred_pos_chroma[row]) {
353*77c1e3ccSAndroid Build Coastguard Worker       dealloc_arrays(params, pred_pos_luma_p, pred_pos_chroma_p,
354*77c1e3ccSAndroid Build Coastguard Worker                      luma_grain_block, cb_grain_block, cr_grain_block,
355*77c1e3ccSAndroid Build Coastguard Worker                      y_line_buf, cb_line_buf, cr_line_buf, y_col_buf,
356*77c1e3ccSAndroid Build Coastguard Worker                      cb_col_buf, cr_col_buf);
357*77c1e3ccSAndroid Build Coastguard Worker       return false;
358*77c1e3ccSAndroid Build Coastguard Worker     }
359*77c1e3ccSAndroid Build Coastguard Worker   }
360*77c1e3ccSAndroid Build Coastguard Worker 
361*77c1e3ccSAndroid Build Coastguard Worker   int pos_ar_index = 0;
362*77c1e3ccSAndroid Build Coastguard Worker 
363*77c1e3ccSAndroid Build Coastguard Worker   for (int row = -params->ar_coeff_lag; row < 0; row++) {
364*77c1e3ccSAndroid Build Coastguard Worker     for (int col = -params->ar_coeff_lag; col < params->ar_coeff_lag + 1;
365*77c1e3ccSAndroid Build Coastguard Worker          col++) {
366*77c1e3ccSAndroid Build Coastguard Worker       pred_pos_luma[pos_ar_index][0] = row;
367*77c1e3ccSAndroid Build Coastguard Worker       pred_pos_luma[pos_ar_index][1] = col;
368*77c1e3ccSAndroid Build Coastguard Worker       pred_pos_luma[pos_ar_index][2] = 0;
369*77c1e3ccSAndroid Build Coastguard Worker 
370*77c1e3ccSAndroid Build Coastguard Worker       pred_pos_chroma[pos_ar_index][0] = row;
371*77c1e3ccSAndroid Build Coastguard Worker       pred_pos_chroma[pos_ar_index][1] = col;
372*77c1e3ccSAndroid Build Coastguard Worker       pred_pos_chroma[pos_ar_index][2] = 0;
373*77c1e3ccSAndroid Build Coastguard Worker       ++pos_ar_index;
374*77c1e3ccSAndroid Build Coastguard Worker     }
375*77c1e3ccSAndroid Build Coastguard Worker   }
376*77c1e3ccSAndroid Build Coastguard Worker 
377*77c1e3ccSAndroid Build Coastguard Worker   for (int col = -params->ar_coeff_lag; col < 0; col++) {
378*77c1e3ccSAndroid Build Coastguard Worker     pred_pos_luma[pos_ar_index][0] = 0;
379*77c1e3ccSAndroid Build Coastguard Worker     pred_pos_luma[pos_ar_index][1] = col;
380*77c1e3ccSAndroid Build Coastguard Worker     pred_pos_luma[pos_ar_index][2] = 0;
381*77c1e3ccSAndroid Build Coastguard Worker 
382*77c1e3ccSAndroid Build Coastguard Worker     pred_pos_chroma[pos_ar_index][0] = 0;
383*77c1e3ccSAndroid Build Coastguard Worker     pred_pos_chroma[pos_ar_index][1] = col;
384*77c1e3ccSAndroid Build Coastguard Worker     pred_pos_chroma[pos_ar_index][2] = 0;
385*77c1e3ccSAndroid Build Coastguard Worker 
386*77c1e3ccSAndroid Build Coastguard Worker     ++pos_ar_index;
387*77c1e3ccSAndroid Build Coastguard Worker   }
388*77c1e3ccSAndroid Build Coastguard Worker 
389*77c1e3ccSAndroid Build Coastguard Worker   if (params->num_y_points > 0) {
390*77c1e3ccSAndroid Build Coastguard Worker     pred_pos_chroma[pos_ar_index][0] = 0;
391*77c1e3ccSAndroid Build Coastguard Worker     pred_pos_chroma[pos_ar_index][1] = 0;
392*77c1e3ccSAndroid Build Coastguard Worker     pred_pos_chroma[pos_ar_index][2] = 1;
393*77c1e3ccSAndroid Build Coastguard Worker   }
394*77c1e3ccSAndroid Build Coastguard Worker 
395*77c1e3ccSAndroid Build Coastguard Worker   *pred_pos_luma_p = pred_pos_luma;
396*77c1e3ccSAndroid Build Coastguard Worker   *pred_pos_chroma_p = pred_pos_chroma;
397*77c1e3ccSAndroid Build Coastguard Worker 
398*77c1e3ccSAndroid Build Coastguard Worker   *y_line_buf = (int *)aom_malloc(sizeof(**y_line_buf) * luma_stride * 2);
399*77c1e3ccSAndroid Build Coastguard Worker   *cb_line_buf = (int *)aom_malloc(sizeof(**cb_line_buf) * chroma_stride *
400*77c1e3ccSAndroid Build Coastguard Worker                                    (2 >> chroma_subsamp_y));
401*77c1e3ccSAndroid Build Coastguard Worker   *cr_line_buf = (int *)aom_malloc(sizeof(**cr_line_buf) * chroma_stride *
402*77c1e3ccSAndroid Build Coastguard Worker                                    (2 >> chroma_subsamp_y));
403*77c1e3ccSAndroid Build Coastguard Worker 
404*77c1e3ccSAndroid Build Coastguard Worker   *y_col_buf =
405*77c1e3ccSAndroid Build Coastguard Worker       (int *)aom_malloc(sizeof(**y_col_buf) * (luma_subblock_size_y + 2) * 2);
406*77c1e3ccSAndroid Build Coastguard Worker   *cb_col_buf =
407*77c1e3ccSAndroid Build Coastguard Worker       (int *)aom_malloc(sizeof(**cb_col_buf) *
408*77c1e3ccSAndroid Build Coastguard Worker                         (chroma_subblock_size_y + (2 >> chroma_subsamp_y)) *
409*77c1e3ccSAndroid Build Coastguard Worker                         (2 >> chroma_subsamp_x));
410*77c1e3ccSAndroid Build Coastguard Worker   *cr_col_buf =
411*77c1e3ccSAndroid Build Coastguard Worker       (int *)aom_malloc(sizeof(**cr_col_buf) *
412*77c1e3ccSAndroid Build Coastguard Worker                         (chroma_subblock_size_y + (2 >> chroma_subsamp_y)) *
413*77c1e3ccSAndroid Build Coastguard Worker                         (2 >> chroma_subsamp_x));
414*77c1e3ccSAndroid Build Coastguard Worker 
415*77c1e3ccSAndroid Build Coastguard Worker   *luma_grain_block =
416*77c1e3ccSAndroid Build Coastguard Worker       (int *)aom_malloc(sizeof(**luma_grain_block) * luma_grain_samples);
417*77c1e3ccSAndroid Build Coastguard Worker   *cb_grain_block =
418*77c1e3ccSAndroid Build Coastguard Worker       (int *)aom_malloc(sizeof(**cb_grain_block) * chroma_grain_samples);
419*77c1e3ccSAndroid Build Coastguard Worker   *cr_grain_block =
420*77c1e3ccSAndroid Build Coastguard Worker       (int *)aom_malloc(sizeof(**cr_grain_block) * chroma_grain_samples);
421*77c1e3ccSAndroid Build Coastguard Worker   if (!(*pred_pos_luma_p && *pred_pos_chroma_p && *y_line_buf && *cb_line_buf &&
422*77c1e3ccSAndroid Build Coastguard Worker         *cr_line_buf && *y_col_buf && *cb_col_buf && *cr_col_buf &&
423*77c1e3ccSAndroid Build Coastguard Worker         *luma_grain_block && *cb_grain_block && *cr_grain_block)) {
424*77c1e3ccSAndroid Build Coastguard Worker     dealloc_arrays(params, pred_pos_luma_p, pred_pos_chroma_p, luma_grain_block,
425*77c1e3ccSAndroid Build Coastguard Worker                    cb_grain_block, cr_grain_block, y_line_buf, cb_line_buf,
426*77c1e3ccSAndroid Build Coastguard Worker                    cr_line_buf, y_col_buf, cb_col_buf, cr_col_buf);
427*77c1e3ccSAndroid Build Coastguard Worker     return false;
428*77c1e3ccSAndroid Build Coastguard Worker   }
429*77c1e3ccSAndroid Build Coastguard Worker   return true;
430*77c1e3ccSAndroid Build Coastguard Worker }
431*77c1e3ccSAndroid Build Coastguard Worker 
432*77c1e3ccSAndroid Build Coastguard Worker // get a number between 0 and 2^bits - 1
get_random_number(int bits)433*77c1e3ccSAndroid Build Coastguard Worker static inline int get_random_number(int bits) {
434*77c1e3ccSAndroid Build Coastguard Worker   uint16_t bit;
435*77c1e3ccSAndroid Build Coastguard Worker   bit = ((random_register >> 0) ^ (random_register >> 1) ^
436*77c1e3ccSAndroid Build Coastguard Worker          (random_register >> 3) ^ (random_register >> 12)) &
437*77c1e3ccSAndroid Build Coastguard Worker         1;
438*77c1e3ccSAndroid Build Coastguard Worker   random_register = (random_register >> 1) | (bit << 15);
439*77c1e3ccSAndroid Build Coastguard Worker   return (random_register >> (16 - bits)) & ((1 << bits) - 1);
440*77c1e3ccSAndroid Build Coastguard Worker }
441*77c1e3ccSAndroid Build Coastguard Worker 
init_random_generator(int luma_line,uint16_t seed)442*77c1e3ccSAndroid Build Coastguard Worker static void init_random_generator(int luma_line, uint16_t seed) {
443*77c1e3ccSAndroid Build Coastguard Worker   // same for the picture
444*77c1e3ccSAndroid Build Coastguard Worker 
445*77c1e3ccSAndroid Build Coastguard Worker   uint16_t msb = (seed >> 8) & 255;
446*77c1e3ccSAndroid Build Coastguard Worker   uint16_t lsb = seed & 255;
447*77c1e3ccSAndroid Build Coastguard Worker 
448*77c1e3ccSAndroid Build Coastguard Worker   random_register = (msb << 8) + lsb;
449*77c1e3ccSAndroid Build Coastguard Worker 
450*77c1e3ccSAndroid Build Coastguard Worker   //  changes for each row
451*77c1e3ccSAndroid Build Coastguard Worker   int luma_num = luma_line >> 5;
452*77c1e3ccSAndroid Build Coastguard Worker 
453*77c1e3ccSAndroid Build Coastguard Worker   random_register ^= ((luma_num * 37 + 178) & 255) << 8;
454*77c1e3ccSAndroid Build Coastguard Worker   random_register ^= ((luma_num * 173 + 105) & 255);
455*77c1e3ccSAndroid Build Coastguard Worker }
456*77c1e3ccSAndroid Build Coastguard Worker 
generate_luma_grain_block(const aom_film_grain_t * params,int ** pred_pos_luma,int * luma_grain_block,int luma_block_size_y,int luma_block_size_x,int luma_grain_stride,int left_pad,int top_pad,int right_pad,int bottom_pad)457*77c1e3ccSAndroid Build Coastguard Worker static void generate_luma_grain_block(
458*77c1e3ccSAndroid Build Coastguard Worker     const aom_film_grain_t *params, int **pred_pos_luma, int *luma_grain_block,
459*77c1e3ccSAndroid Build Coastguard Worker     int luma_block_size_y, int luma_block_size_x, int luma_grain_stride,
460*77c1e3ccSAndroid Build Coastguard Worker     int left_pad, int top_pad, int right_pad, int bottom_pad) {
461*77c1e3ccSAndroid Build Coastguard Worker   if (params->num_y_points == 0) {
462*77c1e3ccSAndroid Build Coastguard Worker     memset(luma_grain_block, 0,
463*77c1e3ccSAndroid Build Coastguard Worker            sizeof(*luma_grain_block) * luma_block_size_y * luma_grain_stride);
464*77c1e3ccSAndroid Build Coastguard Worker     return;
465*77c1e3ccSAndroid Build Coastguard Worker   }
466*77c1e3ccSAndroid Build Coastguard Worker 
467*77c1e3ccSAndroid Build Coastguard Worker   int bit_depth = params->bit_depth;
468*77c1e3ccSAndroid Build Coastguard Worker   int gauss_sec_shift = 12 - bit_depth + params->grain_scale_shift;
469*77c1e3ccSAndroid Build Coastguard Worker 
470*77c1e3ccSAndroid Build Coastguard Worker   int num_pos_luma = 2 * params->ar_coeff_lag * (params->ar_coeff_lag + 1);
471*77c1e3ccSAndroid Build Coastguard Worker   int rounding_offset = (1 << (params->ar_coeff_shift - 1));
472*77c1e3ccSAndroid Build Coastguard Worker 
473*77c1e3ccSAndroid Build Coastguard Worker   for (int i = 0; i < luma_block_size_y; i++)
474*77c1e3ccSAndroid Build Coastguard Worker     for (int j = 0; j < luma_block_size_x; j++)
475*77c1e3ccSAndroid Build Coastguard Worker       luma_grain_block[i * luma_grain_stride + j] =
476*77c1e3ccSAndroid Build Coastguard Worker           (gaussian_sequence[get_random_number(gauss_bits)] +
477*77c1e3ccSAndroid Build Coastguard Worker            ((1 << gauss_sec_shift) >> 1)) >>
478*77c1e3ccSAndroid Build Coastguard Worker           gauss_sec_shift;
479*77c1e3ccSAndroid Build Coastguard Worker 
480*77c1e3ccSAndroid Build Coastguard Worker   for (int i = top_pad; i < luma_block_size_y - bottom_pad; i++)
481*77c1e3ccSAndroid Build Coastguard Worker     for (int j = left_pad; j < luma_block_size_x - right_pad; j++) {
482*77c1e3ccSAndroid Build Coastguard Worker       int wsum = 0;
483*77c1e3ccSAndroid Build Coastguard Worker       for (int pos = 0; pos < num_pos_luma; pos++) {
484*77c1e3ccSAndroid Build Coastguard Worker         wsum = wsum + params->ar_coeffs_y[pos] *
485*77c1e3ccSAndroid Build Coastguard Worker                           luma_grain_block[(i + pred_pos_luma[pos][0]) *
486*77c1e3ccSAndroid Build Coastguard Worker                                                luma_grain_stride +
487*77c1e3ccSAndroid Build Coastguard Worker                                            j + pred_pos_luma[pos][1]];
488*77c1e3ccSAndroid Build Coastguard Worker       }
489*77c1e3ccSAndroid Build Coastguard Worker       luma_grain_block[i * luma_grain_stride + j] =
490*77c1e3ccSAndroid Build Coastguard Worker           clamp(luma_grain_block[i * luma_grain_stride + j] +
491*77c1e3ccSAndroid Build Coastguard Worker                     ((wsum + rounding_offset) >> params->ar_coeff_shift),
492*77c1e3ccSAndroid Build Coastguard Worker                 grain_min, grain_max);
493*77c1e3ccSAndroid Build Coastguard Worker     }
494*77c1e3ccSAndroid Build Coastguard Worker }
495*77c1e3ccSAndroid Build Coastguard Worker 
generate_chroma_grain_blocks(const aom_film_grain_t * params,int ** pred_pos_chroma,int * luma_grain_block,int * cb_grain_block,int * cr_grain_block,int luma_grain_stride,int chroma_block_size_y,int chroma_block_size_x,int chroma_grain_stride,int left_pad,int top_pad,int right_pad,int bottom_pad,int chroma_subsamp_y,int chroma_subsamp_x)496*77c1e3ccSAndroid Build Coastguard Worker static bool generate_chroma_grain_blocks(
497*77c1e3ccSAndroid Build Coastguard Worker     const aom_film_grain_t *params, int **pred_pos_chroma,
498*77c1e3ccSAndroid Build Coastguard Worker     int *luma_grain_block, int *cb_grain_block, int *cr_grain_block,
499*77c1e3ccSAndroid Build Coastguard Worker     int luma_grain_stride, int chroma_block_size_y, int chroma_block_size_x,
500*77c1e3ccSAndroid Build Coastguard Worker     int chroma_grain_stride, int left_pad, int top_pad, int right_pad,
501*77c1e3ccSAndroid Build Coastguard Worker     int bottom_pad, int chroma_subsamp_y, int chroma_subsamp_x) {
502*77c1e3ccSAndroid Build Coastguard Worker   int bit_depth = params->bit_depth;
503*77c1e3ccSAndroid Build Coastguard Worker   int gauss_sec_shift = 12 - bit_depth + params->grain_scale_shift;
504*77c1e3ccSAndroid Build Coastguard Worker 
505*77c1e3ccSAndroid Build Coastguard Worker   int num_pos_chroma = 2 * params->ar_coeff_lag * (params->ar_coeff_lag + 1);
506*77c1e3ccSAndroid Build Coastguard Worker   if (params->num_y_points > 0) ++num_pos_chroma;
507*77c1e3ccSAndroid Build Coastguard Worker   int rounding_offset = (1 << (params->ar_coeff_shift - 1));
508*77c1e3ccSAndroid Build Coastguard Worker   int chroma_grain_block_size = chroma_block_size_y * chroma_grain_stride;
509*77c1e3ccSAndroid Build Coastguard Worker 
510*77c1e3ccSAndroid Build Coastguard Worker   if (params->num_cb_points || params->chroma_scaling_from_luma) {
511*77c1e3ccSAndroid Build Coastguard Worker     init_random_generator(7 << 5, params->random_seed);
512*77c1e3ccSAndroid Build Coastguard Worker 
513*77c1e3ccSAndroid Build Coastguard Worker     for (int i = 0; i < chroma_block_size_y; i++)
514*77c1e3ccSAndroid Build Coastguard Worker       for (int j = 0; j < chroma_block_size_x; j++)
515*77c1e3ccSAndroid Build Coastguard Worker         cb_grain_block[i * chroma_grain_stride + j] =
516*77c1e3ccSAndroid Build Coastguard Worker             (gaussian_sequence[get_random_number(gauss_bits)] +
517*77c1e3ccSAndroid Build Coastguard Worker              ((1 << gauss_sec_shift) >> 1)) >>
518*77c1e3ccSAndroid Build Coastguard Worker             gauss_sec_shift;
519*77c1e3ccSAndroid Build Coastguard Worker   } else {
520*77c1e3ccSAndroid Build Coastguard Worker     memset(cb_grain_block, 0,
521*77c1e3ccSAndroid Build Coastguard Worker            sizeof(*cb_grain_block) * chroma_grain_block_size);
522*77c1e3ccSAndroid Build Coastguard Worker   }
523*77c1e3ccSAndroid Build Coastguard Worker 
524*77c1e3ccSAndroid Build Coastguard Worker   if (params->num_cr_points || params->chroma_scaling_from_luma) {
525*77c1e3ccSAndroid Build Coastguard Worker     init_random_generator(11 << 5, params->random_seed);
526*77c1e3ccSAndroid Build Coastguard Worker 
527*77c1e3ccSAndroid Build Coastguard Worker     for (int i = 0; i < chroma_block_size_y; i++)
528*77c1e3ccSAndroid Build Coastguard Worker       for (int j = 0; j < chroma_block_size_x; j++)
529*77c1e3ccSAndroid Build Coastguard Worker         cr_grain_block[i * chroma_grain_stride + j] =
530*77c1e3ccSAndroid Build Coastguard Worker             (gaussian_sequence[get_random_number(gauss_bits)] +
531*77c1e3ccSAndroid Build Coastguard Worker              ((1 << gauss_sec_shift) >> 1)) >>
532*77c1e3ccSAndroid Build Coastguard Worker             gauss_sec_shift;
533*77c1e3ccSAndroid Build Coastguard Worker   } else {
534*77c1e3ccSAndroid Build Coastguard Worker     memset(cr_grain_block, 0,
535*77c1e3ccSAndroid Build Coastguard Worker            sizeof(*cr_grain_block) * chroma_grain_block_size);
536*77c1e3ccSAndroid Build Coastguard Worker   }
537*77c1e3ccSAndroid Build Coastguard Worker 
538*77c1e3ccSAndroid Build Coastguard Worker   for (int i = top_pad; i < chroma_block_size_y - bottom_pad; i++)
539*77c1e3ccSAndroid Build Coastguard Worker     for (int j = left_pad; j < chroma_block_size_x - right_pad; j++) {
540*77c1e3ccSAndroid Build Coastguard Worker       int wsum_cb = 0;
541*77c1e3ccSAndroid Build Coastguard Worker       int wsum_cr = 0;
542*77c1e3ccSAndroid Build Coastguard Worker       for (int pos = 0; pos < num_pos_chroma; pos++) {
543*77c1e3ccSAndroid Build Coastguard Worker         if (pred_pos_chroma[pos][2] == 0) {
544*77c1e3ccSAndroid Build Coastguard Worker           wsum_cb = wsum_cb + params->ar_coeffs_cb[pos] *
545*77c1e3ccSAndroid Build Coastguard Worker                                   cb_grain_block[(i + pred_pos_chroma[pos][0]) *
546*77c1e3ccSAndroid Build Coastguard Worker                                                      chroma_grain_stride +
547*77c1e3ccSAndroid Build Coastguard Worker                                                  j + pred_pos_chroma[pos][1]];
548*77c1e3ccSAndroid Build Coastguard Worker           wsum_cr = wsum_cr + params->ar_coeffs_cr[pos] *
549*77c1e3ccSAndroid Build Coastguard Worker                                   cr_grain_block[(i + pred_pos_chroma[pos][0]) *
550*77c1e3ccSAndroid Build Coastguard Worker                                                      chroma_grain_stride +
551*77c1e3ccSAndroid Build Coastguard Worker                                                  j + pred_pos_chroma[pos][1]];
552*77c1e3ccSAndroid Build Coastguard Worker         } else if (pred_pos_chroma[pos][2] == 1) {
553*77c1e3ccSAndroid Build Coastguard Worker           int av_luma = 0;
554*77c1e3ccSAndroid Build Coastguard Worker           int luma_coord_y = ((i - top_pad) << chroma_subsamp_y) + top_pad;
555*77c1e3ccSAndroid Build Coastguard Worker           int luma_coord_x = ((j - left_pad) << chroma_subsamp_x) + left_pad;
556*77c1e3ccSAndroid Build Coastguard Worker 
557*77c1e3ccSAndroid Build Coastguard Worker           for (int k = luma_coord_y; k < luma_coord_y + chroma_subsamp_y + 1;
558*77c1e3ccSAndroid Build Coastguard Worker                k++)
559*77c1e3ccSAndroid Build Coastguard Worker             for (int l = luma_coord_x; l < luma_coord_x + chroma_subsamp_x + 1;
560*77c1e3ccSAndroid Build Coastguard Worker                  l++)
561*77c1e3ccSAndroid Build Coastguard Worker               av_luma += luma_grain_block[k * luma_grain_stride + l];
562*77c1e3ccSAndroid Build Coastguard Worker 
563*77c1e3ccSAndroid Build Coastguard Worker           av_luma =
564*77c1e3ccSAndroid Build Coastguard Worker               (av_luma + ((1 << (chroma_subsamp_y + chroma_subsamp_x)) >> 1)) >>
565*77c1e3ccSAndroid Build Coastguard Worker               (chroma_subsamp_y + chroma_subsamp_x);
566*77c1e3ccSAndroid Build Coastguard Worker 
567*77c1e3ccSAndroid Build Coastguard Worker           wsum_cb = wsum_cb + params->ar_coeffs_cb[pos] * av_luma;
568*77c1e3ccSAndroid Build Coastguard Worker           wsum_cr = wsum_cr + params->ar_coeffs_cr[pos] * av_luma;
569*77c1e3ccSAndroid Build Coastguard Worker         } else {
570*77c1e3ccSAndroid Build Coastguard Worker           fprintf(
571*77c1e3ccSAndroid Build Coastguard Worker               stderr,
572*77c1e3ccSAndroid Build Coastguard Worker               "Grain synthesis: prediction between two chroma components is "
573*77c1e3ccSAndroid Build Coastguard Worker               "not supported!");
574*77c1e3ccSAndroid Build Coastguard Worker           return false;
575*77c1e3ccSAndroid Build Coastguard Worker         }
576*77c1e3ccSAndroid Build Coastguard Worker       }
577*77c1e3ccSAndroid Build Coastguard Worker       if (params->num_cb_points || params->chroma_scaling_from_luma)
578*77c1e3ccSAndroid Build Coastguard Worker         cb_grain_block[i * chroma_grain_stride + j] =
579*77c1e3ccSAndroid Build Coastguard Worker             clamp(cb_grain_block[i * chroma_grain_stride + j] +
580*77c1e3ccSAndroid Build Coastguard Worker                       ((wsum_cb + rounding_offset) >> params->ar_coeff_shift),
581*77c1e3ccSAndroid Build Coastguard Worker                   grain_min, grain_max);
582*77c1e3ccSAndroid Build Coastguard Worker       if (params->num_cr_points || params->chroma_scaling_from_luma)
583*77c1e3ccSAndroid Build Coastguard Worker         cr_grain_block[i * chroma_grain_stride + j] =
584*77c1e3ccSAndroid Build Coastguard Worker             clamp(cr_grain_block[i * chroma_grain_stride + j] +
585*77c1e3ccSAndroid Build Coastguard Worker                       ((wsum_cr + rounding_offset) >> params->ar_coeff_shift),
586*77c1e3ccSAndroid Build Coastguard Worker                   grain_min, grain_max);
587*77c1e3ccSAndroid Build Coastguard Worker     }
588*77c1e3ccSAndroid Build Coastguard Worker   return true;
589*77c1e3ccSAndroid Build Coastguard Worker }
590*77c1e3ccSAndroid Build Coastguard Worker 
init_scaling_function(const int scaling_points[][2],int num_points,int scaling_lut[])591*77c1e3ccSAndroid Build Coastguard Worker static void init_scaling_function(const int scaling_points[][2], int num_points,
592*77c1e3ccSAndroid Build Coastguard Worker                                   int scaling_lut[]) {
593*77c1e3ccSAndroid Build Coastguard Worker   if (num_points == 0) return;
594*77c1e3ccSAndroid Build Coastguard Worker 
595*77c1e3ccSAndroid Build Coastguard Worker   for (int i = 0; i < scaling_points[0][0]; i++)
596*77c1e3ccSAndroid Build Coastguard Worker     scaling_lut[i] = scaling_points[0][1];
597*77c1e3ccSAndroid Build Coastguard Worker 
598*77c1e3ccSAndroid Build Coastguard Worker   for (int point = 0; point < num_points - 1; point++) {
599*77c1e3ccSAndroid Build Coastguard Worker     int delta_y = scaling_points[point + 1][1] - scaling_points[point][1];
600*77c1e3ccSAndroid Build Coastguard Worker     int delta_x = scaling_points[point + 1][0] - scaling_points[point][0];
601*77c1e3ccSAndroid Build Coastguard Worker 
602*77c1e3ccSAndroid Build Coastguard Worker     int64_t delta = delta_y * ((65536 + (delta_x >> 1)) / delta_x);
603*77c1e3ccSAndroid Build Coastguard Worker 
604*77c1e3ccSAndroid Build Coastguard Worker     for (int x = 0; x < delta_x; x++) {
605*77c1e3ccSAndroid Build Coastguard Worker       scaling_lut[scaling_points[point][0] + x] =
606*77c1e3ccSAndroid Build Coastguard Worker           scaling_points[point][1] + (int)((x * delta + 32768) >> 16);
607*77c1e3ccSAndroid Build Coastguard Worker     }
608*77c1e3ccSAndroid Build Coastguard Worker   }
609*77c1e3ccSAndroid Build Coastguard Worker 
610*77c1e3ccSAndroid Build Coastguard Worker   for (int i = scaling_points[num_points - 1][0]; i < 256; i++)
611*77c1e3ccSAndroid Build Coastguard Worker     scaling_lut[i] = scaling_points[num_points - 1][1];
612*77c1e3ccSAndroid Build Coastguard Worker }
613*77c1e3ccSAndroid Build Coastguard Worker 
614*77c1e3ccSAndroid Build Coastguard Worker // function that extracts samples from a LUT (and interpolates intemediate
615*77c1e3ccSAndroid Build Coastguard Worker // frames for 10- and 12-bit video)
scale_LUT(int * scaling_lut,int index,int bit_depth)616*77c1e3ccSAndroid Build Coastguard Worker static int scale_LUT(int *scaling_lut, int index, int bit_depth) {
617*77c1e3ccSAndroid Build Coastguard Worker   int x = index >> (bit_depth - 8);
618*77c1e3ccSAndroid Build Coastguard Worker 
619*77c1e3ccSAndroid Build Coastguard Worker   if (!(bit_depth - 8) || x == 255)
620*77c1e3ccSAndroid Build Coastguard Worker     return scaling_lut[x];
621*77c1e3ccSAndroid Build Coastguard Worker   else
622*77c1e3ccSAndroid Build Coastguard Worker     return scaling_lut[x] + (((scaling_lut[x + 1] - scaling_lut[x]) *
623*77c1e3ccSAndroid Build Coastguard Worker                                   (index & ((1 << (bit_depth - 8)) - 1)) +
624*77c1e3ccSAndroid Build Coastguard Worker                               (1 << (bit_depth - 9))) >>
625*77c1e3ccSAndroid Build Coastguard Worker                              (bit_depth - 8));
626*77c1e3ccSAndroid Build Coastguard Worker }
627*77c1e3ccSAndroid Build Coastguard Worker 
add_noise_to_block(const aom_film_grain_t * params,uint8_t * luma,uint8_t * cb,uint8_t * cr,int luma_stride,int chroma_stride,int * luma_grain,int * cb_grain,int * cr_grain,int luma_grain_stride,int chroma_grain_stride,int half_luma_height,int half_luma_width,int bit_depth,int chroma_subsamp_y,int chroma_subsamp_x,int mc_identity)628*77c1e3ccSAndroid Build Coastguard Worker static void add_noise_to_block(const aom_film_grain_t *params, uint8_t *luma,
629*77c1e3ccSAndroid Build Coastguard Worker                                uint8_t *cb, uint8_t *cr, int luma_stride,
630*77c1e3ccSAndroid Build Coastguard Worker                                int chroma_stride, int *luma_grain,
631*77c1e3ccSAndroid Build Coastguard Worker                                int *cb_grain, int *cr_grain,
632*77c1e3ccSAndroid Build Coastguard Worker                                int luma_grain_stride, int chroma_grain_stride,
633*77c1e3ccSAndroid Build Coastguard Worker                                int half_luma_height, int half_luma_width,
634*77c1e3ccSAndroid Build Coastguard Worker                                int bit_depth, int chroma_subsamp_y,
635*77c1e3ccSAndroid Build Coastguard Worker                                int chroma_subsamp_x, int mc_identity) {
636*77c1e3ccSAndroid Build Coastguard Worker   int cb_mult = params->cb_mult - 128;            // fixed scale
637*77c1e3ccSAndroid Build Coastguard Worker   int cb_luma_mult = params->cb_luma_mult - 128;  // fixed scale
638*77c1e3ccSAndroid Build Coastguard Worker   int cb_offset = params->cb_offset - 256;
639*77c1e3ccSAndroid Build Coastguard Worker 
640*77c1e3ccSAndroid Build Coastguard Worker   int cr_mult = params->cr_mult - 128;            // fixed scale
641*77c1e3ccSAndroid Build Coastguard Worker   int cr_luma_mult = params->cr_luma_mult - 128;  // fixed scale
642*77c1e3ccSAndroid Build Coastguard Worker   int cr_offset = params->cr_offset - 256;
643*77c1e3ccSAndroid Build Coastguard Worker 
644*77c1e3ccSAndroid Build Coastguard Worker   int rounding_offset = (1 << (params->scaling_shift - 1));
645*77c1e3ccSAndroid Build Coastguard Worker 
646*77c1e3ccSAndroid Build Coastguard Worker   int apply_y = params->num_y_points > 0 ? 1 : 0;
647*77c1e3ccSAndroid Build Coastguard Worker   int apply_cb =
648*77c1e3ccSAndroid Build Coastguard Worker       (params->num_cb_points > 0 || params->chroma_scaling_from_luma) ? 1 : 0;
649*77c1e3ccSAndroid Build Coastguard Worker   int apply_cr =
650*77c1e3ccSAndroid Build Coastguard Worker       (params->num_cr_points > 0 || params->chroma_scaling_from_luma) ? 1 : 0;
651*77c1e3ccSAndroid Build Coastguard Worker 
652*77c1e3ccSAndroid Build Coastguard Worker   if (params->chroma_scaling_from_luma) {
653*77c1e3ccSAndroid Build Coastguard Worker     cb_mult = 0;        // fixed scale
654*77c1e3ccSAndroid Build Coastguard Worker     cb_luma_mult = 64;  // fixed scale
655*77c1e3ccSAndroid Build Coastguard Worker     cb_offset = 0;
656*77c1e3ccSAndroid Build Coastguard Worker 
657*77c1e3ccSAndroid Build Coastguard Worker     cr_mult = 0;        // fixed scale
658*77c1e3ccSAndroid Build Coastguard Worker     cr_luma_mult = 64;  // fixed scale
659*77c1e3ccSAndroid Build Coastguard Worker     cr_offset = 0;
660*77c1e3ccSAndroid Build Coastguard Worker   }
661*77c1e3ccSAndroid Build Coastguard Worker 
662*77c1e3ccSAndroid Build Coastguard Worker   int min_luma, max_luma, min_chroma, max_chroma;
663*77c1e3ccSAndroid Build Coastguard Worker 
664*77c1e3ccSAndroid Build Coastguard Worker   if (params->clip_to_restricted_range) {
665*77c1e3ccSAndroid Build Coastguard Worker     min_luma = min_luma_legal_range;
666*77c1e3ccSAndroid Build Coastguard Worker     max_luma = max_luma_legal_range;
667*77c1e3ccSAndroid Build Coastguard Worker 
668*77c1e3ccSAndroid Build Coastguard Worker     if (mc_identity) {
669*77c1e3ccSAndroid Build Coastguard Worker       min_chroma = min_luma_legal_range;
670*77c1e3ccSAndroid Build Coastguard Worker       max_chroma = max_luma_legal_range;
671*77c1e3ccSAndroid Build Coastguard Worker     } else {
672*77c1e3ccSAndroid Build Coastguard Worker       min_chroma = min_chroma_legal_range;
673*77c1e3ccSAndroid Build Coastguard Worker       max_chroma = max_chroma_legal_range;
674*77c1e3ccSAndroid Build Coastguard Worker     }
675*77c1e3ccSAndroid Build Coastguard Worker   } else {
676*77c1e3ccSAndroid Build Coastguard Worker     min_luma = min_chroma = 0;
677*77c1e3ccSAndroid Build Coastguard Worker     max_luma = max_chroma = 255;
678*77c1e3ccSAndroid Build Coastguard Worker   }
679*77c1e3ccSAndroid Build Coastguard Worker 
680*77c1e3ccSAndroid Build Coastguard Worker   for (int i = 0; i < (half_luma_height << (1 - chroma_subsamp_y)); i++) {
681*77c1e3ccSAndroid Build Coastguard Worker     for (int j = 0; j < (half_luma_width << (1 - chroma_subsamp_x)); j++) {
682*77c1e3ccSAndroid Build Coastguard Worker       int average_luma = 0;
683*77c1e3ccSAndroid Build Coastguard Worker       if (chroma_subsamp_x) {
684*77c1e3ccSAndroid Build Coastguard Worker         average_luma = (luma[(i << chroma_subsamp_y) * luma_stride +
685*77c1e3ccSAndroid Build Coastguard Worker                              (j << chroma_subsamp_x)] +
686*77c1e3ccSAndroid Build Coastguard Worker                         luma[(i << chroma_subsamp_y) * luma_stride +
687*77c1e3ccSAndroid Build Coastguard Worker                              (j << chroma_subsamp_x) + 1] +
688*77c1e3ccSAndroid Build Coastguard Worker                         1) >>
689*77c1e3ccSAndroid Build Coastguard Worker                        1;
690*77c1e3ccSAndroid Build Coastguard Worker       } else {
691*77c1e3ccSAndroid Build Coastguard Worker         average_luma = luma[(i << chroma_subsamp_y) * luma_stride + j];
692*77c1e3ccSAndroid Build Coastguard Worker       }
693*77c1e3ccSAndroid Build Coastguard Worker 
694*77c1e3ccSAndroid Build Coastguard Worker       if (apply_cb) {
695*77c1e3ccSAndroid Build Coastguard Worker         cb[i * chroma_stride + j] = clamp(
696*77c1e3ccSAndroid Build Coastguard Worker             cb[i * chroma_stride + j] +
697*77c1e3ccSAndroid Build Coastguard Worker                 ((scale_LUT(scaling_lut_cb,
698*77c1e3ccSAndroid Build Coastguard Worker                             clamp(((average_luma * cb_luma_mult +
699*77c1e3ccSAndroid Build Coastguard Worker                                     cb_mult * cb[i * chroma_stride + j]) >>
700*77c1e3ccSAndroid Build Coastguard Worker                                    6) +
701*77c1e3ccSAndroid Build Coastguard Worker                                       cb_offset,
702*77c1e3ccSAndroid Build Coastguard Worker                                   0, (256 << (bit_depth - 8)) - 1),
703*77c1e3ccSAndroid Build Coastguard Worker                             8) *
704*77c1e3ccSAndroid Build Coastguard Worker                       cb_grain[i * chroma_grain_stride + j] +
705*77c1e3ccSAndroid Build Coastguard Worker                   rounding_offset) >>
706*77c1e3ccSAndroid Build Coastguard Worker                  params->scaling_shift),
707*77c1e3ccSAndroid Build Coastguard Worker             min_chroma, max_chroma);
708*77c1e3ccSAndroid Build Coastguard Worker       }
709*77c1e3ccSAndroid Build Coastguard Worker 
710*77c1e3ccSAndroid Build Coastguard Worker       if (apply_cr) {
711*77c1e3ccSAndroid Build Coastguard Worker         cr[i * chroma_stride + j] = clamp(
712*77c1e3ccSAndroid Build Coastguard Worker             cr[i * chroma_stride + j] +
713*77c1e3ccSAndroid Build Coastguard Worker                 ((scale_LUT(scaling_lut_cr,
714*77c1e3ccSAndroid Build Coastguard Worker                             clamp(((average_luma * cr_luma_mult +
715*77c1e3ccSAndroid Build Coastguard Worker                                     cr_mult * cr[i * chroma_stride + j]) >>
716*77c1e3ccSAndroid Build Coastguard Worker                                    6) +
717*77c1e3ccSAndroid Build Coastguard Worker                                       cr_offset,
718*77c1e3ccSAndroid Build Coastguard Worker                                   0, (256 << (bit_depth - 8)) - 1),
719*77c1e3ccSAndroid Build Coastguard Worker                             8) *
720*77c1e3ccSAndroid Build Coastguard Worker                       cr_grain[i * chroma_grain_stride + j] +
721*77c1e3ccSAndroid Build Coastguard Worker                   rounding_offset) >>
722*77c1e3ccSAndroid Build Coastguard Worker                  params->scaling_shift),
723*77c1e3ccSAndroid Build Coastguard Worker             min_chroma, max_chroma);
724*77c1e3ccSAndroid Build Coastguard Worker       }
725*77c1e3ccSAndroid Build Coastguard Worker     }
726*77c1e3ccSAndroid Build Coastguard Worker   }
727*77c1e3ccSAndroid Build Coastguard Worker 
728*77c1e3ccSAndroid Build Coastguard Worker   if (apply_y) {
729*77c1e3ccSAndroid Build Coastguard Worker     for (int i = 0; i < (half_luma_height << 1); i++) {
730*77c1e3ccSAndroid Build Coastguard Worker       for (int j = 0; j < (half_luma_width << 1); j++) {
731*77c1e3ccSAndroid Build Coastguard Worker         luma[i * luma_stride + j] =
732*77c1e3ccSAndroid Build Coastguard Worker             clamp(luma[i * luma_stride + j] +
733*77c1e3ccSAndroid Build Coastguard Worker                       ((scale_LUT(scaling_lut_y, luma[i * luma_stride + j], 8) *
734*77c1e3ccSAndroid Build Coastguard Worker                             luma_grain[i * luma_grain_stride + j] +
735*77c1e3ccSAndroid Build Coastguard Worker                         rounding_offset) >>
736*77c1e3ccSAndroid Build Coastguard Worker                        params->scaling_shift),
737*77c1e3ccSAndroid Build Coastguard Worker                   min_luma, max_luma);
738*77c1e3ccSAndroid Build Coastguard Worker       }
739*77c1e3ccSAndroid Build Coastguard Worker     }
740*77c1e3ccSAndroid Build Coastguard Worker   }
741*77c1e3ccSAndroid Build Coastguard Worker }
742*77c1e3ccSAndroid Build Coastguard Worker 
add_noise_to_block_hbd(const aom_film_grain_t * params,uint16_t * luma,uint16_t * cb,uint16_t * cr,int luma_stride,int chroma_stride,int * luma_grain,int * cb_grain,int * cr_grain,int luma_grain_stride,int chroma_grain_stride,int half_luma_height,int half_luma_width,int bit_depth,int chroma_subsamp_y,int chroma_subsamp_x,int mc_identity)743*77c1e3ccSAndroid Build Coastguard Worker static void add_noise_to_block_hbd(
744*77c1e3ccSAndroid Build Coastguard Worker     const aom_film_grain_t *params, uint16_t *luma, uint16_t *cb, uint16_t *cr,
745*77c1e3ccSAndroid Build Coastguard Worker     int luma_stride, int chroma_stride, int *luma_grain, int *cb_grain,
746*77c1e3ccSAndroid Build Coastguard Worker     int *cr_grain, int luma_grain_stride, int chroma_grain_stride,
747*77c1e3ccSAndroid Build Coastguard Worker     int half_luma_height, int half_luma_width, int bit_depth,
748*77c1e3ccSAndroid Build Coastguard Worker     int chroma_subsamp_y, int chroma_subsamp_x, int mc_identity) {
749*77c1e3ccSAndroid Build Coastguard Worker   int cb_mult = params->cb_mult - 128;            // fixed scale
750*77c1e3ccSAndroid Build Coastguard Worker   int cb_luma_mult = params->cb_luma_mult - 128;  // fixed scale
751*77c1e3ccSAndroid Build Coastguard Worker   // offset value depends on the bit depth
752*77c1e3ccSAndroid Build Coastguard Worker   int cb_offset = (params->cb_offset << (bit_depth - 8)) - (1 << bit_depth);
753*77c1e3ccSAndroid Build Coastguard Worker 
754*77c1e3ccSAndroid Build Coastguard Worker   int cr_mult = params->cr_mult - 128;            // fixed scale
755*77c1e3ccSAndroid Build Coastguard Worker   int cr_luma_mult = params->cr_luma_mult - 128;  // fixed scale
756*77c1e3ccSAndroid Build Coastguard Worker   // offset value depends on the bit depth
757*77c1e3ccSAndroid Build Coastguard Worker   int cr_offset = (params->cr_offset << (bit_depth - 8)) - (1 << bit_depth);
758*77c1e3ccSAndroid Build Coastguard Worker 
759*77c1e3ccSAndroid Build Coastguard Worker   int rounding_offset = (1 << (params->scaling_shift - 1));
760*77c1e3ccSAndroid Build Coastguard Worker 
761*77c1e3ccSAndroid Build Coastguard Worker   int apply_y = params->num_y_points > 0 ? 1 : 0;
762*77c1e3ccSAndroid Build Coastguard Worker   int apply_cb =
763*77c1e3ccSAndroid Build Coastguard Worker       (params->num_cb_points > 0 || params->chroma_scaling_from_luma) > 0 ? 1
764*77c1e3ccSAndroid Build Coastguard Worker                                                                           : 0;
765*77c1e3ccSAndroid Build Coastguard Worker   int apply_cr =
766*77c1e3ccSAndroid Build Coastguard Worker       (params->num_cr_points > 0 || params->chroma_scaling_from_luma) > 0 ? 1
767*77c1e3ccSAndroid Build Coastguard Worker                                                                           : 0;
768*77c1e3ccSAndroid Build Coastguard Worker 
769*77c1e3ccSAndroid Build Coastguard Worker   if (params->chroma_scaling_from_luma) {
770*77c1e3ccSAndroid Build Coastguard Worker     cb_mult = 0;        // fixed scale
771*77c1e3ccSAndroid Build Coastguard Worker     cb_luma_mult = 64;  // fixed scale
772*77c1e3ccSAndroid Build Coastguard Worker     cb_offset = 0;
773*77c1e3ccSAndroid Build Coastguard Worker 
774*77c1e3ccSAndroid Build Coastguard Worker     cr_mult = 0;        // fixed scale
775*77c1e3ccSAndroid Build Coastguard Worker     cr_luma_mult = 64;  // fixed scale
776*77c1e3ccSAndroid Build Coastguard Worker     cr_offset = 0;
777*77c1e3ccSAndroid Build Coastguard Worker   }
778*77c1e3ccSAndroid Build Coastguard Worker 
779*77c1e3ccSAndroid Build Coastguard Worker   int min_luma, max_luma, min_chroma, max_chroma;
780*77c1e3ccSAndroid Build Coastguard Worker 
781*77c1e3ccSAndroid Build Coastguard Worker   if (params->clip_to_restricted_range) {
782*77c1e3ccSAndroid Build Coastguard Worker     min_luma = min_luma_legal_range << (bit_depth - 8);
783*77c1e3ccSAndroid Build Coastguard Worker     max_luma = max_luma_legal_range << (bit_depth - 8);
784*77c1e3ccSAndroid Build Coastguard Worker 
785*77c1e3ccSAndroid Build Coastguard Worker     if (mc_identity) {
786*77c1e3ccSAndroid Build Coastguard Worker       min_chroma = min_luma_legal_range << (bit_depth - 8);
787*77c1e3ccSAndroid Build Coastguard Worker       max_chroma = max_luma_legal_range << (bit_depth - 8);
788*77c1e3ccSAndroid Build Coastguard Worker     } else {
789*77c1e3ccSAndroid Build Coastguard Worker       min_chroma = min_chroma_legal_range << (bit_depth - 8);
790*77c1e3ccSAndroid Build Coastguard Worker       max_chroma = max_chroma_legal_range << (bit_depth - 8);
791*77c1e3ccSAndroid Build Coastguard Worker     }
792*77c1e3ccSAndroid Build Coastguard Worker   } else {
793*77c1e3ccSAndroid Build Coastguard Worker     min_luma = min_chroma = 0;
794*77c1e3ccSAndroid Build Coastguard Worker     max_luma = max_chroma = (256 << (bit_depth - 8)) - 1;
795*77c1e3ccSAndroid Build Coastguard Worker   }
796*77c1e3ccSAndroid Build Coastguard Worker 
797*77c1e3ccSAndroid Build Coastguard Worker   for (int i = 0; i < (half_luma_height << (1 - chroma_subsamp_y)); i++) {
798*77c1e3ccSAndroid Build Coastguard Worker     for (int j = 0; j < (half_luma_width << (1 - chroma_subsamp_x)); j++) {
799*77c1e3ccSAndroid Build Coastguard Worker       int average_luma = 0;
800*77c1e3ccSAndroid Build Coastguard Worker       if (chroma_subsamp_x) {
801*77c1e3ccSAndroid Build Coastguard Worker         average_luma = (luma[(i << chroma_subsamp_y) * luma_stride +
802*77c1e3ccSAndroid Build Coastguard Worker                              (j << chroma_subsamp_x)] +
803*77c1e3ccSAndroid Build Coastguard Worker                         luma[(i << chroma_subsamp_y) * luma_stride +
804*77c1e3ccSAndroid Build Coastguard Worker                              (j << chroma_subsamp_x) + 1] +
805*77c1e3ccSAndroid Build Coastguard Worker                         1) >>
806*77c1e3ccSAndroid Build Coastguard Worker                        1;
807*77c1e3ccSAndroid Build Coastguard Worker       } else {
808*77c1e3ccSAndroid Build Coastguard Worker         average_luma = luma[(i << chroma_subsamp_y) * luma_stride + j];
809*77c1e3ccSAndroid Build Coastguard Worker       }
810*77c1e3ccSAndroid Build Coastguard Worker 
811*77c1e3ccSAndroid Build Coastguard Worker       if (apply_cb) {
812*77c1e3ccSAndroid Build Coastguard Worker         cb[i * chroma_stride + j] = clamp(
813*77c1e3ccSAndroid Build Coastguard Worker             cb[i * chroma_stride + j] +
814*77c1e3ccSAndroid Build Coastguard Worker                 ((scale_LUT(scaling_lut_cb,
815*77c1e3ccSAndroid Build Coastguard Worker                             clamp(((average_luma * cb_luma_mult +
816*77c1e3ccSAndroid Build Coastguard Worker                                     cb_mult * cb[i * chroma_stride + j]) >>
817*77c1e3ccSAndroid Build Coastguard Worker                                    6) +
818*77c1e3ccSAndroid Build Coastguard Worker                                       cb_offset,
819*77c1e3ccSAndroid Build Coastguard Worker                                   0, (256 << (bit_depth - 8)) - 1),
820*77c1e3ccSAndroid Build Coastguard Worker                             bit_depth) *
821*77c1e3ccSAndroid Build Coastguard Worker                       cb_grain[i * chroma_grain_stride + j] +
822*77c1e3ccSAndroid Build Coastguard Worker                   rounding_offset) >>
823*77c1e3ccSAndroid Build Coastguard Worker                  params->scaling_shift),
824*77c1e3ccSAndroid Build Coastguard Worker             min_chroma, max_chroma);
825*77c1e3ccSAndroid Build Coastguard Worker       }
826*77c1e3ccSAndroid Build Coastguard Worker       if (apply_cr) {
827*77c1e3ccSAndroid Build Coastguard Worker         cr[i * chroma_stride + j] = clamp(
828*77c1e3ccSAndroid Build Coastguard Worker             cr[i * chroma_stride + j] +
829*77c1e3ccSAndroid Build Coastguard Worker                 ((scale_LUT(scaling_lut_cr,
830*77c1e3ccSAndroid Build Coastguard Worker                             clamp(((average_luma * cr_luma_mult +
831*77c1e3ccSAndroid Build Coastguard Worker                                     cr_mult * cr[i * chroma_stride + j]) >>
832*77c1e3ccSAndroid Build Coastguard Worker                                    6) +
833*77c1e3ccSAndroid Build Coastguard Worker                                       cr_offset,
834*77c1e3ccSAndroid Build Coastguard Worker                                   0, (256 << (bit_depth - 8)) - 1),
835*77c1e3ccSAndroid Build Coastguard Worker                             bit_depth) *
836*77c1e3ccSAndroid Build Coastguard Worker                       cr_grain[i * chroma_grain_stride + j] +
837*77c1e3ccSAndroid Build Coastguard Worker                   rounding_offset) >>
838*77c1e3ccSAndroid Build Coastguard Worker                  params->scaling_shift),
839*77c1e3ccSAndroid Build Coastguard Worker             min_chroma, max_chroma);
840*77c1e3ccSAndroid Build Coastguard Worker       }
841*77c1e3ccSAndroid Build Coastguard Worker     }
842*77c1e3ccSAndroid Build Coastguard Worker   }
843*77c1e3ccSAndroid Build Coastguard Worker 
844*77c1e3ccSAndroid Build Coastguard Worker   if (apply_y) {
845*77c1e3ccSAndroid Build Coastguard Worker     for (int i = 0; i < (half_luma_height << 1); i++) {
846*77c1e3ccSAndroid Build Coastguard Worker       for (int j = 0; j < (half_luma_width << 1); j++) {
847*77c1e3ccSAndroid Build Coastguard Worker         luma[i * luma_stride + j] =
848*77c1e3ccSAndroid Build Coastguard Worker             clamp(luma[i * luma_stride + j] +
849*77c1e3ccSAndroid Build Coastguard Worker                       ((scale_LUT(scaling_lut_y, luma[i * luma_stride + j],
850*77c1e3ccSAndroid Build Coastguard Worker                                   bit_depth) *
851*77c1e3ccSAndroid Build Coastguard Worker                             luma_grain[i * luma_grain_stride + j] +
852*77c1e3ccSAndroid Build Coastguard Worker                         rounding_offset) >>
853*77c1e3ccSAndroid Build Coastguard Worker                        params->scaling_shift),
854*77c1e3ccSAndroid Build Coastguard Worker                   min_luma, max_luma);
855*77c1e3ccSAndroid Build Coastguard Worker       }
856*77c1e3ccSAndroid Build Coastguard Worker     }
857*77c1e3ccSAndroid Build Coastguard Worker   }
858*77c1e3ccSAndroid Build Coastguard Worker }
859*77c1e3ccSAndroid Build Coastguard Worker 
copy_rect(uint8_t * src,int src_stride,uint8_t * dst,int dst_stride,int width,int height,int use_high_bit_depth)860*77c1e3ccSAndroid Build Coastguard Worker static void copy_rect(uint8_t *src, int src_stride, uint8_t *dst,
861*77c1e3ccSAndroid Build Coastguard Worker                       int dst_stride, int width, int height,
862*77c1e3ccSAndroid Build Coastguard Worker                       int use_high_bit_depth) {
863*77c1e3ccSAndroid Build Coastguard Worker   int hbd_coeff = use_high_bit_depth ? 2 : 1;
864*77c1e3ccSAndroid Build Coastguard Worker   while (height) {
865*77c1e3ccSAndroid Build Coastguard Worker     memcpy(dst, src, width * sizeof(uint8_t) * hbd_coeff);
866*77c1e3ccSAndroid Build Coastguard Worker     src += src_stride;
867*77c1e3ccSAndroid Build Coastguard Worker     dst += dst_stride;
868*77c1e3ccSAndroid Build Coastguard Worker     --height;
869*77c1e3ccSAndroid Build Coastguard Worker   }
870*77c1e3ccSAndroid Build Coastguard Worker   return;
871*77c1e3ccSAndroid Build Coastguard Worker }
872*77c1e3ccSAndroid Build Coastguard Worker 
copy_area(int * src,int src_stride,int * dst,int dst_stride,int width,int height)873*77c1e3ccSAndroid Build Coastguard Worker static void copy_area(int *src, int src_stride, int *dst, int dst_stride,
874*77c1e3ccSAndroid Build Coastguard Worker                       int width, int height) {
875*77c1e3ccSAndroid Build Coastguard Worker   while (height) {
876*77c1e3ccSAndroid Build Coastguard Worker     memcpy(dst, src, width * sizeof(*src));
877*77c1e3ccSAndroid Build Coastguard Worker     src += src_stride;
878*77c1e3ccSAndroid Build Coastguard Worker     dst += dst_stride;
879*77c1e3ccSAndroid Build Coastguard Worker     --height;
880*77c1e3ccSAndroid Build Coastguard Worker   }
881*77c1e3ccSAndroid Build Coastguard Worker   return;
882*77c1e3ccSAndroid Build Coastguard Worker }
883*77c1e3ccSAndroid Build Coastguard Worker 
extend_even(uint8_t * dst,int dst_stride,int width,int height,int use_high_bit_depth)884*77c1e3ccSAndroid Build Coastguard Worker static void extend_even(uint8_t *dst, int dst_stride, int width, int height,
885*77c1e3ccSAndroid Build Coastguard Worker                         int use_high_bit_depth) {
886*77c1e3ccSAndroid Build Coastguard Worker   if ((width & 1) == 0 && (height & 1) == 0) return;
887*77c1e3ccSAndroid Build Coastguard Worker   if (use_high_bit_depth) {
888*77c1e3ccSAndroid Build Coastguard Worker     uint16_t *dst16 = (uint16_t *)dst;
889*77c1e3ccSAndroid Build Coastguard Worker     int dst16_stride = dst_stride / 2;
890*77c1e3ccSAndroid Build Coastguard Worker     if (width & 1) {
891*77c1e3ccSAndroid Build Coastguard Worker       for (int i = 0; i < height; ++i)
892*77c1e3ccSAndroid Build Coastguard Worker         dst16[i * dst16_stride + width] = dst16[i * dst16_stride + width - 1];
893*77c1e3ccSAndroid Build Coastguard Worker     }
894*77c1e3ccSAndroid Build Coastguard Worker     width = (width + 1) & (~1);
895*77c1e3ccSAndroid Build Coastguard Worker     if (height & 1) {
896*77c1e3ccSAndroid Build Coastguard Worker       memcpy(&dst16[height * dst16_stride], &dst16[(height - 1) * dst16_stride],
897*77c1e3ccSAndroid Build Coastguard Worker              sizeof(*dst16) * width);
898*77c1e3ccSAndroid Build Coastguard Worker     }
899*77c1e3ccSAndroid Build Coastguard Worker   } else {
900*77c1e3ccSAndroid Build Coastguard Worker     if (width & 1) {
901*77c1e3ccSAndroid Build Coastguard Worker       for (int i = 0; i < height; ++i)
902*77c1e3ccSAndroid Build Coastguard Worker         dst[i * dst_stride + width] = dst[i * dst_stride + width - 1];
903*77c1e3ccSAndroid Build Coastguard Worker     }
904*77c1e3ccSAndroid Build Coastguard Worker     width = (width + 1) & (~1);
905*77c1e3ccSAndroid Build Coastguard Worker     if (height & 1) {
906*77c1e3ccSAndroid Build Coastguard Worker       memcpy(&dst[height * dst_stride], &dst[(height - 1) * dst_stride],
907*77c1e3ccSAndroid Build Coastguard Worker              sizeof(*dst) * width);
908*77c1e3ccSAndroid Build Coastguard Worker     }
909*77c1e3ccSAndroid Build Coastguard Worker   }
910*77c1e3ccSAndroid Build Coastguard Worker }
911*77c1e3ccSAndroid Build Coastguard Worker 
ver_boundary_overlap(int * left_block,int left_stride,int * right_block,int right_stride,int * dst_block,int dst_stride,int width,int height)912*77c1e3ccSAndroid Build Coastguard Worker static void ver_boundary_overlap(int *left_block, int left_stride,
913*77c1e3ccSAndroid Build Coastguard Worker                                  int *right_block, int right_stride,
914*77c1e3ccSAndroid Build Coastguard Worker                                  int *dst_block, int dst_stride, int width,
915*77c1e3ccSAndroid Build Coastguard Worker                                  int height) {
916*77c1e3ccSAndroid Build Coastguard Worker   if (width == 1) {
917*77c1e3ccSAndroid Build Coastguard Worker     while (height) {
918*77c1e3ccSAndroid Build Coastguard Worker       *dst_block = clamp((*left_block * 23 + *right_block * 22 + 16) >> 5,
919*77c1e3ccSAndroid Build Coastguard Worker                          grain_min, grain_max);
920*77c1e3ccSAndroid Build Coastguard Worker       left_block += left_stride;
921*77c1e3ccSAndroid Build Coastguard Worker       right_block += right_stride;
922*77c1e3ccSAndroid Build Coastguard Worker       dst_block += dst_stride;
923*77c1e3ccSAndroid Build Coastguard Worker       --height;
924*77c1e3ccSAndroid Build Coastguard Worker     }
925*77c1e3ccSAndroid Build Coastguard Worker     return;
926*77c1e3ccSAndroid Build Coastguard Worker   } else if (width == 2) {
927*77c1e3ccSAndroid Build Coastguard Worker     while (height) {
928*77c1e3ccSAndroid Build Coastguard Worker       dst_block[0] = clamp((27 * left_block[0] + 17 * right_block[0] + 16) >> 5,
929*77c1e3ccSAndroid Build Coastguard Worker                            grain_min, grain_max);
930*77c1e3ccSAndroid Build Coastguard Worker       dst_block[1] = clamp((17 * left_block[1] + 27 * right_block[1] + 16) >> 5,
931*77c1e3ccSAndroid Build Coastguard Worker                            grain_min, grain_max);
932*77c1e3ccSAndroid Build Coastguard Worker       left_block += left_stride;
933*77c1e3ccSAndroid Build Coastguard Worker       right_block += right_stride;
934*77c1e3ccSAndroid Build Coastguard Worker       dst_block += dst_stride;
935*77c1e3ccSAndroid Build Coastguard Worker       --height;
936*77c1e3ccSAndroid Build Coastguard Worker     }
937*77c1e3ccSAndroid Build Coastguard Worker     return;
938*77c1e3ccSAndroid Build Coastguard Worker   }
939*77c1e3ccSAndroid Build Coastguard Worker }
940*77c1e3ccSAndroid Build Coastguard Worker 
hor_boundary_overlap(int * top_block,int top_stride,int * bottom_block,int bottom_stride,int * dst_block,int dst_stride,int width,int height)941*77c1e3ccSAndroid Build Coastguard Worker static void hor_boundary_overlap(int *top_block, int top_stride,
942*77c1e3ccSAndroid Build Coastguard Worker                                  int *bottom_block, int bottom_stride,
943*77c1e3ccSAndroid Build Coastguard Worker                                  int *dst_block, int dst_stride, int width,
944*77c1e3ccSAndroid Build Coastguard Worker                                  int height) {
945*77c1e3ccSAndroid Build Coastguard Worker   if (height == 1) {
946*77c1e3ccSAndroid Build Coastguard Worker     while (width) {
947*77c1e3ccSAndroid Build Coastguard Worker       *dst_block = clamp((*top_block * 23 + *bottom_block * 22 + 16) >> 5,
948*77c1e3ccSAndroid Build Coastguard Worker                          grain_min, grain_max);
949*77c1e3ccSAndroid Build Coastguard Worker       ++top_block;
950*77c1e3ccSAndroid Build Coastguard Worker       ++bottom_block;
951*77c1e3ccSAndroid Build Coastguard Worker       ++dst_block;
952*77c1e3ccSAndroid Build Coastguard Worker       --width;
953*77c1e3ccSAndroid Build Coastguard Worker     }
954*77c1e3ccSAndroid Build Coastguard Worker     return;
955*77c1e3ccSAndroid Build Coastguard Worker   } else if (height == 2) {
956*77c1e3ccSAndroid Build Coastguard Worker     while (width) {
957*77c1e3ccSAndroid Build Coastguard Worker       dst_block[0] = clamp((27 * top_block[0] + 17 * bottom_block[0] + 16) >> 5,
958*77c1e3ccSAndroid Build Coastguard Worker                            grain_min, grain_max);
959*77c1e3ccSAndroid Build Coastguard Worker       dst_block[dst_stride] = clamp((17 * top_block[top_stride] +
960*77c1e3ccSAndroid Build Coastguard Worker                                      27 * bottom_block[bottom_stride] + 16) >>
961*77c1e3ccSAndroid Build Coastguard Worker                                         5,
962*77c1e3ccSAndroid Build Coastguard Worker                                     grain_min, grain_max);
963*77c1e3ccSAndroid Build Coastguard Worker       ++top_block;
964*77c1e3ccSAndroid Build Coastguard Worker       ++bottom_block;
965*77c1e3ccSAndroid Build Coastguard Worker       ++dst_block;
966*77c1e3ccSAndroid Build Coastguard Worker       --width;
967*77c1e3ccSAndroid Build Coastguard Worker     }
968*77c1e3ccSAndroid Build Coastguard Worker     return;
969*77c1e3ccSAndroid Build Coastguard Worker   }
970*77c1e3ccSAndroid Build Coastguard Worker }
971*77c1e3ccSAndroid Build Coastguard Worker 
av1_add_film_grain(const aom_film_grain_t * params,const aom_image_t * src,aom_image_t * dst)972*77c1e3ccSAndroid Build Coastguard Worker int av1_add_film_grain(const aom_film_grain_t *params, const aom_image_t *src,
973*77c1e3ccSAndroid Build Coastguard Worker                        aom_image_t *dst) {
974*77c1e3ccSAndroid Build Coastguard Worker   uint8_t *luma, *cb, *cr;
975*77c1e3ccSAndroid Build Coastguard Worker   int height, width, luma_stride, chroma_stride;
976*77c1e3ccSAndroid Build Coastguard Worker   int use_high_bit_depth = 0;
977*77c1e3ccSAndroid Build Coastguard Worker   int chroma_subsamp_x = 0;
978*77c1e3ccSAndroid Build Coastguard Worker   int chroma_subsamp_y = 0;
979*77c1e3ccSAndroid Build Coastguard Worker   int mc_identity = src->mc == AOM_CICP_MC_IDENTITY ? 1 : 0;
980*77c1e3ccSAndroid Build Coastguard Worker 
981*77c1e3ccSAndroid Build Coastguard Worker   switch (src->fmt) {
982*77c1e3ccSAndroid Build Coastguard Worker     case AOM_IMG_FMT_AOMI420:
983*77c1e3ccSAndroid Build Coastguard Worker     case AOM_IMG_FMT_I420:
984*77c1e3ccSAndroid Build Coastguard Worker       use_high_bit_depth = 0;
985*77c1e3ccSAndroid Build Coastguard Worker       chroma_subsamp_x = 1;
986*77c1e3ccSAndroid Build Coastguard Worker       chroma_subsamp_y = 1;
987*77c1e3ccSAndroid Build Coastguard Worker       break;
988*77c1e3ccSAndroid Build Coastguard Worker     case AOM_IMG_FMT_I42016:
989*77c1e3ccSAndroid Build Coastguard Worker       use_high_bit_depth = 1;
990*77c1e3ccSAndroid Build Coastguard Worker       chroma_subsamp_x = 1;
991*77c1e3ccSAndroid Build Coastguard Worker       chroma_subsamp_y = 1;
992*77c1e3ccSAndroid Build Coastguard Worker       break;
993*77c1e3ccSAndroid Build Coastguard Worker       //    case AOM_IMG_FMT_444A:
994*77c1e3ccSAndroid Build Coastguard Worker     case AOM_IMG_FMT_I444:
995*77c1e3ccSAndroid Build Coastguard Worker       use_high_bit_depth = 0;
996*77c1e3ccSAndroid Build Coastguard Worker       chroma_subsamp_x = 0;
997*77c1e3ccSAndroid Build Coastguard Worker       chroma_subsamp_y = 0;
998*77c1e3ccSAndroid Build Coastguard Worker       break;
999*77c1e3ccSAndroid Build Coastguard Worker     case AOM_IMG_FMT_I44416:
1000*77c1e3ccSAndroid Build Coastguard Worker       use_high_bit_depth = 1;
1001*77c1e3ccSAndroid Build Coastguard Worker       chroma_subsamp_x = 0;
1002*77c1e3ccSAndroid Build Coastguard Worker       chroma_subsamp_y = 0;
1003*77c1e3ccSAndroid Build Coastguard Worker       break;
1004*77c1e3ccSAndroid Build Coastguard Worker     case AOM_IMG_FMT_I422:
1005*77c1e3ccSAndroid Build Coastguard Worker       use_high_bit_depth = 0;
1006*77c1e3ccSAndroid Build Coastguard Worker       chroma_subsamp_x = 1;
1007*77c1e3ccSAndroid Build Coastguard Worker       chroma_subsamp_y = 0;
1008*77c1e3ccSAndroid Build Coastguard Worker       break;
1009*77c1e3ccSAndroid Build Coastguard Worker     case AOM_IMG_FMT_I42216:
1010*77c1e3ccSAndroid Build Coastguard Worker       use_high_bit_depth = 1;
1011*77c1e3ccSAndroid Build Coastguard Worker       chroma_subsamp_x = 1;
1012*77c1e3ccSAndroid Build Coastguard Worker       chroma_subsamp_y = 0;
1013*77c1e3ccSAndroid Build Coastguard Worker       break;
1014*77c1e3ccSAndroid Build Coastguard Worker     default:  // unknown input format
1015*77c1e3ccSAndroid Build Coastguard Worker       fprintf(stderr, "Film grain error: input format is not supported!");
1016*77c1e3ccSAndroid Build Coastguard Worker       return -1;
1017*77c1e3ccSAndroid Build Coastguard Worker   }
1018*77c1e3ccSAndroid Build Coastguard Worker 
1019*77c1e3ccSAndroid Build Coastguard Worker   assert(params->bit_depth == src->bit_depth);
1020*77c1e3ccSAndroid Build Coastguard Worker 
1021*77c1e3ccSAndroid Build Coastguard Worker   dst->fmt = src->fmt;
1022*77c1e3ccSAndroid Build Coastguard Worker   dst->bit_depth = src->bit_depth;
1023*77c1e3ccSAndroid Build Coastguard Worker 
1024*77c1e3ccSAndroid Build Coastguard Worker   dst->r_w = src->r_w;
1025*77c1e3ccSAndroid Build Coastguard Worker   dst->r_h = src->r_h;
1026*77c1e3ccSAndroid Build Coastguard Worker   dst->d_w = src->d_w;
1027*77c1e3ccSAndroid Build Coastguard Worker   dst->d_h = src->d_h;
1028*77c1e3ccSAndroid Build Coastguard Worker 
1029*77c1e3ccSAndroid Build Coastguard Worker   dst->cp = src->cp;
1030*77c1e3ccSAndroid Build Coastguard Worker   dst->tc = src->tc;
1031*77c1e3ccSAndroid Build Coastguard Worker   dst->mc = src->mc;
1032*77c1e3ccSAndroid Build Coastguard Worker 
1033*77c1e3ccSAndroid Build Coastguard Worker   dst->monochrome = src->monochrome;
1034*77c1e3ccSAndroid Build Coastguard Worker   dst->csp = src->csp;
1035*77c1e3ccSAndroid Build Coastguard Worker   dst->range = src->range;
1036*77c1e3ccSAndroid Build Coastguard Worker 
1037*77c1e3ccSAndroid Build Coastguard Worker   dst->x_chroma_shift = src->x_chroma_shift;
1038*77c1e3ccSAndroid Build Coastguard Worker   dst->y_chroma_shift = src->y_chroma_shift;
1039*77c1e3ccSAndroid Build Coastguard Worker 
1040*77c1e3ccSAndroid Build Coastguard Worker   dst->temporal_id = src->temporal_id;
1041*77c1e3ccSAndroid Build Coastguard Worker   dst->spatial_id = src->spatial_id;
1042*77c1e3ccSAndroid Build Coastguard Worker 
1043*77c1e3ccSAndroid Build Coastguard Worker   width = src->d_w % 2 ? src->d_w + 1 : src->d_w;
1044*77c1e3ccSAndroid Build Coastguard Worker   height = src->d_h % 2 ? src->d_h + 1 : src->d_h;
1045*77c1e3ccSAndroid Build Coastguard Worker 
1046*77c1e3ccSAndroid Build Coastguard Worker   copy_rect(src->planes[AOM_PLANE_Y], src->stride[AOM_PLANE_Y],
1047*77c1e3ccSAndroid Build Coastguard Worker             dst->planes[AOM_PLANE_Y], dst->stride[AOM_PLANE_Y], src->d_w,
1048*77c1e3ccSAndroid Build Coastguard Worker             src->d_h, use_high_bit_depth);
1049*77c1e3ccSAndroid Build Coastguard Worker   // Note that dst is already assumed to be aligned to even.
1050*77c1e3ccSAndroid Build Coastguard Worker   extend_even(dst->planes[AOM_PLANE_Y], dst->stride[AOM_PLANE_Y], src->d_w,
1051*77c1e3ccSAndroid Build Coastguard Worker               src->d_h, use_high_bit_depth);
1052*77c1e3ccSAndroid Build Coastguard Worker 
1053*77c1e3ccSAndroid Build Coastguard Worker   if (!src->monochrome) {
1054*77c1e3ccSAndroid Build Coastguard Worker     copy_rect(src->planes[AOM_PLANE_U], src->stride[AOM_PLANE_U],
1055*77c1e3ccSAndroid Build Coastguard Worker               dst->planes[AOM_PLANE_U], dst->stride[AOM_PLANE_U],
1056*77c1e3ccSAndroid Build Coastguard Worker               width >> chroma_subsamp_x, height >> chroma_subsamp_y,
1057*77c1e3ccSAndroid Build Coastguard Worker               use_high_bit_depth);
1058*77c1e3ccSAndroid Build Coastguard Worker 
1059*77c1e3ccSAndroid Build Coastguard Worker     copy_rect(src->planes[AOM_PLANE_V], src->stride[AOM_PLANE_V],
1060*77c1e3ccSAndroid Build Coastguard Worker               dst->planes[AOM_PLANE_V], dst->stride[AOM_PLANE_V],
1061*77c1e3ccSAndroid Build Coastguard Worker               width >> chroma_subsamp_x, height >> chroma_subsamp_y,
1062*77c1e3ccSAndroid Build Coastguard Worker               use_high_bit_depth);
1063*77c1e3ccSAndroid Build Coastguard Worker   }
1064*77c1e3ccSAndroid Build Coastguard Worker 
1065*77c1e3ccSAndroid Build Coastguard Worker   luma = dst->planes[AOM_PLANE_Y];
1066*77c1e3ccSAndroid Build Coastguard Worker   cb = dst->planes[AOM_PLANE_U];
1067*77c1e3ccSAndroid Build Coastguard Worker   cr = dst->planes[AOM_PLANE_V];
1068*77c1e3ccSAndroid Build Coastguard Worker 
1069*77c1e3ccSAndroid Build Coastguard Worker   // luma and chroma strides in samples
1070*77c1e3ccSAndroid Build Coastguard Worker   luma_stride = dst->stride[AOM_PLANE_Y] >> use_high_bit_depth;
1071*77c1e3ccSAndroid Build Coastguard Worker   chroma_stride = dst->stride[AOM_PLANE_U] >> use_high_bit_depth;
1072*77c1e3ccSAndroid Build Coastguard Worker 
1073*77c1e3ccSAndroid Build Coastguard Worker   return av1_add_film_grain_run(
1074*77c1e3ccSAndroid Build Coastguard Worker       params, luma, cb, cr, height, width, luma_stride, chroma_stride,
1075*77c1e3ccSAndroid Build Coastguard Worker       use_high_bit_depth, chroma_subsamp_y, chroma_subsamp_x, mc_identity);
1076*77c1e3ccSAndroid Build Coastguard Worker }
1077*77c1e3ccSAndroid Build Coastguard Worker 
av1_add_film_grain_run(const aom_film_grain_t * params,uint8_t * luma,uint8_t * cb,uint8_t * cr,int height,int width,int luma_stride,int chroma_stride,int use_high_bit_depth,int chroma_subsamp_y,int chroma_subsamp_x,int mc_identity)1078*77c1e3ccSAndroid Build Coastguard Worker int av1_add_film_grain_run(const aom_film_grain_t *params, uint8_t *luma,
1079*77c1e3ccSAndroid Build Coastguard Worker                            uint8_t *cb, uint8_t *cr, int height, int width,
1080*77c1e3ccSAndroid Build Coastguard Worker                            int luma_stride, int chroma_stride,
1081*77c1e3ccSAndroid Build Coastguard Worker                            int use_high_bit_depth, int chroma_subsamp_y,
1082*77c1e3ccSAndroid Build Coastguard Worker                            int chroma_subsamp_x, int mc_identity) {
1083*77c1e3ccSAndroid Build Coastguard Worker   int **pred_pos_luma;
1084*77c1e3ccSAndroid Build Coastguard Worker   int **pred_pos_chroma;
1085*77c1e3ccSAndroid Build Coastguard Worker   int *luma_grain_block;
1086*77c1e3ccSAndroid Build Coastguard Worker   int *cb_grain_block;
1087*77c1e3ccSAndroid Build Coastguard Worker   int *cr_grain_block;
1088*77c1e3ccSAndroid Build Coastguard Worker 
1089*77c1e3ccSAndroid Build Coastguard Worker   int *y_line_buf;
1090*77c1e3ccSAndroid Build Coastguard Worker   int *cb_line_buf;
1091*77c1e3ccSAndroid Build Coastguard Worker   int *cr_line_buf;
1092*77c1e3ccSAndroid Build Coastguard Worker 
1093*77c1e3ccSAndroid Build Coastguard Worker   int *y_col_buf;
1094*77c1e3ccSAndroid Build Coastguard Worker   int *cb_col_buf;
1095*77c1e3ccSAndroid Build Coastguard Worker   int *cr_col_buf;
1096*77c1e3ccSAndroid Build Coastguard Worker 
1097*77c1e3ccSAndroid Build Coastguard Worker   random_register = params->random_seed;
1098*77c1e3ccSAndroid Build Coastguard Worker 
1099*77c1e3ccSAndroid Build Coastguard Worker   int left_pad = 3;
1100*77c1e3ccSAndroid Build Coastguard Worker   int right_pad = 3;  // padding to offset for AR coefficients
1101*77c1e3ccSAndroid Build Coastguard Worker   int top_pad = 3;
1102*77c1e3ccSAndroid Build Coastguard Worker   int bottom_pad = 0;
1103*77c1e3ccSAndroid Build Coastguard Worker 
1104*77c1e3ccSAndroid Build Coastguard Worker   int ar_padding = 3;  // maximum lag used for stabilization of AR coefficients
1105*77c1e3ccSAndroid Build Coastguard Worker 
1106*77c1e3ccSAndroid Build Coastguard Worker   luma_subblock_size_y = 32;
1107*77c1e3ccSAndroid Build Coastguard Worker   luma_subblock_size_x = 32;
1108*77c1e3ccSAndroid Build Coastguard Worker 
1109*77c1e3ccSAndroid Build Coastguard Worker   chroma_subblock_size_y = luma_subblock_size_y >> chroma_subsamp_y;
1110*77c1e3ccSAndroid Build Coastguard Worker   chroma_subblock_size_x = luma_subblock_size_x >> chroma_subsamp_x;
1111*77c1e3ccSAndroid Build Coastguard Worker 
1112*77c1e3ccSAndroid Build Coastguard Worker   // Initial padding is only needed for generation of
1113*77c1e3ccSAndroid Build Coastguard Worker   // film grain templates (to stabilize the AR process)
1114*77c1e3ccSAndroid Build Coastguard Worker   // Only a 64x64 luma and 32x32 chroma part of a template
1115*77c1e3ccSAndroid Build Coastguard Worker   // is used later for adding grain, padding can be discarded
1116*77c1e3ccSAndroid Build Coastguard Worker 
1117*77c1e3ccSAndroid Build Coastguard Worker   int luma_block_size_y =
1118*77c1e3ccSAndroid Build Coastguard Worker       top_pad + 2 * ar_padding + luma_subblock_size_y * 2 + bottom_pad;
1119*77c1e3ccSAndroid Build Coastguard Worker   int luma_block_size_x = left_pad + 2 * ar_padding + luma_subblock_size_x * 2 +
1120*77c1e3ccSAndroid Build Coastguard Worker                           2 * ar_padding + right_pad;
1121*77c1e3ccSAndroid Build Coastguard Worker 
1122*77c1e3ccSAndroid Build Coastguard Worker   int chroma_block_size_y = top_pad + (2 >> chroma_subsamp_y) * ar_padding +
1123*77c1e3ccSAndroid Build Coastguard Worker                             chroma_subblock_size_y * 2 + bottom_pad;
1124*77c1e3ccSAndroid Build Coastguard Worker   int chroma_block_size_x = left_pad + (2 >> chroma_subsamp_x) * ar_padding +
1125*77c1e3ccSAndroid Build Coastguard Worker                             chroma_subblock_size_x * 2 +
1126*77c1e3ccSAndroid Build Coastguard Worker                             (2 >> chroma_subsamp_x) * ar_padding + right_pad;
1127*77c1e3ccSAndroid Build Coastguard Worker 
1128*77c1e3ccSAndroid Build Coastguard Worker   int luma_grain_stride = luma_block_size_x;
1129*77c1e3ccSAndroid Build Coastguard Worker   int chroma_grain_stride = chroma_block_size_x;
1130*77c1e3ccSAndroid Build Coastguard Worker 
1131*77c1e3ccSAndroid Build Coastguard Worker   int overlap = params->overlap_flag;
1132*77c1e3ccSAndroid Build Coastguard Worker   int bit_depth = params->bit_depth;
1133*77c1e3ccSAndroid Build Coastguard Worker 
1134*77c1e3ccSAndroid Build Coastguard Worker   const int grain_center = 128 << (bit_depth - 8);
1135*77c1e3ccSAndroid Build Coastguard Worker   grain_min = 0 - grain_center;
1136*77c1e3ccSAndroid Build Coastguard Worker   grain_max = grain_center - 1;
1137*77c1e3ccSAndroid Build Coastguard Worker 
1138*77c1e3ccSAndroid Build Coastguard Worker   if (!init_arrays(params, luma_stride, chroma_stride, &pred_pos_luma,
1139*77c1e3ccSAndroid Build Coastguard Worker                    &pred_pos_chroma, &luma_grain_block, &cb_grain_block,
1140*77c1e3ccSAndroid Build Coastguard Worker                    &cr_grain_block, &y_line_buf, &cb_line_buf, &cr_line_buf,
1141*77c1e3ccSAndroid Build Coastguard Worker                    &y_col_buf, &cb_col_buf, &cr_col_buf,
1142*77c1e3ccSAndroid Build Coastguard Worker                    luma_block_size_y * luma_block_size_x,
1143*77c1e3ccSAndroid Build Coastguard Worker                    chroma_block_size_y * chroma_block_size_x, chroma_subsamp_y,
1144*77c1e3ccSAndroid Build Coastguard Worker                    chroma_subsamp_x))
1145*77c1e3ccSAndroid Build Coastguard Worker     return -1;
1146*77c1e3ccSAndroid Build Coastguard Worker 
1147*77c1e3ccSAndroid Build Coastguard Worker   generate_luma_grain_block(params, pred_pos_luma, luma_grain_block,
1148*77c1e3ccSAndroid Build Coastguard Worker                             luma_block_size_y, luma_block_size_x,
1149*77c1e3ccSAndroid Build Coastguard Worker                             luma_grain_stride, left_pad, top_pad, right_pad,
1150*77c1e3ccSAndroid Build Coastguard Worker                             bottom_pad);
1151*77c1e3ccSAndroid Build Coastguard Worker 
1152*77c1e3ccSAndroid Build Coastguard Worker   if (!generate_chroma_grain_blocks(
1153*77c1e3ccSAndroid Build Coastguard Worker           params, pred_pos_chroma, luma_grain_block, cb_grain_block,
1154*77c1e3ccSAndroid Build Coastguard Worker           cr_grain_block, luma_grain_stride, chroma_block_size_y,
1155*77c1e3ccSAndroid Build Coastguard Worker           chroma_block_size_x, chroma_grain_stride, left_pad, top_pad,
1156*77c1e3ccSAndroid Build Coastguard Worker           right_pad, bottom_pad, chroma_subsamp_y, chroma_subsamp_x))
1157*77c1e3ccSAndroid Build Coastguard Worker     return -1;
1158*77c1e3ccSAndroid Build Coastguard Worker 
1159*77c1e3ccSAndroid Build Coastguard Worker   init_scaling_function(params->scaling_points_y, params->num_y_points,
1160*77c1e3ccSAndroid Build Coastguard Worker                         scaling_lut_y);
1161*77c1e3ccSAndroid Build Coastguard Worker 
1162*77c1e3ccSAndroid Build Coastguard Worker   if (params->chroma_scaling_from_luma) {
1163*77c1e3ccSAndroid Build Coastguard Worker     memcpy(scaling_lut_cb, scaling_lut_y, sizeof(*scaling_lut_y) * 256);
1164*77c1e3ccSAndroid Build Coastguard Worker     memcpy(scaling_lut_cr, scaling_lut_y, sizeof(*scaling_lut_y) * 256);
1165*77c1e3ccSAndroid Build Coastguard Worker   } else {
1166*77c1e3ccSAndroid Build Coastguard Worker     init_scaling_function(params->scaling_points_cb, params->num_cb_points,
1167*77c1e3ccSAndroid Build Coastguard Worker                           scaling_lut_cb);
1168*77c1e3ccSAndroid Build Coastguard Worker     init_scaling_function(params->scaling_points_cr, params->num_cr_points,
1169*77c1e3ccSAndroid Build Coastguard Worker                           scaling_lut_cr);
1170*77c1e3ccSAndroid Build Coastguard Worker   }
1171*77c1e3ccSAndroid Build Coastguard Worker   for (int y = 0; y < height / 2; y += (luma_subblock_size_y >> 1)) {
1172*77c1e3ccSAndroid Build Coastguard Worker     init_random_generator(y * 2, params->random_seed);
1173*77c1e3ccSAndroid Build Coastguard Worker 
1174*77c1e3ccSAndroid Build Coastguard Worker     for (int x = 0; x < width / 2; x += (luma_subblock_size_x >> 1)) {
1175*77c1e3ccSAndroid Build Coastguard Worker       int offset_y = get_random_number(8);
1176*77c1e3ccSAndroid Build Coastguard Worker       int offset_x = (offset_y >> 4) & 15;
1177*77c1e3ccSAndroid Build Coastguard Worker       offset_y &= 15;
1178*77c1e3ccSAndroid Build Coastguard Worker 
1179*77c1e3ccSAndroid Build Coastguard Worker       int luma_offset_y = left_pad + 2 * ar_padding + (offset_y << 1);
1180*77c1e3ccSAndroid Build Coastguard Worker       int luma_offset_x = top_pad + 2 * ar_padding + (offset_x << 1);
1181*77c1e3ccSAndroid Build Coastguard Worker 
1182*77c1e3ccSAndroid Build Coastguard Worker       int chroma_offset_y = top_pad + (2 >> chroma_subsamp_y) * ar_padding +
1183*77c1e3ccSAndroid Build Coastguard Worker                             offset_y * (2 >> chroma_subsamp_y);
1184*77c1e3ccSAndroid Build Coastguard Worker       int chroma_offset_x = left_pad + (2 >> chroma_subsamp_x) * ar_padding +
1185*77c1e3ccSAndroid Build Coastguard Worker                             offset_x * (2 >> chroma_subsamp_x);
1186*77c1e3ccSAndroid Build Coastguard Worker 
1187*77c1e3ccSAndroid Build Coastguard Worker       if (overlap && x) {
1188*77c1e3ccSAndroid Build Coastguard Worker         ver_boundary_overlap(
1189*77c1e3ccSAndroid Build Coastguard Worker             y_col_buf, 2,
1190*77c1e3ccSAndroid Build Coastguard Worker             luma_grain_block + luma_offset_y * luma_grain_stride +
1191*77c1e3ccSAndroid Build Coastguard Worker                 luma_offset_x,
1192*77c1e3ccSAndroid Build Coastguard Worker             luma_grain_stride, y_col_buf, 2, 2,
1193*77c1e3ccSAndroid Build Coastguard Worker             AOMMIN(luma_subblock_size_y + 2, height - (y << 1)));
1194*77c1e3ccSAndroid Build Coastguard Worker 
1195*77c1e3ccSAndroid Build Coastguard Worker         ver_boundary_overlap(
1196*77c1e3ccSAndroid Build Coastguard Worker             cb_col_buf, 2 >> chroma_subsamp_x,
1197*77c1e3ccSAndroid Build Coastguard Worker             cb_grain_block + chroma_offset_y * chroma_grain_stride +
1198*77c1e3ccSAndroid Build Coastguard Worker                 chroma_offset_x,
1199*77c1e3ccSAndroid Build Coastguard Worker             chroma_grain_stride, cb_col_buf, 2 >> chroma_subsamp_x,
1200*77c1e3ccSAndroid Build Coastguard Worker             2 >> chroma_subsamp_x,
1201*77c1e3ccSAndroid Build Coastguard Worker             AOMMIN(chroma_subblock_size_y + (2 >> chroma_subsamp_y),
1202*77c1e3ccSAndroid Build Coastguard Worker                    (height - (y << 1)) >> chroma_subsamp_y));
1203*77c1e3ccSAndroid Build Coastguard Worker 
1204*77c1e3ccSAndroid Build Coastguard Worker         ver_boundary_overlap(
1205*77c1e3ccSAndroid Build Coastguard Worker             cr_col_buf, 2 >> chroma_subsamp_x,
1206*77c1e3ccSAndroid Build Coastguard Worker             cr_grain_block + chroma_offset_y * chroma_grain_stride +
1207*77c1e3ccSAndroid Build Coastguard Worker                 chroma_offset_x,
1208*77c1e3ccSAndroid Build Coastguard Worker             chroma_grain_stride, cr_col_buf, 2 >> chroma_subsamp_x,
1209*77c1e3ccSAndroid Build Coastguard Worker             2 >> chroma_subsamp_x,
1210*77c1e3ccSAndroid Build Coastguard Worker             AOMMIN(chroma_subblock_size_y + (2 >> chroma_subsamp_y),
1211*77c1e3ccSAndroid Build Coastguard Worker                    (height - (y << 1)) >> chroma_subsamp_y));
1212*77c1e3ccSAndroid Build Coastguard Worker 
1213*77c1e3ccSAndroid Build Coastguard Worker         int i = y ? 1 : 0;
1214*77c1e3ccSAndroid Build Coastguard Worker 
1215*77c1e3ccSAndroid Build Coastguard Worker         if (use_high_bit_depth) {
1216*77c1e3ccSAndroid Build Coastguard Worker           add_noise_to_block_hbd(
1217*77c1e3ccSAndroid Build Coastguard Worker               params,
1218*77c1e3ccSAndroid Build Coastguard Worker               (uint16_t *)luma + ((y + i) << 1) * luma_stride + (x << 1),
1219*77c1e3ccSAndroid Build Coastguard Worker               (uint16_t *)cb +
1220*77c1e3ccSAndroid Build Coastguard Worker                   ((y + i) << (1 - chroma_subsamp_y)) * chroma_stride +
1221*77c1e3ccSAndroid Build Coastguard Worker                   (x << (1 - chroma_subsamp_x)),
1222*77c1e3ccSAndroid Build Coastguard Worker               (uint16_t *)cr +
1223*77c1e3ccSAndroid Build Coastguard Worker                   ((y + i) << (1 - chroma_subsamp_y)) * chroma_stride +
1224*77c1e3ccSAndroid Build Coastguard Worker                   (x << (1 - chroma_subsamp_x)),
1225*77c1e3ccSAndroid Build Coastguard Worker               luma_stride, chroma_stride, y_col_buf + i * 4,
1226*77c1e3ccSAndroid Build Coastguard Worker               cb_col_buf + i * (2 - chroma_subsamp_y) * (2 - chroma_subsamp_x),
1227*77c1e3ccSAndroid Build Coastguard Worker               cr_col_buf + i * (2 - chroma_subsamp_y) * (2 - chroma_subsamp_x),
1228*77c1e3ccSAndroid Build Coastguard Worker               2, (2 - chroma_subsamp_x),
1229*77c1e3ccSAndroid Build Coastguard Worker               AOMMIN(luma_subblock_size_y >> 1, height / 2 - y) - i, 1,
1230*77c1e3ccSAndroid Build Coastguard Worker               bit_depth, chroma_subsamp_y, chroma_subsamp_x, mc_identity);
1231*77c1e3ccSAndroid Build Coastguard Worker         } else {
1232*77c1e3ccSAndroid Build Coastguard Worker           add_noise_to_block(
1233*77c1e3ccSAndroid Build Coastguard Worker               params, luma + ((y + i) << 1) * luma_stride + (x << 1),
1234*77c1e3ccSAndroid Build Coastguard Worker               cb + ((y + i) << (1 - chroma_subsamp_y)) * chroma_stride +
1235*77c1e3ccSAndroid Build Coastguard Worker                   (x << (1 - chroma_subsamp_x)),
1236*77c1e3ccSAndroid Build Coastguard Worker               cr + ((y + i) << (1 - chroma_subsamp_y)) * chroma_stride +
1237*77c1e3ccSAndroid Build Coastguard Worker                   (x << (1 - chroma_subsamp_x)),
1238*77c1e3ccSAndroid Build Coastguard Worker               luma_stride, chroma_stride, y_col_buf + i * 4,
1239*77c1e3ccSAndroid Build Coastguard Worker               cb_col_buf + i * (2 - chroma_subsamp_y) * (2 - chroma_subsamp_x),
1240*77c1e3ccSAndroid Build Coastguard Worker               cr_col_buf + i * (2 - chroma_subsamp_y) * (2 - chroma_subsamp_x),
1241*77c1e3ccSAndroid Build Coastguard Worker               2, (2 - chroma_subsamp_x),
1242*77c1e3ccSAndroid Build Coastguard Worker               AOMMIN(luma_subblock_size_y >> 1, height / 2 - y) - i, 1,
1243*77c1e3ccSAndroid Build Coastguard Worker               bit_depth, chroma_subsamp_y, chroma_subsamp_x, mc_identity);
1244*77c1e3ccSAndroid Build Coastguard Worker         }
1245*77c1e3ccSAndroid Build Coastguard Worker       }
1246*77c1e3ccSAndroid Build Coastguard Worker 
1247*77c1e3ccSAndroid Build Coastguard Worker       if (overlap && y) {
1248*77c1e3ccSAndroid Build Coastguard Worker         if (x) {
1249*77c1e3ccSAndroid Build Coastguard Worker           hor_boundary_overlap(y_line_buf + (x << 1), luma_stride, y_col_buf, 2,
1250*77c1e3ccSAndroid Build Coastguard Worker                                y_line_buf + (x << 1), luma_stride, 2, 2);
1251*77c1e3ccSAndroid Build Coastguard Worker 
1252*77c1e3ccSAndroid Build Coastguard Worker           hor_boundary_overlap(cb_line_buf + x * (2 >> chroma_subsamp_x),
1253*77c1e3ccSAndroid Build Coastguard Worker                                chroma_stride, cb_col_buf, 2 >> chroma_subsamp_x,
1254*77c1e3ccSAndroid Build Coastguard Worker                                cb_line_buf + x * (2 >> chroma_subsamp_x),
1255*77c1e3ccSAndroid Build Coastguard Worker                                chroma_stride, 2 >> chroma_subsamp_x,
1256*77c1e3ccSAndroid Build Coastguard Worker                                2 >> chroma_subsamp_y);
1257*77c1e3ccSAndroid Build Coastguard Worker 
1258*77c1e3ccSAndroid Build Coastguard Worker           hor_boundary_overlap(cr_line_buf + x * (2 >> chroma_subsamp_x),
1259*77c1e3ccSAndroid Build Coastguard Worker                                chroma_stride, cr_col_buf, 2 >> chroma_subsamp_x,
1260*77c1e3ccSAndroid Build Coastguard Worker                                cr_line_buf + x * (2 >> chroma_subsamp_x),
1261*77c1e3ccSAndroid Build Coastguard Worker                                chroma_stride, 2 >> chroma_subsamp_x,
1262*77c1e3ccSAndroid Build Coastguard Worker                                2 >> chroma_subsamp_y);
1263*77c1e3ccSAndroid Build Coastguard Worker         }
1264*77c1e3ccSAndroid Build Coastguard Worker 
1265*77c1e3ccSAndroid Build Coastguard Worker         hor_boundary_overlap(
1266*77c1e3ccSAndroid Build Coastguard Worker             y_line_buf + ((x ? x + 1 : 0) << 1), luma_stride,
1267*77c1e3ccSAndroid Build Coastguard Worker             luma_grain_block + luma_offset_y * luma_grain_stride +
1268*77c1e3ccSAndroid Build Coastguard Worker                 luma_offset_x + (x ? 2 : 0),
1269*77c1e3ccSAndroid Build Coastguard Worker             luma_grain_stride, y_line_buf + ((x ? x + 1 : 0) << 1), luma_stride,
1270*77c1e3ccSAndroid Build Coastguard Worker             AOMMIN(luma_subblock_size_x - ((x ? 1 : 0) << 1),
1271*77c1e3ccSAndroid Build Coastguard Worker                    width - ((x ? x + 1 : 0) << 1)),
1272*77c1e3ccSAndroid Build Coastguard Worker             2);
1273*77c1e3ccSAndroid Build Coastguard Worker 
1274*77c1e3ccSAndroid Build Coastguard Worker         hor_boundary_overlap(
1275*77c1e3ccSAndroid Build Coastguard Worker             cb_line_buf + ((x ? x + 1 : 0) << (1 - chroma_subsamp_x)),
1276*77c1e3ccSAndroid Build Coastguard Worker             chroma_stride,
1277*77c1e3ccSAndroid Build Coastguard Worker             cb_grain_block + chroma_offset_y * chroma_grain_stride +
1278*77c1e3ccSAndroid Build Coastguard Worker                 chroma_offset_x + ((x ? 1 : 0) << (1 - chroma_subsamp_x)),
1279*77c1e3ccSAndroid Build Coastguard Worker             chroma_grain_stride,
1280*77c1e3ccSAndroid Build Coastguard Worker             cb_line_buf + ((x ? x + 1 : 0) << (1 - chroma_subsamp_x)),
1281*77c1e3ccSAndroid Build Coastguard Worker             chroma_stride,
1282*77c1e3ccSAndroid Build Coastguard Worker             AOMMIN(chroma_subblock_size_x -
1283*77c1e3ccSAndroid Build Coastguard Worker                        ((x ? 1 : 0) << (1 - chroma_subsamp_x)),
1284*77c1e3ccSAndroid Build Coastguard Worker                    (width - ((x ? x + 1 : 0) << 1)) >> chroma_subsamp_x),
1285*77c1e3ccSAndroid Build Coastguard Worker             2 >> chroma_subsamp_y);
1286*77c1e3ccSAndroid Build Coastguard Worker 
1287*77c1e3ccSAndroid Build Coastguard Worker         hor_boundary_overlap(
1288*77c1e3ccSAndroid Build Coastguard Worker             cr_line_buf + ((x ? x + 1 : 0) << (1 - chroma_subsamp_x)),
1289*77c1e3ccSAndroid Build Coastguard Worker             chroma_stride,
1290*77c1e3ccSAndroid Build Coastguard Worker             cr_grain_block + chroma_offset_y * chroma_grain_stride +
1291*77c1e3ccSAndroid Build Coastguard Worker                 chroma_offset_x + ((x ? 1 : 0) << (1 - chroma_subsamp_x)),
1292*77c1e3ccSAndroid Build Coastguard Worker             chroma_grain_stride,
1293*77c1e3ccSAndroid Build Coastguard Worker             cr_line_buf + ((x ? x + 1 : 0) << (1 - chroma_subsamp_x)),
1294*77c1e3ccSAndroid Build Coastguard Worker             chroma_stride,
1295*77c1e3ccSAndroid Build Coastguard Worker             AOMMIN(chroma_subblock_size_x -
1296*77c1e3ccSAndroid Build Coastguard Worker                        ((x ? 1 : 0) << (1 - chroma_subsamp_x)),
1297*77c1e3ccSAndroid Build Coastguard Worker                    (width - ((x ? x + 1 : 0) << 1)) >> chroma_subsamp_x),
1298*77c1e3ccSAndroid Build Coastguard Worker             2 >> chroma_subsamp_y);
1299*77c1e3ccSAndroid Build Coastguard Worker 
1300*77c1e3ccSAndroid Build Coastguard Worker         if (use_high_bit_depth) {
1301*77c1e3ccSAndroid Build Coastguard Worker           add_noise_to_block_hbd(
1302*77c1e3ccSAndroid Build Coastguard Worker               params, (uint16_t *)luma + (y << 1) * luma_stride + (x << 1),
1303*77c1e3ccSAndroid Build Coastguard Worker               (uint16_t *)cb + (y << (1 - chroma_subsamp_y)) * chroma_stride +
1304*77c1e3ccSAndroid Build Coastguard Worker                   (x << ((1 - chroma_subsamp_x))),
1305*77c1e3ccSAndroid Build Coastguard Worker               (uint16_t *)cr + (y << (1 - chroma_subsamp_y)) * chroma_stride +
1306*77c1e3ccSAndroid Build Coastguard Worker                   (x << ((1 - chroma_subsamp_x))),
1307*77c1e3ccSAndroid Build Coastguard Worker               luma_stride, chroma_stride, y_line_buf + (x << 1),
1308*77c1e3ccSAndroid Build Coastguard Worker               cb_line_buf + (x << (1 - chroma_subsamp_x)),
1309*77c1e3ccSAndroid Build Coastguard Worker               cr_line_buf + (x << (1 - chroma_subsamp_x)), luma_stride,
1310*77c1e3ccSAndroid Build Coastguard Worker               chroma_stride, 1,
1311*77c1e3ccSAndroid Build Coastguard Worker               AOMMIN(luma_subblock_size_x >> 1, width / 2 - x), bit_depth,
1312*77c1e3ccSAndroid Build Coastguard Worker               chroma_subsamp_y, chroma_subsamp_x, mc_identity);
1313*77c1e3ccSAndroid Build Coastguard Worker         } else {
1314*77c1e3ccSAndroid Build Coastguard Worker           add_noise_to_block(
1315*77c1e3ccSAndroid Build Coastguard Worker               params, luma + (y << 1) * luma_stride + (x << 1),
1316*77c1e3ccSAndroid Build Coastguard Worker               cb + (y << (1 - chroma_subsamp_y)) * chroma_stride +
1317*77c1e3ccSAndroid Build Coastguard Worker                   (x << ((1 - chroma_subsamp_x))),
1318*77c1e3ccSAndroid Build Coastguard Worker               cr + (y << (1 - chroma_subsamp_y)) * chroma_stride +
1319*77c1e3ccSAndroid Build Coastguard Worker                   (x << ((1 - chroma_subsamp_x))),
1320*77c1e3ccSAndroid Build Coastguard Worker               luma_stride, chroma_stride, y_line_buf + (x << 1),
1321*77c1e3ccSAndroid Build Coastguard Worker               cb_line_buf + (x << (1 - chroma_subsamp_x)),
1322*77c1e3ccSAndroid Build Coastguard Worker               cr_line_buf + (x << (1 - chroma_subsamp_x)), luma_stride,
1323*77c1e3ccSAndroid Build Coastguard Worker               chroma_stride, 1,
1324*77c1e3ccSAndroid Build Coastguard Worker               AOMMIN(luma_subblock_size_x >> 1, width / 2 - x), bit_depth,
1325*77c1e3ccSAndroid Build Coastguard Worker               chroma_subsamp_y, chroma_subsamp_x, mc_identity);
1326*77c1e3ccSAndroid Build Coastguard Worker         }
1327*77c1e3ccSAndroid Build Coastguard Worker       }
1328*77c1e3ccSAndroid Build Coastguard Worker 
1329*77c1e3ccSAndroid Build Coastguard Worker       int i = overlap && y ? 1 : 0;
1330*77c1e3ccSAndroid Build Coastguard Worker       int j = overlap && x ? 1 : 0;
1331*77c1e3ccSAndroid Build Coastguard Worker 
1332*77c1e3ccSAndroid Build Coastguard Worker       if (use_high_bit_depth) {
1333*77c1e3ccSAndroid Build Coastguard Worker         add_noise_to_block_hbd(
1334*77c1e3ccSAndroid Build Coastguard Worker             params,
1335*77c1e3ccSAndroid Build Coastguard Worker             (uint16_t *)luma + ((y + i) << 1) * luma_stride + ((x + j) << 1),
1336*77c1e3ccSAndroid Build Coastguard Worker             (uint16_t *)cb +
1337*77c1e3ccSAndroid Build Coastguard Worker                 ((y + i) << (1 - chroma_subsamp_y)) * chroma_stride +
1338*77c1e3ccSAndroid Build Coastguard Worker                 ((x + j) << (1 - chroma_subsamp_x)),
1339*77c1e3ccSAndroid Build Coastguard Worker             (uint16_t *)cr +
1340*77c1e3ccSAndroid Build Coastguard Worker                 ((y + i) << (1 - chroma_subsamp_y)) * chroma_stride +
1341*77c1e3ccSAndroid Build Coastguard Worker                 ((x + j) << (1 - chroma_subsamp_x)),
1342*77c1e3ccSAndroid Build Coastguard Worker             luma_stride, chroma_stride,
1343*77c1e3ccSAndroid Build Coastguard Worker             luma_grain_block + (luma_offset_y + (i << 1)) * luma_grain_stride +
1344*77c1e3ccSAndroid Build Coastguard Worker                 luma_offset_x + (j << 1),
1345*77c1e3ccSAndroid Build Coastguard Worker             cb_grain_block +
1346*77c1e3ccSAndroid Build Coastguard Worker                 (chroma_offset_y + (i << (1 - chroma_subsamp_y))) *
1347*77c1e3ccSAndroid Build Coastguard Worker                     chroma_grain_stride +
1348*77c1e3ccSAndroid Build Coastguard Worker                 chroma_offset_x + (j << (1 - chroma_subsamp_x)),
1349*77c1e3ccSAndroid Build Coastguard Worker             cr_grain_block +
1350*77c1e3ccSAndroid Build Coastguard Worker                 (chroma_offset_y + (i << (1 - chroma_subsamp_y))) *
1351*77c1e3ccSAndroid Build Coastguard Worker                     chroma_grain_stride +
1352*77c1e3ccSAndroid Build Coastguard Worker                 chroma_offset_x + (j << (1 - chroma_subsamp_x)),
1353*77c1e3ccSAndroid Build Coastguard Worker             luma_grain_stride, chroma_grain_stride,
1354*77c1e3ccSAndroid Build Coastguard Worker             AOMMIN(luma_subblock_size_y >> 1, height / 2 - y) - i,
1355*77c1e3ccSAndroid Build Coastguard Worker             AOMMIN(luma_subblock_size_x >> 1, width / 2 - x) - j, bit_depth,
1356*77c1e3ccSAndroid Build Coastguard Worker             chroma_subsamp_y, chroma_subsamp_x, mc_identity);
1357*77c1e3ccSAndroid Build Coastguard Worker       } else {
1358*77c1e3ccSAndroid Build Coastguard Worker         add_noise_to_block(
1359*77c1e3ccSAndroid Build Coastguard Worker             params, luma + ((y + i) << 1) * luma_stride + ((x + j) << 1),
1360*77c1e3ccSAndroid Build Coastguard Worker             cb + ((y + i) << (1 - chroma_subsamp_y)) * chroma_stride +
1361*77c1e3ccSAndroid Build Coastguard Worker                 ((x + j) << (1 - chroma_subsamp_x)),
1362*77c1e3ccSAndroid Build Coastguard Worker             cr + ((y + i) << (1 - chroma_subsamp_y)) * chroma_stride +
1363*77c1e3ccSAndroid Build Coastguard Worker                 ((x + j) << (1 - chroma_subsamp_x)),
1364*77c1e3ccSAndroid Build Coastguard Worker             luma_stride, chroma_stride,
1365*77c1e3ccSAndroid Build Coastguard Worker             luma_grain_block + (luma_offset_y + (i << 1)) * luma_grain_stride +
1366*77c1e3ccSAndroid Build Coastguard Worker                 luma_offset_x + (j << 1),
1367*77c1e3ccSAndroid Build Coastguard Worker             cb_grain_block +
1368*77c1e3ccSAndroid Build Coastguard Worker                 (chroma_offset_y + (i << (1 - chroma_subsamp_y))) *
1369*77c1e3ccSAndroid Build Coastguard Worker                     chroma_grain_stride +
1370*77c1e3ccSAndroid Build Coastguard Worker                 chroma_offset_x + (j << (1 - chroma_subsamp_x)),
1371*77c1e3ccSAndroid Build Coastguard Worker             cr_grain_block +
1372*77c1e3ccSAndroid Build Coastguard Worker                 (chroma_offset_y + (i << (1 - chroma_subsamp_y))) *
1373*77c1e3ccSAndroid Build Coastguard Worker                     chroma_grain_stride +
1374*77c1e3ccSAndroid Build Coastguard Worker                 chroma_offset_x + (j << (1 - chroma_subsamp_x)),
1375*77c1e3ccSAndroid Build Coastguard Worker             luma_grain_stride, chroma_grain_stride,
1376*77c1e3ccSAndroid Build Coastguard Worker             AOMMIN(luma_subblock_size_y >> 1, height / 2 - y) - i,
1377*77c1e3ccSAndroid Build Coastguard Worker             AOMMIN(luma_subblock_size_x >> 1, width / 2 - x) - j, bit_depth,
1378*77c1e3ccSAndroid Build Coastguard Worker             chroma_subsamp_y, chroma_subsamp_x, mc_identity);
1379*77c1e3ccSAndroid Build Coastguard Worker       }
1380*77c1e3ccSAndroid Build Coastguard Worker 
1381*77c1e3ccSAndroid Build Coastguard Worker       if (overlap) {
1382*77c1e3ccSAndroid Build Coastguard Worker         if (x) {
1383*77c1e3ccSAndroid Build Coastguard Worker           // Copy overlapped column bufer to line buffer
1384*77c1e3ccSAndroid Build Coastguard Worker           copy_area(y_col_buf + (luma_subblock_size_y << 1), 2,
1385*77c1e3ccSAndroid Build Coastguard Worker                     y_line_buf + (x << 1), luma_stride, 2, 2);
1386*77c1e3ccSAndroid Build Coastguard Worker 
1387*77c1e3ccSAndroid Build Coastguard Worker           copy_area(
1388*77c1e3ccSAndroid Build Coastguard Worker               cb_col_buf + (chroma_subblock_size_y << (1 - chroma_subsamp_x)),
1389*77c1e3ccSAndroid Build Coastguard Worker               2 >> chroma_subsamp_x,
1390*77c1e3ccSAndroid Build Coastguard Worker               cb_line_buf + (x << (1 - chroma_subsamp_x)), chroma_stride,
1391*77c1e3ccSAndroid Build Coastguard Worker               2 >> chroma_subsamp_x, 2 >> chroma_subsamp_y);
1392*77c1e3ccSAndroid Build Coastguard Worker 
1393*77c1e3ccSAndroid Build Coastguard Worker           copy_area(
1394*77c1e3ccSAndroid Build Coastguard Worker               cr_col_buf + (chroma_subblock_size_y << (1 - chroma_subsamp_x)),
1395*77c1e3ccSAndroid Build Coastguard Worker               2 >> chroma_subsamp_x,
1396*77c1e3ccSAndroid Build Coastguard Worker               cr_line_buf + (x << (1 - chroma_subsamp_x)), chroma_stride,
1397*77c1e3ccSAndroid Build Coastguard Worker               2 >> chroma_subsamp_x, 2 >> chroma_subsamp_y);
1398*77c1e3ccSAndroid Build Coastguard Worker         }
1399*77c1e3ccSAndroid Build Coastguard Worker 
1400*77c1e3ccSAndroid Build Coastguard Worker         // Copy grain to the line buffer for overlap with a bottom block
1401*77c1e3ccSAndroid Build Coastguard Worker         copy_area(
1402*77c1e3ccSAndroid Build Coastguard Worker             luma_grain_block +
1403*77c1e3ccSAndroid Build Coastguard Worker                 (luma_offset_y + luma_subblock_size_y) * luma_grain_stride +
1404*77c1e3ccSAndroid Build Coastguard Worker                 luma_offset_x + ((x ? 2 : 0)),
1405*77c1e3ccSAndroid Build Coastguard Worker             luma_grain_stride, y_line_buf + ((x ? x + 1 : 0) << 1), luma_stride,
1406*77c1e3ccSAndroid Build Coastguard Worker             AOMMIN(luma_subblock_size_x, width - (x << 1)) - (x ? 2 : 0), 2);
1407*77c1e3ccSAndroid Build Coastguard Worker 
1408*77c1e3ccSAndroid Build Coastguard Worker         copy_area(cb_grain_block +
1409*77c1e3ccSAndroid Build Coastguard Worker                       (chroma_offset_y + chroma_subblock_size_y) *
1410*77c1e3ccSAndroid Build Coastguard Worker                           chroma_grain_stride +
1411*77c1e3ccSAndroid Build Coastguard Worker                       chroma_offset_x + (x ? 2 >> chroma_subsamp_x : 0),
1412*77c1e3ccSAndroid Build Coastguard Worker                   chroma_grain_stride,
1413*77c1e3ccSAndroid Build Coastguard Worker                   cb_line_buf + ((x ? x + 1 : 0) << (1 - chroma_subsamp_x)),
1414*77c1e3ccSAndroid Build Coastguard Worker                   chroma_stride,
1415*77c1e3ccSAndroid Build Coastguard Worker                   AOMMIN(chroma_subblock_size_x,
1416*77c1e3ccSAndroid Build Coastguard Worker                          ((width - (x << 1)) >> chroma_subsamp_x)) -
1417*77c1e3ccSAndroid Build Coastguard Worker                       (x ? 2 >> chroma_subsamp_x : 0),
1418*77c1e3ccSAndroid Build Coastguard Worker                   2 >> chroma_subsamp_y);
1419*77c1e3ccSAndroid Build Coastguard Worker 
1420*77c1e3ccSAndroid Build Coastguard Worker         copy_area(cr_grain_block +
1421*77c1e3ccSAndroid Build Coastguard Worker                       (chroma_offset_y + chroma_subblock_size_y) *
1422*77c1e3ccSAndroid Build Coastguard Worker                           chroma_grain_stride +
1423*77c1e3ccSAndroid Build Coastguard Worker                       chroma_offset_x + (x ? 2 >> chroma_subsamp_x : 0),
1424*77c1e3ccSAndroid Build Coastguard Worker                   chroma_grain_stride,
1425*77c1e3ccSAndroid Build Coastguard Worker                   cr_line_buf + ((x ? x + 1 : 0) << (1 - chroma_subsamp_x)),
1426*77c1e3ccSAndroid Build Coastguard Worker                   chroma_stride,
1427*77c1e3ccSAndroid Build Coastguard Worker                   AOMMIN(chroma_subblock_size_x,
1428*77c1e3ccSAndroid Build Coastguard Worker                          ((width - (x << 1)) >> chroma_subsamp_x)) -
1429*77c1e3ccSAndroid Build Coastguard Worker                       (x ? 2 >> chroma_subsamp_x : 0),
1430*77c1e3ccSAndroid Build Coastguard Worker                   2 >> chroma_subsamp_y);
1431*77c1e3ccSAndroid Build Coastguard Worker 
1432*77c1e3ccSAndroid Build Coastguard Worker         // Copy grain to the column buffer for overlap with the next block to
1433*77c1e3ccSAndroid Build Coastguard Worker         // the right
1434*77c1e3ccSAndroid Build Coastguard Worker 
1435*77c1e3ccSAndroid Build Coastguard Worker         copy_area(luma_grain_block + luma_offset_y * luma_grain_stride +
1436*77c1e3ccSAndroid Build Coastguard Worker                       luma_offset_x + luma_subblock_size_x,
1437*77c1e3ccSAndroid Build Coastguard Worker                   luma_grain_stride, y_col_buf, 2, 2,
1438*77c1e3ccSAndroid Build Coastguard Worker                   AOMMIN(luma_subblock_size_y + 2, height - (y << 1)));
1439*77c1e3ccSAndroid Build Coastguard Worker 
1440*77c1e3ccSAndroid Build Coastguard Worker         copy_area(cb_grain_block + chroma_offset_y * chroma_grain_stride +
1441*77c1e3ccSAndroid Build Coastguard Worker                       chroma_offset_x + chroma_subblock_size_x,
1442*77c1e3ccSAndroid Build Coastguard Worker                   chroma_grain_stride, cb_col_buf, 2 >> chroma_subsamp_x,
1443*77c1e3ccSAndroid Build Coastguard Worker                   2 >> chroma_subsamp_x,
1444*77c1e3ccSAndroid Build Coastguard Worker                   AOMMIN(chroma_subblock_size_y + (2 >> chroma_subsamp_y),
1445*77c1e3ccSAndroid Build Coastguard Worker                          (height - (y << 1)) >> chroma_subsamp_y));
1446*77c1e3ccSAndroid Build Coastguard Worker 
1447*77c1e3ccSAndroid Build Coastguard Worker         copy_area(cr_grain_block + chroma_offset_y * chroma_grain_stride +
1448*77c1e3ccSAndroid Build Coastguard Worker                       chroma_offset_x + chroma_subblock_size_x,
1449*77c1e3ccSAndroid Build Coastguard Worker                   chroma_grain_stride, cr_col_buf, 2 >> chroma_subsamp_x,
1450*77c1e3ccSAndroid Build Coastguard Worker                   2 >> chroma_subsamp_x,
1451*77c1e3ccSAndroid Build Coastguard Worker                   AOMMIN(chroma_subblock_size_y + (2 >> chroma_subsamp_y),
1452*77c1e3ccSAndroid Build Coastguard Worker                          (height - (y << 1)) >> chroma_subsamp_y));
1453*77c1e3ccSAndroid Build Coastguard Worker       }
1454*77c1e3ccSAndroid Build Coastguard Worker     }
1455*77c1e3ccSAndroid Build Coastguard Worker   }
1456*77c1e3ccSAndroid Build Coastguard Worker 
1457*77c1e3ccSAndroid Build Coastguard Worker   dealloc_arrays(params, &pred_pos_luma, &pred_pos_chroma, &luma_grain_block,
1458*77c1e3ccSAndroid Build Coastguard Worker                  &cb_grain_block, &cr_grain_block, &y_line_buf, &cb_line_buf,
1459*77c1e3ccSAndroid Build Coastguard Worker                  &cr_line_buf, &y_col_buf, &cb_col_buf, &cr_col_buf);
1460*77c1e3ccSAndroid Build Coastguard Worker   return 0;
1461*77c1e3ccSAndroid Build Coastguard Worker }
1462