|
1 | 1 | // SPDX-License-Identifier: Apache-2.0 |
2 | 2 | // ---------------------------------------------------------------------------- |
3 | | -// Copyright 2011-2021 Arm Limited |
| 3 | +// Copyright 2011-2023 Arm Limited |
4 | 4 | // |
5 | 5 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not |
6 | 6 | // use this file except in compliance with the License. You may obtain a copy |
@@ -894,32 +894,55 @@ void unpack_color_endpoints( |
894 | 894 | } |
895 | 895 | } |
896 | 896 |
|
897 | | - vint4 ldr_scale(257); |
898 | | - vint4 hdr_scale(1); |
899 | | - vint4 output_scale = ldr_scale; |
| 897 | + // Handle endpoint errors and expansion |
900 | 898 |
|
901 | | - // An LDR profile image |
902 | | - if ((decode_mode == ASTCENC_PRF_LDR) || |
903 | | - (decode_mode == ASTCENC_PRF_LDR_SRGB)) |
| 899 | + // Linear LDR 8-bit endpoints are expanded to 16-bit by replication |
| 900 | + if (decode_mode == ASTCENC_PRF_LDR) |
904 | 901 | { |
905 | | - // Also matches HDR alpha, as cannot have HDR alpha without HDR RGB |
906 | | - if (rgb_hdr == true) |
| 902 | + // Error color - HDR endpoint in an LDR encoding |
| 903 | + if (rgb_hdr || alpha_hdr) |
907 | 904 | { |
908 | | - output0 = vint4(0xFF00, 0x0000, 0xFF00, 0xFF00); |
909 | | - output1 = vint4(0xFF00, 0x0000, 0xFF00, 0xFF00); |
910 | | - output_scale = hdr_scale; |
| 905 | + output0 = vint4(0xFF, 0x00, 0xFF, 0xFF); |
| 906 | + output1 = vint4(0xFF, 0x00, 0xFF, 0xFF); |
| 907 | + rgb_hdr = false; |
| 908 | + alpha_hdr = false; |
| 909 | + } |
911 | 910 |
|
| 911 | + output0 = output0 * 257; |
| 912 | + output1 = output1 * 257; |
| 913 | + } |
| 914 | + // sRGB LDR 8-bit endpoints are expanded to 16 bit by: |
| 915 | + // - RGB = shift left by 8 bits and OR with 0x80 |
| 916 | + // - A = replication |
| 917 | + else if (decode_mode == ASTCENC_PRF_LDR_SRGB) |
| 918 | + { |
| 919 | + // Error color - HDR endpoint in an LDR encoding |
| 920 | + if (rgb_hdr || alpha_hdr) |
| 921 | + { |
| 922 | + output0 = vint4(0xFF, 0x00, 0xFF, 0xFF); |
| 923 | + output1 = vint4(0xFF, 0x00, 0xFF, 0xFF); |
912 | 924 | rgb_hdr = false; |
913 | 925 | alpha_hdr = false; |
914 | 926 | } |
| 927 | + |
| 928 | + vmask4 mask(true, true, true, false); |
| 929 | + |
| 930 | + vint4 output0rgb = lsl<8>(output0) | vint4(0x80); |
| 931 | + vint4 output0a = output0 * 257; |
| 932 | + output0 = select(output0a, output0rgb, mask); |
| 933 | + |
| 934 | + vint4 output1rgb = lsl<8>(output1) | vint4(0x80); |
| 935 | + vint4 output1a = output1 * 257; |
| 936 | + output1 = select(output1a, output1rgb, mask); |
915 | 937 | } |
916 | | - // An HDR profile image |
| 938 | + // An HDR profile decode, but may be using linear LDR endpoints |
| 939 | + // Linear LDR 8-bit endpoints are expanded to 16-bit by replication |
| 940 | + // HDR endpoints are already 16-bit |
917 | 941 | else |
918 | 942 | { |
919 | 943 | vmask4 hdr_lanes(rgb_hdr, rgb_hdr, rgb_hdr, alpha_hdr); |
920 | | - output_scale = select(ldr_scale, hdr_scale, hdr_lanes); |
| 944 | + vint4 output_scale = select(vint4(257), vint4(1), hdr_lanes); |
| 945 | + output0 = output0 * output_scale; |
| 946 | + output1 = output1 * output_scale; |
921 | 947 | } |
922 | | - |
923 | | - output0 = output0 * output_scale; |
924 | | - output1 = output1 * output_scale; |
925 | 948 | } |
0 commit comments