• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: Apache-2.0
2 // ----------------------------------------------------------------------------
3 // Copyright 2011-2023 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 ASTCENCCLI_INTERNAL_INCLUDED
23 #define ASTCENCCLI_INTERNAL_INCLUDED
24 
25 #include <cstddef>
26 #include <cstdint>
27 #include <cstdio>
28 #include <cstdlib>
29 
30 #include "astcenc.h"
31 #include "astcenc_mathlib.h"
32 
33 /**
34  * @brief The payload stored in a compressed ASTC image.
35  */
36 struct astc_compressed_image
37 {
38 	/** @brief The block width in texels. */
39 	unsigned int block_x;
40 
41 	/** @brief The block height in texels. */
42 	unsigned int block_y;
43 
44 	/** @brief The block depth in texels. */
45 	unsigned int block_z;
46 
47 	/** @brief The image width in texels. */
48 	unsigned int dim_x;
49 
50 	/** @brief The image height in texels. */
51 	unsigned int dim_y;
52 
53 	/** @brief The image depth in texels. */
54 	unsigned int dim_z;
55 
56 	/** @brief The binary data payload. */
57 	uint8_t* data;
58 
59 	/** @brief The binary data length in bytes. */
60 	size_t data_len;
61 };
62 
63 /**
64  * @brief Config options that have been read from command line.
65  */
66 struct cli_config_options
67 {
68 	/** @brief The number of threads to use for processing. */
69 	unsigned int thread_count;
70 
71 	/** @brief The number of repeats to execute for benchmarking. */
72 	unsigned int repeat_count;
73 
74 	/** @brief The number of image slices to load for a 3D image. */
75 	unsigned int array_size;
76 
77 	/** @brief @c true if running in silent mode with minimal output. */
78 	bool silentmode;
79 
80 	/** @brief @c true if the images should be y-flipped. */
81 	bool y_flip;
82 
83 	/** @brief @c true if diagnostic images should be stored. */
84 	bool diagnostic_images;
85 
86 	/** @brief The low exposure fstop for error computation. */
87 	int low_fstop;
88 
89 	/** @brief The high exposure fstop for error computation. */
90 	int high_fstop;
91 
92 	/** @brief The  pre-encode swizzle. */
93 	astcenc_swizzle swz_encode;
94 
95 	/** @brief The  post-decode swizzle. */
96 	astcenc_swizzle swz_decode;
97 };
98 
99 /**
100  * @brief Print a string to stderr.
101  */
print_error(const char * format)102 static inline void print_error(
103 	const char* format
104 ) {
105 	fprintf(stderr, "%s", format);
106 }
107 
108 /**
109  * @brief Print a formatted string to stderr.
110  */
111 template<typename ... _Args>
print_error(const char * format,_Args...args)112 static inline void print_error(
113 	const char* format,
114 	_Args...args
115 ) {
116 	fprintf(stderr, format, args...);
117 }
118 
119 /**
120  * @brief Load uncompressed image.
121  *
122  * @param filename               The file path on disk.
123  * @param y_flip                 Should this image be Y flipped?
124  * @param[out] is_hdr            Is the loaded image HDR?
125  * @param[out] component_count   The number of components in the loaded image.
126  *
127  * @return The astc image file, or nullptr on error.
128  */
129 astcenc_image* load_ncimage(
130 	const char* filename,
131 	bool y_flip,
132 	bool& is_hdr,
133 	unsigned int& component_count);
134 
135 /**
136  * @brief Load uncompressed PNG image.
137  *
138  * @param filename               The file path on disk.
139  * @param y_flip                 Should this image be Y flipped?
140  * @param[out] is_hdr            Is the loaded image HDR?
141  * @param[out] component_count   The number of components in the loaded image.
142  *
143  * @return The astc image file, or nullptr on error.
144  */
145 astcenc_image* load_png_with_wuffs(
146 	const char* filename,
147 	bool y_flip,
148 	bool& is_hdr,
149 	unsigned int& component_count);
150 
151 /**
152  * @brief Save an uncompressed image.
153  *
154  * @param img        The source data for the image.
155  * @param filename   The name of the file to save.
156  * @param y_flip     Should the image be vertically flipped?
157  *
158  * @return @c true if the image saved OK, @c false on error.
159  */
160 bool store_ncimage(
161 	const astcenc_image* img,
162 	const char* filename,
163 	int y_flip);
164 
165 /**
166  * @brief Check if the output file type requires a specific bitness.
167  *
168  * @param filename The file name, containing hte extension to check.
169  *
170  * @return Valid values are:
171  *     * -1 - error - unknown file type.
172  *     *  0 - no enforced bitness.
173  *     *  8 - enforced 8-bit UNORM.
174  *     * 16 - enforced 16-bit FP16.
175  */
176 int get_output_filename_enforced_bitness(
177 	const char* filename);
178 
179 /**
180  * @brief Allocate a new image in a canonical format.
181  *
182  * Allocated images must be freed with a @c free_image() call.
183  *
184  * @param bitness   The number of bits per component (8, 16, or 32).
185  * @param dim_x     The width of the image, in texels.
186  * @param dim_y     The height of the image, in texels.
187  * @param dim_z     The depth of the image, in texels.
188  *
189  * @return The allocated image, or @c nullptr on error.
190  */
191 astcenc_image* alloc_image(
192 	unsigned int bitness,
193 	unsigned int dim_x,
194 	unsigned int dim_y,
195 	unsigned int dim_z);
196 
197 /**
198  * @brief Free an image.
199  *
200  * @param img   The image to free.
201  */
202 void free_image(
203 	astcenc_image* img);
204 
205 /**
206  * @brief Determine the number of active components in an image.
207  *
208  * @param img   The image to analyze.
209  *
210  * @return The number of active components in the image.
211  */
212 int determine_image_components(
213 	const astcenc_image* img);
214 
215 /**
216  * @brief Load a compressed .astc image.
217  *
218  * @param filename   The file to load.
219  * @param img        The image to populate with loaded data.
220  *
221  * @return Non-zero on error, zero on success.
222  */
223 int load_cimage(
224 	const char* filename,
225 	astc_compressed_image& img);
226 
227 /**
228  * @brief Store a compressed .astc image.
229  *
230  * @param img        The image to store.
231  * @param filename   The file to save.
232  *
233  * @return Non-zero on error, zero on success.
234  */
235 int store_cimage(
236 	const astc_compressed_image& img,
237 	const char* filename);
238 
239 /**
240  * @brief Load a compressed .ktx image.
241  *
242  * @param filename   The file to load.
243  * @param is_srgb    Is this an sRGB encoded file?
244  * @param img        The image to populate with loaded data.
245  *
246  * @return Non-zero on error, zero on success.
247  */
248 bool load_ktx_compressed_image(
249 	const char* filename,
250 	bool& is_srgb,
251 	astc_compressed_image& img) ;
252 
253 /**
254  * @brief Store a compressed .ktx image.
255  *
256  * @param img        The image to store.
257  * @param filename   The file to store.
258  * @param is_srgb    Is this an sRGB encoded file?
259  *
260  * @return Non-zero on error, zero on success.
261  */
262 bool store_ktx_compressed_image(
263 	const astc_compressed_image& img,
264 	const char* filename,
265 	bool is_srgb);
266 
267 /**
268  * @brief Create an image from a 2D float data array.
269  *
270  * @param data     The raw input data.
271  * @param dim_x    The width of the image, in texels.
272  * @param dim_y    The height of the image, in texels.
273  * @param y_flip   Should this image be vertically flipped?
274  *
275  * @return The populated image.
276  */
277 astcenc_image* astc_img_from_floatx4_array(
278 	const float* data,
279 	unsigned int dim_x,
280 	unsigned int dim_y,
281 	bool y_flip);
282 
283 /**
284  * @brief Create an image from a 2D byte data array.
285  *
286  * @param data     The raw input data.
287  * @param dim_x    The width of the image, in texels.
288  * @param dim_y    The height of the image, in texels.
289  * @param y_flip   Should this image be vertically flipped?
290  *
291  * @return The populated image.
292  */
293 astcenc_image* astc_img_from_unorm8x4_array(
294 	const uint8_t* data,
295 	unsigned int dim_x,
296 	unsigned int dim_y,
297 	bool y_flip);
298 
299 /**
300  * @brief Create a flattened RGBA FLOAT32 data array for a single slice from an image structure.
301  *
302  * The returned data array is allocated with @c new[] and must be freed with a @c delete[] call.
303  *
304  * @param img       The input image.
305  * @param y_flip    Should the data in the array be Y flipped?
306  * @param z_index   The slice index to convert.
307  *
308  * @return The data array.
309  */
310 float* floatx4_array_from_astc_img(
311 	const astcenc_image* img,
312 	bool y_flip,
313 	unsigned int z_index);
314 
315 /**
316  * @brief Create a flattened RGBA UNORM8 data array from an image structure.
317  *
318  * The returned data array is allocated with @c new[] and must be freed with a @c delete[] call.
319  *
320  * @param img      The input image.
321  * @param y_flip   Should the data in the array be Y flipped?
322  *
323  * @return The data array.
324  */
325 uint8_t* unorm8x4_array_from_astc_img(
326 	const astcenc_image* img,
327 	bool y_flip);
328 
329 /* ============================================================================
330   Functions for printing build info and help messages
331 ============================================================================ */
332 
333 /**
334  * @brief Print the tool copyright and version header to stdout.
335  */
336 void astcenc_print_header();
337 
338 /**
339  * @brief Print the tool copyright, version, and short-form help to stdout.
340  */
341 void astcenc_print_shorthelp();
342 
343 /**
344  * @brief Print the tool copyright, version, and long-form help to stdout.
345  */
346 void astcenc_print_longhelp();
347 
348 /**
349  * @brief Compute error metrics comparing two images.
350  *
351  * @param compute_hdr_metrics      True if HDR metrics should be computed.
352  * @param compute_normal_metrics   True if normal map metrics should be computed.
353  * @param input_components         The number of input color components.
354  * @param img1                     The original image.
355  * @param img2                     The compressed image.
356  * @param fstop_lo                 The low exposure fstop (HDR only).
357  * @param fstop_hi                 The high exposure fstop (HDR only).
358  */
359 void compute_error_metrics(
360 	bool compute_hdr_metrics,
361 	bool compute_normal_metrics,
362 	int input_components,
363 	const astcenc_image* img1,
364 	const astcenc_image* img2,
365 	int fstop_lo,
366 	int fstop_hi);
367 
368 /**
369  * @brief Get the current time.
370  *
371  * @return The current time in seconds since arbitrary epoch.
372  */
373 double get_time();
374 
375 /**
376  * @brief Get the number of CPU cores.
377  *
378  * @return The number of online or onlineable CPU cores in the system.
379  */
380 int get_cpu_count();
381 
382 /**
383  * @brief Launch N worker threads and wait for them to complete.
384  *
385  * All threads run the same thread function, and have the same thread payload, but are given a
386  * unique thread ID (0 .. N-1) as a parameter to the run function to allow thread-specific behavior.
387  *
388  * @param operation      The name of the operation for this async task.
389  * @param thread_count   The number of threads to spawn.
390  * @param func           The function to execute. Must have the signature:
391  *                       void (int thread_count, int thread_id, void* payload)
392  * @param payload        Pointer to an opaque thread payload object.
393  */
394 void launch_threads(
395 	const char* operation,
396 	int thread_count,
397 	void (*func)(int, int, void*),
398 	void *payload);
399 
400 /**
401  * @brief The main entry point.
402  *
403  * @param argc   The number of arguments.
404  * @param argv   The vector of arguments.
405  *
406  * @return 0 on success, non-zero otherwise.
407  */
408 int astcenc_main(
409 	int argc,
410 	char **argv);
411 
412 #endif
413