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