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 and data declarations.
20 */
21
22 #ifndef ASTC_CODEC_INTERNALS_INCLUDED
23 #define ASTC_CODEC_INTERNALS_INCLUDED
24
25 #include <cstddef>
26 #include <cstdint>
27 #include <cstdio>
28 #include <cstdlib>
29
30 #include "astc_mathlib.h"
31
32 // ASTC parameters
33 #define MAX_TEXELS_PER_BLOCK 216
34 #define MAX_WEIGHTS_PER_BLOCK 64
35 #define MIN_WEIGHT_BITS_PER_BLOCK 24
36 #define MAX_WEIGHT_BITS_PER_BLOCK 96
37 #define PARTITION_BITS 10
38 #define PARTITION_COUNT (1 << PARTITION_BITS)
39
40 // the sum of weights for one texel.
41 #define TEXEL_WEIGHT_SUM 16
42 #define MAX_DECIMATION_MODES 87
43 #define MAX_WEIGHT_MODES 2048
44
45 enum astc_decode_mode
46 {
47 DECODE_LDR_SRGB,
48 DECODE_LDR,
49 DECODE_HDR
50 };
51
52 /*
53 Partition table representation:
54 For each block size, we have 3 tables, each with 1024 partitionings;
55 these three tables correspond to 2, 3 and 4 partitions respectively.
56 For each partitioning, we have:
57 * a 4-entry table indicating how many texels there are in each of the 4 partitions.
58 This may be from 0 to a very large value.
59 * a table indicating the partition index of each of the texels in the block.
60 Each index may be 0, 1, 2 or 3.
61 * Each element in the table is an uint8_t indicating partition index (0, 1, 2 or 3)
62 */
63
64 struct partition_info
65 {
66 int partition_count;
67 uint8_t partition_of_texel[MAX_TEXELS_PER_BLOCK];
68 };
69
70 /*
71 In ASTC, we don't necessarily provide a weight for every texel.
72 As such, for each block size, there are a number of patterns where some texels
73 have their weights computed as a weighted average of more than 1 weight.
74 As such, the codec uses a data structure that tells us: for each texel, which
75 weights it is a combination of for each weight, which texels it contributes to.
76 The decimation_table is this data structure.
77 */
78 struct decimation_table
79 {
80 int num_weights;
81 uint8_t texel_num_weights[MAX_TEXELS_PER_BLOCK]; // number of indices that go into the calculation for a texel
82 uint8_t texel_weights_int[MAX_TEXELS_PER_BLOCK][4]; // the weight to assign to each weight
83 uint8_t texel_weights[MAX_TEXELS_PER_BLOCK][4]; // the weights that go into a texel calculation
84 };
85
86 /*
87 data structure describing information that pertains to a block size and its associated block modes.
88 */
89 struct block_mode
90 {
91 int8_t decimation_mode;
92 int8_t quantization_mode;
93 int8_t is_dual_plane;
94 int8_t permit_decode;
95 };
96
97 struct block_size_descriptor
98 {
99 int xdim;
100 int ydim;
101 int zdim;
102 int texel_count;
103
104 int decimation_mode_count;
105 const decimation_table *decimation_tables[MAX_DECIMATION_MODES];
106 block_mode block_modes[MAX_WEIGHT_MODES];
107
108 // All the partitioning information for this block size
109 partition_info partitions[(3*PARTITION_COUNT)+1];
110 };
111
112 // data structure representing one block of an image.
113 // it is expanded to float prior to processing to save some computation time
114 // on conversions to/from uint8_t (this also allows us to handle HDR textures easily)
115 struct imageblock
116 {
117 float orig_data[MAX_TEXELS_PER_BLOCK * 4]; // original input data
118 float data_r[MAX_TEXELS_PER_BLOCK]; // the data that we will compress, either linear or LNS (0..65535 in both cases)
119 float data_g[MAX_TEXELS_PER_BLOCK];
120 float data_b[MAX_TEXELS_PER_BLOCK];
121 float data_a[MAX_TEXELS_PER_BLOCK];
122
123 uint8_t rgb_lns[MAX_TEXELS_PER_BLOCK]; // 1 if RGB data are being treated as LNS
124 uint8_t alpha_lns[MAX_TEXELS_PER_BLOCK]; // 1 if Alpha data are being treated as LNS
125 uint8_t nan_texel[MAX_TEXELS_PER_BLOCK]; // 1 if the texel is a NaN-texel.
126
127 float red_min, red_max;
128 float green_min, green_max;
129 float blue_min, blue_max;
130 float alpha_min, alpha_max;
131 int grayscale; // 1 if R=G=B for every pixel, 0 otherwise
132
133 int xpos, ypos, zpos;
134 };
135
136 void update_imageblock_flags(
137 imageblock* pb,
138 int xdim,
139 int ydim,
140 int zdim);
141
142 void imageblock_initialize_orig_from_work(
143 imageblock * pb,
144 int pixelcount);
145
146 void imageblock_initialize_work_from_orig(
147 imageblock * pb,
148 int pixelcount);
149
150 // enumeration of all the quantization methods we support under this format.
151 enum quantization_method
152 {
153 QUANT_2 = 0,
154 QUANT_3 = 1,
155 QUANT_4 = 2,
156 QUANT_5 = 3,
157 QUANT_6 = 4,
158 QUANT_8 = 5,
159 QUANT_10 = 6,
160 QUANT_12 = 7,
161 QUANT_16 = 8,
162 QUANT_20 = 9,
163 QUANT_24 = 10,
164 QUANT_32 = 11,
165 QUANT_40 = 12,
166 QUANT_48 = 13,
167 QUANT_64 = 14,
168 QUANT_80 = 15,
169 QUANT_96 = 16,
170 QUANT_128 = 17,
171 QUANT_160 = 18,
172 QUANT_192 = 19,
173 QUANT_256 = 20
174 };
175
176 /**
177 * @brief Weight quantization transfer table.
178 *
179 * ASTC can store texel weights at many quantization levels, so for performance
180 * we store essential information about each level as a precomputed data
181 * structure.
182 *
183 * Unquantized weights are integers in the range [0, 64], or floats [0, 1].
184 *
185 * This structure provides the following information:
186 * A table, used to estimate the closest quantized
187 weight for a given floating-point weight. For each quantized weight, the corresponding unquantized
188 and floating-point values. For each quantized weight, a previous-value and a next-value.
189 */
190 struct quantization_and_transfer_table
191 {
192 /** The scrambled unquantized values. */
193 uint8_t unquantized_value[32];
194 };
195
196 extern const quantization_and_transfer_table quant_and_xfer_tables[12];
197
198 enum endpoint_formats
199 {
200 FMT_LUMINANCE = 0,
201 FMT_LUMINANCE_DELTA = 1,
202 FMT_HDR_LUMINANCE_LARGE_RANGE = 2,
203 FMT_HDR_LUMINANCE_SMALL_RANGE = 3,
204 FMT_LUMINANCE_ALPHA = 4,
205 FMT_LUMINANCE_ALPHA_DELTA = 5,
206 FMT_RGB_SCALE = 6,
207 FMT_HDR_RGB_SCALE = 7,
208 FMT_RGB = 8,
209 FMT_RGB_DELTA = 9,
210 FMT_RGB_SCALE_ALPHA = 10,
211 FMT_HDR_RGB = 11,
212 FMT_RGBA = 12,
213 FMT_RGBA_DELTA = 13,
214 FMT_HDR_RGB_LDR_ALPHA = 14,
215 FMT_HDR_RGBA = 15,
216 };
217
218 struct symbolic_compressed_block
219 {
220 int error_block; // 1 marks error block, 0 marks non-error-block.
221 int block_mode; // 0 to 2047. Negative value marks constant-color block (-1: FP16, -2:UINT16)
222 int partition_count; // 1 to 4; Zero marks a constant-color block.
223 int partition_index; // 0 to 1023
224 int color_formats[4]; // color format for each endpoint color pair.
225 int color_formats_matched; // color format for all endpoint pairs are matched.
226 int color_values[4][12]; // quantized endpoint color pairs.
227 int color_quantization_level;
228 uint8_t plane1_weights[MAX_WEIGHTS_PER_BLOCK]; // quantized and decimated weights
229 uint8_t plane2_weights[MAX_WEIGHTS_PER_BLOCK];
230 int plane2_color_component; // color component for the secondary plane of weights
231 int constant_color[4]; // constant-color, as FP16 or UINT16. Used for constant-color blocks only.
232 };
233
234 struct physical_compressed_block
235 {
236 uint8_t data[16];
237 };
238
239 /* ============================================================================
240 Functions and data pertaining to quantization and encoding
241 ============================================================================ */
242
243 /**
244 * @brief Populate the blocksize descriptor for the target block size.
245 *
246 * This will also initialize the partition table metadata, which is stored
247 * as part of the BSD structure.
248 *
249 * @param xdim The x axis size of the block.
250 * @param ydim The y axis size of the block.
251 * @param zdim The z axis size of the block.
252 * @param bsd The structure to populate.
253 */
254 void init_block_size_descriptor(
255 int xdim,
256 int ydim,
257 int zdim,
258 block_size_descriptor* bsd);
259
260 void term_block_size_descriptor(
261 block_size_descriptor* bsd);
262
263 /**
264 * @brief Populate the partition tables for the target block size.
265 *
266 * Note the block_size_size descriptor must be initialized before calling this
267 * function.
268 *
269 * @param bsd The structure to populate.
270 */
271 void init_partition_tables(
272 block_size_descriptor* bsd);
273
get_partition_table(const block_size_descriptor * bsd,int partition_count)274 static inline const partition_info *get_partition_table(
275 const block_size_descriptor* bsd,
276 int partition_count
277 ) {
278 if (partition_count == 1) {
279 partition_count = 5;
280 }
281 int index = (partition_count - 2) * PARTITION_COUNT;
282 return bsd->partitions + index;
283 }
284
285 // ***********************************************************
286 // functions and data pertaining to quantization and encoding
287 // **********************************************************
288
289 extern const uint8_t color_unquantization_tables[21][256];
290 extern int quantization_mode_table[17][128];
291
292 void decode_ise(
293 int quantization_level,
294 int elements,
295 const uint8_t* input_data,
296 uint8_t* output_data,
297 int bit_offset);
298
299 int compute_ise_bitcount(
300 int items,
301 quantization_method quant);
302
303 void build_quantization_mode_table(void);
304
305 // unpack a pair of color endpoints from a series of integers.
306 void unpack_color_endpoints(
307 astc_decode_mode decode_mode,
308 int format,
309 int quantization_level,
310 const int* input,
311 int* rgb_hdr,
312 int* alpha_hdr,
313 int* nan_endpoint,
314 uint4* output0,
315 uint4* output1);
316
317 /* *********************************** high-level encode and decode functions ************************************ */
318
319 void decompress_symbolic_block(
320 astc_decode_mode decode_mode,
321 const block_size_descriptor* bsd,
322 int xpos,
323 int ypos,
324 int zpos,
325 const symbolic_compressed_block* scb,
326 imageblock* blk);
327
328 void physical_to_symbolic(
329 const block_size_descriptor* bsd,
330 physical_compressed_block pb,
331 symbolic_compressed_block* res);
332
333 uint16_t unorm16_to_sf16(
334 uint16_t p);
335
336 uint16_t lns_to_sf16(
337 uint16_t p);
338
339 #endif
340