1 // SPDX-License-Identifier: Apache-2.0
2 // ----------------------------------------------------------------------------
3 // Copyright 2011-2020 Arm Limited
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
6 // use this file except in compliance with the License. You may obtain a copy
7 // of the License at:
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 // License for the specific language governing permissions and limitations
15 // under the License.
16 // ----------------------------------------------------------------------------
17 
18 /**
19  * @brief Functions for color unquantization.
20  */
21 
22 #include "astc_codec_internals.h"
23 
24 #include <cassert>
25 
rgb_delta_unpack(const int input[6],int quantization_level,uint4 * output0,uint4 * output1)26 static int rgb_delta_unpack(
27 	const int input[6],
28 	int quantization_level,
29 	uint4* output0,
30 	uint4* output1
31 ) {
32 	// unquantize the color endpoints
33 	int r0 = color_unquantization_tables[quantization_level][input[0]];
34 	int g0 = color_unquantization_tables[quantization_level][input[2]];
35 	int b0 = color_unquantization_tables[quantization_level][input[4]];
36 
37 	int r1 = color_unquantization_tables[quantization_level][input[1]];
38 	int g1 = color_unquantization_tables[quantization_level][input[3]];
39 	int b1 = color_unquantization_tables[quantization_level][input[5]];
40 
41 	// perform the bit-transfer procedure
42 	r0 |= (r1 & 0x80) << 1;
43 	g0 |= (g1 & 0x80) << 1;
44 	b0 |= (b1 & 0x80) << 1;
45 	r1 &= 0x7F;
46 	g1 &= 0x7F;
47 	b1 &= 0x7F;
48 	if (r1 & 0x40)
49 		r1 -= 0x80;
50 	if (g1 & 0x40)
51 		g1 -= 0x80;
52 	if (b1 & 0x40)
53 		b1 -= 0x80;
54 
55 	r0 >>= 1;
56 	g0 >>= 1;
57 	b0 >>= 1;
58 	r1 >>= 1;
59 	g1 >>= 1;
60 	b1 >>= 1;
61 
62 	int rgbsum = r1 + g1 + b1;
63 
64 	r1 += r0;
65 	g1 += g0;
66 	b1 += b0;
67 
68 	int retval;
69 
70 	int r0e, g0e, b0e;
71 	int r1e, g1e, b1e;
72 
73 	if (rgbsum >= 0)
74 	{
75 		r0e = r0;
76 		g0e = g0;
77 		b0e = b0;
78 
79 		r1e = r1;
80 		g1e = g1;
81 		b1e = b1;
82 
83 		retval = 0;
84 	}
85 	else
86 	{
87 		r0e = (r1 + b1) >> 1;
88 		g0e = (g1 + b1) >> 1;
89 		b0e = b1;
90 
91 		r1e = (r0 + b0) >> 1;
92 		g1e = (g0 + b0) >> 1;
93 		b1e = b0;
94 
95 		retval = 1;
96 	}
97 
98 	if (r0e < 0)
99 		r0e = 0;
100 	else if (r0e > 255)
101 		r0e = 255;
102 
103 	if (g0e < 0)
104 		g0e = 0;
105 	else if (g0e > 255)
106 		g0e = 255;
107 
108 	if (b0e < 0)
109 		b0e = 0;
110 	else if (b0e > 255)
111 		b0e = 255;
112 
113 	if (r1e < 0)
114 		r1e = 0;
115 	else if (r1e > 255)
116 		r1e = 255;
117 
118 	if (g1e < 0)
119 		g1e = 0;
120 	else if (g1e > 255)
121 		g1e = 255;
122 
123 	if (b1e < 0)
124 		b1e = 0;
125 	else if (b1e > 255)
126 		b1e = 255;
127 
128 	output0->x = r0e;
129 	output0->y = g0e;
130 	output0->z = b0e;
131 	output0->w = 0xFF;
132 
133 	output1->x = r1e;
134 	output1->y = g1e;
135 	output1->z = b1e;
136 	output1->w = 0xFF;
137 
138 	return retval;
139 }
140 
rgb_unpack(const int input[6],int quantization_level,uint4 * output0,uint4 * output1)141 static int rgb_unpack(
142 	const int input[6],
143 	int quantization_level,
144 	uint4* output0,
145 	uint4* output1
146 ) {
147 	int ri0b = color_unquantization_tables[quantization_level][input[0]];
148 	int ri1b = color_unquantization_tables[quantization_level][input[1]];
149 	int gi0b = color_unquantization_tables[quantization_level][input[2]];
150 	int gi1b = color_unquantization_tables[quantization_level][input[3]];
151 	int bi0b = color_unquantization_tables[quantization_level][input[4]];
152 	int bi1b = color_unquantization_tables[quantization_level][input[5]];
153 
154 	if (ri0b + gi0b + bi0b > ri1b + gi1b + bi1b)
155 	{
156 		// blue-contraction
157 		ri0b = (ri0b + bi0b) >> 1;
158 		gi0b = (gi0b + bi0b) >> 1;
159 		ri1b = (ri1b + bi1b) >> 1;
160 		gi1b = (gi1b + bi1b) >> 1;
161 
162 		output0->x = ri1b;
163 		output0->y = gi1b;
164 		output0->z = bi1b;
165 		output0->w = 255;
166 
167 		output1->x = ri0b;
168 		output1->y = gi0b;
169 		output1->z = bi0b;
170 		output1->w = 255;
171 		return 1;
172 	}
173 	else
174 	{
175 		output0->x = ri0b;
176 		output0->y = gi0b;
177 		output0->z = bi0b;
178 		output0->w = 255;
179 
180 		output1->x = ri1b;
181 		output1->y = gi1b;
182 		output1->z = bi1b;
183 		output1->w = 255;
184 		return 0;
185 	}
186 }
187 
rgba_unpack(const int input[8],int quantization_level,uint4 * output0,uint4 * output1)188 static void rgba_unpack(
189 	const int input[8],
190 	int quantization_level,
191 	uint4* output0,
192 	uint4* output1
193 ) {
194 	int order = rgb_unpack(input, quantization_level, output0, output1);
195 	if (order == 0)
196 	{
197 		output0->w = color_unquantization_tables[quantization_level][input[6]];
198 		output1->w = color_unquantization_tables[quantization_level][input[7]];
199 	}
200 	else
201 	{
202 		output0->w = color_unquantization_tables[quantization_level][input[7]];
203 		output1->w = color_unquantization_tables[quantization_level][input[6]];
204 	}
205 }
206 
rgba_delta_unpack(const int input[8],int quantization_level,uint4 * output0,uint4 * output1)207 static void rgba_delta_unpack(
208 	const int input[8],
209 	int quantization_level,
210 	uint4* output0,
211 	uint4* output1
212 ) {
213 	int a0 = color_unquantization_tables[quantization_level][input[6]];
214 	int a1 = color_unquantization_tables[quantization_level][input[7]];
215 	a0 |= (a1 & 0x80) << 1;
216 	a1 &= 0x7F;
217 	if (a1 & 0x40)
218 		a1 -= 0x80;
219 	a0 >>= 1;
220 	a1 >>= 1;
221 	a1 += a0;
222 
223 	if (a1 < 0)
224 		a1 = 0;
225 	else if (a1 > 255)
226 		a1 = 255;
227 
228 	int order = rgb_delta_unpack(input, quantization_level, output0, output1);
229 	if (order == 0)
230 	{
231 		output0->w = a0;
232 		output1->w = a1;
233 	}
234 	else
235 	{
236 		output0->w = a1;
237 		output1->w = a0;
238 	}
239 }
240 
rgb_scale_unpack(const int input[4],int quantization_level,uint4 * output0,uint4 * output1)241 static void rgb_scale_unpack(
242 	const int input[4],
243 	int quantization_level,
244 	uint4* output0,
245 	uint4* output1
246 ) {
247 	int ir = color_unquantization_tables[quantization_level][input[0]];
248 	int ig = color_unquantization_tables[quantization_level][input[1]];
249 	int ib = color_unquantization_tables[quantization_level][input[2]];
250 
251 	int iscale = color_unquantization_tables[quantization_level][input[3]];
252 
253 	*output1 = uint4(ir, ig, ib, 255);
254 	*output0 = uint4((ir * iscale) >> 8, (ig * iscale) >> 8, (ib * iscale) >> 8, 255);
255 }
256 
rgb_scale_alpha_unpack(const int input[6],int quantization_level,uint4 * output0,uint4 * output1)257 static void rgb_scale_alpha_unpack(
258 	const int input[6],
259 	int quantization_level,
260 	uint4 * output0,
261 	uint4 * output1
262 ) {
263 	rgb_scale_unpack(input, quantization_level, output0, output1);
264 	output0->w = color_unquantization_tables[quantization_level][input[4]];
265 	output1->w = color_unquantization_tables[quantization_level][input[5]];
266 }
267 
luminance_unpack(const int input[2],int quantization_level,uint4 * output0,uint4 * output1)268 static void luminance_unpack(
269 	const int input[2],
270 	int quantization_level,
271 	uint4* output0,
272 	uint4* output1
273 ) {
274 	int lum0 = color_unquantization_tables[quantization_level][input[0]];
275 	int lum1 = color_unquantization_tables[quantization_level][input[1]];
276 	*output0 = uint4(lum0, lum0, lum0, 255);
277 	*output1 = uint4(lum1, lum1, lum1, 255);
278 }
279 
luminance_delta_unpack(const int input[2],int quantization_level,uint4 * output0,uint4 * output1)280 static void luminance_delta_unpack(
281 	const int input[2],
282 	int quantization_level,
283 	uint4* output0,
284 	uint4* output1
285 ) {
286 	int v0 = color_unquantization_tables[quantization_level][input[0]];
287 	int v1 = color_unquantization_tables[quantization_level][input[1]];
288 	int l0 = (v0 >> 2) | (v1 & 0xC0);
289 	int l1 = l0 + (v1 & 0x3F);
290 
291 	if (l1 > 255)
292 		l1 = 255;
293 
294 	*output0 = uint4(l0, l0, l0, 255);
295 	*output1 = uint4(l1, l1, l1, 255);
296 }
297 
luminance_alpha_unpack(const int input[4],int quantization_level,uint4 * output0,uint4 * output1)298 static void luminance_alpha_unpack(
299 	const int input[4],
300 	int quantization_level,
301 	uint4* output0,
302 	uint4* output1
303 ) {
304 	int lum0 = color_unquantization_tables[quantization_level][input[0]];
305 	int lum1 = color_unquantization_tables[quantization_level][input[1]];
306 	int alpha0 = color_unquantization_tables[quantization_level][input[2]];
307 	int alpha1 = color_unquantization_tables[quantization_level][input[3]];
308 	*output0 = uint4(lum0, lum0, lum0, alpha0);
309 	*output1 = uint4(lum1, lum1, lum1, alpha1);
310 }
311 
luminance_alpha_delta_unpack(const int input[4],int quantization_level,uint4 * output0,uint4 * output1)312 static void luminance_alpha_delta_unpack(
313 	const int input[4],
314 	int quantization_level,
315 	uint4* output0,
316 	uint4* output1
317 ) {
318 	int lum0 = color_unquantization_tables[quantization_level][input[0]];
319 	int lum1 = color_unquantization_tables[quantization_level][input[1]];
320 	int alpha0 = color_unquantization_tables[quantization_level][input[2]];
321 	int alpha1 = color_unquantization_tables[quantization_level][input[3]];
322 
323 	lum0 |= (lum1 & 0x80) << 1;
324 	alpha0 |= (alpha1 & 0x80) << 1;
325 	lum1 &= 0x7F;
326 	alpha1 &= 0x7F;
327 	if (lum1 & 0x40)
328 		lum1 -= 0x80;
329 	if (alpha1 & 0x40)
330 		alpha1 -= 0x80;
331 
332 	lum0 >>= 1;
333 	lum1 >>= 1;
334 	alpha0 >>= 1;
335 	alpha1 >>= 1;
336 	lum1 += lum0;
337 	alpha1 += alpha0;
338 
339 	if (lum1 < 0)
340 		lum1 = 0;
341 	else if (lum1 > 255)
342 		lum1 = 255;
343 
344 	if (alpha1 < 0)
345 		alpha1 = 0;
346 	else if (alpha1 > 255)
347 		alpha1 = 255;
348 
349 	*output0 = uint4(lum0, lum0, lum0, alpha0);
350 	*output1 = uint4(lum1, lum1, lum1, alpha1);
351 }
352 
353 // RGB-offset format
hdr_rgbo_unpack3(const int input[4],int quantization_level,uint4 * output0,uint4 * output1)354 static void hdr_rgbo_unpack3(
355 	const int input[4],
356 	int quantization_level,
357 	uint4* output0,
358 	uint4* output1
359 ) {
360 	int v0 = color_unquantization_tables[quantization_level][input[0]];
361 	int v1 = color_unquantization_tables[quantization_level][input[1]];
362 	int v2 = color_unquantization_tables[quantization_level][input[2]];
363 	int v3 = color_unquantization_tables[quantization_level][input[3]];
364 
365 	int modeval = ((v0 & 0xC0) >> 6) | (((v1 & 0x80) >> 7) << 2) | (((v2 & 0x80) >> 7) << 3);
366 
367 	int majcomp;
368 	int mode;
369 	if ((modeval & 0xC) != 0xC)
370 	{
371 		majcomp = modeval >> 2;
372 		mode = modeval & 3;
373 	}
374 	else if (modeval != 0xF)
375 	{
376 		majcomp = modeval & 3;
377 		mode = 4;
378 	}
379 	else
380 	{
381 		majcomp = 0;
382 		mode = 5;
383 	}
384 
385 	int red = v0 & 0x3F;
386 	int green = v1 & 0x1F;
387 	int blue = v2 & 0x1F;
388 	int scale = v3 & 0x1F;
389 
390 	int bit0 = (v1 >> 6) & 1;
391 	int bit1 = (v1 >> 5) & 1;
392 	int bit2 = (v2 >> 6) & 1;
393 	int bit3 = (v2 >> 5) & 1;
394 	int bit4 = (v3 >> 7) & 1;
395 	int bit5 = (v3 >> 6) & 1;
396 	int bit6 = (v3 >> 5) & 1;
397 
398 	int ohcomp = 1 << mode;
399 
400 	if (ohcomp & 0x30)
401 		green |= bit0 << 6;
402 	if (ohcomp & 0x3A)
403 		green |= bit1 << 5;
404 	if (ohcomp & 0x30)
405 		blue |= bit2 << 6;
406 	if (ohcomp & 0x3A)
407 		blue |= bit3 << 5;
408 
409 	if (ohcomp & 0x3D)
410 		scale |= bit6 << 5;
411 	if (ohcomp & 0x2D)
412 		scale |= bit5 << 6;
413 	if (ohcomp & 0x04)
414 		scale |= bit4 << 7;
415 
416 	if (ohcomp & 0x3B)
417 		red |= bit4 << 6;
418 	if (ohcomp & 0x04)
419 		red |= bit3 << 6;
420 
421 	if (ohcomp & 0x10)
422 		red |= bit5 << 7;
423 	if (ohcomp & 0x0F)
424 		red |= bit2 << 7;
425 
426 	if (ohcomp & 0x05)
427 		red |= bit1 << 8;
428 	if (ohcomp & 0x0A)
429 		red |= bit0 << 8;
430 
431 	if (ohcomp & 0x05)
432 		red |= bit0 << 9;
433 	if (ohcomp & 0x02)
434 		red |= bit6 << 9;
435 
436 	if (ohcomp & 0x01)
437 		red |= bit3 << 10;
438 	if (ohcomp & 0x02)
439 		red |= bit5 << 10;
440 
441 	// expand to 12 bits.
442 	static const int shamts[6] = { 1, 1, 2, 3, 4, 5 };
443 	int shamt = shamts[mode];
444 	red <<= shamt;
445 	green <<= shamt;
446 	blue <<= shamt;
447 	scale <<= shamt;
448 
449 	// on modes 0 to 4, the values stored for "green" and "blue" are differentials,
450 	// not absolute values.
451 	if (mode != 5)
452 	{
453 		green = red - green;
454 		blue = red - blue;
455 	}
456 
457 	// switch around components.
458 	int temp;
459 	switch (majcomp)
460 	{
461 	case 1:
462 		temp = red;
463 		red = green;
464 		green = temp;
465 		break;
466 	case 2:
467 		temp = red;
468 		red = blue;
469 		blue = temp;
470 		break;
471 	default:
472 		break;
473 	}
474 
475 	int red0 = red - scale;
476 	int green0 = green - scale;
477 	int blue0 = blue - scale;
478 
479 	// clamp to [0,0xFFF].
480 	if (red < 0)
481 		red = 0;
482 	if (green < 0)
483 		green = 0;
484 	if (blue < 0)
485 		blue = 0;
486 
487 	if (red0 < 0)
488 		red0 = 0;
489 	if (green0 < 0)
490 		green0 = 0;
491 	if (blue0 < 0)
492 		blue0 = 0;
493 
494 	*output0 = uint4(red0 << 4, green0 << 4, blue0 << 4, 0x7800);
495 	*output1 = uint4(red << 4, green << 4, blue << 4, 0x7800);
496 }
497 
hdr_rgb_unpack3(const int input[6],int quantization_level,uint4 * output0,uint4 * output1)498 static void hdr_rgb_unpack3(
499 	const int input[6],
500 	int quantization_level,
501 	uint4* output0,
502 	uint4 * output1
503 ) {
504 
505 	int v0 = color_unquantization_tables[quantization_level][input[0]];
506 	int v1 = color_unquantization_tables[quantization_level][input[1]];
507 	int v2 = color_unquantization_tables[quantization_level][input[2]];
508 	int v3 = color_unquantization_tables[quantization_level][input[3]];
509 	int v4 = color_unquantization_tables[quantization_level][input[4]];
510 	int v5 = color_unquantization_tables[quantization_level][input[5]];
511 
512 	// extract all the fixed-placement bitfields
513 	int modeval = ((v1 & 0x80) >> 7) | (((v2 & 0x80) >> 7) << 1) | (((v3 & 0x80) >> 7) << 2);
514 
515 	int majcomp = ((v4 & 0x80) >> 7) | (((v5 & 0x80) >> 7) << 1);
516 
517 	if (majcomp == 3)
518 	{
519 		*output0 = uint4(v0 << 8, v2 << 8, (v4 & 0x7F) << 9, 0x7800);
520 		*output1 = uint4(v1 << 8, v3 << 8, (v5 & 0x7F) << 9, 0x7800);
521 		return;
522 	}
523 
524 	int a = v0 | ((v1 & 0x40) << 2);
525 	int b0 = v2 & 0x3f;
526 	int b1 = v3 & 0x3f;
527 	int c = v1 & 0x3f;
528 	int d0 = v4 & 0x7f;
529 	int d1 = v5 & 0x7f;
530 
531 	// get hold of the number of bits in 'd0' and 'd1'
532 	static const int dbits_tab[8] = { 7, 6, 7, 6, 5, 6, 5, 6 };
533 	int dbits = dbits_tab[modeval];
534 
535 	// extract six variable-placement bits
536 	int bit0 = (v2 >> 6) & 1;
537 	int bit1 = (v3 >> 6) & 1;
538 
539 	int bit2 = (v4 >> 6) & 1;
540 	int bit3 = (v5 >> 6) & 1;
541 	int bit4 = (v4 >> 5) & 1;
542 	int bit5 = (v5 >> 5) & 1;
543 
544 	// and prepend the variable-placement bits depending on mode.
545 	int ohmod = 1 << modeval;	// one-hot-mode
546 	if (ohmod & 0xA4)
547 		a |= bit0 << 9;
548 	if (ohmod & 0x8)
549 		a |= bit2 << 9;
550 	if (ohmod & 0x50)
551 		a |= bit4 << 9;
552 
553 	if (ohmod & 0x50)
554 		a |= bit5 << 10;
555 	if (ohmod & 0xA0)
556 		a |= bit1 << 10;
557 
558 	if (ohmod & 0xC0)
559 		a |= bit2 << 11;
560 
561 	if (ohmod & 0x4)
562 		c |= bit1 << 6;
563 	if (ohmod & 0xE8)
564 		c |= bit3 << 6;
565 
566 	if (ohmod & 0x20)
567 		c |= bit2 << 7;
568 
569 	if (ohmod & 0x5B)
570 		b0 |= bit0 << 6;
571 	if (ohmod & 0x5B)
572 		b1 |= bit1 << 6;
573 
574 	if (ohmod & 0x12)
575 		b0 |= bit2 << 7;
576 	if (ohmod & 0x12)
577 		b1 |= bit3 << 7;
578 
579 	if (ohmod & 0xAF)
580 		d0 |= bit4 << 5;
581 	if (ohmod & 0xAF)
582 		d1 |= bit5 << 5;
583 	if (ohmod & 0x5)
584 		d0 |= bit2 << 6;
585 	if (ohmod & 0x5)
586 		d1 |= bit3 << 6;
587 
588 	// sign-extend 'd0' and 'd1'
589 	// note: this code assumes that signed right-shift actually sign-fills, not zero-fills.
590 	int32_t d0x = d0;
591 	int32_t d1x = d1;
592 	int sx_shamt = 32 - dbits;
593 	d0x <<= sx_shamt;
594 	d0x >>= sx_shamt;
595 	d1x <<= sx_shamt;
596 	d1x >>= sx_shamt;
597 	d0 = d0x;
598 	d1 = d1x;
599 
600 	// expand all values to 12 bits, with left-shift as needed.
601 	int val_shamt = (modeval >> 1) ^ 3;
602 	a <<= val_shamt;
603 	b0 <<= val_shamt;
604 	b1 <<= val_shamt;
605 	c <<= val_shamt;
606 	d0 <<= val_shamt;
607 	d1 <<= val_shamt;
608 
609 	// then compute the actual color values.
610 	int red1 = a;
611 	int green1 = a - b0;
612 	int blue1 = a - b1;
613 	int red0 = a - c;
614 	int green0 = a - b0 - c - d0;
615 	int blue0 = a - b1 - c - d1;
616 
617 	// clamp the color components to [0,2^12 - 1]
618 	if (red0 < 0)
619 		red0 = 0;
620 	else if (red0 > 0xFFF)
621 		red0 = 0xFFF;
622 
623 	if (green0 < 0)
624 		green0 = 0;
625 	else if (green0 > 0xFFF)
626 		green0 = 0xFFF;
627 
628 	if (blue0 < 0)
629 		blue0 = 0;
630 	else if (blue0 > 0xFFF)
631 		blue0 = 0xFFF;
632 
633 	if (red1 < 0)
634 		red1 = 0;
635 	else if (red1 > 0xFFF)
636 		red1 = 0xFFF;
637 
638 	if (green1 < 0)
639 		green1 = 0;
640 	else if (green1 > 0xFFF)
641 		green1 = 0xFFF;
642 
643 	if (blue1 < 0)
644 		blue1 = 0;
645 	else if (blue1 > 0xFFF)
646 		blue1 = 0xFFF;
647 
648 	// switch around the color components
649 	int temp0, temp1;
650 	switch (majcomp)
651 	{
652 	case 1:					// switch around red and green
653 		temp0 = red0;
654 		temp1 = red1;
655 		red0 = green0;
656 		red1 = green1;
657 		green0 = temp0;
658 		green1 = temp1;
659 		break;
660 	case 2:					// switch around red and blue
661 		temp0 = red0;
662 		temp1 = red1;
663 		red0 = blue0;
664 		red1 = blue1;
665 		blue0 = temp0;
666 		blue1 = temp1;
667 		break;
668 	case 0:					// no switch
669 		break;
670 	}
671 
672 	*output0 = uint4(red0 << 4, green0 << 4, blue0 << 4, 0x7800);
673 	*output1 = uint4(red1 << 4, green1 << 4, blue1 << 4, 0x7800);
674 }
675 
hdr_rgb_ldr_alpha_unpack3(const int input[8],int quantization_level,uint4 * output0,uint4 * output1)676 static void hdr_rgb_ldr_alpha_unpack3(
677 	const int input[8],
678 	int quantization_level,
679 	uint4* output0,
680 	uint4* output1
681 ) {
682 	hdr_rgb_unpack3(input, quantization_level, output0, output1);
683 
684 	int v6 = color_unquantization_tables[quantization_level][input[6]];
685 	int v7 = color_unquantization_tables[quantization_level][input[7]];
686 	output0->w = v6;
687 	output1->w = v7;
688 }
689 
hdr_luminance_small_range_unpack(const int input[2],int quantization_level,uint4 * output0,uint4 * output1)690 static void hdr_luminance_small_range_unpack(
691 	const int input[2],
692 	int quantization_level,
693 	uint4* output0,
694 	uint4* output1
695 ) {
696 	int v0 = color_unquantization_tables[quantization_level][input[0]];
697 	int v1 = color_unquantization_tables[quantization_level][input[1]];
698 
699 	int y0, y1;
700 	if (v0 & 0x80)
701 	{
702 		y0 = ((v1 & 0xE0) << 4) | ((v0 & 0x7F) << 2);
703 		y1 = (v1 & 0x1F) << 2;
704 	}
705 	else
706 	{
707 		y0 = ((v1 & 0xF0) << 4) | ((v0 & 0x7F) << 1);
708 		y1 = (v1 & 0xF) << 1;
709 	}
710 
711 	y1 += y0;
712 	if (y1 > 0xFFF)
713 		y1 = 0xFFF;
714 
715 	*output0 = uint4(y0 << 4, y0 << 4, y0 << 4, 0x7800);
716 	*output1 = uint4(y1 << 4, y1 << 4, y1 << 4, 0x7800);
717 }
718 
hdr_luminance_large_range_unpack(const int input[2],int quantization_level,uint4 * output0,uint4 * output1)719 static void hdr_luminance_large_range_unpack(
720 	const int input[2],
721 	int quantization_level,
722 	uint4* output0,
723 	uint4* output1
724 ) {
725 	int v0 = color_unquantization_tables[quantization_level][input[0]];
726 	int v1 = color_unquantization_tables[quantization_level][input[1]];
727 
728 	int y0, y1;
729 	if (v1 >= v0)
730 	{
731 		y0 = v0 << 4;
732 		y1 = v1 << 4;
733 	}
734 	else
735 	{
736 		y0 = (v1 << 4) + 8;
737 		y1 = (v0 << 4) - 8;
738 	}
739 	*output0 = uint4(y0 << 4, y0 << 4, y0 << 4, 0x7800);
740 	*output1 = uint4(y1 << 4, y1 << 4, y1 << 4, 0x7800);
741 }
742 
hdr_alpha_unpack(const int input[2],int quantization_level,int * a0,int * a1)743 static void hdr_alpha_unpack(
744 	const int input[2],
745 	int quantization_level,
746 	int *a0,
747 	int *a1
748 ) {
749 
750 	int v6 = color_unquantization_tables[quantization_level][input[0]];
751 	int v7 = color_unquantization_tables[quantization_level][input[1]];
752 
753 	int selector = ((v6 >> 7) & 1) | ((v7 >> 6) & 2);
754 	v6 &= 0x7F;
755 	v7 &= 0x7F;
756 	if (selector == 3)
757 	{
758 		*a0 = v6 << 5;
759 		*a1 = v7 << 5;
760 	}
761 	else
762 	{
763 		v6 |= (v7 << (selector + 1)) & 0x780;
764 		v7 &= (0x3f >> selector);
765 		v7 ^= 32 >> selector;
766 		v7 -= 32 >> selector;
767 		v6 <<= (4 - selector);
768 		v7 <<= (4 - selector);
769 		v7 += v6;
770 
771 		if (v7 < 0)
772 			v7 = 0;
773 		else if (v7 > 0xFFF)
774 			v7 = 0xFFF;
775 
776 		*a0 = v6;
777 		*a1 = v7;
778 	}
779 
780 	*a0 <<= 4;
781 	*a1 <<= 4;
782 }
783 
hdr_rgb_hdr_alpha_unpack3(const int input[8],int quantization_level,uint4 * output0,uint4 * output1)784 static void hdr_rgb_hdr_alpha_unpack3(
785 	const int input[8],
786 	int quantization_level,
787 	uint4* output0,
788 	uint4* output1
789 ) {
790 	hdr_rgb_unpack3(input, quantization_level, output0, output1);
791 
792 	int alpha0, alpha1;
793 	hdr_alpha_unpack(input + 6, quantization_level, &alpha0, &alpha1);
794 
795 	output0->w = alpha0;
796 	output1->w = alpha1;
797 }
798 
unpack_color_endpoints(astc_decode_mode decode_mode,int format,int quantization_level,const int * input,int * rgb_hdr,int * alpha_hdr,int * nan_endpoint,uint4 * output0,uint4 * output1)799 void unpack_color_endpoints(
800 	astc_decode_mode decode_mode,
801 	int format,
802 	int quantization_level,
803 	const int* input,
804 	int* rgb_hdr,
805 	int* alpha_hdr,
806 	int* nan_endpoint,
807 	uint4* output0,
808 	uint4* output1
809 ) {
810 	*nan_endpoint = 0;
811 
812 	switch (format)
813 	{
814 	case FMT_LUMINANCE:
815 		*rgb_hdr = 0;
816 		*alpha_hdr = 0;
817 		luminance_unpack(input, quantization_level, output0, output1);
818 		break;
819 
820 	case FMT_LUMINANCE_DELTA:
821 		*rgb_hdr = 0;
822 		*alpha_hdr = 0;
823 		luminance_delta_unpack(input, quantization_level, output0, output1);
824 		break;
825 
826 	case FMT_HDR_LUMINANCE_SMALL_RANGE:
827 		*rgb_hdr = 1;
828 		*alpha_hdr = -1;
829 		hdr_luminance_small_range_unpack(input, quantization_level, output0, output1);
830 		break;
831 
832 	case FMT_HDR_LUMINANCE_LARGE_RANGE:
833 		*rgb_hdr = 1;
834 		*alpha_hdr = -1;
835 		hdr_luminance_large_range_unpack(input, quantization_level, output0, output1);
836 		break;
837 
838 	case FMT_LUMINANCE_ALPHA:
839 		*rgb_hdr = 0;
840 		*alpha_hdr = 0;
841 		luminance_alpha_unpack(input, quantization_level, output0, output1);
842 		break;
843 
844 	case FMT_LUMINANCE_ALPHA_DELTA:
845 		*rgb_hdr = 0;
846 		*alpha_hdr = 0;
847 		luminance_alpha_delta_unpack(input, quantization_level, output0, output1);
848 		break;
849 
850 	case FMT_RGB_SCALE:
851 		*rgb_hdr = 0;
852 		*alpha_hdr = 0;
853 		rgb_scale_unpack(input, quantization_level, output0, output1);
854 		break;
855 
856 	case FMT_RGB_SCALE_ALPHA:
857 		*rgb_hdr = 0;
858 		*alpha_hdr = 0;
859 		rgb_scale_alpha_unpack(input, quantization_level, output0, output1);
860 		break;
861 
862 	case FMT_HDR_RGB_SCALE:
863 		*rgb_hdr = 1;
864 		*alpha_hdr = -1;
865 		hdr_rgbo_unpack3(input, quantization_level, output0, output1);
866 		break;
867 
868 	case FMT_RGB:
869 		*rgb_hdr = 0;
870 		*alpha_hdr = 0;
871 		rgb_unpack(input, quantization_level, output0, output1);
872 		break;
873 
874 	case FMT_RGB_DELTA:
875 		*rgb_hdr = 0;
876 		*alpha_hdr = 0;
877 		rgb_delta_unpack(input, quantization_level, output0, output1);
878 		break;
879 
880 	case FMT_HDR_RGB:
881 		*rgb_hdr = 1;
882 		*alpha_hdr = -1;
883 		hdr_rgb_unpack3(input, quantization_level, output0, output1);
884 		break;
885 
886 	case FMT_RGBA:
887 		*rgb_hdr = 0;
888 		*alpha_hdr = 0;
889 		rgba_unpack(input, quantization_level, output0, output1);
890 		break;
891 
892 	case FMT_RGBA_DELTA:
893 		*rgb_hdr = 0;
894 		*alpha_hdr = 0;
895 		rgba_delta_unpack(input, quantization_level, output0, output1);
896 		break;
897 
898 	case FMT_HDR_RGB_LDR_ALPHA:
899 		*rgb_hdr = 1;
900 		*alpha_hdr = 0;
901 		hdr_rgb_ldr_alpha_unpack3(input, quantization_level, output0, output1);
902 		break;
903 
904 	case FMT_HDR_RGBA:
905 		*rgb_hdr = 1;
906 		*alpha_hdr = 1;
907 		hdr_rgb_hdr_alpha_unpack3(input, quantization_level, output0, output1);
908 		break;
909 
910 	default:
911 		assert(false && "Unreachable");
912 		break;
913 	}
914 
915 	if (*alpha_hdr == -1)
916 	{
917 		{
918 			output0->w = 0x00FF;
919 			output1->w = 0x00FF;
920 			*alpha_hdr = 0;
921 		}
922 	}
923 
924 	switch (decode_mode)
925 	{
926 	case DECODE_LDR_SRGB:
927 		if (*rgb_hdr == 1)
928 		{
929 			output0->x = 0xFF00;
930 			output0->y = 0x0000;
931 			output0->z = 0xFF00;
932 			output0->w = 0xFF00;
933 			output1->x = 0xFF00;
934 			output1->y = 0x0000;
935 			output1->z = 0xFF00;
936 			output1->w = 0xFF00;
937 		}
938 		else
939 		{
940 			output0->x *= 257;
941 			output0->y *= 257;
942 			output0->z *= 257;
943 			output0->w *= 257;
944 			output1->x *= 257;
945 			output1->y *= 257;
946 			output1->z *= 257;
947 			output1->w *= 257;
948 		}
949 		*rgb_hdr = 0;
950 		*alpha_hdr = 0;
951 		break;
952 
953 	case DECODE_LDR:
954 		if (*rgb_hdr == 1)
955 		{
956 			output0->x = 0xFFFF;
957 			output0->y = 0xFFFF;
958 			output0->z = 0xFFFF;
959 			output0->w = 0xFFFF;
960 			output1->x = 0xFFFF;
961 			output1->y = 0xFFFF;
962 			output1->z = 0xFFFF;
963 			output1->w = 0xFFFF;
964 			*nan_endpoint = 1;
965 		}
966 		else
967 		{
968 			output0->x *= 257;
969 			output0->y *= 257;
970 			output0->z *= 257;
971 			output0->w *= 257;
972 			output1->x *= 257;
973 			output1->y *= 257;
974 			output1->z *= 257;
975 			output1->w *= 257;
976 		}
977 		*rgb_hdr = 0;
978 		*alpha_hdr = 0;
979 		break;
980 
981 	case DECODE_HDR:
982 
983 		if (*rgb_hdr == 0)
984 		{
985 			output0->x *= 257;
986 			output0->y *= 257;
987 			output0->z *= 257;
988 			output1->x *= 257;
989 			output1->y *= 257;
990 			output1->z *= 257;
991 		}
992 		if (*alpha_hdr == 0)
993 		{
994 			output0->w *= 257;
995 			output1->w *= 257;
996 		}
997 		break;
998 	}
999 }
1000