• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "ETC_Decoder.hpp"
16 
17 namespace
18 {
clampByte(int value)19 	inline int clampByte(int value)
20 	{
21 		return (value < 0) ? 0 : ((value > 255) ? 255 : value);
22 	}
23 
clampSByte(int value)24 	inline int clampSByte(int value)
25 	{
26 		return (value < -128) ? -128 : ((value > 127) ? 127 : value);
27 	}
28 
29 	struct bgra8
30 	{
31 		unsigned char b;
32 		unsigned char g;
33 		unsigned char r;
34 		unsigned char a;
35 
bgra8__anon2fee71220111::bgra836 		inline bgra8()
37 		{
38 		}
39 
set__anon2fee71220111::bgra840 		inline void set(int red, int green, int blue)
41 		{
42 			r = static_cast<unsigned char>(clampByte(red));
43 			g = static_cast<unsigned char>(clampByte(green));
44 			b = static_cast<unsigned char>(clampByte(blue));
45 		}
46 
set__anon2fee71220111::bgra847 		inline void set(int red, int green, int blue, int alpha)
48 		{
49 			r = static_cast<unsigned char>(clampByte(red));
50 			g = static_cast<unsigned char>(clampByte(green));
51 			b = static_cast<unsigned char>(clampByte(blue));
52 			a = static_cast<unsigned char>(clampByte(alpha));
53 		}
54 
addA__anon2fee71220111::bgra855 		const bgra8& addA(int alpha)
56 		{
57 			a = alpha;
58 			return *this;
59 		}
60 	};
61 
extend_4to8bits(int x)62 	inline int extend_4to8bits(int x)
63 	{
64 		return (x << 4) | x;
65 	}
66 
extend_5to8bits(int x)67 	inline int extend_5to8bits(int x)
68 	{
69 		return (x << 3) | (x >> 2);
70 	}
71 
extend_6to8bits(int x)72 	inline int extend_6to8bits(int x)
73 	{
74 		return (x << 2) | (x >> 4);
75 	}
76 
extend_7to8bits(int x)77 	inline int extend_7to8bits(int x)
78 	{
79 		return (x << 1) | (x >> 6);
80 	}
81 
82 	struct ETC2
83 	{
84 		// Decodes unsigned single or dual channel block to bytes
DecodeBlock__anon2fee71220111::ETC285 		static void DecodeBlock(const ETC2** sources, unsigned char *dest, int nbChannels, int x, int y, int w, int h, int pitch, bool isSigned)
86 		{
87 			if(isSigned)
88 			{
89 				signed char* sDst = reinterpret_cast<signed char*>(dest);
90 				for(int j = 0; j < 4 && (y + j) < h; j++)
91 				{
92 					for(int i = 0; i < 4 && (x + i) < w; i++)
93 					{
94 						for(int c = nbChannels - 1; c >= 0; c--)
95 						{
96 							sDst[i * nbChannels + c] = clampSByte(sources[c]->getSingleChannel(i, j, isSigned));
97 						}
98 					}
99 					sDst += pitch;
100 				}
101 			}
102 			else
103 			{
104 				for(int j = 0; j < 4 && (y + j) < h; j++)
105 				{
106 					for(int i = 0; i < 4 && (x + i) < w; i++)
107 					{
108 						for(int c = nbChannels - 1; c >= 0; c--)
109 						{
110 							dest[i * nbChannels + c] = clampByte(sources[c]->getSingleChannel(i, j, isSigned));
111 						}
112 					}
113 					dest += pitch;
114 				}
115 			}
116 		}
117 
118 		// Decodes RGB block to bgra8
decodeBlock__anon2fee71220111::ETC2119 		void decodeBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, unsigned char alphaValues[4][4], bool punchThroughAlpha) const
120 		{
121 			bool opaqueBit = diffbit;
122 			bool nonOpaquePunchThroughAlpha = punchThroughAlpha && !opaqueBit;
123 
124 			// Select mode
125 			if(diffbit || punchThroughAlpha)
126 			{
127 				int r = (R + dR);
128 				int g = (G + dG);
129 				int b = (B + dB);
130 				if(r < 0 || r > 31)
131 				{
132 					decodeTBlock(dest, x, y, w, h, pitch, alphaValues, nonOpaquePunchThroughAlpha);
133 				}
134 				else if(g < 0 || g > 31)
135 				{
136 					decodeHBlock(dest, x, y, w, h, pitch, alphaValues, nonOpaquePunchThroughAlpha);
137 				}
138 				else if(b < 0 || b > 31)
139 				{
140 					decodePlanarBlock(dest, x, y, w, h, pitch, alphaValues);
141 				}
142 				else
143 				{
144 					decodeDifferentialBlock(dest, x, y, w, h, pitch, alphaValues, nonOpaquePunchThroughAlpha);
145 				}
146 			}
147 			else
148 			{
149 				decodeIndividualBlock(dest, x, y, w, h, pitch, alphaValues, nonOpaquePunchThroughAlpha);
150 			}
151 		}
152 
153 	private:
154 		struct
155 		{
156 			union
157 			{
158 				// Individual, differential, H and T modes
159 				struct
160 				{
161 					union
162 					{
163 						// Individual and differential modes
164 						struct
165 						{
166 							union
167 							{
168 								struct   // Individual colors
169 								{
170 									unsigned char R2 : 4;
171 									unsigned char R1 : 4;
172 									unsigned char G2 : 4;
173 									unsigned char G1 : 4;
174 									unsigned char B2 : 4;
175 									unsigned char B1 : 4;
176 								};
177 
178 								struct   // Differential colors
179 								{
180 									signed char dR : 3;
181 									unsigned char R : 5;
182 									signed char dG : 3;
183 									unsigned char G : 5;
184 									signed char dB : 3;
185 									unsigned char B : 5;
186 								};
187 							};
188 
189 							bool flipbit : 1;
190 							bool diffbit : 1;
191 							unsigned char cw2 : 3;
192 							unsigned char cw1 : 3;
193 						};
194 
195 						// T mode
196 						struct
197 						{
198 							// Byte 1
199 							unsigned char TR1b : 2;
200 							unsigned char TdummyB : 1;
201 							unsigned char TR1a : 2;
202 							unsigned char TdummyA : 3;
203 
204 							// Byte 2
205 							unsigned char TB1 : 4;
206 							unsigned char TG1 : 4;
207 
208 							// Byte 3
209 							unsigned char TG2 : 4;
210 							unsigned char TR2 : 4;
211 
212 							// Byte 4
213 							unsigned char Tdb : 1;
214 							bool Tflipbit : 1;
215 							unsigned char Tda : 2;
216 							unsigned char TB2 : 4;
217 						};
218 
219 						// H mode
220 						struct
221 						{
222 							// Byte 1
223 							unsigned char HG1a : 3;
224 							unsigned char HR1 : 4;
225 							unsigned char HdummyA : 1;
226 
227 							// Byte 2
228 							unsigned char HB1b : 2;
229 							unsigned char HdummyC : 1;
230 							unsigned char HB1a : 1;
231 							unsigned char HG1b : 1;
232 							unsigned char HdummyB : 3;
233 
234 							// Byte 3
235 							unsigned char HG2a : 3;
236 							unsigned char HR2 : 4;
237 							unsigned char HB1c : 1;
238 
239 							// Byte 4
240 							unsigned char Hdb : 1;
241 							bool Hflipbit : 1;
242 							unsigned char Hda : 1;
243 							unsigned char HB2 : 4;
244 							unsigned char HG2b : 1;
245 						};
246 					};
247 
248 					unsigned char pixelIndexMSB[2];
249 					unsigned char pixelIndexLSB[2];
250 				};
251 
252 				// planar mode
253 				struct
254 				{
255 					// Byte 1
256 					unsigned char GO1 : 1;
257 					unsigned char RO : 6;
258 					unsigned char PdummyA : 1;
259 
260 					// Byte 2
261 					unsigned char BO1 : 1;
262 					unsigned char GO2 : 6;
263 					unsigned char PdummyB : 1;
264 
265 					// Byte 3
266 					unsigned char BO3a : 2;
267 					unsigned char PdummyD : 1;
268 					unsigned char BO2 : 2;
269 					unsigned char PdummyC : 3;
270 
271 					// Byte 4
272 					unsigned char RH2 : 1;
273 					bool Pflipbit : 1;
274 					unsigned char RH1 : 5;
275 					unsigned char BO3b : 1;
276 
277 					// Byte 5
278 					unsigned char BHa : 1;
279 					unsigned char GH : 7;
280 
281 					// Byte 6
282 					unsigned char RVa : 3;
283 					unsigned char BHb : 5;
284 
285 					// Byte 7
286 					unsigned char GVa : 5;
287 					unsigned char RVb : 3;
288 
289 					// Byte 8
290 					unsigned char BV : 6;
291 					unsigned char GVb : 2;
292 				};
293 
294 				// Single channel block
295 				struct
296 				{
297 					union
298 					{
299 						unsigned char base_codeword;
300 						signed char signed_base_codeword;
301 					};
302 
303 					unsigned char table_index : 4;
304 					unsigned char multiplier : 4;
305 
306 					unsigned char mc1 : 2;
307 					unsigned char mb : 3;
308 					unsigned char ma : 3;
309 
310 					unsigned char mf1 : 1;
311 					unsigned char me : 3;
312 					unsigned char md : 3;
313 					unsigned char mc2 : 1;
314 
315 					unsigned char mh : 3;
316 					unsigned char mg : 3;
317 					unsigned char mf2 : 2;
318 
319 					unsigned char mk1 : 2;
320 					unsigned char mj : 3;
321 					unsigned char mi : 3;
322 
323 					unsigned char mn1 : 1;
324 					unsigned char mm : 3;
325 					unsigned char ml : 3;
326 					unsigned char mk2 : 1;
327 
328 					unsigned char mp : 3;
329 					unsigned char mo : 3;
330 					unsigned char mn2 : 2;
331 				};
332 			};
333 		};
334 
decodeIndividualBlock__anon2fee71220111::ETC2335 		void decodeIndividualBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, unsigned char alphaValues[4][4], bool nonOpaquePunchThroughAlpha) const
336 		{
337 			int r1 = extend_4to8bits(R1);
338 			int g1 = extend_4to8bits(G1);
339 			int b1 = extend_4to8bits(B1);
340 
341 			int r2 = extend_4to8bits(R2);
342 			int g2 = extend_4to8bits(G2);
343 			int b2 = extend_4to8bits(B2);
344 
345 			decodeIndividualOrDifferentialBlock(dest, x, y, w, h, pitch, r1, g1, b1, r2, g2, b2, alphaValues, nonOpaquePunchThroughAlpha);
346 		}
347 
decodeDifferentialBlock__anon2fee71220111::ETC2348 		void decodeDifferentialBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, unsigned char alphaValues[4][4], bool nonOpaquePunchThroughAlpha) const
349 		{
350 			int b1 = extend_5to8bits(B);
351 			int g1 = extend_5to8bits(G);
352 			int r1 = extend_5to8bits(R);
353 
354 			int r2 = extend_5to8bits(R + dR);
355 			int g2 = extend_5to8bits(G + dG);
356 			int b2 = extend_5to8bits(B + dB);
357 
358 			decodeIndividualOrDifferentialBlock(dest, x, y, w, h, pitch, r1, g1, b1, r2, g2, b2, alphaValues, nonOpaquePunchThroughAlpha);
359 		}
360 
decodeIndividualOrDifferentialBlock__anon2fee71220111::ETC2361 		void decodeIndividualOrDifferentialBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, int r1, int g1, int b1, int r2, int g2, int b2, unsigned char alphaValues[4][4], bool nonOpaquePunchThroughAlpha) const
362 		{
363 			// Table 3.17.2 sorted according to table 3.17.3
364 			static const int intensityModifierDefault[8][4] =
365 			{
366 				{ 2, 8, -2, -8 },
367 				{ 5, 17, -5, -17 },
368 				{ 9, 29, -9, -29 },
369 				{ 13, 42, -13, -42 },
370 				{ 18, 60, -18, -60 },
371 				{ 24, 80, -24, -80 },
372 				{ 33, 106, -33, -106 },
373 				{ 47, 183, -47, -183 }
374 			};
375 
376 			// Table C.12, intensity modifier for non opaque punchthrough alpha
377 			static const int intensityModifierNonOpaque[8][4] =
378 			{
379 				{ 0, 8, 0, -8 },
380 				{ 0, 17, 0, -17 },
381 				{ 0, 29, 0, -29 },
382 				{ 0, 42, 0, -42 },
383 				{ 0, 60, 0, -60 },
384 				{ 0, 80, 0, -80 },
385 				{ 0, 106, 0, -106 },
386 				{ 0, 183, 0, -183 }
387 			};
388 
389 			const int(&intensityModifier)[8][4] = nonOpaquePunchThroughAlpha ? intensityModifierNonOpaque : intensityModifierDefault;
390 
391 			bgra8 subblockColors0[4];
392 			bgra8 subblockColors1[4];
393 
394 			const int i10 = intensityModifier[cw1][0];
395 			const int i11 = intensityModifier[cw1][1];
396 			const int i12 = intensityModifier[cw1][2];
397 			const int i13 = intensityModifier[cw1][3];
398 
399 			subblockColors0[0].set(r1 + i10, g1 + i10, b1 + i10);
400 			subblockColors0[1].set(r1 + i11, g1 + i11, b1 + i11);
401 			subblockColors0[2].set(r1 + i12, g1 + i12, b1 + i12);
402 			subblockColors0[3].set(r1 + i13, g1 + i13, b1 + i13);
403 
404 			const int i20 = intensityModifier[cw2][0];
405 			const int i21 = intensityModifier[cw2][1];
406 			const int i22 = intensityModifier[cw2][2];
407 			const int i23 = intensityModifier[cw2][3];
408 
409 			subblockColors1[0].set(r2 + i20, g2 + i20, b2 + i20);
410 			subblockColors1[1].set(r2 + i21, g2 + i21, b2 + i21);
411 			subblockColors1[2].set(r2 + i22, g2 + i22, b2 + i22);
412 			subblockColors1[3].set(r2 + i23, g2 + i23, b2 + i23);
413 
414 			unsigned char* destStart = dest;
415 
416 			if(flipbit)
417 			{
418 				for(int j = 0; j < 2 && (y + j) < h; j++)
419 				{
420 					bgra8* color = (bgra8*)dest;
421 					if((x + 0) < w) color[0] = subblockColors0[getIndex(0, j)].addA(alphaValues[j][0]);
422 					if((x + 1) < w) color[1] = subblockColors0[getIndex(1, j)].addA(alphaValues[j][1]);
423 					if((x + 2) < w) color[2] = subblockColors0[getIndex(2, j)].addA(alphaValues[j][2]);
424 					if((x + 3) < w) color[3] = subblockColors0[getIndex(3, j)].addA(alphaValues[j][3]);
425 					dest += pitch;
426 				}
427 
428 				for(int j = 2; j < 4 && (y + j) < h; j++)
429 				{
430 					bgra8* color = (bgra8*)dest;
431 					if((x + 0) < w) color[0] = subblockColors1[getIndex(0, j)].addA(alphaValues[j][0]);
432 					if((x + 1) < w) color[1] = subblockColors1[getIndex(1, j)].addA(alphaValues[j][1]);
433 					if((x + 2) < w) color[2] = subblockColors1[getIndex(2, j)].addA(alphaValues[j][2]);
434 					if((x + 3) < w) color[3] = subblockColors1[getIndex(3, j)].addA(alphaValues[j][3]);
435 					dest += pitch;
436 				}
437 			}
438 			else
439 			{
440 				for(int j = 0; j < 4 && (y + j) < h; j++)
441 				{
442 					bgra8* color = (bgra8*)dest;
443 					if((x + 0) < w) color[0] = subblockColors0[getIndex(0, j)].addA(alphaValues[j][0]);
444 					if((x + 1) < w) color[1] = subblockColors0[getIndex(1, j)].addA(alphaValues[j][1]);
445 					if((x + 2) < w) color[2] = subblockColors1[getIndex(2, j)].addA(alphaValues[j][2]);
446 					if((x + 3) < w) color[3] = subblockColors1[getIndex(3, j)].addA(alphaValues[j][3]);
447 					dest += pitch;
448 				}
449 			}
450 
451 			if(nonOpaquePunchThroughAlpha)
452 			{
453 				decodePunchThroughAlphaBlock(destStart, x, y, w, h, pitch);
454 			}
455 		}
456 
decodeTBlock__anon2fee71220111::ETC2457 		void decodeTBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, unsigned char alphaValues[4][4], bool nonOpaquePunchThroughAlpha) const
458 		{
459 			// Table C.8, distance index fot T and H modes
460 			static const int distance[8] = { 3, 6, 11, 16, 23, 32, 41, 64 };
461 
462 			bgra8 paintColors[4];
463 
464 			int r1 = extend_4to8bits(TR1a << 2 | TR1b);
465 			int g1 = extend_4to8bits(TG1);
466 			int b1 = extend_4to8bits(TB1);
467 
468 			int r2 = extend_4to8bits(TR2);
469 			int g2 = extend_4to8bits(TG2);
470 			int b2 = extend_4to8bits(TB2);
471 
472 			const int d = distance[Tda << 1 | Tdb];
473 
474 			paintColors[0].set(r1, g1, b1);
475 			paintColors[1].set(r2 + d, g2 + d, b2 + d);
476 			paintColors[2].set(r2, g2, b2);
477 			paintColors[3].set(r2 - d, g2 - d, b2 - d);
478 
479 			unsigned char* destStart = dest;
480 
481 			for(int j = 0; j < 4 && (y + j) < h; j++)
482 			{
483 				bgra8* color = (bgra8*)dest;
484 				if((x + 0) < w) color[0] = paintColors[getIndex(0, j)].addA(alphaValues[j][0]);
485 				if((x + 1) < w) color[1] = paintColors[getIndex(1, j)].addA(alphaValues[j][1]);
486 				if((x + 2) < w) color[2] = paintColors[getIndex(2, j)].addA(alphaValues[j][2]);
487 				if((x + 3) < w) color[3] = paintColors[getIndex(3, j)].addA(alphaValues[j][3]);
488 				dest += pitch;
489 			}
490 
491 			if(nonOpaquePunchThroughAlpha)
492 			{
493 				decodePunchThroughAlphaBlock(destStart, x, y, w, h, pitch);
494 			}
495 		}
496 
decodeHBlock__anon2fee71220111::ETC2497 		void decodeHBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, unsigned char alphaValues[4][4], bool nonOpaquePunchThroughAlpha) const
498 		{
499 			// Table C.8, distance index fot T and H modes
500 			static const int distance[8] = { 3, 6, 11, 16, 23, 32, 41, 64 };
501 
502 			bgra8 paintColors[4];
503 
504 			int r1 = extend_4to8bits(HR1);
505 			int g1 = extend_4to8bits(HG1a << 1 | HG1b);
506 			int b1 = extend_4to8bits(HB1a << 3 | HB1b << 1 | HB1c);
507 
508 			int r2 = extend_4to8bits(HR2);
509 			int g2 = extend_4to8bits(HG2a << 1 | HG2b);
510 			int b2 = extend_4to8bits(HB2);
511 
512 			const int d = distance[(Hda << 2) | (Hdb << 1) | ((r1 << 16 | g1 << 8 | b1) >= (r2 << 16 | g2 << 8 | b2) ? 1 : 0)];
513 
514 			paintColors[0].set(r1 + d, g1 + d, b1 + d);
515 			paintColors[1].set(r1 - d, g1 - d, b1 - d);
516 			paintColors[2].set(r2 + d, g2 + d, b2 + d);
517 			paintColors[3].set(r2 - d, g2 - d, b2 - d);
518 
519 			unsigned char* destStart = dest;
520 
521 			for(int j = 0; j < 4 && (y + j) < h; j++)
522 			{
523 				bgra8* color = (bgra8*)dest;
524 				if((x + 0) < w) color[0] = paintColors[getIndex(0, j)].addA(alphaValues[j][0]);
525 				if((x + 1) < w) color[1] = paintColors[getIndex(1, j)].addA(alphaValues[j][1]);
526 				if((x + 2) < w) color[2] = paintColors[getIndex(2, j)].addA(alphaValues[j][2]);
527 				if((x + 3) < w) color[3] = paintColors[getIndex(3, j)].addA(alphaValues[j][3]);
528 				dest += pitch;
529 			}
530 
531 			if(nonOpaquePunchThroughAlpha)
532 			{
533 				decodePunchThroughAlphaBlock(destStart, x, y, w, h, pitch);
534 			}
535 		}
536 
decodePlanarBlock__anon2fee71220111::ETC2537 		void decodePlanarBlock(unsigned char *dest, int x, int y, int w, int h, int pitch, unsigned char alphaValues[4][4]) const
538 		{
539 			int ro = extend_6to8bits(RO);
540 			int go = extend_7to8bits(GO1 << 6 | GO2);
541 			int bo = extend_6to8bits(BO1 << 5 | BO2 << 3 | BO3a << 1 | BO3b);
542 
543 			int rh = extend_6to8bits(RH1 << 1 | RH2);
544 			int gh = extend_7to8bits(GH);
545 			int bh = extend_6to8bits(BHa << 5 | BHb);
546 
547 			int rv = extend_6to8bits(RVa << 3 | RVb);
548 			int gv = extend_7to8bits(GVa << 2 | GVb);
549 			int bv = extend_6to8bits(BV);
550 
551 			for(int j = 0; j < 4 && (y + j) < h; j++)
552 			{
553 				int ry = j * (rv - ro) + 2;
554 				int gy = j * (gv - go) + 2;
555 				int by = j * (bv - bo) + 2;
556 				for(int i = 0; i < 4 && (x + i) < w; i++)
557 				{
558 					((bgra8*)(dest))[i].set(((i * (rh - ro) + ry) >> 2) + ro,
559 						((i * (gh - go) + gy) >> 2) + go,
560 						((i * (bh - bo) + by) >> 2) + bo,
561 						alphaValues[j][i]);
562 				}
563 				dest += pitch;
564 			}
565 		}
566 
567 		// Index for individual, differential, H and T modes
getIndex__anon2fee71220111::ETC2568 		inline int getIndex(int x, int y) const
569 		{
570 			int bitIndex = x * 4 + y;
571 			int bitOffset = bitIndex & 7;
572 			int lsb = (pixelIndexLSB[1 - (bitIndex >> 3)] >> bitOffset) & 1;
573 			int msb = (pixelIndexMSB[1 - (bitIndex >> 3)] >> bitOffset) & 1;
574 
575 			return (msb << 1) | lsb;
576 		}
577 
decodePunchThroughAlphaBlock__anon2fee71220111::ETC2578 		void decodePunchThroughAlphaBlock(unsigned char *dest, int x, int y, int w, int h, int pitch) const
579 		{
580 			for(int j = 0; j < 4 && (y + j) < h; j++)
581 			{
582 				for(int i = 0; i < 4 && (x + i) < w; i++)
583 				{
584 					if(getIndex(i, j) == 2) //  msb == 1 && lsb == 0
585 					{
586 						((bgra8*)dest)[i].set(0, 0, 0, 0);
587 					}
588 				}
589 				dest += pitch;
590 			}
591 		}
592 
593 		// Single channel utility functions
getSingleChannel__anon2fee71220111::ETC2594 		inline int getSingleChannel(int x, int y, bool isSigned) const
595 		{
596 			int codeword = isSigned ? signed_base_codeword : base_codeword;
597 			return codeword + getSingleChannelModifier(x, y) * multiplier;
598 		}
599 
getSingleChannelIndex__anon2fee71220111::ETC2600 		inline int getSingleChannelIndex(int x, int y) const
601 		{
602 			switch(x * 4 + y)
603 			{
604 			case 0: return ma;
605 			case 1: return mb;
606 			case 2: return mc1 << 1 | mc2;
607 			case 3: return md;
608 			case 4: return me;
609 			case 5: return mf1 << 2 | mf2;
610 			case 6: return mg;
611 			case 7: return mh;
612 			case 8: return mi;
613 			case 9: return mj;
614 			case 10: return mk1 << 1 | mk2;
615 			case 11: return ml;
616 			case 12: return mm;
617 			case 13: return mn1 << 2 | mn2;
618 			case 14: return mo;
619 			default: return mp; // 15
620 			}
621 		}
622 
getSingleChannelModifier__anon2fee71220111::ETC2623 		inline int getSingleChannelModifier(int x, int y) const
624 		{
625 			static const int modifierTable[16][8] = { { -3, -6, -9, -15, 2, 5, 8, 14 },
626 			{ -3, -7, -10, -13, 2, 6, 9, 12 },
627 			{ -2, -5, -8, -13, 1, 4, 7, 12 },
628 			{ -2, -4, -6, -13, 1, 3, 5, 12 },
629 			{ -3, -6, -8, -12, 2, 5, 7, 11 },
630 			{ -3, -7, -9, -11, 2, 6, 8, 10 },
631 			{ -4, -7, -8, -11, 3, 6, 7, 10 },
632 			{ -3, -5, -8, -11, 2, 4, 7, 10 },
633 			{ -2, -6, -8, -10, 1, 5, 7, 9 },
634 			{ -2, -5, -8, -10, 1, 4, 7, 9 },
635 			{ -2, -4, -8, -10, 1, 3, 7, 9 },
636 			{ -2, -5, -7, -10, 1, 4, 6, 9 },
637 			{ -3, -4, -7, -10, 2, 3, 6, 9 },
638 			{ -1, -2, -3, -10, 0, 1, 2, 9 },
639 			{ -4, -6, -8, -9, 3, 5, 7, 8 },
640 			{ -3, -5, -7, -9, 2, 4, 6, 8 } };
641 
642 			return modifierTable[table_index][getSingleChannelIndex(x, y)];
643 		}
644 	};
645 }
646 
647 // Decodes 1 to 4 channel images to 8 bit output
Decode(const unsigned char * src,unsigned char * dst,int w,int h,int dstW,int dstH,int dstPitch,int dstBpp,InputType inputType)648 bool ETC_Decoder::Decode(const unsigned char* src, unsigned char *dst, int w, int h, int dstW, int dstH, int dstPitch, int dstBpp, InputType inputType)
649 {
650 	const ETC2* sources[2];
651 	sources[0] = (const ETC2*)src;
652 
653 	unsigned char alphaValues[4][4] = { { 255, 255, 255, 255 }, { 255, 255, 255, 255 }, { 255, 255, 255, 255 }, { 255, 255, 255, 255 } };
654 
655 	switch(inputType)
656 	{
657 	case ETC_R_SIGNED:
658 	case ETC_R_UNSIGNED:
659 		for(int y = 0; y < h; y += 4)
660 		{
661 			unsigned char *dstRow = dst + (y * dstPitch);
662 			for(int x = 0; x < w; x += 4, sources[0]++)
663 			{
664 				ETC2::DecodeBlock(sources, dstRow + (x * dstBpp), 1, x, y, dstW, dstH, dstPitch, inputType == ETC_R_SIGNED);
665 			}
666 		}
667 		break;
668 	case ETC_RG_SIGNED:
669 	case ETC_RG_UNSIGNED:
670 		sources[1] = sources[0] + 1;
671 		for(int y = 0; y < h; y += 4)
672 		{
673 			unsigned char *dstRow = dst + (y * dstPitch);
674 			for(int x = 0; x < w; x += 4, sources[0] += 2, sources[1] += 2)
675 			{
676 				ETC2::DecodeBlock(sources, dstRow + (x * dstBpp), 2, x, y, dstW, dstH, dstPitch, inputType == ETC_RG_SIGNED);
677 			}
678 		}
679 		break;
680 	case ETC_RGB:
681 	case ETC_RGB_PUNCHTHROUGH_ALPHA:
682 		for(int y = 0; y < h; y += 4)
683 		{
684 			unsigned char *dstRow = dst + (y * dstPitch);
685 			for(int x = 0; x < w; x += 4, sources[0]++)
686 			{
687 				sources[0]->decodeBlock(dstRow + (x * dstBpp), x, y, dstW, dstH, dstPitch, alphaValues, inputType == ETC_RGB_PUNCHTHROUGH_ALPHA);
688 			}
689 		}
690 		break;
691 	case ETC_RGBA:
692 		for(int y = 0; y < h; y += 4)
693 		{
694 			unsigned char *dstRow = dst + (y * dstPitch);
695 			for(int x = 0; x < w; x += 4)
696 			{
697 				// Decode Alpha
698 				ETC2::DecodeBlock(&sources[0], &(alphaValues[0][0]), 1, x, y, dstW, dstH, 4, false);
699 				sources[0]++; // RGBA packets are 128 bits, so move on to the next 64 bit packet to decode the RGB color
700 
701 				// Decode RGB
702 				sources[0]->decodeBlock(dstRow + (x * dstBpp), x, y, dstW, dstH, dstPitch, alphaValues, false);
703 				sources[0]++;
704 			}
705 		}
706 		break;
707 	default:
708 		return false;
709 	}
710 
711 	return true;
712 }
713