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 texels_per_partition[4];
68 uint8_t partition_of_texel[MAX_TEXELS_PER_BLOCK];
69 uint8_t texels_of_partition[4][MAX_TEXELS_PER_BLOCK];
70 uint64_t coverage_bitmaps[4];
71 };
72
73 /*
74 In ASTC, we don't necessarily provide a weight for every texel.
75 As such, for each block size, there are a number of patterns where some texels
76 have their weights computed as a weighted average of more than 1 weight.
77 As such, the codec uses a data structure that tells us: for each texel, which
78 weights it is a combination of for each weight, which texels it contributes to.
79 The decimation_table is this data structure.
80 */
81 struct decimation_table
82 {
83 int num_texels;
84 int num_weights;
85 uint8_t texel_num_weights[MAX_TEXELS_PER_BLOCK]; // number of indices that go into the calculation for a texel
86 uint8_t texel_weights_int[MAX_TEXELS_PER_BLOCK][4]; // the weight to assign to each weight
87 float texel_weights_float[MAX_TEXELS_PER_BLOCK][4]; // the weight to assign to each weight
88 uint8_t texel_weights[MAX_TEXELS_PER_BLOCK][4]; // the weights that go into a texel calculation
89 uint8_t weight_num_texels[MAX_WEIGHTS_PER_BLOCK]; // the number of texels that a given weight contributes to
90 uint8_t weight_texel[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK]; // the texels that the weight contributes to
91 uint8_t weights_int[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK]; // the weights that the weight contributes to a texel.
92 float weights_flt[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK]; // the weights that the weight contributes to a texel.
93
94 // folded data structures:
95 // * texel_weights_texel[i][j] = texel_weights[weight_texel[i][j]];
96 // * texel_weights_float_texel[i][j] = texel_weights_float[weight_texel[i][j]
97 uint8_t texel_weights_texel[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK][4];
98 float texel_weights_float_texel[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK][4];
99 };
100
101 /*
102 data structure describing information that pertains to a block size and its associated block modes.
103 */
104 struct block_mode
105 {
106 int8_t decimation_mode;
107 int8_t quantization_mode;
108 int8_t is_dual_plane;
109 int8_t permit_encode;
110 int8_t permit_decode;
111 float percentile;
112 };
113
114 struct block_size_descriptor
115 {
116 int xdim;
117 int ydim;
118 int zdim;
119 int texel_count;
120
121 int decimation_mode_count;
122 int decimation_mode_samples[MAX_DECIMATION_MODES];
123 int decimation_mode_maxprec_1plane[MAX_DECIMATION_MODES];
124 int decimation_mode_maxprec_2planes[MAX_DECIMATION_MODES];
125 float decimation_mode_percentile[MAX_DECIMATION_MODES];
126 int permit_encode[MAX_DECIMATION_MODES];
127 const decimation_table *decimation_tables[MAX_DECIMATION_MODES];
128 block_mode block_modes[MAX_WEIGHT_MODES];
129
130 // for the k-means bed bitmap partitioning algorithm, we don't
131 // want to consider more than 64 texels; this array specifies
132 // which 64 texels (if that many) to consider.
133 int texelcount_for_bitmap_partitioning;
134 int texels_for_bitmap_partitioning[64];
135
136 // All the partitioning information for this block size
137 partition_info partitions[(3*PARTITION_COUNT)+1];
138 };
139
140 // data structure representing one block of an image.
141 // it is expanded to float prior to processing to save some computation time
142 // on conversions to/from uint8_t (this also allows us to handle HDR textures easily)
143 struct imageblock
144 {
145 float orig_data[MAX_TEXELS_PER_BLOCK * 4]; // original input data
146 float data_r[MAX_TEXELS_PER_BLOCK]; // the data that we will compress, either linear or LNS (0..65535 in both cases)
147 float data_g[MAX_TEXELS_PER_BLOCK];
148 float data_b[MAX_TEXELS_PER_BLOCK];
149 float data_a[MAX_TEXELS_PER_BLOCK];
150
151 uint8_t rgb_lns[MAX_TEXELS_PER_BLOCK]; // 1 if RGB data are being treated as LNS
152 uint8_t alpha_lns[MAX_TEXELS_PER_BLOCK]; // 1 if Alpha data are being treated as LNS
153 uint8_t nan_texel[MAX_TEXELS_PER_BLOCK]; // 1 if the texel is a NaN-texel.
154
155 float red_min, red_max;
156 float green_min, green_max;
157 float blue_min, blue_max;
158 float alpha_min, alpha_max;
159 int grayscale; // 1 if R=G=B for every pixel, 0 otherwise
160
161 int xpos, ypos, zpos;
162 };
163
164 void update_imageblock_flags(
165 imageblock* pb,
166 int xdim,
167 int ydim,
168 int zdim);
169
170 void imageblock_initialize_orig_from_work(
171 imageblock * pb,
172 int pixelcount);
173
174 void imageblock_initialize_work_from_orig(
175 imageblock * pb,
176 int pixelcount);
177
178 // enumeration of all the quantization methods we support under this format.
179 enum quantization_method
180 {
181 QUANT_2 = 0,
182 QUANT_3 = 1,
183 QUANT_4 = 2,
184 QUANT_5 = 3,
185 QUANT_6 = 4,
186 QUANT_8 = 5,
187 QUANT_10 = 6,
188 QUANT_12 = 7,
189 QUANT_16 = 8,
190 QUANT_20 = 9,
191 QUANT_24 = 10,
192 QUANT_32 = 11,
193 QUANT_40 = 12,
194 QUANT_48 = 13,
195 QUANT_64 = 14,
196 QUANT_80 = 15,
197 QUANT_96 = 16,
198 QUANT_128 = 17,
199 QUANT_160 = 18,
200 QUANT_192 = 19,
201 QUANT_256 = 20
202 };
203
204 /**
205 * @brief Weight quantization transfer table.
206 *
207 * ASTC can store texel weights at many quantization levels, so for performance
208 * we store essential information about each level as a precomputed data
209 * structure.
210 *
211 * Unquantized weights are integers in the range [0, 64], or floats [0, 1].
212 *
213 * This structure provides the following information:
214 * A table, used to estimate the closest quantized
215 weight for a given floating-point weight. For each quantized weight, the corresponding unquantized
216 and floating-point values. For each quantized weight, a previous-value and a next-value.
217 */
218 struct quantization_and_transfer_table
219 {
220 /** The quantization level used */
221 quantization_method method;
222 /** The unscrambled unquantized value. */
223 // TODO: Converted to floats to support AVX gathers
224 float unquantized_value_unsc[33];
225 /** The scrambling order: value[map[i]] == value_unsc[i] */
226 // TODO: Converted to u32 to support AVX gathers
227 int32_t scramble_map[32];
228 /** The scrambled unquantized values. */
229 uint8_t unquantized_value[32];
230 /**
231 * An encoded table of previous-and-next weight values, indexed by the
232 * current unquantized value.
233 * * bits 7:0 = previous-index, unquantized
234 * * bits 15:8 = next-index, unquantized
235 * * bits 23:16 = previous-index, quantized
236 * * bits 31:24 = next-index, quantized
237 */
238 uint32_t prev_next_values[65];
239 };
240
241 extern const quantization_and_transfer_table quant_and_xfer_tables[12];
242
243 enum endpoint_formats
244 {
245 FMT_LUMINANCE = 0,
246 FMT_LUMINANCE_DELTA = 1,
247 FMT_HDR_LUMINANCE_LARGE_RANGE = 2,
248 FMT_HDR_LUMINANCE_SMALL_RANGE = 3,
249 FMT_LUMINANCE_ALPHA = 4,
250 FMT_LUMINANCE_ALPHA_DELTA = 5,
251 FMT_RGB_SCALE = 6,
252 FMT_HDR_RGB_SCALE = 7,
253 FMT_RGB = 8,
254 FMT_RGB_DELTA = 9,
255 FMT_RGB_SCALE_ALPHA = 10,
256 FMT_HDR_RGB = 11,
257 FMT_RGBA = 12,
258 FMT_RGBA_DELTA = 13,
259 FMT_HDR_RGB_LDR_ALPHA = 14,
260 FMT_HDR_RGBA = 15,
261 };
262
263 struct symbolic_compressed_block
264 {
265 int error_block; // 1 marks error block, 0 marks non-error-block.
266 int block_mode; // 0 to 2047. Negative value marks constant-color block (-1: FP16, -2:UINT16)
267 int partition_count; // 1 to 4; Zero marks a constant-color block.
268 int partition_index; // 0 to 1023
269 int color_formats[4]; // color format for each endpoint color pair.
270 int color_formats_matched; // color format for all endpoint pairs are matched.
271 int color_values[4][12]; // quantized endpoint color pairs.
272 int color_quantization_level;
273 uint8_t plane1_weights[MAX_WEIGHTS_PER_BLOCK]; // quantized and decimated weights
274 uint8_t plane2_weights[MAX_WEIGHTS_PER_BLOCK];
275 int plane2_color_component; // color component for the secondary plane of weights
276 int constant_color[4]; // constant-color, as FP16 or UINT16. Used for constant-color blocks only.
277 };
278
279 struct physical_compressed_block
280 {
281 uint8_t data[16];
282 };
283
284 /* ============================================================================
285 Functions and data pertaining to quantization and encoding
286 ============================================================================ */
287
288 /**
289 * @brief Populate the blocksize descriptor for the target block size.
290 *
291 * This will also initialize the partition table metadata, which is stored
292 * as part of the BSD structure.
293 *
294 * @param xdim The x axis size of the block.
295 * @param ydim The y axis size of the block.
296 * @param zdim The z axis size of the block.
297 * @param bsd The structure to populate.
298 */
299 void init_block_size_descriptor(
300 int xdim,
301 int ydim,
302 int zdim,
303 block_size_descriptor* bsd);
304
305 void term_block_size_descriptor(
306 block_size_descriptor* bsd);
307
308 /**
309 * @brief Populate the partition tables for the target block size.
310 *
311 * Note the block_size_size descriptor must be initialized before calling this
312 * function.
313 *
314 * @param bsd The structure to populate.
315 */
316 void init_partition_tables(
317 block_size_descriptor* bsd);
318
get_partition_table(const block_size_descriptor * bsd,int partition_count)319 static inline const partition_info *get_partition_table(
320 const block_size_descriptor* bsd,
321 int partition_count
322 ) {
323 if (partition_count == 1) {
324 partition_count = 5;
325 }
326 int index = (partition_count - 2) * PARTITION_COUNT;
327 return bsd->partitions + index;
328 }
329
330 /**
331 * @brief Get the percentile table for 2D block modes.
332 *
333 * This is an empirically determined prioritization of which block modes to
334 * use in the search in terms of their centile (lower centiles = more useful).
335 *
336 * Returns a dynamically allocated array; caller must free with delete[].
337 *
338 * @param xdim The block x size.
339 * @param ydim The block y size.
340 *
341 * @return The unpacked table.
342 */
343 const float *get_2d_percentile_table(
344 int xdim,
345 int ydim);
346
347 // ***********************************************************
348 // functions and data pertaining to quantization and encoding
349 // **********************************************************
350
351 extern const uint8_t color_unquantization_tables[21][256];
352 extern int quantization_mode_table[17][128];
353
354 void decode_ise(
355 int quantization_level,
356 int elements,
357 const uint8_t* input_data,
358 uint8_t* output_data,
359 int bit_offset);
360
361 int compute_ise_bitcount(
362 int items,
363 quantization_method quant);
364
365 void build_quantization_mode_table(void);
366
367 // unpack a pair of color endpoints from a series of integers.
368 void unpack_color_endpoints(
369 astc_decode_mode decode_mode,
370 int format,
371 int quantization_level,
372 const int* input,
373 int* rgb_hdr,
374 int* alpha_hdr,
375 int* nan_endpoint,
376 uint4* output0,
377 uint4* output1);
378
379 /* *********************************** high-level encode and decode functions ************************************ */
380
381 void decompress_symbolic_block(
382 astc_decode_mode decode_mode,
383 const block_size_descriptor* bsd,
384 int xpos,
385 int ypos,
386 int zpos,
387 const symbolic_compressed_block* scb,
388 imageblock* blk);
389
390 void physical_to_symbolic(
391 const block_size_descriptor* bsd,
392 physical_compressed_block pb,
393 symbolic_compressed_block* res);
394
395 uint16_t unorm16_to_sf16(
396 uint16_t p);
397
398 uint16_t lns_to_sf16(
399 uint16_t p);
400
401 #endif
402