/src/astc-encoder/Source/Fuzzers/fuzz_astc_compress.cpp
Line | Count | Source |
1 | | // SPDX-License-Identifier: Apache-2.0 |
2 | | // ---------------------------------------------------------------------------- |
3 | | // Copyright 2026 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 | | #include "astcenc.h" |
19 | | #include <fuzzer/FuzzedDataProvider.h> |
20 | | #include <vector> |
21 | | |
22 | | extern "C" int LLVMFuzzerTestOneInput( |
23 | | const uint8_t *data, |
24 | | size_t size |
25 | 3.53k | ) { |
26 | 3.53k | FuzzedDataProvider fdp(data, size); |
27 | | |
28 | | // Randomize block size |
29 | 3.53k | static const struct { uint8_t x, y; } block_sizes[] = { |
30 | 3.53k | {4, 4}, {5, 4}, {5, 5}, {6, 5}, {6, 6}, {8, 5}, {8, 6}, {8, 8}, |
31 | 3.53k | {10, 5}, {10, 6}, {10, 8}, {10, 10}, {12, 10}, {12, 12} |
32 | 3.53k | }; |
33 | | |
34 | 3.53k | int bs_idx = fdp.ConsumeIntegralInRange<int>(0, (sizeof(block_sizes) / sizeof(block_sizes[0])) - 1); |
35 | 3.53k | uint32_t block_x = block_sizes[bs_idx].x; |
36 | 3.53k | uint32_t block_y = block_sizes[bs_idx].y; |
37 | 3.53k | uint32_t block_z = 1; |
38 | | |
39 | | // Randomize profile |
40 | 3.53k | astcenc_profile profile = (astcenc_profile)fdp.ConsumeIntegralInRange<int>(0, 3); |
41 | | |
42 | | // Randomize quality |
43 | | // For compression, high quality is very slow. Let's limit it for fuzzing. |
44 | 3.53k | float quality = fdp.ConsumeFloatingPointInRange<float>(ASTCENC_PRE_FASTEST, ASTCENC_PRE_MEDIUM); |
45 | | |
46 | | // Randomize flags |
47 | 3.53k | unsigned int flags = fdp.ConsumeIntegralInRange<unsigned int>(0, ASTCENC_ALL_FLAGS); |
48 | | // Don't use decompress-only flag for compression fuzzer |
49 | 3.53k | flags &= ~ASTCENC_FLG_DECOMPRESS_ONLY; |
50 | | |
51 | 3.53k | astcenc_config config; |
52 | 3.53k | astcenc_error status = astcenc_config_init(profile, block_x, block_y, block_z, quality, flags, &config); |
53 | 3.53k | if (status != ASTCENC_SUCCESS) |
54 | 42 | { |
55 | 42 | return 0; |
56 | 42 | } |
57 | | |
58 | 3.49k | astcenc_context* context = nullptr; |
59 | 3.49k | status = astcenc_context_alloc(&config, 1, &context, nullptr); |
60 | 3.49k | if (status != ASTCENC_SUCCESS) |
61 | 0 | { |
62 | 0 | return 0; |
63 | 0 | } |
64 | | |
65 | | // Image dimensions - small to keep it fast |
66 | 3.49k | uint32_t dim_x = block_x; |
67 | 3.49k | uint32_t dim_y = block_y; |
68 | 3.49k | uint32_t dim_z = 1; |
69 | | |
70 | 3.49k | astcenc_image image; |
71 | 3.49k | image.dim_x = dim_x; |
72 | 3.49k | image.dim_y = dim_y; |
73 | 3.49k | image.dim_z = dim_z; |
74 | 3.49k | image.data_type = ASTCENC_TYPE_U8; |
75 | | |
76 | 3.49k | size_t input_data_len = dim_x * dim_y * 4; |
77 | 3.49k | if (fdp.remaining_bytes() < input_data_len) |
78 | 247 | { |
79 | 247 | astcenc_context_free(context); |
80 | 247 | return 0; |
81 | 247 | } |
82 | | |
83 | 3.24k | std::vector<uint8_t> input_data = fdp.ConsumeBytes<uint8_t>(input_data_len); |
84 | 3.24k | void* slices[] = { input_data.data() }; |
85 | 3.24k | image.data = slices; |
86 | | |
87 | 3.24k | astcenc_swizzle swizzle = { |
88 | 3.24k | ASTCENC_SWZ_R, ASTCENC_SWZ_G, ASTCENC_SWZ_B, ASTCENC_SWZ_A |
89 | 3.24k | }; |
90 | | |
91 | 3.24k | size_t compressed_data_len = 16; // One block |
92 | 3.24k | std::vector<uint8_t> compressed_data(compressed_data_len); |
93 | | |
94 | 3.24k | status = astcenc_compress_image(context, &image, &swizzle, compressed_data.data(), compressed_data.size(), 0); |
95 | | |
96 | 3.24k | astcenc_context_free(context); |
97 | | |
98 | 3.24k | return 0; |
99 | 3.49k | } |