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