xref: /aosp_15_r20/external/angle/src/image_util/loadimage_etc.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2013 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker // loadimage_etc.cpp: Decodes ETC and EAC encoded textures.
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "image_util/loadimage.h"
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker #include <type_traits>
12*8975f5c5SAndroid Build Coastguard Worker #include "common/mathutil.h"
13*8975f5c5SAndroid Build Coastguard Worker 
14*8975f5c5SAndroid Build Coastguard Worker #include "image_util/imageformats.h"
15*8975f5c5SAndroid Build Coastguard Worker 
16*8975f5c5SAndroid Build Coastguard Worker namespace angle
17*8975f5c5SAndroid Build Coastguard Worker {
18*8975f5c5SAndroid Build Coastguard Worker namespace
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker 
21*8975f5c5SAndroid Build Coastguard Worker using IntensityModifier = const int[4];
22*8975f5c5SAndroid Build Coastguard Worker 
23*8975f5c5SAndroid Build Coastguard Worker // Table 3.17.2 sorted according to table 3.17.3
24*8975f5c5SAndroid Build Coastguard Worker // clang-format off
25*8975f5c5SAndroid Build Coastguard Worker static IntensityModifier intensityModifierDefault[] =
26*8975f5c5SAndroid Build Coastguard Worker {
27*8975f5c5SAndroid Build Coastguard Worker     {  2,   8,  -2,   -8 },
28*8975f5c5SAndroid Build Coastguard Worker     {  5,  17,  -5,  -17 },
29*8975f5c5SAndroid Build Coastguard Worker     {  9,  29,  -9,  -29 },
30*8975f5c5SAndroid Build Coastguard Worker     { 13,  42, -13,  -42 },
31*8975f5c5SAndroid Build Coastguard Worker     { 18,  60, -18,  -60 },
32*8975f5c5SAndroid Build Coastguard Worker     { 24,  80, -24,  -80 },
33*8975f5c5SAndroid Build Coastguard Worker     { 33, 106, -33, -106 },
34*8975f5c5SAndroid Build Coastguard Worker     { 47, 183, -47, -183 },
35*8975f5c5SAndroid Build Coastguard Worker };
36*8975f5c5SAndroid Build Coastguard Worker // clang-format on
37*8975f5c5SAndroid Build Coastguard Worker 
38*8975f5c5SAndroid Build Coastguard Worker // Table C.12, intensity modifier for non opaque punchthrough alpha
39*8975f5c5SAndroid Build Coastguard Worker // clang-format off
40*8975f5c5SAndroid Build Coastguard Worker static IntensityModifier intensityModifierNonOpaque[] =
41*8975f5c5SAndroid Build Coastguard Worker {
42*8975f5c5SAndroid Build Coastguard Worker     { 0,   8, 0,   -8 },
43*8975f5c5SAndroid Build Coastguard Worker     { 0,  17, 0,  -17 },
44*8975f5c5SAndroid Build Coastguard Worker     { 0,  29, 0,  -29 },
45*8975f5c5SAndroid Build Coastguard Worker     { 0,  42, 0,  -42 },
46*8975f5c5SAndroid Build Coastguard Worker     { 0,  60, 0,  -60 },
47*8975f5c5SAndroid Build Coastguard Worker     { 0,  80, 0,  -80 },
48*8975f5c5SAndroid Build Coastguard Worker     { 0, 106, 0, -106 },
49*8975f5c5SAndroid Build Coastguard Worker     { 0, 183, 0, -183 },
50*8975f5c5SAndroid Build Coastguard Worker };
51*8975f5c5SAndroid Build Coastguard Worker // clang-format on
52*8975f5c5SAndroid Build Coastguard Worker 
53*8975f5c5SAndroid Build Coastguard Worker static const int kNumPixelsInBlock = 16;
54*8975f5c5SAndroid Build Coastguard Worker 
55*8975f5c5SAndroid Build Coastguard Worker struct ETC2Block
56*8975f5c5SAndroid Build Coastguard Worker {
57*8975f5c5SAndroid Build Coastguard Worker     // Decodes unsigned single or dual channel ETC2 block to 8-bit color
decodeAsSingleETC2Channelangle::__anon4a5303920111::ETC2Block58*8975f5c5SAndroid Build Coastguard Worker     void decodeAsSingleETC2Channel(uint8_t *dest,
59*8975f5c5SAndroid Build Coastguard Worker                                    size_t x,
60*8975f5c5SAndroid Build Coastguard Worker                                    size_t y,
61*8975f5c5SAndroid Build Coastguard Worker                                    size_t w,
62*8975f5c5SAndroid Build Coastguard Worker                                    size_t h,
63*8975f5c5SAndroid Build Coastguard Worker                                    size_t destPixelStride,
64*8975f5c5SAndroid Build Coastguard Worker                                    size_t destRowPitch,
65*8975f5c5SAndroid Build Coastguard Worker                                    bool isSigned) const
66*8975f5c5SAndroid Build Coastguard Worker     {
67*8975f5c5SAndroid Build Coastguard Worker         for (size_t j = 0; j < 4 && (y + j) < h; j++)
68*8975f5c5SAndroid Build Coastguard Worker         {
69*8975f5c5SAndroid Build Coastguard Worker             uint8_t *row = dest + (j * destRowPitch);
70*8975f5c5SAndroid Build Coastguard Worker             for (size_t i = 0; i < 4 && (x + i) < w; i++)
71*8975f5c5SAndroid Build Coastguard Worker             {
72*8975f5c5SAndroid Build Coastguard Worker                 uint8_t *pixel = row + (i * destPixelStride);
73*8975f5c5SAndroid Build Coastguard Worker                 if (isSigned)
74*8975f5c5SAndroid Build Coastguard Worker                 {
75*8975f5c5SAndroid Build Coastguard Worker                     *pixel = clampSByte(getSingleETC2Channel(i, j, isSigned));
76*8975f5c5SAndroid Build Coastguard Worker                 }
77*8975f5c5SAndroid Build Coastguard Worker                 else
78*8975f5c5SAndroid Build Coastguard Worker                 {
79*8975f5c5SAndroid Build Coastguard Worker                     *pixel = clampByte(getSingleETC2Channel(i, j, isSigned));
80*8975f5c5SAndroid Build Coastguard Worker                 }
81*8975f5c5SAndroid Build Coastguard Worker             }
82*8975f5c5SAndroid Build Coastguard Worker         }
83*8975f5c5SAndroid Build Coastguard Worker     }
84*8975f5c5SAndroid Build Coastguard Worker 
85*8975f5c5SAndroid Build Coastguard Worker     // Transcodes  block to BC4
86*8975f5c5SAndroid Build Coastguard Worker     // For simplicity, R11 alpha use the same formula as Alpha8 to decode,
87*8975f5c5SAndroid Build Coastguard Worker     // the result R8 may have some precision issue like multiplier == 0 case.
transcodeAsBC4angle::__anon4a5303920111::ETC2Block88*8975f5c5SAndroid Build Coastguard Worker     void transcodeAsBC4(uint8_t *dest, size_t x, size_t y, size_t w, size_t h, bool isSigned) const
89*8975f5c5SAndroid Build Coastguard Worker     {
90*8975f5c5SAndroid Build Coastguard Worker         static constexpr int kIndexMap[] = {1, 7, 6, 5, 4, 3, 2, 0};
91*8975f5c5SAndroid Build Coastguard Worker         int alpha[16];
92*8975f5c5SAndroid Build Coastguard Worker         size_t k     = 0;
93*8975f5c5SAndroid Build Coastguard Worker         int minAlpha = std::numeric_limits<int>::max();
94*8975f5c5SAndroid Build Coastguard Worker         int maxAlpha = std::numeric_limits<int>::min();
95*8975f5c5SAndroid Build Coastguard Worker         for (size_t j = 0; j < 4; j++)
96*8975f5c5SAndroid Build Coastguard Worker         {
97*8975f5c5SAndroid Build Coastguard Worker             for (size_t i = 0; i < 4; i++)
98*8975f5c5SAndroid Build Coastguard Worker             {
99*8975f5c5SAndroid Build Coastguard Worker                 if (isSigned)
100*8975f5c5SAndroid Build Coastguard Worker                 {
101*8975f5c5SAndroid Build Coastguard Worker                     alpha[k] = clampSByte(getSingleETC2Channel(i, j, isSigned));
102*8975f5c5SAndroid Build Coastguard Worker                 }
103*8975f5c5SAndroid Build Coastguard Worker                 else
104*8975f5c5SAndroid Build Coastguard Worker                 {
105*8975f5c5SAndroid Build Coastguard Worker                     alpha[k] = clampByte(getSingleETC2Channel(i, j, isSigned));
106*8975f5c5SAndroid Build Coastguard Worker                 }
107*8975f5c5SAndroid Build Coastguard Worker                 minAlpha = std::min(minAlpha, alpha[k]);
108*8975f5c5SAndroid Build Coastguard Worker                 maxAlpha = std::max(maxAlpha, alpha[k]);
109*8975f5c5SAndroid Build Coastguard Worker                 k++;
110*8975f5c5SAndroid Build Coastguard Worker             }
111*8975f5c5SAndroid Build Coastguard Worker         }
112*8975f5c5SAndroid Build Coastguard Worker         uint64_t *result = (uint64_t *)dest;
113*8975f5c5SAndroid Build Coastguard Worker         *result          = (maxAlpha & 0xff) | ((minAlpha & 0xff) << 8);
114*8975f5c5SAndroid Build Coastguard Worker         if (minAlpha != maxAlpha)
115*8975f5c5SAndroid Build Coastguard Worker         {
116*8975f5c5SAndroid Build Coastguard Worker             float dist = static_cast<float>(maxAlpha - minAlpha);
117*8975f5c5SAndroid Build Coastguard Worker             for (size_t i = 0; i < 16; i++)
118*8975f5c5SAndroid Build Coastguard Worker             {
119*8975f5c5SAndroid Build Coastguard Worker                 int ind = int(roundf((alpha[i] - minAlpha) / dist * 7.0f));
120*8975f5c5SAndroid Build Coastguard Worker                 // 0 : maxAlpha
121*8975f5c5SAndroid Build Coastguard Worker                 // 1 : minAlpha
122*8975f5c5SAndroid Build Coastguard Worker                 // 2 : 6/7*maxAlpha + 1/7*minAlpha;
123*8975f5c5SAndroid Build Coastguard Worker                 // 3 : 5/7*maxAlpha + 2/7*minAlpha;
124*8975f5c5SAndroid Build Coastguard Worker                 // 4 : 4/7*maxAlpha + 3/7*minAlpha;
125*8975f5c5SAndroid Build Coastguard Worker                 // 5 : 3/7*maxAlpha + 4/7*minAlpha;
126*8975f5c5SAndroid Build Coastguard Worker                 // 6 : 2/7*maxAlpha + 5/7*minAlpha;
127*8975f5c5SAndroid Build Coastguard Worker                 // 7 : 1/7*maxAlpha + 6/7*minAlpha;
128*8975f5c5SAndroid Build Coastguard Worker                 // so the mapping is
129*8975f5c5SAndroid Build Coastguard Worker                 // 0 -> 1
130*8975f5c5SAndroid Build Coastguard Worker                 // 1 -> 7
131*8975f5c5SAndroid Build Coastguard Worker                 // 2 -> 6
132*8975f5c5SAndroid Build Coastguard Worker                 // 3 -> 5
133*8975f5c5SAndroid Build Coastguard Worker                 // 4 -> 4
134*8975f5c5SAndroid Build Coastguard Worker                 // 5 -> 3
135*8975f5c5SAndroid Build Coastguard Worker                 // 6 -> 2
136*8975f5c5SAndroid Build Coastguard Worker                 // 7 -> 0
137*8975f5c5SAndroid Build Coastguard Worker                 *result |= ((uint64_t)kIndexMap[ind]) << ((3 * i) + 16);
138*8975f5c5SAndroid Build Coastguard Worker             }
139*8975f5c5SAndroid Build Coastguard Worker         }
140*8975f5c5SAndroid Build Coastguard Worker     }
141*8975f5c5SAndroid Build Coastguard Worker 
142*8975f5c5SAndroid Build Coastguard Worker     // Decodes unsigned single or dual channel EAC block to 16-bit color
decodeAsSingleEACChannelangle::__anon4a5303920111::ETC2Block143*8975f5c5SAndroid Build Coastguard Worker     void decodeAsSingleEACChannel(uint16_t *dest,
144*8975f5c5SAndroid Build Coastguard Worker                                   size_t x,
145*8975f5c5SAndroid Build Coastguard Worker                                   size_t y,
146*8975f5c5SAndroid Build Coastguard Worker                                   size_t w,
147*8975f5c5SAndroid Build Coastguard Worker                                   size_t h,
148*8975f5c5SAndroid Build Coastguard Worker                                   size_t destPixelStride,
149*8975f5c5SAndroid Build Coastguard Worker                                   size_t destRowPitch,
150*8975f5c5SAndroid Build Coastguard Worker                                   bool isSigned,
151*8975f5c5SAndroid Build Coastguard Worker                                   bool isFloat) const
152*8975f5c5SAndroid Build Coastguard Worker     {
153*8975f5c5SAndroid Build Coastguard Worker         for (size_t j = 0; j < 4 && (y + j) < h; j++)
154*8975f5c5SAndroid Build Coastguard Worker         {
155*8975f5c5SAndroid Build Coastguard Worker             uint16_t *row = reinterpret_cast<uint16_t *>(reinterpret_cast<uint8_t *>(dest) +
156*8975f5c5SAndroid Build Coastguard Worker                                                          (j * destRowPitch));
157*8975f5c5SAndroid Build Coastguard Worker             for (size_t i = 0; i < 4 && (x + i) < w; i++)
158*8975f5c5SAndroid Build Coastguard Worker             {
159*8975f5c5SAndroid Build Coastguard Worker                 uint16_t *pixel = row + (i * destPixelStride);
160*8975f5c5SAndroid Build Coastguard Worker                 if (isSigned)
161*8975f5c5SAndroid Build Coastguard Worker                 {
162*8975f5c5SAndroid Build Coastguard Worker                     int16_t tempPixel =
163*8975f5c5SAndroid Build Coastguard Worker                         renormalizeEAC<int16_t>(getSingleEACChannel(i, j, isSigned));
164*8975f5c5SAndroid Build Coastguard Worker                     *pixel =
165*8975f5c5SAndroid Build Coastguard Worker                         isFloat ? gl::float32ToFloat16(float(gl::normalize(tempPixel))) : tempPixel;
166*8975f5c5SAndroid Build Coastguard Worker                 }
167*8975f5c5SAndroid Build Coastguard Worker                 else
168*8975f5c5SAndroid Build Coastguard Worker                 {
169*8975f5c5SAndroid Build Coastguard Worker                     uint16_t tempPixel =
170*8975f5c5SAndroid Build Coastguard Worker                         renormalizeEAC<uint16_t>(getSingleEACChannel(i, j, isSigned));
171*8975f5c5SAndroid Build Coastguard Worker                     *pixel =
172*8975f5c5SAndroid Build Coastguard Worker                         isFloat ? gl::float32ToFloat16(float(gl::normalize(tempPixel))) : tempPixel;
173*8975f5c5SAndroid Build Coastguard Worker                 }
174*8975f5c5SAndroid Build Coastguard Worker             }
175*8975f5c5SAndroid Build Coastguard Worker         }
176*8975f5c5SAndroid Build Coastguard Worker     }
177*8975f5c5SAndroid Build Coastguard Worker 
178*8975f5c5SAndroid Build Coastguard Worker     // Decodes RGB block to rgba8
decodeAsRGBangle::__anon4a5303920111::ETC2Block179*8975f5c5SAndroid Build Coastguard Worker     void decodeAsRGB(uint8_t *dest,
180*8975f5c5SAndroid Build Coastguard Worker                      size_t x,
181*8975f5c5SAndroid Build Coastguard Worker                      size_t y,
182*8975f5c5SAndroid Build Coastguard Worker                      size_t w,
183*8975f5c5SAndroid Build Coastguard Worker                      size_t h,
184*8975f5c5SAndroid Build Coastguard Worker                      size_t destRowPitch,
185*8975f5c5SAndroid Build Coastguard Worker                      const uint8_t alphaValues[4][4],
186*8975f5c5SAndroid Build Coastguard Worker                      bool punchThroughAlpha) const
187*8975f5c5SAndroid Build Coastguard Worker     {
188*8975f5c5SAndroid Build Coastguard Worker         bool opaqueBit                  = u.idht.mode.idm.diffbit;
189*8975f5c5SAndroid Build Coastguard Worker         bool nonOpaquePunchThroughAlpha = punchThroughAlpha && !opaqueBit;
190*8975f5c5SAndroid Build Coastguard Worker         // Select mode
191*8975f5c5SAndroid Build Coastguard Worker         if (u.idht.mode.idm.diffbit || punchThroughAlpha)
192*8975f5c5SAndroid Build Coastguard Worker         {
193*8975f5c5SAndroid Build Coastguard Worker             const auto &block = u.idht.mode.idm.colors.diff;
194*8975f5c5SAndroid Build Coastguard Worker             int r             = (block.R + block.dR);
195*8975f5c5SAndroid Build Coastguard Worker             int g             = (block.G + block.dG);
196*8975f5c5SAndroid Build Coastguard Worker             int b             = (block.B + block.dB);
197*8975f5c5SAndroid Build Coastguard Worker             if (r < 0 || r > 31)
198*8975f5c5SAndroid Build Coastguard Worker             {
199*8975f5c5SAndroid Build Coastguard Worker                 decodeTBlock(dest, x, y, w, h, destRowPitch, alphaValues,
200*8975f5c5SAndroid Build Coastguard Worker                              nonOpaquePunchThroughAlpha);
201*8975f5c5SAndroid Build Coastguard Worker             }
202*8975f5c5SAndroid Build Coastguard Worker             else if (g < 0 || g > 31)
203*8975f5c5SAndroid Build Coastguard Worker             {
204*8975f5c5SAndroid Build Coastguard Worker                 decodeHBlock(dest, x, y, w, h, destRowPitch, alphaValues,
205*8975f5c5SAndroid Build Coastguard Worker                              nonOpaquePunchThroughAlpha);
206*8975f5c5SAndroid Build Coastguard Worker             }
207*8975f5c5SAndroid Build Coastguard Worker             else if (b < 0 || b > 31)
208*8975f5c5SAndroid Build Coastguard Worker             {
209*8975f5c5SAndroid Build Coastguard Worker                 decodePlanarBlock(dest, x, y, w, h, destRowPitch, alphaValues);
210*8975f5c5SAndroid Build Coastguard Worker             }
211*8975f5c5SAndroid Build Coastguard Worker             else
212*8975f5c5SAndroid Build Coastguard Worker             {
213*8975f5c5SAndroid Build Coastguard Worker                 decodeDifferentialBlock(dest, x, y, w, h, destRowPitch, alphaValues,
214*8975f5c5SAndroid Build Coastguard Worker                                         nonOpaquePunchThroughAlpha);
215*8975f5c5SAndroid Build Coastguard Worker             }
216*8975f5c5SAndroid Build Coastguard Worker         }
217*8975f5c5SAndroid Build Coastguard Worker         else
218*8975f5c5SAndroid Build Coastguard Worker         {
219*8975f5c5SAndroid Build Coastguard Worker             decodeIndividualBlock(dest, x, y, w, h, destRowPitch, alphaValues,
220*8975f5c5SAndroid Build Coastguard Worker                                   nonOpaquePunchThroughAlpha);
221*8975f5c5SAndroid Build Coastguard Worker         }
222*8975f5c5SAndroid Build Coastguard Worker     }
223*8975f5c5SAndroid Build Coastguard Worker 
224*8975f5c5SAndroid Build Coastguard Worker     // Transcodes RGB block to BC1
transcodeAsBC1angle::__anon4a5303920111::ETC2Block225*8975f5c5SAndroid Build Coastguard Worker     void transcodeAsBC1(uint8_t *dest,
226*8975f5c5SAndroid Build Coastguard Worker                         size_t x,
227*8975f5c5SAndroid Build Coastguard Worker                         size_t y,
228*8975f5c5SAndroid Build Coastguard Worker                         size_t w,
229*8975f5c5SAndroid Build Coastguard Worker                         size_t h,
230*8975f5c5SAndroid Build Coastguard Worker                         const uint8_t alphaValues[4][4],
231*8975f5c5SAndroid Build Coastguard Worker                         bool punchThroughAlpha) const
232*8975f5c5SAndroid Build Coastguard Worker     {
233*8975f5c5SAndroid Build Coastguard Worker         bool opaqueBit                  = u.idht.mode.idm.diffbit;
234*8975f5c5SAndroid Build Coastguard Worker         bool nonOpaquePunchThroughAlpha = punchThroughAlpha && !opaqueBit;
235*8975f5c5SAndroid Build Coastguard Worker         // Select mode
236*8975f5c5SAndroid Build Coastguard Worker         if (u.idht.mode.idm.diffbit || punchThroughAlpha)
237*8975f5c5SAndroid Build Coastguard Worker         {
238*8975f5c5SAndroid Build Coastguard Worker             const auto &block = u.idht.mode.idm.colors.diff;
239*8975f5c5SAndroid Build Coastguard Worker             int r             = (block.R + block.dR);
240*8975f5c5SAndroid Build Coastguard Worker             int g             = (block.G + block.dG);
241*8975f5c5SAndroid Build Coastguard Worker             int b             = (block.B + block.dB);
242*8975f5c5SAndroid Build Coastguard Worker             if (r < 0 || r > 31)
243*8975f5c5SAndroid Build Coastguard Worker             {
244*8975f5c5SAndroid Build Coastguard Worker                 transcodeTBlockToBC1(dest, x, y, w, h, alphaValues, nonOpaquePunchThroughAlpha);
245*8975f5c5SAndroid Build Coastguard Worker             }
246*8975f5c5SAndroid Build Coastguard Worker             else if (g < 0 || g > 31)
247*8975f5c5SAndroid Build Coastguard Worker             {
248*8975f5c5SAndroid Build Coastguard Worker                 transcodeHBlockToBC1(dest, x, y, w, h, alphaValues, nonOpaquePunchThroughAlpha);
249*8975f5c5SAndroid Build Coastguard Worker             }
250*8975f5c5SAndroid Build Coastguard Worker             else if (b < 0 || b > 31)
251*8975f5c5SAndroid Build Coastguard Worker             {
252*8975f5c5SAndroid Build Coastguard Worker                 transcodePlanarBlockToBC1(dest, x, y, w, h, alphaValues);
253*8975f5c5SAndroid Build Coastguard Worker             }
254*8975f5c5SAndroid Build Coastguard Worker             else
255*8975f5c5SAndroid Build Coastguard Worker             {
256*8975f5c5SAndroid Build Coastguard Worker                 transcodeDifferentialBlockToBC1(dest, x, y, w, h, alphaValues,
257*8975f5c5SAndroid Build Coastguard Worker                                                 nonOpaquePunchThroughAlpha);
258*8975f5c5SAndroid Build Coastguard Worker             }
259*8975f5c5SAndroid Build Coastguard Worker         }
260*8975f5c5SAndroid Build Coastguard Worker         else
261*8975f5c5SAndroid Build Coastguard Worker         {
262*8975f5c5SAndroid Build Coastguard Worker             transcodeIndividualBlockToBC1(dest, x, y, w, h, alphaValues,
263*8975f5c5SAndroid Build Coastguard Worker                                           nonOpaquePunchThroughAlpha);
264*8975f5c5SAndroid Build Coastguard Worker         }
265*8975f5c5SAndroid Build Coastguard Worker     }
266*8975f5c5SAndroid Build Coastguard Worker 
267*8975f5c5SAndroid Build Coastguard Worker   private:
268*8975f5c5SAndroid Build Coastguard Worker     union
269*8975f5c5SAndroid Build Coastguard Worker     {
270*8975f5c5SAndroid Build Coastguard Worker         // Individual, differential, H and T modes
271*8975f5c5SAndroid Build Coastguard Worker         struct
272*8975f5c5SAndroid Build Coastguard Worker         {
273*8975f5c5SAndroid Build Coastguard Worker             union
274*8975f5c5SAndroid Build Coastguard Worker             {
275*8975f5c5SAndroid Build Coastguard Worker                 // Individual and differential modes
276*8975f5c5SAndroid Build Coastguard Worker                 struct
277*8975f5c5SAndroid Build Coastguard Worker                 {
278*8975f5c5SAndroid Build Coastguard Worker                     union
279*8975f5c5SAndroid Build Coastguard Worker                     {
280*8975f5c5SAndroid Build Coastguard Worker                         struct  // Individual colors
281*8975f5c5SAndroid Build Coastguard Worker                         {
282*8975f5c5SAndroid Build Coastguard Worker                             unsigned char R2 : 4;
283*8975f5c5SAndroid Build Coastguard Worker                             unsigned char R1 : 4;
284*8975f5c5SAndroid Build Coastguard Worker                             unsigned char G2 : 4;
285*8975f5c5SAndroid Build Coastguard Worker                             unsigned char G1 : 4;
286*8975f5c5SAndroid Build Coastguard Worker                             unsigned char B2 : 4;
287*8975f5c5SAndroid Build Coastguard Worker                             unsigned char B1 : 4;
288*8975f5c5SAndroid Build Coastguard Worker                         } indiv;
289*8975f5c5SAndroid Build Coastguard Worker                         struct  // Differential colors
290*8975f5c5SAndroid Build Coastguard Worker                         {
291*8975f5c5SAndroid Build Coastguard Worker                             signed char dR : 3;
292*8975f5c5SAndroid Build Coastguard Worker                             unsigned char R : 5;
293*8975f5c5SAndroid Build Coastguard Worker                             signed char dG : 3;
294*8975f5c5SAndroid Build Coastguard Worker                             unsigned char G : 5;
295*8975f5c5SAndroid Build Coastguard Worker                             signed char dB : 3;
296*8975f5c5SAndroid Build Coastguard Worker                             unsigned char B : 5;
297*8975f5c5SAndroid Build Coastguard Worker                         } diff;
298*8975f5c5SAndroid Build Coastguard Worker                     } colors;
299*8975f5c5SAndroid Build Coastguard Worker                     bool flipbit : 1;
300*8975f5c5SAndroid Build Coastguard Worker                     bool diffbit : 1;
301*8975f5c5SAndroid Build Coastguard Worker                     unsigned char cw2 : 3;
302*8975f5c5SAndroid Build Coastguard Worker                     unsigned char cw1 : 3;
303*8975f5c5SAndroid Build Coastguard Worker                 } idm;
304*8975f5c5SAndroid Build Coastguard Worker                 // T mode
305*8975f5c5SAndroid Build Coastguard Worker                 struct
306*8975f5c5SAndroid Build Coastguard Worker                 {
307*8975f5c5SAndroid Build Coastguard Worker                     // Byte 1
308*8975f5c5SAndroid Build Coastguard Worker                     unsigned char TR1b : 2;
309*8975f5c5SAndroid Build Coastguard Worker                     unsigned char TunusedB : 1;
310*8975f5c5SAndroid Build Coastguard Worker                     unsigned char TR1a : 2;
311*8975f5c5SAndroid Build Coastguard Worker                     unsigned char TunusedA : 3;
312*8975f5c5SAndroid Build Coastguard Worker                     // Byte 2
313*8975f5c5SAndroid Build Coastguard Worker                     unsigned char TB1 : 4;
314*8975f5c5SAndroid Build Coastguard Worker                     unsigned char TG1 : 4;
315*8975f5c5SAndroid Build Coastguard Worker                     // Byte 3
316*8975f5c5SAndroid Build Coastguard Worker                     unsigned char TG2 : 4;
317*8975f5c5SAndroid Build Coastguard Worker                     unsigned char TR2 : 4;
318*8975f5c5SAndroid Build Coastguard Worker                     // Byte 4
319*8975f5c5SAndroid Build Coastguard Worker                     unsigned char Tdb : 1;
320*8975f5c5SAndroid Build Coastguard Worker                     bool Tflipbit : 1;
321*8975f5c5SAndroid Build Coastguard Worker                     unsigned char Tda : 2;
322*8975f5c5SAndroid Build Coastguard Worker                     unsigned char TB2 : 4;
323*8975f5c5SAndroid Build Coastguard Worker                 } tm;
324*8975f5c5SAndroid Build Coastguard Worker                 // H mode
325*8975f5c5SAndroid Build Coastguard Worker                 struct
326*8975f5c5SAndroid Build Coastguard Worker                 {
327*8975f5c5SAndroid Build Coastguard Worker                     // Byte 1
328*8975f5c5SAndroid Build Coastguard Worker                     unsigned char HG1a : 3;
329*8975f5c5SAndroid Build Coastguard Worker                     unsigned char HR1 : 4;
330*8975f5c5SAndroid Build Coastguard Worker                     unsigned char HunusedA : 1;
331*8975f5c5SAndroid Build Coastguard Worker                     // Byte 2
332*8975f5c5SAndroid Build Coastguard Worker                     unsigned char HB1b : 2;
333*8975f5c5SAndroid Build Coastguard Worker                     unsigned char HunusedC : 1;
334*8975f5c5SAndroid Build Coastguard Worker                     unsigned char HB1a : 1;
335*8975f5c5SAndroid Build Coastguard Worker                     unsigned char HG1b : 1;
336*8975f5c5SAndroid Build Coastguard Worker                     unsigned char HunusedB : 3;
337*8975f5c5SAndroid Build Coastguard Worker                     // Byte 3
338*8975f5c5SAndroid Build Coastguard Worker                     unsigned char HG2a : 3;
339*8975f5c5SAndroid Build Coastguard Worker                     unsigned char HR2 : 4;
340*8975f5c5SAndroid Build Coastguard Worker                     unsigned char HB1c : 1;
341*8975f5c5SAndroid Build Coastguard Worker                     // Byte 4
342*8975f5c5SAndroid Build Coastguard Worker                     unsigned char Hdb : 1;
343*8975f5c5SAndroid Build Coastguard Worker                     bool Hflipbit : 1;
344*8975f5c5SAndroid Build Coastguard Worker                     unsigned char Hda : 1;
345*8975f5c5SAndroid Build Coastguard Worker                     unsigned char HB2 : 4;
346*8975f5c5SAndroid Build Coastguard Worker                     unsigned char HG2b : 1;
347*8975f5c5SAndroid Build Coastguard Worker                 } hm;
348*8975f5c5SAndroid Build Coastguard Worker             } mode;
349*8975f5c5SAndroid Build Coastguard Worker             unsigned char pixelIndexMSB[2];
350*8975f5c5SAndroid Build Coastguard Worker             unsigned char pixelIndexLSB[2];
351*8975f5c5SAndroid Build Coastguard Worker         } idht;
352*8975f5c5SAndroid Build Coastguard Worker         // planar mode
353*8975f5c5SAndroid Build Coastguard Worker         struct
354*8975f5c5SAndroid Build Coastguard Worker         {
355*8975f5c5SAndroid Build Coastguard Worker             // Byte 1
356*8975f5c5SAndroid Build Coastguard Worker             unsigned char GO1 : 1;
357*8975f5c5SAndroid Build Coastguard Worker             unsigned char RO : 6;
358*8975f5c5SAndroid Build Coastguard Worker             unsigned char PunusedA : 1;
359*8975f5c5SAndroid Build Coastguard Worker             // Byte 2
360*8975f5c5SAndroid Build Coastguard Worker             unsigned char BO1 : 1;
361*8975f5c5SAndroid Build Coastguard Worker             unsigned char GO2 : 6;
362*8975f5c5SAndroid Build Coastguard Worker             unsigned char PunusedB : 1;
363*8975f5c5SAndroid Build Coastguard Worker             // Byte 3
364*8975f5c5SAndroid Build Coastguard Worker             unsigned char BO3a : 2;
365*8975f5c5SAndroid Build Coastguard Worker             unsigned char PunusedD : 1;
366*8975f5c5SAndroid Build Coastguard Worker             unsigned char BO2 : 2;
367*8975f5c5SAndroid Build Coastguard Worker             unsigned char PunusedC : 3;
368*8975f5c5SAndroid Build Coastguard Worker             // Byte 4
369*8975f5c5SAndroid Build Coastguard Worker             unsigned char RH2 : 1;
370*8975f5c5SAndroid Build Coastguard Worker             bool Pflipbit : 1;
371*8975f5c5SAndroid Build Coastguard Worker             unsigned char RH1 : 5;
372*8975f5c5SAndroid Build Coastguard Worker             unsigned char BO3b : 1;
373*8975f5c5SAndroid Build Coastguard Worker             // Byte 5
374*8975f5c5SAndroid Build Coastguard Worker             unsigned char BHa : 1;
375*8975f5c5SAndroid Build Coastguard Worker             unsigned char GH : 7;
376*8975f5c5SAndroid Build Coastguard Worker             // Byte 6
377*8975f5c5SAndroid Build Coastguard Worker             unsigned char RVa : 3;
378*8975f5c5SAndroid Build Coastguard Worker             unsigned char BHb : 5;
379*8975f5c5SAndroid Build Coastguard Worker             // Byte 7
380*8975f5c5SAndroid Build Coastguard Worker             unsigned char GVa : 5;
381*8975f5c5SAndroid Build Coastguard Worker             unsigned char RVb : 3;
382*8975f5c5SAndroid Build Coastguard Worker             // Byte 8
383*8975f5c5SAndroid Build Coastguard Worker             unsigned char BV : 6;
384*8975f5c5SAndroid Build Coastguard Worker             unsigned char GVb : 2;
385*8975f5c5SAndroid Build Coastguard Worker         } pblk;
386*8975f5c5SAndroid Build Coastguard Worker         // Single channel block
387*8975f5c5SAndroid Build Coastguard Worker         struct
388*8975f5c5SAndroid Build Coastguard Worker         {
389*8975f5c5SAndroid Build Coastguard Worker             union
390*8975f5c5SAndroid Build Coastguard Worker             {
391*8975f5c5SAndroid Build Coastguard Worker                 unsigned char us;
392*8975f5c5SAndroid Build Coastguard Worker                 signed char s;
393*8975f5c5SAndroid Build Coastguard Worker             } base_codeword;
394*8975f5c5SAndroid Build Coastguard Worker             unsigned char table_index : 4;
395*8975f5c5SAndroid Build Coastguard Worker             unsigned char multiplier : 4;
396*8975f5c5SAndroid Build Coastguard Worker             unsigned char mc1 : 2;
397*8975f5c5SAndroid Build Coastguard Worker             unsigned char mb : 3;
398*8975f5c5SAndroid Build Coastguard Worker             unsigned char ma : 3;
399*8975f5c5SAndroid Build Coastguard Worker             unsigned char mf1 : 1;
400*8975f5c5SAndroid Build Coastguard Worker             unsigned char me : 3;
401*8975f5c5SAndroid Build Coastguard Worker             unsigned char md : 3;
402*8975f5c5SAndroid Build Coastguard Worker             unsigned char mc2 : 1;
403*8975f5c5SAndroid Build Coastguard Worker             unsigned char mh : 3;
404*8975f5c5SAndroid Build Coastguard Worker             unsigned char mg : 3;
405*8975f5c5SAndroid Build Coastguard Worker             unsigned char mf2 : 2;
406*8975f5c5SAndroid Build Coastguard Worker             unsigned char mk1 : 2;
407*8975f5c5SAndroid Build Coastguard Worker             unsigned char mj : 3;
408*8975f5c5SAndroid Build Coastguard Worker             unsigned char mi : 3;
409*8975f5c5SAndroid Build Coastguard Worker             unsigned char mn1 : 1;
410*8975f5c5SAndroid Build Coastguard Worker             unsigned char mm : 3;
411*8975f5c5SAndroid Build Coastguard Worker             unsigned char ml : 3;
412*8975f5c5SAndroid Build Coastguard Worker             unsigned char mk2 : 1;
413*8975f5c5SAndroid Build Coastguard Worker             unsigned char mp : 3;
414*8975f5c5SAndroid Build Coastguard Worker             unsigned char mo : 3;
415*8975f5c5SAndroid Build Coastguard Worker             unsigned char mn2 : 2;
416*8975f5c5SAndroid Build Coastguard Worker         } scblk;
417*8975f5c5SAndroid Build Coastguard Worker     } u;
418*8975f5c5SAndroid Build Coastguard Worker 
clampByteangle::__anon4a5303920111::ETC2Block419*8975f5c5SAndroid Build Coastguard Worker     static unsigned char clampByte(int value)
420*8975f5c5SAndroid Build Coastguard Worker     {
421*8975f5c5SAndroid Build Coastguard Worker         return static_cast<unsigned char>(gl::clamp(value, 0, 255));
422*8975f5c5SAndroid Build Coastguard Worker     }
423*8975f5c5SAndroid Build Coastguard Worker 
clampSByteangle::__anon4a5303920111::ETC2Block424*8975f5c5SAndroid Build Coastguard Worker     static signed char clampSByte(int value)
425*8975f5c5SAndroid Build Coastguard Worker     {
426*8975f5c5SAndroid Build Coastguard Worker         return static_cast<signed char>(gl::clamp(value, -128, 127));
427*8975f5c5SAndroid Build Coastguard Worker     }
428*8975f5c5SAndroid Build Coastguard Worker 
429*8975f5c5SAndroid Build Coastguard Worker     template <typename T>
renormalizeEACangle::__anon4a5303920111::ETC2Block430*8975f5c5SAndroid Build Coastguard Worker     static T renormalizeEAC(int value)
431*8975f5c5SAndroid Build Coastguard Worker     {
432*8975f5c5SAndroid Build Coastguard Worker         int upper = 0;
433*8975f5c5SAndroid Build Coastguard Worker         int lower = 0;
434*8975f5c5SAndroid Build Coastguard Worker         int shift = 0;
435*8975f5c5SAndroid Build Coastguard Worker 
436*8975f5c5SAndroid Build Coastguard Worker         if (std::is_same<T, int16_t>::value)
437*8975f5c5SAndroid Build Coastguard Worker         {
438*8975f5c5SAndroid Build Coastguard Worker             // The spec states that -1024 invalid and should be clamped to -1023
439*8975f5c5SAndroid Build Coastguard Worker             upper = 1023;
440*8975f5c5SAndroid Build Coastguard Worker             lower = -1023;
441*8975f5c5SAndroid Build Coastguard Worker             shift = 5;
442*8975f5c5SAndroid Build Coastguard Worker         }
443*8975f5c5SAndroid Build Coastguard Worker         else if (std::is_same<T, uint16_t>::value)
444*8975f5c5SAndroid Build Coastguard Worker         {
445*8975f5c5SAndroid Build Coastguard Worker             upper = 2047;
446*8975f5c5SAndroid Build Coastguard Worker             lower = 0;
447*8975f5c5SAndroid Build Coastguard Worker             shift = 5;
448*8975f5c5SAndroid Build Coastguard Worker         }
449*8975f5c5SAndroid Build Coastguard Worker         else
450*8975f5c5SAndroid Build Coastguard Worker         {
451*8975f5c5SAndroid Build Coastguard Worker             // We currently only support renormalizing int16_t or uint16_t
452*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
453*8975f5c5SAndroid Build Coastguard Worker         }
454*8975f5c5SAndroid Build Coastguard Worker 
455*8975f5c5SAndroid Build Coastguard Worker         return static_cast<T>(gl::clamp(value, lower, upper)) << shift;
456*8975f5c5SAndroid Build Coastguard Worker     }
457*8975f5c5SAndroid Build Coastguard Worker 
createRGBAangle::__anon4a5303920111::ETC2Block458*8975f5c5SAndroid Build Coastguard Worker     static R8G8B8A8 createRGBA(int red, int green, int blue, int alpha)
459*8975f5c5SAndroid Build Coastguard Worker     {
460*8975f5c5SAndroid Build Coastguard Worker         R8G8B8A8 rgba;
461*8975f5c5SAndroid Build Coastguard Worker         rgba.R = clampByte(red);
462*8975f5c5SAndroid Build Coastguard Worker         rgba.G = clampByte(green);
463*8975f5c5SAndroid Build Coastguard Worker         rgba.B = clampByte(blue);
464*8975f5c5SAndroid Build Coastguard Worker         rgba.A = clampByte(alpha);
465*8975f5c5SAndroid Build Coastguard Worker         return rgba;
466*8975f5c5SAndroid Build Coastguard Worker     }
467*8975f5c5SAndroid Build Coastguard Worker 
createRGBAangle::__anon4a5303920111::ETC2Block468*8975f5c5SAndroid Build Coastguard Worker     static R8G8B8A8 createRGBA(int red, int green, int blue)
469*8975f5c5SAndroid Build Coastguard Worker     {
470*8975f5c5SAndroid Build Coastguard Worker         return createRGBA(red, green, blue, 255);
471*8975f5c5SAndroid Build Coastguard Worker     }
472*8975f5c5SAndroid Build Coastguard Worker 
extend_4to8bitsangle::__anon4a5303920111::ETC2Block473*8975f5c5SAndroid Build Coastguard Worker     static int extend_4to8bits(int x) { return (x << 4) | x; }
extend_5to8bitsangle::__anon4a5303920111::ETC2Block474*8975f5c5SAndroid Build Coastguard Worker     static int extend_5to8bits(int x) { return (x << 3) | (x >> 2); }
extend_6to8bitsangle::__anon4a5303920111::ETC2Block475*8975f5c5SAndroid Build Coastguard Worker     static int extend_6to8bits(int x) { return (x << 2) | (x >> 4); }
extend_7to8bitsangle::__anon4a5303920111::ETC2Block476*8975f5c5SAndroid Build Coastguard Worker     static int extend_7to8bits(int x) { return (x << 1) | (x >> 6); }
477*8975f5c5SAndroid Build Coastguard Worker 
decodeIndividualBlockangle::__anon4a5303920111::ETC2Block478*8975f5c5SAndroid Build Coastguard Worker     void decodeIndividualBlock(uint8_t *dest,
479*8975f5c5SAndroid Build Coastguard Worker                                size_t x,
480*8975f5c5SAndroid Build Coastguard Worker                                size_t y,
481*8975f5c5SAndroid Build Coastguard Worker                                size_t w,
482*8975f5c5SAndroid Build Coastguard Worker                                size_t h,
483*8975f5c5SAndroid Build Coastguard Worker                                size_t destRowPitch,
484*8975f5c5SAndroid Build Coastguard Worker                                const uint8_t alphaValues[4][4],
485*8975f5c5SAndroid Build Coastguard Worker                                bool nonOpaquePunchThroughAlpha) const
486*8975f5c5SAndroid Build Coastguard Worker     {
487*8975f5c5SAndroid Build Coastguard Worker         const auto &block = u.idht.mode.idm.colors.indiv;
488*8975f5c5SAndroid Build Coastguard Worker         int r1            = extend_4to8bits(block.R1);
489*8975f5c5SAndroid Build Coastguard Worker         int g1            = extend_4to8bits(block.G1);
490*8975f5c5SAndroid Build Coastguard Worker         int b1            = extend_4to8bits(block.B1);
491*8975f5c5SAndroid Build Coastguard Worker         int r2            = extend_4to8bits(block.R2);
492*8975f5c5SAndroid Build Coastguard Worker         int g2            = extend_4to8bits(block.G2);
493*8975f5c5SAndroid Build Coastguard Worker         int b2            = extend_4to8bits(block.B2);
494*8975f5c5SAndroid Build Coastguard Worker         decodeIndividualOrDifferentialBlock(dest, x, y, w, h, destRowPitch, r1, g1, b1, r2, g2, b2,
495*8975f5c5SAndroid Build Coastguard Worker                                             alphaValues, nonOpaquePunchThroughAlpha);
496*8975f5c5SAndroid Build Coastguard Worker     }
497*8975f5c5SAndroid Build Coastguard Worker 
decodeDifferentialBlockangle::__anon4a5303920111::ETC2Block498*8975f5c5SAndroid Build Coastguard Worker     void decodeDifferentialBlock(uint8_t *dest,
499*8975f5c5SAndroid Build Coastguard Worker                                  size_t x,
500*8975f5c5SAndroid Build Coastguard Worker                                  size_t y,
501*8975f5c5SAndroid Build Coastguard Worker                                  size_t w,
502*8975f5c5SAndroid Build Coastguard Worker                                  size_t h,
503*8975f5c5SAndroid Build Coastguard Worker                                  size_t destRowPitch,
504*8975f5c5SAndroid Build Coastguard Worker                                  const uint8_t alphaValues[4][4],
505*8975f5c5SAndroid Build Coastguard Worker                                  bool nonOpaquePunchThroughAlpha) const
506*8975f5c5SAndroid Build Coastguard Worker     {
507*8975f5c5SAndroid Build Coastguard Worker         const auto &block = u.idht.mode.idm.colors.diff;
508*8975f5c5SAndroid Build Coastguard Worker         int b1            = extend_5to8bits(block.B);
509*8975f5c5SAndroid Build Coastguard Worker         int g1            = extend_5to8bits(block.G);
510*8975f5c5SAndroid Build Coastguard Worker         int r1            = extend_5to8bits(block.R);
511*8975f5c5SAndroid Build Coastguard Worker         int r2            = extend_5to8bits(block.R + block.dR);
512*8975f5c5SAndroid Build Coastguard Worker         int g2            = extend_5to8bits(block.G + block.dG);
513*8975f5c5SAndroid Build Coastguard Worker         int b2            = extend_5to8bits(block.B + block.dB);
514*8975f5c5SAndroid Build Coastguard Worker         decodeIndividualOrDifferentialBlock(dest, x, y, w, h, destRowPitch, r1, g1, b1, r2, g2, b2,
515*8975f5c5SAndroid Build Coastguard Worker                                             alphaValues, nonOpaquePunchThroughAlpha);
516*8975f5c5SAndroid Build Coastguard Worker     }
517*8975f5c5SAndroid Build Coastguard Worker 
decodeIndividualOrDifferentialBlockangle::__anon4a5303920111::ETC2Block518*8975f5c5SAndroid Build Coastguard Worker     void decodeIndividualOrDifferentialBlock(uint8_t *dest,
519*8975f5c5SAndroid Build Coastguard Worker                                              size_t x,
520*8975f5c5SAndroid Build Coastguard Worker                                              size_t y,
521*8975f5c5SAndroid Build Coastguard Worker                                              size_t w,
522*8975f5c5SAndroid Build Coastguard Worker                                              size_t h,
523*8975f5c5SAndroid Build Coastguard Worker                                              size_t destRowPitch,
524*8975f5c5SAndroid Build Coastguard Worker                                              int r1,
525*8975f5c5SAndroid Build Coastguard Worker                                              int g1,
526*8975f5c5SAndroid Build Coastguard Worker                                              int b1,
527*8975f5c5SAndroid Build Coastguard Worker                                              int r2,
528*8975f5c5SAndroid Build Coastguard Worker                                              int g2,
529*8975f5c5SAndroid Build Coastguard Worker                                              int b2,
530*8975f5c5SAndroid Build Coastguard Worker                                              const uint8_t alphaValues[4][4],
531*8975f5c5SAndroid Build Coastguard Worker                                              bool nonOpaquePunchThroughAlpha) const
532*8975f5c5SAndroid Build Coastguard Worker     {
533*8975f5c5SAndroid Build Coastguard Worker         const IntensityModifier *intensityModifier =
534*8975f5c5SAndroid Build Coastguard Worker             nonOpaquePunchThroughAlpha ? intensityModifierNonOpaque : intensityModifierDefault;
535*8975f5c5SAndroid Build Coastguard Worker 
536*8975f5c5SAndroid Build Coastguard Worker         R8G8B8A8 subblockColors0[4];
537*8975f5c5SAndroid Build Coastguard Worker         R8G8B8A8 subblockColors1[4];
538*8975f5c5SAndroid Build Coastguard Worker         for (size_t modifierIdx = 0; modifierIdx < 4; modifierIdx++)
539*8975f5c5SAndroid Build Coastguard Worker         {
540*8975f5c5SAndroid Build Coastguard Worker             const int i1                 = intensityModifier[u.idht.mode.idm.cw1][modifierIdx];
541*8975f5c5SAndroid Build Coastguard Worker             subblockColors0[modifierIdx] = createRGBA(r1 + i1, g1 + i1, b1 + i1);
542*8975f5c5SAndroid Build Coastguard Worker 
543*8975f5c5SAndroid Build Coastguard Worker             const int i2                 = intensityModifier[u.idht.mode.idm.cw2][modifierIdx];
544*8975f5c5SAndroid Build Coastguard Worker             subblockColors1[modifierIdx] = createRGBA(r2 + i2, g2 + i2, b2 + i2);
545*8975f5c5SAndroid Build Coastguard Worker         }
546*8975f5c5SAndroid Build Coastguard Worker 
547*8975f5c5SAndroid Build Coastguard Worker         if (u.idht.mode.idm.flipbit)
548*8975f5c5SAndroid Build Coastguard Worker         {
549*8975f5c5SAndroid Build Coastguard Worker             uint8_t *curPixel = dest;
550*8975f5c5SAndroid Build Coastguard Worker             for (size_t j = 0; j < 2 && (y + j) < h; j++)
551*8975f5c5SAndroid Build Coastguard Worker             {
552*8975f5c5SAndroid Build Coastguard Worker                 R8G8B8A8 *row = reinterpret_cast<R8G8B8A8 *>(curPixel);
553*8975f5c5SAndroid Build Coastguard Worker                 for (size_t i = 0; i < 4 && (x + i) < w; i++)
554*8975f5c5SAndroid Build Coastguard Worker                 {
555*8975f5c5SAndroid Build Coastguard Worker                     row[i]   = subblockColors0[getIndex(i, j)];
556*8975f5c5SAndroid Build Coastguard Worker                     row[i].A = alphaValues[j][i];
557*8975f5c5SAndroid Build Coastguard Worker                 }
558*8975f5c5SAndroid Build Coastguard Worker                 curPixel += destRowPitch;
559*8975f5c5SAndroid Build Coastguard Worker             }
560*8975f5c5SAndroid Build Coastguard Worker             for (size_t j = 2; j < 4 && (y + j) < h; j++)
561*8975f5c5SAndroid Build Coastguard Worker             {
562*8975f5c5SAndroid Build Coastguard Worker                 R8G8B8A8 *row = reinterpret_cast<R8G8B8A8 *>(curPixel);
563*8975f5c5SAndroid Build Coastguard Worker                 for (size_t i = 0; i < 4 && (x + i) < w; i++)
564*8975f5c5SAndroid Build Coastguard Worker                 {
565*8975f5c5SAndroid Build Coastguard Worker                     row[i]   = subblockColors1[getIndex(i, j)];
566*8975f5c5SAndroid Build Coastguard Worker                     row[i].A = alphaValues[j][i];
567*8975f5c5SAndroid Build Coastguard Worker                 }
568*8975f5c5SAndroid Build Coastguard Worker                 curPixel += destRowPitch;
569*8975f5c5SAndroid Build Coastguard Worker             }
570*8975f5c5SAndroid Build Coastguard Worker         }
571*8975f5c5SAndroid Build Coastguard Worker         else
572*8975f5c5SAndroid Build Coastguard Worker         {
573*8975f5c5SAndroid Build Coastguard Worker             uint8_t *curPixel = dest;
574*8975f5c5SAndroid Build Coastguard Worker             for (size_t j = 0; j < 4 && (y + j) < h; j++)
575*8975f5c5SAndroid Build Coastguard Worker             {
576*8975f5c5SAndroid Build Coastguard Worker                 R8G8B8A8 *row = reinterpret_cast<R8G8B8A8 *>(curPixel);
577*8975f5c5SAndroid Build Coastguard Worker                 for (size_t i = 0; i < 2 && (x + i) < w; i++)
578*8975f5c5SAndroid Build Coastguard Worker                 {
579*8975f5c5SAndroid Build Coastguard Worker                     row[i]   = subblockColors0[getIndex(i, j)];
580*8975f5c5SAndroid Build Coastguard Worker                     row[i].A = alphaValues[j][i];
581*8975f5c5SAndroid Build Coastguard Worker                 }
582*8975f5c5SAndroid Build Coastguard Worker                 for (size_t i = 2; i < 4 && (x + i) < w; i++)
583*8975f5c5SAndroid Build Coastguard Worker                 {
584*8975f5c5SAndroid Build Coastguard Worker                     row[i]   = subblockColors1[getIndex(i, j)];
585*8975f5c5SAndroid Build Coastguard Worker                     row[i].A = alphaValues[j][i];
586*8975f5c5SAndroid Build Coastguard Worker                 }
587*8975f5c5SAndroid Build Coastguard Worker                 curPixel += destRowPitch;
588*8975f5c5SAndroid Build Coastguard Worker             }
589*8975f5c5SAndroid Build Coastguard Worker         }
590*8975f5c5SAndroid Build Coastguard Worker         if (nonOpaquePunchThroughAlpha)
591*8975f5c5SAndroid Build Coastguard Worker         {
592*8975f5c5SAndroid Build Coastguard Worker             decodePunchThroughAlphaBlock(dest, x, y, w, h, destRowPitch);
593*8975f5c5SAndroid Build Coastguard Worker         }
594*8975f5c5SAndroid Build Coastguard Worker     }
595*8975f5c5SAndroid Build Coastguard Worker 
decodeTBlockangle::__anon4a5303920111::ETC2Block596*8975f5c5SAndroid Build Coastguard Worker     void decodeTBlock(uint8_t *dest,
597*8975f5c5SAndroid Build Coastguard Worker                       size_t x,
598*8975f5c5SAndroid Build Coastguard Worker                       size_t y,
599*8975f5c5SAndroid Build Coastguard Worker                       size_t w,
600*8975f5c5SAndroid Build Coastguard Worker                       size_t h,
601*8975f5c5SAndroid Build Coastguard Worker                       size_t destRowPitch,
602*8975f5c5SAndroid Build Coastguard Worker                       const uint8_t alphaValues[4][4],
603*8975f5c5SAndroid Build Coastguard Worker                       bool nonOpaquePunchThroughAlpha) const
604*8975f5c5SAndroid Build Coastguard Worker     {
605*8975f5c5SAndroid Build Coastguard Worker         // Table C.8, distance index for T and H modes
606*8975f5c5SAndroid Build Coastguard Worker         const auto &block = u.idht.mode.tm;
607*8975f5c5SAndroid Build Coastguard Worker 
608*8975f5c5SAndroid Build Coastguard Worker         int r1 = extend_4to8bits(block.TR1a << 2 | block.TR1b);
609*8975f5c5SAndroid Build Coastguard Worker         int g1 = extend_4to8bits(block.TG1);
610*8975f5c5SAndroid Build Coastguard Worker         int b1 = extend_4to8bits(block.TB1);
611*8975f5c5SAndroid Build Coastguard Worker         int r2 = extend_4to8bits(block.TR2);
612*8975f5c5SAndroid Build Coastguard Worker         int g2 = extend_4to8bits(block.TG2);
613*8975f5c5SAndroid Build Coastguard Worker         int b2 = extend_4to8bits(block.TB2);
614*8975f5c5SAndroid Build Coastguard Worker 
615*8975f5c5SAndroid Build Coastguard Worker         static int distance[8] = {3, 6, 11, 16, 23, 32, 41, 64};
616*8975f5c5SAndroid Build Coastguard Worker         const int d            = distance[block.Tda << 1 | block.Tdb];
617*8975f5c5SAndroid Build Coastguard Worker 
618*8975f5c5SAndroid Build Coastguard Worker         const R8G8B8A8 paintColors[4] = {
619*8975f5c5SAndroid Build Coastguard Worker             createRGBA(r1, g1, b1),
620*8975f5c5SAndroid Build Coastguard Worker             createRGBA(r2 + d, g2 + d, b2 + d),
621*8975f5c5SAndroid Build Coastguard Worker             createRGBA(r2, g2, b2),
622*8975f5c5SAndroid Build Coastguard Worker             createRGBA(r2 - d, g2 - d, b2 - d),
623*8975f5c5SAndroid Build Coastguard Worker         };
624*8975f5c5SAndroid Build Coastguard Worker 
625*8975f5c5SAndroid Build Coastguard Worker         uint8_t *curPixel = dest;
626*8975f5c5SAndroid Build Coastguard Worker         for (size_t j = 0; j < 4 && (y + j) < h; j++)
627*8975f5c5SAndroid Build Coastguard Worker         {
628*8975f5c5SAndroid Build Coastguard Worker             R8G8B8A8 *row = reinterpret_cast<R8G8B8A8 *>(curPixel);
629*8975f5c5SAndroid Build Coastguard Worker             for (size_t i = 0; i < 4 && (x + i) < w; i++)
630*8975f5c5SAndroid Build Coastguard Worker             {
631*8975f5c5SAndroid Build Coastguard Worker                 row[i]   = paintColors[getIndex(i, j)];
632*8975f5c5SAndroid Build Coastguard Worker                 row[i].A = alphaValues[j][i];
633*8975f5c5SAndroid Build Coastguard Worker             }
634*8975f5c5SAndroid Build Coastguard Worker             curPixel += destRowPitch;
635*8975f5c5SAndroid Build Coastguard Worker         }
636*8975f5c5SAndroid Build Coastguard Worker 
637*8975f5c5SAndroid Build Coastguard Worker         if (nonOpaquePunchThroughAlpha)
638*8975f5c5SAndroid Build Coastguard Worker         {
639*8975f5c5SAndroid Build Coastguard Worker             decodePunchThroughAlphaBlock(dest, x, y, w, h, destRowPitch);
640*8975f5c5SAndroid Build Coastguard Worker         }
641*8975f5c5SAndroid Build Coastguard Worker     }
642*8975f5c5SAndroid Build Coastguard Worker 
decodeHBlockangle::__anon4a5303920111::ETC2Block643*8975f5c5SAndroid Build Coastguard Worker     void decodeHBlock(uint8_t *dest,
644*8975f5c5SAndroid Build Coastguard Worker                       size_t x,
645*8975f5c5SAndroid Build Coastguard Worker                       size_t y,
646*8975f5c5SAndroid Build Coastguard Worker                       size_t w,
647*8975f5c5SAndroid Build Coastguard Worker                       size_t h,
648*8975f5c5SAndroid Build Coastguard Worker                       size_t destRowPitch,
649*8975f5c5SAndroid Build Coastguard Worker                       const uint8_t alphaValues[4][4],
650*8975f5c5SAndroid Build Coastguard Worker                       bool nonOpaquePunchThroughAlpha) const
651*8975f5c5SAndroid Build Coastguard Worker     {
652*8975f5c5SAndroid Build Coastguard Worker         // Table C.8, distance index for T and H modes
653*8975f5c5SAndroid Build Coastguard Worker         const auto &block = u.idht.mode.hm;
654*8975f5c5SAndroid Build Coastguard Worker 
655*8975f5c5SAndroid Build Coastguard Worker         int r1 = extend_4to8bits(block.HR1);
656*8975f5c5SAndroid Build Coastguard Worker         int g1 = extend_4to8bits(block.HG1a << 1 | block.HG1b);
657*8975f5c5SAndroid Build Coastguard Worker         int b1 = extend_4to8bits(block.HB1a << 3 | block.HB1b << 1 | block.HB1c);
658*8975f5c5SAndroid Build Coastguard Worker         int r2 = extend_4to8bits(block.HR2);
659*8975f5c5SAndroid Build Coastguard Worker         int g2 = extend_4to8bits(block.HG2a << 1 | block.HG2b);
660*8975f5c5SAndroid Build Coastguard Worker         int b2 = extend_4to8bits(block.HB2);
661*8975f5c5SAndroid Build Coastguard Worker 
662*8975f5c5SAndroid Build Coastguard Worker         static const int distance[8] = {3, 6, 11, 16, 23, 32, 41, 64};
663*8975f5c5SAndroid Build Coastguard Worker         const int orderingTrickBit =
664*8975f5c5SAndroid Build Coastguard Worker             ((r1 << 16 | g1 << 8 | b1) >= (r2 << 16 | g2 << 8 | b2) ? 1 : 0);
665*8975f5c5SAndroid Build Coastguard Worker         const int d = distance[(block.Hda << 2) | (block.Hdb << 1) | orderingTrickBit];
666*8975f5c5SAndroid Build Coastguard Worker 
667*8975f5c5SAndroid Build Coastguard Worker         const R8G8B8A8 paintColors[4] = {
668*8975f5c5SAndroid Build Coastguard Worker             createRGBA(r1 + d, g1 + d, b1 + d),
669*8975f5c5SAndroid Build Coastguard Worker             createRGBA(r1 - d, g1 - d, b1 - d),
670*8975f5c5SAndroid Build Coastguard Worker             createRGBA(r2 + d, g2 + d, b2 + d),
671*8975f5c5SAndroid Build Coastguard Worker             createRGBA(r2 - d, g2 - d, b2 - d),
672*8975f5c5SAndroid Build Coastguard Worker         };
673*8975f5c5SAndroid Build Coastguard Worker 
674*8975f5c5SAndroid Build Coastguard Worker         uint8_t *curPixel = dest;
675*8975f5c5SAndroid Build Coastguard Worker         for (size_t j = 0; j < 4 && (y + j) < h; j++)
676*8975f5c5SAndroid Build Coastguard Worker         {
677*8975f5c5SAndroid Build Coastguard Worker             R8G8B8A8 *row = reinterpret_cast<R8G8B8A8 *>(curPixel);
678*8975f5c5SAndroid Build Coastguard Worker             for (size_t i = 0; i < 4 && (x + i) < w; i++)
679*8975f5c5SAndroid Build Coastguard Worker             {
680*8975f5c5SAndroid Build Coastguard Worker                 row[i]   = paintColors[getIndex(i, j)];
681*8975f5c5SAndroid Build Coastguard Worker                 row[i].A = alphaValues[j][i];
682*8975f5c5SAndroid Build Coastguard Worker             }
683*8975f5c5SAndroid Build Coastguard Worker             curPixel += destRowPitch;
684*8975f5c5SAndroid Build Coastguard Worker         }
685*8975f5c5SAndroid Build Coastguard Worker 
686*8975f5c5SAndroid Build Coastguard Worker         if (nonOpaquePunchThroughAlpha)
687*8975f5c5SAndroid Build Coastguard Worker         {
688*8975f5c5SAndroid Build Coastguard Worker             decodePunchThroughAlphaBlock(dest, x, y, w, h, destRowPitch);
689*8975f5c5SAndroid Build Coastguard Worker         }
690*8975f5c5SAndroid Build Coastguard Worker     }
691*8975f5c5SAndroid Build Coastguard Worker 
decodePlanarBlockangle::__anon4a5303920111::ETC2Block692*8975f5c5SAndroid Build Coastguard Worker     void decodePlanarBlock(uint8_t *dest,
693*8975f5c5SAndroid Build Coastguard Worker                            size_t x,
694*8975f5c5SAndroid Build Coastguard Worker                            size_t y,
695*8975f5c5SAndroid Build Coastguard Worker                            size_t w,
696*8975f5c5SAndroid Build Coastguard Worker                            size_t h,
697*8975f5c5SAndroid Build Coastguard Worker                            size_t pitch,
698*8975f5c5SAndroid Build Coastguard Worker                            const uint8_t alphaValues[4][4]) const
699*8975f5c5SAndroid Build Coastguard Worker     {
700*8975f5c5SAndroid Build Coastguard Worker         int ro = extend_6to8bits(u.pblk.RO);
701*8975f5c5SAndroid Build Coastguard Worker         int go = extend_7to8bits(u.pblk.GO1 << 6 | u.pblk.GO2);
702*8975f5c5SAndroid Build Coastguard Worker         int bo =
703*8975f5c5SAndroid Build Coastguard Worker             extend_6to8bits(u.pblk.BO1 << 5 | u.pblk.BO2 << 3 | u.pblk.BO3a << 1 | u.pblk.BO3b);
704*8975f5c5SAndroid Build Coastguard Worker         int rh = extend_6to8bits(u.pblk.RH1 << 1 | u.pblk.RH2);
705*8975f5c5SAndroid Build Coastguard Worker         int gh = extend_7to8bits(u.pblk.GH);
706*8975f5c5SAndroid Build Coastguard Worker         int bh = extend_6to8bits(u.pblk.BHa << 5 | u.pblk.BHb);
707*8975f5c5SAndroid Build Coastguard Worker         int rv = extend_6to8bits(u.pblk.RVa << 3 | u.pblk.RVb);
708*8975f5c5SAndroid Build Coastguard Worker         int gv = extend_7to8bits(u.pblk.GVa << 2 | u.pblk.GVb);
709*8975f5c5SAndroid Build Coastguard Worker         int bv = extend_6to8bits(u.pblk.BV);
710*8975f5c5SAndroid Build Coastguard Worker 
711*8975f5c5SAndroid Build Coastguard Worker         uint8_t *curPixel = dest;
712*8975f5c5SAndroid Build Coastguard Worker         for (size_t j = 0; j < 4 && (y + j) < h; j++)
713*8975f5c5SAndroid Build Coastguard Worker         {
714*8975f5c5SAndroid Build Coastguard Worker             R8G8B8A8 *row = reinterpret_cast<R8G8B8A8 *>(curPixel);
715*8975f5c5SAndroid Build Coastguard Worker 
716*8975f5c5SAndroid Build Coastguard Worker             int ry = static_cast<int>(j) * (rv - ro) + 2;
717*8975f5c5SAndroid Build Coastguard Worker             int gy = static_cast<int>(j) * (gv - go) + 2;
718*8975f5c5SAndroid Build Coastguard Worker             int by = static_cast<int>(j) * (bv - bo) + 2;
719*8975f5c5SAndroid Build Coastguard Worker             for (size_t i = 0; i < 4 && (x + i) < w; i++)
720*8975f5c5SAndroid Build Coastguard Worker             {
721*8975f5c5SAndroid Build Coastguard Worker                 row[i] = createRGBA(((static_cast<int>(i) * (rh - ro) + ry) >> 2) + ro,
722*8975f5c5SAndroid Build Coastguard Worker                                     ((static_cast<int>(i) * (gh - go) + gy) >> 2) + go,
723*8975f5c5SAndroid Build Coastguard Worker                                     ((static_cast<int>(i) * (bh - bo) + by) >> 2) + bo,
724*8975f5c5SAndroid Build Coastguard Worker                                     alphaValues[j][i]);
725*8975f5c5SAndroid Build Coastguard Worker             }
726*8975f5c5SAndroid Build Coastguard Worker             curPixel += pitch;
727*8975f5c5SAndroid Build Coastguard Worker         }
728*8975f5c5SAndroid Build Coastguard Worker     }
729*8975f5c5SAndroid Build Coastguard Worker 
730*8975f5c5SAndroid Build Coastguard Worker     // Index for individual, differential, H and T modes
getIndexangle::__anon4a5303920111::ETC2Block731*8975f5c5SAndroid Build Coastguard Worker     size_t getIndex(size_t x, size_t y) const
732*8975f5c5SAndroid Build Coastguard Worker     {
733*8975f5c5SAndroid Build Coastguard Worker         size_t bitIndex  = x * 4 + y;
734*8975f5c5SAndroid Build Coastguard Worker         size_t bitOffset = bitIndex & 7;
735*8975f5c5SAndroid Build Coastguard Worker         size_t lsb       = (u.idht.pixelIndexLSB[1 - (bitIndex >> 3)] >> bitOffset) & 1;
736*8975f5c5SAndroid Build Coastguard Worker         size_t msb       = (u.idht.pixelIndexMSB[1 - (bitIndex >> 3)] >> bitOffset) & 1;
737*8975f5c5SAndroid Build Coastguard Worker         return (msb << 1) | lsb;
738*8975f5c5SAndroid Build Coastguard Worker     }
739*8975f5c5SAndroid Build Coastguard Worker 
decodePunchThroughAlphaBlockangle::__anon4a5303920111::ETC2Block740*8975f5c5SAndroid Build Coastguard Worker     void decodePunchThroughAlphaBlock(uint8_t *dest,
741*8975f5c5SAndroid Build Coastguard Worker                                       size_t x,
742*8975f5c5SAndroid Build Coastguard Worker                                       size_t y,
743*8975f5c5SAndroid Build Coastguard Worker                                       size_t w,
744*8975f5c5SAndroid Build Coastguard Worker                                       size_t h,
745*8975f5c5SAndroid Build Coastguard Worker                                       size_t destRowPitch) const
746*8975f5c5SAndroid Build Coastguard Worker     {
747*8975f5c5SAndroid Build Coastguard Worker         uint8_t *curPixel = dest;
748*8975f5c5SAndroid Build Coastguard Worker         for (size_t j = 0; j < 4 && (y + j) < h; j++)
749*8975f5c5SAndroid Build Coastguard Worker         {
750*8975f5c5SAndroid Build Coastguard Worker             R8G8B8A8 *row = reinterpret_cast<R8G8B8A8 *>(curPixel);
751*8975f5c5SAndroid Build Coastguard Worker             for (size_t i = 0; i < 4 && (x + i) < w; i++)
752*8975f5c5SAndroid Build Coastguard Worker             {
753*8975f5c5SAndroid Build Coastguard Worker                 if (getIndex(i, j) == 2)  //  msb == 1 && lsb == 0
754*8975f5c5SAndroid Build Coastguard Worker                 {
755*8975f5c5SAndroid Build Coastguard Worker                     row[i] = createRGBA(0, 0, 0, 0);
756*8975f5c5SAndroid Build Coastguard Worker                 }
757*8975f5c5SAndroid Build Coastguard Worker             }
758*8975f5c5SAndroid Build Coastguard Worker             curPixel += destRowPitch;
759*8975f5c5SAndroid Build Coastguard Worker         }
760*8975f5c5SAndroid Build Coastguard Worker     }
761*8975f5c5SAndroid Build Coastguard Worker 
RGB8ToRGB565angle::__anon4a5303920111::ETC2Block762*8975f5c5SAndroid Build Coastguard Worker     uint16_t RGB8ToRGB565(const R8G8B8A8 &rgba) const
763*8975f5c5SAndroid Build Coastguard Worker     {
764*8975f5c5SAndroid Build Coastguard Worker         return (static_cast<uint16_t>(rgba.R >> 3) << 11) |
765*8975f5c5SAndroid Build Coastguard Worker                (static_cast<uint16_t>(rgba.G >> 2) << 5) |
766*8975f5c5SAndroid Build Coastguard Worker                (static_cast<uint16_t>(rgba.B >> 3) << 0);
767*8975f5c5SAndroid Build Coastguard Worker     }
768*8975f5c5SAndroid Build Coastguard Worker 
matchBC1Bitsangle::__anon4a5303920111::ETC2Block769*8975f5c5SAndroid Build Coastguard Worker     uint32_t matchBC1Bits(const int *pixelIndices,
770*8975f5c5SAndroid Build Coastguard Worker                           const int *pixelIndexCounts,
771*8975f5c5SAndroid Build Coastguard Worker                           const R8G8B8A8 *subblockColors,
772*8975f5c5SAndroid Build Coastguard Worker                           size_t numColors,
773*8975f5c5SAndroid Build Coastguard Worker                           const R8G8B8A8 &minColor,
774*8975f5c5SAndroid Build Coastguard Worker                           const R8G8B8A8 &maxColor,
775*8975f5c5SAndroid Build Coastguard Worker                           bool nonOpaquePunchThroughAlpha) const
776*8975f5c5SAndroid Build Coastguard Worker     {
777*8975f5c5SAndroid Build Coastguard Worker         // Project each pixel on the (maxColor, minColor) line to decide which
778*8975f5c5SAndroid Build Coastguard Worker         // BC1 code to assign to it.
779*8975f5c5SAndroid Build Coastguard Worker 
780*8975f5c5SAndroid Build Coastguard Worker         uint8_t decodedColors[2][3] = {{maxColor.R, maxColor.G, maxColor.B},
781*8975f5c5SAndroid Build Coastguard Worker                                        {minColor.R, minColor.G, minColor.B}};
782*8975f5c5SAndroid Build Coastguard Worker 
783*8975f5c5SAndroid Build Coastguard Worker         int direction[3];
784*8975f5c5SAndroid Build Coastguard Worker         for (int ch = 0; ch < 3; ch++)
785*8975f5c5SAndroid Build Coastguard Worker         {
786*8975f5c5SAndroid Build Coastguard Worker             direction[ch] = decodedColors[0][ch] - decodedColors[1][ch];
787*8975f5c5SAndroid Build Coastguard Worker         }
788*8975f5c5SAndroid Build Coastguard Worker 
789*8975f5c5SAndroid Build Coastguard Worker         int stops[2];
790*8975f5c5SAndroid Build Coastguard Worker         for (int i = 0; i < 2; i++)
791*8975f5c5SAndroid Build Coastguard Worker         {
792*8975f5c5SAndroid Build Coastguard Worker             stops[i] = decodedColors[i][0] * direction[0] + decodedColors[i][1] * direction[1] +
793*8975f5c5SAndroid Build Coastguard Worker                        decodedColors[i][2] * direction[2];
794*8975f5c5SAndroid Build Coastguard Worker         }
795*8975f5c5SAndroid Build Coastguard Worker 
796*8975f5c5SAndroid Build Coastguard Worker         ASSERT(numColors <= kNumPixelsInBlock);
797*8975f5c5SAndroid Build Coastguard Worker 
798*8975f5c5SAndroid Build Coastguard Worker         int encodedColors[kNumPixelsInBlock];
799*8975f5c5SAndroid Build Coastguard Worker         if (nonOpaquePunchThroughAlpha)
800*8975f5c5SAndroid Build Coastguard Worker         {
801*8975f5c5SAndroid Build Coastguard Worker             for (size_t i = 0; i < numColors; i++)
802*8975f5c5SAndroid Build Coastguard Worker             {
803*8975f5c5SAndroid Build Coastguard Worker                 const int count = pixelIndexCounts[i];
804*8975f5c5SAndroid Build Coastguard Worker                 if (count > 0)
805*8975f5c5SAndroid Build Coastguard Worker                 {
806*8975f5c5SAndroid Build Coastguard Worker                     // In non-opaque mode, 3 is for tranparent pixels.
807*8975f5c5SAndroid Build Coastguard Worker 
808*8975f5c5SAndroid Build Coastguard Worker                     if (0 == subblockColors[i].A)
809*8975f5c5SAndroid Build Coastguard Worker                     {
810*8975f5c5SAndroid Build Coastguard Worker                         encodedColors[i] = 3;
811*8975f5c5SAndroid Build Coastguard Worker                     }
812*8975f5c5SAndroid Build Coastguard Worker                     else
813*8975f5c5SAndroid Build Coastguard Worker                     {
814*8975f5c5SAndroid Build Coastguard Worker                         const R8G8B8A8 &pixel = subblockColors[i];
815*8975f5c5SAndroid Build Coastguard Worker                         const int dot         = pixel.R * direction[0] + pixel.G * direction[1] +
816*8975f5c5SAndroid Build Coastguard Worker                                         pixel.B * direction[2];
817*8975f5c5SAndroid Build Coastguard Worker                         const int factor = gl::clamp(
818*8975f5c5SAndroid Build Coastguard Worker                             static_cast<int>(
819*8975f5c5SAndroid Build Coastguard Worker                                 (static_cast<float>(dot - stops[1]) / (stops[0] - stops[1])) * 2 +
820*8975f5c5SAndroid Build Coastguard Worker                                 0.5f),
821*8975f5c5SAndroid Build Coastguard Worker                             0, 2);
822*8975f5c5SAndroid Build Coastguard Worker                         switch (factor)
823*8975f5c5SAndroid Build Coastguard Worker                         {
824*8975f5c5SAndroid Build Coastguard Worker                             case 0:
825*8975f5c5SAndroid Build Coastguard Worker                                 encodedColors[i] = 0;
826*8975f5c5SAndroid Build Coastguard Worker                                 break;
827*8975f5c5SAndroid Build Coastguard Worker                             case 1:
828*8975f5c5SAndroid Build Coastguard Worker                                 encodedColors[i] = 2;
829*8975f5c5SAndroid Build Coastguard Worker                                 break;
830*8975f5c5SAndroid Build Coastguard Worker                             case 2:
831*8975f5c5SAndroid Build Coastguard Worker                             default:
832*8975f5c5SAndroid Build Coastguard Worker                                 encodedColors[i] = 1;
833*8975f5c5SAndroid Build Coastguard Worker                                 break;
834*8975f5c5SAndroid Build Coastguard Worker                         }
835*8975f5c5SAndroid Build Coastguard Worker                     }
836*8975f5c5SAndroid Build Coastguard Worker                 }
837*8975f5c5SAndroid Build Coastguard Worker             }
838*8975f5c5SAndroid Build Coastguard Worker         }
839*8975f5c5SAndroid Build Coastguard Worker         else
840*8975f5c5SAndroid Build Coastguard Worker         {
841*8975f5c5SAndroid Build Coastguard Worker             for (size_t i = 0; i < numColors; i++)
842*8975f5c5SAndroid Build Coastguard Worker             {
843*8975f5c5SAndroid Build Coastguard Worker                 const int count = pixelIndexCounts[i];
844*8975f5c5SAndroid Build Coastguard Worker                 if (count > 0)
845*8975f5c5SAndroid Build Coastguard Worker                 {
846*8975f5c5SAndroid Build Coastguard Worker                     // In opaque mode, the code is from 0 to 3.
847*8975f5c5SAndroid Build Coastguard Worker 
848*8975f5c5SAndroid Build Coastguard Worker                     const R8G8B8A8 &pixel = subblockColors[i];
849*8975f5c5SAndroid Build Coastguard Worker                     const int dot =
850*8975f5c5SAndroid Build Coastguard Worker                         pixel.R * direction[0] + pixel.G * direction[1] + pixel.B * direction[2];
851*8975f5c5SAndroid Build Coastguard Worker                     const int factor = gl::clamp(
852*8975f5c5SAndroid Build Coastguard Worker                         static_cast<int>(
853*8975f5c5SAndroid Build Coastguard Worker                             (static_cast<float>(dot - stops[1]) / (stops[0] - stops[1])) * 3 +
854*8975f5c5SAndroid Build Coastguard Worker                             0.5f),
855*8975f5c5SAndroid Build Coastguard Worker                         0, 3);
856*8975f5c5SAndroid Build Coastguard Worker                     switch (factor)
857*8975f5c5SAndroid Build Coastguard Worker                     {
858*8975f5c5SAndroid Build Coastguard Worker                         case 0:
859*8975f5c5SAndroid Build Coastguard Worker                             encodedColors[i] = 1;
860*8975f5c5SAndroid Build Coastguard Worker                             break;
861*8975f5c5SAndroid Build Coastguard Worker                         case 1:
862*8975f5c5SAndroid Build Coastguard Worker                             encodedColors[i] = 3;
863*8975f5c5SAndroid Build Coastguard Worker                             break;
864*8975f5c5SAndroid Build Coastguard Worker                         case 2:
865*8975f5c5SAndroid Build Coastguard Worker                             encodedColors[i] = 2;
866*8975f5c5SAndroid Build Coastguard Worker                             break;
867*8975f5c5SAndroid Build Coastguard Worker                         case 3:
868*8975f5c5SAndroid Build Coastguard Worker                         default:
869*8975f5c5SAndroid Build Coastguard Worker                             encodedColors[i] = 0;
870*8975f5c5SAndroid Build Coastguard Worker                             break;
871*8975f5c5SAndroid Build Coastguard Worker                     }
872*8975f5c5SAndroid Build Coastguard Worker                 }
873*8975f5c5SAndroid Build Coastguard Worker             }
874*8975f5c5SAndroid Build Coastguard Worker         }
875*8975f5c5SAndroid Build Coastguard Worker 
876*8975f5c5SAndroid Build Coastguard Worker         uint32_t bits = 0;
877*8975f5c5SAndroid Build Coastguard Worker         for (int i = kNumPixelsInBlock - 1; i >= 0; i--)
878*8975f5c5SAndroid Build Coastguard Worker         {
879*8975f5c5SAndroid Build Coastguard Worker             bits <<= 2;
880*8975f5c5SAndroid Build Coastguard Worker             bits |= encodedColors[pixelIndices[i]];
881*8975f5c5SAndroid Build Coastguard Worker         }
882*8975f5c5SAndroid Build Coastguard Worker 
883*8975f5c5SAndroid Build Coastguard Worker         return bits;
884*8975f5c5SAndroid Build Coastguard Worker     }
885*8975f5c5SAndroid Build Coastguard Worker 
packBC1angle::__anon4a5303920111::ETC2Block886*8975f5c5SAndroid Build Coastguard Worker     void packBC1(void *bc1,
887*8975f5c5SAndroid Build Coastguard Worker                  const int *pixelIndices,
888*8975f5c5SAndroid Build Coastguard Worker                  const int *pixelIndexCounts,
889*8975f5c5SAndroid Build Coastguard Worker                  const R8G8B8A8 *subblockColors,
890*8975f5c5SAndroid Build Coastguard Worker                  size_t numColors,
891*8975f5c5SAndroid Build Coastguard Worker                  int minColorIndex,
892*8975f5c5SAndroid Build Coastguard Worker                  int maxColorIndex,
893*8975f5c5SAndroid Build Coastguard Worker                  bool nonOpaquePunchThroughAlpha) const
894*8975f5c5SAndroid Build Coastguard Worker     {
895*8975f5c5SAndroid Build Coastguard Worker         const R8G8B8A8 &minColor = subblockColors[minColorIndex];
896*8975f5c5SAndroid Build Coastguard Worker         const R8G8B8A8 &maxColor = subblockColors[maxColorIndex];
897*8975f5c5SAndroid Build Coastguard Worker 
898*8975f5c5SAndroid Build Coastguard Worker         uint32_t bits;
899*8975f5c5SAndroid Build Coastguard Worker         uint16_t max16 = RGB8ToRGB565(maxColor);
900*8975f5c5SAndroid Build Coastguard Worker         uint16_t min16 = RGB8ToRGB565(minColor);
901*8975f5c5SAndroid Build Coastguard Worker         if (max16 != min16)
902*8975f5c5SAndroid Build Coastguard Worker         {
903*8975f5c5SAndroid Build Coastguard Worker             // Find the best BC1 code for each pixel
904*8975f5c5SAndroid Build Coastguard Worker             bits = matchBC1Bits(pixelIndices, pixelIndexCounts, subblockColors, numColors, minColor,
905*8975f5c5SAndroid Build Coastguard Worker                                 maxColor, nonOpaquePunchThroughAlpha);
906*8975f5c5SAndroid Build Coastguard Worker         }
907*8975f5c5SAndroid Build Coastguard Worker         else
908*8975f5c5SAndroid Build Coastguard Worker         {
909*8975f5c5SAndroid Build Coastguard Worker             // Same colors, BC1 index 0 is the color in both opaque and transparent mode
910*8975f5c5SAndroid Build Coastguard Worker             bits = 0;
911*8975f5c5SAndroid Build Coastguard Worker             // BC1 index 3 is transparent
912*8975f5c5SAndroid Build Coastguard Worker             if (nonOpaquePunchThroughAlpha)
913*8975f5c5SAndroid Build Coastguard Worker             {
914*8975f5c5SAndroid Build Coastguard Worker                 for (int i = 0; i < kNumPixelsInBlock; i++)
915*8975f5c5SAndroid Build Coastguard Worker                 {
916*8975f5c5SAndroid Build Coastguard Worker                     if (0 == subblockColors[pixelIndices[i]].A)
917*8975f5c5SAndroid Build Coastguard Worker                     {
918*8975f5c5SAndroid Build Coastguard Worker                         bits |= (3 << (i * 2));
919*8975f5c5SAndroid Build Coastguard Worker                     }
920*8975f5c5SAndroid Build Coastguard Worker                 }
921*8975f5c5SAndroid Build Coastguard Worker             }
922*8975f5c5SAndroid Build Coastguard Worker         }
923*8975f5c5SAndroid Build Coastguard Worker 
924*8975f5c5SAndroid Build Coastguard Worker         if (max16 < min16)
925*8975f5c5SAndroid Build Coastguard Worker         {
926*8975f5c5SAndroid Build Coastguard Worker             std::swap(max16, min16);
927*8975f5c5SAndroid Build Coastguard Worker 
928*8975f5c5SAndroid Build Coastguard Worker             uint32_t xorMask = 0;
929*8975f5c5SAndroid Build Coastguard Worker             if (nonOpaquePunchThroughAlpha)
930*8975f5c5SAndroid Build Coastguard Worker             {
931*8975f5c5SAndroid Build Coastguard Worker                 // In transparent mode switching the colors is doing the
932*8975f5c5SAndroid Build Coastguard Worker                 // following code swap: 0 <-> 1. 0xA selects the second bit of
933*8975f5c5SAndroid Build Coastguard Worker                 // each code, bits >> 1 selects the first bit of the code when
934*8975f5c5SAndroid Build Coastguard Worker                 // the seconds bit is set (case 2 and 3). We invert all the
935*8975f5c5SAndroid Build Coastguard Worker                 // non-selected bits, that is the first bit when the code is
936*8975f5c5SAndroid Build Coastguard Worker                 // 0 or 1.
937*8975f5c5SAndroid Build Coastguard Worker                 xorMask = ~((bits >> 1) | 0xAAAAAAAA);
938*8975f5c5SAndroid Build Coastguard Worker             }
939*8975f5c5SAndroid Build Coastguard Worker             else
940*8975f5c5SAndroid Build Coastguard Worker             {
941*8975f5c5SAndroid Build Coastguard Worker                 // In opaque mode switching the two colors is doing the
942*8975f5c5SAndroid Build Coastguard Worker                 // following code swaps: 0 <-> 1 and 2 <-> 3. This is
943*8975f5c5SAndroid Build Coastguard Worker                 // equivalent to flipping the first bit of each code
944*8975f5c5SAndroid Build Coastguard Worker                 // (5 = 0b0101)
945*8975f5c5SAndroid Build Coastguard Worker                 xorMask = 0x55555555;
946*8975f5c5SAndroid Build Coastguard Worker             }
947*8975f5c5SAndroid Build Coastguard Worker             bits ^= xorMask;
948*8975f5c5SAndroid Build Coastguard Worker         }
949*8975f5c5SAndroid Build Coastguard Worker 
950*8975f5c5SAndroid Build Coastguard Worker         struct BC1Block
951*8975f5c5SAndroid Build Coastguard Worker         {
952*8975f5c5SAndroid Build Coastguard Worker             uint16_t color0;
953*8975f5c5SAndroid Build Coastguard Worker             uint16_t color1;
954*8975f5c5SAndroid Build Coastguard Worker             uint32_t bits;
955*8975f5c5SAndroid Build Coastguard Worker         };
956*8975f5c5SAndroid Build Coastguard Worker 
957*8975f5c5SAndroid Build Coastguard Worker         // Encode the opaqueness in the order of the two BC1 colors
958*8975f5c5SAndroid Build Coastguard Worker         BC1Block *dest = reinterpret_cast<BC1Block *>(bc1);
959*8975f5c5SAndroid Build Coastguard Worker         if (nonOpaquePunchThroughAlpha)
960*8975f5c5SAndroid Build Coastguard Worker         {
961*8975f5c5SAndroid Build Coastguard Worker             dest->color0 = min16;
962*8975f5c5SAndroid Build Coastguard Worker             dest->color1 = max16;
963*8975f5c5SAndroid Build Coastguard Worker         }
964*8975f5c5SAndroid Build Coastguard Worker         else
965*8975f5c5SAndroid Build Coastguard Worker         {
966*8975f5c5SAndroid Build Coastguard Worker             dest->color0 = max16;
967*8975f5c5SAndroid Build Coastguard Worker             dest->color1 = min16;
968*8975f5c5SAndroid Build Coastguard Worker         }
969*8975f5c5SAndroid Build Coastguard Worker         dest->bits = bits;
970*8975f5c5SAndroid Build Coastguard Worker     }
971*8975f5c5SAndroid Build Coastguard Worker 
transcodeIndividualBlockToBC1angle::__anon4a5303920111::ETC2Block972*8975f5c5SAndroid Build Coastguard Worker     void transcodeIndividualBlockToBC1(uint8_t *dest,
973*8975f5c5SAndroid Build Coastguard Worker                                        size_t x,
974*8975f5c5SAndroid Build Coastguard Worker                                        size_t y,
975*8975f5c5SAndroid Build Coastguard Worker                                        size_t w,
976*8975f5c5SAndroid Build Coastguard Worker                                        size_t h,
977*8975f5c5SAndroid Build Coastguard Worker                                        const uint8_t alphaValues[4][4],
978*8975f5c5SAndroid Build Coastguard Worker                                        bool nonOpaquePunchThroughAlpha) const
979*8975f5c5SAndroid Build Coastguard Worker     {
980*8975f5c5SAndroid Build Coastguard Worker         const auto &block = u.idht.mode.idm.colors.indiv;
981*8975f5c5SAndroid Build Coastguard Worker         int r1            = extend_4to8bits(block.R1);
982*8975f5c5SAndroid Build Coastguard Worker         int g1            = extend_4to8bits(block.G1);
983*8975f5c5SAndroid Build Coastguard Worker         int b1            = extend_4to8bits(block.B1);
984*8975f5c5SAndroid Build Coastguard Worker         int r2            = extend_4to8bits(block.R2);
985*8975f5c5SAndroid Build Coastguard Worker         int g2            = extend_4to8bits(block.G2);
986*8975f5c5SAndroid Build Coastguard Worker         int b2            = extend_4to8bits(block.B2);
987*8975f5c5SAndroid Build Coastguard Worker         transcodeIndividualOrDifferentialBlockToBC1(dest, x, y, w, h, r1, g1, b1, r2, g2, b2,
988*8975f5c5SAndroid Build Coastguard Worker                                                     alphaValues, nonOpaquePunchThroughAlpha);
989*8975f5c5SAndroid Build Coastguard Worker     }
990*8975f5c5SAndroid Build Coastguard Worker 
transcodeDifferentialBlockToBC1angle::__anon4a5303920111::ETC2Block991*8975f5c5SAndroid Build Coastguard Worker     void transcodeDifferentialBlockToBC1(uint8_t *dest,
992*8975f5c5SAndroid Build Coastguard Worker                                          size_t x,
993*8975f5c5SAndroid Build Coastguard Worker                                          size_t y,
994*8975f5c5SAndroid Build Coastguard Worker                                          size_t w,
995*8975f5c5SAndroid Build Coastguard Worker                                          size_t h,
996*8975f5c5SAndroid Build Coastguard Worker                                          const uint8_t alphaValues[4][4],
997*8975f5c5SAndroid Build Coastguard Worker                                          bool nonOpaquePunchThroughAlpha) const
998*8975f5c5SAndroid Build Coastguard Worker     {
999*8975f5c5SAndroid Build Coastguard Worker         const auto &block = u.idht.mode.idm.colors.diff;
1000*8975f5c5SAndroid Build Coastguard Worker         int b1            = extend_5to8bits(block.B);
1001*8975f5c5SAndroid Build Coastguard Worker         int g1            = extend_5to8bits(block.G);
1002*8975f5c5SAndroid Build Coastguard Worker         int r1            = extend_5to8bits(block.R);
1003*8975f5c5SAndroid Build Coastguard Worker         int r2            = extend_5to8bits(block.R + block.dR);
1004*8975f5c5SAndroid Build Coastguard Worker         int g2            = extend_5to8bits(block.G + block.dG);
1005*8975f5c5SAndroid Build Coastguard Worker         int b2            = extend_5to8bits(block.B + block.dB);
1006*8975f5c5SAndroid Build Coastguard Worker         transcodeIndividualOrDifferentialBlockToBC1(dest, x, y, w, h, r1, g1, b1, r2, g2, b2,
1007*8975f5c5SAndroid Build Coastguard Worker                                                     alphaValues, nonOpaquePunchThroughAlpha);
1008*8975f5c5SAndroid Build Coastguard Worker     }
1009*8975f5c5SAndroid Build Coastguard Worker 
extractPixelIndicesangle::__anon4a5303920111::ETC2Block1010*8975f5c5SAndroid Build Coastguard Worker     void extractPixelIndices(int *pixelIndices,
1011*8975f5c5SAndroid Build Coastguard Worker                              int *pixelIndicesCounts,
1012*8975f5c5SAndroid Build Coastguard Worker                              size_t x,
1013*8975f5c5SAndroid Build Coastguard Worker                              size_t y,
1014*8975f5c5SAndroid Build Coastguard Worker                              size_t w,
1015*8975f5c5SAndroid Build Coastguard Worker                              size_t h,
1016*8975f5c5SAndroid Build Coastguard Worker                              bool flipbit,
1017*8975f5c5SAndroid Build Coastguard Worker                              size_t subblockIdx) const
1018*8975f5c5SAndroid Build Coastguard Worker     {
1019*8975f5c5SAndroid Build Coastguard Worker         size_t dxBegin = 0;
1020*8975f5c5SAndroid Build Coastguard Worker         size_t dxEnd   = 4;
1021*8975f5c5SAndroid Build Coastguard Worker         size_t dyBegin = subblockIdx * 2;
1022*8975f5c5SAndroid Build Coastguard Worker         size_t dyEnd   = dyBegin + 2;
1023*8975f5c5SAndroid Build Coastguard Worker         if (!flipbit)
1024*8975f5c5SAndroid Build Coastguard Worker         {
1025*8975f5c5SAndroid Build Coastguard Worker             std::swap(dxBegin, dyBegin);
1026*8975f5c5SAndroid Build Coastguard Worker             std::swap(dxEnd, dyEnd);
1027*8975f5c5SAndroid Build Coastguard Worker         }
1028*8975f5c5SAndroid Build Coastguard Worker 
1029*8975f5c5SAndroid Build Coastguard Worker         for (size_t j = dyBegin; j < dyEnd; j++)
1030*8975f5c5SAndroid Build Coastguard Worker         {
1031*8975f5c5SAndroid Build Coastguard Worker             int *row = &pixelIndices[j * 4];
1032*8975f5c5SAndroid Build Coastguard Worker             for (size_t i = dxBegin; i < dxEnd; i++)
1033*8975f5c5SAndroid Build Coastguard Worker             {
1034*8975f5c5SAndroid Build Coastguard Worker                 const size_t pixelIndex = subblockIdx * 4 + getIndex(i, j);
1035*8975f5c5SAndroid Build Coastguard Worker                 row[i]                  = static_cast<int>(pixelIndex);
1036*8975f5c5SAndroid Build Coastguard Worker                 pixelIndicesCounts[pixelIndex]++;
1037*8975f5c5SAndroid Build Coastguard Worker             }
1038*8975f5c5SAndroid Build Coastguard Worker         }
1039*8975f5c5SAndroid Build Coastguard Worker     }
1040*8975f5c5SAndroid Build Coastguard Worker 
selectEndPointPCAangle::__anon4a5303920111::ETC2Block1041*8975f5c5SAndroid Build Coastguard Worker     void selectEndPointPCA(const int *pixelIndexCounts,
1042*8975f5c5SAndroid Build Coastguard Worker                            const R8G8B8A8 *subblockColors,
1043*8975f5c5SAndroid Build Coastguard Worker                            size_t numColors,
1044*8975f5c5SAndroid Build Coastguard Worker                            int *minColorIndex,
1045*8975f5c5SAndroid Build Coastguard Worker                            int *maxColorIndex) const
1046*8975f5c5SAndroid Build Coastguard Worker     {
1047*8975f5c5SAndroid Build Coastguard Worker         // determine color distribution
1048*8975f5c5SAndroid Build Coastguard Worker         int mu[3], min[3], max[3];
1049*8975f5c5SAndroid Build Coastguard Worker         for (int ch = 0; ch < 3; ch++)
1050*8975f5c5SAndroid Build Coastguard Worker         {
1051*8975f5c5SAndroid Build Coastguard Worker             int muv  = 0;
1052*8975f5c5SAndroid Build Coastguard Worker             int minv = 255;
1053*8975f5c5SAndroid Build Coastguard Worker             int maxv = 0;
1054*8975f5c5SAndroid Build Coastguard Worker             for (size_t i = 0; i < numColors; i++)
1055*8975f5c5SAndroid Build Coastguard Worker             {
1056*8975f5c5SAndroid Build Coastguard Worker                 const int count = pixelIndexCounts[i];
1057*8975f5c5SAndroid Build Coastguard Worker                 if (count > 0)
1058*8975f5c5SAndroid Build Coastguard Worker                 {
1059*8975f5c5SAndroid Build Coastguard Worker                     const auto &pixel = subblockColors[i];
1060*8975f5c5SAndroid Build Coastguard Worker                     if (pixel.A > 0)
1061*8975f5c5SAndroid Build Coastguard Worker                     {
1062*8975f5c5SAndroid Build Coastguard Worker                         // Non-transparent pixels
1063*8975f5c5SAndroid Build Coastguard Worker                         muv += (&pixel.R)[ch] * count;
1064*8975f5c5SAndroid Build Coastguard Worker                         minv = std::min<int>(minv, (&pixel.R)[ch]);
1065*8975f5c5SAndroid Build Coastguard Worker                         maxv = std::max<int>(maxv, (&pixel.R)[ch]);
1066*8975f5c5SAndroid Build Coastguard Worker                     }
1067*8975f5c5SAndroid Build Coastguard Worker                 }
1068*8975f5c5SAndroid Build Coastguard Worker             }
1069*8975f5c5SAndroid Build Coastguard Worker 
1070*8975f5c5SAndroid Build Coastguard Worker             mu[ch]  = (muv + kNumPixelsInBlock / 2) / kNumPixelsInBlock;
1071*8975f5c5SAndroid Build Coastguard Worker             min[ch] = minv;
1072*8975f5c5SAndroid Build Coastguard Worker             max[ch] = maxv;
1073*8975f5c5SAndroid Build Coastguard Worker         }
1074*8975f5c5SAndroid Build Coastguard Worker 
1075*8975f5c5SAndroid Build Coastguard Worker         // determine covariance matrix
1076*8975f5c5SAndroid Build Coastguard Worker         int cov[6] = {0, 0, 0, 0, 0, 0};
1077*8975f5c5SAndroid Build Coastguard Worker         for (size_t i = 0; i < numColors; i++)
1078*8975f5c5SAndroid Build Coastguard Worker         {
1079*8975f5c5SAndroid Build Coastguard Worker             const int count = pixelIndexCounts[i];
1080*8975f5c5SAndroid Build Coastguard Worker             if (count > 0)
1081*8975f5c5SAndroid Build Coastguard Worker             {
1082*8975f5c5SAndroid Build Coastguard Worker                 const auto &pixel = subblockColors[i];
1083*8975f5c5SAndroid Build Coastguard Worker                 if (pixel.A > 0)
1084*8975f5c5SAndroid Build Coastguard Worker                 {
1085*8975f5c5SAndroid Build Coastguard Worker                     int r = pixel.R - mu[0];
1086*8975f5c5SAndroid Build Coastguard Worker                     int g = pixel.G - mu[1];
1087*8975f5c5SAndroid Build Coastguard Worker                     int b = pixel.B - mu[2];
1088*8975f5c5SAndroid Build Coastguard Worker 
1089*8975f5c5SAndroid Build Coastguard Worker                     cov[0] += r * r * count;
1090*8975f5c5SAndroid Build Coastguard Worker                     cov[1] += r * g * count;
1091*8975f5c5SAndroid Build Coastguard Worker                     cov[2] += r * b * count;
1092*8975f5c5SAndroid Build Coastguard Worker                     cov[3] += g * g * count;
1093*8975f5c5SAndroid Build Coastguard Worker                     cov[4] += g * b * count;
1094*8975f5c5SAndroid Build Coastguard Worker                     cov[5] += b * b * count;
1095*8975f5c5SAndroid Build Coastguard Worker                 }
1096*8975f5c5SAndroid Build Coastguard Worker             }
1097*8975f5c5SAndroid Build Coastguard Worker         }
1098*8975f5c5SAndroid Build Coastguard Worker 
1099*8975f5c5SAndroid Build Coastguard Worker         // Power iteration algorithm to get the eigenvalues and eigenvector
1100*8975f5c5SAndroid Build Coastguard Worker 
1101*8975f5c5SAndroid Build Coastguard Worker         // Starts with diagonal vector
1102*8975f5c5SAndroid Build Coastguard Worker         float vfr        = static_cast<float>(max[0] - min[0]);
1103*8975f5c5SAndroid Build Coastguard Worker         float vfg        = static_cast<float>(max[1] - min[1]);
1104*8975f5c5SAndroid Build Coastguard Worker         float vfb        = static_cast<float>(max[2] - min[2]);
1105*8975f5c5SAndroid Build Coastguard Worker         float eigenvalue = 0.0f;
1106*8975f5c5SAndroid Build Coastguard Worker 
1107*8975f5c5SAndroid Build Coastguard Worker         constexpr size_t kPowerIterations = 4;
1108*8975f5c5SAndroid Build Coastguard Worker         for (size_t i = 0; i < kPowerIterations; i++)
1109*8975f5c5SAndroid Build Coastguard Worker         {
1110*8975f5c5SAndroid Build Coastguard Worker             float r = vfr * cov[0] + vfg * cov[1] + vfb * cov[2];
1111*8975f5c5SAndroid Build Coastguard Worker             float g = vfr * cov[1] + vfg * cov[3] + vfb * cov[4];
1112*8975f5c5SAndroid Build Coastguard Worker             float b = vfr * cov[2] + vfg * cov[4] + vfb * cov[5];
1113*8975f5c5SAndroid Build Coastguard Worker 
1114*8975f5c5SAndroid Build Coastguard Worker             vfr = r;
1115*8975f5c5SAndroid Build Coastguard Worker             vfg = g;
1116*8975f5c5SAndroid Build Coastguard Worker             vfb = b;
1117*8975f5c5SAndroid Build Coastguard Worker 
1118*8975f5c5SAndroid Build Coastguard Worker             eigenvalue = sqrt(r * r + g * g + b * b);
1119*8975f5c5SAndroid Build Coastguard Worker             if (eigenvalue > 0)
1120*8975f5c5SAndroid Build Coastguard Worker             {
1121*8975f5c5SAndroid Build Coastguard Worker                 float invNorm = 1.0f / eigenvalue;
1122*8975f5c5SAndroid Build Coastguard Worker                 vfr *= invNorm;
1123*8975f5c5SAndroid Build Coastguard Worker                 vfg *= invNorm;
1124*8975f5c5SAndroid Build Coastguard Worker                 vfb *= invNorm;
1125*8975f5c5SAndroid Build Coastguard Worker             }
1126*8975f5c5SAndroid Build Coastguard Worker         }
1127*8975f5c5SAndroid Build Coastguard Worker 
1128*8975f5c5SAndroid Build Coastguard Worker         int vr, vg, vb;
1129*8975f5c5SAndroid Build Coastguard Worker 
1130*8975f5c5SAndroid Build Coastguard Worker         static const float kDefaultLuminanceThreshold = 4.0f * 255;
1131*8975f5c5SAndroid Build Coastguard Worker         static const float kQuantizeRange             = 512.0f;
1132*8975f5c5SAndroid Build Coastguard Worker         if (eigenvalue < kDefaultLuminanceThreshold)  // too small, default to luminance
1133*8975f5c5SAndroid Build Coastguard Worker         {
1134*8975f5c5SAndroid Build Coastguard Worker             // Luminance weights defined by ITU-R Recommendation BT.601, scaled by 1000
1135*8975f5c5SAndroid Build Coastguard Worker             vr = 299;
1136*8975f5c5SAndroid Build Coastguard Worker             vg = 587;
1137*8975f5c5SAndroid Build Coastguard Worker             vb = 114;
1138*8975f5c5SAndroid Build Coastguard Worker         }
1139*8975f5c5SAndroid Build Coastguard Worker         else
1140*8975f5c5SAndroid Build Coastguard Worker         {
1141*8975f5c5SAndroid Build Coastguard Worker             // From the eigenvalue and eigenvector, choose the axis to project
1142*8975f5c5SAndroid Build Coastguard Worker             // colors on. When projecting colors we want to do integer computations
1143*8975f5c5SAndroid Build Coastguard Worker             // for speed, so we normalize the eigenvector to the [0, 512] range.
1144*8975f5c5SAndroid Build Coastguard Worker             float magn = std::max({std::abs(vfr), std::abs(vfg), std::abs(vfb)});
1145*8975f5c5SAndroid Build Coastguard Worker             magn       = kQuantizeRange / magn;
1146*8975f5c5SAndroid Build Coastguard Worker             vr         = static_cast<int>(vfr * magn);
1147*8975f5c5SAndroid Build Coastguard Worker             vg         = static_cast<int>(vfg * magn);
1148*8975f5c5SAndroid Build Coastguard Worker             vb         = static_cast<int>(vfb * magn);
1149*8975f5c5SAndroid Build Coastguard Worker         }
1150*8975f5c5SAndroid Build Coastguard Worker 
1151*8975f5c5SAndroid Build Coastguard Worker         // Pick colors at extreme points
1152*8975f5c5SAndroid Build Coastguard Worker         int minD        = INT_MAX;
1153*8975f5c5SAndroid Build Coastguard Worker         int maxD        = 0;
1154*8975f5c5SAndroid Build Coastguard Worker         size_t minIndex = 0;
1155*8975f5c5SAndroid Build Coastguard Worker         size_t maxIndex = 0;
1156*8975f5c5SAndroid Build Coastguard Worker         for (size_t i = 0; i < numColors; i++)
1157*8975f5c5SAndroid Build Coastguard Worker         {
1158*8975f5c5SAndroid Build Coastguard Worker             const int count = pixelIndexCounts[i];
1159*8975f5c5SAndroid Build Coastguard Worker             if (count > 0)
1160*8975f5c5SAndroid Build Coastguard Worker             {
1161*8975f5c5SAndroid Build Coastguard Worker                 const auto &pixel = subblockColors[i];
1162*8975f5c5SAndroid Build Coastguard Worker                 if (pixel.A > 0)
1163*8975f5c5SAndroid Build Coastguard Worker                 {
1164*8975f5c5SAndroid Build Coastguard Worker                     int dot = pixel.R * vr + pixel.G * vg + pixel.B * vb;
1165*8975f5c5SAndroid Build Coastguard Worker                     if (dot < minD)
1166*8975f5c5SAndroid Build Coastguard Worker                     {
1167*8975f5c5SAndroid Build Coastguard Worker                         minD     = dot;
1168*8975f5c5SAndroid Build Coastguard Worker                         minIndex = i;
1169*8975f5c5SAndroid Build Coastguard Worker                     }
1170*8975f5c5SAndroid Build Coastguard Worker                     if (dot > maxD)
1171*8975f5c5SAndroid Build Coastguard Worker                     {
1172*8975f5c5SAndroid Build Coastguard Worker                         maxD     = dot;
1173*8975f5c5SAndroid Build Coastguard Worker                         maxIndex = i;
1174*8975f5c5SAndroid Build Coastguard Worker                     }
1175*8975f5c5SAndroid Build Coastguard Worker                 }
1176*8975f5c5SAndroid Build Coastguard Worker             }
1177*8975f5c5SAndroid Build Coastguard Worker         }
1178*8975f5c5SAndroid Build Coastguard Worker 
1179*8975f5c5SAndroid Build Coastguard Worker         *minColorIndex = static_cast<int>(minIndex);
1180*8975f5c5SAndroid Build Coastguard Worker         *maxColorIndex = static_cast<int>(maxIndex);
1181*8975f5c5SAndroid Build Coastguard Worker     }
1182*8975f5c5SAndroid Build Coastguard Worker 
transcodeIndividualOrDifferentialBlockToBC1angle::__anon4a5303920111::ETC2Block1183*8975f5c5SAndroid Build Coastguard Worker     void transcodeIndividualOrDifferentialBlockToBC1(uint8_t *dest,
1184*8975f5c5SAndroid Build Coastguard Worker                                                      size_t x,
1185*8975f5c5SAndroid Build Coastguard Worker                                                      size_t y,
1186*8975f5c5SAndroid Build Coastguard Worker                                                      size_t w,
1187*8975f5c5SAndroid Build Coastguard Worker                                                      size_t h,
1188*8975f5c5SAndroid Build Coastguard Worker                                                      int r1,
1189*8975f5c5SAndroid Build Coastguard Worker                                                      int g1,
1190*8975f5c5SAndroid Build Coastguard Worker                                                      int b1,
1191*8975f5c5SAndroid Build Coastguard Worker                                                      int r2,
1192*8975f5c5SAndroid Build Coastguard Worker                                                      int g2,
1193*8975f5c5SAndroid Build Coastguard Worker                                                      int b2,
1194*8975f5c5SAndroid Build Coastguard Worker                                                      const uint8_t alphaValues[4][4],
1195*8975f5c5SAndroid Build Coastguard Worker                                                      bool nonOpaquePunchThroughAlpha) const
1196*8975f5c5SAndroid Build Coastguard Worker     {
1197*8975f5c5SAndroid Build Coastguard Worker         // A BC1 block has 2 endpoints, pixels is encoded as linear
1198*8975f5c5SAndroid Build Coastguard Worker         // interpolations of them. A ETC1/ETC2 individual or differential block
1199*8975f5c5SAndroid Build Coastguard Worker         // has 2 subblocks. Each subblock has one color and a modifier. We
1200*8975f5c5SAndroid Build Coastguard Worker         // select axis by principal component analysis (PCA) to use as
1201*8975f5c5SAndroid Build Coastguard Worker         // our two BC1 endpoints and then map pixels to BC1 by projecting on the
1202*8975f5c5SAndroid Build Coastguard Worker         // line between the two endpoints and choosing the right fraction.
1203*8975f5c5SAndroid Build Coastguard Worker 
1204*8975f5c5SAndroid Build Coastguard Worker         // The goal of this algorithm is make it faster than decode ETC to RGBs
1205*8975f5c5SAndroid Build Coastguard Worker         //   and then encode to BC. To achieve this, we only extract subblock
1206*8975f5c5SAndroid Build Coastguard Worker         //   colors, pixel indices, and counts of each pixel indices from ETC.
1207*8975f5c5SAndroid Build Coastguard Worker         //   With those information, we can only encode used subblock colors
1208*8975f5c5SAndroid Build Coastguard Worker         //   to BC1, and copy the bits to the right pixels.
1209*8975f5c5SAndroid Build Coastguard Worker         // Fully decode and encode need to process 16 RGBA pixels. With this
1210*8975f5c5SAndroid Build Coastguard Worker         //   algorithm, it's 8 pixels at maximum for a individual or
1211*8975f5c5SAndroid Build Coastguard Worker         //   differential block. Saves us bandwidth and computations.
1212*8975f5c5SAndroid Build Coastguard Worker 
1213*8975f5c5SAndroid Build Coastguard Worker         static const size_t kNumColors = 8;
1214*8975f5c5SAndroid Build Coastguard Worker 
1215*8975f5c5SAndroid Build Coastguard Worker         const IntensityModifier *intensityModifier =
1216*8975f5c5SAndroid Build Coastguard Worker             nonOpaquePunchThroughAlpha ? intensityModifierNonOpaque : intensityModifierDefault;
1217*8975f5c5SAndroid Build Coastguard Worker 
1218*8975f5c5SAndroid Build Coastguard Worker         // Compute the colors that pixels can have in each subblock both for
1219*8975f5c5SAndroid Build Coastguard Worker         // the decoding of the RGBA data and BC1 encoding
1220*8975f5c5SAndroid Build Coastguard Worker         R8G8B8A8 subblockColors[kNumColors];
1221*8975f5c5SAndroid Build Coastguard Worker         for (size_t modifierIdx = 0; modifierIdx < 4; modifierIdx++)
1222*8975f5c5SAndroid Build Coastguard Worker         {
1223*8975f5c5SAndroid Build Coastguard Worker             if (nonOpaquePunchThroughAlpha && (modifierIdx == 2))
1224*8975f5c5SAndroid Build Coastguard Worker             {
1225*8975f5c5SAndroid Build Coastguard Worker                 // In ETC opaque punch through formats, individual and
1226*8975f5c5SAndroid Build Coastguard Worker                 // differential blocks take index 2 as transparent pixel.
1227*8975f5c5SAndroid Build Coastguard Worker                 // Thus we don't need to compute its color, just assign it
1228*8975f5c5SAndroid Build Coastguard Worker                 // as black.
1229*8975f5c5SAndroid Build Coastguard Worker                 subblockColors[modifierIdx]     = createRGBA(0, 0, 0, 0);
1230*8975f5c5SAndroid Build Coastguard Worker                 subblockColors[4 + modifierIdx] = createRGBA(0, 0, 0, 0);
1231*8975f5c5SAndroid Build Coastguard Worker             }
1232*8975f5c5SAndroid Build Coastguard Worker             else
1233*8975f5c5SAndroid Build Coastguard Worker             {
1234*8975f5c5SAndroid Build Coastguard Worker                 const int i1                = intensityModifier[u.idht.mode.idm.cw1][modifierIdx];
1235*8975f5c5SAndroid Build Coastguard Worker                 subblockColors[modifierIdx] = createRGBA(r1 + i1, g1 + i1, b1 + i1);
1236*8975f5c5SAndroid Build Coastguard Worker 
1237*8975f5c5SAndroid Build Coastguard Worker                 const int i2 = intensityModifier[u.idht.mode.idm.cw2][modifierIdx];
1238*8975f5c5SAndroid Build Coastguard Worker                 subblockColors[4 + modifierIdx] = createRGBA(r2 + i2, g2 + i2, b2 + i2);
1239*8975f5c5SAndroid Build Coastguard Worker             }
1240*8975f5c5SAndroid Build Coastguard Worker         }
1241*8975f5c5SAndroid Build Coastguard Worker 
1242*8975f5c5SAndroid Build Coastguard Worker         int pixelIndices[kNumPixelsInBlock];
1243*8975f5c5SAndroid Build Coastguard Worker         int pixelIndexCounts[kNumColors] = {0};
1244*8975f5c5SAndroid Build Coastguard Worker         // Extract pixel indices from a ETC block.
1245*8975f5c5SAndroid Build Coastguard Worker         for (size_t blockIdx = 0; blockIdx < 2; blockIdx++)
1246*8975f5c5SAndroid Build Coastguard Worker         {
1247*8975f5c5SAndroid Build Coastguard Worker             extractPixelIndices(pixelIndices, pixelIndexCounts, x, y, w, h, u.idht.mode.idm.flipbit,
1248*8975f5c5SAndroid Build Coastguard Worker                                 blockIdx);
1249*8975f5c5SAndroid Build Coastguard Worker         }
1250*8975f5c5SAndroid Build Coastguard Worker 
1251*8975f5c5SAndroid Build Coastguard Worker         int minColorIndex, maxColorIndex;
1252*8975f5c5SAndroid Build Coastguard Worker         selectEndPointPCA(pixelIndexCounts, subblockColors, kNumColors, &minColorIndex,
1253*8975f5c5SAndroid Build Coastguard Worker                           &maxColorIndex);
1254*8975f5c5SAndroid Build Coastguard Worker 
1255*8975f5c5SAndroid Build Coastguard Worker         packBC1(dest, pixelIndices, pixelIndexCounts, subblockColors, kNumColors, minColorIndex,
1256*8975f5c5SAndroid Build Coastguard Worker                 maxColorIndex, nonOpaquePunchThroughAlpha);
1257*8975f5c5SAndroid Build Coastguard Worker     }
1258*8975f5c5SAndroid Build Coastguard Worker 
transcodeTBlockToBC1angle::__anon4a5303920111::ETC2Block1259*8975f5c5SAndroid Build Coastguard Worker     void transcodeTBlockToBC1(uint8_t *dest,
1260*8975f5c5SAndroid Build Coastguard Worker                               size_t x,
1261*8975f5c5SAndroid Build Coastguard Worker                               size_t y,
1262*8975f5c5SAndroid Build Coastguard Worker                               size_t w,
1263*8975f5c5SAndroid Build Coastguard Worker                               size_t h,
1264*8975f5c5SAndroid Build Coastguard Worker                               const uint8_t alphaValues[4][4],
1265*8975f5c5SAndroid Build Coastguard Worker                               bool nonOpaquePunchThroughAlpha) const
1266*8975f5c5SAndroid Build Coastguard Worker     {
1267*8975f5c5SAndroid Build Coastguard Worker         static const size_t kNumColors = 4;
1268*8975f5c5SAndroid Build Coastguard Worker 
1269*8975f5c5SAndroid Build Coastguard Worker         // Table C.8, distance index for T and H modes
1270*8975f5c5SAndroid Build Coastguard Worker         const auto &block = u.idht.mode.tm;
1271*8975f5c5SAndroid Build Coastguard Worker 
1272*8975f5c5SAndroid Build Coastguard Worker         int r1 = extend_4to8bits(block.TR1a << 2 | block.TR1b);
1273*8975f5c5SAndroid Build Coastguard Worker         int g1 = extend_4to8bits(block.TG1);
1274*8975f5c5SAndroid Build Coastguard Worker         int b1 = extend_4to8bits(block.TB1);
1275*8975f5c5SAndroid Build Coastguard Worker         int r2 = extend_4to8bits(block.TR2);
1276*8975f5c5SAndroid Build Coastguard Worker         int g2 = extend_4to8bits(block.TG2);
1277*8975f5c5SAndroid Build Coastguard Worker         int b2 = extend_4to8bits(block.TB2);
1278*8975f5c5SAndroid Build Coastguard Worker 
1279*8975f5c5SAndroid Build Coastguard Worker         static int distance[8] = {3, 6, 11, 16, 23, 32, 41, 64};
1280*8975f5c5SAndroid Build Coastguard Worker         const int d            = distance[block.Tda << 1 | block.Tdb];
1281*8975f5c5SAndroid Build Coastguard Worker 
1282*8975f5c5SAndroid Build Coastguard Worker         // In ETC opaque punch through formats, index == 2 means transparent pixel.
1283*8975f5c5SAndroid Build Coastguard Worker         // Thus we don't need to compute its color, just assign it as black.
1284*8975f5c5SAndroid Build Coastguard Worker         const R8G8B8A8 paintColors[kNumColors] = {
1285*8975f5c5SAndroid Build Coastguard Worker             createRGBA(r1, g1, b1),
1286*8975f5c5SAndroid Build Coastguard Worker             createRGBA(r2 + d, g2 + d, b2 + d),
1287*8975f5c5SAndroid Build Coastguard Worker             nonOpaquePunchThroughAlpha ? createRGBA(0, 0, 0, 0) : createRGBA(r2, g2, b2),
1288*8975f5c5SAndroid Build Coastguard Worker             createRGBA(r2 - d, g2 - d, b2 - d),
1289*8975f5c5SAndroid Build Coastguard Worker         };
1290*8975f5c5SAndroid Build Coastguard Worker 
1291*8975f5c5SAndroid Build Coastguard Worker         int pixelIndices[kNumPixelsInBlock];
1292*8975f5c5SAndroid Build Coastguard Worker         int pixelIndexCounts[kNumColors] = {0};
1293*8975f5c5SAndroid Build Coastguard Worker         for (size_t j = 0; j < 4; j++)
1294*8975f5c5SAndroid Build Coastguard Worker         {
1295*8975f5c5SAndroid Build Coastguard Worker             int *row = &pixelIndices[j * 4];
1296*8975f5c5SAndroid Build Coastguard Worker             for (size_t i = 0; i < 4; i++)
1297*8975f5c5SAndroid Build Coastguard Worker             {
1298*8975f5c5SAndroid Build Coastguard Worker                 const size_t pixelIndex = getIndex(i, j);
1299*8975f5c5SAndroid Build Coastguard Worker                 row[i]                  = static_cast<int>(pixelIndex);
1300*8975f5c5SAndroid Build Coastguard Worker                 pixelIndexCounts[pixelIndex]++;
1301*8975f5c5SAndroid Build Coastguard Worker             }
1302*8975f5c5SAndroid Build Coastguard Worker         }
1303*8975f5c5SAndroid Build Coastguard Worker 
1304*8975f5c5SAndroid Build Coastguard Worker         int minColorIndex, maxColorIndex;
1305*8975f5c5SAndroid Build Coastguard Worker         selectEndPointPCA(pixelIndexCounts, paintColors, kNumColors, &minColorIndex,
1306*8975f5c5SAndroid Build Coastguard Worker                           &maxColorIndex);
1307*8975f5c5SAndroid Build Coastguard Worker 
1308*8975f5c5SAndroid Build Coastguard Worker         packBC1(dest, pixelIndices, pixelIndexCounts, paintColors, kNumColors, minColorIndex,
1309*8975f5c5SAndroid Build Coastguard Worker                 maxColorIndex, nonOpaquePunchThroughAlpha);
1310*8975f5c5SAndroid Build Coastguard Worker     }
1311*8975f5c5SAndroid Build Coastguard Worker 
transcodeHBlockToBC1angle::__anon4a5303920111::ETC2Block1312*8975f5c5SAndroid Build Coastguard Worker     void transcodeHBlockToBC1(uint8_t *dest,
1313*8975f5c5SAndroid Build Coastguard Worker                               size_t x,
1314*8975f5c5SAndroid Build Coastguard Worker                               size_t y,
1315*8975f5c5SAndroid Build Coastguard Worker                               size_t w,
1316*8975f5c5SAndroid Build Coastguard Worker                               size_t h,
1317*8975f5c5SAndroid Build Coastguard Worker                               const uint8_t alphaValues[4][4],
1318*8975f5c5SAndroid Build Coastguard Worker                               bool nonOpaquePunchThroughAlpha) const
1319*8975f5c5SAndroid Build Coastguard Worker     {
1320*8975f5c5SAndroid Build Coastguard Worker         static const size_t kNumColors = 4;
1321*8975f5c5SAndroid Build Coastguard Worker 
1322*8975f5c5SAndroid Build Coastguard Worker         // Table C.8, distance index for T and H modes
1323*8975f5c5SAndroid Build Coastguard Worker         const auto &block = u.idht.mode.hm;
1324*8975f5c5SAndroid Build Coastguard Worker 
1325*8975f5c5SAndroid Build Coastguard Worker         int r1 = extend_4to8bits(block.HR1);
1326*8975f5c5SAndroid Build Coastguard Worker         int g1 = extend_4to8bits(block.HG1a << 1 | block.HG1b);
1327*8975f5c5SAndroid Build Coastguard Worker         int b1 = extend_4to8bits(block.HB1a << 3 | block.HB1b << 1 | block.HB1c);
1328*8975f5c5SAndroid Build Coastguard Worker         int r2 = extend_4to8bits(block.HR2);
1329*8975f5c5SAndroid Build Coastguard Worker         int g2 = extend_4to8bits(block.HG2a << 1 | block.HG2b);
1330*8975f5c5SAndroid Build Coastguard Worker         int b2 = extend_4to8bits(block.HB2);
1331*8975f5c5SAndroid Build Coastguard Worker 
1332*8975f5c5SAndroid Build Coastguard Worker         static const int distance[8] = {3, 6, 11, 16, 23, 32, 41, 64};
1333*8975f5c5SAndroid Build Coastguard Worker         const int orderingTrickBit =
1334*8975f5c5SAndroid Build Coastguard Worker             ((r1 << 16 | g1 << 8 | b1) >= (r2 << 16 | g2 << 8 | b2) ? 1 : 0);
1335*8975f5c5SAndroid Build Coastguard Worker         const int d = distance[(block.Hda << 2) | (block.Hdb << 1) | orderingTrickBit];
1336*8975f5c5SAndroid Build Coastguard Worker 
1337*8975f5c5SAndroid Build Coastguard Worker         // In ETC opaque punch through formats, index == 2 means transparent pixel.
1338*8975f5c5SAndroid Build Coastguard Worker         // Thus we don't need to compute its color, just assign it as black.
1339*8975f5c5SAndroid Build Coastguard Worker         const R8G8B8A8 paintColors[kNumColors] = {
1340*8975f5c5SAndroid Build Coastguard Worker             createRGBA(r1 + d, g1 + d, b1 + d),
1341*8975f5c5SAndroid Build Coastguard Worker             createRGBA(r1 - d, g1 - d, b1 - d),
1342*8975f5c5SAndroid Build Coastguard Worker             nonOpaquePunchThroughAlpha ? createRGBA(0, 0, 0, 0)
1343*8975f5c5SAndroid Build Coastguard Worker                                        : createRGBA(r2 + d, g2 + d, b2 + d),
1344*8975f5c5SAndroid Build Coastguard Worker             createRGBA(r2 - d, g2 - d, b2 - d),
1345*8975f5c5SAndroid Build Coastguard Worker         };
1346*8975f5c5SAndroid Build Coastguard Worker 
1347*8975f5c5SAndroid Build Coastguard Worker         int pixelIndices[kNumPixelsInBlock];
1348*8975f5c5SAndroid Build Coastguard Worker         int pixelIndexCounts[kNumColors] = {0};
1349*8975f5c5SAndroid Build Coastguard Worker         for (size_t j = 0; j < 4; j++)
1350*8975f5c5SAndroid Build Coastguard Worker         {
1351*8975f5c5SAndroid Build Coastguard Worker             int *row = &pixelIndices[j * 4];
1352*8975f5c5SAndroid Build Coastguard Worker             for (size_t i = 0; i < 4; i++)
1353*8975f5c5SAndroid Build Coastguard Worker             {
1354*8975f5c5SAndroid Build Coastguard Worker                 const size_t pixelIndex = getIndex(i, j);
1355*8975f5c5SAndroid Build Coastguard Worker                 row[i]                  = static_cast<int>(pixelIndex);
1356*8975f5c5SAndroid Build Coastguard Worker                 pixelIndexCounts[pixelIndex]++;
1357*8975f5c5SAndroid Build Coastguard Worker             }
1358*8975f5c5SAndroid Build Coastguard Worker         }
1359*8975f5c5SAndroid Build Coastguard Worker 
1360*8975f5c5SAndroid Build Coastguard Worker         int minColorIndex, maxColorIndex;
1361*8975f5c5SAndroid Build Coastguard Worker         selectEndPointPCA(pixelIndexCounts, paintColors, kNumColors, &minColorIndex,
1362*8975f5c5SAndroid Build Coastguard Worker                           &maxColorIndex);
1363*8975f5c5SAndroid Build Coastguard Worker 
1364*8975f5c5SAndroid Build Coastguard Worker         packBC1(dest, pixelIndices, pixelIndexCounts, paintColors, kNumColors, minColorIndex,
1365*8975f5c5SAndroid Build Coastguard Worker                 maxColorIndex, nonOpaquePunchThroughAlpha);
1366*8975f5c5SAndroid Build Coastguard Worker     }
1367*8975f5c5SAndroid Build Coastguard Worker 
transcodePlanarBlockToBC1angle::__anon4a5303920111::ETC2Block1368*8975f5c5SAndroid Build Coastguard Worker     void transcodePlanarBlockToBC1(uint8_t *dest,
1369*8975f5c5SAndroid Build Coastguard Worker                                    size_t x,
1370*8975f5c5SAndroid Build Coastguard Worker                                    size_t y,
1371*8975f5c5SAndroid Build Coastguard Worker                                    size_t w,
1372*8975f5c5SAndroid Build Coastguard Worker                                    size_t h,
1373*8975f5c5SAndroid Build Coastguard Worker                                    const uint8_t alphaValues[4][4]) const
1374*8975f5c5SAndroid Build Coastguard Worker     {
1375*8975f5c5SAndroid Build Coastguard Worker         static const size_t kNumColors = kNumPixelsInBlock;
1376*8975f5c5SAndroid Build Coastguard Worker 
1377*8975f5c5SAndroid Build Coastguard Worker         R8G8B8A8 rgbaBlock[kNumColors];
1378*8975f5c5SAndroid Build Coastguard Worker         decodePlanarBlock(reinterpret_cast<uint8_t *>(rgbaBlock), x, y, w, h, sizeof(R8G8B8A8) * 4,
1379*8975f5c5SAndroid Build Coastguard Worker                           alphaValues);
1380*8975f5c5SAndroid Build Coastguard Worker 
1381*8975f5c5SAndroid Build Coastguard Worker         // Planar block doesn't have a color table, fill indices as full
1382*8975f5c5SAndroid Build Coastguard Worker         int pixelIndices[kNumPixelsInBlock] = {0, 1, 2,  3,  4,  5,  6,  7,
1383*8975f5c5SAndroid Build Coastguard Worker                                                8, 9, 10, 11, 12, 13, 14, 15};
1384*8975f5c5SAndroid Build Coastguard Worker         int pixelIndexCounts[kNumColors]    = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
1385*8975f5c5SAndroid Build Coastguard Worker 
1386*8975f5c5SAndroid Build Coastguard Worker         int minColorIndex, maxColorIndex;
1387*8975f5c5SAndroid Build Coastguard Worker         selectEndPointPCA(pixelIndexCounts, rgbaBlock, kNumColors, &minColorIndex, &maxColorIndex);
1388*8975f5c5SAndroid Build Coastguard Worker 
1389*8975f5c5SAndroid Build Coastguard Worker         packBC1(dest, pixelIndices, pixelIndexCounts, rgbaBlock, kNumColors, minColorIndex,
1390*8975f5c5SAndroid Build Coastguard Worker                 maxColorIndex, false);
1391*8975f5c5SAndroid Build Coastguard Worker     }
1392*8975f5c5SAndroid Build Coastguard Worker 
1393*8975f5c5SAndroid Build Coastguard Worker     // Single channel utility functions
getSingleEACChannelangle::__anon4a5303920111::ETC2Block1394*8975f5c5SAndroid Build Coastguard Worker     int getSingleEACChannel(size_t x, size_t y, bool isSigned) const
1395*8975f5c5SAndroid Build Coastguard Worker     {
1396*8975f5c5SAndroid Build Coastguard Worker         int codeword   = isSigned ? u.scblk.base_codeword.s : u.scblk.base_codeword.us;
1397*8975f5c5SAndroid Build Coastguard Worker         int multiplier = (u.scblk.multiplier == 0) ? 1 : u.scblk.multiplier * 8;
1398*8975f5c5SAndroid Build Coastguard Worker         return codeword * 8 + 4 + getSingleChannelModifier(x, y) * multiplier;
1399*8975f5c5SAndroid Build Coastguard Worker     }
1400*8975f5c5SAndroid Build Coastguard Worker 
getSingleETC2Channelangle::__anon4a5303920111::ETC2Block1401*8975f5c5SAndroid Build Coastguard Worker     int getSingleETC2Channel(size_t x, size_t y, bool isSigned) const
1402*8975f5c5SAndroid Build Coastguard Worker     {
1403*8975f5c5SAndroid Build Coastguard Worker         int codeword = isSigned ? u.scblk.base_codeword.s : u.scblk.base_codeword.us;
1404*8975f5c5SAndroid Build Coastguard Worker         return codeword + getSingleChannelModifier(x, y) * u.scblk.multiplier;
1405*8975f5c5SAndroid Build Coastguard Worker     }
1406*8975f5c5SAndroid Build Coastguard Worker 
getSingleChannelIndexangle::__anon4a5303920111::ETC2Block1407*8975f5c5SAndroid Build Coastguard Worker     int getSingleChannelIndex(size_t x, size_t y) const
1408*8975f5c5SAndroid Build Coastguard Worker     {
1409*8975f5c5SAndroid Build Coastguard Worker         ASSERT(x < 4 && y < 4);
1410*8975f5c5SAndroid Build Coastguard Worker 
1411*8975f5c5SAndroid Build Coastguard Worker         // clang-format off
1412*8975f5c5SAndroid Build Coastguard Worker         switch (x * 4 + y)
1413*8975f5c5SAndroid Build Coastguard Worker         {
1414*8975f5c5SAndroid Build Coastguard Worker             case 0: return u.scblk.ma;
1415*8975f5c5SAndroid Build Coastguard Worker             case 1: return u.scblk.mb;
1416*8975f5c5SAndroid Build Coastguard Worker             case 2: return u.scblk.mc1 << 1 | u.scblk.mc2;
1417*8975f5c5SAndroid Build Coastguard Worker             case 3: return u.scblk.md;
1418*8975f5c5SAndroid Build Coastguard Worker             case 4: return u.scblk.me;
1419*8975f5c5SAndroid Build Coastguard Worker             case 5: return u.scblk.mf1 << 2 | u.scblk.mf2;
1420*8975f5c5SAndroid Build Coastguard Worker             case 6: return u.scblk.mg;
1421*8975f5c5SAndroid Build Coastguard Worker             case 7: return u.scblk.mh;
1422*8975f5c5SAndroid Build Coastguard Worker             case 8: return u.scblk.mi;
1423*8975f5c5SAndroid Build Coastguard Worker             case 9: return u.scblk.mj;
1424*8975f5c5SAndroid Build Coastguard Worker             case 10: return u.scblk.mk1 << 1 | u.scblk.mk2;
1425*8975f5c5SAndroid Build Coastguard Worker             case 11: return u.scblk.ml;
1426*8975f5c5SAndroid Build Coastguard Worker             case 12: return u.scblk.mm;
1427*8975f5c5SAndroid Build Coastguard Worker             case 13: return u.scblk.mn1 << 2 | u.scblk.mn2;
1428*8975f5c5SAndroid Build Coastguard Worker             case 14: return u.scblk.mo;
1429*8975f5c5SAndroid Build Coastguard Worker             case 15: return u.scblk.mp;
1430*8975f5c5SAndroid Build Coastguard Worker             default: UNREACHABLE(); return 0;
1431*8975f5c5SAndroid Build Coastguard Worker         }
1432*8975f5c5SAndroid Build Coastguard Worker         // clang-format on
1433*8975f5c5SAndroid Build Coastguard Worker     }
1434*8975f5c5SAndroid Build Coastguard Worker 
getSingleChannelModifierangle::__anon4a5303920111::ETC2Block1435*8975f5c5SAndroid Build Coastguard Worker     int getSingleChannelModifier(size_t x, size_t y) const
1436*8975f5c5SAndroid Build Coastguard Worker     {
1437*8975f5c5SAndroid Build Coastguard Worker         // clang-format off
1438*8975f5c5SAndroid Build Coastguard Worker         static const int modifierTable[16][8] =
1439*8975f5c5SAndroid Build Coastguard Worker         {
1440*8975f5c5SAndroid Build Coastguard Worker             { -3, -6,  -9, -15, 2, 5, 8, 14 },
1441*8975f5c5SAndroid Build Coastguard Worker             { -3, -7, -10, -13, 2, 6, 9, 12 },
1442*8975f5c5SAndroid Build Coastguard Worker             { -2, -5,  -8, -13, 1, 4, 7, 12 },
1443*8975f5c5SAndroid Build Coastguard Worker             { -2, -4,  -6, -13, 1, 3, 5, 12 },
1444*8975f5c5SAndroid Build Coastguard Worker             { -3, -6,  -8, -12, 2, 5, 7, 11 },
1445*8975f5c5SAndroid Build Coastguard Worker             { -3, -7,  -9, -11, 2, 6, 8, 10 },
1446*8975f5c5SAndroid Build Coastguard Worker             { -4, -7,  -8, -11, 3, 6, 7, 10 },
1447*8975f5c5SAndroid Build Coastguard Worker             { -3, -5,  -8, -11, 2, 4, 7, 10 },
1448*8975f5c5SAndroid Build Coastguard Worker             { -2, -6,  -8, -10, 1, 5, 7,  9 },
1449*8975f5c5SAndroid Build Coastguard Worker             { -2, -5,  -8, -10, 1, 4, 7,  9 },
1450*8975f5c5SAndroid Build Coastguard Worker             { -2, -4,  -8, -10, 1, 3, 7,  9 },
1451*8975f5c5SAndroid Build Coastguard Worker             { -2, -5,  -7, -10, 1, 4, 6,  9 },
1452*8975f5c5SAndroid Build Coastguard Worker             { -3, -4,  -7, -10, 2, 3, 6,  9 },
1453*8975f5c5SAndroid Build Coastguard Worker             { -1, -2,  -3, -10, 0, 1, 2,  9 },
1454*8975f5c5SAndroid Build Coastguard Worker             { -4, -6,  -8,  -9, 3, 5, 7,  8 },
1455*8975f5c5SAndroid Build Coastguard Worker             { -3, -5,  -7,  -9, 2, 4, 6,  8 }
1456*8975f5c5SAndroid Build Coastguard Worker         };
1457*8975f5c5SAndroid Build Coastguard Worker         // clang-format on
1458*8975f5c5SAndroid Build Coastguard Worker 
1459*8975f5c5SAndroid Build Coastguard Worker         return modifierTable[u.scblk.table_index][getSingleChannelIndex(x, y)];
1460*8975f5c5SAndroid Build Coastguard Worker     }
1461*8975f5c5SAndroid Build Coastguard Worker };
1462*8975f5c5SAndroid Build Coastguard Worker 
1463*8975f5c5SAndroid Build Coastguard Worker // clang-format off
1464*8975f5c5SAndroid Build Coastguard Worker static const uint8_t DefaultETCAlphaValues[4][4] =
1465*8975f5c5SAndroid Build Coastguard Worker {
1466*8975f5c5SAndroid Build Coastguard Worker     { 255, 255, 255, 255 },
1467*8975f5c5SAndroid Build Coastguard Worker     { 255, 255, 255, 255 },
1468*8975f5c5SAndroid Build Coastguard Worker     { 255, 255, 255, 255 },
1469*8975f5c5SAndroid Build Coastguard Worker     { 255, 255, 255, 255 },
1470*8975f5c5SAndroid Build Coastguard Worker };
1471*8975f5c5SAndroid Build Coastguard Worker 
1472*8975f5c5SAndroid Build Coastguard Worker // clang-format on
LoadR11EACToR8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch,bool isSigned)1473*8975f5c5SAndroid Build Coastguard Worker void LoadR11EACToR8(const ImageLoadContext &context,
1474*8975f5c5SAndroid Build Coastguard Worker                     size_t width,
1475*8975f5c5SAndroid Build Coastguard Worker                     size_t height,
1476*8975f5c5SAndroid Build Coastguard Worker                     size_t depth,
1477*8975f5c5SAndroid Build Coastguard Worker                     const uint8_t *input,
1478*8975f5c5SAndroid Build Coastguard Worker                     size_t inputRowPitch,
1479*8975f5c5SAndroid Build Coastguard Worker                     size_t inputDepthPitch,
1480*8975f5c5SAndroid Build Coastguard Worker                     uint8_t *output,
1481*8975f5c5SAndroid Build Coastguard Worker                     size_t outputRowPitch,
1482*8975f5c5SAndroid Build Coastguard Worker                     size_t outputDepthPitch,
1483*8975f5c5SAndroid Build Coastguard Worker                     bool isSigned)
1484*8975f5c5SAndroid Build Coastguard Worker {
1485*8975f5c5SAndroid Build Coastguard Worker     for (size_t z = 0; z < depth; z++)
1486*8975f5c5SAndroid Build Coastguard Worker     {
1487*8975f5c5SAndroid Build Coastguard Worker         for (size_t y = 0; y < height; y += 4)
1488*8975f5c5SAndroid Build Coastguard Worker         {
1489*8975f5c5SAndroid Build Coastguard Worker             const ETC2Block *sourceRow =
1490*8975f5c5SAndroid Build Coastguard Worker                 priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch);
1491*8975f5c5SAndroid Build Coastguard Worker             uint8_t *destRow =
1492*8975f5c5SAndroid Build Coastguard Worker                 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
1493*8975f5c5SAndroid Build Coastguard Worker 
1494*8975f5c5SAndroid Build Coastguard Worker             for (size_t x = 0; x < width; x += 4)
1495*8975f5c5SAndroid Build Coastguard Worker             {
1496*8975f5c5SAndroid Build Coastguard Worker                 const ETC2Block *sourceBlock = sourceRow + (x / 4);
1497*8975f5c5SAndroid Build Coastguard Worker                 uint8_t *destPixels          = destRow + x;
1498*8975f5c5SAndroid Build Coastguard Worker 
1499*8975f5c5SAndroid Build Coastguard Worker                 sourceBlock->decodeAsSingleETC2Channel(destPixels, x, y, width, height, 1,
1500*8975f5c5SAndroid Build Coastguard Worker                                                        outputRowPitch, isSigned);
1501*8975f5c5SAndroid Build Coastguard Worker             }
1502*8975f5c5SAndroid Build Coastguard Worker         }
1503*8975f5c5SAndroid Build Coastguard Worker     }
1504*8975f5c5SAndroid Build Coastguard Worker }
1505*8975f5c5SAndroid Build Coastguard Worker 
LoadRG11EACToRG8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch,bool isSigned)1506*8975f5c5SAndroid Build Coastguard Worker void LoadRG11EACToRG8(const ImageLoadContext &context,
1507*8975f5c5SAndroid Build Coastguard Worker                       size_t width,
1508*8975f5c5SAndroid Build Coastguard Worker                       size_t height,
1509*8975f5c5SAndroid Build Coastguard Worker                       size_t depth,
1510*8975f5c5SAndroid Build Coastguard Worker                       const uint8_t *input,
1511*8975f5c5SAndroid Build Coastguard Worker                       size_t inputRowPitch,
1512*8975f5c5SAndroid Build Coastguard Worker                       size_t inputDepthPitch,
1513*8975f5c5SAndroid Build Coastguard Worker                       uint8_t *output,
1514*8975f5c5SAndroid Build Coastguard Worker                       size_t outputRowPitch,
1515*8975f5c5SAndroid Build Coastguard Worker                       size_t outputDepthPitch,
1516*8975f5c5SAndroid Build Coastguard Worker                       bool isSigned)
1517*8975f5c5SAndroid Build Coastguard Worker {
1518*8975f5c5SAndroid Build Coastguard Worker     for (size_t z = 0; z < depth; z++)
1519*8975f5c5SAndroid Build Coastguard Worker     {
1520*8975f5c5SAndroid Build Coastguard Worker         for (size_t y = 0; y < height; y += 4)
1521*8975f5c5SAndroid Build Coastguard Worker         {
1522*8975f5c5SAndroid Build Coastguard Worker             const ETC2Block *sourceRow =
1523*8975f5c5SAndroid Build Coastguard Worker                 priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch);
1524*8975f5c5SAndroid Build Coastguard Worker             uint8_t *destRow =
1525*8975f5c5SAndroid Build Coastguard Worker                 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
1526*8975f5c5SAndroid Build Coastguard Worker 
1527*8975f5c5SAndroid Build Coastguard Worker             for (size_t x = 0; x < width; x += 4)
1528*8975f5c5SAndroid Build Coastguard Worker             {
1529*8975f5c5SAndroid Build Coastguard Worker                 uint8_t *destPixelsRed          = destRow + (x * 2);
1530*8975f5c5SAndroid Build Coastguard Worker                 const ETC2Block *sourceBlockRed = sourceRow + (x / 2);
1531*8975f5c5SAndroid Build Coastguard Worker                 sourceBlockRed->decodeAsSingleETC2Channel(destPixelsRed, x, y, width, height, 2,
1532*8975f5c5SAndroid Build Coastguard Worker                                                           outputRowPitch, isSigned);
1533*8975f5c5SAndroid Build Coastguard Worker 
1534*8975f5c5SAndroid Build Coastguard Worker                 uint8_t *destPixelsGreen          = destPixelsRed + 1;
1535*8975f5c5SAndroid Build Coastguard Worker                 const ETC2Block *sourceBlockGreen = sourceBlockRed + 1;
1536*8975f5c5SAndroid Build Coastguard Worker                 sourceBlockGreen->decodeAsSingleETC2Channel(destPixelsGreen, x, y, width, height, 2,
1537*8975f5c5SAndroid Build Coastguard Worker                                                             outputRowPitch, isSigned);
1538*8975f5c5SAndroid Build Coastguard Worker             }
1539*8975f5c5SAndroid Build Coastguard Worker         }
1540*8975f5c5SAndroid Build Coastguard Worker     }
1541*8975f5c5SAndroid Build Coastguard Worker }
1542*8975f5c5SAndroid Build Coastguard Worker 
LoadR11EACToR16(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch,bool isSigned,bool isFloat)1543*8975f5c5SAndroid Build Coastguard Worker void LoadR11EACToR16(const ImageLoadContext &context,
1544*8975f5c5SAndroid Build Coastguard Worker                      size_t width,
1545*8975f5c5SAndroid Build Coastguard Worker                      size_t height,
1546*8975f5c5SAndroid Build Coastguard Worker                      size_t depth,
1547*8975f5c5SAndroid Build Coastguard Worker                      const uint8_t *input,
1548*8975f5c5SAndroid Build Coastguard Worker                      size_t inputRowPitch,
1549*8975f5c5SAndroid Build Coastguard Worker                      size_t inputDepthPitch,
1550*8975f5c5SAndroid Build Coastguard Worker                      uint8_t *output,
1551*8975f5c5SAndroid Build Coastguard Worker                      size_t outputRowPitch,
1552*8975f5c5SAndroid Build Coastguard Worker                      size_t outputDepthPitch,
1553*8975f5c5SAndroid Build Coastguard Worker                      bool isSigned,
1554*8975f5c5SAndroid Build Coastguard Worker                      bool isFloat)
1555*8975f5c5SAndroid Build Coastguard Worker {
1556*8975f5c5SAndroid Build Coastguard Worker     for (size_t z = 0; z < depth; z++)
1557*8975f5c5SAndroid Build Coastguard Worker     {
1558*8975f5c5SAndroid Build Coastguard Worker         for (size_t y = 0; y < height; y += 4)
1559*8975f5c5SAndroid Build Coastguard Worker         {
1560*8975f5c5SAndroid Build Coastguard Worker             const ETC2Block *sourceRow =
1561*8975f5c5SAndroid Build Coastguard Worker                 priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch);
1562*8975f5c5SAndroid Build Coastguard Worker             uint16_t *destRow =
1563*8975f5c5SAndroid Build Coastguard Worker                 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
1564*8975f5c5SAndroid Build Coastguard Worker 
1565*8975f5c5SAndroid Build Coastguard Worker             for (size_t x = 0; x < width; x += 4)
1566*8975f5c5SAndroid Build Coastguard Worker             {
1567*8975f5c5SAndroid Build Coastguard Worker                 const ETC2Block *sourceBlock = sourceRow + (x / 4);
1568*8975f5c5SAndroid Build Coastguard Worker                 uint16_t *destPixels         = destRow + x;
1569*8975f5c5SAndroid Build Coastguard Worker 
1570*8975f5c5SAndroid Build Coastguard Worker                 sourceBlock->decodeAsSingleEACChannel(destPixels, x, y, width, height, 1,
1571*8975f5c5SAndroid Build Coastguard Worker                                                       outputRowPitch, isSigned, isFloat);
1572*8975f5c5SAndroid Build Coastguard Worker             }
1573*8975f5c5SAndroid Build Coastguard Worker         }
1574*8975f5c5SAndroid Build Coastguard Worker     }
1575*8975f5c5SAndroid Build Coastguard Worker }
1576*8975f5c5SAndroid Build Coastguard Worker 
LoadRG11EACToRG16(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch,bool isSigned,bool isFloat)1577*8975f5c5SAndroid Build Coastguard Worker void LoadRG11EACToRG16(const ImageLoadContext &context,
1578*8975f5c5SAndroid Build Coastguard Worker                        size_t width,
1579*8975f5c5SAndroid Build Coastguard Worker                        size_t height,
1580*8975f5c5SAndroid Build Coastguard Worker                        size_t depth,
1581*8975f5c5SAndroid Build Coastguard Worker                        const uint8_t *input,
1582*8975f5c5SAndroid Build Coastguard Worker                        size_t inputRowPitch,
1583*8975f5c5SAndroid Build Coastguard Worker                        size_t inputDepthPitch,
1584*8975f5c5SAndroid Build Coastguard Worker                        uint8_t *output,
1585*8975f5c5SAndroid Build Coastguard Worker                        size_t outputRowPitch,
1586*8975f5c5SAndroid Build Coastguard Worker                        size_t outputDepthPitch,
1587*8975f5c5SAndroid Build Coastguard Worker                        bool isSigned,
1588*8975f5c5SAndroid Build Coastguard Worker                        bool isFloat)
1589*8975f5c5SAndroid Build Coastguard Worker {
1590*8975f5c5SAndroid Build Coastguard Worker     for (size_t z = 0; z < depth; z++)
1591*8975f5c5SAndroid Build Coastguard Worker     {
1592*8975f5c5SAndroid Build Coastguard Worker         for (size_t y = 0; y < height; y += 4)
1593*8975f5c5SAndroid Build Coastguard Worker         {
1594*8975f5c5SAndroid Build Coastguard Worker             const ETC2Block *sourceRow =
1595*8975f5c5SAndroid Build Coastguard Worker                 priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch);
1596*8975f5c5SAndroid Build Coastguard Worker             uint16_t *destRow =
1597*8975f5c5SAndroid Build Coastguard Worker                 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
1598*8975f5c5SAndroid Build Coastguard Worker 
1599*8975f5c5SAndroid Build Coastguard Worker             for (size_t x = 0; x < width; x += 4)
1600*8975f5c5SAndroid Build Coastguard Worker             {
1601*8975f5c5SAndroid Build Coastguard Worker                 uint16_t *destPixelsRed         = destRow + (x * 2);
1602*8975f5c5SAndroid Build Coastguard Worker                 const ETC2Block *sourceBlockRed = sourceRow + (x / 2);
1603*8975f5c5SAndroid Build Coastguard Worker                 sourceBlockRed->decodeAsSingleEACChannel(destPixelsRed, x, y, width, height, 2,
1604*8975f5c5SAndroid Build Coastguard Worker                                                          outputRowPitch, isSigned, isFloat);
1605*8975f5c5SAndroid Build Coastguard Worker 
1606*8975f5c5SAndroid Build Coastguard Worker                 uint16_t *destPixelsGreen         = destPixelsRed + 1;
1607*8975f5c5SAndroid Build Coastguard Worker                 const ETC2Block *sourceBlockGreen = sourceBlockRed + 1;
1608*8975f5c5SAndroid Build Coastguard Worker                 sourceBlockGreen->decodeAsSingleEACChannel(destPixelsGreen, x, y, width, height, 2,
1609*8975f5c5SAndroid Build Coastguard Worker                                                            outputRowPitch, isSigned, isFloat);
1610*8975f5c5SAndroid Build Coastguard Worker             }
1611*8975f5c5SAndroid Build Coastguard Worker         }
1612*8975f5c5SAndroid Build Coastguard Worker     }
1613*8975f5c5SAndroid Build Coastguard Worker }
1614*8975f5c5SAndroid Build Coastguard Worker 
LoadETC2RGB8ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch,bool punchthroughAlpha)1615*8975f5c5SAndroid Build Coastguard Worker void LoadETC2RGB8ToRGBA8(const ImageLoadContext &context,
1616*8975f5c5SAndroid Build Coastguard Worker                          size_t width,
1617*8975f5c5SAndroid Build Coastguard Worker                          size_t height,
1618*8975f5c5SAndroid Build Coastguard Worker                          size_t depth,
1619*8975f5c5SAndroid Build Coastguard Worker                          const uint8_t *input,
1620*8975f5c5SAndroid Build Coastguard Worker                          size_t inputRowPitch,
1621*8975f5c5SAndroid Build Coastguard Worker                          size_t inputDepthPitch,
1622*8975f5c5SAndroid Build Coastguard Worker                          uint8_t *output,
1623*8975f5c5SAndroid Build Coastguard Worker                          size_t outputRowPitch,
1624*8975f5c5SAndroid Build Coastguard Worker                          size_t outputDepthPitch,
1625*8975f5c5SAndroid Build Coastguard Worker                          bool punchthroughAlpha)
1626*8975f5c5SAndroid Build Coastguard Worker {
1627*8975f5c5SAndroid Build Coastguard Worker     for (size_t z = 0; z < depth; z++)
1628*8975f5c5SAndroid Build Coastguard Worker     {
1629*8975f5c5SAndroid Build Coastguard Worker         for (size_t y = 0; y < height; y += 4)
1630*8975f5c5SAndroid Build Coastguard Worker         {
1631*8975f5c5SAndroid Build Coastguard Worker             const ETC2Block *sourceRow =
1632*8975f5c5SAndroid Build Coastguard Worker                 priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch);
1633*8975f5c5SAndroid Build Coastguard Worker             uint8_t *destRow =
1634*8975f5c5SAndroid Build Coastguard Worker                 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
1635*8975f5c5SAndroid Build Coastguard Worker 
1636*8975f5c5SAndroid Build Coastguard Worker             for (size_t x = 0; x < width; x += 4)
1637*8975f5c5SAndroid Build Coastguard Worker             {
1638*8975f5c5SAndroid Build Coastguard Worker                 const ETC2Block *sourceBlock = sourceRow + (x / 4);
1639*8975f5c5SAndroid Build Coastguard Worker                 uint8_t *destPixels          = destRow + (x * 4);
1640*8975f5c5SAndroid Build Coastguard Worker 
1641*8975f5c5SAndroid Build Coastguard Worker                 sourceBlock->decodeAsRGB(destPixels, x, y, width, height, outputRowPitch,
1642*8975f5c5SAndroid Build Coastguard Worker                                          DefaultETCAlphaValues, punchthroughAlpha);
1643*8975f5c5SAndroid Build Coastguard Worker             }
1644*8975f5c5SAndroid Build Coastguard Worker         }
1645*8975f5c5SAndroid Build Coastguard Worker     }
1646*8975f5c5SAndroid Build Coastguard Worker }
1647*8975f5c5SAndroid Build Coastguard Worker 
LoadETC2RGB8ToBC1(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch,bool punchthroughAlpha)1648*8975f5c5SAndroid Build Coastguard Worker void LoadETC2RGB8ToBC1(const ImageLoadContext &context,
1649*8975f5c5SAndroid Build Coastguard Worker                        size_t width,
1650*8975f5c5SAndroid Build Coastguard Worker                        size_t height,
1651*8975f5c5SAndroid Build Coastguard Worker                        size_t depth,
1652*8975f5c5SAndroid Build Coastguard Worker                        const uint8_t *input,
1653*8975f5c5SAndroid Build Coastguard Worker                        size_t inputRowPitch,
1654*8975f5c5SAndroid Build Coastguard Worker                        size_t inputDepthPitch,
1655*8975f5c5SAndroid Build Coastguard Worker                        uint8_t *output,
1656*8975f5c5SAndroid Build Coastguard Worker                        size_t outputRowPitch,
1657*8975f5c5SAndroid Build Coastguard Worker                        size_t outputDepthPitch,
1658*8975f5c5SAndroid Build Coastguard Worker                        bool punchthroughAlpha)
1659*8975f5c5SAndroid Build Coastguard Worker {
1660*8975f5c5SAndroid Build Coastguard Worker     for (size_t z = 0; z < depth; z++)
1661*8975f5c5SAndroid Build Coastguard Worker     {
1662*8975f5c5SAndroid Build Coastguard Worker         for (size_t y = 0; y < height; y += 4)
1663*8975f5c5SAndroid Build Coastguard Worker         {
1664*8975f5c5SAndroid Build Coastguard Worker             const ETC2Block *sourceRow =
1665*8975f5c5SAndroid Build Coastguard Worker                 priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch);
1666*8975f5c5SAndroid Build Coastguard Worker             uint8_t *destRow = priv::OffsetDataPointer<uint8_t>(output, y / 4, z, outputRowPitch,
1667*8975f5c5SAndroid Build Coastguard Worker                                                                 outputDepthPitch);
1668*8975f5c5SAndroid Build Coastguard Worker 
1669*8975f5c5SAndroid Build Coastguard Worker             for (size_t x = 0; x < width; x += 4)
1670*8975f5c5SAndroid Build Coastguard Worker             {
1671*8975f5c5SAndroid Build Coastguard Worker                 const ETC2Block *sourceBlock = sourceRow + (x / 4);
1672*8975f5c5SAndroid Build Coastguard Worker                 uint8_t *destPixels          = destRow + (x * 2);
1673*8975f5c5SAndroid Build Coastguard Worker 
1674*8975f5c5SAndroid Build Coastguard Worker                 sourceBlock->transcodeAsBC1(destPixels, x, y, width, height, DefaultETCAlphaValues,
1675*8975f5c5SAndroid Build Coastguard Worker                                             punchthroughAlpha);
1676*8975f5c5SAndroid Build Coastguard Worker             }
1677*8975f5c5SAndroid Build Coastguard Worker         }
1678*8975f5c5SAndroid Build Coastguard Worker     }
1679*8975f5c5SAndroid Build Coastguard Worker }
1680*8975f5c5SAndroid Build Coastguard Worker 
LoadETC2RGBA8ToBC3(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch,bool punchthroughAlpha,bool isSigned)1681*8975f5c5SAndroid Build Coastguard Worker void LoadETC2RGBA8ToBC3(const ImageLoadContext &context,
1682*8975f5c5SAndroid Build Coastguard Worker                         size_t width,
1683*8975f5c5SAndroid Build Coastguard Worker                         size_t height,
1684*8975f5c5SAndroid Build Coastguard Worker                         size_t depth,
1685*8975f5c5SAndroid Build Coastguard Worker                         const uint8_t *input,
1686*8975f5c5SAndroid Build Coastguard Worker                         size_t inputRowPitch,
1687*8975f5c5SAndroid Build Coastguard Worker                         size_t inputDepthPitch,
1688*8975f5c5SAndroid Build Coastguard Worker                         uint8_t *output,
1689*8975f5c5SAndroid Build Coastguard Worker                         size_t outputRowPitch,
1690*8975f5c5SAndroid Build Coastguard Worker                         size_t outputDepthPitch,
1691*8975f5c5SAndroid Build Coastguard Worker                         bool punchthroughAlpha,
1692*8975f5c5SAndroid Build Coastguard Worker                         bool isSigned)
1693*8975f5c5SAndroid Build Coastguard Worker {
1694*8975f5c5SAndroid Build Coastguard Worker     for (size_t z = 0; z < depth; z++)
1695*8975f5c5SAndroid Build Coastguard Worker     {
1696*8975f5c5SAndroid Build Coastguard Worker         for (size_t y = 0; y < height; y += 4)
1697*8975f5c5SAndroid Build Coastguard Worker         {
1698*8975f5c5SAndroid Build Coastguard Worker             const ETC2Block *sourceRow =
1699*8975f5c5SAndroid Build Coastguard Worker                 priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch);
1700*8975f5c5SAndroid Build Coastguard Worker             uint8_t *destRow = priv::OffsetDataPointer<uint8_t>(output, y / 4, z, outputRowPitch,
1701*8975f5c5SAndroid Build Coastguard Worker                                                                 outputDepthPitch);
1702*8975f5c5SAndroid Build Coastguard Worker 
1703*8975f5c5SAndroid Build Coastguard Worker             for (size_t x = 0; x < width; x += 4)
1704*8975f5c5SAndroid Build Coastguard Worker             {
1705*8975f5c5SAndroid Build Coastguard Worker                 const ETC2Block *sourceAlphaBlock = sourceRow + (x / 4) * 2;
1706*8975f5c5SAndroid Build Coastguard Worker                 uint8_t *destAlphaPixels          = destRow + (x * 4);
1707*8975f5c5SAndroid Build Coastguard Worker 
1708*8975f5c5SAndroid Build Coastguard Worker                 const ETC2Block *sourceRgbBlock = sourceAlphaBlock + 1;
1709*8975f5c5SAndroid Build Coastguard Worker                 uint8_t *destRgbPixels          = destAlphaPixels + 8;
1710*8975f5c5SAndroid Build Coastguard Worker 
1711*8975f5c5SAndroid Build Coastguard Worker                 sourceRgbBlock->transcodeAsBC1(destRgbPixels, x, y, width, height,
1712*8975f5c5SAndroid Build Coastguard Worker                                                DefaultETCAlphaValues, punchthroughAlpha);
1713*8975f5c5SAndroid Build Coastguard Worker 
1714*8975f5c5SAndroid Build Coastguard Worker                 sourceAlphaBlock->transcodeAsBC4(destAlphaPixels, x, y, width, height, isSigned);
1715*8975f5c5SAndroid Build Coastguard Worker             }
1716*8975f5c5SAndroid Build Coastguard Worker         }
1717*8975f5c5SAndroid Build Coastguard Worker     }
1718*8975f5c5SAndroid Build Coastguard Worker }
1719*8975f5c5SAndroid Build Coastguard Worker 
LoadETC2RGBA8ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch,bool srgb)1720*8975f5c5SAndroid Build Coastguard Worker void LoadETC2RGBA8ToRGBA8(const ImageLoadContext &context,
1721*8975f5c5SAndroid Build Coastguard Worker                           size_t width,
1722*8975f5c5SAndroid Build Coastguard Worker                           size_t height,
1723*8975f5c5SAndroid Build Coastguard Worker                           size_t depth,
1724*8975f5c5SAndroid Build Coastguard Worker                           const uint8_t *input,
1725*8975f5c5SAndroid Build Coastguard Worker                           size_t inputRowPitch,
1726*8975f5c5SAndroid Build Coastguard Worker                           size_t inputDepthPitch,
1727*8975f5c5SAndroid Build Coastguard Worker                           uint8_t *output,
1728*8975f5c5SAndroid Build Coastguard Worker                           size_t outputRowPitch,
1729*8975f5c5SAndroid Build Coastguard Worker                           size_t outputDepthPitch,
1730*8975f5c5SAndroid Build Coastguard Worker                           bool srgb)
1731*8975f5c5SAndroid Build Coastguard Worker {
1732*8975f5c5SAndroid Build Coastguard Worker     uint8_t decodedAlphaValues[4][4];
1733*8975f5c5SAndroid Build Coastguard Worker 
1734*8975f5c5SAndroid Build Coastguard Worker     for (size_t z = 0; z < depth; z++)
1735*8975f5c5SAndroid Build Coastguard Worker     {
1736*8975f5c5SAndroid Build Coastguard Worker         for (size_t y = 0; y < height; y += 4)
1737*8975f5c5SAndroid Build Coastguard Worker         {
1738*8975f5c5SAndroid Build Coastguard Worker             const ETC2Block *sourceRow =
1739*8975f5c5SAndroid Build Coastguard Worker                 priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch);
1740*8975f5c5SAndroid Build Coastguard Worker             uint8_t *destRow =
1741*8975f5c5SAndroid Build Coastguard Worker                 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
1742*8975f5c5SAndroid Build Coastguard Worker 
1743*8975f5c5SAndroid Build Coastguard Worker             for (size_t x = 0; x < width; x += 4)
1744*8975f5c5SAndroid Build Coastguard Worker             {
1745*8975f5c5SAndroid Build Coastguard Worker                 const ETC2Block *sourceBlockAlpha = sourceRow + (x / 2);
1746*8975f5c5SAndroid Build Coastguard Worker                 sourceBlockAlpha->decodeAsSingleETC2Channel(
1747*8975f5c5SAndroid Build Coastguard Worker                     reinterpret_cast<uint8_t *>(decodedAlphaValues), x, y, width, height, 1, 4,
1748*8975f5c5SAndroid Build Coastguard Worker                     false);
1749*8975f5c5SAndroid Build Coastguard Worker 
1750*8975f5c5SAndroid Build Coastguard Worker                 uint8_t *destPixels             = destRow + (x * 4);
1751*8975f5c5SAndroid Build Coastguard Worker                 const ETC2Block *sourceBlockRGB = sourceBlockAlpha + 1;
1752*8975f5c5SAndroid Build Coastguard Worker                 sourceBlockRGB->decodeAsRGB(destPixels, x, y, width, height, outputRowPitch,
1753*8975f5c5SAndroid Build Coastguard Worker                                             decodedAlphaValues, false);
1754*8975f5c5SAndroid Build Coastguard Worker             }
1755*8975f5c5SAndroid Build Coastguard Worker         }
1756*8975f5c5SAndroid Build Coastguard Worker     }
1757*8975f5c5SAndroid Build Coastguard Worker }
1758*8975f5c5SAndroid Build Coastguard Worker 
1759*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
1760*8975f5c5SAndroid Build Coastguard Worker 
LoadETC1RGB8ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1761*8975f5c5SAndroid Build Coastguard Worker void LoadETC1RGB8ToRGBA8(const ImageLoadContext &context,
1762*8975f5c5SAndroid Build Coastguard Worker                          size_t width,
1763*8975f5c5SAndroid Build Coastguard Worker                          size_t height,
1764*8975f5c5SAndroid Build Coastguard Worker                          size_t depth,
1765*8975f5c5SAndroid Build Coastguard Worker                          const uint8_t *input,
1766*8975f5c5SAndroid Build Coastguard Worker                          size_t inputRowPitch,
1767*8975f5c5SAndroid Build Coastguard Worker                          size_t inputDepthPitch,
1768*8975f5c5SAndroid Build Coastguard Worker                          uint8_t *output,
1769*8975f5c5SAndroid Build Coastguard Worker                          size_t outputRowPitch,
1770*8975f5c5SAndroid Build Coastguard Worker                          size_t outputDepthPitch)
1771*8975f5c5SAndroid Build Coastguard Worker {
1772*8975f5c5SAndroid Build Coastguard Worker     LoadETC2RGB8ToRGBA8(context, width, height, depth, input, inputRowPitch, inputDepthPitch,
1773*8975f5c5SAndroid Build Coastguard Worker                         output, outputRowPitch, outputDepthPitch, false);
1774*8975f5c5SAndroid Build Coastguard Worker }
1775*8975f5c5SAndroid Build Coastguard Worker 
LoadETC1RGB8ToBC1(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1776*8975f5c5SAndroid Build Coastguard Worker void LoadETC1RGB8ToBC1(const ImageLoadContext &context,
1777*8975f5c5SAndroid Build Coastguard Worker                        size_t width,
1778*8975f5c5SAndroid Build Coastguard Worker                        size_t height,
1779*8975f5c5SAndroid Build Coastguard Worker                        size_t depth,
1780*8975f5c5SAndroid Build Coastguard Worker                        const uint8_t *input,
1781*8975f5c5SAndroid Build Coastguard Worker                        size_t inputRowPitch,
1782*8975f5c5SAndroid Build Coastguard Worker                        size_t inputDepthPitch,
1783*8975f5c5SAndroid Build Coastguard Worker                        uint8_t *output,
1784*8975f5c5SAndroid Build Coastguard Worker                        size_t outputRowPitch,
1785*8975f5c5SAndroid Build Coastguard Worker                        size_t outputDepthPitch)
1786*8975f5c5SAndroid Build Coastguard Worker {
1787*8975f5c5SAndroid Build Coastguard Worker     LoadETC2RGB8ToBC1(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
1788*8975f5c5SAndroid Build Coastguard Worker                       outputRowPitch, outputDepthPitch, false);
1789*8975f5c5SAndroid Build Coastguard Worker }
1790*8975f5c5SAndroid Build Coastguard Worker 
LoadEACR11ToR8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1791*8975f5c5SAndroid Build Coastguard Worker void LoadEACR11ToR8(const ImageLoadContext &context,
1792*8975f5c5SAndroid Build Coastguard Worker                     size_t width,
1793*8975f5c5SAndroid Build Coastguard Worker                     size_t height,
1794*8975f5c5SAndroid Build Coastguard Worker                     size_t depth,
1795*8975f5c5SAndroid Build Coastguard Worker                     const uint8_t *input,
1796*8975f5c5SAndroid Build Coastguard Worker                     size_t inputRowPitch,
1797*8975f5c5SAndroid Build Coastguard Worker                     size_t inputDepthPitch,
1798*8975f5c5SAndroid Build Coastguard Worker                     uint8_t *output,
1799*8975f5c5SAndroid Build Coastguard Worker                     size_t outputRowPitch,
1800*8975f5c5SAndroid Build Coastguard Worker                     size_t outputDepthPitch)
1801*8975f5c5SAndroid Build Coastguard Worker {
1802*8975f5c5SAndroid Build Coastguard Worker     LoadR11EACToR8(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
1803*8975f5c5SAndroid Build Coastguard Worker                    outputRowPitch, outputDepthPitch, false);
1804*8975f5c5SAndroid Build Coastguard Worker }
1805*8975f5c5SAndroid Build Coastguard Worker 
LoadEACR11SToR8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1806*8975f5c5SAndroid Build Coastguard Worker void LoadEACR11SToR8(const ImageLoadContext &context,
1807*8975f5c5SAndroid Build Coastguard Worker                      size_t width,
1808*8975f5c5SAndroid Build Coastguard Worker                      size_t height,
1809*8975f5c5SAndroid Build Coastguard Worker                      size_t depth,
1810*8975f5c5SAndroid Build Coastguard Worker                      const uint8_t *input,
1811*8975f5c5SAndroid Build Coastguard Worker                      size_t inputRowPitch,
1812*8975f5c5SAndroid Build Coastguard Worker                      size_t inputDepthPitch,
1813*8975f5c5SAndroid Build Coastguard Worker                      uint8_t *output,
1814*8975f5c5SAndroid Build Coastguard Worker                      size_t outputRowPitch,
1815*8975f5c5SAndroid Build Coastguard Worker                      size_t outputDepthPitch)
1816*8975f5c5SAndroid Build Coastguard Worker {
1817*8975f5c5SAndroid Build Coastguard Worker     LoadR11EACToR8(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
1818*8975f5c5SAndroid Build Coastguard Worker                    outputRowPitch, outputDepthPitch, true);
1819*8975f5c5SAndroid Build Coastguard Worker }
1820*8975f5c5SAndroid Build Coastguard Worker 
LoadEACRG11ToRG8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1821*8975f5c5SAndroid Build Coastguard Worker void LoadEACRG11ToRG8(const ImageLoadContext &context,
1822*8975f5c5SAndroid Build Coastguard Worker                       size_t width,
1823*8975f5c5SAndroid Build Coastguard Worker                       size_t height,
1824*8975f5c5SAndroid Build Coastguard Worker                       size_t depth,
1825*8975f5c5SAndroid Build Coastguard Worker                       const uint8_t *input,
1826*8975f5c5SAndroid Build Coastguard Worker                       size_t inputRowPitch,
1827*8975f5c5SAndroid Build Coastguard Worker                       size_t inputDepthPitch,
1828*8975f5c5SAndroid Build Coastguard Worker                       uint8_t *output,
1829*8975f5c5SAndroid Build Coastguard Worker                       size_t outputRowPitch,
1830*8975f5c5SAndroid Build Coastguard Worker                       size_t outputDepthPitch)
1831*8975f5c5SAndroid Build Coastguard Worker {
1832*8975f5c5SAndroid Build Coastguard Worker     LoadRG11EACToRG8(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
1833*8975f5c5SAndroid Build Coastguard Worker                      outputRowPitch, outputDepthPitch, false);
1834*8975f5c5SAndroid Build Coastguard Worker }
1835*8975f5c5SAndroid Build Coastguard Worker 
LoadEACRG11SToRG8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1836*8975f5c5SAndroid Build Coastguard Worker void LoadEACRG11SToRG8(const ImageLoadContext &context,
1837*8975f5c5SAndroid Build Coastguard Worker                        size_t width,
1838*8975f5c5SAndroid Build Coastguard Worker                        size_t height,
1839*8975f5c5SAndroid Build Coastguard Worker                        size_t depth,
1840*8975f5c5SAndroid Build Coastguard Worker                        const uint8_t *input,
1841*8975f5c5SAndroid Build Coastguard Worker                        size_t inputRowPitch,
1842*8975f5c5SAndroid Build Coastguard Worker                        size_t inputDepthPitch,
1843*8975f5c5SAndroid Build Coastguard Worker                        uint8_t *output,
1844*8975f5c5SAndroid Build Coastguard Worker                        size_t outputRowPitch,
1845*8975f5c5SAndroid Build Coastguard Worker                        size_t outputDepthPitch)
1846*8975f5c5SAndroid Build Coastguard Worker {
1847*8975f5c5SAndroid Build Coastguard Worker     LoadRG11EACToRG8(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
1848*8975f5c5SAndroid Build Coastguard Worker                      outputRowPitch, outputDepthPitch, true);
1849*8975f5c5SAndroid Build Coastguard Worker }
1850*8975f5c5SAndroid Build Coastguard Worker 
LoadEACR11ToR16(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1851*8975f5c5SAndroid Build Coastguard Worker void LoadEACR11ToR16(const ImageLoadContext &context,
1852*8975f5c5SAndroid Build Coastguard Worker                      size_t width,
1853*8975f5c5SAndroid Build Coastguard Worker                      size_t height,
1854*8975f5c5SAndroid Build Coastguard Worker                      size_t depth,
1855*8975f5c5SAndroid Build Coastguard Worker                      const uint8_t *input,
1856*8975f5c5SAndroid Build Coastguard Worker                      size_t inputRowPitch,
1857*8975f5c5SAndroid Build Coastguard Worker                      size_t inputDepthPitch,
1858*8975f5c5SAndroid Build Coastguard Worker                      uint8_t *output,
1859*8975f5c5SAndroid Build Coastguard Worker                      size_t outputRowPitch,
1860*8975f5c5SAndroid Build Coastguard Worker                      size_t outputDepthPitch)
1861*8975f5c5SAndroid Build Coastguard Worker {
1862*8975f5c5SAndroid Build Coastguard Worker     LoadR11EACToR16(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
1863*8975f5c5SAndroid Build Coastguard Worker                     outputRowPitch, outputDepthPitch, false, false);
1864*8975f5c5SAndroid Build Coastguard Worker }
1865*8975f5c5SAndroid Build Coastguard Worker 
LoadEACR11SToR16(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1866*8975f5c5SAndroid Build Coastguard Worker void LoadEACR11SToR16(const ImageLoadContext &context,
1867*8975f5c5SAndroid Build Coastguard Worker                       size_t width,
1868*8975f5c5SAndroid Build Coastguard Worker                       size_t height,
1869*8975f5c5SAndroid Build Coastguard Worker                       size_t depth,
1870*8975f5c5SAndroid Build Coastguard Worker                       const uint8_t *input,
1871*8975f5c5SAndroid Build Coastguard Worker                       size_t inputRowPitch,
1872*8975f5c5SAndroid Build Coastguard Worker                       size_t inputDepthPitch,
1873*8975f5c5SAndroid Build Coastguard Worker                       uint8_t *output,
1874*8975f5c5SAndroid Build Coastguard Worker                       size_t outputRowPitch,
1875*8975f5c5SAndroid Build Coastguard Worker                       size_t outputDepthPitch)
1876*8975f5c5SAndroid Build Coastguard Worker {
1877*8975f5c5SAndroid Build Coastguard Worker     LoadR11EACToR16(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
1878*8975f5c5SAndroid Build Coastguard Worker                     outputRowPitch, outputDepthPitch, true, false);
1879*8975f5c5SAndroid Build Coastguard Worker }
1880*8975f5c5SAndroid Build Coastguard Worker 
LoadEACRG11ToRG16(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1881*8975f5c5SAndroid Build Coastguard Worker void LoadEACRG11ToRG16(const ImageLoadContext &context,
1882*8975f5c5SAndroid Build Coastguard Worker                        size_t width,
1883*8975f5c5SAndroid Build Coastguard Worker                        size_t height,
1884*8975f5c5SAndroid Build Coastguard Worker                        size_t depth,
1885*8975f5c5SAndroid Build Coastguard Worker                        const uint8_t *input,
1886*8975f5c5SAndroid Build Coastguard Worker                        size_t inputRowPitch,
1887*8975f5c5SAndroid Build Coastguard Worker                        size_t inputDepthPitch,
1888*8975f5c5SAndroid Build Coastguard Worker                        uint8_t *output,
1889*8975f5c5SAndroid Build Coastguard Worker                        size_t outputRowPitch,
1890*8975f5c5SAndroid Build Coastguard Worker                        size_t outputDepthPitch)
1891*8975f5c5SAndroid Build Coastguard Worker {
1892*8975f5c5SAndroid Build Coastguard Worker     LoadRG11EACToRG16(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
1893*8975f5c5SAndroid Build Coastguard Worker                       outputRowPitch, outputDepthPitch, false, false);
1894*8975f5c5SAndroid Build Coastguard Worker }
1895*8975f5c5SAndroid Build Coastguard Worker 
LoadEACRG11SToRG16(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1896*8975f5c5SAndroid Build Coastguard Worker void LoadEACRG11SToRG16(const ImageLoadContext &context,
1897*8975f5c5SAndroid Build Coastguard Worker                         size_t width,
1898*8975f5c5SAndroid Build Coastguard Worker                         size_t height,
1899*8975f5c5SAndroid Build Coastguard Worker                         size_t depth,
1900*8975f5c5SAndroid Build Coastguard Worker                         const uint8_t *input,
1901*8975f5c5SAndroid Build Coastguard Worker                         size_t inputRowPitch,
1902*8975f5c5SAndroid Build Coastguard Worker                         size_t inputDepthPitch,
1903*8975f5c5SAndroid Build Coastguard Worker                         uint8_t *output,
1904*8975f5c5SAndroid Build Coastguard Worker                         size_t outputRowPitch,
1905*8975f5c5SAndroid Build Coastguard Worker                         size_t outputDepthPitch)
1906*8975f5c5SAndroid Build Coastguard Worker {
1907*8975f5c5SAndroid Build Coastguard Worker     LoadRG11EACToRG16(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
1908*8975f5c5SAndroid Build Coastguard Worker                       outputRowPitch, outputDepthPitch, true, false);
1909*8975f5c5SAndroid Build Coastguard Worker }
1910*8975f5c5SAndroid Build Coastguard Worker 
LoadEACR11ToR16F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1911*8975f5c5SAndroid Build Coastguard Worker void LoadEACR11ToR16F(const ImageLoadContext &context,
1912*8975f5c5SAndroid Build Coastguard Worker                       size_t width,
1913*8975f5c5SAndroid Build Coastguard Worker                       size_t height,
1914*8975f5c5SAndroid Build Coastguard Worker                       size_t depth,
1915*8975f5c5SAndroid Build Coastguard Worker                       const uint8_t *input,
1916*8975f5c5SAndroid Build Coastguard Worker                       size_t inputRowPitch,
1917*8975f5c5SAndroid Build Coastguard Worker                       size_t inputDepthPitch,
1918*8975f5c5SAndroid Build Coastguard Worker                       uint8_t *output,
1919*8975f5c5SAndroid Build Coastguard Worker                       size_t outputRowPitch,
1920*8975f5c5SAndroid Build Coastguard Worker                       size_t outputDepthPitch)
1921*8975f5c5SAndroid Build Coastguard Worker {
1922*8975f5c5SAndroid Build Coastguard Worker     LoadR11EACToR16(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
1923*8975f5c5SAndroid Build Coastguard Worker                     outputRowPitch, outputDepthPitch, false, true);
1924*8975f5c5SAndroid Build Coastguard Worker }
1925*8975f5c5SAndroid Build Coastguard Worker 
LoadEACR11SToR16F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1926*8975f5c5SAndroid Build Coastguard Worker void LoadEACR11SToR16F(const ImageLoadContext &context,
1927*8975f5c5SAndroid Build Coastguard Worker                        size_t width,
1928*8975f5c5SAndroid Build Coastguard Worker                        size_t height,
1929*8975f5c5SAndroid Build Coastguard Worker                        size_t depth,
1930*8975f5c5SAndroid Build Coastguard Worker                        const uint8_t *input,
1931*8975f5c5SAndroid Build Coastguard Worker                        size_t inputRowPitch,
1932*8975f5c5SAndroid Build Coastguard Worker                        size_t inputDepthPitch,
1933*8975f5c5SAndroid Build Coastguard Worker                        uint8_t *output,
1934*8975f5c5SAndroid Build Coastguard Worker                        size_t outputRowPitch,
1935*8975f5c5SAndroid Build Coastguard Worker                        size_t outputDepthPitch)
1936*8975f5c5SAndroid Build Coastguard Worker {
1937*8975f5c5SAndroid Build Coastguard Worker     LoadR11EACToR16(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
1938*8975f5c5SAndroid Build Coastguard Worker                     outputRowPitch, outputDepthPitch, true, true);
1939*8975f5c5SAndroid Build Coastguard Worker }
1940*8975f5c5SAndroid Build Coastguard Worker 
LoadEACRG11ToRG16F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1941*8975f5c5SAndroid Build Coastguard Worker void LoadEACRG11ToRG16F(const ImageLoadContext &context,
1942*8975f5c5SAndroid Build Coastguard Worker                         size_t width,
1943*8975f5c5SAndroid Build Coastguard Worker                         size_t height,
1944*8975f5c5SAndroid Build Coastguard Worker                         size_t depth,
1945*8975f5c5SAndroid Build Coastguard Worker                         const uint8_t *input,
1946*8975f5c5SAndroid Build Coastguard Worker                         size_t inputRowPitch,
1947*8975f5c5SAndroid Build Coastguard Worker                         size_t inputDepthPitch,
1948*8975f5c5SAndroid Build Coastguard Worker                         uint8_t *output,
1949*8975f5c5SAndroid Build Coastguard Worker                         size_t outputRowPitch,
1950*8975f5c5SAndroid Build Coastguard Worker                         size_t outputDepthPitch)
1951*8975f5c5SAndroid Build Coastguard Worker {
1952*8975f5c5SAndroid Build Coastguard Worker     LoadRG11EACToRG16(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
1953*8975f5c5SAndroid Build Coastguard Worker                       outputRowPitch, outputDepthPitch, false, true);
1954*8975f5c5SAndroid Build Coastguard Worker }
1955*8975f5c5SAndroid Build Coastguard Worker 
LoadEACRG11SToRG16F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1956*8975f5c5SAndroid Build Coastguard Worker void LoadEACRG11SToRG16F(const ImageLoadContext &context,
1957*8975f5c5SAndroid Build Coastguard Worker                          size_t width,
1958*8975f5c5SAndroid Build Coastguard Worker                          size_t height,
1959*8975f5c5SAndroid Build Coastguard Worker                          size_t depth,
1960*8975f5c5SAndroid Build Coastguard Worker                          const uint8_t *input,
1961*8975f5c5SAndroid Build Coastguard Worker                          size_t inputRowPitch,
1962*8975f5c5SAndroid Build Coastguard Worker                          size_t inputDepthPitch,
1963*8975f5c5SAndroid Build Coastguard Worker                          uint8_t *output,
1964*8975f5c5SAndroid Build Coastguard Worker                          size_t outputRowPitch,
1965*8975f5c5SAndroid Build Coastguard Worker                          size_t outputDepthPitch)
1966*8975f5c5SAndroid Build Coastguard Worker {
1967*8975f5c5SAndroid Build Coastguard Worker     LoadRG11EACToRG16(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
1968*8975f5c5SAndroid Build Coastguard Worker                       outputRowPitch, outputDepthPitch, true, true);
1969*8975f5c5SAndroid Build Coastguard Worker }
1970*8975f5c5SAndroid Build Coastguard Worker 
LoadETC2RGB8ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1971*8975f5c5SAndroid Build Coastguard Worker void LoadETC2RGB8ToRGBA8(const ImageLoadContext &context,
1972*8975f5c5SAndroid Build Coastguard Worker                          size_t width,
1973*8975f5c5SAndroid Build Coastguard Worker                          size_t height,
1974*8975f5c5SAndroid Build Coastguard Worker                          size_t depth,
1975*8975f5c5SAndroid Build Coastguard Worker                          const uint8_t *input,
1976*8975f5c5SAndroid Build Coastguard Worker                          size_t inputRowPitch,
1977*8975f5c5SAndroid Build Coastguard Worker                          size_t inputDepthPitch,
1978*8975f5c5SAndroid Build Coastguard Worker                          uint8_t *output,
1979*8975f5c5SAndroid Build Coastguard Worker                          size_t outputRowPitch,
1980*8975f5c5SAndroid Build Coastguard Worker                          size_t outputDepthPitch)
1981*8975f5c5SAndroid Build Coastguard Worker {
1982*8975f5c5SAndroid Build Coastguard Worker     LoadETC2RGB8ToRGBA8(context, width, height, depth, input, inputRowPitch, inputDepthPitch,
1983*8975f5c5SAndroid Build Coastguard Worker                         output, outputRowPitch, outputDepthPitch, false);
1984*8975f5c5SAndroid Build Coastguard Worker }
1985*8975f5c5SAndroid Build Coastguard Worker 
LoadETC2RGB8ToBC1(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1986*8975f5c5SAndroid Build Coastguard Worker void LoadETC2RGB8ToBC1(const ImageLoadContext &context,
1987*8975f5c5SAndroid Build Coastguard Worker                        size_t width,
1988*8975f5c5SAndroid Build Coastguard Worker                        size_t height,
1989*8975f5c5SAndroid Build Coastguard Worker                        size_t depth,
1990*8975f5c5SAndroid Build Coastguard Worker                        const uint8_t *input,
1991*8975f5c5SAndroid Build Coastguard Worker                        size_t inputRowPitch,
1992*8975f5c5SAndroid Build Coastguard Worker                        size_t inputDepthPitch,
1993*8975f5c5SAndroid Build Coastguard Worker                        uint8_t *output,
1994*8975f5c5SAndroid Build Coastguard Worker                        size_t outputRowPitch,
1995*8975f5c5SAndroid Build Coastguard Worker                        size_t outputDepthPitch)
1996*8975f5c5SAndroid Build Coastguard Worker {
1997*8975f5c5SAndroid Build Coastguard Worker     LoadETC2RGB8ToBC1(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
1998*8975f5c5SAndroid Build Coastguard Worker                       outputRowPitch, outputDepthPitch, false);
1999*8975f5c5SAndroid Build Coastguard Worker }
2000*8975f5c5SAndroid Build Coastguard Worker 
LoadETC2SRGB8ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)2001*8975f5c5SAndroid Build Coastguard Worker void LoadETC2SRGB8ToRGBA8(const ImageLoadContext &context,
2002*8975f5c5SAndroid Build Coastguard Worker                           size_t width,
2003*8975f5c5SAndroid Build Coastguard Worker                           size_t height,
2004*8975f5c5SAndroid Build Coastguard Worker                           size_t depth,
2005*8975f5c5SAndroid Build Coastguard Worker                           const uint8_t *input,
2006*8975f5c5SAndroid Build Coastguard Worker                           size_t inputRowPitch,
2007*8975f5c5SAndroid Build Coastguard Worker                           size_t inputDepthPitch,
2008*8975f5c5SAndroid Build Coastguard Worker                           uint8_t *output,
2009*8975f5c5SAndroid Build Coastguard Worker                           size_t outputRowPitch,
2010*8975f5c5SAndroid Build Coastguard Worker                           size_t outputDepthPitch)
2011*8975f5c5SAndroid Build Coastguard Worker {
2012*8975f5c5SAndroid Build Coastguard Worker     LoadETC2RGB8ToRGBA8(context, width, height, depth, input, inputRowPitch, inputDepthPitch,
2013*8975f5c5SAndroid Build Coastguard Worker                         output, outputRowPitch, outputDepthPitch, false);
2014*8975f5c5SAndroid Build Coastguard Worker }
2015*8975f5c5SAndroid Build Coastguard Worker 
LoadETC2SRGB8ToBC1(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)2016*8975f5c5SAndroid Build Coastguard Worker void LoadETC2SRGB8ToBC1(const ImageLoadContext &context,
2017*8975f5c5SAndroid Build Coastguard Worker                         size_t width,
2018*8975f5c5SAndroid Build Coastguard Worker                         size_t height,
2019*8975f5c5SAndroid Build Coastguard Worker                         size_t depth,
2020*8975f5c5SAndroid Build Coastguard Worker                         const uint8_t *input,
2021*8975f5c5SAndroid Build Coastguard Worker                         size_t inputRowPitch,
2022*8975f5c5SAndroid Build Coastguard Worker                         size_t inputDepthPitch,
2023*8975f5c5SAndroid Build Coastguard Worker                         uint8_t *output,
2024*8975f5c5SAndroid Build Coastguard Worker                         size_t outputRowPitch,
2025*8975f5c5SAndroid Build Coastguard Worker                         size_t outputDepthPitch)
2026*8975f5c5SAndroid Build Coastguard Worker {
2027*8975f5c5SAndroid Build Coastguard Worker     LoadETC2RGB8ToBC1(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
2028*8975f5c5SAndroid Build Coastguard Worker                       outputRowPitch, outputDepthPitch, false);
2029*8975f5c5SAndroid Build Coastguard Worker }
2030*8975f5c5SAndroid Build Coastguard Worker 
LoadETC2RGB8A1ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)2031*8975f5c5SAndroid Build Coastguard Worker void LoadETC2RGB8A1ToRGBA8(const ImageLoadContext &context,
2032*8975f5c5SAndroid Build Coastguard Worker                            size_t width,
2033*8975f5c5SAndroid Build Coastguard Worker                            size_t height,
2034*8975f5c5SAndroid Build Coastguard Worker                            size_t depth,
2035*8975f5c5SAndroid Build Coastguard Worker                            const uint8_t *input,
2036*8975f5c5SAndroid Build Coastguard Worker                            size_t inputRowPitch,
2037*8975f5c5SAndroid Build Coastguard Worker                            size_t inputDepthPitch,
2038*8975f5c5SAndroid Build Coastguard Worker                            uint8_t *output,
2039*8975f5c5SAndroid Build Coastguard Worker                            size_t outputRowPitch,
2040*8975f5c5SAndroid Build Coastguard Worker                            size_t outputDepthPitch)
2041*8975f5c5SAndroid Build Coastguard Worker {
2042*8975f5c5SAndroid Build Coastguard Worker     LoadETC2RGB8ToRGBA8(context, width, height, depth, input, inputRowPitch, inputDepthPitch,
2043*8975f5c5SAndroid Build Coastguard Worker                         output, outputRowPitch, outputDepthPitch, true);
2044*8975f5c5SAndroid Build Coastguard Worker }
2045*8975f5c5SAndroid Build Coastguard Worker 
LoadETC2RGB8A1ToBC1(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)2046*8975f5c5SAndroid Build Coastguard Worker void LoadETC2RGB8A1ToBC1(const ImageLoadContext &context,
2047*8975f5c5SAndroid Build Coastguard Worker                          size_t width,
2048*8975f5c5SAndroid Build Coastguard Worker                          size_t height,
2049*8975f5c5SAndroid Build Coastguard Worker                          size_t depth,
2050*8975f5c5SAndroid Build Coastguard Worker                          const uint8_t *input,
2051*8975f5c5SAndroid Build Coastguard Worker                          size_t inputRowPitch,
2052*8975f5c5SAndroid Build Coastguard Worker                          size_t inputDepthPitch,
2053*8975f5c5SAndroid Build Coastguard Worker                          uint8_t *output,
2054*8975f5c5SAndroid Build Coastguard Worker                          size_t outputRowPitch,
2055*8975f5c5SAndroid Build Coastguard Worker                          size_t outputDepthPitch)
2056*8975f5c5SAndroid Build Coastguard Worker {
2057*8975f5c5SAndroid Build Coastguard Worker     LoadETC2RGB8ToBC1(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
2058*8975f5c5SAndroid Build Coastguard Worker                       outputRowPitch, outputDepthPitch, true);
2059*8975f5c5SAndroid Build Coastguard Worker }
2060*8975f5c5SAndroid Build Coastguard Worker 
LoadETC2SRGB8A1ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)2061*8975f5c5SAndroid Build Coastguard Worker void LoadETC2SRGB8A1ToRGBA8(const ImageLoadContext &context,
2062*8975f5c5SAndroid Build Coastguard Worker                             size_t width,
2063*8975f5c5SAndroid Build Coastguard Worker                             size_t height,
2064*8975f5c5SAndroid Build Coastguard Worker                             size_t depth,
2065*8975f5c5SAndroid Build Coastguard Worker                             const uint8_t *input,
2066*8975f5c5SAndroid Build Coastguard Worker                             size_t inputRowPitch,
2067*8975f5c5SAndroid Build Coastguard Worker                             size_t inputDepthPitch,
2068*8975f5c5SAndroid Build Coastguard Worker                             uint8_t *output,
2069*8975f5c5SAndroid Build Coastguard Worker                             size_t outputRowPitch,
2070*8975f5c5SAndroid Build Coastguard Worker                             size_t outputDepthPitch)
2071*8975f5c5SAndroid Build Coastguard Worker {
2072*8975f5c5SAndroid Build Coastguard Worker     LoadETC2RGB8ToRGBA8(context, width, height, depth, input, inputRowPitch, inputDepthPitch,
2073*8975f5c5SAndroid Build Coastguard Worker                         output, outputRowPitch, outputDepthPitch, true);
2074*8975f5c5SAndroid Build Coastguard Worker }
2075*8975f5c5SAndroid Build Coastguard Worker 
LoadETC2SRGB8A1ToBC1(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)2076*8975f5c5SAndroid Build Coastguard Worker void LoadETC2SRGB8A1ToBC1(const ImageLoadContext &context,
2077*8975f5c5SAndroid Build Coastguard Worker                           size_t width,
2078*8975f5c5SAndroid Build Coastguard Worker                           size_t height,
2079*8975f5c5SAndroid Build Coastguard Worker                           size_t depth,
2080*8975f5c5SAndroid Build Coastguard Worker                           const uint8_t *input,
2081*8975f5c5SAndroid Build Coastguard Worker                           size_t inputRowPitch,
2082*8975f5c5SAndroid Build Coastguard Worker                           size_t inputDepthPitch,
2083*8975f5c5SAndroid Build Coastguard Worker                           uint8_t *output,
2084*8975f5c5SAndroid Build Coastguard Worker                           size_t outputRowPitch,
2085*8975f5c5SAndroid Build Coastguard Worker                           size_t outputDepthPitch)
2086*8975f5c5SAndroid Build Coastguard Worker {
2087*8975f5c5SAndroid Build Coastguard Worker     LoadETC2RGB8ToBC1(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
2088*8975f5c5SAndroid Build Coastguard Worker                       outputRowPitch, outputDepthPitch, true);
2089*8975f5c5SAndroid Build Coastguard Worker }
2090*8975f5c5SAndroid Build Coastguard Worker 
LoadETC2RGBA8ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)2091*8975f5c5SAndroid Build Coastguard Worker void LoadETC2RGBA8ToRGBA8(const ImageLoadContext &context,
2092*8975f5c5SAndroid Build Coastguard Worker                           size_t width,
2093*8975f5c5SAndroid Build Coastguard Worker                           size_t height,
2094*8975f5c5SAndroid Build Coastguard Worker                           size_t depth,
2095*8975f5c5SAndroid Build Coastguard Worker                           const uint8_t *input,
2096*8975f5c5SAndroid Build Coastguard Worker                           size_t inputRowPitch,
2097*8975f5c5SAndroid Build Coastguard Worker                           size_t inputDepthPitch,
2098*8975f5c5SAndroid Build Coastguard Worker                           uint8_t *output,
2099*8975f5c5SAndroid Build Coastguard Worker                           size_t outputRowPitch,
2100*8975f5c5SAndroid Build Coastguard Worker                           size_t outputDepthPitch)
2101*8975f5c5SAndroid Build Coastguard Worker {
2102*8975f5c5SAndroid Build Coastguard Worker     LoadETC2RGBA8ToRGBA8(context, width, height, depth, input, inputRowPitch, inputDepthPitch,
2103*8975f5c5SAndroid Build Coastguard Worker                          output, outputRowPitch, outputDepthPitch, false);
2104*8975f5c5SAndroid Build Coastguard Worker }
2105*8975f5c5SAndroid Build Coastguard Worker 
LoadETC2SRGBA8ToSRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)2106*8975f5c5SAndroid Build Coastguard Worker void LoadETC2SRGBA8ToSRGBA8(const ImageLoadContext &context,
2107*8975f5c5SAndroid Build Coastguard Worker                             size_t width,
2108*8975f5c5SAndroid Build Coastguard Worker                             size_t height,
2109*8975f5c5SAndroid Build Coastguard Worker                             size_t depth,
2110*8975f5c5SAndroid Build Coastguard Worker                             const uint8_t *input,
2111*8975f5c5SAndroid Build Coastguard Worker                             size_t inputRowPitch,
2112*8975f5c5SAndroid Build Coastguard Worker                             size_t inputDepthPitch,
2113*8975f5c5SAndroid Build Coastguard Worker                             uint8_t *output,
2114*8975f5c5SAndroid Build Coastguard Worker                             size_t outputRowPitch,
2115*8975f5c5SAndroid Build Coastguard Worker                             size_t outputDepthPitch)
2116*8975f5c5SAndroid Build Coastguard Worker {
2117*8975f5c5SAndroid Build Coastguard Worker     LoadETC2RGBA8ToRGBA8(context, width, height, depth, input, inputRowPitch, inputDepthPitch,
2118*8975f5c5SAndroid Build Coastguard Worker                          output, outputRowPitch, outputDepthPitch, true);
2119*8975f5c5SAndroid Build Coastguard Worker }
2120*8975f5c5SAndroid Build Coastguard Worker 
LoadETC2RGBA8ToBC3(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)2121*8975f5c5SAndroid Build Coastguard Worker void LoadETC2RGBA8ToBC3(const ImageLoadContext &context,
2122*8975f5c5SAndroid Build Coastguard Worker                         size_t width,
2123*8975f5c5SAndroid Build Coastguard Worker                         size_t height,
2124*8975f5c5SAndroid Build Coastguard Worker                         size_t depth,
2125*8975f5c5SAndroid Build Coastguard Worker                         const uint8_t *input,
2126*8975f5c5SAndroid Build Coastguard Worker                         size_t inputRowPitch,
2127*8975f5c5SAndroid Build Coastguard Worker                         size_t inputDepthPitch,
2128*8975f5c5SAndroid Build Coastguard Worker                         uint8_t *output,
2129*8975f5c5SAndroid Build Coastguard Worker                         size_t outputRowPitch,
2130*8975f5c5SAndroid Build Coastguard Worker                         size_t outputDepthPitch)
2131*8975f5c5SAndroid Build Coastguard Worker {
2132*8975f5c5SAndroid Build Coastguard Worker     LoadETC2RGBA8ToBC3(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
2133*8975f5c5SAndroid Build Coastguard Worker                        outputRowPitch, outputDepthPitch, false, false);
2134*8975f5c5SAndroid Build Coastguard Worker }
2135*8975f5c5SAndroid Build Coastguard Worker 
LoadETC2SRGBA8ToBC3(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)2136*8975f5c5SAndroid Build Coastguard Worker void LoadETC2SRGBA8ToBC3(const ImageLoadContext &context,
2137*8975f5c5SAndroid Build Coastguard Worker                          size_t width,
2138*8975f5c5SAndroid Build Coastguard Worker                          size_t height,
2139*8975f5c5SAndroid Build Coastguard Worker                          size_t depth,
2140*8975f5c5SAndroid Build Coastguard Worker                          const uint8_t *input,
2141*8975f5c5SAndroid Build Coastguard Worker                          size_t inputRowPitch,
2142*8975f5c5SAndroid Build Coastguard Worker                          size_t inputDepthPitch,
2143*8975f5c5SAndroid Build Coastguard Worker                          uint8_t *output,
2144*8975f5c5SAndroid Build Coastguard Worker                          size_t outputRowPitch,
2145*8975f5c5SAndroid Build Coastguard Worker                          size_t outputDepthPitch)
2146*8975f5c5SAndroid Build Coastguard Worker {
2147*8975f5c5SAndroid Build Coastguard Worker     LoadETC2RGBA8ToBC3(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
2148*8975f5c5SAndroid Build Coastguard Worker                        outputRowPitch, outputDepthPitch, false, false);
2149*8975f5c5SAndroid Build Coastguard Worker }
2150*8975f5c5SAndroid Build Coastguard Worker 
LoadEACR11ToBC4(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch,bool isSigned)2151*8975f5c5SAndroid Build Coastguard Worker void LoadEACR11ToBC4(const ImageLoadContext &context,
2152*8975f5c5SAndroid Build Coastguard Worker                      size_t width,
2153*8975f5c5SAndroid Build Coastguard Worker                      size_t height,
2154*8975f5c5SAndroid Build Coastguard Worker                      size_t depth,
2155*8975f5c5SAndroid Build Coastguard Worker                      const uint8_t *input,
2156*8975f5c5SAndroid Build Coastguard Worker                      size_t inputRowPitch,
2157*8975f5c5SAndroid Build Coastguard Worker                      size_t inputDepthPitch,
2158*8975f5c5SAndroid Build Coastguard Worker                      uint8_t *output,
2159*8975f5c5SAndroid Build Coastguard Worker                      size_t outputRowPitch,
2160*8975f5c5SAndroid Build Coastguard Worker                      size_t outputDepthPitch,
2161*8975f5c5SAndroid Build Coastguard Worker                      bool isSigned)
2162*8975f5c5SAndroid Build Coastguard Worker {
2163*8975f5c5SAndroid Build Coastguard Worker     for (size_t z = 0; z < depth; z++)
2164*8975f5c5SAndroid Build Coastguard Worker     {
2165*8975f5c5SAndroid Build Coastguard Worker         for (size_t y = 0; y < height; y += 4)
2166*8975f5c5SAndroid Build Coastguard Worker         {
2167*8975f5c5SAndroid Build Coastguard Worker             const ETC2Block *sourceRow =
2168*8975f5c5SAndroid Build Coastguard Worker                 priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch);
2169*8975f5c5SAndroid Build Coastguard Worker             uint8_t *destRow = priv::OffsetDataPointer<uint8_t>(output, y / 4, z, outputRowPitch,
2170*8975f5c5SAndroid Build Coastguard Worker                                                                 outputDepthPitch);
2171*8975f5c5SAndroid Build Coastguard Worker 
2172*8975f5c5SAndroid Build Coastguard Worker             for (size_t x = 0; x < width; x += 4)
2173*8975f5c5SAndroid Build Coastguard Worker             {
2174*8975f5c5SAndroid Build Coastguard Worker                 const ETC2Block *sourceR11Block = sourceRow + (x / 4);
2175*8975f5c5SAndroid Build Coastguard Worker                 uint8_t *destR11Pixels          = destRow + (x * 2);
2176*8975f5c5SAndroid Build Coastguard Worker                 sourceR11Block->transcodeAsBC4(destR11Pixels, x, y, width, height, isSigned);
2177*8975f5c5SAndroid Build Coastguard Worker             }
2178*8975f5c5SAndroid Build Coastguard Worker         }
2179*8975f5c5SAndroid Build Coastguard Worker     }
2180*8975f5c5SAndroid Build Coastguard Worker }
2181*8975f5c5SAndroid Build Coastguard Worker 
LoadEACRG11ToBC5(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch,bool isSigned)2182*8975f5c5SAndroid Build Coastguard Worker void LoadEACRG11ToBC5(const ImageLoadContext &context,
2183*8975f5c5SAndroid Build Coastguard Worker                       size_t width,
2184*8975f5c5SAndroid Build Coastguard Worker                       size_t height,
2185*8975f5c5SAndroid Build Coastguard Worker                       size_t depth,
2186*8975f5c5SAndroid Build Coastguard Worker                       const uint8_t *input,
2187*8975f5c5SAndroid Build Coastguard Worker                       size_t inputRowPitch,
2188*8975f5c5SAndroid Build Coastguard Worker                       size_t inputDepthPitch,
2189*8975f5c5SAndroid Build Coastguard Worker                       uint8_t *output,
2190*8975f5c5SAndroid Build Coastguard Worker                       size_t outputRowPitch,
2191*8975f5c5SAndroid Build Coastguard Worker                       size_t outputDepthPitch,
2192*8975f5c5SAndroid Build Coastguard Worker                       bool isSigned)
2193*8975f5c5SAndroid Build Coastguard Worker {
2194*8975f5c5SAndroid Build Coastguard Worker     for (size_t z = 0; z < depth; z++)
2195*8975f5c5SAndroid Build Coastguard Worker     {
2196*8975f5c5SAndroid Build Coastguard Worker         for (size_t y = 0; y < height; y += 4)
2197*8975f5c5SAndroid Build Coastguard Worker         {
2198*8975f5c5SAndroid Build Coastguard Worker             const ETC2Block *sourceRow =
2199*8975f5c5SAndroid Build Coastguard Worker                 priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch);
2200*8975f5c5SAndroid Build Coastguard Worker             uint8_t *destRow = priv::OffsetDataPointer<uint8_t>(output, y / 4, z, outputRowPitch,
2201*8975f5c5SAndroid Build Coastguard Worker                                                                 outputDepthPitch);
2202*8975f5c5SAndroid Build Coastguard Worker 
2203*8975f5c5SAndroid Build Coastguard Worker             for (size_t x = 0; x < width; x += 4)
2204*8975f5c5SAndroid Build Coastguard Worker             {
2205*8975f5c5SAndroid Build Coastguard Worker                 const ETC2Block *sourceR11Block = sourceRow + (x / 2);
2206*8975f5c5SAndroid Build Coastguard Worker                 uint8_t *destR11Pixels          = destRow + (x * 4);
2207*8975f5c5SAndroid Build Coastguard Worker 
2208*8975f5c5SAndroid Build Coastguard Worker                 const ETC2Block *sourceG11Block = sourceR11Block + 1;
2209*8975f5c5SAndroid Build Coastguard Worker                 uint8_t *destG11Pixels          = destR11Pixels + 8;
2210*8975f5c5SAndroid Build Coastguard Worker                 sourceR11Block->transcodeAsBC4(destR11Pixels, x, y, width, height, isSigned);
2211*8975f5c5SAndroid Build Coastguard Worker                 sourceG11Block->transcodeAsBC4(destG11Pixels, x, y, width, height, isSigned);
2212*8975f5c5SAndroid Build Coastguard Worker             }
2213*8975f5c5SAndroid Build Coastguard Worker         }
2214*8975f5c5SAndroid Build Coastguard Worker     }
2215*8975f5c5SAndroid Build Coastguard Worker }
2216*8975f5c5SAndroid Build Coastguard Worker 
LoadEACR11ToBC4(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)2217*8975f5c5SAndroid Build Coastguard Worker void LoadEACR11ToBC4(const ImageLoadContext &context,
2218*8975f5c5SAndroid Build Coastguard Worker                      size_t width,
2219*8975f5c5SAndroid Build Coastguard Worker                      size_t height,
2220*8975f5c5SAndroid Build Coastguard Worker                      size_t depth,
2221*8975f5c5SAndroid Build Coastguard Worker                      const uint8_t *input,
2222*8975f5c5SAndroid Build Coastguard Worker                      size_t inputRowPitch,
2223*8975f5c5SAndroid Build Coastguard Worker                      size_t inputDepthPitch,
2224*8975f5c5SAndroid Build Coastguard Worker                      uint8_t *output,
2225*8975f5c5SAndroid Build Coastguard Worker                      size_t outputRowPitch,
2226*8975f5c5SAndroid Build Coastguard Worker                      size_t outputDepthPitch)
2227*8975f5c5SAndroid Build Coastguard Worker {
2228*8975f5c5SAndroid Build Coastguard Worker     LoadEACR11ToBC4(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
2229*8975f5c5SAndroid Build Coastguard Worker                     outputRowPitch, outputDepthPitch, false);
2230*8975f5c5SAndroid Build Coastguard Worker }
2231*8975f5c5SAndroid Build Coastguard Worker 
LoadEACR11SToBC4(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)2232*8975f5c5SAndroid Build Coastguard Worker void LoadEACR11SToBC4(const ImageLoadContext &context,
2233*8975f5c5SAndroid Build Coastguard Worker                       size_t width,
2234*8975f5c5SAndroid Build Coastguard Worker                       size_t height,
2235*8975f5c5SAndroid Build Coastguard Worker                       size_t depth,
2236*8975f5c5SAndroid Build Coastguard Worker                       const uint8_t *input,
2237*8975f5c5SAndroid Build Coastguard Worker                       size_t inputRowPitch,
2238*8975f5c5SAndroid Build Coastguard Worker                       size_t inputDepthPitch,
2239*8975f5c5SAndroid Build Coastguard Worker                       uint8_t *output,
2240*8975f5c5SAndroid Build Coastguard Worker                       size_t outputRowPitch,
2241*8975f5c5SAndroid Build Coastguard Worker                       size_t outputDepthPitch)
2242*8975f5c5SAndroid Build Coastguard Worker {
2243*8975f5c5SAndroid Build Coastguard Worker     LoadEACR11ToBC4(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
2244*8975f5c5SAndroid Build Coastguard Worker                     outputRowPitch, outputDepthPitch, true);
2245*8975f5c5SAndroid Build Coastguard Worker }
2246*8975f5c5SAndroid Build Coastguard Worker 
LoadEACRG11ToBC5(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)2247*8975f5c5SAndroid Build Coastguard Worker void LoadEACRG11ToBC5(const ImageLoadContext &context,
2248*8975f5c5SAndroid Build Coastguard Worker                       size_t width,
2249*8975f5c5SAndroid Build Coastguard Worker                       size_t height,
2250*8975f5c5SAndroid Build Coastguard Worker                       size_t depth,
2251*8975f5c5SAndroid Build Coastguard Worker                       const uint8_t *input,
2252*8975f5c5SAndroid Build Coastguard Worker                       size_t inputRowPitch,
2253*8975f5c5SAndroid Build Coastguard Worker                       size_t inputDepthPitch,
2254*8975f5c5SAndroid Build Coastguard Worker                       uint8_t *output,
2255*8975f5c5SAndroid Build Coastguard Worker                       size_t outputRowPitch,
2256*8975f5c5SAndroid Build Coastguard Worker                       size_t outputDepthPitch)
2257*8975f5c5SAndroid Build Coastguard Worker {
2258*8975f5c5SAndroid Build Coastguard Worker     LoadEACRG11ToBC5(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
2259*8975f5c5SAndroid Build Coastguard Worker                      outputRowPitch, outputDepthPitch, false);
2260*8975f5c5SAndroid Build Coastguard Worker }
2261*8975f5c5SAndroid Build Coastguard Worker 
LoadEACRG11SToBC5(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)2262*8975f5c5SAndroid Build Coastguard Worker void LoadEACRG11SToBC5(const ImageLoadContext &context,
2263*8975f5c5SAndroid Build Coastguard Worker                        size_t width,
2264*8975f5c5SAndroid Build Coastguard Worker                        size_t height,
2265*8975f5c5SAndroid Build Coastguard Worker                        size_t depth,
2266*8975f5c5SAndroid Build Coastguard Worker                        const uint8_t *input,
2267*8975f5c5SAndroid Build Coastguard Worker                        size_t inputRowPitch,
2268*8975f5c5SAndroid Build Coastguard Worker                        size_t inputDepthPitch,
2269*8975f5c5SAndroid Build Coastguard Worker                        uint8_t *output,
2270*8975f5c5SAndroid Build Coastguard Worker                        size_t outputRowPitch,
2271*8975f5c5SAndroid Build Coastguard Worker                        size_t outputDepthPitch)
2272*8975f5c5SAndroid Build Coastguard Worker {
2273*8975f5c5SAndroid Build Coastguard Worker     LoadEACRG11ToBC5(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
2274*8975f5c5SAndroid Build Coastguard Worker                      outputRowPitch, outputDepthPitch, true);
2275*8975f5c5SAndroid Build Coastguard Worker }
2276*8975f5c5SAndroid Build Coastguard Worker 
2277*8975f5c5SAndroid Build Coastguard Worker }  // namespace angle
2278