1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program Tester Core
3*35238bceSAndroid Build Coastguard Worker * ----------------------------------------
4*35238bceSAndroid Build Coastguard Worker *
5*35238bceSAndroid Build Coastguard Worker * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker *
7*35238bceSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker *
11*35238bceSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker *
13*35238bceSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker *
19*35238bceSAndroid Build Coastguard Worker *//*!
20*35238bceSAndroid Build Coastguard Worker * \file
21*35238bceSAndroid Build Coastguard Worker * \brief Compressed Texture Utilities.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "tcuCompressedTexture.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "tcuAstcUtil.hpp"
27*35238bceSAndroid Build Coastguard Worker
28*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "deFloat16.h"
30*35238bceSAndroid Build Coastguard Worker
31*35238bceSAndroid Build Coastguard Worker #include <algorithm>
32*35238bceSAndroid Build Coastguard Worker
33*35238bceSAndroid Build Coastguard Worker namespace tcu
34*35238bceSAndroid Build Coastguard Worker {
35*35238bceSAndroid Build Coastguard Worker
getBlockSize(CompressedTexFormat format)36*35238bceSAndroid Build Coastguard Worker int getBlockSize(CompressedTexFormat format)
37*35238bceSAndroid Build Coastguard Worker {
38*35238bceSAndroid Build Coastguard Worker if (isAstcFormat(format))
39*35238bceSAndroid Build Coastguard Worker {
40*35238bceSAndroid Build Coastguard Worker return astc::BLOCK_SIZE_BYTES;
41*35238bceSAndroid Build Coastguard Worker }
42*35238bceSAndroid Build Coastguard Worker else if (isEtcFormat(format))
43*35238bceSAndroid Build Coastguard Worker {
44*35238bceSAndroid Build Coastguard Worker switch (format)
45*35238bceSAndroid Build Coastguard Worker {
46*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC1_RGB8:
47*35238bceSAndroid Build Coastguard Worker return 8;
48*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_EAC_R11:
49*35238bceSAndroid Build Coastguard Worker return 8;
50*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:
51*35238bceSAndroid Build Coastguard Worker return 8;
52*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_EAC_RG11:
53*35238bceSAndroid Build Coastguard Worker return 16;
54*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:
55*35238bceSAndroid Build Coastguard Worker return 16;
56*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_RGB8:
57*35238bceSAndroid Build Coastguard Worker return 8;
58*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_SRGB8:
59*35238bceSAndroid Build Coastguard Worker return 8;
60*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
61*35238bceSAndroid Build Coastguard Worker return 8;
62*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
63*35238bceSAndroid Build Coastguard Worker return 8;
64*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:
65*35238bceSAndroid Build Coastguard Worker return 16;
66*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:
67*35238bceSAndroid Build Coastguard Worker return 16;
68*35238bceSAndroid Build Coastguard Worker
69*35238bceSAndroid Build Coastguard Worker default:
70*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
71*35238bceSAndroid Build Coastguard Worker return -1;
72*35238bceSAndroid Build Coastguard Worker }
73*35238bceSAndroid Build Coastguard Worker }
74*35238bceSAndroid Build Coastguard Worker else if (isBcFormat(format))
75*35238bceSAndroid Build Coastguard Worker {
76*35238bceSAndroid Build Coastguard Worker switch (format)
77*35238bceSAndroid Build Coastguard Worker {
78*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK:
79*35238bceSAndroid Build Coastguard Worker return 8;
80*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK:
81*35238bceSAndroid Build Coastguard Worker return 8;
82*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK:
83*35238bceSAndroid Build Coastguard Worker return 8;
84*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK:
85*35238bceSAndroid Build Coastguard Worker return 8;
86*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK:
87*35238bceSAndroid Build Coastguard Worker return 16;
88*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK:
89*35238bceSAndroid Build Coastguard Worker return 16;
90*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK:
91*35238bceSAndroid Build Coastguard Worker return 16;
92*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK:
93*35238bceSAndroid Build Coastguard Worker return 16;
94*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK:
95*35238bceSAndroid Build Coastguard Worker return 8;
96*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK:
97*35238bceSAndroid Build Coastguard Worker return 8;
98*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK:
99*35238bceSAndroid Build Coastguard Worker return 16;
100*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK:
101*35238bceSAndroid Build Coastguard Worker return 16;
102*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK:
103*35238bceSAndroid Build Coastguard Worker return 16;
104*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK:
105*35238bceSAndroid Build Coastguard Worker return 16;
106*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK:
107*35238bceSAndroid Build Coastguard Worker return 16;
108*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:
109*35238bceSAndroid Build Coastguard Worker return 16;
110*35238bceSAndroid Build Coastguard Worker
111*35238bceSAndroid Build Coastguard Worker default:
112*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
113*35238bceSAndroid Build Coastguard Worker return -1;
114*35238bceSAndroid Build Coastguard Worker }
115*35238bceSAndroid Build Coastguard Worker }
116*35238bceSAndroid Build Coastguard Worker else if (isAhbRawFormat(format))
117*35238bceSAndroid Build Coastguard Worker {
118*35238bceSAndroid Build Coastguard Worker switch (format)
119*35238bceSAndroid Build Coastguard Worker {
120*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_AHB_RAW10:
121*35238bceSAndroid Build Coastguard Worker return 5;
122*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_AHB_RAW12:
123*35238bceSAndroid Build Coastguard Worker return 3;
124*35238bceSAndroid Build Coastguard Worker
125*35238bceSAndroid Build Coastguard Worker default:
126*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
127*35238bceSAndroid Build Coastguard Worker return -1;
128*35238bceSAndroid Build Coastguard Worker }
129*35238bceSAndroid Build Coastguard Worker }
130*35238bceSAndroid Build Coastguard Worker else
131*35238bceSAndroid Build Coastguard Worker {
132*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
133*35238bceSAndroid Build Coastguard Worker return -1;
134*35238bceSAndroid Build Coastguard Worker }
135*35238bceSAndroid Build Coastguard Worker }
136*35238bceSAndroid Build Coastguard Worker
getBlockPixelSize(CompressedTexFormat format)137*35238bceSAndroid Build Coastguard Worker IVec3 getBlockPixelSize(CompressedTexFormat format)
138*35238bceSAndroid Build Coastguard Worker {
139*35238bceSAndroid Build Coastguard Worker if (isEtcFormat(format))
140*35238bceSAndroid Build Coastguard Worker {
141*35238bceSAndroid Build Coastguard Worker return IVec3(4, 4, 1);
142*35238bceSAndroid Build Coastguard Worker }
143*35238bceSAndroid Build Coastguard Worker else if (isAstcFormat(format))
144*35238bceSAndroid Build Coastguard Worker {
145*35238bceSAndroid Build Coastguard Worker switch (format)
146*35238bceSAndroid Build Coastguard Worker {
147*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA:
148*35238bceSAndroid Build Coastguard Worker return IVec3(4, 4, 1);
149*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA:
150*35238bceSAndroid Build Coastguard Worker return IVec3(5, 4, 1);
151*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA:
152*35238bceSAndroid Build Coastguard Worker return IVec3(5, 5, 1);
153*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA:
154*35238bceSAndroid Build Coastguard Worker return IVec3(6, 5, 1);
155*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA:
156*35238bceSAndroid Build Coastguard Worker return IVec3(6, 6, 1);
157*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA:
158*35238bceSAndroid Build Coastguard Worker return IVec3(8, 5, 1);
159*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA:
160*35238bceSAndroid Build Coastguard Worker return IVec3(8, 6, 1);
161*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA:
162*35238bceSAndroid Build Coastguard Worker return IVec3(8, 8, 1);
163*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA:
164*35238bceSAndroid Build Coastguard Worker return IVec3(10, 5, 1);
165*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA:
166*35238bceSAndroid Build Coastguard Worker return IVec3(10, 6, 1);
167*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA:
168*35238bceSAndroid Build Coastguard Worker return IVec3(10, 8, 1);
169*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA:
170*35238bceSAndroid Build Coastguard Worker return IVec3(10, 10, 1);
171*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA:
172*35238bceSAndroid Build Coastguard Worker return IVec3(12, 10, 1);
173*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA:
174*35238bceSAndroid Build Coastguard Worker return IVec3(12, 12, 1);
175*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:
176*35238bceSAndroid Build Coastguard Worker return IVec3(4, 4, 1);
177*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:
178*35238bceSAndroid Build Coastguard Worker return IVec3(5, 4, 1);
179*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:
180*35238bceSAndroid Build Coastguard Worker return IVec3(5, 5, 1);
181*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:
182*35238bceSAndroid Build Coastguard Worker return IVec3(6, 5, 1);
183*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:
184*35238bceSAndroid Build Coastguard Worker return IVec3(6, 6, 1);
185*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:
186*35238bceSAndroid Build Coastguard Worker return IVec3(8, 5, 1);
187*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:
188*35238bceSAndroid Build Coastguard Worker return IVec3(8, 6, 1);
189*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:
190*35238bceSAndroid Build Coastguard Worker return IVec3(8, 8, 1);
191*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:
192*35238bceSAndroid Build Coastguard Worker return IVec3(10, 5, 1);
193*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:
194*35238bceSAndroid Build Coastguard Worker return IVec3(10, 6, 1);
195*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:
196*35238bceSAndroid Build Coastguard Worker return IVec3(10, 8, 1);
197*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:
198*35238bceSAndroid Build Coastguard Worker return IVec3(10, 10, 1);
199*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:
200*35238bceSAndroid Build Coastguard Worker return IVec3(12, 10, 1);
201*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:
202*35238bceSAndroid Build Coastguard Worker return IVec3(12, 12, 1);
203*35238bceSAndroid Build Coastguard Worker
204*35238bceSAndroid Build Coastguard Worker default:
205*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
206*35238bceSAndroid Build Coastguard Worker return IVec3();
207*35238bceSAndroid Build Coastguard Worker }
208*35238bceSAndroid Build Coastguard Worker }
209*35238bceSAndroid Build Coastguard Worker else if (isBcFormat(format))
210*35238bceSAndroid Build Coastguard Worker {
211*35238bceSAndroid Build Coastguard Worker return IVec3(4, 4, 1);
212*35238bceSAndroid Build Coastguard Worker }
213*35238bceSAndroid Build Coastguard Worker else if (isAhbRawFormat(format))
214*35238bceSAndroid Build Coastguard Worker {
215*35238bceSAndroid Build Coastguard Worker switch (format)
216*35238bceSAndroid Build Coastguard Worker {
217*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_AHB_RAW10:
218*35238bceSAndroid Build Coastguard Worker return IVec3(4, 1, 1);
219*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_AHB_RAW12:
220*35238bceSAndroid Build Coastguard Worker return IVec3(2, 1, 1);
221*35238bceSAndroid Build Coastguard Worker
222*35238bceSAndroid Build Coastguard Worker default:
223*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
224*35238bceSAndroid Build Coastguard Worker return IVec3();
225*35238bceSAndroid Build Coastguard Worker }
226*35238bceSAndroid Build Coastguard Worker }
227*35238bceSAndroid Build Coastguard Worker else
228*35238bceSAndroid Build Coastguard Worker {
229*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
230*35238bceSAndroid Build Coastguard Worker return IVec3(-1);
231*35238bceSAndroid Build Coastguard Worker }
232*35238bceSAndroid Build Coastguard Worker }
233*35238bceSAndroid Build Coastguard Worker
isEtcFormat(CompressedTexFormat format)234*35238bceSAndroid Build Coastguard Worker bool isEtcFormat(CompressedTexFormat format)
235*35238bceSAndroid Build Coastguard Worker {
236*35238bceSAndroid Build Coastguard Worker switch (format)
237*35238bceSAndroid Build Coastguard Worker {
238*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC1_RGB8:
239*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_EAC_R11:
240*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:
241*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_EAC_RG11:
242*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:
243*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_RGB8:
244*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_SRGB8:
245*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
246*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
247*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:
248*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:
249*35238bceSAndroid Build Coastguard Worker return true;
250*35238bceSAndroid Build Coastguard Worker
251*35238bceSAndroid Build Coastguard Worker default:
252*35238bceSAndroid Build Coastguard Worker return false;
253*35238bceSAndroid Build Coastguard Worker }
254*35238bceSAndroid Build Coastguard Worker }
255*35238bceSAndroid Build Coastguard Worker
isBcFormat(CompressedTexFormat format)256*35238bceSAndroid Build Coastguard Worker bool isBcFormat(CompressedTexFormat format)
257*35238bceSAndroid Build Coastguard Worker {
258*35238bceSAndroid Build Coastguard Worker switch (format)
259*35238bceSAndroid Build Coastguard Worker {
260*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK:
261*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK:
262*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK:
263*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK:
264*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK:
265*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK:
266*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK:
267*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK:
268*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK:
269*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK:
270*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK:
271*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK:
272*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK:
273*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK:
274*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK:
275*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:
276*35238bceSAndroid Build Coastguard Worker return true;
277*35238bceSAndroid Build Coastguard Worker
278*35238bceSAndroid Build Coastguard Worker default:
279*35238bceSAndroid Build Coastguard Worker return false;
280*35238bceSAndroid Build Coastguard Worker }
281*35238bceSAndroid Build Coastguard Worker }
282*35238bceSAndroid Build Coastguard Worker
isBcBitExactFormat(CompressedTexFormat format)283*35238bceSAndroid Build Coastguard Worker bool isBcBitExactFormat(CompressedTexFormat format)
284*35238bceSAndroid Build Coastguard Worker {
285*35238bceSAndroid Build Coastguard Worker switch (format)
286*35238bceSAndroid Build Coastguard Worker {
287*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK:
288*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK:
289*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK:
290*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:
291*35238bceSAndroid Build Coastguard Worker return true;
292*35238bceSAndroid Build Coastguard Worker
293*35238bceSAndroid Build Coastguard Worker default:
294*35238bceSAndroid Build Coastguard Worker return false;
295*35238bceSAndroid Build Coastguard Worker }
296*35238bceSAndroid Build Coastguard Worker }
297*35238bceSAndroid Build Coastguard Worker
isBcSRGBFormat(CompressedTexFormat format)298*35238bceSAndroid Build Coastguard Worker bool isBcSRGBFormat(CompressedTexFormat format)
299*35238bceSAndroid Build Coastguard Worker {
300*35238bceSAndroid Build Coastguard Worker switch (format)
301*35238bceSAndroid Build Coastguard Worker {
302*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK:
303*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK:
304*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK:
305*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK:
306*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:
307*35238bceSAndroid Build Coastguard Worker return true;
308*35238bceSAndroid Build Coastguard Worker
309*35238bceSAndroid Build Coastguard Worker default:
310*35238bceSAndroid Build Coastguard Worker return false;
311*35238bceSAndroid Build Coastguard Worker }
312*35238bceSAndroid Build Coastguard Worker }
313*35238bceSAndroid Build Coastguard Worker
isAstcFormat(CompressedTexFormat format)314*35238bceSAndroid Build Coastguard Worker bool isAstcFormat(CompressedTexFormat format)
315*35238bceSAndroid Build Coastguard Worker {
316*35238bceSAndroid Build Coastguard Worker switch (format)
317*35238bceSAndroid Build Coastguard Worker {
318*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA:
319*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA:
320*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA:
321*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA:
322*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA:
323*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA:
324*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA:
325*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA:
326*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA:
327*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA:
328*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA:
329*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA:
330*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA:
331*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA:
332*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:
333*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:
334*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:
335*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:
336*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:
337*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:
338*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:
339*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:
340*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:
341*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:
342*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:
343*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:
344*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:
345*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:
346*35238bceSAndroid Build Coastguard Worker return true;
347*35238bceSAndroid Build Coastguard Worker
348*35238bceSAndroid Build Coastguard Worker default:
349*35238bceSAndroid Build Coastguard Worker return false;
350*35238bceSAndroid Build Coastguard Worker }
351*35238bceSAndroid Build Coastguard Worker }
352*35238bceSAndroid Build Coastguard Worker
isAstcSRGBFormat(CompressedTexFormat format)353*35238bceSAndroid Build Coastguard Worker bool isAstcSRGBFormat(CompressedTexFormat format)
354*35238bceSAndroid Build Coastguard Worker {
355*35238bceSAndroid Build Coastguard Worker switch (format)
356*35238bceSAndroid Build Coastguard Worker {
357*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:
358*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:
359*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:
360*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:
361*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:
362*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:
363*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:
364*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:
365*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:
366*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:
367*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:
368*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:
369*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:
370*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:
371*35238bceSAndroid Build Coastguard Worker return true;
372*35238bceSAndroid Build Coastguard Worker
373*35238bceSAndroid Build Coastguard Worker default:
374*35238bceSAndroid Build Coastguard Worker return false;
375*35238bceSAndroid Build Coastguard Worker }
376*35238bceSAndroid Build Coastguard Worker }
377*35238bceSAndroid Build Coastguard Worker
isAhbRawFormat(CompressedTexFormat format)378*35238bceSAndroid Build Coastguard Worker bool isAhbRawFormat(CompressedTexFormat format)
379*35238bceSAndroid Build Coastguard Worker {
380*35238bceSAndroid Build Coastguard Worker switch (format)
381*35238bceSAndroid Build Coastguard Worker {
382*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_AHB_RAW10:
383*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_AHB_RAW12:
384*35238bceSAndroid Build Coastguard Worker return true;
385*35238bceSAndroid Build Coastguard Worker
386*35238bceSAndroid Build Coastguard Worker default:
387*35238bceSAndroid Build Coastguard Worker return false;
388*35238bceSAndroid Build Coastguard Worker }
389*35238bceSAndroid Build Coastguard Worker }
390*35238bceSAndroid Build Coastguard Worker
getUncompressedFormat(CompressedTexFormat format)391*35238bceSAndroid Build Coastguard Worker TextureFormat getUncompressedFormat(CompressedTexFormat format)
392*35238bceSAndroid Build Coastguard Worker {
393*35238bceSAndroid Build Coastguard Worker if (isEtcFormat(format))
394*35238bceSAndroid Build Coastguard Worker {
395*35238bceSAndroid Build Coastguard Worker switch (format)
396*35238bceSAndroid Build Coastguard Worker {
397*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC1_RGB8:
398*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8);
399*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_EAC_R11:
400*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::R, TextureFormat::UNORM_INT16);
401*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:
402*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::R, TextureFormat::SNORM_INT16);
403*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_EAC_RG11:
404*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::RG, TextureFormat::UNORM_INT16);
405*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:
406*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::RG, TextureFormat::SNORM_INT16);
407*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_RGB8:
408*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8);
409*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_SRGB8:
410*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::sRGB, TextureFormat::UNORM_INT8);
411*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
412*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8);
413*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
414*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::sRGBA, TextureFormat::UNORM_INT8);
415*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:
416*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8);
417*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:
418*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::sRGBA, TextureFormat::UNORM_INT8);
419*35238bceSAndroid Build Coastguard Worker
420*35238bceSAndroid Build Coastguard Worker default:
421*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
422*35238bceSAndroid Build Coastguard Worker return TextureFormat();
423*35238bceSAndroid Build Coastguard Worker }
424*35238bceSAndroid Build Coastguard Worker }
425*35238bceSAndroid Build Coastguard Worker else if (isAstcFormat(format))
426*35238bceSAndroid Build Coastguard Worker {
427*35238bceSAndroid Build Coastguard Worker if (isAstcSRGBFormat(format))
428*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::sRGBA, TextureFormat::UNORM_INT8);
429*35238bceSAndroid Build Coastguard Worker else
430*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::RGBA, TextureFormat::HALF_FLOAT);
431*35238bceSAndroid Build Coastguard Worker }
432*35238bceSAndroid Build Coastguard Worker else if (isBcFormat(format))
433*35238bceSAndroid Build Coastguard Worker {
434*35238bceSAndroid Build Coastguard Worker if (format == COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK || format == COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK)
435*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::R, TextureFormat::FLOAT);
436*35238bceSAndroid Build Coastguard Worker else if (format == COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK || format == COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK)
437*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::RG, TextureFormat::FLOAT);
438*35238bceSAndroid Build Coastguard Worker else if (format == COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK || format == COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK)
439*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::RGB, TextureFormat::HALF_FLOAT);
440*35238bceSAndroid Build Coastguard Worker else if (isBcSRGBFormat(format))
441*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::sRGBA, TextureFormat::UNORM_INT8);
442*35238bceSAndroid Build Coastguard Worker else
443*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8);
444*35238bceSAndroid Build Coastguard Worker }
445*35238bceSAndroid Build Coastguard Worker else if (isAhbRawFormat(format))
446*35238bceSAndroid Build Coastguard Worker {
447*35238bceSAndroid Build Coastguard Worker if (format == COMPRESSEDTEXFORMAT_AHB_RAW10)
448*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::R,
449*35238bceSAndroid Build Coastguard Worker TextureFormat::UNORM_SHORT_10); // Can be changed to a more fitting value if needed
450*35238bceSAndroid Build Coastguard Worker else // COMPRESSEDTEXFORMAT_AHB_RAW12
451*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::R,
452*35238bceSAndroid Build Coastguard Worker TextureFormat::UNORM_SHORT_12); // Can be changed to a more fitting value if needed
453*35238bceSAndroid Build Coastguard Worker }
454*35238bceSAndroid Build Coastguard Worker else
455*35238bceSAndroid Build Coastguard Worker {
456*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
457*35238bceSAndroid Build Coastguard Worker return TextureFormat();
458*35238bceSAndroid Build Coastguard Worker }
459*35238bceSAndroid Build Coastguard Worker }
460*35238bceSAndroid Build Coastguard Worker
getAstcFormatByBlockSize(const IVec3 & size,bool isSRGB)461*35238bceSAndroid Build Coastguard Worker CompressedTexFormat getAstcFormatByBlockSize(const IVec3 &size, bool isSRGB)
462*35238bceSAndroid Build Coastguard Worker {
463*35238bceSAndroid Build Coastguard Worker if (size.z() > 1)
464*35238bceSAndroid Build Coastguard Worker throw InternalError("3D ASTC textures not currently supported");
465*35238bceSAndroid Build Coastguard Worker
466*35238bceSAndroid Build Coastguard Worker for (int fmtI = 0; fmtI < COMPRESSEDTEXFORMAT_LAST; fmtI++)
467*35238bceSAndroid Build Coastguard Worker {
468*35238bceSAndroid Build Coastguard Worker const CompressedTexFormat fmt = (CompressedTexFormat)fmtI;
469*35238bceSAndroid Build Coastguard Worker
470*35238bceSAndroid Build Coastguard Worker if (isAstcFormat(fmt) && getBlockPixelSize(fmt) == size && isAstcSRGBFormat(fmt) == isSRGB)
471*35238bceSAndroid Build Coastguard Worker return fmt;
472*35238bceSAndroid Build Coastguard Worker }
473*35238bceSAndroid Build Coastguard Worker
474*35238bceSAndroid Build Coastguard Worker throw InternalError("Invalid ASTC block size " + de::toString(size.x()) + "x" + de::toString(size.y()) + "x" +
475*35238bceSAndroid Build Coastguard Worker de::toString(size.z()));
476*35238bceSAndroid Build Coastguard Worker }
477*35238bceSAndroid Build Coastguard Worker
478*35238bceSAndroid Build Coastguard Worker namespace
479*35238bceSAndroid Build Coastguard Worker {
480*35238bceSAndroid Build Coastguard Worker
extend4To8(uint8_t src)481*35238bceSAndroid Build Coastguard Worker inline uint8_t extend4To8(uint8_t src)
482*35238bceSAndroid Build Coastguard Worker {
483*35238bceSAndroid Build Coastguard Worker DE_ASSERT((src & ~((1 << 4) - 1)) == 0);
484*35238bceSAndroid Build Coastguard Worker return (uint8_t)((src << 4) | src);
485*35238bceSAndroid Build Coastguard Worker }
486*35238bceSAndroid Build Coastguard Worker
extend5To8(uint8_t src)487*35238bceSAndroid Build Coastguard Worker inline uint8_t extend5To8(uint8_t src)
488*35238bceSAndroid Build Coastguard Worker {
489*35238bceSAndroid Build Coastguard Worker DE_ASSERT((src & ~((1 << 5) - 1)) == 0);
490*35238bceSAndroid Build Coastguard Worker return (uint8_t)((src << 3) | (src >> 2));
491*35238bceSAndroid Build Coastguard Worker }
492*35238bceSAndroid Build Coastguard Worker
extend6To8(uint8_t src)493*35238bceSAndroid Build Coastguard Worker inline uint8_t extend6To8(uint8_t src)
494*35238bceSAndroid Build Coastguard Worker {
495*35238bceSAndroid Build Coastguard Worker DE_ASSERT((src & ~((1 << 6) - 1)) == 0);
496*35238bceSAndroid Build Coastguard Worker return (uint8_t)((src << 2) | (src >> 4));
497*35238bceSAndroid Build Coastguard Worker }
498*35238bceSAndroid Build Coastguard Worker
499*35238bceSAndroid Build Coastguard Worker // \todo [2013-08-06 nuutti] ETC and ASTC decompression codes are rather unrelated, and are already in their own "private" namespaces - should this be split to multiple files?
500*35238bceSAndroid Build Coastguard Worker
501*35238bceSAndroid Build Coastguard Worker namespace EtcDecompressInternal
502*35238bceSAndroid Build Coastguard Worker {
503*35238bceSAndroid Build Coastguard Worker
504*35238bceSAndroid Build Coastguard Worker enum
505*35238bceSAndroid Build Coastguard Worker {
506*35238bceSAndroid Build Coastguard Worker ETC2_BLOCK_WIDTH = 4,
507*35238bceSAndroid Build Coastguard Worker ETC2_BLOCK_HEIGHT = 4,
508*35238bceSAndroid Build Coastguard Worker ETC2_UNCOMPRESSED_PIXEL_SIZE_A8 = 1,
509*35238bceSAndroid Build Coastguard Worker ETC2_UNCOMPRESSED_PIXEL_SIZE_R11 = 2,
510*35238bceSAndroid Build Coastguard Worker ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11 = 4,
511*35238bceSAndroid Build Coastguard Worker ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8 = 3,
512*35238bceSAndroid Build Coastguard Worker ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8 = 4,
513*35238bceSAndroid Build Coastguard Worker ETC2_UNCOMPRESSED_BLOCK_SIZE_A8 = ETC2_BLOCK_WIDTH * ETC2_BLOCK_HEIGHT * ETC2_UNCOMPRESSED_PIXEL_SIZE_A8,
514*35238bceSAndroid Build Coastguard Worker ETC2_UNCOMPRESSED_BLOCK_SIZE_R11 = ETC2_BLOCK_WIDTH * ETC2_BLOCK_HEIGHT * ETC2_UNCOMPRESSED_PIXEL_SIZE_R11,
515*35238bceSAndroid Build Coastguard Worker ETC2_UNCOMPRESSED_BLOCK_SIZE_RG11 = ETC2_BLOCK_WIDTH * ETC2_BLOCK_HEIGHT * ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11,
516*35238bceSAndroid Build Coastguard Worker ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8 = ETC2_BLOCK_WIDTH * ETC2_BLOCK_HEIGHT * ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8,
517*35238bceSAndroid Build Coastguard Worker ETC2_UNCOMPRESSED_BLOCK_SIZE_RGBA8 = ETC2_BLOCK_WIDTH * ETC2_BLOCK_HEIGHT * ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8
518*35238bceSAndroid Build Coastguard Worker };
519*35238bceSAndroid Build Coastguard Worker
get64BitBlock(const uint8_t * src,int blockNdx)520*35238bceSAndroid Build Coastguard Worker inline uint64_t get64BitBlock(const uint8_t *src, int blockNdx)
521*35238bceSAndroid Build Coastguard Worker {
522*35238bceSAndroid Build Coastguard Worker // Stored in big-endian form.
523*35238bceSAndroid Build Coastguard Worker uint64_t block = 0;
524*35238bceSAndroid Build Coastguard Worker
525*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < 8; i++)
526*35238bceSAndroid Build Coastguard Worker block = (block << 8ull) | (uint64_t)(src[blockNdx * 8 + i]);
527*35238bceSAndroid Build Coastguard Worker
528*35238bceSAndroid Build Coastguard Worker return block;
529*35238bceSAndroid Build Coastguard Worker }
530*35238bceSAndroid Build Coastguard Worker
531*35238bceSAndroid Build Coastguard Worker // Return the first 64 bits of a 128 bit block.
get128BitBlockStart(const uint8_t * src,int blockNdx)532*35238bceSAndroid Build Coastguard Worker inline uint64_t get128BitBlockStart(const uint8_t *src, int blockNdx)
533*35238bceSAndroid Build Coastguard Worker {
534*35238bceSAndroid Build Coastguard Worker return get64BitBlock(src, 2 * blockNdx);
535*35238bceSAndroid Build Coastguard Worker }
536*35238bceSAndroid Build Coastguard Worker
537*35238bceSAndroid Build Coastguard Worker // Return the last 64 bits of a 128 bit block.
get128BitBlockEnd(const uint8_t * src,int blockNdx)538*35238bceSAndroid Build Coastguard Worker inline uint64_t get128BitBlockEnd(const uint8_t *src, int blockNdx)
539*35238bceSAndroid Build Coastguard Worker {
540*35238bceSAndroid Build Coastguard Worker return get64BitBlock(src, 2 * blockNdx + 1);
541*35238bceSAndroid Build Coastguard Worker }
542*35238bceSAndroid Build Coastguard Worker
getBit(uint64_t src,int bit)543*35238bceSAndroid Build Coastguard Worker inline uint32_t getBit(uint64_t src, int bit)
544*35238bceSAndroid Build Coastguard Worker {
545*35238bceSAndroid Build Coastguard Worker return (src >> bit) & 1;
546*35238bceSAndroid Build Coastguard Worker }
547*35238bceSAndroid Build Coastguard Worker
getBits(uint64_t src,int low,int high)548*35238bceSAndroid Build Coastguard Worker inline uint32_t getBits(uint64_t src, int low, int high)
549*35238bceSAndroid Build Coastguard Worker {
550*35238bceSAndroid Build Coastguard Worker const int numBits = (high - low) + 1;
551*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inRange(numBits, 1, 32));
552*35238bceSAndroid Build Coastguard Worker if (numBits < 32)
553*35238bceSAndroid Build Coastguard Worker return (uint32_t)((src >> low) & ((1u << numBits) - 1));
554*35238bceSAndroid Build Coastguard Worker else
555*35238bceSAndroid Build Coastguard Worker return (uint32_t)((src >> low) & 0xFFFFFFFFu);
556*35238bceSAndroid Build Coastguard Worker }
557*35238bceSAndroid Build Coastguard Worker
extend7To8(uint8_t src)558*35238bceSAndroid Build Coastguard Worker inline uint8_t extend7To8(uint8_t src)
559*35238bceSAndroid Build Coastguard Worker {
560*35238bceSAndroid Build Coastguard Worker DE_ASSERT((src & ~((1 << 7) - 1)) == 0);
561*35238bceSAndroid Build Coastguard Worker return (uint8_t)((src << 1) | (src >> 6));
562*35238bceSAndroid Build Coastguard Worker }
563*35238bceSAndroid Build Coastguard Worker
extendSigned3To8(uint8_t src)564*35238bceSAndroid Build Coastguard Worker inline int8_t extendSigned3To8(uint8_t src)
565*35238bceSAndroid Build Coastguard Worker {
566*35238bceSAndroid Build Coastguard Worker const bool isNeg = (src & (1 << 2)) != 0;
567*35238bceSAndroid Build Coastguard Worker return (int8_t)((isNeg ? ~((1 << 3) - 1) : 0) | src);
568*35238bceSAndroid Build Coastguard Worker }
569*35238bceSAndroid Build Coastguard Worker
extend5Delta3To8(uint8_t base5,uint8_t delta3)570*35238bceSAndroid Build Coastguard Worker inline uint8_t extend5Delta3To8(uint8_t base5, uint8_t delta3)
571*35238bceSAndroid Build Coastguard Worker {
572*35238bceSAndroid Build Coastguard Worker const uint8_t t = (uint8_t)((int8_t)base5 + extendSigned3To8(delta3));
573*35238bceSAndroid Build Coastguard Worker return extend5To8(t);
574*35238bceSAndroid Build Coastguard Worker }
575*35238bceSAndroid Build Coastguard Worker
extend11To16(uint16_t src)576*35238bceSAndroid Build Coastguard Worker inline uint16_t extend11To16(uint16_t src)
577*35238bceSAndroid Build Coastguard Worker {
578*35238bceSAndroid Build Coastguard Worker DE_ASSERT((src & ~((1 << 11) - 1)) == 0);
579*35238bceSAndroid Build Coastguard Worker return (uint16_t)((src << 5) | (src >> 6));
580*35238bceSAndroid Build Coastguard Worker }
581*35238bceSAndroid Build Coastguard Worker
extend11To16WithSign(int16_t src)582*35238bceSAndroid Build Coastguard Worker inline int16_t extend11To16WithSign(int16_t src)
583*35238bceSAndroid Build Coastguard Worker {
584*35238bceSAndroid Build Coastguard Worker if (src < 0)
585*35238bceSAndroid Build Coastguard Worker return (int16_t)(-(int16_t)extend11To16((uint16_t)(-src)));
586*35238bceSAndroid Build Coastguard Worker else
587*35238bceSAndroid Build Coastguard Worker return (int16_t)extend11To16(src);
588*35238bceSAndroid Build Coastguard Worker }
589*35238bceSAndroid Build Coastguard Worker
decompressETC1Block(uint8_t dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8],uint64_t src)590*35238bceSAndroid Build Coastguard Worker void decompressETC1Block(uint8_t dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8], uint64_t src)
591*35238bceSAndroid Build Coastguard Worker {
592*35238bceSAndroid Build Coastguard Worker const int diffBit = (int)getBit(src, 33);
593*35238bceSAndroid Build Coastguard Worker const int flipBit = (int)getBit(src, 32);
594*35238bceSAndroid Build Coastguard Worker const uint32_t table[2] = {getBits(src, 37, 39), getBits(src, 34, 36)};
595*35238bceSAndroid Build Coastguard Worker uint8_t baseR[2];
596*35238bceSAndroid Build Coastguard Worker uint8_t baseG[2];
597*35238bceSAndroid Build Coastguard Worker uint8_t baseB[2];
598*35238bceSAndroid Build Coastguard Worker
599*35238bceSAndroid Build Coastguard Worker if (diffBit == 0)
600*35238bceSAndroid Build Coastguard Worker {
601*35238bceSAndroid Build Coastguard Worker // Individual mode.
602*35238bceSAndroid Build Coastguard Worker baseR[0] = extend4To8((uint8_t)getBits(src, 60, 63));
603*35238bceSAndroid Build Coastguard Worker baseR[1] = extend4To8((uint8_t)getBits(src, 56, 59));
604*35238bceSAndroid Build Coastguard Worker baseG[0] = extend4To8((uint8_t)getBits(src, 52, 55));
605*35238bceSAndroid Build Coastguard Worker baseG[1] = extend4To8((uint8_t)getBits(src, 48, 51));
606*35238bceSAndroid Build Coastguard Worker baseB[0] = extend4To8((uint8_t)getBits(src, 44, 47));
607*35238bceSAndroid Build Coastguard Worker baseB[1] = extend4To8((uint8_t)getBits(src, 40, 43));
608*35238bceSAndroid Build Coastguard Worker }
609*35238bceSAndroid Build Coastguard Worker else
610*35238bceSAndroid Build Coastguard Worker {
611*35238bceSAndroid Build Coastguard Worker // Differential mode (diffBit == 1).
612*35238bceSAndroid Build Coastguard Worker uint8_t bR = (uint8_t)getBits(src, 59, 63); // 5b
613*35238bceSAndroid Build Coastguard Worker uint8_t dR = (uint8_t)getBits(src, 56, 58); // 3b
614*35238bceSAndroid Build Coastguard Worker uint8_t bG = (uint8_t)getBits(src, 51, 55);
615*35238bceSAndroid Build Coastguard Worker uint8_t dG = (uint8_t)getBits(src, 48, 50);
616*35238bceSAndroid Build Coastguard Worker uint8_t bB = (uint8_t)getBits(src, 43, 47);
617*35238bceSAndroid Build Coastguard Worker uint8_t dB = (uint8_t)getBits(src, 40, 42);
618*35238bceSAndroid Build Coastguard Worker
619*35238bceSAndroid Build Coastguard Worker baseR[0] = extend5To8(bR);
620*35238bceSAndroid Build Coastguard Worker baseG[0] = extend5To8(bG);
621*35238bceSAndroid Build Coastguard Worker baseB[0] = extend5To8(bB);
622*35238bceSAndroid Build Coastguard Worker
623*35238bceSAndroid Build Coastguard Worker baseR[1] = extend5Delta3To8(bR, dR);
624*35238bceSAndroid Build Coastguard Worker baseG[1] = extend5Delta3To8(bG, dG);
625*35238bceSAndroid Build Coastguard Worker baseB[1] = extend5Delta3To8(bB, dB);
626*35238bceSAndroid Build Coastguard Worker }
627*35238bceSAndroid Build Coastguard Worker
628*35238bceSAndroid Build Coastguard Worker static const int modifierTable[8][4] = {// 00 01 10 11
629*35238bceSAndroid Build Coastguard Worker {2, 8, -2, -8}, {5, 17, -5, -17}, {9, 29, -9, -29},
630*35238bceSAndroid Build Coastguard Worker {13, 42, -13, -42}, {18, 60, -18, -60}, {24, 80, -24, -80},
631*35238bceSAndroid Build Coastguard Worker {33, 106, -33, -106}, {47, 183, -47, -183}};
632*35238bceSAndroid Build Coastguard Worker
633*35238bceSAndroid Build Coastguard Worker // Write final pixels.
634*35238bceSAndroid Build Coastguard Worker for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT * ETC2_BLOCK_WIDTH; pixelNdx++)
635*35238bceSAndroid Build Coastguard Worker {
636*35238bceSAndroid Build Coastguard Worker const int x = pixelNdx / ETC2_BLOCK_HEIGHT;
637*35238bceSAndroid Build Coastguard Worker const int y = pixelNdx % ETC2_BLOCK_HEIGHT;
638*35238bceSAndroid Build Coastguard Worker const int dstOffset = (y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8;
639*35238bceSAndroid Build Coastguard Worker const int subBlock = ((flipBit ? y : x) >= 2) ? 1 : 0;
640*35238bceSAndroid Build Coastguard Worker const uint32_t tableNdx = table[subBlock];
641*35238bceSAndroid Build Coastguard Worker const uint32_t modifierNdx = (getBit(src, 16 + pixelNdx) << 1) | getBit(src, pixelNdx);
642*35238bceSAndroid Build Coastguard Worker const int modifier = modifierTable[tableNdx][modifierNdx];
643*35238bceSAndroid Build Coastguard Worker
644*35238bceSAndroid Build Coastguard Worker dst[dstOffset + 0] = (uint8_t)deClamp32((int)baseR[subBlock] + modifier, 0, 255);
645*35238bceSAndroid Build Coastguard Worker dst[dstOffset + 1] = (uint8_t)deClamp32((int)baseG[subBlock] + modifier, 0, 255);
646*35238bceSAndroid Build Coastguard Worker dst[dstOffset + 2] = (uint8_t)deClamp32((int)baseB[subBlock] + modifier, 0, 255);
647*35238bceSAndroid Build Coastguard Worker }
648*35238bceSAndroid Build Coastguard Worker }
649*35238bceSAndroid Build Coastguard Worker
650*35238bceSAndroid Build Coastguard Worker // if alphaMode is true, do PUNCHTHROUGH and store alpha to alphaDst; otherwise do ordinary ETC2 RGB8.
decompressETC2Block(uint8_t dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8],uint64_t src,uint8_t alphaDst[ETC2_UNCOMPRESSED_BLOCK_SIZE_A8],bool alphaMode)651*35238bceSAndroid Build Coastguard Worker void decompressETC2Block(uint8_t dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8], uint64_t src,
652*35238bceSAndroid Build Coastguard Worker uint8_t alphaDst[ETC2_UNCOMPRESSED_BLOCK_SIZE_A8], bool alphaMode)
653*35238bceSAndroid Build Coastguard Worker {
654*35238bceSAndroid Build Coastguard Worker enum Etc2Mode
655*35238bceSAndroid Build Coastguard Worker {
656*35238bceSAndroid Build Coastguard Worker MODE_INDIVIDUAL = 0,
657*35238bceSAndroid Build Coastguard Worker MODE_DIFFERENTIAL,
658*35238bceSAndroid Build Coastguard Worker MODE_T,
659*35238bceSAndroid Build Coastguard Worker MODE_H,
660*35238bceSAndroid Build Coastguard Worker MODE_PLANAR,
661*35238bceSAndroid Build Coastguard Worker
662*35238bceSAndroid Build Coastguard Worker MODE_LAST
663*35238bceSAndroid Build Coastguard Worker };
664*35238bceSAndroid Build Coastguard Worker
665*35238bceSAndroid Build Coastguard Worker const int diffOpaqueBit = (int)getBit(src, 33);
666*35238bceSAndroid Build Coastguard Worker const int8_t selBR = (int8_t)getBits(src, 59, 63); // 5 bits.
667*35238bceSAndroid Build Coastguard Worker const int8_t selBG = (int8_t)getBits(src, 51, 55);
668*35238bceSAndroid Build Coastguard Worker const int8_t selBB = (int8_t)getBits(src, 43, 47);
669*35238bceSAndroid Build Coastguard Worker const int8_t selDR = extendSigned3To8((uint8_t)getBits(src, 56, 58)); // 3 bits.
670*35238bceSAndroid Build Coastguard Worker const int8_t selDG = extendSigned3To8((uint8_t)getBits(src, 48, 50));
671*35238bceSAndroid Build Coastguard Worker const int8_t selDB = extendSigned3To8((uint8_t)getBits(src, 40, 42));
672*35238bceSAndroid Build Coastguard Worker Etc2Mode mode;
673*35238bceSAndroid Build Coastguard Worker
674*35238bceSAndroid Build Coastguard Worker if (!alphaMode && diffOpaqueBit == 0)
675*35238bceSAndroid Build Coastguard Worker mode = MODE_INDIVIDUAL;
676*35238bceSAndroid Build Coastguard Worker else if (!de::inRange(selBR + selDR, 0, 31))
677*35238bceSAndroid Build Coastguard Worker mode = MODE_T;
678*35238bceSAndroid Build Coastguard Worker else if (!de::inRange(selBG + selDG, 0, 31))
679*35238bceSAndroid Build Coastguard Worker mode = MODE_H;
680*35238bceSAndroid Build Coastguard Worker else if (!de::inRange(selBB + selDB, 0, 31))
681*35238bceSAndroid Build Coastguard Worker mode = MODE_PLANAR;
682*35238bceSAndroid Build Coastguard Worker else
683*35238bceSAndroid Build Coastguard Worker mode = MODE_DIFFERENTIAL;
684*35238bceSAndroid Build Coastguard Worker
685*35238bceSAndroid Build Coastguard Worker if (mode == MODE_INDIVIDUAL || mode == MODE_DIFFERENTIAL)
686*35238bceSAndroid Build Coastguard Worker {
687*35238bceSAndroid Build Coastguard Worker // Individual and differential modes have some steps in common, handle them here.
688*35238bceSAndroid Build Coastguard Worker static const int modifierTable[8][4] = {// 00 01 10 11
689*35238bceSAndroid Build Coastguard Worker {2, 8, -2, -8}, {5, 17, -5, -17}, {9, 29, -9, -29},
690*35238bceSAndroid Build Coastguard Worker {13, 42, -13, -42}, {18, 60, -18, -60}, {24, 80, -24, -80},
691*35238bceSAndroid Build Coastguard Worker {33, 106, -33, -106}, {47, 183, -47, -183}};
692*35238bceSAndroid Build Coastguard Worker
693*35238bceSAndroid Build Coastguard Worker const int flipBit = (int)getBit(src, 32);
694*35238bceSAndroid Build Coastguard Worker const uint32_t table[2] = {getBits(src, 37, 39), getBits(src, 34, 36)};
695*35238bceSAndroid Build Coastguard Worker uint8_t baseR[2];
696*35238bceSAndroid Build Coastguard Worker uint8_t baseG[2];
697*35238bceSAndroid Build Coastguard Worker uint8_t baseB[2];
698*35238bceSAndroid Build Coastguard Worker
699*35238bceSAndroid Build Coastguard Worker if (mode == MODE_INDIVIDUAL)
700*35238bceSAndroid Build Coastguard Worker {
701*35238bceSAndroid Build Coastguard Worker // Individual mode, initial values.
702*35238bceSAndroid Build Coastguard Worker baseR[0] = extend4To8((uint8_t)getBits(src, 60, 63));
703*35238bceSAndroid Build Coastguard Worker baseR[1] = extend4To8((uint8_t)getBits(src, 56, 59));
704*35238bceSAndroid Build Coastguard Worker baseG[0] = extend4To8((uint8_t)getBits(src, 52, 55));
705*35238bceSAndroid Build Coastguard Worker baseG[1] = extend4To8((uint8_t)getBits(src, 48, 51));
706*35238bceSAndroid Build Coastguard Worker baseB[0] = extend4To8((uint8_t)getBits(src, 44, 47));
707*35238bceSAndroid Build Coastguard Worker baseB[1] = extend4To8((uint8_t)getBits(src, 40, 43));
708*35238bceSAndroid Build Coastguard Worker }
709*35238bceSAndroid Build Coastguard Worker else
710*35238bceSAndroid Build Coastguard Worker {
711*35238bceSAndroid Build Coastguard Worker // Differential mode, initial values.
712*35238bceSAndroid Build Coastguard Worker baseR[0] = extend5To8(selBR);
713*35238bceSAndroid Build Coastguard Worker baseG[0] = extend5To8(selBG);
714*35238bceSAndroid Build Coastguard Worker baseB[0] = extend5To8(selBB);
715*35238bceSAndroid Build Coastguard Worker
716*35238bceSAndroid Build Coastguard Worker baseR[1] = extend5To8((uint8_t)(selBR + selDR));
717*35238bceSAndroid Build Coastguard Worker baseG[1] = extend5To8((uint8_t)(selBG + selDG));
718*35238bceSAndroid Build Coastguard Worker baseB[1] = extend5To8((uint8_t)(selBB + selDB));
719*35238bceSAndroid Build Coastguard Worker }
720*35238bceSAndroid Build Coastguard Worker
721*35238bceSAndroid Build Coastguard Worker // Write final pixels for individual or differential mode.
722*35238bceSAndroid Build Coastguard Worker for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT * ETC2_BLOCK_WIDTH; pixelNdx++)
723*35238bceSAndroid Build Coastguard Worker {
724*35238bceSAndroid Build Coastguard Worker const int x = pixelNdx / ETC2_BLOCK_HEIGHT;
725*35238bceSAndroid Build Coastguard Worker const int y = pixelNdx % ETC2_BLOCK_HEIGHT;
726*35238bceSAndroid Build Coastguard Worker const int dstOffset = (y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8;
727*35238bceSAndroid Build Coastguard Worker const int subBlock = ((flipBit ? y : x) >= 2) ? 1 : 0;
728*35238bceSAndroid Build Coastguard Worker const uint32_t tableNdx = table[subBlock];
729*35238bceSAndroid Build Coastguard Worker const uint32_t modifierNdx = (getBit(src, 16 + pixelNdx) << 1) | getBit(src, pixelNdx);
730*35238bceSAndroid Build Coastguard Worker const int alphaDstOffset =
731*35238bceSAndroid Build Coastguard Worker (y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_A8; // Only needed for PUNCHTHROUGH version.
732*35238bceSAndroid Build Coastguard Worker
733*35238bceSAndroid Build Coastguard Worker // If doing PUNCHTHROUGH version (alphaMode), opaque bit may affect colors.
734*35238bceSAndroid Build Coastguard Worker if (alphaMode && diffOpaqueBit == 0 && modifierNdx == 2)
735*35238bceSAndroid Build Coastguard Worker {
736*35238bceSAndroid Build Coastguard Worker dst[dstOffset + 0] = 0;
737*35238bceSAndroid Build Coastguard Worker dst[dstOffset + 1] = 0;
738*35238bceSAndroid Build Coastguard Worker dst[dstOffset + 2] = 0;
739*35238bceSAndroid Build Coastguard Worker alphaDst[alphaDstOffset] = 0;
740*35238bceSAndroid Build Coastguard Worker }
741*35238bceSAndroid Build Coastguard Worker else
742*35238bceSAndroid Build Coastguard Worker {
743*35238bceSAndroid Build Coastguard Worker int modifier;
744*35238bceSAndroid Build Coastguard Worker
745*35238bceSAndroid Build Coastguard Worker // PUNCHTHROUGH version and opaque bit may also affect modifiers.
746*35238bceSAndroid Build Coastguard Worker if (alphaMode && diffOpaqueBit == 0 && (modifierNdx == 0 || modifierNdx == 2))
747*35238bceSAndroid Build Coastguard Worker modifier = 0;
748*35238bceSAndroid Build Coastguard Worker else
749*35238bceSAndroid Build Coastguard Worker modifier = modifierTable[tableNdx][modifierNdx];
750*35238bceSAndroid Build Coastguard Worker
751*35238bceSAndroid Build Coastguard Worker dst[dstOffset + 0] = (uint8_t)deClamp32((int)baseR[subBlock] + modifier, 0, 255);
752*35238bceSAndroid Build Coastguard Worker dst[dstOffset + 1] = (uint8_t)deClamp32((int)baseG[subBlock] + modifier, 0, 255);
753*35238bceSAndroid Build Coastguard Worker dst[dstOffset + 2] = (uint8_t)deClamp32((int)baseB[subBlock] + modifier, 0, 255);
754*35238bceSAndroid Build Coastguard Worker
755*35238bceSAndroid Build Coastguard Worker if (alphaMode)
756*35238bceSAndroid Build Coastguard Worker alphaDst[alphaDstOffset] = 255;
757*35238bceSAndroid Build Coastguard Worker }
758*35238bceSAndroid Build Coastguard Worker }
759*35238bceSAndroid Build Coastguard Worker }
760*35238bceSAndroid Build Coastguard Worker else if (mode == MODE_T || mode == MODE_H)
761*35238bceSAndroid Build Coastguard Worker {
762*35238bceSAndroid Build Coastguard Worker // T and H modes have some steps in common, handle them here.
763*35238bceSAndroid Build Coastguard Worker static const int distTable[8] = {3, 6, 11, 16, 23, 32, 41, 64};
764*35238bceSAndroid Build Coastguard Worker
765*35238bceSAndroid Build Coastguard Worker uint8_t paintR[4];
766*35238bceSAndroid Build Coastguard Worker uint8_t paintG[4];
767*35238bceSAndroid Build Coastguard Worker uint8_t paintB[4];
768*35238bceSAndroid Build Coastguard Worker
769*35238bceSAndroid Build Coastguard Worker if (mode == MODE_T)
770*35238bceSAndroid Build Coastguard Worker {
771*35238bceSAndroid Build Coastguard Worker // T mode, calculate paint values.
772*35238bceSAndroid Build Coastguard Worker const uint8_t R1a = (uint8_t)getBits(src, 59, 60);
773*35238bceSAndroid Build Coastguard Worker const uint8_t R1b = (uint8_t)getBits(src, 56, 57);
774*35238bceSAndroid Build Coastguard Worker const uint8_t G1 = (uint8_t)getBits(src, 52, 55);
775*35238bceSAndroid Build Coastguard Worker const uint8_t B1 = (uint8_t)getBits(src, 48, 51);
776*35238bceSAndroid Build Coastguard Worker const uint8_t R2 = (uint8_t)getBits(src, 44, 47);
777*35238bceSAndroid Build Coastguard Worker const uint8_t G2 = (uint8_t)getBits(src, 40, 43);
778*35238bceSAndroid Build Coastguard Worker const uint8_t B2 = (uint8_t)getBits(src, 36, 39);
779*35238bceSAndroid Build Coastguard Worker const uint32_t distNdx = (getBits(src, 34, 35) << 1) | getBit(src, 32);
780*35238bceSAndroid Build Coastguard Worker const int dist = distTable[distNdx];
781*35238bceSAndroid Build Coastguard Worker
782*35238bceSAndroid Build Coastguard Worker paintR[0] = extend4To8((uint8_t)((R1a << 2) | R1b));
783*35238bceSAndroid Build Coastguard Worker paintG[0] = extend4To8(G1);
784*35238bceSAndroid Build Coastguard Worker paintB[0] = extend4To8(B1);
785*35238bceSAndroid Build Coastguard Worker paintR[2] = extend4To8(R2);
786*35238bceSAndroid Build Coastguard Worker paintG[2] = extend4To8(G2);
787*35238bceSAndroid Build Coastguard Worker paintB[2] = extend4To8(B2);
788*35238bceSAndroid Build Coastguard Worker paintR[1] = (uint8_t)deClamp32((int)paintR[2] + dist, 0, 255);
789*35238bceSAndroid Build Coastguard Worker paintG[1] = (uint8_t)deClamp32((int)paintG[2] + dist, 0, 255);
790*35238bceSAndroid Build Coastguard Worker paintB[1] = (uint8_t)deClamp32((int)paintB[2] + dist, 0, 255);
791*35238bceSAndroid Build Coastguard Worker paintR[3] = (uint8_t)deClamp32((int)paintR[2] - dist, 0, 255);
792*35238bceSAndroid Build Coastguard Worker paintG[3] = (uint8_t)deClamp32((int)paintG[2] - dist, 0, 255);
793*35238bceSAndroid Build Coastguard Worker paintB[3] = (uint8_t)deClamp32((int)paintB[2] - dist, 0, 255);
794*35238bceSAndroid Build Coastguard Worker }
795*35238bceSAndroid Build Coastguard Worker else
796*35238bceSAndroid Build Coastguard Worker {
797*35238bceSAndroid Build Coastguard Worker // H mode, calculate paint values.
798*35238bceSAndroid Build Coastguard Worker const uint8_t R1 = (uint8_t)getBits(src, 59, 62);
799*35238bceSAndroid Build Coastguard Worker const uint8_t G1a = (uint8_t)getBits(src, 56, 58);
800*35238bceSAndroid Build Coastguard Worker const uint8_t G1b = (uint8_t)getBit(src, 52);
801*35238bceSAndroid Build Coastguard Worker const uint8_t B1a = (uint8_t)getBit(src, 51);
802*35238bceSAndroid Build Coastguard Worker const uint8_t B1b = (uint8_t)getBits(src, 47, 49);
803*35238bceSAndroid Build Coastguard Worker const uint8_t R2 = (uint8_t)getBits(src, 43, 46);
804*35238bceSAndroid Build Coastguard Worker const uint8_t G2 = (uint8_t)getBits(src, 39, 42);
805*35238bceSAndroid Build Coastguard Worker const uint8_t B2 = (uint8_t)getBits(src, 35, 38);
806*35238bceSAndroid Build Coastguard Worker uint8_t baseR[2];
807*35238bceSAndroid Build Coastguard Worker uint8_t baseG[2];
808*35238bceSAndroid Build Coastguard Worker uint8_t baseB[2];
809*35238bceSAndroid Build Coastguard Worker uint32_t baseValue[2];
810*35238bceSAndroid Build Coastguard Worker uint32_t distNdx;
811*35238bceSAndroid Build Coastguard Worker int dist;
812*35238bceSAndroid Build Coastguard Worker
813*35238bceSAndroid Build Coastguard Worker baseR[0] = extend4To8(R1);
814*35238bceSAndroid Build Coastguard Worker baseG[0] = extend4To8((uint8_t)((G1a << 1) | G1b));
815*35238bceSAndroid Build Coastguard Worker baseB[0] = extend4To8((uint8_t)((B1a << 3) | B1b));
816*35238bceSAndroid Build Coastguard Worker baseR[1] = extend4To8(R2);
817*35238bceSAndroid Build Coastguard Worker baseG[1] = extend4To8(G2);
818*35238bceSAndroid Build Coastguard Worker baseB[1] = extend4To8(B2);
819*35238bceSAndroid Build Coastguard Worker baseValue[0] = (((uint32_t)baseR[0]) << 16) | (((uint32_t)baseG[0]) << 8) | baseB[0];
820*35238bceSAndroid Build Coastguard Worker baseValue[1] = (((uint32_t)baseR[1]) << 16) | (((uint32_t)baseG[1]) << 8) | baseB[1];
821*35238bceSAndroid Build Coastguard Worker distNdx = (getBit(src, 34) << 2) | (getBit(src, 32) << 1) | (uint32_t)(baseValue[0] >= baseValue[1]);
822*35238bceSAndroid Build Coastguard Worker dist = distTable[distNdx];
823*35238bceSAndroid Build Coastguard Worker
824*35238bceSAndroid Build Coastguard Worker paintR[0] = (uint8_t)deClamp32((int)baseR[0] + dist, 0, 255);
825*35238bceSAndroid Build Coastguard Worker paintG[0] = (uint8_t)deClamp32((int)baseG[0] + dist, 0, 255);
826*35238bceSAndroid Build Coastguard Worker paintB[0] = (uint8_t)deClamp32((int)baseB[0] + dist, 0, 255);
827*35238bceSAndroid Build Coastguard Worker paintR[1] = (uint8_t)deClamp32((int)baseR[0] - dist, 0, 255);
828*35238bceSAndroid Build Coastguard Worker paintG[1] = (uint8_t)deClamp32((int)baseG[0] - dist, 0, 255);
829*35238bceSAndroid Build Coastguard Worker paintB[1] = (uint8_t)deClamp32((int)baseB[0] - dist, 0, 255);
830*35238bceSAndroid Build Coastguard Worker paintR[2] = (uint8_t)deClamp32((int)baseR[1] + dist, 0, 255);
831*35238bceSAndroid Build Coastguard Worker paintG[2] = (uint8_t)deClamp32((int)baseG[1] + dist, 0, 255);
832*35238bceSAndroid Build Coastguard Worker paintB[2] = (uint8_t)deClamp32((int)baseB[1] + dist, 0, 255);
833*35238bceSAndroid Build Coastguard Worker paintR[3] = (uint8_t)deClamp32((int)baseR[1] - dist, 0, 255);
834*35238bceSAndroid Build Coastguard Worker paintG[3] = (uint8_t)deClamp32((int)baseG[1] - dist, 0, 255);
835*35238bceSAndroid Build Coastguard Worker paintB[3] = (uint8_t)deClamp32((int)baseB[1] - dist, 0, 255);
836*35238bceSAndroid Build Coastguard Worker }
837*35238bceSAndroid Build Coastguard Worker
838*35238bceSAndroid Build Coastguard Worker // Write final pixels for T or H mode.
839*35238bceSAndroid Build Coastguard Worker for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT * ETC2_BLOCK_WIDTH; pixelNdx++)
840*35238bceSAndroid Build Coastguard Worker {
841*35238bceSAndroid Build Coastguard Worker const int x = pixelNdx / ETC2_BLOCK_HEIGHT;
842*35238bceSAndroid Build Coastguard Worker const int y = pixelNdx % ETC2_BLOCK_HEIGHT;
843*35238bceSAndroid Build Coastguard Worker const int dstOffset = (y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8;
844*35238bceSAndroid Build Coastguard Worker const uint32_t paintNdx = (getBit(src, 16 + pixelNdx) << 1) | getBit(src, pixelNdx);
845*35238bceSAndroid Build Coastguard Worker const int alphaDstOffset =
846*35238bceSAndroid Build Coastguard Worker (y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_A8; // Only needed for PUNCHTHROUGH version.
847*35238bceSAndroid Build Coastguard Worker
848*35238bceSAndroid Build Coastguard Worker if (alphaMode && diffOpaqueBit == 0 && paintNdx == 2)
849*35238bceSAndroid Build Coastguard Worker {
850*35238bceSAndroid Build Coastguard Worker dst[dstOffset + 0] = 0;
851*35238bceSAndroid Build Coastguard Worker dst[dstOffset + 1] = 0;
852*35238bceSAndroid Build Coastguard Worker dst[dstOffset + 2] = 0;
853*35238bceSAndroid Build Coastguard Worker alphaDst[alphaDstOffset] = 0;
854*35238bceSAndroid Build Coastguard Worker }
855*35238bceSAndroid Build Coastguard Worker else
856*35238bceSAndroid Build Coastguard Worker {
857*35238bceSAndroid Build Coastguard Worker dst[dstOffset + 0] = (uint8_t)deClamp32((int)paintR[paintNdx], 0, 255);
858*35238bceSAndroid Build Coastguard Worker dst[dstOffset + 1] = (uint8_t)deClamp32((int)paintG[paintNdx], 0, 255);
859*35238bceSAndroid Build Coastguard Worker dst[dstOffset + 2] = (uint8_t)deClamp32((int)paintB[paintNdx], 0, 255);
860*35238bceSAndroid Build Coastguard Worker
861*35238bceSAndroid Build Coastguard Worker if (alphaMode)
862*35238bceSAndroid Build Coastguard Worker alphaDst[alphaDstOffset] = 255;
863*35238bceSAndroid Build Coastguard Worker }
864*35238bceSAndroid Build Coastguard Worker }
865*35238bceSAndroid Build Coastguard Worker }
866*35238bceSAndroid Build Coastguard Worker else
867*35238bceSAndroid Build Coastguard Worker {
868*35238bceSAndroid Build Coastguard Worker // Planar mode.
869*35238bceSAndroid Build Coastguard Worker const uint8_t GO1 = (uint8_t)getBit(src, 56);
870*35238bceSAndroid Build Coastguard Worker const uint8_t GO2 = (uint8_t)getBits(src, 49, 54);
871*35238bceSAndroid Build Coastguard Worker const uint8_t BO1 = (uint8_t)getBit(src, 48);
872*35238bceSAndroid Build Coastguard Worker const uint8_t BO2 = (uint8_t)getBits(src, 43, 44);
873*35238bceSAndroid Build Coastguard Worker const uint8_t BO3 = (uint8_t)getBits(src, 39, 41);
874*35238bceSAndroid Build Coastguard Worker const uint8_t RH1 = (uint8_t)getBits(src, 34, 38);
875*35238bceSAndroid Build Coastguard Worker const uint8_t RH2 = (uint8_t)getBit(src, 32);
876*35238bceSAndroid Build Coastguard Worker const uint8_t RO = extend6To8((uint8_t)getBits(src, 57, 62));
877*35238bceSAndroid Build Coastguard Worker const uint8_t GO = extend7To8((uint8_t)((GO1 << 6) | GO2));
878*35238bceSAndroid Build Coastguard Worker const uint8_t BO = extend6To8((uint8_t)((BO1 << 5) | (BO2 << 3) | BO3));
879*35238bceSAndroid Build Coastguard Worker const uint8_t RH = extend6To8((uint8_t)((RH1 << 1) | RH2));
880*35238bceSAndroid Build Coastguard Worker const uint8_t GH = extend7To8((uint8_t)getBits(src, 25, 31));
881*35238bceSAndroid Build Coastguard Worker const uint8_t BH = extend6To8((uint8_t)getBits(src, 19, 24));
882*35238bceSAndroid Build Coastguard Worker const uint8_t RV = extend6To8((uint8_t)getBits(src, 13, 18));
883*35238bceSAndroid Build Coastguard Worker const uint8_t GV = extend7To8((uint8_t)getBits(src, 6, 12));
884*35238bceSAndroid Build Coastguard Worker const uint8_t BV = extend6To8((uint8_t)getBits(src, 0, 5));
885*35238bceSAndroid Build Coastguard Worker
886*35238bceSAndroid Build Coastguard Worker // Write final pixels for planar mode.
887*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < 4; y++)
888*35238bceSAndroid Build Coastguard Worker {
889*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < 4; x++)
890*35238bceSAndroid Build Coastguard Worker {
891*35238bceSAndroid Build Coastguard Worker const int dstOffset = (y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8;
892*35238bceSAndroid Build Coastguard Worker const int unclampedR = (x * ((int)RH - (int)RO) + y * ((int)RV - (int)RO) + 4 * (int)RO + 2) >> 2;
893*35238bceSAndroid Build Coastguard Worker const int unclampedG = (x * ((int)GH - (int)GO) + y * ((int)GV - (int)GO) + 4 * (int)GO + 2) >> 2;
894*35238bceSAndroid Build Coastguard Worker const int unclampedB = (x * ((int)BH - (int)BO) + y * ((int)BV - (int)BO) + 4 * (int)BO + 2) >> 2;
895*35238bceSAndroid Build Coastguard Worker const int alphaDstOffset = (y * ETC2_BLOCK_WIDTH + x) *
896*35238bceSAndroid Build Coastguard Worker ETC2_UNCOMPRESSED_PIXEL_SIZE_A8; // Only needed for PUNCHTHROUGH version.
897*35238bceSAndroid Build Coastguard Worker
898*35238bceSAndroid Build Coastguard Worker dst[dstOffset + 0] = (uint8_t)deClamp32(unclampedR, 0, 255);
899*35238bceSAndroid Build Coastguard Worker dst[dstOffset + 1] = (uint8_t)deClamp32(unclampedG, 0, 255);
900*35238bceSAndroid Build Coastguard Worker dst[dstOffset + 2] = (uint8_t)deClamp32(unclampedB, 0, 255);
901*35238bceSAndroid Build Coastguard Worker
902*35238bceSAndroid Build Coastguard Worker if (alphaMode)
903*35238bceSAndroid Build Coastguard Worker alphaDst[alphaDstOffset] = 255;
904*35238bceSAndroid Build Coastguard Worker }
905*35238bceSAndroid Build Coastguard Worker }
906*35238bceSAndroid Build Coastguard Worker }
907*35238bceSAndroid Build Coastguard Worker }
908*35238bceSAndroid Build Coastguard Worker
decompressEAC8Block(uint8_t dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_A8],uint64_t src)909*35238bceSAndroid Build Coastguard Worker void decompressEAC8Block(uint8_t dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_A8], uint64_t src)
910*35238bceSAndroid Build Coastguard Worker {
911*35238bceSAndroid Build Coastguard Worker static const int modifierTable[16][8] = {
912*35238bceSAndroid Build Coastguard Worker {-3, -6, -9, -15, 2, 5, 8, 14}, {-3, -7, -10, -13, 2, 6, 9, 12}, {-2, -5, -8, -13, 1, 4, 7, 12},
913*35238bceSAndroid Build Coastguard Worker {-2, -4, -6, -13, 1, 3, 5, 12}, {-3, -6, -8, -12, 2, 5, 7, 11}, {-3, -7, -9, -11, 2, 6, 8, 10},
914*35238bceSAndroid Build Coastguard Worker {-4, -7, -8, -11, 3, 6, 7, 10}, {-3, -5, -8, -11, 2, 4, 7, 10}, {-2, -6, -8, -10, 1, 5, 7, 9},
915*35238bceSAndroid Build Coastguard Worker {-2, -5, -8, -10, 1, 4, 7, 9}, {-2, -4, -8, -10, 1, 3, 7, 9}, {-2, -5, -7, -10, 1, 4, 6, 9},
916*35238bceSAndroid Build Coastguard Worker {-3, -4, -7, -10, 2, 3, 6, 9}, {-1, -2, -3, -10, 0, 1, 2, 9}, {-4, -6, -8, -9, 3, 5, 7, 8},
917*35238bceSAndroid Build Coastguard Worker {-3, -5, -7, -9, 2, 4, 6, 8}};
918*35238bceSAndroid Build Coastguard Worker
919*35238bceSAndroid Build Coastguard Worker const uint8_t baseCodeword = (uint8_t)getBits(src, 56, 63);
920*35238bceSAndroid Build Coastguard Worker const uint8_t multiplier = (uint8_t)getBits(src, 52, 55);
921*35238bceSAndroid Build Coastguard Worker const uint32_t tableNdx = getBits(src, 48, 51);
922*35238bceSAndroid Build Coastguard Worker
923*35238bceSAndroid Build Coastguard Worker for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT * ETC2_BLOCK_WIDTH; pixelNdx++)
924*35238bceSAndroid Build Coastguard Worker {
925*35238bceSAndroid Build Coastguard Worker const int x = pixelNdx / ETC2_BLOCK_HEIGHT;
926*35238bceSAndroid Build Coastguard Worker const int y = pixelNdx % ETC2_BLOCK_HEIGHT;
927*35238bceSAndroid Build Coastguard Worker const int dstOffset = (y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_A8;
928*35238bceSAndroid Build Coastguard Worker const int pixelBitNdx = 45 - 3 * pixelNdx;
929*35238bceSAndroid Build Coastguard Worker const uint32_t modifierNdx =
930*35238bceSAndroid Build Coastguard Worker (getBit(src, pixelBitNdx + 2) << 2) | (getBit(src, pixelBitNdx + 1) << 1) | getBit(src, pixelBitNdx);
931*35238bceSAndroid Build Coastguard Worker const int modifier = modifierTable[tableNdx][modifierNdx];
932*35238bceSAndroid Build Coastguard Worker
933*35238bceSAndroid Build Coastguard Worker dst[dstOffset] = (uint8_t)deClamp32((int)baseCodeword + (int)multiplier * modifier, 0, 255);
934*35238bceSAndroid Build Coastguard Worker }
935*35238bceSAndroid Build Coastguard Worker }
936*35238bceSAndroid Build Coastguard Worker
decompressEAC11Block(uint8_t dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_R11],uint64_t src,bool signedMode)937*35238bceSAndroid Build Coastguard Worker void decompressEAC11Block(uint8_t dst[ETC2_UNCOMPRESSED_BLOCK_SIZE_R11], uint64_t src, bool signedMode)
938*35238bceSAndroid Build Coastguard Worker {
939*35238bceSAndroid Build Coastguard Worker static const int modifierTable[16][8] = {
940*35238bceSAndroid Build Coastguard Worker {-3, -6, -9, -15, 2, 5, 8, 14}, {-3, -7, -10, -13, 2, 6, 9, 12}, {-2, -5, -8, -13, 1, 4, 7, 12},
941*35238bceSAndroid Build Coastguard Worker {-2, -4, -6, -13, 1, 3, 5, 12}, {-3, -6, -8, -12, 2, 5, 7, 11}, {-3, -7, -9, -11, 2, 6, 8, 10},
942*35238bceSAndroid Build Coastguard Worker {-4, -7, -8, -11, 3, 6, 7, 10}, {-3, -5, -8, -11, 2, 4, 7, 10}, {-2, -6, -8, -10, 1, 5, 7, 9},
943*35238bceSAndroid Build Coastguard Worker {-2, -5, -8, -10, 1, 4, 7, 9}, {-2, -4, -8, -10, 1, 3, 7, 9}, {-2, -5, -7, -10, 1, 4, 6, 9},
944*35238bceSAndroid Build Coastguard Worker {-3, -4, -7, -10, 2, 3, 6, 9}, {-1, -2, -3, -10, 0, 1, 2, 9}, {-4, -6, -8, -9, 3, 5, 7, 8},
945*35238bceSAndroid Build Coastguard Worker {-3, -5, -7, -9, 2, 4, 6, 8}};
946*35238bceSAndroid Build Coastguard Worker
947*35238bceSAndroid Build Coastguard Worker const int32_t multiplier = (int32_t)getBits(src, 52, 55);
948*35238bceSAndroid Build Coastguard Worker const int32_t tableNdx = (int32_t)getBits(src, 48, 51);
949*35238bceSAndroid Build Coastguard Worker int32_t baseCodeword = (int32_t)getBits(src, 56, 63);
950*35238bceSAndroid Build Coastguard Worker
951*35238bceSAndroid Build Coastguard Worker if (signedMode)
952*35238bceSAndroid Build Coastguard Worker {
953*35238bceSAndroid Build Coastguard Worker if (baseCodeword > 127)
954*35238bceSAndroid Build Coastguard Worker baseCodeword -= 256;
955*35238bceSAndroid Build Coastguard Worker if (baseCodeword == -128)
956*35238bceSAndroid Build Coastguard Worker baseCodeword = -127;
957*35238bceSAndroid Build Coastguard Worker }
958*35238bceSAndroid Build Coastguard Worker
959*35238bceSAndroid Build Coastguard Worker for (int pixelNdx = 0; pixelNdx < ETC2_BLOCK_HEIGHT * ETC2_BLOCK_WIDTH; pixelNdx++)
960*35238bceSAndroid Build Coastguard Worker {
961*35238bceSAndroid Build Coastguard Worker const int x = pixelNdx / ETC2_BLOCK_HEIGHT;
962*35238bceSAndroid Build Coastguard Worker const int y = pixelNdx % ETC2_BLOCK_HEIGHT;
963*35238bceSAndroid Build Coastguard Worker const int dstOffset = (y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_R11;
964*35238bceSAndroid Build Coastguard Worker const int pixelBitNdx = 45 - 3 * pixelNdx;
965*35238bceSAndroid Build Coastguard Worker const uint32_t modifierNdx =
966*35238bceSAndroid Build Coastguard Worker (getBit(src, pixelBitNdx + 2) << 2) | (getBit(src, pixelBitNdx + 1) << 1) | getBit(src, pixelBitNdx);
967*35238bceSAndroid Build Coastguard Worker const int modifier = modifierTable[tableNdx][modifierNdx];
968*35238bceSAndroid Build Coastguard Worker
969*35238bceSAndroid Build Coastguard Worker if (signedMode)
970*35238bceSAndroid Build Coastguard Worker {
971*35238bceSAndroid Build Coastguard Worker int16_t value;
972*35238bceSAndroid Build Coastguard Worker
973*35238bceSAndroid Build Coastguard Worker if (multiplier != 0)
974*35238bceSAndroid Build Coastguard Worker value = (int16_t)deClamp32(baseCodeword * 8 + multiplier * modifier * 8, -1023, 1023);
975*35238bceSAndroid Build Coastguard Worker else
976*35238bceSAndroid Build Coastguard Worker value = (int16_t)deClamp32(baseCodeword * 8 + modifier, -1023, 1023);
977*35238bceSAndroid Build Coastguard Worker
978*35238bceSAndroid Build Coastguard Worker *((int16_t *)(dst + dstOffset)) = value;
979*35238bceSAndroid Build Coastguard Worker }
980*35238bceSAndroid Build Coastguard Worker else
981*35238bceSAndroid Build Coastguard Worker {
982*35238bceSAndroid Build Coastguard Worker uint16_t value;
983*35238bceSAndroid Build Coastguard Worker
984*35238bceSAndroid Build Coastguard Worker if (multiplier != 0)
985*35238bceSAndroid Build Coastguard Worker value = (uint16_t)deClamp32(baseCodeword * 8 + 4 + multiplier * modifier * 8, 0, 2047);
986*35238bceSAndroid Build Coastguard Worker else
987*35238bceSAndroid Build Coastguard Worker value = (uint16_t)deClamp32(baseCodeword * 8 + 4 + modifier, 0, 2047);
988*35238bceSAndroid Build Coastguard Worker
989*35238bceSAndroid Build Coastguard Worker *((uint16_t *)(dst + dstOffset)) = value;
990*35238bceSAndroid Build Coastguard Worker }
991*35238bceSAndroid Build Coastguard Worker }
992*35238bceSAndroid Build Coastguard Worker }
993*35238bceSAndroid Build Coastguard Worker
994*35238bceSAndroid Build Coastguard Worker } // namespace EtcDecompressInternal
995*35238bceSAndroid Build Coastguard Worker
decompressETC1(const PixelBufferAccess & dst,const uint8_t * src)996*35238bceSAndroid Build Coastguard Worker void decompressETC1(const PixelBufferAccess &dst, const uint8_t *src)
997*35238bceSAndroid Build Coastguard Worker {
998*35238bceSAndroid Build Coastguard Worker using namespace EtcDecompressInternal;
999*35238bceSAndroid Build Coastguard Worker
1000*35238bceSAndroid Build Coastguard Worker uint8_t *const dstPtr = (uint8_t *)dst.getDataPtr();
1001*35238bceSAndroid Build Coastguard Worker const uint64_t compressedBlock = get64BitBlock(src, 0);
1002*35238bceSAndroid Build Coastguard Worker
1003*35238bceSAndroid Build Coastguard Worker decompressETC1Block(dstPtr, compressedBlock);
1004*35238bceSAndroid Build Coastguard Worker }
1005*35238bceSAndroid Build Coastguard Worker
decompressETC2(const PixelBufferAccess & dst,const uint8_t * src)1006*35238bceSAndroid Build Coastguard Worker void decompressETC2(const PixelBufferAccess &dst, const uint8_t *src)
1007*35238bceSAndroid Build Coastguard Worker {
1008*35238bceSAndroid Build Coastguard Worker using namespace EtcDecompressInternal;
1009*35238bceSAndroid Build Coastguard Worker
1010*35238bceSAndroid Build Coastguard Worker uint8_t *const dstPtr = (uint8_t *)dst.getDataPtr();
1011*35238bceSAndroid Build Coastguard Worker const uint64_t compressedBlock = get64BitBlock(src, 0);
1012*35238bceSAndroid Build Coastguard Worker
1013*35238bceSAndroid Build Coastguard Worker decompressETC2Block(dstPtr, compressedBlock, NULL, false);
1014*35238bceSAndroid Build Coastguard Worker }
1015*35238bceSAndroid Build Coastguard Worker
decompressETC2_EAC_RGBA8(const PixelBufferAccess & dst,const uint8_t * src)1016*35238bceSAndroid Build Coastguard Worker void decompressETC2_EAC_RGBA8(const PixelBufferAccess &dst, const uint8_t *src)
1017*35238bceSAndroid Build Coastguard Worker {
1018*35238bceSAndroid Build Coastguard Worker using namespace EtcDecompressInternal;
1019*35238bceSAndroid Build Coastguard Worker
1020*35238bceSAndroid Build Coastguard Worker uint8_t *const dstPtr = (uint8_t *)dst.getDataPtr();
1021*35238bceSAndroid Build Coastguard Worker const int dstRowPitch = dst.getRowPitch();
1022*35238bceSAndroid Build Coastguard Worker const int dstPixelSize = ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8;
1023*35238bceSAndroid Build Coastguard Worker
1024*35238bceSAndroid Build Coastguard Worker const uint64_t compressedBlockAlpha = get128BitBlockStart(src, 0);
1025*35238bceSAndroid Build Coastguard Worker const uint64_t compressedBlockRGB = get128BitBlockEnd(src, 0);
1026*35238bceSAndroid Build Coastguard Worker uint8_t uncompressedBlockAlpha[ETC2_UNCOMPRESSED_BLOCK_SIZE_A8];
1027*35238bceSAndroid Build Coastguard Worker uint8_t uncompressedBlockRGB[ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8];
1028*35238bceSAndroid Build Coastguard Worker
1029*35238bceSAndroid Build Coastguard Worker // Decompress.
1030*35238bceSAndroid Build Coastguard Worker decompressETC2Block(uncompressedBlockRGB, compressedBlockRGB, NULL, false);
1031*35238bceSAndroid Build Coastguard Worker decompressEAC8Block(uncompressedBlockAlpha, compressedBlockAlpha);
1032*35238bceSAndroid Build Coastguard Worker
1033*35238bceSAndroid Build Coastguard Worker // Write to dst.
1034*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < (int)ETC2_BLOCK_HEIGHT; y++)
1035*35238bceSAndroid Build Coastguard Worker {
1036*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < (int)ETC2_BLOCK_WIDTH; x++)
1037*35238bceSAndroid Build Coastguard Worker {
1038*35238bceSAndroid Build Coastguard Worker const uint8_t *const srcPixelRGB =
1039*35238bceSAndroid Build Coastguard Worker &uncompressedBlockRGB[(y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8];
1040*35238bceSAndroid Build Coastguard Worker const uint8_t *const srcPixelAlpha =
1041*35238bceSAndroid Build Coastguard Worker &uncompressedBlockAlpha[(y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_A8];
1042*35238bceSAndroid Build Coastguard Worker uint8_t *const dstPixel = dstPtr + y * dstRowPitch + x * dstPixelSize;
1043*35238bceSAndroid Build Coastguard Worker
1044*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8 == 4);
1045*35238bceSAndroid Build Coastguard Worker dstPixel[0] = srcPixelRGB[0];
1046*35238bceSAndroid Build Coastguard Worker dstPixel[1] = srcPixelRGB[1];
1047*35238bceSAndroid Build Coastguard Worker dstPixel[2] = srcPixelRGB[2];
1048*35238bceSAndroid Build Coastguard Worker dstPixel[3] = srcPixelAlpha[0];
1049*35238bceSAndroid Build Coastguard Worker }
1050*35238bceSAndroid Build Coastguard Worker }
1051*35238bceSAndroid Build Coastguard Worker }
1052*35238bceSAndroid Build Coastguard Worker
decompressETC2_RGB8_PUNCHTHROUGH_ALPHA1(const PixelBufferAccess & dst,const uint8_t * src)1053*35238bceSAndroid Build Coastguard Worker void decompressETC2_RGB8_PUNCHTHROUGH_ALPHA1(const PixelBufferAccess &dst, const uint8_t *src)
1054*35238bceSAndroid Build Coastguard Worker {
1055*35238bceSAndroid Build Coastguard Worker using namespace EtcDecompressInternal;
1056*35238bceSAndroid Build Coastguard Worker
1057*35238bceSAndroid Build Coastguard Worker uint8_t *const dstPtr = (uint8_t *)dst.getDataPtr();
1058*35238bceSAndroid Build Coastguard Worker const int dstRowPitch = dst.getRowPitch();
1059*35238bceSAndroid Build Coastguard Worker const int dstPixelSize = ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8;
1060*35238bceSAndroid Build Coastguard Worker
1061*35238bceSAndroid Build Coastguard Worker const uint64_t compressedBlockRGBA = get64BitBlock(src, 0);
1062*35238bceSAndroid Build Coastguard Worker uint8_t uncompressedBlockRGB[ETC2_UNCOMPRESSED_BLOCK_SIZE_RGB8];
1063*35238bceSAndroid Build Coastguard Worker uint8_t uncompressedBlockAlpha[ETC2_UNCOMPRESSED_BLOCK_SIZE_A8];
1064*35238bceSAndroid Build Coastguard Worker
1065*35238bceSAndroid Build Coastguard Worker // Decompress.
1066*35238bceSAndroid Build Coastguard Worker decompressETC2Block(uncompressedBlockRGB, compressedBlockRGBA, uncompressedBlockAlpha, true);
1067*35238bceSAndroid Build Coastguard Worker
1068*35238bceSAndroid Build Coastguard Worker // Write to dst.
1069*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < (int)ETC2_BLOCK_HEIGHT; y++)
1070*35238bceSAndroid Build Coastguard Worker {
1071*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < (int)ETC2_BLOCK_WIDTH; x++)
1072*35238bceSAndroid Build Coastguard Worker {
1073*35238bceSAndroid Build Coastguard Worker const uint8_t *const srcPixel =
1074*35238bceSAndroid Build Coastguard Worker &uncompressedBlockRGB[(y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_RGB8];
1075*35238bceSAndroid Build Coastguard Worker const uint8_t *const srcPixelAlpha =
1076*35238bceSAndroid Build Coastguard Worker &uncompressedBlockAlpha[(y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_A8];
1077*35238bceSAndroid Build Coastguard Worker uint8_t *const dstPixel = dstPtr + y * dstRowPitch + x * dstPixelSize;
1078*35238bceSAndroid Build Coastguard Worker
1079*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(ETC2_UNCOMPRESSED_PIXEL_SIZE_RGBA8 == 4);
1080*35238bceSAndroid Build Coastguard Worker dstPixel[0] = srcPixel[0];
1081*35238bceSAndroid Build Coastguard Worker dstPixel[1] = srcPixel[1];
1082*35238bceSAndroid Build Coastguard Worker dstPixel[2] = srcPixel[2];
1083*35238bceSAndroid Build Coastguard Worker dstPixel[3] = srcPixelAlpha[0];
1084*35238bceSAndroid Build Coastguard Worker }
1085*35238bceSAndroid Build Coastguard Worker }
1086*35238bceSAndroid Build Coastguard Worker }
1087*35238bceSAndroid Build Coastguard Worker
decompressEAC_R11(const PixelBufferAccess & dst,const uint8_t * src,bool signedMode)1088*35238bceSAndroid Build Coastguard Worker void decompressEAC_R11(const PixelBufferAccess &dst, const uint8_t *src, bool signedMode)
1089*35238bceSAndroid Build Coastguard Worker {
1090*35238bceSAndroid Build Coastguard Worker using namespace EtcDecompressInternal;
1091*35238bceSAndroid Build Coastguard Worker
1092*35238bceSAndroid Build Coastguard Worker uint8_t *const dstPtr = (uint8_t *)dst.getDataPtr();
1093*35238bceSAndroid Build Coastguard Worker const int dstRowPitch = dst.getRowPitch();
1094*35238bceSAndroid Build Coastguard Worker const int dstPixelSize = ETC2_UNCOMPRESSED_PIXEL_SIZE_R11;
1095*35238bceSAndroid Build Coastguard Worker
1096*35238bceSAndroid Build Coastguard Worker const uint64_t compressedBlock = get64BitBlock(src, 0);
1097*35238bceSAndroid Build Coastguard Worker uint8_t uncompressedBlock[ETC2_UNCOMPRESSED_BLOCK_SIZE_R11];
1098*35238bceSAndroid Build Coastguard Worker
1099*35238bceSAndroid Build Coastguard Worker // Decompress.
1100*35238bceSAndroid Build Coastguard Worker decompressEAC11Block(uncompressedBlock, compressedBlock, signedMode);
1101*35238bceSAndroid Build Coastguard Worker
1102*35238bceSAndroid Build Coastguard Worker // Write to dst.
1103*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < (int)ETC2_BLOCK_HEIGHT; y++)
1104*35238bceSAndroid Build Coastguard Worker {
1105*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < (int)ETC2_BLOCK_WIDTH; x++)
1106*35238bceSAndroid Build Coastguard Worker {
1107*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(ETC2_UNCOMPRESSED_PIXEL_SIZE_R11 == 2);
1108*35238bceSAndroid Build Coastguard Worker
1109*35238bceSAndroid Build Coastguard Worker if (signedMode)
1110*35238bceSAndroid Build Coastguard Worker {
1111*35238bceSAndroid Build Coastguard Worker const int16_t *const srcPixel =
1112*35238bceSAndroid Build Coastguard Worker (int16_t *)&uncompressedBlock[(y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_R11];
1113*35238bceSAndroid Build Coastguard Worker int16_t *const dstPixel = (int16_t *)(dstPtr + y * dstRowPitch + x * dstPixelSize);
1114*35238bceSAndroid Build Coastguard Worker
1115*35238bceSAndroid Build Coastguard Worker dstPixel[0] = extend11To16WithSign(srcPixel[0]);
1116*35238bceSAndroid Build Coastguard Worker }
1117*35238bceSAndroid Build Coastguard Worker else
1118*35238bceSAndroid Build Coastguard Worker {
1119*35238bceSAndroid Build Coastguard Worker const uint16_t *const srcPixel =
1120*35238bceSAndroid Build Coastguard Worker (uint16_t *)&uncompressedBlock[(y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_R11];
1121*35238bceSAndroid Build Coastguard Worker uint16_t *const dstPixel = (uint16_t *)(dstPtr + y * dstRowPitch + x * dstPixelSize);
1122*35238bceSAndroid Build Coastguard Worker
1123*35238bceSAndroid Build Coastguard Worker dstPixel[0] = extend11To16(srcPixel[0]);
1124*35238bceSAndroid Build Coastguard Worker }
1125*35238bceSAndroid Build Coastguard Worker }
1126*35238bceSAndroid Build Coastguard Worker }
1127*35238bceSAndroid Build Coastguard Worker }
1128*35238bceSAndroid Build Coastguard Worker
decompressEAC_RG11(const PixelBufferAccess & dst,const uint8_t * src,bool signedMode)1129*35238bceSAndroid Build Coastguard Worker void decompressEAC_RG11(const PixelBufferAccess &dst, const uint8_t *src, bool signedMode)
1130*35238bceSAndroid Build Coastguard Worker {
1131*35238bceSAndroid Build Coastguard Worker using namespace EtcDecompressInternal;
1132*35238bceSAndroid Build Coastguard Worker
1133*35238bceSAndroid Build Coastguard Worker uint8_t *const dstPtr = (uint8_t *)dst.getDataPtr();
1134*35238bceSAndroid Build Coastguard Worker const int dstRowPitch = dst.getRowPitch();
1135*35238bceSAndroid Build Coastguard Worker const int dstPixelSize = ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11;
1136*35238bceSAndroid Build Coastguard Worker
1137*35238bceSAndroid Build Coastguard Worker const uint64_t compressedBlockR = get128BitBlockStart(src, 0);
1138*35238bceSAndroid Build Coastguard Worker const uint64_t compressedBlockG = get128BitBlockEnd(src, 0);
1139*35238bceSAndroid Build Coastguard Worker uint8_t uncompressedBlockR[ETC2_UNCOMPRESSED_BLOCK_SIZE_R11];
1140*35238bceSAndroid Build Coastguard Worker uint8_t uncompressedBlockG[ETC2_UNCOMPRESSED_BLOCK_SIZE_R11];
1141*35238bceSAndroid Build Coastguard Worker
1142*35238bceSAndroid Build Coastguard Worker // Decompress.
1143*35238bceSAndroid Build Coastguard Worker decompressEAC11Block(uncompressedBlockR, compressedBlockR, signedMode);
1144*35238bceSAndroid Build Coastguard Worker decompressEAC11Block(uncompressedBlockG, compressedBlockG, signedMode);
1145*35238bceSAndroid Build Coastguard Worker
1146*35238bceSAndroid Build Coastguard Worker // Write to dst.
1147*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < (int)ETC2_BLOCK_HEIGHT; y++)
1148*35238bceSAndroid Build Coastguard Worker {
1149*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < (int)ETC2_BLOCK_WIDTH; x++)
1150*35238bceSAndroid Build Coastguard Worker {
1151*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(ETC2_UNCOMPRESSED_PIXEL_SIZE_RG11 == 4);
1152*35238bceSAndroid Build Coastguard Worker
1153*35238bceSAndroid Build Coastguard Worker if (signedMode)
1154*35238bceSAndroid Build Coastguard Worker {
1155*35238bceSAndroid Build Coastguard Worker const int16_t *const srcPixelR =
1156*35238bceSAndroid Build Coastguard Worker (int16_t *)&uncompressedBlockR[(y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_R11];
1157*35238bceSAndroid Build Coastguard Worker const int16_t *const srcPixelG =
1158*35238bceSAndroid Build Coastguard Worker (int16_t *)&uncompressedBlockG[(y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_R11];
1159*35238bceSAndroid Build Coastguard Worker int16_t *const dstPixel = (int16_t *)(dstPtr + y * dstRowPitch + x * dstPixelSize);
1160*35238bceSAndroid Build Coastguard Worker
1161*35238bceSAndroid Build Coastguard Worker dstPixel[0] = extend11To16WithSign(srcPixelR[0]);
1162*35238bceSAndroid Build Coastguard Worker dstPixel[1] = extend11To16WithSign(srcPixelG[0]);
1163*35238bceSAndroid Build Coastguard Worker }
1164*35238bceSAndroid Build Coastguard Worker else
1165*35238bceSAndroid Build Coastguard Worker {
1166*35238bceSAndroid Build Coastguard Worker const uint16_t *const srcPixelR =
1167*35238bceSAndroid Build Coastguard Worker (uint16_t *)&uncompressedBlockR[(y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_R11];
1168*35238bceSAndroid Build Coastguard Worker const uint16_t *const srcPixelG =
1169*35238bceSAndroid Build Coastguard Worker (uint16_t *)&uncompressedBlockG[(y * ETC2_BLOCK_WIDTH + x) * ETC2_UNCOMPRESSED_PIXEL_SIZE_R11];
1170*35238bceSAndroid Build Coastguard Worker uint16_t *const dstPixel = (uint16_t *)(dstPtr + y * dstRowPitch + x * dstPixelSize);
1171*35238bceSAndroid Build Coastguard Worker
1172*35238bceSAndroid Build Coastguard Worker dstPixel[0] = extend11To16(srcPixelR[0]);
1173*35238bceSAndroid Build Coastguard Worker dstPixel[1] = extend11To16(srcPixelG[0]);
1174*35238bceSAndroid Build Coastguard Worker }
1175*35238bceSAndroid Build Coastguard Worker }
1176*35238bceSAndroid Build Coastguard Worker }
1177*35238bceSAndroid Build Coastguard Worker }
1178*35238bceSAndroid Build Coastguard Worker
1179*35238bceSAndroid Build Coastguard Worker namespace BcDecompressInternal
1180*35238bceSAndroid Build Coastguard Worker {
1181*35238bceSAndroid Build Coastguard Worker
1182*35238bceSAndroid Build Coastguard Worker enum
1183*35238bceSAndroid Build Coastguard Worker {
1184*35238bceSAndroid Build Coastguard Worker BC_BLOCK_WIDTH = 4,
1185*35238bceSAndroid Build Coastguard Worker BC_BLOCK_HEIGHT = 4
1186*35238bceSAndroid Build Coastguard Worker };
1187*35238bceSAndroid Build Coastguard Worker
1188*35238bceSAndroid Build Coastguard Worker static const uint8_t epBits[14] = {10, 7, 11, 11, 11, 9, 8, 8, 8, 6, 10, 11, 12, 16};
1189*35238bceSAndroid Build Coastguard Worker
1190*35238bceSAndroid Build Coastguard Worker static const uint8_t partitions2[64][16] = {
1191*35238bceSAndroid Build Coastguard Worker {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1}, {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1},
1192*35238bceSAndroid Build Coastguard Worker {0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1}, {0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1},
1193*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1}, {0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1},
1194*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1},
1195*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1}, {0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
1196*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1},
1197*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
1198*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1},
1199*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1}, {0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
1200*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0}, {0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0},
1201*35238bceSAndroid Build Coastguard Worker {0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0},
1202*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0}, {0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1},
1203*35238bceSAndroid Build Coastguard Worker {0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0},
1204*35238bceSAndroid Build Coastguard Worker {0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0}, {0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0},
1205*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0}, {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0},
1206*35238bceSAndroid Build Coastguard Worker {0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0}, {0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0},
1207*35238bceSAndroid Build Coastguard Worker {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}, {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1},
1208*35238bceSAndroid Build Coastguard Worker {0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0}, {0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0},
1209*35238bceSAndroid Build Coastguard Worker {0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0}, {0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0},
1210*35238bceSAndroid Build Coastguard Worker {0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1}, {0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1},
1211*35238bceSAndroid Build Coastguard Worker {0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0}, {0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0},
1212*35238bceSAndroid Build Coastguard Worker {0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0}, {0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0},
1213*35238bceSAndroid Build Coastguard Worker {0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0}, {0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1},
1214*35238bceSAndroid Build Coastguard Worker {0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1}, {0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0},
1215*35238bceSAndroid Build Coastguard Worker {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0},
1216*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0}, {0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0},
1217*35238bceSAndroid Build Coastguard Worker {0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1}, {0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1},
1218*35238bceSAndroid Build Coastguard Worker {0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0}, {0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0},
1219*35238bceSAndroid Build Coastguard Worker {0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1}, {0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1},
1220*35238bceSAndroid Build Coastguard Worker {0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1},
1221*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1}, {0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0},
1222*35238bceSAndroid Build Coastguard Worker {0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0}, {0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1}};
1223*35238bceSAndroid Build Coastguard Worker
1224*35238bceSAndroid Build Coastguard Worker static const uint8_t partitions3[64][16] = {
1225*35238bceSAndroid Build Coastguard Worker {0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 2, 1, 2, 2, 2, 2}, {0, 0, 0, 1, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1},
1226*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 0, 2, 0, 0, 1, 2, 2, 1, 1, 2, 2, 1, 1}, {0, 2, 2, 2, 0, 0, 2, 2, 0, 0, 1, 1, 0, 1, 1, 1},
1227*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2}, {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 2, 2},
1228*35238bceSAndroid Build Coastguard Worker {0, 0, 2, 2, 0, 0, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1}, {0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1},
1229*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2}, {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2},
1230*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2}, {0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2},
1231*35238bceSAndroid Build Coastguard Worker {0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2}, {0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2},
1232*35238bceSAndroid Build Coastguard Worker {0, 0, 1, 1, 0, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 2}, {0, 0, 1, 1, 2, 0, 0, 1, 2, 2, 0, 0, 2, 2, 2, 0},
1233*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 2, 1, 1, 2, 2}, {0, 1, 1, 1, 0, 0, 1, 1, 2, 0, 0, 1, 2, 2, 0, 0},
1234*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2}, {0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 1, 1, 1, 1},
1235*35238bceSAndroid Build Coastguard Worker {0, 1, 1, 1, 0, 1, 1, 1, 0, 2, 2, 2, 0, 2, 2, 2}, {0, 0, 0, 1, 0, 0, 0, 1, 2, 2, 2, 1, 2, 2, 2, 1},
1236*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 2, 2, 0, 1, 2, 2}, {0, 0, 0, 0, 1, 1, 0, 0, 2, 2, 1, 0, 2, 2, 1, 0},
1237*35238bceSAndroid Build Coastguard Worker {0, 1, 2, 2, 0, 1, 2, 2, 0, 0, 1, 1, 0, 0, 0, 0}, {0, 0, 1, 2, 0, 0, 1, 2, 1, 1, 2, 2, 2, 2, 2, 2},
1238*35238bceSAndroid Build Coastguard Worker {0, 1, 1, 0, 1, 2, 2, 1, 1, 2, 2, 1, 0, 1, 1, 0}, {0, 0, 0, 0, 0, 1, 1, 0, 1, 2, 2, 1, 1, 2, 2, 1},
1239*35238bceSAndroid Build Coastguard Worker {0, 0, 2, 2, 1, 1, 0, 2, 1, 1, 0, 2, 0, 0, 2, 2}, {0, 1, 1, 0, 0, 1, 1, 0, 2, 0, 0, 2, 2, 2, 2, 2},
1240*35238bceSAndroid Build Coastguard Worker {0, 0, 1, 1, 0, 1, 2, 2, 0, 1, 2, 2, 0, 0, 1, 1}, {0, 0, 0, 0, 2, 0, 0, 0, 2, 2, 1, 1, 2, 2, 2, 1},
1241*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 2, 1, 2, 2, 2}, {0, 2, 2, 2, 0, 0, 2, 2, 0, 0, 1, 2, 0, 0, 1, 1},
1242*35238bceSAndroid Build Coastguard Worker {0, 0, 1, 1, 0, 0, 1, 2, 0, 0, 2, 2, 0, 2, 2, 2}, {0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0},
1243*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0}, {0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0},
1244*35238bceSAndroid Build Coastguard Worker {0, 1, 2, 0, 2, 0, 1, 2, 1, 2, 0, 1, 0, 1, 2, 0}, {0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2, 0, 0, 1, 1},
1245*35238bceSAndroid Build Coastguard Worker {0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0, 1, 1}, {0, 1, 0, 1, 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2},
1246*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 1, 2, 1, 2, 1}, {0, 0, 2, 2, 1, 1, 2, 2, 0, 0, 2, 2, 1, 1, 2, 2},
1247*35238bceSAndroid Build Coastguard Worker {0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 1, 1}, {0, 2, 2, 0, 1, 2, 2, 1, 0, 2, 2, 0, 1, 2, 2, 1},
1248*35238bceSAndroid Build Coastguard Worker {0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 1}, {0, 0, 0, 0, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1},
1249*35238bceSAndroid Build Coastguard Worker {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 2, 2, 2}, {0, 2, 2, 2, 0, 1, 1, 1, 0, 2, 2, 2, 0, 1, 1, 1},
1250*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 2, 1, 1, 1, 2, 0, 0, 0, 2, 1, 1, 1, 2}, {0, 0, 0, 0, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2},
1251*35238bceSAndroid Build Coastguard Worker {0, 2, 2, 2, 0, 1, 1, 1, 0, 1, 1, 1, 0, 2, 2, 2}, {0, 0, 0, 2, 1, 1, 1, 2, 1, 1, 1, 2, 0, 0, 0, 2},
1252*35238bceSAndroid Build Coastguard Worker {0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 2, 2, 2}, {0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 2, 1, 1, 2},
1253*35238bceSAndroid Build Coastguard Worker {0, 1, 1, 0, 0, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2}, {0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 2},
1254*35238bceSAndroid Build Coastguard Worker {0, 0, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 0, 0, 2, 2}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2},
1255*35238bceSAndroid Build Coastguard Worker {0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1}, {0, 2, 2, 2, 1, 2, 2, 2, 0, 2, 2, 2, 1, 2, 2, 2},
1256*35238bceSAndroid Build Coastguard Worker {0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, {0, 1, 1, 1, 2, 0, 1, 1, 2, 2, 0, 1, 2, 2, 2, 0}};
1257*35238bceSAndroid Build Coastguard Worker
1258*35238bceSAndroid Build Coastguard Worker static const uint8_t anchorIndicesSecondSubset2[64] = {15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
1259*35238bceSAndroid Build Coastguard Worker 15, 2, 8, 2, 2, 8, 8, 15, 2, 8, 2, 2, 8, 8, 2, 2,
1260*35238bceSAndroid Build Coastguard Worker 15, 15, 6, 8, 2, 8, 15, 15, 2, 8, 2, 2, 2, 15, 15, 6,
1261*35238bceSAndroid Build Coastguard Worker 6, 2, 6, 8, 15, 15, 2, 2, 15, 15, 15, 15, 15, 2, 2, 15};
1262*35238bceSAndroid Build Coastguard Worker
1263*35238bceSAndroid Build Coastguard Worker static const uint8_t anchorIndicesSecondSubset3[64] = {
1264*35238bceSAndroid Build Coastguard Worker 3, 3, 15, 15, 8, 3, 15, 15, 8, 8, 6, 6, 6, 5, 3, 3, 3, 3, 8, 15, 3, 3, 6, 10, 5, 8, 8, 6, 8, 5, 15, 15,
1265*35238bceSAndroid Build Coastguard Worker 8, 15, 3, 5, 6, 10, 8, 15, 15, 3, 15, 5, 15, 15, 15, 15, 3, 15, 5, 5, 5, 8, 5, 10, 5, 10, 8, 13, 15, 12, 3, 3};
1266*35238bceSAndroid Build Coastguard Worker
1267*35238bceSAndroid Build Coastguard Worker static const uint8_t anchorIndicesThirdSubset[64] = {15, 8, 8, 3, 15, 15, 3, 8, 15, 15, 15, 15, 15, 15, 15, 8,
1268*35238bceSAndroid Build Coastguard Worker 15, 8, 15, 3, 15, 8, 15, 8, 3, 15, 6, 10, 15, 15, 10, 8,
1269*35238bceSAndroid Build Coastguard Worker 15, 3, 15, 10, 10, 8, 9, 10, 6, 15, 8, 15, 3, 6, 6, 8,
1270*35238bceSAndroid Build Coastguard Worker 15, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 15, 15, 8};
1271*35238bceSAndroid Build Coastguard Worker
1272*35238bceSAndroid Build Coastguard Worker static const uint16_t weights2[4] = {0, 21, 43, 64};
1273*35238bceSAndroid Build Coastguard Worker static const uint16_t weights3[8] = {0, 9, 18, 27, 37, 46, 55, 64};
1274*35238bceSAndroid Build Coastguard Worker static const uint16_t weights4[16] = {0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64};
1275*35238bceSAndroid Build Coastguard Worker
uint8ToFloat(uint8_t src)1276*35238bceSAndroid Build Coastguard Worker inline float uint8ToFloat(uint8_t src)
1277*35238bceSAndroid Build Coastguard Worker {
1278*35238bceSAndroid Build Coastguard Worker return ((float)src / 255.0f);
1279*35238bceSAndroid Build Coastguard Worker }
1280*35238bceSAndroid Build Coastguard Worker
int8ToFloat(int8_t src)1281*35238bceSAndroid Build Coastguard Worker inline float int8ToFloat(int8_t src)
1282*35238bceSAndroid Build Coastguard Worker {
1283*35238bceSAndroid Build Coastguard Worker return ((float)src / 128.0f);
1284*35238bceSAndroid Build Coastguard Worker }
1285*35238bceSAndroid Build Coastguard Worker
bgr16torgba32(uint16_t src)1286*35238bceSAndroid Build Coastguard Worker inline uint32_t bgr16torgba32(uint16_t src)
1287*35238bceSAndroid Build Coastguard Worker {
1288*35238bceSAndroid Build Coastguard Worker const uint32_t src32 = src;
1289*35238bceSAndroid Build Coastguard Worker const uint8_t b5 = (src32 & 0x1f);
1290*35238bceSAndroid Build Coastguard Worker const uint8_t g6 = (src32 >> 5) & 0x3f;
1291*35238bceSAndroid Build Coastguard Worker const uint8_t r5 = (src32 >> 11) & 0x1f;
1292*35238bceSAndroid Build Coastguard Worker const uint32_t a8 = 0xff;
1293*35238bceSAndroid Build Coastguard Worker const uint32_t b8 = extend5To8(b5);
1294*35238bceSAndroid Build Coastguard Worker const uint32_t g8 = extend6To8(g6);
1295*35238bceSAndroid Build Coastguard Worker const uint32_t r8 = extend5To8(r5);
1296*35238bceSAndroid Build Coastguard Worker
1297*35238bceSAndroid Build Coastguard Worker return (r8 | (g8 << 8) | (b8 << 16) | (a8 << 24));
1298*35238bceSAndroid Build Coastguard Worker }
1299*35238bceSAndroid Build Coastguard Worker
1300*35238bceSAndroid Build Coastguard Worker // Interpolates color = 1/3 * c0 + 2/3 * c1
interpolateColor(uint32_t c0,uint32_t c1)1301*35238bceSAndroid Build Coastguard Worker inline uint32_t interpolateColor(uint32_t c0, uint32_t c1)
1302*35238bceSAndroid Build Coastguard Worker {
1303*35238bceSAndroid Build Coastguard Worker const uint32_t r0 = c0 & 0xff;
1304*35238bceSAndroid Build Coastguard Worker const uint32_t g0 = (c0 >> 8) & 0xff;
1305*35238bceSAndroid Build Coastguard Worker const uint32_t b0 = (c0 >> 16) & 0xff;
1306*35238bceSAndroid Build Coastguard Worker const uint32_t a0 = (c0 >> 24) & 0xff;
1307*35238bceSAndroid Build Coastguard Worker
1308*35238bceSAndroid Build Coastguard Worker const uint32_t r1 = c1 & 0xff;
1309*35238bceSAndroid Build Coastguard Worker const uint32_t g1 = (c1 >> 8) & 0xff;
1310*35238bceSAndroid Build Coastguard Worker const uint32_t b1 = (c1 >> 16) & 0xff;
1311*35238bceSAndroid Build Coastguard Worker const uint32_t a1 = (c1 >> 24) & 0xff;
1312*35238bceSAndroid Build Coastguard Worker
1313*35238bceSAndroid Build Coastguard Worker const uint32_t r = (r0 + (r1 << 1)) / 3;
1314*35238bceSAndroid Build Coastguard Worker const uint32_t g = (g0 + (g1 << 1)) / 3;
1315*35238bceSAndroid Build Coastguard Worker const uint32_t b = (b0 + (b1 << 1)) / 3;
1316*35238bceSAndroid Build Coastguard Worker const uint32_t a = (a0 + (a1 << 1)) / 3;
1317*35238bceSAndroid Build Coastguard Worker
1318*35238bceSAndroid Build Coastguard Worker return (r | (g << 8) | (b << 16) | (a << 24));
1319*35238bceSAndroid Build Coastguard Worker }
1320*35238bceSAndroid Build Coastguard Worker
1321*35238bceSAndroid Build Coastguard Worker // Average of two colors
averageColor(uint32_t c0,uint32_t c1)1322*35238bceSAndroid Build Coastguard Worker inline uint32_t averageColor(uint32_t c0, uint32_t c1)
1323*35238bceSAndroid Build Coastguard Worker {
1324*35238bceSAndroid Build Coastguard Worker const uint32_t r0 = c0 & 0xff;
1325*35238bceSAndroid Build Coastguard Worker const uint32_t g0 = (c0 >> 8) & 0xff;
1326*35238bceSAndroid Build Coastguard Worker const uint32_t b0 = (c0 >> 16) & 0xff;
1327*35238bceSAndroid Build Coastguard Worker const uint32_t a0 = (c0 >> 24) & 0xff;
1328*35238bceSAndroid Build Coastguard Worker
1329*35238bceSAndroid Build Coastguard Worker const uint32_t r1 = c1 & 0xff;
1330*35238bceSAndroid Build Coastguard Worker const uint32_t g1 = (c1 >> 8) & 0xff;
1331*35238bceSAndroid Build Coastguard Worker const uint32_t b1 = (c1 >> 16) & 0xff;
1332*35238bceSAndroid Build Coastguard Worker const uint32_t a1 = (c1 >> 24) & 0xff;
1333*35238bceSAndroid Build Coastguard Worker
1334*35238bceSAndroid Build Coastguard Worker const uint32_t r = (r0 + r1) >> 1;
1335*35238bceSAndroid Build Coastguard Worker const uint32_t g = (g0 + g1) >> 1;
1336*35238bceSAndroid Build Coastguard Worker const uint32_t b = (b0 + b1) >> 1;
1337*35238bceSAndroid Build Coastguard Worker const uint32_t a = (a0 + a1) >> 1;
1338*35238bceSAndroid Build Coastguard Worker
1339*35238bceSAndroid Build Coastguard Worker return (r | (g << 8) | (b << 16) | (a << 24));
1340*35238bceSAndroid Build Coastguard Worker }
1341*35238bceSAndroid Build Coastguard Worker
extractModeBc6(uint8_t src)1342*35238bceSAndroid Build Coastguard Worker inline int8_t extractModeBc6(uint8_t src)
1343*35238bceSAndroid Build Coastguard Worker {
1344*35238bceSAndroid Build Coastguard Worker // Catch illegal modes
1345*35238bceSAndroid Build Coastguard Worker switch (src & 0x1f)
1346*35238bceSAndroid Build Coastguard Worker {
1347*35238bceSAndroid Build Coastguard Worker case 0x13:
1348*35238bceSAndroid Build Coastguard Worker case 0x17:
1349*35238bceSAndroid Build Coastguard Worker case 0x1b:
1350*35238bceSAndroid Build Coastguard Worker case 0x1f:
1351*35238bceSAndroid Build Coastguard Worker return -1;
1352*35238bceSAndroid Build Coastguard Worker }
1353*35238bceSAndroid Build Coastguard Worker
1354*35238bceSAndroid Build Coastguard Worker switch (src & 0x3)
1355*35238bceSAndroid Build Coastguard Worker {
1356*35238bceSAndroid Build Coastguard Worker case 0:
1357*35238bceSAndroid Build Coastguard Worker return 0;
1358*35238bceSAndroid Build Coastguard Worker case 1:
1359*35238bceSAndroid Build Coastguard Worker return 1;
1360*35238bceSAndroid Build Coastguard Worker case 2:
1361*35238bceSAndroid Build Coastguard Worker return (int8_t)(2 + ((src >> 2) & 0x7));
1362*35238bceSAndroid Build Coastguard Worker case 3:
1363*35238bceSAndroid Build Coastguard Worker return (int8_t)(10 + ((src >> 2) & 0x7));
1364*35238bceSAndroid Build Coastguard Worker }
1365*35238bceSAndroid Build Coastguard Worker
1366*35238bceSAndroid Build Coastguard Worker return -1;
1367*35238bceSAndroid Build Coastguard Worker }
1368*35238bceSAndroid Build Coastguard Worker
extractModeBc7(uint8_t src)1369*35238bceSAndroid Build Coastguard Worker inline int8_t extractModeBc7(uint8_t src)
1370*35238bceSAndroid Build Coastguard Worker {
1371*35238bceSAndroid Build Coastguard Worker for (int8_t i = 0; i < 8; i++)
1372*35238bceSAndroid Build Coastguard Worker if (src & (1 << i))
1373*35238bceSAndroid Build Coastguard Worker return i;
1374*35238bceSAndroid Build Coastguard Worker
1375*35238bceSAndroid Build Coastguard Worker return -1;
1376*35238bceSAndroid Build Coastguard Worker }
1377*35238bceSAndroid Build Coastguard Worker
get64BitBlockLE(const uint8_t * src,int blockNdx)1378*35238bceSAndroid Build Coastguard Worker inline uint64_t get64BitBlockLE(const uint8_t *src, int blockNdx)
1379*35238bceSAndroid Build Coastguard Worker {
1380*35238bceSAndroid Build Coastguard Worker // Same as get64BitBlock, but little-endian.
1381*35238bceSAndroid Build Coastguard Worker uint64_t block = 0;
1382*35238bceSAndroid Build Coastguard Worker
1383*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < 8; i++)
1384*35238bceSAndroid Build Coastguard Worker block |= (uint64_t)(src[blockNdx * 8 + i]) << (8ull * i);
1385*35238bceSAndroid Build Coastguard Worker
1386*35238bceSAndroid Build Coastguard Worker return block;
1387*35238bceSAndroid Build Coastguard Worker }
1388*35238bceSAndroid Build Coastguard Worker
getBits128(uint64_t low,uint64_t high,uint32_t first,uint32_t last)1389*35238bceSAndroid Build Coastguard Worker inline uint32_t getBits128(uint64_t low, uint64_t high, uint32_t first, uint32_t last)
1390*35238bceSAndroid Build Coastguard Worker {
1391*35238bceSAndroid Build Coastguard Worker const uint64_t d[2] = {low, high};
1392*35238bceSAndroid Build Coastguard Worker const bool reverse = first > last;
1393*35238bceSAndroid Build Coastguard Worker uint32_t ret = 0;
1394*35238bceSAndroid Build Coastguard Worker
1395*35238bceSAndroid Build Coastguard Worker if (reverse)
1396*35238bceSAndroid Build Coastguard Worker {
1397*35238bceSAndroid Build Coastguard Worker const uint32_t tmp = first;
1398*35238bceSAndroid Build Coastguard Worker first = last;
1399*35238bceSAndroid Build Coastguard Worker last = tmp;
1400*35238bceSAndroid Build Coastguard Worker }
1401*35238bceSAndroid Build Coastguard Worker
1402*35238bceSAndroid Build Coastguard Worker const int elementFirst = first / 64;
1403*35238bceSAndroid Build Coastguard Worker const int elementLast = last / 64;
1404*35238bceSAndroid Build Coastguard Worker
1405*35238bceSAndroid Build Coastguard Worker if (elementFirst == elementLast)
1406*35238bceSAndroid Build Coastguard Worker {
1407*35238bceSAndroid Build Coastguard Worker // Bits contained in one of the 64bit elements
1408*35238bceSAndroid Build Coastguard Worker const uint32_t shift = first % 64;
1409*35238bceSAndroid Build Coastguard Worker const uint32_t len = last - first + 1;
1410*35238bceSAndroid Build Coastguard Worker const uint32_t mask = (1 << len) - 1;
1411*35238bceSAndroid Build Coastguard Worker ret = (uint32_t)((d[elementFirst] >> shift) & mask);
1412*35238bceSAndroid Build Coastguard Worker }
1413*35238bceSAndroid Build Coastguard Worker else
1414*35238bceSAndroid Build Coastguard Worker {
1415*35238bceSAndroid Build Coastguard Worker // Bits contained in both of the 64bit elements
1416*35238bceSAndroid Build Coastguard Worker DE_ASSERT(last > 63);
1417*35238bceSAndroid Build Coastguard Worker DE_ASSERT(first < 64);
1418*35238bceSAndroid Build Coastguard Worker const uint32_t len0 = 64 - first;
1419*35238bceSAndroid Build Coastguard Worker const uint32_t mask0 = (1 << len0) - 1;
1420*35238bceSAndroid Build Coastguard Worker const uint32_t data0 = (uint32_t)(low >> first) & mask0;
1421*35238bceSAndroid Build Coastguard Worker const uint32_t len1 = last - 63;
1422*35238bceSAndroid Build Coastguard Worker const uint32_t mask1 = (1 << len1) - 1;
1423*35238bceSAndroid Build Coastguard Worker const uint32_t data1 = (uint32_t)(high & mask1);
1424*35238bceSAndroid Build Coastguard Worker ret = (uint32_t)((data1 << len0) | data0);
1425*35238bceSAndroid Build Coastguard Worker }
1426*35238bceSAndroid Build Coastguard Worker
1427*35238bceSAndroid Build Coastguard Worker if (reverse)
1428*35238bceSAndroid Build Coastguard Worker {
1429*35238bceSAndroid Build Coastguard Worker const uint32_t len = last - first + 1;
1430*35238bceSAndroid Build Coastguard Worker const uint32_t orig = ret;
1431*35238bceSAndroid Build Coastguard Worker ret = 0;
1432*35238bceSAndroid Build Coastguard Worker
1433*35238bceSAndroid Build Coastguard Worker for (uint32_t i = 0; i < len; i++)
1434*35238bceSAndroid Build Coastguard Worker {
1435*35238bceSAndroid Build Coastguard Worker ret |= ((orig >> (len - 1 - i)) & 1) << i;
1436*35238bceSAndroid Build Coastguard Worker }
1437*35238bceSAndroid Build Coastguard Worker }
1438*35238bceSAndroid Build Coastguard Worker
1439*35238bceSAndroid Build Coastguard Worker return ret;
1440*35238bceSAndroid Build Coastguard Worker }
1441*35238bceSAndroid Build Coastguard Worker
signExtend(int32_t value,int32_t srcBits,int32_t dstBits)1442*35238bceSAndroid Build Coastguard Worker inline int32_t signExtend(int32_t value, int32_t srcBits, int32_t dstBits)
1443*35238bceSAndroid Build Coastguard Worker {
1444*35238bceSAndroid Build Coastguard Worker uint32_t sign = value & (1 << (srcBits - 1));
1445*35238bceSAndroid Build Coastguard Worker
1446*35238bceSAndroid Build Coastguard Worker if (!sign)
1447*35238bceSAndroid Build Coastguard Worker return value;
1448*35238bceSAndroid Build Coastguard Worker
1449*35238bceSAndroid Build Coastguard Worker int32_t dstMask = (int32_t)(((uint64_t)1 << dstBits) - 1);
1450*35238bceSAndroid Build Coastguard Worker int32_t extendedBits = 0xffffffff << srcBits;
1451*35238bceSAndroid Build Coastguard Worker return (value | extendedBits) & dstMask;
1452*35238bceSAndroid Build Coastguard Worker }
1453*35238bceSAndroid Build Coastguard Worker
unquantize(int32_t x,int mode,bool hasSign)1454*35238bceSAndroid Build Coastguard Worker inline int32_t unquantize(int32_t x, int mode, bool hasSign)
1455*35238bceSAndroid Build Coastguard Worker {
1456*35238bceSAndroid Build Coastguard Worker if (hasSign)
1457*35238bceSAndroid Build Coastguard Worker {
1458*35238bceSAndroid Build Coastguard Worker bool s = false;
1459*35238bceSAndroid Build Coastguard Worker
1460*35238bceSAndroid Build Coastguard Worker if (epBits[mode] >= 16)
1461*35238bceSAndroid Build Coastguard Worker return x;
1462*35238bceSAndroid Build Coastguard Worker
1463*35238bceSAndroid Build Coastguard Worker if (x < 0)
1464*35238bceSAndroid Build Coastguard Worker {
1465*35238bceSAndroid Build Coastguard Worker s = true;
1466*35238bceSAndroid Build Coastguard Worker x = -x;
1467*35238bceSAndroid Build Coastguard Worker }
1468*35238bceSAndroid Build Coastguard Worker
1469*35238bceSAndroid Build Coastguard Worker if (x == 0)
1470*35238bceSAndroid Build Coastguard Worker x = 0;
1471*35238bceSAndroid Build Coastguard Worker else if (x >= (((int32_t)1 << (epBits[mode] - 1)) - 1))
1472*35238bceSAndroid Build Coastguard Worker x = 0x7fff;
1473*35238bceSAndroid Build Coastguard Worker else
1474*35238bceSAndroid Build Coastguard Worker x = (((int32_t)x << 15) + 0x4000) >> (epBits[mode] - 1);
1475*35238bceSAndroid Build Coastguard Worker
1476*35238bceSAndroid Build Coastguard Worker if (s)
1477*35238bceSAndroid Build Coastguard Worker x = -x;
1478*35238bceSAndroid Build Coastguard Worker
1479*35238bceSAndroid Build Coastguard Worker return x;
1480*35238bceSAndroid Build Coastguard Worker }
1481*35238bceSAndroid Build Coastguard Worker else
1482*35238bceSAndroid Build Coastguard Worker {
1483*35238bceSAndroid Build Coastguard Worker if (epBits[mode] >= 15)
1484*35238bceSAndroid Build Coastguard Worker return x;
1485*35238bceSAndroid Build Coastguard Worker else if (x == 0)
1486*35238bceSAndroid Build Coastguard Worker return 0;
1487*35238bceSAndroid Build Coastguard Worker else if (x == (((int32_t)1 << epBits[mode]) - 1))
1488*35238bceSAndroid Build Coastguard Worker return 0xffff;
1489*35238bceSAndroid Build Coastguard Worker else
1490*35238bceSAndroid Build Coastguard Worker return ((((int32_t)x << 15) + 0x4000) >> (epBits[mode] - 1));
1491*35238bceSAndroid Build Coastguard Worker }
1492*35238bceSAndroid Build Coastguard Worker }
1493*35238bceSAndroid Build Coastguard Worker
interpolate(int32_t a,int32_t b,uint32_t index,uint32_t indexPrecision)1494*35238bceSAndroid Build Coastguard Worker inline int32_t interpolate(int32_t a, int32_t b, uint32_t index, uint32_t indexPrecision)
1495*35238bceSAndroid Build Coastguard Worker {
1496*35238bceSAndroid Build Coastguard Worker const uint16_t *weights[] = {weights2, weights3, weights4};
1497*35238bceSAndroid Build Coastguard Worker const uint16_t *weight = weights[indexPrecision - 2];
1498*35238bceSAndroid Build Coastguard Worker DE_ASSERT(indexPrecision >= 2 && indexPrecision <= 4);
1499*35238bceSAndroid Build Coastguard Worker
1500*35238bceSAndroid Build Coastguard Worker return (((64 - weight[index]) * a + weight[index] * b + 32) >> 6);
1501*35238bceSAndroid Build Coastguard Worker }
1502*35238bceSAndroid Build Coastguard Worker
finishUnquantize(int32_t x,bool hasSign)1503*35238bceSAndroid Build Coastguard Worker inline int16_t finishUnquantize(int32_t x, bool hasSign)
1504*35238bceSAndroid Build Coastguard Worker {
1505*35238bceSAndroid Build Coastguard Worker if (hasSign)
1506*35238bceSAndroid Build Coastguard Worker {
1507*35238bceSAndroid Build Coastguard Worker if (x < 0)
1508*35238bceSAndroid Build Coastguard Worker x = -(((-x) * 31) >> 5);
1509*35238bceSAndroid Build Coastguard Worker else
1510*35238bceSAndroid Build Coastguard Worker x = (x * 31) >> 5;
1511*35238bceSAndroid Build Coastguard Worker
1512*35238bceSAndroid Build Coastguard Worker if (x < 0)
1513*35238bceSAndroid Build Coastguard Worker x = (-x) | 0x8000;
1514*35238bceSAndroid Build Coastguard Worker }
1515*35238bceSAndroid Build Coastguard Worker else
1516*35238bceSAndroid Build Coastguard Worker {
1517*35238bceSAndroid Build Coastguard Worker x = (x * 31) / 64;
1518*35238bceSAndroid Build Coastguard Worker }
1519*35238bceSAndroid Build Coastguard Worker
1520*35238bceSAndroid Build Coastguard Worker return (int16_t)x;
1521*35238bceSAndroid Build Coastguard Worker }
1522*35238bceSAndroid Build Coastguard Worker
1523*35238bceSAndroid Build Coastguard Worker } // namespace BcDecompressInternal
1524*35238bceSAndroid Build Coastguard Worker
decompressBc1(const PixelBufferAccess & dst,const uint8_t * src,bool hasAlpha)1525*35238bceSAndroid Build Coastguard Worker void decompressBc1(const PixelBufferAccess &dst, const uint8_t *src, bool hasAlpha)
1526*35238bceSAndroid Build Coastguard Worker {
1527*35238bceSAndroid Build Coastguard Worker using namespace BcDecompressInternal;
1528*35238bceSAndroid Build Coastguard Worker
1529*35238bceSAndroid Build Coastguard Worker uint8_t *const dstPtr = (uint8_t *)dst.getDataPtr();
1530*35238bceSAndroid Build Coastguard Worker const uint32_t dstRowPitch = dst.getRowPitch();
1531*35238bceSAndroid Build Coastguard Worker const uint32_t dstPixelSize = 4;
1532*35238bceSAndroid Build Coastguard Worker const uint16_t color0_16 = ((uint16_t *)src)[0];
1533*35238bceSAndroid Build Coastguard Worker const uint16_t color1_16 = ((uint16_t *)src)[1];
1534*35238bceSAndroid Build Coastguard Worker const uint32_t color0 = bgr16torgba32(color0_16);
1535*35238bceSAndroid Build Coastguard Worker const uint32_t color1 = bgr16torgba32(color1_16);
1536*35238bceSAndroid Build Coastguard Worker const uint8_t *const indices8 = &src[4];
1537*35238bceSAndroid Build Coastguard Worker
1538*35238bceSAndroid Build Coastguard Worker const bool alphaMode = color1_16 > color0_16;
1539*35238bceSAndroid Build Coastguard Worker
1540*35238bceSAndroid Build Coastguard Worker const int32_t indices[16] = {
1541*35238bceSAndroid Build Coastguard Worker (indices8[0] >> 0) & 0x3, (indices8[0] >> 2) & 0x3, (indices8[0] >> 4) & 0x3, (indices8[0] >> 6) & 0x3,
1542*35238bceSAndroid Build Coastguard Worker (indices8[1] >> 0) & 0x3, (indices8[1] >> 2) & 0x3, (indices8[1] >> 4) & 0x3, (indices8[1] >> 6) & 0x3,
1543*35238bceSAndroid Build Coastguard Worker (indices8[2] >> 0) & 0x3, (indices8[2] >> 2) & 0x3, (indices8[2] >> 4) & 0x3, (indices8[2] >> 6) & 0x3,
1544*35238bceSAndroid Build Coastguard Worker (indices8[3] >> 0) & 0x3, (indices8[3] >> 2) & 0x3, (indices8[3] >> 4) & 0x3, (indices8[3] >> 6) & 0x3};
1545*35238bceSAndroid Build Coastguard Worker
1546*35238bceSAndroid Build Coastguard Worker const uint32_t colors[4] = {color0, color1,
1547*35238bceSAndroid Build Coastguard Worker alphaMode ? averageColor(color0, color1) : interpolateColor(color1, color0),
1548*35238bceSAndroid Build Coastguard Worker alphaMode ? (hasAlpha ? 0 : 0xff000000) : interpolateColor(color0, color1)};
1549*35238bceSAndroid Build Coastguard Worker
1550*35238bceSAndroid Build Coastguard Worker for (uint32_t y = 0; y < (uint32_t)BC_BLOCK_HEIGHT; y++)
1551*35238bceSAndroid Build Coastguard Worker {
1552*35238bceSAndroid Build Coastguard Worker for (uint32_t x = 0; x < (uint32_t)BC_BLOCK_WIDTH; x++)
1553*35238bceSAndroid Build Coastguard Worker {
1554*35238bceSAndroid Build Coastguard Worker uint32_t *const dstPixel = (uint32_t *)(dstPtr + y * dstRowPitch + x * dstPixelSize);
1555*35238bceSAndroid Build Coastguard Worker *dstPixel = colors[indices[y * BC_BLOCK_WIDTH + x]];
1556*35238bceSAndroid Build Coastguard Worker }
1557*35238bceSAndroid Build Coastguard Worker }
1558*35238bceSAndroid Build Coastguard Worker }
1559*35238bceSAndroid Build Coastguard Worker
decompressBc2(const PixelBufferAccess & dst,const uint8_t * src)1560*35238bceSAndroid Build Coastguard Worker void decompressBc2(const PixelBufferAccess &dst, const uint8_t *src)
1561*35238bceSAndroid Build Coastguard Worker {
1562*35238bceSAndroid Build Coastguard Worker using namespace BcDecompressInternal;
1563*35238bceSAndroid Build Coastguard Worker
1564*35238bceSAndroid Build Coastguard Worker uint8_t *const dstPtr = (uint8_t *)dst.getDataPtr();
1565*35238bceSAndroid Build Coastguard Worker const uint32_t dstRowPitch = dst.getRowPitch();
1566*35238bceSAndroid Build Coastguard Worker const uint32_t dstPixelSize = 4;
1567*35238bceSAndroid Build Coastguard Worker const uint16_t color0_16 = ((uint16_t *)src)[4];
1568*35238bceSAndroid Build Coastguard Worker const uint16_t color1_16 = ((uint16_t *)src)[5];
1569*35238bceSAndroid Build Coastguard Worker const uint32_t color0 = bgr16torgba32(color0_16);
1570*35238bceSAndroid Build Coastguard Worker const uint32_t color1 = bgr16torgba32(color1_16);
1571*35238bceSAndroid Build Coastguard Worker const uint8_t *const indices8 = &src[12];
1572*35238bceSAndroid Build Coastguard Worker const uint8_t *const alphas8 = src;
1573*35238bceSAndroid Build Coastguard Worker
1574*35238bceSAndroid Build Coastguard Worker const int32_t indices[16] = {
1575*35238bceSAndroid Build Coastguard Worker (indices8[0] >> 0) & 0x3, (indices8[0] >> 2) & 0x3, (indices8[0] >> 4) & 0x3, (indices8[0] >> 6) & 0x3,
1576*35238bceSAndroid Build Coastguard Worker (indices8[1] >> 0) & 0x3, (indices8[1] >> 2) & 0x3, (indices8[1] >> 4) & 0x3, (indices8[1] >> 6) & 0x3,
1577*35238bceSAndroid Build Coastguard Worker (indices8[2] >> 0) & 0x3, (indices8[2] >> 2) & 0x3, (indices8[2] >> 4) & 0x3, (indices8[2] >> 6) & 0x3,
1578*35238bceSAndroid Build Coastguard Worker (indices8[3] >> 0) & 0x3, (indices8[3] >> 2) & 0x3, (indices8[3] >> 4) & 0x3, (indices8[3] >> 6) & 0x3};
1579*35238bceSAndroid Build Coastguard Worker
1580*35238bceSAndroid Build Coastguard Worker const int32_t alphas[16] = {
1581*35238bceSAndroid Build Coastguard Worker extend4To8(((alphas8[0] >> 0) & 0xf)) << 24, extend4To8(((alphas8[0] >> 4) & 0xf)) << 24,
1582*35238bceSAndroid Build Coastguard Worker extend4To8(((alphas8[1] >> 0) & 0xf)) << 24, extend4To8(((alphas8[1] >> 4) & 0xf)) << 24,
1583*35238bceSAndroid Build Coastguard Worker extend4To8(((alphas8[2] >> 0) & 0xf)) << 24, extend4To8(((alphas8[2] >> 4) & 0xf)) << 24,
1584*35238bceSAndroid Build Coastguard Worker extend4To8(((alphas8[3] >> 0) & 0xf)) << 24, extend4To8(((alphas8[3] >> 4) & 0xf)) << 24,
1585*35238bceSAndroid Build Coastguard Worker extend4To8(((alphas8[4] >> 0) & 0xf)) << 24, extend4To8(((alphas8[4] >> 4) & 0xf)) << 24,
1586*35238bceSAndroid Build Coastguard Worker extend4To8(((alphas8[5] >> 0) & 0xf)) << 24, extend4To8(((alphas8[5] >> 4) & 0xf)) << 24,
1587*35238bceSAndroid Build Coastguard Worker extend4To8(((alphas8[6] >> 0) & 0xf)) << 24, extend4To8(((alphas8[6] >> 4) & 0xf)) << 24,
1588*35238bceSAndroid Build Coastguard Worker extend4To8(((alphas8[7] >> 0) & 0xf)) << 24, extend4To8(((alphas8[7] >> 4) & 0xf)) << 24};
1589*35238bceSAndroid Build Coastguard Worker
1590*35238bceSAndroid Build Coastguard Worker const uint32_t colors[4] = {color0, color1, interpolateColor(color1, color0), interpolateColor(color0, color1)};
1591*35238bceSAndroid Build Coastguard Worker
1592*35238bceSAndroid Build Coastguard Worker for (uint32_t y = 0; y < (uint32_t)BC_BLOCK_HEIGHT; y++)
1593*35238bceSAndroid Build Coastguard Worker {
1594*35238bceSAndroid Build Coastguard Worker for (uint32_t x = 0; x < (uint32_t)BC_BLOCK_WIDTH; x++)
1595*35238bceSAndroid Build Coastguard Worker {
1596*35238bceSAndroid Build Coastguard Worker uint32_t *const dstPixel = (uint32_t *)(dstPtr + y * dstRowPitch + x * dstPixelSize);
1597*35238bceSAndroid Build Coastguard Worker *dstPixel = (colors[indices[y * BC_BLOCK_WIDTH + x]] & 0x00ffffff) | alphas[y * BC_BLOCK_WIDTH + x];
1598*35238bceSAndroid Build Coastguard Worker }
1599*35238bceSAndroid Build Coastguard Worker }
1600*35238bceSAndroid Build Coastguard Worker }
1601*35238bceSAndroid Build Coastguard Worker
decompressBc3(const PixelBufferAccess & dst,const uint8_t * src)1602*35238bceSAndroid Build Coastguard Worker void decompressBc3(const PixelBufferAccess &dst, const uint8_t *src)
1603*35238bceSAndroid Build Coastguard Worker {
1604*35238bceSAndroid Build Coastguard Worker using namespace BcDecompressInternal;
1605*35238bceSAndroid Build Coastguard Worker
1606*35238bceSAndroid Build Coastguard Worker uint8_t *const dstPtr = (uint8_t *)dst.getDataPtr();
1607*35238bceSAndroid Build Coastguard Worker const uint32_t dstRowPitch = dst.getRowPitch();
1608*35238bceSAndroid Build Coastguard Worker const uint32_t dstPixelSize = 4;
1609*35238bceSAndroid Build Coastguard Worker const uint8_t alpha0 = src[0];
1610*35238bceSAndroid Build Coastguard Worker const uint8_t alpha1 = src[1];
1611*35238bceSAndroid Build Coastguard Worker const uint16_t color0_16 = ((uint16_t *)src)[4];
1612*35238bceSAndroid Build Coastguard Worker const uint16_t color1_16 = ((uint16_t *)src)[5];
1613*35238bceSAndroid Build Coastguard Worker const uint32_t color0 = bgr16torgba32(color0_16);
1614*35238bceSAndroid Build Coastguard Worker const uint32_t color1 = bgr16torgba32(color1_16);
1615*35238bceSAndroid Build Coastguard Worker const uint8_t *const indices8 = &src[12];
1616*35238bceSAndroid Build Coastguard Worker const uint64_t alphaBits = get64BitBlockLE(src, 0) >> 16;
1617*35238bceSAndroid Build Coastguard Worker uint32_t alphas[8];
1618*35238bceSAndroid Build Coastguard Worker
1619*35238bceSAndroid Build Coastguard Worker const int32_t indices[16] = {
1620*35238bceSAndroid Build Coastguard Worker (indices8[0] >> 0) & 0x3, (indices8[0] >> 2) & 0x3, (indices8[0] >> 4) & 0x3, (indices8[0] >> 6) & 0x3,
1621*35238bceSAndroid Build Coastguard Worker (indices8[1] >> 0) & 0x3, (indices8[1] >> 2) & 0x3, (indices8[1] >> 4) & 0x3, (indices8[1] >> 6) & 0x3,
1622*35238bceSAndroid Build Coastguard Worker (indices8[2] >> 0) & 0x3, (indices8[2] >> 2) & 0x3, (indices8[2] >> 4) & 0x3, (indices8[2] >> 6) & 0x3,
1623*35238bceSAndroid Build Coastguard Worker (indices8[3] >> 0) & 0x3, (indices8[3] >> 2) & 0x3, (indices8[3] >> 4) & 0x3, (indices8[3] >> 6) & 0x3};
1624*35238bceSAndroid Build Coastguard Worker
1625*35238bceSAndroid Build Coastguard Worker const int32_t alphaIndices[16] = {
1626*35238bceSAndroid Build Coastguard Worker (int32_t)((alphaBits >> 0) & 0x7), (int32_t)((alphaBits >> 3) & 0x7), (int32_t)((alphaBits >> 6) & 0x7),
1627*35238bceSAndroid Build Coastguard Worker (int32_t)((alphaBits >> 9) & 0x7), (int32_t)((alphaBits >> 12) & 0x7), (int32_t)((alphaBits >> 15) & 0x7),
1628*35238bceSAndroid Build Coastguard Worker (int32_t)((alphaBits >> 18) & 0x7), (int32_t)((alphaBits >> 21) & 0x7), (int32_t)((alphaBits >> 24) & 0x7),
1629*35238bceSAndroid Build Coastguard Worker (int32_t)((alphaBits >> 27) & 0x7), (int32_t)((alphaBits >> 30) & 0x7), (int32_t)((alphaBits >> 33) & 0x7),
1630*35238bceSAndroid Build Coastguard Worker (int32_t)((alphaBits >> 36) & 0x7), (int32_t)((alphaBits >> 39) & 0x7), (int32_t)((alphaBits >> 42) & 0x7),
1631*35238bceSAndroid Build Coastguard Worker (int32_t)((alphaBits >> 45) & 0x7)};
1632*35238bceSAndroid Build Coastguard Worker
1633*35238bceSAndroid Build Coastguard Worker const uint32_t colors[4] = {color0, color1, interpolateColor(color1, color0), interpolateColor(color0, color1)};
1634*35238bceSAndroid Build Coastguard Worker
1635*35238bceSAndroid Build Coastguard Worker alphas[0] = alpha0 << 24;
1636*35238bceSAndroid Build Coastguard Worker alphas[1] = alpha1 << 24;
1637*35238bceSAndroid Build Coastguard Worker
1638*35238bceSAndroid Build Coastguard Worker if (alpha0 > alpha1)
1639*35238bceSAndroid Build Coastguard Worker {
1640*35238bceSAndroid Build Coastguard Worker for (uint32_t i = 0; i < 6; i++)
1641*35238bceSAndroid Build Coastguard Worker alphas[i + 2] = (((uint32_t)alpha0 * (6 - i) + (uint32_t)alpha1 * (1 + i)) / 7) << 24;
1642*35238bceSAndroid Build Coastguard Worker }
1643*35238bceSAndroid Build Coastguard Worker else
1644*35238bceSAndroid Build Coastguard Worker {
1645*35238bceSAndroid Build Coastguard Worker for (uint32_t i = 0; i < 4; i++)
1646*35238bceSAndroid Build Coastguard Worker alphas[i + 2] = (((uint32_t)alpha0 * (4 - i) + (uint32_t)alpha1 * (1 + i)) / 5) << 24;
1647*35238bceSAndroid Build Coastguard Worker alphas[6] = 0;
1648*35238bceSAndroid Build Coastguard Worker alphas[7] = 0xff000000;
1649*35238bceSAndroid Build Coastguard Worker }
1650*35238bceSAndroid Build Coastguard Worker
1651*35238bceSAndroid Build Coastguard Worker for (uint32_t y = 0; y < (uint32_t)BC_BLOCK_HEIGHT; y++)
1652*35238bceSAndroid Build Coastguard Worker {
1653*35238bceSAndroid Build Coastguard Worker for (uint32_t x = 0; x < (uint32_t)BC_BLOCK_WIDTH; x++)
1654*35238bceSAndroid Build Coastguard Worker {
1655*35238bceSAndroid Build Coastguard Worker uint32_t *const dstPixel = (uint32_t *)(dstPtr + y * dstRowPitch + x * dstPixelSize);
1656*35238bceSAndroid Build Coastguard Worker *dstPixel =
1657*35238bceSAndroid Build Coastguard Worker (colors[indices[y * BC_BLOCK_WIDTH + x]] & 0x00ffffff) | alphas[alphaIndices[y * BC_BLOCK_WIDTH + x]];
1658*35238bceSAndroid Build Coastguard Worker }
1659*35238bceSAndroid Build Coastguard Worker }
1660*35238bceSAndroid Build Coastguard Worker }
1661*35238bceSAndroid Build Coastguard Worker
decompressBc4(const PixelBufferAccess & dst,const uint8_t * src,bool hasSign)1662*35238bceSAndroid Build Coastguard Worker void decompressBc4(const PixelBufferAccess &dst, const uint8_t *src, bool hasSign)
1663*35238bceSAndroid Build Coastguard Worker {
1664*35238bceSAndroid Build Coastguard Worker using namespace BcDecompressInternal;
1665*35238bceSAndroid Build Coastguard Worker
1666*35238bceSAndroid Build Coastguard Worker uint8_t *const dstPtr = (uint8_t *)dst.getDataPtr();
1667*35238bceSAndroid Build Coastguard Worker const uint32_t dstRowPitch = dst.getRowPitch();
1668*35238bceSAndroid Build Coastguard Worker const uint32_t dstPixelSize = 4;
1669*35238bceSAndroid Build Coastguard Worker const uint8_t red0 = src[0];
1670*35238bceSAndroid Build Coastguard Worker const uint8_t red1 = src[1];
1671*35238bceSAndroid Build Coastguard Worker const int8_t red0s = ((int8_t *)src)[0];
1672*35238bceSAndroid Build Coastguard Worker const int8_t red1s = ((int8_t *)src)[1];
1673*35238bceSAndroid Build Coastguard Worker const uint64_t indexBits = get64BitBlockLE(src, 0) >> 16;
1674*35238bceSAndroid Build Coastguard Worker float reds[8];
1675*35238bceSAndroid Build Coastguard Worker
1676*35238bceSAndroid Build Coastguard Worker const int32_t indices[16] = {
1677*35238bceSAndroid Build Coastguard Worker (int32_t)((indexBits >> 0) & 0x7), (int32_t)((indexBits >> 3) & 0x7), (int32_t)((indexBits >> 6) & 0x7),
1678*35238bceSAndroid Build Coastguard Worker (int32_t)((indexBits >> 9) & 0x7), (int32_t)((indexBits >> 12) & 0x7), (int32_t)((indexBits >> 15) & 0x7),
1679*35238bceSAndroid Build Coastguard Worker (int32_t)((indexBits >> 18) & 0x7), (int32_t)((indexBits >> 21) & 0x7), (int32_t)((indexBits >> 24) & 0x7),
1680*35238bceSAndroid Build Coastguard Worker (int32_t)((indexBits >> 27) & 0x7), (int32_t)((indexBits >> 30) & 0x7), (int32_t)((indexBits >> 33) & 0x7),
1681*35238bceSAndroid Build Coastguard Worker (int32_t)((indexBits >> 36) & 0x7), (int32_t)((indexBits >> 39) & 0x7), (int32_t)((indexBits >> 42) & 0x7),
1682*35238bceSAndroid Build Coastguard Worker (int32_t)((indexBits >> 45) & 0x7)};
1683*35238bceSAndroid Build Coastguard Worker
1684*35238bceSAndroid Build Coastguard Worker reds[0] = hasSign ? int8ToFloat(red0s) : uint8ToFloat(red0);
1685*35238bceSAndroid Build Coastguard Worker reds[1] = hasSign ? int8ToFloat(red1s) : uint8ToFloat(red1);
1686*35238bceSAndroid Build Coastguard Worker
1687*35238bceSAndroid Build Coastguard Worker if (reds[0] > reds[1])
1688*35238bceSAndroid Build Coastguard Worker {
1689*35238bceSAndroid Build Coastguard Worker for (uint32_t i = 0; i < 6; i++)
1690*35238bceSAndroid Build Coastguard Worker reds[i + 2] = (reds[0] * (6.0f - (float)i) + reds[1] * (1.0f + (float)i)) / 7.0f;
1691*35238bceSAndroid Build Coastguard Worker }
1692*35238bceSAndroid Build Coastguard Worker else
1693*35238bceSAndroid Build Coastguard Worker {
1694*35238bceSAndroid Build Coastguard Worker for (uint32_t i = 0; i < 4; i++)
1695*35238bceSAndroid Build Coastguard Worker reds[i + 2] = (reds[0] * (4.0f - (float)i) + reds[1] * (1.0f + (float)i)) / 5.0f;
1696*35238bceSAndroid Build Coastguard Worker reds[6] = hasSign ? -1.0f : 0.0f;
1697*35238bceSAndroid Build Coastguard Worker reds[7] = 1.0f;
1698*35238bceSAndroid Build Coastguard Worker }
1699*35238bceSAndroid Build Coastguard Worker
1700*35238bceSAndroid Build Coastguard Worker for (uint32_t y = 0; y < (uint32_t)BC_BLOCK_HEIGHT; y++)
1701*35238bceSAndroid Build Coastguard Worker {
1702*35238bceSAndroid Build Coastguard Worker for (uint32_t x = 0; x < (uint32_t)BC_BLOCK_WIDTH; x++)
1703*35238bceSAndroid Build Coastguard Worker {
1704*35238bceSAndroid Build Coastguard Worker float *const dstPixel = (float *)(dstPtr + y * dstRowPitch + x * dstPixelSize);
1705*35238bceSAndroid Build Coastguard Worker *dstPixel = reds[indices[y * BC_BLOCK_WIDTH + x]];
1706*35238bceSAndroid Build Coastguard Worker }
1707*35238bceSAndroid Build Coastguard Worker }
1708*35238bceSAndroid Build Coastguard Worker }
1709*35238bceSAndroid Build Coastguard Worker
decompressBc5(const PixelBufferAccess & dst,const uint8_t * src,bool hasSign)1710*35238bceSAndroid Build Coastguard Worker void decompressBc5(const PixelBufferAccess &dst, const uint8_t *src, bool hasSign)
1711*35238bceSAndroid Build Coastguard Worker {
1712*35238bceSAndroid Build Coastguard Worker using namespace BcDecompressInternal;
1713*35238bceSAndroid Build Coastguard Worker
1714*35238bceSAndroid Build Coastguard Worker uint8_t *const dstPtr = (uint8_t *)dst.getDataPtr();
1715*35238bceSAndroid Build Coastguard Worker const uint32_t dstRowPitch = dst.getRowPitch();
1716*35238bceSAndroid Build Coastguard Worker const uint32_t dstPixelSize = 8;
1717*35238bceSAndroid Build Coastguard Worker float rg[2][8];
1718*35238bceSAndroid Build Coastguard Worker uint32_t indices[2][16];
1719*35238bceSAndroid Build Coastguard Worker
1720*35238bceSAndroid Build Coastguard Worker for (uint32_t c = 0; c < 2; c++)
1721*35238bceSAndroid Build Coastguard Worker {
1722*35238bceSAndroid Build Coastguard Worker const uint32_t offset = c * 8;
1723*35238bceSAndroid Build Coastguard Worker const uint8_t rg0 = src[offset];
1724*35238bceSAndroid Build Coastguard Worker const uint8_t rg1 = src[offset + 1];
1725*35238bceSAndroid Build Coastguard Worker const int8_t rg0s = ((int8_t *)src)[offset];
1726*35238bceSAndroid Build Coastguard Worker const int8_t rg1s = ((int8_t *)src)[offset + 1];
1727*35238bceSAndroid Build Coastguard Worker const uint64_t indexBits = get64BitBlockLE(src, c) >> 16;
1728*35238bceSAndroid Build Coastguard Worker
1729*35238bceSAndroid Build Coastguard Worker for (uint32_t i = 0; i < 16; i++)
1730*35238bceSAndroid Build Coastguard Worker indices[c][i] = (indexBits >> (i * 3)) & 0x7;
1731*35238bceSAndroid Build Coastguard Worker
1732*35238bceSAndroid Build Coastguard Worker rg[c][0] = hasSign ? int8ToFloat(rg0s) : uint8ToFloat(rg0);
1733*35238bceSAndroid Build Coastguard Worker rg[c][1] = hasSign ? int8ToFloat(rg1s) : uint8ToFloat(rg1);
1734*35238bceSAndroid Build Coastguard Worker
1735*35238bceSAndroid Build Coastguard Worker if (rg[c][0] > rg[c][1])
1736*35238bceSAndroid Build Coastguard Worker {
1737*35238bceSAndroid Build Coastguard Worker for (uint32_t i = 0; i < 6; i++)
1738*35238bceSAndroid Build Coastguard Worker rg[c][i + 2] = (rg[c][0] * (6.0f - (float)i) + rg[c][1] * (1.0f + (float)i)) / 7.0f;
1739*35238bceSAndroid Build Coastguard Worker }
1740*35238bceSAndroid Build Coastguard Worker else
1741*35238bceSAndroid Build Coastguard Worker {
1742*35238bceSAndroid Build Coastguard Worker for (uint32_t i = 0; i < 4; i++)
1743*35238bceSAndroid Build Coastguard Worker rg[c][i + 2] = (rg[c][0] * (4.0f - (float)i) + rg[c][1] * (1.0f + (float)i)) / 5.0f;
1744*35238bceSAndroid Build Coastguard Worker rg[c][6] = hasSign ? -1.0f : 0.0f;
1745*35238bceSAndroid Build Coastguard Worker rg[c][7] = 1.0f;
1746*35238bceSAndroid Build Coastguard Worker }
1747*35238bceSAndroid Build Coastguard Worker }
1748*35238bceSAndroid Build Coastguard Worker
1749*35238bceSAndroid Build Coastguard Worker for (uint32_t y = 0; y < (uint32_t)BC_BLOCK_HEIGHT; y++)
1750*35238bceSAndroid Build Coastguard Worker {
1751*35238bceSAndroid Build Coastguard Worker for (uint32_t x = 0; x < (uint32_t)BC_BLOCK_WIDTH; x++)
1752*35238bceSAndroid Build Coastguard Worker {
1753*35238bceSAndroid Build Coastguard Worker float *const dstPixel = (float *)(dstPtr + y * dstRowPitch + x * dstPixelSize);
1754*35238bceSAndroid Build Coastguard Worker for (uint32_t i = 0; i < 2; i++)
1755*35238bceSAndroid Build Coastguard Worker dstPixel[i] = rg[i][indices[i][y * BC_BLOCK_WIDTH + x]];
1756*35238bceSAndroid Build Coastguard Worker }
1757*35238bceSAndroid Build Coastguard Worker }
1758*35238bceSAndroid Build Coastguard Worker }
1759*35238bceSAndroid Build Coastguard Worker
decompressBc6H(const PixelBufferAccess & dst,const uint8_t * src,bool hasSign)1760*35238bceSAndroid Build Coastguard Worker void decompressBc6H(const PixelBufferAccess &dst, const uint8_t *src, bool hasSign)
1761*35238bceSAndroid Build Coastguard Worker {
1762*35238bceSAndroid Build Coastguard Worker using namespace BcDecompressInternal;
1763*35238bceSAndroid Build Coastguard Worker
1764*35238bceSAndroid Build Coastguard Worker uint8_t *const dstPtr = (uint8_t *)dst.getDataPtr();
1765*35238bceSAndroid Build Coastguard Worker const uint32_t dstRowPitch = dst.getRowPitch();
1766*35238bceSAndroid Build Coastguard Worker const uint32_t dstPixelSize = 6;
1767*35238bceSAndroid Build Coastguard Worker
1768*35238bceSAndroid Build Coastguard Worker int32_t mode = extractModeBc6(src[0]);
1769*35238bceSAndroid Build Coastguard Worker IVec4 r(0);
1770*35238bceSAndroid Build Coastguard Worker IVec4 g(0);
1771*35238bceSAndroid Build Coastguard Worker IVec4 b(0);
1772*35238bceSAndroid Build Coastguard Worker uint32_t deltaBitsR = 0;
1773*35238bceSAndroid Build Coastguard Worker uint32_t deltaBitsG = 0;
1774*35238bceSAndroid Build Coastguard Worker uint32_t deltaBitsB = 0;
1775*35238bceSAndroid Build Coastguard Worker const uint64_t low = ((uint64_t *)src)[0];
1776*35238bceSAndroid Build Coastguard Worker const uint64_t high = ((uint64_t *)src)[1];
1777*35238bceSAndroid Build Coastguard Worker const uint32_t d = mode < 10 ? getBits128(low, high, 77, 81) : 0;
1778*35238bceSAndroid Build Coastguard Worker const uint32_t numRegions = mode > 9 ? 1 : 2;
1779*35238bceSAndroid Build Coastguard Worker const uint32_t numEndpoints = numRegions * 2;
1780*35238bceSAndroid Build Coastguard Worker const bool transformed = mode != 9 && mode != 10;
1781*35238bceSAndroid Build Coastguard Worker const uint32_t colorIndexBC = mode < 10 ? 3 : 4;
1782*35238bceSAndroid Build Coastguard Worker uint64_t colorIndexData = high >> (mode < 10 ? 18 : 1);
1783*35238bceSAndroid Build Coastguard Worker const uint32_t anchorIndex[2] = {0, anchorIndicesSecondSubset2[d]};
1784*35238bceSAndroid Build Coastguard Worker
1785*35238bceSAndroid Build Coastguard Worker switch (mode)
1786*35238bceSAndroid Build Coastguard Worker {
1787*35238bceSAndroid Build Coastguard Worker case 0:
1788*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 2, 2) << 4;
1789*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 3, 3) << 4;
1790*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 4, 4) << 4;
1791*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 5, 14);
1792*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 15, 24);
1793*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 25, 34);
1794*35238bceSAndroid Build Coastguard Worker r[1] |= getBits128(low, high, 35, 39);
1795*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 40, 40) << 4;
1796*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 41, 44);
1797*35238bceSAndroid Build Coastguard Worker g[1] |= getBits128(low, high, 45, 49);
1798*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 50, 50);
1799*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 51, 54);
1800*35238bceSAndroid Build Coastguard Worker b[1] |= getBits128(low, high, 55, 59);
1801*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 60, 60) << 1;
1802*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 61, 64);
1803*35238bceSAndroid Build Coastguard Worker r[2] |= getBits128(low, high, 65, 69);
1804*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 70, 70) << 2;
1805*35238bceSAndroid Build Coastguard Worker r[3] |= getBits128(low, high, 71, 75);
1806*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 76, 76) << 3;
1807*35238bceSAndroid Build Coastguard Worker deltaBitsR = deltaBitsG = deltaBitsB = 5;
1808*35238bceSAndroid Build Coastguard Worker break;
1809*35238bceSAndroid Build Coastguard Worker
1810*35238bceSAndroid Build Coastguard Worker case 1:
1811*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 2, 2) << 5;
1812*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 3, 3) << 4;
1813*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 4, 4) << 5;
1814*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 5, 11);
1815*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 12, 12);
1816*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 13, 13) << 1;
1817*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 14, 14) << 4;
1818*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 15, 21);
1819*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 22, 22) << 5;
1820*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 23, 23) << 2;
1821*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 24, 24) << 4;
1822*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 25, 31);
1823*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 32, 32) << 3;
1824*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 33, 33) << 5;
1825*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 34, 34) << 4;
1826*35238bceSAndroid Build Coastguard Worker r[1] |= getBits128(low, high, 35, 40);
1827*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 41, 44);
1828*35238bceSAndroid Build Coastguard Worker g[1] |= getBits128(low, high, 45, 50);
1829*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 51, 54);
1830*35238bceSAndroid Build Coastguard Worker b[1] |= getBits128(low, high, 55, 60);
1831*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 61, 64);
1832*35238bceSAndroid Build Coastguard Worker r[2] |= getBits128(low, high, 65, 70);
1833*35238bceSAndroid Build Coastguard Worker r[3] |= getBits128(low, high, 71, 76);
1834*35238bceSAndroid Build Coastguard Worker deltaBitsR = deltaBitsG = deltaBitsB = 6;
1835*35238bceSAndroid Build Coastguard Worker break;
1836*35238bceSAndroid Build Coastguard Worker
1837*35238bceSAndroid Build Coastguard Worker case 2:
1838*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 5, 14);
1839*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 15, 24);
1840*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 25, 34);
1841*35238bceSAndroid Build Coastguard Worker r[1] |= getBits128(low, high, 35, 39);
1842*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 40, 40) << 10;
1843*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 41, 44);
1844*35238bceSAndroid Build Coastguard Worker g[1] |= getBits128(low, high, 45, 48);
1845*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 49, 49) << 10;
1846*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 50, 50);
1847*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 51, 54);
1848*35238bceSAndroid Build Coastguard Worker b[1] |= getBits128(low, high, 55, 58);
1849*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 59, 59) << 10;
1850*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 60, 60) << 1;
1851*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 61, 64);
1852*35238bceSAndroid Build Coastguard Worker r[2] |= getBits128(low, high, 65, 69);
1853*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 70, 70) << 2;
1854*35238bceSAndroid Build Coastguard Worker r[3] |= getBits128(low, high, 71, 75);
1855*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 76, 76) << 3;
1856*35238bceSAndroid Build Coastguard Worker deltaBitsR = 5;
1857*35238bceSAndroid Build Coastguard Worker deltaBitsG = deltaBitsB = 4;
1858*35238bceSAndroid Build Coastguard Worker break;
1859*35238bceSAndroid Build Coastguard Worker
1860*35238bceSAndroid Build Coastguard Worker case 3:
1861*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 5, 14);
1862*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 15, 24);
1863*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 25, 34);
1864*35238bceSAndroid Build Coastguard Worker r[1] |= getBits128(low, high, 35, 38);
1865*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 39, 39) << 10;
1866*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 40, 40) << 4;
1867*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 41, 44);
1868*35238bceSAndroid Build Coastguard Worker g[1] |= getBits128(low, high, 45, 49);
1869*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 50, 50) << 10;
1870*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 51, 54);
1871*35238bceSAndroid Build Coastguard Worker b[1] |= getBits128(low, high, 55, 58);
1872*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 59, 59) << 10;
1873*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 60, 60) << 1;
1874*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 61, 64);
1875*35238bceSAndroid Build Coastguard Worker r[2] |= getBits128(low, high, 65, 68);
1876*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 69, 69);
1877*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 70, 70) << 2;
1878*35238bceSAndroid Build Coastguard Worker r[3] |= getBits128(low, high, 71, 74);
1879*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 75, 75) << 4;
1880*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 76, 76) << 3;
1881*35238bceSAndroid Build Coastguard Worker deltaBitsR = deltaBitsB = 4;
1882*35238bceSAndroid Build Coastguard Worker deltaBitsG = 5;
1883*35238bceSAndroid Build Coastguard Worker break;
1884*35238bceSAndroid Build Coastguard Worker
1885*35238bceSAndroid Build Coastguard Worker case 4:
1886*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 5, 14);
1887*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 15, 24);
1888*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 25, 34);
1889*35238bceSAndroid Build Coastguard Worker r[1] |= getBits128(low, high, 35, 38);
1890*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 39, 39) << 10;
1891*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 40, 40) << 4;
1892*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 41, 44);
1893*35238bceSAndroid Build Coastguard Worker g[1] |= getBits128(low, high, 45, 48);
1894*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 49, 49) << 10;
1895*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 50, 50);
1896*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 51, 54);
1897*35238bceSAndroid Build Coastguard Worker b[1] |= getBits128(low, high, 55, 59);
1898*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 60, 60) << 10;
1899*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 61, 64);
1900*35238bceSAndroid Build Coastguard Worker r[2] |= getBits128(low, high, 65, 68);
1901*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 69, 69) << 1;
1902*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 70, 70) << 2;
1903*35238bceSAndroid Build Coastguard Worker r[3] |= getBits128(low, high, 71, 74);
1904*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 75, 75) << 4;
1905*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 76, 76) << 3;
1906*35238bceSAndroid Build Coastguard Worker deltaBitsR = deltaBitsG = 4;
1907*35238bceSAndroid Build Coastguard Worker deltaBitsB = 5;
1908*35238bceSAndroid Build Coastguard Worker break;
1909*35238bceSAndroid Build Coastguard Worker
1910*35238bceSAndroid Build Coastguard Worker case 5:
1911*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 5, 13);
1912*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 14, 14) << 4;
1913*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 15, 23);
1914*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 24, 24) << 4;
1915*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 25, 33);
1916*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 34, 34) << 4;
1917*35238bceSAndroid Build Coastguard Worker r[1] |= getBits128(low, high, 35, 39);
1918*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 40, 40) << 4;
1919*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 41, 44);
1920*35238bceSAndroid Build Coastguard Worker g[1] |= getBits128(low, high, 45, 49);
1921*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 50, 50);
1922*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 51, 54);
1923*35238bceSAndroid Build Coastguard Worker b[1] |= getBits128(low, high, 55, 59);
1924*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 60, 60) << 1;
1925*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 61, 64);
1926*35238bceSAndroid Build Coastguard Worker r[2] |= getBits128(low, high, 65, 69);
1927*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 70, 70) << 2;
1928*35238bceSAndroid Build Coastguard Worker r[3] |= getBits128(low, high, 71, 75);
1929*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 76, 76) << 3;
1930*35238bceSAndroid Build Coastguard Worker deltaBitsR = deltaBitsG = deltaBitsB = 5;
1931*35238bceSAndroid Build Coastguard Worker break;
1932*35238bceSAndroid Build Coastguard Worker
1933*35238bceSAndroid Build Coastguard Worker case 6:
1934*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 5, 12);
1935*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 13, 13) << 4;
1936*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 14, 14) << 4;
1937*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 15, 22);
1938*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 23, 23) << 2;
1939*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 24, 24) << 4;
1940*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 25, 32);
1941*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 33, 33) << 3;
1942*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 34, 34) << 4;
1943*35238bceSAndroid Build Coastguard Worker r[1] |= getBits128(low, high, 35, 40);
1944*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 41, 44);
1945*35238bceSAndroid Build Coastguard Worker g[1] |= getBits128(low, high, 45, 49);
1946*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 50, 50);
1947*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 51, 54);
1948*35238bceSAndroid Build Coastguard Worker b[1] |= getBits128(low, high, 55, 59);
1949*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 60, 60) << 1;
1950*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 61, 64);
1951*35238bceSAndroid Build Coastguard Worker r[2] |= getBits128(low, high, 65, 70);
1952*35238bceSAndroid Build Coastguard Worker r[3] |= getBits128(low, high, 71, 76);
1953*35238bceSAndroid Build Coastguard Worker deltaBitsR = 6;
1954*35238bceSAndroid Build Coastguard Worker deltaBitsG = deltaBitsB = 5;
1955*35238bceSAndroid Build Coastguard Worker break;
1956*35238bceSAndroid Build Coastguard Worker
1957*35238bceSAndroid Build Coastguard Worker case 7:
1958*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 5, 12);
1959*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 13, 13);
1960*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 14, 14) << 4;
1961*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 15, 22);
1962*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 23, 23) << 5;
1963*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 24, 24) << 4;
1964*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 25, 32);
1965*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 33, 33) << 5;
1966*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 34, 34) << 4;
1967*35238bceSAndroid Build Coastguard Worker r[1] |= getBits128(low, high, 35, 39);
1968*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 40, 40) << 4;
1969*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 41, 44);
1970*35238bceSAndroid Build Coastguard Worker g[1] |= getBits128(low, high, 45, 50);
1971*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 51, 54);
1972*35238bceSAndroid Build Coastguard Worker b[1] |= getBits128(low, high, 55, 59);
1973*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 60, 60) << 1;
1974*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 61, 64);
1975*35238bceSAndroid Build Coastguard Worker r[2] |= getBits128(low, high, 65, 69);
1976*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 70, 70) << 2;
1977*35238bceSAndroid Build Coastguard Worker r[3] |= getBits128(low, high, 71, 75);
1978*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 76, 76) << 3;
1979*35238bceSAndroid Build Coastguard Worker deltaBitsR = deltaBitsB = 5;
1980*35238bceSAndroid Build Coastguard Worker deltaBitsG = 6;
1981*35238bceSAndroid Build Coastguard Worker break;
1982*35238bceSAndroid Build Coastguard Worker
1983*35238bceSAndroid Build Coastguard Worker case 8:
1984*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 5, 12);
1985*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 13, 13) << 1;
1986*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 14, 14) << 4;
1987*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 15, 22);
1988*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 23, 23) << 5;
1989*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 24, 24) << 4;
1990*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 25, 32);
1991*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 33, 33) << 5;
1992*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 34, 34) << 4;
1993*35238bceSAndroid Build Coastguard Worker r[1] |= getBits128(low, high, 35, 39);
1994*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 40, 40) << 4;
1995*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 41, 44);
1996*35238bceSAndroid Build Coastguard Worker g[1] |= getBits128(low, high, 45, 49);
1997*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 50, 50);
1998*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 51, 54);
1999*35238bceSAndroid Build Coastguard Worker b[1] |= getBits128(low, high, 55, 60);
2000*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 61, 64);
2001*35238bceSAndroid Build Coastguard Worker r[2] |= getBits128(low, high, 65, 69);
2002*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 70, 70) << 2;
2003*35238bceSAndroid Build Coastguard Worker r[3] |= getBits128(low, high, 71, 75);
2004*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 76, 76) << 3;
2005*35238bceSAndroid Build Coastguard Worker deltaBitsR = deltaBitsG = 5;
2006*35238bceSAndroid Build Coastguard Worker deltaBitsB = 6;
2007*35238bceSAndroid Build Coastguard Worker break;
2008*35238bceSAndroid Build Coastguard Worker
2009*35238bceSAndroid Build Coastguard Worker case 9:
2010*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 5, 10);
2011*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 11, 11) << 4;
2012*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 12, 13);
2013*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 14, 14) << 4;
2014*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 15, 20);
2015*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 21, 21) << 5;
2016*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 22, 22) << 5;
2017*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 23, 23) << 2;
2018*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 24, 24) << 4;
2019*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 25, 30);
2020*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 31, 31) << 5;
2021*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 32, 32) << 3;
2022*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 33, 33) << 5;
2023*35238bceSAndroid Build Coastguard Worker b[3] |= getBits128(low, high, 34, 34) << 4;
2024*35238bceSAndroid Build Coastguard Worker r[1] |= getBits128(low, high, 35, 40);
2025*35238bceSAndroid Build Coastguard Worker g[2] |= getBits128(low, high, 41, 44);
2026*35238bceSAndroid Build Coastguard Worker g[1] |= getBits128(low, high, 45, 50);
2027*35238bceSAndroid Build Coastguard Worker g[3] |= getBits128(low, high, 51, 54);
2028*35238bceSAndroid Build Coastguard Worker b[1] |= getBits128(low, high, 55, 60);
2029*35238bceSAndroid Build Coastguard Worker b[2] |= getBits128(low, high, 61, 64);
2030*35238bceSAndroid Build Coastguard Worker r[2] |= getBits128(low, high, 65, 70);
2031*35238bceSAndroid Build Coastguard Worker r[3] |= getBits128(low, high, 71, 76);
2032*35238bceSAndroid Build Coastguard Worker deltaBitsR = deltaBitsG = deltaBitsB = 6;
2033*35238bceSAndroid Build Coastguard Worker break;
2034*35238bceSAndroid Build Coastguard Worker
2035*35238bceSAndroid Build Coastguard Worker case 10:
2036*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 5, 14);
2037*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 15, 24);
2038*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 25, 34);
2039*35238bceSAndroid Build Coastguard Worker r[1] |= getBits128(low, high, 35, 44);
2040*35238bceSAndroid Build Coastguard Worker g[1] |= getBits128(low, high, 45, 54);
2041*35238bceSAndroid Build Coastguard Worker b[1] |= getBits128(low, high, 55, 64);
2042*35238bceSAndroid Build Coastguard Worker deltaBitsR = deltaBitsG = deltaBitsB = 10;
2043*35238bceSAndroid Build Coastguard Worker break;
2044*35238bceSAndroid Build Coastguard Worker
2045*35238bceSAndroid Build Coastguard Worker case 11:
2046*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 5, 14);
2047*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 15, 24);
2048*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 25, 34);
2049*35238bceSAndroid Build Coastguard Worker r[1] |= getBits128(low, high, 35, 43);
2050*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 44, 44) << 10;
2051*35238bceSAndroid Build Coastguard Worker g[1] |= getBits128(low, high, 45, 53);
2052*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 54, 54) << 10;
2053*35238bceSAndroid Build Coastguard Worker b[1] |= getBits128(low, high, 55, 63);
2054*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 64, 64) << 10;
2055*35238bceSAndroid Build Coastguard Worker deltaBitsR = deltaBitsG = deltaBitsB = 9;
2056*35238bceSAndroid Build Coastguard Worker break;
2057*35238bceSAndroid Build Coastguard Worker
2058*35238bceSAndroid Build Coastguard Worker case 12:
2059*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 5, 14);
2060*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 15, 24);
2061*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 25, 34);
2062*35238bceSAndroid Build Coastguard Worker r[1] |= getBits128(low, high, 35, 42);
2063*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 44, 43) << 10;
2064*35238bceSAndroid Build Coastguard Worker g[1] |= getBits128(low, high, 45, 52);
2065*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 54, 53) << 10;
2066*35238bceSAndroid Build Coastguard Worker b[1] |= getBits128(low, high, 55, 62);
2067*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 64, 63) << 10;
2068*35238bceSAndroid Build Coastguard Worker deltaBitsR = deltaBitsG = deltaBitsB = 8;
2069*35238bceSAndroid Build Coastguard Worker break;
2070*35238bceSAndroid Build Coastguard Worker
2071*35238bceSAndroid Build Coastguard Worker case 13:
2072*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 5, 14);
2073*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 15, 24);
2074*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 25, 34);
2075*35238bceSAndroid Build Coastguard Worker r[1] |= getBits128(low, high, 35, 38);
2076*35238bceSAndroid Build Coastguard Worker r[0] |= getBits128(low, high, 44, 39) << 10;
2077*35238bceSAndroid Build Coastguard Worker g[1] |= getBits128(low, high, 45, 48);
2078*35238bceSAndroid Build Coastguard Worker g[0] |= getBits128(low, high, 54, 49) << 10;
2079*35238bceSAndroid Build Coastguard Worker b[1] |= getBits128(low, high, 55, 58);
2080*35238bceSAndroid Build Coastguard Worker b[0] |= getBits128(low, high, 64, 59) << 10;
2081*35238bceSAndroid Build Coastguard Worker deltaBitsR = deltaBitsG = deltaBitsB = 4;
2082*35238bceSAndroid Build Coastguard Worker break;
2083*35238bceSAndroid Build Coastguard Worker }
2084*35238bceSAndroid Build Coastguard Worker
2085*35238bceSAndroid Build Coastguard Worker if (hasSign)
2086*35238bceSAndroid Build Coastguard Worker {
2087*35238bceSAndroid Build Coastguard Worker r[0] = signExtend(r[0], epBits[mode], 32);
2088*35238bceSAndroid Build Coastguard Worker g[0] = signExtend(g[0], epBits[mode], 32);
2089*35238bceSAndroid Build Coastguard Worker b[0] = signExtend(b[0], epBits[mode], 32);
2090*35238bceSAndroid Build Coastguard Worker }
2091*35238bceSAndroid Build Coastguard Worker
2092*35238bceSAndroid Build Coastguard Worker if (transformed)
2093*35238bceSAndroid Build Coastguard Worker {
2094*35238bceSAndroid Build Coastguard Worker for (uint32_t i = 1; i < numEndpoints; i++)
2095*35238bceSAndroid Build Coastguard Worker {
2096*35238bceSAndroid Build Coastguard Worker r[i] = signExtend(r[i], deltaBitsR, 32);
2097*35238bceSAndroid Build Coastguard Worker r[i] = (r[0] + r[i]) & (((uint32_t)1 << epBits[mode]) - 1);
2098*35238bceSAndroid Build Coastguard Worker g[i] = signExtend(g[i], deltaBitsG, 32);
2099*35238bceSAndroid Build Coastguard Worker g[i] = (g[0] + g[i]) & (((uint32_t)1 << epBits[mode]) - 1);
2100*35238bceSAndroid Build Coastguard Worker b[i] = signExtend(b[i], deltaBitsB, 32);
2101*35238bceSAndroid Build Coastguard Worker b[i] = (b[0] + b[i]) & (((uint32_t)1 << epBits[mode]) - 1);
2102*35238bceSAndroid Build Coastguard Worker }
2103*35238bceSAndroid Build Coastguard Worker }
2104*35238bceSAndroid Build Coastguard Worker
2105*35238bceSAndroid Build Coastguard Worker if (hasSign)
2106*35238bceSAndroid Build Coastguard Worker {
2107*35238bceSAndroid Build Coastguard Worker for (uint32_t i = 1; i < 4; i++)
2108*35238bceSAndroid Build Coastguard Worker {
2109*35238bceSAndroid Build Coastguard Worker r[i] = signExtend(r[i], epBits[mode], 32);
2110*35238bceSAndroid Build Coastguard Worker g[i] = signExtend(g[i], epBits[mode], 32);
2111*35238bceSAndroid Build Coastguard Worker b[i] = signExtend(b[i], epBits[mode], 32);
2112*35238bceSAndroid Build Coastguard Worker }
2113*35238bceSAndroid Build Coastguard Worker }
2114*35238bceSAndroid Build Coastguard Worker
2115*35238bceSAndroid Build Coastguard Worker for (uint32_t i = 0; i < numEndpoints; i++)
2116*35238bceSAndroid Build Coastguard Worker {
2117*35238bceSAndroid Build Coastguard Worker r[i] = unquantize(r[i], mode, hasSign);
2118*35238bceSAndroid Build Coastguard Worker g[i] = unquantize(g[i], mode, hasSign);
2119*35238bceSAndroid Build Coastguard Worker b[i] = unquantize(b[i], mode, hasSign);
2120*35238bceSAndroid Build Coastguard Worker }
2121*35238bceSAndroid Build Coastguard Worker
2122*35238bceSAndroid Build Coastguard Worker for (uint32_t i = 0; i < 16; i++)
2123*35238bceSAndroid Build Coastguard Worker {
2124*35238bceSAndroid Build Coastguard Worker const uint32_t subsetIndex = (numRegions == 1 ? 0 : partitions2[d][i]);
2125*35238bceSAndroid Build Coastguard Worker const uint32_t bits = (i == anchorIndex[subsetIndex]) ? (colorIndexBC - 1) : colorIndexBC;
2126*35238bceSAndroid Build Coastguard Worker const uint32_t colorIndex = (uint32_t)(colorIndexData & ((1 << bits) - 1));
2127*35238bceSAndroid Build Coastguard Worker const int32_t endpointStartR = r[2 * subsetIndex];
2128*35238bceSAndroid Build Coastguard Worker const int32_t endpointEndR = r[2 * subsetIndex + 1];
2129*35238bceSAndroid Build Coastguard Worker const int32_t endpointStartG = g[2 * subsetIndex];
2130*35238bceSAndroid Build Coastguard Worker const int32_t endpointEndG = g[2 * subsetIndex + 1];
2131*35238bceSAndroid Build Coastguard Worker const int32_t endpointStartB = b[2 * subsetIndex];
2132*35238bceSAndroid Build Coastguard Worker const int32_t endpointEndB = b[2 * subsetIndex + 1];
2133*35238bceSAndroid Build Coastguard Worker const int16_t r16 =
2134*35238bceSAndroid Build Coastguard Worker finishUnquantize(interpolate(endpointStartR, endpointEndR, colorIndex, colorIndexBC), hasSign);
2135*35238bceSAndroid Build Coastguard Worker const int16_t g16 =
2136*35238bceSAndroid Build Coastguard Worker finishUnquantize(interpolate(endpointStartG, endpointEndG, colorIndex, colorIndexBC), hasSign);
2137*35238bceSAndroid Build Coastguard Worker const int16_t b16 =
2138*35238bceSAndroid Build Coastguard Worker finishUnquantize(interpolate(endpointStartB, endpointEndB, colorIndex, colorIndexBC), hasSign);
2139*35238bceSAndroid Build Coastguard Worker const int32_t y = i / 4;
2140*35238bceSAndroid Build Coastguard Worker const int32_t x = i % 4;
2141*35238bceSAndroid Build Coastguard Worker int16_t *const dstPixel = (int16_t *)(dstPtr + y * dstRowPitch + x * dstPixelSize);
2142*35238bceSAndroid Build Coastguard Worker
2143*35238bceSAndroid Build Coastguard Worker if (mode == -1)
2144*35238bceSAndroid Build Coastguard Worker {
2145*35238bceSAndroid Build Coastguard Worker dstPixel[0] = 0;
2146*35238bceSAndroid Build Coastguard Worker dstPixel[1] = 0;
2147*35238bceSAndroid Build Coastguard Worker dstPixel[2] = 0;
2148*35238bceSAndroid Build Coastguard Worker }
2149*35238bceSAndroid Build Coastguard Worker else
2150*35238bceSAndroid Build Coastguard Worker {
2151*35238bceSAndroid Build Coastguard Worker dstPixel[0] = r16;
2152*35238bceSAndroid Build Coastguard Worker dstPixel[1] = g16;
2153*35238bceSAndroid Build Coastguard Worker dstPixel[2] = b16;
2154*35238bceSAndroid Build Coastguard Worker }
2155*35238bceSAndroid Build Coastguard Worker
2156*35238bceSAndroid Build Coastguard Worker colorIndexData >>= bits;
2157*35238bceSAndroid Build Coastguard Worker }
2158*35238bceSAndroid Build Coastguard Worker }
2159*35238bceSAndroid Build Coastguard Worker
decompressBc7(const PixelBufferAccess & dst,const uint8_t * src)2160*35238bceSAndroid Build Coastguard Worker void decompressBc7(const PixelBufferAccess &dst, const uint8_t *src)
2161*35238bceSAndroid Build Coastguard Worker {
2162*35238bceSAndroid Build Coastguard Worker using namespace BcDecompressInternal;
2163*35238bceSAndroid Build Coastguard Worker
2164*35238bceSAndroid Build Coastguard Worker static const uint8_t subsets[] = {3, 2, 3, 2, 1, 1, 1, 2};
2165*35238bceSAndroid Build Coastguard Worker static const uint8_t partitionBits[] = {4, 6, 6, 6, 0, 0, 0, 6};
2166*35238bceSAndroid Build Coastguard Worker static const uint8_t endpointBits[8][5] = {//r, g, b, a, p
2167*35238bceSAndroid Build Coastguard Worker {4, 4, 4, 0, 1}, {6, 6, 6, 0, 1}, {5, 5, 5, 0, 0}, {7, 7, 7, 0, 1},
2168*35238bceSAndroid Build Coastguard Worker {5, 5, 5, 6, 0}, {7, 7, 7, 8, 0}, {7, 7, 7, 7, 1}, {5, 5, 5, 5, 1}};
2169*35238bceSAndroid Build Coastguard Worker static const uint8_t indexBits[] = {3, 3, 2, 2, 2, 2, 4, 2};
2170*35238bceSAndroid Build Coastguard Worker
2171*35238bceSAndroid Build Coastguard Worker uint8_t *const dstPtr = (uint8_t *)dst.getDataPtr();
2172*35238bceSAndroid Build Coastguard Worker const uint32_t dstRowPitch = dst.getRowPitch();
2173*35238bceSAndroid Build Coastguard Worker const uint32_t dstPixelSize = 4;
2174*35238bceSAndroid Build Coastguard Worker
2175*35238bceSAndroid Build Coastguard Worker const uint64_t low = ((uint64_t *)src)[0];
2176*35238bceSAndroid Build Coastguard Worker const uint64_t high = ((uint64_t *)src)[1];
2177*35238bceSAndroid Build Coastguard Worker const int32_t mode = extractModeBc7(src[0]);
2178*35238bceSAndroid Build Coastguard Worker uint32_t numSubsets = 1;
2179*35238bceSAndroid Build Coastguard Worker uint32_t offset = mode + 1;
2180*35238bceSAndroid Build Coastguard Worker uint32_t rotation = 0;
2181*35238bceSAndroid Build Coastguard Worker uint32_t idxMode = 0;
2182*35238bceSAndroid Build Coastguard Worker uint32_t endpoints[6][5];
2183*35238bceSAndroid Build Coastguard Worker uint32_t partitionSetId = 0;
2184*35238bceSAndroid Build Coastguard Worker
2185*35238bceSAndroid Build Coastguard Worker // Decode partition data from explicit partition bits
2186*35238bceSAndroid Build Coastguard Worker if (mode == 0 || mode == 1 || mode == 2 || mode == 3 || mode == 7)
2187*35238bceSAndroid Build Coastguard Worker {
2188*35238bceSAndroid Build Coastguard Worker numSubsets = subsets[mode];
2189*35238bceSAndroid Build Coastguard Worker partitionSetId = getBits128(low, high, offset, offset + partitionBits[mode] - 1);
2190*35238bceSAndroid Build Coastguard Worker offset += partitionBits[mode];
2191*35238bceSAndroid Build Coastguard Worker }
2192*35238bceSAndroid Build Coastguard Worker
2193*35238bceSAndroid Build Coastguard Worker // Extract rotation bits
2194*35238bceSAndroid Build Coastguard Worker if (mode == 4 || mode == 5)
2195*35238bceSAndroid Build Coastguard Worker {
2196*35238bceSAndroid Build Coastguard Worker rotation = getBits128(low, high, offset, offset + 1);
2197*35238bceSAndroid Build Coastguard Worker offset += 2;
2198*35238bceSAndroid Build Coastguard Worker if (mode == 4)
2199*35238bceSAndroid Build Coastguard Worker {
2200*35238bceSAndroid Build Coastguard Worker idxMode = getBits128(low, high, offset, offset);
2201*35238bceSAndroid Build Coastguard Worker offset++;
2202*35238bceSAndroid Build Coastguard Worker }
2203*35238bceSAndroid Build Coastguard Worker }
2204*35238bceSAndroid Build Coastguard Worker
2205*35238bceSAndroid Build Coastguard Worker {
2206*35238bceSAndroid Build Coastguard Worker const uint32_t numEndpoints = numSubsets * 2;
2207*35238bceSAndroid Build Coastguard Worker
2208*35238bceSAndroid Build Coastguard Worker // Extract raw, compressed endpoint bits
2209*35238bceSAndroid Build Coastguard Worker for (uint32_t cpnt = 0; cpnt < 5; cpnt++)
2210*35238bceSAndroid Build Coastguard Worker {
2211*35238bceSAndroid Build Coastguard Worker for (uint32_t ep = 0; ep < numEndpoints; ep++)
2212*35238bceSAndroid Build Coastguard Worker {
2213*35238bceSAndroid Build Coastguard Worker if (mode == 1 && cpnt == 4 && ep > 1)
2214*35238bceSAndroid Build Coastguard Worker continue; // Mode 1 has shared P bits
2215*35238bceSAndroid Build Coastguard Worker
2216*35238bceSAndroid Build Coastguard Worker int n = mode == -1 ? 0 : endpointBits[mode][cpnt];
2217*35238bceSAndroid Build Coastguard Worker if (n > 0)
2218*35238bceSAndroid Build Coastguard Worker endpoints[ep][cpnt] = getBits128(low, high, offset, offset + n - 1);
2219*35238bceSAndroid Build Coastguard Worker offset += n;
2220*35238bceSAndroid Build Coastguard Worker }
2221*35238bceSAndroid Build Coastguard Worker }
2222*35238bceSAndroid Build Coastguard Worker
2223*35238bceSAndroid Build Coastguard Worker // Decode endpoints
2224*35238bceSAndroid Build Coastguard Worker if (mode == 0 || mode == 1 || mode == 3 || mode == 6 || mode == 7)
2225*35238bceSAndroid Build Coastguard Worker {
2226*35238bceSAndroid Build Coastguard Worker // First handle modes that have P-bits
2227*35238bceSAndroid Build Coastguard Worker for (uint32_t ep = 0; ep < numEndpoints; ep++)
2228*35238bceSAndroid Build Coastguard Worker {
2229*35238bceSAndroid Build Coastguard Worker for (uint32_t cpnt = 0; cpnt < 4; cpnt++)
2230*35238bceSAndroid Build Coastguard Worker {
2231*35238bceSAndroid Build Coastguard Worker endpoints[ep][cpnt] <<= 1;
2232*35238bceSAndroid Build Coastguard Worker }
2233*35238bceSAndroid Build Coastguard Worker }
2234*35238bceSAndroid Build Coastguard Worker
2235*35238bceSAndroid Build Coastguard Worker if (mode == 1)
2236*35238bceSAndroid Build Coastguard Worker {
2237*35238bceSAndroid Build Coastguard Worker // P-bit is shared
2238*35238bceSAndroid Build Coastguard Worker const uint32_t pbitZero = endpoints[0][4];
2239*35238bceSAndroid Build Coastguard Worker const uint32_t pbitOne = endpoints[1][4];
2240*35238bceSAndroid Build Coastguard Worker
2241*35238bceSAndroid Build Coastguard Worker for (uint32_t cpnt = 0; cpnt < 3; cpnt++)
2242*35238bceSAndroid Build Coastguard Worker {
2243*35238bceSAndroid Build Coastguard Worker endpoints[0][cpnt] |= pbitZero;
2244*35238bceSAndroid Build Coastguard Worker endpoints[1][cpnt] |= pbitZero;
2245*35238bceSAndroid Build Coastguard Worker endpoints[2][cpnt] |= pbitOne;
2246*35238bceSAndroid Build Coastguard Worker endpoints[3][cpnt] |= pbitOne;
2247*35238bceSAndroid Build Coastguard Worker }
2248*35238bceSAndroid Build Coastguard Worker }
2249*35238bceSAndroid Build Coastguard Worker else
2250*35238bceSAndroid Build Coastguard Worker {
2251*35238bceSAndroid Build Coastguard Worker // Unique p-bit per endpoint
2252*35238bceSAndroid Build Coastguard Worker for (uint32_t ep = 0; ep < numEndpoints; ep++)
2253*35238bceSAndroid Build Coastguard Worker {
2254*35238bceSAndroid Build Coastguard Worker for (uint32_t cpnt = 0; cpnt < 4; cpnt++)
2255*35238bceSAndroid Build Coastguard Worker {
2256*35238bceSAndroid Build Coastguard Worker endpoints[ep][cpnt] |= endpoints[ep][4];
2257*35238bceSAndroid Build Coastguard Worker }
2258*35238bceSAndroid Build Coastguard Worker }
2259*35238bceSAndroid Build Coastguard Worker }
2260*35238bceSAndroid Build Coastguard Worker }
2261*35238bceSAndroid Build Coastguard Worker
2262*35238bceSAndroid Build Coastguard Worker for (uint32_t ep = 0; ep < numEndpoints; ep++)
2263*35238bceSAndroid Build Coastguard Worker {
2264*35238bceSAndroid Build Coastguard Worker // Left shift endpoint components so that their MSB lies in bit 7
2265*35238bceSAndroid Build Coastguard Worker for (uint32_t cpnt = 0; cpnt < 4; cpnt++)
2266*35238bceSAndroid Build Coastguard Worker endpoints[ep][cpnt] <<= 8 - (endpointBits[mode][cpnt] + endpointBits[mode][4]);
2267*35238bceSAndroid Build Coastguard Worker
2268*35238bceSAndroid Build Coastguard Worker // Replicate each component's MSB into the LSBs revealed by the left-shift operation above
2269*35238bceSAndroid Build Coastguard Worker for (uint32_t cpnt = 0; cpnt < 4; cpnt++)
2270*35238bceSAndroid Build Coastguard Worker endpoints[ep][cpnt] |= endpoints[ep][cpnt] >> (endpointBits[mode][cpnt] + endpointBits[mode][4]);
2271*35238bceSAndroid Build Coastguard Worker }
2272*35238bceSAndroid Build Coastguard Worker
2273*35238bceSAndroid Build Coastguard Worker // If this mode does not explicitly define the alpha component set alpha equal to 1.0
2274*35238bceSAndroid Build Coastguard Worker if (mode < 4)
2275*35238bceSAndroid Build Coastguard Worker {
2276*35238bceSAndroid Build Coastguard Worker for (uint32_t ep = 0; ep < numEndpoints; ep++)
2277*35238bceSAndroid Build Coastguard Worker endpoints[ep][3] = 255;
2278*35238bceSAndroid Build Coastguard Worker }
2279*35238bceSAndroid Build Coastguard Worker }
2280*35238bceSAndroid Build Coastguard Worker
2281*35238bceSAndroid Build Coastguard Worker {
2282*35238bceSAndroid Build Coastguard Worker uint32_t colorIdxOffset = offset + ((mode == 4 && idxMode) ? 31 : 0);
2283*35238bceSAndroid Build Coastguard Worker uint32_t alphaIdxOffset = offset + ((mode == 5 || (mode == 4 && !idxMode)) ? 31 : 0);
2284*35238bceSAndroid Build Coastguard Worker
2285*35238bceSAndroid Build Coastguard Worker for (uint32_t pixel = 0; pixel < 16; pixel++)
2286*35238bceSAndroid Build Coastguard Worker {
2287*35238bceSAndroid Build Coastguard Worker const uint32_t y = pixel / 4;
2288*35238bceSAndroid Build Coastguard Worker const uint32_t x = pixel % 4;
2289*35238bceSAndroid Build Coastguard Worker uint32_t *const dstPixel = (uint32_t *)(dstPtr + y * dstRowPitch + x * dstPixelSize);
2290*35238bceSAndroid Build Coastguard Worker uint32_t subsetIndex = 0;
2291*35238bceSAndroid Build Coastguard Worker uint32_t anchorIndex = 0;
2292*35238bceSAndroid Build Coastguard Worker uint32_t endpointStart[4];
2293*35238bceSAndroid Build Coastguard Worker uint32_t endpointEnd[4];
2294*35238bceSAndroid Build Coastguard Worker
2295*35238bceSAndroid Build Coastguard Worker if (mode == -1)
2296*35238bceSAndroid Build Coastguard Worker {
2297*35238bceSAndroid Build Coastguard Worker *dstPixel = 0;
2298*35238bceSAndroid Build Coastguard Worker continue;
2299*35238bceSAndroid Build Coastguard Worker }
2300*35238bceSAndroid Build Coastguard Worker
2301*35238bceSAndroid Build Coastguard Worker if (numSubsets == 2)
2302*35238bceSAndroid Build Coastguard Worker subsetIndex = partitions2[partitionSetId][pixel];
2303*35238bceSAndroid Build Coastguard Worker else if (numSubsets == 3)
2304*35238bceSAndroid Build Coastguard Worker subsetIndex = partitions3[partitionSetId][pixel];
2305*35238bceSAndroid Build Coastguard Worker
2306*35238bceSAndroid Build Coastguard Worker if (numSubsets == 2 && subsetIndex == 1)
2307*35238bceSAndroid Build Coastguard Worker {
2308*35238bceSAndroid Build Coastguard Worker anchorIndex = anchorIndicesSecondSubset2[partitionSetId];
2309*35238bceSAndroid Build Coastguard Worker }
2310*35238bceSAndroid Build Coastguard Worker else if (numSubsets == 3)
2311*35238bceSAndroid Build Coastguard Worker {
2312*35238bceSAndroid Build Coastguard Worker if (subsetIndex == 1)
2313*35238bceSAndroid Build Coastguard Worker anchorIndex = anchorIndicesSecondSubset3[partitionSetId];
2314*35238bceSAndroid Build Coastguard Worker else if (subsetIndex == 2)
2315*35238bceSAndroid Build Coastguard Worker anchorIndex = anchorIndicesThirdSubset[partitionSetId];
2316*35238bceSAndroid Build Coastguard Worker }
2317*35238bceSAndroid Build Coastguard Worker
2318*35238bceSAndroid Build Coastguard Worker for (uint32_t cpnt = 0; cpnt < 4; cpnt++)
2319*35238bceSAndroid Build Coastguard Worker {
2320*35238bceSAndroid Build Coastguard Worker endpointStart[cpnt] = endpoints[2 * subsetIndex][cpnt];
2321*35238bceSAndroid Build Coastguard Worker endpointEnd[cpnt] = endpoints[2 * subsetIndex + 1][cpnt];
2322*35238bceSAndroid Build Coastguard Worker }
2323*35238bceSAndroid Build Coastguard Worker
2324*35238bceSAndroid Build Coastguard Worker {
2325*35238bceSAndroid Build Coastguard Worker const uint32_t colorInterpolationBits = indexBits[mode] + idxMode;
2326*35238bceSAndroid Build Coastguard Worker const uint32_t colorIndexBits = colorInterpolationBits - ((anchorIndex == pixel) ? 1 : 0);
2327*35238bceSAndroid Build Coastguard Worker const uint32_t alphaInterpolationBits =
2328*35238bceSAndroid Build Coastguard Worker mode == 4 ? 3 - idxMode : (mode == 5 ? 2 : colorInterpolationBits);
2329*35238bceSAndroid Build Coastguard Worker const uint32_t alphaIndexBits = alphaInterpolationBits - ((anchorIndex == pixel) ? 1 : 0);
2330*35238bceSAndroid Build Coastguard Worker const uint32_t colorIdx = getBits128(low, high, colorIdxOffset, colorIdxOffset + colorIndexBits - 1);
2331*35238bceSAndroid Build Coastguard Worker const uint32_t alphaIdx = (mode == 4 || mode == 5) ? getBits128(low, high, alphaIdxOffset,
2332*35238bceSAndroid Build Coastguard Worker alphaIdxOffset + alphaIndexBits - 1) :
2333*35238bceSAndroid Build Coastguard Worker colorIdx;
2334*35238bceSAndroid Build Coastguard Worker const uint32_t r = interpolate(endpointStart[0], endpointEnd[0], colorIdx, colorInterpolationBits);
2335*35238bceSAndroid Build Coastguard Worker const uint32_t g = interpolate(endpointStart[1], endpointEnd[1], colorIdx, colorInterpolationBits);
2336*35238bceSAndroid Build Coastguard Worker const uint32_t b = interpolate(endpointStart[2], endpointEnd[2], colorIdx, colorInterpolationBits);
2337*35238bceSAndroid Build Coastguard Worker const uint32_t a = interpolate(endpointStart[3], endpointEnd[3], alphaIdx, alphaInterpolationBits);
2338*35238bceSAndroid Build Coastguard Worker
2339*35238bceSAndroid Build Coastguard Worker colorIdxOffset += colorIndexBits;
2340*35238bceSAndroid Build Coastguard Worker alphaIdxOffset += alphaIndexBits;
2341*35238bceSAndroid Build Coastguard Worker
2342*35238bceSAndroid Build Coastguard Worker if ((mode == 4 || mode == 5) && rotation != 0)
2343*35238bceSAndroid Build Coastguard Worker {
2344*35238bceSAndroid Build Coastguard Worker if (rotation == 1)
2345*35238bceSAndroid Build Coastguard Worker *dstPixel = a | (g << 8) | (b << 16) | (r << 24);
2346*35238bceSAndroid Build Coastguard Worker else if (rotation == 2)
2347*35238bceSAndroid Build Coastguard Worker *dstPixel = r | (a << 8) | (b << 16) | (g << 24);
2348*35238bceSAndroid Build Coastguard Worker else
2349*35238bceSAndroid Build Coastguard Worker *dstPixel = r | (g << 8) | (a << 16) | (b << 24);
2350*35238bceSAndroid Build Coastguard Worker }
2351*35238bceSAndroid Build Coastguard Worker else
2352*35238bceSAndroid Build Coastguard Worker {
2353*35238bceSAndroid Build Coastguard Worker *dstPixel = r | (g << 8) | (b << 16) | (a << 24);
2354*35238bceSAndroid Build Coastguard Worker }
2355*35238bceSAndroid Build Coastguard Worker }
2356*35238bceSAndroid Build Coastguard Worker }
2357*35238bceSAndroid Build Coastguard Worker }
2358*35238bceSAndroid Build Coastguard Worker }
2359*35238bceSAndroid Build Coastguard Worker
decompressAhbRaw10(const PixelBufferAccess & dst,const uint8_t * src)2360*35238bceSAndroid Build Coastguard Worker void decompressAhbRaw10(const PixelBufferAccess &dst, const uint8_t *src)
2361*35238bceSAndroid Build Coastguard Worker {
2362*35238bceSAndroid Build Coastguard Worker // Packed format with 4 pixels in 5 bytes
2363*35238bceSAndroid Build Coastguard Worker // Layout: https://developer.android.com/reference/android/graphics/ImageFormat#RAW10
2364*35238bceSAndroid Build Coastguard Worker
2365*35238bceSAndroid Build Coastguard Worker uint32_t firstPixel = (*(src + 0u));
2366*35238bceSAndroid Build Coastguard Worker uint32_t secondPixel = (*(src + 1u));
2367*35238bceSAndroid Build Coastguard Worker uint32_t thirdPixel = (*(src + 2u));
2368*35238bceSAndroid Build Coastguard Worker uint32_t fourthPixel = (*(src + 3u));
2369*35238bceSAndroid Build Coastguard Worker uint32_t packedPixel = (*(src + 4u));
2370*35238bceSAndroid Build Coastguard Worker
2371*35238bceSAndroid Build Coastguard Worker // We now need to take last bits for each pixel from the packed pixel to build all pixel values
2372*35238bceSAndroid Build Coastguard Worker firstPixel = ((firstPixel << 2u) | ((packedPixel >> 0u) & 0b00000011u));
2373*35238bceSAndroid Build Coastguard Worker secondPixel = ((secondPixel << 2u) | ((packedPixel >> 2u) & 0b00000011u));
2374*35238bceSAndroid Build Coastguard Worker thirdPixel = ((thirdPixel << 2u) | ((packedPixel >> 4u) & 0b00000011u));
2375*35238bceSAndroid Build Coastguard Worker fourthPixel = ((fourthPixel << 2u) | ((packedPixel >> 6u) & 0b00000011u));
2376*35238bceSAndroid Build Coastguard Worker
2377*35238bceSAndroid Build Coastguard Worker // Store values in buffer (higher bits is were data is stored)
2378*35238bceSAndroid Build Coastguard Worker uint16_t *pixel = static_cast<uint16_t *>(dst.getDataPtr());
2379*35238bceSAndroid Build Coastguard Worker (*pixel) = static_cast<uint16_t>(firstPixel << 6u);
2380*35238bceSAndroid Build Coastguard Worker
2381*35238bceSAndroid Build Coastguard Worker pixel++;
2382*35238bceSAndroid Build Coastguard Worker (*pixel) = static_cast<uint16_t>(secondPixel << 6u);
2383*35238bceSAndroid Build Coastguard Worker
2384*35238bceSAndroid Build Coastguard Worker pixel++;
2385*35238bceSAndroid Build Coastguard Worker (*pixel) = static_cast<uint16_t>(thirdPixel << 6u);
2386*35238bceSAndroid Build Coastguard Worker
2387*35238bceSAndroid Build Coastguard Worker pixel++;
2388*35238bceSAndroid Build Coastguard Worker (*pixel) = static_cast<uint16_t>(fourthPixel << 6u);
2389*35238bceSAndroid Build Coastguard Worker }
2390*35238bceSAndroid Build Coastguard Worker
decompressAhbRaw12(const PixelBufferAccess & dst,const uint8_t * src)2391*35238bceSAndroid Build Coastguard Worker void decompressAhbRaw12(const PixelBufferAccess &dst, const uint8_t *src)
2392*35238bceSAndroid Build Coastguard Worker {
2393*35238bceSAndroid Build Coastguard Worker // Packed format with 2 pixels in 3 bytes
2394*35238bceSAndroid Build Coastguard Worker // Layout: https://developer.android.com/reference/android/graphics/ImageFormat#RAW12
2395*35238bceSAndroid Build Coastguard Worker
2396*35238bceSAndroid Build Coastguard Worker uint32_t firstPixel = (*(src + 0));
2397*35238bceSAndroid Build Coastguard Worker uint32_t secondPixel = (*(src + 1));
2398*35238bceSAndroid Build Coastguard Worker uint32_t packedPixel = (*(src + 2));
2399*35238bceSAndroid Build Coastguard Worker
2400*35238bceSAndroid Build Coastguard Worker // We now need to take last bits for each pixel from the packed pixel to build all pixel values
2401*35238bceSAndroid Build Coastguard Worker firstPixel = ((firstPixel << 4u) | ((packedPixel >> 0u) & 0b00001111u));
2402*35238bceSAndroid Build Coastguard Worker secondPixel = ((secondPixel << 4u) | ((packedPixel >> 4u) & 0b00001111u));
2403*35238bceSAndroid Build Coastguard Worker
2404*35238bceSAndroid Build Coastguard Worker // Store values in buffer (higher bits is were data is stored)
2405*35238bceSAndroid Build Coastguard Worker uint16_t *pixel = static_cast<uint16_t *>(dst.getDataPtr());
2406*35238bceSAndroid Build Coastguard Worker (*pixel) = static_cast<uint16_t>(firstPixel << 6u);
2407*35238bceSAndroid Build Coastguard Worker
2408*35238bceSAndroid Build Coastguard Worker pixel++;
2409*35238bceSAndroid Build Coastguard Worker (*pixel) = static_cast<uint16_t>(secondPixel << 6u);
2410*35238bceSAndroid Build Coastguard Worker }
2411*35238bceSAndroid Build Coastguard Worker
decompressBlock(CompressedTexFormat format,const PixelBufferAccess & dst,const uint8_t * src,const TexDecompressionParams & params)2412*35238bceSAndroid Build Coastguard Worker void decompressBlock(CompressedTexFormat format, const PixelBufferAccess &dst, const uint8_t *src,
2413*35238bceSAndroid Build Coastguard Worker const TexDecompressionParams ¶ms)
2414*35238bceSAndroid Build Coastguard Worker {
2415*35238bceSAndroid Build Coastguard Worker // No 3D blocks supported right now
2416*35238bceSAndroid Build Coastguard Worker DE_ASSERT(dst.getDepth() == 1);
2417*35238bceSAndroid Build Coastguard Worker
2418*35238bceSAndroid Build Coastguard Worker switch (format)
2419*35238bceSAndroid Build Coastguard Worker {
2420*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC1_RGB8:
2421*35238bceSAndroid Build Coastguard Worker decompressETC1(dst, src);
2422*35238bceSAndroid Build Coastguard Worker break;
2423*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_EAC_R11:
2424*35238bceSAndroid Build Coastguard Worker decompressEAC_R11(dst, src, false);
2425*35238bceSAndroid Build Coastguard Worker break;
2426*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:
2427*35238bceSAndroid Build Coastguard Worker decompressEAC_R11(dst, src, true);
2428*35238bceSAndroid Build Coastguard Worker break;
2429*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_EAC_RG11:
2430*35238bceSAndroid Build Coastguard Worker decompressEAC_RG11(dst, src, false);
2431*35238bceSAndroid Build Coastguard Worker break;
2432*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:
2433*35238bceSAndroid Build Coastguard Worker decompressEAC_RG11(dst, src, true);
2434*35238bceSAndroid Build Coastguard Worker break;
2435*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_RGB8:
2436*35238bceSAndroid Build Coastguard Worker decompressETC2(dst, src);
2437*35238bceSAndroid Build Coastguard Worker break;
2438*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_SRGB8:
2439*35238bceSAndroid Build Coastguard Worker decompressETC2(dst, src);
2440*35238bceSAndroid Build Coastguard Worker break;
2441*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
2442*35238bceSAndroid Build Coastguard Worker decompressETC2_RGB8_PUNCHTHROUGH_ALPHA1(dst, src);
2443*35238bceSAndroid Build Coastguard Worker break;
2444*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
2445*35238bceSAndroid Build Coastguard Worker decompressETC2_RGB8_PUNCHTHROUGH_ALPHA1(dst, src);
2446*35238bceSAndroid Build Coastguard Worker break;
2447*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:
2448*35238bceSAndroid Build Coastguard Worker decompressETC2_EAC_RGBA8(dst, src);
2449*35238bceSAndroid Build Coastguard Worker break;
2450*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:
2451*35238bceSAndroid Build Coastguard Worker decompressETC2_EAC_RGBA8(dst, src);
2452*35238bceSAndroid Build Coastguard Worker break;
2453*35238bceSAndroid Build Coastguard Worker
2454*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA:
2455*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA:
2456*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA:
2457*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA:
2458*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA:
2459*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA:
2460*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA:
2461*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA:
2462*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA:
2463*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA:
2464*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA:
2465*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA:
2466*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA:
2467*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA:
2468*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:
2469*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:
2470*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:
2471*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:
2472*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:
2473*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:
2474*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:
2475*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:
2476*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:
2477*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:
2478*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:
2479*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:
2480*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:
2481*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:
2482*35238bceSAndroid Build Coastguard Worker astc::decompress(dst, src, format, params.astcMode);
2483*35238bceSAndroid Build Coastguard Worker break;
2484*35238bceSAndroid Build Coastguard Worker
2485*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK:
2486*35238bceSAndroid Build Coastguard Worker decompressBc1(dst, src, false);
2487*35238bceSAndroid Build Coastguard Worker break;
2488*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK:
2489*35238bceSAndroid Build Coastguard Worker decompressBc1(dst, src, false);
2490*35238bceSAndroid Build Coastguard Worker break;
2491*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK:
2492*35238bceSAndroid Build Coastguard Worker decompressBc1(dst, src, true);
2493*35238bceSAndroid Build Coastguard Worker break;
2494*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK:
2495*35238bceSAndroid Build Coastguard Worker decompressBc1(dst, src, true);
2496*35238bceSAndroid Build Coastguard Worker break;
2497*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK:
2498*35238bceSAndroid Build Coastguard Worker decompressBc2(dst, src);
2499*35238bceSAndroid Build Coastguard Worker break;
2500*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK:
2501*35238bceSAndroid Build Coastguard Worker decompressBc2(dst, src);
2502*35238bceSAndroid Build Coastguard Worker break;
2503*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK:
2504*35238bceSAndroid Build Coastguard Worker decompressBc3(dst, src);
2505*35238bceSAndroid Build Coastguard Worker break;
2506*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK:
2507*35238bceSAndroid Build Coastguard Worker decompressBc3(dst, src);
2508*35238bceSAndroid Build Coastguard Worker break;
2509*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK:
2510*35238bceSAndroid Build Coastguard Worker decompressBc4(dst, src, false);
2511*35238bceSAndroid Build Coastguard Worker break;
2512*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK:
2513*35238bceSAndroid Build Coastguard Worker decompressBc4(dst, src, true);
2514*35238bceSAndroid Build Coastguard Worker break;
2515*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK:
2516*35238bceSAndroid Build Coastguard Worker decompressBc5(dst, src, false);
2517*35238bceSAndroid Build Coastguard Worker break;
2518*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK:
2519*35238bceSAndroid Build Coastguard Worker decompressBc5(dst, src, true);
2520*35238bceSAndroid Build Coastguard Worker break;
2521*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK:
2522*35238bceSAndroid Build Coastguard Worker decompressBc6H(dst, src, false);
2523*35238bceSAndroid Build Coastguard Worker break;
2524*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK:
2525*35238bceSAndroid Build Coastguard Worker decompressBc6H(dst, src, true);
2526*35238bceSAndroid Build Coastguard Worker break;
2527*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK:
2528*35238bceSAndroid Build Coastguard Worker decompressBc7(dst, src);
2529*35238bceSAndroid Build Coastguard Worker break;
2530*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:
2531*35238bceSAndroid Build Coastguard Worker decompressBc7(dst, src);
2532*35238bceSAndroid Build Coastguard Worker break;
2533*35238bceSAndroid Build Coastguard Worker
2534*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_AHB_RAW10:
2535*35238bceSAndroid Build Coastguard Worker decompressAhbRaw10(dst, src);
2536*35238bceSAndroid Build Coastguard Worker break;
2537*35238bceSAndroid Build Coastguard Worker case COMPRESSEDTEXFORMAT_AHB_RAW12:
2538*35238bceSAndroid Build Coastguard Worker decompressAhbRaw12(dst, src);
2539*35238bceSAndroid Build Coastguard Worker break;
2540*35238bceSAndroid Build Coastguard Worker
2541*35238bceSAndroid Build Coastguard Worker default:
2542*35238bceSAndroid Build Coastguard Worker DE_FATAL("Unexpected format");
2543*35238bceSAndroid Build Coastguard Worker break;
2544*35238bceSAndroid Build Coastguard Worker }
2545*35238bceSAndroid Build Coastguard Worker }
2546*35238bceSAndroid Build Coastguard Worker
componentSum(const IVec3 & vec)2547*35238bceSAndroid Build Coastguard Worker int componentSum(const IVec3 &vec)
2548*35238bceSAndroid Build Coastguard Worker {
2549*35238bceSAndroid Build Coastguard Worker return vec.x() + vec.y() + vec.z();
2550*35238bceSAndroid Build Coastguard Worker }
2551*35238bceSAndroid Build Coastguard Worker
2552*35238bceSAndroid Build Coastguard Worker } // namespace
2553*35238bceSAndroid Build Coastguard Worker
decompress(const PixelBufferAccess & dst,CompressedTexFormat fmt,const uint8_t * src,const TexDecompressionParams & params)2554*35238bceSAndroid Build Coastguard Worker void decompress(const PixelBufferAccess &dst, CompressedTexFormat fmt, const uint8_t *src,
2555*35238bceSAndroid Build Coastguard Worker const TexDecompressionParams ¶ms)
2556*35238bceSAndroid Build Coastguard Worker {
2557*35238bceSAndroid Build Coastguard Worker const int blockSize = getBlockSize(fmt);
2558*35238bceSAndroid Build Coastguard Worker const IVec3 blockPixelSize(getBlockPixelSize(fmt));
2559*35238bceSAndroid Build Coastguard Worker const IVec3 blockCount(deDivRoundUp32(dst.getWidth(), blockPixelSize.x()),
2560*35238bceSAndroid Build Coastguard Worker deDivRoundUp32(dst.getHeight(), blockPixelSize.y()),
2561*35238bceSAndroid Build Coastguard Worker deDivRoundUp32(dst.getDepth(), blockPixelSize.z()));
2562*35238bceSAndroid Build Coastguard Worker const IVec3 blockPitches(blockSize, blockSize * blockCount.x(), blockSize * blockCount.x() * blockCount.y());
2563*35238bceSAndroid Build Coastguard Worker
2564*35238bceSAndroid Build Coastguard Worker std::vector<uint8_t> uncompressedBlock(dst.getFormat().getPixelSize() * blockPixelSize.x() * blockPixelSize.y() *
2565*35238bceSAndroid Build Coastguard Worker blockPixelSize.z());
2566*35238bceSAndroid Build Coastguard Worker const PixelBufferAccess blockAccess(getUncompressedFormat(fmt), blockPixelSize.x(), blockPixelSize.y(),
2567*35238bceSAndroid Build Coastguard Worker blockPixelSize.z(), &uncompressedBlock[0]);
2568*35238bceSAndroid Build Coastguard Worker
2569*35238bceSAndroid Build Coastguard Worker DE_ASSERT(dst.getFormat() == getUncompressedFormat(fmt));
2570*35238bceSAndroid Build Coastguard Worker
2571*35238bceSAndroid Build Coastguard Worker for (int blockZ = 0; blockZ < blockCount.z(); blockZ++)
2572*35238bceSAndroid Build Coastguard Worker for (int blockY = 0; blockY < blockCount.y(); blockY++)
2573*35238bceSAndroid Build Coastguard Worker for (int blockX = 0; blockX < blockCount.x(); blockX++)
2574*35238bceSAndroid Build Coastguard Worker {
2575*35238bceSAndroid Build Coastguard Worker const IVec3 blockPos(blockX, blockY, blockZ);
2576*35238bceSAndroid Build Coastguard Worker const uint8_t *const blockPtr = src + componentSum(blockPos * blockPitches);
2577*35238bceSAndroid Build Coastguard Worker const IVec3 copySize(de::min(blockPixelSize.x(), dst.getWidth() - blockPos.x() * blockPixelSize.x()),
2578*35238bceSAndroid Build Coastguard Worker de::min(blockPixelSize.y(), dst.getHeight() - blockPos.y() * blockPixelSize.y()),
2579*35238bceSAndroid Build Coastguard Worker de::min(blockPixelSize.z(), dst.getDepth() - blockPos.z() * blockPixelSize.z()));
2580*35238bceSAndroid Build Coastguard Worker const IVec3 dstPixelPos = blockPos * blockPixelSize;
2581*35238bceSAndroid Build Coastguard Worker
2582*35238bceSAndroid Build Coastguard Worker decompressBlock(fmt, blockAccess, blockPtr, params);
2583*35238bceSAndroid Build Coastguard Worker
2584*35238bceSAndroid Build Coastguard Worker copy(getSubregion(dst, dstPixelPos.x(), dstPixelPos.y(), dstPixelPos.z(), copySize.x(), copySize.y(),
2585*35238bceSAndroid Build Coastguard Worker copySize.z()),
2586*35238bceSAndroid Build Coastguard Worker getSubregion(blockAccess, 0, 0, 0, copySize.x(), copySize.y(), copySize.z()));
2587*35238bceSAndroid Build Coastguard Worker }
2588*35238bceSAndroid Build Coastguard Worker }
2589*35238bceSAndroid Build Coastguard Worker
CompressedTexture(void)2590*35238bceSAndroid Build Coastguard Worker CompressedTexture::CompressedTexture(void) : m_format(COMPRESSEDTEXFORMAT_LAST), m_width(0), m_height(0), m_depth(0)
2591*35238bceSAndroid Build Coastguard Worker {
2592*35238bceSAndroid Build Coastguard Worker }
2593*35238bceSAndroid Build Coastguard Worker
CompressedTexture(CompressedTexFormat format,int width,int height,int depth)2594*35238bceSAndroid Build Coastguard Worker CompressedTexture::CompressedTexture(CompressedTexFormat format, int width, int height, int depth)
2595*35238bceSAndroid Build Coastguard Worker : m_format(COMPRESSEDTEXFORMAT_LAST)
2596*35238bceSAndroid Build Coastguard Worker , m_width(0)
2597*35238bceSAndroid Build Coastguard Worker , m_height(0)
2598*35238bceSAndroid Build Coastguard Worker , m_depth(0)
2599*35238bceSAndroid Build Coastguard Worker {
2600*35238bceSAndroid Build Coastguard Worker setStorage(format, width, height, depth);
2601*35238bceSAndroid Build Coastguard Worker }
2602*35238bceSAndroid Build Coastguard Worker
~CompressedTexture(void)2603*35238bceSAndroid Build Coastguard Worker CompressedTexture::~CompressedTexture(void)
2604*35238bceSAndroid Build Coastguard Worker {
2605*35238bceSAndroid Build Coastguard Worker }
2606*35238bceSAndroid Build Coastguard Worker
setStorage(CompressedTexFormat format,int width,int height,int depth)2607*35238bceSAndroid Build Coastguard Worker void CompressedTexture::setStorage(CompressedTexFormat format, int width, int height, int depth)
2608*35238bceSAndroid Build Coastguard Worker {
2609*35238bceSAndroid Build Coastguard Worker m_format = format;
2610*35238bceSAndroid Build Coastguard Worker m_width = width;
2611*35238bceSAndroid Build Coastguard Worker m_height = height;
2612*35238bceSAndroid Build Coastguard Worker m_depth = depth;
2613*35238bceSAndroid Build Coastguard Worker
2614*35238bceSAndroid Build Coastguard Worker if (m_format != COMPRESSEDTEXFORMAT_LAST)
2615*35238bceSAndroid Build Coastguard Worker {
2616*35238bceSAndroid Build Coastguard Worker const IVec3 blockPixelSize = getBlockPixelSize(m_format);
2617*35238bceSAndroid Build Coastguard Worker const int blockSize = getBlockSize(m_format);
2618*35238bceSAndroid Build Coastguard Worker
2619*35238bceSAndroid Build Coastguard Worker m_data.resize(deDivRoundUp32(m_width, blockPixelSize.x()) * deDivRoundUp32(m_height, blockPixelSize.y()) *
2620*35238bceSAndroid Build Coastguard Worker deDivRoundUp32(m_depth, blockPixelSize.z()) * blockSize);
2621*35238bceSAndroid Build Coastguard Worker }
2622*35238bceSAndroid Build Coastguard Worker else
2623*35238bceSAndroid Build Coastguard Worker {
2624*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_format == COMPRESSEDTEXFORMAT_LAST);
2625*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_width == 0 && m_height == 0 && m_depth == 0);
2626*35238bceSAndroid Build Coastguard Worker m_data.resize(0);
2627*35238bceSAndroid Build Coastguard Worker }
2628*35238bceSAndroid Build Coastguard Worker }
2629*35238bceSAndroid Build Coastguard Worker
2630*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
2631*35238bceSAndroid Build Coastguard Worker * \brief Decode to uncompressed pixel data
2632*35238bceSAndroid Build Coastguard Worker * \param dst Destination buffer
2633*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
decompress(const PixelBufferAccess & dst,const TexDecompressionParams & params) const2634*35238bceSAndroid Build Coastguard Worker void CompressedTexture::decompress(const PixelBufferAccess &dst, const TexDecompressionParams ¶ms) const
2635*35238bceSAndroid Build Coastguard Worker {
2636*35238bceSAndroid Build Coastguard Worker DE_ASSERT(dst.getWidth() == m_width && dst.getHeight() == m_height && dst.getDepth() == m_depth);
2637*35238bceSAndroid Build Coastguard Worker DE_ASSERT(dst.getFormat() == getUncompressedFormat(m_format));
2638*35238bceSAndroid Build Coastguard Worker
2639*35238bceSAndroid Build Coastguard Worker tcu::decompress(dst, m_format, &m_data[0], params);
2640*35238bceSAndroid Build Coastguard Worker }
2641*35238bceSAndroid Build Coastguard Worker
2642*35238bceSAndroid Build Coastguard Worker } // namespace tcu
2643