1 ///////////////////////////////////////////////////////////////////////////////
3 /// \file test_filter_flags.c
4 /// \brief Tests Filter Flags coders
6 // Copyright (C) 2007 Lasse Collin
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
18 ///////////////////////////////////////////////////////////////////////////////
23 static uint8_t buffer[4096];
24 static lzma_options_filter known_flags;
25 static lzma_options_filter decoded_flags;
26 static lzma_stream strm = LZMA_STREAM_INIT;
30 encode(uint32_t known_size)
32 memcrap(buffer, sizeof(buffer));
35 if (lzma_filter_flags_size(&tmp, &known_flags) != LZMA_OK)
38 if (tmp != known_size)
42 if (lzma_filter_flags_encode(buffer, &out_pos, known_size,
43 &known_flags) != LZMA_OK)
46 if (out_pos != known_size)
54 decode_ret(uint32_t known_size, lzma_ret ret_ok)
56 memcrap(&decoded_flags, sizeof(decoded_flags));
58 if (lzma_filter_flags_decoder(&strm, &decoded_flags) != LZMA_OK)
61 if (decoder_loop_ret(&strm, buffer, known_size, ret_ok))
69 decode(uint32_t known_size)
71 if (decode_ret(known_size, LZMA_STREAM_END))
74 if (known_flags.id != decoded_flags.id)
85 known_flags.id = LZMA_FILTER_COPY;
86 known_flags.options = NULL;
90 expect(decoded_flags.options == NULL);
92 // Test 2 (invalid encoder options)
93 known_flags.options = &known_flags;
96 // Test 3 (good but unusual Filter Flags field)
98 buffer[1] = LZMA_FILTER_COPY;
100 expect(decoded_flags.options == NULL);
102 // Test 4 (invalid Filter Flags field)
104 buffer[1] = LZMA_FILTER_COPY;
106 expect(!decode_ret(3, LZMA_HEADER_ERROR));
108 // Test 5 (good but weird Filter Flags field)
110 buffer[1] = LZMA_FILTER_COPY;
113 expect(decoded_flags.options == NULL);
115 // Test 6 (invalid Filter Flags field)
117 buffer[1] = LZMA_FILTER_COPY;
120 expect(!decode_ret(4, LZMA_HEADER_ERROR));
128 known_flags.id = LZMA_FILTER_SUBBLOCK;
129 known_flags.options = NULL;
133 expect(decoded_flags.options != NULL);
134 expect(((lzma_options_subblock *)(decoded_flags.options))
138 known_flags.options = decoded_flags.options;
141 expect(decoded_flags.options != NULL);
142 expect(((lzma_options_subblock *)(decoded_flags.options))
145 free(decoded_flags.options);
146 free(known_flags.options);
150 buffer[1] = LZMA_FILTER_SUBBLOCK;
153 expect(!decode_ret(4, LZMA_HEADER_ERROR));
161 known_flags.id = LZMA_FILTER_X86;
162 known_flags.options = NULL;
166 expect(decoded_flags.options == NULL);
169 lzma_options_simple options;
170 options.start_offset = 0;
171 known_flags.options = &options;
174 expect(decoded_flags.options == NULL);
177 options.start_offset = 123456;
178 known_flags.options = &options;
181 expect(decoded_flags.options != NULL);
183 lzma_options_simple *decoded = decoded_flags.options;
184 expect(decoded->start_offset == options.start_offset);
194 known_flags.id = LZMA_FILTER_DELTA;
195 known_flags.options = NULL;
199 lzma_options_delta options = { 0 };
200 known_flags.options = &options;
204 options.distance = LZMA_DELTA_DISTANCE_MIN;
207 expect(((lzma_options_delta *)(decoded_flags.options))
208 ->distance == options.distance);
210 free(decoded_flags.options);
213 options.distance = LZMA_DELTA_DISTANCE_MAX;
216 expect(((lzma_options_delta *)(decoded_flags.options))
217 ->distance == options.distance);
219 free(decoded_flags.options);
222 options.distance = LZMA_DELTA_DISTANCE_MAX + 1;
230 const lzma_options_lzma *known = known_flags.options;
231 const lzma_options_lzma *decoded = decoded_flags.options;
233 expect(known->dictionary_size <= decoded->dictionary_size);
235 if (known->dictionary_size == 1)
236 expect(decoded->dictionary_size == 1);
238 expect(known->dictionary_size + known->dictionary_size / 2
239 > decoded->dictionary_size);
241 expect(known->literal_context_bits == decoded->literal_context_bits);
242 expect(known->literal_pos_bits == decoded->literal_pos_bits);
243 expect(known->pos_bits == decoded->pos_bits);
251 known_flags.id = LZMA_FILTER_LZMA;
252 known_flags.options = NULL;
256 lzma_options_lzma options = {
257 .dictionary_size = 0,
258 .literal_context_bits = 0,
259 .literal_pos_bits = 0,
261 .preset_dictionary = NULL,
262 .preset_dictionary_size = 0,
263 .mode = LZMA_MODE_INVALID,
265 .match_finder = LZMA_MF_INVALID,
266 .match_finder_cycles = 0,
269 // Test 3 (empty dictionary not allowed)
270 known_flags.options = &options;
273 // Test 4 (brute-force test some valid dictionary sizes)
274 while (options.dictionary_size != LZMA_DICTIONARY_SIZE_MAX) {
275 if (++options.dictionary_size == 5000)
276 options.dictionary_size = LZMA_DICTIONARY_SIZE_MAX - 5;
282 free(decoded_flags.options);
285 // Test 5 (too big dictionary size)
286 options.dictionary_size = LZMA_DICTIONARY_SIZE_MAX + 1;
289 // Test 6 (brute-force test lc/lp/pb)
290 options.dictionary_size = 1;
291 for (uint32_t lc = LZMA_LITERAL_CONTEXT_BITS_MIN;
292 lc <= LZMA_LITERAL_CONTEXT_BITS_MAX; ++lc) {
293 for (uint32_t lp = LZMA_LITERAL_POS_BITS_MIN;
294 lp <= LZMA_LITERAL_POS_BITS_MAX; ++lp) {
295 for (uint32_t pb = LZMA_POS_BITS_MIN;
296 pb <= LZMA_POS_BITS_MAX; ++pb) {
297 options.literal_context_bits = lc;
298 options.literal_pos_bits = lp;
299 options.pos_bits = pb;
305 free(decoded_flags.options);