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