]> icculus.org git repositories - icculus/xz.git/blob - tests/test_filter_flags.c
Put the interesting parts of XZ Utils into the public domain.
[icculus/xz.git] / tests / test_filter_flags.c
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       test_filter_flags.c
4 /// \brief      Tests Filter Flags coders
5 //
6 //  Author:     Lasse Collin
7 //
8 //  This file has been put into the public domain.
9 //  You can do whatever you want with this file.
10 //
11 ///////////////////////////////////////////////////////////////////////////////
12
13 #include "tests.h"
14
15
16 static uint8_t buffer[4096];
17 static lzma_filter known_flags;
18 static lzma_filter decoded_flags;
19 static lzma_stream strm = LZMA_STREAM_INIT;
20
21
22 static bool
23 encode(uint32_t known_size)
24 {
25         memcrap(buffer, sizeof(buffer));
26
27         uint32_t tmp;
28         if (lzma_filter_flags_size(&tmp, &known_flags) != LZMA_OK)
29                 return true;
30
31         if (tmp != known_size)
32                 return true;
33
34         size_t out_pos = 0;
35         if (lzma_filter_flags_encode(&known_flags,
36                         buffer, &out_pos, known_size) != LZMA_OK)
37                 return true;
38
39         if (out_pos != known_size)
40                 return true;
41
42         return false;
43 }
44
45
46 static bool
47 decode_ret(uint32_t known_size, lzma_ret expected_ret)
48 {
49         memcrap(&decoded_flags, sizeof(decoded_flags));
50
51         size_t pos = 0;
52         if (lzma_filter_flags_decode(&decoded_flags, NULL,
53                                 buffer, &pos, known_size) != expected_ret
54                         || pos != known_size)
55                 return true;
56
57         return false;
58 }
59
60
61 static bool
62 decode(uint32_t known_size)
63 {
64         if (decode_ret(known_size, LZMA_OK))
65                 return true;
66
67         if (known_flags.id != decoded_flags.id)
68                 return true;
69
70         return false;
71 }
72
73
74 #if defined(HAVE_ENCODER_SUBBLOCK) && defined(HAVE_DECODER_SUBBLOCK)
75 static void
76 test_subblock(void)
77 {
78         // Test 1
79         known_flags.id = LZMA_FILTER_SUBBLOCK;
80         known_flags.options = NULL;
81         expect(!encode(2));
82         expect(!decode(2));
83         expect(decoded_flags.options == NULL);
84
85         // Test 2
86         buffer[0] = LZMA_FILTER_SUBBLOCK;
87         buffer[1] = 1;
88         buffer[2] = 0;
89         expect(!decode_ret(3, LZMA_OPTIONS_ERROR));
90 }
91 #endif
92
93
94 #if defined(HAVE_ENCODER_X86) && defined(HAVE_DECODER_X86)
95 static void
96 test_bcj(void)
97 {
98         // Test 1
99         known_flags.id = LZMA_FILTER_X86;
100         known_flags.options = NULL;
101
102         expect(!encode(2));
103         expect(!decode(2));
104         expect(decoded_flags.options == NULL);
105
106         // Test 2
107         lzma_options_bcj options;
108         options.start_offset = 0;
109         known_flags.options = &options;
110         expect(!encode(2));
111         expect(!decode(2));
112         expect(decoded_flags.options == NULL);
113
114         // Test 3
115         options.start_offset = 123456;
116         known_flags.options = &options;
117         expect(!encode(6));
118         expect(!decode(6));
119         expect(decoded_flags.options != NULL);
120
121         lzma_options_bcj *decoded = decoded_flags.options;
122         expect(decoded->start_offset == options.start_offset);
123
124         free(decoded);
125 }
126 #endif
127
128
129 #if defined(HAVE_ENCODER_DELTA) && defined(HAVE_DECODER_DELTA)
130 static void
131 test_delta(void)
132 {
133         // Test 1
134         known_flags.id = LZMA_FILTER_DELTA;
135         known_flags.options = NULL;
136         expect(encode(99));
137
138         // Test 2
139         lzma_options_delta options = {
140                 .type = LZMA_DELTA_TYPE_BYTE,
141                 .dist = 0
142         };
143         known_flags.options = &options;
144         expect(encode(99));
145
146         // Test 3
147         options.dist = LZMA_DELTA_DIST_MIN;
148         expect(!encode(3));
149         expect(!decode(3));
150         expect(((lzma_options_delta *)(decoded_flags.options))->dist
151                         == options.dist);
152
153         free(decoded_flags.options);
154
155         // Test 4
156         options.dist = LZMA_DELTA_DIST_MAX;
157         expect(!encode(3));
158         expect(!decode(3));
159         expect(((lzma_options_delta *)(decoded_flags.options))->dist
160                         == options.dist);
161
162         free(decoded_flags.options);
163
164         // Test 5
165         options.dist = LZMA_DELTA_DIST_MAX + 1;
166         expect(encode(99));
167 }
168 #endif
169
170 /*
171 #ifdef HAVE_FILTER_LZMA
172 static void
173 validate_lzma(void)
174 {
175         const lzma_options_lzma *known = known_flags.options;
176         const lzma_options_lzma *decoded = decoded_flags.options;
177
178         expect(known->dictionary_size <= decoded->dictionary_size);
179
180         if (known->dictionary_size == 1)
181                 expect(decoded->dictionary_size == 1);
182         else
183                 expect(known->dictionary_size + known->dictionary_size / 2
184                                 > decoded->dictionary_size);
185
186         expect(known->literal_context_bits == decoded->literal_context_bits);
187         expect(known->literal_pos_bits == decoded->literal_pos_bits);
188         expect(known->pos_bits == decoded->pos_bits);
189 }
190
191
192 static void
193 test_lzma(void)
194 {
195         // Test 1
196         known_flags.id = LZMA_FILTER_LZMA1;
197         known_flags.options = NULL;
198         expect(encode(99));
199
200         // Test 2
201         lzma_options_lzma options = {
202                 .dictionary_size = 0,
203                 .literal_context_bits = 0,
204                 .literal_pos_bits = 0,
205                 .pos_bits = 0,
206                 .preset_dictionary = NULL,
207                 .preset_dictionary_size = 0,
208                 .mode = LZMA_MODE_INVALID,
209                 .fast_bytes = 0,
210                 .match_finder = LZMA_MF_INVALID,
211                 .match_finder_cycles = 0,
212         };
213
214         // Test 3 (empty dictionary not allowed)
215         known_flags.options = &options;
216         expect(encode(99));
217
218         // Test 4 (brute-force test some valid dictionary sizes)
219         options.dictionary_size = LZMA_DICTIONARY_SIZE_MIN;
220         while (options.dictionary_size != LZMA_DICTIONARY_SIZE_MAX) {
221                 if (++options.dictionary_size == 5000)
222                         options.dictionary_size = LZMA_DICTIONARY_SIZE_MAX - 5;
223
224                 expect(!encode(4));
225                 expect(!decode(4));
226                 validate_lzma();
227
228                 free(decoded_flags.options);
229         }
230
231         // Test 5 (too big dictionary size)
232         options.dictionary_size = LZMA_DICTIONARY_SIZE_MAX + 1;
233         expect(encode(99));
234
235         // Test 6 (brute-force test lc/lp/pb)
236         options.dictionary_size = LZMA_DICTIONARY_SIZE_MIN;
237         for (uint32_t lc = LZMA_LITERAL_CONTEXT_BITS_MIN;
238                         lc <= LZMA_LITERAL_CONTEXT_BITS_MAX; ++lc) {
239                 for (uint32_t lp = LZMA_LITERAL_POS_BITS_MIN;
240                                 lp <= LZMA_LITERAL_POS_BITS_MAX; ++lp) {
241                         for (uint32_t pb = LZMA_POS_BITS_MIN;
242                                         pb <= LZMA_POS_BITS_MAX; ++pb) {
243                                 if (lc + lp > LZMA_LITERAL_BITS_MAX)
244                                         continue;
245
246                                 options.literal_context_bits = lc;
247                                 options.literal_pos_bits = lp;
248                                 options.pos_bits = pb;
249
250                                 expect(!encode(4));
251                                 expect(!decode(4));
252                                 validate_lzma();
253
254                                 free(decoded_flags.options);
255                         }
256                 }
257         }
258 }
259 #endif
260 */
261
262 int
263 main(void)
264 {
265 #if defined(HAVE_ENCODER_SUBBLOCK) && defined(HAVE_DECODER_SUBBLOCK)
266         test_subblock();
267 #endif
268 #if defined(HAVE_ENCODER_X86) && defined(HAVE_DECODER_X86)
269         test_bcj();
270 #endif
271 #if defined(HAVE_ENCODER_DELTA) && defined(HAVE_DECODER_DELTA)
272         test_delta();
273 #endif
274 // #ifdef HAVE_FILTER_LZMA
275 //      test_lzma();
276 // #endif
277
278         lzma_end(&strm);
279
280         return 0;
281 }