• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 converting between symbolic and physical encodings.
20  */
21 
22 #include "astc_codec_internals.h"
23 
24 // routine to read up to 8 bits
read_bits(int bitcount,int bitoffset,const uint8_t * ptr)25 static inline int read_bits(
26 	int bitcount,
27 	int bitoffset,
28 	const uint8_t* ptr
29 ) {
30 	int mask = (1 << bitcount) - 1;
31 	ptr += bitoffset >> 3;
32 	bitoffset &= 7;
33 	int value = ptr[0] | (ptr[1] << 8);
34 	value >>= bitoffset;
35 	value &= mask;
36 	return value;
37 }
38 
bitrev8(int p)39 static inline int bitrev8(int p)
40 {
41 	p = ((p & 0xF) << 4) | ((p >> 4) & 0xF);
42 	p = ((p & 0x33) << 2) | ((p >> 2) & 0x33);
43 	p = ((p & 0x55) << 1) | ((p >> 1) & 0x55);
44 	return p;
45 }
46 
physical_to_symbolic(const block_size_descriptor * bsd,physical_compressed_block pb,symbolic_compressed_block * res)47 void physical_to_symbolic(
48 	const block_size_descriptor* bsd,
49 	physical_compressed_block pb,
50 	symbolic_compressed_block* res
51 ) {
52 	uint8_t bswapped[16];
53 	int i, j;
54 
55 	res->error_block = 0;
56 
57 	// get hold of the decimation tables.
58 	const decimation_table *const *ixtab2 = bsd->decimation_tables;
59 
60 	// extract header fields
61 	int block_mode = read_bits(11, 0, pb.data);
62 	if ((block_mode & 0x1FF) == 0x1FC)
63 	{
64 		// void-extent block!
65 
66 		// check what format the data has
67 		if (block_mode & 0x200)
68 			res->block_mode = -1;	// floating-point
69 		else
70 			res->block_mode = -2;	// unorm16.
71 
72 		res->partition_count = 0;
73 		for (i = 0; i < 4; i++)
74 		{
75 			res->constant_color[i] = pb.data[2 * i + 8] | (pb.data[2 * i + 9] << 8);
76 		}
77 
78 		// additionally, check that the void-extent
79 		if (bsd->zdim == 1)
80 		{
81 			// 2D void-extent
82 			int rsvbits = read_bits(2, 10, pb.data);
83 			if (rsvbits != 3)
84 				res->error_block = 1;
85 
86 			int vx_low_s = read_bits(8, 12, pb.data) | (read_bits(5, 12 + 8, pb.data) << 8);
87 			int vx_high_s = read_bits(8, 25, pb.data) | (read_bits(5, 25 + 8, pb.data) << 8);
88 			int vx_low_t = read_bits(8, 38, pb.data) | (read_bits(5, 38 + 8, pb.data) << 8);
89 			int vx_high_t = read_bits(8, 51, pb.data) | (read_bits(5, 51 + 8, pb.data) << 8);
90 
91 			int all_ones = vx_low_s == 0x1FFF && vx_high_s == 0x1FFF && vx_low_t == 0x1FFF && vx_high_t == 0x1FFF;
92 
93 			if ((vx_low_s >= vx_high_s || vx_low_t >= vx_high_t) && !all_ones)
94 				res->error_block = 1;
95 		}
96 		else
97 		{
98 			// 3D void-extent
99 			int vx_low_s = read_bits(9, 10, pb.data);
100 			int vx_high_s = read_bits(9, 19, pb.data);
101 			int vx_low_t = read_bits(9, 28, pb.data);
102 			int vx_high_t = read_bits(9, 37, pb.data);
103 			int vx_low_p = read_bits(9, 46, pb.data);
104 			int vx_high_p = read_bits(9, 55, pb.data);
105 
106 			int all_ones = vx_low_s == 0x1FF && vx_high_s == 0x1FF && vx_low_t == 0x1FF && vx_high_t == 0x1FF && vx_low_p == 0x1FF && vx_high_p == 0x1FF;
107 
108 			if ((vx_low_s >= vx_high_s || vx_low_t >= vx_high_t || vx_low_p >= vx_high_p) && !all_ones)
109 				res->error_block = 1;
110 		}
111 
112 		return;
113 	}
114 
115 	if (bsd->block_modes[block_mode].permit_decode == 0)
116 	{
117 		res->error_block = 1;
118 		return;
119 	}
120 
121 	int weight_count = ixtab2[bsd->block_modes[block_mode].decimation_mode]->num_weights;
122 	int weight_quantization_method = bsd->block_modes[block_mode].quantization_mode;
123 	int is_dual_plane = bsd->block_modes[block_mode].is_dual_plane;
124 
125 	int real_weight_count = is_dual_plane ? 2 * weight_count : weight_count;
126 
127 	int partition_count = read_bits(2, 11, pb.data) + 1;
128 
129 	res->block_mode = block_mode;
130 	res->partition_count = partition_count;
131 
132 	for (i = 0; i < 16; i++)
133 		bswapped[i] = bitrev8(pb.data[15 - i]);
134 
135 	int bits_for_weights = compute_ise_bitcount(real_weight_count,
136 												(quantization_method) weight_quantization_method);
137 
138 	int below_weights_pos = 128 - bits_for_weights;
139 
140 	if (is_dual_plane)
141 	{
142 		uint8_t indices[64];
143 		decode_ise(weight_quantization_method, real_weight_count, bswapped, indices, 0);
144 		for (i = 0; i < weight_count; i++)
145 		{
146 			res->plane1_weights[i] = indices[2 * i];
147 			res->plane2_weights[i] = indices[2 * i + 1];
148 		}
149 	}
150 	else
151 	{
152 		decode_ise(weight_quantization_method, weight_count, bswapped, res->plane1_weights, 0);
153 	}
154 
155 	if (is_dual_plane && partition_count == 4)
156 		res->error_block = 1;
157 
158 	res->color_formats_matched = 0;
159 
160 	// then, determine the format of each endpoint pair
161 	int color_formats[4];
162 	int encoded_type_highpart_size = 0;
163 	if (partition_count == 1)
164 	{
165 		color_formats[0] = read_bits(4, 13, pb.data);
166 		res->partition_index = 0;
167 	}
168 	else
169 	{
170 		encoded_type_highpart_size = (3 * partition_count) - 4;
171 		below_weights_pos -= encoded_type_highpart_size;
172 		int encoded_type = read_bits(6, 13 + PARTITION_BITS, pb.data) | (read_bits(encoded_type_highpart_size, below_weights_pos, pb.data) << 6);
173 		int baseclass = encoded_type & 0x3;
174 		if (baseclass == 0)
175 		{
176 			for (i = 0; i < partition_count; i++)
177 			{
178 				color_formats[i] = (encoded_type >> 2) & 0xF;
179 			}
180 			below_weights_pos += encoded_type_highpart_size;
181 			res->color_formats_matched = 1;
182 			encoded_type_highpart_size = 0;
183 		}
184 		else
185 		{
186 			int bitpos = 2;
187 			baseclass--;
188 			for (i = 0; i < partition_count; i++)
189 			{
190 				color_formats[i] = (((encoded_type >> bitpos) & 1) + baseclass) << 2;
191 				bitpos++;
192 			}
193 			for (i = 0; i < partition_count; i++)
194 			{
195 				color_formats[i] |= (encoded_type >> bitpos) & 3;
196 				bitpos += 2;
197 			}
198 		}
199 		res->partition_index = read_bits(6, 13, pb.data) | (read_bits(PARTITION_BITS - 6, 19, pb.data) << 6);
200 	}
201 
202 	for (i = 0; i < partition_count; i++)
203 		res->color_formats[i] = color_formats[i];
204 
205 	// then, determine the number of integers we need to unpack for the endpoint pairs
206 	int color_integer_count = 0;
207 	for (i = 0; i < partition_count; i++)
208 	{
209 		int endpoint_class = color_formats[i] >> 2;
210 		color_integer_count += (endpoint_class + 1) * 2;
211 	}
212 
213 	if (color_integer_count > 18)
214 		res->error_block = 1;
215 
216 	// then, determine the color endpoint format to use for these integers
217 	static const int color_bits_arr[5] = { -1, 115 - 4, 113 - 4 - PARTITION_BITS, 113 - 4 - PARTITION_BITS, 113 - 4 - PARTITION_BITS };
218 	int color_bits = color_bits_arr[partition_count] - bits_for_weights - encoded_type_highpart_size;
219 	if (is_dual_plane)
220 		color_bits -= 2;
221 	if (color_bits < 0)
222 		color_bits = 0;
223 
224 	int color_quantization_level = quantization_mode_table[color_integer_count >> 1][color_bits];
225 	res->color_quantization_level = color_quantization_level;
226 	if (color_quantization_level < 4)
227 		res->error_block = 1;
228 
229 	// then unpack the integer-bits
230 	uint8_t values_to_decode[32];
231 	decode_ise(color_quantization_level, color_integer_count, pb.data, values_to_decode, (partition_count == 1 ? 17 : 19 + PARTITION_BITS));
232 
233 	// and distribute them over the endpoint types
234 	int valuecount_to_decode = 0;
235 
236 	for (i = 0; i < partition_count; i++)
237 	{
238 		int vals = 2 * (color_formats[i] >> 2) + 2;
239 		for (j = 0; j < vals; j++)
240 			res->color_values[i][j] = values_to_decode[j + valuecount_to_decode];
241 		valuecount_to_decode += vals;
242 	}
243 
244 	// get hold of color component for second-plane in the case of dual plane of weights.
245 	if (is_dual_plane)
246 		res->plane2_color_component = read_bits(2, below_weights_pos - 2, pb.data);
247 }
248