| /////////////////////////////////////////////////////////////////////////////// | |
| // | |
| /// \file test_filter_flags.c | |
| /// \brief Tests Filter Flags coders | |
| // | |
| // Author: Lasse Collin | |
| // | |
| // This file has been put into the public domain. | |
| // You can do whatever you want with this file. | |
| // | |
| /////////////////////////////////////////////////////////////////////////////// | |
| #include "tests.h" | |
| static uint8_t buffer[4096]; | |
| static lzma_filter known_flags; | |
| static lzma_filter decoded_flags; | |
| static lzma_stream strm = LZMA_STREAM_INIT; | |
| static bool | |
| encode(uint32_t known_size) | |
| { | |
| memcrap(buffer, sizeof(buffer)); | |
| uint32_t tmp; | |
| if (lzma_filter_flags_size(&tmp, &known_flags) != LZMA_OK) | |
| return true; | |
| if (tmp != known_size) | |
| return true; | |
| size_t out_pos = 0; | |
| if (lzma_filter_flags_encode(&known_flags, | |
| buffer, &out_pos, known_size) != LZMA_OK) | |
| return true; | |
| if (out_pos != known_size) | |
| return true; | |
| return false; | |
| } | |
| static bool | |
| decode_ret(uint32_t known_size, lzma_ret expected_ret) | |
| { | |
| memcrap(&decoded_flags, sizeof(decoded_flags)); | |
| size_t pos = 0; | |
| if (lzma_filter_flags_decode(&decoded_flags, NULL, | |
| buffer, &pos, known_size) != expected_ret | |
| || pos != known_size) | |
| return true; | |
| return false; | |
| } | |
| static bool | |
| decode(uint32_t known_size) | |
| { | |
| if (decode_ret(known_size, LZMA_OK)) | |
| return true; | |
| if (known_flags.id != decoded_flags.id) | |
| return true; | |
| return false; | |
| } | |
| #if defined(HAVE_ENCODER_X86) && defined(HAVE_DECODER_X86) | |
| static void | |
| test_bcj(void) | |
| { | |
| // Test 1 | |
| known_flags.id = LZMA_FILTER_X86; | |
| known_flags.options = NULL; | |
| expect(!encode(2)); | |
| expect(!decode(2)); | |
| expect(decoded_flags.options == NULL); | |
| // Test 2 | |
| lzma_options_bcj options; | |
| options.start_offset = 0; | |
| known_flags.options = &options; | |
| expect(!encode(2)); | |
| expect(!decode(2)); | |
| expect(decoded_flags.options == NULL); | |
| // Test 3 | |
| options.start_offset = 123456; | |
| known_flags.options = &options; | |
| expect(!encode(6)); | |
| expect(!decode(6)); | |
| expect(decoded_flags.options != NULL); | |
| lzma_options_bcj *decoded = decoded_flags.options; | |
| expect(decoded->start_offset == options.start_offset); | |
| free(decoded); | |
| } | |
| #endif | |
| #if defined(HAVE_ENCODER_DELTA) && defined(HAVE_DECODER_DELTA) | |
| static void | |
| test_delta(void) | |
| { | |
| // Test 1 | |
| known_flags.id = LZMA_FILTER_DELTA; | |
| known_flags.options = NULL; | |
| expect(encode(99)); | |
| // Test 2 | |
| lzma_options_delta options = { | |
| .type = LZMA_DELTA_TYPE_BYTE, | |
| .dist = 0 | |
| }; | |
| known_flags.options = &options; | |
| expect(encode(99)); | |
| // Test 3 | |
| options.dist = LZMA_DELTA_DIST_MIN; | |
| expect(!encode(3)); | |
| expect(!decode(3)); | |
| expect(((lzma_options_delta *)(decoded_flags.options))->dist | |
| == options.dist); | |
| free(decoded_flags.options); | |
| // Test 4 | |
| options.dist = LZMA_DELTA_DIST_MAX; | |
| expect(!encode(3)); | |
| expect(!decode(3)); | |
| expect(((lzma_options_delta *)(decoded_flags.options))->dist | |
| == options.dist); | |
| free(decoded_flags.options); | |
| // Test 5 | |
| options.dist = LZMA_DELTA_DIST_MAX + 1; | |
| expect(encode(99)); | |
| } | |
| #endif | |
| /* | |
| #ifdef HAVE_FILTER_LZMA | |
| static void | |
| validate_lzma(void) | |
| { | |
| const lzma_options_lzma *known = known_flags.options; | |
| const lzma_options_lzma *decoded = decoded_flags.options; | |
| expect(known->dictionary_size <= decoded->dictionary_size); | |
| if (known->dictionary_size == 1) | |
| expect(decoded->dictionary_size == 1); | |
| else | |
| expect(known->dictionary_size + known->dictionary_size / 2 | |
| > decoded->dictionary_size); | |
| expect(known->literal_context_bits == decoded->literal_context_bits); | |
| expect(known->literal_pos_bits == decoded->literal_pos_bits); | |
| expect(known->pos_bits == decoded->pos_bits); | |
| } | |
| static void | |
| test_lzma(void) | |
| { | |
| // Test 1 | |
| known_flags.id = LZMA_FILTER_LZMA1; | |
| known_flags.options = NULL; | |
| expect(encode(99)); | |
| // Test 2 | |
| lzma_options_lzma options = { | |
| .dictionary_size = 0, | |
| .literal_context_bits = 0, | |
| .literal_pos_bits = 0, | |
| .pos_bits = 0, | |
| .preset_dictionary = NULL, | |
| .preset_dictionary_size = 0, | |
| .mode = LZMA_MODE_INVALID, | |
| .fast_bytes = 0, | |
| .match_finder = LZMA_MF_INVALID, | |
| .match_finder_cycles = 0, | |
| }; | |
| // Test 3 (empty dictionary not allowed) | |
| known_flags.options = &options; | |
| expect(encode(99)); | |
| // Test 4 (brute-force test some valid dictionary sizes) | |
| options.dictionary_size = LZMA_DICTIONARY_SIZE_MIN; | |
| while (options.dictionary_size != LZMA_DICTIONARY_SIZE_MAX) { | |
| if (++options.dictionary_size == 5000) | |
| options.dictionary_size = LZMA_DICTIONARY_SIZE_MAX - 5; | |
| expect(!encode(4)); | |
| expect(!decode(4)); | |
| validate_lzma(); | |
| free(decoded_flags.options); | |
| } | |
| // Test 5 (too big dictionary size) | |
| options.dictionary_size = LZMA_DICTIONARY_SIZE_MAX + 1; | |
| expect(encode(99)); | |
| // Test 6 (brute-force test lc/lp/pb) | |
| options.dictionary_size = LZMA_DICTIONARY_SIZE_MIN; | |
| for (uint32_t lc = LZMA_LITERAL_CONTEXT_BITS_MIN; | |
| lc <= LZMA_LITERAL_CONTEXT_BITS_MAX; ++lc) { | |
| for (uint32_t lp = LZMA_LITERAL_POS_BITS_MIN; | |
| lp <= LZMA_LITERAL_POS_BITS_MAX; ++lp) { | |
| for (uint32_t pb = LZMA_POS_BITS_MIN; | |
| pb <= LZMA_POS_BITS_MAX; ++pb) { | |
| if (lc + lp > LZMA_LITERAL_BITS_MAX) | |
| continue; | |
| options.literal_context_bits = lc; | |
| options.literal_pos_bits = lp; | |
| options.pos_bits = pb; | |
| expect(!encode(4)); | |
| expect(!decode(4)); | |
| validate_lzma(); | |
| free(decoded_flags.options); | |
| } | |
| } | |
| } | |
| } | |
| #endif | |
| */ | |
| int | |
| main(void) | |
| { | |
| #if defined(HAVE_ENCODER_X86) && defined(HAVE_DECODER_X86) | |
| test_bcj(); | |
| #endif | |
| #if defined(HAVE_ENCODER_DELTA) && defined(HAVE_DECODER_DELTA) | |
| test_delta(); | |
| #endif | |
| // #ifdef HAVE_FILTER_LZMA | |
| // test_lzma(); | |
| // #endif | |
| lzma_end(&strm); | |
| return 0; | |
| } |