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 16static uint8_t buffer[4096]; 17static lzma_filter known_flags; 18static lzma_filter decoded_flags; 19static lzma_stream strm = LZMA_STREAM_INIT; 20 21 22static bool 23encode(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 46static bool 47decode_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 61static bool 62decode(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_X86) && defined(HAVE_DECODER_X86) 75static void 76test_bcj(void) 77{ 78 // Test 1 79 known_flags.id = LZMA_FILTER_X86; 80 known_flags.options = NULL; 81 82 expect(!encode(2)); 83 expect(!decode(2)); 84 expect(decoded_flags.options == NULL); 85 86 // Test 2 87 lzma_options_bcj options; 88 options.start_offset = 0; 89 known_flags.options = &options; 90 expect(!encode(2)); 91 expect(!decode(2)); 92 expect(decoded_flags.options == NULL); 93 94 // Test 3 95 options.start_offset = 123456; 96 known_flags.options = &options; 97 expect(!encode(6)); 98 expect(!decode(6)); 99 expect(decoded_flags.options != NULL); 100 101 lzma_options_bcj *decoded = decoded_flags.options; 102 expect(decoded->start_offset == options.start_offset); 103 104 free(decoded); 105} 106#endif 107 108 109#if defined(HAVE_ENCODER_DELTA) && defined(HAVE_DECODER_DELTA) 110static void 111test_delta(void) 112{ 113 // Test 1 114 known_flags.id = LZMA_FILTER_DELTA; 115 known_flags.options = NULL; 116 expect(encode(99)); 117 118 // Test 2 119 lzma_options_delta options = { 120 .type = LZMA_DELTA_TYPE_BYTE, 121 .dist = 0 122 }; 123 known_flags.options = &options; 124 expect(encode(99)); 125 126 // Test 3 127 options.dist = LZMA_DELTA_DIST_MIN; 128 expect(!encode(3)); 129 expect(!decode(3)); 130 expect(((lzma_options_delta *)(decoded_flags.options))->dist 131 == options.dist); 132 133 free(decoded_flags.options); 134 135 // Test 4 136 options.dist = LZMA_DELTA_DIST_MAX; 137 expect(!encode(3)); 138 expect(!decode(3)); 139 expect(((lzma_options_delta *)(decoded_flags.options))->dist 140 == options.dist); 141 142 free(decoded_flags.options); 143 144 // Test 5 145 options.dist = LZMA_DELTA_DIST_MAX + 1; 146 expect(encode(99)); 147} 148#endif 149 150/* 151#ifdef HAVE_FILTER_LZMA 152static void 153validate_lzma(void) 154{ 155 const lzma_options_lzma *known = known_flags.options; 156 const lzma_options_lzma *decoded = decoded_flags.options; 157 158 expect(known->dictionary_size <= decoded->dictionary_size); 159 160 if (known->dictionary_size == 1) 161 expect(decoded->dictionary_size == 1); 162 else 163 expect(known->dictionary_size + known->dictionary_size / 2 164 > decoded->dictionary_size); 165 166 expect(known->literal_context_bits == decoded->literal_context_bits); 167 expect(known->literal_pos_bits == decoded->literal_pos_bits); 168 expect(known->pos_bits == decoded->pos_bits); 169} 170 171 172static void 173test_lzma(void) 174{ 175 // Test 1 176 known_flags.id = LZMA_FILTER_LZMA1; 177 known_flags.options = NULL; 178 expect(encode(99)); 179 180 // Test 2 181 lzma_options_lzma options = { 182 .dictionary_size = 0, 183 .literal_context_bits = 0, 184 .literal_pos_bits = 0, 185 .pos_bits = 0, 186 .preset_dictionary = NULL, 187 .preset_dictionary_size = 0, 188 .mode = LZMA_MODE_INVALID, 189 .fast_bytes = 0, 190 .match_finder = LZMA_MF_INVALID, 191 .match_finder_cycles = 0, 192 }; 193 194 // Test 3 (empty dictionary not allowed) 195 known_flags.options = &options; 196 expect(encode(99)); 197 198 // Test 4 (brute-force test some valid dictionary sizes) 199 options.dictionary_size = LZMA_DICTIONARY_SIZE_MIN; 200 while (options.dictionary_size != LZMA_DICTIONARY_SIZE_MAX) { 201 if (++options.dictionary_size == 5000) 202 options.dictionary_size = LZMA_DICTIONARY_SIZE_MAX - 5; 203 204 expect(!encode(4)); 205 expect(!decode(4)); 206 validate_lzma(); 207 208 free(decoded_flags.options); 209 } 210 211 // Test 5 (too big dictionary size) 212 options.dictionary_size = LZMA_DICTIONARY_SIZE_MAX + 1; 213 expect(encode(99)); 214 215 // Test 6 (brute-force test lc/lp/pb) 216 options.dictionary_size = LZMA_DICTIONARY_SIZE_MIN; 217 for (uint32_t lc = LZMA_LITERAL_CONTEXT_BITS_MIN; 218 lc <= LZMA_LITERAL_CONTEXT_BITS_MAX; ++lc) { 219 for (uint32_t lp = LZMA_LITERAL_POS_BITS_MIN; 220 lp <= LZMA_LITERAL_POS_BITS_MAX; ++lp) { 221 for (uint32_t pb = LZMA_POS_BITS_MIN; 222 pb <= LZMA_POS_BITS_MAX; ++pb) { 223 if (lc + lp > LZMA_LITERAL_BITS_MAX) 224 continue; 225 226 options.literal_context_bits = lc; 227 options.literal_pos_bits = lp; 228 options.pos_bits = pb; 229 230 expect(!encode(4)); 231 expect(!decode(4)); 232 validate_lzma(); 233 234 free(decoded_flags.options); 235 } 236 } 237 } 238} 239#endif 240*/ 241 242int 243main(void) 244{ 245#if defined(HAVE_ENCODER_X86) && defined(HAVE_DECODER_X86) 246 test_bcj(); 247#endif 248#if defined(HAVE_ENCODER_DELTA) && defined(HAVE_DECODER_DELTA) 249 test_delta(); 250#endif 251// #ifdef HAVE_FILTER_LZMA 252// test_lzma(); 253// #endif 254 255 lzma_end(&strm); 256 257 return 0; 258} 259