aboutsummaryrefslogtreecommitdiff
path: root/dep
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2014-10-10 20:17:30 +0200
committerShauren <shauren.trinity@gmail.com>2014-10-10 20:17:30 +0200
commit88ae3da6373dee1f04d03b823ee63d6f1db1502e (patch)
treef9ac27f0a743a57b70e90b37f5971e024992eb00 /dep
parentbc97908822c4afa23740ce70151c2486c340e2c2 (diff)
Tools/Extractors: Updated map extractor
Diffstat (limited to 'dep')
-rw-r--r--dep/CMakeLists.txt2
-rw-r--r--dep/CascLib/CMakeLists.txt42
-rw-r--r--dep/CascLib/LICENSE21
-rw-r--r--dep/CascLib/README.md4
-rw-r--r--dep/CascLib/doc/history.txt10
-rw-r--r--dep/CascLib/src/CascBuildCfg.cpp922
-rw-r--r--dep/CascLib/src/CascCommon.cpp67
-rw-r--r--dep/CascLib/src/CascCommon.h374
-rw-r--r--dep/CascLib/src/CascDecompress.cpp83
-rw-r--r--dep/CascLib/src/CascDumpData.cpp524
-rw-r--r--dep/CascLib/src/CascFindFile.cpp364
-rw-r--r--dep/CascLib/src/CascLib.h171
-rw-r--r--dep/CascLib/src/CascMndxRoot.cpp3476
-rw-r--r--dep/CascLib/src/CascMndxRoot.h365
-rw-r--r--dep/CascLib/src/CascMndxRoot_x86.asm4369
-rw-r--r--dep/CascLib/src/CascOpenFile.cpp440
-rw-r--r--dep/CascLib/src/CascOpenStorage.cpp1226
-rw-r--r--dep/CascLib/src/CascPort.h (renamed from dep/StormLib/src/StormPort.h)105
-rw-r--r--dep/CascLib/src/CascReadFile.cpp475
-rw-r--r--dep/CascLib/src/common/Common.cpp672
-rw-r--r--dep/CascLib/src/common/Common.h98
-rw-r--r--dep/CascLib/src/common/Directory.cpp102
-rw-r--r--dep/CascLib/src/common/FileStream.cpp2721
-rw-r--r--dep/CascLib/src/common/FileStream.h238
-rw-r--r--dep/CascLib/src/common/ListFile.cpp266
-rw-r--r--dep/CascLib/src/common/ListFile.h18
-rw-r--r--dep/CascLib/src/common/Map.cpp178
-rw-r--r--dep/CascLib/src/common/Map.h39
-rw-r--r--dep/CascLib/src/jenkins/lookup.h (renamed from dep/StormLib/src/jenkins/lookup.h)0
-rw-r--r--dep/CascLib/src/jenkins/lookup3.c (renamed from dep/StormLib/src/jenkins/lookup3.c)0
-rw-r--r--dep/CascLib/src/libtomcrypt/src/hashes/hash_memory.c (renamed from dep/StormLib/src/libtomcrypt/src/hashes/hash_memory.c)0
-rw-r--r--dep/CascLib/src/libtomcrypt/src/hashes/md5.c (renamed from dep/StormLib/src/libtomcrypt/src/hashes/md5.c)0
-rw-r--r--dep/CascLib/src/libtomcrypt/src/headers/tomcrypt.h (renamed from dep/StormLib/src/libtomcrypt/src/headers/tomcrypt.h)0
-rw-r--r--dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_argchk.h (renamed from dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_argchk.h)0
-rw-r--r--dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h (renamed from dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h)0
-rw-r--r--dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_cipher.h (renamed from dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_cipher.h)0
-rw-r--r--dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_custom.h (renamed from dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_custom.h)0
-rw-r--r--dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_hash.h (renamed from dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_hash.h)0
-rw-r--r--dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_mac.h (renamed from dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_mac.h)0
-rw-r--r--dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_macros.h (renamed from dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_macros.h)0
-rw-r--r--dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_math.h (renamed from dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_math.h)0
-rw-r--r--dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_misc.h (renamed from dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_misc.h)0
-rw-r--r--dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_pk.h (renamed from dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_pk.h)0
-rw-r--r--dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_pkcs.h (renamed from dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_pkcs.h)0
-rw-r--r--dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_prng.h (renamed from dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_prng.h)0
-rw-r--r--dep/CascLib/src/libtomcrypt/src/misc/crypt_argchk.c (renamed from dep/StormLib/src/libtomcrypt/src/misc/crypt_argchk.c)0
-rw-r--r--dep/CascLib/src/libtomcrypt/src/misc/crypt_hash_descriptor.c (renamed from dep/StormLib/src/libtomcrypt/src/misc/crypt_hash_descriptor.c)0
-rw-r--r--dep/CascLib/src/libtomcrypt/src/misc/crypt_hash_is_valid.c (renamed from dep/StormLib/src/libtomcrypt/src/misc/crypt_hash_is_valid.c)0
-rw-r--r--dep/CascLib/src/libtomcrypt/src/misc/crypt_libc.c (renamed from dep/StormLib/src/libtomcrypt/src/misc/crypt_libc.c)0
-rw-r--r--dep/StormLib/CMakeLists.txt272
-rw-r--r--dep/StormLib/doc/History.txt62
-rw-r--r--dep/StormLib/doc/Sector Offset MD5.txt25
-rw-r--r--dep/StormLib/doc/The MoPaQ File Format 0.9.txt318
-rw-r--r--dep/StormLib/doc/The MoPaQ File Format 1.0.txt433
-rw-r--r--dep/StormLib/doc/d3-authenticationcode-deDE.txt1
-rw-r--r--dep/StormLib/doc/d3-authenticationcode-enGB.txt1
-rw-r--r--dep/StormLib/doc/d3-authenticationcode-enSG.txt1
-rw-r--r--dep/StormLib/doc/d3-authenticationcode-enUS.txt1
-rw-r--r--dep/StormLib/doc/d3-authenticationcode-esES.txt1
-rw-r--r--dep/StormLib/doc/d3-authenticationcode-esMX.txt1
-rw-r--r--dep/StormLib/doc/d3-authenticationcode-frFR.txt1
-rw-r--r--dep/StormLib/doc/d3-authenticationcode-itIT.txt1
-rw-r--r--dep/StormLib/doc/d3-authenticationcode-koKR.txt1
-rw-r--r--dep/StormLib/doc/d3-authenticationcode-plPL.txt1
-rw-r--r--dep/StormLib/doc/d3-authenticationcode-ptBR.txt1
-rw-r--r--dep/StormLib/doc/d3-authenticationcode-zhTW.txt1
-rw-r--r--dep/StormLib/doc/diablo3_ruru_disk_encrypted_win.blob49
-rw-r--r--dep/StormLib/doc/diablo3_urls.txt14
-rw-r--r--dep/StormLib/src/FileStream.cpp2294
-rw-r--r--dep/StormLib/src/FileStream.h189
-rw-r--r--dep/StormLib/src/SBaseCommon.cpp1700
-rw-r--r--dep/StormLib/src/SBaseDumpData.cpp144
-rw-r--r--dep/StormLib/src/SBaseFileTable.cpp2550
-rw-r--r--dep/StormLib/src/SCompression.cpp1135
-rw-r--r--dep/StormLib/src/SFileAddFile.cpp1286
-rw-r--r--dep/StormLib/src/SFileAttributes.cpp477
-rw-r--r--dep/StormLib/src/SFileCompactArchive.cpp765
-rw-r--r--dep/StormLib/src/SFileCreateArchive.cpp255
-rw-r--r--dep/StormLib/src/SFileExtractFile.cpp67
-rw-r--r--dep/StormLib/src/SFileFindFile.cpp446
-rw-r--r--dep/StormLib/src/SFileListFile.cpp557
-rw-r--r--dep/StormLib/src/SFileOpenArchive.cpp470
-rw-r--r--dep/StormLib/src/SFileOpenFileEx.cpp469
-rw-r--r--dep/StormLib/src/SFilePatchArchives.cpp587
-rw-r--r--dep/StormLib/src/SFileReadFile.cpp1183
-rw-r--r--dep/StormLib/src/SFileVerify.cpp921
-rw-r--r--dep/StormLib/src/StormCommon.h274
-rw-r--r--dep/StormLib/src/StormLib.h984
-rw-r--r--dep/StormLib/src/adpcm/adpcm.cpp358
-rw-r--r--dep/StormLib/src/adpcm/adpcm.h22
-rw-r--r--dep/StormLib/src/bzip2/blocksort.c1094
-rw-r--r--dep/StormLib/src/bzip2/bzlib.c1573
-rw-r--r--dep/StormLib/src/bzip2/bzlib.h282
-rw-r--r--dep/StormLib/src/bzip2/bzlib_private.h509
-rw-r--r--dep/StormLib/src/bzip2/compress.c672
-rw-r--r--dep/StormLib/src/bzip2/crctable.c104
-rw-r--r--dep/StormLib/src/bzip2/decompress.c626
-rw-r--r--dep/StormLib/src/bzip2/huffman.c205
-rw-r--r--dep/StormLib/src/bzip2/randtable.c84
-rw-r--r--dep/StormLib/src/huffman/huff.cpp1303
-rw-r--r--dep/StormLib/src/huffman/huff.h142
-rw-r--r--dep/StormLib/src/huffman/huff_patch.cpp1120
-rw-r--r--dep/StormLib/src/huffman/huff_patch.h145
-rw-r--r--dep/StormLib/src/libtomcrypt/src/hashes/sha1.c288
-rw-r--r--dep/StormLib/src/libtomcrypt/src/math/ltm_desc.c483
-rw-r--r--dep/StormLib/src/libtomcrypt/src/math/multi.c61
-rw-r--r--dep/StormLib/src/libtomcrypt/src/math/rand_prime.c87
-rw-r--r--dep/StormLib/src/libtomcrypt/src/misc/base64_decode.c104
-rw-r--r--dep/StormLib/src/libtomcrypt/src/misc/crypt_find_hash.c40
-rw-r--r--dep/StormLib/src/libtomcrypt/src/misc/crypt_find_prng.c41
-rw-r--r--dep/StormLib/src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c13
-rw-r--r--dep/StormLib/src/libtomcrypt/src/misc/crypt_prng_descriptor.c26
-rw-r--r--dep/StormLib/src/libtomcrypt/src/misc/crypt_prng_is_valid.c36
-rw-r--r--dep/StormLib/src/libtomcrypt/src/misc/crypt_register_hash.c54
-rw-r--r--dep/StormLib/src/libtomcrypt/src/misc/crypt_register_prng.c54
-rw-r--r--dep/StormLib/src/libtomcrypt/src/misc/zeromem.c34
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c102
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_boolean.c47
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_choice.c182
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c96
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_integer.c110
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c99
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c91
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c96
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c287
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c386
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c139
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c68
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utctime.c127
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c111
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_bit_string.c54
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_boolean.c35
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c194
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_integer.c82
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c89
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_octet_string.c53
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_printable_string.c166
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_sequence.c169
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_short_integer.c70
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utctime.c46
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c83
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/asn1/der_sequence_free.c65
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c76
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c207
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c222
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c60
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c196
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c147
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c108
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c189
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c177
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c110
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_exptmod.c113
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_free.c34
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_import.c143
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_make_key.c112
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c167
-rw-r--r--dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c87
-rw-r--r--dep/StormLib/src/libtommath/bn_fast_mp_invmod.c148
-rw-r--r--dep/StormLib/src/libtommath/bn_fast_mp_montgomery_reduce.c172
-rw-r--r--dep/StormLib/src/libtommath/bn_fast_s_mp_mul_digs.c107
-rw-r--r--dep/StormLib/src/libtommath/bn_fast_s_mp_mul_high_digs.c98
-rw-r--r--dep/StormLib/src/libtommath/bn_fast_s_mp_sqr.c114
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_2expt.c48
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_abs.c43
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_add.c53
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_add_d.c112
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_addmod.c41
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_and.c57
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_clamp.c44
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_clear.c44
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_clear_multi.c34
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_cmp.c43
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_cmp_d.c44
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_cmp_mag.c55
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_cnt_lsb.c53
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_copy.c68
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_count_bits.c45
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_div.c292
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_div_2.c68
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_div_2d.c97
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_div_3.c79
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_div_d.c115
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_dr_is_modulus.c43
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_dr_reduce.c94
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_dr_setup.c32
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_exch.c34
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_expt_d.c57
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_exptmod.c112
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_exptmod_fast.c321
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_exteuclid.c82
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_fread.c67
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_fwrite.c52
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_gcd.c105
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_get_int.c45
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_grow.c57
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_init.c46
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_init_copy.c32
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_init_multi.c59
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_init_set.c32
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_init_set_int.c31
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_init_size.c48
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_invmod.c43
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_invmod_slow.c175
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_is_square.c109
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_jacobi.c105
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_karatsuba_mul.c167
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_karatsuba_sqr.c121
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_lcm.c60
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_lshd.c67
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_mod.c48
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_mod_2d.c55
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_mod_d.c27
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_montgomery_calc_normalization.c59
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_montgomery_reduce.c118
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_montgomery_setup.c59
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_mul.c66
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_mul_2.c82
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_mul_2d.c85
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_mul_d.c79
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_mulmod.c40
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_n_root.c132
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_neg.c40
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_or.c50
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_prime_fermat.c62
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_prime_is_divisible.c50
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_prime_is_prime.c83
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_prime_miller_rabin.c103
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_prime_next_prime.c170
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_prime_rabin_miller_trials.c52
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_prime_random_ex.c125
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_radix_size.c78
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_radix_smap.c24
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_rand.c55
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_read_radix.c85
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_read_signed_bin.c41
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_read_unsigned_bin.c55
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_reduce.c100
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_reduce_2k.c61
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_reduce_2k_l.c62
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_reduce_2k_setup.c47
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_reduce_2k_setup_l.c44
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_reduce_is_2k.c52
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_reduce_is_2k_l.c44
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_reduce_setup.c34
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_rshd.c72
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_set.c29
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_set_int.c48
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_shrink.c35
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_signed_bin_size.c27
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_sqr.c58
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_sqrmod.c41
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_sqrt.c81
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_sub.c59
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_sub_d.c93
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_submod.c42
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_to_signed_bin.c33
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_to_signed_bin_n.c31
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_to_unsigned_bin.c48
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_to_unsigned_bin_n.c31
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_toom_mul.c284
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_toom_sqr.c226
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_toradix.c75
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_toradix_n.c88
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_unsigned_bin_size.c28
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_xor.c51
-rw-r--r--dep/StormLib/src/libtommath/bn_mp_zero.c36
-rw-r--r--dep/StormLib/src/libtommath/bn_prime_tab.c61
-rw-r--r--dep/StormLib/src/libtommath/bn_reverse.c39
-rw-r--r--dep/StormLib/src/libtommath/bn_s_mp_add.c109
-rw-r--r--dep/StormLib/src/libtommath/bn_s_mp_exptmod.c252
-rw-r--r--dep/StormLib/src/libtommath/bn_s_mp_mul_digs.c90
-rw-r--r--dep/StormLib/src/libtommath/bn_s_mp_mul_high_digs.c81
-rw-r--r--dep/StormLib/src/libtommath/bn_s_mp_sqr.c84
-rw-r--r--dep/StormLib/src/libtommath/bn_s_mp_sub.c89
-rw-r--r--dep/StormLib/src/libtommath/bncore.c36
-rw-r--r--dep/StormLib/src/libtommath/tommath.h584
-rw-r--r--dep/StormLib/src/libtommath/tommath_class.h999
-rw-r--r--dep/StormLib/src/libtommath/tommath_superclass.h76
-rw-r--r--dep/StormLib/src/lzma/C/LzFind.c761
-rw-r--r--dep/StormLib/src/lzma/C/LzFind.h115
-rw-r--r--dep/StormLib/src/lzma/C/LzFindMt.c793
-rw-r--r--dep/StormLib/src/lzma/C/LzFindMt.h105
-rw-r--r--dep/StormLib/src/lzma/C/LzHash.h54
-rw-r--r--dep/StormLib/src/lzma/C/LzmaDec.c999
-rw-r--r--dep/StormLib/src/lzma/C/LzmaDec.h231
-rw-r--r--dep/StormLib/src/lzma/C/LzmaEnc.c2268
-rw-r--r--dep/StormLib/src/lzma/C/LzmaEnc.h80
-rw-r--r--dep/StormLib/src/lzma/C/Threads.c84
-rw-r--r--dep/StormLib/src/lzma/C/Threads.h59
-rw-r--r--dep/StormLib/src/lzma/C/Types.h236
-rw-r--r--dep/StormLib/src/lzma/info.txt1
-rw-r--r--dep/StormLib/src/pklib/crc32.c66
-rw-r--r--dep/StormLib/src/pklib/explode.c522
-rw-r--r--dep/StormLib/src/pklib/implode.c769
-rw-r--r--dep/StormLib/src/pklib/pklib.h148
-rw-r--r--dep/StormLib/src/sparse/sparse.cpp292
-rw-r--r--dep/StormLib/src/sparse/sparse.h19
-rw-r--r--dep/StormLib/src/zlib/adler32.c149
-rw-r--r--dep/StormLib/src/zlib/compress2.c79
-rw-r--r--dep/StormLib/src/zlib/crc32.c423
-rw-r--r--dep/StormLib/src/zlib/crc32.h441
-rw-r--r--dep/StormLib/src/zlib/deflate.c1736
-rw-r--r--dep/StormLib/src/zlib/deflate.h331
-rw-r--r--dep/StormLib/src/zlib/inffast.c318
-rw-r--r--dep/StormLib/src/zlib/inffast.h11
-rw-r--r--dep/StormLib/src/zlib/inffixed.h94
-rw-r--r--dep/StormLib/src/zlib/inflate.c1368
-rw-r--r--dep/StormLib/src/zlib/inflate.h115
-rw-r--r--dep/StormLib/src/zlib/inftrees.c329
-rw-r--r--dep/StormLib/src/zlib/inftrees.h55
-rw-r--r--dep/StormLib/src/zlib/trees.c1219
-rw-r--r--dep/StormLib/src/zlib/trees.h128
-rw-r--r--dep/StormLib/src/zlib/zconf.h332
-rw-r--r--dep/StormLib/src/zlib/zlib.h1357
-rw-r--r--dep/StormLib/src/zlib/zutil.c318
-rw-r--r--dep/StormLib/src/zlib/zutil.h269
-rw-r--r--dep/StormLib/storm_dll/storm_dll.cpp117
-rw-r--r--dep/StormLib/storm_dll/storm_dll.def25
-rw-r--r--dep/StormLib/storm_dll/storm_dll.h67
-rw-r--r--dep/StormLib/stormlib_dll/DllMain.c24
-rw-r--r--dep/StormLib/stormlib_dll/StormLib.def76
-rw-r--r--dep/StormLib/stormlib_dll/StormLib.exp75
-rw-r--r--dep/StormLib/test/Test.cpp1892
-rw-r--r--dep/StormLib/test/x86_ripped_code.asm1231
-rw-r--r--dep/StormLib/test/x86_starcraft_lzma.asm11066
326 files changed, 17331 insertions, 74634 deletions
diff --git a/dep/CMakeLists.txt b/dep/CMakeLists.txt
index 8ae2e7ac6d7..b469cb694e2 100644
--- a/dep/CMakeLists.txt
+++ b/dep/CMakeLists.txt
@@ -39,5 +39,5 @@ if(SERVERS)
endif()
if(TOOLS)
- add_subdirectory(StormLib)
+ add_subdirectory(CascLib)
endif()
diff --git a/dep/CascLib/CMakeLists.txt b/dep/CascLib/CMakeLists.txt
new file mode 100644
index 00000000000..429ebfb78e8
--- /dev/null
+++ b/dep/CascLib/CMakeLists.txt
@@ -0,0 +1,42 @@
+set(HEADER_FILES
+ src/CascCommon.h
+ src/CascLib.h
+ src/CascMndxRoot.h
+ src/CascPort.h
+ src/common/Common.h
+ src/common/FileStream.h
+ src/common/ListFile.h
+ src/common/Map.h
+ src/jenkins/lookup.h
+)
+
+set(SRC_FILES
+ src/common/Common.cpp
+ src/common/Directory.cpp
+ src/common/FileStream.cpp
+ src/common/ListFile.cpp
+ src/common/Map.cpp
+ src/jenkins/lookup3.c
+ src/CascBuildCfg.cpp
+ src/CascCommon.cpp
+ src/CascDecompress.cpp
+ src/CascDumpData.cpp
+ src/CascFindFile.cpp
+ src/CascMndxRoot.cpp
+ src/CascOpenFile.cpp
+ src/CascOpenStorage.cpp
+ src/CascReadFile.cpp
+)
+
+set(TOMCRYPT_FILES
+ src/libtomcrypt/src/hashes/hash_memory.c
+ src/libtomcrypt/src/hashes/md5.c
+ src/libtomcrypt/src/misc/crypt_argchk.c
+ src/libtomcrypt/src/misc/crypt_hash_descriptor.c
+ src/libtomcrypt/src/misc/crypt_hash_is_valid.c
+ src/libtomcrypt/src/misc/crypt_libc.c
+)
+
+include_directories(${CMAKE_SOURCE_DIR}/dep)
+
+add_library(casc STATIC ${SRC_FILES} ${TOMCRYPT_FILES})
diff --git a/dep/CascLib/LICENSE b/dep/CascLib/LICENSE
new file mode 100644
index 00000000000..4d14b10c885
--- /dev/null
+++ b/dep/CascLib/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Ladislav Zezula
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE. \ No newline at end of file
diff --git a/dep/CascLib/README.md b/dep/CascLib/README.md
new file mode 100644
index 00000000000..91b217842b8
--- /dev/null
+++ b/dep/CascLib/README.md
@@ -0,0 +1,4 @@
+CascLib
+=======
+
+An open-source implementation of library for reading CASC storage from Blizzard games since 2014
diff --git a/dep/CascLib/doc/history.txt b/dep/CascLib/doc/history.txt
new file mode 100644
index 00000000000..45d8354379f
--- /dev/null
+++ b/dep/CascLib/doc/history.txt
@@ -0,0 +1,10 @@
+StormLib history
+
+================
+
+
+Version 1.00
+
+
+
+- Created
diff --git a/dep/CascLib/src/CascBuildCfg.cpp b/dep/CascLib/src/CascBuildCfg.cpp
new file mode 100644
index 00000000000..effb74552c5
--- /dev/null
+++ b/dep/CascLib/src/CascBuildCfg.cpp
@@ -0,0 +1,922 @@
+/*****************************************************************************/
+/* CascBuildCfg.cpp Copyright (c) Ladislav Zezula 2014 */
+/*---------------------------------------------------------------------------*/
+/* Build configuration for CascLib */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 29.04.14 1.00 Lad The first version of CascBuildCfg.cpp */
+/*****************************************************************************/
+
+#define __CASCLIB_SELF__
+#include "CascLib.h"
+#include "CascCommon.h"
+
+//-----------------------------------------------------------------------------
+// Local functions
+
+static bool inline IsValueSeparator(LPBYTE pbVarValue)
+{
+ return ((0 <= pbVarValue[0] && pbVarValue[0] <= 0x20) || (pbVarValue[0] == '|'));
+}
+
+static bool IsCharDigit(BYTE OneByte)
+{
+ return ('0' <= OneByte && OneByte <= '9');
+}
+
+static void FreeCascBlob(PQUERY_KEY pBlob)
+{
+ if(pBlob != NULL)
+ {
+ if(pBlob->pbData != NULL)
+ CASC_FREE(pBlob->pbData);
+
+ pBlob->pbData = NULL;
+ pBlob->cbData = 0;
+ }
+}
+
+static bool IsInfoVariable(const char * szLineBegin, const char * szLineEnd, const char * szVarName, const char * szVarType)
+{
+ size_t nLength;
+
+ // Check the variable name
+ nLength = strlen(szVarName);
+ if((size_t)(szLineEnd - szLineBegin) > nLength)
+ {
+ // Check the variable name
+ if(!_strnicmp(szLineBegin, szVarName, nLength))
+ {
+ // Skip variable name and the exclamation mark
+ szLineBegin += nLength;
+ if(szLineBegin < szLineEnd && szLineBegin[0] == '!')
+ {
+ // Skip the exclamation mark
+ szLineBegin++;
+
+ // Check the variable type
+ nLength = strlen(szVarType);
+ if((size_t)(szLineEnd - szLineBegin) > nLength)
+ {
+ // Check the variable name
+ if(!_strnicmp(szLineBegin, szVarType, nLength))
+ {
+ // Skip variable type and the doublecolon
+ szLineBegin += nLength;
+ return (szLineBegin < szLineEnd && szLineBegin[0] == ':');
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+static const char * SkipInfoVariable(const char * szLineBegin, const char * szLineEnd)
+{
+ while(szLineBegin < szLineEnd)
+ {
+ if(szLineBegin[0] == '|')
+ return szLineBegin + 1;
+
+ szLineBegin++;
+ }
+
+ return NULL;
+}
+
+static TCHAR * CheckForIndexDirectory(TCascStorage * hs, const TCHAR * szSubDir)
+{
+ TCHAR * szIndexPath;
+
+ // Cpmbine the index path
+ szIndexPath = CombinePath(hs->szDataPath, szSubDir);
+ if(DirectoryExists(szIndexPath))
+ {
+ hs->szIndexPath = szIndexPath;
+ return hs->szIndexPath;
+ }
+
+ delete [] szIndexPath;
+ return NULL;
+}
+
+TCHAR * AppendBlobText(TCHAR * szBuffer, LPBYTE pbData, DWORD cbData, TCHAR chSeparator)
+{
+ // Put the separator, if any
+ if(chSeparator != 0)
+ *szBuffer++ = chSeparator;
+
+ // Copy the blob data as text
+ for(DWORD i = 0; i < cbData; i++)
+ {
+ *szBuffer++ = IntToHexChar[pbData[0] >> 0x04];
+ *szBuffer++ = IntToHexChar[pbData[0] & 0x0F];
+ pbData++;
+ }
+
+ // Terminate the string
+ *szBuffer = 0;
+
+ // Return new buffer position
+ return szBuffer;
+}
+
+static int StringBlobToBinaryBlob(
+ PQUERY_KEY pBlob,
+ LPBYTE pbBlobBegin,
+ LPBYTE pbBlobEnd)
+{
+ // Sanity checks
+ assert(pBlob != NULL && pBlob->pbData != NULL);
+
+ // Reset the blob length
+ pBlob->cbData = 0;
+
+ // Convert the blob
+ while(pbBlobBegin < pbBlobEnd)
+ {
+ BYTE DigitOne;
+ BYTE DigitTwo;
+
+ DigitOne = (BYTE)(AsciiToUpperTable[pbBlobBegin[0]] - '0');
+ if(DigitOne > 9)
+ DigitOne -= 'A' - '9' - 1;
+
+ DigitTwo = (BYTE)(AsciiToUpperTable[pbBlobBegin[1]] - '0');
+ if(DigitTwo > 9)
+ DigitTwo -= 'A' - '9' - 1;
+
+ if(DigitOne > 0x0F || DigitTwo > 0x0F || pBlob->cbData >= MAX_CASC_KEY_LENGTH)
+ return ERROR_BAD_FORMAT;
+
+ pBlob->pbData[pBlob->cbData++] = (DigitOne << 0x04) | DigitTwo;
+ pbBlobBegin += 2;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+
+static LPBYTE FindNextSeparator(PQUERY_KEY pFileBlob, LPBYTE pbFilePtr)
+{
+ LPBYTE pbFileBegin = pFileBlob->pbData;
+ LPBYTE pbFileEnd = pFileBlob->pbData + pFileBlob->cbData;
+
+ if(pbFileBegin <= pbFilePtr && pbFilePtr < pbFileEnd)
+ {
+ while(pbFilePtr < pbFileEnd && pbFilePtr[0] != '|')
+ pbFilePtr++;
+
+ return pbFilePtr;
+ }
+
+ return NULL;
+}
+
+static bool GetNextFileLine(PQUERY_KEY pFileBlob, LPBYTE * ppbLineBegin, LPBYTE * ppbLineEnd)
+{
+ LPBYTE pbLineBegin = *ppbLineBegin;
+ LPBYTE pbLineEnd = *ppbLineEnd;
+ LPBYTE pbFileEnd = pFileBlob->pbData + pFileBlob->cbData;
+
+ // If there was a previous line, skip all end-of-line chars
+ if(pbLineEnd != NULL)
+ {
+ // Go to the next line
+ while(pbLineEnd < pbFileEnd && (pbLineEnd[0] == 0x0A || pbLineEnd[0] == 0x0D))
+ pbLineEnd++;
+ pbLineBegin = pbLineEnd;
+
+ // If there is no more data, return false
+ if(pbLineEnd >= pbFileEnd)
+ return false;
+ }
+
+ // Skip all spaces before the line begins
+ while(pbLineBegin < pbFileEnd && (pbLineBegin[0] == 0x09 || pbLineBegin[0] == 0x20))
+ pbLineBegin++;
+ pbLineEnd = pbLineBegin;
+
+ // Go to the end of the line
+ while(pbLineEnd < pbFileEnd && pbLineEnd[0] != 0x0A && pbLineEnd[0] != 0x0D)
+ pbLineEnd++;
+
+ // Give the results to the caller
+ *ppbLineBegin = pbLineBegin;
+ *ppbLineEnd = pbLineEnd;
+ return true;
+}
+
+static LPBYTE CheckLineVariable(LPBYTE pbLineBegin, LPBYTE pbLineEnd, const char * szVarName)
+{
+ size_t nLineLength = (size_t)(pbLineEnd - pbLineBegin);
+ size_t nNameLength = strlen(szVarName);
+
+ // If the line longer than the variable name?
+ if(nLineLength > nNameLength)
+ {
+ if(!_strnicmp((const char *)pbLineBegin, szVarName, nNameLength))
+ {
+ // Skip the variable name
+ pbLineBegin += nNameLength;
+
+ // Skip the separator(s)
+ while(pbLineBegin < pbLineEnd && IsValueSeparator(pbLineBegin))
+ pbLineBegin++;
+
+ // Check if there is "="
+ if(pbLineBegin >= pbLineEnd || pbLineBegin[0] != '=')
+ return NULL;
+ pbLineBegin++;
+
+ // Skip the separator(s)
+ while(pbLineBegin < pbLineEnd && IsValueSeparator(pbLineBegin))
+ pbLineBegin++;
+
+ // Check if there is "="
+ if(pbLineBegin >= pbLineEnd)
+ return NULL;
+
+ // Return the begin of the variable
+ return pbLineBegin;
+ }
+ }
+
+ return NULL;
+}
+
+static int LoadInfoVariable(PQUERY_KEY pVarBlob, const char * szLineBegin, const char * szLineEnd, bool bHexaValue)
+{
+ const char * szLinePtr = szLineBegin;
+
+ // Sanity checks
+ assert(pVarBlob->pbData == NULL);
+ assert(pVarBlob->cbData == 0);
+
+ // Check length of the variable
+ while(szLinePtr < szLineEnd && szLinePtr[0] != '|')
+ szLinePtr++;
+
+ // Allocate space for the blob
+ if(bHexaValue)
+ {
+ // Initialize the blob
+ pVarBlob->pbData = CASC_ALLOC(BYTE, (szLinePtr - szLineBegin) / 2);
+ return StringBlobToBinaryBlob(pVarBlob, (LPBYTE)szLineBegin, (LPBYTE)szLinePtr);
+ }
+
+ // Initialize the blob
+ pVarBlob->pbData = CASC_ALLOC(BYTE, (szLinePtr - szLineBegin) + 1);
+ pVarBlob->cbData = (size_t)(szLinePtr - szLineBegin);
+
+ // Check for success
+ if(pVarBlob->pbData == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ // Copy the string
+ memcpy(pVarBlob->pbData, szLineBegin, pVarBlob->cbData);
+ pVarBlob->pbData[pVarBlob->cbData] = 0;
+ return ERROR_SUCCESS;
+}
+
+
+static void AppendConfigFilePath(TCHAR * szFileName, PQUERY_KEY pFileKey)
+{
+ // Get to the end of the file name
+ szFileName = szFileName + _tcslen(szFileName);
+
+ // Append the "config" directory
+ _tcscat(szFileName, _T("/config"));
+ szFileName += 7;
+
+ // Append the first level directory
+ szFileName = AppendBlobText(szFileName, pFileKey->pbData, 1, _T('/'));
+ szFileName = AppendBlobText(szFileName, pFileKey->pbData + 1, 1, _T('/'));
+ szFileName = AppendBlobText(szFileName, pFileKey->pbData, pFileKey->cbData, _T('/'));
+}
+
+static DWORD GetBlobCount(LPBYTE pbLineBegin, LPBYTE pbLineEnd)
+{
+ DWORD dwBlobCount = 0;
+
+ // Until we find an end of the line
+ while(pbLineBegin < pbLineEnd)
+ {
+ // Skip the blob
+ while(pbLineBegin < pbLineEnd && IsValueSeparator(pbLineBegin) == false)
+ pbLineBegin++;
+
+ // Increment the number of blobs
+ dwBlobCount++;
+
+ // Skip the separator
+ while(pbLineBegin < pbLineEnd && IsValueSeparator(pbLineBegin))
+ pbLineBegin++;
+ }
+
+ return dwBlobCount;
+}
+
+static int LoadBlobArray(
+ PQUERY_KEY pBlob,
+ DWORD dwMaxBlobs,
+ LPBYTE pbLineBegin,
+ LPBYTE pbLineEnd,
+ LPBYTE pbBuffer,
+ DWORD dwBufferSize)
+{
+ LPBYTE pbBlobBegin = pbLineBegin;
+ LPBYTE pbBlobEnd = pbLineBegin;
+ int nError = ERROR_SUCCESS;
+
+ // Sanity check
+ assert(pbBuffer != NULL);
+
+ // Until we find an end of the line
+ while(pbBlobBegin < pbLineEnd)
+ {
+ // Convert the blob from string to binary
+ if(dwBufferSize < MAX_CASC_KEY_LENGTH)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ // Find the end of the text blob
+ while(pbBlobEnd < pbLineEnd && IsValueSeparator(pbBlobEnd) == false)
+ pbBlobEnd++;
+
+ // Convert the blob from ANSI to binary
+ pBlob->pbData = pbBuffer;
+ nError = StringBlobToBinaryBlob(pBlob, pbBlobBegin, pbBlobEnd);
+ if(nError != ERROR_SUCCESS || dwMaxBlobs == 1)
+ break;
+
+ // Move the blob, buffer, and limits
+ dwBufferSize -= MAX_CASC_KEY_LENGTH;
+ pbBuffer += MAX_CASC_KEY_LENGTH;
+ dwMaxBlobs--;
+ pBlob++;
+
+ // Skip the separator
+ while(pbBlobEnd < pbLineEnd && IsValueSeparator(pbBlobEnd))
+ pbBlobEnd++;
+ pbBlobBegin = pbBlobEnd;
+ }
+
+ return nError;
+}
+
+static int LoadSingleBlob(PQUERY_KEY pBlob, LPBYTE pbBlobBegin, LPBYTE pbBlobEnd)
+{
+ LPBYTE pbBuffer;
+ size_t nLength = (pbBlobEnd - pbBlobBegin) / 2;
+
+ // Check maximum size
+ if(nLength > MAX_CASC_KEY_LENGTH)
+ return ERROR_INVALID_PARAMETER;
+
+ // Allocate the blob buffer
+ pbBuffer = CASC_ALLOC(BYTE, MAX_CASC_KEY_LENGTH);
+ if(pbBuffer == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ return LoadBlobArray(pBlob, 1, pbBlobBegin, pbBlobEnd, pbBuffer, MAX_CASC_KEY_LENGTH);
+}
+
+static PQUERY_KEY LoadMultipleBlobs(LPBYTE pbLineBegin, LPBYTE pbLineEnd, DWORD * pdwBlobCount)
+{
+ PQUERY_KEY pBlobArray = NULL;
+ LPBYTE pbBuffer = NULL;
+ DWORD dwBlobCount = GetBlobCount(pbLineBegin, pbLineEnd);
+ int nError;
+
+ // Only if there is at least 1 blob
+ if(dwBlobCount != 0)
+ {
+ // Allocate the array of blobs
+ pBlobArray = CASC_ALLOC(QUERY_KEY, dwBlobCount);
+ if(pBlobArray != NULL)
+ {
+ // Zero the blob array
+ memset(pBlobArray, 0, dwBlobCount * sizeof(QUERY_KEY));
+
+ // Allocate buffer for the blobs
+ pbBuffer = CASC_ALLOC(BYTE, dwBlobCount * MAX_CASC_KEY_LENGTH);
+ if(pbBuffer != NULL)
+ {
+ // Zero the buffer
+ memset(pbBuffer, 0, dwBlobCount * MAX_CASC_KEY_LENGTH);
+
+ // Load the entire blob array
+ nError = LoadBlobArray(pBlobArray, dwBlobCount, pbLineBegin, pbLineEnd, pbBuffer, dwBlobCount * MAX_CASC_KEY_LENGTH);
+ if(nError == ERROR_SUCCESS)
+ {
+ *pdwBlobCount = dwBlobCount;
+ return pBlobArray;
+ }
+
+ // Free the buffer
+ CASC_FREE(pbBuffer);
+ }
+
+ // Free the array of blobs
+ CASC_FREE(pBlobArray);
+ pBlobArray = NULL;
+ }
+
+ // Reset the blob count
+ dwBlobCount = 0;
+ }
+
+ *pdwBlobCount = dwBlobCount;
+ return pBlobArray;
+}
+
+static int LoadTextFile(const TCHAR * szFileName, PQUERY_KEY pFileBlob)
+{
+ TFileStream * pStream;
+ ULONGLONG FileSize = 0;
+ int nError = ERROR_SUCCESS;
+
+ // Open the agent file
+ pStream = FileStream_OpenFile(szFileName, STREAM_FLAG_READ_ONLY | STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE);
+ if(pStream != NULL)
+ {
+ // Retrieve its size
+ FileStream_GetSize(pStream, &FileSize);
+
+ // Load the file to memory
+ if(0 < FileSize && FileSize < 0x100000)
+ {
+ // Initialize the blob
+ pFileBlob->cbData = (DWORD)FileSize;
+ pFileBlob->pbData = CASC_ALLOC(BYTE, pFileBlob->cbData + 1);
+
+ // Load the file data into the blob
+ if(pFileBlob->pbData != NULL)
+ {
+ FileStream_Read(pStream, NULL, pFileBlob->pbData, (DWORD)FileSize);
+ pFileBlob->pbData[pFileBlob->cbData] = 0;
+ }
+ else
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+ else
+ nError = ERROR_INVALID_PARAMETER;
+
+ FileStream_Close(pStream);
+ }
+ else
+ nError = GetLastError();
+
+ return nError;
+}
+
+static int GetGameType(TCascStorage * hs, LPBYTE pbVarBegin, LPBYTE pbLineEnd)
+{
+ // Alpha build of Heroes of the Storm
+ if((pbLineEnd - pbVarBegin) == 4 && !_strnicmp((const char *)pbVarBegin, "Hero", 4))
+ {
+ hs->dwGameInfo = CASC_GAME_HOTS;
+ return ERROR_SUCCESS;
+ }
+
+ // Alpha build of World of Warcraft - Warlords of Draenor
+ if((pbLineEnd - pbVarBegin) == 3 && !_strnicmp((const char *)pbVarBegin, "WoW", 3))
+ {
+ hs->dwGameInfo = CASC_GAME_WOW6;
+ return ERROR_SUCCESS;
+ }
+
+ // An unknown game
+ assert(false);
+ return ERROR_BAD_FORMAT;
+}
+
+// "B29049"
+// "WOW-18125patch6.0.1"
+static int GetBuildNumber(TCascStorage * hs, LPBYTE pbVarBegin, LPBYTE pbLineEnd)
+{
+ DWORD dwBuildNumber = 0;
+
+ // Skip all non-digit characters
+ while(pbVarBegin < pbLineEnd && IsCharDigit(pbVarBegin[0]) == false)
+ pbVarBegin++;
+
+ // Convert the build number
+ while(pbVarBegin < pbLineEnd && IsCharDigit(pbVarBegin[0]))
+ dwBuildNumber = (dwBuildNumber * 10) + (*pbVarBegin++ - '0');
+
+ assert(dwBuildNumber != 0);
+ hs->dwBuildNumber = dwBuildNumber;
+ return (dwBuildNumber != 0) ? ERROR_SUCCESS : ERROR_BAD_FORMAT;
+}
+
+static int FetchAndVerifyConfigFile(TCascStorage * hs, PQUERY_KEY pFileKey, PQUERY_KEY pFileBlob)
+{
+ TCHAR * szFileName;
+ int nError;
+
+ // Construct the local file name
+ szFileName = NewStr(hs->szDataPath, 8 + 3 + 3 + 32);
+ if(szFileName == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ // Add the part where the config file path is
+ AppendConfigFilePath(szFileName, pFileKey);
+
+ // Load the config file
+ nError = LoadTextFile(szFileName, pFileBlob);
+ if(nError == ERROR_SUCCESS)
+ {
+ // Verify the blob's MD5
+ if(!VerifyDataBlockHash(pFileBlob->pbData, pFileBlob->cbData, pFileKey->pbData))
+ {
+ FreeCascBlob(pFileBlob);
+ nError = ERROR_BAD_FORMAT;
+ }
+ }
+
+ CASC_FREE(szFileName);
+ return nError;
+}
+
+static int ParseInfoFile(TCascStorage * hs, PQUERY_KEY pFileBlob)
+{
+ QUERY_KEY CdnHost = {NULL, 0};
+ QUERY_KEY CdnPath = {NULL, 0};
+ const char * szLineBegin1 = NULL;
+ const char * szLineBegin2 = NULL;
+ const char * szLineEnd1 = NULL;
+ const char * szLineEnd2 = NULL;
+ const char * szFileEnd = (const char *)(pFileBlob->pbData + pFileBlob->cbData);
+ const char * szFilePtr = (const char *)pFileBlob->pbData;
+ int nError = ERROR_BAD_FORMAT;
+
+ // Find the first line
+ szLineBegin1 = szFilePtr;
+ while(szFilePtr < szFileEnd)
+ {
+ // Check for the end of the line
+ if(szFilePtr[0] == 0x0D || szFilePtr[0] == 0x0A)
+ {
+ szLineEnd1 = szFilePtr;
+ break;
+ }
+
+ szFilePtr++;
+ }
+
+ // Skip the newline character(s)
+ while(szFilePtr < szFileEnd && (szFilePtr[0] == 0x0D || szFilePtr[0] == 0x0A))
+ szFilePtr++;
+
+ // Find the second line
+ szLineBegin2 = szFilePtr;
+ while(szFilePtr < szFileEnd)
+ {
+ // Check for the end of the line
+ if(szFilePtr[0] == 0x0D || szFilePtr[0] == 0x0A)
+ {
+ szLineEnd2 = szFilePtr;
+ break;
+ }
+
+ szFilePtr++;
+ }
+
+ // Find the build key, CDN config key and the URL path
+ while(szLineBegin1 < szLineEnd1)
+ {
+ // Check for variables we need
+ if(IsInfoVariable(szLineBegin1, szLineEnd1, "Build Key", "HEX"))
+ LoadInfoVariable(&hs->CdnBuildKey, szLineBegin2, szLineEnd2, true);
+ if(IsInfoVariable(szLineBegin1, szLineEnd1, "CDN Key", "HEX"))
+ LoadInfoVariable(&hs->CdnConfigKey, szLineBegin2, szLineEnd2, true);
+ if(IsInfoVariable(szLineBegin1, szLineEnd1, "CDN Hosts", "STRING"))
+ LoadInfoVariable(&CdnHost, szLineBegin2, szLineEnd2, false);
+ if(IsInfoVariable(szLineBegin1, szLineEnd1, "CDN Path", "STRING"))
+ LoadInfoVariable(&CdnPath, szLineBegin2, szLineEnd2, false);
+
+ // Move both line pointers
+ szLineBegin1 = SkipInfoVariable(szLineBegin1, szLineEnd1);
+ if(szLineBegin1 == NULL)
+ break;
+
+ szLineBegin2 = SkipInfoVariable(szLineBegin2, szLineEnd2);
+ if(szLineBegin2 == NULL)
+ break;
+ }
+
+ // All four must be present
+ if(hs->CdnBuildKey.pbData != NULL &&
+ hs->CdnConfigKey.pbData != NULL &&
+ CdnHost.pbData != NULL &&
+ CdnPath.pbData != NULL)
+ {
+ // Merge the CDN host and CDN path
+ hs->szUrlPath = CASC_ALLOC(TCHAR, CdnHost.cbData + CdnPath.cbData + 1);
+ if(hs->szUrlPath != NULL)
+ {
+ CopyString(hs->szUrlPath, (char *)CdnHost.pbData, CdnHost.cbData);
+ CopyString(hs->szUrlPath + CdnHost.cbData, (char *)CdnPath.pbData, CdnPath.cbData);
+ nError = ERROR_SUCCESS;
+ }
+ }
+
+ FreeCascBlob(&CdnHost);
+ FreeCascBlob(&CdnPath);
+ return nError;
+}
+
+static int ParseAgentFile(TCascStorage * hs, PQUERY_KEY pFileBlob)
+{
+ LPBYTE pbBlobBegin = pFileBlob->pbData;
+ LPBYTE pbBlobEnd;
+ int nError = ERROR_SUCCESS;
+
+ // Extract the CDN build hash
+ pbBlobEnd = FindNextSeparator(pFileBlob, pbBlobBegin);
+ if(pbBlobEnd != NULL)
+ {
+ // Convert the string to a blob
+ nError = LoadSingleBlob(&hs->CdnBuildKey, pbBlobBegin, pbBlobEnd);
+
+ // Move to the next part
+ if(pbBlobEnd[0] == _T('|'))
+ pbBlobEnd++;
+ pbBlobBegin = pbBlobEnd;
+ }
+
+ // Extract the CDN config hash
+ pbBlobEnd = FindNextSeparator(pFileBlob, pbBlobBegin);
+ if(pbBlobEnd != NULL)
+ {
+ // Convert the string to a blob
+ nError = LoadSingleBlob(&hs->CdnConfigKey, pbBlobBegin, pbBlobEnd);
+
+ // Move to the next part
+ if(pbBlobEnd[0] == _T('|'))
+ pbBlobEnd++;
+ pbBlobBegin = pbBlobEnd;
+ }
+
+ // Skip the intermediate part
+ pbBlobEnd = FindNextSeparator(pFileBlob, pbBlobBegin);
+ if(pbBlobEnd != NULL)
+ {
+ // Move to the next part
+ if(pbBlobEnd[0] == _T('|'))
+ pbBlobEnd++;
+ pbBlobBegin = pbBlobEnd;
+ }
+
+ // Extract the URL config hash
+ pbBlobEnd = FindNextSeparator(pFileBlob, pbBlobBegin);
+ if(pbBlobEnd != NULL)
+ {
+ // Convert the string to a blob
+ hs->szUrlPath = NewStrFromAnsi(pbBlobBegin, pbBlobEnd);
+ }
+
+ // Verify all variables
+ if(hs->CdnBuildKey.pbData == NULL || hs->CdnConfigKey.pbData == NULL || hs->szUrlPath == NULL)
+ nError = ERROR_BAD_FORMAT;
+ return nError;
+}
+
+static int LoadCdnConfigFile(TCascStorage * hs, PQUERY_KEY pFileBlob)
+{
+ LPBYTE pbLineBegin = pFileBlob->pbData;
+ LPBYTE pbVarBegin;
+ LPBYTE pbLineEnd = NULL;
+ int nError;
+
+ while(pbLineBegin != NULL)
+ {
+ // Get the next line
+ if(!GetNextFileLine(pFileBlob, &pbLineBegin, &pbLineEnd))
+ break;
+
+ // Archive group
+ pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "archive-group");
+ if(pbVarBegin != NULL)
+ {
+ nError = LoadSingleBlob(&hs->ArchiveGroup, pbVarBegin, pbLineEnd);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+ continue;
+ }
+
+ // Archives
+ pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "archives");
+ if(pbVarBegin != NULL)
+ {
+ hs->pArchiveArray = LoadMultipleBlobs(pbVarBegin, pbLineEnd, &hs->ArchiveCount);
+ if(hs->pArchiveArray == NULL || hs->ArchiveCount == 0)
+ return ERROR_BAD_FORMAT;
+ continue;
+ }
+
+ // Patch archive group
+ pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "patch-archive-group");
+ if(pbVarBegin != NULL)
+ {
+ LoadSingleBlob(&hs->PatchArchiveGroup, pbVarBegin, pbLineEnd);
+ continue;
+ }
+
+ // Patch archives
+ pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "patch-archives");
+ if(pbVarBegin != NULL)
+ {
+ hs->pPatchArchiveArray = LoadMultipleBlobs(pbVarBegin, pbLineEnd, &hs->PatchArchiveCount);
+ continue;
+ }
+ }
+
+ // Check if all required fields are present
+ if(hs->ArchiveGroup.pbData == NULL || hs->ArchiveGroup.cbData == 0 || hs->pArchiveArray == NULL || hs->ArchiveCount == 0)
+ return ERROR_BAD_FORMAT;
+
+ return ERROR_SUCCESS;
+}
+
+static int LoadCdnBuildFile(TCascStorage * hs, PQUERY_KEY pFileBlob)
+{
+ LPBYTE pbLineBegin = pFileBlob->pbData;
+ LPBYTE pbVarBegin;
+ LPBYTE pbLineEnd = NULL;
+
+ while(pbLineBegin != NULL)
+ {
+ // Get the next line
+ if(!GetNextFileLine(pFileBlob, &pbLineBegin, &pbLineEnd))
+ break;
+
+ // Game name
+ pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "build-product");
+ if(pbVarBegin != NULL)
+ {
+ GetGameType(hs, pbVarBegin, pbLineEnd);
+ continue;
+ }
+
+ // Game build number
+ pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "build-name");
+ if(pbVarBegin != NULL)
+ {
+ GetBuildNumber(hs, pbVarBegin, pbLineEnd);
+ continue;
+ }
+
+ // Root
+ pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "root");
+ if(pbVarBegin != NULL)
+ {
+ LoadSingleBlob(&hs->RootKey, pbVarBegin, pbLineEnd);
+ continue;
+ }
+
+ // Patch
+ pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "patch");
+ if(pbVarBegin != NULL)
+ {
+ LoadSingleBlob(&hs->PatchKey, pbVarBegin, pbLineEnd);
+ continue;
+ }
+
+ // Download
+ pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "download");
+ if(pbVarBegin != NULL)
+ {
+ LoadSingleBlob(&hs->DownloadKey, pbVarBegin, pbLineEnd);
+ continue;
+ }
+
+ // Install
+ pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "install");
+ if(pbVarBegin != NULL)
+ {
+ LoadSingleBlob(&hs->InstallKey, pbVarBegin, pbLineEnd);
+ continue;
+ }
+
+ // Encoding keys
+ pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "encoding");
+ if(pbVarBegin != NULL)
+ {
+ hs->pEncodingKeys = LoadMultipleBlobs(pbVarBegin, pbLineEnd, &hs->EncodingKeys);
+ if(hs->pEncodingKeys == NULL || hs->EncodingKeys != 2)
+ return ERROR_BAD_FORMAT;
+
+ hs->EncodingKey = hs->pEncodingKeys[0];
+ hs->EncodingEKey = hs->pEncodingKeys[1];
+ continue;
+ }
+ }
+
+ // Check the encoding keys
+ if(hs->pEncodingKeys == NULL || hs->EncodingKeys == 0)
+ return ERROR_BAD_FORMAT;
+ return ERROR_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Public functions
+
+int LoadBuildConfiguration(TCascStorage * hs)
+{
+ QUERY_KEY InfoFile = {NULL, 0};
+ QUERY_KEY FileData = {NULL, 0};
+ TCHAR * szAgentFile;
+ TCHAR * szInfoFile;
+ bool bBuildConfigComplete = false;
+ int nError = ERROR_SUCCESS;
+
+ // Since HOTS build 30027, the game uses build.info file for storage info
+ if(bBuildConfigComplete == false)
+ {
+ szInfoFile = CombinePath(hs->szRootPath, _T(".build.info"));
+ if(szInfoFile != NULL)
+ {
+ nError = LoadTextFile(szInfoFile, &InfoFile);
+ if(nError == ERROR_SUCCESS)
+ {
+ // Parse the info file
+ nError = ParseInfoFile(hs, &InfoFile);
+ if(nError == ERROR_SUCCESS)
+ bBuildConfigComplete = true;
+
+ // Free the loaded blob
+ FreeCascBlob(&InfoFile);
+ }
+
+ CASC_FREE(szInfoFile);
+ }
+ }
+
+ // If the info file has not been loaded, try the legacy .build.db
+ if(bBuildConfigComplete == false)
+ {
+ szAgentFile = CombinePath(hs->szRootPath, _T(".build.db"));
+ if(szAgentFile != NULL)
+ {
+ nError = LoadTextFile(szAgentFile, &FileData);
+ if(nError == ERROR_SUCCESS)
+ {
+ nError = ParseAgentFile(hs, &FileData);
+ if(nError == ERROR_SUCCESS)
+ bBuildConfigComplete = true;
+
+ FreeCascBlob(&FileData);
+ }
+ CASC_FREE(szAgentFile);
+ }
+ }
+
+ // If the .build.info and .build.db file hasn't been loaded,
+ if(nError == ERROR_SUCCESS && bBuildConfigComplete == false)
+ {
+ nError = ERROR_FILE_CORRUPT;
+ }
+
+ // Load the configuration file
+ if(nError == ERROR_SUCCESS)
+ {
+ nError = FetchAndVerifyConfigFile(hs, &hs->CdnConfigKey, &FileData);
+ if(nError == ERROR_SUCCESS)
+ {
+ nError = LoadCdnConfigFile(hs, &FileData);
+ FreeCascBlob(&FileData);
+ }
+ }
+
+ // Load the build file
+ if(nError == ERROR_SUCCESS)
+ {
+ nError = FetchAndVerifyConfigFile(hs, &hs->CdnBuildKey, &FileData);
+ if(nError == ERROR_SUCCESS)
+ {
+ nError = LoadCdnBuildFile(hs, &FileData);
+ FreeCascBlob(&FileData);
+ }
+ }
+
+ // Fill the index directory
+ if(nError == ERROR_SUCCESS)
+ {
+ // First, check for more common "data" subdirectory
+ if((hs->szIndexPath = CheckForIndexDirectory(hs, _T("data"))) != NULL)
+ return ERROR_SUCCESS;
+
+ // Second, try the "darch" subdirectory (older builds of HOTS - Alpha)
+ if((hs->szIndexPath = CheckForIndexDirectory(hs, _T("darch"))) != NULL)
+ return ERROR_SUCCESS;
+
+ nError = ERROR_FILE_NOT_FOUND;
+ }
+
+ return nError;
+}
diff --git a/dep/CascLib/src/CascCommon.cpp b/dep/CascLib/src/CascCommon.cpp
new file mode 100644
index 00000000000..8ad7d716b82
--- /dev/null
+++ b/dep/CascLib/src/CascCommon.cpp
@@ -0,0 +1,67 @@
+/*****************************************************************************/
+/* CascCommon.cpp Copyright (c) Ladislav Zezula 2014 */
+/*---------------------------------------------------------------------------*/
+/* Common functions for CascLib */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 29.04.14 1.00 Lad The first version of CascCommon.cpp */
+/*****************************************************************************/
+
+#define __CASCLIB_SELF__
+#include "CascLib.h"
+#include "CascCommon.h"
+
+//-----------------------------------------------------------------------------
+// Conversion of big-endian to integer
+
+// Read the 24-bit big-endian offset into ULONGLONG
+DWORD ConvertBytesToInteger_3(LPBYTE ValueAsBytes)
+{
+ DWORD Value = 0;
+
+ Value = (Value << 0x08) | ValueAsBytes[0];
+ Value = (Value << 0x08) | ValueAsBytes[1];
+ Value = (Value << 0x08) | ValueAsBytes[2];
+
+ return Value;
+}
+
+// Read the 32-bit big-endian offset into ULONGLONG
+DWORD ConvertBytesToInteger_4(LPBYTE ValueAsBytes)
+{
+ DWORD Value = 0;
+
+ Value = (Value << 0x08) | ValueAsBytes[0];
+ Value = (Value << 0x08) | ValueAsBytes[1];
+ Value = (Value << 0x08) | ValueAsBytes[2];
+ Value = (Value << 0x08) | ValueAsBytes[3];
+
+ return Value;
+}
+
+DWORD ConvertBytesToInteger_4_LE(LPBYTE ValueAsBytes)
+{
+ DWORD Value = 0;
+
+ Value = (Value << 0x08) | ValueAsBytes[3];
+ Value = (Value << 0x08) | ValueAsBytes[2];
+ Value = (Value << 0x08) | ValueAsBytes[1];
+ Value = (Value << 0x08) | ValueAsBytes[0];
+
+ return Value;
+}
+
+// Read the 40-bit big-endian offset into ULONGLONG
+ULONGLONG ConvertBytesToInteger_5(LPBYTE ValueAsBytes)
+{
+ ULONGLONG Value = 0;
+
+ Value = (Value << 0x08) | ValueAsBytes[0];
+ Value = (Value << 0x08) | ValueAsBytes[1];
+ Value = (Value << 0x08) | ValueAsBytes[2];
+ Value = (Value << 0x08) | ValueAsBytes[3];
+ Value = (Value << 0x08) | ValueAsBytes[4];
+
+ return Value;
+}
diff --git a/dep/CascLib/src/CascCommon.h b/dep/CascLib/src/CascCommon.h
new file mode 100644
index 00000000000..b2f6a156e39
--- /dev/null
+++ b/dep/CascLib/src/CascCommon.h
@@ -0,0 +1,374 @@
+/*****************************************************************************/
+/* CascCommon.h Copyright (c) Ladislav Zezula 2014 */
+/*---------------------------------------------------------------------------*/
+/* Common functions for CascLib */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 29.04.14 1.00 Lad The first version of CascCommon.h */
+/*****************************************************************************/
+
+#ifndef __CASCCOMMON_H__
+#define __CASCCOMMON_H__
+
+//-----------------------------------------------------------------------------
+// Compression support
+
+// Include functions from zlib
+#ifndef __SYS_ZLIB
+ #include "zlib/zlib.h"
+#else
+ #include <zlib.h>
+#endif
+
+#include "CascPort.h"
+#include "common/Common.h"
+#include "common/FileStream.h"
+#include "common/ListFile.h"
+#include "common/Map.h"
+
+// Headers from LibTomCrypt
+#include "libtomcrypt/src/headers/tomcrypt.h"
+
+// For HashStringJenkins
+#include "jenkins/lookup.h"
+
+//-----------------------------------------------------------------------------
+// CascLib private defines
+
+#define CASC_GAME_HOTS 0x00010000 // Heroes of the Storm
+#define CASC_GAME_WOW6 0x00020000 // World of Warcraft - Warlords of Draenor
+#define CASC_GAME_MASK 0xFFFF0000 // Mask for getting game ID
+
+#define CASC_INDEX_COUNT 0x10
+#define CASC_FILE_KEY_SIZE 0x09 // Size of the file key
+#define CASC_MAX_DATA_FILES 0x100
+#define CASC_MAX_MAR_FILES 3 // Maximum of 3 MAR files are supported
+#define CASC_MNDX_SIGNATURE 0x58444E4D // 'MNDX'
+
+#define CASC_SEARCH_HAVE_NAME 0x0001 // Indicated that previous search found a name
+
+// Prevent problems with CRT "min" and "max" functions,
+// as they are not defined on all platforms
+#define CASCLIB_MIN(a, b) ((a < b) ? a : b)
+#define CASCLIB_MAX(a, b) ((a > b) ? a : b)
+#define CASCLIB_UNUSED(p) ((void)(p))
+
+#define CASC_PACKAGE_BUFFER 0x1000
+
+//-----------------------------------------------------------------------------
+// Structures
+
+struct TFileStream;
+struct _MAR_FILE;
+
+typedef struct _CASC_INDEX_ENTRY
+{
+ BYTE IndexKey[CASC_FILE_KEY_SIZE]; // The first 9 bytes of the encoding key
+ BYTE FileOffset[5]; //
+ BYTE FileSize[4];
+} CASC_INDEX_ENTRY, *PCASC_INDEX_ENTRY;
+
+typedef struct _CASC_MAPPING_TABLE
+{
+ TCHAR * szFileName; // Name of the key mapping file
+ LPBYTE pbFileData; // Pointer to the file data
+ DWORD cbFileData; // Length of the file data
+ BYTE ExtraBytes; // (?) Extra bytes in the key record
+ BYTE SpanSizeBytes; // Size of field with file size
+ BYTE SpanOffsBytes; // Size of field with file offset
+ BYTE KeyBytes; // Size of the file key
+ BYTE SegmentBits; // Number of bits for the file offset (rest is archive index)
+ ULONGLONG MaxFileOffset;
+
+ PCASC_INDEX_ENTRY pIndexEntries; // Sorted array of index entries
+ DWORD nIndexEntries; // Number of index entries
+
+} CASC_MAPPING_TABLE, *PCASC_MAPPING_TABLE;
+
+typedef struct _CASC_FILE_FRAME
+{
+ DWORD FrameArchiveOffset; // Archive file pointer corresponding to the begin of the frame
+ DWORD FrameFileOffset; // File pointer corresponding to the begin of the frame
+ DWORD CompressedSize; // Compressed size of the file
+ DWORD FrameSize; // Size of the frame
+ BYTE md5[MD5_HASH_SIZE]; // MD5 hash of the file sector
+} CASC_FILE_FRAME, *PCASC_FILE_FRAME;
+
+typedef struct _CASC_ENCODING_HEADER
+{
+ BYTE Magic[2]; // "EN"
+ BYTE field_2;
+ BYTE field_3;
+ BYTE field_4;
+ BYTE field_5[2];
+ BYTE field_7[2];
+ BYTE NumSegments[4]; // Number of entries (big endian)
+ BYTE field_D[4];
+ BYTE field_11;
+ BYTE SegmentsPos[4]; // Offset of encoding segments
+
+} CASC_ENCODING_HEADER, *PCASC_ENCODING_HEADER;
+
+typedef struct _CASC_ENCODING_ENTRY
+{
+ USHORT KeyCount; // Number of subitems
+ BYTE FileSizeBytes[4]; // File size as bytes (big-endian)
+ BYTE EncodingKey[MD5_HASH_SIZE]; // File encoding key
+
+ // Followed by the index keys
+ // (number of items = KeyCount)
+ // Followed by the index keys (number of items = KeyCount)
+} CASC_ENCODING_ENTRY, *PCASC_ENCODING_ENTRY;
+
+typedef struct _CASC_ROOT_LOCALE_BLOCK
+{
+ DWORD NumberOfFiles; // Number of entries
+ DWORD Flags;
+ DWORD FileLocales; // File locales (CASC_LOCALE_XXX)
+
+ // Followed by a block of 32-bit integers (count: NumberOfFiles)
+ // Followed by the MD5 and file name hash (count: NumberOfFiles)
+
+} CASC_ROOT_LOCALE_BLOCK, *PCASC_ROOT_LOCALE_BLOCK;
+
+typedef struct _CASC_ROOT_ENTRY
+{
+ BYTE EncodingKey[MD5_HASH_SIZE]; // File encoding key (MD5)
+ ULONGLONG FileNameHash; // Jenkins hash of the file name
+ DWORD Locales; // File locales (see CASC_LOCALE_XXX)
+ DWORD Flags; // File flags
+
+} CASC_ROOT_ENTRY, *PCASC_ROOT_ENTRY;
+
+typedef struct _CASC_ROOT_KEY_INFO
+{
+ BYTE EncodingKey[MD5_HASH_SIZE]; // Encoding key for the file, obtained from root info
+ ULONGLONG FileSize; // Size of the file, in bytes
+ BYTE Flags; // File flags
+} CASC_ROOT_KEY_INFO, *PCASC_ROOT_KEY_INFO;
+
+typedef struct _CASC_MNDX_ENTRY
+{
+ DWORD Flags; // High 8 bits: Flags, low 24 bits: package index
+ BYTE EncodingKey[MD5_HASH_SIZE]; // Encoding key for the file
+ DWORD FileSize; // Size of the file, in bytes
+
+} CASC_MNDX_ENTRY, *PCASC_MNDX_ENTRY;
+
+typedef struct _CASC_MNDX_INFO
+{
+ bool bRootFileLoaded; // true if the root info file was properly loaded
+ BYTE RootFileName[MD5_HASH_SIZE]; // Name (aka MD5) of the root file
+ DWORD HeaderVersion; // Must be <= 2
+ DWORD FormatVersion;
+ DWORD field_1C;
+ DWORD field_20;
+ DWORD MarInfoOffset; // Offset of the first MAR entry info
+ DWORD MarInfoCount; // Number of the MAR info entries
+ DWORD MarInfoSize; // Size of the MAR info entry
+ DWORD MndxEntriesOffset;
+ DWORD MndxEntriesTotal; // Total number of MNDX root entries
+ DWORD MndxEntriesValid; // Number of valid MNDX root entries
+ DWORD MndxEntrySize; // Size of one MNDX root entry
+ struct _MAR_FILE * pMarFile1; // File name list for the packages
+ struct _MAR_FILE * pMarFile2; // File name list for names stripped of package names
+ struct _MAR_FILE * pMarFile3; // File name list for complete names
+ PCASC_MNDX_ENTRY pMndxEntries;
+ PCASC_MNDX_ENTRY * ppValidEntries;
+
+} CASC_MNDX_INFO, *PCASC_MNDX_INFO;
+
+typedef struct _CASC_PACKAGE
+{
+ char * szFileName; // Pointer to file name
+ size_t nLength; // Length of the file name
+
+} CASC_PACKAGE, *PCASC_PACKAGE;
+
+typedef struct _CASC_PACKAGES
+{
+ char * szNameBuffer; // Pointer to the buffer for file names
+ size_t NameEntries; // Number of name entries in Names
+ size_t NameBufferUsed; // Number of bytes used in the name buffer
+ size_t NameBufferMax; // Total size of the name buffer
+
+ CASC_PACKAGE Packages[1]; // List of packages
+
+} CASC_PACKAGES, *PCASC_PACKAGES;
+
+typedef struct _TCascStorage
+{
+ const char * szClassName; // "TCascStorage"
+ const TCHAR * szIndexFormat; // Format of the index file name
+ TCHAR * szRootPath; // This is the game directory
+ TCHAR * szDataPath; // This is the directory where data files are
+ TCHAR * szIndexPath; // This is the directory where index files are
+ TCHAR * szUrlPath; // URL to the Blizzard servers
+ DWORD dwRefCount; // Number of references
+ DWORD dwGameInfo; // Game type
+ DWORD dwBuildNumber; // Game build number
+
+ QUERY_KEY CdnConfigKey;
+ QUERY_KEY CdnBuildKey;
+
+ PQUERY_KEY pArchiveArray; // Array of the archives
+ QUERY_KEY ArchiveGroup; // Name of the group archive file
+ DWORD ArchiveCount; // Number of archives in the array
+
+ PQUERY_KEY pPatchArchiveArray; // Array of the patch archives
+ QUERY_KEY PatchArchiveGroup; // Name of the patch group archive file
+ DWORD PatchArchiveCount; // Number of patch archives in the array
+
+ QUERY_KEY RootKey;
+ QUERY_KEY PatchKey;
+ QUERY_KEY DownloadKey;
+ QUERY_KEY InstallKey;
+
+ PQUERY_KEY pEncodingKeys;
+ QUERY_KEY EncodingKey;
+ QUERY_KEY EncodingEKey;
+ DWORD EncodingKeys;
+
+ TFileStream * DataFileArray[CASC_MAX_DATA_FILES]; // Data file handles
+
+ CASC_MAPPING_TABLE KeyMapping[CASC_INDEX_COUNT]; // Key mapping
+ PCASC_MAP pIndexEntryMap; // Map of index entries
+
+ PCASC_ENCODING_HEADER pEncodingHeader; // The encoding file
+ PCASC_ENCODING_ENTRY * ppEncodingEntries; // Map of encoding entries
+ size_t nEncodingEntries;
+
+ PCASC_ROOT_ENTRY * ppRootEntries; // Sorted array of root entries
+ PCASC_ROOT_ENTRY pRootEntries; // Linear array of root entries
+ size_t nRootEntries; // Number of root entries
+
+ PCASC_MNDX_INFO pMndxInfo; // Used for storages which have MNDX/MAR file
+ PCASC_PACKAGES pPackages; // Linear list of present packages
+
+} TCascStorage;
+
+typedef struct _TCascFile
+{
+ TCascStorage * hs; // Pointer to storage structure
+ TFileStream * pStream; // An open data stream
+ const char * szClassName; // "TCascFile"
+
+ DWORD FilePointer; // Current file pointer
+
+ DWORD ArchiveIndex; // Index of the archive (data.###)
+ DWORD HeaderOffset; // Offset of the BLTE header, relative to the begin of the archive
+ DWORD FramesOffset; // Offset of the frame data, relative to the begin of the archive
+ DWORD CompressedSize; // Compressed size of the file (in bytes)
+ DWORD FileSize; // Size of file, in bytes
+
+ PCASC_FILE_FRAME pFrames; // Array of file frames
+ DWORD FrameCount; // Number of the file frames
+
+ LPBYTE pbFileCache; // Pointer to file cache
+ DWORD cbFileCache; // Size of the file cache
+ DWORD CacheStart; // Starting offset in the cache
+ DWORD CacheEnd; // Ending offset in the cache
+
+} TCascFile;
+
+class TMndxFindResult;
+
+typedef struct _TCascSearch
+{
+ TCascStorage * hs; // Pointer to the storage handle
+ const char * szClassName;
+ TCHAR * szListFile;
+ void * pCache; // Listfile cache
+ TMndxFindResult * pStruct1C; // Search structure for MNDX info
+ char * szMask;
+ char szFileName[MAX_PATH]; // Buffer for the file name
+ char szNormName[MAX_PATH]; // Buffer for normalized file name
+ ULONGLONG FileNameHash; // Name hash being searched right now
+ size_t RootIndex; // Root index of the previously found item
+ DWORD dwState; // Pointer to the state (0 = listfile, 1 = nameless, 2 = done)
+ BYTE BitArray[1]; // Bit array of already-reported files
+
+} TCascSearch;
+
+//-----------------------------------------------------------------------------
+// Memory management
+//
+// We use our own macros for allocating/freeing memory. If you want
+// to redefine them, please keep the following rules:
+//
+// - The memory allocation must return NULL if not enough memory
+// (i.e not to throw exception)
+// - The allocating function does not need to fill the allocated buffer with zeros
+// - The reallocating function must support NULL as the previous block
+// - Memory freeing function doesn't have to test the pointer to NULL
+//
+
+#if defined(_MSC_VER) && defined(_DEBUG)
+/*
+void * DbgRealloc(void * ptr, size_t nSize);
+
+#define CASC_REALLOC(type, ptr, count) (type *)DbgRealloc(ptr, ((count) * sizeof(type)))
+#define CASC_ALLOC(type, count) (type *)HeapAlloc(GetProcessHeap(), 0, ((count) * sizeof(type)))
+#define CASC_FREE(ptr) HeapFree(GetProcessHeap(), 0, ptr)
+*/
+
+#define CASC_REALLOC(type, ptr, count) (type *)realloc(ptr, (count) * sizeof(type))
+#define CASC_ALLOC(type, count) (type *)malloc((count) * sizeof(type))
+#define CASC_FREE(ptr) free(ptr)
+
+#else
+
+#define CASC_REALLOC(type, ptr, count) (type *)realloc(ptr, (count) * sizeof(type))
+#define CASC_ALLOC(type, count) (type *)malloc((count) * sizeof(type))
+#define CASC_FREE(ptr) free(ptr)
+
+#endif
+
+//-----------------------------------------------------------------------------
+// Big endian number manipulation
+
+DWORD ConvertBytesToInteger_3(LPBYTE ValueAsBytes);
+DWORD ConvertBytesToInteger_4(LPBYTE ValueAsBytes);
+DWORD ConvertBytesToInteger_4_LE(LPBYTE ValueAsBytes);
+ULONGLONG ConvertBytesToInteger_5(LPBYTE ValueAsBytes);
+
+//-----------------------------------------------------------------------------
+// Build configuration reading
+
+int LoadBuildConfiguration(TCascStorage * hs);
+
+//-----------------------------------------------------------------------------
+// Internal file functions
+
+TCascStorage * IsValidStorageHandle(HANDLE hStorage);
+TCascFile * IsValidFileHandle(HANDLE hFile);
+
+PCASC_ROOT_ENTRY FindFirstRootEntry(TCascStorage * hs, const char * szFileName, size_t * PtrIndex);
+PCASC_ENCODING_ENTRY FindEncodingEntry(TCascStorage * hs, PQUERY_KEY pEncodingKey, size_t * PtrIndex);
+PCASC_INDEX_ENTRY FindIndexEntry(TCascStorage * hs, PQUERY_KEY pIndexKey);
+
+int CascDecompress(void * pvOutBuffer, PDWORD pcbOutBuffer, void * pvInBuffer, DWORD cbInBuffer);
+
+//-----------------------------------------------------------------------------
+// Dump data
+
+#ifdef _DEBUG
+void CascDumpSparseArray(const char * szFileName, void * pvSparseArray);
+void CascDumpNameFragTable(const char * szFileName, void * pvMarFile);
+void CascDumpFileNames(const char * szFileName, void * pvMarFile);
+void CascDumpMndxRoot(const char * szFileName, PCASC_MNDX_INFO pMndxInfo);
+void CascDumpIndexEntries(const char * szFileName, TCascStorage * hs);
+void CascDumpStorage(const char * szFileName, TCascStorage * hs, const TCHAR * szListFile);
+void CascDumpFile(const char * szFileName, HANDLE hFile);
+#else // _DEBUG
+#define CascDumpSparseArray(n,a) /* */
+#define CascDumpNameFragTable(n, m) /* */
+#define CascDumpFileNames(n, m) /* */
+#define CascDumpMndxRoot(n,i) /* */
+#define CascDumpIndexEntries(n,h) /* */
+#define CascDumpStorage(n,h) /* */
+#define CascDumpFile(n,h) /* */
+#endif // _DEBUG
+
+#endif // __CASCCOMMON_H__
diff --git a/dep/CascLib/src/CascDecompress.cpp b/dep/CascLib/src/CascDecompress.cpp
new file mode 100644
index 00000000000..2858bcec5ab
--- /dev/null
+++ b/dep/CascLib/src/CascDecompress.cpp
@@ -0,0 +1,83 @@
+/*****************************************************************************/
+/* CascDecompress.cpp Copyright (c) Ladislav Zezula 2014 */
+/*---------------------------------------------------------------------------*/
+/* Decompression functions */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 02.05.14 1.00 Lad The first version of CascDecompress.cpp */
+/*****************************************************************************/
+
+#define __CASCLIB_SELF__
+#include "CascLib.h"
+#include "CascCommon.h"
+
+//-----------------------------------------------------------------------------
+// Local functions
+
+static int Decompress_ZLIB(LPBYTE pbOutBuffer, PDWORD pcbOutBuffer, LPBYTE pbInBuffer, DWORD cbInBuffer)
+{
+ z_stream z; // Stream information for zlib
+ int nResult;
+
+ // Fill the stream structure for zlib
+ z.next_in = pbInBuffer;
+ z.avail_in = cbInBuffer;
+ z.total_in = cbInBuffer;
+ z.next_out = pbOutBuffer;
+ z.avail_out = *pcbOutBuffer;
+ z.total_out = 0;
+ z.zalloc = NULL;
+ z.zfree = NULL;
+
+ // Initialize the decompression structure
+ if((nResult = inflateInit(&z)) == Z_OK)
+ {
+ // Call zlib to decompress the data
+ nResult = inflate(&z, Z_NO_FLUSH);
+ inflateEnd(&z);
+
+ // Give the size of the uncompressed data
+ *pcbOutBuffer = z.total_out;
+ }
+
+ // Return an error code
+ return (nResult == Z_OK || nResult == Z_STREAM_END) ? ERROR_SUCCESS : ERROR_FILE_CORRUPT;
+}
+
+//-----------------------------------------------------------------------------
+// Public functions
+
+int CascDecompress(void * pvOutBuffer, PDWORD pcbOutBuffer, void * pvInBuffer, DWORD cbInBuffer)
+{
+ LPBYTE pbOutBuffer = (LPBYTE)pvOutBuffer;
+ LPBYTE pbInBuffer = (LPBYTE)pvInBuffer;
+ DWORD cbOutBuffer = *pcbOutBuffer; // Current size of the output buffer
+ BYTE uCompression; // Decompressions applied to the data
+
+ // Verify buffer sizes
+ if(cbInBuffer <= 1)
+ return 0;
+
+ // Get applied compression types and decrement data length
+ uCompression = *pbInBuffer++;
+ cbInBuffer--;
+
+ // Perform the decompressions
+ switch(uCompression)
+ {
+ case 'N': // Uncompressed
+
+ assert(cbOutBuffer == cbInBuffer);
+ memcpy(pbOutBuffer, pbInBuffer, cbInBuffer);
+ *pcbOutBuffer = cbOutBuffer;
+ return ERROR_SUCCESS;
+
+ case 'Z': // ZLIB
+
+ return Decompress_ZLIB(pbOutBuffer, pcbOutBuffer, pbInBuffer, cbInBuffer);
+ }
+
+ assert(false);
+ return ERROR_NOT_SUPPORTED;
+}
diff --git a/dep/CascLib/src/CascDumpData.cpp b/dep/CascLib/src/CascDumpData.cpp
new file mode 100644
index 00000000000..d3871709fce
--- /dev/null
+++ b/dep/CascLib/src/CascDumpData.cpp
@@ -0,0 +1,524 @@
+/*****************************************************************************/
+/* CascDumpData.cpp Copyright (c) Ladislav Zezula 2014 */
+/*---------------------------------------------------------------------------*/
+/* System-dependent directory functions for CascLib */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 07.05.14 1.00 Lad The first version of CascDumpData.cpp */
+/*****************************************************************************/
+
+#define __CASCLIB_SELF__
+#include "CascLib.h"
+#include "CascCommon.h"
+#include "CascMndxRoot.h"
+
+#ifdef _DEBUG // The entire file is only valid for debug purposes
+
+//-----------------------------------------------------------------------------
+// Local functions
+
+static char * StringFromIndexKey(LPBYTE md5, char * szBuffer)
+{
+ return StringFromBinary(md5, 9, szBuffer);
+}
+
+static char * StringFromMD5(LPBYTE md5, char * szBuffer)
+{
+ return StringFromBinary(md5, MD5_HASH_SIZE, szBuffer);
+}
+
+static int CompareIndexEntries_FilePos(const void *, const void * pvIndexEntry1, const void * pvIndexEntry2)
+{
+ PCASC_INDEX_ENTRY pIndexEntry1 = (PCASC_INDEX_ENTRY)pvIndexEntry1;
+ PCASC_INDEX_ENTRY pIndexEntry2 = (PCASC_INDEX_ENTRY)pvIndexEntry2;
+ ULONGLONG FileOffset1 = ConvertBytesToInteger_5(pIndexEntry1->FileOffset);
+ ULONGLONG FileOffset2 = ConvertBytesToInteger_5(pIndexEntry2->FileOffset);
+ DWORD ArchIndex1 = (DWORD)(FileOffset1 >> 0x1E);
+ DWORD ArchIndex2 = (DWORD)(FileOffset2 >> 0x1E);
+
+ // First, compare the archive index
+ if(ArchIndex1 < ArchIndex2)
+ return -1;
+ if(ArchIndex1 > ArchIndex2)
+ return +1;
+
+ // Second, compare the archive offset
+ FileOffset1 &= 0x3FFFFFFF;
+ FileOffset2 &= 0x3FFFFFFF;
+ if(FileOffset1 < FileOffset2)
+ return -1;
+ if(FileOffset1 > FileOffset2)
+ return +1;
+
+ return 0;
+}
+
+
+static char ** CreateFileNameArray(TCascStorage * hs, const TCHAR * szListFile)
+{
+ PCASC_ROOT_ENTRY pRootEntry;
+ char ** FileNameArray = NULL;
+ void * pvListFile;
+ size_t nRootIndex;
+ char szFileName1[MAX_PATH+1];
+ char szFileName2[MAX_PATH+1];
+
+ // Open the listfile stream and initialize the listfile cache
+ pvListFile = ListFile_OpenExternal(szListFile);
+ if(pvListFile != NULL)
+ {
+ // Allocate the array of file names
+ FileNameArray = CASC_ALLOC(char*, hs->nRootEntries);
+ if(FileNameArray != NULL)
+ {
+ // Zero the name array
+ memset(FileNameArray, 0, hs->nRootEntries * sizeof(char *));
+
+ // Perform search
+ while(ListFile_GetNext(pvListFile, "*", szFileName1, MAX_PATH))
+ {
+ // Create normalized name
+ strcpy(szFileName2, szFileName1);
+ NormalizeFileName_UpperBkSlash(szFileName2);
+
+ // Try to find the root entry
+ pRootEntry = FindFirstRootEntry(hs, szFileName2, &nRootIndex);
+ if(pRootEntry != NULL)
+ {
+ assert(nRootIndex < hs->nRootEntries);
+ if(FileNameArray[nRootIndex] == NULL)
+ FileNameArray[nRootIndex] = NewStr(szFileName1, 0);
+ }
+ }
+ }
+
+ // Close the listfile cache
+ ListFile_Free(pvListFile);
+ }
+
+ return FileNameArray;
+}
+
+static void FreeFileNameArray(TCascStorage * hs, char ** FileNameArray)
+{
+ if(FileNameArray != NULL)
+ {
+ // Free all sub-entries
+ for(size_t i = 0; i < hs->nRootEntries; i++)
+ {
+ if(FileNameArray[i] != NULL)
+ CASC_FREE(FileNameArray[i]);
+ }
+
+ // Free the array itself
+ CASC_FREE(FileNameArray);
+ }
+}
+
+static void DumpIndexKey(
+ FILE * fp,
+ TCascStorage * hs,
+ LPBYTE pbEncodingKey,
+ PCASC_INDEX_ENTRY * ppIndexEntries)
+{
+ PCASC_INDEX_ENTRY pIndexEntry;
+ QUERY_KEY QueryKey;
+ size_t EntryIndex = 0;
+ char szMd5[MD5_STRING_SIZE];
+
+ QueryKey.pbData = pbEncodingKey;
+ QueryKey.cbData = MD5_HASH_SIZE;
+ pIndexEntry = FindIndexEntry(hs, &QueryKey);
+ if(pIndexEntry != NULL)
+ {
+ ULONGLONG FileOffset = ConvertBytesToInteger_5(pIndexEntry->FileOffset);
+ DWORD ArchIndex = (DWORD)(FileOffset >> 0x1E);
+ DWORD FileSize = *(PDWORD)pIndexEntry->FileSize;
+
+ // Mark the index entry as dumped
+ ppIndexEntries[EntryIndex] = NULL;
+
+ // Mask the file offset
+ FileOffset &= 0x3FFFFFFF;
+ fprintf(fp, " Index: %s, ArchIdx: %02x FileOffset %08x FileSize: %lx\n",
+ StringFromIndexKey(pIndexEntry->IndexKey, szMd5),
+ ArchIndex,
+ (DWORD)FileOffset,
+ FileSize);
+ }
+ else
+ {
+ fprintf(fp, " NO INDEX ENTRY\n");
+ }
+}
+
+static void DumpEncodingEntry(
+ FILE * fp,
+ TCascStorage * hs,
+ PCASC_ENCODING_ENTRY pEncodingEntry,
+ PCASC_INDEX_ENTRY * ppIndexEntries)
+{
+ LPBYTE pbEncodingKey;
+ char szMd5[MD5_STRING_SIZE];
+
+ fprintf(fp, " Encoding Key: %s Key Count: %u Size: %lx\n",
+ StringFromMD5(pEncodingEntry->EncodingKey, szMd5),
+ pEncodingEntry->KeyCount,
+ ConvertBytesToInteger_4(pEncodingEntry->FileSizeBytes));
+
+ // If there is a file key
+ if(pEncodingEntry->KeyCount != 0)
+ {
+ // Get the first encoding key
+ pbEncodingKey = pEncodingEntry->EncodingKey + MD5_HASH_SIZE;
+
+ // Dump all encoding keys
+ for(DWORD j = 0; j < pEncodingEntry->KeyCount; j++)
+ {
+ fprintf(fp, " Index Key: %s\n", StringFromMD5(pbEncodingKey, szMd5));
+ DumpIndexKey(fp, hs, pbEncodingKey, ppIndexEntries);
+ pbEncodingKey += MD5_HASH_SIZE;
+ }
+ }
+ else
+ {
+ fprintf(fp, " ZERO FILE KEYS\n");
+ return;
+ }
+}
+
+static void DumpEncodingEntry(
+ FILE * fp,
+ TCascStorage * hs,
+ PCASC_ROOT_ENTRY pRootEntry,
+ PCASC_ENCODING_ENTRY * ppEncodingKeys,
+ PCASC_INDEX_ENTRY * ppIndexEntries)
+{
+ PCASC_ENCODING_ENTRY pEncodingKey;
+ QUERY_KEY QueryKey;
+ size_t EntryIndex = 0;
+
+ // Find the encoding key
+ QueryKey.pbData = pRootEntry->EncodingKey;
+ QueryKey.cbData = MD5_HASH_SIZE;
+ pEncodingKey = FindEncodingEntry(hs, &QueryKey, &EntryIndex);
+ if(pEncodingKey == NULL)
+ {
+ fprintf(fp, " NO ENCODING KEY\n");
+ return;
+ }
+
+ // Get the file key, clear the encoding key
+ ppEncodingKeys[EntryIndex] = NULL;
+ DumpEncodingEntry(fp, hs, pEncodingKey, ppIndexEntries);
+}
+
+static void DumpRootEntries(FILE * fp, TCascStorage * hs, char ** FileNameArray)
+{
+ PCASC_ENCODING_ENTRY * ppEncodingEntries; // Array of encoding entries
+ PCASC_INDEX_ENTRY * ppIndexEntries; // Complete list of key entries for all files
+ const char * szFileName = NULL;
+ ULONGLONG PrevNameHash = (ULONGLONG)-1;
+ char szMd5[MD5_STRING_SIZE];
+
+ // Create copy of the encoding keys and file keys
+ ppEncodingEntries = CASC_ALLOC(PCASC_ENCODING_ENTRY, hs->nEncodingEntries);
+ ppIndexEntries = CASC_ALLOC(PCASC_INDEX_ENTRY, hs->pIndexEntryMap->ItemCount);
+ if(ppEncodingEntries && ppIndexEntries)
+ {
+ // Copy all pointers
+ memcpy(ppEncodingEntries, hs->ppEncodingEntries, hs->nEncodingEntries * sizeof(PCASC_ENCODING_ENTRY));
+ Map_EnumObjects(hs->pIndexEntryMap, (void **)ppIndexEntries);
+
+ // Parse all entries
+ for(size_t i = 0; i < hs->nRootEntries; i++)
+ {
+ PCASC_ROOT_ENTRY pRootEntry = hs->ppRootEntries[i];
+ const char * szDuplicate = "";
+
+ // Check duplicates
+ if(pRootEntry->FileNameHash != PrevNameHash)
+ szFileName = FileNameArray[i];
+ else
+ szDuplicate = "(DUPLICATE) ";
+
+ // Dump the root entry
+ fprintf(fp, "NameHash: %016llx Locales: %08lx MD5: %s %sFileName: %s\n",
+ pRootEntry->FileNameHash,
+ pRootEntry->Locales,
+ StringFromMD5(pRootEntry->EncodingKey, szMd5),
+ szDuplicate,
+ szFileName);
+
+ DumpEncodingEntry(fp, hs, pRootEntry, ppEncodingEntries, ppIndexEntries);
+ PrevNameHash = pRootEntry->FileNameHash;
+ fprintf(fp, "\n");
+ }
+
+ // Dump all orphaned encoding keys
+ for(size_t i = 0; i < hs->nEncodingEntries; i++)
+ {
+ if(ppEncodingEntries[i] != NULL)
+ {
+ fprintf(fp, "[NO ROOT KEY]\n");
+
+ DumpEncodingEntry(fp, hs, ppEncodingEntries[i], ppIndexEntries);
+ ppEncodingEntries[i] = NULL;
+
+ fprintf(fp, "\n");
+ }
+ }
+
+
+ CASC_FREE(ppIndexEntries);
+ CASC_FREE(ppEncodingEntries);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Public functions
+
+void CascDumpSparseArray(const char * szFileName, void * pvSparseArray)
+{
+ TSparseArray * pSparseArray = (TSparseArray *)pvSparseArray;
+ FILE * fp;
+
+ // Create the dump file
+ fp = fopen(szFileName, "wt");
+ if(fp != NULL)
+ {
+ // Write header
+ fprintf(fp, "## Value\n-- -----\n");
+
+ // Write the values
+ for(DWORD i = 0; i < pSparseArray->TotalItemCount; i++)
+ {
+ DWORD Value = 0;
+
+ if(pSparseArray->IsItemPresent(i))
+ {
+ Value = pSparseArray->GetItemValue(i);
+ fprintf(fp, "%02X %02X\n", i, Value);
+ }
+ else
+ {
+ fprintf(fp, "%02X --\n", i);
+ }
+ }
+
+ fclose(fp);
+ }
+}
+
+void CascDumpNameFragTable(const char * szFileName, void * pMarFile)
+{
+ TFileNameDatabase * pDB = ((PMAR_FILE)pMarFile)->pDatabasePtr->pDB;
+ FILE * fp;
+
+ // Create the dump file
+ fp = fopen(szFileName, "wt");
+ if(fp != NULL)
+ {
+ PNAME_FRAG pNameTable = pDB->NameFragTable.NameFragArray;
+ const char * szNames = pDB->IndexStruct_174.NameFragments.CharArray;
+ const char * szLastEntry;
+ char szMatchType[0x100];
+
+ // Dump the table header
+ fprintf(fp, "Indx ThisHash NextHash FragOffs\n");
+ fprintf(fp, "---- -------- -------- --------\n");
+
+ // Dump all name entries
+ for(DWORD i = 0; i < pDB->NameFragTable.ItemCount; i++)
+ {
+ // Reset both match types
+ szMatchType[0] = 0;
+ szLastEntry = "";
+
+ // Only if the table entry is not empty
+ if(pNameTable->ItemIndex != 0xFFFFFFFF)
+ {
+ // Prepare the entry
+ if(IS_SINGLE_CHAR_MATCH(pDB->NameFragTable, i))
+ sprintf(szMatchType, "SINGLE_CHAR (\'%c\')", (pNameTable->FragOffs & 0xFF));
+ else
+ sprintf(szMatchType, "NAME_FRAGMT (\"%s\")", szNames + pNameTable->FragOffs);
+ }
+
+ // Dump the entry
+ fprintf(fp, "0x%02X %08x %08x %08x %s%s\n", i, pNameTable->ItemIndex,
+ pNameTable->NextIndex,
+ pNameTable->FragOffs,
+ szMatchType,
+ szLastEntry);
+ pNameTable++;
+ }
+ fclose(fp);
+ }
+}
+
+void CascDumpFileNames(const char * szFileName, void * pvMarFile)
+{
+ TMndxFindResult Struct1C;
+ PMAR_FILE pMarFile = (PMAR_FILE)pvMarFile;
+ FILE * fp;
+ char szNameBuff[0x200];
+ bool bFindResult;
+
+ // Create the dump file
+ fp = fopen(szFileName, "wt");
+ if(fp != NULL)
+ {
+ // Set an empty path as search mask (?)
+ Struct1C.SetSearchPath("", 0);
+
+ // Keep searching
+ for(;;)
+ {
+ // Search the next file name
+ pMarFile->pDatabasePtr->sub_1956CE0(&Struct1C, &bFindResult);
+
+ // Stop the search in case of failure
+ if(!bFindResult)
+ break;
+
+ // Printf the found file name
+ memcpy(szNameBuff, Struct1C.szFoundPath, Struct1C.cchFoundPath);
+ szNameBuff[Struct1C.cchFoundPath] = 0;
+ fprintf(fp, "%s\n", szNameBuff);
+ }
+
+ fclose(fp);
+ }
+
+ // Free the search structures
+ Struct1C.FreeStruct40();
+}
+
+void CascDumpMndxRoot(const char * szFileName, PCASC_MNDX_INFO pMndxInfo)
+{
+ PCASC_MNDX_ENTRY pMndxEntry;
+ FILE * fp;
+ char szMd5[MD5_STRING_SIZE];
+
+ // Create the dump file
+ fp = fopen(szFileName, "wt");
+ if(fp != NULL)
+ {
+ fprintf(fp, "Indx Fl+Asset EncodingKey FileSize\n==== ======== ================================ ========\n");
+ for(DWORD i = 0; i < pMndxInfo->MndxEntriesValid; i++)
+ {
+ pMndxEntry = pMndxInfo->ppValidEntries[i];
+
+ fprintf(fp, "%04X %08X %s %08X\n", i,
+ pMndxEntry->Flags,
+ StringFromMD5(pMndxEntry->EncodingKey, szMd5),
+ pMndxEntry->FileSize);
+ }
+ fclose(fp);
+ }
+}
+
+void CascDumpIndexEntries(const char * szFileName, TCascStorage * hs)
+{
+ PCASC_INDEX_ENTRY * ppIndexEntries;
+ FILE * fp;
+ size_t nIndexEntries = hs->pIndexEntryMap->ItemCount;
+ char szIndexKey[0x40];
+
+ // Create the dump file
+ fp = fopen(szFileName, "wt");
+ if(fp != NULL)
+ {
+ // Create linear aray
+ ppIndexEntries = CASC_ALLOC(PCASC_INDEX_ENTRY, nIndexEntries);
+ if(ppIndexEntries != NULL)
+ {
+ // Obtain the linear array of index entries
+ Map_EnumObjects(hs->pIndexEntryMap, (void **)ppIndexEntries);
+
+ // Sort the array by archive number and archive offset
+ qsort_pointer_array((void **)ppIndexEntries, nIndexEntries, CompareIndexEntries_FilePos, NULL);
+
+ // Parse the array
+ fprintf(fp, "ArNo ArOffset FileSize IndexKey\n==== ======== ======== ================================\n");
+ for(size_t i = 0; i < nIndexEntries; i++)
+ {
+ PCASC_INDEX_ENTRY pIndexEntry = ppIndexEntries[i];
+ ULONGLONG ArchOffset = ConvertBytesToInteger_5(pIndexEntry->FileOffset);
+ DWORD ArchIndex = (DWORD)(ArchOffset >> 0x1E);
+ DWORD FileSize;
+
+ FileSize = ConvertBytesToInteger_4_LE(pIndexEntry->FileSize);
+ ArchOffset &= 0x3FFFFFFF;
+
+ fprintf(fp, " %02X %08X %08X %s\n", ArchIndex, ArchOffset, FileSize, StringFromBinary(pIndexEntry->IndexKey, CASC_FILE_KEY_SIZE, szIndexKey));
+ }
+
+ CASC_FREE(ppIndexEntries);
+ }
+
+ fclose(fp);
+ }
+}
+
+void CascDumpStorage(const char * szFileName, TCascStorage * hs, const TCHAR * szListFile)
+{
+ char ** FileNameArray = NULL;
+ FILE * fp;
+
+ // Validate the storage handle
+ if(hs != NULL)
+ {
+ // Create the dump file
+ fp = fopen(szFileName, "wt");
+ if(fp != NULL)
+ {
+ // If we also have listfile, open it
+ if(szListFile != NULL)
+ FileNameArray = CreateFileNameArray(hs, szListFile);
+
+ // Dump all root keys
+ fprintf(fp, "Root Entries\n=========\n\n");
+ DumpRootEntries(fp, hs, FileNameArray);
+
+ FreeFileNameArray(hs, FileNameArray);
+ fclose(fp);
+ }
+ }
+}
+
+
+void CascDumpFile(const char * szFileName, HANDLE hFile)
+{
+ FILE * fp;
+ DWORD dwBytesRead = 1;
+ DWORD dwFilePos = CascSetFilePointer(hFile, 0, NULL, FILE_BEGIN);
+ BYTE Buffer[0x1000];
+
+ // Create the dump file
+ fp = fopen(szFileName, "wb");
+ if(fp != NULL)
+ {
+ // Read data as long as we can, write as long as we can
+ while(dwBytesRead != 0)
+ {
+ // Read from the source file
+ if(!CascReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead))
+ break;
+
+ // Write to the destination file
+ if(fwrite(Buffer, 1, dwBytesRead, fp) != dwBytesRead)
+ break;
+ }
+
+ // Close the local file
+ fclose(fp);
+
+ // Restore the file pointer
+ CascSetFilePointer(hFile, dwFilePos, NULL, FILE_BEGIN);
+ }
+}
+
+#endif // _DEBUG
diff --git a/dep/CascLib/src/CascFindFile.cpp b/dep/CascLib/src/CascFindFile.cpp
new file mode 100644
index 00000000000..f1b14560bed
--- /dev/null
+++ b/dep/CascLib/src/CascFindFile.cpp
@@ -0,0 +1,364 @@
+/*****************************************************************************/
+/* CascFindFile.cpp Copyright (c) Ladislav Zezula 2014 */
+/*---------------------------------------------------------------------------*/
+/* System-dependent directory functions for CascLib */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 10.05.14 1.00 Lad The first version of CascFindFile.cpp */
+/*****************************************************************************/
+
+#define __CASCLIB_SELF__
+#include "CascLib.h"
+#include "CascCommon.h"
+#include "CascMndxRoot.h"
+
+//-----------------------------------------------------------------------------
+// Local functions
+
+static TCascSearch * IsValidSearchHandle(HANDLE hFind)
+{
+ TCascSearch * pSearch = (TCascSearch *)hFind;
+
+ return (pSearch != NULL && pSearch->szClassName != NULL && !strcmp(pSearch->szClassName, "TCascSearch") && pSearch->szMask != NULL) ? pSearch : NULL;
+}
+
+static void FreeSearchHandle(TCascSearch * pSearch)
+{
+ // Only if the storage handle is valid
+ assert(pSearch != NULL);
+
+ // Close (dereference) the archive handle
+ if(pSearch->hs != NULL)
+ CascCloseStorage((HANDLE)pSearch->hs);
+ pSearch->hs = NULL;
+
+ // Free the file cache and frame array
+ if(pSearch->szMask != NULL)
+ CASC_FREE(pSearch->szMask);
+ if(pSearch->szListFile != NULL)
+ CASC_FREE(pSearch->szListFile);
+ if(pSearch->pStruct1C != NULL)
+ delete pSearch->pStruct1C;
+ if(pSearch->pCache != NULL)
+ ListFile_Free(pSearch->pCache);
+
+ // Free the structure itself
+ pSearch->szClassName = NULL;
+ CASC_FREE(pSearch);
+}
+/*
+DWORD dwRootEntries = 0;
+DWORD dwEncoEntries = 0;
+DWORD dwIndexEntries = 0;
+*/
+static bool VerifyRootEntry(TCascSearch * pSearch, PCASC_ROOT_ENTRY pRootEntry, PCASC_FIND_DATA pFindData, size_t nRootIndex)
+{
+ PCASC_ENCODING_ENTRY pEncodingEntry;
+ PCASC_INDEX_ENTRY pIndexEntry;
+ TCascStorage * hs = pSearch->hs;
+ QUERY_KEY QueryKey;
+ DWORD dwByteIndex = (DWORD)(nRootIndex / 0x08);
+ DWORD dwBitIndex = (DWORD)(nRootIndex & 0x07);
+
+ // First of all, check if that entry has been reported before
+ // If the bit is set, then the file has already been reported
+ // by a previous search iteration
+ if(pSearch->BitArray[dwByteIndex] & (1 << dwBitIndex))
+ return false;
+ pSearch->BitArray[dwByteIndex] |= (1 << dwBitIndex);
+
+ // Increment the number of root entries
+// dwRootEntries++;
+
+ // Now try to find that encoding key in the array of encoding keys
+ QueryKey.pbData = pRootEntry->EncodingKey;
+ QueryKey.cbData = MD5_HASH_SIZE;
+ pEncodingEntry = FindEncodingEntry(hs, &QueryKey, NULL);
+ if(pEncodingEntry == NULL)
+ return false;
+
+// dwEncoEntries++;
+
+ // Now try to find the index entry. Note that we take the first key
+ QueryKey.pbData = pEncodingEntry->EncodingKey + MD5_HASH_SIZE;
+ QueryKey.cbData = MD5_HASH_SIZE;
+ pIndexEntry = FindIndexEntry(hs, &QueryKey);
+ if(pIndexEntry == NULL)
+ return false;
+
+// dwIndexEntries++;
+
+ // Fill the name hash and the MD5
+ memcpy(pFindData->EncodingKey, pRootEntry->EncodingKey, MD5_HASH_SIZE);
+ pFindData->FileNameHash = pRootEntry->FileNameHash;
+ pFindData->dwPackageIndex = 0;
+ pFindData->dwLocaleFlags = pRootEntry->Locales;
+ pFindData->dwFileSize = ConvertBytesToInteger_4(pEncodingEntry->FileSizeBytes);
+ return true;
+}
+
+static TCascSearch * AllocateSearchHandle(TCascStorage * hs, const TCHAR * szListFile, const char * szMask)
+{
+ TCascSearch * pSearch;
+ size_t cbToAllocate;
+
+ // When using the MNDX info, do not allocate the extra bit array
+ cbToAllocate = sizeof(TCascSearch) + ((hs->pMndxInfo == NULL) ? (hs->nRootEntries / 8) : 0);
+ pSearch = (TCascSearch *)CASC_ALLOC(BYTE, cbToAllocate);
+ if(pSearch != NULL)
+ {
+ // Initialize the structure
+ memset(pSearch, 0, cbToAllocate);
+ pSearch->szClassName = "TCascSearch";
+
+ // Save the search handle
+ pSearch->hs = hs;
+ hs->dwRefCount++;
+
+ // If the mask was not given, use default
+ if(szMask == NULL)
+ szMask = "*";
+
+ // Save the other variables
+ if(szListFile != NULL)
+ {
+ pSearch->szListFile = NewStr(szListFile, 0);
+ if(pSearch->szListFile == NULL)
+ {
+ FreeSearchHandle(pSearch);
+ return NULL;
+ }
+ }
+
+ // Allocate the search mask
+ pSearch->szMask = NewStr(szMask, 0);
+ if(pSearch->szMask == NULL)
+ {
+ FreeSearchHandle(pSearch);
+ return NULL;
+ }
+ }
+
+ return pSearch;
+}
+
+static bool DoStorageSearch_ListFile(TCascSearch * pSearch, PCASC_FIND_DATA pFindData)
+{
+ PCASC_ROOT_ENTRY pRootEntry;
+ TCascStorage * hs = pSearch->hs;
+ size_t RootIndex;
+
+ for(;;)
+ {
+ // Shall we get a new file name from the listfile?
+ if(pSearch->FileNameHash == 0)
+ {
+ // Try to get next file from the listfile
+ if(!ListFile_GetNext(pSearch->pCache, pSearch->szMask, pSearch->szFileName, MAX_PATH))
+ break;
+
+// if(!_stricmp(pSearch->szFileName, "Interface\\Glues\\MODELS\\UI_MainMenu_Warlords\\Caustic_MedFreq.blp"))
+// DebugBreak();
+
+ // Normalize the file name
+ strcpy(pSearch->szNormName, pSearch->szFileName);
+ NormalizeFileName_UpperBkSlash(pSearch->szNormName);
+
+ // Find the first root entry belonging to this file name
+ pRootEntry = FindFirstRootEntry(pSearch->hs, pSearch->szNormName, &RootIndex);
+ if(pRootEntry == NULL)
+ continue;
+
+ // We have the name now, search all locales
+ pSearch->FileNameHash = pRootEntry->FileNameHash;
+ pSearch->RootIndex = RootIndex;
+ }
+
+ // Is the root index in range?
+ while(pSearch->RootIndex < hs->nRootEntries)
+ {
+ // Get the next root entry. If name mismatches, stop searching
+ pRootEntry = hs->ppRootEntries[pSearch->RootIndex];
+ if(pRootEntry->FileNameHash != pSearch->FileNameHash)
+ break;
+
+ // Verify whether the file exists in the storage
+ if(VerifyRootEntry(pSearch, pRootEntry, pFindData, pSearch->RootIndex++))
+ {
+ strcpy(pFindData->szFileName, pSearch->szFileName);
+ pFindData->szPlainName = (char *)GetPlainFileName(pFindData->szFileName);
+ return true;
+ }
+ }
+
+ // Reset the name hash and root index and retry search
+ pSearch->FileNameHash = 0;
+ }
+
+ // Listfile search ended
+ return false;
+}
+
+static bool DoStorageSearch_Hash(TCascSearch * pSearch, PCASC_FIND_DATA pFindData)
+{
+ PCASC_ROOT_ENTRY pRootEntry;
+ TCascStorage * hs = pSearch->hs;
+
+ // Check if there is more files with the same name hash
+ while(pSearch->RootIndex < hs->nRootEntries)
+ {
+ // Get the pointer to the root entry
+ pRootEntry = hs->ppRootEntries[pSearch->RootIndex];
+
+ // Verify if that root entry exists in the CASC storage
+ // Note that the file name will be there from the previous search
+ if(VerifyRootEntry(pSearch, pRootEntry, pFindData, pSearch->RootIndex))
+ {
+ pFindData->szFileName[0] = 0;
+ pFindData->szPlainName = NULL;
+ return true;
+ }
+
+ // Move to the next entry
+ pSearch->RootIndex++;
+ }
+
+ // Nameless search ended
+ return false;
+}
+
+static bool DoStorageSearch(TCascSearch * pSearch, PCASC_FIND_DATA pFindData)
+{
+ // Are we searching using the MNDX ?
+ if(pSearch->hs->pMndxInfo != NULL)
+ return DoStorageSearch_MNDX(pSearch, pFindData);
+
+ // State 0: No search done yet
+ if(pSearch->dwState == 0)
+ {
+ // Does the search specify listfile?
+ if(pSearch->szListFile != NULL)
+ pSearch->pCache = ListFile_OpenExternal(pSearch->szListFile);
+
+ // Move the search phase to the listfile searching
+ pSearch->FileNameHash = 0;
+ pSearch->RootIndex = 0;
+ pSearch->dwState++;
+
+ // If either file stream or listfile cache are invalid,
+ // move to the next phase
+ if(pSearch->pCache == NULL)
+ pSearch->dwState++;
+ }
+
+ // State 1: Searching the list file
+ if(pSearch->dwState == 1)
+ {
+ if(DoStorageSearch_ListFile(pSearch, pFindData))
+ return true;
+
+ // Move to the nameless search state
+ pSearch->RootIndex = 0;
+ pSearch->dwState++;
+ }
+
+ // State 2: Searching the remaining entries
+ if(pSearch->dwState == 2)
+ {
+ if(DoStorageSearch_Hash(pSearch, pFindData))
+ return true;
+
+ // Move to the final search state
+ pSearch->dwState++;
+ }
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Public functions
+
+HANDLE WINAPI CascFindFirstFile(
+ HANDLE hStorage,
+ const char * szMask,
+ PCASC_FIND_DATA pFindData,
+ const TCHAR * szListFile)
+{
+ TCascStorage * hs;
+ TCascSearch * pSearch = NULL;
+ int nError = ERROR_SUCCESS;
+
+ // Check parameters
+ if((hs = IsValidStorageHandle(hStorage)) == NULL)
+ nError = ERROR_INVALID_HANDLE;
+ if(szMask == NULL || pFindData == NULL)
+ nError = ERROR_INVALID_PARAMETER;
+
+ // Allocate the structure for archive search
+ if(nError == ERROR_SUCCESS)
+ {
+ // Clear the entire search structure
+ memset(pFindData, 0, sizeof(CASC_FIND_DATA));
+
+ // We must have listfile for non-MNDX storages
+ if(hs->pMndxInfo == NULL && szListFile == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ // Allocate the search handle
+ pSearch = AllocateSearchHandle(hs, szListFile, szMask);
+ if(pSearch == NULL)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Perform search
+ if(nError == ERROR_SUCCESS)
+ {
+ if(!DoStorageSearch(pSearch, pFindData))
+ nError = ERROR_NO_MORE_FILES;
+ }
+
+ if(nError != ERROR_SUCCESS)
+ {
+ if(pSearch != NULL)
+ FreeSearchHandle(pSearch);
+ pSearch = NULL;
+ }
+
+ return (HANDLE)pSearch;
+}
+
+bool WINAPI CascFindNextFile(
+ HANDLE hFind,
+ PCASC_FIND_DATA pFindData)
+{
+ TCascSearch * pSearch;
+
+ pSearch = IsValidSearchHandle(hFind);
+ if(pSearch == NULL || pFindData == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return false;
+ }
+
+ // Perform search
+ return DoStorageSearch(pSearch, pFindData);
+}
+
+bool WINAPI CascFindClose(HANDLE hFind)
+{
+ TCascSearch * pSearch;
+
+ pSearch = IsValidSearchHandle(hFind);
+ if(pSearch == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return false;
+ }
+
+ FreeSearchHandle(pSearch);
+ return true;
+}
diff --git a/dep/CascLib/src/CascLib.h b/dep/CascLib/src/CascLib.h
new file mode 100644
index 00000000000..a3960a558c2
--- /dev/null
+++ b/dep/CascLib/src/CascLib.h
@@ -0,0 +1,171 @@
+/*****************************************************************************/
+/* CascLib.h Copyright (c) Ladislav Zezula 2014 */
+/*---------------------------------------------------------------------------*/
+/* CascLib library v 1.00 */
+/* */
+/* Author : Ladislav Zezula */
+/* E-mail : ladik@zezula.net */
+/* WWW : http://www.zezula.net */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 29.04.14 1.00 Lad Created */
+/*****************************************************************************/
+
+#ifndef __CASCLIB_H__
+#define __CASCLIB_H__
+
+#ifdef _MSC_VER
+#pragma warning(disable:4668) // 'XXX' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'
+#pragma warning(disable:4820) // 'XXX' : '2' bytes padding added after data member 'XXX::yyy'
+#endif
+
+#include "CascPort.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//-----------------------------------------------------------------------------
+// Defines
+
+#define CASCLIB_VERSION 0x0100 // Current version of CascLib (1.0)
+#define CASCLIB_VERSION_STRING "1.00" // String version of CascLib version
+
+#define ERROR_UNKNOWN_FILE_KEY 10001 // Returned by encrypted stream when can't find file key
+#define ERROR_FILE_INCOMPLETE 10006 // The required file part is missing
+
+// Values for CascOpenStorage
+#define CASC_STOR_XXXXX 0x00000001 // Not used
+
+// Values for CascOpenFile
+#define CASC_FILE_XXXXX 0x00000001 // Not used
+
+// Flags for file stream
+#define BASE_PROVIDER_FILE 0x00000000 // Base data source is a file
+#define BASE_PROVIDER_MAP 0x00000001 // Base data source is memory-mapped file
+#define BASE_PROVIDER_HTTP 0x00000002 // Base data source is a file on web server
+#define BASE_PROVIDER_MASK 0x0000000F // Mask for base provider value
+
+#define STREAM_PROVIDER_FLAT 0x00000000 // Stream is linear with no offset mapping
+#define STREAM_PROVIDER_PARTIAL 0x00000010 // Stream is partial file (.part)
+#define STREAM_PROVIDER_ENCRYPTED 0x00000020 // Stream is an encrypted archive
+#define STREAM_PROVIDER_BLOCK4 0x00000030 // 0x4000 per block, text MD5 after each block, max 0x2000 blocks per file
+#define STREAM_PROVIDER_MASK 0x000000F0 // Mask for stream provider value
+
+#define STREAM_FLAG_READ_ONLY 0x00000100 // Stream is read only
+#define STREAM_FLAG_WRITE_SHARE 0x00000200 // Allow write sharing when open for write
+#define STREAM_FLAG_USE_BITMAP 0x00000400 // If the file has a file bitmap, load it and use it
+#define STREAM_OPTIONS_MASK 0x0000FF00 // Mask for stream options
+
+#define STREAM_PROVIDERS_MASK 0x000000FF // Mask to get stream providers
+#define STREAM_FLAGS_MASK 0x0000FFFF // Mask for all stream flags (providers+options)
+
+#define CASC_LOCALE_ALL 0xFFFFFFFF
+#define CASC_LOCALE_NONE 0x00000000
+#define CASC_LOCALE_UNKNOWN1 0x00000001
+#define CASC_LOCALE_ENUS 0x00000002
+#define CASC_LOCALE_KOKR 0x00000004
+#define CASC_LOCALE_UNKNOWN8 0x00000008
+#define CASC_LOCALE_FRFR 0x00000010
+#define CASC_LOCALE_DEDE 0x00000020
+#define CASC_LOCALE_ZHCN 0x00000040
+#define CASC_LOCALE_ESES 0x00000080
+#define CASC_LOCALE_ZHTW 0x00000100
+#define CASC_LOCALE_ENGB 0x00000200
+#define CASC_LOCALE_ENCN 0x00000400
+#define CASC_LOCALE_ENTW 0x00000800
+#define CASC_LOCALE_ESMX 0x00001000
+#define CASC_LOCALE_RURU 0x00002000
+#define CASC_LOCALE_PTBR 0x00004000
+#define CASC_LOCALE_ITIT 0x00008000
+#define CASC_LOCALE_PTPT 0x00010000
+
+#define MAX_CASC_KEY_LENGTH 0x10 // Maximum length of the key (equal to MD5 hash)
+
+#ifndef MD5_HASH_SIZE
+#define MD5_HASH_SIZE 0x10
+#define MD5_STRING_SIZE 0x21
+#endif
+
+#ifndef SHA1_DIGEST_SIZE
+#define SHA1_DIGEST_SIZE 0x14 // 160 bits
+#endif
+
+#ifndef LANG_NEUTRAL
+#define LANG_NEUTRAL 0x00 // Neutral locale
+#endif
+
+// Return value for CascGetFileSize and CascSetFilePointer
+#define CASC_INVALID_SIZE 0xFFFFFFFF
+#define CASC_INVALID_POS 0xFFFFFFFF
+
+// Flags for CascGetStorageInfo
+#define CASC_FEATURE_LISTFILE 0x00000001 // The storage supports listfile
+
+//-----------------------------------------------------------------------------
+// Structures
+
+typedef enum _CASC_STORAGE_INFO_CLASS
+{
+ CascStorageFileCount,
+ CascStorageFeatures,
+ CascStorageInfoClassMax
+
+} CASC_STORAGE_INFO_CLASS, *PCASC_STORAGE_INFO_CLASS;
+
+
+typedef struct _QUERY_KEY
+{
+ LPBYTE pbData;
+ DWORD cbData;
+} QUERY_KEY, *PQUERY_KEY;
+
+// Structure for SFileFindFirstFile and SFileFindNextFile
+typedef struct _CASC_FIND_DATA
+{
+ char szFileName[MAX_PATH]; // Full name of the found file
+ char * szPlainName; // Plain name of the found file
+ ULONGLONG FileNameHash; // File name hash
+ BYTE EncodingKey[MD5_HASH_SIZE]; // Encoding key
+ DWORD dwPackageIndex; // File package index (HOTS only)
+ DWORD dwLocaleFlags; // Locale flags (WoW only)
+ DWORD dwFileSize; // Size of the file
+
+} CASC_FIND_DATA, *PCASC_FIND_DATA;
+
+//-----------------------------------------------------------------------------
+// Callback functions
+
+typedef struct TFileStream TFileStream;
+typedef void (WINAPI * STREAM_DOWNLOAD_CALLBACK)(void * pvUserData, ULONGLONG ByteOffset, DWORD dwTotalBytes);
+
+//-----------------------------------------------------------------------------
+// We have our own qsort implementation, optimized for sorting array of pointers
+
+void qsort_pointer_array(void ** base, size_t num, int (*compare)(const void *, const void *, const void *), const void * context);
+
+//-----------------------------------------------------------------------------
+// Functions for storage manipulation
+
+bool WINAPI CascOpenStorage(const TCHAR * szDataPath, DWORD dwFlags, HANDLE * phStorage);
+bool WINAPI CascGetStorageInfo(HANDLE hStorage, CASC_STORAGE_INFO_CLASS InfoClass, void * pvStorageInfo, size_t cbStorageInfo, size_t * pcbLengthNeeded);
+bool WINAPI CascCloseStorage(HANDLE hStorage);
+
+bool WINAPI CascOpenFileByIndexKey(HANDLE hStorage, PQUERY_KEY pIndexKey, DWORD dwFlags, HANDLE * phFile);
+bool WINAPI CascOpenFileByEncodingKey(HANDLE hStorage, PQUERY_KEY pEncodingKey, DWORD dwFlags, HANDLE * phFile);
+bool WINAPI CascOpenFile(HANDLE hStorage, const char * szFileName, DWORD dwLocale, DWORD dwFlags, HANDLE * phFile);
+DWORD WINAPI CascGetFileSize(HANDLE hFile, PDWORD pdwFileSizeHigh);
+DWORD WINAPI CascSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * plFilePosHigh, DWORD dwMoveMethod);
+bool WINAPI CascReadFile(HANDLE hFile, void * lpBuffer, DWORD dwToRead, PDWORD pdwRead);
+bool WINAPI CascCloseFile(HANDLE hFile);
+
+HANDLE WINAPI CascFindFirstFile(HANDLE hStorage, const char * szMask, PCASC_FIND_DATA pFindData, const TCHAR * szListFile);
+bool WINAPI CascFindNextFile(HANDLE hFind, PCASC_FIND_DATA pFindData);
+bool WINAPI CascFindClose(HANDLE hFind);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // __CASCLIB_H__
diff --git a/dep/CascLib/src/CascMndxRoot.cpp b/dep/CascLib/src/CascMndxRoot.cpp
new file mode 100644
index 00000000000..a788b652573
--- /dev/null
+++ b/dep/CascLib/src/CascMndxRoot.cpp
@@ -0,0 +1,3476 @@
+/*****************************************************************************/
+/* CascMndxRoot.cpp Copyright (c) Ladislav Zezula 2014 */
+/*---------------------------------------------------------------------------*/
+/* Common functions for CascLib */
+/* Note: "HOTS" refers to Play.exe, v2.5.0.29049 (Heroes of the Storm Alpha) */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 18.05.14 1.00 Lad The first version of CascMndxRoot.cpp */
+/*****************************************************************************/
+
+#define __CASCLIB_SELF__
+#include "CascLib.h"
+#include "CascCommon.h"
+#include "CascMndxRoot.h"
+
+//-----------------------------------------------------------------------------
+// Local defines
+
+#define CASC_MAR_SIGNATURE 0x0052414d // 'MAR\0'
+
+//-----------------------------------------------------------------------------
+// Local structures
+
+typedef struct _FILE_MNDX_HEADER
+{
+ DWORD Signature; // 'MNDX'
+ DWORD HeaderVersion; // Must be <= 2
+ DWORD FormatVersion;
+
+} FILE_MNDX_HEADER, *PFILE_MNDX_HEADER;
+
+typedef struct _FILE_MAR_INFO
+{
+ DWORD MarIndex;
+ DWORD MarDataSize;
+ DWORD MarDataSizeHi;
+ DWORD MarDataOffset;
+ DWORD MarDataOffsetHi;
+} FILE_MAR_INFO, *PFILE_MAR_INFO;
+
+//-----------------------------------------------------------------------------
+// Testing functions prototypes
+
+#if defined(_DEBUG) && defined(_X86_) && defined(CASCLIB_TEST)
+extern "C" bool _cdecl sub_1958B00_x86(TFileNameDatabase * pDB, TMndxFindResult * pStruct1C);
+void TestMndxRootFile(PCASC_MNDX_INFO pMndxInfo);
+#endif
+
+//-----------------------------------------------------------------------------
+// Local variables
+
+unsigned char table_1BA1818[0x800] =
+{
+ 0x07, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x06, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x07, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x06, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x07, 0x07, 0x07, 0x01, 0x07, 0x02, 0x02, 0x01, 0x07, 0x03, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01,
+ 0x07, 0x04, 0x04, 0x01, 0x04, 0x02, 0x02, 0x01, 0x04, 0x03, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01,
+ 0x07, 0x05, 0x05, 0x01, 0x05, 0x02, 0x02, 0x01, 0x05, 0x03, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01,
+ 0x05, 0x04, 0x04, 0x01, 0x04, 0x02, 0x02, 0x01, 0x04, 0x03, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01,
+ 0x07, 0x06, 0x06, 0x01, 0x06, 0x02, 0x02, 0x01, 0x06, 0x03, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01,
+ 0x06, 0x04, 0x04, 0x01, 0x04, 0x02, 0x02, 0x01, 0x04, 0x03, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01,
+ 0x06, 0x05, 0x05, 0x01, 0x05, 0x02, 0x02, 0x01, 0x05, 0x03, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01,
+ 0x05, 0x04, 0x04, 0x01, 0x04, 0x02, 0x02, 0x01, 0x04, 0x03, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01,
+ 0x07, 0x07, 0x07, 0x01, 0x07, 0x02, 0x02, 0x01, 0x07, 0x03, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01,
+ 0x07, 0x04, 0x04, 0x01, 0x04, 0x02, 0x02, 0x01, 0x04, 0x03, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01,
+ 0x07, 0x05, 0x05, 0x01, 0x05, 0x02, 0x02, 0x01, 0x05, 0x03, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01,
+ 0x05, 0x04, 0x04, 0x01, 0x04, 0x02, 0x02, 0x01, 0x04, 0x03, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01,
+ 0x07, 0x06, 0x06, 0x01, 0x06, 0x02, 0x02, 0x01, 0x06, 0x03, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01,
+ 0x06, 0x04, 0x04, 0x01, 0x04, 0x02, 0x02, 0x01, 0x04, 0x03, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01,
+ 0x06, 0x05, 0x05, 0x01, 0x05, 0x02, 0x02, 0x01, 0x05, 0x03, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01,
+ 0x05, 0x04, 0x04, 0x01, 0x04, 0x02, 0x02, 0x01, 0x04, 0x03, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x02, 0x07, 0x07, 0x07, 0x03, 0x07, 0x03, 0x03, 0x02,
+ 0x07, 0x07, 0x07, 0x04, 0x07, 0x04, 0x04, 0x02, 0x07, 0x04, 0x04, 0x03, 0x04, 0x03, 0x03, 0x02,
+ 0x07, 0x07, 0x07, 0x05, 0x07, 0x05, 0x05, 0x02, 0x07, 0x05, 0x05, 0x03, 0x05, 0x03, 0x03, 0x02,
+ 0x07, 0x05, 0x05, 0x04, 0x05, 0x04, 0x04, 0x02, 0x05, 0x04, 0x04, 0x03, 0x04, 0x03, 0x03, 0x02,
+ 0x07, 0x07, 0x07, 0x06, 0x07, 0x06, 0x06, 0x02, 0x07, 0x06, 0x06, 0x03, 0x06, 0x03, 0x03, 0x02,
+ 0x07, 0x06, 0x06, 0x04, 0x06, 0x04, 0x04, 0x02, 0x06, 0x04, 0x04, 0x03, 0x04, 0x03, 0x03, 0x02,
+ 0x07, 0x06, 0x06, 0x05, 0x06, 0x05, 0x05, 0x02, 0x06, 0x05, 0x05, 0x03, 0x05, 0x03, 0x03, 0x02,
+ 0x06, 0x05, 0x05, 0x04, 0x05, 0x04, 0x04, 0x02, 0x05, 0x04, 0x04, 0x03, 0x04, 0x03, 0x03, 0x02,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x02, 0x07, 0x07, 0x07, 0x03, 0x07, 0x03, 0x03, 0x02,
+ 0x07, 0x07, 0x07, 0x04, 0x07, 0x04, 0x04, 0x02, 0x07, 0x04, 0x04, 0x03, 0x04, 0x03, 0x03, 0x02,
+ 0x07, 0x07, 0x07, 0x05, 0x07, 0x05, 0x05, 0x02, 0x07, 0x05, 0x05, 0x03, 0x05, 0x03, 0x03, 0x02,
+ 0x07, 0x05, 0x05, 0x04, 0x05, 0x04, 0x04, 0x02, 0x05, 0x04, 0x04, 0x03, 0x04, 0x03, 0x03, 0x02,
+ 0x07, 0x07, 0x07, 0x06, 0x07, 0x06, 0x06, 0x02, 0x07, 0x06, 0x06, 0x03, 0x06, 0x03, 0x03, 0x02,
+ 0x07, 0x06, 0x06, 0x04, 0x06, 0x04, 0x04, 0x02, 0x06, 0x04, 0x04, 0x03, 0x04, 0x03, 0x03, 0x02,
+ 0x07, 0x06, 0x06, 0x05, 0x06, 0x05, 0x05, 0x02, 0x06, 0x05, 0x05, 0x03, 0x05, 0x03, 0x03, 0x02,
+ 0x06, 0x05, 0x05, 0x04, 0x05, 0x04, 0x04, 0x02, 0x05, 0x04, 0x04, 0x03, 0x04, 0x03, 0x03, 0x02,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x04, 0x07, 0x07, 0x07, 0x04, 0x07, 0x04, 0x04, 0x03,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x07, 0x07, 0x07, 0x05, 0x07, 0x05, 0x05, 0x03,
+ 0x07, 0x07, 0x07, 0x05, 0x07, 0x05, 0x05, 0x04, 0x07, 0x05, 0x05, 0x04, 0x05, 0x04, 0x04, 0x03,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x07, 0x07, 0x07, 0x06, 0x07, 0x06, 0x06, 0x03,
+ 0x07, 0x07, 0x07, 0x06, 0x07, 0x06, 0x06, 0x04, 0x07, 0x06, 0x06, 0x04, 0x06, 0x04, 0x04, 0x03,
+ 0x07, 0x07, 0x07, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x06, 0x06, 0x05, 0x06, 0x05, 0x05, 0x03,
+ 0x07, 0x06, 0x06, 0x05, 0x06, 0x05, 0x05, 0x04, 0x06, 0x05, 0x05, 0x04, 0x05, 0x04, 0x04, 0x03,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x04, 0x07, 0x07, 0x07, 0x04, 0x07, 0x04, 0x04, 0x03,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x07, 0x07, 0x07, 0x05, 0x07, 0x05, 0x05, 0x03,
+ 0x07, 0x07, 0x07, 0x05, 0x07, 0x05, 0x05, 0x04, 0x07, 0x05, 0x05, 0x04, 0x05, 0x04, 0x04, 0x03,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x07, 0x07, 0x07, 0x06, 0x07, 0x06, 0x06, 0x03,
+ 0x07, 0x07, 0x07, 0x06, 0x07, 0x06, 0x06, 0x04, 0x07, 0x06, 0x06, 0x04, 0x06, 0x04, 0x04, 0x03,
+ 0x07, 0x07, 0x07, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x06, 0x06, 0x05, 0x06, 0x05, 0x05, 0x03,
+ 0x07, 0x06, 0x06, 0x05, 0x06, 0x05, 0x05, 0x04, 0x06, 0x05, 0x05, 0x04, 0x05, 0x04, 0x04, 0x03,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x04,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x05,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x07, 0x07, 0x07, 0x05, 0x07, 0x05, 0x05, 0x04,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x07, 0x07, 0x07, 0x06, 0x07, 0x06, 0x06, 0x04,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x07, 0x07, 0x07, 0x06, 0x07, 0x06, 0x06, 0x05,
+ 0x07, 0x07, 0x07, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x06, 0x06, 0x05, 0x06, 0x05, 0x05, 0x04,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x04,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x05,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x07, 0x07, 0x07, 0x05, 0x07, 0x05, 0x05, 0x04,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x07, 0x07, 0x07, 0x06, 0x07, 0x06, 0x06, 0x04,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x07, 0x07, 0x07, 0x06, 0x07, 0x06, 0x06, 0x05,
+ 0x07, 0x07, 0x07, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x06, 0x06, 0x05, 0x06, 0x05, 0x05, 0x04,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x05,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x07, 0x07, 0x07, 0x06, 0x07, 0x06, 0x06, 0x05,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x05,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x07, 0x07, 0x07, 0x06, 0x07, 0x06, 0x06, 0x05,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07
+};
+
+//-----------------------------------------------------------------------------
+// Local functions - Number of set bits in an integer
+
+// HOTS: inlined
+DWORD GetNumberOfSetBits(DWORD Value32)
+{
+ Value32 = ((Value32 >> 1) & 0x55555555) + (Value32 & 0x55555555);
+ Value32 = ((Value32 >> 2) & 0x33333333) + (Value32 & 0x33333333);
+ Value32 = ((Value32 >> 4) & 0x0F0F0F0F) + (Value32 & 0x0F0F0F0F);
+
+ return (Value32 * 0x01010101);
+}
+
+#define GetNumbrOfSetBits32(x) (GetNumberOfSetBits(x) >> 0x18)
+
+//-----------------------------------------------------------------------------
+// Local functions - common
+
+static bool RootFileRead(LPBYTE pbFilePointer, LPBYTE pbFileEnd, void * pvBuffer, size_t dwBytesToRead)
+{
+ if((size_t)(pbFileEnd - pbFilePointer) < dwBytesToRead)
+ return false;
+
+ memcpy(pvBuffer, pbFilePointer, dwBytesToRead);
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Local functions - TMndxFindResult
+
+// HOTS: 01956EE0
+TMndxFindResult::TMndxFindResult()
+{
+ szSearchMask = NULL;
+ cchSearchMask = 0;
+ field_8 = 0;
+ szFoundPath = NULL;
+ cchFoundPath = 0;
+ FileNameIndex = 0;
+ pStruct40 = NULL;
+}
+
+// HOTS: 01956F00
+TMndxFindResult::~TMndxFindResult()
+{
+ FreeStruct40();
+}
+
+// HOTS: 01956F30
+int TMndxFindResult::CreateStruct40()
+{
+ if(pStruct40 != NULL)
+ return ERROR_INVALID_PARAMETER;
+
+ pStruct40 = new TStruct40();
+ return (pStruct40 != NULL) ? ERROR_SUCCESS : ERROR_NOT_ENOUGH_MEMORY;
+}
+
+void TMndxFindResult::FreeStruct40()
+{
+ if(pStruct40 != NULL)
+ delete pStruct40;
+ pStruct40 = NULL;
+}
+
+// HOTS: 01956E70
+int TMndxFindResult::SetSearchPath(
+ const char * szNewSearchMask,
+ size_t cchNewSearchMask)
+{
+ if(szSearchMask == NULL && cchSearchMask != 0)
+ return ERROR_INVALID_PARAMETER;
+
+ if(pStruct40 != NULL)
+ pStruct40->SearchPhase = CASC_SEARCH_INITIALIZING;
+
+ szSearchMask = szNewSearchMask;
+ cchSearchMask = cchNewSearchMask;
+ return ERROR_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// TByteStream functions
+
+// HOTS: 01959990
+TByteStream::TByteStream()
+{
+ pbByteData = NULL;
+ pvMappedFile = NULL;
+ cbByteData = 0;
+ field_C = 0;
+ hFile = 0;
+ hMap = 0;
+}
+
+// HOTS: 19599F0
+void TByteStream::ExchangeWith(TByteStream & Target)
+{
+ TByteStream WorkBuff;
+
+ WorkBuff = *this;
+ *this = Target;
+ Target = WorkBuff;
+}
+
+// HOTS: 19599F0
+int TByteStream::GetBytes(DWORD cbByteCount, PARRAY_POINTER PtrArray)
+{
+ if(cbByteData < cbByteCount)
+ return ERROR_BAD_FORMAT;
+
+ // Give the buffer to the caller
+ PtrArray->Bytes = pbByteData;
+
+ // Move pointers
+ pbByteData += cbByteCount;
+ cbByteData -= cbByteCount;
+ return ERROR_SUCCESS;
+}
+
+// HOTS: 1957190
+int TByteStream::GetArray_DWORDs(PARRAY_POINTER PtrArray, DWORD ItemCount)
+{
+ if(PtrArray == NULL && ItemCount != 0)
+ return ERROR_INVALID_PARAMETER;
+ if(ItemCount > CASC_MAX_ENTRIES(DWORD))
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ return GetBytes(ItemCount * 4, PtrArray);
+}
+
+// HOTS: 19571E0
+int TByteStream::GetArray_Triplets(PARRAY_POINTER PtrArray, DWORD ItemCount)
+{
+ if(PtrArray == NULL && ItemCount != 0)
+ return ERROR_INVALID_PARAMETER;
+ if(ItemCount > CASC_MAX_ENTRIES(TRIPLET))
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ return GetBytes(ItemCount * sizeof(TRIPLET), PtrArray);
+}
+
+// HOTS: 1957230
+int TByteStream::GetArray_BYTES(PARRAY_POINTER PtrArray, DWORD ItemCount)
+{
+ if(PtrArray == NULL && ItemCount != 0)
+ return ERROR_INVALID_PARAMETER;
+ if(ItemCount > CASC_MAX_ENTRIES(BYTE))
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ return GetBytes(ItemCount, PtrArray);
+}
+
+// HOTS: 1957280
+int TByteStream::GetArray_NameTable(PARRAY_POINTER PtrArray, DWORD ItemCount)
+{
+ if(PtrArray == NULL && ItemCount != 0)
+ return ERROR_INVALID_PARAMETER;
+ if(ItemCount > CASC_MAX_ENTRIES(NAME_FRAG))
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ return GetBytes(ItemCount * sizeof(NAME_FRAG), PtrArray);
+}
+
+// HOTS: 1959A60
+int TByteStream::SkipBytes(DWORD cbByteCount)
+{
+ ARRAY_POINTER Dummy;
+
+ return GetBytes(cbByteCount, &Dummy);
+}
+
+// HOTS: 1959AF0
+int TByteStream::SetByteBuffer(LPBYTE pbNewByteData, DWORD cbNewByteData)
+{
+ if(pbNewByteData != NULL || cbNewByteData == 0)
+ {
+ pbByteData = pbNewByteData;
+ cbByteData = cbNewByteData;
+ return ERROR_SUCCESS;
+ }
+
+ return ERROR_INVALID_PARAMETER;
+}
+
+
+// HOTS: 1957160
+int TByteStream::GetValue_DWORD(DWORD & Value)
+{
+ ARRAY_POINTER Pointer;
+ int nError;
+
+ nError = GetBytes(sizeof(DWORD), &Pointer);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ Value = Pointer.Uint32s[0];
+ return ERROR_SUCCESS;
+}
+
+int TByteStream::GetValue_ItemCount(DWORD & NumberOfBytes, DWORD & ItemCount, DWORD ItemSize)
+{
+ ARRAY_POINTER Pointer;
+ ULONGLONG ByteCount;
+ int nError;
+
+ // Verify if there is at least - 8 bytes
+ nError = GetBytes(sizeof(ULONGLONG), &Pointer);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ // Extract the number of bytes
+ ByteCount = Pointer.Int64Ptr[0];
+ if(ByteCount > 0xFFFFFFFF || (ByteCount % ItemSize) != 0)
+ return ERROR_BAD_FORMAT;
+
+ // Give the result to the caller
+ NumberOfBytes = (DWORD)ByteCount;
+ ItemCount = (DWORD)(ByteCount / ItemSize);
+ return ERROR_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// TGenericArray functions
+
+TGenericArray::TGenericArray()
+{
+ DataBuffer.Bytes = NULL;
+ FirstValid.Bytes = NULL;
+ ArrayPointer.Bytes = NULL;
+ ItemCount = 0;
+ MaxItemCount = 0;
+ bIsValidArray = false;
+}
+
+TGenericArray::~TGenericArray()
+{
+ if(DataBuffer.Bytes != NULL)
+ CASC_FREE(DataBuffer.Bytes);
+}
+
+// HOTS: inlined
+void TGenericArray::ExchangeWith(TGenericArray & Target)
+{
+ TGenericArray WorkBuff;
+
+ WorkBuff = *this;
+ *this = Target;
+ Target = WorkBuff;
+}
+
+// HOTS: Inlined
+void TGenericArray::CopyFrom(TGenericArray & Source)
+{
+ if(DataBuffer.Bytes != NULL)
+ CASC_FREE(DataBuffer.Bytes);
+ *this = Source;
+}
+
+// HOTS: 1957090 (SetDwordsValid)
+// HOTS: 19570B0 (SetTripletsValid)
+// HOTS: 19570D0 (? SetBitsValid ?)
+// HOTS: 19570F0 (SetNameFragmentsValid)
+int TGenericArray::SetArrayValid()
+{
+ if(bIsValidArray != 0)
+ return 1;
+
+ bIsValidArray = true;
+ return ERROR_SUCCESS;
+}
+
+
+// HOTS: 19575A0
+void TGenericArray::SetMaxItems_CHARS(DWORD NewMaxItemCount)
+{
+ ARRAY_POINTER OldDataBuffer = DataBuffer;
+ ARRAY_POINTER NewDataBuffer;
+
+ // Allocate new data buffer
+ NewDataBuffer.Chars = CASC_ALLOC(char, NewMaxItemCount);
+ if(NewDataBuffer.Chars != NULL)
+ {
+ // Copy the old items to the buffer
+ for(DWORD i = 0; i < ItemCount; i++)
+ {
+ NewDataBuffer.Chars[i] = FirstValid.Chars[i];
+ }
+ }
+
+ DataBuffer = NewDataBuffer;
+ FirstValid = NewDataBuffer;
+ ArrayPointer = NewDataBuffer;
+ MaxItemCount = NewMaxItemCount;
+ CASC_FREE(OldDataBuffer.Chars);
+}
+
+// HOTS: 1957600
+void TGenericArray::SetMaxItems_PATH_STOP(DWORD NewMaxItemCount)
+{
+ ARRAY_POINTER OldDataBuffer = DataBuffer;
+ ARRAY_POINTER NewDataBuffer;
+
+ // Allocate new data buffer
+ NewDataBuffer.PathStopPtr = CASC_ALLOC(PATH_STOP, NewMaxItemCount);
+ if(NewDataBuffer.PathStopPtr != NULL)
+ {
+ // Copy the old items to the buffer
+ for(DWORD i = 0; i < ItemCount; i++)
+ {
+ NewDataBuffer.PathStopPtr[i] = FirstValid.PathStopPtr[i];
+ }
+ }
+
+ DataBuffer = NewDataBuffer;
+ FirstValid = NewDataBuffer;
+ ArrayPointer = NewDataBuffer;
+ MaxItemCount = NewMaxItemCount;
+ CASC_FREE(OldDataBuffer.PathStopPtr);
+}
+
+// HOTS: inline
+void TGenericArray::InsertOneItem_CHAR(char NewItem)
+{
+ DWORD NewMaxItemCount;
+ DWORD NewItemCount;
+
+ NewItemCount = ItemCount + 1;
+ if(NewItemCount > MaxItemCount)
+ {
+ NewMaxItemCount = NewItemCount;
+
+ if(MaxItemCount > (NewItemCount / 2))
+ {
+ if(MaxItemCount <= (CASC_MAX_ENTRIES(BYTE) / 2))
+ NewMaxItemCount = MaxItemCount + MaxItemCount;
+ else
+ NewMaxItemCount = CASC_MAX_ENTRIES(BYTE);
+ }
+
+ SetMaxItems_CHARS(NewMaxItemCount);
+ }
+
+ // Put the character to the slot that has been reserved
+ FirstValid.Chars[ItemCount++] = NewItem;
+}
+
+// HOTS: 1958330, inline
+void TGenericArray::InsertOneItem_PATH_STOP(PATH_STOP & NewItem)
+{
+ DWORD NewMaxItemCount;
+ DWORD NewItemCount;
+
+ NewItemCount = ItemCount + 1;
+ if(NewItemCount > MaxItemCount)
+ {
+ NewMaxItemCount = NewItemCount;
+
+ if(MaxItemCount > (NewItemCount / 2))
+ {
+ if(MaxItemCount <= (CASC_MAX_ENTRIES(PATH_STOP) / 2))
+ NewMaxItemCount = MaxItemCount + MaxItemCount;
+ else
+ NewMaxItemCount = CASC_MAX_ENTRIES(PATH_STOP);
+ }
+
+ SetMaxItems_PATH_STOP(NewMaxItemCount);
+ }
+
+ // Put the structure to the slot that has been reserved
+ FirstValid.PathStopPtr[ItemCount++] = NewItem;
+}
+
+// HOTS: 19583A0
+void TGenericArray::sub_19583A0(DWORD NewItemCount)
+{
+ DWORD OldMaxItemCount = MaxItemCount;
+
+ if(NewItemCount > MaxItemCount)
+ {
+ DWORD NewMaxItemCount = NewItemCount;
+
+ if(MaxItemCount > (NewItemCount / 2))
+ {
+ if(MaxItemCount <= (CASC_MAX_ENTRIES(PATH_STOP) / 2))
+ NewMaxItemCount = MaxItemCount + MaxItemCount;
+ else
+ NewMaxItemCount = CASC_MAX_ENTRIES(PATH_STOP);
+ }
+
+ SetMaxItems_PATH_STOP(NewMaxItemCount);
+ }
+
+ // Initialize the newly inserted items
+ for(DWORD i = OldMaxItemCount; i < NewItemCount; i++)
+ {
+ FirstValid.PathStopPtr[i].ItemIndex = 0;
+ FirstValid.PathStopPtr[i].field_4 = 0;
+ FirstValid.PathStopPtr[i].field_8 = 0;
+ FirstValid.PathStopPtr[i].field_C = 0xFFFFFFFF;
+ FirstValid.PathStopPtr[i].field_10 = 0xFFFFFFFF;
+ }
+
+ ItemCount = NewItemCount;
+}
+
+// HOTS: 1957440
+int TGenericArray::LoadDwordsArray(TByteStream & InStream)
+{
+ DWORD NumberOfBytes;
+ int nError;
+
+ // Get and verify the number of items
+ nError = InStream.GetValue_ItemCount(NumberOfBytes, ItemCount, sizeof(DWORD));
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ nError = InStream.GetArray_DWORDs(&ArrayPointer, ItemCount);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ nError = InStream.SkipBytes((0 - (DWORD)NumberOfBytes) & 0x07);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ return SetArrayValid();
+}
+
+// HOTS: 19574E0
+int TGenericArray::LoadTripletsArray(TByteStream & InStream)
+{
+ DWORD NumberOfBytes;
+ int nError;
+
+ // Get and verify the number of items
+ nError = InStream.GetValue_ItemCount(NumberOfBytes, ItemCount, sizeof(TRIPLET));
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ nError = InStream.GetArray_Triplets(&ArrayPointer, ItemCount);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ nError = InStream.SkipBytes((0 - (DWORD)NumberOfBytes) & 0x07);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ return SetArrayValid();
+}
+
+// HOTS: 1957690
+int TGenericArray::LoadByteArray(TByteStream & InStream)
+{
+ DWORD NumberOfBytes;
+ int nError;
+
+ // Get and verify the number of items
+ nError = InStream.GetValue_ItemCount(NumberOfBytes, ItemCount, sizeof(BYTE));
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ nError = InStream.GetArray_BYTES(&ArrayPointer, ItemCount);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ nError = InStream.SkipBytes((0 - (DWORD)NumberOfBytes) & 0x07);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ return SetArrayValid();
+}
+
+// HOTS: 1957700
+int TGenericArray::LoadFragmentInfos(TByteStream & InStream)
+{
+ DWORD NumberOfBytes;
+ int nError;
+
+ // Get and verify the number of items
+ nError = InStream.GetValue_ItemCount(NumberOfBytes, ItemCount, sizeof(NAME_FRAG));
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ nError = InStream.GetArray_NameTable(&ArrayPointer, ItemCount);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ nError = InStream.SkipBytes((0 - (DWORD)NumberOfBytes) & 0x07);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ return SetArrayValid();
+}
+
+// HOTS: 195A220
+int TGenericArray::LoadStrings(TByteStream & InStream)
+{
+ DWORD NumberOfBytes;
+ int nError;
+
+ // Get and verify the number of items
+ nError = InStream.GetValue_ItemCount(NumberOfBytes, ItemCount, sizeof(char));
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ nError = InStream.GetArray_BYTES(&ArrayPointer, ItemCount);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ nError = InStream.SkipBytes((0 - (DWORD)NumberOfBytes) & 0x07);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ return SetArrayValid();
+}
+
+// HOTS: 19581C0
+int TGenericArray::LoadDwordsArray_Copy(TByteStream & InStream)
+{
+ TGenericArray TempArray;
+ int nError;
+
+ nError = TempArray.LoadDwordsArray(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ CopyFrom(TempArray);
+ return ERROR_SUCCESS;
+}
+
+// HOTS: 1958250
+int TGenericArray::LoadTripletsArray_Copy(TByteStream & InStream)
+{
+ TGenericArray TempArray;
+ int nError;
+
+ nError = TempArray.LoadTripletsArray(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ CopyFrom(TempArray);
+ return ERROR_SUCCESS;
+}
+
+// HOTS: 1958420
+int TGenericArray::LoadBytes_Copy(TByteStream & InStream)
+{
+ TGenericArray TempArray;
+ int nError;
+
+ nError = TempArray.LoadByteArray(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ CopyFrom(TempArray);
+ return 0;
+}
+
+// HOTS: 19584F0
+int TGenericArray::LoadFragmentInfos_Copy(TByteStream & InStream)
+{
+ TGenericArray TempArray;
+ int nError;
+
+ nError = TempArray.LoadFragmentInfos(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ CopyFrom(TempArray);
+ return ERROR_SUCCESS;
+}
+
+// HOTS: 195A360
+int TGenericArray::LoadStringsWithCopy(TByteStream & InStream)
+{
+ TGenericArray TempArray;
+ int nError;
+
+ nError = TempArray.LoadStrings(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ CopyFrom(TempArray);
+ return ERROR_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// TBitEntryArray functions
+
+TBitEntryArray::TBitEntryArray()
+{
+ BitsPerEntry = 0;
+ EntryBitMask = 0;
+ TotalEntries = 0;
+}
+
+TBitEntryArray::~TBitEntryArray()
+{}
+
+// HOTS: 01957D20
+void TBitEntryArray::ExchangeWith(TBitEntryArray & Target)
+{
+ TBitEntryArray WorkBuff;
+
+ WorkBuff = *this;
+ *this = Target;
+ Target = WorkBuff;
+}
+
+// HOTS: 1958580
+int TBitEntryArray::LoadFromStream(TByteStream & InStream)
+{
+ ARRAY_POINTER Pointer;
+ ULONGLONG Value = 0;
+ int nError;
+
+ nError = LoadDwordsArray_Copy(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ nError = InStream.GetBytes(sizeof(DWORD), &Pointer);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ BitsPerEntry = Pointer.Uint32s[0];
+ if(BitsPerEntry > 0x20)
+ return ERROR_BAD_FORMAT;
+
+ nError = InStream.GetBytes(sizeof(DWORD), &Pointer);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+ EntryBitMask = Pointer.Uint32s[0];
+
+ nError = InStream.GetBytes(sizeof(ULONGLONG), &Pointer);
+ if(nError == ERROR_SUCCESS)
+ Value = Pointer.Int64Ptr[0];
+ if(Value > 0xFFFFFFFF)
+ return ERROR_BAD_FORMAT;
+ TotalEntries = (DWORD)Value;
+
+ assert((BitsPerEntry * TotalEntries) / 32 <= ItemCount);
+ return ERROR_SUCCESS;
+}
+
+// HOTS: 1959300
+int TBitEntryArray::LoadFromStream_Exchange(TByteStream & InStream)
+{
+ TBitEntryArray TempArray;
+ int nError;
+
+ nError = TempArray.LoadFromStream(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ ExchangeWith(TempArray);
+ return ERROR_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// TStruct40 functions
+
+TStruct40::TStruct40()
+{
+ ItemIndex = 0;
+ CharIndex = 0;
+ ItemCount = 0;
+ SearchPhase = CASC_SEARCH_INITIALIZING;
+}
+
+// HOTS: 19586B0
+void TStruct40::InitSearchBuffers()
+{
+ DWORD NewMaxItemCount;
+
+ array_00.ItemCount = 0;
+
+ // HOTS: 19586BD
+ if(array_00.MaxItemCount < 0x40)
+ {
+ // HOTS: 19586C2
+ NewMaxItemCount = 0x40;
+
+ if(array_00.MaxItemCount > 0x20)
+ {
+ if(array_00.MaxItemCount <= 0x7FFFFFFF)
+ NewMaxItemCount = array_00.MaxItemCount + array_00.MaxItemCount;
+ else
+ NewMaxItemCount = CASC_MAX_ENTRIES(BYTE);
+ }
+
+ array_00.SetMaxItems_CHARS(NewMaxItemCount);
+ }
+
+ // HOTS: 19586E1
+ // Set the new item count
+ PathStops.sub_19583A0(0);
+
+ if(PathStops.MaxItemCount < 4)
+ {
+ // HOTS: 19586F2
+ NewMaxItemCount = 4;
+
+ // HOTS: 19586EA
+ if(PathStops.MaxItemCount > 2)
+ {
+ if(PathStops.MaxItemCount <= 0x6666666)
+ NewMaxItemCount = PathStops.MaxItemCount + PathStops.MaxItemCount;
+ else
+ NewMaxItemCount = CASC_MAX_ENTRIES(PATH_STOP);
+ }
+
+ // HOTS: 195870B
+ PathStops.SetMaxItems_PATH_STOP(NewMaxItemCount);
+ }
+
+ ItemIndex = 0;
+ CharIndex = 0;
+ ItemCount = 0;
+ SearchPhase = CASC_SEARCH_SEARCHING;
+}
+
+//-----------------------------------------------------------------------------
+// TSparseArray functions
+
+TSparseArray::TSparseArray()
+{
+ TotalItemCount = 0;
+ ValidItemCount = 0;
+}
+
+// HOTS: 1957DA0
+void TSparseArray::ExchangeWith(TSparseArray & Target)
+{
+ TSparseArray WorkBuff;
+
+ WorkBuff = *this;
+ *this = Target;
+ Target = WorkBuff;
+}
+
+// HOTS: 1958630
+int TSparseArray::LoadFromStream(TByteStream & InStream)
+{
+ ARRAY_POINTER Pointer;
+ int nError;
+
+ nError = ItemBits.LoadDwordsArray_Copy(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ nError = InStream.GetBytes(sizeof(DWORD), &Pointer);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+ TotalItemCount = Pointer.Uint32s[0];
+
+ nError = InStream.GetBytes(sizeof(DWORD), &Pointer);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+ ValidItemCount = Pointer.Uint32s[0];
+
+ if(ValidItemCount > TotalItemCount)
+ return ERROR_FILE_CORRUPT;
+
+ nError = BaseValues.LoadTripletsArray_Copy(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ nError = ArrayDwords_38.LoadDwordsArray_Copy(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ nError = ArrayDwords_50.LoadDwordsArray_Copy(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ return ERROR_SUCCESS;
+}
+
+// HOTS: 1959380
+int TSparseArray::LoadFromStream_Exchange(TByteStream & InStream)
+{
+ TSparseArray NewStruct68;
+ int nError;
+
+ nError = NewStruct68.LoadFromStream(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ ExchangeWith(NewStruct68);
+ return ERROR_SUCCESS;
+}
+
+// HOTS: 1959B60
+DWORD TSparseArray::GetItemValue(DWORD ItemIndex)
+{
+ PTRIPLET pTriplet;
+ DWORD DwordIndex;
+ DWORD BaseValue;
+ DWORD BitMask;
+
+ //
+ // Divide the low-8-bits index to four parts:
+ //
+ // |-----------------------|---|------------|
+ // | A (23 bits) | B | C |
+ // |-----------------------|---|------------|
+ //
+ // A (23-bits): Index to the table (60 bits per entry)
+ //
+ // Layout of the table entry:
+ // |--------------------------------|-------|--------|--------|---------|---------|---------|---------|-----|
+ // | Base Value | val[0]| val[1] | val[2] | val[3] | val[4] | val[5] | val[6] | - |
+ // | 32 bits | 7 bits| 8 bits | 8 bits | 9 bits | 9 bits | 9 bits | 9 bits |5bits|
+ // |--------------------------------|-------|--------|--------|---------|---------|---------|---------|-----|
+ //
+ // B (3 bits) : Index of the variable-bit value in the array (val[#], see above)
+ //
+ // C (32 bits): Number of bits to be checked (up to 0x3F bits).
+ // Number of set bits is then added to the values obtained from A and B
+
+ // Upper 23 bits contain index to the table
+ pTriplet = BaseValues.TripletArray + (ItemIndex >> 0x09);
+ BaseValue = pTriplet->BaseValue;
+
+ // Next 3 bits contain the index to the VBR
+ switch(((ItemIndex >> 0x06) & 0x07) - 1)
+ {
+ case 0: // Add the 1st value (7 bits)
+ BaseValue += (pTriplet->Value2 & 0x7F);
+ break;
+
+ case 1: // Add the 2nd value (8 bits)
+ BaseValue += (pTriplet->Value2 >> 0x07) & 0xFF;
+ break;
+
+ case 2: // Add the 3rd value (8 bits)
+ BaseValue += (pTriplet->Value2 >> 0x0F) & 0xFF;
+ break;
+
+ case 3: // Add the 4th value (9 bits)
+ BaseValue += (pTriplet->Value2 >> 0x17);
+ break;
+
+ case 4: // Add the 5th value (9 bits)
+ BaseValue += (pTriplet->Value3 & 0x1FF);
+ break;
+
+ case 5: // Add the 6th value (9 bits)
+ BaseValue += (pTriplet->Value3 >> 0x09) & 0x1FF;
+ break;
+
+ case 6: // Add the 7th value (9 bits)
+ BaseValue += (pTriplet->Value3 >> 0x12) & 0x1FF;
+ break;
+ }
+
+ //
+ // Take the upper 27 bits as an index to DWORD array, take lower 5 bits
+ // as number of bits to mask. Then calculate number of set bits in the value
+ // masked value.
+ //
+
+ // Get the index into the array of DWORDs
+ DwordIndex = (ItemIndex >> 0x05);
+
+ // Add number of set bits in the masked value up to 0x3F bits
+ if(ItemIndex & 0x20)
+ BaseValue += GetNumbrOfSetBits32(ItemBits.Uint32Array[DwordIndex - 1]);
+
+ BitMask = (1 << (ItemIndex & 0x1F)) - 1;
+ return BaseValue + GetNumbrOfSetBits32(ItemBits.Uint32Array[DwordIndex] & BitMask);
+}
+
+//-----------------------------------------------------------------------------
+// TNameIndexStruct functions
+
+// HOTS: 0195A290
+TNameIndexStruct::TNameIndexStruct()
+{}
+
+// HOTS: inlined
+TNameIndexStruct::~TNameIndexStruct()
+{}
+
+// HOTS: 195A180
+bool TNameIndexStruct::CheckNameFragment(TMndxFindResult * pStruct1C, DWORD dwFragOffs)
+{
+ TStruct40 * pStruct40 = pStruct1C->pStruct40;
+ const char * szPathFragment;
+ const char * szSearchMask;
+
+ if(!Struct68.TotalItemCount)
+ {
+ // Get the offset of the fragment to compare. For convenience with pStruct40->CharIndex,
+ // subtract the CharIndex from the fragment offset
+ szPathFragment = (NameFragments.CharArray + dwFragOffs - pStruct40->CharIndex);
+ szSearchMask = pStruct1C->szSearchMask;
+
+ // Keep searching as long as the name matches with the fragment
+ while(szPathFragment[pStruct40->CharIndex] == szSearchMask[pStruct40->CharIndex])
+ {
+ // Move to the next character
+ pStruct40->CharIndex++;
+
+ // Is it the end of the fragment or end of the path?
+ if(szPathFragment[pStruct40->CharIndex] == 0)
+ return true;
+ if(pStruct40->CharIndex >= pStruct1C->cchSearchMask)
+ return false;
+ }
+
+ return false;
+ }
+ else
+ {
+ // Get the offset of the fragment to compare.
+ szPathFragment = (const char *)(NameFragments.CharArray);
+ szSearchMask = pStruct1C->szSearchMask;
+
+ // Keep searching as long as the name matches with the fragment
+ while(szPathFragment[dwFragOffs] == szSearchMask[pStruct40->CharIndex])
+ {
+ // Move to the next character
+ pStruct40->CharIndex++;
+
+ // Is it the end of the fragment or end of the path?
+ if(Struct68.IsItemPresent(dwFragOffs++))
+ return true;
+ if(dwFragOffs >= pStruct1C->cchSearchMask)
+ return false;
+ }
+
+ return false;
+ }
+}
+
+// HOTS: 195A570
+bool TNameIndexStruct::CheckAndCopyNameFragment(TMndxFindResult * pStruct1C, DWORD dwFragOffs)
+{
+ TStruct40 * pStruct40 = pStruct1C->pStruct40;
+ const char * szPathFragment;
+ const char * szSearchMask;
+
+ if(!Struct68.TotalItemCount)
+ {
+ // Get the offset of the fragment to compare. For convenience with pStruct40->CharIndex,
+ // subtract the CharIndex from the fragment offset
+ szPathFragment = (const char *)(NameFragments.CharArray + dwFragOffs - pStruct40->CharIndex);
+ szSearchMask = pStruct1C->szSearchMask;
+
+ // Keep copying as long as we don't reach the end of the search mask
+ while(pStruct40->CharIndex < pStruct1C->cchSearchMask)
+ {
+ // HOTS: 195A5A0
+ if(szPathFragment[pStruct40->CharIndex] != szSearchMask[pStruct40->CharIndex])
+ return false;
+
+ // HOTS: 195A5B7
+ pStruct40->array_00.InsertOneItem_CHAR(szPathFragment[pStruct40->CharIndex]);
+ pStruct40->CharIndex++;
+
+ if(szPathFragment[pStruct40->CharIndex] == 0)
+ return true;
+ }
+
+ // Fixup the address of the fragment
+ szPathFragment += pStruct40->CharIndex;
+
+ // HOTS: 195A660
+ // Now we need to copy the rest of the fragment
+ while(szPathFragment[0] != 0)
+ {
+ pStruct40->array_00.InsertOneItem_CHAR(szPathFragment[0]);
+ szPathFragment++;
+ }
+ }
+ else
+ {
+ // Get the offset of the fragment to compare
+ // HOTS: 195A6B7
+ szPathFragment = NameFragments.CharArray;
+ szSearchMask = pStruct1C->szSearchMask;
+
+ // Keep copying as long as we don't reach the end of the search mask
+ while(dwFragOffs < pStruct1C->cchSearchMask)
+ {
+ if(szPathFragment[dwFragOffs] != szSearchMask[pStruct40->CharIndex])
+ return false;
+
+ pStruct40->array_00.InsertOneItem_CHAR(szPathFragment[dwFragOffs]);
+ pStruct40->CharIndex++;
+
+ // Keep going as long as the given bit is not set
+ if(Struct68.IsItemPresent(dwFragOffs++))
+ return true;
+ }
+
+ // Fixup the address of the fragment
+ szPathFragment += dwFragOffs;
+
+ // Now we need to copy the rest of the fragment
+ while(Struct68.IsItemPresent(dwFragOffs++) == 0)
+ {
+ // HOTS: 195A7A6
+ pStruct40->array_00.InsertOneItem_CHAR(szPathFragment[0]);
+ szPathFragment++;
+ }
+ }
+
+ return true;
+}
+
+// HOTS: 195A3F0
+void TNameIndexStruct::CopyNameFragment(TMndxFindResult * pStruct1C, DWORD dwFragOffs)
+{
+ TStruct40 * pStruct40 = pStruct1C->pStruct40;
+ const char * szPathFragment;
+
+ // HOTS: 195A3FA
+ if(!Struct68.TotalItemCount)
+ {
+ // HOTS: 195A40C
+ szPathFragment = NameFragments.CharArray + dwFragOffs;
+ while(szPathFragment[0] != 0)
+ {
+ // Insert the character to the path being built
+ pStruct40->array_00.InsertOneItem_CHAR(*szPathFragment++);
+ }
+ }
+ else
+ {
+ // HOTS: 195A4B3
+ for(;;)
+ {
+ // Insert the character to the path being built
+ pStruct40->array_00.InsertOneItem_CHAR(NameFragments.CharArray[dwFragOffs]);
+
+ // Keep going as long as the given bit is not set
+ if(Struct68.IsItemPresent(dwFragOffs++))
+ break;
+ }
+ }
+}
+
+// HOTS: 0195A300
+void TNameIndexStruct::ExchangeWith(TNameIndexStruct & Target)
+{
+ TNameIndexStruct WorkBuff;
+
+ WorkBuff = *this;
+ *this = Target;
+ Target = WorkBuff;
+}
+
+// HOTS: 0195A820
+int TNameIndexStruct::LoadFromStream(TByteStream & InStream)
+{
+ int nError;
+
+ nError = NameFragments.LoadStringsWithCopy(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ return Struct68.LoadFromStream_Exchange(InStream);
+}
+
+// HOTS: 195A850
+int TNameIndexStruct::LoadFromStream_Exchange(TByteStream & InStream)
+{
+ TNameIndexStruct TempIndexStruct;
+ int nError;
+
+ nError = TempIndexStruct.LoadFromStream(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ ExchangeWith(TempIndexStruct);
+ return ERROR_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// TStruct10 functions
+
+TStruct10::TStruct10()
+{
+ field_0 = 0x03;
+ field_4 = 0x200;
+ field_8 = 0x1000;
+ field_C = 0x20000;
+}
+
+// HOTS: inline
+void TStruct10::CopyFrom(TStruct10 & Target)
+{
+ field_0 = Target.field_0;
+ field_4 = Target.field_4;
+ field_8 = Target.field_8;
+ field_C = Target.field_C;
+}
+
+// HOTS: 1956FD0
+int TStruct10::sub_1956FD0(DWORD dwBitMask)
+{
+ switch(dwBitMask & 0xF80)
+ {
+ case 0x00:
+ field_4 = 0x200;
+ return ERROR_SUCCESS;
+
+ case 0x80:
+ field_4 = 0x80;
+ return ERROR_SUCCESS;
+
+ case 0x100:
+ field_4 = 0x100;
+ return ERROR_SUCCESS;
+
+ case 0x200:
+ field_4 = 0x200;
+ return ERROR_SUCCESS;
+
+ case 0x400:
+ field_4 = 0x400;
+ return ERROR_SUCCESS;
+
+ case 0x800:
+ field_4 = 0x800;
+ return ERROR_SUCCESS;
+ }
+
+ return ERROR_INVALID_PARAMETER;
+}
+
+// HOTS: 1957050
+int TStruct10::sub_1957050(DWORD dwBitMask)
+{
+ switch(dwBitMask & 0xF0000)
+ {
+ case 0x00:
+ field_C = 0x20000;
+ return ERROR_SUCCESS;
+
+ case 0x10000:
+ field_C = 0x10000;
+ return ERROR_SUCCESS;
+
+ case 0x20000:
+ field_C = 0x20000;
+ return ERROR_SUCCESS;
+ }
+
+ return ERROR_INVALID_PARAMETER;
+}
+
+// HOTS: 19572E0
+int TStruct10::sub_19572E0(DWORD dwBitMask)
+{
+ DWORD dwSubMask;
+ int nError;
+
+ if(dwBitMask & 0xFFF00000)
+ return ERROR_INVALID_PARAMETER;
+
+ dwSubMask = dwBitMask & 0x7F;
+ if(dwSubMask)
+ field_0 = dwSubMask;
+
+ nError = sub_1956FD0(dwBitMask);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ dwSubMask = dwBitMask & 0xF000;
+ if(dwSubMask == 0 || dwSubMask == 0x1000)
+ {
+ field_8 = 0x1000;
+ return sub_1957050(dwBitMask);
+ }
+
+ if(dwSubMask == 0x2000)
+ {
+ field_8 = 0x2000;
+ return sub_1957050(dwBitMask);
+ }
+
+ return ERROR_INVALID_PARAMETER;
+}
+
+// HOTS: 1957800
+int TStruct10::sub_1957800(DWORD dwBitMask)
+{
+ TStruct10 TempStruct;
+ int nError;
+
+ nError = TempStruct.sub_19572E0(dwBitMask);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ CopyFrom(TempStruct);
+ return ERROR_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// TFileNameDatabase functions
+
+// HOTS: 01958730
+TFileNameDatabase::TFileNameDatabase()
+{
+ NameFragIndexMask = 0;
+ field_214 = 0;
+}
+
+// HOTS: inlined
+void TFileNameDatabase::ExchangeWith(TFileNameDatabase & Target)
+{
+ TFileNameDatabasePtr TempPtr;
+ DWORD dwTemp;
+
+ Struct68_00.ExchangeWith(Target.Struct68_00);
+ FileNameIndexes.ExchangeWith(Target.FileNameIndexes);
+ Struct68_D0.ExchangeWith(Target.Struct68_D0);
+
+ FrgmDist_LoBits.ExchangeWith(Target.FrgmDist_LoBits);
+ FrgmDist_HiBits.ExchangeWith(Target.FrgmDist_HiBits);
+
+ IndexStruct_174.ExchangeWith(Target.IndexStruct_174);
+
+ TempPtr = NextDB;
+ NextDB = Target.NextDB;
+ Target.NextDB = TempPtr;
+
+ NameFragTable.ExchangeWith(Target.NameFragTable);
+
+ dwTemp = NameFragIndexMask;
+ NameFragIndexMask = Target.NameFragIndexMask;
+ Target.NameFragIndexMask = dwTemp;
+
+ dwTemp = field_214;
+ field_214 = Target.field_214;
+ Target.field_214 = dwTemp;
+
+ Struct10.CopyFrom(Target.Struct10);
+}
+
+// HOTS: 1959CB0
+DWORD TFileNameDatabase::sub_1959CB0(DWORD dwItemIndex)
+{
+ PTRIPLET pTriplet;
+ DWORD dwKeyShifted = (dwItemIndex >> 9);
+ DWORD eax, ebx, ecx, edx, esi, edi;
+
+ // If lower 9 is zero
+ edx = dwItemIndex;
+ if((edx & 0x1FF) == 0)
+ return Struct68_00.ArrayDwords_38.Uint32Array[dwKeyShifted];
+
+ eax = Struct68_00.ArrayDwords_38.Uint32Array[dwKeyShifted] >> 9;
+ esi = (Struct68_00.ArrayDwords_38.Uint32Array[dwKeyShifted + 1] + 0x1FF) >> 9;
+ dwItemIndex = esi;
+
+ if((eax + 0x0A) >= esi)
+ {
+ // HOTS: 1959CF7
+ pTriplet = Struct68_00.BaseValues.TripletArray + eax + 1;
+ edi = (eax << 0x09);
+ ebx = edi - pTriplet->BaseValue + 0x200;
+ while(edx >= ebx)
+ {
+ // HOTS: 1959D14
+ edi += 0x200;
+ pTriplet++;
+
+ ebx = edi - pTriplet->BaseValue + 0x200;
+ eax++;
+ }
+ }
+ else
+ {
+ // HOTS: 1959D2E
+ while((eax + 1) < esi)
+ {
+ // HOTS: 1959D38
+ // ecx = Struct68_00.BaseValues.TripletArray;
+ esi = (esi + eax) >> 1;
+ ebx = (esi << 0x09) - Struct68_00.BaseValues.TripletArray[esi].BaseValue;
+ if(edx < ebx)
+ {
+ // HOTS: 01959D4B
+ dwItemIndex = esi;
+ }
+ else
+ {
+ // HOTS: 1959D50
+ eax = esi;
+ esi = dwItemIndex;
+ }
+ }
+ }
+
+ // HOTS: 1959D5F
+ pTriplet = Struct68_00.BaseValues.TripletArray + eax;
+ edx += pTriplet->BaseValue - (eax << 0x09);
+ edi = (eax << 4);
+
+ eax = pTriplet->Value2;
+ ecx = (eax >> 0x17);
+ ebx = 0x100 - ecx;
+ if(edx < ebx)
+ {
+ // HOTS: 1959D8C
+ ecx = ((eax >> 0x07) & 0xFF);
+ esi = 0x80 - ecx;
+ if(edx < esi)
+ {
+ // HOTS: 01959DA2
+ eax = eax & 0x7F;
+ ecx = 0x40 - eax;
+ if(edx >= ecx)
+ {
+ // HOTS: 01959DB7
+ edi += 2;
+ edx = edx + eax - 0x40;
+ }
+ }
+ else
+ {
+ // HOTS: 1959DC0
+ eax = (eax >> 0x0F) & 0xFF;
+ esi = 0xC0 - eax;
+ if(edx < esi)
+ {
+ // HOTS: 1959DD3
+ edi += 4;
+ edx = edx + ecx - 0x80;
+ }
+ else
+ {
+ // HOTS: 1959DD3
+ edi += 6;
+ edx = edx + eax - 0xC0;
+ }
+ }
+ }
+ else
+ {
+ // HOTS: 1959DE8
+ esi = pTriplet->Value3;
+ eax = ((esi >> 0x09) & 0x1FF);
+ ebx = 0x180 - eax;
+ if(edx < ebx)
+ {
+ // HOTS: 01959E00
+ esi = esi & 0x1FF;
+ eax = (0x140 - esi);
+ if(edx < eax)
+ {
+ // HOTS: 1959E11
+ edi = edi + 8;
+ edx = edx + ecx - 0x100;
+ }
+ else
+ {
+ // HOTS: 1959E1D
+ edi = edi + 0x0A;
+ edx = edx + esi - 0x140;
+ }
+ }
+ else
+ {
+ // HOTS: 1959E29
+ esi = (esi >> 0x12) & 0x1FF;
+ ecx = (0x1C0 - esi);
+ if(edx < ecx)
+ {
+ // HOTS: 1959E3D
+ edi = edi + 0x0C;
+ edx = edx + eax - 0x180;
+ }
+ else
+ {
+ // HOTS: 1959E49
+ edi = edi + 0x0E;
+ edx = edx + esi - 0x1C0;
+ }
+ }
+ }
+
+ // HOTS: 1959E53:
+ // Calculate the number of bits set in the value of "ecx"
+ ecx = ~Struct68_00.ItemBits.Uint32Array[edi];
+ eax = GetNumberOfSetBits(ecx);
+ esi = eax >> 0x18;
+
+ if(edx >= esi)
+ {
+ // HOTS: 1959ea4
+ ecx = ~Struct68_00.ItemBits.Uint32Array[++edi];
+ edx = edx - esi;
+ eax = GetNumberOfSetBits(ecx);
+ }
+
+ // HOTS: 1959eea
+ // ESI gets the number of set bits in the lower 16 bits of ECX
+ esi = (eax >> 0x08) & 0xFF;
+ edi = edi << 0x05;
+ if(edx < esi)
+ {
+ // HOTS: 1959EFC
+ eax = eax & 0xFF;
+ if(edx >= eax)
+ {
+ // HOTS: 1959F05
+ ecx >>= 0x08;
+ edi += 0x08;
+ edx -= eax;
+ }
+ }
+ else
+ {
+ // HOTS: 1959F0D
+ eax = (eax >> 0x10) & 0xFF;
+ if(edx < eax)
+ {
+ // HOTS: 1959F19
+ ecx >>= 0x10;
+ edi += 0x10;
+ edx -= esi;
+ }
+ else
+ {
+ // HOTS: 1959F23
+ ecx >>= 0x18;
+ edi += 0x18;
+ edx -= eax;
+ }
+ }
+
+ // HOTS: 1959f2b
+ edx = edx << 0x08;
+ ecx = ecx & 0xFF;
+
+ // BUGBUG: Possible buffer overflow here. Happens when dwItemIndex >= 0x9C.
+ // The same happens in Heroes of the Storm (build 29049), so I am not sure
+ // if this is a bug or a case that never happens
+ assert((ecx + edx) < sizeof(table_1BA1818));
+ return table_1BA1818[ecx + edx] + edi;
+}
+
+DWORD TFileNameDatabase::sub_1959F50(DWORD arg_0)
+{
+ PTRIPLET pTriplet;
+ PDWORD ItemArray;
+ DWORD eax, ebx, ecx, edx, esi, edi;
+
+ edx = arg_0;
+ eax = arg_0 >> 0x09;
+ if((arg_0 & 0x1FF) == 0)
+ return Struct68_00.ArrayDwords_50.Uint32Array[eax];
+
+ ItemArray = Struct68_00.ArrayDwords_50.Uint32Array + eax;
+ eax = (ItemArray[0] >> 0x09);
+ edi = (ItemArray[1] + 0x1FF) >> 0x09;
+
+ if((eax + 0x0A) > edi)
+ {
+ // HOTS: 01959F94
+ pTriplet = Struct68_00.BaseValues.TripletArray + eax + 1;
+ while(edx >= pTriplet->BaseValue)
+ {
+ // HOTS: 1959FA3
+ pTriplet++;
+ eax++;
+ }
+ }
+ else
+ {
+ // Binary search
+ // HOTS: 1959FAD
+ if((eax + 1) < edi)
+ {
+ // HOTS: 1959FB4
+ esi = (edi + eax) >> 1;
+ if(edx < Struct68_00.BaseValues.TripletArray[esi].BaseValue)
+ {
+ // HOTS: 1959FC4
+ edi = esi;
+ }
+ else
+ {
+ // HOTS: 1959FC8
+ eax = esi;
+ }
+ }
+ }
+
+ // HOTS: 1959FD4
+ pTriplet = Struct68_00.BaseValues.TripletArray + eax;
+ edx = edx - pTriplet->BaseValue;
+ edi = eax << 0x04;
+ eax = pTriplet->Value2;
+ ebx = (eax >> 0x17);
+ if(edx < ebx)
+ {
+ // HOTS: 1959FF1
+ esi = (eax >> 0x07) & 0xFF;
+ if(edx < esi)
+ {
+ // HOTS: 0195A000
+ eax = eax & 0x7F;
+ if(edx >= eax)
+ {
+ // HOTS: 195A007
+ edi = edi + 2;
+ edx = edx - eax;
+ }
+ }
+ else
+ {
+ // HOTS: 195A00E
+ eax = (eax >> 0x0F) & 0xFF;
+ if(edx < eax)
+ {
+ // HOTS: 195A01A
+ edi += 4;
+ edx = edx - esi;
+ }
+ else
+ {
+ // HOTS: 195A01F
+ edi += 6;
+ edx = edx - eax;
+ }
+ }
+ }
+ else
+ {
+ // HOTS: 195A026
+ esi = pTriplet->Value3;
+ eax = (pTriplet->Value3 >> 0x09) & 0x1FF;
+ if(edx < eax)
+ {
+ // HOTS: 195A037
+ esi = esi & 0x1FF;
+ if(edx < esi)
+ {
+ // HOTS: 195A041
+ edi = edi + 8;
+ edx = edx - ebx;
+ }
+ else
+ {
+ // HOTS: 195A048
+ edi = edi + 0x0A;
+ edx = edx - esi;
+ }
+ }
+ else
+ {
+ // HOTS: 195A04D
+ esi = (esi >> 0x12) & 0x1FF;
+ if(edx < esi)
+ {
+ // HOTS: 195A05A
+ edi = edi + 0x0C;
+ edx = edx - eax;
+ }
+ else
+ {
+ // HOTS: 195A061
+ edi = edi + 0x0E;
+ edx = edx - esi;
+ }
+ }
+ }
+
+ // HOTS: 195A066
+ esi = Struct68_00.ItemBits.Uint32Array[edi];
+ eax = GetNumberOfSetBits(esi);
+ ecx = eax >> 0x18;
+
+ if(edx >= ecx)
+ {
+ // HOTS: 195A0B2
+ esi = Struct68_00.ItemBits.Uint32Array[++edi];
+ edx = edx - ecx;
+ eax = GetNumberOfSetBits(esi);
+ }
+
+ // HOTS: 195A0F6
+ ecx = (eax >> 0x08) & 0xFF;
+
+ edi = (edi << 0x05);
+ if(edx < ecx)
+ {
+ // HOTS: 195A111
+ eax = eax & 0xFF;
+ if(edx >= eax)
+ {
+ // HOTS: 195A111
+ edi = edi + 0x08;
+ esi = esi >> 0x08;
+ edx = edx - eax;
+ }
+ }
+ else
+ {
+ // HOTS: 195A119
+ eax = (eax >> 0x10) & 0xFF;
+ if(edx < eax)
+ {
+ // HOTS: 195A125
+ esi = esi >> 0x10;
+ edi = edi + 0x10;
+ edx = edx - ecx;
+ }
+ else
+ {
+ // HOTS: 195A12F
+ esi = esi >> 0x18;
+ edi = edi + 0x18;
+ edx = edx - eax;
+ }
+ }
+
+ esi = esi & 0xFF;
+ edx = edx << 0x08;
+
+ // BUGBUG: Potential buffer overflow
+ // Happens in Heroes of the Storm when arg_0 == 0x5B
+ assert((esi + edx) < sizeof(table_1BA1818));
+ return table_1BA1818[esi + edx] + edi;
+}
+
+// HOTS: 1957970
+bool TFileNameDatabase::CheckNextPathFragment(TMndxFindResult * pStruct1C)
+{
+ TStruct40 * pStruct40 = pStruct1C->pStruct40;
+ LPBYTE pbPathName = (LPBYTE)pStruct1C->szSearchMask;
+ DWORD CollisionIndex;
+ DWORD NameFragIndex;
+ DWORD SaveCharIndex;
+ DWORD HiBitsIndex;
+ DWORD FragOffs;
+
+ // Calculate index of the next name fragment in the name fragment table
+ NameFragIndex = ((pStruct40->ItemIndex << 0x05) ^ pStruct40->ItemIndex ^ pbPathName[pStruct40->CharIndex]) & NameFragIndexMask;
+
+ // Does the hash value match?
+ if(NameFragTable.NameFragArray[NameFragIndex].ItemIndex == pStruct40->ItemIndex)
+ {
+ // Check if there is single character match
+ if(IS_SINGLE_CHAR_MATCH(NameFragTable, NameFragIndex))
+ {
+ pStruct40->ItemIndex = NameFragTable.NameFragArray[NameFragIndex].NextIndex;
+ pStruct40->CharIndex++;
+ return true;
+ }
+
+ // Check if there is a name fragment match
+ if(NextDB.pDB != NULL)
+ {
+ if(!NextDB.pDB->sub_1957B80(pStruct1C, NameFragTable.NameFragArray[NameFragIndex].FragOffs))
+ return false;
+ }
+ else
+ {
+ if(!IndexStruct_174.CheckNameFragment(pStruct1C, NameFragTable.NameFragArray[NameFragIndex].FragOffs))
+ return false;
+ }
+
+ pStruct40->ItemIndex = NameFragTable.NameFragArray[NameFragIndex].NextIndex;
+ return true;
+ }
+
+ //
+ // Conflict: Multiple hashes give the same table index
+ //
+
+ // HOTS: 1957A0E
+ CollisionIndex = sub_1959CB0(pStruct40->ItemIndex) + 1;
+ if(!Struct68_00.IsItemPresent(CollisionIndex))
+ return false;
+
+ pStruct40->ItemIndex = (CollisionIndex - pStruct40->ItemIndex - 1);
+ HiBitsIndex = 0xFFFFFFFF;
+
+// CascDumpSparseArray("E:\\casc-array-68.txt", &FileNameIndexes);
+// CascDumpSparseArray("E:\\casc-array-D0.txt", &Struct68_D0);
+
+ // HOTS: 1957A41:
+ do
+ {
+ // HOTS: 1957A41
+ // Check if the low 8 bits if the fragment offset contain a single character
+ // or an offset to a name fragment
+ if(Struct68_D0.IsItemPresent(pStruct40->ItemIndex))
+ {
+ if(HiBitsIndex == 0xFFFFFFFF)
+ {
+ // HOTS: 1957A6C
+ HiBitsIndex = Struct68_D0.GetItemValue(pStruct40->ItemIndex);
+ }
+ else
+ {
+ // HOTS: 1957A7F
+ HiBitsIndex++;
+ }
+
+ // HOTS: 1957A83
+ SaveCharIndex = pStruct40->CharIndex;
+
+ // Get the name fragment offset as combined value from lower 8 bits and upper bits
+ FragOffs = GetNameFragmentOffsetEx(pStruct40->ItemIndex, HiBitsIndex);
+
+ // Compare the string with the fragment name database
+ if(NextDB.pDB != NULL)
+ {
+ // HOTS: 1957AEC
+ if(NextDB.pDB->sub_1957B80(pStruct1C, FragOffs))
+ return true;
+ }
+ else
+ {
+ // HOTS: 1957AF7
+ if(IndexStruct_174.CheckNameFragment(pStruct1C, FragOffs))
+ return true;
+ }
+
+ // HOTS: 1957B0E
+ // If there was partial match with the fragment, end the search
+ if(pStruct40->CharIndex != SaveCharIndex)
+ return false;
+ }
+ else
+ {
+ // HOTS: 1957B1C
+ if(FrgmDist_LoBits.ByteArray[pStruct40->ItemIndex] == pStruct1C->szSearchMask[pStruct40->CharIndex])
+ {
+ pStruct40->CharIndex++;
+ return true;
+ }
+ }
+
+ // HOTS: 1957B32
+ pStruct40->ItemIndex++;
+ CollisionIndex++;
+ }
+ while(Struct68_00.IsItemPresent(CollisionIndex));
+ return false;
+}
+
+// HOTS: 1957B80
+bool TFileNameDatabase::sub_1957B80(TMndxFindResult * pStruct1C, DWORD arg_4)
+{
+ TStruct40 * pStruct40 = pStruct1C->pStruct40;
+ PNAME_FRAG pNameEntry;
+ DWORD FragOffs;
+ DWORD eax, edi;
+
+ edi = arg_4;
+
+ // HOTS: 1957B95
+ for(;;)
+ {
+ pNameEntry = NameFragTable.NameFragArray + (edi & NameFragIndexMask);
+ if(edi == pNameEntry->NextIndex)
+ {
+ // HOTS: 01957BB4
+ if((pNameEntry->FragOffs & 0xFFFFFF00) != 0xFFFFFF00)
+ {
+ // HOTS: 1957BC7
+ if(NextDB.pDB != NULL)
+ {
+ // HOTS: 1957BD3
+ if(!NextDB.pDB->sub_1957B80(pStruct1C, pNameEntry->FragOffs))
+ return false;
+ }
+ else
+ {
+ // HOTS: 1957BE0
+ if(!IndexStruct_174.CheckNameFragment(pStruct1C, pNameEntry->FragOffs))
+ return false;
+ }
+ }
+ else
+ {
+ // HOTS: 1957BEE
+ if(pStruct1C->szSearchMask[pStruct40->CharIndex] != (char)pNameEntry->FragOffs)
+ return false;
+ pStruct40->CharIndex++;
+ }
+
+ // HOTS: 1957C05
+ edi = pNameEntry->ItemIndex;
+ if(edi == 0)
+ return true;
+
+ if(pStruct40->CharIndex >= pStruct1C->cchSearchMask)
+ return false;
+ }
+ else
+ {
+ // HOTS: 1957C30
+ if(Struct68_D0.IsItemPresent(edi))
+ {
+ // HOTS: 1957C4C
+ if(NextDB.pDB != NULL)
+ {
+ // HOTS: 1957C58
+ FragOffs = GetNameFragmentOffset(edi);
+ if(!NextDB.pDB->sub_1957B80(pStruct1C, FragOffs))
+ return false;
+ }
+ else
+ {
+ // HOTS: 1957350
+ FragOffs = GetNameFragmentOffset(edi);
+ if(!IndexStruct_174.CheckNameFragment(pStruct1C, FragOffs))
+ return false;
+ }
+ }
+ else
+ {
+ // HOTS: 1957C8E
+ if(FrgmDist_LoBits.ByteArray[edi] != pStruct1C->szSearchMask[pStruct40->CharIndex])
+ return false;
+
+ pStruct40->CharIndex++;
+ }
+
+ // HOTS: 1957CB2
+ if(edi <= field_214)
+ return true;
+
+ if(pStruct40->CharIndex >= pStruct1C->cchSearchMask)
+ return false;
+
+ eax = sub_1959F50(edi);
+ edi = (eax - edi - 1);
+ }
+ }
+}
+
+// HOTS: 1958D70
+void TFileNameDatabase::sub_1958D70(TMndxFindResult * pStruct1C, DWORD arg_4)
+{
+ TStruct40 * pStruct40 = pStruct1C->pStruct40;
+ PNAME_FRAG pNameEntry;
+
+ // HOTS: 1958D84
+ for(;;)
+ {
+ pNameEntry = NameFragTable.NameFragArray + (arg_4 & NameFragIndexMask);
+ if(arg_4 == pNameEntry->NextIndex)
+ {
+ // HOTS: 1958DA6
+ if((pNameEntry->FragOffs & 0xFFFFFF00) != 0xFFFFFF00)
+ {
+ // HOTS: 1958DBA
+ if(NextDB.pDB != NULL)
+ {
+ NextDB.pDB->sub_1958D70(pStruct1C, pNameEntry->FragOffs);
+ }
+ else
+ {
+ IndexStruct_174.CopyNameFragment(pStruct1C, pNameEntry->FragOffs);
+ }
+ }
+ else
+ {
+ // HOTS: 1958DE7
+ // Insert the low 8 bits to the path being built
+ pStruct40->array_00.InsertOneItem_CHAR((char)(pNameEntry->FragOffs & 0xFF));
+ }
+
+ // HOTS: 1958E71
+ arg_4 = pNameEntry->ItemIndex;
+ if(arg_4 == 0)
+ return;
+ }
+ else
+ {
+ // HOTS: 1958E8E
+ if(Struct68_D0.IsItemPresent(arg_4))
+ {
+ DWORD FragOffs;
+
+ // HOTS: 1958EAF
+ FragOffs = GetNameFragmentOffset(arg_4);
+ if(NextDB.pDB != NULL)
+ {
+ NextDB.pDB->sub_1958D70(pStruct1C, FragOffs);
+ }
+ else
+ {
+ IndexStruct_174.CopyNameFragment(pStruct1C, FragOffs);
+ }
+ }
+ else
+ {
+ // HOTS: 1958F50
+ // Insert one character to the path being built
+ pStruct40->array_00.InsertOneItem_CHAR(FrgmDist_LoBits.CharArray[arg_4]);
+ }
+
+ // HOTS: 1958FDE
+ if(arg_4 <= field_214)
+ return;
+
+ arg_4 = 0xFFFFFFFF - arg_4 + sub_1959F50(arg_4);
+ }
+ }
+}
+
+// HOTS: 1959010
+bool TFileNameDatabase::sub_1959010(TMndxFindResult * pStruct1C, DWORD arg_4)
+{
+ TStruct40 * pStruct40 = pStruct1C->pStruct40;
+ PNAME_FRAG pNameEntry;
+
+ // HOTS: 1959024
+ for(;;)
+ {
+ pNameEntry = NameFragTable.NameFragArray + (arg_4 & NameFragIndexMask);
+ if(arg_4 == pNameEntry->NextIndex)
+ {
+ // HOTS: 1959047
+ if((pNameEntry->FragOffs & 0xFFFFFF00) != 0xFFFFFF00)
+ {
+ // HOTS: 195905A
+ if(NextDB.pDB != NULL)
+ {
+ if(!NextDB.pDB->sub_1959010(pStruct1C, pNameEntry->FragOffs))
+ return false;
+ }
+ else
+ {
+ if(!IndexStruct_174.CheckAndCopyNameFragment(pStruct1C, pNameEntry->FragOffs))
+ return false;
+ }
+ }
+ else
+ {
+ // HOTS: 1959092
+ if((char)(pNameEntry->FragOffs & 0xFF) != pStruct1C->szSearchMask[pStruct40->CharIndex])
+ return false;
+
+ // Insert the low 8 bits to the path being built
+ pStruct40->array_00.InsertOneItem_CHAR((char)(pNameEntry->FragOffs & 0xFF));
+ pStruct40->CharIndex++;
+ }
+
+ // HOTS: 195912E
+ arg_4 = pNameEntry->ItemIndex;
+ if(arg_4 == 0)
+ return true;
+ }
+ else
+ {
+ // HOTS: 1959147
+ if(Struct68_D0.IsItemPresent(arg_4))
+ {
+ DWORD FragOffs;
+
+ // HOTS: 195917C
+ FragOffs = GetNameFragmentOffset(arg_4);
+ if(NextDB.pDB != NULL)
+ {
+ if(!NextDB.pDB->sub_1959010(pStruct1C, FragOffs))
+ return false;
+ }
+ else
+ {
+ if(!IndexStruct_174.CheckAndCopyNameFragment(pStruct1C, FragOffs))
+ return false;
+ }
+ }
+ else
+ {
+ // HOTS: 195920E
+ if(FrgmDist_LoBits.CharArray[arg_4] != pStruct1C->szSearchMask[pStruct40->CharIndex])
+ return false;
+
+ // Insert one character to the path being built
+ pStruct40->array_00.InsertOneItem_CHAR(FrgmDist_LoBits.CharArray[arg_4]);
+ pStruct40->CharIndex++;
+ }
+
+ // HOTS: 19592B6
+ if(arg_4 <= field_214)
+ return true;
+
+ arg_4 = 0xFFFFFFFF - arg_4 + sub_1959F50(arg_4);
+ }
+
+ // HOTS: 19592D5
+ if(pStruct40->CharIndex >= pStruct1C->cchSearchMask)
+ break;
+ }
+
+ sub_1958D70(pStruct1C, arg_4);
+ return true;
+}
+
+// HOTS: 1959460
+bool TFileNameDatabase::sub_1959460(TMndxFindResult * pStruct1C)
+{
+ TStruct40 * pStruct40 = pStruct1C->pStruct40;
+ PPATH_STOP pPathStop;
+ PATH_STOP PathStop;
+ DWORD NewMaxItemCount;
+ DWORD FragOffs;
+ DWORD edi;
+
+ if(pStruct40->SearchPhase == CASC_SEARCH_FINISHED)
+ return false;
+
+ if(pStruct40->SearchPhase != CASC_SEARCH_SEARCHING)
+ {
+ // HOTS: 1959489
+ pStruct40->InitSearchBuffers();
+
+ // If the caller passed a part of the search path, we need to find that one
+ while(pStruct40->CharIndex < pStruct1C->cchSearchMask)
+ {
+ if(!sub_1958B00(pStruct1C))
+ {
+ pStruct40->SearchPhase = CASC_SEARCH_FINISHED;
+ return false;
+ }
+ }
+
+ // HOTS: 19594b0
+ PathStop.ItemIndex = pStruct40->ItemIndex;
+ PathStop.field_4 = 0;
+ PathStop.field_8 = pStruct40->array_00.ItemCount;
+ PathStop.field_C = 0xFFFFFFFF;
+ PathStop.field_10 = 0xFFFFFFFF;
+ pStruct40->PathStops.InsertOneItem_PATH_STOP(PathStop);
+ pStruct40->ItemCount = 1;
+
+ if(FileNameIndexes.IsItemPresent(pStruct40->ItemIndex))
+ {
+ pStruct1C->szFoundPath = pStruct40->array_00.FirstValid.Chars;
+ pStruct1C->cchFoundPath = pStruct40->array_00.ItemCount;
+ pStruct1C->FileNameIndex = FileNameIndexes.GetItemValue(pStruct40->ItemIndex);
+ return true;
+ }
+ }
+
+ // HOTS: 1959522
+ for(;;)
+ {
+ // HOTS: 1959530
+ if(pStruct40->ItemCount == pStruct40->PathStops.ItemCount)
+ {
+ PPATH_STOP pLastStop;
+ DWORD CollisionIndex;
+
+ pLastStop = pStruct40->PathStops.FirstValid.PathStopPtr + pStruct40->PathStops.ItemCount - 1;
+ CollisionIndex = sub_1959CB0(pLastStop->ItemIndex) + 1;
+
+ // Insert a new structure
+ PathStop.ItemIndex = CollisionIndex - pLastStop->ItemIndex - 1;;
+ PathStop.field_4 = CollisionIndex;
+ PathStop.field_8 = 0;
+ PathStop.field_C = 0xFFFFFFFF;
+ PathStop.field_10 = 0xFFFFFFFF;
+ pStruct40->PathStops.InsertOneItem_PATH_STOP(PathStop);
+ }
+
+ // HOTS: 19595BD
+ pPathStop = pStruct40->PathStops.FirstValid.PathStopPtr + pStruct40->ItemCount;
+
+ // HOTS: 19595CC
+ if(Struct68_00.IsItemPresent(pPathStop->field_4++))
+ {
+ // HOTS: 19595F2
+ pStruct40->ItemCount++;
+
+ if(Struct68_D0.IsItemPresent(pPathStop->ItemIndex))
+ {
+ // HOTS: 1959617
+ if(pPathStop->field_C == 0xFFFFFFFF)
+ pPathStop->field_C = Struct68_D0.GetItemValue(pPathStop->ItemIndex);
+ else
+ pPathStop->field_C++;
+
+ // HOTS: 1959630
+ FragOffs = GetNameFragmentOffsetEx(pPathStop->ItemIndex, pPathStop->field_C);
+ if(NextDB.pDB != NULL)
+ {
+ // HOTS: 1959649
+ NextDB.pDB->sub_1958D70(pStruct1C, FragOffs);
+ }
+ else
+ {
+ // HOTS: 1959654
+ IndexStruct_174.CopyNameFragment(pStruct1C, FragOffs);
+ }
+ }
+ else
+ {
+ // HOTS: 1959665
+ // Insert one character to the path being built
+ pStruct40->array_00.InsertOneItem_CHAR(FrgmDist_LoBits.CharArray[pPathStop->ItemIndex]);
+ }
+
+ // HOTS: 19596AE
+ pPathStop->field_8 = pStruct40->array_00.ItemCount;
+
+ // HOTS: 19596b6
+ if(FileNameIndexes.IsItemPresent(pPathStop->ItemIndex))
+ {
+ // HOTS: 19596D1
+ if(pPathStop->field_10 == 0xFFFFFFFF)
+ {
+ // HOTS: 19596D9
+ pPathStop->field_10 = FileNameIndexes.GetItemValue(pPathStop->ItemIndex);
+ }
+ else
+ {
+ pPathStop->field_10++;
+ }
+
+ // HOTS: 1959755
+ pStruct1C->szFoundPath = pStruct40->array_00.FirstValid.Chars;
+ pStruct1C->cchFoundPath = pStruct40->array_00.ItemCount;
+ pStruct1C->FileNameIndex = pPathStop->field_10;
+ return true;
+ }
+ }
+ else
+ {
+ // HOTS: 19596E9
+ if(pStruct40->ItemCount == 1)
+ {
+ pStruct40->SearchPhase = CASC_SEARCH_FINISHED;
+ return false;
+ }
+
+ // HOTS: 19596F5
+ pPathStop = pStruct40->PathStops.FirstValid.PathStopPtr + pStruct40->ItemCount - 1;
+ pPathStop->ItemIndex++;
+
+ pPathStop = pStruct40->PathStops.FirstValid.PathStopPtr + pStruct40->ItemCount - 2;
+ edi = pPathStop->field_8;
+
+ if(edi > pStruct40->array_00.MaxItemCount)
+ {
+ // HOTS: 1959717
+ NewMaxItemCount = edi;
+
+ if(pStruct40->array_00.MaxItemCount > (edi / 2))
+ {
+ if(pStruct40->array_00.MaxItemCount > 0x7FFFFFFF)
+ {
+ NewMaxItemCount = 0xFFFFFFFF;
+ }
+ else
+ {
+ NewMaxItemCount = pStruct40->array_00.MaxItemCount + pStruct40->array_00.MaxItemCount;
+ }
+ }
+
+ pStruct40->array_00.SetMaxItems_CHARS(NewMaxItemCount);
+ }
+
+ // HOTS: 1959749
+ pStruct40->array_00.ItemCount = edi;
+ pStruct40->ItemCount--;
+ }
+ }
+}
+
+// HOTS: 1958B00
+bool TFileNameDatabase::sub_1958B00(TMndxFindResult * pStruct1C)
+{
+ TStruct40 * pStruct40 = pStruct1C->pStruct40;
+ LPBYTE pbPathName = (LPBYTE)pStruct1C->szSearchMask;
+ DWORD CollisionIndex;
+ DWORD FragmentOffset;
+ DWORD SaveCharIndex;
+ DWORD ItemIndex;
+ DWORD FragOffs;
+ DWORD var_4;
+
+ ItemIndex = pbPathName[pStruct40->CharIndex] ^ (pStruct40->ItemIndex << 0x05) ^ pStruct40->ItemIndex;
+ ItemIndex = ItemIndex & NameFragIndexMask;
+ if(pStruct40->ItemIndex == NameFragTable.NameFragArray[ItemIndex].ItemIndex)
+ {
+ // HOTS: 1958B45
+ FragmentOffset = NameFragTable.NameFragArray[ItemIndex].FragOffs;
+ if((FragmentOffset & 0xFFFFFF00) == 0xFFFFFF00)
+ {
+ // HOTS: 1958B88
+ pStruct40->array_00.InsertOneItem_CHAR((char)FragmentOffset);
+ pStruct40->ItemIndex = NameFragTable.NameFragArray[ItemIndex].NextIndex;
+ pStruct40->CharIndex++;
+ return true;
+ }
+
+ // HOTS: 1958B59
+ if(NextDB.pDB != NULL)
+ {
+ if(!NextDB.pDB->sub_1959010(pStruct1C, FragmentOffset))
+ return false;
+ }
+ else
+ {
+ if(!IndexStruct_174.CheckAndCopyNameFragment(pStruct1C, FragmentOffset))
+ return false;
+ }
+
+ // HOTS: 1958BCA
+ pStruct40->ItemIndex = NameFragTable.NameFragArray[ItemIndex].NextIndex;
+ return true;
+ }
+
+ // HOTS: 1958BE5
+ CollisionIndex = sub_1959CB0(pStruct40->ItemIndex) + 1;
+ if(!Struct68_00.IsItemPresent(CollisionIndex))
+ return false;
+
+ pStruct40->ItemIndex = (CollisionIndex - pStruct40->ItemIndex - 1);
+ var_4 = 0xFFFFFFFF;
+
+ // HOTS: 1958C20
+ for(;;)
+ {
+ if(Struct68_D0.IsItemPresent(pStruct40->ItemIndex))
+ {
+ // HOTS: 1958C0E
+ if(var_4 == 0xFFFFFFFF)
+ {
+ // HOTS: 1958C4B
+ var_4 = Struct68_D0.GetItemValue(pStruct40->ItemIndex);
+ }
+ else
+ {
+ var_4++;
+ }
+
+ // HOTS: 1958C62
+ SaveCharIndex = pStruct40->CharIndex;
+
+ FragOffs = GetNameFragmentOffsetEx(pStruct40->ItemIndex, var_4);
+ if(NextDB.pDB != NULL)
+ {
+ // HOTS: 1958CCB
+ if(NextDB.pDB->sub_1959010(pStruct1C, FragOffs))
+ return true;
+ }
+ else
+ {
+ // HOTS: 1958CD6
+ if(IndexStruct_174.CheckAndCopyNameFragment(pStruct1C, FragOffs))
+ return true;
+ }
+
+ // HOTS: 1958CED
+ if(SaveCharIndex != pStruct40->CharIndex)
+ return false;
+ }
+ else
+ {
+ // HOTS: 1958CFB
+ if(FrgmDist_LoBits.ByteArray[pStruct40->ItemIndex] == pStruct1C->szSearchMask[pStruct40->CharIndex])
+ {
+ // HOTS: 1958D11
+ pStruct40->array_00.InsertOneItem_CHAR(FrgmDist_LoBits.ByteArray[pStruct40->ItemIndex]);
+ pStruct40->CharIndex++;
+ return true;
+ }
+ }
+
+ // HOTS: 1958D11
+ pStruct40->ItemIndex++;
+ CollisionIndex++;
+
+ if(!Struct68_00.IsItemPresent(CollisionIndex))
+ break;
+ }
+
+ return false;
+}
+
+// HOTS: 1957EF0
+bool TFileNameDatabase::FindFileInDatabase(TMndxFindResult * pStruct1C)
+{
+ TStruct40 * pStruct40 = pStruct1C->pStruct40;
+
+ pStruct40->ItemIndex = 0;
+ pStruct40->CharIndex = 0;
+ pStruct40->SearchPhase = CASC_SEARCH_INITIALIZING;
+
+ if(pStruct1C->cchSearchMask > 0)
+ {
+ while(pStruct40->CharIndex < pStruct1C->cchSearchMask)
+ {
+ // HOTS: 01957F12
+ if(!CheckNextPathFragment(pStruct1C))
+ return false;
+ }
+ }
+
+ // HOTS: 1957F26
+ if(!FileNameIndexes.IsItemPresent(pStruct40->ItemIndex))
+ return false;
+
+ pStruct1C->szFoundPath = pStruct1C->szSearchMask;
+ pStruct1C->cchFoundPath = pStruct1C->cchSearchMask;
+ pStruct1C->FileNameIndex = FileNameIndexes.GetItemValue(pStruct40->ItemIndex);
+ return true;
+}
+
+// HOTS: 1959790
+int TFileNameDatabase::LoadFromStream(TByteStream & InStream)
+{
+ DWORD dwBitMask;
+ int nError;
+
+ nError = Struct68_00.LoadFromStream_Exchange(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ nError = FileNameIndexes.LoadFromStream_Exchange(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ nError = Struct68_D0.LoadFromStream_Exchange(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ // HOTS: 019597CD
+ nError = FrgmDist_LoBits.LoadBytes_Copy(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ nError = FrgmDist_HiBits.LoadFromStream_Exchange(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ // HOTS: 019597F5
+ nError = IndexStruct_174.LoadFromStream_Exchange(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ // HOTS: 0195980A
+ if(Struct68_D0.ValidItemCount != 0 && IndexStruct_174.NameFragments.ItemCount == 0)
+ {
+ TFileNameDatabase * pNextDB = new TFileNameDatabase;
+
+ nError = NextDB.SetDatabase(pNextDB);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ if(NextDB.pDB == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ nError = NextDB.pDB->LoadFromStream(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+ }
+
+ // HOTS: 0195986B
+ nError = NameFragTable.LoadFragmentInfos_Copy(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ NameFragIndexMask = NameFragTable.ItemCount - 1;
+
+ nError = InStream.GetValue_DWORD(field_214);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ nError = InStream.GetValue_DWORD(dwBitMask);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ return Struct10.sub_1957800(dwBitMask);
+}
+
+// HOTS: 19598D0
+int TFileNameDatabase::LoadFromStream_Exchange(TByteStream & InStream)
+{
+ TFileNameDatabase TempDatabase;
+ ARRAY_POINTER Pointer;
+ DWORD dwSignature;
+ int nError;
+
+ // Get pointer to MAR signature
+ nError = InStream.GetBytes(sizeof(DWORD), &Pointer);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ // Verify the signature
+ dwSignature = Pointer.Uint32s[0];
+ if(dwSignature != CASC_MAR_SIGNATURE)
+ return ERROR_BAD_FORMAT;
+
+ nError = TempDatabase.LoadFromStream(InStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ MarStream.ExchangeWith(InStream);
+ ExchangeWith(TempDatabase);
+ return ERROR_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// TFileNameDatabasePtr functions
+
+// HOTS: 01956D70
+TFileNameDatabasePtr::TFileNameDatabasePtr()
+{
+ pDB = NULL;
+}
+
+TFileNameDatabasePtr::~TFileNameDatabasePtr()
+{
+ delete pDB;
+}
+
+// HOTS: 1956C60
+int TFileNameDatabasePtr::FindFileInDatabase(TMndxFindResult * pStruct1C)
+{
+ int nError = ERROR_SUCCESS;
+
+ if(pDB == NULL)
+ return ERROR_INVALID_PARAMETER;
+
+ nError = pStruct1C->CreateStruct40();
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ if(!pDB->FindFileInDatabase(pStruct1C))
+ nError = ERROR_FILE_NOT_FOUND;
+
+ pStruct1C->FreeStruct40();
+ return nError;
+}
+
+// HOTS: 1956CE0
+int TFileNameDatabasePtr::sub_1956CE0(TMndxFindResult * pStruct1C, bool * pbFindResult)
+{
+ int nError = ERROR_SUCCESS;
+
+ if(pDB == NULL)
+ return ERROR_INVALID_PARAMETER;
+
+ // Create the pStruct40, if not initialized yet
+ if(pStruct1C->pStruct40 == NULL)
+ {
+ nError = pStruct1C->CreateStruct40();
+ if(nError != ERROR_SUCCESS)
+ return nError;
+ }
+
+ *pbFindResult = pDB->sub_1959460(pStruct1C);
+ return nError;
+}
+
+// HOTS: 1956D20
+int TFileNameDatabasePtr::GetFileNameCount(PDWORD PtrFileNameCount)
+{
+ if(pDB == NULL)
+ return ERROR_INVALID_PARAMETER;
+
+ PtrFileNameCount[0] = pDB->FileNameIndexes.ValidItemCount;
+ return ERROR_SUCCESS;
+}
+
+// HOTS: 1956DA0
+int TFileNameDatabasePtr::CreateDatabase(LPBYTE pbMarData, DWORD cbMarData)
+{
+ TFileNameDatabase * pDatabase;
+ TByteStream ByteStream;
+ int nError;
+
+ if(pbMarData == NULL && cbMarData != 0)
+ return ERROR_INVALID_PARAMETER;
+
+ pDatabase = new TFileNameDatabase;
+ if(pDatabase == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ nError = ByteStream.SetByteBuffer(pbMarData, cbMarData);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ // HOTS: 1956E11
+ nError = pDatabase->LoadFromStream_Exchange(ByteStream);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ pDB = pDatabase;
+ return ERROR_SUCCESS;
+}
+
+// HOTS: 19584B0
+int TFileNameDatabasePtr::SetDatabase(TFileNameDatabase * pNewDB)
+{
+ if(pNewDB != NULL && pDB == pNewDB)
+ return ERROR_INVALID_PARAMETER;
+
+ if(pDB != NULL)
+ delete pDB;
+ pDB = pNewDB;
+ return ERROR_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Local functions - MAR file
+
+// HOTS: 00E94180
+static void MAR_FILE_CreateDatabase(PMAR_FILE pMarFile)
+{
+ pMarFile->pDatabasePtr = new TFileNameDatabasePtr;
+ if(pMarFile->pDatabasePtr != NULL)
+ pMarFile->pDatabasePtr->CreateDatabase(pMarFile->pbMarData, pMarFile->cbMarData);
+}
+
+static int MAR_FILE_SearchFile(PMAR_FILE pMarFile, TMndxFindResult * pStruct1C)
+{
+ return pMarFile->pDatabasePtr->FindFileInDatabase(pStruct1C);
+}
+
+static void MAR_FILE_Destructor(PMAR_FILE pMarFile)
+{
+ if(pMarFile != NULL)
+ {
+ if(pMarFile->pDatabasePtr != NULL)
+ delete pMarFile->pDatabasePtr;
+ if(pMarFile->pbMarData != NULL)
+ CASC_FREE(pMarFile->pbMarData);
+
+ CASC_FREE(pMarFile);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Package functions
+
+// TODO: When working, increment these values to lower number of (re)allocations
+#define CASC_PACKAGES_INIT 0x10
+#define CASC_PACKAGES_DELTA 0x10
+
+static PCASC_PACKAGES AllocatePackages(size_t nNameEntries, size_t nNameBufferMax)
+{
+ PCASC_PACKAGES pPackages;
+ size_t cbToAllocate;
+
+ // Allocate space
+ cbToAllocate = sizeof(CASC_PACKAGES) + (nNameEntries * sizeof(CASC_PACKAGE)) + nNameBufferMax;
+ pPackages = (PCASC_PACKAGES)CASC_ALLOC(BYTE, cbToAllocate);
+ if(pPackages != NULL)
+ {
+ // Fill the structure
+ memset(pPackages, 0, cbToAllocate);
+
+ // Init the list entries
+ pPackages->szNameBuffer = (char *)(&pPackages->Packages[nNameEntries]);
+ pPackages->NameEntries = nNameEntries;
+ pPackages->NameBufferUsed = 0;
+ pPackages->NameBufferMax = nNameBufferMax;
+ }
+
+ return pPackages;
+}
+
+static PCASC_PACKAGES InsertToPackageList(
+ PCASC_PACKAGES pPackages,
+ const char * szFileName,
+ size_t cchFileName,
+ size_t nPackageIndex)
+{
+ size_t nNewNameEntries = pPackages->NameEntries;
+ size_t nNewNameBufferMax = pPackages->NameBufferMax;
+ size_t cbToAllocate;
+ char * szNameBuffer;
+
+ // Need to reallocate?
+ while(nPackageIndex >= nNewNameEntries)
+ nNewNameEntries = nNewNameEntries + CASC_PACKAGES_DELTA;
+ if((pPackages->NameBufferUsed + cchFileName + 1) > nNewNameBufferMax)
+ nNewNameBufferMax = nNewNameBufferMax + 0x1000;
+
+ // If any of the two variables overflowed, we need to reallocate the name list
+ if(nNewNameEntries > pPackages->NameEntries || nNewNameBufferMax > pPackages->NameBufferMax)
+ {
+ PCASC_PACKAGES pOldPackages = pPackages;
+
+ // Allocate new name list
+ cbToAllocate = sizeof(CASC_PACKAGES) + (nNewNameEntries * sizeof(CASC_PACKAGE)) + nNewNameBufferMax;
+ pPackages = (PCASC_PACKAGES)CASC_ALLOC(BYTE, cbToAllocate);
+ if(pPackages == NULL)
+ return NULL;
+
+ // Copy the old entries
+ memset(pPackages, 0, cbToAllocate);
+ pPackages->szNameBuffer = szNameBuffer = (char *)(&pPackages->Packages[nNewNameEntries]);
+ memcpy(pPackages->szNameBuffer, pOldPackages->szNameBuffer, pOldPackages->NameBufferUsed);
+
+ // Copy the old entries
+ for(size_t i = 0; i < pOldPackages->NameEntries; i++)
+ {
+ if(pOldPackages->Packages[i].szFileName != NULL)
+ {
+ pPackages->Packages[i].szFileName = pPackages->szNameBuffer + (pOldPackages->Packages[i].szFileName - pOldPackages->szNameBuffer);
+ pPackages->Packages[i].nLength = pOldPackages->Packages[i].nLength;
+ }
+ }
+
+ // Fill the limits
+ pPackages->NameEntries = nNewNameEntries;
+ pPackages->NameBufferUsed = pOldPackages->NameBufferUsed;
+ pPackages->NameBufferMax = nNewNameBufferMax;
+
+ // Switch the name lists
+ CASC_FREE(pOldPackages);
+ }
+
+ // The slot is expected to be empty at the moment
+ assert(pPackages->Packages[nPackageIndex].szFileName == NULL);
+ assert(pPackages->Packages[nPackageIndex].nLength == 0);
+
+ // Set the file name entry
+ szNameBuffer = pPackages->szNameBuffer + pPackages->NameBufferUsed;
+ pPackages->Packages[nPackageIndex].szFileName = szNameBuffer;
+ pPackages->Packages[nPackageIndex].nLength = cchFileName;
+ memcpy(szNameBuffer, szFileName, cchFileName);
+ pPackages->NameBufferUsed += (cchFileName + 1);
+ return pPackages;
+}
+
+static int LoadPackageNames(TCascStorage * hs)
+{
+ TMndxFindResult Struct1C;
+ PCASC_PACKAGES pPackages = NULL;
+ PMAR_FILE pMarFile;
+
+ // Sanity checks
+ assert(hs->pMndxInfo != NULL);
+
+ // Prepare the file name search in the top level directory
+ pMarFile = hs->pMndxInfo->pMarFile1;
+ Struct1C.SetSearchPath("", 0);
+
+ // Allocate initial name list structure
+ pPackages = AllocatePackages(CASC_PACKAGES_INIT, 0x1000);
+ if(pPackages == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ // Keep searching as long as we find something
+ for(;;)
+ {
+ bool bFindResult = false;
+
+ // Search the next file name
+ pMarFile->pDatabasePtr->sub_1956CE0(&Struct1C, &bFindResult);
+ if(bFindResult == false)
+ break;
+
+ // Insert the found name to the top level directory list
+ pPackages = InsertToPackageList(pPackages, Struct1C.szFoundPath, Struct1C.cchFoundPath, Struct1C.FileNameIndex);
+ if(pPackages == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Set the name list to the CASC storage structure
+ hs->pPackages = pPackages;
+ return ERROR_SUCCESS;
+}
+
+PCASC_PACKAGE FindMndxPackage(TCascStorage * hs, const char * szFileName)
+{
+ PCASC_PACKAGE pMatching = NULL;
+ PCASC_PACKAGE pPackage;
+ size_t nMaxLength = 0;
+ size_t nLength = strlen(szFileName);
+
+ // Packages must be loaded
+ assert(hs->pPackages != NULL);
+ pPackage = hs->pPackages->Packages;
+
+ // Find the longest matching name
+ for(size_t i = 0; i < hs->pPackages->NameEntries; i++, pPackage++)
+ {
+ if(pPackage->szFileName != NULL && pPackage->nLength < nLength && pPackage->nLength > nMaxLength)
+ {
+ // Compare the package name
+ if(!strncmp(szFileName, pPackage->szFileName, pPackage->nLength))
+ {
+ pMatching = pPackage;
+ nMaxLength = pPackage->nLength;
+ }
+ }
+ }
+
+ // Give the package pointer or NULL if not found
+ return pMatching;
+}
+
+static bool FillFindData(TCascSearch * pSearch, PCASC_FIND_DATA pFindData, TMndxFindResult * pStruct1C)
+{
+ CASC_ROOT_KEY_INFO RootKeyInfo;
+ TCascStorage * hs = pSearch->hs;
+ PCASC_PACKAGE pPackage;
+ char * szStrippedName;
+ int nError;
+
+ // Sanity check
+ assert(pStruct1C->cchFoundPath < MAX_PATH);
+
+ // Fill the file name
+ memcpy(pFindData->szFileName, pStruct1C->szFoundPath, pStruct1C->cchFoundPath);
+ pFindData->szFileName[pStruct1C->cchFoundPath] = 0;
+ pFindData->dwFileSize = CASC_INVALID_SIZE;
+
+ // Fill the file size
+ pPackage = FindMndxPackage(hs, pFindData->szFileName);
+ if(pPackage != NULL)
+ {
+ // Cut the package name off the full path
+ szStrippedName = pFindData->szFileName + pPackage->nLength;
+ while(szStrippedName[0] == '/')
+ szStrippedName++;
+
+ nError = SearchMndxInfo(hs->pMndxInfo, szStrippedName, (DWORD)(pPackage - hs->pPackages->Packages), &RootKeyInfo);
+ if(nError == ERROR_SUCCESS)
+ {
+ pFindData->dwFileSize = (DWORD)RootKeyInfo.FileSize;
+ }
+ }
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Public functions - MNDX info
+
+int LoadMndxRootFile(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile)
+{
+ PFILE_MNDX_HEADER pMndxHeader = (PFILE_MNDX_HEADER)pbRootFile;
+ PCASC_MNDX_INFO pMndxInfo;
+ FILE_MAR_INFO MarInfo;
+ PMAR_FILE pMarFile;
+ LPBYTE pbRootFileEnd = pbRootFile + cbRootFile;
+ DWORD cbToAllocate;
+ DWORD dwFilePointer = 0;
+ DWORD i;
+ int nError = ERROR_SUCCESS;
+
+ // Check signature and the other variables
+ if(pMndxHeader->Signature != CASC_MNDX_SIGNATURE || pMndxHeader->FormatVersion > 2 || pMndxHeader->FormatVersion < 1)
+ return ERROR_BAD_FORMAT;
+
+ // Allocate space for the CASC_MNDX_INFO structure
+ pMndxInfo = CASC_ALLOC(CASC_MNDX_INFO, 1);
+ if(pMndxInfo == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ // Copy the header into the MNDX info
+ memset(pMndxInfo, 0, sizeof(CASC_MNDX_INFO));
+ pMndxInfo->HeaderVersion = pMndxHeader->HeaderVersion;
+ pMndxInfo->FormatVersion = pMndxHeader->FormatVersion;
+ dwFilePointer += sizeof(FILE_MNDX_HEADER);
+
+ // Header version 2 has 2 extra fields that we need to load
+ if(pMndxInfo->HeaderVersion == 2)
+ {
+ if(!RootFileRead(pbRootFile + dwFilePointer, pbRootFileEnd, &pMndxInfo->field_1C, sizeof(DWORD) + sizeof(DWORD)))
+ return ERROR_FILE_CORRUPT;
+ dwFilePointer += sizeof(DWORD) + sizeof(DWORD);
+ }
+
+ // Load the rest of the file header
+ if(!RootFileRead(pbRootFile + dwFilePointer, pbRootFileEnd, &pMndxInfo->MarInfoOffset, 0x1C))
+ return ERROR_FILE_CORRUPT;
+
+ // Verify the structure
+ if(pMndxInfo->MarInfoCount > CASC_MAX_MAR_FILES || pMndxInfo->MarInfoSize != sizeof(FILE_MAR_INFO))
+ return ERROR_FILE_CORRUPT;
+
+ // Load all MAR infos
+ for(i = 0; i < pMndxInfo->MarInfoCount; i++)
+ {
+ // Load the n-th MAR info
+ dwFilePointer = pMndxInfo->MarInfoOffset + (pMndxInfo->MarInfoSize * i);
+ if(!RootFileRead(pbRootFile + dwFilePointer, pbRootFileEnd, &MarInfo, sizeof(FILE_MAR_INFO)))
+ return ERROR_FILE_CORRUPT;
+
+ // Allocate MAR_FILE structure
+ pMarFile = CASC_ALLOC(MAR_FILE, 1);
+ if(pMarFile == NULL)
+ {
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ break;
+ }
+
+ // Allocate space for the MAR data
+ pMarFile->pDatabasePtr = NULL;
+ pMarFile->pbMarData = CASC_ALLOC(BYTE, MarInfo.MarDataSize);
+ pMarFile->cbMarData = MarInfo.MarDataSize;
+ if(pMarFile->pbMarData == NULL)
+ {
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ break;
+ }
+
+ // Read the MAR data
+ if(!RootFileRead(pbRootFile + MarInfo.MarDataOffset, pbRootFileEnd, pMarFile->pbMarData, pMarFile->cbMarData))
+ {
+ nError = ERROR_FILE_CORRUPT;
+ break;
+ }
+
+ // HOTS: 00E94FF1
+ MAR_FILE_CreateDatabase(pMarFile);
+ if(i == 0)
+ pMndxInfo->pMarFile1 = pMarFile;
+ if(i == 1)
+ pMndxInfo->pMarFile2 = pMarFile;
+ if(i == 2)
+ pMndxInfo->pMarFile3 = pMarFile;
+ }
+
+ // All three MAR files must be loaded
+ // HOTS: 00E9503B
+ if(nError == ERROR_SUCCESS)
+ {
+ if(pMndxInfo->pMarFile1 == NULL || pMndxInfo->pMarFile2 == NULL || pMndxInfo->pMarFile3 == NULL)
+ nError = ERROR_BAD_FORMAT;
+ if(pMndxInfo->MndxEntrySize != sizeof(CASC_MNDX_ENTRY))
+ nError = ERROR_BAD_FORMAT;
+ }
+
+ // Load the complete array of MNDX entries
+ if(nError == ERROR_SUCCESS)
+ {
+ TFileNameDatabasePtr * pDbPtr = pMndxInfo->pMarFile2->pDatabasePtr;
+ DWORD FileNameCount;
+
+ nError = pDbPtr->GetFileNameCount(&FileNameCount);
+ if(nError == ERROR_SUCCESS && FileNameCount == pMndxInfo->MndxEntriesValid)
+ {
+ cbToAllocate = pMndxInfo->MndxEntriesTotal * pMndxInfo->MndxEntrySize;
+ pMndxInfo->pMndxEntries = (PCASC_MNDX_ENTRY)CASC_ALLOC(BYTE, cbToAllocate);
+ if(pMndxInfo->pMndxEntries != NULL)
+ {
+ if(!RootFileRead(pbRootFile + pMndxInfo->MndxEntriesOffset, pbRootFileEnd, pMndxInfo->pMndxEntries, cbToAllocate))
+ nError = ERROR_FILE_CORRUPT;
+ }
+ else
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+ else
+ nError = ERROR_FILE_CORRUPT;
+ }
+
+ // Pick the valid MNDX entries and put them to a separate array
+ if(nError == ERROR_SUCCESS)
+ {
+ assert(pMndxInfo->MndxEntriesValid <= pMndxInfo->MndxEntriesTotal);
+ pMndxInfo->ppValidEntries = CASC_ALLOC(PCASC_MNDX_ENTRY, pMndxInfo->MndxEntriesValid + 1);
+ if(pMndxInfo->ppValidEntries != NULL)
+ {
+ PCASC_MNDX_ENTRY pMndxEntry = pMndxInfo->pMndxEntries;
+ DWORD ValidEntryCount = 1; // edx
+ DWORD nIndex1 = 0;
+
+ // The first entry is always valid
+ pMndxInfo->ppValidEntries[nIndex1++] = pMndxInfo->pMndxEntries;
+
+ // Put the remaining entries
+ for(i = 0; i < pMndxInfo->MndxEntriesTotal; i++, pMndxEntry++)
+ {
+ if(ValidEntryCount > pMndxInfo->MndxEntriesValid)
+ break;
+
+ if(pMndxEntry->Flags & 0x80000000)
+ {
+ pMndxInfo->ppValidEntries[nIndex1++] = pMndxEntry + 1;
+ ValidEntryCount++;
+ }
+ }
+
+ // Verify the final number of valid entries
+ if((ValidEntryCount - 1) != pMndxInfo->MndxEntriesValid)
+ nError = ERROR_BAD_FORMAT;
+
+ // Mark the MNDX info as fully loaded
+ pMndxInfo->bRootFileLoaded = true;
+ }
+ else
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Save the MNDX info to the archive storage
+ if(nError == ERROR_SUCCESS)
+ {
+ // Store the MNDX database into the archive
+ hs->pMndxInfo = pMndxInfo;
+ pMndxInfo = NULL;
+
+#if defined(_DEBUG) && defined(_X86_) && defined(CASCLIB_TEST)
+// CascDumpNameFragTable("E:\\casc-name-fragment-table.txt", hs->pMndxInfo->pMarFile1);
+// CascDumpFileNames("E:\\casc-listfile.txt", hs->pMndxInfo->pMarFile1);
+ TestMndxRootFile(hs->pMndxInfo);
+#endif
+ // Load the top level entries
+ nError = LoadPackageNames(hs);
+ }
+
+ // If anything failed, free the memory remaining allocated
+ if(nError != ERROR_SUCCESS)
+ {
+ if(pMndxInfo != NULL)
+ FreeMndxInfo(pMndxInfo);
+ pMndxInfo = NULL;
+ }
+
+ return nError;
+}
+
+int SearchMndxInfo(PCASC_MNDX_INFO pMndxInfo, const char * szFileName, DWORD dwPackage, PCASC_ROOT_KEY_INFO pFoundInfo)
+{
+ PCASC_MNDX_ENTRY pMndxEntry;
+ TMndxFindResult Struct1C;
+
+ // Search the database for the file name
+ if(pMndxInfo->bRootFileLoaded)
+ {
+ Struct1C.SetSearchPath(szFileName, strlen(szFileName));
+
+ // Search the file name in the second MAR info (the one with stripped package names)
+ if(MAR_FILE_SearchFile(pMndxInfo->pMarFile2, &Struct1C) != ERROR_SUCCESS)
+ return ERROR_FILE_NOT_FOUND;
+
+ // The found MNDX index must fall into range of valid MNDX entries
+ if(Struct1C.FileNameIndex < pMndxInfo->MndxEntriesValid)
+ {
+ // HOTS: E945F4
+ pMndxEntry = pMndxInfo->ppValidEntries[Struct1C.FileNameIndex];
+ while((pMndxEntry->Flags & 0x00FFFFFF) != dwPackage)
+ {
+ // The highest bit serves as a terminator if set
+ if(pMndxEntry->Flags & 0x80000000)
+ return ERROR_FILE_NOT_FOUND;
+
+ pMndxEntry++;
+ }
+
+ // Fill the root info
+ memcpy(pFoundInfo->EncodingKey, pMndxEntry->EncodingKey, MD5_HASH_SIZE);
+ pFoundInfo->FileSize = pMndxEntry->FileSize;
+ pFoundInfo->Flags = (BYTE)((pMndxEntry->Flags >> 0x18) & 0x3F);
+ return ERROR_SUCCESS;
+ }
+ }
+
+ return ERROR_FILE_NOT_FOUND;
+}
+
+bool DoStorageSearch_MNDX(TCascSearch * pSearch, PCASC_FIND_DATA pFindData)
+{
+ TMndxFindResult * pStruct1C = NULL;
+ PCASC_MNDX_INFO pMndxInfo = pSearch->hs->pMndxInfo;
+ PMAR_FILE pMarFile = pMndxInfo->pMarFile3;
+ bool bFindResult = false;
+
+ // Sanity checks
+ assert(pMndxInfo != NULL);
+
+ // If the first time, allocate the structure for the search result
+ if(pSearch->pStruct1C == NULL)
+ {
+ // Create the new search structure
+ pSearch->pStruct1C = pStruct1C = new TMndxFindResult;
+ if(pSearch->pStruct1C == NULL)
+ return false;
+
+ // Setup the search mask
+ pStruct1C->SetSearchPath("", 0);
+ }
+
+ // Make shortcut for the search structure
+ assert(pSearch->pStruct1C != NULL);
+ pStruct1C = (TMndxFindResult *)pSearch->pStruct1C;
+
+ // Search the next file name (our code)
+ pMarFile->pDatabasePtr->sub_1956CE0(pStruct1C, &bFindResult);
+ if(bFindResult)
+ return FillFindData(pSearch, pFindData, pStruct1C);
+
+ return false;
+}
+
+void FreeMndxInfo(PCASC_MNDX_INFO pMndxInfo)
+{
+ if(pMndxInfo != NULL)
+ {
+ if(pMndxInfo->pMarFile1 != NULL)
+ MAR_FILE_Destructor(pMndxInfo->pMarFile1);
+ if(pMndxInfo->pMarFile2 != NULL)
+ MAR_FILE_Destructor(pMndxInfo->pMarFile2);
+ if(pMndxInfo->pMarFile3 != NULL)
+ MAR_FILE_Destructor(pMndxInfo->pMarFile3);
+ if(pMndxInfo->ppValidEntries != NULL)
+ CASC_FREE(pMndxInfo->ppValidEntries);
+ if(pMndxInfo->pMndxEntries != NULL)
+ CASC_FREE(pMndxInfo->pMndxEntries);
+ CASC_FREE(pMndxInfo);
+ }
+}
+
+//----------------------------------------------------------------------------
+// Unit tests
+
+#if defined(_DEBUG) && defined(_X86_) && defined(CASCLIB_TEST)
+
+extern "C" {
+ DWORD _cdecl sub_19573D0_x86(TFileNameDatabase * pDB, DWORD arg_0, DWORD arg_4);
+ DWORD _cdecl sub_1957EF0_x86(TFileNameDatabase * pDB, TMndxFindResult * pStruct1C);
+ bool _cdecl sub_1959460_x86(TFileNameDatabase * pDB, TMndxFindResult * pStruct1C);
+ DWORD _cdecl GetItemValue_x86(TSparseArray * pStruct, DWORD dwKey);
+ DWORD _cdecl sub_1959CB0_x86(TFileNameDatabase * pDB, DWORD dwKey);
+ DWORD _cdecl sub_1959F50_x86(TFileNameDatabase * pDB, DWORD arg_0);
+}
+
+extern "C" void * allocate_zeroed_memory_x86(size_t bytes)
+{
+ return calloc(bytes, 1);
+}
+
+extern "C" void free_memory_x86(void * ptr)
+{
+ if(ptr != NULL)
+ {
+ free(ptr);
+ }
+}
+
+static int sub_1956CE0_x86(TFileNameDatabasePtr * pDatabasePtr, TMndxFindResult * pStruct1C, bool * pbFindResult)
+{
+ int nError = ERROR_SUCCESS;
+
+ if(pDatabasePtr->pDB == NULL)
+ return ERROR_INVALID_PARAMETER;
+
+ // Create the pStruct40, if not initialized yet
+ if(pStruct1C->pStruct40 == NULL)
+ {
+ nError = pStruct1C->CreateStruct40();
+ if(nError != ERROR_SUCCESS)
+ return nError;
+ }
+
+ *pbFindResult = sub_1959460_x86(pDatabasePtr->pDB, pStruct1C);
+ return nError;
+}
+/*
+static void TestFileSearch_SubStrings(PMAR_FILE pMarFile, char * szFileName, size_t nLength)
+{
+ TMndxFindResult Struct1C_1;
+ TMndxFindResult Struct1C_2;
+
+// if(strcmp(szFileName, "mods/heroes.stormmod/base.stormassets/assets/textures/storm_temp_war3_btnstatup.dds"))
+// return;
+
+ // Perform search on anything, that is longer than 4 chars
+ while(nLength >= 4)
+ {
+ // Set a substring as search name
+ Struct1C_1.SetSearchPath(szFileName, nLength);
+ Struct1C_2.SetSearchPath(szFileName, nLength);
+ szFileName[nLength] = 0;
+
+ // Keep searching
+ for(;;)
+ {
+ bool bFindResult1 = false;
+ bool bFindResult2 = false;
+
+ // Search the next file name (orig HOTS code)
+ sub_1956CE0_x86(pMarFile->pDatabasePtr, &Struct1C_1, &bFindResult1);
+
+ // Search the next file name (our code)
+ pMarFile->pDatabasePtr->sub_1956CE0(&Struct1C_2, &bFindResult2);
+
+ // Check the result
+ assert(bFindResult1 == bFindResult2);
+ assert(Struct1C_1.cchFoundPath == Struct1C_1.cchFoundPath);
+ assert(Struct1C_1.FileNameIndex == Struct1C_2.FileNameIndex);
+ assert(strncmp(Struct1C_1.szFoundPath, Struct1C_2.szFoundPath, Struct1C_1.cchFoundPath) == 0);
+ assert(Struct1C_1.cchFoundPath < MAX_PATH);
+
+ // Stop the search in case of failure
+ if(bFindResult1 == false || bFindResult2 == false)
+ break;
+ }
+
+ // Free the search structures
+ Struct1C_1.FreeStruct40();
+ Struct1C_2.FreeStruct40();
+ nLength--;
+ }
+}
+*/
+
+static void TestFindPackage(PMAR_FILE pMarFile, const char * szPackageName)
+{
+ TMndxFindResult Struct1C;
+
+ // Search the database for the file name
+ Struct1C.SetSearchPath(szPackageName, strlen(szPackageName));
+
+ // Search the file name in the second MAR info (the one with stripped package names)
+ MAR_FILE_SearchFile(pMarFile, &Struct1C);
+}
+
+static void TestFileSearch(PMAR_FILE pMarFile, const char * szFileName)
+{
+ TMndxFindResult Struct1C_1;
+ TMndxFindResult Struct1C_2;
+ size_t nLength = strlen(szFileName);
+ char szNameBuff[MAX_PATH + 1];
+
+ // Set an empty path as search mask (?)
+ Struct1C_1.SetSearchPath(szFileName, nLength);
+ Struct1C_2.SetSearchPath(szFileName, nLength);
+
+ // Keep searching
+ for(;;)
+ {
+ bool bFindResult1 = false;
+ bool bFindResult2 = false;
+
+ // Search the next file name (orig HOTS code)
+ sub_1956CE0_x86(pMarFile->pDatabasePtr, &Struct1C_1, &bFindResult1);
+
+ // Search the next file name (our code)
+ pMarFile->pDatabasePtr->sub_1956CE0(&Struct1C_2, &bFindResult2);
+
+ assert(bFindResult1 == bFindResult2);
+ assert(Struct1C_1.cchFoundPath == Struct1C_1.cchFoundPath);
+ assert(Struct1C_1.FileNameIndex == Struct1C_2.FileNameIndex);
+ assert(strncmp(Struct1C_1.szFoundPath, Struct1C_2.szFoundPath, Struct1C_1.cchFoundPath) == 0);
+ assert(Struct1C_1.cchFoundPath < MAX_PATH);
+
+ // Stop the search in case of failure
+ if(bFindResult1 == false || bFindResult2 == false)
+ break;
+
+ // Printf the found file name
+ memcpy(szNameBuff, Struct1C_2.szFoundPath, Struct1C_2.cchFoundPath);
+ szNameBuff[Struct1C_2.cchFoundPath] = 0;
+// printf("%s \r", szNameBuff);
+
+ // Perform sub-searches on this string and its substrings that are longer than 4 chars
+// TestFileSearch_SubStrings(pMarFile, szNameBuff, Struct1C_2.cchFoundPath);
+ }
+
+ // Free the search structures
+ Struct1C_1.FreeStruct40();
+ Struct1C_2.FreeStruct40();
+}
+
+static void TestMarFile(PMAR_FILE pMarFile, const char * szFileName, size_t nLength)
+{
+ TFileNameDatabase * pDB = pMarFile->pDatabasePtr->pDB;
+ DWORD dwFileNameIndex1 = 0xFFFFFFFF;
+ DWORD dwFileNameIndex2 = 0xFFFFFFFF;
+
+ // Perform the search using original HOTS code
+ {
+ TMndxFindResult Struct1C;
+
+ Struct1C.CreateStruct40();
+ Struct1C.SetSearchPath(szFileName, nLength);
+
+ // Call the original HOTS function
+ sub_1957EF0_x86(pDB, &Struct1C);
+ dwFileNameIndex1 = Struct1C.FileNameIndex;
+ }
+
+ // Perform the search using our code
+ {
+ TMndxFindResult Struct1C;
+
+ Struct1C.CreateStruct40();
+ Struct1C.SetSearchPath(szFileName, nLength);
+
+ // Call our function
+ pDB->FindFileInDatabase(&Struct1C);
+ dwFileNameIndex2 = Struct1C.FileNameIndex;
+ }
+
+ // Compare both
+ assert(dwFileNameIndex1 == dwFileNameIndex2);
+}
+
+static void TestMndxFunctions(PMAR_FILE pMarFile)
+{
+ TFileNameDatabase * pDB = pMarFile->pDatabasePtr->pDB;
+
+ // Exercise function sub_19573D0
+ for(DWORD arg_0 = 0; arg_0 < 0x100; arg_0++)
+ {
+ for(DWORD arg_4 = 0; arg_4 < 0x100; arg_4++)
+ {
+ DWORD dwResult1 = sub_19573D0_x86(pDB, arg_0, arg_4);
+ DWORD dwResult2 = pDB->GetNameFragmentOffsetEx(arg_0, arg_4);
+
+ assert(dwResult1 == dwResult2);
+ }
+ }
+
+ // Exercise function GetItemValue
+ for(DWORD i = 0; i < 0x10000; i++)
+ {
+ DWORD dwResult1 = GetItemValue_x86(&pDB->Struct68_D0, i);
+ DWORD dwResult2 = pDB->Struct68_D0.GetItemValue(i);
+
+ assert(dwResult1 == dwResult2);
+ }
+
+ // Exercise function sub_1959CB0
+ for(DWORD i = 0; i < 0x9C; i++)
+ {
+ DWORD dwResult1 = sub_1959CB0_x86(pDB, i);
+ DWORD dwResult2 = pDB->sub_1959CB0(i);
+
+ assert(dwResult1 == dwResult2);
+ }
+
+ // Exercise function sub_1959F50
+ for(DWORD i = 0; i < 0x40; i++)
+ {
+ DWORD dwResult1 = sub_1959F50_x86(pDB, i);
+ DWORD dwResult2 = pDB->sub_1959F50(i);
+
+ assert(dwResult1 == dwResult2);
+ }
+}
+
+void TestMndxRootFile(PCASC_MNDX_INFO pMndxInfo)
+{
+ size_t nLength;
+ char szFileName[MAX_PATH+1];
+ void * pvListFile;
+
+ // Exercise low level functions and compare their results
+ // with original code from Heroes of the Storm
+ TestMndxFunctions(pMndxInfo->pMarFile1);
+ TestMndxFunctions(pMndxInfo->pMarFile2);
+ TestMndxFunctions(pMndxInfo->pMarFile3);
+
+ // Find a "mods" in the package array
+ TestFindPackage(pMndxInfo->pMarFile3, "mods/heroes.stormmod/base.stormassets/assets/textures/glow_green2.dds");
+ TestMarFile(pMndxInfo->pMarFile3, "mods/heroes.stormmod/base.stormassets/assets/textures/glow_green2.dds", 69);
+
+ // Search the package MAR file aith a path shorter than a fragment
+ TestFileSearch(pMndxInfo->pMarFile1, "mods/heroes.s");
+
+ // Test the file search
+ TestFileSearch(pMndxInfo->pMarFile1, "");
+ TestFileSearch(pMndxInfo->pMarFile2, "");
+ TestFileSearch(pMndxInfo->pMarFile3, "");
+
+ // False file search
+ TestFileSearch(pMndxInfo->pMarFile2, "assets/textures/storm_temp_hrhu");
+
+ // Open the listfile stream and initialize the listfile cache
+ pvListFile = ListFile_OpenExternal(_T("e:\\Ladik\\Appdir\\CascLib\\listfile\\listfile-hots-29049.txt"));
+ if(pvListFile != NULL)
+ {
+ // Check every file in the database
+ while((nLength = ListFile_GetNext(pvListFile, "*", szFileName, MAX_PATH)) != 0)
+ {
+ // Normalize the file name: ToLower + BackSlashToSlash
+ NormalizeFileName_LowerSlash(szFileName);
+
+ // Check the file with all three MAR files
+ TestMarFile(pMndxInfo->pMarFile1, szFileName, nLength);
+ TestMarFile(pMndxInfo->pMarFile2, szFileName, nLength);
+ TestMarFile(pMndxInfo->pMarFile3, szFileName, nLength);
+ }
+
+ ListFile_Free(pvListFile);
+ }
+}
+#endif // defined(_DEBUG) && defined(_X86_) && defined(CASCLIB_TEST)
diff --git a/dep/CascLib/src/CascMndxRoot.h b/dep/CascLib/src/CascMndxRoot.h
new file mode 100644
index 00000000000..23017642ff9
--- /dev/null
+++ b/dep/CascLib/src/CascMndxRoot.h
@@ -0,0 +1,365 @@
+/*****************************************************************************/
+/* CascMndxRoot.h Copyright (c) Ladislav Zezula 2014 */
+/*---------------------------------------------------------------------------*/
+/* Interface file for MNDX structures */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 15.05.14 1.00 Lad Created */
+/*****************************************************************************/
+
+#ifndef __CASC_MNDX_ROOT__
+#define __CASC_MNDX_ROOT__
+
+class TFileNameDatabase;
+
+#define CASC_MAX_ENTRIES(type) (0xFFFFFFFF / sizeof(type))
+
+#define CASC_SEARCH_INITIALIZING 0
+#define CASC_SEARCH_SEARCHING 2
+#define CASC_SEARCH_FINISHED 4
+
+typedef struct _TRIPLET
+{
+ DWORD BaseValue;
+ DWORD Value2;
+ DWORD Value3;
+} TRIPLET, *PTRIPLET;
+
+typedef struct _NAME_FRAG
+{
+ DWORD ItemIndex; // Back index to various tables
+ DWORD NextIndex; // The following item index
+ DWORD FragOffs; // Higher 24 bits are 0xFFFFFF00 --> A single matching character
+ // Otherwise --> Offset to the name fragment table
+} NAME_FRAG, *PNAME_FRAG;
+
+typedef struct _PATH_STOP
+{
+ DWORD ItemIndex;
+ DWORD field_4;
+ DWORD field_8;
+ DWORD field_C;
+ DWORD field_10;
+} PATH_STOP, *PPATH_STOP;
+
+typedef union _ARRAY_POINTER
+{
+ LPBYTE Bytes; // Pointer to an octet
+ char * Chars; // Pointer to a character
+ PDWORD Uint32s; // Pointer to a DWORD
+ PTRIPLET Triplets; // Pointer to TRIPLET
+ PNAME_FRAG NameFrags; // Pointer to name fragment entry
+ PPATH_STOP PathStopPtr; // Pointer to path checkpoint
+ PULONGLONG Int64Ptr; // Pointer to 64-bit integer
+
+} ARRAY_POINTER, *PARRAY_POINTER;
+
+// Simple access to various tables within TGenericArray
+#define ByteArray ArrayPointer.Bytes
+#define CharArray ArrayPointer.Chars
+#define Uint32Array ArrayPointer.Uint32s
+#define TripletArray ArrayPointer.Triplets
+#define NameFragArray ArrayPointer.NameFrags
+
+class TByteStream
+{
+ public:
+
+ TByteStream();
+
+ void ExchangeWith(TByteStream & Target);
+ int GetBytes(DWORD cbByteCount, PARRAY_POINTER PtrArray);
+ int SkipBytes(DWORD cbByteCount);
+ int SetByteBuffer(LPBYTE pbNewMarData, DWORD cbNewMarData);
+ int GetValue_DWORD(DWORD & Value);
+ int GetValue_ItemCount(DWORD & NumberOfBytes, DWORD & ItemCount, DWORD ItemSize);
+ int GetArray_DWORDs(PARRAY_POINTER PtrArray, DWORD ItemCount);
+ int GetArray_Triplets(PARRAY_POINTER PtrArray, DWORD ItemCount);
+ int GetArray_NameTable(PARRAY_POINTER PtrArray, DWORD ItemCount);
+ int GetArray_BYTES(PARRAY_POINTER PtrArray, DWORD ItemCount);
+
+ LPBYTE pbByteData;
+ void * pvMappedFile;
+ DWORD cbByteData;
+ DWORD field_C;
+ HANDLE hFile;
+ HANDLE hMap;
+};
+
+class TGenericArray
+{
+ public:
+
+ TGenericArray();
+ ~TGenericArray();
+
+ int SetArrayValid();
+
+ void ExchangeWith(TGenericArray & Target);
+ void CopyFrom(TGenericArray & Source);
+
+ void SetMaxItems_CHARS(DWORD NewMaxItemCount);
+ void SetMaxItems_PATH_STOP(DWORD NewMaxItemCount);
+
+ void InsertOneItem_CHAR(char OneChar);
+ void InsertOneItem_PATH_STOP(PATH_STOP & NewItem);
+
+ void sub_19583A0(DWORD NewItemCount);
+
+ int LoadDwordsArray(TByteStream & InStream);
+ int LoadTripletsArray(TByteStream & InStream);
+ int LoadByteArray(TByteStream & InStream);
+ int LoadFragmentInfos(TByteStream & InStream);
+ int LoadStrings(TByteStream & InStream);
+
+ int LoadDwordsArray_Copy(TByteStream & InStream);
+ int LoadTripletsArray_Copy(TByteStream & InStream);
+ int LoadBytes_Copy(TByteStream & InStream);
+ int LoadFragmentInfos_Copy(TByteStream & InStream);
+ int LoadStringsWithCopy(TByteStream & InStream);
+
+ ARRAY_POINTER DataBuffer;
+ ARRAY_POINTER FirstValid;
+
+ ARRAY_POINTER ArrayPointer;
+ DWORD ItemCount; // Number of items in the array
+ DWORD MaxItemCount; // Capacity of the array
+ bool bIsValidArray;
+};
+
+class TBitEntryArray : public TGenericArray
+{
+ public:
+
+ TBitEntryArray();
+ ~TBitEntryArray();
+
+ DWORD GetBitEntry(DWORD EntryIndex)
+ {
+ DWORD dwItemIndex = (EntryIndex * BitsPerEntry) >> 0x05;
+ DWORD dwStartBit = (EntryIndex * BitsPerEntry) & 0x1F;
+ DWORD dwEndBit = dwStartBit + BitsPerEntry;
+ DWORD dwResult;
+
+ // If the end bit index is greater than 32,
+ // we also need to load from the next 32-bit item
+ if(dwEndBit > 0x20)
+ {
+ dwResult = (Uint32Array[dwItemIndex + 1] << (0x20 - dwStartBit)) | (Uint32Array[dwItemIndex] >> dwStartBit);
+ }
+ else
+ {
+ dwResult = Uint32Array[dwItemIndex] >> dwStartBit;
+ }
+
+ // Now we also need to mask the result by the bit mask
+ return dwResult & EntryBitMask;
+ }
+
+ void ExchangeWith(TBitEntryArray & Target);
+ int LoadFromStream(TByteStream & InStream);
+ int LoadFromStream_Exchange(TByteStream & InStream);
+
+ DWORD BitsPerEntry;
+ DWORD EntryBitMask;
+ DWORD TotalEntries;
+};
+
+class TStruct40
+{
+ public:
+
+ TStruct40();
+
+ void InitSearchBuffers();
+
+ TGenericArray array_00;
+ TGenericArray PathStops; // Array of path checkpoints
+ DWORD ItemIndex; // Current name fragment: Index to various tables
+ DWORD CharIndex;
+ DWORD ItemCount;
+ DWORD SearchPhase; // 0 = initializing, 2 = searching, 4 = finished
+};
+
+class TMndxFindResult
+{
+ public:
+
+ TMndxFindResult();
+ ~TMndxFindResult();
+
+ int CreateStruct40();
+ void FreeStruct40();
+
+ int SetSearchPath(const char * szNewSearchPath, size_t cchNewSearchPath);
+
+ const char * szSearchMask; // Search mask without wioldcards
+ size_t cchSearchMask; // Length of the search mask
+ DWORD field_8;
+ const char * szFoundPath; // Found path name
+ size_t cchFoundPath; // Length of the found path name
+ DWORD FileNameIndex; // Index of the file name
+ TStruct40 * pStruct40;
+};
+
+class TSparseArray
+{
+ public:
+
+ TSparseArray();
+
+ void ExchangeWith(TSparseArray & TargetObject);
+ int LoadFromStream(TByteStream & InStream);
+ int LoadFromStream_Exchange(TByteStream & InStream);
+
+ // Returns true if the item at n-th position is present
+ DWORD IsItemPresent(DWORD ItemIndex)
+ {
+ return (ItemBits.Uint32Array[ItemIndex >> 0x05] & (1 << (ItemIndex & 0x1F)));
+ }
+
+ DWORD GetItemValue(DWORD ItemIndex);
+
+ TGenericArray ItemBits; // Bit array for each item (1 = item is present)
+ DWORD TotalItemCount; // Total number of items in the array
+ DWORD ValidItemCount; // Number of present items in the array
+ TGenericArray BaseValues; // Array of base values for item indexes >= 0x200
+ TGenericArray ArrayDwords_38;
+ TGenericArray ArrayDwords_50;
+};
+
+class TNameIndexStruct
+{
+ public:
+
+ TNameIndexStruct();
+ ~TNameIndexStruct();
+
+ bool CheckNameFragment(TMndxFindResult * pStruct1C, DWORD dwFragOffs);
+ bool CheckAndCopyNameFragment(TMndxFindResult * pStruct1C, DWORD dwFragOffs);
+ void CopyNameFragment(TMndxFindResult * pStruct1C, DWORD dwFragOffs);
+
+ void ExchangeWith(TNameIndexStruct & Target);
+ int LoadFromStream(TByteStream & InStream);
+ int LoadFromStream_Exchange(TByteStream & InStream);
+
+ TGenericArray NameFragments;
+ TSparseArray Struct68;
+};
+
+class TStruct10
+{
+ public:
+
+ TStruct10();
+
+ void CopyFrom(TStruct10 & Target);
+ int sub_1956FD0(DWORD dwBitMask);
+ int sub_1957050(DWORD dwBitMask);
+ int sub_19572E0(DWORD dwBitMask);
+ int sub_1957800(DWORD dwBitMask);
+
+ DWORD field_0;
+ DWORD field_4;
+ DWORD field_8;
+ DWORD field_C;
+};
+
+class TFileNameDatabasePtr
+{
+ public:
+
+ TFileNameDatabasePtr();
+ ~TFileNameDatabasePtr();
+
+ int FindFileInDatabase(TMndxFindResult * pStruct1C);
+ int sub_1956CE0(TMndxFindResult * pStruct1C, bool * pbFindResult);
+
+ int GetFileNameCount(PDWORD PtrFileNameCount);
+ int CreateDatabase(LPBYTE pbMarData, DWORD cbMarData);
+ int SetDatabase(TFileNameDatabase * pNewDB);
+
+ TFileNameDatabase * pDB;
+};
+
+class TFileNameDatabase
+{
+ public:
+
+ TFileNameDatabase();
+
+ void ExchangeWith(TFileNameDatabase & Target);
+ int LoadFromStream(TByteStream & InStream);
+ int LoadFromStream_Exchange(TByteStream & InStream);
+
+ DWORD sub_1959CB0(DWORD dwHashValue);
+ DWORD sub_1959F50(DWORD arg_0);
+
+ // Retrieves the name fragment distance
+ // HOTS: 19573D0/inlined
+ DWORD GetNameFragmentOffsetEx(DWORD LoBitsIndex, DWORD HiBitsIndex)
+ {
+ return (FrgmDist_HiBits.GetBitEntry(HiBitsIndex) << 0x08) | FrgmDist_LoBits.ByteArray[LoBitsIndex];
+ }
+
+ // HOTS: 1957350, inlined
+ DWORD GetNameFragmentOffset(DWORD LoBitsIndex)
+ {
+ return GetNameFragmentOffsetEx(LoBitsIndex, Struct68_D0.GetItemValue(LoBitsIndex));
+ }
+
+ bool sub_1957B80(TMndxFindResult * pStruct1C, DWORD dwKey);
+ bool CheckNextPathFragment(TMndxFindResult * pStruct1C);
+ bool FindFileInDatabase(TMndxFindResult * pStruct1C);
+
+ void sub_1958D70(TMndxFindResult * pStruct1C, DWORD arg_4);
+ bool sub_1959010(TMndxFindResult * pStruct1C, DWORD arg_4);
+ bool sub_1958B00(TMndxFindResult * pStruct1C);
+ bool sub_1959460(TMndxFindResult * pStruct1C);
+
+ TSparseArray Struct68_00;
+ TSparseArray FileNameIndexes; // Array of file name indexes
+ TSparseArray Struct68_D0;
+
+ // This pair of arrays serves for fast conversion from name hash to fragment offset
+ TGenericArray FrgmDist_LoBits; // Array of lower 8 bits of name fragment offset
+ TBitEntryArray FrgmDist_HiBits; // Array of upper x bits of name fragment offset
+
+ TNameIndexStruct IndexStruct_174;
+ TFileNameDatabasePtr NextDB;
+
+ TGenericArray NameFragTable;
+
+ DWORD NameFragIndexMask;
+ DWORD field_214;
+ TStruct10 Struct10;
+ TByteStream MarStream;
+};
+
+typedef struct _MAR_FILE
+{
+ TFileNameDatabasePtr * pDatabasePtr;
+ LPBYTE pbMarData;
+ DWORD cbMarData;
+} MAR_FILE, *PMAR_FILE;
+
+//-----------------------------------------------------------------------------
+// Macros
+
+// Returns nonzero if the name fragment match is a single-char match
+inline bool IS_SINGLE_CHAR_MATCH(TGenericArray & Table, DWORD ItemIndex)
+{
+ return ((Table.NameFragArray[ItemIndex].FragOffs & 0xFFFFFF00) == 0xFFFFFF00);
+}
+
+//-----------------------------------------------------------------------------
+// CASC functions related to MNDX
+
+int LoadMndxRootFile(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile);
+PCASC_PACKAGE FindMndxPackage(TCascStorage * hs, const char * szFileName);
+int SearchMndxInfo(PCASC_MNDX_INFO pMndxInfo, const char * szFileName, DWORD dwPackage, PCASC_ROOT_KEY_INFO pFoundInfo);
+bool DoStorageSearch_MNDX(TCascSearch * pSearch, PCASC_FIND_DATA pFindData);
+void FreeMndxInfo(PCASC_MNDX_INFO pMndxInfo);
+
+#endif // __CASC_MNDX_ROOT__
diff --git a/dep/CascLib/src/CascMndxRoot_x86.asm b/dep/CascLib/src/CascMndxRoot_x86.asm
new file mode 100644
index 00000000000..c0e787d0872
--- /dev/null
+++ b/dep/CascLib/src/CascMndxRoot_x86.asm
@@ -0,0 +1,4369 @@
+.686P
+.MODEL FLAT
+ASSUME FS: NOTHING
+
+; ---------------------------------------------------------------------------
+
+TMndxFindResult struc ; (sizeof=0x1C) ; XREF: GAME_OBJECT_03F7E848::sub_E94500_r
+szSearchMask dd ? ; XREF: TMndxFindResult__SetPath+2D_w
+ ; TMndxFindResult__Constructor+4_w ...
+cchSearchMask dd ? ; XREF: TMndxFindResult__SetPath:loc_1956E9A_w
+ ; TMndxFindResult__Constructor+6_w ...
+field_8 dd ? ; XREF: TMndxFindResult__Constructor+9_w
+szFoundPath dd ? ; XREF: TMndxFindResult__Constructor+C_w
+ ; TFileNameDatabase__FindFileInDatabase+55_w
+cchFoundPath dd ? ; XREF: TMndxFindResult__Constructor+F_w
+ ; TFileNameDatabase__FindFileInDatabase+5B_w
+FileNameIndex dd ? ; XREF: TMndxFindResult__Constructor+12_w
+ ; TFileNameDatabase__FindFileInDatabase+6B_w
+pStruct40 dd ? ; XREF: MAR_FILE__FindFileInDatabase+19_r
+ ; TMndxFindResult__SetPath:loc_1956E8C_r ...
+TMndxFindResult ends
+
+; ---------------------------------------------------------------------------
+
+TRIPLET struc ; (sizeof=0xC)
+BitIndex dd ? ; XREF: TFileNameDatabase__CheckNextPathFragment+39_r
+NextKey dd ? ; XREF: TFileNameDatabase__CheckNextPathFragment+8C_r
+ ; TSparseArray__GetItemValue:loc_1959B8F_r ...
+Distance dd ? ; XREF: TFileNameDatabase__CheckNextPathFragment+3E_r
+ ; TSparseArray__GetItemValue:loc_1959BBE_r ...
+TRIPLET ends
+
+; ---------------------------------------------------------------------------
+
+NAME_ENTRY struc ; (sizeof=0xC)
+ExpectedHashModifier dd ?
+NextHashModifier dd ? ; XREF: TArchiveDatabase__sub_1958B00+D3r
+ ; sub_1958D70+2Cr
+FragmentOffset dd ? ; XREF: TArchiveDatabase__sub_1958B00+45r
+ ; sub_1958D70+36r
+NAME_ENTRY ends
+
+; ---------------------------------------------------------------------------
+
+TStruct14 struc ; (sizeof=0x14) ; XREF: TFileNameDatabase::sub_1959460r
+HashValue dd ? ; XREF: TGenericArray__InsertItem_STRUCT14+44r
+ ; TGenericArray__InsertItem_STRUCT14+46w ...
+field_4 dd ? ; XREF: TGenericArray__InsertItem_STRUCT14+48r
+ ; TGenericArray__InsertItem_STRUCT14+4Bw ...
+field_8 dd ? ; XREF: TGenericArray__InsertItem_STRUCT14+4Er
+ ; TGenericArray__InsertItem_STRUCT14+51w ...
+field_C dd ? ; XREF: TGenericArray__InsertItem_STRUCT14+54r
+ ; TGenericArray__InsertItem_STRUCT14+57w ...
+field_10 dd ? ; XREF: TGenericArray__InsertItem_STRUCT14+5Ar
+ ; TGenericArray__InsertItem_STRUCT14+5Dw ...
+TStruct14 ends
+
+; ---------------------------------------------------------------------------
+
+TGenericArray struc ; (sizeof=0x15) ; XREF: TGenericArray::LoadDwordsArrayWithCopyr
+ ; TFileNameDatabase::LoadBytesr ...
+DataBuffer dd ? ; XREF: TMndxFindResult__CreateStruct40+24w
+ ; TMndxFindResult__CreateStruct40+35w ...
+field_4 dd ? ; XREF: TMndxFindResult__CreateStruct40+26w
+ ; TMndxFindResult__CreateStruct40+38w ...
+ItemArray dd ? ; XREF: TMndxFindResult__CreateStruct40+29w
+ ; TMndxFindResult__CreateStruct40+3Bw ...
+ItemCount dd ? ; XREF: TMndxFindResult__CreateStruct40+2Cw
+ ; TMndxFindResult__CreateStruct40+3Ew ...
+MaxItemCount dd ? ; XREF: TFileNameDatabasePtr__CreateDatabase+27o
+ ; TMndxFindResult__CreateStruct40+2Fw ...
+bIsValidArray db ? ; XREF: LoadAndVerifyIndexFileHeader+31w
+ ; TMndxFindResult__CreateStruct40+32w ...
+TGenericArray ends
+
+; ---------------------------------------------------------------------------
+
+TBitEntryArray struc ; (sizeof=0x24) ; XREF: TGenericArrayEx::LoadFromStream_Exchanger
+ ; TFileNameDatabaser
+DataBuffer dd ? ; XREF: TArchiveDatabase__Destructor+64r
+ ; TArchiveDatabase__Constructor+1A3w
+field_4 dd ? ; XREF: TArchiveDatabase__Constructor+1A9w
+ItemArray dd ? ; XREF: sub_1957350+31r
+ ; sub_19573D0+1Fr ...
+ItemCount dd ? ; XREF: TArchiveDatabase__Constructor+1B5w
+MaxItemCount dd ? ; XREF: TArchiveDatabase__Constructor+1BBw
+bIsValidArray db ? ; XREF: TArchiveDatabase__Constructor+1C1w
+ db ? ; undefined
+ db ? ; undefined
+ db ? ; undefined
+BitsPerEntry dd ? ; XREF: sub_1957350+1Fr
+ ; sub_19573D0+6r ...
+EntryBitMask dd ? ; XREF: sub_1957350:loc_19573B1r
+ ; sub_19573D0:loc_1957419r ...
+TotalEntries dd ? ; XREF: TGenericArrayEx__LoadFromStream:loc_195861Bw
+ ; TArchiveDatabase__Constructor+1D3w
+TBitEntryArray ends
+ ; TFileNameDatabase__Constructor+1D3_w
+; ---------------------------------------------------------------------------
+
+TStruct40 struc ; (sizeof=0x40)
+array_00 TGenericArray <> ; XREF: TMndxFindResult__CreateStruct40+24w
+ ; TMndxFindResult__CreateStruct40+26w ...
+ db ? ; undefined
+ db ? ; undefined
+ db ? ; undefined
+array_18 TGenericArray <> ; XREF: TMndxFindResult__CreateStruct40+35w
+ ; TMndxFindResult__CreateStruct40+38w ...
+ db ? ; undefined
+ db ? ; undefined
+ db ? ; undefined
+HashValue dd ? ; XREF: TMndxFindResult__CreateStruct40+47w
+ ; TFileNameDatabase__CheckNextPathFragment+1Ar ...
+CharIndex dd ? ; XREF: TMndxFindResult__CreateStruct40+4Aw
+ ; TFileNameDatabase__CheckNextPathFragment+11r ...
+ItemCount dd ? ; XREF: TMndxFindResult__CreateStruct40+4Dw
+ ; TStruct40__InitSearchBuffers+6Bw ...
+SearchPhase dd ? ; XREF: TMndxFindResult__CreateStruct40+50w
+ ; TFileNameDatabase__FindFileInDatabase+17w ...
+TStruct40 ends
+
+; ---------------------------------------------------------------------------
+
+TSparseArray struc ; (sizeof=0x65) ; XREF: TSparseArray::LoadFromStream_Exchange_r
+ ; TNameIndexStruct_r ...
+ItemIsPresent TGenericArray <> ; XREF: LoadAndVerifyIndexFileHeader+31_w
+ ; TFileNameDatabase__Destructor+4C_r ...
+ db ? ; undefined
+ db ? ; undefined
+ db ? ; undefined
+TotalItemCount dd ? ; XREF: TSparseArray__ExchangeWith+4D_r
+ ; TSparseArray__ExchangeWith+56_w ...
+ValidItemCount dd ? ; XREF: TFileNameDatabasePtr__GetFileNameCount:loc_1956D32_r
+ ; TSparseArray__ExchangeWith+59_r ...
+ArrayTriplets_20 TGenericArray <> ; XREF: TFileNameDatabase__Destructor+40_r
+ ; TFileNameDatabase__Destructor+94_r ...
+ db ? ; undefined
+ db ? ; undefined
+ db ? ; undefined
+ArrayDwords_38 TGenericArray <> ; XREF: TFileNameDatabasePtr__CreateDatabase+27_o
+ ; TFileNameDatabase__Destructor+34_r ...
+ db ? ; undefined
+ db ? ; undefined
+ db ? ; undefined
+ArrayDwords_50 TGenericArray <> ; XREF: TFileNameDatabase__Destructor+28_r
+ ; TFileNameDatabase__Destructor+7C_r ...
+TSparseArray ends
+
+; ---------------------------------------------------------------------------
+
+TNameIndexStruct struc ; (sizeof=0x7D) ; XREF: TNameIndexStruct::LoadFromStream_Exchange_r
+ ; TFileNameDatabaser
+NameFragments TGenericArray <> ; XREF: TFileNameDatabase__Destructor+58_r
+ ; TFileNameDatabase__LoadFromStream+82_r ...
+ db ? ; undefined
+ db ? ; undefined
+ db ? ; undefined
+Struct68 TSparseArray <> ; XREF: LoadAndVerifyIndexFileHeader+31_w
+ ; TFileNameDatabase__Destructor+28_r ...
+TNameIndexStruct ends
+
+; ---------------------------------------------------------------------------
+
+TByteStream struc ; (sizeof=0x18) ; XREF: TFileNameDatabasePtr::CreateDatabase_r
+ ; TFileNameDatabase_r
+pbData dd ? ; XREF: TByteStream__Constructor+4_w
+ ; TByteStream__IsMarDataValid+2_r ...
+pvMappedFile dd ? ; XREF: TByteStream__Constructor+6_w
+ ; TByteStream__Destructor+3_r
+cbData dd ? ; XREF: TByteStream__Constructor+9_w
+ ; TByteStream__GetBytes:loc_1959A05_r ...
+field_C dd ? ; XREF: TByteStream__Constructor+C_w
+hFile dd ? ; XREF: TByteStream__Constructor+F_w
+ ; TByteStream__Destructor:loc_19599D2_r
+hMap dd ? ; XREF: TByteStream__Constructor+12_w
+ ; TByteStream__Destructor:loc_19599C2_r
+TByteStream ends
+
+; ---------------------------------------------------------------------------
+
+TStruct10 struc ; (sizeof=0x10) ; XREF: TStruct10::sub_1957800_r
+ ; TFileNameDatabase_r
+field_0 dd ? ; XREF: sub_19572E0+24_w
+ ; TFileNameDatabase__Constructor+21A_w
+field_4 dd ? ; XREF: sub_1956FD0+28_w
+ ; sub_1956FD0:loc_1957001_w ...
+field_8 dd ? ; XREF: sub_19572E0+4A_w
+ ; sub_19572E0+5B_w ...
+field_C dd ? ; XREF: sub_1957050:loc_1957074_w
+ ; sub_1957050:loc_1957081_w ...
+TStruct10 ends
+
+; ---------------------------------------------------------------------------
+
+TFileNameDatabasePtr struc ; (sizeof=0x4) ; XREF: TFileNameDatabase_r
+ ; MAR_FILE_r
+pDatabase dd ? ; XREF: MAR_FILE__Constructor+1D_w
+ ; MAR_FILE__CreateDatabase+22_w ...
+TFileNameDatabasePtr ends
+
+; ---------------------------------------------------------------------------
+
+TFileNameDatabase struc ; (sizeof=0x240) ; XREF: TFileNameDatabase::LoadFromStream_Exchange_r
+Struct68_00 TSparseArray <> ; XREF: TFileNameDatabasePtr__CreateDatabase+27_o
+ ; TFileNameDatabase__Destructor+D9_r ...
+ db ? ; undefined
+ db ? ; undefined
+ db ? ; undefined
+FileNameIndexes TSparseArray <> ; XREF: TFileNameDatabasePtr__GetFileNameCount:loc_1956D32_r
+ ; TFileNameDatabase__Destructor+AC_r ...
+ db ? ; undefined
+ db ? ; undefined
+ db ? ; undefined
+Struct68_D0 TSparseArray <> ; XREF: TFileNameDatabase__Destructor+7C_r
+ ; TFileNameDatabase__Destructor+88_r ...
+ db ? ; undefined
+ db ? ; undefined
+ db ? ; undefined
+FrgmDist_LoBits TGenericArray <> ; XREF: TFileNameDatabase__Destructor+70_r
+ ; TFileNameDatabase__CheckNextPathFragment:loc_1957AC9_r ...
+ db ? ; undefined
+ db ? ; undefined
+ db ? ; undefined
+FrgmDist_HiBits TBitEntryArray <> ; XREF: TFileNameDatabase__Destructor+64_r
+ ; TFileNameDatabase__CheckNextPathFragment+119_r ...
+IndexStruct_174 TNameIndexStruct <> ; XREF: TFileNameDatabase__Destructor+28_r
+ ; TFileNameDatabase__Destructor+34_r ...
+ db ? ; undefined
+ db ? ; undefined
+ db ? ; undefined
+NextDB TFileNameDatabasePtr <> ; XREF: TFileNameDatabase__Destructor+1D_o
+ ; TFileNameDatabase__CheckNextPathFragment+52_r ...
+NameFragTable TGenericArray <> ; XREF: TFileNameDatabase__Destructor+E_r
+ ; TFileNameDatabase__CheckNextPathFragment+2F_r ...
+ db ? ; undefined
+ db ? ; undefined
+ db ? ; undefined
+NameFragIndexMask dd ? ; XREF: TFileNameDatabase__CheckNextPathFragment+26_r
+ ; sub_1957B80:loc_1957B95_r ...
+field_214 dd ? ; XREF: TFileNameDatabase__Constructor+20E_w
+ ; TFileNameDatabase__LoadFromStream+110_w
+Struct10 TStruct10 <> ; XREF: TFileNameDatabase__Constructor+21A_w
+ ; TFileNameDatabase__Constructor+224_w ...
+MarStream TByteStream <> ; XREF: TFileNameDatabase__Destructor+3_o
+ ; TFileNameDatabase__Constructor+214_o
+TFileNameDatabase ends
+
+; ---------------------------------------------------------------------------
+
+MAR_FILE struc ; (sizeof=0xC)
+pDatabasePtr TFileNameDatabasePtr <> ; XREF: MAR_FILE__Constructor+1D_w
+ ; MAR_FILE__CreateDatabase+22_w ...
+pbMarFileData dd ? ; XREF: MAR_FILE__Constructor+1A_w
+ ; MAR_FILE__CreateDatabase+1B_r ...
+cbMarFileData dd ? ; XREF: MAR_FILE__Constructor+12_w
+ ; MAR_FILE__CreateDatabase+18_r ...
+MAR_FILE ends
+
+.DATA
+table_1BA1818 db 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0
+ db 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0
+ db 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0
+ db 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0
+ db 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0
+ db 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0
+ db 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0
+ db 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+ db 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0
+ db 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0
+ db 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0
+ db 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0
+ db 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0
+ db 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0
+ db 2, 0, 1, 0, 3 dup(7), 1, 7, 2 dup(2), 1, 7, 2 dup(3)
+ db 1, 3, 2 dup(2), 1, 7, 2 dup(4), 1, 4, 2 dup(2), 1, 4
+ db 2 dup(3), 1, 3, 2 dup(2), 1, 7, 2 dup(5), 1, 5, 2 dup(2)
+ db 1, 5, 2 dup(3), 1, 3, 2 dup(2), 1, 5, 2 dup(4), 1, 4
+ db 2 dup(2), 1, 4, 2 dup(3), 1, 3, 2 dup(2), 1, 7, 2 dup(6)
+ db 1, 6, 2 dup(2), 1, 6, 2 dup(3), 1, 3, 2 dup(2), 1, 6
+ db 2 dup(4), 1, 4, 2 dup(2), 1, 4, 2 dup(3), 1, 3, 2 dup(2)
+ db 1, 6, 2 dup(5), 1, 5, 2 dup(2), 1, 5, 2 dup(3), 1, 3
+ db 2 dup(2), 1, 5, 2 dup(4), 1, 4, 2 dup(2), 1, 4, 2 dup(3)
+ db 1, 3, 2 dup(2), 1, 3 dup(7), 1, 7, 2 dup(2), 1, 7, 2 dup(3)
+ db 1, 3, 2 dup(2), 1, 7, 2 dup(4), 1, 4, 2 dup(2), 1, 4
+ db 2 dup(3), 1, 3, 2 dup(2), 1, 7, 2 dup(5), 1, 5, 2 dup(2)
+ db 1, 5, 2 dup(3), 1, 3, 2 dup(2), 1, 5, 2 dup(4), 1, 4
+ db 2 dup(2), 1, 4, 2 dup(3), 1, 3, 2 dup(2), 1, 7, 2 dup(6)
+ db 1, 6, 2 dup(2), 1, 6, 2 dup(3), 1, 3, 2 dup(2), 1, 6
+ db 2 dup(4), 1, 4, 2 dup(2), 1, 4, 2 dup(3), 1, 3, 2 dup(2)
+ db 1, 6, 2 dup(5), 1, 5, 2 dup(2), 1, 5, 2 dup(3), 1, 3
+ db 2 dup(2), 1, 5, 2 dup(4), 1, 4, 2 dup(2), 1, 4, 2 dup(3)
+ db 1, 3, 2 dup(2), 1, 7 dup(7), 2, 3 dup(7), 3, 7, 2 dup(3)
+ db 2, 3 dup(7), 4, 7, 2 dup(4), 2, 7, 2 dup(4), 3, 4, 2 dup(3)
+ db 2, 3 dup(7), 5, 7, 2 dup(5), 2, 7, 2 dup(5), 3, 5, 2 dup(3)
+ db 2, 7, 2 dup(5), 4, 5, 2 dup(4), 2, 5, 2 dup(4), 3, 4
+ db 2 dup(3), 2, 3 dup(7), 6, 7, 2 dup(6), 2, 7, 2 dup(6)
+ db 3, 6, 2 dup(3), 2, 7, 2 dup(6), 4, 6, 2 dup(4), 2, 6
+ db 2 dup(4), 3, 4, 2 dup(3), 2, 7, 2 dup(6), 5, 6, 2 dup(5)
+ db 2, 6, 2 dup(5), 3, 5, 2 dup(3), 2, 6, 2 dup(5), 4, 5
+ db 2 dup(4), 2, 5, 2 dup(4), 3, 4, 2 dup(3), 2, 7 dup(7)
+ db 2, 3 dup(7), 3, 7, 2 dup(3), 2, 3 dup(7), 4, 7, 2 dup(4)
+ db 2, 7, 2 dup(4), 3, 4, 2 dup(3), 2, 3 dup(7), 5, 7, 2 dup(5)
+ db 2, 7, 2 dup(5), 3, 5, 2 dup(3), 2, 7, 2 dup(5), 4, 5
+ db 2 dup(4), 2, 5, 2 dup(4), 3, 4, 2 dup(3), 2, 3 dup(7)
+ db 6, 7, 2 dup(6), 2, 7, 2 dup(6), 3, 6, 2 dup(3), 2, 7
+ db 2 dup(6), 4, 6, 2 dup(4), 2, 6, 2 dup(4), 3, 4, 2 dup(3)
+ db 2, 7, 2 dup(6), 5, 6, 2 dup(5), 2, 6, 2 dup(5), 3, 5
+ db 2 dup(3), 2, 6, 2 dup(5), 4, 5, 2 dup(4), 2, 5, 2 dup(4)
+ db 3, 4, 2 dup(3), 2, 0Fh dup(7), 3, 7 dup(7), 4, 3 dup(7)
+ db 4, 7, 2 dup(4), 3, 7 dup(7), 5, 3 dup(7), 5, 7, 2 dup(5)
+ db 3, 3 dup(7), 5, 7, 2 dup(5), 4, 7, 2 dup(5), 4, 5, 2 dup(4)
+ db 3, 7 dup(7), 6, 3 dup(7), 6, 7, 2 dup(6), 3, 3 dup(7)
+ db 6, 7, 2 dup(6), 4, 7, 2 dup(6), 4, 6, 2 dup(4), 3, 3 dup(7)
+ db 6, 7, 2 dup(6), 5, 7, 2 dup(6), 5, 6, 2 dup(5), 3, 7
+ db 2 dup(6), 5, 6, 2 dup(5), 4, 6, 2 dup(5), 4, 5, 2 dup(4)
+ db 3, 0Fh dup(7), 3, 7 dup(7), 4, 3 dup(7), 4, 7, 2 dup(4)
+ db 3, 7 dup(7), 5, 3 dup(7), 5, 7, 2 dup(5), 3, 3 dup(7)
+ db 5, 7, 2 dup(5), 4, 7, 2 dup(5), 4, 5, 2 dup(4), 3, 7 dup(7)
+ db 6, 3 dup(7), 6, 7, 2 dup(6), 3, 3 dup(7), 6, 7, 2 dup(6)
+ db 4, 7, 2 dup(6), 4, 6, 2 dup(4), 3, 3 dup(7), 6, 7, 2 dup(6)
+ db 5, 7, 2 dup(6), 5, 6, 2 dup(5), 3, 7, 2 dup(6), 5, 6
+ db 2 dup(5), 4, 6, 2 dup(5), 4, 5, 2 dup(4), 3, 1Fh dup(7)
+ db 4, 0Fh dup(7), 5, 7 dup(7), 5, 3 dup(7), 5, 7, 2 dup(5)
+ db 4, 0Fh dup(7), 6, 7 dup(7), 6, 3 dup(7), 6, 7, 2 dup(6)
+ db 4, 7 dup(7), 6, 3 dup(7), 6, 7, 2 dup(6), 5, 3 dup(7)
+ db 6, 7, 2 dup(6), 5, 7, 2 dup(6), 5, 6, 2 dup(5), 4, 1Fh dup(7)
+ db 4, 0Fh dup(7), 5, 7 dup(7), 5, 3 dup(7), 5, 7, 2 dup(5)
+ db 4, 0Fh dup(7), 6, 7 dup(7), 6, 3 dup(7), 6, 7, 2 dup(6)
+ db 4, 7 dup(7), 6, 3 dup(7), 6, 7, 2 dup(6), 5, 3 dup(7)
+ db 6, 7, 2 dup(6), 5, 7, 2 dup(6), 5, 6, 2 dup(5), 4, 3Fh dup(7)
+ db 5, 1Fh dup(7), 6, 0Fh dup(7), 6, 7 dup(7), 6, 3 dup(7)
+ db 6, 7, 2 dup(6), 5, 3Fh dup(7), 5, 1Fh dup(7), 6, 0Fh dup(7)
+ db 6, 7 dup(7), 6, 3 dup(7), 6, 7, 2 dup(6), 5, 7Fh dup(7)
+ db 6, 7Fh dup(7), 6, 100h dup(7)
+
+unk_53ABE00 db 0
+
+.CODE
+
+;
+; void * operator_new_safe(size_t ByteCount, void * unk_53ABE00);
+;
+
+EXTERN _allocate_zeroed_memory_x86:PROC
+EXTERN _free_memory_x86:PROC
+
+j_operator_new_safe PROC
+ push ebp
+ mov ebp, esp
+ push [ebp+08]
+ call _allocate_zeroed_memory_x86
+ add esp, 4
+ mov esp, ebp
+ pop ebp
+ ret
+j_operator_new_safe ENDP
+
+operator_delete PROC
+ push ebp
+ mov ebp, esp
+ push [ebp+08]
+ call _free_memory_x86
+ add esp, 4
+ mov esp, ebp
+ pop ebp
+ ret
+operator_delete ENDP
+
+
+TSparseArray__GetItemValue proc near ; CODE XREF: sub_1957350+1A_p
+ ; TFileNameDatabase__CheckNextPathFragment+103_p ...
+
+arg_0 = dword ptr 8
+
+ push ebp
+ mov ebp, esp
+ mov edx, [ecx+28h]
+ push ebx
+ push esi
+ push edi
+ mov edi, [ebp+arg_0]
+ mov eax, edi
+ shr eax, 9
+ lea eax, [eax+eax*2]
+ mov esi, [edx+eax*4]
+ lea eax, [edx+eax*4]
+ mov edx, edi
+ shr edx, 6
+ and edx, 7
+ dec edx
+ cmp edx, 6 ; switch 7 cases
+ ja short loc_1959BE0 ; jumptable 01959B88 default case
+ jmp ds:off_1959C90[edx*4] ; switch jump
+
+loc_1959B8F: ; DATA XREF: .text:off_1959C90o
+ mov eax, [eax+4] ; jumptable 01959B88 case 0
+ and eax, 7Fh
+ jmp short loc_1959BDE
+; ---------------------------------------------------------------------------
+
+loc_1959B97: ; CODE XREF: TSparseArray__GetItemValue+28_j
+ ; DATA XREF: .text:off_1959C90o
+ mov edx, [eax+4] ; jumptable 01959B88 case 1
+ shr edx, 7
+ and edx, 0FFh
+ add esi, edx
+ jmp short loc_1959BE0 ; jumptable 01959B88 default case
+; ---------------------------------------------------------------------------
+
+loc_1959BA7: ; CODE XREF: TSparseArray__GetItemValue+28_j
+ ; DATA XREF: .text:off_1959C90o
+ mov eax, [eax+4] ; jumptable 01959B88 case 2
+ shr eax, 0Fh
+ and eax, 0FFh
+ jmp short loc_1959BDE
+; ---------------------------------------------------------------------------
+
+loc_1959BB4: ; CODE XREF: TSparseArray__GetItemValue+28_j
+ ; DATA XREF: .text:off_1959C90o
+ mov edx, [eax+4] ; jumptable 01959B88 case 3
+ shr edx, 17h
+ add esi, edx
+ jmp short loc_1959BE0 ; jumptable 01959B88 default case
+; ---------------------------------------------------------------------------
+
+loc_1959BBE: ; CODE XREF: TSparseArray__GetItemValue+28_j
+ ; DATA XREF: .text:off_1959C90o
+ mov eax, [eax+8] ; jumptable 01959B88 case 4
+ jmp short loc_1959BD9
+; ---------------------------------------------------------------------------
+
+loc_1959BC3: ; CODE XREF: TSparseArray__GetItemValue+28_j
+ ; DATA XREF: .text:off_1959C90o
+ mov edx, [eax+8] ; jumptable 01959B88 case 5
+ shr edx, 9
+ and edx, 1FFh
+ add esi, edx
+ jmp short loc_1959BE0 ; jumptable 01959B88 default case
+; ---------------------------------------------------------------------------
+
+loc_1959BD3: ; CODE XREF: TSparseArray__GetItemValue+28_j
+ ; DATA XREF: .text:off_1959C90o
+ mov eax, [eax+8] ; jumptable 01959B88 case 6
+ shr eax, 12h
+
+loc_1959BD9: ; CODE XREF: TSparseArray__GetItemValue+61_j
+ and eax, 1FFh
+
+loc_1959BDE: ; CODE XREF: TSparseArray__GetItemValue+35_j
+ ; TSparseArray__GetItemValue+52_j
+ add esi, eax
+
+loc_1959BE0: ; CODE XREF: TSparseArray__GetItemValue+26_j
+ ; TSparseArray__GetItemValue+45_j ...
+ mov ebx, edi ; jumptable 01959B88 default case
+ shr ebx, 5
+ test bl, 1
+ jz short loc_1959C31
+ mov edx, [ecx+8]
+ mov edx, [edx+ebx*4-4]
+ mov eax, edx
+ shr eax, 1
+ and eax, 55555555h
+ and edx, 55555555h
+ add eax, edx
+ mov edx, eax
+ and eax, 33333333h
+ shr edx, 2
+ and edx, 33333333h
+ add edx, eax
+ mov eax, edx
+ shr eax, 4
+ and eax, 0F0F0F0Fh
+ and edx, 0F0F0F0Fh
+ add eax, edx
+ imul eax, 1010101h
+ shr eax, 18h
+ add esi, eax
+
+loc_1959C31: ; CODE XREF: TSparseArray__GetItemValue+88_j
+ mov edx, [ecx+8]
+ mov ecx, edi
+ and ecx, 1Fh
+ mov eax, 1
+ shl eax, cl
+ mov ecx, [edx+ebx*4]
+ pop edi
+ dec eax
+ and ecx, eax
+ mov eax, ecx
+ shr eax, 1
+ and eax, 55555555h
+ and ecx, 55555555h
+ add eax, ecx
+ mov ecx, eax
+ and eax, 33333333h
+ shr ecx, 2
+ and ecx, 33333333h
+ add ecx, eax
+ mov eax, ecx
+ shr eax, 4
+ and eax, 0F0F0F0Fh
+ and ecx, 0F0F0F0Fh
+ add eax, ecx
+ imul eax, 1010101h
+ shr eax, 18h
+ add eax, esi
+ pop esi
+ pop ebx
+ pop ebp
+ retn 4
+
+off_1959C90 dd offset loc_1959B8F ; DATA XREF: TSparseArray__GetItemValue+28_r
+ dd offset loc_1959B97 ; jump table for switch statement
+ dd offset loc_1959BA7
+ dd offset loc_1959BB4
+ dd offset loc_1959BBE
+ dd offset loc_1959BC3
+ dd offset loc_1959BD3
+
+TSparseArray__GetItemValue endp
+
+;------------------------------------------------------------------------------
+; TArchiveDatabase__sub_1959CB0
+
+TArchiveDatabase__sub_1959CB0 proc near
+ ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+A1_p
+ ; sub_1958B00+E8_p ...
+
+pThis = dword ptr -4
+dwKey = dword ptr 8
+
+ push ebp
+ mov ebp, esp
+ push ecx
+ mov edx, [ebp+dwKey]
+ mov eax, edx
+ shr eax, 9
+ mov [ebp+pThis], ecx
+ test edx, 1FFh ; if(dwKey & 0x01FF)
+ jnz short loc_1959CD3
+ mov ecx, [ecx+40h]
+ mov eax, [ecx+eax*4] ; EAX = pDatabase->NextKeyTable[dwKey >> 0x09]
+ mov esp, ebp
+ pop ebp
+ retn 4
+; ---------------------------------------------------------------------------
+
+loc_1959CD3: ; CODE XREF: TFileNameDatabase__FindNextMatch+15_j
+ push ebx
+ push esi
+ mov esi, [ecx+40h]
+ lea esi, [esi+eax*4]
+ mov eax, [esi]
+ mov esi, [esi+4]
+ shr eax, 9
+ add esi, 1FFh
+ push edi
+ shr esi, 9
+ lea edi, [eax+0Ah]
+ mov [ebp+dwKey], esi
+ cmp edi, esi
+ jb short loc_1959D2E
+ mov edi, [ecx+28h]
+ lea esi, [eax+eax*2+3]
+ lea esi, [edi+esi*4]
+ mov edi, eax
+ shl edi, 9
+ mov ebx, edi
+ sub ebx, [esi]
+ add ebx, 200h
+ cmp edx, ebx
+ jb short loc_1959D5F
+
+loc_1959D14: ; CODE XREF: TFileNameDatabase__FindNextMatch+7Aj
+ add edi, 200h
+ add esi, 0Ch
+ mov ebx, edi
+ sub ebx, [esi]
+ inc eax
+ add ebx, 200h
+ cmp edx, ebx
+ jnb short loc_1959D14
+ jmp short loc_1959D5F
+; ---------------------------------------------------------------------------
+
+loc_1959D2E: ; CODE XREF: TFileNameDatabase__FindNextMatch+45_j
+ lea edi, [eax+1]
+ cmp edi, esi
+ jnb short loc_1959D5F
+ mov ecx, [ecx+28h]
+
+loc_1959D38: ; CODE XREF: TFileNameDatabase__FindNextMatch+AAj
+ add esi, eax
+ shr esi, 1
+ mov ebx, esi
+ shl ebx, 9
+ lea edi, [esi+esi*2]
+ sub ebx, [ecx+edi*4]
+ cmp edx, ebx
+ jnb short loc_1959D50
+ mov [ebp+dwKey], esi
+ jmp short loc_1959D55
+; ---------------------------------------------------------------------------
+
+loc_1959D50: ; CODE XREF: TFileNameDatabase__FindNextMatch+99_j
+ mov eax, esi
+ mov esi, [ebp+dwKey]
+
+loc_1959D55: ; CODE XREF: TFileNameDatabase__FindNextMatch+9E_j
+ lea edi, [eax+1]
+ cmp edi, esi
+ jb short loc_1959D38
+ mov ecx, [ebp+pThis]
+
+loc_1959D5F: ; CODE XREF: TFileNameDatabase__FindNextMatch+62_j
+ ; TFileNameDatabase__FindNextMatch+7C_j ...
+ mov ecx, [ecx+28h]
+ lea esi, [eax+eax*2]
+ mov edi, [ecx+esi*4] ; EDI = Struct68_00.ArrayTriplets_20.ItemArray[eax]
+ lea esi, [ecx+esi*4] ; ESI = Struct68_00.ArrayTriplets_20.ItemArray + eax
+ mov ecx, eax
+ shl ecx, 9
+ sub edi, ecx
+ shl eax, 4
+ add edx, edi
+ mov edi, eax
+ mov eax, [esi+4]
+ mov ecx, eax
+ shr ecx, 17h
+ mov ebx, 100h
+ sub ebx, ecx
+ cmp edx, ebx
+ jnb short loc_1959DE8
+ mov ecx, eax
+ shr ecx, 7
+ and ecx, 0FFh
+ mov esi, 80h
+ sub esi, ecx
+ cmp edx, esi
+ jnb short loc_1959DC0
+ and eax, 7Fh
+ mov ecx, 40h
+ sub ecx, eax
+ cmp edx, ecx
+ jb loc_1959E53
+ add edi, 2
+ lea edx, [edx+eax-40h]
+ jmp loc_1959E53
+; ---------------------------------------------------------------------------
+
+loc_1959DC0: ; CODE XREF: TFileNameDatabase__FindNextMatch+F0_j
+ shr eax, 0Fh
+ and eax, 0FFh
+ mov esi, 0C0h
+ sub esi, eax
+ cmp edx, esi
+ jnb short loc_1959DDC
+ add edi, 4
+ lea edx, [edx+ecx-80h]
+ jmp short loc_1959E53
+; ---------------------------------------------------------------------------
+
+loc_1959DDC: ; CODE XREF: TFileNameDatabase__FindNextMatch+121_j
+ add edi, 6
+ lea edx, [edx+eax-0C0h]
+ jmp short loc_1959E53
+; ---------------------------------------------------------------------------
+
+loc_1959DE8: ; CODE XREF: TFileNameDatabase__FindNextMatch+DA_j
+ mov esi, [esi+8]
+ mov eax, esi
+ shr eax, 9
+ and eax, 1FFh
+ mov ebx, 180h
+ sub ebx, eax
+ cmp edx, ebx
+ jnb short loc_1959E29
+ and esi, 1FFh
+ mov eax, 140h
+ sub eax, esi
+ cmp edx, eax
+ jnb short loc_1959E1D
+ add edi, 8
+ lea edx, [edx+ecx-100h]
+ jmp short loc_1959E53
+; ---------------------------------------------------------------------------
+
+loc_1959E1D: ; CODE XREF: TFileNameDatabase__FindNextMatch+15F_j
+ add edi, 0Ah
+ lea edx, [edx+esi-140h]
+ jmp short loc_1959E53
+; ---------------------------------------------------------------------------
+
+loc_1959E29: ; CODE XREF: TFileNameDatabase__FindNextMatch+14E_j
+ shr esi, 12h
+ and esi, 1FFh
+ mov ecx, 1C0h
+ sub ecx, esi
+ cmp edx, ecx
+ jnb short loc_1959E49
+ add edi, 0Ch
+ lea edx, [edx+eax-180h]
+ jmp short loc_1959E53
+; ---------------------------------------------------------------------------
+
+loc_1959E49: ; CODE XREF: TFileNameDatabase__FindNextMatch+18B_j
+ add edi, 0Eh
+ lea edx, [edx+esi-1C0h]
+
+loc_1959E53: ; CODE XREF: TFileNameDatabase__FindNextMatch+FE_j
+ ; TFileNameDatabase__FindNextMatch+10B_j ...
+ mov eax, [ebp+pThis]
+ mov ebx, [eax+8]
+ mov ecx, [ebx+edi*4]
+ not ecx
+ mov eax, ecx
+ shr eax, 1
+ and eax, 55555555h
+ mov esi, ecx
+ and esi, 55555555h
+ add eax, esi
+ mov esi, eax
+ shr esi, 2
+ and eax, 33333333h
+ and esi, 33333333h
+ add esi, eax
+ mov eax, esi
+ shr eax, 4
+ and esi, 0F0F0F0Fh
+ and eax, 0F0F0F0Fh
+ add eax, esi
+ imul eax, 1010101h
+ mov esi, eax
+ shr esi, 18h
+ cmp edx, esi
+ jb short loc_1959EEA
+ mov ecx, [ebx+edi*4+4]
+ inc edi
+ sub edx, esi
+ not ecx
+ mov eax, ecx
+ shr eax, 1
+ and eax, 55555555h
+ mov esi, ecx
+ and esi, 55555555h
+ add eax, esi
+ mov esi, eax
+ shr esi, 2
+ and eax, 33333333h
+ and esi, 33333333h
+ add esi, eax
+ mov eax, esi
+ shr eax, 4
+ and eax, 0F0F0F0Fh
+ and esi, 0F0F0F0Fh
+ add eax, esi
+ imul eax, 1010101h
+
+loc_1959EEA: ; CODE XREF: TFileNameDatabase__FindNextMatch+1F2_j
+ mov esi, eax
+ shr esi, 8
+ and esi, 0FFh
+ shl edi, 5
+ cmp edx, esi
+ jnb short loc_1959F0D
+ and eax, 0FFh
+ cmp edx, eax
+ jb short loc_1959F2B
+ add edi, 8
+ shr ecx, 8
+ jmp short loc_1959F29
+; ---------------------------------------------------------------------------
+
+loc_1959F0D: ; CODE XREF: TFileNameDatabase__FindNextMatch+24A_j
+ shr eax, 10h
+ and eax, 0FFh
+ cmp edx, eax
+ jnb short loc_1959F23
+ add edi, 10h
+ shr ecx, 10h
+ sub edx, esi
+ jmp short loc_1959F2B
+; ---------------------------------------------------------------------------
+
+loc_1959F23: ; CODE XREF: TFileNameDatabase__FindNextMatch+267_j
+ add edi, 18h
+ shr ecx, 18h
+
+loc_1959F29: ; CODE XREF: TFileNameDatabase__FindNextMatch+25B_j
+ sub edx, eax
+
+loc_1959F2B: ; CODE XREF: TFileNameDatabase__FindNextMatch+253_j
+ ; TFileNameDatabase__FindNextMatch+271_j
+ and ecx, 0FFh
+ shl edx, 8
+ movzx eax, byte ptr ds:table_1BA1818[ecx+edx]
+ add eax, edi
+ pop edi
+ pop esi
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 4
+TArchiveDatabase__sub_1959CB0 endp
+
+; =============== S U B R O U T I N E =======================================
+
+; Attributes: bp-based frame
+
+TNameIndexStruct__CheckNameFragment proc near ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+6B_p
+ ; TFileNameDatabase__CheckNextPathFragment+191_p ...
+
+pThis = dword ptr -4
+pUnknownStruct1C= dword ptr 8
+dwDistance = dword ptr 0Ch
+
+ push ebp
+ mov ebp, esp
+ push ecx
+ push ebx
+ push esi
+ push edi
+ mov edi, ecx
+ cmp [edi+TNameIndexStruct.Struct68.TotalItemCount], 0
+ mov ecx, [ebp+pUnknownStruct1C]
+ mov edx, [ecx+TMndxFindResult.pStruct40]
+ mov [ebp+pThis], edi
+ jnz short loc_195A1C8
+ mov edi, [edi+TNameIndexStruct.NameFragments.ItemArray] ; Pointer to name table
+ sub edi, [edx+TStruct40.CharIndex]
+ add edi, [ebp+dwDistance] ; EDI = szPathFragment
+
+loc_195A1A1: ; CODE XREF: TNameIndexStruct__CheckNameFragment+3Bj
+ mov eax, [edx+TStruct40.CharIndex]
+ mov esi, [ecx+TMndxFindResult.szSearchMask]
+ mov bl, [eax+edi]
+ cmp bl, [eax+esi]
+ jnz short loc_195A1BD
+ inc eax
+ mov [edx+TStruct40.CharIndex], eax
+ cmp byte ptr [eax+edi], 0
+ jz short loc_195A215
+ cmp eax, [ecx+TMndxFindResult.cchSearchMask]
+ jb short loc_195A1A1
+
+loc_195A1BD: ; CODE XREF: TNameIndexStruct__CheckNameFragment+2C_j
+ ; TNameIndexStruct__CheckNameFragment+5Ej ...
+ pop edi
+ pop esi
+ xor al, al
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 8
+; ---------------------------------------------------------------------------
+
+loc_195A1C8: ; CODE XREF: TNameIndexStruct__CheckNameFragment+16_j
+ mov eax, [ebp+dwDistance]
+ jmp short loc_195A1D0
+; ---------------------------------------------------------------------------
+ align 10h
+
+loc_195A1D0: ; CODE XREF: TNameIndexStruct__CheckNameFragment+4B_j
+ ; TNameIndexStruct__CheckNameFragment+93j
+ mov ebx, [edi+TNameIndexStruct.NameFragments.ItemArray]
+ mov esi, [edx+TStruct40.CharIndex]
+ mov ecx, [ecx+TMndxFindResult.szSearchMask]
+ mov bl, [eax+ebx] ; pNameList[dwNameOffset] == szPathName[nCharIndex]
+ cmp bl, [esi+ecx]
+ jnz short loc_195A1BD
+ lea ecx, [esi+1]
+ mov [edx+TStruct40.CharIndex], ecx
+ mov edi, [edi+TNameIndexStruct.Struct68.ItemIsPresent.ItemArray]
+ mov [ebp+dwDistance], ecx
+ mov ecx, eax
+ and ecx, 1Fh ; ecx = (dwNameOffset & 0x1F)
+ mov esi, eax
+ mov ebx, 1
+ shl ebx, cl ; ebx = 1 << (dwNameOffset & 0x1F);
+ shr esi, 5 ; esi = (dwNameOffset >> 0x05)
+ mov ecx, [edi+esi*4]
+ inc eax
+ and ecx, ebx
+ jnz short loc_195A215
+ mov esi, [ebp+dwDistance]
+ mov ecx, [ebp+pUnknownStruct1C]
+ cmp esi, [ecx+4]
+ jnb short loc_195A1BD
+ mov edi, [ebp+pThis]
+ jmp short loc_195A1D0
+; ---------------------------------------------------------------------------
+
+loc_195A215: ; CODE XREF: TNameIndexStruct__CheckNameFragment+36_j
+ ; TNameIndexStruct__CheckNameFragment+83_j
+ pop edi
+ pop esi
+ mov al, 1
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 8
+TNameIndexStruct__CheckNameFragment endp
+
+; =============== S U B R O U T I N E =======================================
+
+; Attributes: bp-based frame
+
+sub_1957350 proc near ; CODE XREF: sub_1957B80+D8p
+ ; sub_1957B80:loc_1957C73p ...
+
+arg_0 = dword ptr 8
+
+ push ebp
+ mov ebp, esp
+ mov eax, [ebp+arg_0]
+ push ebx
+ push esi
+ mov esi, ecx
+ mov ebx, [esi+140h]
+ push edi
+ push eax
+ lea ecx, [esi+0D0h]
+ add ebx, eax
+ call TSparseArray__GetItemValue
+ mov edi, [esi+168h]
+ mov ecx, edi
+ imul ecx, eax
+ mov eax, ecx
+ and ecx, 1Fh
+ mov edx, ecx
+ mov ecx, [esi+158h]
+ add edi, edx
+ shr eax, 5
+ cmp edi, 20h
+ ja short loc_195739A
+ mov eax, [ecx+eax*4]
+ mov ecx, edx
+ shr eax, cl
+ jmp short loc_19573B1
+; ---------------------------------------------------------------------------
+
+loc_195739A: ; CODE XREF: sub_1957350+3F_j
+ lea edi, [ecx+eax*4]
+ mov eax, [edi+4]
+ mov edi, [edi]
+ mov ecx, 20h
+ sub ecx, edx
+ shl eax, cl
+ mov ecx, edx
+ shr edi, cl
+ or eax, edi
+
+loc_19573B1: ; CODE XREF: sub_1957350+48_j
+ and eax, [esi+16Ch]
+ movzx edx, byte ptr [ebx]
+ pop edi
+ shl eax, 8
+ pop esi
+ or eax, edx
+ pop ebx
+ pop ebp
+ retn 4
+sub_1957350 endp
+
+; ---------------------------------------------------------------------------
+
+
+; =============== S U B R O U T I N E =======================================
+
+; Attributes: bp-based frame
+
+sub_1959F50 proc near ; CODE XREF: sub_1957B80+14C_p
+ ; sub_1958980+62_p ...
+
+var_4 = dword ptr -4
+arg_0 = dword ptr 8
+
+ push ebp
+ mov ebp, esp
+ push ecx
+ mov edx, [ebp+arg_0]
+ mov eax, edx
+ shr eax, 9
+ mov [ebp+var_4], ecx
+ test edx, 1FFh
+ jnz short loc_1959F73
+ mov ecx, [ecx+58h]
+ mov eax, [ecx+eax*4]
+ mov esp, ebp
+ pop ebp
+ retn 4
+; ---------------------------------------------------------------------------
+
+loc_1959F73: ; CODE XREF: sub_1959F50+15_j
+ push ebx
+ push esi
+ mov esi, [ecx+58h]
+ lea esi, [esi+eax*4]
+ mov eax, [esi]
+ push edi
+ mov edi, [esi+4]
+ shr eax, 9
+ add edi, 1FFh
+ shr edi, 9
+ lea esi, [eax+0Ah]
+ cmp esi, edi
+ jb short loc_1959FAD
+ mov edi, [ecx+28h]
+ lea esi, [eax+eax*2+3]
+ cmp edx, [edi+esi*4]
+ lea esi, [edi+esi*4]
+ jb short loc_1959FD4
+
+loc_1959FA3: ; CODE XREF: sub_1959F50+59j
+ add esi, 0Ch
+ inc eax
+ cmp edx, [esi]
+ jnb short loc_1959FA3
+ jmp short loc_1959FD4
+; ---------------------------------------------------------------------------
+
+loc_1959FAD: ; CODE XREF: sub_1959F50+42_j
+ lea esi, [eax+1]
+ cmp esi, edi
+ jnb short loc_1959FD4
+ mov ecx, [ecx+28h]
+
+loc_1959FB7: ; CODE XREF: sub_1959F50+7Fj
+ lea esi, [edi+eax]
+ shr esi, 1
+ lea ebx, [esi+esi*2]
+ cmp edx, [ecx+ebx*4]
+ jnb short loc_1959FC8
+ mov edi, esi
+ jmp short loc_1959FCA
+; ---------------------------------------------------------------------------
+
+loc_1959FC8: ; CODE XREF: sub_1959F50+72_j
+ mov eax, esi
+
+loc_1959FCA: ; CODE XREF: sub_1959F50+76_j
+ lea esi, [eax+1]
+ cmp esi, edi
+ jb short loc_1959FB7
+ mov ecx, [ebp+var_4]
+
+loc_1959FD4: ; CODE XREF: sub_1959F50+51_j
+ ; sub_1959F50+5B_j ...
+ mov edi, [ecx+28h]
+ lea esi, [eax+eax*2]
+ sub edx, [edi+esi*4]
+ shl eax, 4
+ lea esi, [edi+esi*4]
+ mov edi, eax
+ mov eax, [esi+4]
+ mov ebx, eax
+ shr ebx, 17h
+ cmp edx, ebx
+ jnb short loc_195A026
+ mov esi, eax
+ shr esi, 7
+ and esi, 0FFh
+ cmp edx, esi
+ jnb short loc_195A00E
+ and eax, 7Fh
+ cmp edx, eax
+ jb short loc_195A066
+ add edi, 2
+ sub edx, eax
+ jmp short loc_195A066
+; ---------------------------------------------------------------------------
+
+loc_195A00E: ; CODE XREF: sub_1959F50+AE_j
+ shr eax, 0Fh
+ and eax, 0FFh
+ cmp edx, eax
+ jnb short loc_195A01F
+ add edi, 4
+ jmp short loc_195A064
+; ---------------------------------------------------------------------------
+
+loc_195A01F: ; CODE XREF: sub_1959F50+C8_j
+ add edi, 6
+ sub edx, eax
+ jmp short loc_195A066
+; ---------------------------------------------------------------------------
+
+loc_195A026: ; CODE XREF: sub_1959F50+9F_j
+ mov esi, [esi+8]
+ mov eax, esi
+ shr eax, 9
+ and eax, 1FFh
+ cmp edx, eax
+ jnb short loc_195A04D
+ and esi, 1FFh
+ cmp edx, esi
+ jnb short loc_195A048
+ add edi, 8
+ sub edx, ebx
+ jmp short loc_195A066
+; ---------------------------------------------------------------------------
+
+loc_195A048: ; CODE XREF: sub_1959F50+EF_j
+ add edi, 0Ah
+ jmp short loc_195A064
+; ---------------------------------------------------------------------------
+
+loc_195A04D: ; CODE XREF: sub_1959F50+E5_j
+ shr esi, 12h
+ and esi, 1FFh
+ cmp edx, esi
+ jnb short loc_195A061
+ add edi, 0Ch
+ sub edx, eax
+ jmp short loc_195A066
+; ---------------------------------------------------------------------------
+
+loc_195A061: ; CODE XREF: sub_1959F50+108_j
+ add edi, 0Eh
+
+loc_195A064: ; CODE XREF: sub_1959F50+CD_j
+ ; sub_1959F50+FB_j
+ sub edx, esi
+
+loc_195A066: ; CODE XREF: sub_1959F50+B5_j
+ ; sub_1959F50+BC_j ...
+ mov ebx, [ecx+8]
+ mov esi, [ebx+edi*4]
+ mov eax, esi
+ shr eax, 1
+ and eax, 55555555h
+ mov ecx, esi
+ and ecx, 55555555h
+ add eax, ecx
+ mov ecx, eax
+ shr ecx, 2
+ and eax, 33333333h
+ and ecx, 33333333h
+ add ecx, eax
+ mov eax, ecx
+ shr eax, 4
+ and ecx, 0F0F0F0Fh
+ and eax, 0F0F0F0Fh
+ add eax, ecx
+ imul eax, 1010101h
+ mov ecx, eax
+ shr ecx, 18h
+ cmp edx, ecx
+ jb short loc_195A0F6
+ mov esi, [ebx+edi*4+4]
+ sub edx, ecx
+ inc edi
+ mov eax, esi
+ shr eax, 1
+ and eax, 55555555h
+ mov ecx, esi
+ and ecx, 55555555h
+ add eax, ecx
+ mov ecx, eax
+ shr ecx, 2
+ and eax, 33333333h
+ and ecx, 33333333h
+ add ecx, eax
+ mov eax, ecx
+ shr eax, 4
+ and eax, 0F0F0F0Fh
+ and ecx, 0F0F0F0Fh
+ add eax, ecx
+ imul eax, 1010101h
+
+loc_195A0F6: ; CODE XREF: sub_1959F50+160_j
+ mov ecx, eax
+ shr ecx, 8
+ and ecx, 0FFh
+ shl edi, 5
+ cmp edx, ecx
+ jnb short loc_195A119
+ and eax, 0FFh
+ cmp edx, eax
+ jb short loc_195A137
+ add edi, 8
+ shr esi, 8
+ jmp short loc_195A135
+; ---------------------------------------------------------------------------
+
+loc_195A119: ; CODE XREF: sub_1959F50+1B6_j
+ shr eax, 10h
+ and eax, 0FFh
+ cmp edx, eax
+ jnb short loc_195A12F
+ add edi, 10h
+ shr esi, 10h
+ sub edx, ecx
+ jmp short loc_195A137
+; ---------------------------------------------------------------------------
+
+loc_195A12F: ; CODE XREF: sub_1959F50+1D3_j
+ add edi, 18h
+ shr esi, 18h
+
+loc_195A135: ; CODE XREF: sub_1959F50+1C7_j
+ sub edx, eax
+
+loc_195A137: ; CODE XREF: sub_1959F50+1BF_j
+ ; sub_1959F50+1DD_j
+ and esi, 0FFh
+ shl edx, 8
+ movzx eax, ds:table_1BA1818[esi+edx]
+ add eax, edi
+ pop edi
+ pop esi
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 4
+sub_1959F50 endp
+
+; ---------------------------------------------------------------------------
+
+; =============== S U B R O U T I N E =======================================
+
+; Attributes: bp-based frame
+
+sub_1957B80 proc near ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+5E_p
+ ; TFileNameDatabase__CheckNextPathFragment+180_p ...
+
+pStruct40 = dword ptr -4
+arg_0 = dword ptr 8
+arg_4 = dword ptr 0Ch
+
+ push ebp
+ mov ebp, esp
+ push ecx
+ push ebx
+ mov ebx, [ebp+arg_0]
+ mov eax, [ebx+18h]
+ push esi
+ push edi
+ mov edi, [ebp+arg_4]
+ mov esi, ecx
+ mov [ebp+pStruct40], eax
+
+loc_1957B95: ; CODE XREF: sub_1957B80+9Fj
+ ; sub_1957B80+156j
+ mov eax, [esi+TFileNameDatabase.NameFragIndexMask]
+ and eax, edi
+ lea ecx, [eax+eax*2]
+ mov eax, [esi+TFileNameDatabase.NameFragTable.ItemArray]
+ add ecx, ecx
+ add ecx, ecx
+ add eax, ecx
+ mov [ebp+arg_4], ecx
+ cmp edi, [eax+4]
+ jnz short loc_1957C30
+ mov edx, [eax+8]
+ mov edi, edx
+ and edi, 0FFFFFF00h
+ cmp edi, 0FFFFFF00h
+ jz short loc_1957BEE
+ mov ecx, [esi+TFileNameDatabase.NextDB.pDatabase]
+ push edx
+ push ebx
+ test ecx, ecx
+ jz short loc_1957BDA
+ call sub_1957B80
+ jmp short loc_1957BE5
+; ---------------------------------------------------------------------------
+
+loc_1957BDA: ; CODE XREF: sub_1957B80+51_j
+ lea ecx, [esi+TFileNameDatabase.IndexStruct_174]
+ call TNameIndexStruct__CheckNameFragment
+
+loc_1957BE5: ; CODE XREF: sub_1957B80+58_j
+ test al, al
+ jz short loc_1957C25
+ mov ecx, [ebp+arg_4]
+ jmp short loc_1957C05
+; ---------------------------------------------------------------------------
+
+loc_1957BEE: ; CODE XREF: sub_1957B80+45_j
+ mov edx, [ebp+pStruct40]
+ mov edi, [edx+34h]
+ mov edx, [ebx]
+ mov al, [eax+8]
+ cmp al, [edi+edx]
+ jnz short loc_1957C25
+ mov edx, [ebp+pStruct40]
+ inc edi
+ mov [edx+34h], edi
+
+loc_1957C05: ; CODE XREF: sub_1957B80+6C_j
+ mov eax, [esi+200h]
+ mov edi, [ecx+eax]
+ test edi, edi
+ jz loc_1957CDB
+ mov ecx, [ebp+pStruct40]
+ mov edx, [ecx+34h]
+ cmp edx, [ebx+4]
+ jb loc_1957B95
+
+loc_1957C25: ; CODE XREF: sub_1957B80+67_j
+ ; sub_1957B80+7C_j ...
+ pop edi
+ pop esi
+ xor al, al
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 8
+; ---------------------------------------------------------------------------
+
+loc_1957C30: ; CODE XREF: sub_1957B80+32_j
+ mov edx, [esi+0D8h]
+ mov ecx, edi
+ and ecx, 1Fh
+ mov ebx, 1
+ shl ebx, cl
+ mov eax, edi
+ shr eax, 5
+ test [edx+eax*4], ebx
+ jz short loc_1957C8E
+ cmp dword ptr [esi+1F4h], 0
+ push edi
+ mov ecx, esi
+ jz short loc_1957C73
+ call sub_1957350
+ mov ecx, [esi+1F4h]
+ mov ebx, [ebp+arg_0]
+ push eax
+ push ebx
+ test ecx, ecx
+ jz short loc_1957C7D
+ call sub_1957B80
+ jmp short loc_1957C88
+; ---------------------------------------------------------------------------
+
+loc_1957C73: ; CODE XREF: sub_1957B80+D6_j
+ call sub_1957350
+ mov ebx, [ebp+arg_0]
+ push eax
+ push ebx
+
+loc_1957C7D: ; CODE XREF: sub_1957B80+EA_j
+ lea ecx, [esi+174h]
+ call TNameIndexStruct__CheckNameFragment
+
+loc_1957C88: ; CODE XREF: sub_1957B80+F1_j
+ test al, al
+ jz short loc_1957C25
+ jmp short loc_1957CB2
+; ---------------------------------------------------------------------------
+
+loc_1957C8E: ; CODE XREF: sub_1957B80+CA_j
+ mov eax, [ebp+pStruct40]
+ mov ecx, [esi+140h]
+ mov ebx, [ebp+arg_0]
+ mov eax, [eax+34h]
+ mov edx, [ebx]
+ mov cl, [edi+ecx]
+ cmp cl, [eax+edx]
+ jnz loc_1957C25
+ mov edx, [ebp+pStruct40]
+ inc eax
+ mov [edx+34h], eax
+
+loc_1957CB2: ; CODE XREF: sub_1957B80+10C_j
+ cmp edi, [esi+214h]
+ jbe short loc_1957CDB
+ mov eax, [ebp+pStruct40]
+ mov ecx, [eax+34h]
+ cmp ecx, [ebx+4]
+ jnb loc_1957C25
+ push edi
+ mov ecx, esi
+ call sub_1959F50
+ sub eax, edi
+ lea edi, [eax-1]
+ jmp loc_1957B95
+; ---------------------------------------------------------------------------
+
+loc_1957CDB: ; CODE XREF: sub_1957B80+90_j
+ ; sub_1957B80+138_j
+ pop edi
+ pop esi
+ mov al, 1
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 8
+sub_1957B80 endp
+
+
+; =============== S U B R O U T I N E =======================================
+
+; Attributes: bp-based frame
+
+sub_19573D0 proc near ; CODE XREF: TFileNameDatabase__sub_1959460+1D9p
+
+arg_0 = dword ptr 8
+arg_4 = dword ptr 0Ch
+
+ push ebp
+ mov ebp, esp
+ push esi
+ mov esi, ecx
+ mov edx, [esi+TFileNameDatabase.FrgmDist_HiBits.BitsPerEntry]
+ mov eax, edx
+ imul eax, [ebp+arg_4]
+ mov ecx, eax
+ and eax, 1Fh
+ add edx, eax
+ shr ecx, 5
+ cmp edx, 20h
+ mov edx, [esi+TFileNameDatabase.FrgmDist_HiBits.ItemArray]
+ ja short loc_1957400
+ mov edx, [edx+ecx*4]
+ mov ecx, eax
+ shr edx, cl
+ jmp short loc_1957419
+; ---------------------------------------------------------------------------
+
+loc_1957400: ; CODE XREF: sub_19573D0+25j
+ push edi
+ lea edi, [edx+ecx*4]
+ mov edx, [edi+4]
+ mov edi, [edi]
+ mov ecx, 20h
+ sub ecx, eax
+ shl edx, cl
+ mov ecx, eax
+ shr edi, cl
+ or edx, edi
+ pop edi
+
+loc_1957419: ; CODE XREF: sub_19573D0+2Ej
+ and edx, [esi+TFileNameDatabase.FrgmDist_HiBits.EntryBitMask]
+ mov eax, [esi+TFileNameDatabase.FrgmDist_LoBits.ItemArray]
+ mov ecx, [ebp+arg_0]
+ movzx eax, byte ptr [eax+ecx]
+ shl edx, 8
+ or eax, edx
+ pop esi
+ pop ebp
+ retn 8
+sub_19573D0 endp
+
+; ---------------------------------------------------------------------------
+
+; =============== S U B R O U T I N E =======================================
+
+; Attributes: bp-based frame
+
+TFileNameDatabase__CheckNextPathFragment proc near ; CODE XREF: TFileNameDatabase__FindFileInDatabase+25p
+
+var_C = dword ptr -0Ch
+CollisionIndex = dword ptr -8
+var_4 = dword ptr -4
+pStruct1C = dword ptr 8
+
+ push ebp
+ mov ebp, esp
+ mov edx, [ebp+pStruct1C]
+ sub esp, 0Ch
+ push ebx
+ mov ebx, [edx+TMndxFindResult.szSearchMask]
+ push esi
+ push edi
+ mov edi, [edx+TMndxFindResult.pStruct40]
+ mov eax, [edi+TStruct40.CharIndex]
+ movzx eax, byte ptr [eax+ebx] ; EAX = szPathName[nCharIndex]
+ mov esi, ecx
+ mov ecx, [edi+TStruct40.HashValue]
+ mov ebx, ecx
+ shl ebx, 5
+ xor eax, ebx
+ xor eax, ecx
+ and eax, [esi+TFileNameDatabase.NameFragIndexMask] ; (000000ff) - Mask value
+ lea ebx, [eax+eax*2]
+ mov eax, [esi+TFileNameDatabase.NameFragTable.ItemArray] ; (7f3ae128) - Array of 256 triplets
+ add ebx, ebx
+ add ebx, ebx ; EBX = Offset of the triplet we want to know
+ cmp ecx, [eax+ebx+TRIPLET.BitIndex]
+ jnz short loc_1957A0E
+ mov eax, [eax+ebx+TRIPLET.Distance]
+ mov ecx, eax
+ and ecx, 0FFFFFF00h
+ cmp ecx, 0FFFFFF00h
+ jz short loc_19579EF
+ mov ecx, [esi+TFileNameDatabase.NextDB.pDatabase]
+ push eax
+ push edx
+ test ecx, ecx
+ jz short loc_19579D5
+ call sub_1957B80
+ jmp short loc_19579E0
+; ---------------------------------------------------------------------------
+
+loc_19579D5: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+5C_j
+ lea ecx, [esi+TFileNameDatabase.IndexStruct_174]
+ call TNameIndexStruct__CheckNameFragment
+
+loc_19579E0: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+63_j
+ test al, al
+ jnz short loc_19579F6
+
+loc_19579E4: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+C1j
+ ; TFileNameDatabase__CheckNextPathFragment+1A4j
+ pop edi
+ pop esi
+ xor al, al
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 4
+; ---------------------------------------------------------------------------
+
+loc_19579EF: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+50_j
+ mov eax, [edi+TStruct40.CharIndex] ; nCharIndex = nCharIndex + 1
+ inc eax
+ mov [edi+TStruct40.CharIndex], eax
+
+loc_19579F6: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+72_j
+ mov edx, [esi+TFileNameDatabase.NameFragTable.ItemArray] ; EDX = pTripletArray
+ mov eax, [edx+ebx+TRIPLET.NextKey]
+ mov [edi+TStruct40.HashValue], eax
+
+loc_1957A03: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+198j
+ pop edi
+ pop esi
+ mov al, 1
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 4
+; ---------------------------------------------------------------------------
+
+loc_1957A0E: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+3C_j
+ push ecx ; dwKey
+ mov ecx, esi ; pDatabase
+ call TArchiveDatabase__sub_1959CB0
+ mov ebx, [esi+TFileNameDatabase.Struct68_00.ItemIsPresent.ItemArray]
+ inc eax
+ mov ecx, eax
+ and ecx, 1Fh
+ mov edx, 1
+ shl edx, cl
+ mov ecx, eax
+ shr ecx, 5
+ mov [ebp+CollisionIndex], eax
+ test [ebx+ecx*4], edx
+ jz short loc_19579E4
+ sub eax, [edi+TStruct40.HashValue]
+ mov [ebp+var_4], 0FFFFFFFFh
+ dec eax
+ mov [edi+TStruct40.HashValue], eax
+
+loc_1957A41: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+1E1j
+ mov eax, [edi+TStruct40.HashValue]
+ mov ebx, [esi+TFileNameDatabase.Struct68_D0.ItemIsPresent.ItemArray]
+ mov ecx, eax
+ and ecx, 1Fh
+ mov edx, 1
+ shl edx, cl
+ mov ecx, eax
+ shr ecx, 5
+ test [ebx+ecx*4], edx
+ jz loc_1957B1C
+ mov ecx, [ebp+var_4]
+ cmp ecx, 0FFFFFFFFh
+ jnz short loc_1957A7F
+ push eax
+ lea ecx, [esi+TFileNameDatabase.Struct68_D0]
+ call TSparseArray__GetItemValue
+ mov ecx, eax
+ mov [ebp+var_4], eax
+ jmp short loc_1957A83
+; ---------------------------------------------------------------------------
+
+loc_1957A7F: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+FA_j
+ inc ecx
+ mov [ebp+var_4], ecx
+
+loc_1957A83: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+10D_j
+ mov edx, [edi+TStruct40.CharIndex]
+ mov [ebp+var_C], edx
+ mov edx, [esi+TFileNameDatabase.FrgmDist_HiBits.BitsPerEntry]
+ mov eax, edx
+ imul eax, ecx
+ mov ecx, eax
+ and eax, 1Fh
+ add edx, eax
+ shr ecx, 5
+ cmp edx, 20h
+ mov edx, [esi+TFileNameDatabase.FrgmDist_HiBits.ItemArray]
+ ja short loc_1957AB2
+ mov edx, [edx+ecx*4]
+ mov ecx, eax
+ shr edx, cl
+ jmp short loc_1957AC9
+; ---------------------------------------------------------------------------
+
+loc_1957AB2: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+137_j
+ lea ebx, [edx+ecx*4]
+ mov edx, [ebx+4]
+ mov ebx, [ebx]
+ mov ecx, 20h
+ sub ecx, eax
+ shl edx, cl
+ mov ecx, eax
+ shr ebx, cl
+ or edx, ebx
+
+loc_1957AC9: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+140_j
+ mov ecx, [esi+TFileNameDatabase.FrgmDist_LoBits.ItemArray]
+ and edx, [esi+TFileNameDatabase.FrgmDist_HiBits.EntryBitMask]
+ mov eax, [edi+TStruct40.HashValue]
+ movzx eax, byte ptr [ecx+eax]
+ mov ecx, [esi+TFileNameDatabase.NextDB.pDatabase]
+ shl edx, 8
+ or eax, edx
+ push eax
+ test ecx, ecx
+ jz short loc_1957AF7
+ mov edx, [ebp+pStruct1C]
+ push edx
+ call sub_1957B80
+ jmp short loc_1957B06
+; ---------------------------------------------------------------------------
+
+loc_1957AF7: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+17A_j
+ mov eax, [ebp+pStruct1C]
+ push eax
+ lea ecx, [esi+TFileNameDatabase.IndexStruct_174]
+ call TNameIndexStruct__CheckNameFragment
+
+loc_1957B06: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+185_j
+ test al, al
+ jnz loc_1957A03
+ mov ecx, [ebp+var_C]
+ cmp [edi+TStruct40.CharIndex], ecx
+ jnz loc_19579E4
+ jmp short loc_1957B32
+; ---------------------------------------------------------------------------
+
+loc_1957B1C: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+EE_j
+ mov edx, [esi+TFileNameDatabase.FrgmDist_LoBits.ItemArray]
+ mov ebx, [ebp+pStruct1C]
+ mov ecx, [edi+TStruct40.CharIndex]
+ mov ebx, [ebx+TMndxFindResult.szSearchMask]
+ mov dl, [eax+edx]
+ cmp dl, [ecx+ebx]
+ jz short loc_1957B62
+
+loc_1957B32: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+1AA_j
+ mov eax, [ebp+CollisionIndex]
+ inc [edi+TStruct40.HashValue]
+ inc eax
+ mov ecx, eax
+ and ecx, 1Fh
+ mov edx, 1
+ shl edx, cl
+ mov ecx, [esi+TFileNameDatabase.Struct68_00.ItemIsPresent.ItemArray]
+ mov [ebp+CollisionIndex], eax
+ shr eax, 5
+ test [ecx+eax*4], edx
+ jnz loc_1957A41
+ pop edi
+ pop esi
+ xor al, al
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 4
+; ---------------------------------------------------------------------------
+
+loc_1957B62: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+1C0_j
+ mov eax, 1
+ add [edi+TStruct40.CharIndex], eax
+ pop edi
+ pop esi
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 4
+TFileNameDatabase__CheckNextPathFragment endp
+
+
+TFileNameDatabase__FindFileInDatabase proc near
+ ; CODE XREF: MAR_FILE__FindFileInDatabase+2D_p
+
+pThis = dword ptr -4
+pStruct1C = dword ptr 8
+
+ push ebp ; ecx = Pointer to ARCHIVE_DATABASE
+ mov ebp, esp
+ push ecx
+ push ebx
+ push esi
+ mov esi, [ebp+pStruct1C]
+ xor eax, eax
+ push edi
+ mov edi, [esi+TMndxFindResult.pStruct40]
+ mov ebx, ecx
+ mov [edi+TStruct40.HashValue], eax
+ mov [edi+TStruct40.CharIndex], eax
+ mov [edi+TStruct40.SearchPhase], eax
+ mov [ebp+pThis], ebx
+ cmp [esi+TMndxFindResult.cchSearchMask], eax
+ jbe short loc_1957F26
+
+label_process_all_characters: ; CODE XREF: TFileNameDatabase__FindFileInDatabase+34j
+ push esi
+ mov ecx, ebx
+ call TFileNameDatabase__CheckNextPathFragment
+ test al, al
+ jz short label_return_false
+ mov eax, [edi+TStruct40.CharIndex]
+ cmp eax, [esi+TMndxFindResult.cchSearchMask]
+ jb short label_process_all_characters
+
+loc_1957F26: ; CODE XREF: TFileNameDatabase__FindFileInDatabase+20_j
+ mov ecx, [edi+TStruct40.HashValue]
+ mov eax, [ebx+TFileNameDatabase.FileNameIndexes.ItemIsPresent.ItemArray]
+ mov edx, ecx
+ and ecx, 1Fh
+ mov ebx, 1
+ shl ebx, cl
+ shr edx, 5
+ test [eax+edx*4], ebx
+ jz short label_return_false
+ mov ecx, [esi+TMndxFindResult.szSearchMask]
+ mov eax, [esi+TMndxFindResult.cchSearchMask]
+ mov [esi+TMndxFindResult.szFoundPath], ecx
+ mov ecx, [ebp+pThis]
+ mov [esi+TMndxFindResult.cchFoundPath], eax
+ mov edi, [edi+TStruct40.HashValue]
+ push edi
+ add ecx, TFileNameDatabase.FileNameIndexes
+ call TSparseArray__GetItemValue
+ pop edi
+ mov [esi+TMndxFindResult.FileNameIndex], eax
+ pop esi
+ mov al, 1
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 4
+; ---------------------------------------------------------------------------
+
+label_return_false: ; CODE XREF: TFileNameDatabase__FindFileInDatabase+2C_j
+ ; TFileNameDatabase__FindFileInDatabase+4E_j
+ pop edi
+ pop esi
+ xor al, al
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 4
+TFileNameDatabase__FindFileInDatabase endp
+
+
+; =============== S U B R O U T I N E =======================================
+
+; Attributes: bp-based frame
+
+TGenericArray__SetMaxItems_BYTE proc near ; CODE XREF: sub_19582E0+2Cp
+ ; TStruct40__InitSearchBuffers+2Cp ...
+
+ByteCount = dword ptr 8
+
+ push ebp
+ mov ebp, esp
+ push ebx
+ mov ebx, [ebp+ByteCount]
+ push esi
+ push edi
+ push offset unk_53ABE00
+ push ebx
+ mov esi, ecx
+ call j_operator_new_safe
+ xor ecx, ecx
+ add esp, 8
+ mov edi, eax
+ cmp [esi+TGenericArray.ItemCount], ecx
+ jbe short loc_19575D7
+
+loc_19575C2: ; CODE XREF: TGenericArray__SetMaxItems_BYTE+35j
+ lea edx, [ecx+edi]
+ test edx, edx
+ jz short loc_19575D1
+ mov eax, [esi+TGenericArray.field_4]
+ mov al, [ecx+eax]
+ mov [edx], al
+
+loc_19575D1: ; CODE XREF: TGenericArray__SetMaxItems_BYTE+27j
+ inc ecx
+ cmp ecx, [esi+TGenericArray.ItemCount]
+ jb short loc_19575C2
+
+loc_19575D7: ; CODE XREF: TGenericArray__SetMaxItems_BYTE+20j
+ mov eax, [esi+TGenericArray.DataBuffer]
+ push eax
+ mov [esi+TGenericArray.DataBuffer], edi
+ mov [esi+TGenericArray.field_4], edi
+ mov [esi+TGenericArray.ItemArray], edi
+ mov [esi+TGenericArray.MaxItemCount], ebx
+ call operator_delete
+ add esp, 4
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+ retn 4
+TGenericArray__SetMaxItems_BYTE endp
+
+; =============== S U B R O U T I N E =======================================
+
+; Attributes: bp-based frame
+
+TGenericArray__SetMaxItems_STRUCT14 proc near
+ ; CODE XREF: TGenericArray__InsertItem_STRUCT14+2Cp
+ ; TGenericArray__sub_19583A0+2Dp ...
+
+var_4 = dword ptr -4
+ItemCount = dword ptr 8
+
+ push ebp
+ mov ebp, esp
+ push ecx
+ push esi
+ push edi
+ mov edi, [ebp+ItemCount]
+ lea eax, [edi+edi*4] ; EAX = (ItemCount * 5)
+ add eax, eax ; EAX = (ItemCount * 10)
+ add eax, eax ; EAX = (ItemCount * 20)
+ push offset unk_53ABE00
+ push eax
+ mov esi, ecx
+ call j_operator_new_safe
+ mov ecx, eax
+ xor eax, eax
+ add esp, 8
+ mov [ebp+var_4], ecx
+ cmp [esi+0Ch], eax
+ jbe short loc_195766A
+ xor edi, edi
+ mov edx, ecx
+ push ebx
+
+loc_1957631: ; CODE XREF: TGenericArray__SetMaxItems_STRUCT14+64j
+ test edx, edx
+ jz short loc_195765A
+ mov ecx, [esi+4]
+ mov ebx, [ecx+edi]
+ add ecx, edi
+ mov [edx], ebx
+ mov ebx, [ecx+4]
+ mov [edx+4], ebx
+ mov ebx, [ecx+8]
+ mov [edx+8], ebx
+ mov ebx, [ecx+0Ch]
+ mov [edx+0Ch], ebx
+ mov ecx, [ecx+10h]
+ mov [edx+10h], ecx
+ mov ecx, [ebp+var_4]
+
+loc_195765A: ; CODE XREF: TGenericArray__SetMaxItems_STRUCT14+33j
+ inc eax
+ add edi, 14h
+ add edx, 14h
+ cmp eax, [esi+0Ch]
+ jb short loc_1957631
+ mov edi, [ebp+ItemCount]
+ pop ebx
+
+loc_195766A: ; CODE XREF: TGenericArray__SetMaxItems_STRUCT14+2Aj
+ mov eax, [esi+TGenericArray.DataBuffer]
+ push eax
+ mov [esi+TGenericArray.DataBuffer], ecx
+ mov [esi+TGenericArray.field_4], ecx
+ mov [esi+TGenericArray.ItemArray], ecx
+ mov [esi+TGenericArray.MaxItemCount], edi
+ call operator_delete
+ add esp, 4
+ pop edi
+ pop esi
+ mov esp, ebp
+ pop ebp
+ retn 4
+TGenericArray__SetMaxItems_STRUCT14 endp
+
+; =============== S U B R O U T I N E =======================================
+
+; Attributes: bp-based frame
+
+TGenericArray__sub_19583A0 proc near ; CODE XREF: TStruct40__InitSearchBuffers+35p
+
+NewItemCount = dword ptr 8
+
+ push ebp
+ mov ebp, esp
+ push esi
+ mov esi, ecx
+ mov eax, [esi+TGenericArray.MaxItemCount]
+ push edi
+ mov edi, [ebp+NewItemCount]
+ cmp edi, eax
+ jbe short loc_19583D2
+ mov edx, edi
+ shr edx, 1
+ mov ecx, edi
+ cmp eax, edx
+ jbe short loc_19583CA
+ mov ecx, 0CCCCCCCh
+ cmp eax, 6666666h
+ ja short loc_19583CA
+ lea ecx, [eax+eax]
+
+loc_19583CA: ; CODE XREF: TGenericArray__sub_19583A0+19j
+ ; TGenericArray__sub_19583A0+25j
+ push ecx
+ mov ecx, esi
+ call TGenericArray__SetMaxItems_STRUCT14
+
+loc_19583D2: ; CODE XREF: TGenericArray__sub_19583A0+Fj
+ mov eax, [esi+TGenericArray.ItemCount]
+ cmp eax, edi
+ jnb short loc_1958410
+ lea ecx, [eax+eax*4]
+ add ecx, ecx
+ mov edx, edi
+ push ebx
+ add ecx, ecx
+ sub edx, eax
+ or ebx, 0FFFFFFFFh
+
+loc_19583E8: ; CODE XREF: TGenericArray__sub_19583A0+6Dj
+ mov eax, [esi+TGenericArray.field_4]
+ add eax, ecx
+ jz short loc_1958409
+ mov dword ptr [eax], 0
+ mov dword ptr [eax+4], 0
+ mov dword ptr [eax+8], 0
+ mov [eax+0Ch], ebx
+ mov [eax+10h], ebx
+
+loc_1958409: ; CODE XREF: TGenericArray__sub_19583A0+4Dj
+ add ecx, 14h
+ dec edx
+ jnz short loc_19583E8
+ pop ebx
+
+loc_1958410: ; CODE XREF: TGenericArray__sub_19583A0+37j
+ mov [esi+TGenericArray.ItemCount], edi
+ pop edi
+ pop esi
+ pop ebp
+ retn 4
+TGenericArray__sub_19583A0 endp
+
+; =============== S U B R O U T I N E =======================================
+
+
+TStruct40__InitSearchBuffers proc near ; CODE XREF: TFileNameDatabase__sub_1959460+2Bp
+ push ebx
+ push esi
+ mov esi, ecx
+ mov eax, [esi+TStruct40.array_00.MaxItemCount]
+ xor ebx, ebx
+ push edi
+ mov [esi+TStruct40.array_00.ItemCount], ebx
+ cmp eax, 40h
+ jnb short loc_19586E1
+ lea ecx, [ebx+40h] ; ECX = 0x40
+ cmp eax, 20h
+ jbe short loc_19586D9
+ cmp eax, 7FFFFFFFh
+ jbe short loc_19586D6
+ or ecx, 0FFFFFFFFh
+ jmp short loc_19586D9
+; ---------------------------------------------------------------------------
+
+loc_19586D6: ; CODE XREF: TStruct40__InitSearchBuffers+1Fj
+ lea ecx, [eax+eax]
+
+loc_19586D9: ; CODE XREF: TStruct40__InitSearchBuffers+18j
+ ; TStruct40__InitSearchBuffers+24j
+ push ecx
+ mov ecx, esi
+ call TGenericArray__SetMaxItems_BYTE
+
+loc_19586E1: ; CODE XREF: TStruct40__InitSearchBuffers+10j
+ push ebx
+ lea ecx, [esi+TStruct40.array_18]
+ call TGenericArray__sub_19583A0
+ mov eax, [esi+TStruct40.array_18.MaxItemCount]
+ cmp eax, 4
+ jnb short loc_1958714
+ mov ecx, 4
+ cmp eax, 2
+ jbe short loc_195870B
+ mov ecx, 0CCCCCCCh
+ cmp eax, 6666666h
+ ja short loc_195870B
+ lea ecx, [eax+eax]
+
+loc_195870B: ; CODE XREF: TStruct40__InitSearchBuffers+4Aj
+ ; TStruct40__InitSearchBuffers+56j
+ push ecx
+ lea ecx, [esi+TStruct40.array_18]
+ call TGenericArray__SetMaxItems_STRUCT14
+
+loc_1958714: ; CODE XREF: TStruct40__InitSearchBuffers+40j
+ pop edi
+ mov [esi+TStruct40.HashValue], ebx
+ mov [esi+TStruct40.CharIndex], ebx
+ mov [esi+TStruct40.ItemCount], ebx
+ mov [esi+TStruct40.SearchPhase], 2
+ pop esi
+ pop ebx
+ retn
+TStruct40__InitSearchBuffers endp
+
+; =============== S U B R O U T I N E =======================================
+
+; Attributes: bp-based frame
+
+TGenericArray__InsertItem_STRUCT14 proc near
+ ; CODE XREF: TFileNameDatabase__sub_1959460+73p
+
+pStruct14 = dword ptr 8
+
+ push ebp
+ mov ebp, esp
+ push esi
+ mov esi, ecx
+ mov eax, [esi+TGenericArray.ItemCount]
+ mov ecx, [esi+TGenericArray.MaxItemCount]
+ inc eax
+ cmp eax, ecx
+ jbe short loc_1958361
+ mov edx, eax
+ shr eax, 1
+ cmp ecx, eax
+ jbe short loc_1958359
+ mov edx, 0CCCCCCCh
+ cmp ecx, 6666666h
+ ja short loc_1958359
+ lea edx, [ecx+ecx]
+
+loc_1958359: ; CODE XREF: TGenericArray__InsertItem_STRUCT14+17j
+ ; TGenericArray__InsertItem_STRUCT14+24j
+ push edx
+ mov ecx, esi
+ call TGenericArray__SetMaxItems_STRUCT14
+
+loc_1958361: ; CODE XREF: TGenericArray__InsertItem_STRUCT14+Fj
+ mov eax, [esi+TGenericArray.ItemCount]
+ mov ecx, [esi+TGenericArray.field_4]
+ lea eax, [eax+eax*4]
+ lea eax, [ecx+eax*4]
+ test eax, eax
+ jz short loc_1958390
+ mov ecx, [ebp+pStruct14]
+ mov edx, [ecx+TStruct14.HashValue]
+ mov [eax+TStruct14.HashValue], edx
+ mov edx, [ecx+TStruct14.field_4]
+ mov [eax+TStruct14.field_4], edx
+ mov edx, [ecx+TStruct14.field_8]
+ mov [eax+TStruct14.field_8], edx
+ mov edx, [ecx+TStruct14.field_C]
+ mov [eax+TStruct14.field_C], edx
+ mov ecx, [ecx+TStruct14.field_10]
+ mov [eax+TStruct14.field_10], ecx
+
+loc_1958390: ; CODE XREF: TGenericArray__InsertItem_STRUCT14+3Fj
+ inc [esi+TGenericArray.ItemCount]
+ pop esi
+ pop ebp
+ retn 4
+TGenericArray__InsertItem_STRUCT14 endp
+
+; =============== S U B R O U T I N E =======================================
+
+; Attributes: bp-based frame
+
+CopyNameFragment proc near ; CODE XREF: sub_1958980+DAp
+ ; sub_1958D70+6Dp ...
+
+pThis = dword ptr -4
+pStruct1C = dword ptr 8
+dwDistance = dword ptr 0Ch
+
+ push ebp
+ mov ebp, esp
+ push ecx
+ mov eax, [ebp+pStruct1C]
+ push ebx
+ mov ebx, ecx
+ cmp [ebx+TNameIndexStruct.Struct68.TotalItemCount], 0
+ push esi
+ mov esi, [eax+TMndxFindResult.pStruct40]
+ push edi
+ mov [ebp+pThis], ebx
+ jnz loc_195A4B3
+ mov ebx, [ebx+TNameIndexStruct.NameFragments.ItemArray]
+ add ebx, [ebp+dwDistance]
+ cmp byte ptr [ebx], 0
+ mov [ebp+dwDistance], ebx
+ jz loc_195A55E
+ mov edi, edi
+
+loc_195A420: ; CODE XREF: CopyNameFragment+B4j
+ mov eax, [esi+TStruct40.array_00.ItemCount]
+ mov ecx, [esi+TStruct40.array_00.MaxItemCount]
+ inc eax
+ cmp eax, ecx
+ jbe short loc_195A48E
+ mov ebx, eax
+ shr eax, 1
+ cmp ecx, eax
+ jbe short loc_195A443
+ cmp ecx, 7FFFFFFFh
+ jbe short loc_195A440
+ or ebx, 0FFFFFFFFh
+ jmp short loc_195A443
+; ---------------------------------------------------------------------------
+
+loc_195A440: ; CODE XREF: CopyNameFragment+49j
+ lea ebx, [ecx+ecx]
+
+loc_195A443: ; CODE XREF: CopyNameFragment+41j
+ ; CopyNameFragment+4Ej
+ push offset unk_53ABE00
+ push ebx
+ call j_operator_new_safe
+ xor ecx, ecx
+ add esp, 8
+ mov edi, eax
+ cmp [esi+TStruct40.array_00.ItemCount], ecx
+ jbe short loc_195A475
+ lea ebx, [ebx+0]
+
+loc_195A460: ; CODE XREF: CopyNameFragment+83j
+ lea edx, [ecx+edi]
+ test edx, edx
+ jz short loc_195A46F
+ mov eax, [esi+TStruct40.array_00.field_4]
+ mov al, [ecx+eax]
+ mov [edx], al
+
+loc_195A46F: ; CODE XREF: CopyNameFragment+75j
+ inc ecx
+ cmp ecx, [esi+TStruct40.array_00.ItemCount]
+ jb short loc_195A460
+
+loc_195A475: ; CODE XREF: CopyNameFragment+68j
+ mov eax, [esi+TStruct40.array_00.DataBuffer]
+ push eax
+ mov [esi+TStruct40.array_00.DataBuffer], edi
+ mov [esi+TStruct40.array_00.field_4], edi
+ mov [esi+TStruct40.array_00.ItemArray], edi
+ mov [esi+TStruct40.array_00.MaxItemCount], ebx
+ call operator_delete
+ mov ebx, [ebp+dwDistance]
+ add esp, 4
+
+loc_195A48E: ; CODE XREF: CopyNameFragment+39j
+ mov eax, [esi+TStruct40.array_00.ItemCount]
+ add eax, [esi+TStruct40.array_00.field_4]
+ jz short loc_195A49A
+ mov cl, [ebx]
+ mov [eax], cl
+
+loc_195A49A: ; CODE XREF: CopyNameFragment+A4j
+ inc [esi+TStruct40.array_00.ItemCount]
+ inc ebx
+ cmp byte ptr [ebx], 0
+ mov [ebp+dwDistance], ebx
+ jnz loc_195A420
+ pop edi
+ pop esi
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 8
+; ---------------------------------------------------------------------------
+
+loc_195A4B3: ; CODE XREF: CopyNameFragment+16j
+ ; CopyNameFragment+168j
+ mov eax, [esi+TStruct40.array_00.ItemCount]
+ mov edx, [ebx+TNameIndexStruct.NameFragments.ItemArray]
+ mov edi, [ebp+dwDistance]
+ mov ecx, [esi+TStruct40.array_00.MaxItemCount]
+ add edx, edi
+ inc eax
+ mov [ebp+pStruct1C], edx
+ cmp eax, ecx
+ jbe short loc_195A52C
+ mov ebx, eax
+ shr eax, 1
+ cmp ecx, eax
+ jbe short loc_195A4E1
+ cmp ecx, 7FFFFFFFh
+ jbe short loc_195A4DE
+ or ebx, 0FFFFFFFFh
+ jmp short loc_195A4E1
+; ---------------------------------------------------------------------------
+
+loc_195A4DE: ; CODE XREF: CopyNameFragment+E7j
+ lea ebx, [ecx+ecx]
+
+loc_195A4E1: ; CODE XREF: CopyNameFragment+DFj
+ ; CopyNameFragment+ECj
+ push offset unk_53ABE00
+ push ebx
+ call j_operator_new_safe
+ xor ecx, ecx
+ add esp, 8
+ mov edi, eax
+ cmp [esi+TStruct40.array_00.ItemCount], ecx
+ jbe short loc_195A50D
+
+loc_195A4F8: ; CODE XREF: CopyNameFragment+11Bj
+ lea edx, [ecx+edi]
+ test edx, edx
+ jz short loc_195A507
+ mov eax, [esi+TStruct40.array_00.field_4]
+ mov al, [ecx+eax]
+ mov [edx], al
+
+loc_195A507: ; CODE XREF: CopyNameFragment+10Dj
+ inc ecx
+ cmp ecx, [esi+TStruct40.array_00.ItemCount]
+ jb short loc_195A4F8
+
+loc_195A50D: ; CODE XREF: CopyNameFragment+106j
+ mov eax, [esi+TStruct40.array_00.DataBuffer]
+ push eax
+ mov [esi+TStruct40.array_00.DataBuffer], edi
+ mov [esi+TStruct40.array_00.field_4], edi
+ mov [esi+TStruct40.array_00.ItemArray], edi
+ mov [esi+TStruct40.array_00.MaxItemCount], ebx
+ call operator_delete
+ mov edx, [ebp+pStruct1C]
+ mov edi, [ebp+dwDistance]
+ mov ebx, [ebp+pThis]
+ add esp, 4
+
+loc_195A52C: ; CODE XREF: CopyNameFragment+D7j
+ mov eax, [esi+TStruct40.array_00.ItemCount]
+ add eax, [esi+TStruct40.array_00.field_4]
+ jz short loc_195A538
+ mov cl, [edx]
+ mov [eax], cl
+
+loc_195A538: ; CODE XREF: CopyNameFragment+142j
+ inc [esi+TStruct40.array_00.ItemCount]
+ mov ecx, edi
+ and ecx, 1Fh
+ mov edx, 1
+ shl edx, cl
+ mov ecx, [ebx+TNameIndexStruct.Struct68.ItemIsPresent.ItemArray]
+ mov eax, edi
+ shr eax, 5
+ and edx, [ecx+eax*4]
+ inc edi
+ mov [ebp+dwDistance], edi
+ test edx, edx
+ jz loc_195A4B3
+
+loc_195A55E: ; CODE XREF: CopyNameFragment+28j
+ pop edi
+ pop esi
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 8
+CopyNameFragment endp
+
+; =============== S U B R O U T I N E =======================================
+
+; Attributes: bp-based frame
+
+sub_1958D70 proc near ; CODE XREF: sub_1958980+C9p
+ ; sub_1958D70+59p ...
+
+var_C = dword ptr -0Ch
+var_8 = dword ptr -8
+var_1 = byte ptr -1
+pStruct1C = dword ptr 8
+arg_4 = dword ptr 0Ch
+
+ push ebp
+ mov ebp, esp
+ mov eax, [ebp+pStruct1C]
+ sub esp, 0Ch
+ push ebx
+ push esi
+ mov esi, [eax+TMndxFindResult.pStruct40]
+ push edi
+ mov edi, ecx
+ mov ecx, [ebp+arg_4]
+
+loc_1958D84: ; CODE XREF: sub_1958D70+10Fj
+ ; sub_1958D70+28Fj
+ mov eax, [edi+TFileNameDatabase.NameFragIndexMask]
+ and eax, ecx
+ lea ebx, [eax+eax*2]
+ mov eax, [edi+TFileNameDatabase.NameFragTable.ItemArray]
+ add ebx, ebx
+ add ebx, ebx
+ mov [ebp+var_C], ebx
+ cmp ecx, [eax+ebx+4]
+ jnz loc_1958E8E
+ mov edx, [eax+ebx+8]
+ mov ecx, edx
+ and ecx, 0FFFFFF00h
+ cmp ecx, 0FFFFFF00h
+ jz short loc_1958DE7
+ mov ecx, [edi+TFileNameDatabase.NextDB.pDatabase]
+ push edx
+ test ecx, ecx
+ jz short loc_1958DD3
+ mov edx, [ebp+pStruct1C]
+ push edx
+ call sub_1958D70
+ jmp loc_1958E71
+; ---------------------------------------------------------------------------
+
+loc_1958DD3: ; CODE XREF: sub_1958D70+53j
+ mov eax, [ebp+pStruct1C]
+ push eax
+ lea ecx, [edi+TFileNameDatabase.IndexStruct_174]
+ call CopyNameFragment
+ jmp loc_1958E71
+; ---------------------------------------------------------------------------
+
+loc_1958DE7: ; CODE XREF: sub_1958D70+48j
+ mov eax, [esi+TStruct40.array_00.ItemCount]
+ mov ecx, [esi+TStruct40.array_00.MaxItemCount]
+ inc eax
+ mov byte ptr [ebp+arg_4+3], dl
+ cmp eax, ecx
+ jbe short loc_1958E61
+ mov [ebp+var_8], eax
+ shr eax, 1
+ cmp ecx, eax
+ jbe short loc_1958E15
+ cmp ecx, 7FFFFFFFh
+ jbe short loc_1958E0F
+ mov [ebp+var_8], 0FFFFFFFFh
+ jmp short loc_1958E15
+; ---------------------------------------------------------------------------
+
+loc_1958E0F: ; CODE XREF: sub_1958D70+94j
+ lea edx, [ecx+ecx]
+ mov [ebp+var_8], edx
+
+loc_1958E15: ; CODE XREF: sub_1958D70+8Cj
+ ; sub_1958D70+9Dj
+ mov eax, [ebp+var_8]
+ push offset unk_53ABE00
+ push eax
+ call j_operator_new_safe
+ xor ecx, ecx
+ add esp, 8
+ cmp [esi+TStruct40.array_00.ItemCount], ecx
+ jbe short loc_1958E48
+ lea ecx, [ecx+0]
+
+loc_1958E30: ; CODE XREF: sub_1958D70+D6j
+ lea edx, [ecx+eax]
+ test edx, edx
+ jz short loc_1958E42
+ mov ebx, [esi+4]
+ mov bl, [ecx+ebx]
+ mov [edx], bl
+ mov ebx, [ebp+var_C]
+
+loc_1958E42: ; CODE XREF: sub_1958D70+C5j
+ inc ecx
+ cmp ecx, [esi+TStruct40.array_00.ItemCount]
+ jb short loc_1958E30
+
+loc_1958E48: ; CODE XREF: sub_1958D70+BBj
+ mov ecx, [esi]
+ mov edx, [ebp+var_8]
+ push ecx
+ mov [esi+TStruct40.array_00.DataBuffer], eax
+ mov [esi+TStruct40.array_00.field_4], eax
+ mov [esi+TStruct40.array_00.ItemArray], eax
+ mov [esi+TStruct40.array_00.MaxItemCount], edx
+ call operator_delete
+ add esp, 4
+
+loc_1958E61: ; CODE XREF: sub_1958D70+83j
+ mov eax, [esi+TStruct40.array_00.field_4]
+ add eax, [esi+TStruct40.array_00.ItemCount]
+ jz short loc_1958E6E
+ mov cl, byte ptr [ebp+arg_4+3]
+ mov [eax], cl
+
+loc_1958E6E: ; CODE XREF: sub_1958D70+F7j
+ inc [esi+TStruct40.array_00.ItemCount]
+
+loc_1958E71: ; CODE XREF: sub_1958D70+5Ej
+ ; sub_1958D70+72j
+ mov edx, [edi+TFileNameDatabase.NameFragTable.ItemArray]
+ mov ecx, [ebx+edx]
+ mov [ebp+arg_4], ecx
+ test ecx, ecx
+ jnz loc_1958D84
+
+loc_1958E85: ; CODE XREF: sub_1958D70+277j
+ pop edi
+ pop esi
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 8
+; ---------------------------------------------------------------------------
+
+loc_1958E8E: ; CODE XREF: sub_1958D70+30j
+ mov edx, [edi+TFileNameDatabase.Struct68_D0.ItemIsPresent.ItemArray]
+ mov eax, ecx
+ and ecx, 1Fh
+ mov ebx, 1
+ shl ebx, cl
+ shr eax, 5
+ test [edx+eax*4], ebx
+ mov eax, [ebp+arg_4]
+ jz loc_1958F50
+ mov ebx, [edi+TFileNameDatabase.FrgmDist_LoBits.ItemArray]
+ push eax
+ lea ecx, [edi+TFileNameDatabase.Struct68_D0]
+ add ebx, eax
+ call TSparseArray__GetItemValue
+ mov ecx, [edi+TFileNameDatabase.FrgmDist_HiBits.BitsPerEntry]
+ imul ecx, eax
+ mov eax, ecx
+ and ecx, 1Fh
+ mov edx, ecx
+ mov ecx, [edi+TFileNameDatabase.FrgmDist_HiBits.BitsPerEntry]
+ add ecx, edx
+ shr eax, 5
+ cmp ecx, 20h
+ mov ecx, [edi+TFileNameDatabase.FrgmDist_HiBits.ItemArray]
+ ja short loc_1958EF2
+ mov eax, [ecx+eax*4]
+ mov ecx, edx
+ shr eax, cl
+ jmp short loc_1958F15
+; ---------------------------------------------------------------------------
+
+loc_1958EF2: ; CODE XREF: sub_1958D70+177j
+ lea eax, [ecx+eax*4]
+ mov [ebp+var_C], eax
+ mov eax, [eax+4]
+ mov ecx, 20h
+ sub ecx, edx
+ shl eax, cl
+ mov ecx, [ebp+var_C]
+ mov ecx, [ecx]
+ mov [ebp+var_C], ecx
+ mov ecx, edx
+ mov edx, [ebp+var_C]
+ shr edx, cl
+ or eax, edx
+
+loc_1958F15: ; CODE XREF: sub_1958D70+180j
+ and eax, [edi+TFileNameDatabase.FrgmDist_HiBits.EntryBitMask]
+ movzx edx, byte ptr [ebx]
+ mov ecx, [edi+TFileNameDatabase.NextDB.pDatabase]
+ shl eax, 8
+ or eax, edx
+ push eax
+ test ecx, ecx
+ jz short loc_1958F3C
+ mov eax, [ebp+pStruct1C]
+ push eax
+ call sub_1958D70
+ jmp loc_1958FDE
+; ---------------------------------------------------------------------------
+
+loc_1958F3C: ; CODE XREF: sub_1958D70+1BCj
+ mov ecx, [ebp+pStruct1C]
+ push ecx
+ lea ecx, [edi+TFileNameDatabase.IndexStruct_174]
+ call CopyNameFragment
+ jmp loc_1958FDE
+; ---------------------------------------------------------------------------
+
+loc_1958F50: ; CODE XREF: sub_1958D70+139j
+ mov edx, [edi+TFileNameDatabase.FrgmDist_LoBits.ItemArray]
+ mov cl, [eax+edx]
+ mov eax, [esi+TStruct40.array_00.ItemCount]
+ mov [ebp+var_1], cl
+ mov ecx, [esi+TStruct40.array_00.MaxItemCount]
+ inc eax
+ cmp eax, ecx
+ jbe short loc_1958FCE
+ mov ebx, eax
+ shr eax, 1
+ mov [ebp+var_8], ebx
+ cmp ecx, eax
+ jbe short loc_1958F85
+ cmp ecx, 7FFFFFFFh
+ jbe short loc_1958F7F
+ or ebx, 0FFFFFFFFh
+ jmp short loc_1958F82
+; ---------------------------------------------------------------------------
+
+loc_1958F7F: ; CODE XREF: sub_1958D70+208j
+ lea ebx, [ecx+ecx]
+
+loc_1958F82: ; CODE XREF: sub_1958D70+20Dj
+ mov [ebp+var_8], ebx
+
+loc_1958F85: ; CODE XREF: sub_1958D70+200j
+ push offset unk_53ABE00
+ push ebx
+ call j_operator_new_safe
+ xor ecx, ecx
+ add esp, 8
+ cmp [esi+TStruct40.array_00.ItemCount], ecx
+ jbe short loc_1958FB8
+ lea ebx, [ebx+0]
+
+loc_1958FA0: ; CODE XREF: sub_1958D70+243j
+ lea edx, [ecx+eax]
+ test edx, edx
+ jz short loc_1958FAF
+ mov ebx, [esi+TStruct40.array_00.field_4]
+ mov bl, [ecx+ebx]
+ mov [edx], bl
+
+loc_1958FAF: ; CODE XREF: sub_1958D70+235j
+ inc ecx
+ cmp ecx, [esi+TStruct40.array_00.ItemCount]
+ jb short loc_1958FA0
+ mov ebx, [ebp+var_8]
+
+loc_1958FB8: ; CODE XREF: sub_1958D70+228j
+ mov ecx, [esi+TStruct40.array_00.DataBuffer]
+ push ecx
+ mov [esi+TStruct40.array_00.DataBuffer], eax
+ mov [esi+TStruct40.array_00.field_4], eax
+ mov [esi+TStruct40.array_00.ItemArray], eax
+ mov [esi+TStruct40.array_00.MaxItemCount], ebx
+ call operator_delete
+ add esp, 4
+
+loc_1958FCE: ; CODE XREF: sub_1958D70+1F5j
+ mov eax, [esi+TStruct40.array_00.field_4]
+ add eax, [esi+TStruct40.array_00.ItemCount]
+ jz short loc_1958FDB
+ mov dl, [ebp+var_1]
+ mov [eax], dl
+
+loc_1958FDB: ; CODE XREF: sub_1958D70+264j
+ inc [esi+TStruct40.array_00.ItemCount]
+
+loc_1958FDE: ; CODE XREF: sub_1958D70+1C7j
+ ; sub_1958D70+1DBj
+ mov ebx, [ebp+arg_4]
+ cmp ebx, [edi+TFileNameDatabase.field_214]
+ jbe loc_1958E85
+ push ebx
+ mov ecx, edi
+ call sub_1959F50
+ or ecx, 0FFFFFFFFh
+ sub ecx, ebx
+ add ecx, eax
+ mov [ebp+arg_4], ecx
+ jmp loc_1958D84
+sub_1958D70 endp
+
+; =============== S U B R O U T I N E =======================================
+
+; Attributes: bp-based frame
+
+TFileNameDatabase__sub_1959CB0 proc near ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+A1p
+ ; TFileNameDatabase__sub_1958B00+E8p ...
+
+pThis = dword ptr -4
+dwKey = dword ptr 8
+
+ push ebp
+ mov ebp, esp
+ push ecx
+ mov edx, [ebp+dwKey]
+ mov eax, edx
+ shr eax, 9
+ mov [ebp+pThis], ecx
+ test edx, 1FFh ; if(dwKey & 0x01FF)
+ jnz short loc_1959CD3
+ mov ecx, [ecx+TFileNameDatabase.Struct68_00.ArrayDwords_38.ItemArray]
+ mov eax, [ecx+eax*4] ; EAX = pDatabase->NextKeyTable[dwKey >> 0x09]
+ mov esp, ebp
+ pop ebp
+ retn 4
+; ---------------------------------------------------------------------------
+
+loc_1959CD3: ; CODE XREF: TFileNameDatabase__sub_1959CB0+15j
+ push ebx
+ push esi
+ mov esi, [ecx+TFileNameDatabase.Struct68_00.ArrayDwords_38.ItemArray]
+ lea esi, [esi+eax*4]
+ mov eax, [esi]
+ mov esi, [esi+4]
+ shr eax, 9
+ add esi, 1FFh
+ push edi
+ shr esi, 9
+ lea edi, [eax+0Ah]
+ mov [ebp+dwKey], esi
+ cmp edi, esi
+ jb short loc_1959D2E
+ mov edi, [ecx+TFileNameDatabase.Struct68_00.ArrayTriplets_20.ItemArray]
+ lea esi, [eax+eax*2+3]
+ lea esi, [edi+esi*4]
+ mov edi, eax
+ shl edi, 9
+ mov ebx, edi
+ sub ebx, [esi]
+ add ebx, 200h
+ cmp edx, ebx
+ jb short loc_1959D5F
+
+loc_1959D14: ; CODE XREF: TFileNameDatabase__sub_1959CB0+7Aj
+ add edi, 200h
+ add esi, 0Ch
+ mov ebx, edi
+ sub ebx, [esi]
+ inc eax
+ add ebx, 200h
+ cmp edx, ebx
+ jnb short loc_1959D14
+ jmp short loc_1959D5F
+; ---------------------------------------------------------------------------
+
+loc_1959D2E: ; CODE XREF: TFileNameDatabase__sub_1959CB0+45j
+ lea edi, [eax+1]
+ cmp edi, esi
+ jnb short loc_1959D5F
+ mov ecx, [ecx+TFileNameDatabase.Struct68_00.ArrayTriplets_20.ItemArray]
+
+loc_1959D38: ; CODE XREF: TFileNameDatabase__sub_1959CB0+AAj
+ add esi, eax
+ shr esi, 1
+ mov ebx, esi
+ shl ebx, 9
+ lea edi, [esi+esi*2]
+ sub ebx, [ecx+edi*4]
+ cmp edx, ebx
+ jnb short loc_1959D50
+ mov [ebp+dwKey], esi
+ jmp short loc_1959D55
+; ---------------------------------------------------------------------------
+
+loc_1959D50: ; CODE XREF: TFileNameDatabase__sub_1959CB0+99j
+ mov eax, esi
+ mov esi, [ebp+dwKey]
+
+loc_1959D55: ; CODE XREF: TFileNameDatabase__sub_1959CB0+9Ej
+ lea edi, [eax+1]
+ cmp edi, esi
+ jb short loc_1959D38
+ mov ecx, [ebp+pThis]
+
+loc_1959D5F: ; CODE XREF: TFileNameDatabase__sub_1959CB0+62j
+ ; TFileNameDatabase__sub_1959CB0+7Cj ...
+ mov ecx, [ecx+TFileNameDatabase.Struct68_00.ArrayTriplets_20.ItemArray]
+ lea esi, [eax+eax*2]
+ mov edi, [ecx+esi*4] ; EDI = Struct68_00.ArrayTriplets_20.ItemArray[eax]
+ lea esi, [ecx+esi*4] ; ESI = Struct68_00.ArrayTriplets_20.ItemArray + eax
+ mov ecx, eax
+ shl ecx, 9
+ sub edi, ecx
+ shl eax, 4
+ add edx, edi
+ mov edi, eax
+ mov eax, [esi+TRIPLET.NextKey]
+ mov ecx, eax
+ shr ecx, 17h
+ mov ebx, 100h
+ sub ebx, ecx
+ cmp edx, ebx
+ jnb short loc_1959DE8
+ mov ecx, eax
+ shr ecx, 7
+ and ecx, 0FFh
+ mov esi, 80h
+ sub esi, ecx
+ cmp edx, esi
+ jnb short loc_1959DC0
+ and eax, 7Fh
+ mov ecx, 40h
+ sub ecx, eax
+ cmp edx, ecx
+ jb loc_1959E53
+ add edi, 2
+ lea edx, [edx+eax-40h]
+ jmp loc_1959E53
+; ---------------------------------------------------------------------------
+
+loc_1959DC0: ; CODE XREF: TFileNameDatabase__sub_1959CB0+F0j
+ shr eax, 0Fh
+ and eax, 0FFh
+ mov esi, 0C0h
+ sub esi, eax
+ cmp edx, esi
+ jnb short loc_1959DDC
+ add edi, 4
+ lea edx, [edx+ecx-80h]
+ jmp short loc_1959E53
+; ---------------------------------------------------------------------------
+
+loc_1959DDC: ; CODE XREF: TFileNameDatabase__sub_1959CB0+121j
+ add edi, 6
+ lea edx, [edx+eax-0C0h]
+ jmp short loc_1959E53
+; ---------------------------------------------------------------------------
+
+loc_1959DE8: ; CODE XREF: TFileNameDatabase__sub_1959CB0+DAj
+ mov esi, [esi+TRIPLET.Distance]
+ mov eax, esi
+ shr eax, 9
+ and eax, 1FFh
+ mov ebx, 180h
+ sub ebx, eax
+ cmp edx, ebx
+ jnb short loc_1959E29
+ and esi, 1FFh
+ mov eax, 140h
+ sub eax, esi
+ cmp edx, eax
+ jnb short loc_1959E1D
+ add edi, 8
+ lea edx, [edx+ecx-100h]
+ jmp short loc_1959E53
+; ---------------------------------------------------------------------------
+
+loc_1959E1D: ; CODE XREF: TFileNameDatabase__sub_1959CB0+15Fj
+ add edi, 0Ah
+ lea edx, [edx+esi-140h]
+ jmp short loc_1959E53
+; ---------------------------------------------------------------------------
+
+loc_1959E29: ; CODE XREF: TFileNameDatabase__sub_1959CB0+14Ej
+ shr esi, 12h
+ and esi, 1FFh
+ mov ecx, 1C0h
+ sub ecx, esi
+ cmp edx, ecx
+ jnb short loc_1959E49
+ add edi, 0Ch
+ lea edx, [edx+eax-180h]
+ jmp short loc_1959E53
+; ---------------------------------------------------------------------------
+
+loc_1959E49: ; CODE XREF: TFileNameDatabase__sub_1959CB0+18Bj
+ add edi, 0Eh
+ lea edx, [edx+esi-1C0h]
+
+loc_1959E53: ; CODE XREF: TFileNameDatabase__sub_1959CB0+FEj
+ ; TFileNameDatabase__sub_1959CB0+10Bj ...
+ mov eax, [ebp+pThis]
+ mov ebx, [eax+TFileNameDatabase.Struct68_00.ItemIsPresent.ItemArray]
+ mov ecx, [ebx+edi*4]
+ not ecx
+ mov eax, ecx
+ shr eax, 1
+ and eax, 55555555h
+ mov esi, ecx
+ and esi, 55555555h
+ add eax, esi
+ mov esi, eax
+ shr esi, 2
+ and eax, 33333333h
+ and esi, 33333333h
+ add esi, eax
+ mov eax, esi
+ shr eax, 4
+ and esi, 0F0F0F0Fh
+ and eax, 0F0F0F0Fh
+ add eax, esi
+ imul eax, 1010101h
+ mov esi, eax
+ shr esi, 18h
+ cmp edx, esi
+ jb short loc_1959EEA
+ mov ecx, [ebx+edi*4+4]
+ inc edi
+ sub edx, esi
+ not ecx
+ mov eax, ecx
+ shr eax, 1
+ and eax, 55555555h
+ mov esi, ecx
+ and esi, 55555555h
+ add eax, esi
+ mov esi, eax
+ shr esi, 2
+ and eax, 33333333h
+ and esi, 33333333h
+ add esi, eax
+ mov eax, esi
+ shr eax, 4
+ and eax, 0F0F0F0Fh
+ and esi, 0F0F0F0Fh
+ add eax, esi
+ imul eax, 1010101h
+
+loc_1959EEA: ; CODE XREF: TFileNameDatabase__sub_1959CB0+1F2j
+ mov esi, eax
+ shr esi, 8
+ and esi, 0FFh
+ shl edi, 5
+ cmp edx, esi
+ jnb short loc_1959F0D
+ and eax, 0FFh
+ cmp edx, eax
+ jb short loc_1959F2B
+ add edi, 8
+ shr ecx, 8
+ jmp short loc_1959F29
+; ---------------------------------------------------------------------------
+
+loc_1959F0D: ; CODE XREF: TFileNameDatabase__sub_1959CB0+24Aj
+ shr eax, 10h
+ and eax, 0FFh
+ cmp edx, eax
+ jnb short loc_1959F23
+ add edi, 10h
+ shr ecx, 10h
+ sub edx, esi
+ jmp short loc_1959F2B
+; ---------------------------------------------------------------------------
+
+loc_1959F23: ; CODE XREF: TFileNameDatabase__sub_1959CB0+267j
+ add edi, 18h
+ shr ecx, 18h
+
+loc_1959F29: ; CODE XREF: TFileNameDatabase__sub_1959CB0+25Bj
+ sub edx, eax
+
+loc_1959F2B: ; CODE XREF: TFileNameDatabase__sub_1959CB0+253j
+ ; TFileNameDatabase__sub_1959CB0+271j
+ and ecx, 0FFh
+ shl edx, 8
+ movzx eax, ds:table_1BA1818[ecx+edx]
+ add eax, edi
+ pop edi
+ pop esi
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 4
+TFileNameDatabase__sub_1959CB0 endp
+
+; =============== S U B R O U T I N E =======================================
+
+; Attributes: bp-based frame
+
+TNameIndexStruct__CheckAndCopyNameFragment proc near ; CODE XREF: TArchiveDatabase__sub_1958B00+74p
+ ; TArchiveDatabase__sub_1958B00+1E0p ...
+
+var_C = dword ptr -0Ch
+pThis = dword ptr -8
+var_4 = dword ptr -4
+pStruct1C = dword ptr 8
+dwDistance = dword ptr 0Ch
+
+ push ebp
+ mov ebp, esp
+ sub esp, 0Ch
+ mov eax, [ebp+pStruct1C]
+ push ebx
+ mov edx, ecx
+ cmp [edx+TNameIndexStruct.Struct68.TotalItemCount], 0
+ push esi
+ mov esi, [eax+TMndxFindResult.pStruct40]
+ push edi
+ mov [ebp+pThis], edx
+ jnz loc_195A6B7
+ mov edi, [edx+TNameIndexStruct.NameFragments.ItemArray]
+ sub edi, [esi+TStruct40.CharIndex]
+ add edi, [ebp+dwDistance]
+ mov [ebp+pThis], edi
+ lea ebx, [ebx+0]
+
+loc_195A5A0: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+E6j
+ mov edx, [esi+TStruct40.CharIndex]
+ mov ecx, [ebp+pStruct1C]
+ mov eax, [ecx+TMndxFindResult.szSearchMask]
+ mov cl, [edx+edi]
+ mov [ebp+dwDistance], edx
+ cmp cl, [edx+eax]
+ jnz loc_195A67D
+ mov eax, [esi+TStruct40.array_00.ItemCount]
+ mov ecx, [esi+TStruct40.array_00.MaxItemCount]
+ mov ebx, 1
+ add eax, ebx
+ cmp eax, ecx
+ jbe short loc_195A62D
+ mov ebx, eax
+ shr eax, 1
+ cmp ecx, eax
+ jbe short loc_195A5E0
+ cmp ecx, 7FFFFFFFh
+ jbe short loc_195A5DD
+ or ebx, 0FFFFFFFFh
+ jmp short loc_195A5E0
+; ---------------------------------------------------------------------------
+
+loc_195A5DD: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+66j
+ lea ebx, [ecx+ecx]
+
+loc_195A5E0: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+5Ej
+ ; TNameIndexStruct__CheckAndCopyNameFragment+6Bj
+ push offset unk_53ABE00
+ push ebx
+ call j_operator_new_safe
+ xor ecx, ecx
+ add esp, 8
+ mov edi, eax
+ cmp [esi+TStruct40.array_00.ItemCount], ecx
+ jbe short loc_195A60C
+
+loc_195A5F7: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+9Aj
+ lea edx, [ecx+edi]
+ test edx, edx
+ jz short loc_195A606
+ mov eax, [esi+TStruct40.array_00.field_4]
+ mov al, [ecx+eax]
+ mov [edx], al
+
+loc_195A606: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+8Cj
+ inc ecx
+ cmp ecx, [esi+TStruct40.array_00.ItemCount]
+ jb short loc_195A5F7
+
+loc_195A60C: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+85j
+ mov eax, [esi+TStruct40.array_00.DataBuffer]
+ push eax
+ mov [esi+TStruct40.array_00.DataBuffer], edi
+ mov [esi+TStruct40.array_00.field_4], edi
+ mov [esi+TStruct40.array_00.ItemArray], edi
+ mov [esi+TStruct40.array_00.MaxItemCount], ebx
+ call operator_delete
+ mov edx, [ebp+dwDistance]
+ mov edi, [ebp+pThis]
+ add esp, 4
+ mov ebx, 1
+
+loc_195A62D: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+56j
+ mov eax, [esi+TStruct40.array_00.field_4]
+ add eax, [esi+TStruct40.array_00.ItemCount]
+ jz short loc_195A63A
+ mov cl, [edx+edi]
+ mov [eax], cl
+
+loc_195A63A: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+C3j
+ add [esi+TStruct40.CharIndex], ebx
+ add [esi+TStruct40.array_00.ItemCount], ebx
+ mov ecx, [esi+TStruct40.CharIndex]
+ cmp byte ptr [ecx+edi], 0
+ mov eax, [esi+TStruct40.array_00.ItemCount]
+ jz loc_195A806
+ mov edx, [ebp+pStruct1C]
+ cmp ecx, [edx+TMndxFindResult.cchSearchMask]
+ jb loc_195A5A0
+ add edi, ecx
+ mov edi, edi
+
+loc_195A660: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+13Aj
+ mov ecx, [esi+TStruct40.array_00.MaxItemCount]
+ inc eax
+ cmp eax, ecx
+ jbe short loc_195A693
+ mov edx, eax
+ shr eax, 1
+ cmp ecx, eax
+ jbe short loc_195A68B
+ cmp ecx, 7FFFFFFFh
+ jbe short loc_195A688
+ or edx, 0FFFFFFFFh
+ jmp short loc_195A68B
+; ---------------------------------------------------------------------------
+
+loc_195A67D: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+41j
+ ; TNameIndexStruct__CheckAndCopyNameFragment+16Bj
+ pop edi
+ pop esi
+ xor al, al
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 8
+; ---------------------------------------------------------------------------
+
+loc_195A688: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+106j
+ lea edx, [ecx+ecx]
+
+loc_195A68B: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+FEj
+ ; TNameIndexStruct__CheckAndCopyNameFragment+10Bj
+ push edx
+ mov ecx, esi
+ call TGenericArray__SetMaxItems_BYTE
+
+loc_195A693: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+F6j
+ mov eax, [esi+TStruct40.array_00.field_4]
+ add eax, [esi+TStruct40.array_00.ItemCount]
+ jz short loc_195A69F
+ mov cl, [edi]
+ mov [eax], cl
+
+loc_195A69F: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+129j
+ add [esi+TStruct40.array_00.ItemCount], ebx
+ mov eax, [esi+TStruct40.array_00.ItemCount]
+ add edi, ebx
+ cmp byte ptr [edi], 0
+ jnz short loc_195A660
+ pop edi
+ pop esi
+ mov al, 1
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 8
+; ---------------------------------------------------------------------------
+
+loc_195A6B7: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+18j
+ mov ebx, [ebp+dwDistance]
+ lea ebx, [ebx+0]
+
+loc_195A6C0: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+231j
+ mov edi, [edx+TNameIndexStruct.NameFragments.ItemArray]
+ mov eax, [ebp+pStruct1C]
+ mov ecx, [esi+TStruct40.CharIndex]
+ mov eax, [eax]
+ add edi, ebx
+ mov [ebp+var_4], edx
+ mov dl, [edi]
+ cmp dl, [ecx+eax]
+ mov edx, [ebp+var_4]
+ mov [ebp+var_C], edi
+ jnz short loc_195A67D
+ mov eax, [esi+TStruct40.array_00.ItemCount]
+ mov ecx, [esi+TStruct40.array_00.MaxItemCount]
+ inc eax
+ cmp eax, ecx
+ jbe short loc_195A752
+ mov [ebp+var_4], eax
+ shr eax, 1
+ cmp ecx, eax
+ jbe short loc_195A707
+ cmp ecx, 7FFFFFFFh
+ jbe short loc_195A702
+ mov [ebp+var_4], 0FFFFFFFFh
+ jmp short loc_195A707
+; ---------------------------------------------------------------------------
+
+loc_195A702: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+187j
+ add ecx, ecx
+ mov [ebp+var_4], ecx
+
+loc_195A707: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+17Fj
+ ; TNameIndexStruct__CheckAndCopyNameFragment+190j
+ mov edx, [ebp+var_4]
+ push offset unk_53ABE00
+ push edx
+ call j_operator_new_safe
+ xor ecx, ecx
+ add esp, 8
+ mov edi, eax
+ cmp [esi+TStruct40.array_00.ItemCount], ecx
+ jbe short loc_195A736
+
+loc_195A721: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+1C4j
+ lea edx, [ecx+edi]
+ test edx, edx
+ jz short loc_195A730
+ mov eax, [esi+TStruct40.array_00.field_4]
+ mov al, [ecx+eax]
+ mov [edx], al
+
+loc_195A730: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+1B6j
+ inc ecx
+ cmp ecx, [esi+TStruct40.array_00.ItemCount]
+ jb short loc_195A721
+
+loc_195A736: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+1AFj
+ mov eax, [esi+TStruct40.array_00.DataBuffer]
+ mov ecx, [ebp+var_4]
+ push eax
+ mov [esi+TStruct40.array_00.DataBuffer], edi
+ mov [esi+TStruct40.array_00.field_4], edi
+ mov [esi+TStruct40.array_00.ItemArray], edi
+ mov [esi+TStruct40.array_00.MaxItemCount], ecx
+ call operator_delete
+ mov edx, [ebp+pThis]
+ add esp, 4
+
+loc_195A752: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+176j
+ mov edi, [esi+TStruct40.array_00.field_4]
+ add edi, [esi+TStruct40.array_00.ItemCount]
+ jz short loc_195A761
+ mov eax, [ebp+var_C]
+ mov cl, [eax]
+ mov [edi], cl
+
+loc_195A761: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+1E8j
+ mov ecx, 1
+ add [esi+TStruct40.array_00.ItemCount], ecx
+ add [esi+TStruct40.CharIndex], ecx
+ mov edx, [edx+20h]
+ mov eax, [esi+TStruct40.array_00.ItemCount]
+ mov ecx, ebx
+ mov edi, ebx
+ and ecx, 1Fh
+ mov ebx, 1
+ shl ebx, cl
+ shr edi, 5
+ mov ecx, [edx+edi*4]
+ and ecx, ebx
+ mov ebx, [ebp+dwDistance]
+ inc ebx
+ mov [ebp+dwDistance], ebx
+ test ecx, ecx
+ jnz short loc_195A806
+ mov ecx, [esi+TStruct40.CharIndex]
+ mov edx, [ebp+pStruct1C]
+ cmp ecx, [edx+4]
+ jnb short loc_195A7A6
+ mov edx, [ebp+pThis]
+ jmp loc_195A6C0
+; ---------------------------------------------------------------------------
+
+loc_195A7A6: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+22Cj
+ ; TNameIndexStruct__CheckAndCopyNameFragment+294j
+ mov ecx, [ebp+pThis]
+ mov edi, [ecx+8]
+ mov ecx, [esi+TStruct40.array_00.MaxItemCount]
+ inc eax
+ cmp eax, ecx
+ jbe short loc_195A7D4
+ mov edx, eax
+ shr eax, 1
+ cmp ecx, eax
+ jbe short loc_195A7CC
+ cmp ecx, 7FFFFFFFh
+ jbe short loc_195A7C9
+ or edx, 0FFFFFFFFh
+ jmp short loc_195A7CC
+; ---------------------------------------------------------------------------
+
+loc_195A7C9: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+252j
+ lea edx, [ecx+ecx]
+
+loc_195A7CC: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+24Aj
+ ; TNameIndexStruct__CheckAndCopyNameFragment+257j
+ push edx
+ mov ecx, esi
+ call TGenericArray__SetMaxItems_BYTE
+
+loc_195A7D4: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+242j
+ mov eax, [esi+TStruct40.array_00.field_4]
+ add eax, [esi+TStruct40.array_00.ItemCount]
+ jz short loc_195A7E1
+ mov dl, [edi+ebx]
+ mov [eax], dl
+
+loc_195A7E1: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+26Aj
+ inc [esi+TStruct40.array_00.ItemCount]
+ mov edi, [ebp+pThis]
+ mov edi, [edi+20h]
+ mov eax, [esi+TStruct40.array_00.ItemCount]
+ mov ecx, ebx
+ and ecx, 1Fh
+ mov edx, 1
+ shl edx, cl
+ mov ecx, ebx
+ shr ecx, 5
+ inc ebx
+ and edx, [edi+ecx*4]
+ test edx, edx
+ jz short loc_195A7A6
+
+loc_195A806: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+DAj
+ ; TNameIndexStruct__CheckAndCopyNameFragment+221j
+ pop edi
+ pop esi
+ mov al, 1
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 8
+TNameIndexStruct__CheckAndCopyNameFragment endp
+
+; =============== S U B R O U T I N E =======================================
+
+; Attributes: bp-based frame
+
+sub_1959010 proc near ; CODE XREF: TArchiveDatabase__sub_1958B00+67p
+ ; TArchiveDatabase__sub_1958B00+1CFp ...
+
+pFragmentInfo = dword ptr -0Ch
+var_8 = dword ptr -8
+var_1 = byte ptr -1
+pStruct1C = dword ptr 8
+arg_4 = dword ptr 0Ch
+
+ push ebp
+ mov ebp, esp
+ mov eax, [ebp+pStruct1C]
+ sub esp, 0Ch
+ push ebx
+ push esi
+ mov esi, [eax+TMndxFindResult.pStruct40]
+ push edi
+ mov edi, ecx
+ mov ecx, [ebp+arg_4]
+
+loc_1959024: ; CODE XREF: sub_1959010+2CEj
+ mov eax, [edi+TFileNameDatabase.NameFragIndexMask]
+ and eax, ecx
+ lea ebx, [eax+eax*2]
+ mov eax, [edi+TFileNameDatabase.NameFragTable.ItemArray]
+ add ebx, ebx
+ add ebx, ebx
+ add eax, ebx
+ mov [ebp+pFragmentInfo], ebx
+ cmp ecx, [eax+NAME_ENTRY.NextHashModifier]
+ jnz loc_1959147
+ mov edx, [eax+NAME_ENTRY.FragmentOffset]
+ mov ecx, edx
+ and ecx, 0FFFFFF00h
+ cmp ecx, 0FFFFFF00h
+ jz short loc_1959092
+ mov ecx, [edi+TFileNameDatabase.NextDB.pDatabase]
+ push edx
+ test ecx, ecx
+ jz short loc_1959070
+ mov edx, [ebp+pStruct1C]
+ push edx
+ call sub_1959010
+ jmp short loc_195907F
+; ---------------------------------------------------------------------------
+
+loc_1959070: ; CODE XREF: sub_1959010+53j
+ mov eax, [ebp+pStruct1C]
+ push eax
+ lea ecx, [edi+TFileNameDatabase.IndexStruct_174]
+ call TNameIndexStruct__CheckAndCopyNameFragment
+
+loc_195907F: ; CODE XREF: sub_1959010+5Ej
+ test al, al
+ jnz loc_195912E
+
+loc_1959087: ; CODE XREF: sub_1959010+90j
+ ; sub_1959010+1F3j ...
+ pop edi
+ pop esi
+ xor al, al
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 8
+; ---------------------------------------------------------------------------
+
+loc_1959092: ; CODE XREF: sub_1959010+48j
+ mov ecx, [ebp+pStruct1C]
+ mov eax, [ecx+TMndxFindResult.szSearchMask]
+ mov ecx, [esi+TStruct40.CharIndex]
+ mov byte ptr [ebp+arg_4+3], dl
+ cmp dl, [eax+ecx]
+ jnz short loc_1959087
+ mov eax, [esi+TStruct40.array_00.ItemCount]
+ mov ecx, [esi+TStruct40.array_00.MaxItemCount]
+ inc eax
+ cmp eax, ecx
+ jbe short loc_1959119
+ mov [ebp+var_8], eax
+ shr eax, 1
+ cmp ecx, eax
+ jbe short loc_19590CD
+ cmp ecx, 7FFFFFFFh
+ jbe short loc_19590C7
+ mov [ebp+var_8], 0FFFFFFFFh
+ jmp short loc_19590CD
+; ---------------------------------------------------------------------------
+
+loc_19590C7: ; CODE XREF: sub_1959010+ACj
+ lea edx, [ecx+ecx]
+ mov [ebp+var_8], edx
+
+loc_19590CD: ; CODE XREF: sub_1959010+A4j
+ ; sub_1959010+B5j
+ mov eax, [ebp+var_8]
+ push offset unk_53ABE00
+ push eax
+ call j_operator_new_safe
+ xor ecx, ecx
+ add esp, 8
+ cmp [esi+TStruct40.array_00.ItemCount], ecx
+ jbe short loc_19590FD
+
+loc_19590E5: ; CODE XREF: sub_1959010+EBj
+ lea edx, [ecx+eax]
+ test edx, edx
+ jz short loc_19590F7
+ mov ebx, [esi+TStruct40.array_00.field_4]
+ mov bl, [ecx+ebx]
+ mov [edx], bl
+ mov ebx, [ebp+pFragmentInfo]
+
+loc_19590F7: ; CODE XREF: sub_1959010+DAj
+ inc ecx
+ cmp ecx, [esi+TStruct40.array_00.ItemCount]
+ jb short loc_19590E5
+
+loc_19590FD: ; CODE XREF: sub_1959010+D3j
+ mov ecx, [esi+TStruct40.array_00.DataBuffer]
+ mov edx, [ebp+var_8]
+ push ecx
+ mov [esi+TStruct40.array_00.DataBuffer], eax
+ mov [esi+TStruct40.array_00.field_4], eax
+ mov [esi+TStruct40.array_00.ItemArray], eax
+ mov [esi+TStruct40.array_00.MaxItemCount], edx
+ call operator_delete
+ mov dl, byte ptr [ebp+arg_4+3]
+ add esp, 4
+
+loc_1959119: ; CODE XREF: sub_1959010+9Bj
+ mov eax, [esi+TStruct40.array_00.field_4]
+ add eax, [esi+TStruct40.array_00.ItemCount]
+ jz short loc_1959123
+ mov [eax], dl
+
+loc_1959123: ; CODE XREF: sub_1959010+10Fj
+ mov eax, 1
+ add [esi+TStruct40.array_00.ItemCount], eax
+ add [esi+TStruct40.CharIndex], eax
+
+loc_195912E: ; CODE XREF: sub_1959010+71j
+ mov eax, [edi+TFileNameDatabase.NameFragTable.ItemArray]
+ mov ecx, [ebx+eax]
+ mov [ebp+arg_4], ecx
+ test ecx, ecx
+ jz loc_19592ED
+ jmp loc_19592D5
+; ---------------------------------------------------------------------------
+
+loc_1959147: ; CODE XREF: sub_1959010+31j
+ mov eax, [edi+TFileNameDatabase.Struct68_D0.ItemIsPresent.ItemArray]
+ mov edx, ecx
+ and ecx, 1Fh
+ mov ebx, 1
+ shl ebx, cl
+ shr edx, 5
+ test [eax+edx*4], ebx
+ mov eax, [ebp+arg_4]
+ jz loc_195920E
+ mov ebx, [edi+TFileNameDatabase.FrgmDist_LoBits.ItemArray]
+ push eax
+ lea ecx, [edi+TFileNameDatabase.Struct68_D0]
+ add ebx, eax
+ call TSparseArray__GetItemValue
+ mov ecx, [edi+TFileNameDatabase.FrgmDist_HiBits.BitsPerEntry]
+ imul ecx, eax
+ mov eax, ecx
+ and ecx, 1Fh
+ mov edx, ecx
+ mov ecx, [edi+TFileNameDatabase.FrgmDist_HiBits.BitsPerEntry]
+ add ecx, edx
+ shr eax, 5
+ cmp ecx, 20h
+ mov ecx, [edi+TFileNameDatabase.FrgmDist_HiBits.ItemArray]
+ ja short loc_19591AB
+ mov eax, [ecx+eax*4]
+ mov ecx, edx
+ shr eax, cl
+ jmp short loc_19591CE
+; ---------------------------------------------------------------------------
+
+loc_19591AB: ; CODE XREF: sub_1959010+190j
+ lea eax, [ecx+eax*4]
+ mov [ebp+pFragmentInfo], eax
+ mov eax, [eax+4]
+ mov ecx, 20h
+ sub ecx, edx
+ shl eax, cl
+ mov ecx, [ebp+pFragmentInfo]
+ mov ecx, [ecx]
+ mov [ebp+pFragmentInfo], ecx
+ mov ecx, edx
+ mov edx, [ebp+pFragmentInfo]
+ shr edx, cl
+ or eax, edx
+
+loc_19591CE: ; CODE XREF: sub_1959010+199j
+ and eax, [edi+TFileNameDatabase.FrgmDist_HiBits.EntryBitMask]
+ movzx edx, byte ptr [ebx]
+ mov ecx, [edi+TFileNameDatabase.NextDB.pDatabase]
+ shl eax, 8
+ or eax, edx
+ push eax
+ test ecx, ecx
+ jz short loc_19591F2
+ mov eax, [ebp+pStruct1C]
+ push eax
+ call sub_1959010
+ jmp short loc_1959201
+; ---------------------------------------------------------------------------
+
+loc_19591F2: ; CODE XREF: sub_1959010+1D5j
+ mov ecx, [ebp+pStruct1C]
+ push ecx
+ lea ecx, [edi+TFileNameDatabase.IndexStruct_174]
+ call TNameIndexStruct__CheckAndCopyNameFragment
+
+loc_1959201: ; CODE XREF: sub_1959010+1E0j
+ test al, al
+ jz loc_1959087
+ jmp loc_19592B6
+; ---------------------------------------------------------------------------
+
+loc_195920E: ; CODE XREF: sub_1959010+152j
+ mov edx, [edi+TFileNameDatabase.FrgmDist_LoBits.ItemArray]
+ mov dl, [eax+edx]
+ mov ecx, [ebp+pStruct1C]
+ mov eax, [ecx+TMndxFindResult.szSearchMask]
+ mov ecx, [esi+TStruct40.CharIndex]
+ mov [ebp+var_1], dl
+ cmp dl, [eax+ecx]
+ jnz loc_1959087
+ mov eax, [esi+TStruct40.array_00.ItemCount]
+ mov ecx, [esi+TStruct40.array_00.MaxItemCount]
+ inc eax
+ cmp eax, ecx
+ jbe short loc_19592A1
+ mov ebx, eax
+ shr eax, 1
+ mov [ebp+var_8], ebx
+ cmp ecx, eax
+ jbe short loc_1959254
+ cmp ecx, 7FFFFFFFh
+ jbe short loc_195924E
+ or ebx, 0FFFFFFFFh
+ jmp short loc_1959251
+; ---------------------------------------------------------------------------
+
+loc_195924E: ; CODE XREF: sub_1959010+237j
+ lea ebx, [ecx+ecx]
+
+loc_1959251: ; CODE XREF: sub_1959010+23Cj
+ mov [ebp+var_8], ebx
+
+loc_1959254: ; CODE XREF: sub_1959010+22Fj
+ push offset unk_53ABE00
+ push ebx
+ call j_operator_new_safe
+ xor ecx, ecx
+ add esp, 8
+ cmp [esi+TStruct40.array_00.ItemCount], ecx
+ jbe short loc_1959288
+ lea esp, [esp+0]
+
+loc_1959270: ; CODE XREF: sub_1959010+273j
+ lea edx, [ecx+eax]
+ test edx, edx
+ jz short loc_195927F
+ mov ebx, [esi+TStruct40.array_00.field_4]
+ mov bl, [ecx+ebx]
+ mov [edx], bl
+
+loc_195927F: ; CODE XREF: sub_1959010+265j
+ inc ecx
+ cmp ecx, [esi+TStruct40.array_00.ItemCount]
+ jb short loc_1959270
+ mov ebx, [ebp+var_8]
+
+loc_1959288: ; CODE XREF: sub_1959010+257j
+ mov ecx, [esi+TStruct40.array_00.DataBuffer]
+ push ecx
+ mov [esi+TStruct40.array_00.DataBuffer], eax
+ mov [esi+TStruct40.array_00.field_4], eax
+ mov [esi+TStruct40.array_00.ItemArray], eax
+ mov [esi+TStruct40.array_00.MaxItemCount], ebx
+ call operator_delete
+ mov dl, [ebp+var_1]
+ add esp, 4
+
+loc_19592A1: ; CODE XREF: sub_1959010+224j
+ mov eax, [esi+TStruct40.array_00.field_4]
+ add eax, [esi+TStruct40.array_00.ItemCount]
+ jz short loc_19592AB
+ mov [eax], dl
+
+loc_19592AB: ; CODE XREF: sub_1959010+297j
+ mov eax, 1
+ add [esi+TStruct40.array_00.ItemCount], eax
+ add [esi+TStruct40.CharIndex], eax
+
+loc_19592B6: ; CODE XREF: sub_1959010+1F9j
+ mov ebx, [ebp+arg_4]
+ cmp ebx, [edi+TFileNameDatabase.field_214]
+ jbe short loc_19592ED
+ push ebx
+ mov ecx, edi
+ call sub_1959F50
+ or edx, 0FFFFFFFFh
+ sub edx, ebx
+ add eax, edx
+ mov ecx, eax
+ mov [ebp+arg_4], eax
+
+loc_19592D5: ; CODE XREF: sub_1959010+132j
+ mov edx, [esi+TStruct40.CharIndex]
+ mov eax, [ebp+pStruct1C]
+ cmp edx, [eax+TMndxFindResult.cchSearchMask]
+ jb loc_1959024
+ push ecx
+ push eax
+ mov ecx, edi
+ call sub_1958D70
+
+loc_19592ED: ; CODE XREF: sub_1959010+12Cj
+ ; sub_1959010+2AFj
+ pop edi
+ pop esi
+ mov al, 1
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 8
+sub_1959010 endp
+
+; =============== S U B R O U T I N E =======================================
+
+; Attributes: bp-based frame
+
+sub_19582E0 proc near ; CODE XREF: TFileNameDatabase__sub_1958B00+253p
+
+arg_0 = dword ptr 8
+
+ push ebp
+ mov ebp, esp
+ push esi
+ mov esi, ecx
+ mov eax, [esi+0Ch]
+ mov ecx, [esi+10h]
+ inc eax
+ cmp eax, ecx
+ jbe short loc_1958311
+ mov edx, eax
+ shr eax, 1
+ cmp ecx, eax
+ jbe short loc_1958309
+ cmp ecx, 7FFFFFFFh
+ jbe short loc_1958306
+ or edx, 0FFFFFFFFh
+ jmp short loc_1958309
+; ---------------------------------------------------------------------------
+
+loc_1958306: ; CODE XREF: sub_19582E0+1Fj
+ lea edx, [ecx+ecx]
+
+loc_1958309: ; CODE XREF: sub_19582E0+17j
+ ; sub_19582E0+24j
+ push edx
+ mov ecx, esi
+ call TGenericArray__SetMaxItems_BYTE
+
+loc_1958311: ; CODE XREF: sub_19582E0+Fj
+ mov eax, [esi+4]
+ add eax, [esi+0Ch]
+ jz short loc_1958320
+ mov ecx, [ebp+arg_0]
+ mov dl, [ecx]
+ mov [eax], dl
+
+loc_1958320: ; CODE XREF: sub_19582E0+37j
+ inc dword ptr [esi+0Ch]
+ pop esi
+ pop ebp
+ retn 4
+sub_19582E0 endp
+
+; =============== S U B R O U T I N E =======================================
+
+; Attributes: bp-based frame
+
+TFileNameDatabase__sub_1958B00 proc near ; CODE XREF: TFileNameDatabase__sub_1959460+3Bp
+
+var_C = dword ptr -0Ch
+ItemArrayOffset = dword ptr -8
+var_4 = dword ptr -4
+arg_0 = dword ptr 8
+
+ push ebp
+ mov ebp, esp
+ sub esp, 0Ch
+ mov edx, [ebp+pStruct1C]
+ push ebx
+ mov ebx, [edx+TMndxFindResult.szSearchMask]
+ push esi
+ push edi
+ mov edi, [edx+TMndxFindResult.pStruct40]
+ mov eax, [edi+TStruct40.CharIndex]
+ movzx eax, byte ptr [eax+ebx]
+ mov esi, ecx
+ mov ecx, [edi+TStruct40.HashValue]
+ mov ebx, ecx
+ shl ebx, 5
+ xor eax, ebx
+ mov ebx, [esi+TFileNameDatabase.NameFragTable.ItemArray]
+ xor eax, ecx
+ and eax, [esi+TFileNameDatabase.NameFragIndexMask]
+ lea eax, [eax+eax*2]
+ add eax, eax
+ add eax, eax
+ mov [ebp+ItemArrayOffset], eax
+ cmp ecx, [eax+ebx]
+ jnz loc_1958BE5
+ mov ecx, [eax+ebx+NAME_ENTRY.FragmentOffset]
+ mov ebx, ecx
+ and ebx, 0FFFFFF00h
+ cmp ebx, 0FFFFFF00h
+ jz short loc_1958B88
+ mov eax, [esi+TFileNameDatabase.NextDB.pDatabase]
+ push ecx
+ push edx
+ test eax, eax
+ jz short loc_1958B6E
+ mov ecx, eax
+ call sub_1959010
+ jmp short loc_1958B79
+; ---------------------------------------------------------------------------
+
+loc_1958B6E: ; CODE XREF: TArchiveDatabase__sub_1958B00+63j
+ lea ecx, [esi+TFileNameDatabase.IndexStruct_174]
+ call TNameIndexStruct__CheckAndCopyNameFragment
+
+loc_1958B79: ; CODE XREF: TArchiveDatabase__sub_1958B00+6Cj
+ test al, al
+ jnz short loc_1958BCA
+
+loc_1958B7D: ; CODE XREF: TArchiveDatabase__sub_1958B00+108j
+ ; TArchiveDatabase__sub_1958B00+1F3j
+ pop edi
+ pop esi
+ xor al, al
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 4
+; ---------------------------------------------------------------------------
+
+loc_1958B88: ; CODE XREF: TArchiveDatabase__sub_1958B00+57j
+ mov eax, [edi+TStruct40.array_00.ItemCount]
+ mov bl, cl
+ mov ecx, [edi+TStruct40.array_00.MaxItemCount]
+ inc eax
+ cmp eax, ecx
+ jbe short loc_1958BB5
+ mov edx, eax
+ shr eax, 1
+ cmp ecx, eax
+ jbe short loc_1958BAD
+ cmp ecx, 7FFFFFFFh
+ jbe short loc_1958BAA
+ or edx, 0FFFFFFFFh
+ jmp short loc_1958BAD
+; ---------------------------------------------------------------------------
+
+loc_1958BAA: ; CODE XREF: TArchiveDatabase__sub_1958B00+A3j
+ lea edx, [ecx+ecx]
+
+loc_1958BAD: ; CODE XREF: TArchiveDatabase__sub_1958B00+9Bj
+ ; TArchiveDatabase__sub_1958B00+A8j
+ push edx
+ mov ecx, edi
+ call TGenericArray__SetMaxItems_BYTE
+
+loc_1958BB5: ; CODE XREF: TArchiveDatabase__sub_1958B00+93j
+ mov eax, [edi+TStruct40.array_00.field_4]
+ add eax, [edi+TStruct40.array_00.ItemCount]
+ jz short loc_1958BBF
+ mov [eax], bl
+
+loc_1958BBF: ; CODE XREF: TArchiveDatabase__sub_1958B00+BBj
+ mov eax, 1
+ add [edi+TStruct40.array_00.ItemCount], eax
+ add [edi+TStruct40.CharIndex], eax
+
+loc_1958BCA: ; CODE XREF: TArchiveDatabase__sub_1958B00+7Bj
+ mov ecx, [esi+TFileNameDatabase.NameFragTable.ItemArray]
+ mov edx, [ebp+ItemArrayOffset]
+ mov eax, [ecx+edx+NAME_ENTRY.NextHashModifier]
+ mov [edi+TStruct40.HashValue], eax
+
+loc_1958BDA: ; CODE XREF: TArchiveDatabase__sub_1958B00+1E7j
+ pop edi
+ pop esi
+ mov al, 1
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 4
+; ---------------------------------------------------------------------------
+
+loc_1958BE5: ; CODE XREF: TArchiveDatabase__sub_1958B00+3Fj
+ push ecx
+ mov ecx, esi
+ call TArchiveDatabase__sub_1959CB0
+ mov ebx, [esi+TFileNameDatabase.Struct68_00.ItemIsPresent.ItemArray]
+ inc eax
+ mov ecx, eax
+ and ecx, 1Fh
+ mov edx, 1
+ shl edx, cl
+ mov ecx, eax
+ shr ecx, 5
+ mov [ebp+ItemArrayOffset], eax
+ test [ebx+ecx*4], edx
+ jz loc_1958B7D
+ sub eax, [edi+TStruct40.HashValue]
+ mov [ebp+var_4], 0FFFFFFFFh
+ dec eax
+ mov [edi+TStruct40.HashValue], eax
+ lea esp, [esp+0]
+
+loc_1958C20: ; CODE XREF: TArchiveDatabase__sub_1958B00+230j
+ mov eax, [edi+TStruct40.HashValue]
+ mov ebx, [esi+TFileNameDatabase.Struct68_D0.ItemIsPresent.ItemArray]
+ mov ecx, eax
+ and ecx, 1Fh
+ mov edx, 1
+ shl edx, cl
+ mov ecx, eax
+ shr ecx, 5
+ test [ebx+ecx*4], edx
+ jz loc_1958CFB
+ mov ecx, [ebp+var_4]
+ cmp ecx, 0FFFFFFFFh
+ jnz short loc_1958C5E
+ push eax
+ lea ecx, [esi+TFileNameDatabase.Struct68_D0]
+ call TSparseArray__GetItemValue
+ mov ecx, eax
+ mov [ebp+var_4], eax
+ jmp short loc_1958C62
+; ---------------------------------------------------------------------------
+
+loc_1958C5E: ; CODE XREF: TArchiveDatabase__sub_1958B00+149j
+ inc ecx
+ mov [ebp+var_4], ecx
+
+loc_1958C62: ; CODE XREF: TArchiveDatabase__sub_1958B00+15Cj
+ mov edx, [edi+TStruct40.CharIndex]
+ mov [ebp+var_C], edx
+ mov edx, [esi+TFileNameDatabase.FrgmDist_HiBits.BitsPerEntry]
+ mov eax, edx
+ imul eax, ecx
+ mov ecx, eax
+ and eax, 1Fh
+ add edx, eax
+ shr ecx, 5
+ cmp edx, 20h
+ mov edx, [esi+TFileNameDatabase.FrgmDist_HiBits.ItemArray]
+ ja short loc_1958C91
+ mov edx, [edx+ecx*4]
+ mov ecx, eax
+ shr edx, cl
+ jmp short loc_1958CA8
+; ---------------------------------------------------------------------------
+
+loc_1958C91: ; CODE XREF: TArchiveDatabase__sub_1958B00+186j
+ lea ebx, [edx+ecx*4]
+ mov edx, [ebx+4]
+ mov ebx, [ebx]
+ mov ecx, 20h
+ sub ecx, eax
+ shl edx, cl
+ mov ecx, eax
+ shr ebx, cl
+ or edx, ebx
+
+loc_1958CA8: ; CODE XREF: TArchiveDatabase__sub_1958B00+18Fj
+ mov ecx, [esi+TFileNameDatabase.FrgmDist_LoBits.ItemArray]
+ and edx, [esi+TFileNameDatabase.FrgmDist_HiBits.EntryBitMask]
+ mov eax, [edi+TStruct40.HashValue]
+ movzx eax, byte ptr [ecx+eax]
+ mov ecx, [esi+TFileNameDatabase.NextDB.pDatabase]
+ shl edx, 8
+ or eax, edx
+ push eax
+ test ecx, ecx
+ jz short loc_1958CD6
+ mov edx, [ebp+pStruct1C]
+ push edx
+ call sub_1959010
+ jmp short loc_1958CE5
+; ---------------------------------------------------------------------------
+
+loc_1958CD6: ; CODE XREF: TArchiveDatabase__sub_1958B00+1C9j
+ mov eax, [ebp+pStruct1C]
+ push eax
+ lea ecx, [esi+TFileNameDatabase.IndexStruct_174]
+ call TNameIndexStruct__CheckAndCopyNameFragment
+
+loc_1958CE5: ; CODE XREF: TArchiveDatabase__sub_1958B00+1D4j
+ test al, al
+ jnz loc_1958BDA
+ mov ecx, [ebp+var_C]
+ cmp [edi+TStruct40.CharIndex], ecx
+ jnz loc_1958B7D
+ jmp short loc_1958D11
+; ---------------------------------------------------------------------------
+
+loc_1958CFB: ; CODE XREF: TArchiveDatabase__sub_1958B00+13Dj
+ mov edx, [esi+TFileNameDatabase.FrgmDist_LoBits.ItemArray]
+ mov ebx, [ebp+pStruct1C]
+ mov ecx, [edi+TStruct40.CharIndex]
+ mov ebx, [ebx+TMndxFindResult.szSearchMask]
+ mov dl, [eax+edx]
+ cmp dl, [ecx+ebx]
+ jz short loc_1958D41
+
+loc_1958D11: ; CODE XREF: TArchiveDatabase__sub_1958B00+1F9j
+ mov eax, [ebp+ItemArrayOffset]
+ inc [edi+TStruct40.HashValue]
+ inc eax
+ mov ecx, eax
+ and ecx, 1Fh
+ mov edx, 1
+ shl edx, cl
+ mov ecx, [esi+TFileNameDatabase.Struct68_00.ItemIsPresent.ItemArray]
+ mov [ebp+ItemArrayOffset], eax
+ shr eax, 5
+ test [ecx+eax*4], edx
+ jnz loc_1958C20
+ pop edi
+ pop esi
+ xor al, al
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 4
+; ---------------------------------------------------------------------------
+
+loc_1958D41: ; CODE XREF: TArchiveDatabase__sub_1958B00+20Fj
+ mov edx, [esi+TFileNameDatabase.FrgmDist_LoBits.ItemArray]
+ mov cl, [edx+eax]
+ lea edx, [ebp+pStruct1C+3]
+ mov byte ptr [ebp+pStruct1C+3], cl
+ push edx
+ mov ecx, edi
+ call sub_19582E0
+ mov eax, 1
+ add [edi+TStruct40.CharIndex], eax
+ pop edi
+ pop esi
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 4
+TFileNameDatabase__sub_1958B00 endp
+
+; =============== S U B R O U T I N E =======================================
+
+; Attributes: bp-based frame
+
+TFileNameDatabase__sub_1959460 proc near ; CODE XREF: TFileNameDatabasePtr__sub_1956CE0+2Dp
+
+Struct14 = dword ptr -20h
+var_1C = dword ptr -1Ch
+var_18 = dword ptr -18h
+var_14 = dword ptr -14h
+var_10 = dword ptr -10h
+pStruct14 = dword ptr -0Ch
+pThis = dword ptr -8
+OneChar = byte ptr -1
+pStruct1C = dword ptr 8
+
+ push ebp
+ mov ebp, esp
+ sub esp, 20h
+ push ebx
+ push esi
+ push edi
+ mov edi, [ebp+pStruct1C]
+ mov esi, [edi+TMndxFindResult.pStruct40]
+ mov eax, [esi+TStruct40.SearchPhase]
+ mov ebx, ecx
+ mov [ebp+pThis], ebx
+ cmp eax, 4
+ jz return_false
+ cmp eax, 2
+ jz loc_1959530
+ mov ecx, esi
+ call TStruct40__InitSearchBuffers
+ mov eax, [esi+TStruct40.CharIndex]
+ cmp eax, [edi+TMndxFindResult.cchSearchMask]
+ jnb short loc_19594B0
+
+loc_1959498: ; CODE XREF: TFileNameDatabase__sub_1959460+4Ej
+ push edi
+ mov ecx, ebx
+ call TFileNameDatabase__sub_1958B00
+ test al, al
+ jz loc_1959778
+ mov ecx, [esi+TStruct40.CharIndex]
+ cmp ecx, [edi+TMndxFindResult.cchSearchMask]
+ jb short loc_1959498
+
+loc_19594B0: ; CODE XREF: TFileNameDatabase__sub_1959460+36j
+ mov edx, [esi+TStruct40.HashValue]
+ or eax, 0FFFFFFFFh
+ mov [ebp+Struct14], edx
+ mov [ebp+var_14], eax
+ mov [ebp+var_10], eax
+ mov eax, [esi+TStruct40.array_00.ItemCount]
+ lea edx, [ebp+Struct14]
+ lea ecx, [esi+TStruct40.array_18]
+ push edx
+ mov [ebp+var_1C], 0
+ mov [ebp+var_18], eax
+ call TGenericArray__InsertItem_STRUCT14
+ mov ecx, [esi+TStruct40.HashValue]
+ mov eax, ecx
+ and ecx, 1Fh
+ mov edi, 1
+ shl edi, cl
+ mov [esi+TStruct40.ItemCount], 1
+ mov edx, [ebx+TFileNameDatabase.FileNameIndexes.ItemIsPresent.ItemArray]
+ shr eax, 5
+ test [edx+eax*4], edi
+ jz short loc_1959530
+ mov ecx, [esi+TStruct40.array_00.field_4]
+ mov eax, [esi+TStruct40.array_00.ItemCount]
+ mov edi, [ebp+pStruct1C]
+ mov [edi+TMndxFindResult.szFoundPath], ecx
+ mov [edi+TMndxFindResult.cchFoundPath], eax
+ mov esi, [esi+TStruct40.HashValue]
+ push esi
+ lea ecx, [ebx+TFileNameDatabase.FileNameIndexes]
+ call TSparseArray__GetItemValue
+ mov [edi+TMndxFindResult.FileNameIndex], eax
+ pop edi
+ pop esi
+ mov al, 1
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 4
+; ---------------------------------------------------------------------------
+
+loc_1959522: ; CODE XREF: TFileNameDatabase__sub_1959460+26Bj
+ ; TFileNameDatabase__sub_1959460+2D9j ...
+ mov ebx, [ebp+pThis]
+ jmp short loc_1959530
+; ---------------------------------------------------------------------------
+ align 10h
+
+loc_1959530: ; CODE XREF: TFileNameDatabase__sub_1959460+23j
+ ; TFileNameDatabase__sub_1959460+97j ...
+ mov edx, [esi+TStruct40.ItemCount]
+ cmp edx, [esi+TStruct40.array_18.ItemCount]
+ jnz loc_19595BD
+ mov eax, [esi+TStruct40.array_18.ItemCount]
+ mov ecx, [esi+TStruct40.array_18.field_4]
+ lea eax, [eax+eax*4]
+ lea eax, [ecx+eax*4-14h]
+ mov [ebp+pStruct14], eax
+ mov eax, [eax+TStruct14.HashValue]
+ push eax
+ mov ecx, ebx
+ call TFileNameDatabase__sub_1959CB0
+ mov edx, [ebp+pStruct14]
+ mov ecx, [esi+TStruct40.array_18.ItemCount]
+ inc eax
+ mov ebx, eax
+ sub ebx, [edx+TStruct14.HashValue]
+ mov edx, [esi+TStruct40.array_18.MaxItemCount]
+ inc ecx
+ dec ebx
+ mov [ebp+var_1C], eax
+ cmp ecx, edx
+ jbe short loc_1959591
+ mov eax, ecx
+ shr ecx, 1
+ cmp edx, ecx
+ jbe short loc_1959585
+ mov eax, 0CCCCCCCh
+ cmp edx, 6666666h
+ ja short loc_1959585
+ lea eax, [edx+edx]
+
+loc_1959585: ; CODE XREF: TFileNameDatabase__sub_1959460+113j
+ ; TFileNameDatabase__sub_1959460+120j
+ push eax
+ lea ecx, [esi+TStruct40.array_18]
+ call TGenericArray__SetMaxItems_STRUCT14
+ mov eax, [ebp+var_1C]
+
+loc_1959591: ; CODE XREF: TFileNameDatabase__sub_1959460+10Bj
+ mov ecx, [esi+TStruct40.array_18.ItemCount]
+ mov edx, [esi+TStruct40.array_18.field_4]
+ lea ecx, [ecx+ecx*4]
+ lea ecx, [edx+ecx*4]
+ test ecx, ecx
+ jz short loc_19595B7
+ mov [ecx+TStruct14.HashValue], ebx
+ mov [ecx+TStruct14.field_4], eax
+ xor eax, eax
+ mov [ecx+TStruct14.field_8], eax
+ or eax, 0FFFFFFFFh
+ mov [ecx+TStruct14.field_C], eax
+ or eax, 0FFFFFFFFh
+ mov [ecx+TStruct14.field_10], eax
+
+loc_19595B7: ; CODE XREF: TFileNameDatabase__sub_1959460+13Fj
+ inc [esi+TStruct40.array_18.ItemCount]
+ mov ebx, [ebp+pThis]
+
+loc_19595BD: ; CODE XREF: TFileNameDatabase__sub_1959460+D6j
+ mov eax, [esi+TStruct40.ItemCount]
+ mov ecx, [esi+TStruct40.array_18.field_4]
+ mov ebx, [ebx+TFileNameDatabase.Struct68_00.ItemIsPresent.ItemArray]
+ lea eax, [eax+eax*4]
+ lea edi, [ecx+eax*4]
+ mov eax, [edi+TStruct14.field_4]
+ mov ecx, eax
+ and ecx, 1Fh
+ mov edx, 1
+ shl edx, cl
+ mov ecx, eax
+ shr ecx, 5
+ test [ebx+ecx*4], edx
+ setnz cl
+ inc eax
+ mov [edi+TStruct14.field_4], eax
+ test cl, cl
+ jz loc_19596E9
+ inc [esi+TStruct40.ItemCount]
+ mov ecx, [edi+TStruct14.HashValue]
+ mov eax, [ebp+pThis]
+ mov eax, [eax+TFileNameDatabase.Struct68_D0.ItemIsPresent.ItemArray]
+ mov edx, ecx
+ and ecx, 1Fh
+ mov ebx, 1
+ shl ebx, cl
+ shr edx, 5
+ test [eax+edx*4], ebx
+ mov ebx, [ebp+pThis]
+ jz short loc_1959665
+ mov eax, [edi+TStruct14.field_C]
+ cmp eax, 0FFFFFFFFh
+ jnz short loc_195962F
+ mov eax, [edi+TStruct14.HashValue]
+ push eax
+ lea ecx, [ebx+TFileNameDatabase.Struct68_D0]
+ call TSparseArray__GetItemValue
+ jmp short loc_1959630
+; ---------------------------------------------------------------------------
+
+loc_195962F: ; CODE XREF: TFileNameDatabase__sub_1959460+1BDj
+ inc eax
+
+loc_1959630: ; CODE XREF: TFileNameDatabase__sub_1959460+1CDj
+ mov ecx, [edi+TStruct14.HashValue]
+ push eax
+ push ecx
+ mov ecx, ebx
+ mov [edi+TStruct14.field_C], eax
+ call sub_19573D0
+ mov ecx, [ebx+TFileNameDatabase.NextDB.pDatabase]
+ push eax
+ test ecx, ecx
+ jz short loc_1959654
+ mov edx, [ebp+pStruct1C]
+ push edx
+ call sub_1958D70
+ jmp short loc_19596AE
+; ---------------------------------------------------------------------------
+
+loc_1959654: ; CODE XREF: TFileNameDatabase__sub_1959460+1E7j
+ mov eax, [ebp+pStruct1C]
+ push eax
+ lea ecx, [ebx+TFileNameDatabase.IndexStruct_174]
+ call CopyNameFragment
+ jmp short loc_19596AE
+; ---------------------------------------------------------------------------
+
+loc_1959665: ; CODE XREF: TFileNameDatabase__sub_1959460+1B5j
+ mov ecx, [ebx+TFileNameDatabase.FrgmDist_LoBits.ItemArray]
+ mov eax, [edi+TStruct14.HashValue]
+ mov dl, [eax+ecx]
+ mov eax, [esi+TStruct40.array_00.ItemCount]
+ mov ecx, [esi+TStruct40.array_00.MaxItemCount]
+ inc eax
+ mov [ebp+OneChar], dl
+ cmp eax, ecx
+ jbe short loc_195969E
+ mov edx, eax
+ shr eax, 1
+ cmp ecx, eax
+ jbe short loc_1959696
+ cmp ecx, 7FFFFFFFh
+ jbe short loc_1959693
+ or edx, 0FFFFFFFFh
+ jmp short loc_1959696
+; ---------------------------------------------------------------------------
+
+loc_1959693: ; CODE XREF: TFileNameDatabase__sub_1959460+22Cj
+ lea edx, [ecx+ecx]
+
+loc_1959696: ; CODE XREF: TFileNameDatabase__sub_1959460+224j
+ ; TFileNameDatabase__sub_1959460+231j
+ push edx
+ mov ecx, esi
+ call TGenericArray__SetMaxItems_BYTE
+
+loc_195969E: ; CODE XREF: TFileNameDatabase__sub_1959460+21Cj
+ mov eax, [esi+TStruct40.array_00.field_4]
+ add eax, [esi+TStruct40.array_00.ItemCount]
+ jz short loc_19596AB
+ mov cl, [ebp+OneChar]
+ mov [eax], cl
+
+loc_19596AB: ; CODE XREF: TFileNameDatabase__sub_1959460+244j
+ inc [esi+TStruct40.array_00.ItemCount]
+
+loc_19596AE: ; CODE XREF: TFileNameDatabase__sub_1959460+1F2j
+ ; TFileNameDatabase__sub_1959460+203j
+ mov edx, [esi+TStruct40.array_00.ItemCount]
+ mov ecx, [edi+TStruct14.HashValue]
+ mov [edi+TStruct14.field_8], edx
+ mov edx, [ebx+TFileNameDatabase.FileNameIndexes.ItemIsPresent.ItemArray]
+ mov eax, ecx
+ and ecx, 1Fh
+ mov ebx, 1
+ shl ebx, cl
+ shr eax, 5
+ test [edx+eax*4], ebx
+ jz loc_1959522
+ mov eax, [edi+TStruct14.field_10]
+ cmp eax, 0FFFFFFFFh
+ jnz short loc_1959754
+ mov eax, [edi+TStruct14.HashValue]
+ mov ecx, [ebp+pThis]
+ push eax
+ add ecx, TFileNameDatabase.FileNameIndexes
+ call TSparseArray__GetItemValue
+ jmp short loc_1959755
+; ---------------------------------------------------------------------------
+
+loc_19596E9: ; CODE XREF: TFileNameDatabase__sub_1959460+18Cj
+ mov eax, [esi+TStruct40.ItemCount]
+ cmp eax, 1
+ jz loc_1959778
+ mov ecx, [esi+TStruct40.array_18.field_4]
+ lea eax, [eax+eax*4]
+ inc dword ptr [ecx+eax*4-14h]
+ lea eax, [ecx+eax*4-14h]
+ mov eax, [esi+TStruct40.ItemCount]
+ lea edx, [eax+eax*4]
+ mov eax, [esi+TStruct40.array_18.field_4]
+ mov edi, [eax+edx*4-20h]
+ mov eax, [esi+TStruct40.array_00.MaxItemCount]
+ cmp edi, eax
+ jbe short loc_1959749
+ mov edx, edi
+ shr edx, 1
+ mov ecx, edi
+ cmp eax, edx
+ jbe short loc_1959741
+ cmp eax, 7FFFFFFFh
+ jbe short loc_195973E
+ or ecx, 0FFFFFFFFh
+ push ecx
+ mov ecx, esi
+ call TGenericArray__SetMaxItems_BYTE
+ dec [esi+TStruct40.ItemCount]
+ mov [esi+TStruct40.array_00.ItemCount], edi
+ jmp loc_1959522
+; ---------------------------------------------------------------------------
+
+loc_195973E: ; CODE XREF: TFileNameDatabase__sub_1959460+2C6j
+ lea ecx, [eax+eax]
+
+loc_1959741: ; CODE XREF: TFileNameDatabase__sub_1959460+2BFj
+ push ecx
+ mov ecx, esi
+ call TGenericArray__SetMaxItems_BYTE
+
+loc_1959749: ; CODE XREF: TFileNameDatabase__sub_1959460+2B5j
+ dec [esi+TStruct40.ItemCount]
+ mov [esi+TStruct40.array_00.ItemCount], edi
+ jmp loc_1959522
+; ---------------------------------------------------------------------------
+
+loc_1959754: ; CODE XREF: TFileNameDatabase__sub_1959460+277j
+ inc eax
+
+loc_1959755: ; CODE XREF: TFileNameDatabase__sub_1959460+287j
+ mov [edi+TStruct14.field_10], eax
+ mov ecx, [esi+TStruct40.array_00.ItemCount]
+ mov edx, [esi+TStruct40.array_00.field_4]
+ mov eax, [ebp+pStruct1C]
+ mov [eax+TMndxFindResult.szFoundPath], edx
+ mov [eax+TMndxFindResult.cchFoundPath], ecx
+ mov ecx, [edi+TStruct14.field_10]
+ pop edi
+ pop esi
+ mov [eax+TMndxFindResult.FileNameIndex], ecx
+ mov al, 1
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 4
+; ---------------------------------------------------------------------------
+
+loc_1959778: ; CODE XREF: TFileNameDatabase__sub_1959460+42j
+ ; TFileNameDatabase__sub_1959460+28Fj
+ mov [esi+TStruct40.SearchPhase], 4
+
+return_false: ; CODE XREF: TFileNameDatabase__sub_1959460+1Aj
+ pop edi
+ pop esi
+ xor al, al
+ pop ebx
+ mov esp, ebp
+ pop ebp
+ retn 4
+TFileNameDatabase__sub_1959460 endp
+
+; ---------------------------------------------------------------------------
+
+;------------------------------------------------------------------------------
+; Public functions callable from C++
+
+;
+; DWORD _cdecl sub_19573D0_x86(TFileNameDatabase * pDB, DWORD arg_0, DWORD arg_4);
+;
+
+_sub_19573D0_x86 PROC
+
+ push ebp
+ mov ebp, esp
+ mov ecx, [ebp+8] ; pDB
+ push [ebp+10h] ; arg_4
+ push [ebp+0Ch] ; arg_0
+ call sub_19573D0
+ mov esp, ebp
+ pop ebp
+ ret
+
+_sub_19573D0_x86 ENDP
+
+;
+; DWORD _cdecl sub_1957EF0_x86(TFileNameDatabase * pDB, TMndxFindResult * pStruct1C);
+;
+
+_sub_1957EF0_x86 PROC
+
+ push ebp
+ mov ebp, esp
+ mov ecx, [ebp+8] ; pDB
+ push [ebp+0Ch] ; pStruct1C
+ call TFileNameDatabase__FindFileInDatabase
+ mov esp, ebp
+ pop ebp
+ ret
+
+_sub_1957EF0_x86 ENDP
+
+;
+; bool _cdecl _sub_1959460_x86(TFileNameDatabase * pDB, TMndxFindResult * pStruct1C);
+;
+
+_sub_1959460_x86 PROC
+
+ push ebp
+ mov ebp, esp
+ mov ecx, [ebp+8] ; pDB
+ push [ebp+0Ch] ; pStruct1C
+ call TFileNameDatabase__sub_1959460
+ mov esp, ebp
+ pop ebp
+ ret
+
+_sub_1959460_x86 ENDP
+
+;
+; bool _cdecl sub_1958B00_x86(TFileNameDatabase * pDB, TMndxFindResult * pStruct1C);
+;
+
+_sub_1958B00_x86 PROC
+
+ push ebp
+ mov ebp, esp
+ mov ecx, [ebp+8] ; pDB
+ push [ebp+0Ch] ; pStruct1C
+ call TFileNameDatabase__sub_1959460
+ mov esp, ebp
+ pop ebp
+ ret
+
+_sub_1958B00_x86 ENDP
+
+;
+; DWORD _cdecl GetItemValue_x86(TSparseArray * pStruct, DWORD dwKey);
+;
+
+_GetItemValue_x86 PROC
+
+ push ebp
+ mov ebp, esp
+ mov ecx, [ebp+8] ; pStruct68
+ push [ebp+0Ch] ; dwKey
+ call TSparseArray__GetItemValue
+ mov esp, ebp
+ pop ebp
+ ret
+
+_GetItemValue_x86 ENDP
+
+;
+; DWORD _cdecl sub_1959CB0_x86(TFileNameDatabase * pDB, DWORD dwKey);
+;
+
+_sub_1959CB0_x86 PROC
+
+ push ebp
+ mov ebp, esp
+ mov ecx, [ebp+8] ; pDB
+ push [ebp+0Ch] ; dwKey
+ call TArchiveDatabase__sub_1959CB0
+ mov esp, ebp
+ pop ebp
+ ret
+
+_sub_1959CB0_x86 ENDP
+
+;
+; DWORD _cdecl sub_1959F50_x86(TFileNameDatabase * pDB, DWORD arg_0);
+;
+
+_sub_1959F50_x86 PROC
+
+ push ebp
+ mov ebp, esp
+ mov ecx, [ebp+8] ; pDB
+ push [ebp+0Ch] ; dwKey
+ call sub_1959F50
+ mov esp, ebp
+ pop ebp
+ ret
+
+_sub_1959F50_x86 ENDP
+
+END
diff --git a/dep/CascLib/src/CascOpenFile.cpp b/dep/CascLib/src/CascOpenFile.cpp
new file mode 100644
index 00000000000..e7cdb9aa107
--- /dev/null
+++ b/dep/CascLib/src/CascOpenFile.cpp
@@ -0,0 +1,440 @@
+/*****************************************************************************/
+/* CascOpenFile.cpp Copyright (c) Ladislav Zezula 2014 */
+/*---------------------------------------------------------------------------*/
+/* System-dependent directory functions for CascLib */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 01.05.14 1.00 Lad The first version of CascOpenFile.cpp */
+/*****************************************************************************/
+
+#define __CASCLIB_SELF__
+#include "CascLib.h"
+#include "CascCommon.h"
+#include "CascMndxRoot.h"
+
+//-----------------------------------------------------------------------------
+// Local structures
+
+//-----------------------------------------------------------------------------
+// Local functions
+
+TCascFile * IsValidFileHandle(HANDLE hFile)
+{
+ TCascFile * hf = (TCascFile *)hFile;
+
+ return (hf != NULL && hf->hs != NULL && hf->szClassName != NULL && !strcmp(hf->szClassName, "TCascFile")) ? hf : NULL;
+}
+
+PCASC_INDEX_ENTRY FindIndexEntry(TCascStorage * hs, PQUERY_KEY pIndexKey)
+{
+ PCASC_INDEX_ENTRY pIndexEntry = NULL;
+
+ if(hs->pIndexEntryMap != NULL)
+ pIndexEntry = (PCASC_INDEX_ENTRY)Map_FindObject(hs->pIndexEntryMap, pIndexKey->pbData);
+
+ return pIndexEntry;
+}
+
+PCASC_ENCODING_ENTRY FindEncodingEntry(TCascStorage * hs, PQUERY_KEY pEncodingKey, size_t * PtrIndex)
+{
+ PCASC_ENCODING_ENTRY pEncodingEntry;
+ size_t StartEntry = 0;
+ size_t MidlEntry;
+ size_t EndEntry = hs->nEncodingEntries;
+ int nResult;
+
+ // Perform binary search
+ while(StartEntry < EndEntry)
+ {
+ // Calculate the middle of the interval
+ MidlEntry = StartEntry + ((EndEntry - StartEntry) / 2);
+ pEncodingEntry = hs->ppEncodingEntries[MidlEntry];
+
+ // Did we find it?
+ nResult = memcmp(pEncodingKey->pbData, pEncodingEntry->EncodingKey, MD5_HASH_SIZE);
+ if(nResult == 0)
+ {
+ if(PtrIndex != NULL)
+ PtrIndex[0] = MidlEntry;
+ return pEncodingEntry;
+ }
+
+ // Move the interval to the left or right
+ (nResult < 0) ? EndEntry = MidlEntry : StartEntry = MidlEntry + 1;
+ }
+
+ // Not found, sorry
+ return NULL;
+}
+
+// Also used in CascSearchFile
+PCASC_ROOT_ENTRY FindFirstRootEntry(TCascStorage * hs, const char * szFileName, size_t * PtrIndex)
+{
+ PCASC_ROOT_ENTRY pFoundEntry = NULL;
+ PCASC_ROOT_ENTRY pRootEntry;
+ ULONGLONG FileNameHash;
+ uint32_t dwHashHigh = 0;
+ uint32_t dwHashLow = 0;
+ size_t StartEntry = 0;
+ size_t MidlEntry = 0;
+ size_t EndEntry = hs->nRootEntries;
+
+ // Calculate the HASH value of the normalized file name
+ hashlittle2(szFileName, strlen(szFileName), &dwHashHigh, &dwHashLow);
+ FileNameHash = ((ULONGLONG)dwHashHigh << 0x20) | dwHashLow;
+
+ // Perform binary search
+ while(StartEntry < EndEntry)
+ {
+ // Calculate the middle of the interval
+ MidlEntry = StartEntry + ((EndEntry - StartEntry) / 2);
+ pRootEntry = hs->ppRootEntries[MidlEntry];
+
+ // Did we find it?
+ if(pRootEntry->FileNameHash == FileNameHash)
+ {
+ pFoundEntry = pRootEntry;
+ break;
+ }
+
+ // Move the interval to the left or right
+ (FileNameHash < pRootEntry->FileNameHash) ? EndEntry = MidlEntry : StartEntry = MidlEntry + 1;
+ }
+
+ // Move the pointer back to the first entry with that hash
+ if(pFoundEntry != NULL)
+ {
+ while(MidlEntry > 0 && hs->ppRootEntries[MidlEntry - 1]->FileNameHash == FileNameHash)
+ {
+ pFoundEntry = hs->ppRootEntries[MidlEntry - 1];
+ MidlEntry--;
+ }
+ }
+
+ // Return what we found
+ if(PtrIndex != NULL)
+ *PtrIndex = MidlEntry;
+ return pFoundEntry;
+}
+
+// Check the root directory for that hash
+PCASC_ROOT_ENTRY FindRootEntryLocale(TCascStorage * hs, char * szFileName, DWORD Locale)
+{
+ PCASC_ROOT_ENTRY pThatEntry = NULL;
+ PCASC_ROOT_ENTRY pENUSEntry = NULL;
+ PCASC_ROOT_ENTRY pENGBEntry = NULL;
+ PCASC_ROOT_ENTRY pAnyEntry = NULL;
+ PCASC_ROOT_ENTRY pEndEntry = NULL;
+ PCASC_ROOT_ENTRY pRootEntry = NULL;
+ ULONGLONG FileNameHash;
+ size_t EntryIndex = 0;
+ size_t EndEntry = hs->nRootEntries;
+
+ // Find a root entry with the given name hash
+ pRootEntry = FindFirstRootEntry(hs, szFileName, &EntryIndex);
+ if(pRootEntry != NULL)
+ {
+ // Rememeber the file name hash
+ pEndEntry = hs->pRootEntries + hs->nRootEntries;
+ FileNameHash = pRootEntry->FileNameHash;
+
+ // Find all suitable root entries
+ while(EntryIndex < EndEntry)
+ {
+ // Get the root entry
+ pRootEntry = hs->ppRootEntries[EntryIndex++];
+ if(pRootEntry->FileNameHash != FileNameHash)
+ break;
+
+ // If a locale has been given, check it
+ if(pThatEntry == NULL && Locale != 0 && (Locale & pRootEntry->Locales))
+ pThatEntry = pRootEntry;
+ if(pENUSEntry == NULL && (pRootEntry->Locales & CASC_LOCALE_ENUS))
+ pENUSEntry = pRootEntry;
+ if(pENGBEntry == NULL && (pRootEntry->Locales & CASC_LOCALE_ENGB))
+ pENGBEntry = pRootEntry;
+ if(pAnyEntry == NULL)
+ pAnyEntry = pRootEntry;
+
+ // Move to the next one
+ pRootEntry++;
+ }
+
+ // Return the key by priority
+ if(pThatEntry != NULL)
+ return pThatEntry;
+ if(pENGBEntry != NULL)
+ return pENGBEntry;
+ if(pENUSEntry != NULL)
+ return pENUSEntry;
+ }
+
+ // Return whatever we got
+ return pAnyEntry;
+}
+
+static TCascFile * CreateFileHandle(TCascStorage * hs, PCASC_INDEX_ENTRY pIndexEntry)
+{
+ ULONGLONG FileOffsMask = ((ULONGLONG)1 << hs->KeyMapping[0].SegmentBits) - 1;
+ ULONGLONG FileOffset = ConvertBytesToInteger_5(pIndexEntry->FileOffset);
+ TCascFile * hf;
+
+ // Allocate the CASC file structure
+ hf = (TCascFile *)CASC_ALLOC(TCascFile, 1);
+ if(hf != NULL)
+ {
+ // Initialize the structure
+ memset(hf, 0, sizeof(TCascFile));
+ hf->ArchiveIndex = (DWORD)(FileOffset >> hs->KeyMapping[0].SegmentBits);
+ hf->HeaderOffset = (DWORD)(FileOffset & FileOffsMask);
+ hf->szClassName = "TCascFile";
+
+ // Copy the compressed file size
+ hf->CompressedSize = ConvertBytesToInteger_4_LE(pIndexEntry->FileSize) - 0x1E;
+
+ // For now, we set the file size to be equal to compressed size
+ // This is used when loading the "encoding" file, which does not
+ // have entry in the encoding itself
+ hf->FileSize = hf->CompressedSize;
+
+ // Increment the number of references to the archive
+ hs->dwRefCount++;
+ hf->hs = hs;
+ }
+
+ return hf;
+}
+
+static bool OpenFileByIndexKey(TCascStorage * hs, PQUERY_KEY pIndexKey, DWORD dwFlags, HANDLE * phFile)
+{
+ PCASC_INDEX_ENTRY pIndexEntry;
+ TCascFile * hf = NULL;
+ int nError = ERROR_SUCCESS;
+
+ CASCLIB_UNUSED(dwFlags);
+
+ // Find the key entry in the array of file keys
+ pIndexEntry = FindIndexEntry(hs, pIndexKey);
+ if(pIndexEntry == NULL)
+ nError = ERROR_FILE_NOT_FOUND;
+
+ // Create the file handle structure
+ if(nError == ERROR_SUCCESS)
+ {
+ hf = CreateFileHandle(hs, pIndexEntry);
+ *phFile = (HANDLE)hf;
+ if(hf == NULL)
+ nError = ERROR_FILE_NOT_FOUND;
+ }
+
+ if(nError != ERROR_SUCCESS)
+ SetLastError(nError);
+ return (nError == ERROR_SUCCESS);
+}
+
+static bool OpenFileByEncodingKey(TCascStorage * hs, PQUERY_KEY pEncodingKey, DWORD dwFlags, HANDLE * phFile)
+{
+ PCASC_ENCODING_ENTRY pEncodingEntry;
+ QUERY_KEY IndexKey;
+ TCascFile * hf = NULL;
+ int nError = ERROR_SUCCESS;
+
+ // Find the encoding entry
+ pEncodingEntry = FindEncodingEntry(hs, pEncodingKey, NULL);
+ if(pEncodingEntry == NULL)
+ nError = ERROR_FILE_NOT_FOUND;
+
+ // Prepare the file index and open the file by index
+ // Note: We don't know what to do if there is more than just one index key
+ // We always take the first file present. Is that correct?
+// IndexKey.pbData = pEncodingEntry->EncodingKey + (MD5_HASH_SIZE * pEncodingEntry->KeyCount);
+// assert(pEncodingEntry->KeyCount == 1);
+ IndexKey.pbData = pEncodingEntry->EncodingKey + MD5_HASH_SIZE;
+ IndexKey.cbData = MD5_HASH_SIZE;
+ if(OpenFileByIndexKey(hs, &IndexKey, dwFlags, phFile))
+ {
+ // Fix the file size from the encoding key
+ hf = IsValidFileHandle(*phFile);
+ if(hf != NULL)
+ {
+ hf->FileSize = ConvertBytesToInteger_4(pEncodingEntry->FileSizeBytes);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Public functions
+
+bool WINAPI CascOpenFileByIndexKey(HANDLE hStorage, PQUERY_KEY pIndexKey, DWORD dwFlags, HANDLE * phFile)
+{
+ TCascStorage * hs;
+
+ // Validate the storage handle
+ hs = IsValidStorageHandle(hStorage);
+ if(hs == NULL)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return false;
+ }
+
+ // Validate the other parameters
+ if(pIndexKey == NULL || pIndexKey->pbData == NULL || pIndexKey->cbData == 0 || phFile == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return false;
+ }
+
+ // Use the internal function to open the file
+ return OpenFileByIndexKey(hs, pIndexKey, dwFlags, phFile);
+}
+
+bool WINAPI CascOpenFileByEncodingKey(HANDLE hStorage, PQUERY_KEY pEncodingKey, DWORD dwFlags, HANDLE * phFile)
+{
+ TCascStorage * hs;
+
+ // Validate the storage handle
+ hs = IsValidStorageHandle(hStorage);
+ if(hs == NULL)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return false;
+ }
+
+ // Validate the other parameters
+ if(pEncodingKey == NULL || pEncodingKey->pbData == NULL || pEncodingKey->cbData == 0 || phFile == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return false;
+ }
+
+ // Use the internal function fo open the file
+ return OpenFileByEncodingKey(hs, pEncodingKey, dwFlags, phFile);
+}
+
+bool WINAPI CascOpenFile(HANDLE hStorage, const char * szFileName, DWORD dwLocale, DWORD dwFlags, HANDLE * phFile)
+{
+ CASC_ROOT_KEY_INFO EncodingKeyInfo;
+ PCASC_ROOT_ENTRY pRootEntry;
+ PCASC_PACKAGE pPackage;
+ TCascStorage * hs;
+ QUERY_KEY EncodingKey;
+ char * szStrippedName;
+ char * szFileName2;
+ int nError = ERROR_SUCCESS;
+
+ // Validate the storage handle
+ hs = IsValidStorageHandle(hStorage);
+ if(hs == NULL)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return false;
+ }
+
+ // Validate the other parameters
+ if(szFileName == NULL || szFileName[0] == 0 || phFile == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return false;
+ }
+
+ // Create the copy of the file name
+ szFileName2 = NewStr(szFileName, 0);
+ if(szFileName2 != NULL)
+ {
+ // If the storage has a MNDX root directory, use it to search the entry
+ if(hs->pMndxInfo != NULL)
+ {
+ // Convert the file name to lowercase + slashes
+ NormalizeFileName_LowerSlash(szFileName2);
+
+ // Find the package number
+ pPackage = FindMndxPackage(hs, szFileName2);
+ if(pPackage != NULL)
+ {
+ // Cut the package name off the full path
+ szStrippedName = szFileName2 + pPackage->nLength;
+ while(szStrippedName[0] == '/')
+ szStrippedName++;
+
+ nError = SearchMndxInfo(hs->pMndxInfo, szStrippedName, (DWORD)(pPackage - hs->pPackages->Packages), &EncodingKeyInfo);
+ if(nError == ERROR_SUCCESS)
+ {
+ // Prepare the encoding key
+ EncodingKey.pbData = EncodingKeyInfo.EncodingKey;
+ EncodingKey.cbData = MD5_HASH_SIZE;
+ }
+ }
+ else
+ {
+ nError = ERROR_FILE_NOT_FOUND;
+ }
+ }
+ else
+ {
+ // Convert the file name to lowercase + slashes
+ NormalizeFileName_UpperBkSlash(szFileName2);
+
+ // Check the root directory for that hash
+ pRootEntry = FindRootEntryLocale(hs, szFileName2, dwLocale);
+ nError = (pRootEntry != NULL) ? ERROR_SUCCESS : ERROR_FILE_NOT_FOUND;
+ if(pRootEntry != NULL)
+ {
+ // Prepare the root key
+ EncodingKey.pbData = pRootEntry->EncodingKey;
+ EncodingKey.cbData = MD5_HASH_SIZE;
+ }
+ }
+
+ // Use the root key to find the file in the encoding table entry
+ if(nError == ERROR_SUCCESS)
+ {
+ if(!OpenFileByEncodingKey(hs, &EncodingKey, dwFlags, phFile))
+ {
+ assert(GetLastError() != ERROR_SUCCESS);
+ nError = GetLastError();
+ }
+ }
+
+ // Delete the file name copy
+ delete [] szFileName2;
+ }
+ else
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+
+ if(nError != ERROR_SUCCESS)
+ SetLastError(nError);
+ return (nError == ERROR_SUCCESS);
+}
+
+bool WINAPI CascCloseFile(HANDLE hFile)
+{
+ TCascFile * hf;
+
+ hf = IsValidFileHandle(hFile);
+ if(hf != NULL)
+ {
+ // Close (dereference) the archive handle
+ if(hf->hs != NULL)
+ CascCloseStorage((HANDLE)hf->hs);
+ hf->hs = NULL;
+
+ // Free the file cache and frame array
+ if(hf->pbFileCache != NULL)
+ CASC_FREE(hf->pbFileCache);
+ if(hf->pFrames != NULL)
+ CASC_FREE(hf->pFrames);
+
+ // Free the structure itself
+ hf->szClassName = NULL;
+ CASC_FREE(hf);
+ return true;
+ }
+
+ SetLastError(ERROR_INVALID_HANDLE);
+ return false;
+}
+
diff --git a/dep/CascLib/src/CascOpenStorage.cpp b/dep/CascLib/src/CascOpenStorage.cpp
new file mode 100644
index 00000000000..f9e6ba6f4d4
--- /dev/null
+++ b/dep/CascLib/src/CascOpenStorage.cpp
@@ -0,0 +1,1226 @@
+/*****************************************************************************/
+/* CascOpenStorage.cpp Copyright (c) Ladislav Zezula 2014 */
+/*---------------------------------------------------------------------------*/
+/* Storage functions for CASC */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 29.04.14 1.00 Lad The first version of CascOpenStorage.cpp */
+/*****************************************************************************/
+
+#define __CASCLIB_SELF__
+#include "CascLib.h"
+#include "CascCommon.h"
+#include "CascMndxRoot.h"
+
+//-----------------------------------------------------------------------------
+// Local structures
+
+#define CASC_ENCODING_SEGMENT_SIZE 0x1000
+
+typedef struct _BLOCK_SIZE_AND_HASH
+{
+ DWORD cbBlockSize;
+ DWORD dwBlockHash;
+
+} BLOCK_SIZE_AND_HASH, *PBLOCK_SIZE_AND_HASH;
+
+typedef struct _FILE_INDEX_HEADER_V1
+{
+ USHORT field_0;
+ BYTE KeyIndex; // Key index (0 for data.i0x, 1 for data.i1x, 2 for data.i2x etc.)
+ BYTE align_3;
+ DWORD field_4;
+ ULONGLONG field_8;
+ ULONGLONG MaxFileOffset;
+ BYTE SpanSizeBytes;
+ BYTE SpanOffsBytes;
+ BYTE KeyBytes;
+ BYTE SegmentBits; // Number of bits for file offset
+ DWORD KeyCount1;
+ DWORD KeyCount2;
+ DWORD KeysHash1;
+ DWORD KeysHash2;
+ DWORD dwHeaderHash;
+} FILE_INDEX_HEADER_V1, *PFILE_INDEX_HEADER_V1;
+
+typedef struct _FILE_INDEX_HEADER_V2
+{
+ USHORT IndexVersion; // Must be 0x07
+ BYTE KeyIndex; // Must be equal to the file key index
+ BYTE ExtraBytes; // (?) Extra bytes in the key record
+ BYTE SpanSizeBytes; // Size of field with file size
+ BYTE SpanOffsBytes; // Size of field with file offset
+ BYTE KeyBytes; // Size of the file key (bytes)
+ BYTE SegmentBits; // Number of bits for the file offset (rest is archive index)
+ ULONGLONG MaxFileOffset;
+
+} FILE_INDEX_HEADER_V2, *PFILE_INDEX_HEADER_V2;
+
+typedef struct _FILE_ENCODING_HEADER
+{
+ BYTE Magic[2]; // "EN"
+ BYTE field_2;
+ BYTE field_3;
+ BYTE field_4;
+ BYTE field_5[2];
+ BYTE field_7[2];
+ BYTE NumSegments[4]; // Number of entries (big endian)
+ BYTE field_D[4];
+ BYTE field_11;
+ BYTE SegmentsPos[4]; // Offset of encoding segments
+
+} FILE_ENCODING_HEADER, *PFILE_ENCODING_HEADER;
+
+typedef struct _FILE_ENCODING_SEGMENT
+{
+ BYTE FirstEncodingKey[MD5_HASH_SIZE]; // The first encoding key in the segment
+ BYTE SegmentHash[MD5_HASH_SIZE]; // MD5 hash of the entire segment
+
+} FILE_ENCODING_SEGMENT, *PFILE_ENCODING_SEGMENT;
+
+typedef struct _FILE_LOCALE_BLOCK
+{
+ DWORD NumberOfFiles; // Number of entries
+ DWORD Flags;
+ DWORD Locales; // File locale mask (CASC_LOCALE_XXX)
+
+ // Followed by a block of 32-bit integers (count: NumberOfFiles)
+ // Followed by the MD5 and file name hash (count: NumberOfFiles)
+
+} FILE_LOCALE_BLOCK, *PFILE_LOCALE_BLOCK;
+
+typedef struct _FILE_ROOT_ENTRY
+{
+ BYTE EncodingKey[MD5_HASH_SIZE]; // MD5 of the file
+ ULONGLONG FileNameHash; // Jenkins hash of the file name
+
+} FILE_ROOT_ENTRY, *PFILE_ROOT_ENTRY;
+
+typedef struct _ROOT_BLOCK_INFO
+{
+ PFILE_LOCALE_BLOCK pLocaleBlockHdr; // Pointer to the locale block
+ PDWORD pInt32Array; // Pointer to the array of 32-bit integers
+ PFILE_ROOT_ENTRY pRootEntries;
+
+} ROOT_BLOCK_INFO, *PROOT_BLOCK_INFO;
+
+//-----------------------------------------------------------------------------
+// Local variables
+
+static const TCHAR * szAllowedHexChars = _T("0123456789aAbBcCdDeEfF");
+static const TCHAR * szIndexFormat_V1 = _T("data.i%x%x");
+static const TCHAR * szIndexFormat_V2 = _T("%02x%08x.idx");
+
+//-----------------------------------------------------------------------------
+// Local functions
+
+inline void CopyFileKey(LPBYTE Trg, LPBYTE Src)
+{
+ Trg[0x00] = Src[0x00];
+ Trg[0x01] = Src[0x01];
+ Trg[0x02] = Src[0x02];
+ Trg[0x03] = Src[0x03];
+ Trg[0x04] = Src[0x04];
+ Trg[0x05] = Src[0x05];
+ Trg[0x06] = Src[0x06];
+ Trg[0x07] = Src[0x07];
+ Trg[0x08] = Src[0x08];
+ Trg[0x09] = Src[0x09];
+ Trg[0x0A] = Src[0x0A];
+ Trg[0x0B] = Src[0x0B];
+ Trg[0x0C] = Src[0x0C];
+ Trg[0x0D] = Src[0x0D];
+ Trg[0x0E] = Src[0x0E];
+ Trg[0x0F] = Src[0x0F];
+}
+
+TCascStorage * IsValidStorageHandle(HANDLE hStorage)
+{
+ TCascStorage * hs = (TCascStorage *)hStorage;
+
+ return (hs != NULL && hs->szClassName != NULL && !strcmp(hs->szClassName, "TCascStorage")) ? hs : NULL;
+}
+
+// "data.iXY"
+static bool IsIndexFileName_V1(const TCHAR * szFileName)
+{
+ // Check if the name looks like a valid index file
+ return (_tcslen(szFileName) == 8 &&
+ _tcsnicmp(szFileName, _T("data.i"), 6) == 0 &&
+ _tcsspn(szFileName + 6, szAllowedHexChars) == 2);
+}
+
+static bool IsIndexFileName_V2(const TCHAR * szFileName)
+{
+ // Check if the name looks like a valid index file
+ return (_tcslen(szFileName) == 14 &&
+ _tcsspn(szFileName, _T("0123456789aAbBcCdDeEfF")) == 0x0A &&
+ _tcsicmp(szFileName + 0x0A, _T(".idx")) == 0);
+}
+
+static void QUERY_KEY_Free(PQUERY_KEY pBlob)
+{
+ if(pBlob != NULL)
+ {
+ if(pBlob->pbData != NULL)
+ CASC_FREE(pBlob->pbData);
+
+ pBlob->pbData = NULL;
+ pBlob->cbData = 0;
+ }
+}
+
+static void QUERY_KEY_FreeArray(PQUERY_KEY pBlobArray)
+{
+ // Free the buffer in the first blob
+ // (will also free all buffers in the array)
+ QUERY_KEY_Free(pBlobArray);
+
+ // Free the array itself
+ CASC_FREE(pBlobArray);
+}
+
+static int CompareRootEntries(const void *, const void * pvKeyEntry1, const void * pvKeyEntry2)
+{
+ PCASC_ROOT_ENTRY pRootEntry1 = (PCASC_ROOT_ENTRY)pvKeyEntry1;
+ PCASC_ROOT_ENTRY pRootEntry2 = (PCASC_ROOT_ENTRY)pvKeyEntry2;
+
+ // Compare name hash first
+ if(pRootEntry1->FileNameHash < pRootEntry2->FileNameHash)
+ return -1;
+ if(pRootEntry1->FileNameHash > pRootEntry2->FileNameHash)
+ return +1;
+ return 0;
+}
+
+static bool IsCascIndexHeader_V1(LPBYTE pbFileData, DWORD cbFileData)
+{
+ PFILE_INDEX_HEADER_V1 pIndexHeader = (PFILE_INDEX_HEADER_V1)pbFileData;
+ DWORD dwHeaderHash;
+ bool bResult = false;
+
+ // Check the size
+ if(cbFileData >= sizeof(FILE_INDEX_HEADER_V1))
+ {
+ // Save the header hash
+ dwHeaderHash = pIndexHeader->dwHeaderHash;
+ pIndexHeader->dwHeaderHash = 0;
+
+ // Calculate the hash
+ if(hashlittle(pIndexHeader, sizeof(FILE_INDEX_HEADER_V1), 0) == dwHeaderHash)
+ bResult = true;
+
+ // Put the hash back
+ pIndexHeader->dwHeaderHash = dwHeaderHash;
+ }
+
+ return bResult;
+}
+
+static bool IsCascIndexHeader_V2(LPBYTE pbFileData, DWORD cbFileData)
+{
+ PBLOCK_SIZE_AND_HASH pSizeAndHash = (PBLOCK_SIZE_AND_HASH)pbFileData;
+ unsigned int HashHigh = 0;
+ unsigned int HashLow = 0;
+
+ // Check for the header
+ if(cbFileData < sizeof(BLOCK_SIZE_AND_HASH) || pSizeAndHash->cbBlockSize < 0x10)
+ return false;
+ if(cbFileData < pSizeAndHash->cbBlockSize + sizeof(BLOCK_SIZE_AND_HASH))
+ return false;
+
+ // The index header for CASC v 2.0 begins with length and checksum
+ hashlittle2(pSizeAndHash + 1, pSizeAndHash->cbBlockSize, &HashHigh, &HashLow);
+ return (HashHigh == pSizeAndHash->dwBlockHash);
+}
+
+static LPBYTE VerifyLocaleBlock(PROOT_BLOCK_INFO pBlockInfo, LPBYTE pbFilePointer, LPBYTE pbFileEnd)
+{
+ // Validate the locale header
+ pBlockInfo->pLocaleBlockHdr = (PFILE_LOCALE_BLOCK)pbFilePointer;
+ pbFilePointer += sizeof(FILE_LOCALE_BLOCK);
+ if(pbFilePointer >= pbFileEnd)
+ return NULL;
+
+ // Validate the array of 32-bit integers
+ pBlockInfo->pInt32Array = (PDWORD)pbFilePointer;
+ pbFilePointer = (LPBYTE)(pBlockInfo->pInt32Array + pBlockInfo->pLocaleBlockHdr->NumberOfFiles);
+ if(pbFilePointer >= pbFileEnd)
+ return NULL;
+
+ // Validate the array of root entries
+ pBlockInfo->pRootEntries = (PFILE_ROOT_ENTRY)pbFilePointer;
+ pbFilePointer = (LPBYTE)(pBlockInfo->pRootEntries + pBlockInfo->pLocaleBlockHdr->NumberOfFiles);
+ if(pbFilePointer > pbFileEnd)
+ return NULL;
+
+ // Return the position of the next block
+ return pbFilePointer;
+}
+
+static int InitializeCascDirectories(TCascStorage * hs, const TCHAR * szDataPath)
+{
+ TCHAR * szLastPathPart;
+
+ // Save the game data directory
+ hs->szDataPath = NewStr(szDataPath, 0);
+
+ // Save the root game directory
+ hs->szRootPath = NewStr(szDataPath, 0);
+
+ // Find the last part
+ szLastPathPart = hs->szRootPath;
+ for(size_t i = 0; hs->szRootPath[i] != 0; i++)
+ {
+ if(hs->szRootPath[i] == '\\' || hs->szRootPath[i] == '/')
+ szLastPathPart = hs->szRootPath + i;
+ }
+
+ // Cut the last part
+ if(szLastPathPart != NULL)
+ szLastPathPart[0] = 0;
+ return (hs->szRootPath && hs->szDataPath) ? ERROR_SUCCESS : ERROR_NOT_ENOUGH_MEMORY;
+}
+
+static bool IndexDirectory_OnFileFound(
+ const TCHAR * szFileName,
+ PDWORD IndexArray,
+ PDWORD OldIndexArray,
+ void * pvContext)
+{
+ TCascStorage * hs = (TCascStorage *)pvContext;
+ DWORD IndexValue = 0;
+ DWORD IndexVersion = 0;
+
+ // Auto-detect the format of the index file name
+ if(hs->szIndexFormat == NULL)
+ {
+ if(IsIndexFileName_V1(szFileName))
+ hs->szIndexFormat = szIndexFormat_V1;
+ else if(IsIndexFileName_V2(szFileName))
+ hs->szIndexFormat = szIndexFormat_V2;
+ else
+ return false;
+ }
+
+ if(hs->szIndexFormat == szIndexFormat_V1)
+ {
+ // Check the index file name format
+ if(!IsIndexFileName_V1(szFileName))
+ return false;
+
+ // Get the main index from the first two digits
+ if(ConvertDigitToInt32(szFileName + 6, &IndexValue) != ERROR_SUCCESS)
+ return false;
+ if(ConvertDigitToInt32(szFileName + 7, &IndexVersion) != ERROR_SUCCESS)
+ return false;
+ }
+
+ else if(hs->szIndexFormat == szIndexFormat_V2)
+ {
+ // Check the index file name format
+ if(!IsIndexFileName_V2(szFileName))
+ return false;
+
+ // Get the main index from the first two digits
+ if(ConvertStringToInt32(szFileName, 2, &IndexValue) != ERROR_SUCCESS)
+ return false;
+ if(ConvertStringToInt32(szFileName + 2, 8, &IndexVersion) != ERROR_SUCCESS)
+ return false;
+ }
+ else
+ {
+ // Should never happen
+ assert(false);
+ return false;
+ }
+
+ // The index value must not be greater than 0x0F
+ if(IndexValue >= CASC_INDEX_COUNT)
+ return false;
+
+ // If the new subindex is greater than the previous one,
+ // use this one instead
+ if(IndexVersion > IndexArray[IndexValue])
+ {
+ OldIndexArray[IndexValue] = IndexArray[IndexValue];
+ IndexArray[IndexValue] = IndexVersion;
+ }
+ else if(IndexVersion > OldIndexArray[IndexValue])
+ {
+ OldIndexArray[IndexValue] = IndexVersion;
+ }
+
+ // Note: WoW6 only keeps last two index files
+ // Any additional index files are deleted at this point
+ return true;
+}
+
+static TCHAR * CreateIndexFileName(TCascStorage * hs, DWORD IndexValue, DWORD IndexVersion)
+{
+ TCHAR szPlainName[0x40];
+
+ // Sanity checks
+ assert(hs->szIndexFormat != NULL);
+ assert(hs->szIndexPath != NULL);
+ assert(IndexValue <= 0x0F);
+
+ // Create the full path
+ _stprintf(szPlainName, hs->szIndexFormat, IndexValue, IndexVersion);
+ return CombinePath(hs->szIndexPath, szPlainName);
+}
+
+static int VerifyAndParseKeyMapping_V1(PCASC_MAPPING_TABLE pKeyMapping, DWORD KeyIndex)
+{
+ PFILE_INDEX_HEADER_V1 pIndexHeader = (PFILE_INDEX_HEADER_V1)pKeyMapping->pbFileData;
+ DWORD dwDataHash1;
+ DWORD dwDataHash2;
+
+ // Verify the format
+ if(pIndexHeader->field_0 != 0x0005)
+ return ERROR_NOT_SUPPORTED;
+ if(pIndexHeader->KeyIndex != KeyIndex)
+ return ERROR_NOT_SUPPORTED;
+ if(pIndexHeader->field_8 == 0)
+ return ERROR_NOT_SUPPORTED;
+
+ // Verofy the bit counts
+ if(pIndexHeader->SpanSizeBytes != 0x04 ||
+ pIndexHeader->SpanOffsBytes != 0x05 ||
+ pIndexHeader->KeyBytes != 0x09)
+ return ERROR_NOT_SUPPORTED;
+
+ pKeyMapping->ExtraBytes = 0;
+ pKeyMapping->SpanSizeBytes = pIndexHeader->SpanSizeBytes;
+ pKeyMapping->SpanOffsBytes = pIndexHeader->SpanOffsBytes;
+ pKeyMapping->KeyBytes = pIndexHeader->KeyBytes;
+ pKeyMapping->SegmentBits = pIndexHeader->SegmentBits;
+ pKeyMapping->MaxFileOffset = pIndexHeader->MaxFileOffset;
+
+ // Get the pointer to the key entry array
+ pKeyMapping->nIndexEntries = pIndexHeader->KeyCount1 + pIndexHeader->KeyCount2;
+ if(pKeyMapping->nIndexEntries != 0)
+ pKeyMapping->pIndexEntries = (PCASC_INDEX_ENTRY)(pKeyMapping->pbFileData + sizeof(FILE_INDEX_HEADER_V1));
+
+ // Verify hashes
+ dwDataHash1 = hashlittle(pKeyMapping->pIndexEntries, pIndexHeader->KeyCount1 * sizeof(CASC_INDEX_ENTRY), 0);
+ dwDataHash2 = hashlittle(pKeyMapping->pIndexEntries + pIndexHeader->KeyCount1, pIndexHeader->KeyCount2 * sizeof(CASC_INDEX_ENTRY), 0);
+ if(dwDataHash1 != pIndexHeader->KeysHash1 || dwDataHash2 != pIndexHeader->KeysHash2)
+ return ERROR_FILE_CORRUPT;
+
+ return ERROR_SUCCESS;
+}
+
+static int VerifyAndParseKeyMapping_V2(PCASC_MAPPING_TABLE pKeyMapping, DWORD KeyIndex)
+{
+ PFILE_INDEX_HEADER_V2 pIndexHeader = (PFILE_INDEX_HEADER_V2)pKeyMapping->pbFileData;
+ PBLOCK_SIZE_AND_HASH pSizeAndHash;
+ LPBYTE pbLastPartEnd;
+ LPBYTE pbLastPart;
+ DWORD FilePosition;
+ DWORD LastPartLength;
+ unsigned int HashHigh = 0;
+ unsigned int HashLow = 0;
+
+ // The index header v2 begins after the SizeAndHash
+ pSizeAndHash = (PBLOCK_SIZE_AND_HASH)pKeyMapping->pbFileData;
+ pIndexHeader = (PFILE_INDEX_HEADER_V2)(pSizeAndHash + 1);
+ if(pIndexHeader->IndexVersion != 0x07 || pIndexHeader->KeyIndex != KeyIndex)
+ return ERROR_BAD_FORMAT;
+
+ if(pIndexHeader->ExtraBytes != 0x00 ||
+ pIndexHeader->SpanSizeBytes != 0x04 ||
+ pIndexHeader->SpanOffsBytes != 0x05 ||
+ pIndexHeader->KeyBytes != CASC_FILE_KEY_SIZE)
+ return ERROR_BAD_FORMAT;
+
+ // Remember the sizes
+ pKeyMapping->ExtraBytes = pIndexHeader->ExtraBytes;
+ pKeyMapping->SpanSizeBytes = pIndexHeader->SpanSizeBytes;
+ pKeyMapping->SpanOffsBytes = pIndexHeader->SpanOffsBytes;
+ pKeyMapping->KeyBytes = pIndexHeader->KeyBytes;
+ pKeyMapping->SegmentBits = pIndexHeader->SegmentBits;
+ pKeyMapping->MaxFileOffset = pIndexHeader->MaxFileOffset;
+
+ // Get the data position
+ FilePosition = (sizeof(BLOCK_SIZE_AND_HASH) + pSizeAndHash->cbBlockSize + 0x0F) & 0xFFFFFFF0;
+ if((FilePosition + 0x08) > pKeyMapping->cbFileData)
+ return ERROR_BAD_FORMAT;
+
+ // Get the pointer to "size+hash" block
+ pSizeAndHash = (PBLOCK_SIZE_AND_HASH)(pKeyMapping->pbFileData + FilePosition);
+ FilePosition += 0x08;
+
+ if((FilePosition + pSizeAndHash->cbBlockSize) > pKeyMapping->cbFileData)
+ return ERROR_BAD_FORMAT;
+ if(pSizeAndHash->cbBlockSize < sizeof(CASC_INDEX_ENTRY))
+ return ERROR_BAD_FORMAT;
+
+ // Remember the array of file keys
+ pKeyMapping->pIndexEntries = (PCASC_INDEX_ENTRY)(pKeyMapping->pbFileData + FilePosition);
+ pKeyMapping->nIndexEntries = pSizeAndHash->cbBlockSize / sizeof(CASC_INDEX_ENTRY);
+ FilePosition += pSizeAndHash->cbBlockSize;
+
+ // Verify the integrity of the key array
+ for(DWORD i = 0; i < pKeyMapping->nIndexEntries; i++)
+ hashlittle2(pKeyMapping->pIndexEntries + i, sizeof(CASC_INDEX_ENTRY), &HashHigh, &HashLow);
+ if(HashHigh != pSizeAndHash->dwBlockHash)
+ return ERROR_BAD_FORMAT;
+
+ // Align the data position up to next 0x1000
+ FilePosition = ALIGN_TO_SIZE(FilePosition, 0x1000);
+ if(FilePosition > pKeyMapping->cbFileData)
+ return ERROR_BAD_FORMAT;
+
+ LastPartLength = pKeyMapping->cbFileData - FilePosition;
+ if(LastPartLength < 0x7800)
+ return ERROR_BAD_FORMAT;
+
+ pbLastPart = pKeyMapping->pbFileData + FilePosition;
+ pbLastPartEnd = pbLastPart + ((LastPartLength >> 0x09) << 0x09);
+
+ while(pbLastPart < pbLastPartEnd)
+ {
+ for(int i = 0; i < 0x1F8; i += 0x18)
+ {
+ PDWORD PtrLastPart = (PDWORD)pbLastPart;
+ if(PtrLastPart[0] == 0)
+ return ERROR_SUCCESS;
+
+ HashLow = hashlittle(PtrLastPart + 1, 0x13, 0) | 0x80000000;
+ if(HashLow != PtrLastPart[0])
+ return ERROR_BAD_FORMAT;
+ }
+
+ pbLastPart += 0x200;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+static int VerifyAndParseKeyMapping(PCASC_MAPPING_TABLE pKeyMapping, DWORD KeyIndex)
+{
+ // Sanity checks
+ assert(pKeyMapping->pbFileData != NULL);
+ assert(pKeyMapping->cbFileData != 0);
+
+ // Check for CASC version 2
+ if(IsCascIndexHeader_V2(pKeyMapping->pbFileData, pKeyMapping->cbFileData))
+ return VerifyAndParseKeyMapping_V2(pKeyMapping, KeyIndex);
+
+ // Check for CASC version 1
+ if(IsCascIndexHeader_V1(pKeyMapping->pbFileData, pKeyMapping->cbFileData))
+ return VerifyAndParseKeyMapping_V1(pKeyMapping, KeyIndex);
+
+ // Unknown CASC version
+ assert(false);
+ return ERROR_BAD_FORMAT;
+}
+
+static int LoadKeyMapping(PCASC_MAPPING_TABLE pKeyMapping, DWORD KeyIndex)
+{
+ TFileStream * pStream;
+ ULONGLONG FileSize = 0;
+ int nError = ERROR_SUCCESS;
+
+ // Sanity checks
+ assert(pKeyMapping->szFileName != NULL && pKeyMapping->szFileName[0] != 0);
+
+ // Open the stream for read-only access and read the file
+ pStream = FileStream_OpenFile(pKeyMapping->szFileName, STREAM_FLAG_READ_ONLY | STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE);
+ if(pStream != NULL)
+ {
+ // Retrieve the file size
+ FileStream_GetSize(pStream, &FileSize);
+ if((0 < FileSize && FileSize <= 0x90000) || 1)
+ {
+ // WoW6 actually reads THE ENTIRE file to memory
+ // Verified on Mac build (x64)
+ pKeyMapping->pbFileData = CASC_ALLOC(BYTE, (DWORD)FileSize);
+ pKeyMapping->cbFileData = (DWORD)FileSize;
+
+ // Load the data to memory and parse it
+ if(pKeyMapping->pbFileData != NULL)
+ {
+ if(FileStream_Read(pStream, NULL, pKeyMapping->pbFileData, pKeyMapping->cbFileData))
+ {
+ nError = VerifyAndParseKeyMapping(pKeyMapping, KeyIndex);
+ }
+ }
+ else
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+ else
+ {
+ assert(false);
+ nError = ERROR_BAD_FORMAT;
+ }
+
+ // Close the file stream
+ FileStream_Close(pStream);
+ }
+ else
+ nError = GetLastError();
+
+ return ERROR_SUCCESS;
+}
+
+static int CreateArrayOfIndexEntries(TCascStorage * hs)
+{
+ PCASC_MAP pMap;
+ DWORD TotalCount = 0;
+ int nError = ERROR_NOT_ENOUGH_MEMORY;
+
+ // Count the total number of files in the storage
+ for(size_t i = 0; i < CASC_INDEX_COUNT; i++)
+ TotalCount += hs->KeyMapping[i].nIndexEntries;
+
+ // Create the map of all index entries
+ pMap = Map_Create(TotalCount, CASC_FILE_KEY_SIZE, FIELD_OFFSET(CASC_INDEX_ENTRY, IndexKey));
+ if(pMap != NULL)
+ {
+ // Put all index entries in the map
+ for(size_t i = 0; i < CASC_INDEX_COUNT; i++)
+ {
+ PCASC_INDEX_ENTRY pIndexEntry = hs->KeyMapping[i].pIndexEntries;
+ DWORD nIndexEntries = hs->KeyMapping[i].nIndexEntries;
+
+ for(DWORD j = 0; j < nIndexEntries; j++)
+ {
+ // Insert the index entry to the map
+ // Note that duplicate entries will not be inserted to the map
+ //
+ // Duplicate entries in WoW-WOD build 18179:
+ // 9e dc a7 8f e2 09 ad d8 b7 (encoding file)
+ // f3 5e bb fb d1 2b 3f ef 8b
+ // c8 69 9f 18 a2 5e df 7e 52
+ Map_InsertObject(pMap, pIndexEntry->IndexKey);
+
+ // Move to the next entry
+ pIndexEntry++;
+ }
+ }
+
+ // Store the map to the storage handle
+ hs->pIndexEntryMap = pMap;
+ nError = ERROR_SUCCESS;
+ }
+
+ return nError;
+}
+
+static int CreateMapOfEncodingKeys(TCascStorage * hs, PFILE_ENCODING_SEGMENT pEncodingSegment, DWORD dwNumberOfSegments)
+{
+ PCASC_ENCODING_ENTRY pEncodingEntry;
+ size_t nMaxEntries;
+ size_t nEntries = 0;
+ int nError = ERROR_SUCCESS;
+
+ // Sanity check
+ assert(hs->ppEncodingEntries == NULL);
+ assert(hs->pIndexEntryMap != NULL);
+
+ // Calculate the largest eventual number of encodign entries
+ nMaxEntries = (dwNumberOfSegments * CASC_ENCODING_SEGMENT_SIZE) / (sizeof(CASC_ENCODING_ENTRY) + MD5_HASH_SIZE);
+
+ // Allocate the array of pointers to encoding entries
+ hs->ppEncodingEntries = CASC_ALLOC(PCASC_ENCODING_ENTRY, nMaxEntries);
+ if(hs->ppEncodingEntries != NULL)
+ {
+ LPBYTE pbStartOfSegment = (LPBYTE)(pEncodingSegment + dwNumberOfSegments);
+
+ // Parse all segments
+ for(DWORD i = 0; i < dwNumberOfSegments; i++)
+ {
+ LPBYTE pbEncodingEntry = pbStartOfSegment;
+ LPBYTE pbEndOfSegment = pbStartOfSegment + CASC_ENCODING_SEGMENT_SIZE - sizeof(CASC_ENCODING_ENTRY) - MD5_HASH_SIZE;
+
+ // Parse all encoding entries
+ while(pbEncodingEntry <= pbEndOfSegment)
+ {
+ // Get pointer to the encoding entry
+ pEncodingEntry = (PCASC_ENCODING_ENTRY)pbEncodingEntry;
+ if(pEncodingEntry->KeyCount == 0)
+ break;
+
+ // Insert the pointer the array
+ hs->ppEncodingEntries[nEntries++] = pEncodingEntry;
+
+ // Move to the next encoding entry
+ pbEncodingEntry += sizeof(CASC_ENCODING_ENTRY) + (pEncodingEntry->KeyCount * MD5_HASH_SIZE);
+ }
+
+ // Move to the next segment
+ pbStartOfSegment += CASC_ENCODING_SEGMENT_SIZE;
+ }
+
+ // Remember the total number of encoding entries
+ hs->nEncodingEntries = nEntries;
+ }
+ else
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+
+ return nError;
+}
+
+static DWORD GetSizeOfEncodingFile(HANDLE hFile)
+{
+ CASC_ENCODING_HEADER EncodingHeader;
+ DWORD cbEncodingFile = 0;
+ DWORD dwSegmentPos;
+ DWORD dwNumSegments;
+ DWORD dwBytesRead;
+
+ // Read the endoding header
+ CascReadFile(hFile, &EncodingHeader, sizeof(CASC_ENCODING_HEADER), &dwBytesRead);
+ if(dwBytesRead == sizeof(CASC_ENCODING_HEADER))
+ {
+ dwNumSegments = ConvertBytesToInteger_4(EncodingHeader.NumSegments);
+ dwSegmentPos = ConvertBytesToInteger_4(EncodingHeader.SegmentsPos);
+
+ cbEncodingFile = sizeof(CASC_ENCODING_HEADER) +
+ dwSegmentPos +
+ dwNumSegments * (sizeof(FILE_ENCODING_SEGMENT) + CASC_ENCODING_SEGMENT_SIZE);
+ }
+
+ // Reset the position back
+ CascSetFilePointer(hFile, 0, NULL, FILE_BEGIN);
+ return cbEncodingFile;
+}
+
+static LPBYTE LoadCascFile(HANDLE hFile, DWORD cbMaxSize, PDWORD pcbFileData)
+{
+ LPBYTE pbFileData = NULL;
+ DWORD cbFileData;
+ DWORD dwBytesRead = 0;
+ int nError = ERROR_SUCCESS;
+
+ // Retrieve the size of the file
+ cbFileData = CascGetFileSize(hFile, NULL);
+ if(cbFileData != 0 && cbFileData != CASC_INVALID_SIZE)
+ {
+ // Trim the size to the maximum
+ cbFileData = CASCLIB_MIN(cbMaxSize, cbFileData);
+
+ // Allocate the buffer that will hold the entire file
+ pbFileData = CASC_ALLOC(BYTE, cbFileData);
+ if(pbFileData != NULL)
+ {
+ // Read the entire file to memory
+ CascReadFile(hFile, pbFileData, cbFileData, &dwBytesRead);
+ if(dwBytesRead != cbFileData)
+ nError = ERROR_FILE_CORRUPT;
+ }
+ else
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+ else
+ nError = ERROR_FILE_CORRUPT;
+
+ // If something failed, clean-up the buffers
+ if(nError != ERROR_SUCCESS)
+ {
+ // Clear the file data
+ if(pbFileData != NULL)
+ CASC_FREE(pbFileData);
+ pbFileData = NULL;
+ cbFileData = 0;
+
+ // Set the last error value
+ SetLastError(nError);
+ }
+
+ // Return what we got
+ if(pcbFileData != NULL)
+ *pcbFileData = cbFileData;
+ return pbFileData;
+}
+
+static int LoadIndexFiles(TCascStorage * hs)
+{
+ DWORD IndexArray[CASC_INDEX_COUNT];
+ DWORD OldIndexArray[CASC_INDEX_COUNT];
+ int nError;
+ int i;
+
+ // Scan all index files
+ memset(IndexArray, 0, sizeof(IndexArray));
+ memset(OldIndexArray, 0, sizeof(OldIndexArray));
+ nError = ScanIndexDirectory(hs->szIndexPath, IndexDirectory_OnFileFound, IndexArray, OldIndexArray, hs);
+ if(nError == ERROR_SUCCESS)
+ {
+ // Load each index file
+ for(i = 0; i < CASC_INDEX_COUNT; i++)
+ {
+ hs->KeyMapping[i].szFileName = CreateIndexFileName(hs, i, IndexArray[i]);
+ if(hs->KeyMapping[i].szFileName != NULL)
+ {
+ nError = LoadKeyMapping(&hs->KeyMapping[i], i);
+ if(nError != ERROR_SUCCESS)
+ break;
+ }
+ }
+ }
+
+ // Now we need to build the map of the index entries
+ if(nError == ERROR_SUCCESS)
+ {
+ nError = CreateArrayOfIndexEntries(hs);
+ }
+
+ return nError;
+}
+
+static int LoadEncodingFile(TCascStorage * hs)
+{
+ PFILE_ENCODING_SEGMENT pEncodingSegment;
+ PCASC_ENCODING_ENTRY pEncodingEntry;
+ LPBYTE pbStartOfSegment;
+ LPBYTE pbEncodingFile = NULL;
+ HANDLE hFile = NULL;
+ DWORD cbEncodingFile = 0;
+ DWORD dwNumberOfSegments = 0;
+ DWORD dwSegmentsPos = 0;
+ int nError = ERROR_SUCCESS;
+
+ // Open the encoding file
+ if(!CascOpenFileByIndexKey((HANDLE)hs, &hs->EncodingEKey, 0, &hFile))
+ nError = GetLastError();
+
+ // Load the encoding file to memory
+ if(nError == ERROR_SUCCESS)
+ {
+ // Retrieve the CASC header. We do not usually need to load
+ // the entire file, but we need to know how big part of it we need
+ cbEncodingFile = GetSizeOfEncodingFile(hFile);
+
+ // Load the entire file to memory
+ pbEncodingFile = LoadCascFile(hFile, cbEncodingFile, &cbEncodingFile);
+ if(pbEncodingFile == NULL || cbEncodingFile <= sizeof(CASC_ENCODING_HEADER))
+ nError = ERROR_FILE_CORRUPT;
+
+ CascCloseFile(hFile);
+ }
+
+ // Verify all encoding segments
+ if(nError == ERROR_SUCCESS)
+ {
+ // Save the encoding header
+ hs->pEncodingHeader = (PCASC_ENCODING_HEADER)pbEncodingFile;
+
+ // Convert size and offset
+ dwNumberOfSegments = ConvertBytesToInteger_4(hs->pEncodingHeader->NumSegments);
+ dwSegmentsPos = ConvertBytesToInteger_4(hs->pEncodingHeader->SegmentsPos);
+
+ // Allocate the array of encoding segments
+ pEncodingSegment = (PFILE_ENCODING_SEGMENT)(pbEncodingFile + sizeof(CASC_ENCODING_HEADER) + dwSegmentsPos);
+ pbStartOfSegment = (LPBYTE)(pEncodingSegment + dwNumberOfSegments);
+
+ // Go through all encoding segments and verify them
+ for(DWORD i = 0; i < dwNumberOfSegments; i++)
+ {
+ // Check if there is enough space in the buffer
+ if((pbStartOfSegment + CASC_ENCODING_SEGMENT_SIZE) > (pbEncodingFile + cbEncodingFile))
+ {
+ nError = ERROR_FILE_CORRUPT;
+ break;
+ }
+
+ // Check the hash of the entire segment
+ // Note that verifying takes considerable time of the storage loading
+// if(!VerifyDataBlockHash(pbStartOfSegment, CASC_ENCODING_SEGMENT_SIZE, pEncodingSegment->SegmentHash))
+// {
+// nError = ERROR_FILE_CORRUPT;
+// break;
+// }
+
+ // Check if the encoding key matches
+ pEncodingEntry = (PCASC_ENCODING_ENTRY)pbStartOfSegment;
+ if(memcmp(pEncodingEntry->EncodingKey, pEncodingSegment->FirstEncodingKey, MD5_HASH_SIZE))
+ {
+ nError = ERROR_FILE_CORRUPT;
+ break;
+ }
+
+ // Move to the next segment
+ pbStartOfSegment += CASC_ENCODING_SEGMENT_SIZE;
+ pEncodingSegment++;
+ }
+ }
+
+ // Create the map of the encoding keys
+ // Note that the array of encoding keys is already sorted - no need to sort it
+ if(nError == ERROR_SUCCESS)
+ {
+ pEncodingSegment = (PFILE_ENCODING_SEGMENT)(pbEncodingFile + sizeof(CASC_ENCODING_HEADER) + dwSegmentsPos);
+ nError = CreateMapOfEncodingKeys(hs, pEncodingSegment, dwNumberOfSegments);
+ }
+ return nError;
+}
+
+static int LoadRootFile(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile)
+{
+ PFILE_ROOT_ENTRY pSrcEntry;
+ PCASC_ROOT_ENTRY pTrgEntry;
+ ROOT_BLOCK_INFO BlockInfo;
+ LPBYTE pbRootFileEnd = pbRootFile + cbRootFile;
+ LPBYTE pbFilePointer;
+ size_t nRootEntries = 0;
+ size_t nRootIndex = 0;
+ int nError = ERROR_NOT_ENOUGH_MEMORY;
+
+ // Calculate the root entries
+ for(pbFilePointer = pbRootFile; pbFilePointer <= pbRootFileEnd; )
+ {
+ // Validate the root block
+ pbFilePointer = VerifyLocaleBlock(&BlockInfo, pbFilePointer, pbRootFileEnd);
+ if(pbFilePointer == NULL)
+ break;
+
+ // Add the number of entries
+ nRootEntries = nRootEntries + BlockInfo.pLocaleBlockHdr->NumberOfFiles;
+ }
+
+ // Create a linear array of the root entries and sort it
+ hs->pRootEntries = pTrgEntry = CASC_ALLOC(CASC_ROOT_ENTRY, nRootEntries);
+ hs->ppRootEntries = CASC_ALLOC(PCASC_ROOT_ENTRY, nRootEntries);
+ if(hs->ppRootEntries && hs->pRootEntries)
+ {
+ // Convert each entry from FILE_ROOT_ENTRY to CASC_ROOT_ENTRY
+ for(pbFilePointer = pbRootFile; pbFilePointer <= pbRootFileEnd; )
+ {
+ // Validate the root block
+ pbFilePointer = VerifyLocaleBlock(&BlockInfo, pbFilePointer, pbRootFileEnd);
+ if(pbFilePointer == NULL)
+ break;
+
+ // Get the pointer to the first root entry
+ pSrcEntry = (PFILE_ROOT_ENTRY)BlockInfo.pRootEntries;
+
+ // Convert all entries
+ for(DWORD i = 0; i < BlockInfo.pLocaleBlockHdr->NumberOfFiles; i++)
+ {
+ // Copy the root entry
+ CopyFileKey(pTrgEntry->EncodingKey, pSrcEntry->EncodingKey);
+ pTrgEntry->FileNameHash = pSrcEntry->FileNameHash;
+ pTrgEntry->Locales = BlockInfo.pLocaleBlockHdr->Locales;
+ pTrgEntry->Flags = BlockInfo.pLocaleBlockHdr->Flags;
+
+// if(pTrgEntry->FileNameHash == 0x5ddb88608673f698ULL)
+// DebugBreak();
+
+ // Insert the CASC root entry to the linear array of pointers
+ hs->ppRootEntries[nRootIndex++] = pTrgEntry;
+
+ // Move to the next root entry
+ pSrcEntry++;
+ pTrgEntry++;
+ }
+ }
+
+ // Save the number of entries
+ assert(nRootIndex == nRootEntries);
+ hs->nRootEntries = nRootIndex;
+
+ // Now sort the array
+ qsort_pointer_array((void **)hs->ppRootEntries, hs->nRootEntries, CompareRootEntries, NULL);
+ nError = ERROR_SUCCESS;
+ }
+
+ return nError;
+
+/*
+ FILE * fp = fopen("E:\\root_entries.txt", "wt");
+ if(fp != NULL)
+ {
+ for(size_t i = 0; i < nRootEntries; i++)
+ {
+ fprintf(fp, "%08X: %016I64lX\n", i, hs->ppRootEntries[i]->FileNameHash);
+ }
+ fclose(fp);
+ }
+*/
+}
+
+static int LoadRootFile(TCascStorage * hs)
+{
+ PDWORD FileSignature;
+ HANDLE hFile = NULL;
+ LPBYTE pbRootFile = NULL;
+ DWORD cbRootFile = 0;
+ int nError = ERROR_SUCCESS;
+
+ // Sanity checks
+ assert(hs->ppEncodingEntries != NULL);
+ assert(hs->pRootEntries == NULL);
+ assert(hs->nRootEntries == 0);
+
+ // The root file is either MNDX file (Heroes of the Storm)
+ // or a file containing an array of root entries (World of Warcraft 6.0+)
+ // Note: The "root" key file's MD5 hash is equal to its name
+ // in the configuration
+ if(!CascOpenFileByEncodingKey((HANDLE)hs, &hs->RootKey, 0, &hFile))
+ nError = GetLastError();
+
+ // Load ther entire root file to memory
+ if(nError == ERROR_SUCCESS)
+ {
+ // Load the entire root file to memory
+ pbRootFile = LoadCascFile(hFile, 0xFFFFFFFF, &cbRootFile);
+ if(pbRootFile == NULL || cbRootFile == 0)
+ nError = ERROR_FILE_CORRUPT;
+
+ // Close the root file
+ CascCloseFile(hFile);
+ }
+
+ // Check if the file is a MNDX file
+ if(nError == ERROR_SUCCESS)
+ {
+ FileSignature = (PDWORD)pbRootFile;
+ if(FileSignature[0] == CASC_MNDX_SIGNATURE)
+ {
+ nError = LoadMndxRootFile(hs, pbRootFile, cbRootFile);
+ }
+ else
+ {
+ nError = LoadRootFile(hs, pbRootFile, cbRootFile);
+ }
+ }
+
+ // Free the root file
+ CASC_FREE(pbRootFile);
+ return nError;
+}
+
+static TCascStorage * FreeCascStorage(TCascStorage * hs)
+{
+ size_t i;
+
+ if(hs != NULL)
+ {
+ // Free the MNDX info
+ if(hs->pPackages != NULL)
+ CASC_FREE(hs->pPackages);
+ if(hs->pMndxInfo != NULL)
+ FreeMndxInfo(hs->pMndxInfo);
+
+ // Free the pointers to file entries
+ if(hs->ppRootEntries != NULL)
+ CASC_FREE(hs->ppRootEntries);
+ if(hs->pRootEntries != NULL)
+ CASC_FREE(hs->pRootEntries);
+ if(hs->ppEncodingEntries != NULL)
+ CASC_FREE(hs->ppEncodingEntries);
+ if(hs->pEncodingHeader != NULL)
+ CASC_FREE(hs->pEncodingHeader);
+ if(hs->pIndexEntryMap != NULL)
+ Map_Free(hs->pIndexEntryMap);
+
+ // Close all data files
+ for(i = 0; i < CASC_MAX_DATA_FILES; i++)
+ {
+ if(hs->DataFileArray[i] != NULL)
+ {
+ FileStream_Close(hs->DataFileArray[i]);
+ hs->DataFileArray[i] = NULL;
+ }
+ }
+
+ // Close all key mappings
+ for(i = 0; i < CASC_INDEX_COUNT; i++)
+ {
+ if(hs->KeyMapping[i].szFileName != NULL)
+ CASC_FREE(hs->KeyMapping[i].szFileName);
+ if(hs->KeyMapping[i].pbFileData != NULL)
+ CASC_FREE(hs->KeyMapping[i].pbFileData);
+ hs->KeyMapping[i].pIndexEntries = NULL;
+ }
+
+ // Free the file paths
+ if(hs->szRootPath != NULL)
+ CASC_FREE(hs->szRootPath);
+ if(hs->szDataPath != NULL)
+ CASC_FREE(hs->szDataPath);
+ if(hs->szIndexPath != NULL)
+ CASC_FREE(hs->szIndexPath);
+ if(hs->szUrlPath != NULL)
+ CASC_FREE(hs->szUrlPath);
+
+ // Fre the blob arrays
+ QUERY_KEY_FreeArray(hs->pArchiveArray);
+ QUERY_KEY_FreeArray(hs->pPatchArchiveArray);
+ QUERY_KEY_FreeArray(hs->pEncodingKeys);
+
+ // Free the blobs
+ QUERY_KEY_Free(&hs->CdnConfigKey);
+ QUERY_KEY_Free(&hs->CdnBuildKey);
+ QUERY_KEY_Free(&hs->ArchiveGroup);
+ QUERY_KEY_Free(&hs->PatchArchiveGroup);
+ QUERY_KEY_Free(&hs->RootKey);
+ QUERY_KEY_Free(&hs->PatchKey);
+ QUERY_KEY_Free(&hs->DownloadKey);
+ QUERY_KEY_Free(&hs->InstallKey);
+
+ // Free the storage structure
+ hs->szClassName = NULL;
+ CASC_FREE(hs);
+ }
+
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Public functions
+
+bool WINAPI CascOpenStorage(const TCHAR * szDataPath, DWORD dwFlags, HANDLE * phStorage)
+{
+ TCascStorage * hs;
+ int nError = ERROR_SUCCESS;
+
+ CASCLIB_UNUSED(dwFlags);
+
+ // Allocate the storage structure
+ hs = (TCascStorage *)CASC_ALLOC(TCascStorage, 1);
+ if(hs == NULL)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+
+ // Load the storage configuration
+ if(nError == ERROR_SUCCESS)
+ {
+ // Prepare the base storage parameters
+ memset(hs, 0, sizeof(TCascStorage));
+ hs->szClassName = "TCascStorage";
+ hs->dwRefCount = 1;
+ nError = InitializeCascDirectories(hs, szDataPath);
+ }
+
+ // Now we need to load the root file so we know the config files
+ if(nError == ERROR_SUCCESS)
+ {
+ nError = LoadBuildConfiguration(hs);
+ }
+
+ // Load the index files
+ if(nError == ERROR_SUCCESS)
+ {
+ nError = LoadIndexFiles(hs);
+ }
+
+ // Load the index files
+ if(nError == ERROR_SUCCESS)
+ {
+ nError = LoadEncodingFile(hs);
+ }
+
+ // Load the index files
+ if(nError == ERROR_SUCCESS)
+ {
+ nError = LoadRootFile(hs);
+ }
+
+#ifdef _DEBUG
+// if(nError == ERROR_SUCCESS)
+// {
+// CascDumpStorage("E:\\casc_dump.txt", hs, _T("e:\\Ladik\\Appdir\\CascLib\\listfile\\listfile-wow6.txt"));
+// CascDumpIndexEntries("E:\\casc_index.txt", hs);
+// }
+#endif
+
+ // If something failed, free the storage and return
+ if(nError != ERROR_SUCCESS)
+ {
+ hs = FreeCascStorage(hs);
+ SetLastError(nError);
+ }
+
+ *phStorage = (HANDLE)hs;
+ return (nError == ERROR_SUCCESS);
+}
+
+bool WINAPI CascGetStorageInfo(
+ HANDLE hStorage,
+ CASC_STORAGE_INFO_CLASS InfoClass,
+ void * pvStorageInfo,
+ size_t cbStorageInfo,
+ size_t * pcbLengthNeeded)
+{
+ TCascStorage * hs;
+ DWORD dwCascFeatures = 0;
+
+ // Verify the storage handle
+ hs = IsValidStorageHandle(hStorage);
+ if(hs == NULL)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return false;
+ }
+
+ // Differentiate between info classes
+ switch(InfoClass)
+ {
+ case CascStorageFileCount:
+
+ // Check the buffer size
+ if(cbStorageInfo < sizeof(DWORD))
+ {
+ *pcbLengthNeeded = sizeof(DWORD);
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return false;
+ }
+
+ // Give the number of files
+ *(PDWORD)pvStorageInfo = (DWORD)hs->pIndexEntryMap->ItemCount;
+ return true;
+
+ case CascStorageFeatures:
+
+ // Check the buffer size
+ if(cbStorageInfo < sizeof(DWORD))
+ {
+ *pcbLengthNeeded = sizeof(DWORD);
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return false;
+ }
+
+ // Construct the features
+ if(hs->pMndxInfo != NULL)
+ dwCascFeatures |= CASC_FEATURE_LISTFILE;
+
+ // Give the number of files
+ *(PDWORD)pvStorageInfo = dwCascFeatures;
+ return true;
+
+ default:
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return false;
+ }
+}
+
+
+
+bool WINAPI CascCloseStorage(HANDLE hStorage)
+{
+ TCascStorage * hs;
+
+ // Verify the storage handle
+ hs = IsValidStorageHandle(hStorage);
+ if(hs == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return false;
+ }
+
+ // Only free the storage if the reference count reaches 0
+ if(hs->dwRefCount == 1)
+ {
+ FreeCascStorage(hs);
+ return true;
+ }
+
+ // Just decrement number of references
+ hs->dwRefCount--;
+ return true;
+}
+
diff --git a/dep/StormLib/src/StormPort.h b/dep/CascLib/src/CascPort.h
index 0914654b9af..6d0595ce522 100644
--- a/dep/StormLib/src/StormPort.h
+++ b/dep/CascLib/src/CascPort.h
@@ -1,30 +1,16 @@
/*****************************************************************************/
-/* StormPort.h Copyright (c) Marko Friedemann 2001 */
+/* CascPort.h Copyright (c) Ladislav Zezula 2014 */
/*---------------------------------------------------------------------------*/
-/* Portability module for the StormLib library. Contains a wrapper symbols */
+/* Portability module for the CascLib library. Contains a wrapper symbols */
/* to make the compilation under Linux work */
-/* */
-/* Author: Marko Friedemann <marko.friedemann@bmx-chemnitz.de> */
-/* Created at: Mon Jan 29 18:26:01 CEST 2001 */
-/* Computer: whiplash.flachland-chemnitz.de */
-/* System: Linux 2.4.0 on i686 */
-/* */
-/* Author: Sam Wilkins <swilkins1337@gmail.com> */
-/* System: Mac OS X and port to big endian processor */
-/* */
/*---------------------------------------------------------------------------*/
/* Date Ver Who Comment */
/* -------- ---- --- ------- */
-/* 29.01.01 1.00 Mar Created */
-/* 24.03.03 1.01 Lad Some cosmetic changes */
-/* 12.11.03 1.02 Dan Macintosh compatibility */
-/* 24.07.04 1.03 Sam Mac OS X compatibility */
-/* 22.11.06 1.04 Sam Mac OS X compatibility (for StormLib 6.0) */
-/* 31.12.06 1.05 XPinguin Full GNU/Linux compatibility */
+/* 29.04.14 1.00 Lad Created */
/*****************************************************************************/
-#ifndef __STORMPORT_H__
-#define __STORMPORT_H__
+#ifndef __CASCPORT_H__
+#define __CASCPORT_H__
#ifndef __cplusplus
#define bool char
@@ -32,7 +18,9 @@
#define false 0
#endif
+//-----------------------------------------------------------------------------
// Defines for Windows
+
#if !defined(PLATFORM_DEFINED) && (defined(WIN32) || defined(WIN64))
// In MSVC 8.0, there are some functions declared as deprecated.
@@ -47,6 +35,7 @@
#include <stdio.h>
#include <windows.h>
#include <wininet.h>
+ #include <sys/types.h>
#define PLATFORM_LITTLE_ENDIAN
#ifdef WIN64
@@ -55,12 +44,17 @@
#define PLATFORM_32BIT
#endif
+ #define PATH_SEPARATOR '\\'
+ #define CREATE_DIRECTORY(name) CreateDirectory(name, NULL);
+
#define PLATFORM_WINDOWS
#define PLATFORM_DEFINED // The platform is known now
#endif
-// Defines for Mac
+//-----------------------------------------------------------------------------
+// Defines for Mac
+
#if !defined(PLATFORM_DEFINED) && defined(__APPLE__) // Mac BSD API
// Macintosh
@@ -70,8 +64,15 @@
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
+ #include <dirent.h>
#include <errno.h>
-
+
+ // Support for PowerPC on Max OS X
+ #if (__ppc__ == 1) || (__POWERPC__ == 1) || (_ARCH_PPC == 1)
+ #include <stdint.h>
+ #include <CoreFoundation/CFByteOrder.h>
+ #endif
+
#define PKEXPORT
#define __SYS_ZLIB
#define __SYS_BZLIB
@@ -80,19 +81,27 @@
#define PLATFORM_LITTLE_ENDIAN
#endif
+ #define PATH_SEPARATOR '/'
+ #define CREATE_DIRECTORY(name) mkdir(name, 0755)
+
#define PLATFORM_MAC
#define PLATFORM_DEFINED // The platform is known now
+ #define FIELD_OFFSET(t,f) offsetof(t,f)
#endif
+//-----------------------------------------------------------------------------
// Assumption: we are not on Windows nor Macintosh, so this must be linux *grin*
+
#if !defined(PLATFORM_DEFINED)
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
+ #include <dirent.h>
#include <unistd.h>
+ #include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
@@ -102,13 +111,19 @@
#include <assert.h>
#include <errno.h>
+ #define PATH_SEPARATOR '/'
+ #define CREATE_DIRECTORY(name) mkdir(name, 0755)
+
#define PLATFORM_LITTLE_ENDIAN
#define PLATFORM_LINUX
#define PLATFORM_DEFINED
+ #define FIELD_OFFSET(t,f) offsetof(t,f)
#endif
-// Definition of Windows-specific structures for non-Windows platforms
+//-----------------------------------------------------------------------------
+// Definition of Windows-specific types for non-Windows platforms
+
#ifndef PLATFORM_WINDOWS
#if __LP64__
#define PLATFORM_64BIT
@@ -126,12 +141,13 @@
typedef long INT_PTR;
typedef long long LONGLONG;
typedef unsigned long long ULONGLONG;
+ typedef unsigned long long *PULONGLONG;
typedef void * HANDLE;
typedef void * LPOVERLAPPED; // Unsupported on Linux and Mac
typedef char TCHAR;
typedef unsigned int LCID;
typedef LONG * PLONG;
- typedef DWORD * LPDWORD;
+ typedef DWORD * PDWORD;
typedef BYTE * LPBYTE;
#ifdef PLATFORM_32BIT
@@ -149,30 +165,38 @@
#define FILE_CURRENT SEEK_CUR
#define FILE_END SEEK_END
+ #define INVALID_HANDLE_VALUE ((HANDLE)-1)
+
#define _T(x) x
#define _tcslen strlen
#define _tcscpy strcpy
#define _tcscat strcat
+ #define _tcschr strchr
#define _tcsrchr strrchr
+ #define _tcsstr strstr
+ #define _tcsspn strspn
#define _tprintf printf
#define _stprintf sprintf
#define _tremove remove
+ #define _tmkdir mkdir
#define _stricmp strcasecmp
#define _strnicmp strncasecmp
+ #define _tcsicmp strcasecmp
#define _tcsnicmp strncasecmp
-#endif // !WIN32
+#endif // !PLATFORM_WINDOWS
// 64-bit calls are supplied by "normal" calls on Mac
#if defined(PLATFORM_MAC)
#define stat64 stat
#define fstat64 fstat
#define lseek64 lseek
+ #define ftruncate64 ftruncate
#define off64_t off_t
#define O_LARGEFILE 0
#endif
-
+
// Platform-specific error codes for UNIX-based platforms
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
#define ERROR_SUCCESS 0
@@ -180,18 +204,21 @@
#define ERROR_ACCESS_DENIED EPERM
#define ERROR_INVALID_HANDLE EBADF
#define ERROR_NOT_ENOUGH_MEMORY ENOMEM
- #define ERROR_BAD_FORMAT 105 // No such error code under Linux
- #define ERROR_NO_MORE_FILES 106
- #define ERROR_HANDLE_EOF 107 // No such error code under Linux
#define ERROR_NOT_SUPPORTED ENOTSUP
#define ERROR_INVALID_PARAMETER EINVAL
#define ERROR_DISK_FULL ENOSPC
#define ERROR_ALREADY_EXISTS EEXIST
- #define ERROR_CAN_NOT_COMPLETE 108 // No such error code under Linux
- #define ERROR_FILE_CORRUPT 109 // No such error code under Linux
#define ERROR_INSUFFICIENT_BUFFER ENOBUFS
+ #define ERROR_BAD_FORMAT 1000 // No such error code under Linux
+ #define ERROR_NO_MORE_FILES 1001 // No such error code under Linux
+ #define ERROR_HANDLE_EOF 1002 // No such error code under Linux
+ #define ERROR_CAN_NOT_COMPLETE 1003 // No such error code under Linux
+ #define ERROR_FILE_CORRUPT 1004 // No such error code under Linux
#endif
+//-----------------------------------------------------------------------------
+// Swapping functions
+
#ifdef PLATFORM_LITTLE_ENDIAN
#define BSWAP_INT16_UNSIGNED(a) (a)
#define BSWAP_INT16_SIGNED(a) (a)
@@ -202,10 +229,11 @@
#define BSWAP_ARRAY16_UNSIGNED(a,b) {}
#define BSWAP_ARRAY32_UNSIGNED(a,b) {}
#define BSWAP_ARRAY64_UNSIGNED(a,b) {}
- #define BSWAP_PART_HEADER(a) {}
- #define BSWAP_TMPQUSERDATA(a) {}
- #define BSWAP_TMPQHEADER(a) {}
#else
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
int16_t SwapInt16(uint16_t);
uint16_t SwapUInt16(uint16_t);
int32_t SwapInt32(uint32_t);
@@ -215,9 +243,9 @@
void ConvertUInt16Buffer(void * ptr, size_t length);
void ConvertUInt32Buffer(void * ptr, size_t length);
void ConvertUInt64Buffer(void * ptr, size_t length);
- void ConvertPartHeader(void * partHeader);
- void ConvertTMPQUserData(void *userData);
- void ConvertTMPQHeader(void *header);
+#ifdef __cplusplus
+ }
+#endif
#define BSWAP_INT16_SIGNED(a) SwapInt16((a))
#define BSWAP_INT16_UNSIGNED(a) SwapUInt16((a))
#define BSWAP_INT32_SIGNED(a) SwapInt32((a))
@@ -227,9 +255,6 @@
#define BSWAP_ARRAY16_UNSIGNED(a,b) ConvertUInt16Buffer((a),(b))
#define BSWAP_ARRAY32_UNSIGNED(a,b) ConvertUInt32Buffer((a),(b))
#define BSWAP_ARRAY64_UNSIGNED(a,b) ConvertUInt64Buffer((a),(b))
- #define BSWAP_PART_HEADER(a) ConvertPartHeader(a)
- #define BSWAP_TMPQUSERDATA(a) ConvertTMPQUserData((a))
- #define BSWAP_TMPQHEADER(a) ConvertTMPQHeader((a))
#endif
-#endif // __STORMPORT_H__
+#endif // __CASCPORT_H__
diff --git a/dep/CascLib/src/CascReadFile.cpp b/dep/CascLib/src/CascReadFile.cpp
new file mode 100644
index 00000000000..64dd66ef88a
--- /dev/null
+++ b/dep/CascLib/src/CascReadFile.cpp
@@ -0,0 +1,475 @@
+/*****************************************************************************/
+/* CascOpenFile.cpp Copyright (c) Ladislav Zezula 2014 */
+/*---------------------------------------------------------------------------*/
+/* System-dependent directory functions for CascLib */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 01.05.14 1.00 Lad The first version of CascOpenFile.cpp */
+/*****************************************************************************/
+
+#define __CASCLIB_SELF__
+#include "CascLib.h"
+#include "CascCommon.h"
+
+//-----------------------------------------------------------------------------
+// Local structures
+
+#define BLTE_HEADER_SIGNATURE 0x45544C42
+
+// Data file begin:
+// BYTE HeaderHash[MD5_HASH_SIZE]; // MD5 of the frame array
+// DWORD dwFileSize; // Size of the file
+// BYTE SomeSize[4]; // Some size (big endian)
+// BYTE Padding[6]; // Padding (?)
+
+typedef struct _BLTE_HEADER
+{
+ DWORD dwSignature; // Must be "BLTE"
+ BYTE HeaderSizeAsBytes[4]; // Header size in bytes (big endian)
+ BYTE MustBe0F; // Must be 0x0F
+ BYTE FrameCount[3]; // Number of frames (big endian)
+
+} BLTE_HEADER, *PBLTE_HEADER;
+
+typedef struct _BLTE_FRAME
+{
+ BYTE CompressedSize[4]; // Compressed file size as big endian
+ BYTE FrameSize[4]; // File size as big endian
+ BYTE md5[MD5_HASH_SIZE]; // Hash of the frame
+
+} BLTE_FRAME, *PBLTE_FRAME;
+
+//-----------------------------------------------------------------------------
+// Local functions
+
+TCascFile * IsValidFileHandle(HANDLE hFile); // In CascOpenFile.cpp
+
+static int EnsureDataStreamIsOpen(TCascFile * hf)
+{
+ TCascStorage * hs = hf->hs;
+ TFileStream * pStream = NULL;
+ TCHAR * szDataFile;
+ TCHAR szPlainName[0x40];
+
+ // If the file is not open yet, do it
+ if(hs->DataFileArray[hf->ArchiveIndex] == NULL)
+ {
+ // Prepare the name of the data file
+ _stprintf(szPlainName, _T("data.%03u"), hf->ArchiveIndex);
+ szDataFile = CombinePath(hs->szIndexPath, szPlainName);
+
+ // Open the data file
+ if(szDataFile != NULL)
+ {
+ // Open the stream
+ pStream = FileStream_OpenFile(szDataFile, STREAM_FLAG_READ_ONLY | STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE);
+ hs->DataFileArray[hf->ArchiveIndex] = pStream;
+
+ // TODO: There is 0x1E bytes at the beginning of the file stream
+ // Ignore them for now, but we will want to know what they mean
+ // Offs0000: MD5 of something
+ // Offs0010: 2 bytes
+ CASC_FREE(szDataFile);
+ }
+ }
+
+ // Return error or success
+ hf->pStream = hs->DataFileArray[hf->ArchiveIndex];
+ return (hf->pStream != NULL) ? ERROR_SUCCESS : ERROR_FILE_NOT_FOUND;
+}
+
+static int LoadFileFrames(TCascFile * hf, DWORD FrameCount)
+{
+ PBLTE_FRAME pFileFrames;
+ PBLTE_FRAME pFileFrame;
+ ULONGLONG ArchiveFileOffset;
+ DWORD FrameOffset = 0;
+ DWORD FileSize = 0;
+ int nError = ERROR_SUCCESS;
+
+ assert(hf != NULL);
+ assert(hf->pStream != NULL);
+ assert(hf->pFrames != NULL);
+
+ // Allocate frame array
+ pFileFrames = pFileFrame = CASC_ALLOC(BLTE_FRAME, FrameCount);
+ if(pFileFrames != NULL)
+ {
+ // Load the frame array
+ ArchiveFileOffset = hf->FramesOffset;
+ if(FileStream_Read(hf->pStream, &ArchiveFileOffset, pFileFrames, FrameCount * sizeof(BLTE_FRAME)))
+ {
+ // Move the raw archive offset
+ ArchiveFileOffset += (hf->FrameCount * sizeof(BLTE_FRAME));
+
+ // Copy the frames to the file structure
+ for(DWORD i = 0; i < FrameCount; i++, pFileFrame++)
+ {
+ hf->pFrames[i].FrameArchiveOffset = (DWORD)ArchiveFileOffset;
+ hf->pFrames[i].FrameFileOffset = FrameOffset;
+ hf->pFrames[i].CompressedSize = ConvertBytesToInteger_4(pFileFrame->CompressedSize);
+ hf->pFrames[i].FrameSize = ConvertBytesToInteger_4(pFileFrame->FrameSize);
+ memcpy(hf->pFrames[i].md5, pFileFrame->md5, MD5_HASH_SIZE);
+
+ ArchiveFileOffset += hf->pFrames[i].CompressedSize;
+ FrameOffset += hf->pFrames[i].FrameSize;
+ FileSize += hf->pFrames[i].FrameSize;
+ }
+
+ // Fill-in the frame count
+ hf->FrameCount = FrameCount;
+ }
+ else
+ nError = GetLastError();
+
+ // Verify the file size
+// assert(FileSize == hf->FileSize);
+// hf->FileSize = FileSize;
+
+ // Free the array
+ CASC_FREE(pFileFrames);
+ }
+ else
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+
+ return nError;
+}
+
+static int EnsureFrameHeadersLoaded(TCascFile * hf)
+{
+ PBLTE_HEADER pBlteHeader;
+ ULONGLONG FileOffset = hf->HeaderOffset;
+ DWORD dwHeaderOffsetFixup = 0;
+ DWORD dwFrameHeaderSize;
+ DWORD dwFrameCount;
+ BYTE HeaderBuffer[sizeof(BLTE_HEADER) + 0x20];
+ int nError = ERROR_SUCCESS;
+
+ // Sanity check
+ assert(hf->pStream != NULL);
+
+ // If the frame headers are not loaded yet, do it
+ if(hf->pFrames == NULL)
+ {
+ // Note that older builds of Heroes of the Storm have entries pointing
+ // to the begin of the BLTE header, which is MD5 + some junk.
+ // Newer versions of HOTS have encoding entries pointing directly to
+ // the BLTE header
+ FileStream_Read(hf->pStream, &FileOffset, HeaderBuffer, sizeof(HeaderBuffer));
+ pBlteHeader = (PBLTE_HEADER)HeaderBuffer;
+
+ // If we don't have the BLTE header right there,
+ // just get the block that is 0x1E bytes later
+ if(pBlteHeader->dwSignature != BLTE_HEADER_SIGNATURE)
+ {
+ memcpy(&HeaderBuffer[0x00], &HeaderBuffer[0x1E], sizeof(BLTE_HEADER));
+ dwHeaderOffsetFixup = 0x1E;
+ }
+
+ // Check for the BLTE header signature
+ if(pBlteHeader->dwSignature != BLTE_HEADER_SIGNATURE)
+ return ERROR_BAD_FORMAT;
+ hf->HeaderOffset += dwHeaderOffsetFixup;
+
+ // Check for a single unit file
+ dwFrameHeaderSize = ConvertBytesToInteger_4(pBlteHeader->HeaderSizeAsBytes);
+ dwFrameCount = (dwFrameHeaderSize != 0) ? ConvertBytesToInteger_3(pBlteHeader->FrameCount) : 1;
+
+ // Allocate the frame array
+ hf->pFrames = CASC_ALLOC(CASC_FILE_FRAME, dwFrameCount);
+ if(hf->pFrames != NULL)
+ {
+ // Save the number of frames
+ hf->FrameCount = dwFrameCount;
+
+ // Either load the frames from the file or supply them on our own
+ if(dwFrameHeaderSize != 0)
+ {
+ if(pBlteHeader->MustBe0F != 0x0F)
+ return ERROR_FILE_CORRUPT;
+
+ hf->FramesOffset = hf->HeaderOffset + sizeof(BLTE_HEADER);
+ nError = LoadFileFrames(hf, dwFrameCount);
+ }
+ else
+ {
+ // Offset of the first frame is right after the file frames
+ hf->FramesOffset = hf->HeaderOffset + sizeof(pBlteHeader->dwSignature) + sizeof(pBlteHeader->HeaderSizeAsBytes);
+
+ hf->pFrames[0].FrameArchiveOffset = hf->FramesOffset;
+ hf->pFrames[0].FrameFileOffset = 0;
+ hf->pFrames[0].CompressedSize = hf->CompressedSize;
+ hf->pFrames[0].FrameSize = hf->FileSize;
+ memset(hf->pFrames[0].md5, 0, MD5_HASH_SIZE);
+ }
+ }
+
+ // Return result
+ return (hf->pFrames != NULL) ? ERROR_SUCCESS : ERROR_FILE_CORRUPT;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+static PCASC_FILE_FRAME FindFileFrame(TCascFile * hf, DWORD FilePointer)
+{
+ PCASC_FILE_FRAME pFrame = hf->pFrames;
+ DWORD FrameBegin;
+ DWORD FrameEnd;
+
+ // Sanity checks
+ assert(hf->pFrames != NULL);
+ assert(hf->FrameCount != 0);
+
+ // Find the frame where to read from
+ for(DWORD i = 0; i < hf->FrameCount; i++, pFrame++)
+ {
+ // Does the read request fit into the current frame?
+ FrameBegin = pFrame->FrameFileOffset;
+ FrameEnd = FrameBegin + pFrame->FrameSize;
+ if(FrameBegin <= FilePointer && FilePointer < FrameEnd)
+ return pFrame;
+ }
+
+ // Not found, sorry
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Public functions
+
+DWORD WINAPI CascGetFileSize(HANDLE hFile, PDWORD pdwFileSizeHigh)
+{
+ TCascFile * hf;
+
+ CASCLIB_UNUSED(pdwFileSizeHigh);
+
+ // Validate the file handle
+ if((hf = IsValidFileHandle(hFile)) == NULL)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return CASC_INVALID_SIZE;
+ }
+
+ // Give the file size to the caller
+ if(pdwFileSizeHigh != NULL)
+ *pdwFileSizeHigh = 0;
+ return hf->FileSize;
+}
+
+DWORD WINAPI CascSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * plFilePosHigh, DWORD dwMoveMethod)
+{
+ TCascFile * hf;
+ ULONGLONG FilePosition;
+ ULONGLONG MoveOffset;
+ DWORD dwFilePosHi;
+
+ // If the hFile is not a valid file handle, return an error.
+ hf = IsValidFileHandle(hFile);
+ if(hf == NULL)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return CASC_INVALID_POS;
+ }
+
+ // Get the relative point where to move from
+ switch(dwMoveMethod)
+ {
+ case FILE_BEGIN:
+ FilePosition = 0;
+ break;
+
+ case FILE_CURRENT:
+ FilePosition = hf->FilePointer;
+ break;
+
+ case FILE_END:
+ FilePosition = hf->FileSize;
+ break;
+
+ default:
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return CASC_INVALID_POS;
+ }
+
+ // Now get the move offset. Note that both values form
+ // a signed 64-bit value (a file pointer can be moved backwards)
+ if(plFilePosHigh != NULL)
+ dwFilePosHi = *plFilePosHigh;
+ else
+ dwFilePosHi = (lFilePos & 0x80000000) ? 0xFFFFFFFF : 0;
+ MoveOffset = MAKE_OFFSET64(dwFilePosHi, lFilePos);
+
+ // Now calculate the new file pointer
+ // Do not allow the file pointer to overflow
+ FilePosition = ((FilePosition + MoveOffset) >= FilePosition) ? (FilePosition + MoveOffset) : 0;
+
+ // CASC files can't be bigger than 4 GB.
+ // We don't allow to go past 4 GB
+ if(FilePosition >> 32)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return CASC_INVALID_POS;
+ }
+
+ // Change the file position
+ hf->FilePointer = (DWORD)FilePosition;
+
+ // Return the new file position
+ if(plFilePosHigh != NULL)
+ *plFilePosHigh = 0;
+ return hf->FilePointer;
+}
+
+bool WINAPI CascReadFile(HANDLE hFile, void * pvBuffer, DWORD dwBytesToRead, PDWORD pdwBytesRead)
+{
+ PCASC_FILE_FRAME pFrame = NULL;
+ ULONGLONG FileOffset;
+ TCascFile * hf;
+ LPBYTE pbBuffer = (LPBYTE)pvBuffer;
+ DWORD dwStartPointer = 0;
+ DWORD dwFilePointer = 0;
+ DWORD dwEndPointer = 0;
+ DWORD cbOutBuffer;
+ int nError = ERROR_SUCCESS;
+
+ // The buffer must be valid
+ if(pvBuffer == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return false;
+ }
+
+ // Validate the file handle
+ if((hf = IsValidFileHandle(hFile)) == NULL)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return false;
+ }
+
+ // If the file position is at or beyond end of file, do nothing
+ if(hf->FilePointer >= hf->FileSize)
+ {
+ *pdwBytesRead = 0;
+ return ERROR_SUCCESS;
+ }
+
+ // Make sure we have that data file open
+ if(nError == ERROR_SUCCESS)
+ {
+ nError = EnsureDataStreamIsOpen(hf);
+ }
+
+ // If the file frames are not loaded yet, do it now
+ if(nError == ERROR_SUCCESS)
+ {
+ nError = EnsureFrameHeadersLoaded(hf);
+ }
+
+ // Find the file frame where to read from
+ if(nError == ERROR_SUCCESS)
+ {
+ // Get the frame
+ pFrame = FindFileFrame(hf, hf->FilePointer);
+ if(pFrame == NULL)
+ nError = ERROR_FILE_CORRUPT;
+ }
+
+ // Perform the read
+ if(nError == ERROR_SUCCESS)
+ {
+ // If not enough bytes in the file remaining, cut them
+ dwStartPointer = dwFilePointer = hf->FilePointer;
+ dwEndPointer = dwStartPointer + dwBytesToRead;
+ if(dwEndPointer > hf->FileSize)
+ dwEndPointer = hf->FileSize;
+
+ // Perform block read from each file frame
+ while(dwFilePointer < dwEndPointer)
+ {
+ LPBYTE pbRawData = NULL;
+ DWORD dwFrameStart = pFrame->FrameFileOffset;
+ DWORD dwFrameEnd = pFrame->FrameFileOffset + pFrame->FrameSize;
+
+ // Shall we populate the cache with a new data?
+ if(dwFrameStart != hf->CacheStart || hf->CacheEnd != dwFrameEnd)
+ {
+ // Shall we reallocate the cache buffer?
+ if(pFrame->FrameSize > hf->cbFileCache)
+ {
+ if(hf->pbFileCache != NULL)
+ CASC_FREE(hf->pbFileCache);
+
+ hf->pbFileCache = CASC_ALLOC(BYTE, pFrame->FrameSize);
+ hf->cbFileCache = pFrame->FrameSize;
+ }
+
+ // We also need to allocate buffer for the raw data
+ pbRawData = CASC_ALLOC(BYTE, pFrame->CompressedSize);
+ if(pbRawData == NULL)
+ {
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ break;
+ }
+
+ // Load the raw file data to memory
+ FileOffset = pFrame->FrameArchiveOffset;
+ if(!FileStream_Read(hf->pStream, &FileOffset, pbRawData, pFrame->CompressedSize))
+ {
+ CASC_FREE(pbRawData);
+ nError = GetLastError();
+ break;
+ }
+
+ // Verify the block MD5
+ if(IsValidMD5(pFrame->md5) && !VerifyDataBlockHash(pbRawData, pFrame->CompressedSize, pFrame->md5))
+ {
+ CASC_FREE(pbRawData);
+ nError = ERROR_FILE_CORRUPT;
+ break;
+ }
+
+ // Decompress the file frame
+ cbOutBuffer = pFrame->FrameSize;
+ nError = CascDecompress(hf->pbFileCache, &cbOutBuffer, pbRawData, pFrame->CompressedSize);
+ if(nError != ERROR_SUCCESS || cbOutBuffer != pFrame->FrameSize)
+ {
+ CASC_FREE(pbRawData);
+ nError = ERROR_FILE_CORRUPT;
+ break;
+ }
+
+ // Set the start and end of the cache
+ hf->CacheStart = dwFrameStart;
+ hf->CacheEnd = dwFrameEnd;
+
+ // Free the decompress buffer, if needed
+ CASC_FREE(pbRawData);
+ }
+
+ // Copy the decompressed data
+ if(dwFrameEnd > dwEndPointer)
+ dwFrameEnd = dwEndPointer;
+ memcpy(pbBuffer, hf->pbFileCache + (dwFilePointer - dwFrameStart), (dwFrameEnd - dwFilePointer));
+ pbBuffer += (dwFrameEnd - dwFilePointer);
+
+ // Move pointers
+ dwFilePointer = dwFrameEnd;
+ pFrame++;
+ }
+ }
+
+ // Update the file position
+ if(nError == ERROR_SUCCESS)
+ {
+ if(pdwBytesRead != NULL)
+ *pdwBytesRead = (dwFilePointer - dwStartPointer);
+ hf->FilePointer = dwFilePointer;
+ }
+
+ if(nError != ERROR_SUCCESS)
+ SetLastError(nError);
+ return (nError == ERROR_SUCCESS);
+}
+
diff --git a/dep/CascLib/src/common/Common.cpp b/dep/CascLib/src/common/Common.cpp
new file mode 100644
index 00000000000..d81c1b6fd89
--- /dev/null
+++ b/dep/CascLib/src/common/Common.cpp
@@ -0,0 +1,672 @@
+/*****************************************************************************/
+/* CascCommon.cpp Copyright (c) Ladislav Zezula 2014 */
+/*---------------------------------------------------------------------------*/
+/* Common functions for CascLib */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 29.04.14 1.00 Lad The first version of CascCommon.cpp */
+/*****************************************************************************/
+
+#define __CASCLIB_SELF__
+#include "../CascLib.h"
+#include "../CascCommon.h"
+
+//-----------------------------------------------------------------------------
+// Conversion to uppercase/lowercase
+
+// Converts ASCII characters to lowercase
+// Converts slash (0x2F) to backslash (0x5C)
+unsigned char AsciiToLowerTable[256] =
+{
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x5C,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+ 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
+ 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+ 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+ 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+ 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
+ 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
+};
+
+// Converts ASCII characters to uppercase
+// Converts slash (0x2F) to backslash (0x5C)
+unsigned char AsciiToUpperTable[256] =
+{
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x5C,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+ 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
+ 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+ 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+ 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+ 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
+ 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
+};
+
+unsigned char IntToHexChar[] = "0123456789abcdef";
+
+//-----------------------------------------------------------------------------
+// Support for memory reallocation
+
+#if defined(_MSC_VER) && defined(_DEBUG)
+void * DbgRealloc(void * ptr, size_t nSize)
+{
+ // HeapReAlloc does not support NULL as previous block
+ if(ptr == NULL)
+ return HeapAlloc(GetProcessHeap, 0, nSize);
+
+ return HeapReAlloc(GetProcessHeap(), 0, ptr, nSize);
+}
+#endif
+
+//-----------------------------------------------------------------------------
+// GetLastError/SetLastError support for non-Windows platform
+
+#ifndef PLATFORM_WINDOWS
+static int nLastError = ERROR_SUCCESS;
+
+int GetLastError()
+{
+ return nLastError;
+}
+
+void SetLastError(int nError)
+{
+ nLastError = nError;
+}
+#endif
+
+//-----------------------------------------------------------------------------
+// String manipulation
+
+void CopyString(char * szTarget, const char * szSource, size_t cchLength)
+{
+ memcpy(szTarget, szSource, cchLength);
+ szTarget[cchLength] = 0;
+}
+
+void CopyString(wchar_t * szTarget, const char * szSource, size_t cchLength)
+{
+ mbstowcs(szTarget, szSource, cchLength);
+ szTarget[cchLength] = 0;
+}
+
+void CopyString(char * szTarget, const wchar_t * szSource, size_t cchLength)
+{
+ wcstombs(szTarget, szSource, cchLength);
+ szTarget[cchLength] = 0;
+}
+
+char * NewStr(const char * szString, size_t nCharsToReserve)
+{
+ char * szNewString = NULL;
+ size_t nLength;
+
+ if(szString != NULL)
+ {
+ nLength = strlen(szString);
+ szNewString = CASC_ALLOC(char, nLength + nCharsToReserve + 1);
+ if(szNewString != NULL)
+ {
+ memcpy(szNewString, szString, nLength);
+ szNewString[nLength] = 0;
+ }
+ }
+
+ return szNewString;
+}
+
+wchar_t * NewStr(const wchar_t * szString, size_t nCharsToReserve)
+{
+ wchar_t * szNewString = NULL;
+ size_t nLength;
+
+ if(szString != NULL)
+ {
+ nLength = wcslen(szString);
+ szNewString = CASC_ALLOC(wchar_t, nLength + nCharsToReserve + 1);
+ if(szNewString != NULL)
+ {
+ memcpy(szNewString, szString, nLength * sizeof(wchar_t));
+ szNewString[nLength] = 0;
+ }
+ }
+
+ return szNewString;
+}
+
+TCHAR * NewStrFromAnsi(LPBYTE pbStringBegin, LPBYTE pbStringEnd)
+{
+ TCHAR * szNewString = NULL;
+ TCHAR * szStringPtr = NULL;
+ size_t nLength = (size_t)(pbStringEnd - pbStringBegin);
+
+ if(pbStringEnd > pbStringBegin)
+ {
+ szNewString = szStringPtr = CASC_ALLOC(TCHAR, nLength + 1);
+ if(szNewString != NULL)
+ {
+ CopyString(szStringPtr, (const char *)pbStringBegin, nLength);
+ szStringPtr[nLength] = 0;
+ }
+ }
+
+ return szNewString;
+}
+
+TCHAR * CombinePath(const TCHAR * szDirectory, const TCHAR * szSubDir)
+{
+ TCHAR * szFullPath = NULL;
+ TCHAR * szPathPtr;
+ size_t nLength1 = 0;
+ size_t nLength2 = 0;
+
+ // Calculate lengths of each part
+ if(szDirectory != NULL)
+ {
+ // Get the length of the directory
+ nLength1 = _tcslen(szDirectory);
+
+ // Cut all ending backslashes
+ while(nLength1 > 0 && szDirectory[nLength1 - 1] == _T(PATH_SEPARATOR))
+ nLength1--;
+ }
+
+ if(szSubDir != NULL)
+ {
+ // Cut all leading backslashes
+ while(szSubDir[0] == _T(PATH_SEPARATOR))
+ szSubDir++;
+
+ // Get the length of the subdir
+ nLength2 = _tcslen(szSubDir);
+
+ // Cut all ending backslashes
+ while(nLength2 > 0 && szSubDir[nLength2 - 1] == _T(PATH_SEPARATOR))
+ nLength2--;
+ }
+
+ // Allocate space for the full path
+ szFullPath = szPathPtr = CASC_ALLOC(TCHAR, nLength1 + nLength2 + 2);
+ if(szFullPath != NULL)
+ {
+ // Copy the directory
+ if(szDirectory != NULL && nLength1 != 0)
+ {
+ memcpy(szPathPtr, szDirectory, (nLength1 * sizeof(TCHAR)));
+ szPathPtr += nLength1;
+ }
+
+ // Copy the sub-directory
+ if(szSubDir != NULL && nLength2 != 0)
+ {
+ // Append backslash to the previous one
+ if(szPathPtr > szFullPath)
+ *szPathPtr++ = _T(PATH_SEPARATOR);
+
+ // Copy the string
+ memcpy(szPathPtr, szSubDir, (nLength2 * sizeof(TCHAR)));
+ szPathPtr += nLength2;
+ }
+
+ // Terminate the string
+ szPathPtr[0] = 0;
+ }
+
+ return szFullPath;
+}
+
+void NormalizeFileName_UpperBkSlash(char * szFileName)
+{
+ // Normalize the file name: ToLower + BackSlashToSlash
+ for(size_t i = 0; szFileName[i] != 0; i++)
+ szFileName[i] = AsciiToUpperTable[szFileName[i]];
+}
+
+void NormalizeFileName_LowerSlash(char * szFileName)
+{
+ // Normalize the file name: ToLower + BackSlashToSlash
+ for(size_t i = 0; szFileName[i] != 0; i++)
+ {
+ szFileName[i] = AsciiToLowerTable[szFileName[i]];
+ szFileName[i] = (szFileName[i] != '\\') ? szFileName[i] : '/';
+ }
+}
+
+int ConvertDigitToInt32(const TCHAR * szString, PDWORD PtrValue)
+{
+ BYTE Digit;
+
+ Digit = (BYTE)(AsciiToUpperTable[szString[0]] - _T('0'));
+ if(Digit > 9)
+ Digit -= 'A' - '9' - 1;
+
+ PtrValue[0] = Digit;
+ return (Digit > 0x0F) ? ERROR_BAD_FORMAT : ERROR_SUCCESS;
+}
+
+int ConvertStringToInt32(const TCHAR * szString, size_t nMaxDigits, PDWORD PtrValue)
+{
+ // The number of digits must be even
+ assert((nMaxDigits & 0x01) == 0);
+ assert(nMaxDigits <= 8);
+
+ // Prepare the variables
+ PtrValue[0] = 0;
+ nMaxDigits >>= 1;
+
+ // Convert the string up to the number of digits
+ for(size_t i = 0; i < nMaxDigits; i++)
+ {
+ BYTE DigitOne;
+ BYTE DigitTwo;
+
+ DigitOne = (BYTE)(AsciiToUpperTable[szString[0]] - _T('0'));
+ if(DigitOne > 9)
+ DigitOne -= 'A' - '9' - 1;
+
+ DigitTwo = (BYTE)(AsciiToUpperTable[szString[1]] - _T('0'));
+ if(DigitTwo > 9)
+ DigitTwo -= 'A' - '9' - 1;
+
+ if(DigitOne > 0x0F || DigitTwo > 0x0F)
+ return ERROR_BAD_FORMAT;
+
+ PtrValue[0] = (PtrValue[0] << 0x08) | (DigitOne << 0x04) | DigitTwo;
+ szString += 2;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+char * StringFromBinary(LPBYTE pbBinary, size_t cbBinary, char * szBuffer)
+{
+ char * szSaveBuffer = szBuffer;
+
+ // Convert the string to the array of MD5
+ // Copy the blob data as text
+ for(size_t i = 0; i < cbBinary; i++)
+ {
+ *szBuffer++ = IntToHexChar[pbBinary[0] >> 0x04];
+ *szBuffer++ = IntToHexChar[pbBinary[0] & 0x0F];
+ pbBinary++;
+ }
+
+ // Terminate the string
+ *szBuffer = 0;
+ return szSaveBuffer;
+}
+
+//-----------------------------------------------------------------------------
+// File name utilities
+
+const wchar_t * GetPlainFileName(const wchar_t * szFileName)
+{
+ const wchar_t * szPlainName = szFileName;
+
+ while(*szFileName != 0)
+ {
+ if(*szFileName == '\\' || *szFileName == '/')
+ szPlainName = szFileName + 1;
+ szFileName++;
+ }
+
+ return szPlainName;
+}
+
+const char * GetPlainFileName(const char * szFileName)
+{
+ const char * szPlainName = szFileName;
+
+ while(*szFileName != 0)
+ {
+ if(*szFileName == '\\' || *szFileName == '/')
+ szPlainName = szFileName + 1;
+ szFileName++;
+ }
+
+ return szPlainName;
+}
+
+bool CheckWildCard(const char * szString, const char * szWildCard)
+{
+ const char * szSubString;
+ int nSubStringLength;
+ int nMatchCount = 0;
+
+ // When the mask is empty, it never matches
+ if(szWildCard == NULL || *szWildCard == 0)
+ return false;
+
+ // If the wildcard contains just "*", then it always matches
+ if(szWildCard[0] == '*' && szWildCard[1] == 0)
+ return true;
+
+ // Do normal test
+ for(;;)
+ {
+ // If there is '?' in the wildcard, we skip one char
+ while(*szWildCard == '?')
+ {
+ szWildCard++;
+ szString++;
+ }
+
+ // If there is '*', means zero or more chars. We have to
+ // find the sequence after '*'
+ if(*szWildCard == '*')
+ {
+ // More stars is equal to one star
+ while(*szWildCard == '*' || *szWildCard == '?')
+ szWildCard++;
+
+ // If we found end of the wildcard, it's a match
+ if(*szWildCard == 0)
+ return true;
+
+ // Determine the length of the substring in szWildCard
+ szSubString = szWildCard;
+ while(*szSubString != 0 && *szSubString != '?' && *szSubString != '*')
+ szSubString++;
+ nSubStringLength = (int)(szSubString - szWildCard);
+ nMatchCount = 0;
+
+ // Now we have to find a substring in szString,
+ // that matches the substring in szWildCard
+ while(*szString != 0)
+ {
+ // Calculate match count
+ while(nMatchCount < nSubStringLength)
+ {
+ if(AsciiToUpperTable[(BYTE)szString[nMatchCount]] != AsciiToUpperTable[(BYTE)szWildCard[nMatchCount]])
+ break;
+ if(szString[nMatchCount] == 0)
+ break;
+ nMatchCount++;
+ }
+
+ // If the match count has reached substring length, we found a match
+ if(nMatchCount == nSubStringLength)
+ {
+ szWildCard += nMatchCount;
+ szString += nMatchCount;
+ break;
+ }
+
+ // No match, move to the next char in szString
+ nMatchCount = 0;
+ szString++;
+ }
+ }
+ else
+ {
+ // If we came to the end of the string, compare it to the wildcard
+ if(AsciiToUpperTable[(BYTE)*szString] != AsciiToUpperTable[(BYTE)*szWildCard])
+ return false;
+
+ // If we arrived to the end of the string, it's a match
+ if(*szString == 0)
+ return true;
+
+ // Otherwise, continue in comparing
+ szWildCard++;
+ szString++;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Hashing functions
+
+bool IsValidMD5(LPBYTE pbMd5)
+{
+ BYTE BitSummary = 0;
+
+ // The MD5 is considered invalid of it is zeroed
+ BitSummary |= pbMd5[0x00] | pbMd5[0x01] | pbMd5[0x02] | pbMd5[0x03] | pbMd5[0x04] | pbMd5[0x05] | pbMd5[0x06] | pbMd5[0x07];
+ BitSummary |= pbMd5[0x08] | pbMd5[0x09] | pbMd5[0x0A] | pbMd5[0x0B] | pbMd5[0x0C] | pbMd5[0x0D] | pbMd5[0x0E] | pbMd5[0x0F];
+ return (BitSummary != 0);
+}
+
+bool VerifyDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE expected_md5)
+{
+ hash_state md5_state;
+ BYTE md5_digest[MD5_HASH_SIZE];
+
+ // Don't verify the block if the MD5 is not valid.
+ if(!IsValidMD5(expected_md5))
+ return true;
+
+ // Calculate the MD5 of the data block
+ md5_init(&md5_state);
+ md5_process(&md5_state, (unsigned char *)pvDataBlock, cbDataBlock);
+ md5_done(&md5_state, md5_digest);
+
+ // Does the MD5's match?
+ return (memcmp(md5_digest, expected_md5, MD5_HASH_SIZE) == 0);
+}
+
+void CalculateDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE md5_hash)
+{
+ hash_state md5_state;
+
+ md5_init(&md5_state);
+ md5_process(&md5_state, (unsigned char *)pvDataBlock, cbDataBlock);
+ md5_done(&md5_state, md5_hash);
+}
+
+//-----------------------------------------------------------------------------
+// We have our own qsort implementation, optimized for using array of pointers
+
+#define STKSIZ (8*sizeof(void*) - 2)
+
+#define SWAP_ENTRIES(index1, index2) \
+{ \
+ temp = base[index1]; \
+ base[index1] = base[index2]; \
+ base[index2] = temp; \
+}
+
+void qsort_pointer_array(void ** base, size_t num, int (*compare)(const void *, const void *, const void *), const void * context)
+{
+ size_t lo, hi; /* ends of sub-array currently sorting */
+ size_t mid; /* points to middle of subarray */
+ size_t loguy, higuy; /* traveling pointers for partition step */
+ size_t size; /* size of the sub-array */
+ size_t lostk[STKSIZ], histk[STKSIZ];
+ void * temp;
+ int stkptr; /* stack for saving sub-array to be processed */
+
+ /* validation section */
+ assert(base != NULL);
+ assert(compare != NULL);
+
+ if (num < 2)
+ return; /* nothing to do */
+
+ stkptr = 0; /* initialize stack */
+
+ lo = 0;
+ hi = (num-1); /* initialize limits */
+
+ /* this entry point is for pseudo-recursion calling: setting
+ lo and hi and jumping to here is like recursion, but stkptr is
+ preserved, locals aren't, so we preserve stuff on the stack */
+recurse:
+
+ size = (hi - lo) + 1; /* number of el's to sort */
+
+ /* First we pick a partitioning element. The efficiency of the
+ algorithm demands that we find one that is approximately the median
+ of the values, but also that we select one fast. We choose the
+ median of the first, middle, and last elements, to avoid bad
+ performance in the face of already sorted data, or data that is made
+ up of multiple sorted runs appended together. Testing shows that a
+ median-of-three algorithm provides better performance than simply
+ picking the middle element for the latter case. */
+
+ mid = lo + (size / 2); /* find middle element */
+
+ /* Sort the first, middle, last elements into order */
+ if (compare(context, base[lo], base[mid]) > 0) {
+ SWAP_ENTRIES(lo, mid);
+ }
+ if (compare(context, base[lo], base[hi]) > 0) {
+ SWAP_ENTRIES(lo, hi);
+ }
+ if (compare(context, base[mid], base[hi]) > 0) {
+ SWAP_ENTRIES(mid, hi);
+ }
+
+ /* We now wish to partition the array into three pieces, one consisting
+ of elements <= partition element, one of elements equal to the
+ partition element, and one of elements > than it. This is done
+ below; comments indicate conditions established at every step. */
+
+ loguy = lo;
+ higuy = hi;
+
+ /* Note that higuy decreases and loguy increases on every iteration,
+ so loop must terminate. */
+ for (;;) {
+ /* lo <= loguy < hi, lo < higuy <= hi,
+ A[i] <= A[mid] for lo <= i <= loguy,
+ A[i] > A[mid] for higuy <= i < hi,
+ A[hi] >= A[mid] */
+
+ /* The doubled loop is to avoid calling comp(mid,mid), since some
+ existing comparison funcs don't work when passed the same
+ value for both pointers. */
+
+ if (mid > loguy) {
+ do {
+ loguy ++;
+ } while (loguy < mid && compare(context, base[loguy], base[mid]) <= 0);
+ }
+ if (mid <= loguy) {
+ do {
+ loguy ++;
+ } while (loguy <= hi && compare(context, base[loguy], base[mid]) <= 0);
+ }
+
+ /* lo < loguy <= hi+1, A[i] <= A[mid] for lo <= i < loguy,
+ either loguy > hi or A[loguy] > A[mid] */
+
+ do {
+ higuy --;
+ } while (higuy > mid && compare(context, base[higuy], base[mid]) > 0);
+
+ /* lo <= higuy < hi, A[i] > A[mid] for higuy < i < hi,
+ either higuy == lo or A[higuy] <= A[mid] */
+
+ if (higuy < loguy)
+ break;
+
+ /* if loguy > hi or higuy == lo, then we would have exited, so
+ A[loguy] > A[mid], A[higuy] <= A[mid],
+ loguy <= hi, higuy > lo */
+
+ SWAP_ENTRIES(loguy, higuy);
+
+ /* If the partition element was moved, follow it. Only need
+ to check for mid == higuy, since before the swap,
+ A[loguy] > A[mid] implies loguy != mid. */
+
+ if (mid == higuy)
+ mid = loguy;
+
+ /* A[loguy] <= A[mid], A[higuy] > A[mid]; so condition at top
+ of loop is re-established */
+ }
+
+ /* A[i] <= A[mid] for lo <= i < loguy,
+ A[i] > A[mid] for higuy < i < hi,
+ A[hi] >= A[mid]
+ higuy < loguy
+ implying:
+ higuy == loguy-1
+ or higuy == hi - 1, loguy == hi + 1, A[hi] == A[mid] */
+
+ /* Find adjacent elements equal to the partition element. The
+ doubled loop is to avoid calling comp(mid,mid), since some
+ existing comparison funcs don't work when passed the same value
+ for both pointers. */
+
+ higuy ++;
+ if (mid < higuy) {
+ do {
+ higuy --;
+ } while (higuy > mid && compare(context, base[higuy], base[mid]) == 0);
+ }
+ if (mid >= higuy) {
+ do {
+ higuy --;
+ } while (higuy > lo && compare(context, base[higuy], base[mid]) == 0);
+ }
+
+ /* OK, now we have the following:
+ higuy < loguy
+ lo <= higuy <= hi
+ A[i] <= A[mid] for lo <= i <= higuy
+ A[i] == A[mid] for higuy < i < loguy
+ A[i] > A[mid] for loguy <= i < hi
+ A[hi] >= A[mid] */
+
+ /* We've finished the partition, now we want to sort the subarrays
+ [lo, higuy] and [loguy, hi].
+ We do the smaller one first to minimize stack usage.
+ We only sort arrays of length 2 or more.*/
+
+ if ( higuy - lo >= hi - loguy ) {
+ if (lo < higuy) {
+ lostk[stkptr] = lo;
+ histk[stkptr] = higuy;
+ ++stkptr;
+ } /* save big recursion for later */
+
+ if (loguy < hi) {
+ lo = loguy;
+ goto recurse; /* do small recursion */
+ }
+ }
+ else {
+ if (loguy < hi) {
+ lostk[stkptr] = loguy;
+ histk[stkptr] = hi;
+ ++stkptr; /* save big recursion for later */
+ }
+
+ if (lo < higuy) {
+ hi = higuy;
+ goto recurse; /* do small recursion */
+ }
+ }
+
+ /* We have sorted the array, except for any pending sorts on the stack.
+ Check if there are any, and do them. */
+
+ --stkptr;
+ if (stkptr >= 0) {
+ lo = lostk[stkptr];
+ hi = histk[stkptr];
+ goto recurse; /* pop subarray from stack */
+ }
+ else
+ return; /* all subarrays done */
+}
diff --git a/dep/CascLib/src/common/Common.h b/dep/CascLib/src/common/Common.h
new file mode 100644
index 00000000000..eb192fd50ca
--- /dev/null
+++ b/dep/CascLib/src/common/Common.h
@@ -0,0 +1,98 @@
+/*****************************************************************************/
+/* CascCommon.h Copyright (c) Ladislav Zezula 2014 */
+/*---------------------------------------------------------------------------*/
+/* Common functions for CascLib */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 29.04.14 1.00 Lad The first version of CascCommon.h */
+/*****************************************************************************/
+
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+//-----------------------------------------------------------------------------
+// Common macros
+
+// Macro for building 64-bit file offset from two 32-bit
+#define MAKE_OFFSET64(hi, lo) (((ULONGLONG)hi << 32) | (ULONGLONG)lo)
+
+#ifndef ALIGN_TO_SIZE
+#define ALIGN_TO_SIZE(x, a) (((x) + (a)-1) & ~((a)-1))
+#endif
+
+//-----------------------------------------------------------------------------
+// Conversion tables
+
+extern unsigned char AsciiToLowerTable[256];
+extern unsigned char AsciiToUpperTable[256];
+extern unsigned char IntToHexChar[];
+
+//-----------------------------------------------------------------------------
+// Memory management helper
+
+#if defined(_MSC_VER) && defined(_DEBUG)
+void * DbgRealloc(void * ptr, size_t nSize);
+#endif
+
+//-----------------------------------------------------------------------------
+// GetLastError/SetLastError support for non-Windows platform
+
+#ifndef PLATFORM_WINDOWS
+int GetLastError();
+void SetLastError(int nError);
+#endif // PLATFORM_WINDOWS
+
+//-----------------------------------------------------------------------------
+// String manipulation
+
+void CopyString(char * szTarget, const char * szSource, size_t cchLength);
+void CopyString(wchar_t * szTarget, const char * szSource, size_t cchLength);
+void CopyString(char * szTarget, const wchar_t * szSource, size_t cchLength);
+
+char * NewStr(const char * szString, size_t nCharsToReserve);
+wchar_t * NewStr(const wchar_t * szString, size_t nCharsToReserve);
+
+TCHAR * NewStrFromAnsi(LPBYTE pbStringBegin, LPBYTE pbStringEnd);
+
+TCHAR * CombinePath(const TCHAR * szPath, const TCHAR * szSubDir);
+
+void NormalizeFileName_UpperBkSlash(char * szFileName);
+void NormalizeFileName_LowerSlash(char * szFileName);
+
+int ConvertDigitToInt32(const TCHAR * szString, PDWORD PtrValue);
+int ConvertStringToInt32(const TCHAR * szString, size_t nMaxDigits, PDWORD PtrValue);
+char * StringFromBinary(LPBYTE pbBinary, size_t cbBinary, char * szBuffer);
+
+//-----------------------------------------------------------------------------
+// File name utilities
+
+bool CheckWildCard(const char * szString, const char * szWildCard);
+const wchar_t * GetPlainFileName(const wchar_t * szFileName);
+const char * GetPlainFileName(const char * szFileName);
+
+//-----------------------------------------------------------------------------
+// Hashing functions
+
+ULONGLONG HashStringJenkins(const char * szFileName);
+
+bool IsValidMD5(LPBYTE pbMd5);
+void CalculateDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE md5_hash);
+bool VerifyDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE expected_md5);
+
+//-----------------------------------------------------------------------------
+// Scanning a directory
+
+typedef bool (*INDEX_FILE_FOUND)(const TCHAR * szFileName, PDWORD IndexArray, PDWORD OldIndexArray, void * pvContext);
+
+bool DirectoryExists(const TCHAR * szDirectory);
+
+int ScanIndexDirectory(
+ const TCHAR * szIndexPath,
+ INDEX_FILE_FOUND pfnOnFileFound,
+ PDWORD IndexArray,
+ PDWORD OldIndexArray,
+ void * pvContext
+ );
+
+#endif // __COMMON_H__
diff --git a/dep/CascLib/src/common/Directory.cpp b/dep/CascLib/src/common/Directory.cpp
new file mode 100644
index 00000000000..cd02db19be3
--- /dev/null
+++ b/dep/CascLib/src/common/Directory.cpp
@@ -0,0 +1,102 @@
+/*****************************************************************************/
+/* Directory.cpp Copyright (c) Ladislav Zezula 2014 */
+/*---------------------------------------------------------------------------*/
+/* System-dependent directory functions for CascLib */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 29.04.14 1.00 Lad The first version of Directory.cpp */
+/*****************************************************************************/
+
+#define __CASCLIB_SELF__
+#include "../CascLib.h"
+#include "../CascCommon.h"
+
+//-----------------------------------------------------------------------------
+// Public functions
+
+bool DirectoryExists(const TCHAR * szDirectory)
+{
+#ifdef PLATFORM_WINDOWS
+
+ DWORD dwAttributes = GetFileAttributes(szDirectory);
+ if((dwAttributes != INVALID_FILE_ATTRIBUTES) && (dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ return true;
+
+#else // PLATFORM_WINDOWS
+
+ DIR * dir = opendir(szDirectory);
+
+ if(dir != NULL)
+ {
+ closedir(dir);
+ return true;
+ }
+
+#endif
+
+ return false;
+}
+
+int ScanIndexDirectory(
+ const TCHAR * szIndexPath,
+ INDEX_FILE_FOUND pfnOnFileFound,
+ PDWORD MainIndexes,
+ PDWORD OldIndexArray,
+ void * pvContext)
+{
+#ifdef PLATFORM_WINDOWS
+
+ WIN32_FIND_DATA wf;
+ TCHAR * szSearchMask;
+ HANDLE hFind;
+
+ // Prepare the search mask
+ szSearchMask = CombinePath(szIndexPath, _T("*"));
+ if(szSearchMask == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ // Prepare directory search
+ hFind = FindFirstFile(szSearchMask, &wf);
+ if(hFind != INVALID_HANDLE_VALUE)
+ {
+ // Skip the first file as it's always just "." or ".."
+ while(FindNextFile(hFind, &wf))
+ {
+ // If the found object is a file, pass it to the handler
+ if(!(wf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ // Let the callback scan the file name
+ pfnOnFileFound(wf.cFileName, MainIndexes, OldIndexArray, pvContext);
+ }
+ }
+
+ // Close the search handle
+ FindClose(hFind);
+ }
+
+ CASC_FREE(szSearchMask);
+
+#else // PLATFORM_WINDOWS
+
+ struct dirent * dir_entry;
+ DIR * dir;
+
+ dir = opendir(szIndexPath);
+ if(dir != NULL)
+ {
+ while((dir_entry = readdir(dir)) != NULL)
+ {
+ if(dir_entry->d_type != DT_DIR)
+ {
+ pfnOnFileFound(dir_entry->d_name, MainIndexes, OldIndexArray, pvContext);
+ }
+ }
+
+ closedir(dir);
+ }
+
+#endif
+
+ return ERROR_SUCCESS;
+}
diff --git a/dep/CascLib/src/common/FileStream.cpp b/dep/CascLib/src/common/FileStream.cpp
new file mode 100644
index 00000000000..09ac47bd095
--- /dev/null
+++ b/dep/CascLib/src/common/FileStream.cpp
@@ -0,0 +1,2721 @@
+/*****************************************************************************/
+/* FileStream.cpp Copyright (c) Ladislav Zezula 2010 */
+/*---------------------------------------------------------------------------*/
+/* File stream support for CascLib */
+/* */
+/* Windows support: Written by Ladislav Zezula */
+/* Mac support: Written by Sam Wilkins */
+/* Linux support: Written by Sam Wilkins and Ivan Komissarov */
+/* Big-endian: Written & debugged by Sam Wilkins */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 28.04.14 1.00 Lad Copied from StormLib */
+/*****************************************************************************/
+
+#define __CASCLIB_SELF__
+#include "../CascLib.h"
+#include "../CascCommon.h"
+#include "FileStream.h"
+
+#ifdef _MSC_VER
+#pragma comment(lib, "wininet.lib") // Internet functions for HTTP stream
+#pragma warning(disable: 4800) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
+#endif
+
+//-----------------------------------------------------------------------------
+// Local functions - platform-specific functions
+
+static DWORD StringToInt(const char * szString)
+{
+ DWORD dwValue = 0;
+
+ while('0' <= szString[0] && szString[0] <= '9')
+ {
+ dwValue = (dwValue * 10) + (szString[0] - '9');
+ szString++;
+ }
+
+ return dwValue;
+}
+
+//-----------------------------------------------------------------------------
+// Dummy init function
+
+static void BaseNone_Init(TFileStream *)
+{
+ // Nothing here
+}
+
+//-----------------------------------------------------------------------------
+// Local functions - base file support
+
+static bool BaseFile_Create(TFileStream * pStream)
+{
+#ifdef PLATFORM_WINDOWS
+ {
+ DWORD dwWriteShare = (pStream->dwFlags & STREAM_FLAG_WRITE_SHARE) ? FILE_SHARE_WRITE : 0;
+
+ pStream->Base.File.hFile = CreateFile(pStream->szFileName,
+ GENERIC_READ | GENERIC_WRITE,
+ dwWriteShare | FILE_SHARE_READ,
+ NULL,
+ CREATE_ALWAYS,
+ 0,
+ NULL);
+ if(pStream->Base.File.hFile == INVALID_HANDLE_VALUE)
+ return false;
+ }
+#endif
+
+#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+ {
+ intptr_t handle;
+
+ handle = open(pStream->szFileName, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ if(handle == -1)
+ {
+ SetLastError(errno);
+ return false;
+ }
+
+ pStream->Base.File.hFile = (HANDLE)handle;
+ }
+#endif
+
+ // Reset the file size and position
+ pStream->Base.File.FileSize = 0;
+ pStream->Base.File.FilePos = 0;
+ return true;
+}
+
+static bool BaseFile_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD dwStreamFlags)
+{
+#ifdef PLATFORM_WINDOWS
+ {
+ ULARGE_INTEGER FileSize;
+ DWORD dwWriteAccess = (dwStreamFlags & STREAM_FLAG_READ_ONLY) ? 0 : FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES;
+ DWORD dwWriteShare = (dwStreamFlags & STREAM_FLAG_WRITE_SHARE) ? FILE_SHARE_WRITE : 0;
+
+ // Open the file
+ pStream->Base.File.hFile = CreateFile(szFileName,
+ FILE_READ_DATA | FILE_READ_ATTRIBUTES | dwWriteAccess,
+ FILE_SHARE_READ | dwWriteShare,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+ if(pStream->Base.File.hFile == INVALID_HANDLE_VALUE)
+ return false;
+
+ // Query the file size
+ FileSize.LowPart = GetFileSize(pStream->Base.File.hFile, &FileSize.HighPart);
+ pStream->Base.File.FileSize = FileSize.QuadPart;
+
+ // Query last write time
+ GetFileTime(pStream->Base.File.hFile, NULL, NULL, (LPFILETIME)&pStream->Base.File.FileTime);
+ }
+#endif
+
+#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+ {
+ struct stat64 fileinfo;
+ int oflag = (dwStreamFlags & STREAM_FLAG_READ_ONLY) ? O_RDONLY : O_RDWR;
+ intptr_t handle;
+
+ // Open the file
+ handle = open(szFileName, oflag | O_LARGEFILE);
+ if(handle == -1)
+ {
+ SetLastError(errno);
+ return false;
+ }
+
+ // Get the file size
+ if(fstat64(handle, &fileinfo) == -1)
+ {
+ SetLastError(errno);
+ return false;
+ }
+
+ // time_t is number of seconds since 1.1.1970, UTC.
+ // 1 second = 10000000 (decimal) in FILETIME
+ // Set the start to 1.1.1970 00:00:00
+ pStream->Base.File.FileTime = 0x019DB1DED53E8000ULL + (10000000 * fileinfo.st_mtime);
+ pStream->Base.File.FileSize = (ULONGLONG)fileinfo.st_size;
+ pStream->Base.File.hFile = (HANDLE)handle;
+ }
+#endif
+
+ // Reset the file position
+ pStream->Base.File.FilePos = 0;
+ return true;
+}
+
+static bool BaseFile_Read(
+ TFileStream * pStream, // Pointer to an open stream
+ ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position
+ void * pvBuffer, // Pointer to data to be read
+ DWORD dwBytesToRead) // Number of bytes to read from the file
+{
+ ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.File.FilePos;
+ DWORD dwBytesRead = 0; // Must be set by platform-specific code
+
+#ifdef PLATFORM_WINDOWS
+ {
+ // Note: CascLib no longer supports Windows 9x.
+ // Thus, we can use the OVERLAPPED structure to specify
+ // file offset to read from file. This allows us to skip
+ // one system call to SetFilePointer
+
+ // Update the byte offset
+ pStream->Base.File.FilePos = ByteOffset;
+
+ // Read the data
+ if(dwBytesToRead != 0)
+ {
+ OVERLAPPED Overlapped;
+
+ Overlapped.OffsetHigh = (DWORD)(ByteOffset >> 32);
+ Overlapped.Offset = (DWORD)ByteOffset;
+ Overlapped.hEvent = NULL;
+ if(!ReadFile(pStream->Base.File.hFile, pvBuffer, dwBytesToRead, &dwBytesRead, &Overlapped))
+ return false;
+ }
+ }
+#endif
+
+#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+ {
+ ssize_t bytes_read;
+
+ // If the byte offset is different from the current file position,
+ // we have to update the file position
+ if(ByteOffset != pStream->Base.File.FilePos)
+ {
+ lseek64((intptr_t)pStream->Base.File.hFile, (off64_t)(ByteOffset), SEEK_SET);
+ pStream->Base.File.FilePos = ByteOffset;
+ }
+
+ // Perform the read operation
+ if(dwBytesToRead != 0)
+ {
+ bytes_read = read((intptr_t)pStream->Base.File.hFile, pvBuffer, (size_t)dwBytesToRead);
+ if(bytes_read == -1)
+ {
+ SetLastError(errno);
+ return false;
+ }
+
+ dwBytesRead = (DWORD)(size_t)bytes_read;
+ }
+ }
+#endif
+
+ // Increment the current file position by number of bytes read
+ // If the number of bytes read doesn't match to required amount, return false
+ pStream->Base.File.FilePos = ByteOffset + dwBytesRead;
+ if(dwBytesRead != dwBytesToRead)
+ SetLastError(ERROR_HANDLE_EOF);
+ return (dwBytesRead == dwBytesToRead);
+}
+
+/**
+ * \a pStream Pointer to an open stream
+ * \a pByteOffset Pointer to file byte offset. If NULL, writes to current position
+ * \a pvBuffer Pointer to data to be written
+ * \a dwBytesToWrite Number of bytes to write to the file
+ */
+
+static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const void * pvBuffer, DWORD dwBytesToWrite)
+{
+ ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.File.FilePos;
+ DWORD dwBytesWritten = 0; // Must be set by platform-specific code
+
+#ifdef PLATFORM_WINDOWS
+ {
+ // Note: CascLib no longer supports Windows 9x.
+ // Thus, we can use the OVERLAPPED structure to specify
+ // file offset to read from file. This allows us to skip
+ // one system call to SetFilePointer
+
+ // Update the byte offset
+ pStream->Base.File.FilePos = ByteOffset;
+
+ // Read the data
+ if(dwBytesToWrite != 0)
+ {
+ OVERLAPPED Overlapped;
+
+ Overlapped.OffsetHigh = (DWORD)(ByteOffset >> 32);
+ Overlapped.Offset = (DWORD)ByteOffset;
+ Overlapped.hEvent = NULL;
+ if(!WriteFile(pStream->Base.File.hFile, pvBuffer, dwBytesToWrite, &dwBytesWritten, &Overlapped))
+ return false;
+ }
+ }
+#endif
+
+#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+ {
+ ssize_t bytes_written;
+
+ // If the byte offset is different from the current file position,
+ // we have to update the file position
+ if(ByteOffset != pStream->Base.File.FilePos)
+ {
+ lseek64((intptr_t)pStream->Base.File.hFile, (off64_t)(ByteOffset), SEEK_SET);
+ pStream->Base.File.FilePos = ByteOffset;
+ }
+
+ // Perform the read operation
+ bytes_written = write((intptr_t)pStream->Base.File.hFile, pvBuffer, (size_t)dwBytesToWrite);
+ if(bytes_written == -1)
+ {
+ SetLastError(errno);
+ return false;
+ }
+
+ dwBytesWritten = (DWORD)(size_t)bytes_written;
+ }
+#endif
+
+ // Increment the current file position by number of bytes read
+ pStream->Base.File.FilePos = ByteOffset + dwBytesWritten;
+
+ // Also modify the file size, if needed
+ if(pStream->Base.File.FilePos > pStream->Base.File.FileSize)
+ pStream->Base.File.FileSize = pStream->Base.File.FilePos;
+
+ if(dwBytesWritten != dwBytesToWrite)
+ SetLastError(ERROR_DISK_FULL);
+ return (dwBytesWritten == dwBytesToWrite);
+}
+
+/**
+ * \a pStream Pointer to an open stream
+ * \a NewFileSize New size of the file
+ */
+static bool BaseFile_Resize(TFileStream * pStream, ULONGLONG NewFileSize)
+{
+#ifdef PLATFORM_WINDOWS
+ {
+ LONG FileSizeHi = (LONG)(NewFileSize >> 32);
+ LONG FileSizeLo;
+ DWORD dwNewPos;
+ bool bResult;
+
+ // Set the position at the new file size
+ dwNewPos = SetFilePointer(pStream->Base.File.hFile, (LONG)NewFileSize, &FileSizeHi, FILE_BEGIN);
+ if(dwNewPos == INVALID_SET_FILE_POINTER && GetLastError() != ERROR_SUCCESS)
+ return false;
+
+ // Set the current file pointer as the end of the file
+ bResult = (bool)SetEndOfFile(pStream->Base.File.hFile);
+ if(bResult)
+ pStream->Base.File.FileSize = NewFileSize;
+
+ // Restore the file position
+ FileSizeHi = (LONG)(pStream->Base.File.FilePos >> 32);
+ FileSizeLo = (LONG)(pStream->Base.File.FilePos);
+ SetFilePointer(pStream->Base.File.hFile, FileSizeLo, &FileSizeHi, FILE_BEGIN);
+ return bResult;
+ }
+#endif
+
+#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+ {
+ if(ftruncate64((intptr_t)pStream->Base.File.hFile, (off64_t)NewFileSize) == -1)
+ {
+ SetLastError(errno);
+ return false;
+ }
+
+ pStream->Base.File.FileSize = NewFileSize;
+ return true;
+ }
+#endif
+}
+
+// Gives the current file size
+static bool BaseFile_GetSize(TFileStream * pStream, ULONGLONG * pFileSize)
+{
+ // Note: Used by all thre base providers.
+ // Requires the TBaseData union to have the same layout for all three base providers
+ *pFileSize = pStream->Base.File.FileSize;
+ return true;
+}
+
+// Gives the current file position
+static bool BaseFile_GetPos(TFileStream * pStream, ULONGLONG * pByteOffset)
+{
+ // Note: Used by all thre base providers.
+ // Requires the TBaseData union to have the same layout for all three base providers
+ *pByteOffset = pStream->Base.File.FilePos;
+ return true;
+}
+
+// Renames the file pointed by pStream so that it contains data from pNewStream
+static bool BaseFile_Replace(TFileStream * pStream, TFileStream * pNewStream)
+{
+#ifdef PLATFORM_WINDOWS
+ // Delete the original stream file. Don't check the result value,
+ // because if the file doesn't exist, it would fail
+ DeleteFile(pStream->szFileName);
+
+ // Rename the new file to the old stream's file
+ return (bool)MoveFile(pNewStream->szFileName, pStream->szFileName);
+#endif
+
+#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+ // "rename" on Linux also works if the target file exists
+ if(rename(pNewStream->szFileName, pStream->szFileName) == -1)
+ {
+ SetLastError(errno);
+ return false;
+ }
+
+ return true;
+#endif
+}
+
+static void BaseFile_Close(TFileStream * pStream)
+{
+ if(pStream->Base.File.hFile != INVALID_HANDLE_VALUE)
+ {
+#ifdef PLATFORM_WINDOWS
+ CloseHandle(pStream->Base.File.hFile);
+#endif
+
+#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+ close((intptr_t)pStream->Base.File.hFile);
+#endif
+ }
+
+ // Also invalidate the handle
+ pStream->Base.File.hFile = INVALID_HANDLE_VALUE;
+}
+
+// Initializes base functions for the disk file
+static void BaseFile_Init(TFileStream * pStream)
+{
+ pStream->BaseCreate = BaseFile_Create;
+ pStream->BaseOpen = BaseFile_Open;
+ pStream->BaseRead = BaseFile_Read;
+ pStream->BaseWrite = BaseFile_Write;
+ pStream->BaseResize = BaseFile_Resize;
+ pStream->BaseGetSize = BaseFile_GetSize;
+ pStream->BaseGetPos = BaseFile_GetPos;
+ pStream->BaseClose = BaseFile_Close;
+}
+
+//-----------------------------------------------------------------------------
+// Local functions - base memory-mapped file support
+
+static bool BaseMap_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD dwStreamFlags)
+{
+#ifdef PLATFORM_WINDOWS
+
+ ULARGE_INTEGER FileSize;
+ HANDLE hFile;
+ HANDLE hMap;
+ bool bResult = false;
+
+ // Keep compiler happy
+ dwStreamFlags = dwStreamFlags;
+
+ // Open the file for read access
+ hFile = CreateFile(szFileName, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+ if(hFile != INVALID_HANDLE_VALUE)
+ {
+ // Retrieve file size. Don't allow mapping file of a zero size.
+ FileSize.LowPart = GetFileSize(hFile, &FileSize.HighPart);
+ if(FileSize.QuadPart != 0)
+ {
+ // Now create mapping object
+ hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+ if(hMap != NULL)
+ {
+ // Map the entire view into memory
+ // Note that this operation will fail if the file can't fit
+ // into usermode address space
+ pStream->Base.Map.pbFile = (LPBYTE)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
+ if(pStream->Base.Map.pbFile != NULL)
+ {
+ // Retrieve file time
+ GetFileTime(hFile, NULL, NULL, (LPFILETIME)&pStream->Base.Map.FileTime);
+
+ // Retrieve file size and position
+ pStream->Base.Map.FileSize = FileSize.QuadPart;
+ pStream->Base.Map.FilePos = 0;
+ bResult = true;
+ }
+
+ // Close the map handle
+ CloseHandle(hMap);
+ }
+ }
+
+ // Close the file handle
+ CloseHandle(hFile);
+ }
+
+ // If the file is not there and is not available for random access,
+ // report error
+ if(bResult == false)
+ return false;
+#endif
+
+#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+ struct stat64 fileinfo;
+ intptr_t handle;
+ bool bResult = false;
+
+ // Open the file
+ handle = open(szFileName, O_RDONLY);
+ if(handle != -1)
+ {
+ // Get the file size
+ if(fstat64(handle, &fileinfo) != -1)
+ {
+ pStream->Base.Map.pbFile = (LPBYTE)mmap(NULL, (size_t)fileinfo.st_size, PROT_READ, MAP_PRIVATE, handle, 0);
+ if(pStream->Base.Map.pbFile != NULL)
+ {
+ // time_t is number of seconds since 1.1.1970, UTC.
+ // 1 second = 10000000 (decimal) in FILETIME
+ // Set the start to 1.1.1970 00:00:00
+ pStream->Base.Map.FileTime = 0x019DB1DED53E8000ULL + (10000000 * fileinfo.st_mtime);
+ pStream->Base.Map.FileSize = (ULONGLONG)fileinfo.st_size;
+ pStream->Base.Map.FilePos = 0;
+ bResult = true;
+ }
+ }
+ close(handle);
+ }
+
+ // Did the mapping fail?
+ if(bResult == false)
+ {
+ SetLastError(errno);
+ return false;
+ }
+#endif
+
+ return true;
+}
+
+static bool BaseMap_Read(
+ TFileStream * pStream, // Pointer to an open stream
+ ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position
+ void * pvBuffer, // Pointer to data to be read
+ DWORD dwBytesToRead) // Number of bytes to read from the file
+{
+ ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.Map.FilePos;
+
+ // Do we have to read anything at all?
+ if(dwBytesToRead != 0)
+ {
+ // Don't allow reading past file size
+ if((ByteOffset + dwBytesToRead) > pStream->Base.Map.FileSize)
+ return false;
+
+ // Copy the required data
+ memcpy(pvBuffer, pStream->Base.Map.pbFile + (size_t)ByteOffset, dwBytesToRead);
+ }
+
+ // Move the current file position
+ pStream->Base.Map.FilePos += dwBytesToRead;
+ return true;
+}
+
+static void BaseMap_Close(TFileStream * pStream)
+{
+#ifdef PLATFORM_WINDOWS
+ if(pStream->Base.Map.pbFile != NULL)
+ UnmapViewOfFile(pStream->Base.Map.pbFile);
+#endif
+
+#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+ if(pStream->Base.Map.pbFile != NULL)
+ munmap(pStream->Base.Map.pbFile, (size_t )pStream->Base.Map.FileSize);
+#endif
+
+ pStream->Base.Map.pbFile = NULL;
+}
+
+// Initializes base functions for the mapped file
+static void BaseMap_Init(TFileStream * pStream)
+{
+ // Supply the file stream functions
+ pStream->BaseOpen = BaseMap_Open;
+ pStream->BaseRead = BaseMap_Read;
+ pStream->BaseGetSize = BaseFile_GetSize; // Reuse BaseFile function
+ pStream->BaseGetPos = BaseFile_GetPos; // Reuse BaseFile function
+ pStream->BaseClose = BaseMap_Close;
+
+ // Mapped files are read-only
+ pStream->dwFlags |= STREAM_FLAG_READ_ONLY;
+}
+
+//-----------------------------------------------------------------------------
+// Local functions - base HTTP file support
+
+static const TCHAR * BaseHttp_ExtractServerName(const TCHAR * szFileName, TCHAR * szServerName)
+{
+ // Check for HTTP
+ if(!_tcsnicmp(szFileName, _T("http://"), 7))
+ szFileName += 7;
+
+ // Cut off the server name
+ if(szServerName != NULL)
+ {
+ while(szFileName[0] != 0 && szFileName[0] != _T('/'))
+ *szServerName++ = *szFileName++;
+ *szServerName = 0;
+ }
+ else
+ {
+ while(szFileName[0] != 0 && szFileName[0] != _T('/'))
+ szFileName++;
+ }
+
+ // Return the remainder
+ return szFileName;
+}
+
+static bool BaseHttp_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD dwStreamFlags)
+{
+#ifdef PLATFORM_WINDOWS
+
+ HINTERNET hRequest;
+ DWORD dwTemp = 0;
+ bool bFileAvailable = false;
+ int nError = ERROR_SUCCESS;
+
+ // Keep compiler happy
+ dwStreamFlags = dwStreamFlags;
+
+ // Don't connect to the internet
+ if(!InternetGetConnectedState(&dwTemp, 0))
+ nError = GetLastError();
+
+ // Initiate the connection to the internet
+ if(nError == ERROR_SUCCESS)
+ {
+ pStream->Base.Http.hInternet = InternetOpen(_T("CascLib HTTP archive reader"),
+ INTERNET_OPEN_TYPE_PRECONFIG,
+ NULL,
+ NULL,
+ 0);
+ if(pStream->Base.Http.hInternet == NULL)
+ nError = GetLastError();
+ }
+
+ // Connect to the server
+ if(nError == ERROR_SUCCESS)
+ {
+ TCHAR szServerName[MAX_PATH];
+ DWORD dwFlags = INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_UI | INTERNET_FLAG_NO_CACHE_WRITE;
+
+ // Initiate connection with the server
+ szFileName = BaseHttp_ExtractServerName(szFileName, szServerName);
+ pStream->Base.Http.hConnect = InternetConnect(pStream->Base.Http.hInternet,
+ szServerName,
+ INTERNET_DEFAULT_HTTP_PORT,
+ NULL,
+ NULL,
+ INTERNET_SERVICE_HTTP,
+ dwFlags,
+ 0);
+ if(pStream->Base.Http.hConnect == NULL)
+ nError = GetLastError();
+ }
+
+ // Now try to query the file size
+ if(nError == ERROR_SUCCESS)
+ {
+ // Open HTTP request to the file
+ hRequest = HttpOpenRequest(pStream->Base.Http.hConnect, _T("GET"), szFileName, NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
+ if(hRequest != NULL)
+ {
+ if(HttpSendRequest(hRequest, NULL, 0, NULL, 0))
+ {
+ ULONGLONG FileTime = 0;
+ DWORD dwFileSize = 0;
+ DWORD dwDataSize;
+ DWORD dwIndex = 0;
+
+ // Check if the archive has Last Modified field
+ dwDataSize = sizeof(ULONGLONG);
+ if(HttpQueryInfo(hRequest, HTTP_QUERY_LAST_MODIFIED | HTTP_QUERY_FLAG_SYSTEMTIME, &FileTime, &dwDataSize, &dwIndex))
+ pStream->Base.Http.FileTime = FileTime;
+
+ // Verify if the server supports random access
+ dwDataSize = sizeof(DWORD);
+ if(HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &dwFileSize, &dwDataSize, &dwIndex))
+ {
+ if(dwFileSize != 0)
+ {
+ pStream->Base.Http.FileSize = dwFileSize;
+ pStream->Base.Http.FilePos = 0;
+ bFileAvailable = true;
+ }
+ }
+ }
+ InternetCloseHandle(hRequest);
+ }
+ }
+
+ // If the file is not there and is not available for random access,
+ // report error
+ if(bFileAvailable == false)
+ {
+ pStream->BaseClose(pStream);
+ return false;
+ }
+
+ return true;
+
+#else
+
+ // Not supported
+ SetLastError(ERROR_NOT_SUPPORTED);
+ pStream = pStream;
+ return false;
+
+#endif
+}
+
+static bool BaseHttp_Read(
+ TFileStream * pStream, // Pointer to an open stream
+ ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position
+ void * pvBuffer, // Pointer to data to be read
+ DWORD dwBytesToRead) // Number of bytes to read from the file
+{
+#ifdef PLATFORM_WINDOWS
+ ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.Http.FilePos;
+ DWORD dwTotalBytesRead = 0;
+
+ // Do we have to read anything at all?
+ if(dwBytesToRead != 0)
+ {
+ HINTERNET hRequest;
+ LPCTSTR szFileName;
+ LPBYTE pbBuffer = (LPBYTE)pvBuffer;
+ TCHAR szRangeRequest[0x80];
+ DWORD dwStartOffset = (DWORD)ByteOffset;
+ DWORD dwEndOffset = dwStartOffset + dwBytesToRead;
+
+ // Open HTTP request to the file
+ szFileName = BaseHttp_ExtractServerName(pStream->szFileName, NULL);
+ hRequest = HttpOpenRequest(pStream->Base.Http.hConnect, _T("GET"), szFileName, NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
+ if(hRequest != NULL)
+ {
+ // Add range request to the HTTP headers
+ // http://www.clevercomponents.com/articles/article015/resuming.asp
+ _stprintf(szRangeRequest, _T("Range: bytes=%u-%u"), (unsigned int)dwStartOffset, (unsigned int)dwEndOffset);
+ HttpAddRequestHeaders(hRequest, szRangeRequest, 0xFFFFFFFF, HTTP_ADDREQ_FLAG_ADD_IF_NEW);
+
+ // Send the request to the server
+ if(HttpSendRequest(hRequest, NULL, 0, NULL, 0))
+ {
+ while(dwTotalBytesRead < dwBytesToRead)
+ {
+ DWORD dwBlockBytesToRead = dwBytesToRead - dwTotalBytesRead;
+ DWORD dwBlockBytesRead = 0;
+
+ // Read the block from the file
+ if(dwBlockBytesToRead > 0x200)
+ dwBlockBytesToRead = 0x200;
+ InternetReadFile(hRequest, pbBuffer, dwBlockBytesToRead, &dwBlockBytesRead);
+
+ // Check for end
+ if(dwBlockBytesRead == 0)
+ break;
+
+ // Move buffers
+ dwTotalBytesRead += dwBlockBytesRead;
+ pbBuffer += dwBlockBytesRead;
+ }
+ }
+ InternetCloseHandle(hRequest);
+ }
+ }
+
+ // Increment the current file position by number of bytes read
+ pStream->Base.Http.FilePos = ByteOffset + dwTotalBytesRead;
+
+ // If the number of bytes read doesn't match the required amount, return false
+ if(dwTotalBytesRead != dwBytesToRead)
+ SetLastError(ERROR_HANDLE_EOF);
+ return (dwTotalBytesRead == dwBytesToRead);
+
+#else
+
+ // Not supported
+ pStream = pStream;
+ pByteOffset = pByteOffset;
+ pvBuffer = pvBuffer;
+ dwBytesToRead = dwBytesToRead;
+ SetLastError(ERROR_NOT_SUPPORTED);
+ return false;
+
+#endif
+}
+
+static void BaseHttp_Close(TFileStream * pStream)
+{
+#ifdef PLATFORM_WINDOWS
+ if(pStream->Base.Http.hConnect != NULL)
+ InternetCloseHandle(pStream->Base.Http.hConnect);
+ pStream->Base.Http.hConnect = NULL;
+
+ if(pStream->Base.Http.hInternet != NULL)
+ InternetCloseHandle(pStream->Base.Http.hInternet);
+ pStream->Base.Http.hInternet = NULL;
+#else
+ pStream = pStream;
+#endif
+}
+
+// Initializes base functions for the mapped file
+static void BaseHttp_Init(TFileStream * pStream)
+{
+ // Supply the stream functions
+ pStream->BaseOpen = BaseHttp_Open;
+ pStream->BaseRead = BaseHttp_Read;
+ pStream->BaseGetSize = BaseFile_GetSize; // Reuse BaseFile function
+ pStream->BaseGetPos = BaseFile_GetPos; // Reuse BaseFile function
+ pStream->BaseClose = BaseHttp_Close;
+
+ // HTTP files are read-only
+ pStream->dwFlags |= STREAM_FLAG_READ_ONLY;
+}
+
+//-----------------------------------------------------------------------------
+// Local functions - base block-based support
+
+// Generic function that loads blocks from the file
+// The function groups the block with the same availability,
+// so the called BlockRead can finish the request in a single system call
+static bool BlockStream_Read(
+ TBlockStream * pStream, // Pointer to an open stream
+ ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position
+ void * pvBuffer, // Pointer to data to be read
+ DWORD dwBytesToRead) // Number of bytes to read from the file
+{
+ ULONGLONG BlockOffset0;
+ ULONGLONG BlockOffset;
+ ULONGLONG ByteOffset;
+ ULONGLONG EndOffset;
+ LPBYTE TransferBuffer;
+ LPBYTE BlockBuffer;
+ DWORD BlockBufferOffset; // Offset of the desired data in the block buffer
+ DWORD BytesNeeded; // Number of bytes that really need to be read
+ DWORD BlockSize = pStream->BlockSize;
+ DWORD BlockCount;
+ bool bPrevBlockAvailable;
+ bool bCallbackCalled = false;
+ bool bBlockAvailable;
+ bool bResult = true;
+
+ // The base block read function must be present
+ assert(pStream->BlockRead != NULL);
+
+ // NOP reading of zero bytes
+ if(dwBytesToRead == 0)
+ return true;
+
+ // Get the current position in the stream
+ ByteOffset = (pByteOffset != NULL) ? pByteOffset[0] : pStream->StreamPos;
+ EndOffset = ByteOffset + dwBytesToRead;
+ if(EndOffset > pStream->StreamSize)
+ {
+ SetLastError(ERROR_HANDLE_EOF);
+ return false;
+ }
+
+ // Calculate the block parameters
+ BlockOffset0 = BlockOffset = ByteOffset & ~((ULONGLONG)BlockSize - 1);
+ BlockCount = (DWORD)(((EndOffset - BlockOffset) + (BlockSize - 1)) / BlockSize);
+ BytesNeeded = (DWORD)(EndOffset - BlockOffset);
+
+ // Remember where we have our data
+ assert((BlockSize & (BlockSize - 1)) == 0);
+ BlockBufferOffset = (DWORD)(ByteOffset & (BlockSize - 1));
+
+ // Allocate buffer for reading blocks
+ TransferBuffer = BlockBuffer = CASC_ALLOC(BYTE, (BlockCount * BlockSize));
+ if(TransferBuffer == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return false;
+ }
+
+ // If all blocks are available, just read all blocks at once
+ if(pStream->IsComplete == 0)
+ {
+ // Now parse the blocks and send the block read request
+ // to all blocks with the same availability
+ assert(pStream->BlockCheck != NULL);
+ bPrevBlockAvailable = pStream->BlockCheck(pStream, BlockOffset);
+
+ // Loop as long as we have something to read
+ while(BlockOffset < EndOffset)
+ {
+ // Determine availability of the next block
+ bBlockAvailable = pStream->BlockCheck(pStream, BlockOffset);
+
+ // If the availability has changed, read all blocks up to this one
+ if(bBlockAvailable != bPrevBlockAvailable)
+ {
+ // Call the file stream callback, if the block is not available
+ if(pStream->pMaster && pStream->pfnCallback && bPrevBlockAvailable == false)
+ {
+ pStream->pfnCallback(pStream->UserData, BlockOffset0, (DWORD)(BlockOffset - BlockOffset0));
+ bCallbackCalled = true;
+ }
+
+ // Load the continuous blocks with the same availability
+ assert(BlockOffset > BlockOffset0);
+ bResult = pStream->BlockRead(pStream, BlockOffset0, BlockOffset, BlockBuffer, BytesNeeded, bPrevBlockAvailable);
+ if(!bResult)
+ break;
+
+ // Move the block offset
+ BlockBuffer += (DWORD)(BlockOffset - BlockOffset0);
+ BytesNeeded -= (DWORD)(BlockOffset - BlockOffset0);
+ bPrevBlockAvailable = bBlockAvailable;
+ BlockOffset0 = BlockOffset;
+ }
+
+ // Move to the block offset in the stream
+ BlockOffset += BlockSize;
+ }
+
+ // If there is a block(s) remaining to be read, do it
+ if(BlockOffset > BlockOffset0)
+ {
+ // Call the file stream callback, if the block is not available
+ if(pStream->pMaster && pStream->pfnCallback && bPrevBlockAvailable == false)
+ {
+ pStream->pfnCallback(pStream->UserData, BlockOffset0, (DWORD)(BlockOffset - BlockOffset0));
+ bCallbackCalled = true;
+ }
+
+ // Read the complete blocks from the file
+ if(BlockOffset > pStream->StreamSize)
+ BlockOffset = pStream->StreamSize;
+ bResult = pStream->BlockRead(pStream, BlockOffset0, BlockOffset, BlockBuffer, BytesNeeded, bPrevBlockAvailable);
+ }
+ }
+ else
+ {
+ // Read the complete blocks from the file
+ if(EndOffset > pStream->StreamSize)
+ EndOffset = pStream->StreamSize;
+ bResult = pStream->BlockRead(pStream, BlockOffset, EndOffset, BlockBuffer, BytesNeeded, true);
+ }
+
+ // Now copy the data to the user buffer
+ if(bResult)
+ {
+ memcpy(pvBuffer, TransferBuffer + BlockBufferOffset, dwBytesToRead);
+ pStream->StreamPos = ByteOffset + dwBytesToRead;
+ }
+ else
+ {
+ // If the block read failed, set the last error
+ SetLastError(ERROR_FILE_INCOMPLETE);
+ }
+
+ // Call the callback to indicate we are done
+ if(bCallbackCalled)
+ pStream->pfnCallback(pStream->UserData, 0, 0);
+
+ // Free the block buffer and return
+ CASC_FREE(TransferBuffer);
+ return bResult;
+}
+
+static bool BlockStream_GetSize(TFileStream * pStream, ULONGLONG * pFileSize)
+{
+ *pFileSize = pStream->StreamSize;
+ return true;
+}
+
+static bool BlockStream_GetPos(TFileStream * pStream, ULONGLONG * pByteOffset)
+{
+ *pByteOffset = pStream->StreamPos;
+ return true;
+}
+
+static void BlockStream_Close(TBlockStream * pStream)
+{
+ // Free the data map, if any
+ if(pStream->FileBitmap != NULL)
+ CASC_FREE(pStream->FileBitmap);
+ pStream->FileBitmap = NULL;
+
+ // Call the base class for closing the stream
+ pStream->BaseClose(pStream);
+}
+
+//-----------------------------------------------------------------------------
+// File stream allocation function
+
+static STREAM_INIT StreamBaseInit[4] =
+{
+ BaseFile_Init,
+ BaseMap_Init,
+ BaseHttp_Init,
+ BaseNone_Init
+};
+
+// This function allocates an empty structure for the file stream
+// The stream structure is created as flat block, variable length
+// The file name is placed after the end of the stream structure data
+static TFileStream * AllocateFileStream(
+ const TCHAR * szFileName,
+ size_t StreamSize,
+ DWORD dwStreamFlags)
+{
+ TFileStream * pMaster = NULL;
+ TFileStream * pStream;
+ const TCHAR * szNextFile = szFileName;
+ size_t FileNameSize;
+
+ // Sanity check
+ assert(StreamSize != 0);
+
+ // The caller can specify chain of files in the following form:
+ // C:\archive.MPQ*http://www.server.com/MPQs/archive-server.MPQ
+ // In that case, we use the part after "*" as master file name
+ while(szNextFile[0] != 0 && szNextFile[0] != _T('*'))
+ szNextFile++;
+ FileNameSize = (size_t)((szNextFile - szFileName) * sizeof(TCHAR));
+
+ // If we have a next file, we need to open it as master stream
+ // Note that we don't care if the master stream exists or not,
+ // If it doesn't, later attempts to read missing file block will fail
+ if(szNextFile[0] == _T('*'))
+ {
+ // Don't allow another master file in the string
+ if(_tcschr(szNextFile + 1, _T('*')) != NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ // Open the master file
+ pMaster = FileStream_OpenFile(szNextFile + 1, STREAM_FLAG_READ_ONLY);
+ }
+
+ // Allocate the stream structure for the given stream type
+ pStream = (TFileStream *)CASC_ALLOC(BYTE, StreamSize + FileNameSize + sizeof(TCHAR));
+ if(pStream != NULL)
+ {
+ // Zero the entire structure
+ memset(pStream, 0, StreamSize);
+ pStream->pMaster = pMaster;
+ pStream->dwFlags = dwStreamFlags;
+
+ // Initialize the file name
+ pStream->szFileName = (TCHAR *)((BYTE *)pStream + StreamSize);
+ memcpy(pStream->szFileName, szFileName, FileNameSize);
+ pStream->szFileName[FileNameSize / sizeof(TCHAR)] = 0;
+
+ // Initialize the stream functions
+ StreamBaseInit[dwStreamFlags & 0x03](pStream);
+ }
+
+ return pStream;
+}
+
+//-----------------------------------------------------------------------------
+// Local functions - flat stream support
+
+static DWORD FlatStream_CheckFile(TBlockStream * pStream)
+{
+ LPBYTE FileBitmap = (LPBYTE)pStream->FileBitmap;
+ DWORD WholeByteCount = (pStream->BlockCount / 8);
+ DWORD ExtraBitsCount = (pStream->BlockCount & 7);
+ BYTE ExpectedValue;
+
+ // Verify the whole bytes - their value must be 0xFF
+ for(DWORD i = 0; i < WholeByteCount; i++)
+ {
+ if(FileBitmap[i] != 0xFF)
+ return 0;
+ }
+
+ // If there are extra bits, calculate the mask
+ if(ExtraBitsCount != 0)
+ {
+ ExpectedValue = (BYTE)((1 << ExtraBitsCount) - 1);
+ if(FileBitmap[WholeByteCount] != ExpectedValue)
+ return 0;
+ }
+
+ // Yes, the file is complete
+ return 1;
+}
+
+static bool FlatStream_LoadBitmap(TBlockStream * pStream)
+{
+ FILE_BITMAP_FOOTER Footer;
+ ULONGLONG ByteOffset;
+ LPBYTE FileBitmap;
+ DWORD BlockCount;
+ DWORD BitmapSize;
+
+ // Do not load the bitmap if we should not have to
+ if(!(pStream->dwFlags & STREAM_FLAG_USE_BITMAP))
+ return false;
+
+ // Only if the size is greater than size of bitmap footer
+ if(pStream->Base.File.FileSize > sizeof(FILE_BITMAP_FOOTER))
+ {
+ // Load the bitmap footer
+ ByteOffset = pStream->Base.File.FileSize - sizeof(FILE_BITMAP_FOOTER);
+ if(pStream->BaseRead(pStream, &ByteOffset, &Footer, sizeof(FILE_BITMAP_FOOTER)))
+ {
+ // Make sure that the array is properly BSWAP-ed
+ BSWAP_ARRAY32_UNSIGNED((PDWORD)(&Footer), sizeof(FILE_BITMAP_FOOTER));
+
+ // Verify if there is actually a footer
+ if(Footer.Signature == ID_FILE_BITMAP_FOOTER && Footer.Version == 0x03)
+ {
+ // Get the offset of the bitmap, number of blocks and size of the bitmap
+ ByteOffset = MAKE_OFFSET64(Footer.MapOffsetHi, Footer.MapOffsetLo);
+ BlockCount = (DWORD)(((ByteOffset - 1) / Footer.BlockSize) + 1);
+ BitmapSize = ((BlockCount + 7) / 8);
+
+ // Check if the sizes match
+ if(ByteOffset + BitmapSize + sizeof(FILE_BITMAP_FOOTER) == pStream->Base.File.FileSize)
+ {
+ // Allocate space for the bitmap
+ FileBitmap = CASC_ALLOC(BYTE, BitmapSize);
+ if(FileBitmap != NULL)
+ {
+ // Load the bitmap bits
+ if(!pStream->BaseRead(pStream, &ByteOffset, FileBitmap, BitmapSize))
+ {
+ CASC_FREE(FileBitmap);
+ return false;
+ }
+
+ // Update the stream size
+ pStream->BuildNumber = Footer.BuildNumber;
+ pStream->StreamSize = ByteOffset;
+
+ // Fill the bitmap information
+ pStream->FileBitmap = FileBitmap;
+ pStream->BitmapSize = BitmapSize;
+ pStream->BlockSize = Footer.BlockSize;
+ pStream->BlockCount = BlockCount;
+ pStream->IsComplete = FlatStream_CheckFile(pStream);
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+static void FlatStream_UpdateBitmap(
+ TBlockStream * pStream, // Pointer to an open stream
+ ULONGLONG StartOffset,
+ ULONGLONG EndOffset)
+{
+ LPBYTE FileBitmap = (LPBYTE)pStream->FileBitmap;
+ DWORD BlockIndex;
+ DWORD BlockSize = pStream->BlockSize;
+ DWORD ByteIndex;
+ BYTE BitMask;
+
+ // Sanity checks
+ assert((StartOffset & (BlockSize - 1)) == 0);
+ assert(FileBitmap != NULL);
+
+ // Calculate the index of the block
+ BlockIndex = (DWORD)(StartOffset / BlockSize);
+ ByteIndex = (BlockIndex / 0x08);
+ BitMask = (BYTE)(1 << (BlockIndex & 0x07));
+
+ // Set all bits for the specified range
+ while(StartOffset < EndOffset)
+ {
+ // Set the bit
+ FileBitmap[ByteIndex] |= BitMask;
+
+ // Move all
+ StartOffset += BlockSize;
+ ByteIndex += (BitMask >> 0x07);
+ BitMask = (BitMask >> 0x07) | (BitMask << 0x01);
+ }
+
+ // Increment the bitmap update count
+ pStream->IsModified = 1;
+}
+
+static bool FlatStream_BlockCheck(
+ TBlockStream * pStream, // Pointer to an open stream
+ ULONGLONG BlockOffset)
+{
+ LPBYTE FileBitmap = (LPBYTE)pStream->FileBitmap;
+ DWORD BlockIndex;
+ BYTE BitMask;
+
+ // Sanity checks
+ assert((BlockOffset & (pStream->BlockSize - 1)) == 0);
+ assert(FileBitmap != NULL);
+
+ // Calculate the index of the block
+ BlockIndex = (DWORD)(BlockOffset / pStream->BlockSize);
+ BitMask = (BYTE)(1 << (BlockIndex & 0x07));
+
+ // Check if the bit is present
+ return (FileBitmap[BlockIndex / 0x08] & BitMask) ? true : false;
+}
+
+static bool FlatStream_BlockRead(
+ TBlockStream * pStream, // Pointer to an open stream
+ ULONGLONG StartOffset,
+ ULONGLONG EndOffset,
+ LPBYTE BlockBuffer,
+ DWORD BytesNeeded,
+ bool bAvailable)
+{
+ DWORD BytesToRead = (DWORD)(EndOffset - StartOffset);
+
+ // The starting offset must be aligned to size of the block
+ assert(pStream->FileBitmap != NULL);
+ assert((StartOffset & (pStream->BlockSize - 1)) == 0);
+ assert(StartOffset < EndOffset);
+
+ // If the blocks are not available, we need to load them from the master
+ // and then save to the mirror
+ if(bAvailable == false)
+ {
+ // If we have no master, we cannot satisfy read request
+ if(pStream->pMaster == NULL)
+ return false;
+
+ // Load the blocks from the master stream
+ // Note that we always have to read complete blocks
+ // so they get properly stored to the mirror stream
+ if(!FileStream_Read(pStream->pMaster, &StartOffset, BlockBuffer, BytesToRead))
+ return false;
+
+ // Store the loaded blocks to the mirror file.
+ // Note that this operation is not required to succeed
+ if(pStream->BaseWrite(pStream, &StartOffset, BlockBuffer, BytesToRead))
+ FlatStream_UpdateBitmap(pStream, StartOffset, EndOffset);
+
+ return true;
+ }
+ else
+ {
+ if(BytesToRead > BytesNeeded)
+ BytesToRead = BytesNeeded;
+ return pStream->BaseRead(pStream, &StartOffset, BlockBuffer, BytesToRead);
+ }
+}
+
+static void FlatStream_Close(TBlockStream * pStream)
+{
+ FILE_BITMAP_FOOTER Footer;
+
+ if(pStream->FileBitmap && pStream->IsModified)
+ {
+ // Write the file bitmap
+ pStream->BaseWrite(pStream, &pStream->StreamSize, pStream->FileBitmap, pStream->BitmapSize);
+
+ // Prepare and write the file footer
+ Footer.Signature = ID_FILE_BITMAP_FOOTER;
+ Footer.Version = 3;
+ Footer.BuildNumber = pStream->BuildNumber;
+ Footer.MapOffsetLo = (DWORD)(pStream->StreamSize & 0xFFFFFFFF);
+ Footer.MapOffsetHi = (DWORD)(pStream->StreamSize >> 0x20);
+ Footer.BlockSize = pStream->BlockSize;
+ BSWAP_ARRAY32_UNSIGNED(&Footer, sizeof(FILE_BITMAP_FOOTER));
+ pStream->BaseWrite(pStream, NULL, &Footer, sizeof(FILE_BITMAP_FOOTER));
+ }
+
+ // Close the base class
+ BlockStream_Close(pStream);
+}
+
+static bool FlatStream_CreateMirror(TBlockStream * pStream)
+{
+ ULONGLONG MasterSize = 0;
+ ULONGLONG MirrorSize = 0;
+ LPBYTE FileBitmap = NULL;
+ DWORD dwBitmapSize;
+ DWORD dwBlockCount;
+ bool bNeedCreateMirrorStream = true;
+ bool bNeedResizeMirrorStream = true;
+
+ // Do we have master function and base creation function?
+ if(pStream->pMaster == NULL || pStream->BaseCreate == NULL)
+ return false;
+
+ // Retrieve the master file size, block count and bitmap size
+ FileStream_GetSize(pStream->pMaster, &MasterSize);
+ dwBlockCount = (DWORD)((MasterSize + DEFAULT_BLOCK_SIZE - 1) / DEFAULT_BLOCK_SIZE);
+ dwBitmapSize = (DWORD)((dwBlockCount + 7) / 8);
+
+ // Setup stream size and position
+ pStream->BuildNumber = DEFAULT_BUILD_NUMBER; // BUGBUG: Really???
+ pStream->StreamSize = MasterSize;
+ pStream->StreamPos = 0;
+
+ // Open the base stream for write access
+ if(pStream->BaseOpen(pStream, pStream->szFileName, 0))
+ {
+ // If the file open succeeded, check if the file size matches required size
+ pStream->BaseGetSize(pStream, &MirrorSize);
+ if(MirrorSize == MasterSize + dwBitmapSize + sizeof(FILE_BITMAP_FOOTER))
+ {
+ // Attempt to load an existing file bitmap
+ if(FlatStream_LoadBitmap(pStream))
+ return true;
+
+ // We need to create new file bitmap
+ bNeedResizeMirrorStream = false;
+ }
+
+ // We need to create mirror stream
+ bNeedCreateMirrorStream = false;
+ }
+
+ // Create a new stream, if needed
+ if(bNeedCreateMirrorStream)
+ {
+ if(!pStream->BaseCreate(pStream))
+ return false;
+ }
+
+ // If we need to, then resize the mirror stream
+ if(bNeedResizeMirrorStream)
+ {
+ if(!pStream->BaseResize(pStream, MasterSize + dwBitmapSize + sizeof(FILE_BITMAP_FOOTER)))
+ return false;
+ }
+
+ // Allocate the bitmap array
+ FileBitmap = CASC_ALLOC(BYTE, dwBitmapSize);
+ if(FileBitmap == NULL)
+ return false;
+
+ // Initialize the bitmap
+ memset(FileBitmap, 0, dwBitmapSize);
+ pStream->FileBitmap = FileBitmap;
+ pStream->BitmapSize = dwBitmapSize;
+ pStream->BlockSize = DEFAULT_BLOCK_SIZE;
+ pStream->BlockCount = dwBlockCount;
+ pStream->IsComplete = 0;
+ pStream->IsModified = 1;
+
+ // Note: Don't write the stream bitmap right away.
+ // Doing so would cause sparse file resize on NTFS,
+ // which would take long time on larger files.
+ return true;
+}
+
+static TFileStream * FlatStream_Open(const TCHAR * szFileName, DWORD dwStreamFlags)
+{
+ TBlockStream * pStream;
+ ULONGLONG ByteOffset = 0;
+
+ // Create new empty stream
+ pStream = (TBlockStream *)AllocateFileStream(szFileName, sizeof(TBlockStream), dwStreamFlags);
+ if(pStream == NULL)
+ return NULL;
+
+ // Do we have a master stream?
+ if(pStream->pMaster != NULL)
+ {
+ if(!FlatStream_CreateMirror(pStream))
+ {
+ FileStream_Close(pStream);
+ SetLastError(ERROR_FILE_NOT_FOUND);
+ return NULL;
+ }
+ }
+ else
+ {
+ // Attempt to open the base stream
+ if(!pStream->BaseOpen(pStream, pStream->szFileName, dwStreamFlags))
+ {
+ FileStream_Close(pStream);
+ return NULL;
+ }
+
+ // Load the bitmap, if required to
+ if(dwStreamFlags & STREAM_FLAG_USE_BITMAP)
+ FlatStream_LoadBitmap(pStream);
+ }
+
+ // If we have a stream bitmap, set the reading functions
+ // which check presence of each file block
+ if(pStream->FileBitmap != NULL)
+ {
+ // Set the stream position to zero. Stream size is already set
+ assert(pStream->StreamSize != 0);
+ pStream->StreamPos = 0;
+ pStream->dwFlags |= STREAM_FLAG_READ_ONLY;
+
+ // Supply the stream functions
+ pStream->StreamRead = (STREAM_READ)BlockStream_Read;
+ pStream->StreamGetSize = BlockStream_GetSize;
+ pStream->StreamGetPos = BlockStream_GetPos;
+ pStream->StreamClose = (STREAM_CLOSE)FlatStream_Close;
+
+ // Supply the block functions
+ pStream->BlockCheck = (BLOCK_CHECK)FlatStream_BlockCheck;
+ pStream->BlockRead = (BLOCK_READ)FlatStream_BlockRead;
+ }
+ else
+ {
+ // Reset the base position to zero
+ pStream->BaseRead(pStream, &ByteOffset, NULL, 0);
+
+ // Setup stream size and position
+ pStream->StreamSize = pStream->Base.File.FileSize;
+ pStream->StreamPos = 0;
+
+ // Set the base functions
+ pStream->StreamRead = pStream->BaseRead;
+ pStream->StreamWrite = pStream->BaseWrite;
+ pStream->StreamResize = pStream->BaseResize;
+ pStream->StreamGetSize = pStream->BaseGetSize;
+ pStream->StreamGetPos = pStream->BaseGetPos;
+ pStream->StreamClose = pStream->BaseClose;
+ }
+
+ return pStream;
+}
+
+//-----------------------------------------------------------------------------
+// Local functions - partial stream support
+
+static bool IsPartHeader(PPART_FILE_HEADER pPartHdr)
+{
+ // Version number must be 2
+ if(pPartHdr->PartialVersion == 2)
+ {
+ // GameBuildNumber must be an ASCII number
+ if(isdigit(pPartHdr->GameBuildNumber[0]) && isdigit(pPartHdr->GameBuildNumber[1]) && isdigit(pPartHdr->GameBuildNumber[2]))
+ {
+ // Block size must be power of 2
+ if((pPartHdr->BlockSize & (pPartHdr->BlockSize - 1)) == 0)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static DWORD PartStream_CheckFile(TBlockStream * pStream)
+{
+ PPART_FILE_MAP_ENTRY FileBitmap = (PPART_FILE_MAP_ENTRY)pStream->FileBitmap;
+ DWORD dwBlockCount;
+
+ // Get the number of blocks
+ dwBlockCount = (DWORD)((pStream->StreamSize + pStream->BlockSize - 1) / pStream->BlockSize);
+
+ // Check all blocks
+ for(DWORD i = 0; i < dwBlockCount; i++, FileBitmap++)
+ {
+ // Few sanity checks
+ assert(FileBitmap->LargeValueHi == 0);
+ assert(FileBitmap->LargeValueLo == 0);
+ assert(FileBitmap->Flags == 0 || FileBitmap->Flags == 3);
+
+ // Check if this block is present
+ if(FileBitmap->Flags != 3)
+ return 0;
+ }
+
+ // Yes, the file is complete
+ return 1;
+}
+
+static bool PartStream_LoadBitmap(TBlockStream * pStream)
+{
+ PPART_FILE_MAP_ENTRY FileBitmap;
+ PART_FILE_HEADER PartHdr;
+ ULONGLONG ByteOffset = 0;
+ ULONGLONG StreamSize = 0;
+ DWORD BlockCount;
+ DWORD BitmapSize;
+
+ // Only if the size is greater than size of the bitmap header
+ if(pStream->Base.File.FileSize > sizeof(PART_FILE_HEADER))
+ {
+ // Attempt to read PART file header
+ if(pStream->BaseRead(pStream, &ByteOffset, &PartHdr, sizeof(PART_FILE_HEADER)))
+ {
+ // We need to swap PART file header on big-endian platforms
+ BSWAP_ARRAY32_UNSIGNED(&PartHdr, sizeof(PART_FILE_HEADER));
+
+ // Verify the PART file header
+ if(IsPartHeader(&PartHdr))
+ {
+ // Get the number of blocks and size of one block
+ StreamSize = MAKE_OFFSET64(PartHdr.FileSizeHi, PartHdr.FileSizeLo);
+ ByteOffset = sizeof(PART_FILE_HEADER);
+ BlockCount = (DWORD)((StreamSize + PartHdr.BlockSize - 1) / PartHdr.BlockSize);
+ BitmapSize = BlockCount * sizeof(PART_FILE_MAP_ENTRY);
+
+ // Check if sizes match
+ if((ByteOffset + BitmapSize) < pStream->Base.File.FileSize)
+ {
+ // Allocate space for the array of PART_FILE_MAP_ENTRY
+ FileBitmap = CASC_ALLOC(PART_FILE_MAP_ENTRY, BlockCount);
+ if(FileBitmap != NULL)
+ {
+ // Load the block map
+ if(!pStream->BaseRead(pStream, &ByteOffset, FileBitmap, BitmapSize))
+ {
+ CASC_FREE(FileBitmap);
+ return false;
+ }
+
+ // Make sure that the byte order is correct
+ BSWAP_ARRAY32_UNSIGNED(FileBitmap, BitmapSize);
+
+ // Update the stream size
+ pStream->BuildNumber = StringToInt(PartHdr.GameBuildNumber);
+ pStream->StreamSize = StreamSize;
+
+ // Fill the bitmap information
+ pStream->FileBitmap = FileBitmap;
+ pStream->BitmapSize = BitmapSize;
+ pStream->BlockSize = PartHdr.BlockSize;
+ pStream->BlockCount = BlockCount;
+ pStream->IsComplete = PartStream_CheckFile(pStream);
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+static void PartStream_UpdateBitmap(
+ TBlockStream * pStream, // Pointer to an open stream
+ ULONGLONG StartOffset,
+ ULONGLONG EndOffset,
+ ULONGLONG RealOffset)
+{
+ PPART_FILE_MAP_ENTRY FileBitmap;
+ DWORD BlockSize = pStream->BlockSize;
+
+ // Sanity checks
+ assert((StartOffset & (BlockSize - 1)) == 0);
+ assert(pStream->FileBitmap != NULL);
+
+ // Calculate the first entry in the block map
+ FileBitmap = (PPART_FILE_MAP_ENTRY)pStream->FileBitmap + (StartOffset / BlockSize);
+
+ // Set all bits for the specified range
+ while(StartOffset < EndOffset)
+ {
+ // Set the bit
+ FileBitmap->BlockOffsHi = (DWORD)(RealOffset >> 0x20);
+ FileBitmap->BlockOffsLo = (DWORD)(RealOffset & 0xFFFFFFFF);
+ FileBitmap->Flags = 3;
+
+ // Move all
+ StartOffset += BlockSize;
+ RealOffset += BlockSize;
+ FileBitmap++;
+ }
+
+ // Increment the bitmap update count
+ pStream->IsModified = 1;
+}
+
+static bool PartStream_BlockCheck(
+ TBlockStream * pStream, // Pointer to an open stream
+ ULONGLONG BlockOffset)
+{
+ PPART_FILE_MAP_ENTRY FileBitmap;
+
+ // Sanity checks
+ assert((BlockOffset & (pStream->BlockSize - 1)) == 0);
+ assert(pStream->FileBitmap != NULL);
+
+ // Calculate the block map entry
+ FileBitmap = (PPART_FILE_MAP_ENTRY)pStream->FileBitmap + (BlockOffset / pStream->BlockSize);
+
+ // Check if the flags are present
+ return (FileBitmap->Flags & 0x03) ? true : false;
+}
+
+static bool PartStream_BlockRead(
+ TBlockStream * pStream,
+ ULONGLONG StartOffset,
+ ULONGLONG EndOffset,
+ LPBYTE BlockBuffer,
+ DWORD BytesNeeded,
+ bool bAvailable)
+{
+ PPART_FILE_MAP_ENTRY FileBitmap;
+ ULONGLONG ByteOffset;
+ DWORD BytesToRead;
+ DWORD BlockIndex = (DWORD)(StartOffset / pStream->BlockSize);
+
+ // The starting offset must be aligned to size of the block
+ assert(pStream->FileBitmap != NULL);
+ assert((StartOffset & (pStream->BlockSize - 1)) == 0);
+ assert(StartOffset < EndOffset);
+
+ // If the blocks are not available, we need to load them from the master
+ // and then save to the mirror
+ if(bAvailable == false)
+ {
+ // If we have no master, we cannot satisfy read request
+ if(pStream->pMaster == NULL)
+ return false;
+
+ // Load the blocks from the master stream
+ // Note that we always have to read complete blocks
+ // so they get properly stored to the mirror stream
+ BytesToRead = (DWORD)(EndOffset - StartOffset);
+ if(!FileStream_Read(pStream->pMaster, &StartOffset, BlockBuffer, BytesToRead))
+ return false;
+
+ // The loaded blocks are going to be stored to the end of the file
+ // Note that this operation is not required to succeed
+ if(pStream->BaseGetSize(pStream, &ByteOffset))
+ {
+ // Store the loaded blocks to the mirror file.
+ if(pStream->BaseWrite(pStream, &ByteOffset, BlockBuffer, BytesToRead))
+ {
+ PartStream_UpdateBitmap(pStream, StartOffset, EndOffset, ByteOffset);
+ }
+ }
+ }
+ else
+ {
+ // Get the file map entry
+ FileBitmap = (PPART_FILE_MAP_ENTRY)pStream->FileBitmap + BlockIndex;
+
+ // Read all blocks
+ while(StartOffset < EndOffset)
+ {
+ // Get the number of bytes to be read
+ BytesToRead = (DWORD)(EndOffset - StartOffset);
+ if(BytesToRead > pStream->BlockSize)
+ BytesToRead = pStream->BlockSize;
+ if(BytesToRead > BytesNeeded)
+ BytesToRead = BytesNeeded;
+
+ // Read the block
+ ByteOffset = MAKE_OFFSET64(FileBitmap->BlockOffsHi, FileBitmap->BlockOffsLo);
+ if(!pStream->BaseRead(pStream, &ByteOffset, BlockBuffer, BytesToRead))
+ return false;
+
+ // Move the pointers
+ StartOffset += pStream->BlockSize;
+ BlockBuffer += pStream->BlockSize;
+ BytesNeeded -= pStream->BlockSize;
+ FileBitmap++;
+ }
+ }
+
+ return true;
+}
+
+static void PartStream_Close(TBlockStream * pStream)
+{
+ PART_FILE_HEADER PartHeader;
+ ULONGLONG ByteOffset = 0;
+
+ if(pStream->FileBitmap && pStream->IsModified)
+ {
+ // Prepare the part file header
+ memset(&PartHeader, 0, sizeof(PART_FILE_HEADER));
+ PartHeader.PartialVersion = 2;
+ PartHeader.FileSizeHi = (DWORD)(pStream->StreamSize >> 0x20);
+ PartHeader.FileSizeLo = (DWORD)(pStream->StreamSize & 0xFFFFFFFF);
+ PartHeader.BlockSize = pStream->BlockSize;
+
+ // Make sure that the header is properly BSWAPed
+ BSWAP_ARRAY32_UNSIGNED(&PartHeader, sizeof(PART_FILE_HEADER));
+ sprintf(PartHeader.GameBuildNumber, "%u", (unsigned int)pStream->BuildNumber);
+
+ // Write the part header
+ pStream->BaseWrite(pStream, &ByteOffset, &PartHeader, sizeof(PART_FILE_HEADER));
+
+ // Write the block bitmap
+ BSWAP_ARRAY32_UNSIGNED(pStream->FileBitmap, pStream->BitmapSize);
+ pStream->BaseWrite(pStream, NULL, pStream->FileBitmap, pStream->BitmapSize);
+ }
+
+ // Close the base class
+ BlockStream_Close(pStream);
+}
+
+static bool PartStream_CreateMirror(TBlockStream * pStream)
+{
+ ULONGLONG RemainingSize;
+ ULONGLONG MasterSize = 0;
+ ULONGLONG MirrorSize = 0;
+ LPBYTE FileBitmap = NULL;
+ DWORD dwBitmapSize;
+ DWORD dwBlockCount;
+ bool bNeedCreateMirrorStream = true;
+ bool bNeedResizeMirrorStream = true;
+
+ // Do we have master function and base creation function?
+ if(pStream->pMaster == NULL || pStream->BaseCreate == NULL)
+ return false;
+
+ // Retrieve the master file size, block count and bitmap size
+ FileStream_GetSize(pStream->pMaster, &MasterSize);
+ dwBlockCount = (DWORD)((MasterSize + DEFAULT_BLOCK_SIZE - 1) / DEFAULT_BLOCK_SIZE);
+ dwBitmapSize = (DWORD)(dwBlockCount * sizeof(PART_FILE_MAP_ENTRY));
+
+ // Setup stream size and position
+ pStream->BuildNumber = DEFAULT_BUILD_NUMBER; // BUGBUG: Really???
+ pStream->StreamSize = MasterSize;
+ pStream->StreamPos = 0;
+
+ // Open the base stream for write access
+ if(pStream->BaseOpen(pStream, pStream->szFileName, 0))
+ {
+ // If the file open succeeded, check if the file size matches required size
+ pStream->BaseGetSize(pStream, &MirrorSize);
+ if(MirrorSize >= sizeof(PART_FILE_HEADER) + dwBitmapSize)
+ {
+ // Check if the remaining size is aligned to block
+ RemainingSize = MirrorSize - sizeof(PART_FILE_HEADER) - dwBitmapSize;
+ if((RemainingSize & (DEFAULT_BLOCK_SIZE - 1)) == 0 || RemainingSize == MasterSize)
+ {
+ // Attempt to load an existing file bitmap
+ if(PartStream_LoadBitmap(pStream))
+ return true;
+ }
+ }
+
+ // We need to create mirror stream
+ bNeedCreateMirrorStream = false;
+ }
+
+ // Create a new stream, if needed
+ if(bNeedCreateMirrorStream)
+ {
+ if(!pStream->BaseCreate(pStream))
+ return false;
+ }
+
+ // If we need to, then resize the mirror stream
+ if(bNeedResizeMirrorStream)
+ {
+ if(!pStream->BaseResize(pStream, sizeof(PART_FILE_HEADER) + dwBitmapSize))
+ return false;
+ }
+
+ // Allocate the bitmap array
+ FileBitmap = CASC_ALLOC(BYTE, dwBitmapSize);
+ if(FileBitmap == NULL)
+ return false;
+
+ // Initialize the bitmap
+ memset(FileBitmap, 0, dwBitmapSize);
+ pStream->FileBitmap = FileBitmap;
+ pStream->BitmapSize = dwBitmapSize;
+ pStream->BlockSize = DEFAULT_BLOCK_SIZE;
+ pStream->BlockCount = dwBlockCount;
+ pStream->IsComplete = 0;
+ pStream->IsModified = 1;
+
+ // Note: Don't write the stream bitmap right away.
+ // Doing so would cause sparse file resize on NTFS,
+ // which would take long time on larger files.
+ return true;
+}
+
+
+static TFileStream * PartStream_Open(const TCHAR * szFileName, DWORD dwStreamFlags)
+{
+ TBlockStream * pStream;
+
+ // Create new empty stream
+ pStream = (TBlockStream *)AllocateFileStream(szFileName, sizeof(TBlockStream), dwStreamFlags);
+ if(pStream == NULL)
+ return NULL;
+
+ // Do we have a master stream?
+ if(pStream->pMaster != NULL)
+ {
+ if(!PartStream_CreateMirror(pStream))
+ {
+ FileStream_Close(pStream);
+ SetLastError(ERROR_FILE_NOT_FOUND);
+ return NULL;
+ }
+ }
+ else
+ {
+ // Attempt to open the base stream
+ if(!pStream->BaseOpen(pStream, pStream->szFileName, dwStreamFlags))
+ {
+ FileStream_Close(pStream);
+ return NULL;
+ }
+
+ // Load the part stream block map
+ if(!PartStream_LoadBitmap(pStream))
+ {
+ FileStream_Close(pStream);
+ SetLastError(ERROR_BAD_FORMAT);
+ return NULL;
+ }
+ }
+
+ // Set the stream position to zero. Stream size is already set
+ assert(pStream->StreamSize != 0);
+ pStream->StreamPos = 0;
+ pStream->dwFlags |= STREAM_FLAG_READ_ONLY;
+
+ // Set new function pointers
+ pStream->StreamRead = (STREAM_READ)BlockStream_Read;
+ pStream->StreamGetPos = BlockStream_GetPos;
+ pStream->StreamGetSize = BlockStream_GetSize;
+ pStream->StreamClose = (STREAM_CLOSE)PartStream_Close;
+
+ // Supply the block functions
+ pStream->BlockCheck = (BLOCK_CHECK)PartStream_BlockCheck;
+ pStream->BlockRead = (BLOCK_READ)PartStream_BlockRead;
+ return pStream;
+}
+
+//-----------------------------------------------------------------------------
+// Local functions - encrypted stream support
+
+static const char * szKeyTemplate = "expand 32-byte k000000000000000000000000000000000000000000000000";
+
+static const char * AuthCodeArray[] =
+{
+ // Starcraft II (Heart of the Swarm)
+ // Authentication code URL: http://dist.blizzard.com/mediakey/hots-authenticationcode-bgdl.txt
+ // -0C- -1C--08- -18--04- -14--00- -10-
+ "S48B6CDTN5XEQAKQDJNDLJBJ73FDFM3U", // SC2 Heart of the Swarm-all : "expand 32-byte kQAKQ0000FM3UN5XE000073FD6CDT0000LJBJS48B0000DJND"
+
+ // Diablo III: Agent.exe (1.0.0.954)
+ // Address of decryption routine: 00502b00
+ // Pointer to decryptor object: ECX
+ // Pointer to key: ECX+0x5C
+ // Authentication code URL: http://dist.blizzard.com/mediakey/d3-authenticationcode-enGB.txt
+ // -0C- -1C--08- -18--04- -14--00- -10-
+ "UCMXF6EJY352EFH4XFRXCFH2XC9MQRZK", // Diablo III Installer (deDE): "expand 32-byte kEFH40000QRZKY3520000XC9MF6EJ0000CFH2UCMX0000XFRX"
+ "MMKVHY48RP7WXP4GHYBQ7SL9J9UNPHBP", // Diablo III Installer (enGB): "expand 32-byte kXP4G0000PHBPRP7W0000J9UNHY4800007SL9MMKV0000HYBQ"
+ "8MXLWHQ7VGGLTZ9MQZQSFDCLJYET3CPP", // Diablo III Installer (enSG): "expand 32-byte kTZ9M00003CPPVGGL0000JYETWHQ70000FDCL8MXL0000QZQS"
+ "EJ2R5TM6XFE2GUNG5QDGHKQ9UAKPWZSZ", // Diablo III Installer (enUS): "expand 32-byte kGUNG0000WZSZXFE20000UAKP5TM60000HKQ9EJ2R00005QDG"
+ "PBGFBE42Z6LNK65UGJQ3WZVMCLP4HQQT", // Diablo III Installer (esES): "expand 32-byte kK65U0000HQQTZ6LN0000CLP4BE420000WZVMPBGF0000GJQ3"
+ "X7SEJJS9TSGCW5P28EBSC47AJPEY8VU2", // Diablo III Installer (esMX): "expand 32-byte kW5P200008VU2TSGC0000JPEYJJS90000C47AX7SE00008EBS"
+ "5KVBQA8VYE6XRY3DLGC5ZDE4XS4P7YA2", // Diablo III Installer (frFR): "expand 32-byte kRY3D00007YA2YE6X0000XS4PQA8V0000ZDE45KVB0000LGC5"
+ "478JD2K56EVNVVY4XX8TDWYT5B8KB254", // Diablo III Installer (itIT): "expand 32-byte kVVY40000B2546EVN00005B8KD2K50000DWYT478J0000XX8T"
+ "8TS4VNFQRZTN6YWHE9CHVDH9NVWD474A", // Diablo III Installer (koKR): "expand 32-byte k6YWH0000474ARZTN0000NVWDVNFQ0000VDH98TS40000E9CH"
+ "LJ52Z32DF4LZ4ZJJXVKK3AZQA6GABLJB", // Diablo III Installer (plPL): "expand 32-byte k4ZJJ0000BLJBF4LZ0000A6GAZ32D00003AZQLJ520000XVKK"
+ "K6BDHY2ECUE2545YKNLBJPVYWHE7XYAG", // Diablo III Installer (ptBR): "expand 32-byte k545Y0000XYAGCUE20000WHE7HY2E0000JPVYK6BD0000KNLB"
+ "NDVW8GWLAYCRPGRNY8RT7ZZUQU63VLPR", // Diablo III Installer (ruRU): "expand 32-byte kXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ "6VWCQTN8V3ZZMRUCZXV8A8CGUX2TAA8H", // Diablo III Installer (zhTW): "expand 32-byte kMRUC0000AA8HV3ZZ0000UX2TQTN80000A8CG6VWC0000ZXV8"
+// "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", // Diablo III Installer (zhCN): "expand 32-byte kXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+
+ // Starcraft II (Wings of Liberty): Installer.exe (4.1.1.4219)
+ // Address of decryption routine: 0053A3D0
+ // Pointer to decryptor object: ECX
+ // Pointer to key: ECX+0x5C
+ // Authentication code URL: http://dist.blizzard.com/mediakey/sc2-authenticationcode-enUS.txt
+ // -0C- -1C--08- -18--04- -14--00- -10-
+ "Y45MD3CAK4KXSSXHYD9VY64Z8EKJ4XFX", // SC2 Wings of Liberty (deDE): "expand 32-byte kSSXH00004XFXK4KX00008EKJD3CA0000Y64ZY45M0000YD9V"
+ "G8MN8UDG6NA2ANGY6A3DNY82HRGF29ZH", // SC2 Wings of Liberty (enGB): "expand 32-byte kANGY000029ZH6NA20000HRGF8UDG0000NY82G8MN00006A3D"
+ "W9RRHLB2FDU9WW5B3ECEBLRSFWZSF7HW", // SC2 Wings of Liberty (enSG): "expand 32-byte kWW5B0000F7HWFDU90000FWZSHLB20000BLRSW9RR00003ECE"
+ "3DH5RE5NVM5GTFD85LXGWT6FK859ETR5", // SC2 Wings of Liberty (enUS): "expand 32-byte kTFD80000ETR5VM5G0000K859RE5N0000WT6F3DH500005LXG"
+ "8WLKUAXE94PFQU4Y249PAZ24N4R4XKTQ", // SC2 Wings of Liberty (esES): "expand 32-byte kQU4Y0000XKTQ94PF0000N4R4UAXE0000AZ248WLK0000249P"
+ "A34DXX3VHGGXSQBRFE5UFFDXMF9G4G54", // SC2 Wings of Liberty (esMX): "expand 32-byte kSQBR00004G54HGGX0000MF9GXX3V0000FFDXA34D0000FE5U"
+ "ZG7J9K938HJEFWPQUA768MA2PFER6EAJ", // SC2 Wings of Liberty (frFR): "expand 32-byte kFWPQ00006EAJ8HJE0000PFER9K9300008MA2ZG7J0000UA76"
+ "NE7CUNNNTVAPXV7E3G2BSVBWGVMW8BL2", // SC2 Wings of Liberty (itIT): "expand 32-byte kXV7E00008BL2TVAP0000GVMWUNNN0000SVBWNE7C00003G2B"
+ "3V9E2FTMBM9QQWK7U6MAMWAZWQDB838F", // SC2 Wings of Liberty (koKR): "expand 32-byte kQWK70000838FBM9Q0000WQDB2FTM0000MWAZ3V9E0000U6MA"
+ "2NSFB8MELULJ83U6YHA3UP6K4MQD48L6", // SC2 Wings of Liberty (plPL): "expand 32-byte k83U6000048L6LULJ00004MQDB8ME0000UP6K2NSF0000YHA3"
+ "QA2TZ9EWZ4CUU8BMB5WXCTY65F9CSW4E", // SC2 Wings of Liberty (ptBR): "expand 32-byte kU8BM0000SW4EZ4CU00005F9CZ9EW0000CTY6QA2T0000B5WX"
+ "VHB378W64BAT9SH7D68VV9NLQDK9YEGT", // SC2 Wings of Liberty (ruRU): "expand 32-byte k9SH70000YEGT4BAT0000QDK978W60000V9NLVHB30000D68V"
+ "U3NFQJV4M6GC7KBN9XQJ3BRDN3PLD9NE", // SC2 Wings of Liberty (zhTW): "expand 32-byte k7KBN0000D9NEM6GC0000N3PLQJV400003BRDU3NF00009XQJ"
+
+ NULL
+};
+
+static DWORD Rol32(DWORD dwValue, DWORD dwRolCount)
+{
+ DWORD dwShiftRight = 32 - dwRolCount;
+
+ return (dwValue << dwRolCount) | (dwValue >> dwShiftRight);
+}
+
+static void CreateKeyFromAuthCode(
+ LPBYTE pbKeyBuffer,
+ const char * szAuthCode)
+{
+ PDWORD KeyPosition = (PDWORD)(pbKeyBuffer + 0x10);
+ PDWORD AuthCode32 = (PDWORD)szAuthCode;
+
+ memcpy(pbKeyBuffer, szKeyTemplate, ENCRYPTED_CHUNK_SIZE);
+ KeyPosition[0x00] = AuthCode32[0x03];
+ KeyPosition[0x02] = AuthCode32[0x07];
+ KeyPosition[0x03] = AuthCode32[0x02];
+ KeyPosition[0x05] = AuthCode32[0x06];
+ KeyPosition[0x06] = AuthCode32[0x01];
+ KeyPosition[0x08] = AuthCode32[0x05];
+ KeyPosition[0x09] = AuthCode32[0x00];
+ KeyPosition[0x0B] = AuthCode32[0x04];
+ BSWAP_ARRAY32_UNSIGNED(pbKeyBuffer, ENCRYPTED_CHUNK_SIZE);
+}
+
+static void DecryptFileChunk(
+ DWORD * ChunkData,
+ LPBYTE pbKey,
+ ULONGLONG ByteOffset,
+ DWORD dwLength)
+{
+ ULONGLONG ChunkOffset;
+ DWORD KeyShuffled[0x10];
+ DWORD KeyMirror[0x10];
+ DWORD RoundCount = 0x14;
+
+ // Prepare the key
+ ChunkOffset = ByteOffset / ENCRYPTED_CHUNK_SIZE;
+ memcpy(KeyMirror, pbKey, ENCRYPTED_CHUNK_SIZE);
+ BSWAP_ARRAY32_UNSIGNED(KeyMirror, ENCRYPTED_CHUNK_SIZE);
+ KeyMirror[0x05] = (DWORD)(ChunkOffset >> 32);
+ KeyMirror[0x08] = (DWORD)(ChunkOffset);
+
+ while(dwLength >= ENCRYPTED_CHUNK_SIZE)
+ {
+ // Shuffle the key - part 1
+ KeyShuffled[0x0E] = KeyMirror[0x00];
+ KeyShuffled[0x0C] = KeyMirror[0x01];
+ KeyShuffled[0x05] = KeyMirror[0x02];
+ KeyShuffled[0x0F] = KeyMirror[0x03];
+ KeyShuffled[0x0A] = KeyMirror[0x04];
+ KeyShuffled[0x07] = KeyMirror[0x05];
+ KeyShuffled[0x0B] = KeyMirror[0x06];
+ KeyShuffled[0x09] = KeyMirror[0x07];
+ KeyShuffled[0x03] = KeyMirror[0x08];
+ KeyShuffled[0x06] = KeyMirror[0x09];
+ KeyShuffled[0x08] = KeyMirror[0x0A];
+ KeyShuffled[0x0D] = KeyMirror[0x0B];
+ KeyShuffled[0x02] = KeyMirror[0x0C];
+ KeyShuffled[0x04] = KeyMirror[0x0D];
+ KeyShuffled[0x01] = KeyMirror[0x0E];
+ KeyShuffled[0x00] = KeyMirror[0x0F];
+
+ // Shuffle the key - part 2
+ for(DWORD i = 0; i < RoundCount; i += 2)
+ {
+ KeyShuffled[0x0A] = KeyShuffled[0x0A] ^ Rol32((KeyShuffled[0x0E] + KeyShuffled[0x02]), 0x07);
+ KeyShuffled[0x03] = KeyShuffled[0x03] ^ Rol32((KeyShuffled[0x0A] + KeyShuffled[0x0E]), 0x09);
+ KeyShuffled[0x02] = KeyShuffled[0x02] ^ Rol32((KeyShuffled[0x03] + KeyShuffled[0x0A]), 0x0D);
+ KeyShuffled[0x0E] = KeyShuffled[0x0E] ^ Rol32((KeyShuffled[0x02] + KeyShuffled[0x03]), 0x12);
+
+ KeyShuffled[0x07] = KeyShuffled[0x07] ^ Rol32((KeyShuffled[0x0C] + KeyShuffled[0x04]), 0x07);
+ KeyShuffled[0x06] = KeyShuffled[0x06] ^ Rol32((KeyShuffled[0x07] + KeyShuffled[0x0C]), 0x09);
+ KeyShuffled[0x04] = KeyShuffled[0x04] ^ Rol32((KeyShuffled[0x06] + KeyShuffled[0x07]), 0x0D);
+ KeyShuffled[0x0C] = KeyShuffled[0x0C] ^ Rol32((KeyShuffled[0x04] + KeyShuffled[0x06]), 0x12);
+
+ KeyShuffled[0x0B] = KeyShuffled[0x0B] ^ Rol32((KeyShuffled[0x05] + KeyShuffled[0x01]), 0x07);
+ KeyShuffled[0x08] = KeyShuffled[0x08] ^ Rol32((KeyShuffled[0x0B] + KeyShuffled[0x05]), 0x09);
+ KeyShuffled[0x01] = KeyShuffled[0x01] ^ Rol32((KeyShuffled[0x08] + KeyShuffled[0x0B]), 0x0D);
+ KeyShuffled[0x05] = KeyShuffled[0x05] ^ Rol32((KeyShuffled[0x01] + KeyShuffled[0x08]), 0x12);
+
+ KeyShuffled[0x09] = KeyShuffled[0x09] ^ Rol32((KeyShuffled[0x0F] + KeyShuffled[0x00]), 0x07);
+ KeyShuffled[0x0D] = KeyShuffled[0x0D] ^ Rol32((KeyShuffled[0x09] + KeyShuffled[0x0F]), 0x09);
+ KeyShuffled[0x00] = KeyShuffled[0x00] ^ Rol32((KeyShuffled[0x0D] + KeyShuffled[0x09]), 0x0D);
+ KeyShuffled[0x0F] = KeyShuffled[0x0F] ^ Rol32((KeyShuffled[0x00] + KeyShuffled[0x0D]), 0x12);
+
+ KeyShuffled[0x04] = KeyShuffled[0x04] ^ Rol32((KeyShuffled[0x0E] + KeyShuffled[0x09]), 0x07);
+ KeyShuffled[0x08] = KeyShuffled[0x08] ^ Rol32((KeyShuffled[0x04] + KeyShuffled[0x0E]), 0x09);
+ KeyShuffled[0x09] = KeyShuffled[0x09] ^ Rol32((KeyShuffled[0x08] + KeyShuffled[0x04]), 0x0D);
+ KeyShuffled[0x0E] = KeyShuffled[0x0E] ^ Rol32((KeyShuffled[0x09] + KeyShuffled[0x08]), 0x12);
+
+ KeyShuffled[0x01] = KeyShuffled[0x01] ^ Rol32((KeyShuffled[0x0C] + KeyShuffled[0x0A]), 0x07);
+ KeyShuffled[0x0D] = KeyShuffled[0x0D] ^ Rol32((KeyShuffled[0x01] + KeyShuffled[0x0C]), 0x09);
+ KeyShuffled[0x0A] = KeyShuffled[0x0A] ^ Rol32((KeyShuffled[0x0D] + KeyShuffled[0x01]), 0x0D);
+ KeyShuffled[0x0C] = KeyShuffled[0x0C] ^ Rol32((KeyShuffled[0x0A] + KeyShuffled[0x0D]), 0x12);
+
+ KeyShuffled[0x00] = KeyShuffled[0x00] ^ Rol32((KeyShuffled[0x05] + KeyShuffled[0x07]), 0x07);
+ KeyShuffled[0x03] = KeyShuffled[0x03] ^ Rol32((KeyShuffled[0x00] + KeyShuffled[0x05]), 0x09);
+ KeyShuffled[0x07] = KeyShuffled[0x07] ^ Rol32((KeyShuffled[0x03] + KeyShuffled[0x00]), 0x0D);
+ KeyShuffled[0x05] = KeyShuffled[0x05] ^ Rol32((KeyShuffled[0x07] + KeyShuffled[0x03]), 0x12);
+
+ KeyShuffled[0x02] = KeyShuffled[0x02] ^ Rol32((KeyShuffled[0x0F] + KeyShuffled[0x0B]), 0x07);
+ KeyShuffled[0x06] = KeyShuffled[0x06] ^ Rol32((KeyShuffled[0x02] + KeyShuffled[0x0F]), 0x09);
+ KeyShuffled[0x0B] = KeyShuffled[0x0B] ^ Rol32((KeyShuffled[0x06] + KeyShuffled[0x02]), 0x0D);
+ KeyShuffled[0x0F] = KeyShuffled[0x0F] ^ Rol32((KeyShuffled[0x0B] + KeyShuffled[0x06]), 0x12);
+ }
+
+ // Decrypt one data chunk
+ BSWAP_ARRAY32_UNSIGNED(ChunkData, ENCRYPTED_CHUNK_SIZE);
+ ChunkData[0x00] = ChunkData[0x00] ^ (KeyShuffled[0x0E] + KeyMirror[0x00]);
+ ChunkData[0x01] = ChunkData[0x01] ^ (KeyShuffled[0x04] + KeyMirror[0x0D]);
+ ChunkData[0x02] = ChunkData[0x02] ^ (KeyShuffled[0x08] + KeyMirror[0x0A]);
+ ChunkData[0x03] = ChunkData[0x03] ^ (KeyShuffled[0x09] + KeyMirror[0x07]);
+ ChunkData[0x04] = ChunkData[0x04] ^ (KeyShuffled[0x0A] + KeyMirror[0x04]);
+ ChunkData[0x05] = ChunkData[0x05] ^ (KeyShuffled[0x0C] + KeyMirror[0x01]);
+ ChunkData[0x06] = ChunkData[0x06] ^ (KeyShuffled[0x01] + KeyMirror[0x0E]);
+ ChunkData[0x07] = ChunkData[0x07] ^ (KeyShuffled[0x0D] + KeyMirror[0x0B]);
+ ChunkData[0x08] = ChunkData[0x08] ^ (KeyShuffled[0x03] + KeyMirror[0x08]);
+ ChunkData[0x09] = ChunkData[0x09] ^ (KeyShuffled[0x07] + KeyMirror[0x05]);
+ ChunkData[0x0A] = ChunkData[0x0A] ^ (KeyShuffled[0x05] + KeyMirror[0x02]);
+ ChunkData[0x0B] = ChunkData[0x0B] ^ (KeyShuffled[0x00] + KeyMirror[0x0F]);
+ ChunkData[0x0C] = ChunkData[0x0C] ^ (KeyShuffled[0x02] + KeyMirror[0x0C]);
+ ChunkData[0x0D] = ChunkData[0x0D] ^ (KeyShuffled[0x06] + KeyMirror[0x09]);
+ ChunkData[0x0E] = ChunkData[0x0E] ^ (KeyShuffled[0x0B] + KeyMirror[0x06]);
+ ChunkData[0x0F] = ChunkData[0x0F] ^ (KeyShuffled[0x0F] + KeyMirror[0x03]);
+ BSWAP_ARRAY32_UNSIGNED(ChunkData, ENCRYPTED_CHUNK_SIZE);
+
+ // Update byte offset in the key
+ KeyMirror[0x08]++;
+ if(KeyMirror[0x08] == 0)
+ KeyMirror[0x05]++;
+
+ // Move pointers and decrease number of bytes to decrypt
+ ChunkData += (ENCRYPTED_CHUNK_SIZE / sizeof(DWORD));
+ dwLength -= ENCRYPTED_CHUNK_SIZE;
+ }
+}
+
+static bool EncrStream_DetectFileKey(TEncryptedStream * pStream)
+{
+ ULONGLONG ByteOffset = 0;
+ BYTE EncryptedHeader[ENCRYPTED_CHUNK_SIZE];
+ BYTE FileHeader[ENCRYPTED_CHUNK_SIZE];
+
+ // Read the first file chunk
+ if(pStream->BaseRead(pStream, &ByteOffset, EncryptedHeader, sizeof(EncryptedHeader)))
+ {
+ // We just try all known keys one by one
+ for(int i = 0; AuthCodeArray[i] != NULL; i++)
+ {
+ // Prepare they decryption key from game serial number
+ CreateKeyFromAuthCode(pStream->Key, AuthCodeArray[i]);
+
+ // Try to decrypt with the given key
+ memcpy(FileHeader, EncryptedHeader, ENCRYPTED_CHUNK_SIZE);
+ DecryptFileChunk((PDWORD)FileHeader, pStream->Key, ByteOffset, ENCRYPTED_CHUNK_SIZE);
+
+ // We check the decrypted data
+ // All known encrypted archives have header at the begin of the file,
+ // so we check for archive signature there.
+ if(FileHeader[0] == 'M' && FileHeader[1] == 'P' && FileHeader[2] == 'Q')
+ {
+ // Update the stream size
+ pStream->StreamSize = pStream->Base.File.FileSize;
+
+ // Fill the block information
+ pStream->BlockSize = ENCRYPTED_CHUNK_SIZE;
+ pStream->BlockCount = (DWORD)(pStream->Base.File.FileSize + ENCRYPTED_CHUNK_SIZE - 1) / ENCRYPTED_CHUNK_SIZE;
+ pStream->IsComplete = 1;
+ return true;
+ }
+ }
+ }
+
+ // Key not found, sorry
+ return false;
+}
+
+static bool EncrStream_BlockRead(
+ TEncryptedStream * pStream,
+ ULONGLONG StartOffset,
+ ULONGLONG EndOffset,
+ LPBYTE BlockBuffer,
+ DWORD BytesNeeded,
+ bool bAvailable)
+{
+ DWORD dwBytesToRead;
+
+ assert((StartOffset & (pStream->BlockSize - 1)) == 0);
+ assert(StartOffset < EndOffset);
+ assert(bAvailable != false);
+ BytesNeeded = BytesNeeded;
+ bAvailable = bAvailable;
+
+ // Read the file from the stream as-is
+ // Limit the reading to number of blocks really needed
+ dwBytesToRead = (DWORD)(EndOffset - StartOffset);
+ if(!pStream->BaseRead(pStream, &StartOffset, BlockBuffer, dwBytesToRead))
+ return false;
+
+ // Decrypt the data
+ dwBytesToRead = (dwBytesToRead + ENCRYPTED_CHUNK_SIZE - 1) & ~(ENCRYPTED_CHUNK_SIZE - 1);
+ DecryptFileChunk((PDWORD)BlockBuffer, pStream->Key, StartOffset, dwBytesToRead);
+ return true;
+}
+
+static TFileStream * EncrStream_Open(const TCHAR * szFileName, DWORD dwStreamFlags)
+{
+ TEncryptedStream * pStream;
+
+ // Create new empty stream
+ pStream = (TEncryptedStream *)AllocateFileStream(szFileName, sizeof(TEncryptedStream), dwStreamFlags);
+ if(pStream == NULL)
+ return NULL;
+
+ // Attempt to open the base stream
+ assert(pStream->BaseOpen != NULL);
+ if(!pStream->BaseOpen(pStream, pStream->szFileName, dwStreamFlags))
+ return NULL;
+
+ // Determine the encryption key for the archive
+ if(EncrStream_DetectFileKey(pStream))
+ {
+ // Set the stream position and size
+ assert(pStream->StreamSize != 0);
+ pStream->StreamPos = 0;
+ pStream->dwFlags |= STREAM_FLAG_READ_ONLY;
+
+ // Set new function pointers
+ pStream->StreamRead = (STREAM_READ)BlockStream_Read;
+ pStream->StreamGetPos = BlockStream_GetPos;
+ pStream->StreamGetSize = BlockStream_GetSize;
+ pStream->StreamClose = pStream->BaseClose;
+
+ // Supply the block functions
+ pStream->BlockRead = (BLOCK_READ)EncrStream_BlockRead;
+ return pStream;
+ }
+
+ // Cleanup the stream and return
+ FileStream_Close(pStream);
+ SetLastError(ERROR_UNKNOWN_FILE_KEY);
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Local functions - Block4 stream support
+
+#define BLOCK4_BLOCK_SIZE 0x4000 // Size of one block
+#define BLOCK4_HASH_SIZE 0x20 // Size of MD5 hash that is after each block
+#define BLOCK4_MAX_BLOCKS 0x00002000 // Maximum amount of blocks per file
+#define BLOCK4_MAX_FSIZE 0x08040000 // Max size of one file
+
+static bool Block4Stream_BlockRead(
+ TBlockStream * pStream, // Pointer to an open stream
+ ULONGLONG StartOffset,
+ ULONGLONG EndOffset,
+ LPBYTE BlockBuffer,
+ DWORD BytesNeeded,
+ bool bAvailable)
+{
+ TBaseProviderData * BaseArray = (TBaseProviderData *)pStream->FileBitmap;
+ ULONGLONG ByteOffset;
+ DWORD BytesToRead;
+ DWORD StreamIndex;
+ DWORD BlockIndex;
+ bool bResult;
+
+ // The starting offset must be aligned to size of the block
+ assert(pStream->FileBitmap != NULL);
+ assert((StartOffset & (pStream->BlockSize - 1)) == 0);
+ assert(StartOffset < EndOffset);
+ assert(bAvailable == true);
+
+ // Keep compiler happy
+ bAvailable = bAvailable;
+ EndOffset = EndOffset;
+
+ while(BytesNeeded != 0)
+ {
+ // Calculate the block index and the file index
+ StreamIndex = (DWORD)((StartOffset / pStream->BlockSize) / BLOCK4_MAX_BLOCKS);
+ BlockIndex = (DWORD)((StartOffset / pStream->BlockSize) % BLOCK4_MAX_BLOCKS);
+ if(StreamIndex > pStream->BitmapSize)
+ return false;
+
+ // Calculate the block offset
+ ByteOffset = ((ULONGLONG)BlockIndex * (BLOCK4_BLOCK_SIZE + BLOCK4_HASH_SIZE));
+ BytesToRead = CASCLIB_MIN(BytesNeeded, BLOCK4_BLOCK_SIZE);
+
+ // Read from the base stream
+ pStream->Base = BaseArray[StreamIndex];
+ bResult = pStream->BaseRead(pStream, &ByteOffset, BlockBuffer, BytesToRead);
+ BaseArray[StreamIndex] = pStream->Base;
+
+ // Did the result succeed?
+ if(bResult == false)
+ return false;
+
+ // Move pointers
+ StartOffset += BytesToRead;
+ BlockBuffer += BytesToRead;
+ BytesNeeded -= BytesToRead;
+ }
+
+ return true;
+}
+
+
+static void Block4Stream_Close(TBlockStream * pStream)
+{
+ TBaseProviderData * BaseArray = (TBaseProviderData *)pStream->FileBitmap;
+
+ // If we have a non-zero count of base streams,
+ // we have to close them all
+ if(BaseArray != NULL)
+ {
+ // Close all base streams
+ for(DWORD i = 0; i < pStream->BitmapSize; i++)
+ {
+ memcpy(&pStream->Base, BaseArray + i, sizeof(TBaseProviderData));
+ pStream->BaseClose(pStream);
+ }
+ }
+
+ // Free the data map, if any
+ if(pStream->FileBitmap != NULL)
+ CASC_FREE(pStream->FileBitmap);
+ pStream->FileBitmap = NULL;
+
+ // Do not call the BaseClose function,
+ // we closed all handles already
+ return;
+}
+
+static TFileStream * Block4Stream_Open(const TCHAR * szFileName, DWORD dwStreamFlags)
+{
+ TBaseProviderData * NewBaseArray = NULL;
+ ULONGLONG RemainderBlock;
+ ULONGLONG BlockCount;
+ ULONGLONG FileSize;
+ TBlockStream * pStream;
+ TCHAR * szNameBuff;
+ size_t nNameLength;
+ DWORD dwBaseFiles = 0;
+ DWORD dwBaseFlags;
+
+ // Create new empty stream
+ pStream = (TBlockStream *)AllocateFileStream(szFileName, sizeof(TBlockStream), dwStreamFlags);
+ if(pStream == NULL)
+ return NULL;
+
+ // Sanity check
+ assert(pStream->BaseOpen != NULL);
+
+ // Get the length of the file name without numeric suffix
+ nNameLength = _tcslen(pStream->szFileName);
+ if(pStream->szFileName[nNameLength - 2] == '.' && pStream->szFileName[nNameLength - 1] == '0')
+ nNameLength -= 2;
+ pStream->szFileName[nNameLength] = 0;
+
+ // Supply the stream functions
+ pStream->StreamRead = (STREAM_READ)BlockStream_Read;
+ pStream->StreamGetSize = BlockStream_GetSize;
+ pStream->StreamGetPos = BlockStream_GetPos;
+ pStream->StreamClose = (STREAM_CLOSE)Block4Stream_Close;
+ pStream->BlockRead = (BLOCK_READ)Block4Stream_BlockRead;
+
+ // Allocate work space for numeric names
+ szNameBuff = CASC_ALLOC(TCHAR, nNameLength + 4);
+ if(szNameBuff != NULL)
+ {
+ // Set the base flags
+ dwBaseFlags = (dwStreamFlags & STREAM_PROVIDERS_MASK) | STREAM_FLAG_READ_ONLY;
+
+ // Go all suffixes from 0 to 30
+ for(int nSuffix = 0; nSuffix < 30; nSuffix++)
+ {
+ // Open the n-th file
+ _stprintf(szNameBuff, _T("%s.%u"), pStream->szFileName, nSuffix);
+ if(!pStream->BaseOpen(pStream, szNameBuff, dwBaseFlags))
+ break;
+
+ // If the open succeeded, we re-allocate the base provider array
+ NewBaseArray = CASC_ALLOC(TBaseProviderData, dwBaseFiles + 1);
+ if(NewBaseArray == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return NULL;
+ }
+
+ // Copy the old base data array to the new base data array
+ if(pStream->FileBitmap != NULL)
+ {
+ memcpy(NewBaseArray, pStream->FileBitmap, sizeof(TBaseProviderData) * dwBaseFiles);
+ CASC_FREE(pStream->FileBitmap);
+ }
+
+ // Also copy the opened base array
+ memcpy(NewBaseArray + dwBaseFiles, &pStream->Base, sizeof(TBaseProviderData));
+ pStream->FileBitmap = NewBaseArray;
+ dwBaseFiles++;
+
+ // Get the size of the base stream
+ pStream->BaseGetSize(pStream, &FileSize);
+ assert(FileSize <= BLOCK4_MAX_FSIZE);
+ RemainderBlock = FileSize % (BLOCK4_BLOCK_SIZE + BLOCK4_HASH_SIZE);
+ BlockCount = FileSize / (BLOCK4_BLOCK_SIZE + BLOCK4_HASH_SIZE);
+
+ // Increment the stream size and number of blocks
+ pStream->StreamSize += (BlockCount * BLOCK4_BLOCK_SIZE);
+ pStream->BlockCount += (DWORD)BlockCount;
+
+ // Is this the last file?
+ if(FileSize < BLOCK4_MAX_FSIZE)
+ {
+ if(RemainderBlock)
+ {
+ pStream->StreamSize += (RemainderBlock - BLOCK4_HASH_SIZE);
+ pStream->BlockCount++;
+ }
+ break;
+ }
+ }
+
+ // Fill the remainining block stream variables
+ pStream->BitmapSize = dwBaseFiles;
+ pStream->BlockSize = BLOCK4_BLOCK_SIZE;
+ pStream->IsComplete = 1;
+ pStream->IsModified = 0;
+
+ // Fill the remaining stream variables
+ pStream->StreamPos = 0;
+ pStream->dwFlags |= STREAM_FLAG_READ_ONLY;
+
+ CASC_FREE(szNameBuff);
+ }
+
+ // If we opened something, return success
+ if(dwBaseFiles == 0)
+ {
+ FileStream_Close(pStream);
+ SetLastError(ERROR_FILE_NOT_FOUND);
+ pStream = NULL;
+ }
+
+ return pStream;
+}
+
+//-----------------------------------------------------------------------------
+// Public functions
+
+/**
+ * This function creates a new file for read-write access
+ *
+ * - If the current platform supports file sharing,
+ * the file must be created for read sharing (i.e. another application
+ * can open the file for read, but not for write)
+ * - If the file does not exist, the function must create new one
+ * - If the file exists, the function must rewrite it and set to zero size
+ * - The parameters of the function must be validate by the caller
+ * - The function must initialize all stream function pointers in TFileStream
+ * - If the function fails from any reason, it must close all handles
+ * and free all memory that has been allocated in the process of stream creation,
+ * including the TFileStream structure itself
+ *
+ * \a szFileName Name of the file to create
+ */
+
+TFileStream * FileStream_CreateFile(
+ const TCHAR * szFileName,
+ DWORD dwStreamFlags)
+{
+ TFileStream * pStream;
+
+ // We only support creation of flat, local file
+ if((dwStreamFlags & (STREAM_PROVIDERS_MASK)) != (STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE))
+ {
+ SetLastError(ERROR_NOT_SUPPORTED);
+ return NULL;
+ }
+
+ // Allocate file stream structure for flat stream
+ pStream = AllocateFileStream(szFileName, sizeof(TBlockStream), dwStreamFlags);
+ if(pStream != NULL)
+ {
+ // Attempt to create the disk file
+ if(BaseFile_Create(pStream))
+ {
+ // Fill the stream provider functions
+ pStream->StreamRead = pStream->BaseRead;
+ pStream->StreamWrite = pStream->BaseWrite;
+ pStream->StreamResize = pStream->BaseResize;
+ pStream->StreamGetSize = pStream->BaseGetSize;
+ pStream->StreamGetPos = pStream->BaseGetPos;
+ pStream->StreamClose = pStream->BaseClose;
+ return pStream;
+ }
+
+ // File create failed, delete the stream
+ CASC_FREE(pStream);
+ pStream = NULL;
+ }
+
+ // Return the stream
+ return pStream;
+}
+
+/**
+ * This function opens an existing file for read or read-write access
+ * - If the current platform supports file sharing,
+ * the file must be open for read sharing (i.e. another application
+ * can open the file for read, but not for write)
+ * - If the file does not exist, the function must return NULL
+ * - If the file exists but cannot be open, then function must return NULL
+ * - The parameters of the function must be validate by the caller
+ * - The function must initialize all stream function pointers in TFileStream
+ * - If the function fails from any reason, it must close all handles
+ * and free all memory that has been allocated in the process of stream creation,
+ * including the TFileStream structure itself
+ *
+ * \a szFileName Name of the file to open
+ * \a dwStreamFlags specifies the provider and base storage type
+ */
+
+TFileStream * FileStream_OpenFile(
+ const TCHAR * szFileName,
+ DWORD dwStreamFlags)
+{
+ DWORD dwProvider = dwStreamFlags & STREAM_PROVIDERS_MASK;
+ size_t nPrefixLength = FileStream_Prefix(szFileName, &dwProvider);
+
+ // Re-assemble the stream flags
+ dwStreamFlags = (dwStreamFlags & STREAM_OPTIONS_MASK) | dwProvider;
+ szFileName += nPrefixLength;
+
+ // Perform provider-specific open
+ switch(dwStreamFlags & STREAM_PROVIDER_MASK)
+ {
+ case STREAM_PROVIDER_FLAT:
+ return FlatStream_Open(szFileName, dwStreamFlags);
+
+ case STREAM_PROVIDER_PARTIAL:
+ return PartStream_Open(szFileName, dwStreamFlags);
+
+ case STREAM_PROVIDER_ENCRYPTED:
+ return EncrStream_Open(szFileName, dwStreamFlags);
+
+ case STREAM_PROVIDER_BLOCK4:
+ return Block4Stream_Open(szFileName, dwStreamFlags);
+
+ default:
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+}
+
+/**
+ * Returns the file name of the stream
+ *
+ * \a pStream Pointer to an open stream
+ */
+const TCHAR * FileStream_GetFileName(TFileStream * pStream)
+{
+ assert(pStream != NULL);
+ return pStream->szFileName;
+}
+
+/**
+ * Returns the length of the provider prefix. Returns zero if no prefix
+ *
+ * \a szFileName Pointer to a stream name (file, mapped file, URL)
+ * \a pdwStreamProvider Pointer to a DWORD variable that receives stream provider (STREAM_PROVIDER_XXX)
+ */
+
+size_t FileStream_Prefix(const TCHAR * szFileName, DWORD * pdwProvider)
+{
+ size_t nPrefixLength1 = 0;
+ size_t nPrefixLength2 = 0;
+ DWORD dwProvider = 0;
+
+ if(szFileName != NULL)
+ {
+ //
+ // Determine the stream provider
+ //
+
+ if(!_tcsnicmp(szFileName, _T("flat-"), 5))
+ {
+ dwProvider |= STREAM_PROVIDER_FLAT;
+ nPrefixLength1 = 5;
+ }
+
+ else if(!_tcsnicmp(szFileName, _T("part-"), 5))
+ {
+ dwProvider |= STREAM_PROVIDER_PARTIAL;
+ nPrefixLength1 = 5;
+ }
+
+ else if(!_tcsnicmp(szFileName, _T("mpqe-"), 5))
+ {
+ dwProvider |= STREAM_PROVIDER_ENCRYPTED;
+ nPrefixLength1 = 5;
+ }
+
+ else if(!_tcsnicmp(szFileName, _T("blk4-"), 5))
+ {
+ dwProvider |= STREAM_PROVIDER_BLOCK4;
+ nPrefixLength1 = 5;
+ }
+
+ //
+ // Determine the base provider
+ //
+
+ if(!_tcsnicmp(szFileName+nPrefixLength1, _T("file:"), 5))
+ {
+ dwProvider |= BASE_PROVIDER_FILE;
+ nPrefixLength2 = 5;
+ }
+
+ else if(!_tcsnicmp(szFileName+nPrefixLength1, _T("map:"), 4))
+ {
+ dwProvider |= BASE_PROVIDER_MAP;
+ nPrefixLength2 = 4;
+ }
+
+ else if(!_tcsnicmp(szFileName+nPrefixLength1, _T("http:"), 5))
+ {
+ dwProvider |= BASE_PROVIDER_HTTP;
+ nPrefixLength2 = 5;
+ }
+
+ // Only accept stream provider if we recognized the base provider
+ if(nPrefixLength2 != 0)
+ {
+ // It is also allowed to put "//" after the base provider, e.g. "file://", "http://"
+ if(szFileName[nPrefixLength1+nPrefixLength2] == '/' && szFileName[nPrefixLength1+nPrefixLength2+1] == '/')
+ nPrefixLength2 += 2;
+
+ if(pdwProvider != NULL)
+ *pdwProvider = dwProvider;
+ return nPrefixLength1 + nPrefixLength2;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Sets a download callback. Whenever the stream needs to download one or more blocks
+ * from the server, the callback is called
+ *
+ * \a pStream Pointer to an open stream
+ * \a pfnCallback Pointer to callback function
+ * \a pvUserData Arbitrary user pointer passed to the download callback
+ */
+
+bool FileStream_SetCallback(TFileStream * pStream, STREAM_DOWNLOAD_CALLBACK pfnCallback, void * pvUserData)
+{
+ TBlockStream * pBlockStream = (TBlockStream *)pStream;
+
+ if(pStream->BlockRead == NULL)
+ {
+ SetLastError(ERROR_NOT_SUPPORTED);
+ return false;
+ }
+
+ pBlockStream->pfnCallback = pfnCallback;
+ pBlockStream->UserData = pvUserData;
+ return true;
+}
+
+/**
+ * Reads data from the stream
+ *
+ * - Returns true if the read operation succeeded and all bytes have been read
+ * - Returns false if either read failed or not all bytes have been read
+ * - If the pByteOffset is NULL, the function must read the data from the current file position
+ * - The function can be called with dwBytesToRead = 0. In that case, pvBuffer is ignored
+ * and the function just adjusts file pointer.
+ *
+ * \a pStream Pointer to an open stream
+ * \a pByteOffset Pointer to file byte offset. If NULL, it reads from the current position
+ * \a pvBuffer Pointer to data to be read
+ * \a dwBytesToRead Number of bytes to read from the file
+ *
+ * \returns
+ * - If the function reads the required amount of bytes, it returns true.
+ * - If the function reads less than required bytes, it returns false and GetLastError() returns ERROR_HANDLE_EOF
+ * - If the function fails, it reads false and GetLastError() returns an error code different from ERROR_HANDLE_EOF
+ */
+bool FileStream_Read(TFileStream * pStream, ULONGLONG * pByteOffset, void * pvBuffer, DWORD dwBytesToRead)
+{
+ assert(pStream->StreamRead != NULL);
+ return pStream->StreamRead(pStream, pByteOffset, pvBuffer, dwBytesToRead);
+}
+
+/**
+ * This function writes data to the stream
+ *
+ * - Returns true if the write operation succeeded and all bytes have been written
+ * - Returns false if either write failed or not all bytes have been written
+ * - If the pByteOffset is NULL, the function must write the data to the current file position
+ *
+ * \a pStream Pointer to an open stream
+ * \a pByteOffset Pointer to file byte offset. If NULL, it reads from the current position
+ * \a pvBuffer Pointer to data to be written
+ * \a dwBytesToWrite Number of bytes to write to the file
+ */
+bool FileStream_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const void * pvBuffer, DWORD dwBytesToWrite)
+{
+ if(pStream->dwFlags & STREAM_FLAG_READ_ONLY)
+ {
+ SetLastError(ERROR_ACCESS_DENIED);
+ return false;
+ }
+
+ assert(pStream->StreamWrite != NULL);
+ return pStream->StreamWrite(pStream, pByteOffset, pvBuffer, dwBytesToWrite);
+}
+
+/**
+ * Returns the size of a file
+ *
+ * \a pStream Pointer to an open stream
+ * \a FileSize Pointer where to store the file size
+ */
+bool FileStream_GetSize(TFileStream * pStream, ULONGLONG * pFileSize)
+{
+ assert(pStream->StreamGetSize != NULL);
+ return pStream->StreamGetSize(pStream, pFileSize);
+}
+
+/**
+ * Sets the size of a file
+ *
+ * \a pStream Pointer to an open stream
+ * \a NewFileSize File size to set
+ */
+bool FileStream_SetSize(TFileStream * pStream, ULONGLONG NewFileSize)
+{
+ if(pStream->dwFlags & STREAM_FLAG_READ_ONLY)
+ {
+ SetLastError(ERROR_ACCESS_DENIED);
+ return false;
+ }
+
+ assert(pStream->StreamResize != NULL);
+ return pStream->StreamResize(pStream, NewFileSize);
+}
+
+/**
+ * This function returns the current file position
+ * \a pStream
+ * \a pByteOffset
+ */
+bool FileStream_GetPos(TFileStream * pStream, ULONGLONG * pByteOffset)
+{
+ assert(pStream->StreamGetPos != NULL);
+ return pStream->StreamGetPos(pStream, pByteOffset);
+}
+
+/**
+ * Returns the last write time of a file
+ *
+ * \a pStream Pointer to an open stream
+ * \a pFileType Pointer where to store the file last write time
+ */
+bool FileStream_GetTime(TFileStream * pStream, ULONGLONG * pFileTime)
+{
+ // Just use the saved filetime value
+ *pFileTime = pStream->Base.File.FileTime;
+ return true;
+}
+
+/**
+ * Returns the stream flags
+ *
+ * \a pStream Pointer to an open stream
+ * \a pdwStreamFlags Pointer where to store the stream flags
+ */
+bool FileStream_GetFlags(TFileStream * pStream, PDWORD pdwStreamFlags)
+{
+ *pdwStreamFlags = pStream->dwFlags;
+ return true;
+}
+
+/**
+ * Switches a stream with another. Used for final phase of archive compacting.
+ * Performs these steps:
+ *
+ * 1) Closes the handle to the existing file
+ * 2) Renames the temporary file to the original file, overwrites existing one
+ * 3) Opens the file stores the handle and stream position to the new stream structure
+ *
+ * \a pStream Pointer to an open stream
+ * \a pNewStream Temporary ("working") stream (created during archive compacting)
+ */
+bool FileStream_Replace(TFileStream * pStream, TFileStream * pNewStream)
+{
+ // Only supported on flat files
+ if((pStream->dwFlags & STREAM_PROVIDERS_MASK) != (STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE))
+ {
+ SetLastError(ERROR_NOT_SUPPORTED);
+ return false;
+ }
+
+ // Not supported on read-only streams
+ if(pStream->dwFlags & STREAM_FLAG_READ_ONLY)
+ {
+ SetLastError(ERROR_ACCESS_DENIED);
+ return false;
+ }
+
+ // Close both stream's base providers
+ pNewStream->BaseClose(pNewStream);
+ pStream->BaseClose(pStream);
+
+ // Now we have to delete the (now closed) old file and rename the new file
+ if(!BaseFile_Replace(pStream, pNewStream))
+ return false;
+
+ // Now open the base file again
+ if(!BaseFile_Open(pStream, pStream->szFileName, pStream->dwFlags))
+ return false;
+
+ // Cleanup the new stream
+ FileStream_Close(pNewStream);
+ return true;
+}
+
+/**
+ * This function closes an archive file and frees any data buffers
+ * that have been allocated for stream management. The function must also
+ * support partially allocated structure, i.e. one or more buffers
+ * can be NULL, if there was an allocation failure during the process
+ *
+ * \a pStream Pointer to an open stream
+ */
+void FileStream_Close(TFileStream * pStream)
+{
+ // Check if the stream structure is allocated at all
+ if(pStream != NULL)
+ {
+ // Free the master stream, if any
+ if(pStream->pMaster != NULL)
+ FileStream_Close(pStream->pMaster);
+ pStream->pMaster = NULL;
+
+ // Close the stream provider.
+ if(pStream->StreamClose != NULL)
+ pStream->StreamClose(pStream);
+
+ // Also close base stream, if any
+ else if(pStream->BaseClose != NULL)
+ pStream->BaseClose(pStream);
+
+ // Free the stream itself
+ CASC_FREE(pStream);
+ }
+}
diff --git a/dep/CascLib/src/common/FileStream.h b/dep/CascLib/src/common/FileStream.h
new file mode 100644
index 00000000000..1e51acfc845
--- /dev/null
+++ b/dep/CascLib/src/common/FileStream.h
@@ -0,0 +1,238 @@
+/*****************************************************************************/
+/* FileStream.h Copyright (c) Ladislav Zezula 2012 */
+/*---------------------------------------------------------------------------*/
+/* Description: Definitions for FileStream object */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 14.04.12 1.00 Lad The first version of FileStream.h */
+/*****************************************************************************/
+
+#ifndef __FILESTREAM_H__
+#define __FILESTREAM_H__
+
+//-----------------------------------------------------------------------------
+// Function prototypes
+
+typedef void (*STREAM_INIT)(
+ struct TFileStream * pStream // Pointer to an unopened stream
+);
+
+typedef bool (*STREAM_CREATE)(
+ struct TFileStream * pStream // Pointer to an unopened stream
+ );
+
+typedef bool (*STREAM_OPEN)(
+ struct TFileStream * pStream, // Pointer to an unopened stream
+ const TCHAR * szFileName, // Pointer to file name to be open
+ DWORD dwStreamFlags // Stream flags
+ );
+
+typedef bool (*STREAM_READ)(
+ struct TFileStream * pStream, // Pointer to an open stream
+ ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position
+ void * pvBuffer, // Pointer to data to be read
+ DWORD dwBytesToRead // Number of bytes to read from the file
+ );
+
+typedef bool (*STREAM_WRITE)(
+ struct TFileStream * pStream, // Pointer to an open stream
+ ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it writes to the current position
+ const void * pvBuffer, // Pointer to data to be written
+ DWORD dwBytesToWrite // Number of bytes to read from the file
+ );
+
+typedef bool (*STREAM_RESIZE)(
+ struct TFileStream * pStream, // Pointer to an open stream
+ ULONGLONG FileSize // New size for the file, in bytes
+ );
+
+typedef bool (*STREAM_GETSIZE)(
+ struct TFileStream * pStream, // Pointer to an open stream
+ ULONGLONG * pFileSize // Receives the file size, in bytes
+ );
+
+typedef bool (*STREAM_GETPOS)(
+ struct TFileStream * pStream, // Pointer to an open stream
+ ULONGLONG * pByteOffset // Pointer to store current file position
+ );
+
+typedef void (*STREAM_CLOSE)(
+ struct TFileStream * pStream // Pointer to an open stream
+ );
+
+typedef bool (*BLOCK_READ)(
+ struct TFileStream * pStream, // Pointer to a block-oriented stream
+ ULONGLONG StartOffset, // Byte offset of start of the block array
+ ULONGLONG EndOffset, // End offset (either end of the block or end of the file)
+ LPBYTE BlockBuffer, // Pointer to block-aligned buffer
+ DWORD BytesNeeded, // Number of bytes that are really needed
+ bool bAvailable // true if the block is available
+ );
+
+typedef bool (*BLOCK_CHECK)(
+ struct TFileStream * pStream, // Pointer to a block-oriented stream
+ ULONGLONG BlockOffset // Offset of the file to check
+ );
+
+typedef void (*BLOCK_SAVEMAP)(
+ struct TFileStream * pStream // Pointer to a block-oriented stream
+ );
+
+//-----------------------------------------------------------------------------
+// Local structures - partial file structure and bitmap footer
+
+#define ID_FILE_BITMAP_FOOTER 0x33767470 // Signature of the file bitmap footer ('ptv3')
+#define DEFAULT_BLOCK_SIZE 0x00004000 // Default size of the stream block
+#define DEFAULT_BUILD_NUMBER 10958 // Build number for newly created partial MPQs
+
+typedef struct _PART_FILE_HEADER
+{
+ DWORD PartialVersion; // Always set to 2
+ char GameBuildNumber[0x20]; // Minimum build number of the game that can use this MPQ
+ DWORD Flags; // Flags (details unknown)
+ DWORD FileSizeLo; // Low 32 bits of the contained file size
+ DWORD FileSizeHi; // High 32 bits of the contained file size
+ DWORD BlockSize; // Size of one file block, in bytes
+
+} PART_FILE_HEADER, *PPART_FILE_HEADER;
+
+// Structure describing the block-to-file map entry
+typedef struct _PART_FILE_MAP_ENTRY
+{
+ DWORD Flags; // 3 = the block is present in the file
+ DWORD BlockOffsLo; // Low 32 bits of the block position in the file
+ DWORD BlockOffsHi; // High 32 bits of the block position in the file
+ DWORD LargeValueLo; // 64-bit value, meaning is unknown
+ DWORD LargeValueHi;
+
+} PART_FILE_MAP_ENTRY, *PPART_FILE_MAP_ENTRY;
+
+typedef struct _FILE_BITMAP_FOOTER
+{
+ DWORD Signature; // 'ptv3' (ID_FILE_BITMAP_FOOTER)
+ DWORD Version; // Unknown, seems to always have value of 3 (version?)
+ DWORD BuildNumber; // Game build number for that MPQ
+ DWORD MapOffsetLo; // Low 32-bits of the offset of the bit map
+ DWORD MapOffsetHi; // High 32-bits of the offset of the bit map
+ DWORD BlockSize; // Size of one block (usually 0x4000 bytes)
+
+} FILE_BITMAP_FOOTER, *PFILE_BITMAP_FOOTER;
+
+//-----------------------------------------------------------------------------
+// Structure for file stream
+
+union TBaseProviderData
+{
+ struct
+ {
+ ULONGLONG FileSize; // Size of the file
+ ULONGLONG FilePos; // Current file position
+ ULONGLONG FileTime; // Last write time
+ HANDLE hFile; // File handle
+ } File;
+
+ struct
+ {
+ ULONGLONG FileSize; // Size of the file
+ ULONGLONG FilePos; // Current file position
+ ULONGLONG FileTime; // Last write time
+ LPBYTE pbFile; // Pointer to mapped view
+ } Map;
+
+ struct
+ {
+ ULONGLONG FileSize; // Size of the file
+ ULONGLONG FilePos; // Current file position
+ ULONGLONG FileTime; // Last write time
+ HANDLE hInternet; // Internet handle
+ HANDLE hConnect; // Connection to the internet server
+ } Http;
+};
+
+struct TFileStream
+{
+ // Stream provider functions
+ STREAM_READ StreamRead; // Pointer to stream read function for this archive. Do not use directly.
+ STREAM_WRITE StreamWrite; // Pointer to stream write function for this archive. Do not use directly.
+ STREAM_RESIZE StreamResize; // Pointer to function changing file size
+ STREAM_GETSIZE StreamGetSize; // Pointer to function returning file size
+ STREAM_GETPOS StreamGetPos; // Pointer to function that returns current file position
+ STREAM_CLOSE StreamClose; // Pointer to function closing the stream
+
+ // Block-oriented functions
+ BLOCK_READ BlockRead; // Pointer to function reading one or more blocks
+ BLOCK_CHECK BlockCheck; // Pointer to function checking whether the block is present
+
+ // Base provider functions
+ STREAM_CREATE BaseCreate; // Pointer to base create function
+ STREAM_OPEN BaseOpen; // Pointer to base open function
+ STREAM_READ BaseRead; // Read from the stream
+ STREAM_WRITE BaseWrite; // Write to the stream
+ STREAM_RESIZE BaseResize; // Pointer to function changing file size
+ STREAM_GETSIZE BaseGetSize; // Pointer to function returning file size
+ STREAM_GETPOS BaseGetPos; // Pointer to function that returns current file position
+ STREAM_CLOSE BaseClose; // Pointer to function closing the stream
+
+ // Base provider data (file size, file position)
+ TBaseProviderData Base;
+
+ // Stream provider data
+ TFileStream * pMaster; // Master stream (e.g. MPQ on a web server)
+ TCHAR * szFileName; // File name (self-relative pointer)
+
+ ULONGLONG StreamSize; // Stream size (can be less than file size)
+ ULONGLONG StreamPos; // Stream position
+ DWORD BuildNumber; // Game build number
+ DWORD dwFlags; // Stream flags
+
+ // Followed by stream provider data, with variable length
+};
+
+//-----------------------------------------------------------------------------
+// Structures for block-oriented stream
+
+struct TBlockStream : public TFileStream
+{
+ STREAM_DOWNLOAD_CALLBACK pfnCallback; // Callback for downloading
+ void * FileBitmap; // Array of bits for file blocks
+ void * UserData; // User data to be passed to the download callback
+ DWORD BitmapSize; // Size of the file bitmap (in bytes)
+ DWORD BlockSize; // Size of one block, in bytes
+ DWORD BlockCount; // Number of data blocks in the file
+ DWORD IsComplete; // If nonzero, no blocks are missing
+ DWORD IsModified; // nonzero if the bitmap has been modified
+};
+
+//-----------------------------------------------------------------------------
+// Structure for encrypted stream
+
+#define ENCRYPTED_CHUNK_SIZE 0x40 // Size of one chunk to be decrypted
+
+struct TEncryptedStream : public TBlockStream
+{
+ BYTE Key[ENCRYPTED_CHUNK_SIZE]; // File key
+};
+
+//-----------------------------------------------------------------------------
+// Public functions for file stream
+
+TFileStream * FileStream_CreateFile(const TCHAR * szFileName, DWORD dwStreamFlags);
+TFileStream * FileStream_OpenFile(const TCHAR * szFileName, DWORD dwStreamFlags);
+const TCHAR * FileStream_GetFileName(TFileStream * pStream);
+size_t FileStream_Prefix(const TCHAR * szFileName, DWORD * pdwProvider);
+
+bool FileStream_SetCallback(TFileStream * pStream, STREAM_DOWNLOAD_CALLBACK pfnCallback, void * pvUserData);
+
+bool FileStream_Read(TFileStream * pStream, ULONGLONG * pByteOffset, void * pvBuffer, DWORD dwBytesToRead);
+bool FileStream_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const void * pvBuffer, DWORD dwBytesToWrite);
+bool FileStream_SetSize(TFileStream * pStream, ULONGLONG NewFileSize);
+bool FileStream_GetSize(TFileStream * pStream, ULONGLONG * pFileSize);
+bool FileStream_GetPos(TFileStream * pStream, ULONGLONG * pByteOffset);
+bool FileStream_GetTime(TFileStream * pStream, ULONGLONG * pFT);
+bool FileStream_GetFlags(TFileStream * pStream, PDWORD pdwStreamFlags);
+bool FileStream_Replace(TFileStream * pStream, TFileStream * pNewStream);
+void FileStream_Close(TFileStream * pStream);
+
+
+#endif // __FILESTREAM_H__
diff --git a/dep/CascLib/src/common/ListFile.cpp b/dep/CascLib/src/common/ListFile.cpp
new file mode 100644
index 00000000000..4b742b1d07c
--- /dev/null
+++ b/dep/CascLib/src/common/ListFile.cpp
@@ -0,0 +1,266 @@
+/*****************************************************************************/
+/* ListFile.cpp Copyright (c) Ladislav Zezula 2004 */
+/*---------------------------------------------------------------------------*/
+/* Description: */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 12.06.04 1.00 Lad The first version of ListFile.cpp */
+/*****************************************************************************/
+
+#define __CASCLIB_SELF__
+#include "../CascLib.h"
+#include "../CascCommon.h"
+
+//-----------------------------------------------------------------------------
+// Listfile entry structure
+
+#define CACHE_BUFFER_SIZE 0x1000 // Size of the cache buffer
+
+typedef bool (*RELOAD_CACHE)(void * pvCacheContext, LPBYTE pbBuffer, DWORD dwBytesToRead);
+typedef void (*CLOSE_STREAM)(void * pvCacheContext);
+
+struct TListFileCache
+{
+ RELOAD_CACHE pfnReloadCache; // Function for reloading the cache
+ CLOSE_STREAM pfnCloseStream; // Function for closing the stream
+ void * pvCacheContext; // Reload context passed to reload function
+ char * szMask; // Self-relative pointer to file mask
+ DWORD dwFileSize; // Total size of the cached file
+ DWORD dwFilePos; // Position of the cache in the file
+ BYTE * pBegin; // The begin of the listfile cache
+ BYTE * pPos;
+ BYTE * pEnd; // The last character in the file cache
+
+ BYTE Buffer[CACHE_BUFFER_SIZE];
+// char MaskBuff[1] // Followed by the name mask (if any)
+};
+
+//-----------------------------------------------------------------------------
+// Local functions
+
+static bool ReloadCache_ExternalFile(void * pvCacheContext, LPBYTE pbBuffer, DWORD dwBytesToRead)
+{
+ TFileStream * pStream = (TFileStream *)pvCacheContext;
+
+ return FileStream_Read(pStream, NULL, pbBuffer, dwBytesToRead);
+}
+
+static void CloseStream_ExternalFile(void * pvCacheContext)
+{
+ TFileStream * pStream = (TFileStream *)pvCacheContext;
+
+ return FileStream_Close(pStream);
+}
+
+
+// Reloads the cache. Returns number of characters
+// that has been loaded into the cache.
+static DWORD ReloadListFileCache(TListFileCache * pCache)
+{
+ DWORD dwBytesToRead = 0;
+
+ // Only do something if the cache is empty
+ if(pCache->pPos >= pCache->pEnd)
+ {
+ // Move the file position forward
+ pCache->dwFilePos += CACHE_BUFFER_SIZE;
+ if(pCache->dwFilePos >= pCache->dwFileSize)
+ return 0;
+
+ // Get the number of bytes remaining
+ dwBytesToRead = pCache->dwFileSize - pCache->dwFilePos;
+ if(dwBytesToRead > CACHE_BUFFER_SIZE)
+ dwBytesToRead = CACHE_BUFFER_SIZE;
+
+ // Load the next data chunk to the cache
+ // If we didn't read anything, it might mean that the block
+ // of the file is not available
+ // We stop reading the file at this point, because the rest
+ // of the listfile is unreliable
+ if(!pCache->pfnReloadCache(pCache->pvCacheContext, pCache->Buffer, dwBytesToRead))
+ return 0;
+
+ // Set the buffer pointers
+ pCache->pBegin =
+ pCache->pPos = &pCache->Buffer[0];
+ pCache->pEnd = pCache->pBegin + dwBytesToRead;
+ }
+
+ return dwBytesToRead;
+}
+
+static size_t ReadListFileLine(TListFileCache * pCache, char * szLine, size_t nMaxChars)
+{
+ char * szLineBegin = szLine;
+ char * szLineEnd = szLine + nMaxChars - 1;
+ char * szExtraString = NULL;
+
+ // Skip newlines, spaces, tabs and another non-printable stuff
+ for(;;)
+ {
+ // If we need to reload the cache, do it
+ if(pCache->pPos == pCache->pEnd)
+ {
+ if(ReloadListFileCache(pCache) == 0)
+ break;
+ }
+
+ // If we found a non-whitespace character, stop
+ if(pCache->pPos[0] > 0x20)
+ break;
+
+ // Skip the character
+ pCache->pPos++;
+ }
+
+ // Copy the remaining characters
+ while(szLine < szLineEnd)
+ {
+ // If we need to reload the cache, do it now and resume copying
+ if(pCache->pPos == pCache->pEnd)
+ {
+ if(ReloadListFileCache(pCache) == 0)
+ break;
+ }
+
+ // If we have found a newline, stop loading
+ if(*pCache->pPos == 0x0D || *pCache->pPos == 0x0A)
+ break;
+
+ // Blizzard listfiles can also contain information about patch:
+ // Pass1\Files\MacOS\unconditional\user\Background Downloader.app\Contents\Info.plist~Patch(Data#frFR#base-frFR,1326)
+ if(*pCache->pPos == '~')
+ szExtraString = szLine;
+
+ // Copy the character
+ *szLine++ = *pCache->pPos++;
+ }
+
+ // Terminate line with zero
+ *szLine = 0;
+
+ // If there was extra string after the file name, clear it
+ if(szExtraString != NULL)
+ {
+ if(szExtraString[0] == '~' && szExtraString[1] == 'P')
+ {
+ szLine = szExtraString;
+ *szExtraString = 0;
+ }
+ }
+
+ // Return the length of the line
+ return (szLine - szLineBegin);
+}
+
+static TListFileCache * CreateListFileCache(RELOAD_CACHE pfnReloadCache, CLOSE_STREAM pfnCloseStream, void * pvCacheContext, DWORD dwFileSize)
+{
+ TListFileCache * pCache = NULL;
+ DWORD dwBytesToRead;
+
+ // Allocate cache for one file block
+ pCache = (TListFileCache *)CASC_ALLOC(BYTE, sizeof(TListFileCache));
+ if(pCache != NULL)
+ {
+ // Clear the entire structure
+ memset(pCache, 0, sizeof(TListFileCache));
+ pCache->pfnReloadCache = pfnReloadCache;
+ pCache->pfnCloseStream = pfnCloseStream;
+ pCache->pvCacheContext = pvCacheContext;
+ pCache->dwFileSize = dwFileSize;
+
+ // Load the file cache from the file
+ dwBytesToRead = CASCLIB_MIN(CACHE_BUFFER_SIZE, dwFileSize);
+ if(pfnReloadCache(pvCacheContext, pCache->Buffer, dwBytesToRead))
+ {
+ // Allocate pointers
+ pCache->pBegin = pCache->pPos = &pCache->Buffer[0];
+ pCache->pEnd = pCache->pBegin + dwBytesToRead;
+ }
+ else
+ {
+ ListFile_Free(pCache);
+ pCache = NULL;
+ }
+ }
+
+ // Return the cache
+ return pCache;
+}
+
+//-----------------------------------------------------------------------------
+// Listfile functions
+
+void * ListFile_OpenExternal(const TCHAR * szListFile)
+{
+ TListFileCache * pCache;
+ TFileStream * pStream;
+ ULONGLONG FileSize = 0;
+
+ // Open the external listfile
+ pStream = FileStream_OpenFile(szListFile, STREAM_FLAG_READ_ONLY);
+ if(pStream != NULL)
+ {
+ // Retrieve the size of the external listfile
+ FileStream_GetSize(pStream, &FileSize);
+ if(0 < FileSize && FileSize <= 0xFFFFFFFF)
+ {
+ // Create the cache for the listfile
+ pCache = CreateListFileCache(ReloadCache_ExternalFile, CloseStream_ExternalFile, pStream, (DWORD)FileSize);
+ if(pCache != NULL)
+ return pCache;
+ }
+
+ // Close the file stream
+ FileStream_Close(pStream);
+ }
+
+ return NULL;
+}
+
+size_t ListFile_GetNext(void * pvListFile, const char * szMask, char * szBuffer, size_t nMaxChars)
+{
+ TListFileCache * pCache = (TListFileCache *)pvListFile;
+ size_t nLength = 0;
+ int nError = ERROR_INVALID_PARAMETER;
+
+ // Check for parameters
+ if(pCache != NULL)
+ {
+ for(;;)
+ {
+ // Read the (next) line
+ nLength = ReadListFileLine(pCache, szBuffer, nMaxChars);
+ if(nLength == 0)
+ {
+ nError = ERROR_NO_MORE_FILES;
+ break;
+ }
+
+ // If some mask entered, check it
+ if(CheckWildCard(szBuffer, szMask))
+ {
+ nError = ERROR_SUCCESS;
+ break;
+ }
+ }
+ }
+
+ if(nError != ERROR_SUCCESS)
+ SetLastError(nError);
+ return nLength;
+}
+
+void ListFile_Free(void * pvListFile)
+{
+ TListFileCache * pCache = (TListFileCache *)pvListFile;
+
+ // Valid parameter check
+ if(pCache != NULL)
+ {
+ if(pCache->pfnCloseStream != NULL)
+ pCache->pfnCloseStream(pCache->pvCacheContext);
+ CASC_FREE(pCache);
+ }
+}
diff --git a/dep/CascLib/src/common/ListFile.h b/dep/CascLib/src/common/ListFile.h
new file mode 100644
index 00000000000..1c603af3766
--- /dev/null
+++ b/dep/CascLib/src/common/ListFile.h
@@ -0,0 +1,18 @@
+/*****************************************************************************/
+/* ListFile.h Copyright (c) Ladislav Zezula 2014 */
+/*---------------------------------------------------------------------------*/
+/* Common functions for CascLib */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 10.05.14 1.00 Lad The first version of ListFile.h */
+/*****************************************************************************/
+
+#ifndef __LISTFILE_H__
+#define __LISTFILE_H__
+
+void * ListFile_OpenExternal(const TCHAR * szListFile);
+size_t ListFile_GetNext(void * pvListFile, const char * szMask, char * szBuffer, size_t nMaxChars);
+void ListFile_Free(void * pvListFile);
+
+#endif // __LISTFILE_H__
diff --git a/dep/CascLib/src/common/Map.cpp b/dep/CascLib/src/common/Map.cpp
new file mode 100644
index 00000000000..70697a158ab
--- /dev/null
+++ b/dep/CascLib/src/common/Map.cpp
@@ -0,0 +1,178 @@
+/*****************************************************************************/
+/* Map.cpp Copyright (c) Ladislav Zezula 2014 */
+/*---------------------------------------------------------------------------*/
+/* Implementation of map for CascLib */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 10.06.14 1.00 Lad The first version of Map.cpp */
+/*****************************************************************************/
+
+#define __CASCLIB_SELF__
+#include "../CascLib.h"
+#include "../CascCommon.h"
+
+//-----------------------------------------------------------------------------
+// Local functions
+
+static DWORD CalcHashIndex(PCASC_MAP pMap, void * pvIdentifier)
+{
+ DWORD dwHash = 0x7EEE7EEE;
+
+ // Is it a string table?
+ if(pMap->KeyLength == KEY_LENGTH_STRING)
+ {
+ char * szString = (char *)pvIdentifier;
+
+ for(size_t i = 0; szString[i] != 0; i++)
+ dwHash = (dwHash >> 24) ^ (dwHash << 5) ^ dwHash ^ szString[i];
+ }
+ else
+ {
+ LPBYTE pbHash = (LPBYTE)pvIdentifier;
+
+ // Construct the hash from the first 4 digits
+ for(size_t i = 0; i < pMap->KeyLength; i++)
+ dwHash = (dwHash >> 24) ^ (dwHash << 5) ^ dwHash ^ pbHash[i];
+ }
+
+ // Return the hash limited by the table size
+ return (dwHash % pMap->TableSize);
+}
+
+static bool CompareIdentifier(PCASC_MAP pMap, void * pvTableEntry, void * pvIdentifier)
+{
+ // Is it a string table?
+ if(pMap->KeyLength == KEY_LENGTH_STRING)
+ {
+ char * szTableEntry = (char *)pvTableEntry;
+ char * szIdentifier = (char *)pvIdentifier;
+
+ return (strcmp(szTableEntry, szIdentifier) == 0);
+ }
+ else
+ {
+ return (memcmp(pvTableEntry, pvIdentifier, pMap->KeyLength) == 0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Public functions
+
+PCASC_MAP Map_Create(DWORD dwMaxItems, DWORD dwKeyLength, DWORD dwMemberOffset)
+{
+ PCASC_MAP pMap;
+ size_t cbToAllocate;
+ size_t dwTableSize;
+
+ // Calculate the size of the table
+ dwTableSize = (dwMaxItems * 3 / 2) | 0x01;
+
+ // Allocate new map for the objects
+ cbToAllocate = sizeof(CASC_MAP) + (dwTableSize * sizeof(void *));
+ pMap = (PCASC_MAP)CASC_ALLOC(LPBYTE, cbToAllocate);
+ if(pMap != NULL)
+ {
+ memset(pMap, 0, cbToAllocate);
+ pMap->KeyLength = dwKeyLength;
+ pMap->TableSize = dwTableSize;
+ pMap->MemberOffset = dwMemberOffset;
+ }
+
+ // Return the allocated map
+ return pMap;
+}
+
+size_t Map_EnumObjects(PCASC_MAP pMap, void **ppvArray)
+{
+ size_t nIndex = 0;
+
+ // Verify pointer to the map
+ if(pMap != NULL && ppvArray != NULL)
+ {
+ // Enumerate all items in main table
+ for(size_t i = 0; i < pMap->TableSize; i++)
+ {
+ // Is that cell valid?
+ if(pMap->HashTable[i] != NULL)
+ {
+ ppvArray[nIndex++] = pMap->HashTable[i];
+ }
+ }
+ }
+
+ return pMap->ItemCount;
+}
+
+void * Map_FindObject(PCASC_MAP pMap, void * pvIdentifier)
+{
+ void * pvTableEntry;
+ DWORD dwHashIndex;
+
+ // Verify pointer to the map
+ if(pMap != NULL)
+ {
+ // Construct the main index
+ dwHashIndex = CalcHashIndex(pMap, pvIdentifier);
+ while(pMap->HashTable[dwHashIndex] != NULL)
+ {
+ // Get the pointer at that position
+ pvTableEntry = pMap->HashTable[dwHashIndex];
+
+ // Compare the hash
+ if(CompareIdentifier(pMap, pvTableEntry, pvIdentifier))
+ return ((LPBYTE)pvTableEntry - pMap->MemberOffset);
+
+ // Move to the next entry
+ dwHashIndex = (dwHashIndex + 1) % pMap->TableSize;
+ }
+ }
+
+ // Not found, sorry
+ return NULL;
+}
+
+bool Map_InsertObject(PCASC_MAP pMap, void * pvIdentifier)
+{
+ void * pvTableEntry;
+ DWORD dwHashIndex;
+
+ // Verify pointer to the map
+ if(pMap != NULL)
+ {
+ // Limit check
+ if((pMap->ItemCount + 1) >= pMap->TableSize)
+ return false;
+
+ // Construct the hash index
+ dwHashIndex = CalcHashIndex(pMap, pvIdentifier);
+ while(pMap->HashTable[dwHashIndex] != NULL)
+ {
+ // Get the pointer at that position
+ pvTableEntry = pMap->HashTable[dwHashIndex];
+
+ // Check if hash being inserted conflicts with an existing hash
+ if(CompareIdentifier(pMap, pvTableEntry, pvIdentifier))
+ return false;
+
+ // Move to the next entry
+ dwHashIndex = (dwHashIndex + 1) % pMap->TableSize;
+ }
+
+ // Insert at that position
+ pMap->HashTable[dwHashIndex] = pvIdentifier;
+ pMap->ItemCount++;
+ return true;
+ }
+
+ // Failed
+ return false;
+}
+
+void Map_Free(PCASC_MAP pMap)
+{
+ if(pMap != NULL)
+ {
+ CASC_FREE(pMap);
+ }
+}
diff --git a/dep/CascLib/src/common/Map.h b/dep/CascLib/src/common/Map.h
new file mode 100644
index 00000000000..b4b9c918df3
--- /dev/null
+++ b/dep/CascLib/src/common/Map.h
@@ -0,0 +1,39 @@
+/*****************************************************************************/
+/* Map.h Copyright (c) Ladislav Zezula 2014 */
+/*---------------------------------------------------------------------------*/
+/* Interface of hash-to-ptr map for CascLib */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 10.06.14 1.00 Lad The first version of Map.h */
+/*****************************************************************************/
+
+#ifndef __HASHTOPTR_H__
+#define __HASHTOPTR_H__
+
+//-----------------------------------------------------------------------------
+// Structures
+
+#define KEY_LENGTH_STRING 0xFFFFFFFF // Pass this to Map_Create as dwKeyLength when you want map of string->object
+
+typedef struct _CASC_MAP
+{
+ size_t TableSize;
+ size_t ItemCount; // Number of items in the map
+ size_t MemberOffset; // How far is the hash from the begin of the structure (in bytes)
+ size_t KeyLength; // Length of the hash key
+ void * HashTable[1]; // Pointer table
+
+} CASC_MAP, *PCASC_MAP;
+
+//-----------------------------------------------------------------------------
+// Functions
+
+PCASC_MAP Map_Create(DWORD dwMaxItems, DWORD dwKeyLength, DWORD dwMemberOffset);
+size_t Map_EnumObjects(PCASC_MAP pMap, void **ppvArray);
+void * Map_FindObject(PCASC_MAP pMap, void * pvIdentifier);
+bool Map_InsertObject(PCASC_MAP pMap, void * pvIdentifier);
+void Map_Sort(PCASC_MAP pMap);
+void Map_Free(PCASC_MAP pMap);
+
+#endif // __HASHTOPTR_H__
diff --git a/dep/StormLib/src/jenkins/lookup.h b/dep/CascLib/src/jenkins/lookup.h
index 54ccc979ca6..54ccc979ca6 100644
--- a/dep/StormLib/src/jenkins/lookup.h
+++ b/dep/CascLib/src/jenkins/lookup.h
diff --git a/dep/StormLib/src/jenkins/lookup3.c b/dep/CascLib/src/jenkins/lookup3.c
index 6af56b481ad..6af56b481ad 100644
--- a/dep/StormLib/src/jenkins/lookup3.c
+++ b/dep/CascLib/src/jenkins/lookup3.c
diff --git a/dep/StormLib/src/libtomcrypt/src/hashes/hash_memory.c b/dep/CascLib/src/libtomcrypt/src/hashes/hash_memory.c
index 1daf0bffa1b..1daf0bffa1b 100644
--- a/dep/StormLib/src/libtomcrypt/src/hashes/hash_memory.c
+++ b/dep/CascLib/src/libtomcrypt/src/hashes/hash_memory.c
diff --git a/dep/StormLib/src/libtomcrypt/src/hashes/md5.c b/dep/CascLib/src/libtomcrypt/src/hashes/md5.c
index 4cbd000c0d4..4cbd000c0d4 100644
--- a/dep/StormLib/src/libtomcrypt/src/hashes/md5.c
+++ b/dep/CascLib/src/libtomcrypt/src/hashes/md5.c
diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt.h b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt.h
index 74cdff47549..74cdff47549 100644
--- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt.h
+++ b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt.h
diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_argchk.h b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_argchk.h
index cfc93ad7ea6..cfc93ad7ea6 100644
--- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_argchk.h
+++ b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_argchk.h
diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h
index 7feae6e8bdc..7feae6e8bdc 100644
--- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h
+++ b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h
diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_cipher.h b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_cipher.h
index bd740bf4a0c..bd740bf4a0c 100644
--- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_cipher.h
+++ b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_cipher.h
diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_custom.h b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_custom.h
index 88ec8f984ab..88ec8f984ab 100644
--- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_custom.h
+++ b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_custom.h
diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_hash.h b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_hash.h
index 18553ebf9da..18553ebf9da 100644
--- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_hash.h
+++ b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_hash.h
diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_mac.h b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_mac.h
index 7ad9516bd29..7ad9516bd29 100644
--- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_mac.h
+++ b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_mac.h
diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_macros.h b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_macros.h
index 53bda9bb4ba..53bda9bb4ba 100644
--- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_macros.h
+++ b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_macros.h
diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_math.h b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_math.h
index a05d7fff942..a05d7fff942 100644
--- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_math.h
+++ b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_math.h
diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_misc.h b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_misc.h
index f5384cacc51..f5384cacc51 100644
--- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_misc.h
+++ b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_misc.h
diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_pk.h b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_pk.h
index b5f277a8848..b5f277a8848 100644
--- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_pk.h
+++ b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_pk.h
diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_pkcs.h b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_pkcs.h
index 84fb82a6229..84fb82a6229 100644
--- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_pkcs.h
+++ b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_pkcs.h
diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_prng.h b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_prng.h
index f3e3e550e88..f3e3e550e88 100644
--- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_prng.h
+++ b/dep/CascLib/src/libtomcrypt/src/headers/tomcrypt_prng.h
diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_argchk.c b/dep/CascLib/src/libtomcrypt/src/misc/crypt_argchk.c
index 537516d80d9..537516d80d9 100644
--- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_argchk.c
+++ b/dep/CascLib/src/libtomcrypt/src/misc/crypt_argchk.c
diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_hash_descriptor.c b/dep/CascLib/src/libtomcrypt/src/misc/crypt_hash_descriptor.c
index 5925fd27302..5925fd27302 100644
--- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_hash_descriptor.c
+++ b/dep/CascLib/src/libtomcrypt/src/misc/crypt_hash_descriptor.c
diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_hash_is_valid.c b/dep/CascLib/src/libtomcrypt/src/misc/crypt_hash_is_valid.c
index 8ed5105b56c..8ed5105b56c 100644
--- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_hash_is_valid.c
+++ b/dep/CascLib/src/libtomcrypt/src/misc/crypt_hash_is_valid.c
diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_libc.c b/dep/CascLib/src/libtomcrypt/src/misc/crypt_libc.c
index bcc89f4f94d..bcc89f4f94d 100644
--- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_libc.c
+++ b/dep/CascLib/src/libtomcrypt/src/misc/crypt_libc.c
diff --git a/dep/StormLib/CMakeLists.txt b/dep/StormLib/CMakeLists.txt
deleted file mode 100644
index 7096c8f8729..00000000000
--- a/dep/StormLib/CMakeLists.txt
+++ /dev/null
@@ -1,272 +0,0 @@
-set(SRC_FILES
- src/adpcm/adpcm.cpp
- src/huffman/huff.cpp
- src/jenkins/lookup3.c
- src/lzma/C/LzFind.c
- src/lzma/C/LzmaDec.c
- src/lzma/C/LzmaEnc.c
- src/pklib/explode.c
- src/pklib/implode.c
- src/sparse/sparse.cpp
- src/FileStream.cpp
- src/SBaseCommon.cpp
- src/SBaseFileTable.cpp
- src/SCompression.cpp
- src/SFileAddFile.cpp
- src/SFileAttributes.cpp
- src/SFileCompactArchive.cpp
- src/SFileCreateArchive.cpp
- src/SFileExtractFile.cpp
- src/SFileFindFile.cpp
- src/SFileListFile.cpp
- src/SFileOpenArchive.cpp
- src/SFileOpenFileEx.cpp
- src/SFilePatchArchives.cpp
- src/SFileReadFile.cpp
- src/SFileVerify.cpp
-)
-
-set(TOMCRYPT_FILES
- src/libtomcrypt/src/hashes/hash_memory.c
- src/libtomcrypt/src/hashes/md5.c
- src/libtomcrypt/src/hashes/sha1.c
- src/libtomcrypt/src/math/ltm_desc.c
- src/libtomcrypt/src/math/multi.c
- src/libtomcrypt/src/math/rand_prime.c
- src/libtomcrypt/src/misc/base64_decode.c
- src/libtomcrypt/src/misc/crypt_argchk.c
- src/libtomcrypt/src/misc/crypt_find_hash.c
- src/libtomcrypt/src/misc/crypt_find_prng.c
- src/libtomcrypt/src/misc/crypt_hash_descriptor.c
- src/libtomcrypt/src/misc/crypt_hash_is_valid.c
- src/libtomcrypt/src/misc/crypt_libc.c
- src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c
- src/libtomcrypt/src/misc/crypt_prng_descriptor.c
- src/libtomcrypt/src/misc/crypt_prng_is_valid.c
- src/libtomcrypt/src/misc/crypt_register_hash.c
- src/libtomcrypt/src/misc/crypt_register_prng.c
- src/libtomcrypt/src/misc/zeromem.c
- src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c
- src/libtomcrypt/src/pk/asn1/der_decode_boolean.c
- src/libtomcrypt/src/pk/asn1/der_decode_choice.c
- src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c
- src/libtomcrypt/src/pk/asn1/der_decode_integer.c
- src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c
- src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c
- src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c
- src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c
- src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c
- src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c
- src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c
- src/libtomcrypt/src/pk/asn1/der_decode_utctime.c
- src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c
- src/libtomcrypt/src/pk/asn1/der_length_bit_string.c
- src/libtomcrypt/src/pk/asn1/der_length_boolean.c
- src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c
- src/libtomcrypt/src/pk/asn1/der_length_integer.c
- src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c
- src/libtomcrypt/src/pk/asn1/der_length_octet_string.c
- src/libtomcrypt/src/pk/asn1/der_length_printable_string.c
- src/libtomcrypt/src/pk/asn1/der_length_sequence.c
- src/libtomcrypt/src/pk/asn1/der_length_utctime.c
- src/libtomcrypt/src/pk/asn1/der_sequence_free.c
- src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c
- src/libtomcrypt/src/pk/asn1/der_length_short_integer.c
- src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c
- src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c
- src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c
- src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c
- src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c
- src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c
- src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c
- src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c
- src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c
- src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c
- src/libtomcrypt/src/pk/rsa/rsa_exptmod.c
- src/libtomcrypt/src/pk/rsa/rsa_free.c
- src/libtomcrypt/src/pk/rsa/rsa_import.c
- src/libtomcrypt/src/pk/rsa/rsa_make_key.c
- src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c
- src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c
-)
-
-set(TOMMATH_FILES
- src/libtommath/bncore.c
- src/libtommath/bn_fast_mp_invmod.c
- src/libtommath/bn_fast_mp_montgomery_reduce.c
- src/libtommath/bn_fast_s_mp_mul_digs.c
- src/libtommath/bn_fast_s_mp_mul_high_digs.c
- src/libtommath/bn_fast_s_mp_sqr.c
- src/libtommath/bn_mp_2expt.c
- src/libtommath/bn_mp_abs.c
- src/libtommath/bn_mp_add.c
- src/libtommath/bn_mp_addmod.c
- src/libtommath/bn_mp_add_d.c
- src/libtommath/bn_mp_and.c
- src/libtommath/bn_mp_clamp.c
- src/libtommath/bn_mp_clear.c
- src/libtommath/bn_mp_clear_multi.c
- src/libtommath/bn_mp_cmp.c
- src/libtommath/bn_mp_cmp_d.c
- src/libtommath/bn_mp_cmp_mag.c
- src/libtommath/bn_mp_cnt_lsb.c
- src/libtommath/bn_mp_copy.c
- src/libtommath/bn_mp_count_bits.c
- src/libtommath/bn_mp_div.c
- src/libtommath/bn_mp_div_2.c
- src/libtommath/bn_mp_div_2d.c
- src/libtommath/bn_mp_div_3.c
- src/libtommath/bn_mp_div_d.c
- src/libtommath/bn_mp_dr_is_modulus.c
- src/libtommath/bn_mp_dr_reduce.c
- src/libtommath/bn_mp_dr_setup.c
- src/libtommath/bn_mp_exch.c
- src/libtommath/bn_mp_exptmod.c
- src/libtommath/bn_mp_exptmod_fast.c
- src/libtommath/bn_mp_expt_d.c
- src/libtommath/bn_mp_exteuclid.c
- src/libtommath/bn_mp_fread.c
- src/libtommath/bn_mp_fwrite.c
- src/libtommath/bn_mp_gcd.c
- src/libtommath/bn_mp_get_int.c
- src/libtommath/bn_mp_grow.c
- src/libtommath/bn_mp_init.c
- src/libtommath/bn_mp_init_copy.c
- src/libtommath/bn_mp_init_multi.c
- src/libtommath/bn_mp_init_set.c
- src/libtommath/bn_mp_init_set_int.c
- src/libtommath/bn_mp_init_size.c
- src/libtommath/bn_mp_invmod.c
- src/libtommath/bn_mp_invmod_slow.c
- src/libtommath/bn_mp_is_square.c
- src/libtommath/bn_mp_jacobi.c
- src/libtommath/bn_mp_karatsuba_mul.c
- src/libtommath/bn_mp_karatsuba_sqr.c
- src/libtommath/bn_mp_lcm.c
- src/libtommath/bn_mp_lshd.c
- src/libtommath/bn_mp_mod.c
- src/libtommath/bn_mp_mod_2d.c
- src/libtommath/bn_mp_mod_d.c
- src/libtommath/bn_mp_montgomery_calc_normalization.c
- src/libtommath/bn_mp_montgomery_reduce.c
- src/libtommath/bn_mp_montgomery_setup.c
- src/libtommath/bn_mp_mul.c
- src/libtommath/bn_mp_mulmod.c
- src/libtommath/bn_mp_mul_2.c
- src/libtommath/bn_mp_mul_2d.c
- src/libtommath/bn_mp_mul_d.c
- src/libtommath/bn_mp_neg.c
- src/libtommath/bn_mp_n_root.c
- src/libtommath/bn_mp_or.c
- src/libtommath/bn_mp_prime_fermat.c
- src/libtommath/bn_mp_prime_is_divisible.c
- src/libtommath/bn_mp_prime_is_prime.c
- src/libtommath/bn_mp_prime_miller_rabin.c
- src/libtommath/bn_mp_prime_next_prime.c
- src/libtommath/bn_mp_prime_rabin_miller_trials.c
- src/libtommath/bn_mp_prime_random_ex.c
- src/libtommath/bn_mp_radix_size.c
- src/libtommath/bn_mp_radix_smap.c
- src/libtommath/bn_mp_rand.c
- src/libtommath/bn_mp_read_radix.c
- src/libtommath/bn_mp_read_signed_bin.c
- src/libtommath/bn_mp_read_unsigned_bin.c
- src/libtommath/bn_mp_reduce.c
- src/libtommath/bn_mp_reduce_2k.c
- src/libtommath/bn_mp_reduce_2k_l.c
- src/libtommath/bn_mp_reduce_2k_setup.c
- src/libtommath/bn_mp_reduce_2k_setup_l.c
- src/libtommath/bn_mp_reduce_is_2k.c
- src/libtommath/bn_mp_reduce_is_2k_l.c
- src/libtommath/bn_mp_reduce_setup.c
- src/libtommath/bn_mp_rshd.c
- src/libtommath/bn_mp_set.c
- src/libtommath/bn_mp_set_int.c
- src/libtommath/bn_mp_shrink.c
- src/libtommath/bn_mp_signed_bin_size.c
- src/libtommath/bn_mp_sqr.c
- src/libtommath/bn_mp_sqrmod.c
- src/libtommath/bn_mp_sqrt.c
- src/libtommath/bn_mp_sub.c
- src/libtommath/bn_mp_submod.c
- src/libtommath/bn_mp_sub_d.c
- src/libtommath/bn_mp_toom_mul.c
- src/libtommath/bn_mp_toom_sqr.c
- src/libtommath/bn_mp_toradix.c
- src/libtommath/bn_mp_toradix_n.c
- src/libtommath/bn_mp_to_signed_bin.c
- src/libtommath/bn_mp_to_signed_bin_n.c
- src/libtommath/bn_mp_to_unsigned_bin.c
- src/libtommath/bn_mp_to_unsigned_bin_n.c
- src/libtommath/bn_mp_unsigned_bin_size.c
- src/libtommath/bn_mp_xor.c
- src/libtommath/bn_mp_zero.c
- src/libtommath/bn_prime_tab.c
- src/libtommath/bn_reverse.c
- src/libtommath/bn_s_mp_add.c
- src/libtommath/bn_s_mp_exptmod.c
- src/libtommath/bn_s_mp_mul_digs.c
- src/libtommath/bn_s_mp_mul_high_digs.c
- src/libtommath/bn_s_mp_sqr.c
- src/libtommath/bn_s_mp_sub.c
-)
-
-set(ZLIB_BZIP2_FILES
- src/bzip2/blocksort.c
- src/bzip2/bzlib.c
- src/bzip2/compress.c
- src/bzip2/crctable.c
- src/bzip2/decompress.c
- src/bzip2/huffman.c
- src/bzip2/randtable.c
- src/zlib/adler32.c
- src/zlib/compress2.c
- src/zlib/crc32.c
- src/zlib/deflate.c
- src/zlib/inffast.c
- src/zlib/inflate.c
- src/zlib/inftrees.c
- src/zlib/trees.c
- src/zlib/zutil.c
-)
-
-set(TEST_SRC_FILES
- test/Test.cpp
-)
-
-add_definitions(-D_7ZIP_ST -DBZ_STRICT_ANSI)
-
-if(WIN32)
- if(MSVC)
- add_definitions(-D_7ZIP_ST -DWIN32)
- endif()
- set(SRC_ADDITIONAL_FILES ${ZLIB_BZIP2_FILES} ${TOMCRYPT_FILES} ${TOMMATH_FILES})
- set(LINK_LIBS wininet)
-endif()
-
-if(APPLE)
- set(LINK_LIBS z bz2)
- set(SRC_ADDITIONAL_FILES ${TOMCRYPT_FILES} ${TOMMATH_FILES})
-endif()
-
-if (${CMAKE_SYSTEM_NAME} STREQUAL Linux)
- option(WITH_LIBTOMCRYPT "Use system LibTomCrypt library" OFF)
- if(WITH_LIBTOMCRYPT)
- set(LINK_LIBS z bz2 tomcrypt)
- else()
- set(LINK_LIBS z bz2)
- set(SRC_ADDITIONAL_FILES ${TOMCRYPT_FILES} ${TOMMATH_FILES})
- endif()
-endif()
-
-add_library(storm STATIC ${SRC_FILES} ${SRC_ADDITIONAL_FILES})
-target_link_libraries(storm ${LINK_LIBS})
-
-if(UNIX)
- set_target_properties(storm PROPERTIES SOVERSION 0)
-endif()
-
-# On Win32, build StormLib.dll since we don't want to clash with Storm.dll
-if(WIN32)
- set_target_properties(storm PROPERTIES OUTPUT_NAME StormLib)
-endif()
diff --git a/dep/StormLib/doc/History.txt b/dep/StormLib/doc/History.txt
deleted file mode 100644
index 5e32894d7b1..00000000000
--- a/dep/StormLib/doc/History.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-
- StormLib history
- ================
-
- Version 8.02
-
- - Support for UNICODE encoding for on-disk files
- - Optimized file deleting
-
- Version 8.01
-
- - SFileFindFirstFile and SFileFindNextFile no longer find files that have
- patch file in the oldest MPQ in the patch chain
- - Write support for MPQs version 4
-
- Version 8.00
-
- - Updated support for protected maps from Warcraft III
-
- Version 7.11
-
- - Support for MPQs v 3.0 (WOW-Cataclysm BETA)
- - StormLib now deals properly with files that have MPQ_SECTOR_CHECKSUM missing,
- but have sector checksum entry present in the sector offset table
-
- Version 7.10
-
- - Support for partial MPQs ("interface.MPQ.part")
- - The only operation that is externally allowed to do with internal files
- ("(listfile)", "(attributes)" and "(signature)") is reading. Attempt to modify any of the file
- fails and GetLastError returns ERROR_INTERNAL_FILE
- - Fixed memory leak that has occured when writing more than one sector to the file at once
-
- Version 7.01
-
- - Support for adding files from memory
- - Fixed improper validation of handles to MPQ file and MPQ archive
- - Fixed bug where StormLib didn't save CRC32 of the file when added to archive
-
- Version 7.00
-
- - Properly deals with MPQs protected by w3xMaster
- - Major rewrite
- - Fixed support for (attributes)
- - Added file verification
- - Added MPQ signature verification
-
- Version 6.22
-
- - Properly deals with MPQs protected by w3xMaster
-
- Version 6.21
-
- - SFileRenameFile now properly re-crypts the file if necessary.
- - SFileFindFirstFile correctly deals with deleted files
-
- Version 6.20
-
- - Fixed lots of bugs when processing files with same names but different locales
- - Fixed bugs when repeately extracts the same file with MPQ_FILE_SINGLE_UNIT flag
- - Added SFileFlushArchive
- - Fixed issue opening AVI files renamed to MPQ using SFileCreateArchiveEx
diff --git a/dep/StormLib/doc/Sector Offset MD5.txt b/dep/StormLib/doc/Sector Offset MD5.txt
deleted file mode 100644
index a22506ac704..00000000000
--- a/dep/StormLib/doc/Sector Offset MD5.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-
- After sector offset table
- =========================
-
-FileSize CmpSize DWORDs
-00007588 000075A4 0x01
-0000A9EA 000095EC 0x01
-0000E51D 0000E20D 0x02
-00015C00 00015C40 0x02
-0001C578 000186C4 0x02
-0002A9D4 0002A9EA 0x04
-00037BAC 00037A42 0x06
-0003C3C1 00034084 0x06
-0003D224 0003B30F 0x06
-00045105 0004195A 0x07
-00045D9C 0003D87D 0x07
-0004AAB8 0004860A 0x08
-0004D18E 00048E0C 0x07
-00056B4C 00056BDD 0x09
-0005DC08 00059426 0x09
-00061EC0 00057711 0x0A
-0006CEC4 00062561 0x0B
-000778EE 00066736 0x0C
-000AD0CB 0007F32E 0x11
-00327EAC 00303395 0x53
diff --git a/dep/StormLib/doc/The MoPaQ File Format 0.9.txt b/dep/StormLib/doc/The MoPaQ File Format 0.9.txt
deleted file mode 100644
index ce8d8f70166..00000000000
--- a/dep/StormLib/doc/The MoPaQ File Format 0.9.txt
+++ /dev/null
@@ -1,318 +0,0 @@
-THE MOPAQ ARCHIVE FORMAT
-v0.9 (Thursday, June 30, 2005)
-by Justin Olbrantz(Quantam)
-
-Distribution and reproduction of this specification are allowed without limitation, as long as it is not altered. Quoting
-in other works is freely allowed, as long as the source and author of the quote is stated.
-
-TABLE OF CONTENTS
-1. Introduction to the MoPaQ Format
-2. The MoPaQ Format
- 2.1 General Archive Layout
- 2.2 Archive Header
- 2.3 Block Table
- 2.4 Hash Table
- 2.5 File Data
- 2.6 Listfile
- 2.7 Extended Attributes
- 2.8 Weak (Old) Digital Signature
- 2.9 Strong (New) Digital Signature
-3. Algorithm Source Code
- 3.1 Encryption/Decryption
- 3.2 Hashing
- 3.3 Conversion of FILETIME and time_t
-
-1. INTRODUCTION TO THE MOPAQ FORMAT
-The MoPaQ (or MPQ) format is an archive file format designed by Mike O'Brien (hence the name Mike O'brien PaCK) at Blizzard
-Entertainment. The format has been used in all Blizzard games since (and including) Diablo. It is heavily optimized to be
-a read-only game archive format, and excels at this role.
-
-The Blizzard MoPaQ-reading functions are contained in the Storm module, which my be either statically or dynamically linked.
-The Blizzard MoPaQ-writing functions are contained in the MPQAPI module, which is always statically linked.
-
-2. THE MOPAQ FORMAT
-All numbers in the MoPaQ format are in little endian. Data types are listed either as int (integer, the number of bits specified),
-byte (8 bits), and char (bytes which contain ASCII characters). All sizes and offsets are in bytes, unless specified otherwise.
-Structure members are listed in the following general form:
-offset from the beginning of the structure: data type(array size) member name : member description
-
-2.1 GENERAL ARCHIVE LAYOUT
-- Archive Header
-- File Data
-- File Data - Special Files
-- Hash Table
-- Block Table
-- Strong Digital signature
-
-This is the usual archive format, and is not absolutely essential. Some archives have been observed placing the hash table
-and file table after the archive header, and before the file data.
-
-2.2 ARCHIVE HEADER
-00h: char(4) Magic : Indicates that the file is a MoPaQ archive. Must be ASCII "MPQ" 1Ah.
-04h: int32 HeaderSize : Size of the archive header. Should be 32.
-08h: int32 ArchiveSize : Size of the whole archive, including the header. Does not include the strong digital signature, if present.
-This size is used, among other things, for determining the region to hash in computing the digital signature.
-0Ch: int16 Unknown : Unknown
-0Eh: int8 SectorSizeShift : Power of two exponent specifying the number of 512-byte disk sectors in each logical sector
-in the archive. The size of each logical sector the archive is 512 * 2^SectorSizeShift. Bugs in the Storm library dictate
-that this should always be 3 (4096 byte sectors).
-10h: int32 HashTableOffset : Offset to the beginning of the hash table, relative to the beginning of the archive.
-14h: int32 BlockTableOffset : Offset to the beginning of the block table, relative to the beginning of the archive.
-18h: int32 HashTableEntries : Number of entries in the hash table. Must be a power of two, and must be less than 2^16.
-1Ch: int32 BlockTableEntries : Number of entries in the block table.
-
-The archive header is the first structure in the archive, at archive offset 0, but the archive does not need to be at offset
-0 of the containing file. The offset of the archive in the file is referred to here as ArchiveOffset. If the archive is not
-at the beginning of the file, it must begin at a disk sector boundary (512 bytes). Early versions of Storm require that the
-archive be at the end of the containing file (ArchiveOffset + ArchiveSize = file size), but this is not required in newer
-versions (due to the strong digital signature not being considered a part of the archive).
-
-2.3 BLOCK TABLE
-The block table contains entries for each region in the archive. Regions may be either files or empty space, which may be
-overwritten by new files (typically this space is from deleted file data). The block table is encrypted, using the hash
-of "(block table)" as the key. Each entry is structured as follows:
-
-00h: int32 BlockOffset : Offset of the beginning of the block, relative to the beginning of the archive. Meaningless if the block size is 0.
-04h: int32 BlockSize : Size of the block in the archive.
-08h: int32 FileSize : Size of the file data stored in the block. Only valid if the block is a file, otherwise meaningless, and should be 0. If the file is compressed, this is the size of the uncompressed file data.
-0Ch: int32 Flags : Bit mask of the flags for the block. The following values are conclusively identified:
- 80000000h: Block is a file, and follows the file data format; otherwise, block is free space, and may be overwritten. If the block is not a file, all other flags should be cleared.
- 01000000h: File is stored as a single unit, rather than split into sectors.
- 00020000h: The file's encryption key is adjusted by the block offset and file size (explained in detail in the File Data section). File must be encrypted.
- 00010000h: File is encrypted.
- 00000200h: File is compressed. Mutually exclusive to file imploded.
- 00000100h: File is imploded. Mutually exclusive to file compressed.
-
-2.4 HASH TABLE
-Instead of storing file names, for quick access MoPaQs use a fixed, power of two-size hash table of files in the archive. A file is uniquely identified by its file path, its language, and its platform. The home entry for a file in the hash table is computed as a hash of the file path. In the event of a collision (the home entry is occupied by another file), progressive overflow is used, and the file is placed in the next available hash table entry. Searches for a desired file in the hash table proceed from the home entry for the file until either the file is found, the entire hash table is searched, or an empty hash table entry (FileBlockIndex of FFFFFFFFh) is encountered. The hash table is encrypted using the hash of "(hash table)" as the key. Each entry is structured as follows:
-
-00h: int32 FilePathHashA : The hash of the file path, using method A.
-04h: int32 FilePathHashB : The hash of the file path, using method B.
-08h: int16 Language : The language of the file. This is a Windows LANGID data type, and uses the same values. 0 indicates the default language (American English), or that the file is language-neutral.
-0Ah: int8 Platform : The platform the file is used for. 0 indicates the default platform. No other values have been observed.
-0Ch: int32 FileBlockIndex : If the hash table entry is valid, this is the index into the block table of the file. Otherwise, one of the following two values:
- FFFFFFFFh: Hash table entry is empty, and has always been empty. Terminates searches for a given file.
- FFFFFFFEh: Hash table entry is empty, but was valid at some point (in other words, the file was deleted). Does not terminate searches for a given file.
-
-2.5 FILE DATA
-00h: int32(SectorsInFile + 1) SectorOffsetTable : Offsets to the start of each sector's data, relative to the beginning of the file data. Not present if this information is calculatable (see details below).
-immediately following SectorOffsetTable: SectorData : Data of each sector in the file, packed end to end (see details below).
-
-Normally, file data is split up into sectors, for simple streaming. All sectors, save for the last, will contain as many bytes of file data as specified in the archive header's SectorSizeShift; the last sector may be smaller than this, depending on the size of the file data. This sector size is the size of the raw file data; if the file is compressed, the compressed sector will be smaller or the same size as the uncompressed sector size. Individual sectors in a compressed file may be stored uncompressed; this occurs if and only if the sector could not be compressed by the algorithm used (if the compressed sector size was greater than or equal to the size of the raw data), and is indicated by the sector's compressed size in SectorOffsetTable being equal to the uncompressed size of the sector (which may be calculated from the FileSize).
-
-If the sector is compressed (but not imploded), a bit mask byte of the compression algorithm(s) used to compress the sector is appended to the beginning of the compressed sector data. This additional byte counts towards the total size of the sector; if the size of the sector (including this byte) exceeds or matches the uncompressed size of the sector data, the sector will be stored uncompressed, and this byte omitted. Multiple compression algorithms may be used on the same sector; in this case, successive compression occurs in the order the algorithms are listed below, and decompression occurs in the opposite order. For implimentations of all of these algorithms, see StormLib.
- 40h: IMA ADPCM mono
- 80h: IMA ADPCM stereo
- 01h: Huffman encoded
- 02h: Deflated (see ZLib)
- 08h: Imploded (see PKWare Data Compression Library)
- 10h: BZip2 compressed (see BZip2)
-
-If the file is stored as a single unit (indicated in the file's Flags), there is effectively only a single sector, which
-contains the entire file.
-
-If the file is encrypted, each sector (after compression and appendage of the compression type byte, if applicable)
-is encrypted with the file's key. The base key for a file is determined by a hash of the file name stripped of the
-directory (i.e. the key for a file named "directory\file" would be computed as the hash of "file"). If this key is
-adjusted, as indicated in the file's Flags, the final key is calculated as ((base key + BlockOffset - ArchiveOffset)
-XOR FileSize) (StormLib - an open-source implementation of the MoPaQ reading and writing functions,
-by Ladislav Zezula - incorrectly uses an AND in place of the XOR). Each sector is encrypted using the key + the
-0-based index of the sector in the file. The SectorOffsetTable, if present, is encrypted using the key - 1.
-
-The SectorOffsetTable is omitted when the sizes and offsets of all sectors in the file are calculatable from the FileSize.
-This can happen in several circumstances. If the file is not compressed/imploded, then the size and offset of all sectors
-is known, based on the archive's SectorSizeShift. If the file is stored as a single unit compressed/imploded, then the
-SectorOffsetTable is omitted, as the single file "sector" corresponds to BlockSize and FileSize, as mentioned previously.
-Note that the SectorOffsetTable will always be present if the file is compressed/imploded and the file is not stored as
-a single unit, even if there is only a single sector in the file (the size of the file is less than or equal to the
-archive's sector size).
-
-2.6 LISTFILE
-The listfile is a very simple extension to the MoPaQ format that contains the file paths of (most) files in the archive.
-The languages and platforms of the files are not stored in the listfile. The listfile is contained in the file "(listfile)",
-and is simply a non-Unix-style text file with one file path on each line, lines terminated with the bytes 0Dh 0Ah. The file
-"(listfile)" may not be listed in the listfile.
-
-2.7 EXTENDED ATTRIBUTES
-The extended attributes are optional file attributes for files in the block table. These attributes were added at times after
-the MoPaQ format was already finalized, and it is not necessary for every archive to have all (or any) of the extended attributes.
-If an archive contains a given attribute, there will be an instance of that attribute for every block in the block table, although
-the attribute will be meaningless if the block is not a file. The order of the attributes for blocks correspond to the order of the
-blocks in the block table, and are of the same number. The attributes are stored in parallel arrays in the "(attributes)" file,
-in the archive. The attributes corresponding to this file need not be valid (and logically cannot be). Unlike all the other
-structures in the MoPaQ format, entries in the extended attributes are NOT guaranteed to be aligned. Also note that in some
-archives, malicious zeroing of the attributes has been observed, perhaps with the intent of breaking archive viewers. This
-file is structured as follows:
-
-00h: int32 Version : Specifies the extended attributes format version. For now, must be 100.
-04h: int32 AttributesPresent : Bit mask of the extended attributes present in the archive:
- 00000001h: File CRC32s.
- 00000002h: File timestamps.
- 00000004h: File MD5s.
-08h: int32(BlockTableEntries) CRC32s : CRC32s of the (uncompressed) file data for each block in the archive. Omitted if the
-archive does not have CRC32s. immediately after CRC32s: FILETIME(BlockTableEntries) Timestamps : Timestamps for each block
-in the archive. The format is that of the Windows FILETIME structure. Omitted if the archive does not have timestamps.
-immediately after Timestamps: MD5(BlockTableEntries) MD5s : MD5s of the (uncompressed) file data for each block in the archive.
-Omitted if the archive does not have MD5s.
-
-2.8 WEAK DIGITAL SIGNATURE
-The weak digital signature is a digital signature using Microsoft CryptoAPI. It is an implimentation of the RSASSA-PKCS1-v1_5
-digital signature protocol, using the MD5 hashing algorithm and a 512-bit (weak) RSA key (for more information about this
-protocol, see the RSA Labs PKCS1 specification). The public key and exponent are stored in a resource in Storm. The signature
-is stored uncompressed, unencrypted in the file "(signature)" in the archive. The archive is hashed from the beginning of the
-archive (ArchiveOffset in the containing file) to the end of the archive (the length indicated by ArchiveSize); the signature
-file is added to the archive before signing, and the space occupied by the file is considered to be all binary 0s during
-signing/verification. This file is structured as follows:
-
-00h: int32 Unknown : Must be 0.
-04h: int32 Unknown : must be 0.
-08h: int512 Signature : The digital signature. Like all other numbers in the MoPaQ format, this is stored in little-endian order.
-
-2.9 STRONG DIGITAL SIGNATURE
-The strong digital signature uses a simple proprietary implementation of RSA signing, using the SHA-1 hashing algorithm and
-a 2048-bit (strong) RSA key. The default public key and exponent are stored in Storm, but other keys may be used as well.
-The strong digital signature is stored immediately after the archive, in the containing file; the entire archive (ArchiveSize
-bytes, starting at ArchiveOffset in the containing file) is hashed as a single block. The signature has the following format:
-
-00h: char(4) Magic : Indicates the presence of a digital signature. Must be "NGIS" ("SIGN" backwards).
-04h: int2048 Signature : The digital signature, stored in little-endian format.
-
-When the Signature field is decrypted with the public key and exponent, and the result stored in little-endian order, it is structured as follows:
-
-00h: byte Padding : Must be 0Bh.
-01h: byte(235) Padding : Must be BBh.
-ECh: byte(20) SHA-1 : SHA-1 hash of the archive, in standard SHA-1 format.
-
-3. ALGORITHM SOURCE CODE
-3.1 ENCRYPTION/DECRYPTION
-I believe this was derived at some point from code in StormLib. Assumes the long type to be 32 bits, and the machine to be little endian order.
-
-unsigned long dwCryptTable[0x500];
-
-void InitializeCryptTable()
-{
- unsigned long seed = 0x00100001;
- unsigned long index1 = 0;
- unsigned long index2 = 0;
- int i;
-
- for (index1 = 0; index1 < 0x100; index1++)
- {
- for (index2 = index1, i = 0; i < 5; i++, index2 += 0x100)
- {
- unsigned long temp1, temp2;
-
- seed = (seed * 125 + 3) % 0x2AAAAB;
- temp1 = (seed & 0xFFFF) << 0x10;
-
- seed = (seed * 125 + 3) % 0x2AAAAB;
- temp2 = (seed & 0xFFFF);
-
- dwCryptTable[index2] = (temp1 | temp2);
- }
- }
-}
-
-void EncryptData(void *lpbyBuffer, unsigned long dwLength, unsigned long dwKey)
-{
- unsigned long *lpdwBuffer = (unsigned long *)lpbyBuffer;
- unsigned long seed = 0xEEEEEEEE;
- unsigned long ch;
-
- assert(lpbyBuffer);
-
- dwLength /= sizeof(unsigned long);
-
- while(dwLength-- > 0)
- {
- seed += dwCryptTable[0x400 + (dwKey & 0xFF)];
- ch = *lpdwBuffer ^ (dwKey + seed);
-
- dwKey = ((~dwKey << 0x15) + 0x11111111) | (dwKey >> 0x0B);
- seed = *lpdwBuffer + seed + (seed << 5) + 3;
-
- *lpdwBuffer++ = ch;
- }
-}
-
-void DecryptData(void *lpbyBuffer, unsigned long dwLength, unsigned long dwKey)
-{
- unsigned long *lpdwBuffer = (unsigned long *)lpbyBuffer;
- unsigned long seed = 0xEEEEEEEE;
- unsigned long ch;
-
- assert(lpbyBuffer);
-
- dwLength /= sizeof(unsigned long);
-
- while(dwLength-- > 0)
- {
- seed += dwCryptTable[0x400 + (dwKey & 0xFF)];
- ch = *lpdwBuffer ^ (dwKey + seed);
-
- dwKey = ((~dwKey << 0x15) + 0x11111111) | (dwKey >> 0x0B);
- seed = ch + seed + (seed << 5) + 3;
-
- *lpdwBuffer++ = ch;
- }
-}
-
-3.2 HASHING
-Based on code from StormLib.
-
-// Different types of hashes to make with HashString
-#define MPQ_HASH_TABLE_OFFSET 0
-#define MPQ_HASH_NAME_A 1
-#define MPQ_HASH_NAME_B 2
-#define MPQ_HASH_FILE_KEY 3
-
-unsigned long HashString(const char *lpszString, unsigned long dwHashType)
-{
- unsigned long seed1 = 0x7FED7FED;
- unsigned long seed2 = 0xEEEEEEEE;
- int ch;
-
- while (*lpszString != 0)
- {
- ch = toupper(*lpszString++);
-
- seed1 = dwCryptTable[(dwHashType * 0xFF) + ch] ^ (seed1 + seed2);
- seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;
- }
- return seed1;
-}
-
-3.3 CONVERSION OF FILETIME AND time_t
-
-#define EPOCH_OFFSET 116444736000000000ULL // Number of 100 ns units between 01/01/1601 and 01/01/1970
-
-bool GetTimeFromFileTime(FILETIME &fileTime, time_t &time)
-{
- // The FILETIME represents a 64-bit integer: the number of 100 ns units since January 1, 1601
- unsigned long long nTime = ((unsigned long long)fileTime.dwHighDateTime << 32) + fileTime.dwLowDateTime;
-
- if (nTime < EPOCH_OFFSET)
- return false;
-
- nTime -= EPOCH_OFFSET; // Convert the time base from 01/01/1601 to 01/01/1970
- nTime /= 10000000ULL; // Convert 100 ns to sec
-
- time = (time_t)nTime;
-
- // Test for overflow (FILETIME is 64 bits, time_t is 32 bits)
- if ((nTime - (unsigned long long)time) > 0)
- return false;
-
- return true;
-}
-
-void GetFileTimeFromTime(time_t &time, FILETIME &fileTime)
-{
- unsigned long long nTime = (unsigned long long)time;
-
- nTime *= 10000000ULL;
- nTime += EPOCH_OFFSET;
-
- fileTime.dwLowDateTime = (DWORD)nTime;
- fileTime.dwHighDateTime = (DWORD)(nTime >> 32);
-}
diff --git a/dep/StormLib/doc/The MoPaQ File Format 1.0.txt b/dep/StormLib/doc/The MoPaQ File Format 1.0.txt
deleted file mode 100644
index 2f139453e0e..00000000000
--- a/dep/StormLib/doc/The MoPaQ File Format 1.0.txt
+++ /dev/null
@@ -1,433 +0,0 @@
-THE MOPAQ ARCHIVE FORMAT
-v1.0 (Friday, September 1, 2006)
-by Justin Olbrantz(Quantam)
-
-Distribution and reproduction of this specification are allowed without limitation, as long as it is not altered. Quotation in other works is freely allowed, as long as the source and author of the quote are stated.
-
-TABLE OF CONTENTS
-1. Introduction to the MoPaQ Format
-2. The MoPaQ Format
- 2.1 General Archive Layout
- 2.2 Archive Header
- 2.3 Block Table
- 2.4 Extended Block Table
- 2.5 Hash Table
- 2.6 File Data
- 2.7 Listfile
- 2.8 Extended Attributes
- 2.9 Weak (Old) Digital Signature
- 2.10 Strong (New) Digital Signature
-3. Algorithm Source Code
- 3.1 Encryption/Decryption
- 3.2 Hashing and File Key Computation
- 3.3 Finding Files
- 3.4 Deleting Files
- 3.5 Conversion of FILETIME and time_t
- 3.6 Forming a 64-bit Large Archive Offset from 32-bit and 16-bit Components
-4. Revision History
-
-1. INTRODUCTION TO THE MOPAQ FORMAT
-The MoPaQ (or MPQ) format is an archive file format designed by Mike O'Brien (hence the name Mike O'brien PaCK) at Blizzard Entertainment. The format has been used in all Blizzard games since (and including) Diablo. It is heavily optimized to be a read-only game archive format, and excels at this role.
-
-The Blizzard MoPaQ-reading functions are contained in the Storm module, which my be either statically or dynamically linked. The Blizzard MoPaQ-writing functions are contained in the MPQAPI module, which is always statically linked.
-
-StormLib - mentioned several times in this specification - is an open-source MoPaQ reading and writing library written by Ladislav Zezula (no affiliation with Blizzard Entertainment). While it's a bit dated, and does not support all of the newer MoPaQ features, it contains source code to the more exotic compression methods used by MoPaQ, such as the PKWare implode algorithm, MoPaQ's huffman compression algorithm, and the IMA ADPCM compression used by MoPaQ.
-
-2. THE MOPAQ FORMAT
-All numbers in the MoPaQ format are in little endian byte order; signed numbers use the two's complement system. Data types are listed either as int (integer, the number of bits specified), byte (8 bits), or char (bytes which contain ASCII characters). All sizes and offsets are in bytes, unless specified otherwise. Structure members are listed in the following general form:
-offset from the beginning of the structure: data type(array size) member name : member description
-
-2.1 GENERAL ARCHIVE LAYOUT
-- Archive Header
-- File Data
-- File Data - Special Files
-- Hash Table
-- Block Table
-- Extended Block Table
-- Strong Digital signature
-
-This is the usual archive format, but it is not mandatory. Some archives have been observed placing the hash table and file table after the archive header, and before the file data.
-
-2.2 ARCHIVE HEADER
-00h: char(4) Magic : Indicates that the file is a MoPaQ archive. Must be ASCII "MPQ" 1Ah.
-04h: int32 HeaderSize : Size of the archive header.
-08h: int32 ArchiveSize : Size of the whole archive, including the header. Does not include the strong digital signature, if present. This size is used, among other things, for determining the region to hash in computing the digital signature. This field is deprecated in the Burning Crusade MoPaQ format, and the size of the archive is calculated as the size from the beginning of the archive to the end of the hash table, block table, or extended block table (whichever is largest).
-0Ch: int16 FormatVersion : MoPaQ format version. MPQAPI will not open archives where this is negative. Known versions:
- 0000h: Original format. HeaderSize should be 20h, and large archives are not supported.
- 0001h: Burning Crusade format. Header size should be 2Ch, and large archives are supported.
-0Eh: int8 SectorSizeShift : Power of two exponent specifying the number of 512-byte disk sectors in each logical sector in the archive. The size of each logical sector in the archive is 512 * 2^SectorSizeShift. Bugs in the Storm library dictate that this should always be 3 (4096 byte sectors).
-10h: int32 HashTableOffset : Offset to the beginning of the hash table, relative to the beginning of the archive.
-14h: int32 BlockTableOffset : Offset to the beginning of the block table, relative to the beginning of the archive.
-18h: int32 HashTableEntries : Number of entries in the hash table. Must be a power of two, and must be less than 2^16 for the original MoPaQ format, or less than 2^20 for the Burning Crusade format.
-1Ch: int32 BlockTableEntries : Number of entries in the block table.
-Fields only present in the Burning Crusade format and later:
-20h: int64 ExtendedBlockTableOffset : Offset to the beginning of the extended block table, relative to the beginning of the archive.
-28h: int16 HashTableOffsetHigh : High 16 bits of the hash table offset for large archives.
-2Ah: int16 BlockTableOffsetHigh : High 16 bits of the block table offset for large archives.
-
-The archive header is the first structure in the archive, at archive offset 0; however, the archive does not need to be at offset 0 of the containing file. The offset of the archive in the file is referred to here as ArchiveOffset. If the archive is not at the beginning of the file, it must begin at a disk sector boundary (512 bytes). Early versions of Storm require that the archive be at the end of the containing file (ArchiveOffset + ArchiveSize = file size), but this is not required in newer versions (due to the strong digital signature not being considered a part of the archive).
-
-2.3 BLOCK TABLE
-The block table contains entries for each region in the archive. Regions may be either files, empty space, which may be overwritten by new files (typically this space is from deleted file data), or unused block table entries. Empty space entries should have BlockOffset and BlockSize nonzero, and FileSize and Flags zero; unused block table entries should have BlockSize, FileSize, and Flags zero. The block table is encrypted, using the hash of "(block table)" as the key. Each entry is structured as follows:
-
-00h: int32 BlockOffset : Offset of the beginning of the block, relative to the beginning of the archive.
-04h: int32 BlockSize : Size of the block in the archive.
-08h: int32 FileSize : Size of the file data stored in the block. Only valid if the block is a file; otherwise meaningless, and should be 0. If the file is compressed, this is the size of the uncompressed file data.
-0Ch: int32 Flags : Bit mask of the flags for the block. The following values are conclusively identified:
- 80000000h: Block is a file, and follows the file data format; otherwise, block is free space or unused. If the block is not a file, all other flags should be cleared, and FileSize should be 0.
- 01000000h: File is stored as a single unit, rather than split into sectors.
- 00020000h: The file's encryption key is adjusted by the block offset and file size (explained in detail in the File Data section). File must be encrypted.
- 00010000h: File is encrypted.
- 00000200h: File is compressed. File cannot be imploded.
- 00000100h: File is imploded. File cannot be compressed.
-
-2.4 EXTENDED BLOCK TABLE
-The extended block table was added to support archives larger than 4 gigabytes (2^32 bytes). The table contains the upper bits of the archive offsets for each block in the block table. It is simply an array of int16s, which become bits 32-47 of the archive offsets for each block, with bits 48-63 being zero. Individual blocks in the archive are still limited to 4 gigabytes in size. This table is only present in Burning Crusade format archives that exceed 4 gigabytes size.
-
-As of the Burning Crusade Friends and Family beta, this table is not encrypted.
-
-2.5 HASH TABLE
-Instead of storing file names, for quick access MoPaQs use a fixed, power of two-size hash table of files in the archive. A file is uniquely identified by its file path, its language, and its platform. The home entry for a file in the hash table is computed as a hash of the file path. In the event of a collision (the home entry is occupied by another file), progressive overflow is used, and the file is placed in the next available hash table entry. Searches for a desired file in the hash table proceed from the home entry for the file until either the file is found, the entire hash table is searched, or an empty hash table entry (FileBlockIndex of FFFFFFFFh) is encountered. The hash table is encrypted using the hash of "(hash table)" as the key. Each entry is structured as follows:
-
-00h: int32 FilePathHashA : The hash of the file path, using method A.
-04h: int32 FilePathHashB : The hash of the file path, using method B.
-08h: int16 Language : The language of the file. This is a Windows LANGID data type, and uses the same values. 0 indicates the default language (American English), or that the file is language-neutral.
-0Ah: int8 Platform : The platform the file is used for. 0 indicates the default platform. No other values have been observed.
-0Ch: int32 FileBlockIndex : If the hash table entry is valid, this is the index into the block table of the file. Otherwise, one of the following two values:
- FFFFFFFFh: Hash table entry is empty, and has always been empty. Terminates searches for a given file.
- FFFFFFFEh: Hash table entry is empty, but was valid at some point (in other words, the file was deleted). Does not terminate searches for a given file.
-
-2.6 FILE DATA
-The data for each file is composed of the following structure:
-00h: int32(SectorsInFile + 1) SectorOffsetTable : Offsets to the start of each sector, relative to the beginning of the file data. The last entry contains the file size, making it possible to easily calculate the size of any given sector. This table is not present if this information can be calculated (see details below).
-immediately following SectorOffsetTable: SECTOR Sectors(SectorsInFile) : Data of each sector in the file, packed end to end (see details below).
-
-Normally, file data is split up into sectors, for simple streaming. All sectors, save for the last, will contain as many bytes of file data as specified in the archive header's SectorSizeShift; the last sector may contain less than this, depending on the size of the entire file's data. If the file is compressed or imploded, the sector will be smaller or the same size as the file data it contains. Individual sectors in a compressed or imploded file may be stored uncompressed; this occurs if and only if the file data the sector contains could not be compressed by the algorithm(s) used (if the compressed sector size was greater than or equal to the size of the file data), and is indicated by the sector's size in SectorOffsetTable being equal to the size of the file data in the sector (which may be calculated from the FileSize).
-
-The format of each sector depends on the kind of sector it is. Uncompressed sectors are simply the the raw file data contained in the sector. Imploded sectors are the raw compressed data following compression with the implode algorithm (these sectors can only be in imploded files). Compressed sectors (only found in compressed - not imploded - files) are compressed with one or more compression algorithms, and have the following structure:
-00h: byte CompressionMask : Mask of the compression types applied to this sector. If multiple compression types are used, they are applied in the order listed below, and decompression is performed in the opposite order. This byte counts towards the total sector size, meaning that the sector will be stored uncompressed if the data cannot be compressed by at least two bytes; as well, this byte is encrypted with the sector data, if applicable. The following compression types are defined (for implementations of these algorithms, see StormLib):
- 40h: IMA ADPCM mono
- 80h: IMA ADPCM stereo
- 01h: Huffman encoded
- 02h: Deflated (see ZLib)
- 08h: Imploded (see PKWare Data Compression Library)
- 10h: BZip2 compressed (see BZip2)
-01h: byte(SectorSize - 1) SectorData : The compressed data for the sector.
-
-If the file is stored as a single unit (indicated in the file's Flags), there is effectively only a single sector, which contains the entire file data.
-
-If the file is encrypted, each sector (after compression/implosion, if applicable) is encrypted with the file's key. The base key for a file is determined by a hash of the file name stripped of the directory (i.e. the key for a file named "directory\file" would be computed as the hash of "file"). If this key is adjusted, as indicated in the file's Flags, the final key is calculated as ((base key + BlockOffset - ArchiveOffset) XOR FileSize) (StormLib incorrectly uses an AND in place of the XOR). Each sector is encrypted using the key + the 0-based index of the sector in the file. The SectorOffsetTable, if present, is encrypted using the key - 1.
-
-The SectorOffsetTable is omitted when the sizes and offsets of all sectors in the file are calculatable from the FileSize. This can happen in several circumstances. If the file is not compressed/imploded, then the size and offset of all sectors is known, based on the archive's SectorSizeShift. If the file is stored as a single unit compressed/imploded, then the SectorOffsetTable is omitted, as the single file "sector" corresponds to BlockSize and FileSize, as mentioned previously. However, the SectorOffsetTable will be present if the file is compressed/imploded and the file is not stored as a single unit, even if there is only a single sector in the file (the size of the file is less than or equal to the archive's sector size).
-
-2.7 LISTFILE
-The listfile is a very simple extension to the MoPaQ format that contains the file paths of (most) files in the archive. The languages and platforms of the files are not stored in the listfile. The listfile is contained in the file "(listfile)" (default language and platform), and is simply a text file with file paths separated by ';', 0Dh, 0Ah, or some combination of these. The file "(listfile)" may not be listed in the listfile.
-
-2.8 EXTENDED ATTRIBUTES
-The extended attributes are optional file attributes for files in the block table. These attributes were added at times after the MoPaQ format was already finalized, and it is not necessary for every archive to have all (or any) of the extended attributes. If an archive contains a given attribute, there will be an instance of that attribute for every block in the block table, although the attribute will be meaningless if the block is not a file. The order of the attributes for blocks correspond to the order of the blocks in the block table, and are of the same number. The attributes are stored in parallel arrays in the "(attributes)" file (default language and platform), in the archive. The attributes corresponding to this file need not be valid (and logically cannot be). Unlike all the other structures in the MoPaQ format, entries in the extended attributes are NOT guaranteed to be aligned. Also note that in some archives, malicious zeroing of the attributes has been observed, perhaps with the intent of breaking archive viewers. This file is structured as follows:
-
-00h: int32 Version : Specifies the extended attributes format version. For now, must be 100.
-04h: int32 AttributesPresent : Bit mask of the extended attributes present in the archive:
- 00000001h: File CRC32s.
- 00000002h: File timestamps.
- 00000004h: File MD5s.
-08h: int32(BlockTableEntries) CRC32s : CRC32s of the (uncompressed) file data for each block in the archive. Omitted if the archive does not have CRC32s.
-immediately after CRC32s: FILETIME(BlockTableEntries) Timestamps : Timestamps for each block in the archive. The format is that of the Windows FILETIME structure. Omitted if the archive does not have timestamps.
-immediately after Timestamps: MD5(BlockTableEntries) MD5s : MD5s of the (uncompressed) file data for each block in the archive. Omitted if the archive does not have MD5s.
-
-2.9 WEAK DIGITAL SIGNATURE
-The weak digital signature is a digital signature using Microsoft CryptoAPI. It is an implimentation
-of the RSASSA-PKCS1-v1_5 digital signature protocol, using the MD5 hashing algorithm and a 512-bit (weak)
-RSA key (for more information about this protocol, see the RSA Labs PKCS1 specification). The public key
-and exponent are stored in a resource in Storm, the private key is stored in a separate file, whose filename
-is passed to MPQAPI (the private key is not stored in MPQAPI). The signature is stored uncompressed,
-unencrypted in the file "(signature)" (default language and platform) in the archive. The archive
-is hashed from the beginning of the archive (ArchiveOffset in the containing file) to the end of
-the archive (the length indicated by ArchiveSize, or calculated in the Burning Crusade MoPaQ format);
-the signature file is added to the archive before signing, and the space occupied by the file is considered
-to be all binary 0s during signing/verification. This file is structured as follows:
-
-00h: int32 Unknown : Must be 0.
-04h: int32 Unknown : Must be 0.
-08h: int512 Signature : The digital signature. Like all other numbers in the MoPaQ format, this is stored
-in little-endian order. The structure of this, when decrypted, follows the RSASSA-PKCS1-v1_5 specification;
-this format is rather icky to work with (I wrote a program to verify this signature using nothing but an MD5
-function and huge integer functions; it wasn't pleasant), and best left to an encryption library such as Cryto++.
-
-2.10 STRONG DIGITAL SIGNATURE
-The strong digital signature uses a simple proprietary implementation of RSA signing, using the SHA-1 hashing algorithm and a 2048-bit (strong) RSA key. The default public key and exponent are stored in Storm, but other keys may be used as well. The strong digital signature is stored immediately after the archive, in the containing file; the entire archive (ArchiveSize bytes, starting at ArchiveOffset in the containing file) is hashed as a single block. The signature has the following format:
-
-00h: char(4) Magic : Indicates the presence of a digital signature. Must be "NGIS" ("SIGN" backwards).
-04h: int2048 Signature : The digital signature, stored in little-endian format.
-
-When the Signature field is decrypted with the public key and exponent, and the resulting large integer is stored in little-endian order, it is structured as follows:
-
-00h: byte Padding : Must be 0Bh.
-01h: byte(235) Padding : Must be BBh.
-ECh: byte(20) SHA-1 : SHA-1 hash of the archive, in standard SHA-1 byte order.
-
-3. ALGORITHM SOURCE CODE
-All of the sample code here assumes little endian machine byte order, that the short type is 16 bits, that the long type is 32 bits, and that the long long type is 64 bits. Adjustments must be made if these assumptions are not correct on a given platform. All code not credited otherwise was written by myself in the writing of this specification.
-
-3.1 ENCRYPTION/DECRYPTION
-Based on code from StormLib.
-
-unsigned long dwCryptTable[0x500];
-
-// The encryption and hashing functions use a number table in their procedures. This table must be initialized before the functions are called the first time.
-void InitializeCryptTable()
-{
- unsigned long seed = 0x00100001;
- unsigned long index1 = 0;
- unsigned long index2 = 0;
- int i;
-
- for (index1 = 0; index1 < 0x100; index1++)
- {
- for (index2 = index1, i = 0; i < 5; i++, index2 += 0x100)
- {
- unsigned long temp1, temp2;
-
- seed = (seed * 125 + 3) % 0x2AAAAB;
- temp1 = (seed & 0xFFFF) << 0x10;
-
- seed = (seed * 125 + 3) % 0x2AAAAB;
- temp2 = (seed & 0xFFFF);
-
- dwCryptTable[index2] = (temp1 | temp2);
- }
- }
-}
-
-void EncryptData(void *lpbyBuffer, unsigned long dwLength, unsigned long dwKey)
-{
- assert(lpbyBuffer);
-
- unsigned long *lpdwBuffer = (unsigned long *)lpbyBuffer;
- unsigned long seed = 0xEEEEEEEE;
- unsigned long ch;
-
- dwLength /= sizeof(unsigned long);
-
- while(dwLength-- > 0)
- {
- seed += dwCryptTable[0x400 + (dwKey & 0xFF)];
- ch = *lpdwBuffer ^ (dwKey + seed);
-
- dwKey = ((~dwKey << 0x15) + 0x11111111) | (dwKey >> 0x0B);
- seed = *lpdwBuffer + seed + (seed << 5) + 3;
-
- *lpdwBuffer++ = ch;
- }
-}
-
-void DecryptData(void *lpbyBuffer, unsigned long dwLength, unsigned long dwKey)
-{
- assert(lpbyBuffer);
-
- unsigned long *lpdwBuffer = (unsigned long *)lpbyBuffer;
- unsigned long seed = 0xEEEEEEEEL;
- unsigned long ch;
-
- dwLength /= sizeof(unsigned long);
-
- while(dwLength-- > 0)
- {
- seed += dwCryptTable[0x400 + (dwKey & 0xFF)];
- ch = *lpdwBuffer ^ (dwKey + seed);
-
- dwKey = ((~dwKey << 0x15) + 0x11111111L) | (dwKey >> 0x0B);
- seed = ch + seed + (seed << 5) + 3;
-
- *lpdwBuffer++ = ch;
- }
-}
-
-3.2 HASHING AND FILE KEY COMPUTATION
-These functions may have been derived from StormLib code at some point in the very distant past. It was so long ago that I don't remember for certain.
-
-// Different types of hashes to make with HashString
-#define MPQ_HASH_TABLE_OFFSET 0
-#define MPQ_HASH_NAME_A 1
-#define MPQ_HASH_NAME_B 2
-#define MPQ_HASH_FILE_KEY 3
-
-// Based on code from StormLib.
-unsigned long HashString(const char *lpszString, unsigned long dwHashType)
-{
- assert(lpszString);
- assert(dwHashType <= MPQ_HASH_FILE_KEY);
-
- unsigned long seed1 = 0x7FED7FEDL;
- unsigned long seed2 = 0xEEEEEEEEL;
- int ch;
-
- while (*lpszString != 0)
- {
- ch = toupper(*lpszString++);
-
- seed1 = dwCryptTable[(dwHashType * 0x100) + ch] ^ (seed1 + seed2);
- seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;
- }
- return seed1;
-}
-
-#define BLOCK_OFFSET_ADJUSTED_KEY 0x00020000L
-
-unsigned long ComputeFileKey(const char *lpszFilePath, const BlockTableEntry &blockEntry, unsigned long nArchiveOffset)
-{
- assert(lpszFilePath);
-
- // Find the file name part of the path
- const char *lpszFileName = strrchr(lpszFilePath, '\\');
- if (lpszFileName)
- lpszFileName++; // Skip the \
- else
- lpszFileName = lpszFilePath;
-
- // Hash the name to get the base key
- unsigned long nFileKey = HashString(lpszFileName, MPQ_HASH_FILE_KEY);
-
- // Offset-adjust the key if necessary
- if (blockEntry.Flags & BLOCK_OFFSET_ADJUSTED_KEY)
- nFileKey = (nFileKey + blockEntry.BlockOffset) ^ blockEntry.FileSize;
-
- return nFileKey;
-}
-
-3.3 FINDING FILES
-
-#define MPQ_HASH_ENTRY_EMPTY 0xFFFFFFFFL
-#define MPQ_HASH_ENTRY_DELETED 0xFFFFFFFEL
-
-bool FindFileInHashTable(const HashTableEntry *lpHashTable, unsigned long nHashTableSize, const char *lpszFilePath, unsigned short nLang, unsigned char nPlatform, unsigned long &iFileHashEntry)
-{
- assert(lpHashTable);
- assert(nHashTableSize);
- assert(lpszFilePath);
-
- // Find the home entry in the hash table for the file
- unsigned long iInitEntry = HashString(lpszFilePath, MPQ_HASH_TABLE_OFFSET) & (nHashTableSize - 1);
-
- // Is there anything there at all?
- if (lpHashTable[iInitEntry].FileBlockIndex == MPQ_HASH_ENTRY_EMPTY)
- return false;
-
- // Compute the hashes to compare the hash table entry against
- unsigned long nNameHashA = HashString(lpszFilePath, MPQ_HASH_NAME_A),
- nNameHashB = HashString(lpszFilePath, MPQ_HASH_NAME_B),
- iCurEntry = iInitEntry;
-
- // Check each entry in the hash table till a termination point is reached
- do
- {
- if (lpHashTable[iCurEntry].FileBlockIndex != MPQ_HASH_ENTRY_DELETED)
- {
- if (lpHashTable[iCurEntry].FilePathHashA == nNameHashA
- && lpHashTable[iCurEntry].FilePathHashB == nNameHashB
- && lpHashTable[iCurEntry].Language == nLang
- && lpHashTable[iCurEntry].Platform == nPlatform)
- {
- iFileHashEntry = iCurEntry;
-
- return true;
- }
- }
-
- iCurEntry = (iCurEntry + 1) & (nHashTableSize - 1);
- } while (iCurEntry != iInitEntry && lpHashTable[iCurEntry].FileBlockIndex != MPQ_HASH_ENTRY_EMPTY);
-
- return false;
-}
-
-3.4 DELETING FILES
-
-bool DeleteFile(HashTableEntry *lpHashTable, unsigned long nHashTableSize, BlockTableEntry *lpBlockTable, const char *lpszFilePath, unsigned short nLang, unsigned char nPlatform)
-{
- assert(lpHashTable);
- assert(nHashTableSize);
- assert(lpBlockTable);
-
- // Find the file in the hash table
- unsigned long iFileHashEntry;
-
- if (!FindFileInHashTable(lpHashTable, nHashTableSize, lpszFilePath, nLang, nPlatform, iFileHashEntry))
- return false;
-
- // Get the block table index before we nuke the hash table entry
- unsigned long iFileBlockEntry = lpHashTable[iFileHashEntry].FileBlockIndex;
-
- // Delete the file's entry in the hash table
- memset(&lpHashTable[iFileHashEntry], 0xFF, sizeof(HashTableEntry));
-
- // If the next entry is empty, mark this one as empty; otherwise, mark this as deleted.
- if (lpHashTable[(iFileHashEntry + 1) & (nHashTableSize - 1)].FileBlockIndex == MPQ_HASH_ENTRY_EMPTY)
- lpHashTable[iFileHashEntry].FileBlockIndex = MPQ_HASH_ENTRY_EMPTY;
- else
- lpHashTable[iFileHashEntry].FileBlockIndex = MPQ_HASH_ENTRY_DELETED;
-
- // If the block occupies space, mark the block as free space; otherwise, clear the block table entry.
- if (lpBlockTable[iFileBlockEntry].BlockSize > 0)
- {
- lpBlockTable[iFileBlockEntry].FileSize = 0;
- lpBlockTable[iFileBlockEntry].Flags = 0;
- }
- else
- memset(&lpBlockTable[iFileBlockEntry], 0, sizeof(BlockTableEntry);
-
- return true;
-}
-
-3.5 CONVERSION OF FILETIME AND time_t
-This code assumes that the base ("zero") date for time_t is 01/01/1970. This is true on Windows, Unix System V systems, and Mac OS X. It is unknown whether this is true on all other platforms. You'll need to research this yourself, if you plan on porting it somewhere else.
-
-#define EPOCH_OFFSET 116444736000000000ULL // Number of 100 ns units between 01/01/1601 and 01/01/1970
-
-bool GetTimeFromFileTime(const FILETIME &fileTime, time_t &time)
-{
- // The FILETIME represents a 64-bit integer: the number of 100 ns units since January 1, 1601
- unsigned long long nTime = ((unsigned long long)fileTime.dwHighDateTime << 32) + fileTime.dwLowDateTime;
-
- if (nTime < EPOCH_OFFSET)
- return false;
-
- nTime -= EPOCH_OFFSET; // Convert the time base from 01/01/1601 to 01/01/1970
- nTime /= 10000000ULL; // Convert 100 ns to sec
-
- time = (time_t)nTime;
-
- // Test for overflow (FILETIME is 64 bits, time_t is 32 bits)
- if ((nTime - (unsigned long long)time) > 0)
- return false;
-
- return true;
-}
-
-void GetFileTimeFromTime(const time_t &time, FILETIME &fileTime)
-{
- unsigned long long nTime = (unsigned long long)time;
-
- nTime *= 10000000ULL;
- nTime += EPOCH_OFFSET;
-
- fileTime.dwLowDateTime = (DWORD)nTime;
- fileTime.dwHighDateTime = (DWORD)(nTime >> 32);
-}
-
-3.6 FORMING A 64-BIT LARGE ARCHIVE OFFSET FROM 32-BIT AND 16-BIT COMPONENTS
-unsigned long long MakeLargeArchiveOffset(unsigned long nOffsetLow, unsigned short nOffsetHigh)
-{
- return ((unsigned long long)nOffsetHigh << 32) + (unsigned long long)nOffsetLow;
-}
-
-4. REVISION HISTORY
-1.0
- - Updated to include most of the changes found in the Burning Crusade Friends and Family beta
-
-0.91.
- - Updated several structure member descriptions
- - Listed the full set of characters that can separate list file entries
- - Noted that (attributes), (listfile), and (signature) use the default language and platform codes
- - Redid part of the file data specs to clarify the format of sectors
- - Enhanced descriptions of the different kinds of block table entries
- - Added ComputeFileKey, FindFileInHashTable, and DeleteFile source \ No newline at end of file
diff --git a/dep/StormLib/doc/d3-authenticationcode-deDE.txt b/dep/StormLib/doc/d3-authenticationcode-deDE.txt
deleted file mode 100644
index cac66712af0..00000000000
--- a/dep/StormLib/doc/d3-authenticationcode-deDE.txt
+++ /dev/null
@@ -1 +0,0 @@
-UCMXF6EJY352EFH4XFRXCFH2XC9MQRZK \ No newline at end of file
diff --git a/dep/StormLib/doc/d3-authenticationcode-enGB.txt b/dep/StormLib/doc/d3-authenticationcode-enGB.txt
deleted file mode 100644
index 2bc9c83859d..00000000000
--- a/dep/StormLib/doc/d3-authenticationcode-enGB.txt
+++ /dev/null
@@ -1 +0,0 @@
-MMKVHY48RP7WXP4GHYBQ7SL9J9UNPHBP \ No newline at end of file
diff --git a/dep/StormLib/doc/d3-authenticationcode-enSG.txt b/dep/StormLib/doc/d3-authenticationcode-enSG.txt
deleted file mode 100644
index e6f1ec29609..00000000000
--- a/dep/StormLib/doc/d3-authenticationcode-enSG.txt
+++ /dev/null
@@ -1 +0,0 @@
-8MXLWHQ7VGGLTZ9MQZQSFDCLJYET3CPP \ No newline at end of file
diff --git a/dep/StormLib/doc/d3-authenticationcode-enUS.txt b/dep/StormLib/doc/d3-authenticationcode-enUS.txt
deleted file mode 100644
index 8d73e61def9..00000000000
--- a/dep/StormLib/doc/d3-authenticationcode-enUS.txt
+++ /dev/null
@@ -1 +0,0 @@
-EJ2R5TM6XFE2GUNG5QDGHKQ9UAKPWZSZ \ No newline at end of file
diff --git a/dep/StormLib/doc/d3-authenticationcode-esES.txt b/dep/StormLib/doc/d3-authenticationcode-esES.txt
deleted file mode 100644
index 6b1b0a1b811..00000000000
--- a/dep/StormLib/doc/d3-authenticationcode-esES.txt
+++ /dev/null
@@ -1 +0,0 @@
-PBGFBE42Z6LNK65UGJQ3WZVMCLP4HQQT \ No newline at end of file
diff --git a/dep/StormLib/doc/d3-authenticationcode-esMX.txt b/dep/StormLib/doc/d3-authenticationcode-esMX.txt
deleted file mode 100644
index 504759e8d55..00000000000
--- a/dep/StormLib/doc/d3-authenticationcode-esMX.txt
+++ /dev/null
@@ -1 +0,0 @@
-X7SEJJS9TSGCW5P28EBSC47AJPEY8VU2 \ No newline at end of file
diff --git a/dep/StormLib/doc/d3-authenticationcode-frFR.txt b/dep/StormLib/doc/d3-authenticationcode-frFR.txt
deleted file mode 100644
index bb35a2bfdc6..00000000000
--- a/dep/StormLib/doc/d3-authenticationcode-frFR.txt
+++ /dev/null
@@ -1 +0,0 @@
-5KVBQA8VYE6XRY3DLGC5ZDE4XS4P7YA2 \ No newline at end of file
diff --git a/dep/StormLib/doc/d3-authenticationcode-itIT.txt b/dep/StormLib/doc/d3-authenticationcode-itIT.txt
deleted file mode 100644
index a62031d3883..00000000000
--- a/dep/StormLib/doc/d3-authenticationcode-itIT.txt
+++ /dev/null
@@ -1 +0,0 @@
-478JD2K56EVNVVY4XX8TDWYT5B8KB254 \ No newline at end of file
diff --git a/dep/StormLib/doc/d3-authenticationcode-koKR.txt b/dep/StormLib/doc/d3-authenticationcode-koKR.txt
deleted file mode 100644
index 296ffcc9450..00000000000
--- a/dep/StormLib/doc/d3-authenticationcode-koKR.txt
+++ /dev/null
@@ -1 +0,0 @@
-8TS4VNFQRZTN6YWHE9CHVDH9NVWD474A \ No newline at end of file
diff --git a/dep/StormLib/doc/d3-authenticationcode-plPL.txt b/dep/StormLib/doc/d3-authenticationcode-plPL.txt
deleted file mode 100644
index a92563c1815..00000000000
--- a/dep/StormLib/doc/d3-authenticationcode-plPL.txt
+++ /dev/null
@@ -1 +0,0 @@
-LJ52Z32DF4LZ4ZJJXVKK3AZQA6GABLJB \ No newline at end of file
diff --git a/dep/StormLib/doc/d3-authenticationcode-ptBR.txt b/dep/StormLib/doc/d3-authenticationcode-ptBR.txt
deleted file mode 100644
index e6e5c3568d9..00000000000
--- a/dep/StormLib/doc/d3-authenticationcode-ptBR.txt
+++ /dev/null
@@ -1 +0,0 @@
-K6BDHY2ECUE2545YKNLBJPVYWHE7XYAG \ No newline at end of file
diff --git a/dep/StormLib/doc/d3-authenticationcode-zhTW.txt b/dep/StormLib/doc/d3-authenticationcode-zhTW.txt
deleted file mode 100644
index 138a5449c7a..00000000000
--- a/dep/StormLib/doc/d3-authenticationcode-zhTW.txt
+++ /dev/null
@@ -1 +0,0 @@
-6VWCQTN8V3ZZMRUCZXV8A8CGUX2TAA8H \ No newline at end of file
diff --git a/dep/StormLib/doc/diablo3_ruru_disk_encrypted_win.blob b/dep/StormLib/doc/diablo3_ruru_disk_encrypted_win.blob
deleted file mode 100644
index 7972b2d7636..00000000000
--- a/dep/StormLib/doc/diablo3_ruru_disk_encrypted_win.blob
+++ /dev/null
@@ -1,49 +0,0 @@
-{
-"config":{
- "product": "D3",
- "install_progress_percent": 70.0,
- "install_progress_info": [8000000000.0, 0.0, 0.0],
- "download_progress_info": [10000000.0, 500000000.0, 500000000.0],
- "install_progress_speed": 5000000.0,
- "tome_download_progress_percent": 0.0,
- "updater_product": "d3_patch",
- "expansion_level": 0,
- "ptr": false,
- "beta": false,
- "update_method": "patch on demand",
- "supports_multibox": false,
- "data_dir": "Data_D3/PC/MPQs/",
- "patch_url": "http://ruRU.patch.battle.net:1119/patch",
- "update_regex": "(?P<prefix>d3-update-(?P<dataset>\\w+))-(?P<build>\\d+)\\.mpq$",
- "update_identifier": "d3-update-",
- "torrent_file_path": "Diablo III.tfil",
- "manifest_file_path": "Diablo III.mfil",
- "priority_file_path": "Diablo III.pfil",
- "priority_file_layout": "Retail",
- "binary_version_path": "Diablo III.exe",
- "binary_launch_path": "Diablo III.exe",
- "display_locales":["ruRU"],
- "supported_locales" : ["enUS", "esMX", "ptBR", "enGB", "deDE", "esES", "frFR", "itIT", "plPL", "enSG", "ptPT", "ruRU", "koKR", "zhTW", "zhCN"],
- "launch_arguments":["-launch","-uid","diablo3_ruru"],
- "form": {
- "eula": {
- "eula":false
- },
- "game_dir": {
- "default": "Program Files",
- "dirname": "Diablo III",
- "required_space": 15032385536
- },
- "language": {
- "default":["ruRU"],
- "list":["ruRU"]
- },
- "authentication_key": {
- "url": [
- "http://ruru.nydus.battle.net/D3/ruRU/setup/mediakey",
- "http://dist.blizzard.com/mediakey/d3-authenticationcode-ruRU.txt"
- ]
- }
- }
- }
-} \ No newline at end of file
diff --git a/dep/StormLib/doc/diablo3_urls.txt b/dep/StormLib/doc/diablo3_urls.txt
deleted file mode 100644
index d89f4899528..00000000000
--- a/dep/StormLib/doc/diablo3_urls.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-http://dist.blizzard.com/mediakey/d3-authenticationcode-deDE.txt
-http://dist.blizzard.com/mediakey/d3-authenticationcode-enGB.txt
-http://dist.blizzard.com/mediakey/d3-authenticationcode-enSG.txt
-http://dist.blizzard.com/mediakey/d3-authenticationcode-enUS.txt
-http://dist.blizzard.com/mediakey/d3-authenticationcode-esES.txt
-http://dist.blizzard.com/mediakey/d3-authenticationcode-esMX.txt
-http://dist.blizzard.com/mediakey/d3-authenticationcode-frFR.txt
-http://dist.blizzard.com/mediakey/d3-authenticationcode-itIT.txt
-http://dist.blizzard.com/mediakey/d3-authenticationcode-koKR.txt
-http://dist.blizzard.com/mediakey/d3-authenticationcode-plPL.txt
-http://dist.blizzard.com/mediakey/d3-authenticationcode-ptBR.txt
-http://dist.blizzard.com/mediakey/d3-authenticationcode-ruRU.txt <====
-http://dist.blizzard.com/mediakey/d3-authenticationcode-zhTW.txt
-http://dist.blizzard.com/mediakey/d3-authenticationcode-zhCN.txt <====
diff --git a/dep/StormLib/src/FileStream.cpp b/dep/StormLib/src/FileStream.cpp
deleted file mode 100644
index 413f2acb3a2..00000000000
--- a/dep/StormLib/src/FileStream.cpp
+++ /dev/null
@@ -1,2294 +0,0 @@
-/*****************************************************************************/
-/* FileStream.cpp Copyright (c) Ladislav Zezula 2010 */
-/*---------------------------------------------------------------------------*/
-/* File stream support for StormLib */
-/* */
-/* Windows support: Written by Ladislav Zezula */
-/* Mac support: Written by Sam Wilkins */
-/* Linux support: Written by Sam Wilkins and Ivan Komissarov */
-/* Big-endian: Written & debugged by Sam Wilkins */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 11.06.10 1.00 Lad Derived from StormPortMac.cpp and StormPortLinux.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "StormCommon.h"
-#include "FileStream.h"
-
-#ifdef _MSC_VER
-#pragma comment(lib, "wininet.lib")
-#endif
-
-//-----------------------------------------------------------------------------
-// Local defines
-
-#ifndef INVALID_HANDLE_VALUE
-#define INVALID_HANDLE_VALUE ((HANDLE)-1)
-#endif
-
-#ifdef _MSC_VER
-#pragma warning(disable: 4800) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
-#endif
-
-//-----------------------------------------------------------------------------
-// Local functions - platform-specific functions
-
-#ifndef PLATFORM_WINDOWS
-static int nLastError = ERROR_SUCCESS;
-
-int GetLastError()
-{
- return nLastError;
-}
-
-void SetLastError(int nError)
-{
- nLastError = nError;
-}
-#endif
-
-#ifndef PLATFORM_LITTLE_ENDIAN
-void ConvertPartHeader(void * partHeader)
-{
- PPART_FILE_HEADER theHeader = (PPART_FILE_HEADER)partHeader;
-
- theHeader->PartialVersion = SwapUInt32(theHeader->PartialVersion);
- theHeader->Flags = SwapUInt32(theHeader->Flags);
- theHeader->FileSizeLo = SwapUInt32(theHeader->FileSizeLo);
- theHeader->FileSizeHi = SwapUInt32(theHeader->FileSizeHi);
- theHeader->BlockSize = SwapUInt32(theHeader->BlockSize);
-}
-#endif
-
-//-----------------------------------------------------------------------------
-// Preparing file bitmap for a complete file of a given size
-
-#define DEFAULT_BLOCK_SIZE 0x4000
-
-static bool Dummy_GetBitmap(
- TFileStream * pStream,
- TFileBitmap * pBitmap,
- DWORD Length,
- LPDWORD LengthNeeded)
-{
- ULONGLONG FileSize = 0;
- DWORD TotalLength;
- DWORD BlockCount;
- DWORD BitmapSize;
- DWORD LastByte;
- bool bResult = false;
-
- // Get file size and calculate bitmap length
- FileStream_GetSize(pStream, FileSize);
- BlockCount = (DWORD)(((FileSize - 1) / DEFAULT_BLOCK_SIZE) + 1);
- BitmapSize = (DWORD)(((BlockCount - 1) / 8) + 1);
-
- // Calculate and give the total length
- TotalLength = sizeof(TFileBitmap) + BitmapSize;
- if(LengthNeeded != NULL)
- *LengthNeeded = TotalLength;
-
- // Has the caller given enough space for storing the structure?
- if(Length >= sizeof(TFileBitmap))
- {
- memset(pBitmap, 0, sizeof(TFileBitmap));
- pBitmap->EndOffset = FileSize;
- pBitmap->IsComplete = 1;
- pBitmap->BitmapSize = BitmapSize;
- pBitmap->BlockSize = DEFAULT_BLOCK_SIZE;
- bResult = true;
- }
-
- // Do we have enough space to fill the bitmap as well?
- if(Length >= TotalLength)
- {
- LPBYTE pbBitmap = (LPBYTE)(pBitmap + 1);
-
- // Fill the full blocks
- memset(pbBitmap, 0xFF, (BlockCount / 8));
- pbBitmap += (BlockCount / 8);
- bResult = true;
-
- // Supply the last block
- if(BlockCount & 7)
- {
- LastByte = (1 << (BlockCount & 7)) - 1;
- pbBitmap[0] = (BYTE)LastByte;
- }
- }
-
- return bResult;
-}
-
-//-----------------------------------------------------------------------------
-// Local functions - base file support
-
-static bool BaseFile_Read(
- TFileStream * pStream, // Pointer to an open stream
- ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position
- void * pvBuffer, // Pointer to data to be read
- DWORD dwBytesToRead) // Number of bytes to read from the file
-{
- ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.File.FilePos;
- DWORD dwBytesRead = 0; // Must be set by platform-specific code
-
-#ifdef PLATFORM_WINDOWS
- {
- // Note: StormLib no longer supports Windows 9x.
- // Thus, we can use the OVERLAPPED structure to specify
- // file offset to read from file. This allows us to skip
- // one system call to SetFilePointer
-
- // Update the byte offset
- pStream->Base.File.FilePos = ByteOffset;
-
- // Read the data
- if(dwBytesToRead != 0)
- {
- OVERLAPPED Overlapped;
-
- Overlapped.OffsetHigh = (DWORD)(ByteOffset >> 32);
- Overlapped.Offset = (DWORD)ByteOffset;
- Overlapped.hEvent = NULL;
- if(!ReadFile(pStream->Base.File.hFile, pvBuffer, dwBytesToRead, &dwBytesRead, &Overlapped))
- return false;
- }
-/*
- // If the byte offset is different from the current file position,
- // we have to update the file position
- if(ByteOffset != pStream->Base.File.FilePos)
- {
- LONG ByteOffsetHi = (LONG)(ByteOffset >> 32);
-
- SetFilePointer(pStream->Base.File.hFile, (LONG)ByteOffset, &ByteOffsetHi, FILE_BEGIN);
- pStream->Base.File.FilePos = ByteOffset;
- }
-
- // Read the data
- if(dwBytesToRead != 0)
- {
- if(!ReadFile(pStream->Base.File.hFile, pvBuffer, dwBytesToRead, &dwBytesRead, NULL))
- return false;
- }
-*/
- }
-#endif
-
-#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
- {
- ssize_t bytes_read;
-
- // If the byte offset is different from the current file position,
- // we have to update the file position
- if(ByteOffset != pStream->Base.File.FilePos)
- {
- lseek((intptr_t)pStream->Base.File.hFile, (off_t)(ByteOffset), SEEK_SET);
- pStream->Base.File.FilePos = ByteOffset;
- }
-
- // Perform the read operation
- if(dwBytesToRead != 0)
- {
- bytes_read = read((intptr_t)pStream->Base.File.hFile, pvBuffer, (size_t)dwBytesToRead);
- if(bytes_read == -1)
- {
- nLastError = errno;
- return false;
- }
-
- dwBytesRead = (DWORD)(size_t)bytes_read;
- }
- }
-#endif
-
- // Increment the current file position by number of bytes read
- // If the number of bytes read doesn't match to required amount, return false
- pStream->Base.File.FilePos = ByteOffset + dwBytesRead;
- if(dwBytesRead != dwBytesToRead)
- SetLastError(ERROR_HANDLE_EOF);
- return (dwBytesRead == dwBytesToRead);
-}
-
-/**
- * \a pStream Pointer to an open stream
- * \a pByteOffset Pointer to file byte offset. If NULL, writes to current position
- * \a pvBuffer Pointer to data to be written
- * \a dwBytesToWrite Number of bytes to write to the file
- */
-
-static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const void * pvBuffer, DWORD dwBytesToWrite)
-{
- ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.File.FilePos;
- DWORD dwBytesWritten = 0; // Must be set by platform-specific code
-
-#ifdef PLATFORM_WINDOWS
- {
- // Note: StormLib no longer supports Windows 9x.
- // Thus, we can use the OVERLAPPED structure to specify
- // file offset to read from file. This allows us to skip
- // one system call to SetFilePointer
-
- // Update the byte offset
- pStream->Base.File.FilePos = ByteOffset;
-
- // Read the data
- if(dwBytesToWrite != 0)
- {
- OVERLAPPED Overlapped;
-
- Overlapped.OffsetHigh = (DWORD)(ByteOffset >> 32);
- Overlapped.Offset = (DWORD)ByteOffset;
- Overlapped.hEvent = NULL;
- if(!WriteFile(pStream->Base.File.hFile, pvBuffer, dwBytesToWrite, &dwBytesWritten, &Overlapped))
- return false;
- }
-/*
- // If the byte offset is different from the current file position,
- // we have to update the file position
- if(ByteOffset != pStream->Base.File.FilePos)
- {
- LONG ByteOffsetHi = (LONG)(ByteOffset >> 32);
-
- SetFilePointer(pStream->Base.File.hFile, (LONG)ByteOffset, &ByteOffsetHi, FILE_BEGIN);
- pStream->Base.File.FilePos = ByteOffset;
- }
-
- // Read the data
- if(dwBytesToWrite != 0)
- {
- if(!WriteFile(pStream->Base.File.hFile, pvBuffer, dwBytesToWrite, &dwBytesWritten, NULL))
- return false;
- }
-*/
- }
-#endif
-
-#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
- {
- ssize_t bytes_written;
-
- // If the byte offset is different from the current file position,
- // we have to update the file position
- if(ByteOffset != pStream->Base.File.FilePos)
- {
- lseek((intptr_t)pStream->Base.File.hFile, (off_t)(ByteOffset), SEEK_SET);
- pStream->Base.File.FilePos = ByteOffset;
- }
-
- // Perform the read operation
- bytes_written = write((intptr_t)pStream->Base.File.hFile, pvBuffer, (size_t)dwBytesToWrite);
- if(bytes_written == -1)
- {
- nLastError = errno;
- return false;
- }
-
- dwBytesWritten = (DWORD)(size_t)bytes_written;
- }
-#endif
-
- // Increment the current file position by number of bytes read
- pStream->Base.File.FilePos = ByteOffset + dwBytesWritten;
-
- // Also modify the file size, if needed
- if(pStream->Base.File.FilePos > pStream->Base.File.FileSize)
- pStream->Base.File.FileSize = pStream->Base.File.FilePos;
-
- if(dwBytesWritten != dwBytesToWrite)
- SetLastError(ERROR_DISK_FULL);
- return (dwBytesWritten == dwBytesToWrite);
-}
-
-static bool BaseFile_GetPos(
- TFileStream * pStream, // Pointer to an open stream
- ULONGLONG & ByteOffset) // Pointer to file byte offset
-{
- ByteOffset = pStream->Base.File.FilePos;
- return true;
-}
-
-static bool BaseFile_GetSize(
- TFileStream * pStream, // Pointer to an open stream
- ULONGLONG & FileSize) // Pointer where to store file size
-{
- FileSize = pStream->Base.File.FileSize;
- return true;
-}
-
-/**
- * \a pStream Pointer to an open stream
- * \a NewFileSize New size of the file
- */
-static bool BaseFile_SetSize(TFileStream * pStream, ULONGLONG NewFileSize)
-{
-#ifdef PLATFORM_WINDOWS
- {
- LONG FileSizeHi = (LONG)(NewFileSize >> 32);
- LONG FileSizeLo;
- DWORD dwNewPos;
- bool bResult;
-
- // Set the position at the new file size
- dwNewPos = SetFilePointer(pStream->Base.File.hFile, (LONG)NewFileSize, &FileSizeHi, FILE_BEGIN);
- if(dwNewPos == INVALID_SET_FILE_POINTER && GetLastError() != ERROR_SUCCESS)
- return false;
-
- // Set the current file pointer as the end of the file
- bResult = (bool)SetEndOfFile(pStream->Base.File.hFile);
-
- // Restore the file position
- FileSizeHi = (LONG)(pStream->Base.File.FilePos >> 32);
- FileSizeLo = (LONG)(pStream->Base.File.FilePos);
- SetFilePointer(pStream->Base.File.hFile, FileSizeLo, &FileSizeHi, FILE_BEGIN);
- return bResult;
- }
-#endif
-
-#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
- {
- if(ftruncate((intptr_t)pStream->Base.File.hFile, (off_t)NewFileSize) == -1)
- {
- nLastError = errno;
- return false;
- }
-
- return true;
- }
-#endif
-}
-
-static bool BaseFile_GetTime(TFileStream * pStream, ULONGLONG * pFileTime)
-{
- *pFileTime = pStream->Base.File.FileTime;
- return true;
-}
-
-// Renames the file pointed by pStream so that it contains data from pNewStream
-static bool BaseFile_Switch(TFileStream * pStream, TFileStream * pNewStream)
-{
-#ifdef PLATFORM_WINDOWS
- // Delete the original stream file. Don't check the result value,
- // because if the file doesn't exist, it would fail
- DeleteFile(pStream->szFileName);
-
- // Rename the new file to the old stream's file
- return (bool)MoveFile(pNewStream->szFileName, pStream->szFileName);
-#endif
-
-#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
- // "rename" on Linux also works if the target file exists
- if(rename(pNewStream->szFileName, pStream->szFileName) == -1)
- {
- nLastError = errno;
- return false;
- }
-
- return true;
-#endif
-}
-
-static void BaseFile_Close(TFileStream * pStream)
-{
- if(pStream->Base.File.hFile != INVALID_HANDLE_VALUE)
- {
-#ifdef PLATFORM_WINDOWS
- CloseHandle(pStream->Base.File.hFile);
-#endif
-
-#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
- close((intptr_t)pStream->Base.File.hFile);
-#endif
- }
-
- // Also invalidate the handle
- pStream->Base.File.hFile = INVALID_HANDLE_VALUE;
-}
-
-static bool BaseFile_Create(
- TFileStream * pStream,
- const TCHAR * szFileName,
- DWORD dwStreamFlags)
-{
-#ifdef PLATFORM_WINDOWS
- {
- DWORD dwWriteShare = (dwStreamFlags & STREAM_FLAG_WRITE_SHARE) ? FILE_SHARE_WRITE : 0;
-
- pStream->Base.File.hFile = CreateFile(szFileName,
- GENERIC_READ | GENERIC_WRITE,
- dwWriteShare | FILE_SHARE_READ,
- NULL,
- CREATE_ALWAYS,
- 0,
- NULL);
- if(pStream->Base.File.hFile == INVALID_HANDLE_VALUE)
- return false;
- }
-#endif
-
-#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
- {
- intptr_t handle;
-
- handle = open(szFileName, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- if(handle == -1)
- {
- nLastError = errno;
- return false;
- }
-
- pStream->Base.File.hFile = (HANDLE)handle;
- }
-#endif
-
- // Fill-in the entry points
- pStream->BaseRead = BaseFile_Read;
- pStream->BaseWrite = BaseFile_Write;
- pStream->BaseGetPos = BaseFile_GetPos;
- pStream->BaseGetSize = BaseFile_GetSize;
- pStream->BaseSetSize = BaseFile_SetSize;
- pStream->BaseSetSize = BaseFile_SetSize;
- pStream->BaseGetTime = BaseFile_GetTime;
- pStream->BaseClose = BaseFile_Close;
-
- // Reset the file position
- pStream->Base.File.FileSize = 0;
- pStream->Base.File.FilePos = 0;
- pStream->dwFlags = dwStreamFlags;
- return true;
-}
-
-static bool BaseFile_Open(
- TFileStream * pStream,
- const TCHAR * szFileName,
- DWORD dwStreamFlags)
-{
-#ifdef PLATFORM_WINDOWS
- {
- ULARGE_INTEGER FileSize;
- DWORD dwDesiredAccess = (dwStreamFlags & STREAM_FLAG_READ_ONLY) ? GENERIC_READ : GENERIC_ALL;
- DWORD dwWriteShare = (dwStreamFlags & STREAM_FLAG_WRITE_SHARE) ? FILE_SHARE_WRITE : 0;
-
- // Open the file
- pStream->Base.File.hFile = CreateFile(szFileName,
- dwDesiredAccess,
- dwWriteShare | FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL);
- if(pStream->Base.File.hFile == INVALID_HANDLE_VALUE)
- return false;
-
- // Query the file size
- FileSize.LowPart = GetFileSize(pStream->Base.File.hFile, &FileSize.HighPart);
- pStream->Base.File.FileSize = FileSize.QuadPart;
-
- // Query last write time
- GetFileTime(pStream->Base.File.hFile, NULL, NULL, (LPFILETIME)&pStream->Base.File.FileTime);
- }
-#endif
-
-#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
- {
- struct stat fileinfo;
- int oflag = (dwStreamFlags & STREAM_FLAG_READ_ONLY) ? O_RDONLY : O_RDWR;
- intptr_t handle;
-
- // Open the file
- handle = open(szFileName, oflag);
- if(handle == -1)
- {
- nLastError = errno;
- return false;
- }
-
- // Get the file size
- if(fstat(handle, &fileinfo) == -1)
- {
- nLastError = errno;
- return false;
- }
-
- // time_t is number of seconds since 1.1.1970, UTC.
- // 1 second = 10000000 (decimal) in FILETIME
- // Set the start to 1.1.1970 00:00:00
- pStream->Base.File.FileTime = 0x019DB1DED53E8000ULL + (10000000 * fileinfo.st_mtime);
- pStream->Base.File.FileSize = (ULONGLONG)fileinfo.st_size;
- pStream->Base.File.hFile = (HANDLE)handle;
- }
-#endif
-
- // Fill-in the entry points
- pStream->BaseRead = BaseFile_Read;
- pStream->BaseWrite = BaseFile_Write;
- pStream->BaseGetPos = BaseFile_GetPos;
- pStream->BaseGetSize = BaseFile_GetSize;
- pStream->BaseSetSize = BaseFile_SetSize;
- pStream->BaseGetTime = BaseFile_GetTime;
- pStream->BaseClose = BaseFile_Close;
-
- // Reset the file position
- pStream->Base.File.FilePos = 0;
- pStream->dwFlags = dwStreamFlags;
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Local functions - base memory-mapped file support
-
-static bool BaseMap_Read(
- TFileStream * pStream, // Pointer to an open stream
- ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position
- void * pvBuffer, // Pointer to data to be read
- DWORD dwBytesToRead) // Number of bytes to read from the file
-{
- ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.Map.FilePos;
-
- // Do we have to read anything at all?
- if(dwBytesToRead != 0)
- {
- // Don't allow reading past file size
- if((ByteOffset + dwBytesToRead) > pStream->Base.Map.FileSize)
- return false;
-
- // Copy the required data
- memcpy(pvBuffer, pStream->Base.Map.pbFile + (size_t)ByteOffset, dwBytesToRead);
- }
-
- // Move the current file position
- pStream->Base.Map.FilePos += dwBytesToRead;
- return true;
-}
-
-static bool BaseMap_GetPos(
- TFileStream * pStream, // Pointer to an open stream
- ULONGLONG & ByteOffset) // Pointer to file byte offset
-{
- ByteOffset = pStream->Base.Map.FilePos;
- return true;
-}
-
-static bool BaseMap_GetSize(
- TFileStream * pStream, // Pointer to an open stream
- ULONGLONG & FileSize) // Pointer where to store file size
-{
- FileSize = pStream->Base.Map.FileSize;
- return true;
-}
-
-static bool BaseMap_GetTime(TFileStream * pStream, ULONGLONG * pFileTime)
-{
- *pFileTime = pStream->Base.Map.FileTime;
- return true;
-}
-
-static void BaseMap_Close(TFileStream * pStream)
-{
-#ifdef PLATFORM_WINDOWS
- if(pStream->Base.Map.pbFile != NULL)
- UnmapViewOfFile(pStream->Base.Map.pbFile);
-#endif
-
-#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
- if(pStream->Base.Map.pbFile != NULL)
- munmap(pStream->Base.Map.pbFile, (size_t )pStream->Base.Map.FileSize);
-#endif
-
- pStream->Base.Map.pbFile = NULL;
-}
-
-static bool BaseMap_Open(
- TFileStream * pStream,
- const TCHAR * szFileName,
- DWORD dwStreamFlags)
-{
-#ifdef PLATFORM_WINDOWS
-
- ULARGE_INTEGER FileSize;
- HANDLE hFile;
- HANDLE hMap;
- bool bResult = false;
-
- // Open the file for read access
- hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
- if(hFile != NULL)
- {
- // Retrieve file size. Don't allow mapping file of a zero size.
- FileSize.LowPart = GetFileSize(hFile, &FileSize.HighPart);
- if(FileSize.QuadPart != 0)
- {
- // Retrieve file time
- GetFileTime(hFile, NULL, NULL, (LPFILETIME)&pStream->Base.Map.FileTime);
-
- // Now create mapping object
- hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
- if(hMap != NULL)
- {
- // Map the entire view into memory
- // Note that this operation will fail if the file can't fit
- // into usermode address space
- pStream->Base.Map.pbFile = (LPBYTE)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
- if(pStream->Base.Map.pbFile != NULL)
- {
- pStream->Base.Map.FileSize = FileSize.QuadPart;
- pStream->Base.Map.FilePos = 0;
- bResult = true;
- }
-
- // Close the map handle
- CloseHandle(hMap);
- }
- }
-
- // Close the file handle
- CloseHandle(hFile);
- }
-
- // If the file is not there and is not available for random access,
- // report error
- if(bResult == false)
- return false;
-#endif
-
-#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
- struct stat fileinfo;
- intptr_t handle;
- bool bResult = false;
-
- // Open the file
- handle = open(szFileName, O_RDONLY);
- if(handle != -1)
- {
- // Get the file size
- if(fstat(handle, &fileinfo) != -1)
- {
- pStream->Base.Map.pbFile = (LPBYTE)mmap(NULL, (size_t)fileinfo.st_size, PROT_READ, MAP_PRIVATE, handle, 0);
- if(pStream->Base.Map.pbFile != NULL)
- {
- // time_t is number of seconds since 1.1.1970, UTC.
- // 1 second = 10000000 (decimal) in FILETIME
- // Set the start to 1.1.1970 00:00:00
- pStream->Base.Map.FileTime = 0x019DB1DED53E8000ULL + (10000000 * fileinfo.st_mtime);
- pStream->Base.Map.FileSize = (ULONGLONG)fileinfo.st_size;
- pStream->Base.Map.FilePos = 0;
- bResult = true;
- }
- }
- close(handle);
- }
-
- // Did the mapping fail?
- if(bResult == false)
- {
- nLastError = errno;
- return false;
- }
-#endif
-
- // Fill-in entry points
- pStream->BaseRead = BaseMap_Read;
- pStream->BaseGetPos = BaseMap_GetPos;
- pStream->BaseGetSize = BaseMap_GetSize;
- pStream->BaseGetTime = BaseMap_GetTime;
- pStream->BaseClose = BaseMap_Close;
- pStream->dwFlags = dwStreamFlags;
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Local functions - base HTTP file support
-
-static const TCHAR * BaseHttp_ExtractServerName(const TCHAR * szFileName, TCHAR * szServerName)
-{
- // Check for HTTP
- if(!_tcsnicmp(szFileName, _T("http://"), 7))
- szFileName += 7;
-
- // Cut off the server name
- if(szServerName != NULL)
- {
- while(szFileName[0] != 0 && szFileName[0] != _T('/'))
- *szServerName++ = *szFileName++;
- *szServerName = 0;
- }
- else
- {
- while(szFileName[0] != 0 && szFileName[0] != _T('/'))
- *szFileName++;
- }
-
- // Return the remainder
- return szFileName;
-}
-
-static bool BaseHttp_Read(
- TFileStream * pStream, // Pointer to an open stream
- ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position
- void * pvBuffer, // Pointer to data to be read
- DWORD dwBytesToRead) // Number of bytes to read from the file
-{
-#ifdef PLATFORM_WINDOWS
- ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.Http.FilePos;
- DWORD dwTotalBytesRead = 0;
-
- // Do we have to read anything at all?
- if(dwBytesToRead != 0)
- {
- HINTERNET hRequest;
- LPCTSTR szFileName;
- LPBYTE pbBuffer = (LPBYTE)pvBuffer;
- TCHAR szRangeRequest[0x80];
- DWORD dwStartOffset = (DWORD)ByteOffset;
- DWORD dwEndOffset = dwStartOffset + dwBytesToRead;
- BYTE Buffer[0x200];
-
- // Open HTTP request to the file
- szFileName = BaseHttp_ExtractServerName(pStream->szFileName, NULL);
- hRequest = HttpOpenRequest(pStream->Base.Http.hConnect, _T("GET"), szFileName, NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
- if(hRequest != NULL)
- {
- // Add range request to the HTTP headers
- // http://www.clevercomponents.com/articles/article015/resuming.asp
- _stprintf(szRangeRequest, _T("Range: bytes=%d-%d"), dwStartOffset, dwEndOffset);
- HttpAddRequestHeaders(hRequest, szRangeRequest, 0xFFFFFFFF, HTTP_ADDREQ_FLAG_ADD_IF_NEW);
-
- // Send the request to the server
- if(HttpSendRequest(hRequest, NULL, 0, NULL, 0))
- {
- while(dwTotalBytesRead < dwBytesToRead)
- {
- DWORD dwBlockBytesToRead = dwBytesToRead - dwTotalBytesRead;
- DWORD dwBlockBytesRead = 0;
-
- // Read the block from the file
- if(dwBlockBytesToRead > sizeof(Buffer))
- dwBlockBytesToRead = sizeof(Buffer);
- InternetReadFile(hRequest, pbBuffer, dwBlockBytesToRead, &dwBlockBytesRead);
-
- // Check for end
- if(dwBlockBytesRead == 0)
- break;
-
- // Move buffers
- dwTotalBytesRead += dwBlockBytesRead;
- pbBuffer += dwBlockBytesRead;
- }
- }
- InternetCloseHandle(hRequest);
- }
- }
-
- // Increment the current file position by number of bytes read
- pStream->Base.Http.FilePos = ByteOffset + dwTotalBytesRead;
-
- // If the number of bytes read doesn't match the required amount, return false
- if(dwTotalBytesRead != dwBytesToRead)
- SetLastError(ERROR_HANDLE_EOF);
- return (dwTotalBytesRead == dwBytesToRead);
-
-#else
-
- // Not supported
- pStream = pStream;
- pByteOffset = pByteOffset;
- pvBuffer = pvBuffer;
- dwBytesToRead = dwBytesToRead;
- SetLastError(ERROR_NOT_SUPPORTED);
- return false;
-
-#endif
-}
-
-static bool BaseHttp_GetPos(
- TFileStream * pStream, // Pointer to an open stream
- ULONGLONG & ByteOffset) // Pointer to file byte offset
-{
- ByteOffset = pStream->Base.Http.FilePos;
- return true;
-}
-
-static bool BaseHttp_GetSize(
- TFileStream * pStream, // Pointer to an open stream
- ULONGLONG & FileSize) // Pointer where to store file size
-{
- FileSize = pStream->Base.Http.FileSize;
- return true;
-}
-
-static bool BaseHttp_GetTime(TFileStream * pStream, ULONGLONG * pFileTime)
-{
- *pFileTime = pStream->Base.Http.FileTime;
- return true;
-}
-
-static void BaseHttp_Close(TFileStream * pStream)
-{
-#ifdef PLATFORM_WINDOWS
- if(pStream->Base.Http.hConnect != NULL)
- InternetCloseHandle(pStream->Base.Http.hConnect);
- pStream->Base.Http.hConnect = NULL;
-
- if(pStream->Base.Http.hInternet != NULL)
- InternetCloseHandle(pStream->Base.Http.hInternet);
- pStream->Base.Http.hInternet = NULL;
-#else
- pStream = pStream;
-#endif
-}
-
-static bool BaseHttp_Open(
- TFileStream * pStream,
- const TCHAR * szFileName,
- DWORD dwStreamFlags)
-{
-#ifdef PLATFORM_WINDOWS
-
- HINTERNET hRequest;
- DWORD dwTemp = 0;
- bool bFileAvailable = false;
- int nError = ERROR_SUCCESS;
-
- // Don't connect to the internet
- if(!InternetGetConnectedState(&dwTemp, 0))
- nError = GetLastError();
-
- // Initiate the connection to the internet
- if(nError == ERROR_SUCCESS)
- {
- pStream->Base.Http.hInternet = InternetOpen(_T("StormLib HTTP MPQ reader"),
- INTERNET_OPEN_TYPE_PRECONFIG,
- NULL,
- NULL,
- 0);
- if(pStream->Base.Http.hInternet == NULL)
- nError = GetLastError();
- }
-
- // Connect to the server
- if(nError == ERROR_SUCCESS)
- {
- TCHAR szServerName[MAX_PATH];
- DWORD dwFlags = INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_UI | INTERNET_FLAG_NO_CACHE_WRITE;
-
- // Initiate connection with the server
- szFileName = BaseHttp_ExtractServerName(szFileName, szServerName);
- pStream->Base.Http.hConnect = InternetConnect(pStream->Base.Http.hInternet,
- szServerName,
- INTERNET_DEFAULT_HTTP_PORT,
- NULL,
- NULL,
- INTERNET_SERVICE_HTTP,
- dwFlags,
- 0);
- if(pStream->Base.Http.hConnect == NULL)
- nError = GetLastError();
- }
-
- // Now try to query the file size
- if(nError == ERROR_SUCCESS)
- {
- // Open HTTP request to the file
- hRequest = HttpOpenRequest(pStream->Base.Http.hConnect, _T("GET"), szFileName, NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
- if(hRequest != NULL)
- {
- if(HttpSendRequest(hRequest, NULL, 0, NULL, 0))
- {
- ULONGLONG FileTime = 0;
- DWORD dwFileSize = 0;
- DWORD dwDataSize;
- DWORD dwIndex = 0;
-
- // Check if the MPQ has Last Modified field
- dwDataSize = sizeof(ULONGLONG);
- if(HttpQueryInfo(hRequest, HTTP_QUERY_LAST_MODIFIED | HTTP_QUERY_FLAG_SYSTEMTIME, &FileTime, &dwDataSize, &dwIndex))
- pStream->Base.Http.FileTime = FileTime;
-
- // Verify if the server supports random access
- dwDataSize = sizeof(DWORD);
- if(HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &dwFileSize, &dwDataSize, &dwIndex))
- {
- if(dwFileSize != 0)
- {
- pStream->Base.Http.FileSize = dwFileSize;
- pStream->Base.Http.FilePos = 0;
- bFileAvailable = true;
- }
- }
- }
- InternetCloseHandle(hRequest);
- }
- }
-
- // If the file is not there and is not available for random access,
- // report error
- if(bFileAvailable == false)
- {
- BaseHttp_Close(pStream);
- return false;
- }
-
- // Fill-in entry points
- pStream->BaseRead = BaseHttp_Read;
- pStream->BaseGetPos = BaseHttp_GetPos;
- pStream->BaseGetSize = BaseHttp_GetSize;
- pStream->BaseGetTime = BaseHttp_GetTime;
- pStream->BaseClose = BaseHttp_Close;
- pStream->dwFlags = dwStreamFlags;
- return true;
-
-#else
-
- // Not supported
- pStream = pStream;
- szFileName = szFileName;
- SetLastError(ERROR_NOT_SUPPORTED);
- return false;
-
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Local functions - linear stream support
-
-static bool LinearStream_Read(
- TLinearStream * pStream, // Pointer to an open stream
- ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position
- void * pvBuffer, // Pointer to data to be read
- DWORD dwBytesToRead) // Number of bytes to read from the file
-{
- ULONGLONG ByteOffset;
- ULONGLONG EndOffset;
- LPBYTE pbBitmap;
- DWORD BlockIndex;
- DWORD ByteIndex;
- DWORD BitMask;
-
- // At this point, we must have a bitmap set
- assert(pStream->pBitmap != NULL);
-
- // If we have data map, we must check if the data block is present in the MPQ
- if(dwBytesToRead != 0)
- {
- DWORD BlockSize = pStream->pBitmap->BlockSize;
-
- // Get the offset where we read it from
- if(pByteOffset == NULL)
- pStream->BaseGetPos(pStream, ByteOffset);
- else
- ByteOffset = *pByteOffset;
- EndOffset = ByteOffset + dwBytesToRead;
-
- // If the start of the area is within the region
- // protected by data map, check each block
- if(ByteOffset < pStream->pBitmap->EndOffset)
- {
- // Cut the end of the stream protected by the data map
- EndOffset = STORMLIB_MIN(EndOffset, pStream->pBitmap->EndOffset);
-
- // Calculate the initial block index
- BlockIndex = (DWORD)(ByteOffset / BlockSize);
- pbBitmap = (LPBYTE)(pStream->pBitmap + 1);
-
- // Parse each block
- while(ByteOffset < EndOffset)
- {
- // Prepare byte index and bit mask
- ByteIndex = BlockIndex / 8;
- BitMask = 1 << (BlockIndex & 0x07);
-
- // If that bit is not set, it means that the block is not present
- if((pbBitmap[ByteIndex] & BitMask) == 0)
- {
- SetLastError(ERROR_FILE_CORRUPT);
- return false;
- }
-
- // Move to tne next block
- ByteOffset += BlockSize;
- BlockIndex++;
- }
- }
- }
-
- // Now if all tests passed, we can call the base read function
- return pStream->BaseRead(pStream, pByteOffset, pvBuffer, dwBytesToRead);
-}
-
-static bool LinearStream_Switch(TLinearStream * pStream, TLinearStream * pNewStream)
-{
- // Sanity checks
- assert((pNewStream->dwFlags & STREAM_PROVIDER_MASK) == STREAM_PROVIDER_LINEAR);
- assert((pNewStream->dwFlags & BASE_PROVIDER_MASK) == BASE_PROVIDER_FILE);
- assert((pStream->dwFlags & STREAM_PROVIDER_MASK) == STREAM_PROVIDER_LINEAR);
- assert((pStream->dwFlags & BASE_PROVIDER_MASK) == BASE_PROVIDER_FILE);
-
- // Close the new stream
- pNewStream->BaseClose(pNewStream);
-
- // Close the source stream
- pStream->BaseClose(pStream);
-
- // Rename the new data source file to the existing file
- if(!BaseFile_Switch(pStream, pNewStream))
- return false;
-
- // Now we have to open the "pStream" again
- if(!BaseFile_Open(pStream, pStream->szFileName, pNewStream->dwFlags))
- return false;
-
- // We need to cleanup the new data stream
- FileStream_Close(pNewStream);
- return true;
-}
-
-static bool LinearStream_GetBitmap(
- TLinearStream * pStream,
- TFileBitmap * pBitmap,
- DWORD Length,
- LPDWORD LengthNeeded)
-{
- DWORD TotalLength;
- bool bResult = false;
-
- // Assumed that we have bitmap now
- assert(pStream->pBitmap != NULL);
-
- // Give the bitmap length
- TotalLength = sizeof(TFileBitmap) + pStream->pBitmap->BitmapSize;
- if(LengthNeeded != NULL)
- *LengthNeeded = TotalLength;
-
- // Do we have enough space to fill at least the bitmap structure?
- if(Length >= sizeof(TFileBitmap))
- {
- // Enough space for complete bitmap?
- if(Length >= TotalLength)
- {
- memcpy(pBitmap, pStream->pBitmap, TotalLength);
- bResult = true;
- }
- else
- {
- memcpy(pBitmap, pStream->pBitmap, sizeof(TFileBitmap));
- bResult = true;
- }
- }
-
- return bResult;
-}
-
-static void LinearStream_Close(TLinearStream * pStream)
-{
- // Free the data map, if any
- if(pStream->pBitmap != NULL)
- STORM_FREE(pStream->pBitmap);
- pStream->pBitmap = NULL;
-
- // Call the base class for closing the stream
- return pStream->BaseClose(pStream);
-}
-
-static bool LinearStream_Open(TLinearStream * pStream)
-{
- // No extra work here really; just set entry points
- pStream->StreamRead = pStream->BaseRead;
- pStream->StreamWrite = pStream->BaseWrite;
- pStream->StreamGetPos = pStream->BaseGetPos;
- pStream->StreamGetSize = pStream->BaseGetSize;
- pStream->StreamSetSize = pStream->BaseSetSize;
- pStream->StreamGetTime = pStream->BaseGetTime;
- pStream->StreamGetBmp = (STREAM_GETBMP)Dummy_GetBitmap;
- pStream->StreamSwitch = (STREAM_SWITCH)LinearStream_Switch;
- pStream->StreamClose = (STREAM_CLOSE)LinearStream_Close;
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Local functions - partial stream support
-
-static bool IsPartHeader(PPART_FILE_HEADER pPartHdr)
-{
- // Version number must be 2
- if(pPartHdr->PartialVersion == 2)
- {
- // GameBuildNumber must be an ASCII number
- if(isdigit(pPartHdr->GameBuildNumber[0]) && isdigit(pPartHdr->GameBuildNumber[1]) && isdigit(pPartHdr->GameBuildNumber[2]))
- {
- // Block size must be power of 2
- if((pPartHdr->BlockSize & (pPartHdr->BlockSize - 1)) == 0)
- return true;
- }
- }
-
- return false;
-}
-
-static bool PartialStream_Read(
- TPartialStream * pStream,
- ULONGLONG * pByteOffset,
- void * pvBuffer,
- DWORD dwBytesToRead)
-{
- ULONGLONG RawByteOffset;
- LPBYTE pbBuffer = (LPBYTE)pvBuffer;
- DWORD dwBytesRemaining = dwBytesToRead;
- DWORD dwPartOffset;
- DWORD dwPartIndex;
- DWORD dwBytesRead = 0;
- DWORD dwBlockSize = pStream->BlockSize;
- bool bResult = false;
- int nFailReason = ERROR_HANDLE_EOF; // Why it failed if not enough bytes was read
-
- // If the byte offset is not entered, use the current position
- if(pByteOffset == NULL)
- pByteOffset = &pStream->VirtualPos;
-
- // Check if the file position is not at or beyond end of the file
- if(*pByteOffset >= pStream->VirtualSize)
- {
- SetLastError(ERROR_HANDLE_EOF);
- return false;
- }
-
- // Get the part index where the read offset is
- // Note that the part index should now be within the range,
- // as read requests beyond-EOF are handled by the previous test
- dwPartIndex = (DWORD)(*pByteOffset / pStream->BlockSize);
- assert(dwPartIndex < pStream->BlockCount);
-
- // If the number of bytes remaining goes past
- // the end of the file, cut them
- if((*pByteOffset + dwBytesRemaining) > pStream->VirtualSize)
- dwBytesRemaining = (DWORD)(pStream->VirtualSize - *pByteOffset);
-
- // Calculate the offset in the current part
- dwPartOffset = (DWORD)(*pByteOffset) & (pStream->BlockSize - 1);
-
- // Read all data, one part at a time
- while(dwBytesRemaining != 0)
- {
- PPART_FILE_MAP_ENTRY PartMap = pStream->PartMap + dwPartIndex;
- DWORD dwBytesInPart;
-
- // If the part is not present in the file, we fail the read
- if((PartMap->Flags & 3) == 0)
- {
- nFailReason = ERROR_FILE_CORRUPT;
- bResult = false;
- break;
- }
-
- // If we are in the last part, we have to cut the number of bytes in the last part
- if(dwPartIndex == pStream->BlockCount - 1)
- dwBlockSize = (DWORD)pStream->VirtualSize & (pStream->BlockSize - 1);
-
- // Get the number of bytes reamining in the current part
- dwBytesInPart = dwBlockSize - dwPartOffset;
-
- // Compute the raw file offset of the file part
- RawByteOffset = MAKE_OFFSET64(PartMap->BlockOffsHi, PartMap->BlockOffsLo);
- if(RawByteOffset == 0)
- {
- nFailReason = ERROR_FILE_CORRUPT;
- bResult = false;
- break;
- }
-
- // If the number of bytes in part is too big, cut it
- if(dwBytesInPart > dwBytesRemaining)
- dwBytesInPart = dwBytesRemaining;
-
- // Append the offset within the part
- RawByteOffset += dwPartOffset;
- if(!pStream->BaseRead(pStream, &RawByteOffset, pbBuffer, dwBytesInPart))
- {
- nFailReason = ERROR_FILE_CORRUPT;
- bResult = false;
- break;
- }
-
- // Increment the file position
- dwBytesRemaining -= dwBytesInPart;
- dwBytesRead += dwBytesInPart;
- pbBuffer += dwBytesInPart;
-
- // Move to the next file part
- dwPartOffset = 0;
- dwPartIndex++;
- }
-
- // Move the file position by the number of bytes read
- pStream->VirtualPos = *pByteOffset + dwBytesRead;
- if(dwBytesRead != dwBytesToRead)
- SetLastError(nFailReason);
- return (dwBytesRead == dwBytesToRead);
-}
-
-static bool PartialStream_GetPos(
- TPartialStream * pStream,
- ULONGLONG & ByteOffset)
-{
- ByteOffset = pStream->VirtualPos;
- return true;
-}
-
-static bool PartialStream_GetSize(
- TPartialStream * pStream, // Pointer to an open stream
- ULONGLONG & FileSize) // Pointer where to store file size
-{
- FileSize = pStream->VirtualSize;
- return true;
-}
-
-static bool PartialStream_GetBitmap(
- TPartialStream * pStream,
- TFileBitmap * pBitmap,
- DWORD Length,
- LPDWORD LengthNeeded)
-{
- LPBYTE pbBitmap;
- DWORD TotalLength;
- DWORD BitmapSize = 0;
- DWORD ByteOffset;
- DWORD BitMask;
- bool bResult = false;
-
- // Do we have stream bitmap?
- BitmapSize = ((pStream->BlockCount - 1) / 8) + 1;
-
- // Give the bitmap length
- TotalLength = sizeof(TFileBitmap) + BitmapSize;
- if(LengthNeeded != NULL)
- *LengthNeeded = TotalLength;
-
- // Do we have enough to fill at least the header?
- if(Length >= sizeof(TFileBitmap))
- {
- // Fill the bitmap header
- pBitmap->StartOffset = 0;
- pBitmap->EndOffset = pStream->VirtualSize;
- pBitmap->IsComplete = 1;
- pBitmap->BitmapSize = BitmapSize;
- pBitmap->BlockSize = pStream->BlockSize;
- pBitmap->Reserved = 0;
-
- // Is there at least one incomplete block?
- for(DWORD i = 0; i < pStream->BlockCount; i++)
- {
- if(pStream->PartMap[i].Flags != 3)
- {
- pBitmap->IsComplete = 0;
- break;
- }
- }
-
- bResult = true;
- }
-
- // Do we have enough space for supplying the bitmap?
- if(Length >= TotalLength)
- {
- // Fill the file bitmap
- pbBitmap = (LPBYTE)(pBitmap + 1);
- for(DWORD i = 0; i < pStream->BlockCount; i++)
- {
- // Is the block there?
- if(pStream->PartMap[i].Flags == 3)
- {
- ByteOffset = i / 8;
- BitMask = 1 << (i & 7);
- pbBitmap[ByteOffset] |= BitMask;
- }
- }
- bResult = true;
- }
-
- return bResult;
-}
-
-static void PartialStream_Close(TPartialStream * pStream)
-{
- // Free the part map
- if(pStream->PartMap != NULL)
- STORM_FREE(pStream->PartMap);
- pStream->PartMap = NULL;
-
- // Clear variables
- pStream->VirtualSize = 0;
- pStream->VirtualPos = 0;
-
- // Close the base stream
- assert(pStream->BaseClose != NULL);
- pStream->BaseClose(pStream);
-}
-
-static bool PartialStream_Open(TPartialStream * pStream)
-{
- PART_FILE_HEADER PartHdr;
- ULONGLONG VirtualSize; // Size of the file stored in part file
- ULONGLONG ByteOffset = {0};
- DWORD BlockCount;
-
- // Sanity check
- assert(pStream->BaseRead != NULL);
-
- // Attempt to read PART file header
- if(pStream->BaseRead(pStream, &ByteOffset, &PartHdr, sizeof(PART_FILE_HEADER)))
- {
- // We need to swap PART file header on big-endian platforms
- BSWAP_PART_HEADER(&PartHdr);
-
- // Verify the PART file header
- if(IsPartHeader(&PartHdr))
- {
- // Calculate the number of parts in the file
- VirtualSize = MAKE_OFFSET64(PartHdr.FileSizeHi, PartHdr.FileSizeLo);
- assert(VirtualSize != 0);
- BlockCount = (DWORD)((VirtualSize + PartHdr.BlockSize - 1) / PartHdr.BlockSize);
-
- // Allocate the map entry array
- pStream->PartMap = STORM_ALLOC(PART_FILE_MAP_ENTRY, BlockCount);
- if(pStream->PartMap != NULL)
- {
- // Load the block map
- if(pStream->BaseRead(pStream, NULL, pStream->PartMap, BlockCount * sizeof(PART_FILE_MAP_ENTRY)))
- {
- // Swap the array of file map entries
- BSWAP_ARRAY32_UNSIGNED(pStream->PartMap, BlockCount * sizeof(PART_FILE_MAP_ENTRY));
-
- // Fill the members of PART file stream
- pStream->VirtualSize = ((ULONGLONG)PartHdr.FileSizeHi) + PartHdr.FileSizeLo;
- pStream->VirtualPos = 0;
- pStream->BlockCount = BlockCount;
- pStream->BlockSize = PartHdr.BlockSize;
-
- // Set new function pointers
- pStream->StreamRead = (STREAM_READ)PartialStream_Read;
- pStream->StreamGetPos = (STREAM_GETPOS)PartialStream_GetPos;
- pStream->StreamGetSize = (STREAM_GETSIZE)PartialStream_GetSize;
- pStream->StreamGetTime = pStream->BaseGetTime;
- pStream->StreamGetTime = pStream->BaseGetTime;
- pStream->StreamGetBmp = (STREAM_GETBMP)PartialStream_GetBitmap;
- pStream->StreamClose = (STREAM_CLOSE)PartialStream_Close;
- return true;
- }
-
- // Free the part map
- STORM_FREE(pStream->PartMap);
- pStream->PartMap = NULL;
- }
- }
- }
-
- SetLastError(ERROR_BAD_FORMAT);
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// Local functions - encrypted stream support
-
-// Note: Starcraft II - Installer.exe (4.1.1.4219): Suffix derived from battle.net auth. code
-// Address of decryption routine: 0053A3D0 http://us.battle.net/static/mediakey/sc2-authenticationcode-enUS.txt
-// Pointer to decryptor object: ECX Numbers mean offset of 4-char group of auth code (follows in comment)
-// Pointer to key: ECX+0x5C -0C- -1C--08- -18--04- -14--00- -10-
-static const char * MpqeKey_Starcraft2_Install_deDE = "expand 32-byte kSSXH00004XFXK4KX00008EKJD3CA0000Y64ZY45M0000YD9V"; // Y45MD3CAK4KXSSXHYD9VY64Z8EKJ4XFX
-static const char * MpqeKey_Starcraft2_Install_enGB = "expand 32-byte kANGY000029ZH6NA20000HRGF8UDG0000NY82G8MN00006A3D"; // G8MN8UDG6NA2ANGY6A3DNY82HRGF29ZH
-static const char * MpqeKey_Starcraft2_Install_enSG = "expand 32-byte kWW5B0000F7HWFDU90000FWZSHLB20000BLRSW9RR00003ECE"; // W9RRHLB2FDU9WW5B3ECEBLRSFWZSF7HW
-static const char * MpqeKey_Starcraft2_Install_enUS = "expand 32-byte kTFD80000ETR5VM5G0000K859RE5N0000WT6F3DH500005LXG"; // 3DH5RE5NVM5GTFD85LXGWT6FK859ETR5
-static const char * MpqeKey_Starcraft2_Install_esES = "expand 32-byte kQU4Y0000XKTQ94PF0000N4R4UAXE0000AZ248WLK0000249P"; // 8WLKUAXE94PFQU4Y249PAZ24N4R4XKTQ
-static const char * MpqeKey_Starcraft2_Install_esMX = "expand 32-byte kSQBR00004G54HGGX0000MF9GXX3V0000FFDXA34D0000FE5U"; // A34DXX3VHGGXSQBRFE5UFFDXMF9G4G54
-static const char * MpqeKey_Starcraft2_Install_frFR = "expand 32-byte kFWPQ00006EAJ8HJE0000PFER9K9300008MA2ZG7J0000UA76"; // ZG7J9K938HJEFWPQUA768MA2PFER6EAJ
-static const char * MpqeKey_Starcraft2_Install_itIT = "expand 32-byte kXV7E00008BL2TVAP0000GVMWUNNN0000SVBWNE7C00003G2B"; // NE7CUNNNTVAPXV7E3G2BSVBWGVMW8BL2
-static const char * MpqeKey_Starcraft2_Install_koKR = "expand 32-byte kQWK70000838FBM9Q0000WQDB2FTM0000MWAZ3V9E0000U6MA"; // 3V9E2FTMBM9QQWK7U6MAMWAZWQDB838F
-static const char * MpqeKey_Starcraft2_Install_plPL = "expand 32-byte k83U6000048L6LULJ00004MQDB8ME0000UP6K2NSF0000YHA3"; // 2NSFB8MELULJ83U6YHA3UP6K4MQD48L6
-static const char * MpqeKey_Starcraft2_Install_ptBR = "expand 32-byte kU8BM0000SW4EZ4CU00005F9CZ9EW0000CTY6QA2T0000B5WX"; // QA2TZ9EWZ4CUU8BMB5WXCTY65F9CSW4E
-static const char * MpqeKey_Starcraft2_Install_ruRU = "expand 32-byte k9SH70000YEGT4BAT0000QDK978W60000V9NLVHB30000D68V"; // VHB378W64BAT9SH7D68VV9NLQDK9YEGT
-static const char * MpqeKey_Starcraft2_Install_zhTW = "expand 32-byte k7KBN0000D9NEM6GC0000N3PLQJV400003BRDU3NF00009XQJ"; // U3NFQJV4M6GC7KBN9XQJ3BRDN3PLD9NE
-
-// Note: Diablo III: Agent.exe (1.0.0.954): Suffix derived from battle.net auth. code
-// Address of decryption routine: 00502b00 http://dist.blizzard.com/mediakey/d3-authenticationcode-enGB.txt
-// Pointer to decryptor object: ECX Numbers mean offset of 4-char group of auth code (follows in comment)
-// Pointer to key: ECX+0x5C -0C- -1C--08- -18--04- -14--00- -10-
-static const char * MpqeKey_Diablo3_Install_deDE = "expand 32-byte kEFH40000QRZKY3520000XC9MF6EJ0000CFH2UCMX0000XFRX"; // UCMXF6EJY352EFH4XFRXCFH2XC9MQRZK
-static const char * MpqeKey_Diablo3_Install_enGB = "expand 32-byte kXP4G0000PHBPRP7W0000J9UNHY4800007SL9MMKV0000HYBQ"; // MMKVHY48RP7WXP4GHYBQ7SL9J9UNPHBP
-static const char * MpqeKey_Diablo3_Install_enSG = "expand 32-byte kTZ9M00003CPPVGGL0000JYETWHQ70000FDCL8MXL0000QZQS"; // 8MXLWHQ7VGGLTZ9MQZQSFDCLJYET3CPP
-static const char * MpqeKey_Diablo3_Install_enUS = "expand 32-byte kGUNG0000WZSZXFE20000UAKP5TM60000HKQ9EJ2R00005QDG"; // EJ2R5TM6XFE2GUNG5QDGHKQ9UAKPWZSZ
-static const char * MpqeKey_Diablo3_Install_esES = "expand 32-byte kK65U0000HQQTZ6LN0000CLP4BE420000WZVMPBGF0000GJQ3"; // PBGFBE42Z6LNK65UGJQ3WZVMCLP4HQQT
-static const char * MpqeKey_Diablo3_Install_esMX = "expand 32-byte kW5P200008VU2TSGC0000JPEYJJS90000C47AX7SE00008EBS"; // X7SEJJS9TSGCW5P28EBSC47AJPEY8VU2
-static const char * MpqeKey_Diablo3_Install_frFR = "expand 32-byte kRY3D00007YA2YE6X0000XS4PQA8V0000ZDE45KVB0000LGC5"; // 5KVBQA8VYE6XRY3DLGC5ZDE4XS4P7YA2
-static const char * MpqeKey_Diablo3_Install_itIT = "expand 32-byte kVVY40000B2546EVN00005B8KD2K50000DWYT478J0000XX8T"; // 478JD2K56EVNVVY4XX8TDWYT5B8KB254
-static const char * MpqeKey_Diablo3_Install_koKR = "expand 32-byte k6YWH0000474ARZTN0000NVWDVNFQ0000VDH98TS40000E9CH"; // 8TS4VNFQRZTN6YWHE9CHVDH9NVWD474A
-static const char * MpqeKey_Diablo3_Install_plPL = "expand 32-byte k4ZJJ0000BLJBF4LZ0000A6GAZ32D00003AZQLJ520000XVKK"; // LJ52Z32DF4LZ4ZJJXVKK3AZQA6GABLJB
-static const char * MpqeKey_Diablo3_Install_ptBR = "expand 32-byte k545Y0000XYAGCUE20000WHE7HY2E0000JPVYK6BD0000KNLB"; // K6BDHY2ECUE2545YKNLBJPVYWHE7XYAG
-static const char * MpqeKey_Diablo3_Install_ruRU = "expand 32-byte kXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; //
-static const char * MpqeKey_Diablo3_Install_zhTW = "expand 32-byte kMRUC0000AA8HV3ZZ0000UX2TQTN80000A8CG6VWC0000ZXV8"; // 6VWCQTN8V3ZZMRUCZXV8A8CGUX2TAA8H
-static const char * MpqeKey_Diablo3_Install_zhCN = "expand 32-byte kXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; //
-
-static const char * MpqKeyArray[] =
-{
- MpqeKey_Starcraft2_Install_deDE,
- MpqeKey_Starcraft2_Install_enGB,
- MpqeKey_Starcraft2_Install_enSG,
- MpqeKey_Starcraft2_Install_enUS,
- MpqeKey_Starcraft2_Install_esES,
- MpqeKey_Starcraft2_Install_esMX,
- MpqeKey_Starcraft2_Install_frFR,
- MpqeKey_Starcraft2_Install_itIT,
- MpqeKey_Starcraft2_Install_koKR,
- MpqeKey_Starcraft2_Install_plPL,
- MpqeKey_Starcraft2_Install_ptBR,
- MpqeKey_Starcraft2_Install_ruRU,
- MpqeKey_Starcraft2_Install_zhTW,
-
- MpqeKey_Diablo3_Install_deDE,
- MpqeKey_Diablo3_Install_enGB,
- MpqeKey_Diablo3_Install_enSG,
- MpqeKey_Diablo3_Install_enUS,
- MpqeKey_Diablo3_Install_esES,
- MpqeKey_Diablo3_Install_esMX,
- MpqeKey_Diablo3_Install_frFR,
- MpqeKey_Diablo3_Install_itIT,
- MpqeKey_Diablo3_Install_koKR,
- MpqeKey_Diablo3_Install_plPL,
- MpqeKey_Diablo3_Install_ptBR,
-// MpqeKey_Diablo3_Install_ruRU,
- MpqeKey_Diablo3_Install_zhTW,
-// MpqeKey_Diablo3_Install_zhCN,
-
- NULL
-};
-
-static DWORD Rol32(DWORD dwValue, DWORD dwRolCount)
-{
- DWORD dwShiftRight = 32 - dwRolCount;
-
- return (dwValue << dwRolCount) | (dwValue >> dwShiftRight);
-}
-
-static void DecryptFileChunk(
- DWORD * MpqData,
- LPBYTE pbKey,
- ULONGLONG ByteOffset,
- DWORD dwLength)
-{
- ULONGLONG ChunkOffset;
- DWORD KeyShuffled[0x10];
- DWORD KeyMirror[0x10];
- DWORD RoundCount = 0x14;
-
- // Prepare the key
- ChunkOffset = ByteOffset / MPQE_CHUNK_SIZE;
- memcpy(KeyMirror, pbKey, MPQE_CHUNK_SIZE);
- BSWAP_ARRAY32_UNSIGNED(KeyMirror, MPQE_CHUNK_SIZE);
- KeyMirror[0x05] = (DWORD)(ChunkOffset >> 32);
- KeyMirror[0x08] = (DWORD)(ChunkOffset);
-
- while(dwLength >= MPQE_CHUNK_SIZE)
- {
- // Shuffle the key - part 1
- KeyShuffled[0x0E] = KeyMirror[0x00];
- KeyShuffled[0x0C] = KeyMirror[0x01];
- KeyShuffled[0x05] = KeyMirror[0x02];
- KeyShuffled[0x0F] = KeyMirror[0x03];
- KeyShuffled[0x0A] = KeyMirror[0x04];
- KeyShuffled[0x07] = KeyMirror[0x05];
- KeyShuffled[0x0B] = KeyMirror[0x06];
- KeyShuffled[0x09] = KeyMirror[0x07];
- KeyShuffled[0x03] = KeyMirror[0x08];
- KeyShuffled[0x06] = KeyMirror[0x09];
- KeyShuffled[0x08] = KeyMirror[0x0A];
- KeyShuffled[0x0D] = KeyMirror[0x0B];
- KeyShuffled[0x02] = KeyMirror[0x0C];
- KeyShuffled[0x04] = KeyMirror[0x0D];
- KeyShuffled[0x01] = KeyMirror[0x0E];
- KeyShuffled[0x00] = KeyMirror[0x0F];
-
- // Shuffle the key - part 2
- for(DWORD i = 0; i < RoundCount; i += 2)
- {
- KeyShuffled[0x0A] = KeyShuffled[0x0A] ^ Rol32((KeyShuffled[0x0E] + KeyShuffled[0x02]), 0x07);
- KeyShuffled[0x03] = KeyShuffled[0x03] ^ Rol32((KeyShuffled[0x0A] + KeyShuffled[0x0E]), 0x09);
- KeyShuffled[0x02] = KeyShuffled[0x02] ^ Rol32((KeyShuffled[0x03] + KeyShuffled[0x0A]), 0x0D);
- KeyShuffled[0x0E] = KeyShuffled[0x0E] ^ Rol32((KeyShuffled[0x02] + KeyShuffled[0x03]), 0x12);
-
- KeyShuffled[0x07] = KeyShuffled[0x07] ^ Rol32((KeyShuffled[0x0C] + KeyShuffled[0x04]), 0x07);
- KeyShuffled[0x06] = KeyShuffled[0x06] ^ Rol32((KeyShuffled[0x07] + KeyShuffled[0x0C]), 0x09);
- KeyShuffled[0x04] = KeyShuffled[0x04] ^ Rol32((KeyShuffled[0x06] + KeyShuffled[0x07]), 0x0D);
- KeyShuffled[0x0C] = KeyShuffled[0x0C] ^ Rol32((KeyShuffled[0x04] + KeyShuffled[0x06]), 0x12);
-
- KeyShuffled[0x0B] = KeyShuffled[0x0B] ^ Rol32((KeyShuffled[0x05] + KeyShuffled[0x01]), 0x07);
- KeyShuffled[0x08] = KeyShuffled[0x08] ^ Rol32((KeyShuffled[0x0B] + KeyShuffled[0x05]), 0x09);
- KeyShuffled[0x01] = KeyShuffled[0x01] ^ Rol32((KeyShuffled[0x08] + KeyShuffled[0x0B]), 0x0D);
- KeyShuffled[0x05] = KeyShuffled[0x05] ^ Rol32((KeyShuffled[0x01] + KeyShuffled[0x08]), 0x12);
-
- KeyShuffled[0x09] = KeyShuffled[0x09] ^ Rol32((KeyShuffled[0x0F] + KeyShuffled[0x00]), 0x07);
- KeyShuffled[0x0D] = KeyShuffled[0x0D] ^ Rol32((KeyShuffled[0x09] + KeyShuffled[0x0F]), 0x09);
- KeyShuffled[0x00] = KeyShuffled[0x00] ^ Rol32((KeyShuffled[0x0D] + KeyShuffled[0x09]), 0x0D);
- KeyShuffled[0x0F] = KeyShuffled[0x0F] ^ Rol32((KeyShuffled[0x00] + KeyShuffled[0x0D]), 0x12);
-
- KeyShuffled[0x04] = KeyShuffled[0x04] ^ Rol32((KeyShuffled[0x0E] + KeyShuffled[0x09]), 0x07);
- KeyShuffled[0x08] = KeyShuffled[0x08] ^ Rol32((KeyShuffled[0x04] + KeyShuffled[0x0E]), 0x09);
- KeyShuffled[0x09] = KeyShuffled[0x09] ^ Rol32((KeyShuffled[0x08] + KeyShuffled[0x04]), 0x0D);
- KeyShuffled[0x0E] = KeyShuffled[0x0E] ^ Rol32((KeyShuffled[0x09] + KeyShuffled[0x08]), 0x12);
-
- KeyShuffled[0x01] = KeyShuffled[0x01] ^ Rol32((KeyShuffled[0x0C] + KeyShuffled[0x0A]), 0x07);
- KeyShuffled[0x0D] = KeyShuffled[0x0D] ^ Rol32((KeyShuffled[0x01] + KeyShuffled[0x0C]), 0x09);
- KeyShuffled[0x0A] = KeyShuffled[0x0A] ^ Rol32((KeyShuffled[0x0D] + KeyShuffled[0x01]), 0x0D);
- KeyShuffled[0x0C] = KeyShuffled[0x0C] ^ Rol32((KeyShuffled[0x0A] + KeyShuffled[0x0D]), 0x12);
-
- KeyShuffled[0x00] = KeyShuffled[0x00] ^ Rol32((KeyShuffled[0x05] + KeyShuffled[0x07]), 0x07);
- KeyShuffled[0x03] = KeyShuffled[0x03] ^ Rol32((KeyShuffled[0x00] + KeyShuffled[0x05]), 0x09);
- KeyShuffled[0x07] = KeyShuffled[0x07] ^ Rol32((KeyShuffled[0x03] + KeyShuffled[0x00]), 0x0D);
- KeyShuffled[0x05] = KeyShuffled[0x05] ^ Rol32((KeyShuffled[0x07] + KeyShuffled[0x03]), 0x12);
-
- KeyShuffled[0x02] = KeyShuffled[0x02] ^ Rol32((KeyShuffled[0x0F] + KeyShuffled[0x0B]), 0x07);
- KeyShuffled[0x06] = KeyShuffled[0x06] ^ Rol32((KeyShuffled[0x02] + KeyShuffled[0x0F]), 0x09);
- KeyShuffled[0x0B] = KeyShuffled[0x0B] ^ Rol32((KeyShuffled[0x06] + KeyShuffled[0x02]), 0x0D);
- KeyShuffled[0x0F] = KeyShuffled[0x0F] ^ Rol32((KeyShuffled[0x0B] + KeyShuffled[0x06]), 0x12);
- }
-
- // Decrypt one data chunk
- BSWAP_ARRAY32_UNSIGNED(MpqData, MPQE_CHUNK_SIZE);
- MpqData[0x00] = MpqData[0x00] ^ (KeyShuffled[0x0E] + KeyMirror[0x00]);
- MpqData[0x01] = MpqData[0x01] ^ (KeyShuffled[0x04] + KeyMirror[0x0D]);
- MpqData[0x02] = MpqData[0x02] ^ (KeyShuffled[0x08] + KeyMirror[0x0A]);
- MpqData[0x03] = MpqData[0x03] ^ (KeyShuffled[0x09] + KeyMirror[0x07]);
- MpqData[0x04] = MpqData[0x04] ^ (KeyShuffled[0x0A] + KeyMirror[0x04]);
- MpqData[0x05] = MpqData[0x05] ^ (KeyShuffled[0x0C] + KeyMirror[0x01]);
- MpqData[0x06] = MpqData[0x06] ^ (KeyShuffled[0x01] + KeyMirror[0x0E]);
- MpqData[0x07] = MpqData[0x07] ^ (KeyShuffled[0x0D] + KeyMirror[0x0B]);
- MpqData[0x08] = MpqData[0x08] ^ (KeyShuffled[0x03] + KeyMirror[0x08]);
- MpqData[0x09] = MpqData[0x09] ^ (KeyShuffled[0x07] + KeyMirror[0x05]);
- MpqData[0x0A] = MpqData[0x0A] ^ (KeyShuffled[0x05] + KeyMirror[0x02]);
- MpqData[0x0B] = MpqData[0x0B] ^ (KeyShuffled[0x00] + KeyMirror[0x0F]);
- MpqData[0x0C] = MpqData[0x0C] ^ (KeyShuffled[0x02] + KeyMirror[0x0C]);
- MpqData[0x0D] = MpqData[0x0D] ^ (KeyShuffled[0x06] + KeyMirror[0x09]);
- MpqData[0x0E] = MpqData[0x0E] ^ (KeyShuffled[0x0B] + KeyMirror[0x06]);
- MpqData[0x0F] = MpqData[0x0F] ^ (KeyShuffled[0x0F] + KeyMirror[0x03]);
- BSWAP_ARRAY32_UNSIGNED(MpqData, MPQE_CHUNK_SIZE);
-
- // Update byte offset in the key
- KeyMirror[0x08]++;
- if(KeyMirror[0x08] == 0)
- KeyMirror[0x05]++;
-
- // Move pointers and decrease number of bytes to decrypt
- MpqData += (MPQE_CHUNK_SIZE / sizeof(DWORD));
- dwLength -= MPQE_CHUNK_SIZE;
- }
-}
-
-static const char * DetectFileKey(LPBYTE pbEncryptedHeader)
-{
- ULONGLONG ByteOffset = 0;
- BYTE FileHeader[MPQE_CHUNK_SIZE];
- BYTE Key[MPQE_CHUNK_SIZE];
-
- // We just try all known keys one by one
- for(int i = 0; MpqKeyArray[i] != NULL; i++)
- {
- // Copy the key there
- memcpy(Key, MpqKeyArray[i], MPQE_CHUNK_SIZE);
- BSWAP_ARRAY32_UNSIGNED(Key, MPQE_CHUNK_SIZE);
-
- // Try to decrypt with the given key
- memcpy(FileHeader, pbEncryptedHeader, MPQE_CHUNK_SIZE);
- DecryptFileChunk((LPDWORD)FileHeader, Key, ByteOffset, MPQE_CHUNK_SIZE);
-
- // We check the decrypted data
- // All known encrypted MPQs have header at the begin of the file,
- // so we check for MPQ signature there.
- if(FileHeader[0] == 'M' && FileHeader[1] == 'P' && FileHeader[2] == 'Q')
- return MpqKeyArray[i];
- }
-
- // Key not found, sorry
- return NULL;
-}
-
-static bool EncryptedStream_Read(
- TEncryptedStream * pStream, // Pointer to an open stream
- ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position
- void * pvBuffer, // Pointer to data to be read
- DWORD dwBytesToRead) // Number of bytes to read from the file
-{
- ULONGLONG StartOffset; // Offset of the first byte to be read from the file
- ULONGLONG ByteOffset; // Offset that the caller wants
- ULONGLONG EndOffset; // End offset that is to be read from the file
- DWORD dwBytesToAllocate;
- DWORD dwBytesToDecrypt;
- DWORD dwOffsetInCache;
- LPBYTE pbMpqData = NULL;
- bool bResult = false;
-
- // Get the byte offset
- if(pByteOffset == NULL)
- pStream->BaseGetPos(pStream, ByteOffset);
- else
- ByteOffset = *pByteOffset;
-
- // Cut it down to MPQE chunk size
- StartOffset = ByteOffset;
- StartOffset = StartOffset & ~(MPQE_CHUNK_SIZE - 1);
- EndOffset = ByteOffset + dwBytesToRead;
-
- // Calculate number of bytes to decrypt
- dwBytesToDecrypt = (DWORD)(EndOffset - StartOffset);
- dwBytesToAllocate = (dwBytesToDecrypt + (MPQE_CHUNK_SIZE - 1)) & ~(MPQE_CHUNK_SIZE - 1);
-
- // Allocate buffers for encrypted and decrypted data
- pbMpqData = STORM_ALLOC(BYTE, dwBytesToAllocate);
- if(pbMpqData)
- {
- // Get the offset of the desired data in the cache
- dwOffsetInCache = (DWORD)(ByteOffset - StartOffset);
-
- // Read the file from the stream as-is
- if(pStream->BaseRead(pStream, &StartOffset, pbMpqData, dwBytesToDecrypt))
- {
- // Decrypt the data
- DecryptFileChunk((LPDWORD)pbMpqData, pStream->Key, StartOffset, dwBytesToAllocate);
-
- // Copy the decrypted data
- memcpy(pvBuffer, pbMpqData + dwOffsetInCache, dwBytesToRead);
- bResult = true;
- }
- else
- {
- assert(false);
- }
-
- // Free decryption buffer
- STORM_FREE(pbMpqData);
- }
-
- // Free buffers and exit
- return bResult;
-}
-
-static bool EncryptedStream_Open(TEncryptedStream * pStream)
-{
- ULONGLONG ByteOffset = 0;
- BYTE EncryptedHeader[MPQE_CHUNK_SIZE];
- const char * szKey;
-
- // Sanity check
- assert(pStream->BaseRead != NULL);
-
- // Load one MPQE chunk and try to detect the file key
- if(pStream->BaseRead(pStream, &ByteOffset, EncryptedHeader, sizeof(EncryptedHeader)))
- {
- // Attempt to decrypt the MPQ header with all known keys
- szKey = DetectFileKey(EncryptedHeader);
- if(szKey != NULL)
- {
- // Copy the key for the file
- memcpy(pStream->Key, szKey, MPQE_CHUNK_SIZE);
- BSWAP_ARRAY32_UNSIGNED(pStream->Key, MPQE_CHUNK_SIZE);
-
- // Assign functions
- pStream->StreamRead = (STREAM_READ)EncryptedStream_Read;
- pStream->StreamGetPos = pStream->BaseGetPos;
- pStream->StreamGetSize = pStream->BaseGetSize;
- pStream->StreamGetTime = pStream->BaseGetTime;
- pStream->StreamGetBmp = (STREAM_GETBMP)Dummy_GetBitmap;
- pStream->StreamClose = pStream->BaseClose;
-
- // We need to reset the position back to the begin of the file
- pStream->BaseRead(pStream, &ByteOffset, EncryptedHeader, 0);
- return true;
- }
-
- // An unknown key
- SetLastError(ERROR_UNKNOWN_FILE_KEY);
- }
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// Public functions
-
-/**
- * This function creates a new file for read-write access
- *
- * - If the current platform supports file sharing,
- * the file must be created for read sharing (i.e. another application
- * can open the file for read, but not for write)
- * - If the file does not exist, the function must create new one
- * - If the file exists, the function must rewrite it and set to zero size
- * - The parameters of the function must be validate by the caller
- * - The function must initialize all stream function pointers in TFileStream
- * - If the function fails from any reason, it must close all handles
- * and free all memory that has been allocated in the process of stream creation,
- * including the TFileStream structure itself
- *
- * \a szFileName Name of the file to create
- */
-
-TFileStream * FileStream_CreateFile(
- const TCHAR * szFileName,
- DWORD dwStreamFlags)
-{
- TFileStream * pStream;
-
- // We only support creation of linear, local file
- if((dwStreamFlags & (STREAM_PROVIDER_MASK | BASE_PROVIDER_MASK)) != (STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE))
- {
- SetLastError(ERROR_NOT_SUPPORTED);
- return NULL;
- }
-
- // Allocate file stream structure for linear stream
- pStream = STORM_ALLOC(TFileStream, 1);
- if(pStream != NULL)
- {
- // Reset entire structure to zero
- memset(pStream, 0, sizeof(TFileStream));
- _tcscpy(pStream->szFileName, szFileName);
-
- // Attempt to create the disk file
- if(BaseFile_Create(pStream, szFileName, dwStreamFlags))
- {
- // Fill the stream provider functions
- pStream->StreamRead = pStream->BaseRead;
- pStream->StreamWrite = pStream->BaseWrite;
- pStream->StreamGetPos = pStream->BaseGetPos;
- pStream->StreamGetSize = pStream->BaseGetSize;
- pStream->StreamSetSize = pStream->BaseSetSize;
- pStream->StreamGetTime = pStream->BaseGetTime;
- pStream->StreamGetBmp = (STREAM_GETBMP)Dummy_GetBitmap;;
- pStream->StreamSwitch = (STREAM_SWITCH)LinearStream_Switch;
- pStream->StreamClose = pStream->BaseClose;
- return pStream;
- }
-
- // File create failed, delete the stream
- STORM_FREE(pStream);
- pStream = NULL;
- }
-
- // Return the stream
- return pStream;
-}
-
-/**
- * This function opens an existing file for read or read-write access
- * - If the current platform supports file sharing,
- * the file must be open for read sharing (i.e. another application
- * can open the file for read, but not for write)
- * - If the file does not exist, the function must return NULL
- * - If the file exists but cannot be open, then function must return NULL
- * - The parameters of the function must be validate by the caller
- * - The function must check if the file is a PART file,
- * and create TPartialStream object if so.
- * - The function must initialize all stream function pointers in TFileStream
- * - If the function fails from any reason, it must close all handles
- * and free all memory that has been allocated in the process of stream creation,
- * including the TFileStream structure itself
- *
- * \a szFileName Name of the file to open
- * \a dwStreamFlags specifies the provider and base storage type
- */
-
-TFileStream * FileStream_OpenFile(
- const TCHAR * szFileName,
- DWORD dwStreamFlags)
-{
- TFileStream * pStream = NULL;
- size_t StreamSize = 0;
- bool bStreamResult = false;
- bool bBaseResult = false;
-
- // Allocate file stream for each stream provider
- switch(dwStreamFlags & STREAM_PROVIDER_MASK)
- {
- case STREAM_PROVIDER_LINEAR: // Allocate structure for linear stream
- StreamSize = sizeof(TLinearStream);
- break;
-
- case STREAM_PROVIDER_PARTIAL:
- dwStreamFlags |= STREAM_FLAG_READ_ONLY;
- StreamSize = sizeof(TPartialStream);
- break;
-
- case STREAM_PROVIDER_ENCRYPTED:
- dwStreamFlags |= STREAM_FLAG_READ_ONLY;
- StreamSize = sizeof(TEncryptedStream);
- break;
-
- default:
- return NULL;
- }
-
- // Allocate the stream for each type
- pStream = (TFileStream *)STORM_ALLOC(BYTE, StreamSize);
- if(pStream == NULL)
- return NULL;
-
- // Fill the stream structure with zeros
- memset(pStream, 0, StreamSize);
- _tcscpy(pStream->szFileName, szFileName);
-
- // Now initialize the respective base provider
- switch(dwStreamFlags & BASE_PROVIDER_MASK)
- {
- case BASE_PROVIDER_FILE:
- bBaseResult = BaseFile_Open(pStream, szFileName, dwStreamFlags);
- break;
-
- case BASE_PROVIDER_MAP:
- dwStreamFlags |= STREAM_FLAG_READ_ONLY;
- bBaseResult = BaseMap_Open(pStream, szFileName, dwStreamFlags);
- break;
-
- case BASE_PROVIDER_HTTP:
- dwStreamFlags |= STREAM_FLAG_READ_ONLY;
- bBaseResult = BaseHttp_Open(pStream, szFileName, dwStreamFlags);
- break;
- }
-
- // If we failed to open the base storage, fail the operation
- if(bBaseResult == false)
- {
- STORM_FREE(pStream);
- return NULL;
- }
-
- // Now initialize the stream provider
- switch(dwStreamFlags & STREAM_PROVIDER_MASK)
- {
- case STREAM_PROVIDER_LINEAR:
- bStreamResult = LinearStream_Open((TLinearStream *)pStream);
- break;
-
- case STREAM_PROVIDER_PARTIAL:
- bStreamResult = PartialStream_Open((TPartialStream *)pStream);
- break;
-
- case STREAM_PROVIDER_ENCRYPTED:
- bStreamResult = EncryptedStream_Open((TEncryptedStream *)pStream);
- break;
- }
-
- // If the operation failed, free the stream and set it to NULL
- if(bStreamResult == false)
- {
- // Only close the base stream
- pStream->BaseClose(pStream);
- STORM_FREE(pStream);
- pStream = NULL;
- }
-
- return pStream;
-}
-
-/**
- * Reads data from the stream
- *
- * - Returns true if the read operation succeeded and all bytes have been read
- * - Returns false if either read failed or not all bytes have been read
- * - If the pByteOffset is NULL, the function must read the data from the current file position
- * - The function can be called with dwBytesToRead = 0. In that case, pvBuffer is ignored
- * and the function just adjusts file pointer.
- *
- * \a pStream Pointer to an open stream
- * \a pByteOffset Pointer to file byte offset. If NULL, it reads from the current position
- * \a pvBuffer Pointer to data to be read
- * \a dwBytesToRead Number of bytes to read from the file
- *
- * \returns
- * - If the function reads the required amount of bytes, it returns true.
- * - If the function reads less than required bytes, it returns false and GetLastError() returns ERROR_HANDLE_EOF
- * - If the function fails, it reads false and GetLastError() returns an error code different from ERROR_HANDLE_EOF
- */
-bool FileStream_Read(TFileStream * pStream, ULONGLONG * pByteOffset, void * pvBuffer, DWORD dwBytesToRead)
-{
- assert(pStream->StreamRead != NULL);
- return pStream->StreamRead(pStream, pByteOffset, pvBuffer, dwBytesToRead);
-}
-
-/**
- * This function writes data to the stream
- *
- * - Returns true if the write operation succeeded and all bytes have been written
- * - Returns false if either write failed or not all bytes have been written
- * - If the pByteOffset is NULL, the function must write the data to the current file position
- *
- * \a pStream Pointer to an open stream
- * \a pByteOffset Pointer to file byte offset. If NULL, it reads from the current position
- * \a pvBuffer Pointer to data to be written
- * \a dwBytesToWrite Number of bytes to write to the file
- */
-bool FileStream_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const void * pvBuffer, DWORD dwBytesToWrite)
-{
- if(pStream->dwFlags & STREAM_FLAG_READ_ONLY)
- return false;
-
- assert(pStream->StreamWrite != NULL);
- return pStream->StreamWrite(pStream, pByteOffset, pvBuffer, dwBytesToWrite);
-}
-
-/**
- * This function returns the current file position
- * \a pStream
- * \a ByteOffset
- */
-bool FileStream_GetPos(TFileStream * pStream, ULONGLONG & ByteOffset)
-{
- assert(pStream->StreamGetPos != NULL);
- return pStream->StreamGetPos(pStream, ByteOffset);
-}
-
-/**
- * Returns the size of a file
- *
- * \a pStream Pointer to an open stream
- * \a FileSize Pointer where to store the file size
- */
-bool FileStream_GetSize(TFileStream * pStream, ULONGLONG & FileSize)
-{
- assert(pStream->StreamGetSize != NULL);
- return pStream->StreamGetSize(pStream, FileSize);
-}
-
-/**
- * Sets the size of a file
- *
- * \a pStream Pointer to an open stream
- * \a NewFileSize File size to set
- */
-bool FileStream_SetSize(TFileStream * pStream, ULONGLONG NewFileSize)
-{
- if(pStream->dwFlags & STREAM_FLAG_READ_ONLY)
- return false;
-
- assert(pStream->StreamSetSize != NULL);
- return pStream->StreamSetSize(pStream, NewFileSize);
-}
-
-/**
- * Returns the last write time of a file
- *
- * \a pStream Pointer to an open stream
- * \a pFileType Pointer where to store the file last write time
- */
-bool FileStream_GetTime(TFileStream * pStream, ULONGLONG * pFileTime)
-{
- assert(pStream->StreamGetTime != NULL);
- return pStream->StreamGetTime(pStream, pFileTime);
-}
-
-/**
- * Switches a stream with another. Used for final phase of archive compacting.
- * Performs these steps:
- *
- * 1) Closes the handle to the existing MPQ
- * 2) Renames the temporary MPQ to the original MPQ, overwrites existing one
- * 3) Opens the MPQ stores the handle and stream position to the new stream structure
- *
- * \a pStream Pointer to an open stream
- * \a pTempStream Temporary ("working") stream (created during archive compacting)
- */
-bool FileStream_Switch(TFileStream * pStream, TFileStream * pNewStream)
-{
- if(pStream->dwFlags & STREAM_FLAG_READ_ONLY)
- return false;
-
- assert(pStream->StreamSwitch != NULL);
- return pStream->StreamSwitch(pStream, pNewStream);
-}
-
-/**
- * Returns the file name of the stream
- *
- * \a pStream Pointer to an open stream
- */
-TCHAR * FileStream_GetFileName(TFileStream * pStream)
-{
- assert(pStream != NULL);
- return pStream->szFileName;
-}
-
-/**
- * Returns true if the stream is read-only
- *
- * \a pStream Pointer to an open stream
- */
-bool FileStream_IsReadOnly(TFileStream * pStream)
-{
- return (pStream->dwFlags & STREAM_FLAG_READ_ONLY) ? true : false;
-}
-
-/**
- * This function enabled a linear stream to include data bitmap.
- * Used by MPQs v 4.0 from WoW. Each file block is represented by
- * a bit in the bitmap. 1 means the block is present, 0 means it's not.
- *
- * \a pStream Pointer to an open stream
- * \a pBitmap Pointer to file bitmap
- */
-
-bool FileStream_SetBitmap(TFileStream * pStream, TFileBitmap * pBitmap)
-{
- TLinearStream * pLinearStream;
-
- // It must be a linear stream.
- if((pStream->dwFlags & STREAM_PROVIDER_MASK) != STREAM_PROVIDER_LINEAR)
- return false;
- pLinearStream = (TLinearStream *)pStream;
-
- // Two bitmaps are not allowed
- if(pLinearStream->pBitmap != NULL)
- return false;
-
- // We need to change some entry points
- pLinearStream->StreamRead = (STREAM_READ)LinearStream_Read;
- pLinearStream->StreamGetBmp = (STREAM_GETBMP)LinearStream_GetBitmap;
-
- // Using data bitmap renders the stream to be read only.
- pLinearStream->dwFlags |= STREAM_FLAG_READ_ONLY;
- pLinearStream->pBitmap = pBitmap;
- return true;
-}
-
-/**
- * This function retrieves the file bitmap. A file bitmap is an array
- * of bits, each bit representing one file block. A value of 1 means
- * that the block is present in the file, a value of 0 means that the
- * block is not present.
- *
- * \a pStream Pointer to an open stream
- * \a pBitmap Pointer to buffer where to store the file bitmap
- * \a Length Size of buffer pointed by pBitmap, in bytes
- * \a LengthNeeded If non-NULL, the function supplies the necessary byte size of the buffer
- */
-bool FileStream_GetBitmap(TFileStream * pStream, TFileBitmap * pBitmap, DWORD Length, LPDWORD LengthNeeded)
-{
- assert(pStream->StreamGetBmp != NULL);
- return pStream->StreamGetBmp(pStream, pBitmap, Length, LengthNeeded);
-}
-
-/**
- * This function closes an archive file and frees any data buffers
- * that have been allocated for stream management. The function must also
- * support partially allocated structure, i.e. one or more buffers
- * can be NULL, if there was an allocation failure during the process
- *
- * \a pStream Pointer to an open stream
- */
-void FileStream_Close(TFileStream * pStream)
-{
- // Check if the stream structure is allocated at all
- if(pStream != NULL)
- {
- // Close the stream provider.
- // This will also close the base stream
- assert(pStream->StreamClose != NULL);
- pStream->StreamClose(pStream);
-
- // Free the stream itself
- STORM_FREE(pStream);
- }
-}
-
-//-----------------------------------------------------------------------------
-// main - for testing purposes
-
-#ifdef __STORMLIB_TEST__
-int FileStream_Test(const TCHAR * szFileName, DWORD dwStreamFlags)
-{
- TFileStream * pStream;
- TMPQHeader MpqHeader;
- ULONGLONG FilePos;
- TMPQBlock * pBlock;
- TMPQHash * pHash;
-
- InitializeMpqCryptography();
-
- pStream = FileStream_OpenFile(szFileName, dwStreamFlags);
- if(pStream == NULL)
- return GetLastError();
-
- // Read the MPQ header
- FileStream_Read(pStream, NULL, &MpqHeader, MPQ_HEADER_SIZE_V2);
- if(MpqHeader.dwID != ID_MPQ)
- return ERROR_FILE_CORRUPT;
-
- // Read the hash table
- pHash = STORM_ALLOC(TMPQHash, MpqHeader.dwHashTableSize);
- if(pHash != NULL)
- {
- FilePos = MpqHeader.dwHashTablePos;
- FileStream_Read(pStream, &FilePos, pHash, MpqHeader.dwHashTableSize * sizeof(TMPQHash));
- DecryptMpqBlock(pHash, MpqHeader.dwHashTableSize * sizeof(TMPQHash), MPQ_KEY_HASH_TABLE);
- STORM_FREE(pHash);
- }
-
- // Read the block table
- pBlock = STORM_ALLOC(TMPQBlock, MpqHeader.dwBlockTableSize);
- if(pBlock != NULL)
- {
- FilePos = MpqHeader.dwBlockTablePos;
- FileStream_Read(pStream, &FilePos, pBlock, MpqHeader.dwBlockTableSize * sizeof(TMPQBlock));
- DecryptMpqBlock(pBlock, MpqHeader.dwBlockTableSize * sizeof(TMPQBlock), MPQ_KEY_BLOCK_TABLE);
- STORM_FREE(pBlock);
- }
-
- FileStream_Close(pStream);
- return ERROR_SUCCESS;
-}
-#endif
-
-/*
-int FileStream_Test()
-{
- TFileStream * pStream;
-
- InitializeMpqCryptography();
-
- //
- // Test 1: Write to a stream
- //
-
- pStream = FileStream_CreateFile("E:\\Stream.bin", 0);
- if(pStream != NULL)
- {
- char szString1[100] = "This is a single line\n\r";
- DWORD dwLength = strlen(szString1);
-
- for(int i = 0; i < 10; i++)
- {
- if(!FileStream_Write(pStream, NULL, szString1, dwLength))
- {
- printf("Failed to write to the stream\n");
- return ERROR_CAN_NOT_COMPLETE;
- }
- }
- FileStream_Close(pStream);
- }
-
- //
- // Test2: Read from the stream
- //
-
- pStream = FileStream_OpenFile("E:\\Stream.bin", STREAM_FLAG_READ_ONLY | STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
- if(pStream != NULL)
- {
- char szString1[100] = "This is a single line\n\r";
- char szString2[100];
- DWORD dwLength = strlen(szString1);
-
- // This call must end with an error
- if(FileStream_Write(pStream, NULL, "aaa", 3))
- {
- printf("Write succeeded while it should fail\n");
- return -1;
- }
-
- for(int i = 0; i < 10; i++)
- {
- if(!FileStream_Read(pStream, NULL, szString2, dwLength))
- {
- printf("Failed to read from the stream\n");
- return -1;
- }
-
- szString2[dwLength] = 0;
- if(strcmp(szString1, szString2))
- {
- printf("Data read from file are different from data written\n");
- return -1;
- }
- }
- FileStream_Close(pStream);
- }
-
- //
- // Test3: Open the temp stream, write some data and switch it to the original stream
- //
-
- pStream = FileStream_OpenFile("E:\\Stream.bin", STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
- if(pStream != NULL)
- {
- TFileStream * pTempStream;
- ULONGLONG FileSize;
-
- pTempStream = FileStream_CreateFile("E:\\TempStream.bin", 0);
- if(pTempStream == NULL)
- {
- printf("Failed to create temp stream\n");
- return -1;
- }
-
- // Copy the original stream to the temp
- if(!FileStream_GetSize(pStream, FileSize))
- {
- printf("Failed to get the file size\n");
- return -1;
- }
-
- while(FileSize != 0)
- {
- DWORD dwBytesToRead = (DWORD)FileSize;
- char Buffer[0x80];
-
- if(dwBytesToRead > sizeof(Buffer))
- dwBytesToRead = sizeof(Buffer);
-
- if(!FileStream_Read(pStream, NULL, Buffer, dwBytesToRead))
- {
- printf("CopyStream: Read source file failed\n");
- return -1;
- }
-
- if(!FileStream_Write(pTempStream, NULL, Buffer, dwBytesToRead))
- {
- printf("CopyStream: Write target file failed\n");
- return -1;
- }
-
- FileSize -= dwBytesToRead;
- }
-
- // Switch the streams
- // Note that the pTempStream is closed by the operation
- FileStream_Switch(pStream, pTempStream);
- FileStream_Close(pStream);
- }
-
- //
- // Test4: Read from the stream again
- //
-
- pStream = FileStream_OpenFile("E:\\Stream.bin", STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
- if(pStream != NULL)
- {
- char szString1[100] = "This is a single line\n\r";
- char szString2[100];
- DWORD dwLength = strlen(szString1);
-
- for(int i = 0; i < 10; i++)
- {
- if(!FileStream_Read(pStream, NULL, szString2, dwLength))
- {
- printf("Failed to read from the stream\n");
- return -1;
- }
-
- szString2[dwLength] = 0;
- if(strcmp(szString1, szString2))
- {
- printf("Data read from file are different from data written\n");
- return -1;
- }
- }
- FileStream_Close(pStream);
- }
-
- return 0;
-}
-*/
-
diff --git a/dep/StormLib/src/FileStream.h b/dep/StormLib/src/FileStream.h
deleted file mode 100644
index 31fe757514d..00000000000
--- a/dep/StormLib/src/FileStream.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*****************************************************************************/
-/* FileStream.h Copyright (c) Ladislav Zezula 2012 */
-/*---------------------------------------------------------------------------*/
-/* Description: Definitions for FileStream object */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 14.04.12 1.00 Lad The first version of FileStream.h */
-/*****************************************************************************/
-
-#ifndef __FILESTREAM_H__
-#define __FILESTREAM_H__
-
-//-----------------------------------------------------------------------------
-// Function prototypes
-
-typedef bool (*STREAM_READ)(
- struct TFileStream * pStream, // Pointer to an open stream
- ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position
- void * pvBuffer, // Pointer to data to be read
- DWORD dwBytesToRead // Number of bytes to read from the file
- );
-
-typedef bool (*STREAM_WRITE)(
- struct TFileStream * pStream, // Pointer to an open stream
- ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it writes to the current position
- const void * pvBuffer, // Pointer to data to be written
- DWORD dwBytesToWrite // Number of bytes to read from the file
- );
-
-typedef bool (*STREAM_GETPOS)(
- struct TFileStream * pStream, // Pointer to an open stream
- ULONGLONG & ByteOffset // Pointer to store current file position
- );
-
-typedef bool (*STREAM_GETSIZE)(
- struct TFileStream * pStream, // Pointer to an open stream
- ULONGLONG & FileSize // Receives the file size, in bytes
- );
-
-typedef bool (*STREAM_SETSIZE)(
- struct TFileStream * pStream, // Pointer to an open stream
- ULONGLONG FileSize // New size for the file, in bytes
- );
-
-typedef bool (*STREAM_GETTIME)(
- struct TFileStream * pStream,
- ULONGLONG * pFT
- );
-
-typedef bool (*STREAM_SWITCH)(
- struct TFileStream * pStream,
- struct TFileStream * pNewStream
- );
-
-typedef bool (*STREAM_GETBMP)(
- TFileStream * pStream,
- TFileBitmap * pBitmap,
- DWORD Length,
- LPDWORD LengthNeeded
- );
-
-typedef void (*STREAM_CLOSE)(
- struct TFileStream * pStream
- );
-
-//-----------------------------------------------------------------------------
-// Local structures - part file structure
-
-typedef struct _PART_FILE_HEADER
-{
- DWORD PartialVersion; // Always set to 2
- char GameBuildNumber[0x20]; // Minimum build number of the game that can use this MPQ
- DWORD Flags; // Flags (details unknown)
- DWORD FileSizeLo; // Low 32 bits of the contained file size
- DWORD FileSizeHi; // High 32 bits of the contained file size
- DWORD BlockSize; // Size of one file block, in bytes
-
-} PART_FILE_HEADER, *PPART_FILE_HEADER;
-
-// Structure describing the block-to-file map entry
-typedef struct _PART_FILE_MAP_ENTRY
-{
- DWORD Flags; // 3 = the block is present in the file
- DWORD BlockOffsLo; // Low 32 bits of the block position in the file
- DWORD BlockOffsHi; // High 32 bits of the block position in the file
- DWORD LargeValueLo; // 64-bit value, meaning is unknown
- DWORD LargeValueHi;
-
-} PART_FILE_MAP_ENTRY, *PPART_FILE_MAP_ENTRY;
-
-//-----------------------------------------------------------------------------
-// Local structures
-
-union TBaseData
-{
- struct
- {
- ULONGLONG FileSize; // Size of the file
- ULONGLONG FilePos; // Current file position
- ULONGLONG FileTime; // Date/time of last modification of the file
- HANDLE hFile; // File handle
- } File;
-
- struct
- {
- ULONGLONG FileSize; // Mapped file size
- ULONGLONG FilePos; // Current stream position
- ULONGLONG FileTime; // Date/time of last modification of the file
- LPBYTE pbFile; // Pointer to mapped view
- } Map;
-
- struct
- {
- ULONGLONG FileSize; // Size of the internet file
- ULONGLONG FilePos; // Current position in the file
- ULONGLONG FileTime; // Date/time of last modification of the file
- HANDLE hInternet; // Internet handle
- HANDLE hConnect; // Connection to the internet server
- } Http;
-};
-
-//-----------------------------------------------------------------------------
-// Structure for linear stream
-
-struct TFileStream
-{
- // Stream provider functions
- STREAM_READ StreamRead; // Pointer to stream read function for this archive. Do not use directly.
- STREAM_WRITE StreamWrite; // Pointer to stream write function for this archive. Do not use directly.
- STREAM_GETPOS StreamGetPos; // Pointer to function that returns current file position
- STREAM_GETSIZE StreamGetSize; // Pointer to function returning file size
- STREAM_SETSIZE StreamSetSize; // Pointer to function changing file size
- STREAM_GETTIME StreamGetTime; // Pointer to function retrieving the file time
- STREAM_GETBMP StreamGetBmp; // Pointer to function that retrieves the file bitmap
- STREAM_SWITCH StreamSwitch; // Pointer to function changing the stream to another file
- STREAM_CLOSE StreamClose; // Pointer to function closing the stream
-
- // Stream provider data members
- TCHAR szFileName[MAX_PATH]; // File name
- DWORD dwFlags; // Stream flags
-
- // Base provider functions
- STREAM_READ BaseRead;
- STREAM_WRITE BaseWrite;
- STREAM_GETPOS BaseGetPos; // Pointer to function that returns current file position
- STREAM_GETSIZE BaseGetSize; // Pointer to function returning file size
- STREAM_SETSIZE BaseSetSize; // Pointer to function changing file size
- STREAM_GETTIME BaseGetTime; // Pointer to function retrieving the file time
- STREAM_CLOSE BaseClose; // Pointer to function closing the stream
-
- // Base provider data members
- TBaseData Base; // Base provider data
-
- // Followed by stream provider data, with variable length
-};
-
-//-----------------------------------------------------------------------------
-// Structure for linear stream
-
-struct TLinearStream : public TFileStream
-{
- TFileBitmap * pBitmap; // Pointer to the stream bitmap
-};
-
-//-----------------------------------------------------------------------------
-// Structure for partial stream
-
-struct TPartialStream : public TFileStream
-{
- ULONGLONG VirtualSize; // Virtual size of the file
- ULONGLONG VirtualPos; // Virtual position in the file
- DWORD BlockCount; // Number of file blocks. Used by partial file stream
- DWORD BlockSize; // Size of one block. Used by partial file stream
-
- PPART_FILE_MAP_ENTRY PartMap; // File map, variable length
-};
-
-//-----------------------------------------------------------------------------
-// Structure for encrypted stream
-
-#define MPQE_CHUNK_SIZE 0x40 // Size of one chunk to be decrypted
-
-struct TEncryptedStream : public TFileStream
-{
- BYTE Key[MPQE_CHUNK_SIZE]; // File key
-};
-
-#endif // __FILESTREAM_H__
diff --git a/dep/StormLib/src/SBaseCommon.cpp b/dep/StormLib/src/SBaseCommon.cpp
deleted file mode 100644
index 65818784521..00000000000
--- a/dep/StormLib/src/SBaseCommon.cpp
+++ /dev/null
@@ -1,1700 +0,0 @@
-/*****************************************************************************/
-/* SBaseCommon.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Common functions for StormLib, used by all SFile*** modules */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 24.03.03 1.00 Lad The first version of SFileCommon.cpp */
-/* 19.11.03 1.01 Dan Big endian handling */
-/* 12.06.04 1.01 Lad Renamed to SCommon.cpp */
-/* 06.09.10 1.01 Lad Renamed to SBaseCommon.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "StormCommon.h"
-
-char StormLibCopyright[] = "StormLib v " STORMLIB_VERSION_STRING " Copyright Ladislav Zezula 1998-2012";
-
-//-----------------------------------------------------------------------------
-// The buffer for decryption engine.
-
-LCID lcFileLocale = LANG_NEUTRAL; // File locale
-USHORT wPlatform = 0; // File platform
-
-//-----------------------------------------------------------------------------
-// Storm buffer functions
-
-#define STORM_BUFFER_SIZE 0x500
-
-static DWORD StormBuffer[STORM_BUFFER_SIZE]; // Buffer for the decryption engine
-static bool bMpqCryptographyInitialized = false;
-
-DWORD HashString(const char * szFileName, DWORD dwHashType)
-{
- LPBYTE pbKey = (BYTE *)szFileName;
- DWORD dwSeed1 = 0x7FED7FED;
- DWORD dwSeed2 = 0xEEEEEEEE;
- DWORD ch;
-
- while(*pbKey != 0)
- {
- ch = toupper(*pbKey++);
-
- dwSeed1 = StormBuffer[dwHashType + ch] ^ (dwSeed1 + dwSeed2);
- dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3;
- }
-
- return dwSeed1;
-}
-
-void InitializeMpqCryptography()
-{
- DWORD dwSeed = 0x00100001;
- DWORD index1 = 0;
- DWORD index2 = 0;
- int i;
-
- // Initialize the decryption buffer.
- // Do nothing if already done.
- if(bMpqCryptographyInitialized == false)
- {
- for(index1 = 0; index1 < 0x100; index1++)
- {
- for(index2 = index1, i = 0; i < 5; i++, index2 += 0x100)
- {
- DWORD temp1, temp2;
-
- dwSeed = (dwSeed * 125 + 3) % 0x2AAAAB;
- temp1 = (dwSeed & 0xFFFF) << 0x10;
-
- dwSeed = (dwSeed * 125 + 3) % 0x2AAAAB;
- temp2 = (dwSeed & 0xFFFF);
-
- StormBuffer[index2] = (temp1 | temp2);
- }
- }
-
- // Also register both MD5 and SHA1 hash algorithms
- register_hash(&md5_desc);
- register_hash(&sha1_desc);
-
- // Use LibTomMath as support math library for LibTomCrypt
- ltc_mp = ltm_desc;
-
- // Don't do that again
- bMpqCryptographyInitialized = true;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Calculates the hash table size for a given amount of files
-
-DWORD GetHashTableSizeForFileCount(DWORD dwFileCount)
-{
- DWORD dwPowerOfTwo;
-
- // Round the hash table size up to the nearest power of two
- for(dwPowerOfTwo = HASH_TABLE_SIZE_MIN; dwPowerOfTwo < HASH_TABLE_SIZE_MAX; dwPowerOfTwo <<= 1)
- {
- if(dwPowerOfTwo >= dwFileCount)
- {
- return dwPowerOfTwo;
- }
- }
-
- // Don't allow the hash table size go over allowed maximum
- return HASH_TABLE_SIZE_MAX;
-}
-
-//-----------------------------------------------------------------------------
-// Calculates a Jenkin's Encrypting and decrypting MPQ file data
-
-ULONGLONG HashStringJenkins(const char * szFileName)
-{
- char * szTemp;
- char szLocFileName[0x108];
- char chOneChar;
- size_t nLength = 0;
- unsigned int primary_hash = 1;
- unsigned int secondary_hash = 2;
-
- // This is required to produce defined results
- assert(szFileName != NULL);
-
- // Normalize the file name - convert to uppercase, and convert "/" to "\\".
- if(szFileName != NULL)
- {
- szTemp = szLocFileName;
- while(*szFileName != 0)
- {
- chOneChar = (char)tolower(*szFileName++);
- if(chOneChar == '/')
- chOneChar = '\\';
-
- *szTemp++ = chOneChar;
- }
-
- nLength = szTemp - szLocFileName;
- *szTemp = 0;
- }
-
- // Thanks Quantam for finding out what the algorithm is.
- // I am really getting old for reversing large chunks of assembly
- // that does hashing :-)
- hashlittle2(szLocFileName, nLength, &secondary_hash, &primary_hash);
-
- // Combine those 2 together
- return (ULONGLONG)primary_hash * (ULONGLONG)0x100000000ULL + (ULONGLONG)secondary_hash;
-}
-
-//-----------------------------------------------------------------------------
-// This function converts the MPQ header so it always looks like version 4
-
-int ConvertMpqHeaderToFormat4(
- TMPQArchive * ha,
- ULONGLONG FileSize,
- DWORD dwFlags)
-{
- ULONGLONG ByteOffset;
- TMPQHeader * pHeader = ha->pHeader;
- DWORD dwExpectedArchiveSize;
- USHORT wFormatVersion = pHeader->wFormatVersion;
- int nError = ERROR_SUCCESS;
-
- // If version 1.0 is forced, then the format version is forced to be 1.0
- // Reason: Storm.dll in Warcraft III ignores format version value
- if(dwFlags & MPQ_OPEN_FORCE_MPQ_V1)
- wFormatVersion = MPQ_FORMAT_VERSION_1;
-
- // Format-specific fixes
- switch(wFormatVersion)
- {
- case MPQ_FORMAT_VERSION_1:
-
- // Check for malformed MPQ header version 1.0
- if(pHeader->dwHeaderSize != MPQ_HEADER_SIZE_V1)
- {
- pHeader->dwHeaderSize = MPQ_HEADER_SIZE_V1;
- ha->dwFlags |= MPQ_FLAG_PROTECTED;
- }
-
- //
- // The value of "dwArchiveSize" member in the MPQ header
- // is ignored by Storm.dll and can contain garbage value
- // ("w3xmaster" protector).
- //
-
- dwExpectedArchiveSize = (DWORD)(FileSize - ha->MpqPos);
- if(pHeader->dwArchiveSize != dwExpectedArchiveSize)
- {
- // Note: dwExpectedArchiveSize might be incorrect at this point.
- // MPQs version 1.0 can have strong digital signature appended at the end,
- // or they might just have arbitrary data there.
- // In either case, we recalculate the archive size later when
- // block table is loaded and positions of all files is known.
- pHeader->dwArchiveSize = dwExpectedArchiveSize;
- ha->dwFlags |= MPQ_FLAG_NEED_FIX_SIZE;
- }
-
- // Zero the fields in 2.0 part of the MPQ header
- pHeader->HiBlockTablePos64 = 0;
- pHeader->wHashTablePosHi = 0;
- pHeader->wBlockTablePosHi = 0;
- // No break here !!!
-
- case MPQ_FORMAT_VERSION_2:
- case MPQ_FORMAT_VERSION_3:
-
- // In MPQ format 3.0, the entire header is optional
- // and the size of the header can actually be identical
- // to size of header 2.0
- if(pHeader->dwHeaderSize < MPQ_HEADER_SIZE_V3)
- {
- ULONGLONG ArchiveSize64 = pHeader->dwArchiveSize;
-
- // In format 2.0, the archive size is obsolete and is calculated
- // as the highest offset of hash table, block table or hi-block table.
- // However, we can still rely on it, if the size of the archive is under 4 GB
- if((FileSize - ha->MpqPos) >> 32)
- {
- ByteOffset = MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos) + (pHeader->dwHashTableSize * sizeof(TMPQHash));
- if(ByteOffset > ArchiveSize64)
- ArchiveSize64 = ByteOffset;
-
- ByteOffset = MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos) + (pHeader->dwBlockTableSize * sizeof(TMPQBlock));
- if(ByteOffset > ArchiveSize64)
- ArchiveSize64 = ByteOffset;
-
- // Only if we actually have a hi-block table
- if(pHeader->HiBlockTablePos64)
- {
- ByteOffset = pHeader->HiBlockTablePos64 + (pHeader->dwBlockTableSize * sizeof(USHORT));
- if(ByteOffset > ArchiveSize64)
- ArchiveSize64 = ByteOffset;
- }
-
- // We need to recalculate archive size later,
- // when block table is loaded and the position of files is known
- ha->dwFlags |= MPQ_FLAG_NEED_FIX_SIZE;
- }
-
- // Initialize the rest of the 3.0 header
- pHeader->ArchiveSize64 = ArchiveSize64;
- pHeader->HetTablePos64 = 0;
- pHeader->BetTablePos64 = 0;
- }
-
- //
- // Calculate compressed size of each table. We assume the following order:
- // 1) HET table
- // 2) BET table
- // 3) Classic hash table
- // 4) Classic block table
- // 5) Hi-block table
- //
-
- // Set all sizes to zero
- pHeader->HetTableSize64 = 0;
- pHeader->BetTableSize64 = 0;
-
- // Either both HET and BET table exist or none of them does.
- if(pHeader->HetTablePos64)
- {
- // Compressed size of the HET and BET tables
- pHeader->HetTableSize64 = pHeader->BetTablePos64 - pHeader->HetTablePos64;
- pHeader->BetTableSize64 = MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos) - pHeader->HetTablePos64;
- }
-
- // Compressed size of hash and block table
- if(wFormatVersion >= MPQ_FORMAT_VERSION_2)
- {
- // Compressed size of the hash table
- pHeader->HashTableSize64 = MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos) - MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos);
-
- // Block and hi-block table
- if(pHeader->HiBlockTablePos64)
- {
- pHeader->BlockTableSize64 = pHeader->HiBlockTablePos64 - MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
- pHeader->HiBlockTableSize64 = pHeader->ArchiveSize64 - pHeader->HiBlockTablePos64;
- }
- else
- {
- pHeader->BlockTableSize64 = pHeader->ArchiveSize64 - MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
- pHeader->HiBlockTableSize64 = 0;
- }
- }
- else
- {
- // No known MPQ in format 1.0 has any of the tables compressed
- pHeader->HashTableSize64 = pHeader->dwHashTableSize * sizeof(TMPQHash);
- pHeader->BlockTableSize64 = pHeader->dwBlockTableSize * sizeof(TMPQBlock);
- pHeader->HiBlockTableSize64 = 0;
- }
-
- // Set the data chunk size for MD5 to zero
- pHeader->dwRawChunkSize = 0;
-
- // Fill the MD5's
- memset(pHeader->MD5_BlockTable, 0, MD5_DIGEST_SIZE);
- memset(pHeader->MD5_HashTable, 0, MD5_DIGEST_SIZE);
- memset(pHeader->MD5_HiBlockTable, 0, MD5_DIGEST_SIZE);
- memset(pHeader->MD5_BetTable, 0, MD5_DIGEST_SIZE);
- memset(pHeader->MD5_HetTable, 0, MD5_DIGEST_SIZE);
- memset(pHeader->MD5_MpqHeader, 0, MD5_DIGEST_SIZE);
- // No break here !!!!
-
- case MPQ_FORMAT_VERSION_4:
-
- // Verify header MD5. Header MD5 is calculated from the MPQ header since the 'MPQ\x1A'
- // signature until the position of header MD5 at offset 0xC0
- if(!VerifyDataBlockHash(ha->pHeader, MPQ_HEADER_SIZE_V4 - MD5_DIGEST_SIZE, ha->pHeader->MD5_MpqHeader))
- nError = ERROR_FILE_CORRUPT;
- break;
- }
-
- return nError;
-}
-
-//-----------------------------------------------------------------------------
-// Default flags for (attributes) and (listfile)
-
-DWORD GetDefaultSpecialFileFlags(TMPQArchive * ha, DWORD dwFileSize)
-{
- // Fixed for format 1.0
- if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1)
- return MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY;
-
- // Size-dependent for formats 2.0-4.0
- return (dwFileSize > 0x4000) ? (MPQ_FILE_COMPRESS | MPQ_FILE_SECTOR_CRC) : (MPQ_FILE_COMPRESS | MPQ_FILE_SINGLE_UNIT);
-}
-
-
-//-----------------------------------------------------------------------------
-// Encrypting and decrypting MPQ file data
-
-void EncryptMpqBlock(void * pvFileBlock, DWORD dwLength, DWORD dwSeed1)
-{
- LPDWORD block = (LPDWORD)pvFileBlock;
- DWORD dwSeed2 = 0xEEEEEEEE;
- DWORD ch;
-
- // Round to DWORDs
- dwLength >>= 2;
-
- while(dwLength-- > 0)
- {
- dwSeed2 += StormBuffer[0x400 + (dwSeed1 & 0xFF)];
- ch = *block;
- *block++ = ch ^ (dwSeed1 + dwSeed2);
-
- dwSeed1 = ((~dwSeed1 << 0x15) + 0x11111111) | (dwSeed1 >> 0x0B);
- dwSeed2 = ch + dwSeed2 + (dwSeed2 << 5) + 3;
- }
-}
-
-void DecryptMpqBlock(void * pvFileBlock, DWORD dwLength, DWORD dwSeed1)
-{
- LPDWORD block = (LPDWORD)pvFileBlock;
- DWORD dwSeed2 = 0xEEEEEEEE;
- DWORD ch;
-
- // Round to DWORDs
- dwLength >>= 2;
-
- while(dwLength-- > 0)
- {
- dwSeed2 += StormBuffer[0x400 + (dwSeed1 & 0xFF)];
- ch = *block ^ (dwSeed1 + dwSeed2);
-
- dwSeed1 = ((~dwSeed1 << 0x15) + 0x11111111) | (dwSeed1 >> 0x0B);
- dwSeed2 = ch + dwSeed2 + (dwSeed2 << 5) + 3;
- *block++ = ch;
- }
-}
-
-/*
-void EncryptMpqTable(void * pvMpqTable, DWORD dwLength, const char * szKey)
-{
- EncryptMpqBlock(pvMpqTable, dwLength, HashString(szKey, MPQ_HASH_FILE_KEY));
-}
-
-void DecryptMpqTable(void * pvMpqTable, DWORD dwLength, const char * szKey)
-{
- DecryptMpqBlock(pvMpqTable, dwLength, HashString(szKey, MPQ_HASH_FILE_KEY));
-}
-*/
-
-/**
- * Functions tries to get file decryption key. The trick comes from sector
- * positions which are stored at the begin of each compressed file. We know the
- * file size, that means we know number of sectors that means we know the first
- * DWORD value in sector position. And if we know encrypted and decrypted value,
- * we can find the decryption key !!!
- *
- * hf - MPQ file handle
- * SectorOffsets - DWORD array of sector positions
- * ch - Decrypted value of the first sector pos
- */
-
-DWORD DetectFileKeyBySectorSize(LPDWORD SectorOffsets, DWORD decrypted)
-{
- DWORD saveKey1;
- DWORD temp = *SectorOffsets ^ decrypted; // temp = seed1 + seed2
- temp -= 0xEEEEEEEE; // temp = seed1 + StormBuffer[0x400 + (seed1 & 0xFF)]
-
- for(int i = 0; i < 0x100; i++) // Try all 255 possibilities
- {
- DWORD seed1;
- DWORD seed2 = 0xEEEEEEEE;
- DWORD ch;
-
- // Try the first DWORD (We exactly know the value)
- seed1 = temp - StormBuffer[0x400 + i];
- seed2 += StormBuffer[0x400 + (seed1 & 0xFF)];
- ch = SectorOffsets[0] ^ (seed1 + seed2);
-
- if(ch != decrypted)
- continue;
-
- // Add 1 because we are decrypting sector positions
- saveKey1 = seed1 + 1;
-
- // If OK, continue and test the second value. We don't know exactly the value,
- // but we know that the second one has lower 16 bits set to zero
- // (no compressed sector is larger than 0xFFFF bytes)
- seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B);
- seed2 = ch + seed2 + (seed2 << 5) + 3;
-
- seed2 += StormBuffer[0x400 + (seed1 & 0xFF)];
- ch = SectorOffsets[1] ^ (seed1 + seed2);
-
- if((ch & 0xFFFF0000) == 0)
- return saveKey1;
- }
- return 0;
-}
-
-// Function tries to detect file encryption key. It expectes at least two uncompressed bytes
-DWORD DetectFileKeyByKnownContent(void * pvFileContent, DWORD nDwords, ...)
-{
- LPDWORD pdwContent = (LPDWORD)pvFileContent;
- va_list argList;
- DWORD dwDecrypted[0x10];
- DWORD saveKey1;
- DWORD dwTemp;
- DWORD i, j;
-
- // We need at least two DWORDS to detect the file key
- if(nDwords < 0x02 || nDwords > 0x10)
- return 0;
-
- va_start(argList, nDwords);
- for(i = 0; i < nDwords; i++)
- dwDecrypted[i] = va_arg(argList, DWORD);
- va_end(argList);
-
- dwTemp = (*pdwContent ^ dwDecrypted[0]) - 0xEEEEEEEE;
- for(i = 0; i < 0x100; i++) // Try all 256 possibilities
- {
- DWORD seed1;
- DWORD seed2 = 0xEEEEEEEE;
- DWORD ch;
-
- // Try the first DWORD
- seed1 = dwTemp - StormBuffer[0x400 + i];
- seed2 += StormBuffer[0x400 + (seed1 & 0xFF)];
- ch = pdwContent[0] ^ (seed1 + seed2);
-
- if(ch != dwDecrypted[0])
- continue;
-
- saveKey1 = seed1;
-
- // If OK, continue and test all bytes.
- for(j = 1; j < nDwords; j++)
- {
- seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B);
- seed2 = ch + seed2 + (seed2 << 5) + 3;
-
- seed2 += StormBuffer[0x400 + (seed1 & 0xFF)];
- ch = pdwContent[j] ^ (seed1 + seed2);
-
- if(ch == dwDecrypted[j] && j == nDwords - 1)
- return saveKey1;
- }
- }
- return 0;
-}
-
-DWORD DetectFileKeyByContent(void * pvFileContent, DWORD dwFileSize)
-{
- DWORD dwFileKey;
-
- // Try to break the file encryption key as if it was a WAVE file
- if(dwFileSize >= 0x0C)
- {
- dwFileKey = DetectFileKeyByKnownContent(pvFileContent, 3, 0x46464952, dwFileSize - 8, 0x45564157);
- if(dwFileKey != 0)
- return dwFileKey;
- }
-
- // Try to break the encryption key as if it was an EXE file
- if(dwFileSize > 0x40)
- {
- dwFileKey = DetectFileKeyByKnownContent(pvFileContent, 2, 0x00905A4D, 0x00000003);
- if(dwFileKey != 0)
- return dwFileKey;
- }
-
- // Try to break the encryption key as if it was a XML file
- if(dwFileSize > 0x04)
- {
- dwFileKey = DetectFileKeyByKnownContent(pvFileContent, 2, 0x6D783F3C, 0x6576206C);
- if(dwFileKey != 0)
- return dwFileKey;
- }
-
- // Not detected, sorry
- return 0;
-}
-
-DWORD DecryptFileKey(
- const char * szFileName,
- ULONGLONG MpqPos,
- DWORD dwFileSize,
- DWORD dwFlags)
-{
- DWORD dwFileKey;
- DWORD dwMpqPos = (DWORD)MpqPos;
-
- // File key is calculated from plain name
- szFileName = GetPlainFileNameA(szFileName);
- dwFileKey = HashString(szFileName, MPQ_HASH_FILE_KEY);
-
- // Fix the key, if needed
- if(dwFlags & MPQ_FILE_FIX_KEY)
- dwFileKey = (dwFileKey + dwMpqPos) ^ dwFileSize;
-
- // Return the key
- return dwFileKey;
-}
-
-//-----------------------------------------------------------------------------
-// Handle validation functions
-
-bool IsValidMpqHandle(TMPQArchive * ha)
-{
- if(ha == NULL)
- return false;
- if(ha->pHeader == NULL || ha->pHeader->dwID != ID_MPQ)
- return false;
-
- return (bool)(ha->pHeader->dwID == ID_MPQ);
-}
-
-bool IsValidFileHandle(TMPQFile * hf)
-{
- if(hf == NULL)
- return false;
-
- if(hf->dwMagic != ID_MPQ_FILE)
- return false;
-
- if(hf->pStream != NULL)
- return true;
-
- return IsValidMpqHandle(hf->ha);
-}
-
-//-----------------------------------------------------------------------------
-// Hash table and block table manipulation
-
-// Retrieves the first hash entry for the given file.
-// Every locale version of a file has its own hash entry
-TMPQHash * GetFirstHashEntry(TMPQArchive * ha, const char * szFileName)
-{
- TMPQHash * pStartHash; // File hash entry (start)
- TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize;
- TMPQHash * pHash; // File hash entry (current)
- DWORD dwHashTableSizeMask;
- DWORD dwIndex = HashString(szFileName, MPQ_HASH_TABLE_INDEX);
- DWORD dwName1 = HashString(szFileName, MPQ_HASH_NAME_A);
- DWORD dwName2 = HashString(szFileName, MPQ_HASH_NAME_B);
-
- // Get the first possible has entry that might be the one
- dwHashTableSizeMask = ha->pHeader->dwHashTableSize ? (ha->pHeader->dwHashTableSize - 1) : 0;
- pStartHash = pHash = ha->pHashTable + (dwIndex & dwHashTableSizeMask);
-
- // There might be deleted entries in the hash table prior to our desired entry.
- while(pHash->dwBlockIndex != HASH_ENTRY_FREE)
- {
- // If the entry agrees, we found it.
- if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && pHash->dwBlockIndex < ha->dwFileTableSize)
- return pHash;
-
- // Move to the next hash entry. Stop searching
- // if we got reached the original hash entry
- if(++pHash >= pHashEnd)
- pHash = ha->pHashTable;
- if(pHash == pStartHash)
- break;
- }
-
- // The apropriate hash entry was not found
- return NULL;
-}
-
-TMPQHash * GetNextHashEntry(TMPQArchive * ha, TMPQHash * pFirstHash, TMPQHash * pPrevHash)
-{
- TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize;
- TMPQHash * pHash = pPrevHash;
- DWORD dwName1 = pPrevHash->dwName1;
- DWORD dwName2 = pPrevHash->dwName2;
-
- // Now go for any next entry that follows the pPrevHash,
- // until either free hash entry was found, or the start entry was reached
- for(;;)
- {
- // Move to the next hash entry. Stop searching
- // if we got reached the original hash entry
- if(++pHash >= pHashEnd)
- pHash = ha->pHashTable;
- if(pHash == pFirstHash)
- break;
-
- // If the entry is a free entry, stop search
- if(pHash->dwBlockIndex == HASH_ENTRY_FREE)
- break;
-
- // If the entry is not free and the name agrees, we found it
- if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && pHash->dwBlockIndex < ha->pHeader->dwBlockTableSize)
- return pHash;
- }
-
- // No next entry
- return NULL;
-}
-
-// Allocates an entry in the hash table
-DWORD AllocateHashEntry(
- TMPQArchive * ha,
- TFileEntry * pFileEntry)
-{
- TMPQHash * pStartHash; // File hash entry (start)
- TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize;
- TMPQHash * pHash; // File hash entry (current)
- DWORD dwHashTableSizeMask;
- DWORD dwIndex = HashString(pFileEntry->szFileName, MPQ_HASH_TABLE_INDEX);
- DWORD dwName1 = HashString(pFileEntry->szFileName, MPQ_HASH_NAME_A);
- DWORD dwName2 = HashString(pFileEntry->szFileName, MPQ_HASH_NAME_B);
-
- // Get the first possible has entry that might be the one
- dwHashTableSizeMask = ha->pHeader->dwHashTableSize ? (ha->pHeader->dwHashTableSize - 1) : 0;
- pStartHash = pHash = ha->pHashTable + (dwIndex & dwHashTableSizeMask);
-
- // There might be deleted entries in the hash table prior to our desired entry.
- while(pHash->dwBlockIndex < HASH_ENTRY_DELETED)
- {
- // If there already is an existing entry, reuse it.
- if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && pHash->lcLocale == pFileEntry->lcLocale)
- break;
-
- // Move to the next hash entry.
- // If we reached the starting entry, it's failure.
- if(++pHash >= pHashEnd)
- pHash = ha->pHashTable;
- if(pHash == pStartHash)
- return HASH_ENTRY_FREE;
- }
-
- // Fill the free hash entry
- pHash->dwName1 = dwName1;
- pHash->dwName2 = dwName2;
- pHash->lcLocale = pFileEntry->lcLocale;
- pHash->wPlatform = pFileEntry->wPlatform;
- pHash->dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable);
-
- // Fill the hash index in the file entry
- pFileEntry->dwHashIndex = (DWORD)(pHash - ha->pHashTable);
- return pFileEntry->dwHashIndex;
-}
-
-// Finds a free space in the MPQ where to store next data
-// The free space begins beyond the file that is stored at the fuhrtest
-// position in the MPQ.
-void FindFreeMpqSpace(TMPQArchive * ha, ULONGLONG * pFreeSpacePos)
-{
- TMPQHeader * pHeader = ha->pHeader;
- TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
- TFileEntry * pFileEntry = ha->pFileTable;
- ULONGLONG FreeSpacePos = ha->pHeader->dwHeaderSize;
- DWORD dwChunkCount;
-
- // Parse the entire block table
- for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
- {
- // Only take existing files
- if(pFileEntry->dwFlags & MPQ_FILE_EXISTS)
- {
- // If the end of the file is bigger than current MPQ table pos, update it
- if((pFileEntry->ByteOffset + pFileEntry->dwCmpSize) > FreeSpacePos)
- {
- // Get the end of the file data
- FreeSpacePos = pFileEntry->ByteOffset + pFileEntry->dwCmpSize;
-
- // Add the MD5 chunks, if present
- if(pHeader->dwRawChunkSize != 0 && pFileEntry->dwCmpSize != 0)
- {
- dwChunkCount = ((pFileEntry->dwCmpSize - 1) / pHeader->dwRawChunkSize) + 1;
- FreeSpacePos += dwChunkCount * MD5_DIGEST_SIZE;
- }
- }
- }
- }
-
- // Give the free space position to the caller
- if(pFreeSpacePos != NULL)
- *pFreeSpacePos = FreeSpacePos;
-}
-
-//-----------------------------------------------------------------------------
-// Common functions - MPQ File
-
-TMPQFile * CreateMpqFile(TMPQArchive * ha)
-{
- TMPQFile * hf;
-
- // Allocate space for TMPQFile
- hf = STORM_ALLOC(TMPQFile, 1);
- if(hf != NULL)
- {
- // Fill the file structure
- memset(hf, 0, sizeof(TMPQFile));
- hf->ha = ha;
- hf->pStream = NULL;
- hf->dwMagic = ID_MPQ_FILE;
- }
-
- return hf;
-}
-
-// Loads a table from MPQ.
-// Can be used for hash table, block table, sector offset table or sector checksum table
-int LoadMpqTable(
- TMPQArchive * ha,
- ULONGLONG ByteOffset,
- void * pvTable,
- DWORD dwCompressedSize,
- DWORD dwRealSize,
- DWORD dwKey)
-{
- LPBYTE pbCompressed = NULL;
- LPBYTE pbToRead = (LPBYTE)pvTable;
- int nError = ERROR_SUCCESS;
-
- // "interface.MPQ.part" in trial version of World of Warcraft
- // has block table and hash table compressed.
- if(dwCompressedSize < dwRealSize)
- {
- // Allocate temporary buffer for holding compressed data
- pbCompressed = STORM_ALLOC(BYTE, dwCompressedSize);
- if(pbCompressed == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Assign the temporary buffer as target for read operation
- pbToRead = pbCompressed;
- }
-
- // Read the table
- if(FileStream_Read(ha->pStream, &ByteOffset, pbToRead, dwCompressedSize))
- {
- // First of all, decrypt the table
- if(dwKey != 0)
- {
- BSWAP_ARRAY32_UNSIGNED(pbToRead, dwCompressedSize);
- DecryptMpqBlock(pbToRead, dwCompressedSize, dwKey);
- BSWAP_ARRAY32_UNSIGNED(pbToRead, dwCompressedSize);
- }
-
- // If the table is compressed, decompress it
- if(dwCompressedSize < dwRealSize)
- {
- int cbOutBuffer = (int)dwRealSize;
- int cbInBuffer = (int)dwCompressedSize;
-
- if(!SCompDecompress2((char *)pvTable, &cbOutBuffer, (char *)pbCompressed, cbInBuffer))
- nError = GetLastError();
-
- // Free the temporary buffer
- STORM_FREE(pbCompressed);
- }
- }
- else
- {
- nError = GetLastError();
- }
-
- BSWAP_ARRAY32_UNSIGNED(pvTable, dwRealSize);
- return nError;
-}
-
-void CalculateRawSectorOffset(
- ULONGLONG & RawFilePos,
- TMPQFile * hf,
- DWORD dwSectorOffset)
-{
- //
- // Some MPQ protectors place the sector offset table after the actual file data.
- // Sector offsets in the sector offset table are negative. When added
- // to MPQ file offset from the block table entry, the result is a correct
- // position of the file data in the MPQ.
- //
- // The position of sector table must be always within the MPQ, however.
- // When a negative sector offset is found, we make sure that we make the addition
- // just in 32-bits, and then add the MPQ offset.
- //
-
- if(dwSectorOffset & 0x80000000)
- {
- RawFilePos = hf->ha->MpqPos + ((DWORD)hf->pFileEntry->ByteOffset + dwSectorOffset);
- }
- else
- {
- RawFilePos = hf->RawFilePos + dwSectorOffset;
- }
-
- // We also have to add patch header size, if patch header is present
- if(hf->pPatchInfo != NULL)
- RawFilePos += hf->pPatchInfo->dwLength;
-}
-
-unsigned char * AllocateMd5Buffer(
- DWORD dwRawDataSize,
- DWORD dwChunkSize,
- LPDWORD pcbMd5Size)
-{
- unsigned char * md5_array;
- DWORD cbMd5Size;
-
- // Sanity check
- assert(dwRawDataSize != 0);
- assert(dwChunkSize != 0);
-
- // Calculate how many MD5's we will calculate
- cbMd5Size = (((dwRawDataSize - 1) / dwChunkSize) + 1) * MD5_DIGEST_SIZE;
-
- // Allocate space for array or MD5s
- md5_array = STORM_ALLOC(BYTE, cbMd5Size);
-
- // Give the size of the MD5 array
- if(pcbMd5Size != NULL)
- *pcbMd5Size = cbMd5Size;
- return md5_array;
-}
-
-// Allocates sector buffer and sector offset table
-int AllocateSectorBuffer(TMPQFile * hf)
-{
- TMPQArchive * ha = hf->ha;
-
- // Caller of AllocateSectorBuffer must ensure these
- assert(hf->pbFileSector == NULL);
- assert(hf->pFileEntry != NULL);
- assert(hf->ha != NULL);
-
- // Don't allocate anything if the file has zero size
- if(hf->pFileEntry->dwFileSize == 0 || hf->dwDataSize == 0)
- return ERROR_SUCCESS;
-
- // Determine the file sector size and allocate buffer for it
- hf->dwSectorSize = (hf->pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) ? hf->dwDataSize : ha->dwSectorSize;
- hf->pbFileSector = STORM_ALLOC(BYTE, hf->dwSectorSize);
- hf->dwSectorOffs = SFILE_INVALID_POS;
-
- // Return result
- return (hf->pbFileSector != NULL) ? (int)ERROR_SUCCESS : (int)ERROR_NOT_ENOUGH_MEMORY;
-}
-
-// Allocates sector offset table
-int AllocatePatchInfo(TMPQFile * hf, bool bLoadFromFile)
-{
- TMPQArchive * ha = hf->ha;
- DWORD dwLength = sizeof(TPatchInfo);
-
- // The following conditions must be true
- assert(hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE);
- assert(hf->pPatchInfo == NULL);
-
-__AllocateAndLoadPatchInfo:
-
- // Allocate space for patch header. Start with default size,
- // and if its size if bigger, then we reload them
- hf->pPatchInfo = (TPatchInfo *)STORM_ALLOC(BYTE, dwLength);
- if(hf->pPatchInfo == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Do we have to load the patch header from the file ?
- if(bLoadFromFile)
- {
- // Load the patch header
- if(!FileStream_Read(ha->pStream, &hf->RawFilePos, hf->pPatchInfo, dwLength))
- {
- // Free the patch info
- STORM_FREE(hf->pPatchInfo);
- hf->pPatchInfo = NULL;
- return GetLastError();
- }
-
- // Perform necessary swapping
- hf->pPatchInfo->dwLength = BSWAP_INT32_UNSIGNED(hf->pPatchInfo->dwLength);
- hf->pPatchInfo->dwFlags = BSWAP_INT32_UNSIGNED(hf->pPatchInfo->dwFlags);
- hf->pPatchInfo->dwDataSize = BSWAP_INT32_UNSIGNED(hf->pPatchInfo->dwDataSize);
-
- // Verify the size of the patch header
- // If it's not default size, we have to reload them
- if(hf->pPatchInfo->dwLength > dwLength)
- {
- // Free the patch info
- dwLength = hf->pPatchInfo->dwLength;
- STORM_FREE(hf->pPatchInfo);
- hf->pPatchInfo = NULL;
-
- // If the length is out of all possible ranges, fail the operation
- if(dwLength > 0x400)
- return ERROR_FILE_CORRUPT;
- goto __AllocateAndLoadPatchInfo;
- }
-
- // Patch file data size according to the patch header
- hf->dwDataSize = hf->pPatchInfo->dwDataSize;
- }
- else
- {
- memset(hf->pPatchInfo, 0, dwLength);
- }
-
- // Save the final length to the patch header
- hf->pPatchInfo->dwLength = dwLength;
- hf->pPatchInfo->dwFlags = 0x80000000;
- return ERROR_SUCCESS;
-}
-
-// Allocates sector offset table
-int AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile)
-{
- TMPQArchive * ha = hf->ha;
- TFileEntry * pFileEntry = hf->pFileEntry;
- DWORD dwSectorOffsLen;
- bool bSectorOffsetTableCorrupt = false;
-
- // Caller of AllocateSectorOffsets must ensure these
- assert(hf->SectorOffsets == NULL);
- assert(hf->pFileEntry != NULL);
- assert(hf->dwDataSize != 0);
- assert(hf->ha != NULL);
-
- // If the file is stored as single unit, just set number of sectors to 1
- if(pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT)
- {
- hf->dwSectorCount = 1;
- return ERROR_SUCCESS;
- }
-
- // Calculate the number of data sectors
- // Note that this doesn't work if the file size is zero
- hf->dwSectorCount = ((hf->dwDataSize - 1) / hf->dwSectorSize) + 1;
-
- // Calculate the number of file sectors
- dwSectorOffsLen = (hf->dwSectorCount + 1) * sizeof(DWORD);
-
- // If MPQ_FILE_SECTOR_CRC flag is set, there will either be extra DWORD
- // or an array of MD5's. Either way, we read at least 4 bytes more
- // in order to save additional read from the file.
- if(pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC)
- dwSectorOffsLen += sizeof(DWORD);
-
- // Only allocate and load the table if the file is compressed
- if(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED)
- {
- __LoadSectorOffsets:
-
- // Allocate the sector offset table
- hf->SectorOffsets = (DWORD *)STORM_ALLOC(BYTE, dwSectorOffsLen);
- if(hf->SectorOffsets == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Only read from the file if we are supposed to do so
- if(bLoadFromFile)
- {
- ULONGLONG RawFilePos = hf->RawFilePos;
-
- if(hf->pPatchInfo != NULL)
- RawFilePos += hf->pPatchInfo->dwLength;
-
- // Load the sector offsets from the file
- if(!FileStream_Read(ha->pStream, &RawFilePos, hf->SectorOffsets, dwSectorOffsLen))
- {
- // Free the sector offsets
- STORM_FREE(hf->SectorOffsets);
- hf->SectorOffsets = NULL;
- return GetLastError();
- }
-
- // Swap the sector positions
- BSWAP_ARRAY32_UNSIGNED(hf->SectorOffsets, dwSectorOffsLen);
-
- // Decrypt loaded sector positions if necessary
- if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
- {
- // If we don't know the file key, try to find it.
- if(hf->dwFileKey == 0)
- {
- hf->dwFileKey = DetectFileKeyBySectorSize(hf->SectorOffsets, dwSectorOffsLen);
- if(hf->dwFileKey == 0)
- {
- STORM_FREE(hf->SectorOffsets);
- hf->SectorOffsets = NULL;
- return ERROR_UNKNOWN_FILE_KEY;
- }
- }
-
- // Decrypt sector positions
- DecryptMpqBlock(hf->SectorOffsets, dwSectorOffsLen, hf->dwFileKey - 1);
- }
-
- //
- // Validate the sector offset table
- //
- // Note: Some MPQ protectors put the actual file data before the sector offset table.
- // In this case, the sector offsets are negative (> 0x80000000).
- //
-
- for(DWORD i = 0; i < hf->dwSectorCount; i++)
- {
- DWORD dwSectorOffset1 = hf->SectorOffsets[i+1];
- DWORD dwSectorOffset0 = hf->SectorOffsets[i];
-
- // Every following sector offset must be bigger than the previous one
- if(dwSectorOffset1 <= dwSectorOffset0)
- {
- bSectorOffsetTableCorrupt = true;
- break;
- }
-
- // The sector size must not be bigger than compressed file size
- if((dwSectorOffset1 - dwSectorOffset0) > pFileEntry->dwCmpSize)
- {
- bSectorOffsetTableCorrupt = true;
- break;
- }
- }
-
- // If data corruption detected, free the sector offset table
- if(bSectorOffsetTableCorrupt)
- {
- STORM_FREE(hf->SectorOffsets);
- hf->SectorOffsets = NULL;
- return ERROR_FILE_CORRUPT;
- }
-
- //
- // There may be various extra DWORDs loaded after the sector offset table.
- // They are mostly empty on WoW release MPQs, but on MPQs from PTR,
- // they contain random non-zero data. Their meaning is unknown.
- //
- // These extra values are, however, include in the dwCmpSize in the file
- // table. We cannot ignore them, because compacting archive would fail
- //
-
- if(hf->SectorOffsets[0] > dwSectorOffsLen)
- {
- dwSectorOffsLen = hf->SectorOffsets[0];
- STORM_FREE(hf->SectorOffsets);
- hf->SectorOffsets = NULL;
- goto __LoadSectorOffsets;
- }
- }
- else
- {
- memset(hf->SectorOffsets, 0, dwSectorOffsLen);
- hf->SectorOffsets[0] = dwSectorOffsLen;
- }
- }
-
- return ERROR_SUCCESS;
-}
-
-int AllocateSectorChecksums(TMPQFile * hf, bool bLoadFromFile)
-{
- TMPQArchive * ha = hf->ha;
- TFileEntry * pFileEntry = hf->pFileEntry;
- ULONGLONG RawFilePos;
- DWORD dwCompressedSize = 0;
- DWORD dwExpectedSize;
- DWORD dwCrcOffset; // Offset of the CRC table, relative to file offset in the MPQ
- DWORD dwCrcSize;
-
- // Caller of AllocateSectorChecksums must ensure these
- assert(hf->SectorChksums == NULL);
- assert(hf->SectorOffsets != NULL);
- assert(hf->pFileEntry != NULL);
- assert(hf->ha != NULL);
-
- // Single unit files don't have sector checksums
- if(pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT)
- return ERROR_SUCCESS;
-
- // Caller must ensure that we are only called when we have sector checksums
- assert(pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC);
-
- //
- // Older MPQs store an array of CRC32's after
- // the raw file data in the MPQ.
- //
- // In newer MPQs, the (since Cataclysm BETA) the (attributes) file
- // contains additional 32-bit values beyond the sector table.
- // Their number depends on size of the (attributes), but their
- // meaning is unknown. They are usually zeroed in retail game files,
- // but contain some sort of checksum in BETA MPQs
- //
-
- // Does the size of the file table match with the CRC32-based checksums?
- dwExpectedSize = (hf->dwSectorCount + 2) * sizeof(DWORD);
- if(hf->SectorOffsets[0] == dwExpectedSize)
- {
- // Is there valid size of the sector checksums?
- if(hf->SectorOffsets[hf->dwSectorCount + 1] >= hf->SectorOffsets[hf->dwSectorCount])
- dwCompressedSize = hf->SectorOffsets[hf->dwSectorCount + 1] - hf->SectorOffsets[hf->dwSectorCount];
-
- // Ignore cases when the length is too small or too big.
- if(dwCompressedSize < sizeof(DWORD) || dwCompressedSize > hf->dwSectorSize)
- return ERROR_SUCCESS;
-
- // Allocate the array for the sector checksums
- hf->SectorChksums = STORM_ALLOC(DWORD, hf->dwSectorCount);
- if(hf->SectorChksums == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // If we are not supposed to load it from the file, allocate empty buffer
- if(bLoadFromFile == false)
- {
- memset(hf->SectorChksums, 0, hf->dwSectorCount * sizeof(DWORD));
- return ERROR_SUCCESS;
- }
-
- // Calculate offset of the CRC table
- dwCrcSize = hf->dwSectorCount * sizeof(DWORD);
- dwCrcOffset = hf->SectorOffsets[hf->dwSectorCount];
- CalculateRawSectorOffset(RawFilePos, hf, dwCrcOffset);
-
- // Now read the table from the MPQ
- return LoadMpqTable(ha, RawFilePos, hf->SectorChksums, dwCompressedSize, dwCrcSize, 0);
- }
-
- // If the size doesn't match, we ignore sector checksums
-// assert(false);
- return ERROR_SUCCESS;
-}
-
-int WritePatchInfo(TMPQFile * hf)
-{
- TMPQArchive * ha = hf->ha;
- TPatchInfo * pPatchInfo = hf->pPatchInfo;
-
- // The caller must make sure that this function is only called
- // when the following is true.
- assert(hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE);
- assert(pPatchInfo != NULL);
-
- BSWAP_ARRAY32_UNSIGNED(pPatchInfo, 3 * sizeof(DWORD));
- if(!FileStream_Write(ha->pStream, &hf->RawFilePos, pPatchInfo, sizeof(TPatchInfo)))
- return GetLastError();
-
- return ERROR_SUCCESS;
-}
-
-int WriteSectorOffsets(TMPQFile * hf)
-{
- TMPQArchive * ha = hf->ha;
- TFileEntry * pFileEntry = hf->pFileEntry;
- ULONGLONG RawFilePos = hf->RawFilePos;
- DWORD dwSectorOffsLen;
-
- // The caller must make sure that this function is only called
- // when the following is true.
- assert(hf->pFileEntry->dwFlags & MPQ_FILE_COMPRESSED);
- assert(hf->SectorOffsets != NULL);
- dwSectorOffsLen = hf->SectorOffsets[0];
-
- // If file is encrypted, sector positions are also encrypted
- if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
- EncryptMpqBlock(hf->SectorOffsets, dwSectorOffsLen, hf->dwFileKey - 1);
- BSWAP_ARRAY32_UNSIGNED(hf->SectorOffsets, dwSectorOffsLen);
-
- // Adjust sector offset table position, if we also have patch info
- if(hf->pPatchInfo != NULL)
- RawFilePos += hf->pPatchInfo->dwLength;
-
- // Write sector offsets to the archive
- if(!FileStream_Write(ha->pStream, &RawFilePos, hf->SectorOffsets, dwSectorOffsLen))
- return GetLastError();
-
- // Not necessary, as the sector checksums
- // are going to be freed when this is done.
-// BSWAP_ARRAY32_UNSIGNED(hf->SectorOffsets, dwSectorOffsLen);
- return ERROR_SUCCESS;
-}
-
-
-int WriteSectorChecksums(TMPQFile * hf)
-{
- TMPQArchive * ha = hf->ha;
- ULONGLONG RawFilePos;
- TFileEntry * pFileEntry = hf->pFileEntry;
- LPBYTE pbCompressed;
- DWORD dwCompressedSize = 0;
- DWORD dwCrcSize;
- int nOutSize;
- int nError = ERROR_SUCCESS;
-
- // The caller must make sure that this function is only called
- // when the following is true.
- assert(hf->pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC);
- assert(hf->SectorOffsets != NULL);
- assert(hf->SectorChksums != NULL);
-
- // If the MPQ has MD5 of each raw data chunk,
- // we leave sector offsets empty
- if(ha->pHeader->dwRawChunkSize != 0)
- {
- hf->SectorOffsets[hf->dwSectorCount + 1] = hf->SectorOffsets[hf->dwSectorCount];
- return ERROR_SUCCESS;
- }
-
- // Calculate size of the checksum array
- dwCrcSize = hf->dwSectorCount * sizeof(DWORD);
-
- // Allocate buffer for compressed sector CRCs.
- pbCompressed = STORM_ALLOC(BYTE, dwCrcSize);
- if(pbCompressed == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Perform the compression
- BSWAP_ARRAY32_UNSIGNED(hf->SectorChksums, dwCrcSize);
-
- nOutSize = (int)dwCrcSize;
- SCompCompress((char *)pbCompressed, &nOutSize, (char *)hf->SectorChksums, (int)dwCrcSize, MPQ_COMPRESSION_ZLIB, 0, 0);
- dwCompressedSize = (DWORD)nOutSize;
-
- // Write the sector CRCs to the archive
- RawFilePos = hf->RawFilePos + hf->SectorOffsets[hf->dwSectorCount];
- if(hf->pPatchInfo != NULL)
- RawFilePos += hf->pPatchInfo->dwLength;
- if(!FileStream_Write(ha->pStream, &RawFilePos, pbCompressed, dwCompressedSize))
- nError = GetLastError();
-
- // Not necessary, as the sector checksums
- // are going to be freed when this is done.
-// BSWAP_ARRAY32_UNSIGNED(hf->SectorChksums, dwCrcSize);
-
- // Store the sector CRCs
- hf->SectorOffsets[hf->dwSectorCount + 1] = hf->SectorOffsets[hf->dwSectorCount] + dwCompressedSize;
- pFileEntry->dwCmpSize += dwCompressedSize;
- STORM_FREE(pbCompressed);
- return nError;
-}
-
-int WriteMemDataMD5(
- TFileStream * pStream,
- ULONGLONG RawDataOffs,
- void * pvRawData,
- DWORD dwRawDataSize,
- DWORD dwChunkSize,
- LPDWORD pcbTotalSize)
-{
- unsigned char * md5_array;
- unsigned char * md5;
- LPBYTE pbRawData = (LPBYTE)pvRawData;
- DWORD dwBytesRemaining = dwRawDataSize;
- DWORD dwMd5ArraySize = 0;
- int nError = ERROR_SUCCESS;
-
- // Allocate buffer for array of MD5
- md5_array = md5 = AllocateMd5Buffer(dwRawDataSize, dwChunkSize, &dwMd5ArraySize);
- if(md5_array == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // For every file chunk, calculate MD5
- while(dwBytesRemaining != 0)
- {
- // Get the remaining number of bytes to read
- dwChunkSize = STORMLIB_MIN(dwBytesRemaining, dwChunkSize);
-
- // Calculate MD5
- CalculateDataBlockHash(pbRawData, dwChunkSize, md5);
- md5 += MD5_DIGEST_SIZE;
-
- // Move offset and size
- dwBytesRemaining -= dwChunkSize;
- pbRawData += dwChunkSize;
- }
-
- // Write the array od MD5's to the file
- RawDataOffs += dwRawDataSize;
- if(!FileStream_Write(pStream, &RawDataOffs, md5_array, dwMd5ArraySize))
- nError = GetLastError();
-
- // Give the caller the size of the MD5 array
- if(pcbTotalSize != NULL)
- *pcbTotalSize = dwRawDataSize + dwMd5ArraySize;
-
- // Free buffers and exit
- STORM_FREE(md5_array);
- return nError;
-}
-
-
-// Writes the MD5 for each chunk of the raw file data
-int WriteMpqDataMD5(
- TFileStream * pStream,
- ULONGLONG RawDataOffs,
- DWORD dwRawDataSize,
- DWORD dwChunkSize)
-{
- unsigned char * md5_array;
- unsigned char * md5;
- LPBYTE pbFileChunk;
- DWORD dwMd5ArraySize = 0;
- DWORD dwToRead = dwRawDataSize;
- int nError = ERROR_SUCCESS;
-
- // Allocate buffer for array of MD5
- md5_array = md5 = AllocateMd5Buffer(dwRawDataSize, dwChunkSize, &dwMd5ArraySize);
- if(md5_array == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Allocate space for file chunk
- pbFileChunk = STORM_ALLOC(BYTE, dwChunkSize);
- if(pbFileChunk == NULL)
- {
- STORM_FREE(md5_array);
- return ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // For every file chunk, calculate MD5
- while(dwRawDataSize != 0)
- {
- // Get the remaining number of bytes to read
- dwToRead = STORMLIB_MIN(dwRawDataSize, dwChunkSize);
-
- // Read the chunk
- if(!FileStream_Read(pStream, &RawDataOffs, pbFileChunk, dwToRead))
- {
- nError = GetLastError();
- break;
- }
-
- // Calculate MD5
- CalculateDataBlockHash(pbFileChunk, dwToRead, md5);
- md5 += MD5_DIGEST_SIZE;
-
- // Move offset and size
- RawDataOffs += dwToRead;
- dwRawDataSize -= dwToRead;
- }
-
- // Write the array od MD5's to the file
- if(nError == ERROR_SUCCESS)
- {
- if(!FileStream_Write(pStream, NULL, md5_array, dwMd5ArraySize))
- nError = GetLastError();
- }
-
- // Free buffers and exit
- STORM_FREE(pbFileChunk);
- STORM_FREE(md5_array);
- return nError;
-}
-
-// Frees the structure for MPQ file
-void FreeMPQFile(TMPQFile *& hf)
-{
- if(hf != NULL)
- {
- // If we have patch file attached to this one, free it first
- if(hf->hfPatchFile != NULL)
- FreeMPQFile(hf->hfPatchFile);
-
- // Then free all buffers allocated in the file structure
- if(hf->pPatchHeader != NULL)
- STORM_FREE(hf->pPatchHeader);
- if(hf->pbFileData != NULL)
- STORM_FREE(hf->pbFileData);
- if(hf->pPatchInfo != NULL)
- STORM_FREE(hf->pPatchInfo);
- if(hf->SectorOffsets != NULL)
- STORM_FREE(hf->SectorOffsets);
- if(hf->SectorChksums != NULL)
- STORM_FREE(hf->SectorChksums);
- if(hf->pbFileSector != NULL)
- STORM_FREE(hf->pbFileSector);
- FileStream_Close(hf->pStream);
- STORM_FREE(hf);
- hf = NULL;
- }
-}
-
-// Frees the MPQ archive
-void FreeMPQArchive(TMPQArchive *& ha)
-{
- if(ha != NULL)
- {
- // First of all, free the patch archive, if any
- if(ha->haPatch != NULL)
- FreeMPQArchive(ha->haPatch);
-
- // Close the file stream
- FileStream_Close(ha->pStream);
- ha->pStream = NULL;
-
- // Free the file names from the file table
- if(ha->pFileTable != NULL)
- {
- for(DWORD i = 0; i < ha->dwFileTableSize; i++)
- {
- if(ha->pFileTable[i].szFileName != NULL)
- STORM_FREE(ha->pFileTable[i].szFileName);
- ha->pFileTable[i].szFileName = NULL;
- }
-
- // Then free all buffers allocated in the archive structure
- STORM_FREE(ha->pFileTable);
- }
-
- if(ha->pBitmap != NULL)
- STORM_FREE(ha->pBitmap);
- if(ha->pHashTable != NULL)
- STORM_FREE(ha->pHashTable);
- if(ha->pHetTable != NULL)
- FreeHetTable(ha->pHetTable);
- STORM_FREE(ha);
- ha = NULL;
- }
-}
-
-const char * GetPlainFileNameA(const char * szFileName)
-{
- const char * szPlainName = szFileName;
-
- while(*szFileName != 0)
- {
- if(*szFileName == '\\' || *szFileName == '/')
- szPlainName = szFileName + 1;
- szFileName++;
- }
-
- return szPlainName;
-}
-
-const TCHAR * GetPlainFileNameT(const TCHAR * szFileName)
-{
- const TCHAR * szPlainName = szFileName;
-
- while(*szFileName != 0)
- {
- if(*szFileName == '\\' || *szFileName == '/')
- szPlainName = szFileName + 1;
- szFileName++;
- }
-
- return szPlainName;
-}
-
-bool IsInternalMpqFileName(const char * szFileName)
-{
- if(szFileName != NULL && szFileName[0] == '(')
- {
- if(!_stricmp(szFileName, LISTFILE_NAME) ||
- !_stricmp(szFileName, ATTRIBUTES_NAME) ||
- !_stricmp(szFileName, SIGNATURE_NAME))
- {
- return true;
- }
- }
-
- return false;
-}
-
-// Verifies if the file name is a pseudo-name
-bool IsPseudoFileName(const char * szFileName, DWORD * pdwFileIndex)
-{
- DWORD dwFileIndex = 0;
-
- if(szFileName != NULL)
- {
- // Must be "File########.ext"
- if(!_strnicmp(szFileName, "File", 4))
- {
- // Check 8 digits
- for(int i = 4; i < 4+8; i++)
- {
- if(szFileName[i] < '0' || szFileName[i] > '9')
- return false;
- dwFileIndex = (dwFileIndex * 10) + (szFileName[i] - '0');
- }
-
- // An extension must follow
- if(szFileName[12] == '.')
- {
- if(pdwFileIndex != NULL)
- *pdwFileIndex = dwFileIndex;
- return true;
- }
- }
- }
-
- // Not a pseudo-name
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// Functions calculating and verifying the MD5 signature
-
-bool IsValidMD5(LPBYTE pbMd5)
-{
- BYTE BitSummary = 0;
-
- // The MD5 is considered invalid of it is zeroed
- BitSummary |= pbMd5[0x00] | pbMd5[0x01] | pbMd5[0x02] | pbMd5[0x03] | pbMd5[0x04] | pbMd5[0x05] | pbMd5[0x06] | pbMd5[0x07];
- BitSummary |= pbMd5[0x08] | pbMd5[0x09] | pbMd5[0x0A] | pbMd5[0x0B] | pbMd5[0x0C] | pbMd5[0x0D] | pbMd5[0x0E] | pbMd5[0x0F];
- return (BitSummary != 0);
-}
-
-bool VerifyDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE expected_md5)
-{
- hash_state md5_state;
- BYTE md5_digest[MD5_DIGEST_SIZE];
-
- // Don't verify the block if the MD5 is not valid.
- if(!IsValidMD5(expected_md5))
- return true;
-
- // Calculate the MD5 of the data block
- md5_init(&md5_state);
- md5_process(&md5_state, (unsigned char *)pvDataBlock, cbDataBlock);
- md5_done(&md5_state, md5_digest);
-
- // Does the MD5's match?
- return (memcmp(md5_digest, expected_md5, MD5_DIGEST_SIZE) == 0);
-}
-
-void CalculateDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE md5_hash)
-{
- hash_state md5_state;
-
- md5_init(&md5_state);
- md5_process(&md5_state, (unsigned char *)pvDataBlock, cbDataBlock);
- md5_done(&md5_state, md5_hash);
-}
-
-
-//-----------------------------------------------------------------------------
-// Swapping functions
-
-#ifndef PLATFORM_LITTLE_ENDIAN
-
-//
-// Note that those functions are implemented for Mac operating system,
-// as this is the only supported platform that uses big endian.
-//
-
-// Swaps a signed 16-bit integer
-int16_t SwapInt16(uint16_t data)
-{
- return (int16_t)CFSwapInt16(data);
-}
-
-// Swaps an unsigned 16-bit integer
-uint16_t SwapUInt16(uint16_t data)
-{
- return CFSwapInt16(data);
-}
-
-// Swaps signed 32-bit integer
-int32_t SwapInt32(uint32_t data)
-{
- return (int32_t)CFSwapInt32(data);
-}
-
-// Swaps an unsigned 32-bit integer
-uint32_t SwapUInt32(uint32_t data)
-{
- return CFSwapInt32(data);
-}
-
-// Swaps signed 64-bit integer
-int64_t SwapInt64(int64_t data)
-{
- return (int64_t)CFSwapInt64(data);
-}
-
-// Swaps an unsigned 64-bit integer
-uint64_t SwapUInt64(uint64_t data)
-{
- return CFSwapInt64(data);
-}
-
-// Swaps array of unsigned 16-bit integers
-void ConvertUInt16Buffer(void * ptr, size_t length)
-{
- uint16_t * buffer = (uint16_t *)ptr;
- uint32_t nElements = (uint32_t)(length / sizeof(uint16_t));
-
- while(nElements-- > 0)
- {
- *buffer = SwapUInt16(*buffer);
- buffer++;
- }
-}
-
-// Swaps array of unsigned 32-bit integers
-void ConvertUInt32Buffer(void * ptr, size_t length)
-{
- uint32_t * buffer = (uint32_t *)ptr;
- uint32_t nElements = (uint32_t)(length / sizeof(uint32_t));
-
- while(nElements-- > 0)
- {
- *buffer = SwapUInt32(*buffer);
- buffer++;
- }
-}
-
-// Swaps array of unsigned 64-bit integers
-void ConvertUInt64Buffer(void * ptr, size_t length)
-{
- uint64_t * buffer = (uint64_t *)ptr;
- uint32_t nElements = (uint32_t)(length / sizeof(uint64_t));
-
- while(nElements-- > 0)
- {
- *buffer = SwapUInt64(*buffer);
- buffer++;
- }
-}
-
-// Swaps the TMPQUserData structure
-void ConvertTMPQUserData(void *userData)
-{
- TMPQUserData * theData = (TMPQUserData *)userData;
-
- theData->dwID = SwapUInt32(theData->dwID);
- theData->cbUserDataSize = SwapUInt32(theData->cbUserDataSize);
- theData->dwHeaderOffs = SwapUInt32(theData->dwHeaderOffs);
- theData->cbUserDataHeader = SwapUInt32(theData->cbUserDataHeader);
-}
-
-// Swaps the TMPQHeader structure
-void ConvertTMPQHeader(void *header)
-{
- TMPQHeader * theHeader = (TMPQHeader *)header;
-
- theHeader->dwID = SwapUInt32(theHeader->dwID);
- theHeader->dwHeaderSize = SwapUInt32(theHeader->dwHeaderSize);
- theHeader->dwArchiveSize = SwapUInt32(theHeader->dwArchiveSize);
- theHeader->wFormatVersion = SwapUInt16(theHeader->wFormatVersion);
- theHeader->wSectorSize = SwapUInt16(theHeader->wSectorSize);
- theHeader->dwHashTablePos = SwapUInt32(theHeader->dwHashTablePos);
- theHeader->dwBlockTablePos = SwapUInt32(theHeader->dwBlockTablePos);
- theHeader->dwHashTableSize = SwapUInt32(theHeader->dwHashTableSize);
- theHeader->dwBlockTableSize = SwapUInt32(theHeader->dwBlockTableSize);
-
- if(theHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2)
- {
- // Swap the hi-block table position
- theHeader->HiBlockTablePos64 = SwapUInt64(theHeader->HiBlockTablePos64);
-
- theHeader->wHashTablePosHi = SwapUInt16(theHeader->wHashTablePosHi);
- theHeader->wBlockTablePosHi = SwapUInt16(theHeader->wBlockTablePosHi);
-
- if(theHeader->wFormatVersion >= MPQ_FORMAT_VERSION_3)
- {
- theHeader->ArchiveSize64 = SwapUInt64(theHeader->ArchiveSize64);
- theHeader->BetTablePos64 = SwapUInt64(theHeader->BetTablePos64);
- theHeader->HetTablePos64 = SwapUInt64(theHeader->HetTablePos64);
-
- if(theHeader->wFormatVersion >= MPQ_FORMAT_VERSION_4)
- {
- theHeader->HashTableSize64 = SwapUInt64(theHeader->HashTableSize64);
- theHeader->BlockTableSize64 = SwapUInt64(theHeader->BlockTableSize64);
- theHeader->HiBlockTableSize64 = SwapUInt64(theHeader->HiBlockTableSize64);
- theHeader->HetTableSize64 = SwapUInt64(theHeader->HetTableSize64);
- theHeader->BetTableSize64 = SwapUInt64(theHeader->BetTableSize64);
- }
- }
- }
-}
-
-#endif // PLATFORM_LITTLE_ENDIAN
diff --git a/dep/StormLib/src/SBaseDumpData.cpp b/dep/StormLib/src/SBaseDumpData.cpp
deleted file mode 100644
index c9dcf0a3366..00000000000
--- a/dep/StormLib/src/SBaseDumpData.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/*****************************************************************************/
-/* SBaseDumpData.cpp Copyright (c) Ladislav Zezula 2011 */
-/*---------------------------------------------------------------------------*/
-/* Description : */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 26.01.11 1.00 Lad The first version of SBaseDumpData.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "StormCommon.h"
-
-#ifdef __STORMLIB_DUMP_DATA__
-
-void DumpMpqHeader(TMPQHeader * pHeader)
-{
- printf("== MPQ Header =================================\n");
- printf("DWORD dwID = %08X\n", pHeader->dwID);
- printf("DWORD dwHeaderSize = %08X\n", pHeader->dwHeaderSize);
- printf("DWORD dwArchiveSize = %08X\n", pHeader->dwArchiveSize);
- printf("USHORT wFormatVersion = %04X\n", pHeader->wFormatVersion);
- printf("USHORT wSectorSize = %04X\n", pHeader->wSectorSize);
- printf("DWORD dwHashTablePos = %08X\n", pHeader->dwHashTablePos);
- printf("DWORD dwBlockTablePos = %08X\n", pHeader->dwBlockTablePos);
- printf("DWORD dwHashTableSize = %08X\n", pHeader->dwHashTableSize);
- printf("DWORD dwBlockTableSize = %08X\n", pHeader->dwBlockTableSize);
- printf("ULONGLONG HiBlockTablePos64 = %016llX\n", pHeader->HiBlockTablePos64);
- printf("USHORT wHashTablePosHi = %04X\n", pHeader->wHashTablePosHi);
- printf("USHORT wBlockTablePosHi = %04X\n", pHeader->wBlockTablePosHi);
- printf("ULONGLONG ArchiveSize64 = %016llX\n", pHeader->ArchiveSize64);
- printf("ULONGLONG BetTablePos64 = %016llX\n", pHeader->BetTablePos64);
- printf("ULONGLONG HetTablePos64 = %016llX\n", pHeader->HetTablePos64);
- printf("ULONGLONG HashTableSize64 = %016llX\n", pHeader->HashTableSize64);
- printf("ULONGLONG BlockTableSize64 = %016llX\n", pHeader->BlockTableSize64);
- printf("ULONGLONG HiBlockTableSize64 = %016llX\n", pHeader->HiBlockTableSize64);
- printf("ULONGLONG HetTableSize64 = %016llX\n", pHeader->HetTableSize64);
- printf("ULONGLONG BetTableSize64 = %016llX\n", pHeader->BetTableSize64);
- printf("DWORD dwRawChunkSize = %08X\n", pHeader->dwRawChunkSize);
- printf("-----------------------------------------------\n\n");
-}
-
-void DumpHetAndBetTable(TMPQHetTable * pHetTable, TMPQBetTable * pBetTable)
-{
- DWORD i;
-
- if(pHetTable == NULL || pBetTable == NULL)
- return;
-
- printf("== HET Header =================================\n");
- printf("ULONGLONG AndMask64 = %016llX\n", pHetTable->AndMask64);
- printf("ULONGLONG OrMask64 = %016llX\n", pHetTable->OrMask64);
- printf("DWORD dwIndexSizeTotal = %08X\n", pHetTable->dwIndexSizeTotal);
- printf("DWORD dwIndexSizeExtra = %08X\n", pHetTable->dwIndexSizeExtra);
- printf("DWORD dwIndexSize = %08X\n", pHetTable->dwIndexSize);
- printf("DWORD dwMaxFileCount = %08X\n", pHetTable->dwMaxFileCount);
- printf("DWORD dwHashTableSize = %08X\n", pHetTable->dwHashTableSize);
- printf("DWORD dwHashBitSize = %08X\n", pHetTable->dwHashBitSize);
- printf("-----------------------------------------------\n\n");
-
- printf("== BET Header =================================\n");
- printf("DWORD dwTableEntrySize = %08X\n", pBetTable->dwTableEntrySize);
- printf("DWORD dwBitIndex_FilePos = %08X\n", pBetTable->dwBitIndex_FilePos);
- printf("DWORD dwBitIndex_FileSize = %08X\n", pBetTable->dwBitIndex_FileSize);
- printf("DWORD dwBitIndex_CmpSize = %08X\n", pBetTable->dwBitIndex_CmpSize);
- printf("DWORD dwBitIndex_FlagIndex = %08X\n", pBetTable->dwBitIndex_FlagIndex);
- printf("DWORD dwBitIndex_Unknown = %08X\n", pBetTable->dwBitIndex_Unknown);
- printf("DWORD dwBitCount_FilePos = %08X\n", pBetTable->dwBitCount_FilePos);
- printf("DWORD dwBitCount_FileSize = %08X\n", pBetTable->dwBitCount_FileSize);
- printf("DWORD dwBitCount_CmpSize = %08X\n", pBetTable->dwBitCount_CmpSize);
- printf("DWORD dwBitCount_FlagIndex = %08X\n", pBetTable->dwBitCount_FlagIndex);
- printf("DWORD dwBitCount_Unknown = %08X\n", pBetTable->dwBitCount_Unknown);
- printf("DWORD dwBetHashSizeTotal = %08X\n", pBetTable->dwBetHashSizeTotal);
- printf("DWORD dwBetHashSizeExtra = %08X\n", pBetTable->dwBetHashSizeExtra);
- printf("DWORD dwBetHashSize = %08X\n", pBetTable->dwBetHashSize);
- printf("DWORD dwMaxFileCount = %08X\n", pBetTable->dwMaxFileCount);
- printf("DWORD dwFlagCount = %08X\n", pBetTable->dwFlagCount);
- printf("-----------------------------------------------\n\n");
-
- printf("== HET & Bet Table ======================================================================\n\n");
- printf("HetIdx HetHash BetIdx BetHash ByteOffset FileSize CmpSize FlgIdx Flags \n");
- printf("------ ------- ------ ---------------- ---------------- -------- -------- ------ --------\n");
- for(i = 0; i < pHetTable->dwHashTableSize; i++)
- {
- ULONGLONG ByteOffset = 0;
- ULONGLONG BetHash = 0;
- DWORD dwFileSize = 0;
- DWORD dwCmpSize = 0;
- DWORD dwFlagIndex = 0;
- DWORD dwFlags = 0;
- DWORD dwBetIndex = 0;
-
- pHetTable->pBetIndexes->GetBits(i * pHetTable->dwIndexSizeTotal,
- pHetTable->dwIndexSize,
- &dwBetIndex,
- 4);
-
- if(dwBetIndex < pHetTable->dwMaxFileCount)
- {
- DWORD dwEntryIndex = pBetTable->dwTableEntrySize * dwBetIndex;
-
- pBetTable->pBetHashes->GetBits(dwBetIndex * pBetTable->dwBetHashSizeTotal,
- pBetTable->dwBetHashSize,
- &BetHash,
- 8);
-
- pBetTable->pFileTable->GetBits(dwEntryIndex + pBetTable->dwBitIndex_FilePos,
- pBetTable->dwBitCount_FilePos,
- &ByteOffset,
- 8);
-
- pBetTable->pFileTable->GetBits(dwEntryIndex + pBetTable->dwBitIndex_FileSize,
- pBetTable->dwBitCount_FileSize,
- &dwFileSize,
- 4);
-
- pBetTable->pFileTable->GetBits(dwEntryIndex + pBetTable->dwBitIndex_CmpSize,
- pBetTable->dwBitCount_CmpSize,
- &dwCmpSize,
- 4);
-
- pBetTable->pFileTable->GetBits(dwEntryIndex + pBetTable->dwBitIndex_FlagIndex,
- pBetTable->dwBitCount_FlagIndex,
- &dwFlagIndex,
- 4);
-
- dwFlags = pBetTable->pFileFlags[dwFlagIndex];
- }
-
- printf(" %04X %02lX %04X %016llX %016llX %08X %08X %04X %08X\n", i,
- pHetTable->pHetHashes[i],
- dwBetIndex,
- BetHash,
- ByteOffset,
- dwFileSize,
- dwCmpSize,
- dwFlagIndex,
- dwFlags);
- }
- printf("-----------------------------------------------------------------------------------------\n");
-}
-
-#endif // __STORMLIB_DUMP_DATA__
diff --git a/dep/StormLib/src/SBaseFileTable.cpp b/dep/StormLib/src/SBaseFileTable.cpp
deleted file mode 100644
index 09379ca5da7..00000000000
--- a/dep/StormLib/src/SBaseFileTable.cpp
+++ /dev/null
@@ -1,2550 +0,0 @@
-/*****************************************************************************/
-/* SBaseFileTable.cpp Copyright (c) Ladislav Zezula 2010 */
-/*---------------------------------------------------------------------------*/
-/* Description: Common handler for classic and new hash&block tables */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 06.09.10 1.00 Lad The first version of SBaseFileTable.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "StormCommon.h"
-
-//-----------------------------------------------------------------------------
-// Local defines
-
-#define INVALID_FLAG_VALUE 0xCCCCCCCC
-#define MAX_FLAG_INDEX 512
-
-//-----------------------------------------------------------------------------
-// Local structures
-
-// Structure for HET table header
-typedef struct _HET_TABLE_HEADER
-{
- DWORD dwTableSize; // Size of the entire HET table, including HET_TABLE_HEADER (in bytes)
- DWORD dwMaxFileCount; // Maximum number of files in the MPQ
- DWORD dwHashTableSize; // Size of the hash table (in bytes)
- DWORD dwHashEntrySize; // Effective size of the hash entry (in bits)
- DWORD dwIndexSizeTotal; // Total size of file index (in bits)
- DWORD dwIndexSizeExtra; // Extra bits in the file index
- DWORD dwIndexSize; // Effective size of the file index (in bits)
- DWORD dwIndexTableSize; // Size of the block index subtable (in bytes)
-
-} HET_TABLE_HEADER, *PHET_TABLE_HEADER;
-
-// Structure for BET table header
-typedef struct _BET_TABLE_HEADER
-{
- DWORD dwTableSize; // Size of the entire BET table, including the header (in bytes)
- DWORD dwFileCount; // Number of files in the BET table
- DWORD dwUnknown08;
- DWORD dwTableEntrySize; // Size of one table entry (in bits)
- DWORD dwBitIndex_FilePos; // Bit index of the file position (within the entry record)
- DWORD dwBitIndex_FileSize; // Bit index of the file size (within the entry record)
- DWORD dwBitIndex_CmpSize; // Bit index of the compressed size (within the entry record)
- DWORD dwBitIndex_FlagIndex; // Bit index of the flag index (within the entry record)
- DWORD dwBitIndex_Unknown; // Bit index of the ??? (within the entry record)
- DWORD dwBitCount_FilePos; // Bit size of file position (in the entry record)
- DWORD dwBitCount_FileSize; // Bit size of file size (in the entry record)
- DWORD dwBitCount_CmpSize; // Bit size of compressed file size (in the entry record)
- DWORD dwBitCount_FlagIndex; // Bit size of flags index (in the entry record)
- DWORD dwBitCount_Unknown; // Bit size of ??? (in the entry record)
- DWORD dwBetHashSizeTotal; // Total size of the BET hash
- DWORD dwBetHashSizeExtra; // Extra bits in the BET hash
- DWORD dwBetHashSize; // Effective size of BET hash (in bits)
- DWORD dwBetHashArraySize; // Size of BET hashes array, in bytes
- DWORD dwFlagCount; // Number of flags in the following array
-
-} BET_TABLE_HEADER, *PBET_TABLE_HEADER;
-
-//-----------------------------------------------------------------------------
-// Support for calculating bit sizes
-
-static void InitFileFlagArray(LPDWORD FlagArray)
-{
- for(DWORD dwFlagIndex = 0; dwFlagIndex < MAX_FLAG_INDEX; dwFlagIndex++)
- FlagArray[dwFlagIndex] = INVALID_FLAG_VALUE;
-}
-
-static DWORD GetFileFlagIndex(LPDWORD FlagArray, DWORD dwFlags)
-{
- // Find free or equal entry in the flag array
- for(DWORD dwFlagIndex = 0; dwFlagIndex < MAX_FLAG_INDEX; dwFlagIndex++)
- {
- if(FlagArray[dwFlagIndex] == INVALID_FLAG_VALUE || FlagArray[dwFlagIndex] == dwFlags)
- {
- FlagArray[dwFlagIndex] = dwFlags;
- return dwFlagIndex;
- }
- }
-
- // This should never happen
- assert(false);
- return 0xFFFFFFFF;
-}
-
-static DWORD GetNecessaryBitCount(ULONGLONG MaxValue)
-{
- DWORD dwBitCount = 0;
-
- while(MaxValue > 0)
- {
- MaxValue >>= 1;
- dwBitCount++;
- }
-
- return dwBitCount;
-}
-
-//-----------------------------------------------------------------------------
-// Support functions for BIT_ARRAY
-
-static USHORT SetBitsMask[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
-
-static TBitArray * CreateBitArray(
- DWORD NumberOfBits,
- BYTE FillValue)
-{
- TBitArray * pBitArray;
- size_t nSize = sizeof(TBitArray) + (NumberOfBits + 7) / 8;
-
- // Allocate the bit array
- pBitArray = (TBitArray *)STORM_ALLOC(BYTE, nSize);
- if(pBitArray != NULL)
- {
- memset(pBitArray, FillValue, nSize);
- pBitArray->NumberOfBits = NumberOfBits;
- }
-
- return pBitArray;
-}
-
-void TBitArray::GetBits(
- unsigned int nBitPosition,
- unsigned int nBitLength,
- void * pvBuffer,
- int nResultByteSize)
-{
- unsigned char * pbBuffer = (unsigned char *)pvBuffer;
- unsigned int nBytePosition0 = (nBitPosition / 8);
- unsigned int nBytePosition1 = nBytePosition0 + 1;
- unsigned int nByteLength = (nBitLength / 8);
- unsigned int nBitOffset = (nBitPosition & 0x07);
- unsigned char BitBuffer;
-
- // Keep compiler happy for platforms where nResultByteSize is not used
- nResultByteSize = nResultByteSize;
-
-#ifdef _DEBUG
- // Check if the target is properly zeroed
- for(int i = 0; i < nResultByteSize; i++)
- assert(pbBuffer[i] == 0);
-#endif
-
-#ifndef PLATFORM_LITTLE_ENDIAN
- // Adjust the buffer pointer for big endian platforms
- pbBuffer += (nResultByteSize - 1);
-#endif
-
- // Copy whole bytes, if any
- while(nByteLength > 0)
- {
- // Is the current position in the Elements byte-aligned?
- if(nBitOffset != 0)
- {
- BitBuffer = (unsigned char)((Elements[nBytePosition0] >> nBitOffset) | (Elements[nBytePosition1] << (0x08 - nBitOffset)));
- }
- else
- {
- BitBuffer = Elements[nBytePosition0];
- }
-
-#ifdef PLATFORM_LITTLE_ENDIAN
- *pbBuffer++ = BitBuffer;
-#else
- *pbBuffer-- = BitBuffer;
-#endif
-
- // Move byte positions and lengths
- nBytePosition1++;
- nBytePosition0++;
- nByteLength--;
- }
-
- // Get the rest of the bits
- nBitLength = (nBitLength & 0x07);
- if(nBitLength != 0)
- {
- *pbBuffer = (unsigned char)(Elements[nBytePosition0] >> nBitOffset);
-
- if(nBitLength > (8 - nBitOffset))
- *pbBuffer = (unsigned char)((Elements[nBytePosition1] << (8 - nBitOffset)) | (Elements[nBytePosition0] >> nBitOffset));
-
- *pbBuffer &= (0x01 << nBitLength) - 1;
- }
-}
-
-void TBitArray::SetBits(
- unsigned int nBitPosition,
- unsigned int nBitLength,
- void * pvBuffer,
- int nResultByteSize)
-{
- unsigned char * pbBuffer = (unsigned char *)pvBuffer;
- unsigned int nBytePosition = (nBitPosition / 8);
- unsigned int nBitOffset = (nBitPosition & 0x07);
- unsigned short BitBuffer = 0;
- unsigned short AndMask = 0;
- unsigned short OneByte = 0;
-
- // Keep compiler happy for platforms where nResultByteSize is not used
- nResultByteSize = nResultByteSize;
-
-#ifndef PLATFORM_LITTLE_ENDIAN
- // Adjust the buffer pointer for big endian platforms
- pbBuffer += (nResultByteSize - 1);
-#endif
-
- // Copy whole bytes, if any
- while(nBitLength > 8)
- {
- // Reload the bit buffer
-#ifdef PLATFORM_LITTLE_ENDIAN
- OneByte = *pbBuffer++;
-#else
- OneByte = *pbBuffer--;
-#endif
- // Update the BitBuffer and AndMask for the bit array
- BitBuffer = (BitBuffer >> 0x08) | (OneByte << nBitOffset);
- AndMask = (AndMask >> 0x08) | (0x00FF << nBitOffset);
-
- // Update the byte in the array
- Elements[nBytePosition] = (BYTE)((Elements[nBytePosition] & ~AndMask) | BitBuffer);
-
- // Move byte positions and lengths
- nBytePosition++;
- nBitLength -= 0x08;
- }
-
- if(nBitLength != 0)
- {
- // Reload the bit buffer
- OneByte = *pbBuffer;
-
- // Update the AND mask for the last bit
- BitBuffer = (BitBuffer >> 0x08) | (OneByte << nBitOffset);
- AndMask = (AndMask >> 0x08) | (SetBitsMask[nBitLength] << nBitOffset);
-
- // Update the byte in the array
- Elements[nBytePosition] = (BYTE)((Elements[nBytePosition] & ~AndMask) | BitBuffer);
-
- // Update the next byte, if needed
- if(AndMask & 0xFF00)
- {
- nBytePosition++;
- BitBuffer >>= 0x08;
- AndMask >>= 0x08;
-
- Elements[nBytePosition] = (BYTE)((Elements[nBytePosition] & ~AndMask) | BitBuffer);
- }
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Support for hash table
-
-// Returns a hash table entry in the following order:
-// 1) A hash table entry with the neutral locale
-// 2) A hash table entry with any other locale
-// 3) NULL
-static TMPQHash * GetHashEntryAny(TMPQArchive * ha, const char * szFileName)
-{
- TMPQHash * pHashNeutral = NULL;
- TMPQHash * pFirstHash = GetFirstHashEntry(ha, szFileName);
- TMPQHash * pHashAny = NULL;
- TMPQHash * pHash = pFirstHash;
-
- // Parse the found hashes
- while(pHash != NULL)
- {
- // If we found neutral hash, remember it
- if(pHash->lcLocale == 0)
- pHashNeutral = pHash;
- if(pHashAny == NULL)
- pHashAny = pHash;
-
- // Get the next hash entry for that file
- pHash = GetNextHashEntry(ha, pFirstHash, pHash);
- }
-
- // At the end, return neutral hash (if found), otherwise NULL
- return (pHashNeutral != NULL) ? pHashNeutral : pHashAny;
-}
-
-// Returns a hash table entry in the following order:
-// 1) A hash table entry with the preferred locale
-// 2) A hash table entry with the neutral locale
-// 3) NULL
-static TMPQHash * GetHashEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale)
-{
- TMPQHash * pHashNeutral = NULL;
- TMPQHash * pFirstHash = GetFirstHashEntry(ha, szFileName);
- TMPQHash * pHash = pFirstHash;
-
- // Parse the found hashes
- while(pHash != NULL)
- {
- // If the locales match, return it
- if(pHash->lcLocale == lcLocale)
- return pHash;
-
- // If we found neutral hash, remember it
- if(pHash->lcLocale == 0)
- pHashNeutral = pHash;
-
- // Get the next hash entry for that file
- pHash = GetNextHashEntry(ha, pFirstHash, pHash);
- }
-
- // At the end, return neutral hash (if found), otherwise NULL
- return pHashNeutral;
-}
-
-// Returns a hash table entry in the following order:
-// 1) A hash table entry with the preferred locale
-// 2) NULL
-static TMPQHash * GetHashEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcLocale)
-{
- TMPQHash * pFirstHash = GetFirstHashEntry(ha, szFileName);
- TMPQHash * pHash = pFirstHash;
-
- // Parse the found hashes
- while(pHash != NULL)
- {
- // If the locales match, return it
- if(pHash->lcLocale == lcLocale)
- return pHash;
-
- // Get the next hash entry for that file
- pHash = GetNextHashEntry(ha, pFirstHash, pHash);
- }
-
- // Not found
- return NULL;
-}
-
-static TMPQHash * TranslateHashTable(
- TMPQArchive * ha,
- ULONGLONG * pcbTableSize)
-{
- TMPQHash * pHashTable;
- size_t HashTableSize;
-
- // Allocate copy of the hash table
- pHashTable = STORM_ALLOC(TMPQHash, ha->pHeader->dwHashTableSize);
- if(pHashTable != NULL)
- {
- // Copy the hash table
- HashTableSize = sizeof(TMPQHash) * ha->pHeader->dwHashTableSize;
- memcpy(pHashTable, ha->pHashTable, HashTableSize);
-
- // Give the size to the caller
- if(pcbTableSize != NULL)
- {
- *pcbTableSize = (ULONGLONG)HashTableSize;
- }
- }
-
- return pHashTable;
-}
-
-static TMPQBlock * TranslateBlockTable(
- TMPQArchive * ha,
- ULONGLONG * pcbTableSize,
- bool * pbNeedHiBlockTable)
-{
- TFileEntry * pFileEntry = ha->pFileTable;
- TMPQBlock * pBlockTable;
- TMPQBlock * pBlock;
- size_t BlockTableSize;
- bool bNeedHiBlockTable = false;
-
- // Allocate copy of the hash table
- pBlockTable = pBlock = STORM_ALLOC(TMPQBlock, ha->dwFileTableSize);
- if(pBlockTable != NULL)
- {
- // Copy the block table
- BlockTableSize = sizeof(TMPQBlock) * ha->dwFileTableSize;
- for(DWORD i = 0; i < ha->dwFileTableSize; i++)
- {
- bNeedHiBlockTable = (pFileEntry->ByteOffset >> 32) ? true : false;
- pBlock->dwFilePos = (DWORD)pFileEntry->ByteOffset;
- pBlock->dwFSize = pFileEntry->dwFileSize;
- pBlock->dwCSize = pFileEntry->dwCmpSize;
- pBlock->dwFlags = pFileEntry->dwFlags;
-
- pFileEntry++;
- pBlock++;
- }
-
- // Give the size to the caller
- if(pcbTableSize != NULL)
- *pcbTableSize = (ULONGLONG)BlockTableSize;
-
- if(pbNeedHiBlockTable != NULL)
- *pbNeedHiBlockTable = bNeedHiBlockTable;
- }
-
- return pBlockTable;
-}
-
-static USHORT * TranslateHiBlockTable(
- TMPQArchive * ha,
- ULONGLONG * pcbTableSize)
-{
- TFileEntry * pFileEntry = ha->pFileTable;
- USHORT * pHiBlockTable;
- USHORT * pHiBlock;
- size_t HiBlockTableSize;
-
- // Allocate copy of the hash table
- pHiBlockTable = pHiBlock = STORM_ALLOC(USHORT, ha->dwFileTableSize);
- if(pHiBlockTable != NULL)
- {
- // Copy the block table
- HiBlockTableSize = sizeof(USHORT) * ha->dwFileTableSize;
- for(DWORD i = 0; i < ha->dwFileTableSize; i++)
- pHiBlock[i] = (USHORT)(pFileEntry[i].ByteOffset >> 0x20);
-
- // Give the size to the caller
- if(pcbTableSize != NULL)
- *pcbTableSize = (ULONGLONG)HiBlockTableSize;
- }
-
- return pHiBlockTable;
-}
-
-//-----------------------------------------------------------------------------
-// General EXT table functions
-
-TMPQExtTable * LoadExtTable(
- TMPQArchive * ha,
- ULONGLONG ByteOffset,
- size_t Size,
- DWORD dwSignature,
- DWORD dwKey)
-{
- TMPQExtTable * pCompressed = NULL; // Compressed table
- TMPQExtTable * pExtTable = NULL; // Uncompressed table
-
- // Do nothing if the size is zero
- if(ByteOffset != 0 && Size != 0)
- {
- // Allocate size for the compressed table
- pExtTable = (TMPQExtTable *)STORM_ALLOC(BYTE, Size);
- if(pExtTable != NULL)
- {
- // Load the table from the MPQ
- ByteOffset += ha->MpqPos;
- if(!FileStream_Read(ha->pStream, &ByteOffset, pExtTable, (DWORD)Size))
- {
- STORM_FREE(pExtTable);
- return NULL;
- }
-
- // Swap the ext table header
- BSWAP_ARRAY32_UNSIGNED(pExtTable, sizeof(TMPQExtTable));
- if(pExtTable->dwSignature != dwSignature)
- {
- STORM_FREE(pExtTable);
- return NULL;
- }
-
- // Decrypt the block
- BSWAP_ARRAY32_UNSIGNED(pExtTable + 1, pExtTable->dwDataSize);
- DecryptMpqBlock(pExtTable + 1, (DWORD)(Size - sizeof(TMPQExtTable)), dwKey);
- BSWAP_ARRAY32_UNSIGNED(pExtTable + 1, pExtTable->dwDataSize);
-
- // If the table is compressed, decompress it
- if((pExtTable->dwDataSize + sizeof(TMPQExtTable)) > Size)
- {
- pCompressed = pExtTable;
- pExtTable = (TMPQExtTable *)STORM_ALLOC(BYTE, sizeof(TMPQExtTable) + pCompressed->dwDataSize);
- if(pExtTable != NULL)
- {
- int cbOutBuffer = (int)pCompressed->dwDataSize;
- int cbInBuffer = (int)Size;
-
- // Decompress the extended table
- pExtTable->dwSignature = pCompressed->dwSignature;
- pExtTable->dwVersion = pCompressed->dwVersion;
- pExtTable->dwDataSize = pCompressed->dwDataSize;
- if(!SCompDecompress2((char *)(pExtTable + 1), &cbOutBuffer, (char *)(pCompressed + 1), cbInBuffer))
- {
- STORM_FREE(pExtTable);
- pExtTable = NULL;
- }
- }
-
- // Free the compressed block
- STORM_FREE(pCompressed);
- }
- }
- }
-
- // Return the decompressed table to the caller
- return pExtTable;
-}
-
-// Used in MPQ Editor
-void FreeMpqBuffer(void * pvBuffer)
-{
- STORM_FREE(pvBuffer);
-}
-
-static int SaveMpqTable(
- TMPQArchive * ha,
- void * pMpqTable,
- ULONGLONG ByteOffset,
- size_t Size,
- unsigned char * md5,
- DWORD dwKey,
- bool bCompress)
-{
- ULONGLONG FileOffset;
- void * pCompressed = NULL;
- int nError = ERROR_SUCCESS;
-
- // Do we have to compress the table?
- if(bCompress)
- {
- int cbOutBuffer = (int)Size;
- int cbInBuffer = (int)Size;
-
- // Allocate extra space for compressed table
- pCompressed = STORM_ALLOC(BYTE, Size);
- if(pCompressed == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Compress the table
- SCompCompress((char *)pCompressed, &cbOutBuffer, (char *)pMpqTable, cbInBuffer, MPQ_COMPRESSION_ZLIB, 0, 0);
-
- // If the compression failed, revert it. Otherwise, swap the tables
- if(cbOutBuffer >= cbInBuffer)
- {
- STORM_FREE(pCompressed);
- pCompressed = NULL;
- }
- else
- {
- pMpqTable = pCompressed;
- }
- }
-
- // Encrypt the table
- if(dwKey != 0)
- {
- BSWAP_ARRAY32_UNSIGNED(pMpqTable, Size);
- EncryptMpqBlock(pMpqTable, (DWORD)Size, dwKey);
- BSWAP_ARRAY32_UNSIGNED(pMpqTable, Size);
- }
-
- // Calculate the MD5
- if(md5 != NULL)
- {
- CalculateDataBlockHash(pMpqTable, (DWORD)Size, md5);
- }
-
- // Save the table to the MPQ
- BSWAP_ARRAY32_UNSIGNED(pMpqTable, Size);
- FileOffset = ha->MpqPos + ByteOffset;
- if(!FileStream_Write(ha->pStream, &FileOffset, pMpqTable, (DWORD)Size))
- nError = GetLastError();
-
- // Free the compressed table, if any
- if(pCompressed != NULL)
- STORM_FREE(pCompressed);
- return nError;
-}
-
-static int SaveExtTable(
- TMPQArchive * ha,
- TMPQExtTable * pExtTable,
- ULONGLONG ByteOffset,
- DWORD dwTableSize,
- unsigned char * md5,
- DWORD dwKey,
- bool bCompress,
- LPDWORD pcbTotalSize)
-{
- ULONGLONG FileOffset;
- TMPQExtTable * pCompressed = NULL;
- DWORD cbTotalSize = 0;
- int nError = ERROR_SUCCESS;
-
- // Do we have to compress the table?
- if(bCompress)
- {
- int cbOutBuffer = (int)dwTableSize;
- int cbInBuffer = (int)dwTableSize;
-
- // Allocate extra space for compressed table
- pCompressed = (TMPQExtTable *)STORM_ALLOC(BYTE, dwTableSize);
- if(pCompressed == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Compress the table
- pCompressed->dwSignature = pExtTable->dwSignature;
- pCompressed->dwVersion = pExtTable->dwVersion;
- pCompressed->dwDataSize = pExtTable->dwDataSize;
- SCompCompress((char *)(pCompressed + 1), &cbOutBuffer, (char *)(pExtTable + 1), cbInBuffer, MPQ_COMPRESSION_ZLIB, 0, 0);
-
- // If the compression failed, revert it. Otherwise, swap the tables
- if(cbOutBuffer >= cbInBuffer)
- {
- STORM_FREE(pCompressed);
- pCompressed = NULL;
- }
- else
- {
- pExtTable = pCompressed;
- }
- }
-
- // Encrypt the table
- if(dwKey != 0)
- {
- BSWAP_ARRAY32_UNSIGNED(pExtTable + 1, pExtTable->dwDataSize);
- EncryptMpqBlock(pExtTable + 1, (DWORD)(dwTableSize - sizeof(TMPQExtTable)), dwKey);
- BSWAP_ARRAY32_UNSIGNED(pExtTable + 1, pExtTable->dwDataSize);
- }
-
- // Calculate the MD5 of the table after
- if(md5 != NULL)
- {
- CalculateDataBlockHash(pExtTable, dwTableSize, md5);
- }
-
- // Save the table to the MPQ
- FileOffset = ha->MpqPos + ByteOffset;
- if(FileStream_Write(ha->pStream, &FileOffset, pExtTable, dwTableSize))
- cbTotalSize += dwTableSize;
- else
- nError = GetLastError();
-
- // We have to write raw data MD5
- if(nError == ERROR_SUCCESS && ha->pHeader->dwRawChunkSize != 0)
- {
- nError = WriteMemDataMD5(ha->pStream,
- FileOffset,
- pExtTable,
- dwTableSize,
- ha->pHeader->dwRawChunkSize,
- &cbTotalSize);
- }
-
- // Give the total written size, if needed
- if(pcbTotalSize != NULL)
- *pcbTotalSize = cbTotalSize;
-
- // Free the compressed table, if any
- if(pCompressed != NULL)
- STORM_FREE(pCompressed);
- return nError;
-}
-
-//-----------------------------------------------------------------------------
-// Support for HET table
-
-static void CreateHetHeader(
- TMPQHetTable * pHetTable,
- PHET_TABLE_HEADER pHetHeader)
-{
- // Fill the BET header
- pHetHeader->dwMaxFileCount = pHetTable->dwMaxFileCount;
- pHetHeader->dwHashTableSize = pHetTable->dwHashTableSize;
- pHetHeader->dwHashEntrySize = pHetTable->dwHashBitSize;
- pHetHeader->dwIndexSizeTotal = GetNecessaryBitCount(pHetTable->dwMaxFileCount);
- pHetHeader->dwIndexSizeExtra = 0;
- pHetHeader->dwIndexSize = pHetHeader->dwIndexSizeTotal;
- pHetHeader->dwIndexTableSize = ((pHetHeader->dwIndexSizeTotal * pHetTable->dwHashTableSize) + 7) / 8;
-
- // Calculate the total size needed for holding HET table
- pHetHeader->dwTableSize = sizeof(HET_TABLE_HEADER) +
- pHetHeader->dwHashTableSize +
- pHetHeader->dwIndexTableSize;
-}
-
-TMPQHetTable * CreateHetTable(DWORD dwMaxFileCount, DWORD dwHashBitSize, bool bCreateEmpty)
-{
- TMPQHetTable * pHetTable;
-
- pHetTable = STORM_ALLOC(TMPQHetTable, 1);
- if(pHetTable != NULL)
- {
- pHetTable->dwIndexSizeTotal = 0;
- pHetTable->dwIndexSizeExtra = 0;
- pHetTable->dwIndexSize = pHetTable->dwIndexSizeTotal;
- pHetTable->dwMaxFileCount = dwMaxFileCount;
- pHetTable->dwHashTableSize = (dwMaxFileCount * 4 / 3);
- pHetTable->dwHashBitSize = dwHashBitSize;
-
- // Size of one index is calculated from max file count
- pHetTable->dwIndexSizeTotal = GetNecessaryBitCount(dwMaxFileCount);
- pHetTable->dwIndexSizeExtra = 0;
- pHetTable->dwIndexSize = pHetTable->dwIndexSizeTotal;
-
- // Allocate hash table
- pHetTable->pHetHashes = STORM_ALLOC(BYTE, pHetTable->dwHashTableSize);
- memset(pHetTable->pHetHashes, 0, pHetTable->dwHashTableSize);
-
- // If we shall create empty HET table, we have to allocate empty block index table as well
- if(bCreateEmpty)
- pHetTable->pBetIndexes = CreateBitArray(pHetTable->dwHashTableSize * pHetTable->dwIndexSizeTotal, 0xFF);
-
- // Calculate masks
- pHetTable->AndMask64 = 0;
- if(dwHashBitSize != 0x40)
- pHetTable->AndMask64 = (ULONGLONG)1 << dwHashBitSize;
- pHetTable->AndMask64--;
-
- pHetTable->OrMask64 = (ULONGLONG)1 << (dwHashBitSize - 1);
- }
-
- return pHetTable;
-}
-
-static TMPQHetTable * TranslateHetTable(TMPQExtTable * pExtTable)
-{
- HET_TABLE_HEADER HetHeader;
- TMPQHetTable * pHetTable = NULL;
- LPBYTE pbSrcData = (LPBYTE)(pExtTable + 1);
-
- // Sanity check
- assert(pExtTable->dwSignature == HET_TABLE_SIGNATURE);
- assert(pExtTable->dwVersion == 1);
-
- // Verify size of the HET table
- if(pExtTable != NULL && pExtTable->dwDataSize >= sizeof(HET_TABLE_HEADER))
- {
- // Copy the table header in order to have it aligned and swapped
- memcpy(&HetHeader, pbSrcData, sizeof(HET_TABLE_HEADER));
- BSWAP_ARRAY32_UNSIGNED(&HetHeader, sizeof(HET_TABLE_HEADER));
- pbSrcData += sizeof(HET_TABLE_HEADER);
-
- // Verify the size of the table in the header
- if(HetHeader.dwTableSize == pExtTable->dwDataSize)
- {
- // Create translated table
- pHetTable = CreateHetTable(HetHeader.dwMaxFileCount, HetHeader.dwHashEntrySize, false);
- if(pHetTable != NULL)
- {
- // Copy the hash table size, index size and extra bits from the HET header
- pHetTable->dwHashTableSize = HetHeader.dwHashTableSize;
- pHetTable->dwIndexSizeTotal = HetHeader.dwIndexSizeTotal;
- pHetTable->dwIndexSizeExtra = HetHeader.dwIndexSizeExtra;
-
- // Fill the hash table
- if(pHetTable->pHetHashes != NULL)
- memcpy(pHetTable->pHetHashes, pbSrcData, pHetTable->dwHashTableSize);
- pbSrcData += pHetTable->dwHashTableSize;
-
- // Copy the block index table
- pHetTable->pBetIndexes = CreateBitArray(HetHeader.dwIndexTableSize * 8, 0xFF);
- if(pHetTable->pBetIndexes != NULL)
- memcpy(pHetTable->pBetIndexes->Elements, pbSrcData, HetHeader.dwIndexTableSize);
- pbSrcData += HetHeader.dwIndexTableSize;
- }
- }
- }
-
- return pHetTable;
-}
-
-static TMPQExtTable * TranslateHetTable(TMPQHetTable * pHetTable, ULONGLONG * pcbHetTable)
-{
- TMPQExtTable * pExtTable = NULL;
- HET_TABLE_HEADER HetHeader;
- LPBYTE pbLinearTable = NULL;
- LPBYTE pbTrgData;
- size_t HetTableSize;
-
- // Prepare header of the HET table
- CreateHetHeader(pHetTable, &HetHeader);
-
- // Calculate the total size needed for holding the encrypted HET table
- HetTableSize = HetHeader.dwTableSize;
-
- // Allocate space for the linear table
- pbLinearTable = STORM_ALLOC(BYTE, sizeof(TMPQExtTable) + HetTableSize);
- if(pbLinearTable != NULL)
- {
- // Create the common ext table header
- pExtTable = (TMPQExtTable *)pbLinearTable;
- pExtTable->dwSignature = HET_TABLE_SIGNATURE;
- pExtTable->dwVersion = 1;
- pExtTable->dwDataSize = (DWORD)HetTableSize;
- pbTrgData = (LPBYTE)(pExtTable + 1);
-
- // Copy the HET table header
- memcpy(pbTrgData, &HetHeader, sizeof(HET_TABLE_HEADER));
- BSWAP_ARRAY32_UNSIGNED(pbTrgData, sizeof(HET_TABLE_HEADER));
- pbTrgData += sizeof(HET_TABLE_HEADER);
-
- // Copy the array of HET hashes
- memcpy(pbTrgData, pHetTable->pHetHashes, pHetTable->dwHashTableSize);
- pbTrgData += pHetTable->dwHashTableSize;
-
- // Copy the bit array of BET indexes
- memcpy(pbTrgData, pHetTable->pBetIndexes->Elements, HetHeader.dwIndexTableSize);
-
- // Calculate the total size of the table, including the TMPQExtTable
- if(pcbHetTable != NULL)
- {
- *pcbHetTable = (ULONGLONG)(sizeof(TMPQExtTable) + HetTableSize);
- }
- }
-
- return pExtTable;
-}
-
-DWORD GetFileIndex_Het(TMPQArchive * ha, const char * szFileName)
-{
- TMPQHetTable * pHetTable = ha->pHetTable;
- ULONGLONG FileNameHash;
- ULONGLONG AndMask64;
- ULONGLONG OrMask64;
- ULONGLONG BetHash;
- DWORD StartIndex;
- DWORD Index;
- BYTE HetHash; // Upper 8 bits of the masked file name hash
-
- // Do nothing if the MPQ has no HET table
- assert(ha->pHetTable != NULL);
-
- // Calculate 64-bit hash of the file name
- AndMask64 = pHetTable->AndMask64;
- OrMask64 = pHetTable->OrMask64;
- FileNameHash = (HashStringJenkins(szFileName) & AndMask64) | OrMask64;
-
- // Split the file name hash into two parts:
- // Part 1: The highest 8 bits of the name hash
- // Part 2: The rest of the name hash (without the highest 8 bits)
- HetHash = (BYTE)(FileNameHash >> (pHetTable->dwHashBitSize - 8));
- BetHash = FileNameHash & (AndMask64 >> 0x08);
-
- // Calculate the starting index to the hash table
- StartIndex = Index = (DWORD)(FileNameHash % pHetTable->dwHashTableSize);
-
- // Go through HET table until we find a terminator
- while(pHetTable->pHetHashes[Index] != HET_ENTRY_FREE)
- {
- // Did we find match ?
- if(pHetTable->pHetHashes[Index] == HetHash)
- {
- DWORD dwFileIndex = 0;
-
- // Get the index of the BetHash
- pHetTable->pBetIndexes->GetBits(pHetTable->dwIndexSizeTotal * Index,
- pHetTable->dwIndexSize,
- &dwFileIndex,
- 4);
-
- //
- // TODO: This condition only happens when we are opening a MPQ
- // where some files were deleted by StormLib. Perhaps
- // we should not allow shrinking of the file table in MPQs v 4.0?
- // assert(dwFileIndex <= ha->dwFileTableSize);
- //
-
- // Verify the BetHash against the entry in the table of BET hashes
- if(dwFileIndex <= ha->dwFileTableSize && ha->pFileTable[dwFileIndex].BetHash == BetHash)
- return dwFileIndex;
- }
-
- // Move to the next entry in the primary search table
- // If we came to the start index again, we are done
- Index = (Index + 1) % pHetTable->dwHashTableSize;
- if(Index == StartIndex)
- break;
- }
-
- // File not found
- return HASH_ENTRY_FREE;
-}
-
-DWORD AllocateHetEntry(
- TMPQArchive * ha,
- TFileEntry * pFileEntry)
-{
- TMPQHetTable * pHetTable = ha->pHetTable;
- ULONGLONG FileNameHash;
- ULONGLONG AndMask64;
- ULONGLONG OrMask64;
- ULONGLONG BetHash;
- DWORD FreeHetIndex = HASH_ENTRY_FREE;
- DWORD dwFileIndex;
- DWORD StartIndex;
- DWORD Index;
- BYTE HetHash; // Upper 8 bits of the masked file name hash
-
- // Do nothing if the MPQ has no HET table
- assert(ha->pHetTable != NULL);
-
- // Calculate 64-bit hash of the file name
- AndMask64 = pHetTable->AndMask64;
- OrMask64 = pHetTable->OrMask64;
- FileNameHash = (HashStringJenkins(pFileEntry->szFileName) & AndMask64) | OrMask64;
-
- // Calculate the starting index to the hash table
- StartIndex = Index = (DWORD)(FileNameHash % pHetTable->dwHashTableSize);
-
- // Split the file name hash into two parts:
- // Part 1: The highest 8 bits of the name hash
- // Part 2: The rest of the name hash (without the highest 8 bits)
- HetHash = (BYTE)(FileNameHash >> (pHetTable->dwHashBitSize - 8));
- BetHash = FileNameHash & (AndMask64 >> 0x08);
-
- // Go through HET table until we find a terminator
- for(;;)
- {
- // Check for entries that might have been deleted
- if(pHetTable->pHetHashes[Index] == HET_ENTRY_DELETED)
- {
- DWORD dwInvalidBetIndex = (1 << pHetTable->dwIndexSizeTotal) - 1;
- DWORD dwBetIndex = 0;
-
- // Verify the BET index. If it's really free, we can use it
- dwFileIndex = (DWORD)(pFileEntry - ha->pFileTable);
- pHetTable->pBetIndexes->GetBits(pHetTable->dwIndexSizeTotal * Index,
- pHetTable->dwIndexSize,
- &dwBetIndex,
- 4);
-
- if(dwBetIndex == dwInvalidBetIndex)
- {
- FreeHetIndex = Index;
- break;
- }
- }
-
- // Is that entry free ?
- if(pHetTable->pHetHashes[Index] == HET_ENTRY_FREE)
- {
- FreeHetIndex = Index;
- break;
- }
-
- // Move to the next entry in the primary search table
- // If we came to the start index again, we are done
- Index = (Index + 1) % pHetTable->dwHashTableSize;
- if(Index == StartIndex)
- return HASH_ENTRY_FREE;
- }
-
- // Fill the HET table entry
- dwFileIndex = (DWORD)(pFileEntry - ha->pFileTable);
- pHetTable->pHetHashes[FreeHetIndex] = HetHash;
- pHetTable->pBetIndexes->SetBits(pHetTable->dwIndexSizeTotal * FreeHetIndex,
- pHetTable->dwIndexSize,
- &dwFileIndex,
- 4);
- // Fill the file entry
- pFileEntry->BetHash = BetHash;
- pFileEntry->dwHetIndex = FreeHetIndex;
- return FreeHetIndex;
-}
-
-void FreeHetTable(TMPQHetTable * pHetTable)
-{
- if(pHetTable != NULL)
- {
- if(pHetTable->pHetHashes != NULL)
- STORM_FREE(pHetTable->pHetHashes);
- if(pHetTable->pBetIndexes != NULL)
- STORM_FREE(pHetTable->pBetIndexes);
-
- STORM_FREE(pHetTable);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Support for BET table
-
-static void CreateBetHeader(
- TMPQArchive * ha,
- PBET_TABLE_HEADER pBetHeader)
-{
- TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
- TFileEntry * pFileEntry;
- ULONGLONG MaxByteOffset = 0;
- DWORD FlagArray[MAX_FLAG_INDEX];
- DWORD dwMaxFlagIndex = 0;
- DWORD dwMaxFileSize = 0;
- DWORD dwMaxCmpSize = 0;
- DWORD dwFlagIndex;
-
- // Initialize array of flag combinations
- InitFileFlagArray(FlagArray);
-
- // Get the maximum values for the BET table
- for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
- {
- // Highest file position in the MPQ
- if(pFileEntry->ByteOffset > MaxByteOffset)
- MaxByteOffset = pFileEntry->ByteOffset;
-
- // Biggest file size
- if(pFileEntry->dwFileSize > dwMaxFileSize)
- dwMaxFileSize = pFileEntry->dwFileSize;
-
- // Biggest compressed size
- if(pFileEntry->dwCmpSize > dwMaxCmpSize)
- dwMaxCmpSize = pFileEntry->dwCmpSize;
-
- // Check if this flag was there before
- dwFlagIndex = GetFileFlagIndex(FlagArray, pFileEntry->dwFlags);
- if(dwFlagIndex > dwMaxFlagIndex)
- dwMaxFlagIndex = dwFlagIndex;
- }
-
- // Now save bit count for every piece of file information
- pBetHeader->dwBitIndex_FilePos = 0;
- pBetHeader->dwBitCount_FilePos = GetNecessaryBitCount(MaxByteOffset);
-
- pBetHeader->dwBitIndex_FileSize = pBetHeader->dwBitIndex_FilePos + pBetHeader->dwBitCount_FilePos;
- pBetHeader->dwBitCount_FileSize = GetNecessaryBitCount(dwMaxFileSize);
-
- pBetHeader->dwBitIndex_CmpSize = pBetHeader->dwBitIndex_FileSize + pBetHeader->dwBitCount_FileSize;
- pBetHeader->dwBitCount_CmpSize = GetNecessaryBitCount(dwMaxCmpSize);
-
- pBetHeader->dwBitIndex_FlagIndex = pBetHeader->dwBitIndex_CmpSize + pBetHeader->dwBitCount_CmpSize;
- pBetHeader->dwBitCount_FlagIndex = GetNecessaryBitCount(dwMaxFlagIndex + 1);
-
- pBetHeader->dwBitIndex_Unknown = pBetHeader->dwBitIndex_FlagIndex + pBetHeader->dwBitCount_FlagIndex;
- pBetHeader->dwBitCount_Unknown = 0;
-
- // Calculate the total size of one entry
- pBetHeader->dwTableEntrySize = pBetHeader->dwBitCount_FilePos +
- pBetHeader->dwBitCount_FileSize +
- pBetHeader->dwBitCount_CmpSize +
- pBetHeader->dwBitCount_FlagIndex +
- pBetHeader->dwBitCount_Unknown;
-
- // Save the file count and flag count
- pBetHeader->dwFileCount = ha->dwFileTableSize;
- pBetHeader->dwFlagCount = dwMaxFlagIndex + 1;
- pBetHeader->dwUnknown08 = 0x10;
-
- // Save the total size of the BET hash
- pBetHeader->dwBetHashSizeTotal = ha->pHetTable->dwHashBitSize - 0x08;
- pBetHeader->dwBetHashSizeExtra = 0;
- pBetHeader->dwBetHashSize = pBetHeader->dwBetHashSizeTotal;
- pBetHeader->dwBetHashArraySize = ((pBetHeader->dwBetHashSizeTotal * pBetHeader->dwFileCount) + 7) / 8;
-
- // Save the total table size
- pBetHeader->dwTableSize = sizeof(BET_TABLE_HEADER) +
- pBetHeader->dwFlagCount * sizeof(DWORD) +
- ((pBetHeader->dwTableEntrySize * pBetHeader->dwFileCount) + 7) / 8 +
- pBetHeader->dwBetHashArraySize;
-}
-
-TMPQBetTable * CreateBetTable(DWORD dwFileCount)
-{
- TMPQBetTable * pBetTable;
-
- // Allocate BET table
- pBetTable = STORM_ALLOC(TMPQBetTable, 1);
- if(pBetTable != NULL)
- {
- memset(pBetTable, 0, sizeof(TMPQBetTable));
- pBetTable->dwFileCount = dwFileCount;
- }
-
- return pBetTable;
-}
-
-static TMPQBetTable * TranslateBetTable(
- TMPQArchive * ha,
- TMPQExtTable * pExtTable)
-{
- BET_TABLE_HEADER BetHeader;
- TMPQBetTable * pBetTable = NULL;
- LPBYTE pbSrcData = (LPBYTE)(pExtTable + 1);
- DWORD LengthInBytes;
-
- // Sanity check
- assert(pExtTable->dwSignature == BET_TABLE_SIGNATURE);
- assert(pExtTable->dwVersion == 1);
- assert(ha->pHetTable != NULL);
- ha = ha;
-
- // Verify size of the HET table
- if(pExtTable != NULL && pExtTable->dwDataSize >= sizeof(BET_TABLE_HEADER))
- {
- // Copy the table header in order to have it aligned and swapped
- memcpy(&BetHeader, pbSrcData, sizeof(BET_TABLE_HEADER));
- BSWAP_ARRAY32_UNSIGNED(&BetHeader, sizeof(BET_TABLE_HEADER));
- pbSrcData += sizeof(BET_TABLE_HEADER);
-
- // Some MPQs affected by a bug in StormLib have pBetTable->dwFileCount
- // greater than ha->dwMaxFileCount
- if(BetHeader.dwFileCount > ha->dwMaxFileCount)
- return NULL;
-
- // Verify the size of the table in the header
- if(BetHeader.dwTableSize == pExtTable->dwDataSize)
- {
- // Create translated table
- pBetTable = CreateBetTable(BetHeader.dwFileCount);
- if(pBetTable != NULL)
- {
- // Copy the variables from the header to the BetTable
- pBetTable->dwTableEntrySize = BetHeader.dwTableEntrySize;
- pBetTable->dwBitIndex_FilePos = BetHeader.dwBitIndex_FilePos;
- pBetTable->dwBitIndex_FileSize = BetHeader.dwBitIndex_FileSize;
- pBetTable->dwBitIndex_CmpSize = BetHeader.dwBitIndex_CmpSize;
- pBetTable->dwBitIndex_FlagIndex = BetHeader.dwBitIndex_FlagIndex;
- pBetTable->dwBitIndex_Unknown = BetHeader.dwBitIndex_Unknown;
- pBetTable->dwBitCount_FilePos = BetHeader.dwBitCount_FilePos;
- pBetTable->dwBitCount_FileSize = BetHeader.dwBitCount_FileSize;
- pBetTable->dwBitCount_CmpSize = BetHeader.dwBitCount_CmpSize;
- pBetTable->dwBitCount_FlagIndex = BetHeader.dwBitCount_FlagIndex;
- pBetTable->dwBitCount_Unknown = BetHeader.dwBitCount_Unknown;
-
- // Since we don't know what the "unknown" is, we'll assert when it's nonzero
- assert(pBetTable->dwBitCount_Unknown == 0);
-
- // Allocate array for flags
- if(BetHeader.dwFlagCount != 0)
- {
- // Allocate array for file flags and load it
- pBetTable->pFileFlags = STORM_ALLOC(DWORD, BetHeader.dwFlagCount);
- if(pBetTable->pFileFlags != NULL)
- {
- LengthInBytes = BetHeader.dwFlagCount * sizeof(DWORD);
- memcpy(pBetTable->pFileFlags, pbSrcData, LengthInBytes);
- BSWAP_ARRAY32_UNSIGNED(pBetTable->pFileFlags, LengthInBytes);
- pbSrcData += LengthInBytes;
- }
-
- // Save the number of flags
- pBetTable->dwFlagCount = BetHeader.dwFlagCount;
- }
-
- // Load the bit-based file table
- pBetTable->pFileTable = CreateBitArray(pBetTable->dwTableEntrySize * BetHeader.dwFileCount, 0);
- LengthInBytes = (pBetTable->pFileTable->NumberOfBits + 7) / 8;
- if(pBetTable->pFileTable != NULL)
- memcpy(pBetTable->pFileTable->Elements, pbSrcData, LengthInBytes);
- pbSrcData += LengthInBytes;
-
- // Fill the sizes of BET hash
- pBetTable->dwBetHashSizeTotal = BetHeader.dwBetHashSizeTotal;
- pBetTable->dwBetHashSizeExtra = BetHeader.dwBetHashSizeExtra;
- pBetTable->dwBetHashSize = BetHeader.dwBetHashSize;
-
- // Create and load the array of BET hashes
- pBetTable->pBetHashes = CreateBitArray(pBetTable->dwBetHashSizeTotal * BetHeader.dwFileCount, 0);
- LengthInBytes = (pBetTable->pBetHashes->NumberOfBits + 7) / 8;
- if(pBetTable->pBetHashes != NULL)
- memcpy(pBetTable->pBetHashes->Elements, pbSrcData, LengthInBytes);
- pbSrcData += BetHeader.dwBetHashArraySize;
-
- // Dump both tables
-// DumpHetAndBetTable(ha->pHetTable, pBetTable);
- }
- }
- }
-
- return pBetTable;
-}
-
-TMPQExtTable * TranslateBetTable(
- TMPQArchive * ha,
- ULONGLONG * pcbBetTable)
-{
- TMPQExtTable * pExtTable = NULL;
- BET_TABLE_HEADER BetHeader;
- TBitArray * pBitArray = NULL;
- LPBYTE pbLinearTable = NULL;
- LPBYTE pbTrgData;
- size_t BetTableSize;
- DWORD LengthInBytes;
- DWORD FlagArray[MAX_FLAG_INDEX];
- DWORD i;
-
- // Calculate the bit sizes of various entries
- InitFileFlagArray(FlagArray);
- CreateBetHeader(ha, &BetHeader);
-
- // Calculate the size of the BET table
- BetTableSize = sizeof(BET_TABLE_HEADER) +
- BetHeader.dwFlagCount * sizeof(DWORD) +
- ((BetHeader.dwTableEntrySize * BetHeader.dwFileCount) + 7) / 8 +
- BetHeader.dwBetHashArraySize;
-
- // Allocate space
- pbLinearTable = STORM_ALLOC(BYTE, sizeof(TMPQExtTable) + BetTableSize);
- if(pbLinearTable != NULL)
- {
- // Create the common ext table header
- pExtTable = (TMPQExtTable *)pbLinearTable;
- pExtTable->dwSignature = BET_TABLE_SIGNATURE;
- pExtTable->dwVersion = 1;
- pExtTable->dwDataSize = (DWORD)BetTableSize;
- pbTrgData = (LPBYTE)(pExtTable + 1);
-
- // Copy the BET table header
- memcpy(pbTrgData, &BetHeader, sizeof(BET_TABLE_HEADER));
- BSWAP_ARRAY32_UNSIGNED(pbTrgData, sizeof(BET_TABLE_HEADER));
- pbTrgData += sizeof(BET_TABLE_HEADER);
-
- // Save the bit-based block table
- pBitArray = CreateBitArray(BetHeader.dwFileCount * BetHeader.dwTableEntrySize, 0);
- if(pBitArray != NULL)
- {
- TFileEntry * pFileEntry = ha->pFileTable;
- DWORD dwFlagIndex = 0;
- DWORD nBitOffset = 0;
-
- // Construct the array of flag values and bit-based file table
- for(i = 0; i < BetHeader.dwFileCount; i++, pFileEntry++)
- {
- //
- // Note: Blizzard MPQs contain valid values even for non-existant files
- // (FilePos, FileSize, CmpSize and FlagIndex)
- // Note: If flags is zero, it must be in the flag table too !!!
- //
-
- // Save the byte offset
- pBitArray->SetBits(nBitOffset + BetHeader.dwBitIndex_FilePos,
- BetHeader.dwBitCount_FilePos,
- &pFileEntry->ByteOffset,
- 8);
- pBitArray->SetBits(nBitOffset + BetHeader.dwBitIndex_FileSize,
- BetHeader.dwBitCount_FileSize,
- &pFileEntry->dwFileSize,
- 4);
- pBitArray->SetBits(nBitOffset + BetHeader.dwBitIndex_CmpSize,
- BetHeader.dwBitCount_CmpSize,
- &pFileEntry->dwCmpSize,
- 4);
-
- // Save the flag index
- dwFlagIndex = GetFileFlagIndex(FlagArray, pFileEntry->dwFlags);
- pBitArray->SetBits(nBitOffset + BetHeader.dwBitIndex_FlagIndex,
- BetHeader.dwBitCount_FlagIndex,
- &dwFlagIndex,
- 4);
-
- // Move the bit offset
- nBitOffset += BetHeader.dwTableEntrySize;
- }
-
- // Write the array of flags
- LengthInBytes = BetHeader.dwFlagCount * sizeof(DWORD);
- memcpy(pbTrgData, FlagArray, LengthInBytes);
- BSWAP_ARRAY32_UNSIGNED(pbTrgData, LengthInBytes);
- pbTrgData += LengthInBytes;
-
- // Write the bit-based block table
- LengthInBytes = (pBitArray->NumberOfBits + 7) / 8;
- memcpy(pbTrgData, pBitArray->Elements, LengthInBytes);
- pbTrgData += LengthInBytes;
-
- // Free the bit array
- STORM_FREE(pBitArray);
- }
-
- // Create bit array for BET hashes
- pBitArray = CreateBitArray(BetHeader.dwBetHashSizeTotal * BetHeader.dwFileCount, 0);
- if(pBitArray != NULL)
- {
- TFileEntry * pFileEntry = ha->pFileTable;
- ULONGLONG AndMask64 = ha->pHetTable->AndMask64;
- ULONGLONG OrMask64 = ha->pHetTable->OrMask64;
-
- for(i = 0; i < BetHeader.dwFileCount; i++)
- {
- ULONGLONG FileNameHash = 0;
-
- // Calculate 64-bit hash of the file name
- if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) && pFileEntry->szFileName != NULL)
- {
- FileNameHash = (HashStringJenkins(pFileEntry->szFileName) & AndMask64) | OrMask64;
- FileNameHash = FileNameHash & (AndMask64 >> 0x08);
- }
-
- // Insert the name hash to the bit array
- pBitArray->SetBits(BetHeader.dwBetHashSizeTotal * i,
- BetHeader.dwBetHashSize,
- &FileNameHash,
- 8);
-
- // Move to the next file entry
- pFileEntry++;
- }
-
- // Write the array of BET hashes
- LengthInBytes = (pBitArray->NumberOfBits + 7) / 8;
- memcpy(pbTrgData, pBitArray->Elements, LengthInBytes);
- pbTrgData += LengthInBytes;
-
- // Free the bit array
- STORM_FREE(pBitArray);
- }
-
- // Write the size of the BET table in the MPQ
- if(pcbBetTable != NULL)
- {
- *pcbBetTable = (ULONGLONG)(sizeof(TMPQExtTable) + BetTableSize);
- }
- }
-
- return pExtTable;
-}
-
-void FreeBetTable(TMPQBetTable * pBetTable)
-{
- if(pBetTable != NULL)
- {
- if(pBetTable->pFileTable != NULL)
- STORM_FREE(pBetTable->pFileTable);
- if(pBetTable->pFileFlags != NULL)
- STORM_FREE(pBetTable->pFileFlags);
- if(pBetTable->pBetHashes != NULL)
- STORM_FREE(pBetTable->pBetHashes);
-
- STORM_FREE(pBetTable);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Support for file table
-
-TFileEntry * GetFileEntryAny(TMPQArchive * ha, const char * szFileName)
-{
- TMPQHash * pHash;
- DWORD dwFileIndex;
-
- // If we have HET table in the MPQ, try to find the file in HET table
- if(ha->pHetTable != NULL)
- {
- dwFileIndex = GetFileIndex_Het(ha, szFileName);
- if(dwFileIndex != HASH_ENTRY_FREE)
- return ha->pFileTable + dwFileIndex;
- }
-
- // Otherwise, perform the file search in the classic hash table
- if(ha->pHashTable != NULL)
- {
- pHash = GetHashEntryAny(ha, szFileName);
- if(pHash != NULL && pHash->dwBlockIndex < ha->dwFileTableSize)
- return ha->pFileTable + pHash->dwBlockIndex;
- }
-
- // Not found
- return NULL;
-}
-
-TFileEntry * GetFileEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale)
-{
- TMPQHash * pHash;
- DWORD dwFileIndex;
-
- // If we have HET table in the MPQ, try to find the file in HET table
- if(ha->pHetTable != NULL)
- {
- dwFileIndex = GetFileIndex_Het(ha, szFileName);
- if(dwFileIndex != HASH_ENTRY_FREE)
- return ha->pFileTable + dwFileIndex;
- }
-
- // Otherwise, perform the file search in the classic hash table
- if(ha->pHashTable != NULL)
- {
- pHash = GetHashEntryLocale(ha, szFileName, lcLocale);
- if(pHash != NULL && pHash->dwBlockIndex < ha->dwFileTableSize)
- return ha->pFileTable + pHash->dwBlockIndex;
- }
-
- // Not found
- return NULL;
-}
-
-TFileEntry * GetFileEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcLocale)
-{
- TMPQHash * pHash;
- DWORD dwFileIndex;
-
- // If we have HET table in the MPQ, try to find the file in HET table
- if(ha->pHetTable != NULL)
- {
- dwFileIndex = GetFileIndex_Het(ha, szFileName);
- if(dwFileIndex != HASH_ENTRY_FREE)
- return ha->pFileTable + dwFileIndex;
- }
-
- // Otherwise, perform the file search in the classic hash table
- if(ha->pHashTable != NULL)
- {
- pHash = GetHashEntryExact(ha, szFileName, lcLocale);
- if(pHash != NULL && pHash->dwBlockIndex < ha->dwFileTableSize)
- return ha->pFileTable + pHash->dwBlockIndex;
- }
-
- // Not found
- return NULL;
-}
-
-TFileEntry * GetFileEntryByIndex(TMPQArchive * ha, DWORD dwIndex)
-{
- // For MPQs with classic hash table
- if(dwIndex < ha->dwFileTableSize)
- return ha->pFileTable + dwIndex;
- return NULL;
-}
-
-void AllocateFileName(TFileEntry * pFileEntry, const char * szFileName)
-{
- // Sanity check
- assert(pFileEntry != NULL);
-
- // If the file name is pseudo file name, free it at this point
- if(IsPseudoFileName(pFileEntry->szFileName, NULL))
- {
- if(pFileEntry->szFileName != NULL)
- STORM_FREE(pFileEntry->szFileName);
- pFileEntry->szFileName = NULL;
- }
-
- // Only allocate new file name if it's not there yet
- if(pFileEntry->szFileName == NULL)
- {
- pFileEntry->szFileName = STORM_ALLOC(char, strlen(szFileName) + 1);
- if(pFileEntry->szFileName != NULL)
- strcpy(pFileEntry->szFileName, szFileName);
- }
-}
-
-
-// Finds a free file entry. Does NOT increment table size.
-TFileEntry * FindFreeFileEntry(TMPQArchive * ha)
-{
- TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
- TFileEntry * pFreeEntry = NULL;
- TFileEntry * pFileEntry;
-
- // Try to find a free entry
- for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
- {
- // If that entry is free, we reuse it
- if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) == 0)
- {
- pFreeEntry = pFileEntry;
- break;
- }
-
- //
- // Note: Files with "delete marker" are not deleted.
- // Don't consider them free entries
- //
- }
-
- // Do we have a deleted entry?
- if(pFreeEntry != NULL)
- {
- ClearFileEntry(ha, pFreeEntry);
- return pFreeEntry;
- }
-
- // If no file entry within the existing file table is free,
- // we try the reserve space after current file table
- if(ha->dwFileTableSize < ha->dwMaxFileCount)
- return ha->pFileTable + ha->dwFileTableSize;
-
- // If we reached maximum file count, we cannot add more files to the MPQ
- assert(ha->dwFileTableSize == ha->dwMaxFileCount);
- return NULL;
-}
-
-
-TFileEntry * AllocateFileEntry(TMPQArchive * ha, const char * szFileName, LCID lcLocale)
-{
- TFileEntry * pFileEntry = NULL;
- TMPQHash * pHash;
- DWORD dwHashIndex;
- DWORD dwFileIndex;
- bool bHashEntryExists = false;
- bool bHetEntryExists = false;
-
- // If the archive has classic hash table, we try to
- // find the file in the hash table
- if(ha->pHashTable != NULL)
- {
- // If the hash entry is already there, we reuse the file entry
- pHash = GetHashEntryExact(ha, szFileName, lcLocale);
- if(pHash != NULL)
- {
- pFileEntry = ha->pFileTable + pHash->dwBlockIndex;
- bHashEntryExists = true;
- }
- }
-
- // If the archive has HET table, try to use it for
- // finding the file
- if(ha->pHetTable != NULL)
- {
- dwFileIndex = GetFileIndex_Het(ha, szFileName);
- if(dwFileIndex != HASH_ENTRY_FREE)
- {
- pFileEntry = ha->pFileTable + dwFileIndex;
- bHetEntryExists = true;
- }
- }
-
- // If still haven't found the file entry, we allocate new one
- if(pFileEntry == NULL)
- {
- pFileEntry = FindFreeFileEntry(ha);
- if(pFileEntry == NULL)
- return NULL;
- }
-
- // Fill the rest of the file entry
- pFileEntry->ByteOffset = 0;
- pFileEntry->FileTime = 0;
- pFileEntry->dwFileSize = 0;
- pFileEntry->dwCmpSize = 0;
- pFileEntry->dwFlags = 0;
- pFileEntry->lcLocale = 0;
- pFileEntry->wPlatform = 0;
- pFileEntry->dwCrc32 = 0;
- memset(pFileEntry->md5, 0, MD5_DIGEST_SIZE);
-
- // Allocate space for file name, if it's not there yet
- AllocateFileName(pFileEntry, szFileName);
-
- // If the free file entry is at the end of the file table,
- // we have to increment file table size
- if(pFileEntry == ha->pFileTable + ha->dwFileTableSize)
- {
- assert(ha->dwFileTableSize < ha->dwMaxFileCount);
- ha->pHeader->dwBlockTableSize++;
- ha->dwFileTableSize++;
- }
-
- // If the MPQ has hash table, we have to insert the new entry into the hash table
- if(ha->pHashTable != NULL && bHashEntryExists == false)
- {
- dwHashIndex = AllocateHashEntry(ha, pFileEntry);
- assert(dwHashIndex != HASH_ENTRY_FREE);
- }
-
- // If the MPQ has HET table, we have to insert it to the HET table as well
- if(ha->pHetTable != NULL && bHetEntryExists == false)
- {
- // TODO: Does HET table even support locales?
- // Most probably, Blizzard gave up that silly idea long ago.
- dwHashIndex = AllocateHetEntry(ha, pFileEntry);
- assert(dwHashIndex != HASH_ENTRY_FREE);
- }
-
- // Return the file entry
- return pFileEntry;
-}
-
-int RenameFileEntry(
- TMPQArchive * ha,
- TFileEntry * pFileEntry,
- const char * szNewFileName)
-{
- TMPQHash * pHash;
- DWORD dwFileIndex;
- int nError = ERROR_SUCCESS;
-
- // If the MPQ has classic hash table, clear the entry there
- if(ha->pHashTable != NULL)
- {
- assert(pFileEntry->dwHashIndex < ha->pHeader->dwHashTableSize);
-
- pHash = ha->pHashTable + pFileEntry->dwHashIndex;
- memset(pHash, 0xFF, sizeof(TMPQHash));
- pHash->dwBlockIndex = HASH_ENTRY_DELETED;
- }
-
- // If the MPQ has HET table, clear the entry there as well
- if(ha->pHetTable != NULL)
- {
- TMPQHetTable * pHetTable = ha->pHetTable;
- DWORD dwInvalidFileIndex = (1 << pHetTable->dwIndexSizeTotal) - 1;
-
- assert(pFileEntry->dwHetIndex < pHetTable->dwHashTableSize);
-
- // Clear the entry in the HET hash array
- pHetTable->pHetHashes[pFileEntry->dwHetIndex] = HET_ENTRY_DELETED;
-
- // Set the BET index to invalid index
- pHetTable->pBetIndexes->SetBits(pHetTable->dwIndexSizeTotal * pFileEntry->dwHetIndex,
- pHetTable->dwIndexSize,
- &dwInvalidFileIndex,
- 4);
- }
-
- // Free the old file name
- if(pFileEntry->szFileName != NULL)
- STORM_FREE(pFileEntry->szFileName);
- pFileEntry->szFileName = NULL;
-
- // Allocate new file name
- AllocateFileName(pFileEntry, szNewFileName);
-
- // Now find a hash entry for the new file name
- if(ha->pHashTable != NULL)
- {
- // Try to find the hash table entry for the new file name
- // Note: If this fails, we leave the MPQ in a corrupt state
- dwFileIndex = AllocateHashEntry(ha, pFileEntry);
- if(dwFileIndex == HASH_ENTRY_FREE)
- nError = ERROR_FILE_CORRUPT;
- }
-
- // If the archive has HET table, we have to allocate HET table for the file as well
- // finding the file
- if(ha->pHetTable != NULL)
- {
- dwFileIndex = AllocateHetEntry(ha, pFileEntry);
- if(dwFileIndex == HASH_ENTRY_FREE)
- nError = ERROR_FILE_CORRUPT;
- }
-
- // Invalidate the entries for (listfile) and (attributes)
- // After we are done with MPQ changes, we need to re-create them
- InvalidateInternalFiles(ha);
- return nError;
-}
-
-void ClearFileEntry(
- TMPQArchive * ha,
- TFileEntry * pFileEntry)
-{
- TMPQHash * pHash = NULL;
-
- // If the MPQ has classic hash table, clear the entry there
- if(ha->pHashTable != NULL)
- {
- assert(pFileEntry->dwHashIndex < ha->pHeader->dwHashTableSize);
-
- pHash = ha->pHashTable + pFileEntry->dwHashIndex;
- memset(pHash, 0xFF, sizeof(TMPQHash));
- pHash->dwBlockIndex = HASH_ENTRY_DELETED;
- }
-
- // If the MPQ has HET table, clear the entry there as well
- if(ha->pHetTable != NULL)
- {
- TMPQHetTable * pHetTable = ha->pHetTable;
- DWORD dwInvalidFileIndex = (1 << pHetTable->dwIndexSizeTotal) - 1;
-
- assert(pFileEntry->dwHetIndex < pHetTable->dwHashTableSize);
-
- // Clear the entry in the HET hash array
- pHetTable->pHetHashes[pFileEntry->dwHetIndex] = HET_ENTRY_DELETED;
-
- // Set the BET index to invalid index
- pHetTable->pBetIndexes->SetBits(pHetTable->dwIndexSizeTotal * pFileEntry->dwHetIndex,
- pHetTable->dwIndexSize,
- &dwInvalidFileIndex,
- 4);
- }
-
- // Free the file name, and set the file entry as deleted
- if(pFileEntry->szFileName != NULL)
- STORM_FREE(pFileEntry->szFileName);
-
- // Invalidate the file entry
- memset(pFileEntry, 0, sizeof(TFileEntry));
-}
-
-int FreeFileEntry(
- TMPQArchive * ha,
- TFileEntry * pFileEntry)
-{
- TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
- TFileEntry * pTempEntry;
- int nError = ERROR_SUCCESS;
-
- //
- // If we have HET table, we cannot just get rid of the file
- // Doing so would lead to empty gaps in the HET table
- // We have to keep BET hash, hash index, HET index, locale, platform and file name
- //
-
- if(ha->pHetTable == NULL)
- {
- TFileEntry * pLastFileEntry = ha->pFileTable + ha->dwFileTableSize - 1;
- TFileEntry * pLastUsedEntry = pLastFileEntry;
-
- // Zero the file entry
- ClearFileEntry(ha, pFileEntry);
-
- // Now there is a chance that we created a chunk of free
- // file entries at the end of the file table. We check this
- // and eventually free all deleted file entries at the end
- for(pTempEntry = ha->pFileTable; pTempEntry < pFileTableEnd; pTempEntry++)
- {
- // Is that an occupied file entry?
- if(pTempEntry->dwFlags & MPQ_FILE_EXISTS)
- pLastUsedEntry = pTempEntry;
- }
-
- // Can we free some entries at the end?
- if(pLastUsedEntry < pLastFileEntry)
- {
- // Fix the size of the file table entry
- ha->dwFileTableSize = (DWORD)(pLastUsedEntry - ha->pFileTable) + 1;
- ha->pHeader->dwBlockTableSize = ha->dwFileTableSize;
- }
- }
- else
- {
- // Note: Deleted entries in Blizzard MPQs version 4.0
- // normally contain valid byte offset and length
- pFileEntry->dwFlags &= ~MPQ_FILE_EXISTS;
- nError = ERROR_SUCCESS;
- }
-
- return nError;
-}
-
-void InvalidateInternalFiles(TMPQArchive * ha)
-{
- TFileEntry * pFileEntry;
-
- // Invalidate the (listfile), if not done yet
- if(!(ha->dwFlags & MPQ_FLAG_INV_LISTFILE))
- {
- pFileEntry = GetFileEntryExact(ha, LISTFILE_NAME, LANG_NEUTRAL);
- if(pFileEntry != NULL)
- FreeFileEntry(ha, pFileEntry);
- ha->dwFlags |= MPQ_FLAG_INV_LISTFILE;
- }
-
- // Invalidate the (attributes), if not done yet
- if(!(ha->dwFlags & MPQ_FLAG_INV_ATTRIBUTES))
- {
- pFileEntry = GetFileEntryExact(ha, ATTRIBUTES_NAME, LANG_NEUTRAL);
- if(pFileEntry != NULL)
- FreeFileEntry(ha, pFileEntry);
- ha->dwFlags |= MPQ_FLAG_INV_ATTRIBUTES;
- }
-
- // Remember that the MPQ has been changed and it will be necessary
- // to update the tables
- ha->dwFlags |= MPQ_FLAG_CHANGED;
-}
-
-//-----------------------------------------------------------------------------
-// Functions that loads and verify MPQ data bitmap
-
-int LoadMpqDataBitmap(TMPQArchive * ha, ULONGLONG FileSize, bool * pbFileIsComplete)
-{
- TMPQBitmap * pBitmap = NULL;
- TMPQBitmap DataBitmap;
- ULONGLONG BitmapOffset;
- ULONGLONG EndOfMpq;
- DWORD DataBlockCount = 0;
- DWORD BitmapByteSize;
- DWORD WholeByteCount;
- DWORD ExtraBitsCount;
-
- // Is there enough space for a MPQ bitmap?
- EndOfMpq = ha->MpqPos + ha->pHeader->ArchiveSize64;
- FileSize = FileSize - sizeof(TMPQBitmap);
- if(FileSize > EndOfMpq)
- {
- // Try to load the data bitmap from the end of the file
- if(FileStream_Read(ha->pStream, &FileSize, &DataBitmap, sizeof(TMPQBitmap)))
- {
- // Is it a valid data bitmap?
- BSWAP_ARRAY32_UNSIGNED((LPDWORD)(&DataBitmap), sizeof(TMPQBitmap));
- if(DataBitmap.dwSignature == MPQ_DATA_BITMAP_SIGNATURE)
- {
- // We assume that MPQs with data bitmap begin at position 0
- assert(ha->MpqPos == 0);
-
- // Calculate the number of extra bytes for data bitmap
- DataBlockCount = (DWORD)(((ha->pHeader->ArchiveSize64 - 1) / DataBitmap.dwBlockSize) + 1);
- BitmapByteSize = ((DataBlockCount - 1) / 8) + 1;
-
- // Verify the data block size
- BitmapOffset = ((ULONGLONG)DataBitmap.dwMapOffsetHi << 32) | DataBitmap.dwMapOffsetLo;
- assert((DWORD)(FileSize - BitmapOffset) == BitmapByteSize);
-
- // Allocate space for the data bitmap
- pBitmap = (TMPQBitmap *)STORM_ALLOC(BYTE, sizeof(TMPQBitmap) + BitmapByteSize);
- if(pBitmap != NULL)
- {
- // Copy the bitmap header
- memcpy(pBitmap, &DataBitmap, sizeof(TMPQBitmap));
-
- // Read the remaining part
- if(!FileStream_Read(ha->pStream, &BitmapOffset, (pBitmap + 1), BitmapByteSize))
- {
- STORM_FREE(pBitmap);
- pBitmap = NULL;
- }
- }
- }
- }
- }
-
- // If the caller asks for file completeness, check it
- if(pBitmap != NULL && pbFileIsComplete != NULL)
- {
- LPBYTE pbBitmap = (LPBYTE)(pBitmap + 1);
- DWORD i;
- bool bFileIsComplete = true;
-
- // Calculate the number of whole bytes and extra bits of the bitmap
- WholeByteCount = (DataBlockCount / 8);
- ExtraBitsCount = (DataBlockCount & 7);
-
- // Verify the whole bytes - their value must be 0xFF
- for(i = 0; i < WholeByteCount; i++)
- {
- if(pbBitmap[i] != 0xFF)
- bFileIsComplete = false;
- }
-
- // If there are extra bits, calculate the mask
- if(ExtraBitsCount != 0)
- {
- BYTE ExpectedValue = (BYTE)((1 << ExtraBitsCount) - 1);
-
- if(pbBitmap[i] != ExpectedValue)
- bFileIsComplete = false;
- }
-
- // Give the result to the caller
- *pbFileIsComplete = bFileIsComplete;
- }
-
- ha->pBitmap = pBitmap;
- return ERROR_SUCCESS;
-}
-
-//-----------------------------------------------------------------------------
-// Support for file tables - hash table, block table, hi-block table
-
-int CreateHashTable(TMPQArchive * ha, DWORD dwHashTableSize)
-{
- TMPQHash * pHashTable;
-
- // Sanity checks
- assert((dwHashTableSize & (dwHashTableSize - 1)) == 0);
- assert(ha->pHashTable == NULL);
-
- // Create the hash table
- pHashTable = STORM_ALLOC(TMPQHash, dwHashTableSize);
- if(pHashTable == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Fill it
- memset(pHashTable, 0xFF, dwHashTableSize * sizeof(TMPQHash));
- ha->pHashTable = pHashTable;
-
- // Set the max file count, if needed
- if(ha->pHetTable == NULL)
- ha->dwMaxFileCount = dwHashTableSize;
- return ERROR_SUCCESS;
-}
-
-TMPQHash * LoadHashTable(TMPQArchive * ha)
-{
- TMPQHeader * pHeader = ha->pHeader;
- ULONGLONG ByteOffset;
- TMPQHash * pHashTable;
- DWORD dwTableSize;
- DWORD dwCmpSize;
- int nError;
-
- // If the MPQ has no hash table, do nothing
- if(pHeader->dwHashTablePos == 0 && pHeader->wHashTablePosHi == 0)
- return NULL;
-
- // If the hash table size is zero, do nothing
- if(pHeader->dwHashTableSize == 0)
- return NULL;
-
- // Allocate buffer for the hash table
- dwTableSize = pHeader->dwHashTableSize * sizeof(TMPQHash);
- pHashTable = STORM_ALLOC(TMPQHash, pHeader->dwHashTableSize);
- if(pHashTable == NULL)
- return NULL;
-
- // Compressed size of the hash table
- dwCmpSize = (DWORD)pHeader->HashTableSize64;
-
- //
- // Load the table from the MPQ, with decompression
- //
- // Note: We will NOT check if the hash table is properly decrypted.
- // Some MPQ protectors corrupt the hash table by rewriting part of it.
- // Hash table, the way how it works, allows arbitrary values for unused entries.
- //
-
- ByteOffset = ha->MpqPos + MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos);
- nError = LoadMpqTable(ha, ByteOffset, pHashTable, dwCmpSize, dwTableSize, MPQ_KEY_HASH_TABLE);
- if(nError != ERROR_SUCCESS)
- {
- STORM_FREE(pHashTable);
- pHashTable = NULL;
- }
-
- // Return the hash table
- return pHashTable;
-}
-
-static void FixBlockTableSize(
- TMPQArchive * ha,
- TMPQBlock * pBlockTable,
- DWORD dwClaimedSize)
-{
- TMPQHeader * pHeader = ha->pHeader;
- ULONGLONG BlockTableStart;
- ULONGLONG BlockTableEnd;
- ULONGLONG FileDataStart;
-
- // Only perform this check on MPQs version 1.0
- if(pHeader->dwHeaderSize == MPQ_HEADER_SIZE_V1)
- {
- // Calculate claimed block table begin and end
- BlockTableStart = ha->MpqPos + MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
- BlockTableEnd = BlockTableStart + (pHeader->dwBlockTableSize * sizeof(TMPQBlock));
-
- for(DWORD i = 0; i < dwClaimedSize; i++)
- {
- // If the block table end goes into that file, fix the block table end
- FileDataStart = ha->MpqPos + pBlockTable[i].dwFilePos;
- if(BlockTableStart < FileDataStart && BlockTableEnd > FileDataStart)
- {
- dwClaimedSize = (DWORD)((FileDataStart - BlockTableStart) / sizeof(TMPQBlock));
- BlockTableEnd = FileDataStart;
- }
- }
- }
-
- // Fix the block table size
- pHeader->BlockTableSize64 = dwClaimedSize * sizeof(TMPQBlock);
- pHeader->dwBlockTableSize = dwClaimedSize;
-}
-
-TMPQBlock * LoadBlockTable(TMPQArchive * ha, ULONGLONG FileSize)
-{
- TMPQHeader * pHeader = ha->pHeader;
- TMPQBlock * pBlockTable;
- ULONGLONG ByteOffset;
- DWORD dwTableSize;
- DWORD dwCmpSize;
- int nError;
-
- // Do nothing if the block table position is zero
- if(pHeader->dwBlockTablePos == 0 && pHeader->wBlockTablePosHi == 0)
- return NULL;
-
- // Do nothing if the block table size is zero
- if(pHeader->dwBlockTableSize == 0)
- return NULL;
-
- // Sanity check, enforced by LoadAnyHashTable
- assert(ha->dwMaxFileCount >= pHeader->dwBlockTableSize);
-
- // Calculate sizes of both tables
- ByteOffset = ha->MpqPos + MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
- dwTableSize = pHeader->dwBlockTableSize * sizeof(TMPQBlock);
- dwCmpSize = (DWORD)pHeader->BlockTableSize64;
-
- // Allocate space for the block table
- // Note: pHeader->dwBlockTableSize can be zero !!!
- pBlockTable = STORM_ALLOC(TMPQBlock, ha->dwMaxFileCount);
- if(pBlockTable == NULL)
- return NULL;
-
- // Fill the block table with zeros
- memset(pBlockTable, 0, dwTableSize);
-
- // I found a MPQ which claimed 0x200 entries in the block table,
- // but the file was cut and there was only 0x1A0 entries.
- // We will handle this case properly.
- if(dwTableSize == dwCmpSize && (ByteOffset + dwTableSize) > FileSize)
- {
- pHeader->dwBlockTableSize = (DWORD)((FileSize - ByteOffset) / sizeof(TMPQBlock));
- pHeader->BlockTableSize64 = pHeader->dwBlockTableSize * sizeof(TMPQBlock);
- dwTableSize = dwCmpSize = pHeader->dwBlockTableSize * sizeof(TMPQBlock);
- }
-
- //
- // One of the first cracked versions of Diablo I had block table unencrypted
- // StormLib does NOT support such MPQs anymore, as they are incompatible
- // with compressed block table feature
- //
-
- // Load the block table
- nError = LoadMpqTable(ha, ByteOffset, pBlockTable, dwCmpSize, dwTableSize, MPQ_KEY_BLOCK_TABLE);
- if(nError != ERROR_SUCCESS)
- {
- // Failed, sorry
- STORM_FREE(pBlockTable);
- return NULL;
- }
-
- // Defense against MPQs that claim block table to be bigger than it really is
- FixBlockTableSize(ha, pBlockTable, pHeader->dwBlockTableSize);
- return pBlockTable;
-}
-
-int LoadHetTable(TMPQArchive * ha)
-{
- TMPQExtTable * pExtTable;
- TMPQHeader * pHeader = ha->pHeader;
- int nError = ERROR_SUCCESS;
-
- // If the HET table position is not NULL, we expect
- // both HET and BET tables to be present.
- if(pHeader->HetTablePos64 != 0)
- {
- // Attempt to load the HET table (Hash Extended Table)
- pExtTable = LoadExtTable(ha, pHeader->HetTablePos64, (size_t)pHeader->HetTableSize64, HET_TABLE_SIGNATURE, MPQ_KEY_HASH_TABLE);
- if(pExtTable != NULL)
- {
- // If succeeded, we have to limit the maximum file count
- // to the values saved in the HET table
- // If loading HET table fails, we ignore the result.
- ha->pHetTable = TranslateHetTable(pExtTable);
- if(ha->pHetTable != NULL)
- ha->dwMaxFileCount = ha->pHetTable->dwMaxFileCount;
-
- STORM_FREE(pExtTable);
- }
-
- // If the HET hable failed to load, it's corrupt.
- if(ha->pHetTable == NULL)
- nError = ERROR_FILE_CORRUPT;
- }
-
- return nError;
-}
-
-TMPQBetTable * LoadBetTable(TMPQArchive * ha)
-{
- TMPQExtTable * pExtTable;
- TMPQBetTable * pBetTable = NULL;
- TMPQHeader * pHeader = ha->pHeader;
-
- // If the HET table position is not NULL, we expect
- // both HET and BET tables to be present.
- if(pHeader->BetTablePos64 != 0)
- {
- // Attempt to load the HET table (Hash Extended Table)
- pExtTable = LoadExtTable(ha, pHeader->BetTablePos64, (size_t)pHeader->BetTableSize64, BET_TABLE_SIGNATURE, MPQ_KEY_BLOCK_TABLE);
- if(pExtTable != NULL)
- {
- // If succeeded, we translate the BET table
- // to more readable form
- pBetTable = TranslateBetTable(ha, pExtTable);
- STORM_FREE(pExtTable);
- }
- }
-
- return pBetTable;
-}
-
-int LoadAnyHashTable(TMPQArchive * ha)
-{
- TMPQHeader * pHeader = ha->pHeader;
-
- // If the MPQ archive is empty, don't bother trying to load anything
- if(pHeader->dwHashTableSize == 0 && pHeader->HetTableSize64 == 0)
- return CreateHashTable(ha, HASH_TABLE_SIZE_DEFAULT);
-
- // Try to load HET and/or classic hash table
- LoadHetTable(ha);
-
- // Load the HASH table
- ha->pHashTable = LoadHashTable(ha);
-
- // Set the maximum file count to the size of the hash table
- // In case there is HET table, we have to keep the file limit
- if(ha->pHetTable == NULL)
- ha->dwMaxFileCount = pHeader->dwHashTableSize;
-
- // Did at least one succeed?
- if(ha->pHetTable == NULL && ha->pHashTable == NULL)
- return ERROR_FILE_CORRUPT;
-
- // In theory, a MPQ could have bigger block table than hash table
- if(ha->pHeader->dwBlockTableSize > ha->dwMaxFileCount)
- {
- ha->dwMaxFileCount = ha->pHeader->dwBlockTableSize;
- ha->dwFlags |= MPQ_FLAG_READ_ONLY;
- }
-
- return ERROR_SUCCESS;
-}
-
-int BuildFileTable_Classic(
- TMPQArchive * ha,
- TFileEntry * pFileTable,
- ULONGLONG FileSize)
-{
- TFileEntry * pFileEntry;
- TMPQHeader * pHeader = ha->pHeader;
- TMPQBlock * pBlockTable;
- TMPQBlock * pBlock;
- int nError = ERROR_SUCCESS;
-
- // Sanity checks
- assert(ha->pHashTable != NULL);
-
- // Load the block table
- pBlockTable = LoadBlockTable(ha, FileSize);
- if(pBlockTable != NULL)
- {
- TMPQHash * pHashEnd = ha->pHashTable + pHeader->dwHashTableSize;
- TMPQHash * pHash;
-
- // If we don't have HET table, we build the file entries from the hash&block tables
- if(ha->pHetTable == NULL)
- {
- for(pHash = ha->pHashTable; pHash < pHashEnd; pHash++)
- {
- if(pHash->dwBlockIndex < pHeader->dwBlockTableSize)
- {
- pFileEntry = pFileTable + pHash->dwBlockIndex;
- pBlock = pBlockTable + pHash->dwBlockIndex;
-
- //
- // Yet another silly map protector: For each valid file,
- // there are 4 items in the hash table, that appears to be valid:
- //
- // a6d79af0 e61a0932 001e0000 0000770b <== Fake valid
- // a6d79af0 e61a0932 0000d761 0000dacb <== Fake valid
- // a6d79af0 e61a0932 00000000 0000002f <== Real file entry
- // a6d79af0 e61a0932 00005a4f 000093bc <== Fake valid
- //
-
- if(!(pBlock->dwFlags & ~MPQ_FILE_VALID_FLAGS) && (pBlock->dwFlags & MPQ_FILE_EXISTS))
- {
- // Fill the entry
- pFileEntry->ByteOffset = pBlock->dwFilePos;
- pFileEntry->dwHashIndex = (DWORD)(pHash - ha->pHashTable);
- pFileEntry->dwFileSize = pBlock->dwFSize;
- pFileEntry->dwCmpSize = pBlock->dwCSize;
- pFileEntry->dwFlags = pBlock->dwFlags;
- pFileEntry->lcLocale = pHash->lcLocale;
- pFileEntry->wPlatform = pHash->wPlatform;
- }
- else
- {
- // If the hash table entry doesn't point to the valid file item,
- // we invalidate the entire hash table entry
- pHash->dwName1 = 0xFFFFFFFF;
- pHash->dwName2 = 0xFFFFFFFF;
- pHash->lcLocale = 0xFFFF;
- pHash->wPlatform = 0xFFFF;
- pHash->dwBlockIndex = HASH_ENTRY_DELETED;
- }
- }
- }
- }
- else
- {
- for(pHash = ha->pHashTable; pHash < pHashEnd; pHash++)
- {
- if(pHash->dwBlockIndex < ha->dwFileTableSize)
- {
- pFileEntry = pFileTable + pHash->dwBlockIndex;
- if(pFileEntry->dwFlags & MPQ_FILE_EXISTS)
- {
- pFileEntry->dwHashIndex = (DWORD)(pHash - ha->pHashTable);
- pFileEntry->lcLocale = pHash->lcLocale;
- pFileEntry->wPlatform = pHash->wPlatform;
- }
- }
- }
- }
-
- // Free the block table
- STORM_FREE(pBlockTable);
- }
- else
- {
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Load the hi-block table
- if(nError == ERROR_SUCCESS && pHeader->HiBlockTablePos64 != 0)
- {
- ULONGLONG ByteOffset;
- USHORT * pHiBlockTable = NULL;
- DWORD dwTableSize = pHeader->dwBlockTableSize * sizeof(USHORT);
-
- // Allocate space for the hi-block table
- // Note: pHeader->dwBlockTableSize can be zero !!!
- pHiBlockTable = STORM_ALLOC(USHORT, pHeader->dwBlockTableSize + 1);
- if(pHiBlockTable != NULL)
- {
- // Load the hi-block table. It is not encrypted, nor compressed
- ByteOffset = ha->MpqPos + pHeader->HiBlockTablePos64;
- if(!FileStream_Read(ha->pStream, &ByteOffset, pHiBlockTable, dwTableSize))
- nError = GetLastError();
-
- // Now merge the hi-block table to the file table
- if(nError == ERROR_SUCCESS)
- {
- pFileEntry = pFileTable;
-
- // Add the high file offset to the base file offset.
- // We also need to swap it during the process.
- for(DWORD i = 0; i < pHeader->dwBlockTableSize; i++)
- {
- pFileEntry->ByteOffset |= ((ULONGLONG)BSWAP_INT16_UNSIGNED(pHiBlockTable[i]) << 32);
- pFileEntry++;
- }
- }
-
- // Free the hi-block table
- STORM_FREE(pHiBlockTable);
- }
- else
- {
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
- }
-
- // Set the current size of the file table
- ha->dwFileTableSize = pHeader->dwBlockTableSize;
- return nError;
-}
-
-int BuildFileTable_HetBet(
- TMPQArchive * ha,
- TFileEntry * pFileTable)
-{
- TMPQHetTable * pHetTable = ha->pHetTable;
- TMPQBetTable * pBetTable;
- TFileEntry * pFileEntry = pFileTable;
- TBitArray * pBitArray;
- DWORD dwBitPosition = 0;
- DWORD i;
- int nError = ERROR_FILE_CORRUPT;
-
- // Load the BET table from the MPQ
- pBetTable = LoadBetTable(ha);
- if(pBetTable != NULL)
- {
- // Step one: Fill the indexes to the HET table
- for(i = 0; i < pHetTable->dwHashTableSize; i++)
- {
- DWORD dwFileIndex = 0;
-
- // Is the entry in the HET table occupied?
- if(pHetTable->pHetHashes[i] != 0)
- {
- // Load the index to the BET table
- pHetTable->pBetIndexes->GetBits(pHetTable->dwIndexSizeTotal * i,
- pHetTable->dwIndexSize,
- &dwFileIndex,
- 4);
- // Overflow test
- if(dwFileIndex < pBetTable->dwFileCount)
- {
- // Get the file entry and save HET index
- pFileEntry = pFileTable + dwFileIndex;
- pFileEntry->dwHetIndex = i;
-
- // Load the BET hash
- pBetTable->pBetHashes->GetBits(pBetTable->dwBetHashSizeTotal * dwFileIndex,
- pBetTable->dwBetHashSize,
- &pFileEntry->BetHash,
- 8);
- }
- }
- }
-
- // Go through the entire BET table and convert it to the file table.
- pFileEntry = pFileTable;
- pBitArray = pBetTable->pFileTable;
- for(i = 0; i < pBetTable->dwFileCount; i++)
- {
- DWORD dwFlagIndex = 0;
-
- // Read the file position
- pBitArray->GetBits(dwBitPosition + pBetTable->dwBitIndex_FilePos,
- pBetTable->dwBitCount_FilePos,
- &pFileEntry->ByteOffset,
- 8);
-
- // Read the file size
- pBitArray->GetBits(dwBitPosition + pBetTable->dwBitIndex_FileSize,
- pBetTable->dwBitCount_FileSize,
- &pFileEntry->dwFileSize,
- 4);
-
- // Read the compressed size
- pBitArray->GetBits(dwBitPosition + pBetTable->dwBitIndex_CmpSize,
- pBetTable->dwBitCount_CmpSize,
- &pFileEntry->dwCmpSize,
- 4);
-
-
- // Read the flag index
- if(pBetTable->dwFlagCount != 0)
- {
- pBitArray->GetBits(dwBitPosition + pBetTable->dwBitIndex_FlagIndex,
- pBetTable->dwBitCount_FlagIndex,
- &dwFlagIndex,
- 4);
-
- pFileEntry->dwFlags = pBetTable->pFileFlags[dwFlagIndex];
- }
-
- //
- // TODO: Locale (?)
- //
-
- // Move the current bit position
- dwBitPosition += pBetTable->dwTableEntrySize;
- pFileEntry++;
- }
-
- // Set the current size of the file table
- ha->dwFileTableSize = pBetTable->dwFileCount;
- FreeBetTable(pBetTable);
- nError = ERROR_SUCCESS;
- }
- else
- {
- nError = ERROR_FILE_CORRUPT;
- }
-
- return nError;
-}
-
-int BuildFileTable(TMPQArchive * ha, ULONGLONG FileSize)
-{
- TFileEntry * pFileTable;
- bool bFileTableCreated = false;
-
- // Sanity checks
- assert(ha->dwFileTableSize == 0);
- assert(ha->dwMaxFileCount != 0);
-
- // Allocate the file table with size determined before
- pFileTable = STORM_ALLOC(TFileEntry, ha->dwMaxFileCount);
- if(pFileTable == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Fill the table with zeros
- memset(pFileTable, 0, ha->dwMaxFileCount * sizeof(TFileEntry));
-
- // If we have HET table, we load file table from the BET table
- // Note: If BET table is corrupt or missing, we set the archive as read only
- if(ha->pHetTable != NULL)
- {
- if(BuildFileTable_HetBet(ha, pFileTable) != ERROR_SUCCESS)
- ha->dwFlags |= MPQ_FLAG_READ_ONLY;
- else
- bFileTableCreated = true;
- }
-
- // If we have hash table, we load the file table from the block table
- // Note: If block table is corrupt or missing, we set the archive as read only
- if(ha->pHashTable != NULL)
- {
- if(BuildFileTable_Classic(ha, pFileTable, FileSize) != ERROR_SUCCESS)
- ha->dwFlags |= MPQ_FLAG_READ_ONLY;
- else
- bFileTableCreated = true;
- }
-
- // If something failed, we free the file table entry
- if(bFileTableCreated == false)
- {
- STORM_FREE(pFileTable);
- return ERROR_FILE_CORRUPT;
- }
-
- // Assign it to the archive structure
- ha->pFileTable = pFileTable;
- return ERROR_SUCCESS;
-}
-
-// Saves MPQ header, hash table, block table and hi-block table.
-int SaveMPQTables(TMPQArchive * ha)
-{
- TMPQExtTable * pHetTable = NULL;
- TMPQExtTable * pBetTable = NULL;
- TMPQHeader * pHeader = ha->pHeader;
- TMPQBlock * pBlockTable = NULL;
- TMPQHash * pHashTable = NULL;
- ULONGLONG HetTableSize64 = 0;
- ULONGLONG BetTableSize64 = 0;
- ULONGLONG HashTableSize64 = 0;
- ULONGLONG BlockTableSize64 = 0;
- ULONGLONG HiBlockTableSize64 = 0;
- ULONGLONG TablePos = 0; // A table position, relative to the begin of the MPQ
- USHORT * pHiBlockTable = NULL;
- DWORD cbTotalSize;
- bool bNeedHiBlockTable = false;
- int nError = ERROR_SUCCESS;
-
- // We expect this function to be called only when tables have been changed
- assert(ha->dwFlags & MPQ_FLAG_CHANGED);
-
- // Find the space where the MPQ tables will be saved
- FindFreeMpqSpace(ha, &TablePos);
-
- // If the MPQ has HET table, we prepare a ready-to-save version
- if(nError == ERROR_SUCCESS && ha->pHetTable != NULL)
- {
- pHetTable = TranslateHetTable(ha->pHetTable, &HetTableSize64);
- if(pHetTable == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // If the MPQ has HET table, we also must create BET table to be saved
- if(nError == ERROR_SUCCESS && ha->pHetTable != NULL)
- {
- pBetTable = TranslateBetTable(ha, &BetTableSize64);
- if(pBetTable == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Now create hash table
- if(nError == ERROR_SUCCESS && ha->pHashTable != NULL)
- {
- pHashTable = TranslateHashTable(ha, &HashTableSize64);
- if(pHashTable == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Create block table
- if(nError == ERROR_SUCCESS && ha->pHashTable != NULL)
- {
- pBlockTable = TranslateBlockTable(ha, &BlockTableSize64, &bNeedHiBlockTable);
- if(pBlockTable == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Create hi-block table, if needed
- if(nError == ERROR_SUCCESS && bNeedHiBlockTable)
- {
- pHiBlockTable = TranslateHiBlockTable(ha, &HiBlockTableSize64);
- if(pHiBlockTable == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Write the HET table, if any
- if(nError == ERROR_SUCCESS && pHetTable != NULL)
- {
- pHeader->HetTableSize64 = HetTableSize64;
- pHeader->HetTablePos64 = TablePos;
- nError = SaveExtTable(ha, pHetTable, TablePos, (DWORD)HetTableSize64, pHeader->MD5_HetTable, MPQ_KEY_HASH_TABLE, false, &cbTotalSize);
- TablePos += cbTotalSize;
- }
-
- // Write the BET table, if any
- if(nError == ERROR_SUCCESS && pBetTable != NULL)
- {
- pHeader->BetTableSize64 = BetTableSize64;
- pHeader->BetTablePos64 = TablePos;
- nError = SaveExtTable(ha, pBetTable, TablePos, (DWORD)BetTableSize64, pHeader->MD5_BetTable, MPQ_KEY_BLOCK_TABLE, false, &cbTotalSize);
- TablePos += cbTotalSize;
- }
-
- // Write the hash table, if we have any
- if(nError == ERROR_SUCCESS && pHashTable != NULL)
- {
- pHeader->HashTableSize64 = HashTableSize64;
- pHeader->wHashTablePosHi = (USHORT)(TablePos >> 32);
- pHeader->dwHashTableSize = (DWORD)(HashTableSize64 / sizeof(TMPQHash));
- pHeader->dwHashTablePos = (DWORD)TablePos;
- nError = SaveMpqTable(ha, pHashTable, TablePos, (size_t)HashTableSize64, pHeader->MD5_HashTable, MPQ_KEY_HASH_TABLE, false);
- TablePos += HashTableSize64;
- }
-
- // Write the block table, if we have any
- if(nError == ERROR_SUCCESS && pBlockTable != NULL)
- {
- pHeader->BlockTableSize64 = BlockTableSize64;
- pHeader->wBlockTablePosHi = (USHORT)(TablePos >> 32);
- pHeader->dwBlockTableSize = (DWORD)(BlockTableSize64 / sizeof(TMPQBlock));
- pHeader->dwBlockTablePos = (DWORD)TablePos;
- nError = SaveMpqTable(ha, pBlockTable, TablePos, (size_t)BlockTableSize64, pHeader->MD5_BlockTable, MPQ_KEY_BLOCK_TABLE, false);
- TablePos += BlockTableSize64;
- }
-
- // Write the hi-block table, if we have any
- if(nError == ERROR_SUCCESS && pHiBlockTable != NULL)
- {
- ULONGLONG ByteOffset = ha->MpqPos + TablePos;
-
- pHeader->HiBlockTableSize64 = HiBlockTableSize64;
- pHeader->HiBlockTablePos64 = TablePos;
- BSWAP_ARRAY16_UNSIGNED(pHiBlockTable, HiBlockTableSize64);
-
- if(!FileStream_Write(ha->pStream, &ByteOffset, pHiBlockTable, (DWORD)HiBlockTableSize64))
- nError = GetLastError();
- TablePos += HiBlockTableSize64;
- }
-
- // Cut the MPQ
- if(nError == ERROR_SUCCESS)
- {
- ULONGLONG FileSize = ha->MpqPos + TablePos;
-
- if(!FileStream_SetSize(ha->pStream, FileSize))
- nError = GetLastError();
- }
-
- // Write the MPQ header
- if(nError == ERROR_SUCCESS)
- {
- // Update the size of the archive
- pHeader->ArchiveSize64 = TablePos;
- pHeader->dwArchiveSize = (DWORD)TablePos;
-
- // Update the MD5 of the archive header
- CalculateDataBlockHash(pHeader, MPQ_HEADER_SIZE_V4 - MD5_DIGEST_SIZE, pHeader->MD5_MpqHeader);
-
- // Write the MPQ header to the file
- BSWAP_TMPQHEADER(pHeader);
- if(!FileStream_Write(ha->pStream, &ha->MpqPos, pHeader, pHeader->dwHeaderSize))
- nError = GetLastError();
- BSWAP_TMPQHEADER(pHeader);
- }
-
- // Clear the changed flag
- if(nError == ERROR_SUCCESS)
- ha->dwFlags &= ~MPQ_FLAG_CHANGED;
-
- // Cleanup and exit
- if(pHetTable != NULL)
- STORM_FREE(pHetTable);
- if(pBetTable != NULL)
- STORM_FREE(pBetTable);
- if(pHashTable != NULL)
- STORM_FREE(pHashTable);
- if(pBlockTable != NULL)
- STORM_FREE(pBlockTable);
- if(pHiBlockTable != NULL)
- STORM_FREE(pHiBlockTable);
- return nError;
-}
diff --git a/dep/StormLib/src/SCompression.cpp b/dep/StormLib/src/SCompression.cpp
deleted file mode 100644
index 5c7432248dc..00000000000
--- a/dep/StormLib/src/SCompression.cpp
+++ /dev/null
@@ -1,1135 +0,0 @@
-/*****************************************************************************/
-/* SCompression.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* This module serves as a bridge between StormLib code and (de)compression */
-/* functions. All (de)compression calls go (and should only go) through this */
-/* module. No system headers should be included in this module to prevent */
-/* compile-time problems. */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 01.04.03 1.00 Lad The first version of SCompression.cpp */
-/* 19.11.03 1.01 Dan Big endian handling */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "StormCommon.h"
-
-//-----------------------------------------------------------------------------
-// Local structures
-
-// Information about the input and output buffers for pklib
-typedef struct
-{
- char * pbInBuff; // Pointer to input data buffer
- char * pbInBuffEnd; // End of the input buffer
- char * pbOutBuff; // Pointer to output data buffer
- char * pbOutBuffEnd; // Pointer to output data buffer
-} TDataInfo;
-
-// Prototype of the compression function
-// Function doesn't return an error. A success means that the size of compressed buffer
-// is lower than size of uncompressed buffer.
-typedef void (*COMPRESS)(
- char * pbOutBuffer, // [out] Pointer to the buffer where the compressed data will be stored
- int * pcbOutBuffer, // [in] Pointer to length of the buffer pointed by pbOutBuffer
- // [out] Contains length of the compressed data
- char * pbInBuffer, // [in] Pointer to the buffer with data to compress
- int cbInBuffer, // [in] Length of the buffer pointer by pbInBuffer
- int * pCmpType, // [in] Compression-method specific value. ADPCM Setups this for the following Huffman compression
- int nCmpLevel); // [in] Compression specific value. ADPCM uses this. Should be set to zero.
-
-// Prototype of the decompression function
-// Returns 1 if success, 0 if failure
-typedef int (*DECOMPRESS)(
- char * pbOutBuffer, // [out] Pointer to the buffer where to store decompressed data
- int * pcbOutBuffer, // [in] Pointer to total size of the buffer pointed by pbOutBuffer
- // [out] Contains length of the decompressed data
- char * pbInBuffer, // [in] Pointer to data to be decompressed
- int cbInBuffer); // [in] Length of the data to be decompressed
-
-// Table of compression functions
-typedef struct
-{
- unsigned long uMask; // Compression mask
- COMPRESS Compress; // Compression function
-} TCompressTable;
-
-// Table of decompression functions
-typedef struct
-{
- unsigned long uMask; // Decompression bit
- DECOMPRESS Decompress; // Decompression function
-} TDecompressTable;
-
-
-/*****************************************************************************/
-/* */
-/* Support for Huffman compression (0x01) */
-/* */
-/*****************************************************************************/
-
-// 1500F4C0
-void Compress_huff(
- char * pbOutBuffer,
- int * pcbOutBuffer,
- char * pbInBuffer,
- int cbInBuffer,
- int * pCmpType,
- int /* nCmpLevel */)
-{
- THuffmannTree ht; // Huffmann tree for compression
- TOutputStream os; // Output stream
-
- // Initialize output stream
- os.pbOutBuffer = (unsigned char *)pbOutBuffer;
- os.cbOutSize = *pcbOutBuffer;
- os.pbOutPos = (unsigned char *)pbOutBuffer;
- os.dwBitBuff = 0;
- os.nBits = 0;
-
- // Initialize the Huffmann tree for compression
- ht.InitTree(true);
-
- *pcbOutBuffer = ht.DoCompression(&os, (unsigned char *)pbInBuffer, cbInBuffer, *pCmpType);
-
- // The following code is not necessary to run, because it has no
- // effect on the output data. It only clears the huffmann tree, but when
- // the tree is on the stack, who cares ?
-// ht.UninitTree();
-}
-
-// 1500F5F0
-int Decompress_huff(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer)
-{
- THuffmannTree ht;
- TInputStream is;
-
- // Initialize input stream
- is.pbInBufferEnd = (unsigned char *)pbInBuffer + cbInBuffer;
- is.pbInBuffer = (unsigned char *)pbInBuffer;
- is.BitBuffer = 0;
- is.BitCount = 0;
-
- // Initialize the Huffmann tree for compression
- ht.InitTree(false);
- *pcbOutBuffer = ht.DoDecompression((unsigned char *)pbOutBuffer, *pcbOutBuffer, &is);
- if(*pcbOutBuffer == 0)
- return 0;
-
- // The following code is not necessary to run, because it has no
- // effect on the output data. It only clears the huffmann tree, but when
- // the tree is on the stack, who cares ?
-// ht.UninitTree();
- return 1;
-}
-
-/******************************************************************************/
-/* */
-/* Support for ZLIB compression (0x02) */
-/* */
-/******************************************************************************/
-
-void Compress_ZLIB(
- char * pbOutBuffer,
- int * pcbOutBuffer,
- char * pbInBuffer,
- int cbInBuffer,
- int * /* pCmpType */,
- int /* nCmpLevel */)
-{
- z_stream z; // Stream information for zlib
- int windowBits;
- int nResult;
-
- // Fill the stream structure for zlib
- z.next_in = (Bytef *)pbInBuffer;
- z.avail_in = (uInt)cbInBuffer;
- z.total_in = cbInBuffer;
- z.next_out = (Bytef *)pbOutBuffer;
- z.avail_out = *pcbOutBuffer;
- z.total_out = 0;
- z.zalloc = NULL;
- z.zfree = NULL;
-
- // Determine the proper window bits (WoW.exe build 12694)
- if(cbInBuffer <= 0x100)
- windowBits = 8;
- else if(cbInBuffer <= 0x200)
- windowBits = 9;
- else if(cbInBuffer <= 0x400)
- windowBits = 10;
- else if(cbInBuffer <= 0x800)
- windowBits = 11;
- else if(cbInBuffer <= 0x1000)
- windowBits = 12;
- else if(cbInBuffer <= 0x2000)
- windowBits = 13;
- else if(cbInBuffer <= 0x4000)
- windowBits = 14;
- else
- windowBits = 15;
-
- // Initialize the compression.
- // Storm.dll uses zlib version 1.1.3
- // Wow.exe uses zlib version 1.2.3
- nResult = deflateInit2(&z,
- 6, // Compression level used by WoW MPQs
- Z_DEFLATED,
- windowBits,
- 8,
- Z_DEFAULT_STRATEGY);
- if(nResult == Z_OK)
- {
- // Call zlib to compress the data
- nResult = deflate(&z, Z_FINISH);
-
- if(nResult == Z_OK || nResult == Z_STREAM_END)
- *pcbOutBuffer = z.total_out;
-
- deflateEnd(&z);
- }
-}
-
-int Decompress_ZLIB(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer)
-{
- z_stream z; // Stream information for zlib
- int nResult;
-
- // Fill the stream structure for zlib
- z.next_in = (Bytef *)pbInBuffer;
- z.avail_in = (uInt)cbInBuffer;
- z.total_in = cbInBuffer;
- z.next_out = (Bytef *)pbOutBuffer;
- z.avail_out = *pcbOutBuffer;
- z.total_out = 0;
- z.zalloc = NULL;
- z.zfree = NULL;
-
- // Initialize the decompression structure. Storm.dll uses zlib version 1.1.3
- if((nResult = inflateInit(&z)) == 0)
- {
- // Call zlib to decompress the data
- nResult = inflate(&z, Z_FINISH);
- *pcbOutBuffer = z.total_out;
- inflateEnd(&z);
- }
- return nResult;
-}
-
-/******************************************************************************/
-/* */
-/* Support functions for PKWARE Data Compression Library compression (0x08) */
-/* */
-/******************************************************************************/
-
-// Function loads data from the input buffer. Used by Pklib's "implode"
-// and "explode" function as user-defined callback
-// Returns number of bytes loaded
-//
-// char * buf - Pointer to a buffer where to store loaded data
-// unsigned int * size - Max. number of bytes to read
-// void * param - Custom pointer, parameter of implode/explode
-
-static unsigned int ReadInputData(char * buf, unsigned int * size, void * param)
-{
- TDataInfo * pInfo = (TDataInfo *)param;
- unsigned int nMaxAvail = (unsigned int)(pInfo->pbInBuffEnd - pInfo->pbInBuff);
- unsigned int nToRead = *size;
-
- // Check the case when not enough data available
- if(nToRead > nMaxAvail)
- nToRead = nMaxAvail;
-
- // Load data and increment offsets
- memcpy(buf, pInfo->pbInBuff, nToRead);
- pInfo->pbInBuff += nToRead;
- assert(pInfo->pbInBuff <= pInfo->pbInBuffEnd);
- return nToRead;
-}
-
-// Function for store output data. Used by Pklib's "implode" and "explode"
-// as user-defined callback
-//
-// char * buf - Pointer to data to be written
-// unsigned int * size - Number of bytes to write
-// void * param - Custom pointer, parameter of implode/explode
-
-static void WriteOutputData(char * buf, unsigned int * size, void * param)
-{
- TDataInfo * pInfo = (TDataInfo *)param;
- unsigned int nMaxWrite = (unsigned int)(pInfo->pbOutBuffEnd - pInfo->pbOutBuff);
- unsigned int nToWrite = *size;
-
- // Check the case when not enough space in the output buffer
- if(nToWrite > nMaxWrite)
- nToWrite = nMaxWrite;
-
- // Write output data and increments offsets
- memcpy(pInfo->pbOutBuff, buf, nToWrite);
- pInfo->pbOutBuff += nToWrite;
- assert(pInfo->pbOutBuff <= pInfo->pbOutBuffEnd);
-}
-
-static void Compress_PKLIB(
- char * pbOutBuffer,
- int * pcbOutBuffer,
- char * pbInBuffer,
- int cbInBuffer,
- int * /* pCmpType */,
- int /* nCmpLevel */)
-{
- TDataInfo Info; // Data information
- char * work_buf = STORM_ALLOC(char, CMP_BUFFER_SIZE);// Pklib's work buffer
- unsigned int dict_size; // Dictionary size
- unsigned int ctype = CMP_BINARY; // Compression type
-
- // Fill data information structure
- memset(work_buf, 0, CMP_BUFFER_SIZE);
- Info.pbInBuff = pbInBuffer;
- Info.pbInBuffEnd = pbInBuffer + cbInBuffer;
- Info.pbOutBuff = pbOutBuffer;
- Info.pbOutBuffEnd = pbOutBuffer + *pcbOutBuffer;
-
- //
- // Set the dictionary size
- //
- // Diablo I ues fixed dictionary size of CMP_IMPLODE_DICT_SIZE3
- // Starcraft uses the variable dictionary size based on algorithm below
- //
-
- if (cbInBuffer < 0x600)
- dict_size = CMP_IMPLODE_DICT_SIZE1;
- else if(0x600 <= cbInBuffer && cbInBuffer < 0xC00)
- dict_size = CMP_IMPLODE_DICT_SIZE2;
- else
- dict_size = CMP_IMPLODE_DICT_SIZE3;
-
- // Do the compression
- if(implode(ReadInputData, WriteOutputData, work_buf, &Info, &ctype, &dict_size) == CMP_NO_ERROR)
- *pcbOutBuffer = (int)(Info.pbOutBuff - pbOutBuffer);
-
- STORM_FREE(work_buf);
-}
-
-static int Decompress_PKLIB(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer)
-{
- TDataInfo Info; // Data information
- char * work_buf = STORM_ALLOC(char, EXP_BUFFER_SIZE);// Pklib's work buffer
-
- // Fill data information structure
- memset(work_buf, 0, EXP_BUFFER_SIZE);
- Info.pbInBuff = pbInBuffer;
- Info.pbInBuffEnd = pbInBuffer + cbInBuffer;
- Info.pbOutBuff = pbOutBuffer;
- Info.pbOutBuffEnd = pbOutBuffer + *pcbOutBuffer;
-
- // Do the decompression
- explode(ReadInputData, WriteOutputData, work_buf, &Info);
-
- // If PKLIB is unable to decompress the data, return 0;
- if(Info.pbOutBuff == pbOutBuffer)
- return 0;
-
- // Give away the number of decompressed bytes
- *pcbOutBuffer = (int)(Info.pbOutBuff - pbOutBuffer);
- STORM_FREE(work_buf);
- return 1;
-}
-
-/******************************************************************************/
-/* */
-/* Support for Bzip2 compression (0x10) */
-/* */
-/******************************************************************************/
-
-static void Compress_BZIP2(
- char * pbOutBuffer,
- int * pcbOutBuffer,
- char * pbInBuffer,
- int cbInBuffer,
- int * /* pCmpType */,
- int /* nCmpLevel */)
-{
- bz_stream strm;
- int blockSize100k = 9;
- int workFactor = 30;
- int bzError;
-
- // Initialize the BZIP2 compression
- strm.bzalloc = NULL;
- strm.bzfree = NULL;
-
- // Blizzard uses 9 as blockSize100k, (0x30 as workFactor)
- // Last checked on Starcraft II
- if(BZ2_bzCompressInit(&strm, blockSize100k, 0, workFactor) == BZ_OK)
- {
- strm.next_in = pbInBuffer;
- strm.avail_in = cbInBuffer;
- strm.next_out = pbOutBuffer;
- strm.avail_out = *pcbOutBuffer;
-
- // Perform the compression
- for(;;)
- {
- bzError = BZ2_bzCompress(&strm, (strm.avail_in != 0) ? BZ_RUN : BZ_FINISH);
- if(bzError == BZ_STREAM_END || bzError < 0)
- break;
- }
-
- // Put the stream into idle state
- BZ2_bzCompressEnd(&strm);
-
- if(bzError > 0)
- *pcbOutBuffer = strm.total_out_lo32;
- }
-}
-
-static int Decompress_BZIP2(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer)
-{
- bz_stream strm;
- int nResult = BZ_OK;
-
- // Initialize the BZIP2 decompression
- strm.bzalloc = NULL;
- strm.bzfree = NULL;
- if(BZ2_bzDecompressInit(&strm, 0, 0) == BZ_OK)
- {
- strm.next_in = pbInBuffer;
- strm.avail_in = cbInBuffer;
- strm.next_out = pbOutBuffer;
- strm.avail_out = *pcbOutBuffer;
-
- // Perform the decompression
- while(nResult != BZ_STREAM_END)
- {
- nResult = BZ2_bzDecompress(&strm);
-
- // If any error there, break the loop
- if(nResult < BZ_OK)
- break;
- }
-
- // Put the stream into idle state
- BZ2_bzDecompressEnd(&strm);
-
- // If all succeeded, set the number of output bytes
- if(nResult >= BZ_OK)
- {
- *pcbOutBuffer = strm.total_out_lo32;
- return 1;
- }
- }
-
- // Something failed, so set number of output bytes to zero
- *pcbOutBuffer = 0;
- return 1;
-}
-
-/******************************************************************************/
-/* */
-/* Support functions for LZMA compression (0x12) */
-/* */
-/******************************************************************************/
-
-#define LZMA_HEADER_SIZE (1 + LZMA_PROPS_SIZE + 8)
-
-static SRes LZMA_Callback_Progress(void * /* p */, UInt64 /* inSize */, UInt64 /* outSize */)
-{
- return SZ_OK;
-}
-
-static void * LZMA_Callback_Alloc(void *p, size_t size)
-{
- p = p;
- return STORM_ALLOC(BYTE, size);
-}
-
-/* address can be 0 */
-static void LZMA_Callback_Free(void *p, void *address)
-{
- p = p;
- if(address != NULL)
- STORM_FREE(address);
-}
-
-//
-// Note: So far, I haven't seen any files compressed by LZMA.
-// This code haven't been verified against code ripped from Starcraft II Beta,
-// but we know that Starcraft LZMA decompression code is able to decompress
-// the data compressed by StormLib.
-//
-
-/*static */ void Compress_LZMA(
- char * pbOutBuffer,
- int * pcbOutBuffer,
- char * pbInBuffer,
- int cbInBuffer,
- int * /* pCmpType */,
- int /* nCmpLevel */)
-{
- ICompressProgress Progress;
- CLzmaEncProps props;
- ISzAlloc SzAlloc;
- Byte * destBuffer;
- SizeT destLen = *pcbOutBuffer;
- SizeT srcLen = cbInBuffer;
- Byte encodedProps[LZMA_PROPS_SIZE];
- size_t encodedPropsSize = LZMA_PROPS_SIZE;
- SRes nResult;
-
- // Fill the callbacks in structures
- Progress.Progress = LZMA_Callback_Progress;
- SzAlloc.Alloc = LZMA_Callback_Alloc;
- SzAlloc.Free = LZMA_Callback_Free;
-
- // Initialize properties
- LzmaEncProps_Init(&props);
-
- // Perform compression
- destBuffer = (Byte *)pbOutBuffer + LZMA_HEADER_SIZE;
- destLen = *pcbOutBuffer - LZMA_HEADER_SIZE;
- nResult = LzmaEncode(destBuffer,
- &destLen,
- (Byte *)pbInBuffer,
- srcLen,
- &props,
- encodedProps,
- &encodedPropsSize,
- 0,
- &Progress,
- &SzAlloc,
- &SzAlloc);
- if(nResult != SZ_OK)
- return;
-
- // If we failed to compress the data
- if(destLen >= (SizeT)(*pcbOutBuffer - LZMA_HEADER_SIZE))
- return;
-
- // Write "useFilter" variable. Blizzard MPQ must not use filter.
- *pbOutBuffer++ = 0;
-
- // Copy the encoded properties to the output buffer
- memcpy(pbOutBuffer, encodedProps, encodedPropsSize);
- pbOutBuffer += encodedPropsSize;
-
- // Copy the size of the data
- *pbOutBuffer++ = (unsigned char)(srcLen >> 0x00);
- *pbOutBuffer++ = (unsigned char)(srcLen >> 0x08);
- *pbOutBuffer++ = (unsigned char)(srcLen >> 0x10);
- *pbOutBuffer++ = (unsigned char)(srcLen >> 0x18);
- *pbOutBuffer++ = 0;
- *pbOutBuffer++ = 0;
- *pbOutBuffer++ = 0;
- *pbOutBuffer++ = 0;
-
- // Give the size of the data to the caller
- *pcbOutBuffer = (unsigned int)(destLen + LZMA_HEADER_SIZE);
-}
-
-static int Decompress_LZMA(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer)
-{
- ELzmaStatus LzmaStatus;
- ISzAlloc SzAlloc;
- Byte * destBuffer = (Byte *)pbOutBuffer;
- Byte * srcBuffer = (Byte *)pbInBuffer;
- SizeT destLen = *pcbOutBuffer;
- SizeT srcLen = cbInBuffer;
- SRes nResult;
-
- // There must be at least 0x0E bytes in the buffer
- if(srcLen <= LZMA_HEADER_SIZE)
- return 0;
-
- // We only accept blocks that have no filter used
- if(*srcBuffer != 0)
- return 0;
-
- // Fill the callbacks in structures
- SzAlloc.Alloc = LZMA_Callback_Alloc;
- SzAlloc.Free = LZMA_Callback_Free;
-
- // Perform compression
- srcLen = cbInBuffer - LZMA_HEADER_SIZE;
- nResult = LzmaDecode(destBuffer,
- &destLen,
- srcBuffer + LZMA_HEADER_SIZE,
- &srcLen,
- srcBuffer + 1,
- LZMA_PROPS_SIZE,
- LZMA_FINISH_END,
- &LzmaStatus,
- &SzAlloc);
- if(nResult != SZ_OK)
- return 0;
-
- *pcbOutBuffer = (unsigned int)destLen;
- return 1;
-}
-
-/******************************************************************************/
-/* */
-/* Support functions for SPARSE compression (0x20) */
-/* */
-/******************************************************************************/
-
-void Compress_SPARSE(
- char * pbOutBuffer,
- int * pcbOutBuffer,
- char * pbInBuffer,
- int cbInBuffer,
- int * /* pCmpType */,
- int /* nCmpLevel */)
-{
- CompressSparse((unsigned char *)pbOutBuffer, pcbOutBuffer, (unsigned char *)pbInBuffer, cbInBuffer);
-}
-
-int Decompress_SPARSE(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer)
-{
- return DecompressSparse((unsigned char *)pbOutBuffer, pcbOutBuffer, (unsigned char *)pbInBuffer, cbInBuffer);
-}
-
-/******************************************************************************/
-/* */
-/* Support for ADPCM mono compression (0x40) */
-/* */
-/******************************************************************************/
-
-static void Compress_ADPCM_mono(
- char * pbOutBuffer,
- int * pcbOutBuffer,
- char * pbInBuffer,
- int cbInBuffer,
- int * pCmpType,
- int nCmpLevel)
-{
- // Prepare the compression level for Huffmann compression,
- // which will be called as next step
- if(0 < nCmpLevel && nCmpLevel <= 2)
- {
- nCmpLevel = 4;
- *pCmpType = 6;
- }
- else if(nCmpLevel == 3)
- {
- nCmpLevel = 6;
- *pCmpType = 8;
- }
- else
- {
- nCmpLevel = 5;
- *pCmpType = 7;
- }
- *pcbOutBuffer = CompressADPCM((unsigned char *)pbOutBuffer, *pcbOutBuffer, (short *)pbInBuffer, cbInBuffer, 1, nCmpLevel);
-}
-
-static int Decompress_ADPCM_mono(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer)
-{
- *pcbOutBuffer = DecompressADPCM((unsigned char *)pbOutBuffer, *pcbOutBuffer, (unsigned char *)pbInBuffer, cbInBuffer, 1);
- return 1;
-}
-
-/******************************************************************************/
-/* */
-/* Support for ADPCM stereo compression (0x80) */
-/* */
-/******************************************************************************/
-
-static void Compress_ADPCM_stereo(
- char * pbOutBuffer,
- int * pcbOutBuffer,
- char * pbInBuffer,
- int cbInBuffer,
- int * pCmpType,
- int nCmpLevel)
-{
- // Prepare the compression level for Huffmann compression,
- // which will be called as next step
- if(0 < nCmpLevel && nCmpLevel <= 2)
- {
- nCmpLevel = 4;
- *pCmpType = 6;
- }
- else if(nCmpLevel == 3)
- {
- nCmpLevel = 6;
- *pCmpType = 8;
- }
- else
- {
- nCmpLevel = 5;
- *pCmpType = 7;
- }
- *pcbOutBuffer = CompressADPCM((unsigned char *)pbOutBuffer, *pcbOutBuffer, (short *)pbInBuffer, cbInBuffer, 2, nCmpLevel);
-}
-
-static int Decompress_ADPCM_stereo(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer)
-{
- *pcbOutBuffer = DecompressADPCM((unsigned char *)pbOutBuffer, *pcbOutBuffer, (unsigned char *)pbInBuffer, cbInBuffer, 2);
- return 1;
-}
-
-/*****************************************************************************/
-/* */
-/* SCompImplode */
-/* */
-/*****************************************************************************/
-
-int WINAPI SCompImplode(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer)
-{
- int cbOutBuffer = *pcbOutBuffer;
-
- // Check for valid parameters
- if(!pcbOutBuffer || *pcbOutBuffer < cbInBuffer || !pbOutBuffer || !pbInBuffer)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- // Perform the compression
- Compress_PKLIB(pbOutBuffer, &cbOutBuffer, pbInBuffer, cbInBuffer, NULL, 0);
-
- // If the compression was unsuccessful, copy the data as-is
- if(cbOutBuffer >= *pcbOutBuffer)
- {
- memcpy(pbOutBuffer, pbInBuffer, cbInBuffer);
- cbOutBuffer = *pcbOutBuffer;
- }
-
- *pcbOutBuffer = cbOutBuffer;
- return 1;
-}
-
-/*****************************************************************************/
-/* */
-/* SCompExplode */
-/* */
-/*****************************************************************************/
-
-int WINAPI SCompExplode(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer)
-{
- int cbOutBuffer = *pcbOutBuffer;
-
- // Check for valid parameters
- if(!pcbOutBuffer || *pcbOutBuffer < cbInBuffer || !pbOutBuffer || !pbInBuffer)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- // If the input length is the same as output length, do nothing.
- if(cbInBuffer == cbOutBuffer)
- {
- // If the buffers are equal, don't copy anything.
- if(pbInBuffer == pbOutBuffer)
- return 1;
-
- memcpy(pbOutBuffer, pbInBuffer, cbInBuffer);
- return 1;
- }
-
- // Perform decompression
- if(!Decompress_PKLIB(pbOutBuffer, &cbOutBuffer, pbInBuffer, cbInBuffer))
- {
- SetLastError(ERROR_FILE_CORRUPT);
- return false;
- }
-
- *pcbOutBuffer = cbOutBuffer;
- return 1;
-}
-
-/*****************************************************************************/
-/* */
-/* SCompCompress */
-/* */
-/*****************************************************************************/
-
-// This table contains compress functions which can be applied to
-// uncompressed data. Each bit means the corresponding
-// compression method/function must be applied.
-//
-// WAVes compression Data compression
-// ------------------ -------------------
-// 1st sector - 0x08 0x08 (D, HF, W2, SC, D2)
-// Next sectors - 0x81 0x02 (W3)
-
-static TCompressTable cmp_table[] =
-{
- {MPQ_COMPRESSION_SPARSE, Compress_SPARSE}, // Sparse compression
- {MPQ_COMPRESSION_ADPCM_MONO, Compress_ADPCM_mono}, // IMA ADPCM mono compression
- {MPQ_COMPRESSION_ADPCM_STEREO, Compress_ADPCM_stereo}, // IMA ADPCM stereo compression
- {MPQ_COMPRESSION_HUFFMANN, Compress_huff}, // Huffmann compression
- {MPQ_COMPRESSION_ZLIB, Compress_ZLIB}, // Compression with the "zlib" library
- {MPQ_COMPRESSION_PKWARE, Compress_PKLIB}, // Compression with Pkware DCL
- {MPQ_COMPRESSION_BZIP2, Compress_BZIP2} // Compression Bzip2 library
-};
-
-int WINAPI SCompCompress(
- char * pbOutBuffer,
- int * pcbOutBuffer,
- char * pbInBuffer,
- int cbInBuffer,
- unsigned uCompressionMask,
- int nCmpType,
- int nCmpLevel)
-{
- COMPRESS CompressFuncArray[0x10]; // Array of compression functions, applied sequentially
- unsigned char CompressByte[0x10]; // CompressByte for each method in the CompressFuncArray array
- char * pbWorkBuffer = NULL; // Temporary storage for decompressed data
- char * pbOutput = pbOutBuffer; // Current output buffer
- char * pbInput = pbInBuffer; // Current input buffer
- int nCompressCount = 0;
- int nCompressIndex = 0;
- int nAtLeastOneCompressionDone = 0;
- int cbOutBuffer = 0;
- int cbInLength = cbInBuffer;
- int nResult = 1;
-
- // Check for valid parameters
- if(!pcbOutBuffer || *pcbOutBuffer < cbInBuffer || !pbOutBuffer || !pbInBuffer)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- // Zero input length brings zero output length
- if(cbInBuffer == 0)
- {
- *pcbOutBuffer = 0;
- return true;
- }
-
- // Setup the compression function array
- if(uCompressionMask == MPQ_COMPRESSION_LZMA)
- {
- CompressFuncArray[0] = Compress_LZMA;
- CompressByte[0] = (char)uCompressionMask;
- nCompressCount = 1;
- }
- else
- {
- // Fill the compressions array
- for(size_t i = 0; i < (sizeof(cmp_table) / sizeof(TCompressTable)); i++)
- {
- // If the mask agrees, insert the compression function to the array
- if(uCompressionMask & cmp_table[i].uMask)
- {
- CompressFuncArray[nCompressCount] = cmp_table[i].Compress;
- CompressByte[nCompressCount] = (unsigned char)cmp_table[i].uMask;
- uCompressionMask &= ~cmp_table[i].uMask;
- nCompressCount++;
- }
- }
-
- // If at least one of the compressions remaing unknown, return an error
- if(uCompressionMask != 0)
- {
- SetLastError(ERROR_NOT_SUPPORTED);
- return 0;
- }
- }
-
- // If there is at least one compression, do it
- if(nCompressCount > 0)
- {
- // If we need to do more than 1 compression, allocate intermediate buffer
- if(nCompressCount > 1)
- {
- pbWorkBuffer = STORM_ALLOC(char, *pcbOutBuffer);
- if(pbWorkBuffer == NULL)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return 0;
- }
- }
-
- // Get the current compression index
- nCompressIndex = nCompressCount - 1;
-
- // Perform all compressions in the array
- for(int i = 0; i < nCompressCount; i++)
- {
- // Choose the proper output buffer
- pbOutput = (nCompressIndex & 1) ? pbWorkBuffer : pbOutBuffer;
- nCompressIndex--;
-
- // Perform the (next) compression
- // Note that if the compression method is unable to compress the input data block
- // by at least 2 bytes, we consider it as failure and will use source data instead
- cbOutBuffer = *pcbOutBuffer - 1;
- CompressFuncArray[i](pbOutput + 1, &cbOutBuffer, pbInput, cbInLength, &nCmpType, nCmpLevel);
-
- // If the compression failed, we copy the input buffer as-is.
- // Note that there is one extra byte at the end of the intermediate buffer, so it should be OK
- if(cbOutBuffer > (cbInLength - 2))
- {
- memcpy(pbOutput + nAtLeastOneCompressionDone, pbInput, cbInLength);
- cbOutBuffer = cbInLength;
- }
- else
- {
- // Remember that we have done at least one compression
- nAtLeastOneCompressionDone = 1;
- uCompressionMask |= CompressByte[i];
- }
-
- // Now point input buffer to the output buffer
- pbInput = pbOutput + nAtLeastOneCompressionDone;
- cbInLength = cbOutBuffer;
- }
-
- // If at least one compression succeeded, put the compression
- // mask to the begin of the output buffer
- if(nAtLeastOneCompressionDone)
- *pbOutBuffer = (char)uCompressionMask;
- *pcbOutBuffer = cbOutBuffer + nAtLeastOneCompressionDone;
- }
- else
- {
- memcpy(pbOutBuffer, pbInBuffer, cbInBuffer);
- *pcbOutBuffer = cbInBuffer;
- }
-
- // Cleanup and return
- if(pbWorkBuffer != NULL)
- STORM_FREE(pbWorkBuffer);
- return nResult;
-}
-
-/*****************************************************************************/
-/* */
-/* SCompDecompress */
-/* */
-/*****************************************************************************/
-
-// This table contains decompress functions which can be applied to
-// uncompressed data. The compression mask is stored in the first byte
-// of compressed data
-static TDecompressTable dcmp_table[] =
-{
- {MPQ_COMPRESSION_BZIP2, Decompress_BZIP2}, // Decompression with Bzip2 library
- {MPQ_COMPRESSION_PKWARE, Decompress_PKLIB}, // Decompression with Pkware Data Compression Library
- {MPQ_COMPRESSION_ZLIB, Decompress_ZLIB}, // Decompression with the "zlib" library
- {MPQ_COMPRESSION_HUFFMANN, Decompress_huff}, // Huffmann decompression
- {MPQ_COMPRESSION_ADPCM_STEREO, Decompress_ADPCM_stereo}, // IMA ADPCM stereo decompression
- {MPQ_COMPRESSION_ADPCM_MONO, Decompress_ADPCM_mono}, // IMA ADPCM mono decompression
- {MPQ_COMPRESSION_SPARSE, Decompress_SPARSE} // Sparse decompression
-};
-
-int WINAPI SCompDecompress(
- char * pbOutBuffer,
- int * pcbOutBuffer,
- char * pbInBuffer,
- int cbInBuffer)
-{
- char * pbWorkBuffer = NULL; // Temporary storage for decompressed data
- char * pbOutput = pbOutBuffer; // Where to store decompressed data
- char * pbInput; // Where to store decompressed data
- unsigned uCompressionMask; // Decompressions applied to the data
- unsigned uCompressionCopy; // Decompressions applied to the data
- int cbOutBuffer = *pcbOutBuffer; // Current size of the output buffer
- int cbInLength; // Current size of the input buffer
- int nCompressCount = 0; // Number of compressions to be applied
- int nCompressIndex = 0;
- int nResult = 1;
-
- // Verify buffer sizes
- if(cbOutBuffer < cbInBuffer || cbInBuffer < 1)
- return 0;
-
- // If the input length is the same as output length, do nothing.
- if(cbOutBuffer == cbInBuffer)
- {
- // If the buffers are equal, don't copy anything.
- if(pbInBuffer != pbOutBuffer)
- memcpy(pbOutBuffer, pbInBuffer, cbInBuffer);
- return 1;
- }
-
- // Get applied compression types and decrement data length
- uCompressionMask = uCompressionCopy = (unsigned char)*pbInBuffer++;
- cbInBuffer--;
-
- // Get current compressed data and length of it
- pbInput = pbInBuffer;
- cbInLength = cbInBuffer;
-
- // This compression function doesn't support LZMA
- assert(uCompressionMask != MPQ_COMPRESSION_LZMA);
-
- // Parse the compression mask
- for(size_t i = 0; i < (sizeof(dcmp_table) / sizeof(TDecompressTable)); i++)
- {
- // If the mask agrees, insert the compression function to the array
- if(uCompressionMask & dcmp_table[i].uMask)
- {
- uCompressionCopy &= ~dcmp_table[i].uMask;
- nCompressCount++;
- }
- }
-
- // If at least one of the compressions remaing unknown, return an error
- if(nCompressCount == 0 || uCompressionCopy != 0)
- {
- SetLastError(ERROR_NOT_SUPPORTED);
- return 0;
- }
-
- // If there is more than one compression, we have to allocate extra buffer
- if(nCompressCount > 1)
- {
- pbWorkBuffer = STORM_ALLOC(char, cbOutBuffer);
- if(pbWorkBuffer == NULL)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return 0;
- }
- }
-
- // Get the current compression index
- nCompressIndex = nCompressCount - 1;
-
- // Apply all decompressions
- for(size_t i = 0; i < (sizeof(dcmp_table) / sizeof(TDecompressTable)); i++)
- {
- // Perform the (next) decompression
- if(uCompressionMask & dcmp_table[i].uMask)
- {
- // Get the correct output buffer
- pbOutput = (nCompressIndex & 1) ? pbWorkBuffer : pbOutBuffer;
- nCompressIndex--;
-
- // Perform the decompression
- cbOutBuffer = *pcbOutBuffer;
- nResult = dcmp_table[i].Decompress(pbOutput, &cbOutBuffer, pbInput, cbInLength);
- if(nResult == 0 || cbOutBuffer == 0)
- {
- SetLastError(ERROR_FILE_CORRUPT);
- nResult = 0;
- break;
- }
-
- // Switch buffers
- cbInLength = cbOutBuffer;
- pbInput = pbOutput;
- }
- }
-
- // Put the length of the decompressed data to the output buffer
- *pcbOutBuffer = cbOutBuffer;
-
- // Cleanup and return
- if(pbWorkBuffer != NULL)
- STORM_FREE(pbWorkBuffer);
- return nResult;
-}
-
-int WINAPI SCompDecompress2(
- char * pbOutBuffer,
- int * pcbOutBuffer,
- char * pbInBuffer,
- int cbInBuffer)
-{
- DECOMPRESS pfnDecompress1 = NULL;
- DECOMPRESS pfnDecompress2 = NULL;
- char * pbWorkBuffer = pbOutBuffer;
- int cbWorkBuffer = *pcbOutBuffer;
- int nResult;
- char CompressionMethod;
-
- // Verify buffer sizes
- if(*pcbOutBuffer < cbInBuffer || cbInBuffer < 1)
- return 0;
-
- // If the outputbuffer is as big as input buffer, just copy the block
- if(*pcbOutBuffer == cbInBuffer)
- {
- if(pbOutBuffer != pbInBuffer)
- memcpy(pbOutBuffer, pbInBuffer, cbInBuffer);
- return 1;
- }
-
- // Get the compression methods
- CompressionMethod = *pbInBuffer++;
- cbInBuffer--;
-
- // We only recognize a fixed set of compression methods
- switch((unsigned char)CompressionMethod)
- {
- case MPQ_COMPRESSION_ZLIB:
- pfnDecompress1 = Decompress_ZLIB;
- break;
-
- case MPQ_COMPRESSION_PKWARE:
- pfnDecompress1 = Decompress_PKLIB;
- break;
-
- case MPQ_COMPRESSION_BZIP2:
- pfnDecompress1 = Decompress_BZIP2;
- break;
-
- case MPQ_COMPRESSION_LZMA:
- pfnDecompress1 = Decompress_LZMA;
- break;
-
- case MPQ_COMPRESSION_SPARSE:
- pfnDecompress1 = Decompress_SPARSE;
- break;
-
- case (MPQ_COMPRESSION_SPARSE | MPQ_COMPRESSION_ZLIB):
- pfnDecompress1 = Decompress_ZLIB;
- pfnDecompress2 = Decompress_SPARSE;
- break;
-
- case (MPQ_COMPRESSION_SPARSE | MPQ_COMPRESSION_BZIP2):
- pfnDecompress1 = Decompress_BZIP2;
- pfnDecompress2 = Decompress_SPARSE;
- break;
-
- //
- // Note: Any combination including MPQ_COMPRESSION_ADPCM_MONO,
- // MPQ_COMPRESSION_ADPCM_STEREO or MPQ_COMPRESSION_HUFFMANN
- // is not supported by newer MPQs.
- //
-
- default:
- SetLastError(ERROR_FILE_CORRUPT);
- return 0;
- }
-
- // If we have to use two decompressions, allocate temporary buffer
- if(pfnDecompress2 != NULL)
- {
- pbWorkBuffer = STORM_ALLOC(char, *pcbOutBuffer);
- if(pbWorkBuffer == NULL)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return 0;
- }
- }
-
- // Apply the first decompression method
- nResult = pfnDecompress1(pbWorkBuffer, &cbWorkBuffer, pbInBuffer, cbInBuffer);
-
- // Apply the second decompression method, if any
- if(pfnDecompress2 != NULL && nResult != 0)
- {
- cbInBuffer = cbWorkBuffer;
- cbWorkBuffer = *pcbOutBuffer;
- nResult = pfnDecompress2(pbOutBuffer, &cbWorkBuffer, pbWorkBuffer, cbInBuffer);
- }
-
- // Supply the output buffer size
- *pcbOutBuffer = cbWorkBuffer;
-
- // Free temporary buffer
- if(pbWorkBuffer != pbOutBuffer)
- STORM_FREE(pbWorkBuffer);
-
- if(nResult == 0)
- SetLastError(ERROR_FILE_CORRUPT);
- return nResult;
-}
diff --git a/dep/StormLib/src/SFileAddFile.cpp b/dep/StormLib/src/SFileAddFile.cpp
deleted file mode 100644
index dda47370bd1..00000000000
--- a/dep/StormLib/src/SFileAddFile.cpp
+++ /dev/null
@@ -1,1286 +0,0 @@
-/*****************************************************************************/
-/* SFileAddFile.cpp Copyright (c) Ladislav Zezula 2010 */
-/*---------------------------------------------------------------------------*/
-/* MPQ Editing functions */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 27.03.10 1.00 Lad Splitted from SFileCreateArchiveEx.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "StormCommon.h"
-
-//-----------------------------------------------------------------------------
-// Local structures
-
-#define FILE_SIGNATURE_RIFF 0x46464952
-#define FILE_SIGNATURE_WAVE 0x45564157
-#define FILE_SIGNATURE_FMT 0x20746D66
-#define AUDIO_FORMAT_PCM 1
-
-typedef struct _WAVE_FILE_HEADER
-{
- DWORD dwChunkId; // 0x52494646 ("RIFF")
- DWORD dwChunkSize; // Size of that chunk, in bytes
- DWORD dwFormat; // Must be 0x57415645 ("WAVE")
-
- // Format sub-chunk
- DWORD dwSubChunk1Id; // 0x666d7420 ("fmt ")
- DWORD dwSubChunk1Size; // 0x16 for PCM
- USHORT wAudioFormat; // 1 = PCM. Other value means some sort of compression
- USHORT wChannels; // Number of channels
- DWORD dwSampleRate; // 8000, 44100, etc.
- DWORD dwBytesRate; // SampleRate * NumChannels * BitsPerSample/8
- USHORT wBlockAlign; // NumChannels * BitsPerSample/8
- USHORT wBitsPerSample; // 8 bits = 8, 16 bits = 16, etc.
-
- // Followed by "data" sub-chunk (we don't care)
-} WAVE_FILE_HEADER, *PWAVE_FILE_HEADER;
-
-//-----------------------------------------------------------------------------
-// Local variables
-
-// Data compression for SFileAddFile
-// Kept here for compatibility with code that was created with StormLib version < 6.50
-static DWORD DefaultDataCompression = MPQ_COMPRESSION_PKWARE;
-
-static SFILE_ADDFILE_CALLBACK AddFileCB = NULL;
-static void * pvUserData = NULL;
-
-//-----------------------------------------------------------------------------
-// MPQ write data functions
-
-#define LOSSY_COMPRESSION_MASK (MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO | MPQ_COMPRESSION_HUFFMANN)
-
-static int IsWaveFile(
- LPBYTE pbFileData,
- DWORD cbFileData,
- LPDWORD pdwChannels)
-{
- PWAVE_FILE_HEADER pWaveHdr = (PWAVE_FILE_HEADER)pbFileData;
-
- if(cbFileData > sizeof(WAVE_FILE_HEADER))
- {
- if(pWaveHdr->dwChunkId == FILE_SIGNATURE_RIFF && pWaveHdr->dwFormat == FILE_SIGNATURE_WAVE)
- {
- if(pWaveHdr->dwSubChunk1Id == FILE_SIGNATURE_FMT && pWaveHdr->wAudioFormat == AUDIO_FORMAT_PCM)
- {
- *pdwChannels = pWaveHdr->wChannels;
- return true;
- }
- }
- }
-
- return false;
-}
-
-
-static int WriteDataToMpqFile(
- TMPQArchive * ha,
- TMPQFile * hf,
- LPBYTE pbFileData,
- DWORD dwDataSize,
- DWORD dwCompression)
-{
- TFileEntry * pFileEntry = hf->pFileEntry;
- ULONGLONG ByteOffset;
- LPBYTE pbCompressed = NULL; // Compressed (target) data
- LPBYTE pbToWrite = NULL; // Data to write to the file
- int nCompressionLevel = -1; // ADPCM compression level (only used for wave files)
- int nError = ERROR_SUCCESS;
-
- // If the caller wants ADPCM compression, we will set wave compression level to 4,
- // which corresponds to medium quality
- if(dwCompression & LOSSY_COMPRESSION_MASK)
- nCompressionLevel = 4;
-
- // Make sure that the caller won't overrun the previously initiated file size
- assert(hf->dwFilePos + dwDataSize <= pFileEntry->dwFileSize);
- assert(hf->dwSectorCount != 0);
- assert(hf->pbFileSector != NULL);
- if((hf->dwFilePos + dwDataSize) > pFileEntry->dwFileSize)
- return ERROR_DISK_FULL;
- pbToWrite = hf->pbFileSector;
-
- // Now write all data to the file sector buffer
- if(nError == ERROR_SUCCESS)
- {
- DWORD dwBytesInSector = hf->dwFilePos % hf->dwSectorSize;
- DWORD dwSectorIndex = hf->dwFilePos / hf->dwSectorSize;
- DWORD dwBytesToCopy;
-
- // Process all data.
- while(dwDataSize != 0)
- {
- dwBytesToCopy = dwDataSize;
-
- // Check for sector overflow
- if(dwBytesToCopy > (hf->dwSectorSize - dwBytesInSector))
- dwBytesToCopy = (hf->dwSectorSize - dwBytesInSector);
-
- // Copy the data to the file sector
- memcpy(hf->pbFileSector + dwBytesInSector, pbFileData, dwBytesToCopy);
- dwBytesInSector += dwBytesToCopy;
- pbFileData += dwBytesToCopy;
- dwDataSize -= dwBytesToCopy;
-
- // Update the file position
- hf->dwFilePos += dwBytesToCopy;
-
- // If the current sector is full, or if the file is already full,
- // then write the data to the MPQ
- if(dwBytesInSector >= hf->dwSectorSize || hf->dwFilePos >= pFileEntry->dwFileSize)
- {
- // Set the position in the file
- ByteOffset = hf->RawFilePos + pFileEntry->dwCmpSize;
-
- // Update CRC32 and MD5 of the file
- md5_process((hash_state *)hf->hctx, hf->pbFileSector, dwBytesInSector);
- hf->dwCrc32 = crc32(hf->dwCrc32, hf->pbFileSector, dwBytesInSector);
-
- // Compress the file sector, if needed
- if(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED)
- {
- int nOutBuffer = (int)dwBytesInSector;
- int nInBuffer = (int)dwBytesInSector;
-
- // If the file is compressed, allocate buffer for the compressed data.
- // Note that we allocate buffer that is a bit longer than sector size,
- // for case if the compression method performs a buffer overrun
- if(pbCompressed == NULL)
- {
- pbToWrite = pbCompressed = STORM_ALLOC(BYTE, hf->dwSectorSize + 0x100);
- if(pbCompressed == NULL)
- {
- nError = ERROR_NOT_ENOUGH_MEMORY;
- break;
- }
- }
-
- //
- // Note that both SCompImplode and SCompCompress give original buffer,
- // if they are unable to comperss the data.
- //
-
- if(pFileEntry->dwFlags & MPQ_FILE_IMPLODE)
- {
- SCompImplode((char *)pbCompressed,
- &nOutBuffer,
- (char *)hf->pbFileSector,
- nInBuffer);
- }
-
- if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS)
- {
- SCompCompress((char *)pbCompressed,
- &nOutBuffer,
- (char *)hf->pbFileSector,
- nInBuffer,
- (unsigned)dwCompression,
- 0,
- nCompressionLevel);
- }
-
- // Update sector positions
- dwBytesInSector = nOutBuffer;
- if(hf->SectorOffsets != NULL)
- hf->SectorOffsets[dwSectorIndex+1] = hf->SectorOffsets[dwSectorIndex] + dwBytesInSector;
-
- // We have to calculate sector CRC, if enabled
- if(hf->SectorChksums != NULL)
- hf->SectorChksums[dwSectorIndex] = adler32(0, pbCompressed, nOutBuffer);
- }
-
- // Encrypt the sector, if necessary
- if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
- {
- BSWAP_ARRAY32_UNSIGNED(pbToWrite, dwBytesInSector);
- EncryptMpqBlock(pbToWrite, dwBytesInSector, hf->dwFileKey + dwSectorIndex);
- BSWAP_ARRAY32_UNSIGNED(pbToWrite, dwBytesInSector);
- }
-
- // Write the file sector
- if(!FileStream_Write(ha->pStream, &ByteOffset, pbToWrite, dwBytesInSector))
- {
- nError = GetLastError();
- break;
- }
-
- // Call the compact callback, if any
- if(AddFileCB != NULL)
- AddFileCB(pvUserData, hf->dwFilePos, hf->dwDataSize, false);
-
- // Update the compressed file size
- pFileEntry->dwCmpSize += dwBytesInSector;
- dwBytesInSector = 0;
- dwSectorIndex++;
- }
- }
- }
-
- // Cleanup
- if(pbCompressed != NULL)
- STORM_FREE(pbCompressed);
- return nError;
-}
-
-//-----------------------------------------------------------------------------
-// Recrypts file data for file renaming
-
-static int RecryptFileData(
- TMPQArchive * ha,
- TMPQFile * hf,
- const char * szFileName,
- const char * szNewFileName)
-{
- ULONGLONG RawFilePos;
- TFileEntry * pFileEntry = hf->pFileEntry;
- DWORD dwBytesToRecrypt = pFileEntry->dwCmpSize;
- DWORD dwOldKey;
- DWORD dwNewKey;
- int nError = ERROR_SUCCESS;
-
- // The file must be encrypted
- assert(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED);
-
- // File decryption key is calculated from the plain name
- szNewFileName = GetPlainFileNameA(szNewFileName);
- szFileName = GetPlainFileNameA(szFileName);
-
- // Calculate both file keys
- dwOldKey = DecryptFileKey(szFileName, pFileEntry->ByteOffset, pFileEntry->dwFileSize, pFileEntry->dwFlags);
- dwNewKey = DecryptFileKey(szNewFileName, pFileEntry->ByteOffset, pFileEntry->dwFileSize, pFileEntry->dwFlags);
-
- // Incase the keys are equal, don't recrypt the file
- if(dwNewKey == dwOldKey)
- return ERROR_SUCCESS;
- hf->dwFileKey = dwOldKey;
-
- // Calculate the raw position of the file in the archive
- hf->MpqFilePos = pFileEntry->ByteOffset;
- hf->RawFilePos = ha->MpqPos + hf->MpqFilePos;
-
- // Allocate buffer for file transfer
- nError = AllocateSectorBuffer(hf);
- if(nError != ERROR_SUCCESS)
- return nError;
-
- // Also allocate buffer for sector offsets
- // Note: Don't load sector checksums, we don't need to recrypt them
- nError = AllocateSectorOffsets(hf, true);
- if(nError != ERROR_SUCCESS)
- return nError;
-
- // If we have sector offsets, recrypt these as well
- if(hf->SectorOffsets != NULL)
- {
- // Allocate secondary buffer for sectors copy
- DWORD * SectorOffsetsCopy = (DWORD *)STORM_ALLOC(BYTE, hf->SectorOffsets[0]);
- DWORD dwSectorOffsLen = hf->SectorOffsets[0];
-
- if(SectorOffsetsCopy == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Recrypt the array of sector offsets
- memcpy(SectorOffsetsCopy, hf->SectorOffsets, dwSectorOffsLen);
- EncryptMpqBlock(SectorOffsetsCopy, dwSectorOffsLen, dwNewKey - 1);
- BSWAP_ARRAY32_UNSIGNED(SectorOffsetsCopy, dwSectorOffsLen);
-
- // Write the recrypted array back
- if(!FileStream_Write(ha->pStream, &hf->RawFilePos, SectorOffsetsCopy, dwSectorOffsLen))
- nError = GetLastError();
- STORM_FREE(SectorOffsetsCopy);
- }
-
- // Now we have to recrypt all file sectors. We do it without
- // recompression, because recompression is not necessary in this case
- if(nError == ERROR_SUCCESS)
- {
- for(DWORD dwSector = 0; dwSector < hf->dwSectorCount; dwSector++)
- {
- DWORD dwRawDataInSector = hf->dwSectorSize;
- DWORD dwRawByteOffset = dwSector * hf->dwSectorSize;
-
- // Last sector: If there is not enough bytes remaining in the file, cut the raw size
- if(dwRawDataInSector > dwBytesToRecrypt)
- dwRawDataInSector = dwBytesToRecrypt;
-
- // Fix the raw data length if the file is compressed
- if(hf->SectorOffsets != NULL)
- {
- dwRawDataInSector = hf->SectorOffsets[dwSector+1] - hf->SectorOffsets[dwSector];
- dwRawByteOffset = hf->SectorOffsets[dwSector];
- }
-
- // Calculate the raw file offset of the file sector
- CalculateRawSectorOffset(RawFilePos, hf, dwRawByteOffset);
-
- // Read the file sector
- if(!FileStream_Read(ha->pStream, &RawFilePos, hf->pbFileSector, dwRawDataInSector))
- {
- nError = GetLastError();
- break;
- }
-
- // If necessary, re-encrypt the sector
- // Note: Recompression is not necessary here. Unlike encryption,
- // the compression does not depend on the position of the file in MPQ.
- BSWAP_ARRAY32_UNSIGNED(hf->pbFileSector, dwRawDataInSector);
- DecryptMpqBlock(hf->pbFileSector, dwRawDataInSector, dwOldKey + dwSector);
- EncryptMpqBlock(hf->pbFileSector, dwRawDataInSector, dwNewKey + dwSector);
- BSWAP_ARRAY32_UNSIGNED(hf->pbFileSector, dwRawDataInSector);
-
- // Write the sector back
- if(!FileStream_Write(ha->pStream, &RawFilePos, hf->pbFileSector, dwRawDataInSector))
- {
- nError = GetLastError();
- break;
- }
-
- // Decrement number of bytes remaining
- dwBytesToRecrypt -= hf->dwSectorSize;
- }
- }
-
- return nError;
-}
-
-//-----------------------------------------------------------------------------
-// Support functions for adding files to the MPQ
-
-int SFileAddFile_Init(
- TMPQArchive * ha,
- const char * szFileName,
- ULONGLONG FileTime,
- DWORD dwFileSize,
- LCID lcLocale,
- DWORD dwFlags,
- TMPQFile ** phf)
-{
- TFileEntry * pFileEntry = NULL;
- ULONGLONG TempPos; // For various file offset calculations
- TMPQFile * hf = NULL; // File structure for newly added file
- int nError = ERROR_SUCCESS;
-
- //
- // Note: This is an internal function so no validity checks are done.
- // It is the caller's responsibility to make sure that no invalid
- // flags get to this point
- //
-
- // Sestor CRC is not allowed with single unit files
- if(dwFlags & MPQ_FILE_SINGLE_UNIT)
- dwFlags &= ~MPQ_FILE_SECTOR_CRC;
-
- // Sector CRC is not allowed if the file is not compressed
- if(!(dwFlags & MPQ_FILE_COMPRESSED))
- dwFlags &= ~MPQ_FILE_SECTOR_CRC;
-
- // Fix Key is not allowed if the file is not enrypted
- if(!(dwFlags & MPQ_FILE_ENCRYPTED))
- dwFlags &= ~MPQ_FILE_FIX_KEY;
-
- // If the MPQ is of version 3.0 or higher, we ignore file locale.
- // This is because HET and BET tables have no known support for it
- if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_3)
- lcLocale = 0;
-
- // Allocate the TMPQFile entry for newly added file
- hf = CreateMpqFile(ha);
- if(hf == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
-
- // Find a free space in the MPQ, as well as free block table entry
- if(nError == ERROR_SUCCESS)
- {
- // Find the position where the file will be stored
- FindFreeMpqSpace(ha, &hf->MpqFilePos);
- hf->RawFilePos = ha->MpqPos + hf->MpqFilePos;
- hf->bIsWriteHandle = true;
-
- // Sanity check: The MPQ must be marked as changed at this point
- assert((ha->dwFlags & MPQ_FLAG_CHANGED) != 0);
-
- // When format V1, the size of the archive cannot exceed 4 GB
- if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1)
- {
- TempPos = hf->MpqFilePos + dwFileSize;
- TempPos += ha->pHeader->dwHashTableSize * sizeof(TMPQHash);
- TempPos += ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock);
- TempPos += ha->pHeader->dwBlockTableSize * sizeof(USHORT);
- if((TempPos >> 32) != 0)
- nError = ERROR_DISK_FULL;
- }
- }
-
- // Allocate file entry in the MPQ
- if(nError == ERROR_SUCCESS)
- {
- // Check if the file already exists in the archive
- pFileEntry = GetFileEntryExact(ha, szFileName, lcLocale);
- if(pFileEntry == NULL)
- {
- pFileEntry = AllocateFileEntry(ha, szFileName, lcLocale);
- if(pFileEntry == NULL)
- nError = ERROR_DISK_FULL;
- }
- else
- {
- // If the file exists and "replace existing" is not set, fail it
- if((dwFlags & MPQ_FILE_REPLACEEXISTING) == 0)
- nError = ERROR_ALREADY_EXISTS;
-
- // If the file entry already contains a file
- // and it is a pseudo-name, replace it
- if(nError == ERROR_SUCCESS)
- {
- AllocateFileName(pFileEntry, szFileName);
- }
- }
- }
-
- //
- // At this point, the file name in file entry must be non-NULL
- //
-
- // Create key for file encryption
- if(nError == ERROR_SUCCESS && (dwFlags & MPQ_FILE_ENCRYPTED))
- {
- hf->dwFileKey = DecryptFileKey(szFileName, hf->MpqFilePos, dwFileSize, dwFlags);
- }
-
- if(nError == ERROR_SUCCESS)
- {
- // Initialize the hash entry for the file
- hf->pFileEntry = pFileEntry;
- hf->dwDataSize = dwFileSize;
-
- // Initialize the block table entry for the file
- pFileEntry->ByteOffset = hf->MpqFilePos;
- pFileEntry->dwFileSize = dwFileSize;
- pFileEntry->dwCmpSize = 0;
- pFileEntry->dwFlags = dwFlags | MPQ_FILE_EXISTS;
- pFileEntry->lcLocale = (USHORT)lcLocale;
-
- // Initialize the file time, CRC32 and MD5
- assert(sizeof(hf->hctx) >= sizeof(hash_state));
- memset(pFileEntry->md5, 0, MD5_DIGEST_SIZE);
- md5_init((hash_state *)hf->hctx);
- pFileEntry->dwCrc32 = crc32(0, Z_NULL, 0);
-
- // If the caller gave us a file time, use it.
- pFileEntry->FileTime = FileTime;
-
- // Call the callback, if needed
- if(AddFileCB != NULL)
- AddFileCB(pvUserData, 0, hf->dwDataSize, false);
- }
-
- // If an error occured, remember it
- if(nError != ERROR_SUCCESS)
- hf->bErrorOccured = true;
- *phf = hf;
- return nError;
-}
-
-int SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD dwCompression)
-{
- TMPQArchive * ha;
- TFileEntry * pFileEntry;
- int nError = ERROR_SUCCESS;
-
- // Don't bother if the caller gave us zero size
- if(pvData == NULL || dwSize == 0)
- return ERROR_SUCCESS;
-
- // Get pointer to the MPQ archive
- pFileEntry = hf->pFileEntry;
- ha = hf->ha;
-
- // Allocate file buffers
- if(hf->pbFileSector == NULL)
- {
- ULONGLONG RawFilePos = hf->RawFilePos;
-
- // Allocate buffer for file sector
- nError = AllocateSectorBuffer(hf);
- if(nError != ERROR_SUCCESS)
- {
- hf->bErrorOccured = true;
- return nError;
- }
-
- // Allocate patch info, if the data is patch
- if(hf->pPatchInfo == NULL && IsIncrementalPatchFile(pvData, dwSize, &hf->dwPatchedFileSize))
- {
- // Set the MPQ_FILE_PATCH_FILE flag
- hf->pFileEntry->dwFlags |= MPQ_FILE_PATCH_FILE;
-
- // Allocate the patch info
- nError = AllocatePatchInfo(hf, false);
- if(nError != ERROR_SUCCESS)
- {
- hf->bErrorOccured = true;
- return nError;
- }
- }
-
- // Allocate sector offsets
- if(hf->SectorOffsets == NULL)
- {
- nError = AllocateSectorOffsets(hf, false);
- if(nError != ERROR_SUCCESS)
- {
- hf->bErrorOccured = true;
- return nError;
- }
- }
-
- // Create array of sector checksums
- if(hf->SectorChksums == NULL && (pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC))
- {
- nError = AllocateSectorChecksums(hf, false);
- if(nError != ERROR_SUCCESS)
- {
- hf->bErrorOccured = true;
- return nError;
- }
- }
-
- // Pre-save the patch info, if any
- if(hf->pPatchInfo != NULL)
- {
- if(!FileStream_Write(ha->pStream, &RawFilePos, hf->pPatchInfo, hf->pPatchInfo->dwLength))
- nError = GetLastError();
-
- pFileEntry->dwCmpSize += hf->pPatchInfo->dwLength;
- RawFilePos += hf->pPatchInfo->dwLength;
- }
-
- // Pre-save the sector offset table, just to reserve space in the file.
- // Note that we dont need to swap the sector positions, nor encrypt the table
- // at the moment, as it will be written again after writing all file sectors.
- if(hf->SectorOffsets != NULL)
- {
- if(!FileStream_Write(ha->pStream, &RawFilePos, hf->SectorOffsets, hf->SectorOffsets[0]))
- nError = GetLastError();
-
- pFileEntry->dwCmpSize += hf->SectorOffsets[0];
- RawFilePos += hf->SectorOffsets[0];
- }
- }
-
- // Write the MPQ data to the file
- if(nError == ERROR_SUCCESS)
- nError = WriteDataToMpqFile(ha, hf, (LPBYTE)pvData, dwSize, dwCompression);
-
- // If it succeeded and we wrote all the file data,
- // we need to re-save sector offset table
- if(nError == ERROR_SUCCESS)
- {
- if(hf->dwFilePos >= pFileEntry->dwFileSize)
- {
- // Finish calculating CRC32
- hf->pFileEntry->dwCrc32 = hf->dwCrc32;
-
- // Finish calculating MD5
- md5_done((hash_state *)hf->hctx, hf->pFileEntry->md5);
-
- // If we also have sector checksums, write them to the file
- if(hf->SectorChksums != NULL)
- {
- nError = WriteSectorChecksums(hf);
- if(nError != ERROR_SUCCESS)
- hf->bErrorOccured = true;
- }
-
- // Now write patch info
- if(hf->pPatchInfo != NULL)
- {
- memcpy(hf->pPatchInfo->md5, hf->pFileEntry->md5, MD5_DIGEST_SIZE);
- hf->pPatchInfo->dwDataSize = hf->pFileEntry->dwFileSize;
- hf->pFileEntry->dwFileSize = hf->dwPatchedFileSize;
- nError = WritePatchInfo(hf);
- if(nError != ERROR_SUCCESS)
- hf->bErrorOccured = true;
- }
-
- // Now write sector offsets to the file
- if(hf->SectorOffsets != NULL)
- {
- nError = WriteSectorOffsets(hf);
- if(nError != ERROR_SUCCESS)
- hf->bErrorOccured = true;
- }
-
- // Write the MD5 hashes of each file chunk, if required
- if(ha->pHeader->dwRawChunkSize != 0)
- {
- nError = WriteMpqDataMD5(ha->pStream,
- ha->MpqPos + hf->pFileEntry->ByteOffset,
- hf->pFileEntry->dwCmpSize,
- ha->pHeader->dwRawChunkSize);
- if(nError != ERROR_SUCCESS)
- hf->bErrorOccured = true;
- }
- }
- }
- else
- {
- hf->bErrorOccured = true;
- }
-
- return nError;
-}
-
-int SFileAddFile_Finish(TMPQFile * hf)
-{
- TMPQArchive * ha = hf->ha;
- TFileEntry * pFileEntry = hf->pFileEntry;
- int nError = ERROR_SUCCESS;
-
- // If all previous operations succeeded, we can update the MPQ
- if(!hf->bErrorOccured)
- {
- // Verify if the caller wrote the file properly
- if(hf->pPatchInfo == NULL)
- {
- assert(pFileEntry != NULL);
- if(hf->dwFilePos != pFileEntry->dwFileSize)
- {
- nError = ERROR_CAN_NOT_COMPLETE;
- hf->bErrorOccured = true;
- }
- }
- else
- {
- if(hf->dwFilePos != hf->pPatchInfo->dwDataSize)
- {
- nError = ERROR_CAN_NOT_COMPLETE;
- hf->bErrorOccured = true;
- }
- }
- }
-
- if(!hf->bErrorOccured)
- {
- // Call the user callback, if any
- if(AddFileCB != NULL)
- AddFileCB(pvUserData, hf->dwDataSize, hf->dwDataSize, true);
-
- // Update the size of the block table
- ha->pHeader->dwBlockTableSize = ha->dwFileTableSize;
- }
- else
- {
- // Free the file entry in MPQ tables
- if(pFileEntry != NULL)
- FreeFileEntry(ha, pFileEntry);
- }
-
- // Clear the add file callback
- FreeMPQFile(hf);
- pvUserData = NULL;
- AddFileCB = NULL;
- return nError;
-}
-
-//-----------------------------------------------------------------------------
-// Adds data as file to the archive
-
-bool WINAPI SFileCreateFile(
- HANDLE hMpq,
- const char * szArchivedName,
- ULONGLONG FileTime,
- DWORD dwFileSize,
- LCID lcLocale,
- DWORD dwFlags,
- HANDLE * phFile)
-{
- TMPQArchive * ha = (TMPQArchive *)hMpq;
- int nError = ERROR_SUCCESS;
-
- // Check valid parameters
- if(!IsValidMpqHandle(ha))
- nError = ERROR_INVALID_HANDLE;
- if(szArchivedName == NULL || *szArchivedName == 0)
- nError = ERROR_INVALID_PARAMETER;
- if(phFile == NULL)
- nError = ERROR_INVALID_PARAMETER;
-
- // Don't allow to add file if the MPQ is open for read only
- if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
- nError = ERROR_ACCESS_DENIED;
-
- // Don't allow to add a file under pseudo-file name
- if(IsPseudoFileName(szArchivedName, NULL))
- nError = ERROR_INVALID_PARAMETER;
-
- // Don't allow to add any of the internal files
- if(IsInternalMpqFileName(szArchivedName))
- nError = ERROR_INTERNAL_FILE;
-
- // Perform validity check of the MPQ flags
- if(nError == ERROR_SUCCESS)
- {
- // Mask all unsupported flags out
- dwFlags &= MPQ_FILE_VALID_FLAGS;
-
- // Check for valid flag combinations
- if((dwFlags & (MPQ_FILE_IMPLODE | MPQ_FILE_COMPRESS)) == (MPQ_FILE_IMPLODE | MPQ_FILE_COMPRESS))
- nError = ERROR_INVALID_PARAMETER;
- }
-
- // Create the file in MPQ
- if(nError == ERROR_SUCCESS)
- {
- // Invalidate the entries for (listfile) and (attributes)
- // After we are done with MPQ changes, we need to re-create them anyway
- InvalidateInternalFiles(ha);
-
- // Initiate the add file operation
- nError = SFileAddFile_Init(ha, szArchivedName, FileTime, dwFileSize, lcLocale, dwFlags, (TMPQFile **)phFile);
- }
-
- // Deal with the errors
- if(nError != ERROR_SUCCESS)
- SetLastError(nError);
- return (nError == ERROR_SUCCESS);
-}
-
-bool WINAPI SFileWriteFile(
- HANDLE hFile,
- const void * pvData,
- DWORD dwSize,
- DWORD dwCompression)
-{
- TMPQFile * hf = (TMPQFile *)hFile;
- int nError = ERROR_SUCCESS;
-
- // Check the proper parameters
- if(!IsValidFileHandle(hf))
- nError = ERROR_INVALID_HANDLE;
- if(hf->bIsWriteHandle == false)
- nError = ERROR_INVALID_HANDLE;
-
- // Special checks for single unit files
- if(nError == ERROR_SUCCESS && (hf->pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT))
- {
- //
- // Note: Blizzard doesn't support single unit files
- // that are stored as encrypted or imploded. We will allow them here,
- // the calling application must ensure that such flag combination doesn't get here
- //
-
-// if(dwFlags & MPQ_FILE_IMPLODE)
-// nError = ERROR_INVALID_PARAMETER;
-//
-// if(dwFlags & MPQ_FILE_ENCRYPTED)
-// nError = ERROR_INVALID_PARAMETER;
-
- // Lossy compression is not allowed on single unit files
- if(dwCompression & LOSSY_COMPRESSION_MASK)
- nError = ERROR_INVALID_PARAMETER;
- }
-
-
- // Write the data to the file
- if(nError == ERROR_SUCCESS)
- nError = SFileAddFile_Write(hf, pvData, dwSize, dwCompression);
-
- // Deal with errors
- if(nError != ERROR_SUCCESS)
- SetLastError(nError);
- return (nError == ERROR_SUCCESS);
-}
-
-bool WINAPI SFileFinishFile(HANDLE hFile)
-{
- TMPQFile * hf = (TMPQFile *)hFile;
- int nError = ERROR_SUCCESS;
-
- // Check the proper parameters
- if(!IsValidFileHandle(hf))
- nError = ERROR_INVALID_HANDLE;
- if(hf->bIsWriteHandle == false)
- nError = ERROR_INVALID_HANDLE;
-
- // Finish the file
- if(nError == ERROR_SUCCESS)
- nError = SFileAddFile_Finish(hf);
-
- // Deal with errors
- if(nError != ERROR_SUCCESS)
- SetLastError(nError);
- return (nError == ERROR_SUCCESS);
-}
-
-//-----------------------------------------------------------------------------
-// Adds a file to the archive
-
-bool WINAPI SFileAddFileEx(
- HANDLE hMpq,
- const TCHAR * szFileName,
- const char * szArchivedName,
- DWORD dwFlags,
- DWORD dwCompression, // Compression of the first sector
- DWORD dwCompressionNext) // Compression of next sectors
-{
- ULONGLONG FileSize = 0;
- ULONGLONG FileTime = 0;
- TFileStream * pStream = NULL;
- HANDLE hMpqFile = NULL;
- LPBYTE pbFileData = NULL;
- DWORD dwBytesRemaining = 0;
- DWORD dwBytesToRead;
- DWORD dwSectorSize = 0x1000;
- DWORD dwChannels = 0;
- bool bIsAdpcmCompression = false;
- bool bIsFirstSector = true;
- int nError = ERROR_SUCCESS;
-
- // Check parameters
- if(szFileName == NULL || *szFileName == 0)
- nError = ERROR_INVALID_PARAMETER;
-
- // Open added file
- if(nError == ERROR_SUCCESS)
- {
- pStream = FileStream_OpenFile(szFileName, STREAM_FLAG_READ_ONLY | STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
- if(pStream == NULL)
- nError = GetLastError();
- }
-
- // Get the file size and file time
- if(nError == ERROR_SUCCESS)
- {
- FileStream_GetTime(pStream, &FileTime);
- FileStream_GetSize(pStream, FileSize);
-
- // Files bigger than 4GB cannot be added to MPQ
- if(FileSize >> 32)
- nError = ERROR_DISK_FULL;
- }
-
- // Allocate data buffer for reading from the source file
- if(nError == ERROR_SUCCESS)
- {
- dwBytesRemaining = (DWORD)FileSize;
- pbFileData = STORM_ALLOC(BYTE, dwSectorSize);
- if(pbFileData == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Deal with various combination of compressions
- if(nError == ERROR_SUCCESS)
- {
- // When the compression for next blocks is set to default,
- // we will copy the compression for the first sector
- if(dwCompressionNext == MPQ_COMPRESSION_NEXT_SAME)
- dwCompressionNext = dwCompression;
-
- // If the caller wants ADPCM compression, we make sure
- // that the first sector is not compressed with lossy compression
- if(dwCompressionNext & (MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO))
- {
- // The first compression must not be WAVE
- if(dwCompression & (MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO))
- dwCompression = MPQ_COMPRESSION_PKWARE;
-
- dwCompressionNext &= ~(MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO);
- bIsAdpcmCompression = true;
- }
-
- // Initiate adding file to the MPQ
- if(!SFileCreateFile(hMpq, szArchivedName, FileTime, (DWORD)FileSize, lcFileLocale, dwFlags, &hMpqFile))
- nError = GetLastError();
- }
-
- // Write the file data to the MPQ
- while(nError == ERROR_SUCCESS && dwBytesRemaining != 0)
- {
- // Get the number of bytes remaining in the source file
- dwBytesToRead = dwBytesRemaining;
- if(dwBytesToRead > dwSectorSize)
- dwBytesToRead = dwSectorSize;
-
- // Read data from the local file
- if(!FileStream_Read(pStream, NULL, pbFileData, dwBytesToRead))
- {
- nError = GetLastError();
- break;
- }
-
- // If the file being added is a WAVE file, we check number of channels
- if(bIsFirstSector && bIsAdpcmCompression)
- {
- // The file must really be a wave file, otherwise it's data corruption
- if(!IsWaveFile(pbFileData, dwBytesToRead, &dwChannels))
- {
- nError = ERROR_BAD_FORMAT;
- break;
- }
-
- // Setup the compression according to number of channels
- dwCompressionNext |= (dwChannels == 1) ? MPQ_COMPRESSION_ADPCM_MONO : MPQ_COMPRESSION_ADPCM_STEREO;
- bIsFirstSector = false;
- }
-
- // Add the file sectors to the MPQ
- if(!SFileWriteFile(hMpqFile, pbFileData, dwBytesToRead, dwCompression))
- {
- nError = GetLastError();
- break;
- }
-
- // Set the next data compression
- dwBytesRemaining -= dwBytesToRead;
- dwCompression = dwCompressionNext;
- }
-
- // Finish the file writing
- if(hMpqFile != NULL)
- {
- if(!SFileFinishFile(hMpqFile))
- nError = GetLastError();
- }
-
- // Cleanup and exit
- if(pbFileData != NULL)
- STORM_FREE(pbFileData);
- if(pStream != NULL)
- FileStream_Close(pStream);
- if(nError != ERROR_SUCCESS)
- SetLastError(nError);
- return (nError == ERROR_SUCCESS);
-}
-
-// Adds a data file into the archive
-bool WINAPI SFileAddFile(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags)
-{
- return SFileAddFileEx(hMpq,
- szFileName,
- szArchivedName,
- dwFlags,
- DefaultDataCompression,
- DefaultDataCompression);
-}
-
-// Adds a WAVE file into the archive
-bool WINAPI SFileAddWave(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags, DWORD dwQuality)
-{
- DWORD dwCompression = 0;
-
- //
- // Note to wave compression level:
- // The following conversion table applied:
- // High quality: WaveCompressionLevel = -1
- // Medium quality: WaveCompressionLevel = 4
- // Low quality: WaveCompressionLevel = 2
- //
- // Starcraft files are packed as Mono (0x41) on medium quality.
- // Because this compression is not used anymore, our compression functions
- // will default to WaveCompressionLevel = 4 when using ADPCM compression
- //
-
- // Convert quality to data compression
- switch(dwQuality)
- {
- case MPQ_WAVE_QUALITY_HIGH:
-// WaveCompressionLevel = -1;
- dwCompression = MPQ_COMPRESSION_PKWARE;
- break;
-
- case MPQ_WAVE_QUALITY_MEDIUM:
-// WaveCompressionLevel = 4;
- dwCompression = MPQ_COMPRESSION_ADPCM_STEREO | MPQ_COMPRESSION_HUFFMANN;
- break;
-
- case MPQ_WAVE_QUALITY_LOW:
-// WaveCompressionLevel = 2;
- dwCompression = MPQ_COMPRESSION_ADPCM_STEREO | MPQ_COMPRESSION_HUFFMANN;
- break;
- }
-
- return SFileAddFileEx(hMpq,
- szFileName,
- szArchivedName,
- dwFlags,
- MPQ_COMPRESSION_PKWARE, // First sector should be compressed as data
- dwCompression); // Next sectors should be compressed as WAVE
-}
-
-//-----------------------------------------------------------------------------
-// bool SFileRemoveFile(HANDLE hMpq, char * szFileName)
-//
-// This function removes a file from the archive. The file content
-// remains there, only the entries in the hash table and in the block
-// table are updated.
-
-bool WINAPI SFileRemoveFile(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope)
-{
- TMPQArchive * ha = (TMPQArchive *)hMpq;
- TFileEntry * pFileEntry = NULL; // File entry of the file to be deleted
- DWORD dwFileIndex = 0;
- int nError = ERROR_SUCCESS;
-
- // Keep compiler happy
- dwSearchScope = dwSearchScope;
-
- // Check the parameters
- if(nError == ERROR_SUCCESS)
- {
- if(!IsValidMpqHandle(ha))
- nError = ERROR_INVALID_HANDLE;
- if(szFileName == NULL || *szFileName == 0)
- nError = ERROR_INVALID_PARAMETER;
- if(IsInternalMpqFileName(szFileName))
- nError = ERROR_INTERNAL_FILE;
- }
-
- if(nError == ERROR_SUCCESS)
- {
- // Do not allow to remove files from MPQ open for read only
- if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
- nError = ERROR_ACCESS_DENIED;
- }
-
- // Get hash entry belonging to this file
- if(nError == ERROR_SUCCESS)
- {
- if(!IsPseudoFileName(szFileName, &dwFileIndex))
- {
- if((pFileEntry = GetFileEntryExact(ha, (char *)szFileName, lcFileLocale)) == NULL)
- nError = ERROR_FILE_NOT_FOUND;
- }
- else
- {
- if((pFileEntry = GetFileEntryByIndex(ha, dwFileIndex)) == NULL)
- nError = ERROR_FILE_NOT_FOUND;
- }
- }
-
- // Test if the file is not already deleted
- if(nError == ERROR_SUCCESS)
- {
- if(!(pFileEntry->dwFlags & MPQ_FILE_EXISTS))
- nError = ERROR_FILE_NOT_FOUND;
- }
-
- if(nError == ERROR_SUCCESS)
- {
- // Invalidate the entries for (listfile) and (attributes)
- // After we are done with MPQ changes, we need to re-create them anyway
- InvalidateInternalFiles(ha);
-
- // Mark the file entry as free
- nError = FreeFileEntry(ha, pFileEntry);
- }
-
- // Resolve error and exit
- if(nError != ERROR_SUCCESS)
- SetLastError(nError);
- return (nError == ERROR_SUCCESS);
-}
-
-// Renames the file within the archive.
-bool WINAPI SFileRenameFile(HANDLE hMpq, const char * szFileName, const char * szNewFileName)
-{
- TMPQArchive * ha = (TMPQArchive *)hMpq;
- TFileEntry * pFileEntry = NULL;
- ULONGLONG RawDataOffs;
- TMPQFile * hf;
- int nError = ERROR_SUCCESS;
-
- // Test the valid parameters
- if(nError == ERROR_SUCCESS)
- {
- if(!IsValidMpqHandle(ha))
- nError = ERROR_INVALID_HANDLE;
- if(szFileName == NULL || *szFileName == 0 || szNewFileName == NULL || *szNewFileName == 0)
- nError = ERROR_INVALID_PARAMETER;
- }
-
- if(nError == ERROR_SUCCESS)
- {
- // Do not allow to rename files in MPQ open for read only
- if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
- nError = ERROR_ACCESS_DENIED;
-
- // Do not allow renaming anything to a pseudo-file name
- if(IsPseudoFileName(szFileName, NULL) || IsPseudoFileName(szNewFileName, NULL))
- nError = ERROR_INVALID_PARAMETER;
-
- // Do not allow to rename any of the internal files
- // Also do not allow to rename any of files to an internal file
- if(IsInternalMpqFileName(szFileName) || IsInternalMpqFileName(szNewFileName))
- nError = ERROR_INTERNAL_FILE;
- }
-
- // Find the current file entry.
- if(nError == ERROR_SUCCESS)
- {
- // Get the file entry
- pFileEntry = GetFileEntryLocale(ha, szFileName, lcFileLocale);
- if(pFileEntry == NULL)
- nError = ERROR_FILE_NOT_FOUND;
- }
-
- // Also try to find file entry for the new file.
- // This verifies if we are not overwriting an existing file
- // (whose name we perhaps don't know)
- if(nError == ERROR_SUCCESS)
- {
- if(GetFileEntryLocale(ha, szNewFileName, pFileEntry->lcLocale) != NULL)
- nError = ERROR_ALREADY_EXISTS;
- }
-
- // Now we rename the existing file entry.
- if(nError == ERROR_SUCCESS)
- {
- // Rename the file entry
- nError = RenameFileEntry(ha, pFileEntry, szNewFileName);
- }
-
- // Now we copy the existing file entry to the new one
- if(nError == ERROR_SUCCESS)
- {
- // If the file is encrypted, we have to re-crypt the file content
- // with the new decryption key
- if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
- {
- hf = CreateMpqFile(ha);
- if(hf != NULL)
- {
- // Recrypt the file data in the MPQ
- hf->pFileEntry = pFileEntry;
- hf->dwDataSize = pFileEntry->dwFileSize;
- nError = RecryptFileData(ha, hf, szFileName, szNewFileName);
-
- // Update the MD5
- if(ha->pHeader->dwRawChunkSize != 0)
- {
- RawDataOffs = ha->MpqPos + pFileEntry->ByteOffset;
- WriteMpqDataMD5(ha->pStream,
- RawDataOffs,
- pFileEntry->dwCmpSize,
- ha->pHeader->dwRawChunkSize);
- }
-
- FreeMPQFile(hf);
- }
- else
- {
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
- }
- }
-
- //
- // Note: MPQ_FLAG_CHANGED is set by RenameFileEntry
- //
-
- // Resolve error and return
- if(nError != ERROR_SUCCESS)
- SetLastError(nError);
- return (nError == ERROR_SUCCESS);
-}
-
-//-----------------------------------------------------------------------------
-// Sets default data compression for SFileAddFile
-
-bool WINAPI SFileSetDataCompression(DWORD DataCompression)
-{
- unsigned int uValidMask = (MPQ_COMPRESSION_ZLIB | MPQ_COMPRESSION_PKWARE | MPQ_COMPRESSION_BZIP2 | MPQ_COMPRESSION_SPARSE);
-
- if((DataCompression & uValidMask) != DataCompression)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return false;
- }
-
- DefaultDataCompression = DataCompression;
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Changes locale ID of a file
-
-bool WINAPI SFileSetFileLocale(HANDLE hFile, LCID lcNewLocale)
-{
- TMPQArchive * ha;
- TFileEntry * pFileEntry;
- TMPQFile * hf = (TMPQFile *)hFile;
-
- // Invalid handle => do nothing
- if(!IsValidFileHandle(hf))
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return false;
- }
-
- // Do not allow unnamed access
- if(hf->pFileEntry->szFileName == NULL)
- {
- SetLastError(ERROR_CAN_NOT_COMPLETE);
- return false;
- }
-
- // Do not allow to change locale of any internal file
- if(IsInternalMpqFileName(hf->pFileEntry->szFileName))
- {
- SetLastError(ERROR_INTERNAL_FILE);
- return false;
- }
-
- // Do not allow changing file locales in MPQs version 3 or higher
- ha = hf->ha;
- if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_3)
- {
- SetLastError(ERROR_NOT_SUPPORTED);
- return false;
- }
-
- // Do not allow to rename files in MPQ open for read only
- if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
- {
- SetLastError(ERROR_ACCESS_DENIED);
- return false;
- }
-
- // If the file already has that locale, return OK
- if(hf->pFileEntry->lcLocale == lcNewLocale)
- return true;
-
- // We have to check if the file+locale is not already there
- pFileEntry = GetFileEntryExact(ha, hf->pFileEntry->szFileName, lcNewLocale);
- if(pFileEntry != NULL)
- {
- SetLastError(ERROR_ALREADY_EXISTS);
- return false;
- }
-
- // Set the locale and return success
- pFileEntry = hf->pFileEntry;
- pFileEntry->lcLocale = (USHORT)lcNewLocale;
-
- // Save the new locale to the hash table, if any
- if(ha->pHashTable != NULL)
- ha->pHashTable[pFileEntry->dwHashIndex].lcLocale = (USHORT)lcNewLocale;
-
- // Remember that the MPQ tables have been changed
- ha->dwFlags |= MPQ_FLAG_CHANGED;
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Sets add file callback
-
-bool WINAPI SFileSetAddFileCallback(HANDLE /* hMpq */, SFILE_ADDFILE_CALLBACK aAddFileCB, void * pvData)
-{
- pvUserData = pvData;
- AddFileCB = aAddFileCB;
- return true;
-}
diff --git a/dep/StormLib/src/SFileAttributes.cpp b/dep/StormLib/src/SFileAttributes.cpp
deleted file mode 100644
index 0f056088fa3..00000000000
--- a/dep/StormLib/src/SFileAttributes.cpp
+++ /dev/null
@@ -1,477 +0,0 @@
-/*****************************************************************************/
-/* SAttrFile.cpp Copyright (c) Ladislav Zezula 2007 */
-/*---------------------------------------------------------------------------*/
-/* Description: */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 12.06.04 1.00 Lad The first version of SAttrFile.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "StormCommon.h"
-
-//-----------------------------------------------------------------------------
-// Local structures
-
-typedef struct _MPQ_ATTRIBUTES_HEADER
-{
- DWORD dwVersion; // Version of the (attributes) file. Must be 100 (0x64)
- DWORD dwFlags; // See MPQ_ATTRIBUTE_XXXX
-
- // Followed by an array of CRC32
- // Followed by an array of file times
- // Followed by an array of MD5
- // Followed by an array of patch bits
-} MPQ_ATTRIBUTES_HEADER, *PMPQ_ATTRIBUTES_HEADER;
-
-//-----------------------------------------------------------------------------
-// Public functions (internal use by StormLib)
-
-int SAttrLoadAttributes(TMPQArchive * ha)
-{
- MPQ_ATTRIBUTES_HEADER AttrHeader;
- TMPQFile * hf;
- HANDLE hFile = NULL;
- DWORD dwBlockTableSize = ha->pHeader->dwBlockTableSize;
- DWORD dwArraySize;
- DWORD dwBytesRead;
- DWORD i;
- int nError = ERROR_SUCCESS;
-
- // File table must be initialized
- assert(ha->pFileTable != NULL);
-
- // Attempt to open the "(attributes)" file.
- // If it's not there, then the archive doesn't support attributes
- if(SFileOpenFileEx((HANDLE)ha, ATTRIBUTES_NAME, SFILE_OPEN_ANY_LOCALE, &hFile))
- {
- // Remember the flags for (attributes)
- hf = (TMPQFile *)hFile;
- ha->dwFileFlags2 = hf->pFileEntry->dwFlags;
-
- // Load the content of the attributes file
- SFileReadFile(hFile, &AttrHeader, sizeof(MPQ_ATTRIBUTES_HEADER), &dwBytesRead, NULL);
- if(dwBytesRead != sizeof(MPQ_ATTRIBUTES_HEADER))
- nError = ERROR_FILE_CORRUPT;
-
- // Verify the header of the (attributes) file
- if(nError == ERROR_SUCCESS)
- {
- AttrHeader.dwVersion = BSWAP_INT32_UNSIGNED(AttrHeader.dwVersion);
- AttrHeader.dwFlags = BSWAP_INT32_UNSIGNED(AttrHeader.dwFlags);
- ha->dwAttrFlags = AttrHeader.dwFlags;
- if(dwBytesRead != sizeof(MPQ_ATTRIBUTES_HEADER))
- nError = ERROR_FILE_CORRUPT;
- }
-
- // Verify format of the attributes
- if(nError == ERROR_SUCCESS)
- {
- if(AttrHeader.dwVersion > MPQ_ATTRIBUTES_V1)
- nError = ERROR_BAD_FORMAT;
- }
-
- // Load the CRC32 (if any)
- if(nError == ERROR_SUCCESS && (AttrHeader.dwFlags & MPQ_ATTRIBUTE_CRC32))
- {
- LPDWORD pArrayCRC32 = STORM_ALLOC(DWORD, dwBlockTableSize);
-
- if(pArrayCRC32 != NULL)
- {
- dwArraySize = dwBlockTableSize * sizeof(DWORD);
- SFileReadFile(hFile, pArrayCRC32, dwArraySize, &dwBytesRead, NULL);
- if(dwBytesRead == dwArraySize)
- {
- for(i = 0; i < dwBlockTableSize; i++)
- ha->pFileTable[i].dwCrc32 = BSWAP_INT32_UNSIGNED(pArrayCRC32[i]);
- }
- else
- nError = ERROR_FILE_CORRUPT;
-
- STORM_FREE(pArrayCRC32);
- }
- else
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Read the array of file times
- if(nError == ERROR_SUCCESS && (AttrHeader.dwFlags & MPQ_ATTRIBUTE_FILETIME))
- {
- ULONGLONG * pArrayFileTime = STORM_ALLOC(ULONGLONG, dwBlockTableSize);
-
- if(pArrayFileTime != NULL)
- {
- dwArraySize = dwBlockTableSize * sizeof(ULONGLONG);
- SFileReadFile(hFile, pArrayFileTime, dwArraySize, &dwBytesRead, NULL);
- if(dwBytesRead == dwArraySize)
- {
- for(i = 0; i < dwBlockTableSize; i++)
- ha->pFileTable[i].FileTime = BSWAP_INT64_UNSIGNED(pArrayFileTime[i]);
- }
- else
- nError = ERROR_FILE_CORRUPT;
-
- STORM_FREE(pArrayFileTime);
- }
- else
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Read the MD5 (if any)
- // Note: MD5 array can be incomplete, if it's the last array in the (attributes)
- if(nError == ERROR_SUCCESS && (AttrHeader.dwFlags & MPQ_ATTRIBUTE_MD5))
- {
- unsigned char * pArrayMD5 = STORM_ALLOC(unsigned char, (dwBlockTableSize * MD5_DIGEST_SIZE));
- unsigned char * md5;
-
- if(pArrayMD5 != NULL)
- {
- dwArraySize = dwBlockTableSize * MD5_DIGEST_SIZE;
- SFileReadFile(hFile, pArrayMD5, dwArraySize, &dwBytesRead, NULL);
- if(dwBytesRead == dwArraySize)
- {
- md5 = pArrayMD5;
- for(i = 0; i < dwBlockTableSize; i++)
- {
- memcpy(ha->pFileTable[i].md5, md5, MD5_DIGEST_SIZE);
- md5 += MD5_DIGEST_SIZE;
- }
- }
- else
- nError = ERROR_FILE_CORRUPT;
-
- STORM_FREE(pArrayMD5);
- }
- else
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Read the patch bit for each file
- if(nError == ERROR_SUCCESS && (AttrHeader.dwFlags & MPQ_ATTRIBUTE_PATCH_BIT))
- {
- LPBYTE pbBitArray;
- DWORD dwByteSize = ((dwBlockTableSize - 1) / 8) + 1;
-
- pbBitArray = STORM_ALLOC(BYTE, dwByteSize);
- if(pbBitArray != NULL)
- {
- SFileReadFile(hFile, pbBitArray, dwByteSize, &dwBytesRead, NULL);
- if(dwBytesRead == dwByteSize)
- {
- for(i = 0; i < dwBlockTableSize; i++)
- {
- DWORD dwByteIndex = i / 8;
- DWORD dwBitMask = 0x80 >> (i & 7);
-
- // Is the appropriate bit set?
- if(pbBitArray[dwByteIndex] & dwBitMask)
- {
- // At the moment, we assume that the patch bit is present
- // in both file table and (attributes)
- assert((ha->pFileTable[i].dwFlags & MPQ_FILE_PATCH_FILE) != 0);
- ha->pFileTable[i].dwFlags |= MPQ_FILE_PATCH_FILE;
- }
- }
- }
- else
- nError = ERROR_FILE_CORRUPT;
-
- STORM_FREE(pbBitArray);
- }
- }
-
- //
- // Note: Version 7.00 of StormLib saved the (attributes) incorrectly.
- // Sometimes, number of entries in the (attributes) was 1 item less
- // than block table size.
- // If we encounter such table, we will zero all three arrays
- //
-
- if(nError != ERROR_SUCCESS)
- ha->dwAttrFlags = 0;
-
- // Cleanup & exit
- SFileCloseFile(hFile);
- }
- return nError;
-}
-
-int SAttrFileSaveToMpq(TMPQArchive * ha)
-{
- MPQ_ATTRIBUTES_HEADER AttrHeader;
- TFileEntry * pFileEntry;
- TMPQFile * hf = NULL;
- DWORD dwFinalBlockTableSize = ha->dwFileTableSize;
- DWORD dwFileSize = 0;
- DWORD dwToWrite;
- DWORD i;
- int nError = ERROR_SUCCESS;
-
- // Now we have to check if we need patch bits in the (attributes)
- if(nError == ERROR_SUCCESS)
- {
- for(i = 0; i < ha->dwFileTableSize; i++)
- {
- if(ha->pFileTable[i].dwFlags & MPQ_FILE_PATCH_FILE)
- {
- ha->dwAttrFlags |= MPQ_ATTRIBUTE_PATCH_BIT;
- break;
- }
- }
- }
-
- // If the (attributes) is not in the file table yet,
- // we have to increase the final block table size
- pFileEntry = GetFileEntryExact(ha, ATTRIBUTES_NAME, LANG_NEUTRAL);
- if(pFileEntry != NULL)
- {
- // If "(attributes)" file exists, and it's set to 0, then remove it
- if(ha->dwAttrFlags == 0)
- {
- FreeFileEntry(ha, pFileEntry);
- return ERROR_SUCCESS;
- }
- }
- else
- {
- // If we don't want to create file atributes, do nothing
- if(ha->dwAttrFlags == 0)
- return ERROR_SUCCESS;
-
- // Check where the file entry is going to be allocated.
- // If at the end of the file table, we have to increment
- // the expected size of the (attributes) file.
- pFileEntry = FindFreeFileEntry(ha);
- if(pFileEntry == ha->pFileTable + ha->dwFileTableSize)
- dwFinalBlockTableSize++;
- }
-
- // Calculate the size of the attributes file
- if(nError == ERROR_SUCCESS)
- {
- dwFileSize = sizeof(MPQ_ATTRIBUTES_HEADER); // Header
- if(ha->dwAttrFlags & MPQ_ATTRIBUTE_CRC32)
- dwFileSize += dwFinalBlockTableSize * sizeof(DWORD);
- if(ha->dwAttrFlags & MPQ_ATTRIBUTE_FILETIME)
- dwFileSize += dwFinalBlockTableSize * sizeof(ULONGLONG);
- if(ha->dwAttrFlags & MPQ_ATTRIBUTE_MD5)
- dwFileSize += dwFinalBlockTableSize * MD5_DIGEST_SIZE;
- if(ha->dwAttrFlags & MPQ_ATTRIBUTE_PATCH_BIT)
- dwFileSize += ((dwFinalBlockTableSize - 1)) / 8 + 1;
- }
-
- // Determine the flags for (attributes)
- if(ha->dwFileFlags2 == 0)
- ha->dwFileFlags2 = GetDefaultSpecialFileFlags(ha, dwFileSize);
-
- // Create the attributes file in the MPQ
- nError = SFileAddFile_Init(ha, ATTRIBUTES_NAME,
- 0,
- dwFileSize,
- LANG_NEUTRAL,
- ha->dwFileFlags2 | MPQ_FILE_REPLACEEXISTING,
- &hf);
-
- // Write all parts of the (attributes) file
- if(nError == ERROR_SUCCESS)
- {
- assert(ha->dwFileTableSize == dwFinalBlockTableSize);
-
- // Note that we don't know what the new bit (0x08) means.
- AttrHeader.dwVersion = BSWAP_INT32_UNSIGNED(100);
- AttrHeader.dwFlags = BSWAP_INT32_UNSIGNED((ha->dwAttrFlags & MPQ_ATTRIBUTE_ALL));
- dwToWrite = sizeof(MPQ_ATTRIBUTES_HEADER);
- nError = SFileAddFile_Write(hf, &AttrHeader, dwToWrite, MPQ_COMPRESSION_ZLIB);
- }
-
- // Write the array of CRC32
- if(nError == ERROR_SUCCESS && (ha->dwAttrFlags & MPQ_ATTRIBUTE_CRC32))
- {
- LPDWORD pArrayCRC32 = STORM_ALLOC(DWORD, dwFinalBlockTableSize);
-
- if(pArrayCRC32 != NULL)
- {
- // Copy from file table
- for(i = 0; i < ha->dwFileTableSize; i++)
- pArrayCRC32[i] = BSWAP_INT32_UNSIGNED(ha->pFileTable[i].dwCrc32);
-
- dwToWrite = ha->dwFileTableSize * sizeof(DWORD);
- nError = SFileAddFile_Write(hf, pArrayCRC32, dwToWrite, MPQ_COMPRESSION_ZLIB);
- STORM_FREE(pArrayCRC32);
- }
- }
-
- // Write the array of file time
- if(nError == ERROR_SUCCESS && (ha->dwAttrFlags & MPQ_ATTRIBUTE_FILETIME))
- {
- ULONGLONG * pArrayFileTime = STORM_ALLOC(ULONGLONG, ha->dwFileTableSize);
-
- if(pArrayFileTime != NULL)
- {
- // Copy from file table
- for(i = 0; i < ha->dwFileTableSize; i++)
- pArrayFileTime[i] = BSWAP_INT64_UNSIGNED(ha->pFileTable[i].FileTime);
-
- dwToWrite = ha->dwFileTableSize * sizeof(ULONGLONG);
- nError = SFileAddFile_Write(hf, pArrayFileTime, dwToWrite, MPQ_COMPRESSION_ZLIB);
- STORM_FREE(pArrayFileTime);
- }
- }
-
- // Write the array of MD5s
- if(nError == ERROR_SUCCESS && (ha->dwAttrFlags & MPQ_ATTRIBUTE_MD5))
- {
- char * pArrayMD5 = STORM_ALLOC(char, ha->dwFileTableSize * MD5_DIGEST_SIZE);
-
- if(pArrayMD5 != NULL)
- {
- // Copy from file table
- for(i = 0; i < ha->dwFileTableSize; i++)
- memcpy(&pArrayMD5[i * MD5_DIGEST_SIZE], ha->pFileTable[i].md5, MD5_DIGEST_SIZE);
-
- dwToWrite = ha->dwFileTableSize * MD5_DIGEST_SIZE;
- nError = SFileAddFile_Write(hf, pArrayMD5, dwToWrite, MPQ_COMPRESSION_ZLIB);
- STORM_FREE(pArrayMD5);
- }
- }
-
- // Write the array of patch bits
- if(nError == ERROR_SUCCESS && (ha->dwAttrFlags & MPQ_ATTRIBUTE_PATCH_BIT))
- {
- LPBYTE pbBitArray;
- DWORD dwByteSize = ((ha->dwFileTableSize - 1) / 8) + 1;
-
- pbBitArray = STORM_ALLOC(BYTE, dwByteSize);
- if(pbBitArray != NULL)
- {
- memset(pbBitArray, 0, dwByteSize);
- for(i = 0; i < ha->dwFileTableSize; i++)
- {
- DWORD dwByteIndex = i / 8;
- DWORD dwBitMask = 0x80 >> (i & 7);
-
- if(ha->pFileTable[i].dwFlags & MPQ_FILE_PATCH_FILE)
- pbBitArray[dwByteIndex] |= dwBitMask;
- }
-
- nError = SFileAddFile_Write(hf, pbBitArray, dwByteSize, MPQ_COMPRESSION_ZLIB);
- STORM_FREE(pbBitArray);
- }
- }
-
- // Finalize the file in the archive
- if(hf != NULL)
- {
- SFileAddFile_Finish(hf);
- }
-
- if(nError == ERROR_SUCCESS)
- ha->dwFlags &= ~MPQ_FLAG_INV_ATTRIBUTES;
- return nError;
-}
-
-//-----------------------------------------------------------------------------
-// Public functions
-
-DWORD WINAPI SFileGetAttributes(HANDLE hMpq)
-{
- TMPQArchive * ha = (TMPQArchive *)hMpq;
-
- // Verify the parameters
- if(!IsValidMpqHandle(ha))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return SFILE_INVALID_ATTRIBUTES;
- }
-
- return ha->dwAttrFlags;
-}
-
-bool WINAPI SFileSetAttributes(HANDLE hMpq, DWORD dwFlags)
-{
- TMPQArchive * ha = (TMPQArchive *)hMpq;
-
- // Verify the parameters
- if(!IsValidMpqHandle(ha))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return false;
- }
-
- // Not allowed when the archive is read-only
- if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
- {
- SetLastError(ERROR_ACCESS_DENIED);
- return false;
- }
-
- // Set the attributes
- InvalidateInternalFiles(ha);
- ha->dwAttrFlags = (dwFlags & MPQ_ATTRIBUTE_ALL);
- return true;
-}
-
-bool WINAPI SFileUpdateFileAttributes(HANDLE hMpq, const char * szFileName)
-{
- hash_state md5_state;
- TMPQArchive * ha = (TMPQArchive *)hMpq;
- TMPQFile * hf;
- BYTE Buffer[0x1000];
- HANDLE hFile = NULL;
- DWORD dwTotalBytes = 0;
- DWORD dwBytesRead;
- DWORD dwCrc32;
-
- // Verify the parameters
- if(!IsValidMpqHandle(ha))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return false;
- }
-
- // Not allowed when the archive is read-only
- if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
- {
- SetLastError(ERROR_ACCESS_DENIED);
- return false;
- }
-
- // Attempt to open the file
- if(!SFileOpenFileEx(hMpq, szFileName, SFILE_OPEN_FROM_MPQ, &hFile))
- return false;
-
- // Get the file size
- hf = (TMPQFile *)hFile;
- SFileGetFileInfo(hFile, SFILE_INFO_FILE_SIZE, &dwTotalBytes, sizeof(DWORD));
-
- // Initialize the CRC32 and MD5 contexts
- md5_init(&md5_state);
- dwCrc32 = crc32(0, Z_NULL, 0);
-
- // Go through entire file and calculate both CRC32 and MD5
- while(dwTotalBytes != 0)
- {
- // Read data from file
- SFileReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, NULL);
- if(dwBytesRead == 0)
- break;
-
- // Update CRC32 and MD5
- dwCrc32 = crc32(dwCrc32, Buffer, dwBytesRead);
- md5_process(&md5_state, Buffer, dwBytesRead);
-
- // Decrement the total size
- dwTotalBytes -= dwBytesRead;
- }
-
- // Update both CRC32 and MD5
- hf->pFileEntry->dwCrc32 = dwCrc32;
- md5_done(&md5_state, hf->pFileEntry->md5);
-
- // Remember that we need to save the MPQ tables
- InvalidateInternalFiles(ha);
- SFileCloseFile(hFile);
- return true;
-}
diff --git a/dep/StormLib/src/SFileCompactArchive.cpp b/dep/StormLib/src/SFileCompactArchive.cpp
deleted file mode 100644
index 319108b08f4..00000000000
--- a/dep/StormLib/src/SFileCompactArchive.cpp
+++ /dev/null
@@ -1,765 +0,0 @@
-/*****************************************************************************/
-/* SFileCompactArchive.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Archive compacting function */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 14.04.03 1.00 Lad Splitted from SFileCreateArchiveEx.cpp */
-/* 19.11.03 1.01 Dan Big endian handling */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "StormCommon.h"
-
-/*****************************************************************************/
-/* Local variables */
-/*****************************************************************************/
-
-static SFILE_COMPACT_CALLBACK CompactCB = NULL;
-static ULONGLONG CompactBytesProcessed = 0;
-static ULONGLONG CompactTotalBytes = 0;
-static void * pvUserData = NULL;
-
-/*****************************************************************************/
-/* Local functions */
-/*****************************************************************************/
-
-static int CheckIfAllFilesKnown(TMPQArchive * ha, const char * szListFile, LPDWORD pFileKeys)
-{
- TFileEntry * pFileTableEnd;
- TFileEntry * pFileEntry;
- DWORD dwBlockIndex = 0;
- int nError = ERROR_SUCCESS;
-
- // Add the listfile to the MPQ
- if(nError == ERROR_SUCCESS && szListFile != NULL)
- {
- // Notify the user
- if(CompactCB != NULL)
- CompactCB(pvUserData, CCB_CHECKING_FILES, CompactBytesProcessed, CompactTotalBytes);
-
- nError = SFileAddListFile((HANDLE)ha, szListFile);
- }
-
- // Verify the file table
- if(nError == ERROR_SUCCESS)
- {
- pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
- for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++, dwBlockIndex++)
- {
- if(pFileEntry->dwFlags & MPQ_FILE_EXISTS)
- {
- if(pFileEntry->szFileName != NULL && !IsPseudoFileName(pFileEntry->szFileName, NULL))
- {
- DWORD dwFileKey = 0;
-
- // Resolve the file key. Use plain file name for it
- if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
- {
- dwFileKey = DecryptFileKey(pFileEntry->szFileName,
- pFileEntry->ByteOffset,
- pFileEntry->dwFileSize,
- pFileEntry->dwFlags);
- }
-
- // Give the key to the caller
- if(pFileKeys != NULL)
- pFileKeys[dwBlockIndex] = dwFileKey;
- }
- else
- {
- nError = ERROR_CAN_NOT_COMPLETE;
- break;
- }
- }
- }
- }
-
- return nError;
-}
-
-static int CopyNonMpqData(
- TFileStream * pSrcStream,
- TFileStream * pTrgStream,
- ULONGLONG & ByteOffset,
- ULONGLONG & ByteCount)
-{
- ULONGLONG DataSize = ByteCount;
- DWORD dwToRead;
- char DataBuffer[0x1000];
- int nError = ERROR_SUCCESS;
-
- // Copy the data
- while(DataSize > 0)
- {
- // Get the proper size of data
- dwToRead = sizeof(DataBuffer);
- if(DataSize < dwToRead)
- dwToRead = (DWORD)DataSize;
-
- // Read from the source stream
- if(!FileStream_Read(pSrcStream, &ByteOffset, DataBuffer, dwToRead))
- {
- nError = GetLastError();
- break;
- }
-
- // Write to the target stream
- if(!FileStream_Write(pTrgStream, NULL, DataBuffer, dwToRead))
- {
- nError = GetLastError();
- break;
- }
-
- // Update the progress
- if(CompactCB != NULL)
- {
- CompactBytesProcessed += dwToRead;
- CompactCB(pvUserData, CCB_COPYING_NON_MPQ_DATA, CompactBytesProcessed, CompactTotalBytes);
- }
-
- // Decrement the number of data to be copied
- ByteOffset += dwToRead;
- DataSize -= dwToRead;
- }
-
- return ERROR_SUCCESS;
-}
-
-// Copies all file sectors into another archive.
-static int CopyMpqFileSectors(
- TMPQArchive * ha,
- TMPQFile * hf,
- TFileStream * pNewStream)
-{
- TFileEntry * pFileEntry = hf->pFileEntry;
- ULONGLONG RawFilePos; // Used for calculating sector offset in the old MPQ archive
- ULONGLONG MpqFilePos; // MPQ file position in the new archive
- DWORD dwBytesToCopy = pFileEntry->dwCmpSize;
- DWORD dwPatchSize = 0; // Size of patch header
- DWORD dwFileKey1 = 0; // File key used for decryption
- DWORD dwFileKey2 = 0; // File key used for encryption
- DWORD dwCmpSize = 0; // Compressed file size, including patch header
- int nError = ERROR_SUCCESS;
-
- // Remember the position in the destination file
- FileStream_GetPos(pNewStream, MpqFilePos);
- MpqFilePos -= ha->MpqPos;
-
- // Resolve decryption keys. Note that the file key given
- // in the TMPQFile structure also includes the key adjustment
- if(nError == ERROR_SUCCESS && (pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED))
- {
- dwFileKey2 = dwFileKey1 = hf->dwFileKey;
- if(pFileEntry->dwFlags & MPQ_FILE_FIX_KEY)
- {
- dwFileKey2 = (dwFileKey1 ^ pFileEntry->dwFileSize) - (DWORD)pFileEntry->ByteOffset;
- dwFileKey2 = (dwFileKey2 + (DWORD)MpqFilePos) ^ pFileEntry->dwFileSize;
- }
- }
-
- // If we have to save patch header, do it
- if(nError == ERROR_SUCCESS && hf->pPatchInfo != NULL)
- {
- BSWAP_ARRAY32_UNSIGNED(hf->pPatchInfo, sizeof(DWORD) * 3);
- if(!FileStream_Write(pNewStream, NULL, hf->pPatchInfo, hf->pPatchInfo->dwLength))
- nError = GetLastError();
-
- // Save the size of the patch info
- dwPatchSize = hf->pPatchInfo->dwLength;
- }
-
- // If we have to save sector offset table, do it.
- if(nError == ERROR_SUCCESS && hf->SectorOffsets != NULL)
- {
- DWORD * SectorOffsetsCopy = (DWORD *)STORM_ALLOC(BYTE, hf->SectorOffsets[0]);
- DWORD dwSectorOffsLen = hf->SectorOffsets[0];
-
- assert((pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) == 0);
- assert(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED);
-
- if(SectorOffsetsCopy == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
-
- // Encrypt the secondary sector offset table and write it to the target file
- if(nError == ERROR_SUCCESS)
- {
- memcpy(SectorOffsetsCopy, hf->SectorOffsets, dwSectorOffsLen);
- if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
- EncryptMpqBlock(SectorOffsetsCopy, dwSectorOffsLen, dwFileKey2 - 1);
-
- BSWAP_ARRAY32_UNSIGNED(SectorOffsetsCopy, dwSectorOffsLen);
- if(!FileStream_Write(pNewStream, NULL, SectorOffsetsCopy, dwSectorOffsLen))
- nError = GetLastError();
-
- dwBytesToCopy -= dwSectorOffsLen;
- dwCmpSize += dwSectorOffsLen;
- }
-
- // Update compact progress
- if(CompactCB != NULL)
- {
- CompactBytesProcessed += dwSectorOffsLen;
- CompactCB(pvUserData, CCB_COMPACTING_FILES, CompactBytesProcessed, CompactTotalBytes);
- }
-
- STORM_FREE(SectorOffsetsCopy);
- }
-
- // Now we have to copy all file sectors. We do it without
- // recompression, because recompression is not necessary in this case
- if(nError == ERROR_SUCCESS)
- {
- for(DWORD dwSector = 0; dwSector < hf->dwSectorCount; dwSector++)
- {
- DWORD dwRawDataInSector = hf->dwSectorSize;
- DWORD dwRawByteOffset = dwSector * hf->dwSectorSize;
-
- // Fix the raw data length if the file is compressed
- if(hf->SectorOffsets != NULL)
- {
- dwRawDataInSector = hf->SectorOffsets[dwSector+1] - hf->SectorOffsets[dwSector];
- dwRawByteOffset = hf->SectorOffsets[dwSector];
- }
-
- // Last sector: If there is not enough bytes remaining in the file, cut the raw size
- if(dwRawDataInSector > dwBytesToCopy)
- dwRawDataInSector = dwBytesToCopy;
-
- // Calculate the raw file offset of the file sector
- CalculateRawSectorOffset(RawFilePos, hf, dwRawByteOffset);
-
- // Read the file sector
- if(!FileStream_Read(ha->pStream, &RawFilePos, hf->pbFileSector, dwRawDataInSector))
- {
- nError = GetLastError();
- break;
- }
-
- // If necessary, re-encrypt the sector
- // Note: Recompression is not necessary here. Unlike encryption,
- // the compression does not depend on the position of the file in MPQ.
- if((pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) && dwFileKey1 != dwFileKey2)
- {
- BSWAP_ARRAY32_UNSIGNED(hf->pbFileSector, dwRawDataInSector);
- DecryptMpqBlock(hf->pbFileSector, dwRawDataInSector, dwFileKey1 + dwSector);
- EncryptMpqBlock(hf->pbFileSector, dwRawDataInSector, dwFileKey2 + dwSector);
- BSWAP_ARRAY32_UNSIGNED(hf->pbFileSector, dwRawDataInSector);
- }
-
- // Now write the sector back to the file
- if(!FileStream_Write(pNewStream, NULL, hf->pbFileSector, dwRawDataInSector))
- {
- nError = GetLastError();
- break;
- }
-
- // Update compact progress
- if(CompactCB != NULL)
- {
- CompactBytesProcessed += dwRawDataInSector;
- CompactCB(pvUserData, CCB_COMPACTING_FILES, CompactBytesProcessed, CompactTotalBytes);
- }
-
- // Adjust byte counts
- dwBytesToCopy -= dwRawDataInSector;
- dwCmpSize += dwRawDataInSector;
- }
- }
-
- // Copy the sector CRCs, if any
- // Sector CRCs are always compressed (not imploded) and unencrypted
- if(nError == ERROR_SUCCESS && hf->SectorOffsets != NULL && hf->SectorChksums != NULL)
- {
- DWORD dwCrcLength;
-
- dwCrcLength = hf->SectorOffsets[hf->dwSectorCount + 1] - hf->SectorOffsets[hf->dwSectorCount];
- if(dwCrcLength != 0)
- {
- if(!FileStream_Read(ha->pStream, NULL, hf->SectorChksums, dwCrcLength))
- nError = GetLastError();
-
- if(!FileStream_Write(pNewStream, NULL, hf->SectorChksums, dwCrcLength))
- nError = GetLastError();
-
- // Update compact progress
- if(CompactCB != NULL)
- {
- CompactBytesProcessed += dwCrcLength;
- CompactCB(pvUserData, CCB_COMPACTING_FILES, CompactBytesProcessed, CompactTotalBytes);
- }
-
- // Size of the CRC block is also included in the compressed file size
- dwBytesToCopy -= dwCrcLength;
- dwCmpSize += dwCrcLength;
- }
- }
-
- // There might be extra data beyond sector checksum table
- // Sometimes, these data are even part of sector offset table
- // Examples:
- // 2012 - WoW\15354\locale-enGB.MPQ:DBFilesClient\SpellLevels.dbc
- // 2012 - WoW\15354\locale-enGB.MPQ:Interface\AddOns\Blizzard_AuctionUI\Blizzard_AuctionUI.xml
- if(nError == ERROR_SUCCESS && dwBytesToCopy != 0)
- {
- LPBYTE pbExtraData;
-
- // Allocate space for the extra data
- pbExtraData = STORM_ALLOC(BYTE, dwBytesToCopy);
- if(pbExtraData != NULL)
- {
- if(!FileStream_Read(ha->pStream, NULL, pbExtraData, dwBytesToCopy))
- nError = GetLastError();
-
- if(!FileStream_Write(pNewStream, NULL, pbExtraData, dwBytesToCopy))
- nError = GetLastError();
-
- // Include these extra data in the compressed size
- dwCmpSize += dwBytesToCopy;
- dwBytesToCopy = 0;
- STORM_FREE(pbExtraData);
- }
- else
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Write the MD5's of the raw file data, if needed
- if(nError == ERROR_SUCCESS && ha->pHeader->dwRawChunkSize != 0)
- {
- nError = WriteMpqDataMD5(pNewStream,
- ha->MpqPos + MpqFilePos,
- pFileEntry->dwCmpSize,
- ha->pHeader->dwRawChunkSize);
- }
-
- // Update file position in the block table
- if(nError == ERROR_SUCCESS)
- {
- // At this point, number of bytes written should be exactly
- // the same like the compressed file size. If it isn't,
- // there's something wrong (an unknown archive version, MPQ protection, ...)
- //
- // Note: Diablo savegames have very weird layout, and the file "hero"
- // seems to have improper compressed size. Instead of real compressed size,
- // the "dwCmpSize" member of the block table entry contains
- // uncompressed size of file data + size of the sector table.
- // If we compact the archive, Diablo will refuse to load the game
- // Seems like some sort of protection to me.
- //
- // Note: Some patch files in WOW patches don't count the patch header
- // into compressed size
- //
-
- if(dwCmpSize <= pFileEntry->dwCmpSize && pFileEntry->dwCmpSize <= dwCmpSize + dwPatchSize)
- {
- // Note: DO NOT update the compressed size in the file entry, no matter how bad it is.
- pFileEntry->ByteOffset = MpqFilePos;
- }
- else
- {
- nError = ERROR_FILE_CORRUPT;
- assert(false);
- }
- }
-
- return nError;
-}
-
-static int CopyMpqFiles(TMPQArchive * ha, LPDWORD pFileKeys, TFileStream * pNewStream)
-{
- TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
- TFileEntry * pFileEntry;
- TMPQFile * hf = NULL;
- int nError = ERROR_SUCCESS;
-
- // Walk through all files and write them to the destination MPQ archive
- for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
- {
- // Copy all the file sectors
- // Only do that when the file has nonzero size
- if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) && pFileEntry->dwFileSize != 0)
- {
- // Allocate structure for the MPQ file
- hf = CreateMpqFile(ha);
- if(hf == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Store file entry
- hf->pFileEntry = pFileEntry;
-
- // Set the raw file position
- hf->MpqFilePos = pFileEntry->ByteOffset;
- hf->RawFilePos = ha->MpqPos + hf->MpqFilePos;
-
- // Set the file decryption key
- hf->dwFileKey = pFileKeys[pFileEntry - ha->pFileTable];
- hf->dwDataSize = pFileEntry->dwFileSize;
-
- // If the file is a patch file, load the patch header
- if(pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE)
- {
- nError = AllocatePatchInfo(hf, true);
- if(nError != ERROR_SUCCESS)
- break;
- }
-
- // Allocate buffers for file sector and sector offset table
- nError = AllocateSectorBuffer(hf);
- if(nError != ERROR_SUCCESS)
- break;
-
- // Also allocate sector offset table and sector checksum table
- nError = AllocateSectorOffsets(hf, true);
- if(nError != ERROR_SUCCESS)
- break;
-
- // Also load sector checksums, if any
- if(pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC)
- {
- nError = AllocateSectorChecksums(hf, false);
- if(nError != ERROR_SUCCESS)
- break;
- }
-
- // Copy all file sectors
- nError = CopyMpqFileSectors(ha, hf, pNewStream);
- if(nError != ERROR_SUCCESS)
- break;
-
- // Free buffers. This also sets "hf" to NULL.
- FreeMPQFile(hf);
- }
- }
-
- // Cleanup and exit
- if(hf != NULL)
- FreeMPQFile(hf);
- return nError;
-}
-
-
-/*****************************************************************************/
-/* Public functions */
-/*****************************************************************************/
-
-bool WINAPI SFileSetCompactCallback(HANDLE /* hMpq */, SFILE_COMPACT_CALLBACK aCompactCB, void * pvData)
-{
- CompactCB = aCompactCB;
- pvUserData = pvData;
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Archive compacting
-
-bool WINAPI SFileCompactArchive(HANDLE hMpq, const char * szListFile, bool /* bReserved */)
-{
- TFileStream * pTempStream = NULL;
- TMPQArchive * ha = (TMPQArchive *)hMpq;
- ULONGLONG ByteOffset;
- ULONGLONG ByteCount;
- LPDWORD pFileKeys = NULL;
- TCHAR szTempFile[MAX_PATH] = _T("");
- TCHAR * szTemp = NULL;
- int nError = ERROR_SUCCESS;
-
- // Test the valid parameters
- if(!IsValidMpqHandle(ha))
- nError = ERROR_INVALID_HANDLE;
- if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
- nError = ERROR_ACCESS_DENIED;
-
- // If the MPQ is changed at this moment, we have to flush the archive
- if(nError == ERROR_SUCCESS && (ha->dwFlags & MPQ_FLAG_CHANGED))
- {
- SFileFlushArchive(hMpq);
- }
-
- // Create the table with file keys
- if(nError == ERROR_SUCCESS)
- {
- if((pFileKeys = STORM_ALLOC(DWORD, ha->dwFileTableSize)) != NULL)
- memset(pFileKeys, 0, sizeof(DWORD) * ha->dwFileTableSize);
- else
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // First of all, we have to check of we are able to decrypt all files.
- // If not, sorry, but the archive cannot be compacted.
- if(nError == ERROR_SUCCESS)
- {
- // Initialize the progress variables for compact callback
- FileStream_GetSize(ha->pStream, CompactTotalBytes);
- CompactBytesProcessed = 0;
- nError = CheckIfAllFilesKnown(ha, szListFile, pFileKeys);
- }
-
- // Get the temporary file name and create it
- if(nError == ERROR_SUCCESS)
- {
- _tcscpy(szTempFile, FileStream_GetFileName(ha->pStream));
- if((szTemp = _tcsrchr(szTempFile, '.')) != NULL)
- _tcscpy(szTemp + 1, _T("mp_"));
- else
- _tcscat(szTempFile, _T("_"));
-
- pTempStream = FileStream_CreateFile(szTempFile, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
- if(pTempStream == NULL)
- nError = GetLastError();
- }
-
- // Write the data before MPQ user data (if any)
- if(nError == ERROR_SUCCESS && ha->UserDataPos != 0)
- {
- // Inform the application about the progress
- if(CompactCB != NULL)
- CompactCB(pvUserData, CCB_COPYING_NON_MPQ_DATA, CompactBytesProcessed, CompactTotalBytes);
-
- ByteOffset = 0;
- ByteCount = ha->UserDataPos;
- nError = CopyNonMpqData(ha->pStream, pTempStream, ByteOffset, ByteCount);
- }
-
- // Write the MPQ user data (if any)
- if(nError == ERROR_SUCCESS && ha->MpqPos > ha->UserDataPos)
- {
- // At this point, we assume that the user data size is equal
- // to pUserData->dwHeaderOffs.
- // If this assumption doesn't work, then we have an unknown version of MPQ
- ByteOffset = ha->UserDataPos;
- ByteCount = ha->MpqPos - ha->UserDataPos;
-
- assert(ha->pUserData != NULL);
- assert(ha->pUserData->dwHeaderOffs == ByteCount);
- nError = CopyNonMpqData(ha->pStream, pTempStream, ByteOffset, ByteCount);
- }
-
- // Write the MPQ header
- if(nError == ERROR_SUCCESS)
- {
- // Remember the header size before swapping
- DWORD dwBytesToWrite = ha->pHeader->dwHeaderSize;
-
- BSWAP_TMPQHEADER(ha->pHeader);
- if(!FileStream_Write(pTempStream, NULL, ha->pHeader, dwBytesToWrite))
- nError = GetLastError();
- BSWAP_TMPQHEADER(ha->pHeader);
-
- // Update the progress
- CompactBytesProcessed += ha->pHeader->dwHeaderSize;
- }
-
- // Now copy all files
- if(nError == ERROR_SUCCESS)
- {
- nError = CopyMpqFiles(ha, pFileKeys, pTempStream);
- ha->dwFlags |= MPQ_FLAG_CHANGED;
- }
-
- // If succeeded, switch the streams
- if(nError == ERROR_SUCCESS)
- {
- if(FileStream_Switch(ha->pStream, pTempStream))
- pTempStream = NULL;
- else
- nError = ERROR_CAN_NOT_COMPLETE;
- }
-
- // If all succeeded, save the MPQ tables
- if(nError == ERROR_SUCCESS)
- {
- //
- // Note: We don't recalculate position of the MPQ tables at this point.
- // SaveMPQTables does it automatically.
- //
-
- nError = SaveMPQTables(ha);
- if(nError == ERROR_SUCCESS && CompactCB != NULL)
- {
- CompactBytesProcessed += (ha->pHeader->dwHashTableSize * sizeof(TMPQHash));
- CompactBytesProcessed += (ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock));
- CompactCB(pvUserData, CCB_CLOSING_ARCHIVE, CompactBytesProcessed, CompactTotalBytes);
- }
- }
-
- // Invalidate the compact callback
- pvUserData = NULL;
- CompactCB = NULL;
-
- // Cleanup and return
- if(pTempStream != NULL)
- FileStream_Close(pTempStream);
- if(pFileKeys != NULL)
- STORM_FREE(pFileKeys);
- if(nError != ERROR_SUCCESS)
- SetLastError(nError);
- return (nError == ERROR_SUCCESS);
-}
-
-//-----------------------------------------------------------------------------
-// Changing hash table size
-
-DWORD WINAPI SFileGetMaxFileCount(HANDLE hMpq)
-{
- TMPQArchive * ha = (TMPQArchive *)hMpq;
-
- return ha->dwMaxFileCount;
-}
-
-bool WINAPI SFileSetMaxFileCount(HANDLE hMpq, DWORD dwMaxFileCount)
-{
- TMPQHetTable * pOldHetTable = NULL;
- TMPQArchive * ha = (TMPQArchive *)hMpq;
- TFileEntry * pOldFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
- TFileEntry * pOldFileTable = NULL;
- TFileEntry * pOldFileEntry;
- TFileEntry * pFileEntry;
- TMPQHash * pOldHashTable = NULL;
- DWORD dwOldHashTableSize = 0;
- DWORD dwOldFileTableSize = 0;
- int nError = ERROR_SUCCESS;
-
- // Test the valid parameters
- if(!IsValidMpqHandle(ha))
- nError = ERROR_INVALID_HANDLE;
- if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
- nError = ERROR_ACCESS_DENIED;
-
- // The new limit must not be lower than the index of the last file entry in the table
- if(nError == ERROR_SUCCESS && ha->dwFileTableSize > dwMaxFileCount)
- nError = ERROR_DISK_FULL;
-
- // ALL file names must be known in order to be able
- // to rebuild hash table size
- if(nError == ERROR_SUCCESS)
- {
- nError = CheckIfAllFilesKnown(ha, NULL, NULL);
- }
-
- // If the MPQ has a hash table, then we relocate the hash table
- if(nError == ERROR_SUCCESS && ha->pHashTable != NULL)
- {
- // Save parameters for the current hash table
- dwOldHashTableSize = ha->pHeader->dwHashTableSize;
- pOldHashTable = ha->pHashTable;
-
- // Allocate new hash table
- ha->pHeader->dwHashTableSize = GetHashTableSizeForFileCount(dwMaxFileCount);
- ha->pHashTable = STORM_ALLOC(TMPQHash, ha->pHeader->dwHashTableSize);
- if(ha->pHashTable != NULL)
- memset(ha->pHashTable, 0xFF, ha->pHeader->dwHashTableSize * sizeof(TMPQHash));
- else
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // If the MPQ has HET table, allocate new one as well
- if(nError == ERROR_SUCCESS && ha->pHetTable != NULL)
- {
- // Save the original HET table
- pOldHetTable = ha->pHetTable;
-
- // Create new one
- ha->pHetTable = CreateHetTable(dwMaxFileCount, 0x40, true);
- if(ha->pHetTable == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Now reallocate the file table
- if(nError == ERROR_SUCCESS)
- {
- // Save the current file table
- dwOldFileTableSize = ha->dwFileTableSize;
- pOldFileTable = ha->pFileTable;
-
- // Create new one
- ha->pFileTable = STORM_ALLOC(TFileEntry, dwMaxFileCount);
- if(ha->pFileTable != NULL)
- memset(ha->pFileTable, 0, dwMaxFileCount * sizeof(TFileEntry));
- else
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Now we have to build both classic hash table and HET table.
- if(nError == ERROR_SUCCESS)
- {
- DWORD dwFileIndex = 0;
- DWORD dwHashIndex = 0;
-
- // Create new hash and HET entry for each file
- pFileEntry = ha->pFileTable;
- for(pOldFileEntry = pOldFileTable; pOldFileEntry < pOldFileTableEnd; pOldFileEntry++)
- {
- if(pOldFileEntry->dwFlags & MPQ_FILE_EXISTS)
- {
- // Copy the old file entry to the new one
- memcpy(pFileEntry, pOldFileEntry, sizeof(TFileEntry));
- assert(pFileEntry->szFileName != NULL);
-
- // Create new entry in the hash table
- if(ha->pHashTable != NULL)
- {
- dwHashIndex = AllocateHashEntry(ha, pFileEntry);
- if(dwHashIndex == HASH_ENTRY_FREE)
- {
- nError = ERROR_CAN_NOT_COMPLETE;
- break;
- }
- }
-
- // Create new entry in the HET table, if needed
- if(ha->pHetTable != NULL)
- {
- dwHashIndex = AllocateHetEntry(ha, pFileEntry);
- if(dwHashIndex == HASH_ENTRY_FREE)
- {
- nError = ERROR_CAN_NOT_COMPLETE;
- break;
- }
- }
-
- // Move to the next file entry in the new table
- pFileEntry++;
- dwFileIndex++;
- }
- }
- }
-
- // Mark the archive as changed
- // Note: We always have to rebuild the (attributes) file due to file table change
- if(nError == ERROR_SUCCESS)
- {
- ha->dwMaxFileCount = dwMaxFileCount;
- InvalidateInternalFiles(ha);
- }
- else
- {
- // Revert the hash table
- if(ha->pHashTable != NULL && pOldHashTable != NULL)
- {
- STORM_FREE(ha->pHashTable);
- ha->pHeader->dwHashTableSize = dwOldHashTableSize;
- ha->pHashTable = pOldHashTable;
- }
-
- // Revert the HET table
- if(ha->pHetTable != NULL && pOldHetTable != NULL)
- {
- FreeHetTable(ha->pHetTable);
- ha->pHetTable = pOldHetTable;
- }
-
- // Revert the file table
- if(pOldFileTable != NULL)
- {
- STORM_FREE(ha->pFileTable);
- ha->pFileTable = pOldFileTable;
- }
-
- SetLastError(nError);
- }
-
- // Return the result
- return (nError == ERROR_SUCCESS);
-}
diff --git a/dep/StormLib/src/SFileCreateArchive.cpp b/dep/StormLib/src/SFileCreateArchive.cpp
deleted file mode 100644
index 59f3d3fa9e8..00000000000
--- a/dep/StormLib/src/SFileCreateArchive.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-/*****************************************************************************/
-/* SFileCreateArchive.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* MPQ Editing functions */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 24.03.03 1.00 Lad Splitted from SFileOpenArchive.cpp */
-/* 08.06.10 1.00 Lad Renamed to SFileCreateArchive.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "StormCommon.h"
-
-//-----------------------------------------------------------------------------
-// Local variables
-
-static const DWORD MpqHeaderSizes[] =
-{
- MPQ_HEADER_SIZE_V1,
- MPQ_HEADER_SIZE_V2,
- MPQ_HEADER_SIZE_V3,
- MPQ_HEADER_SIZE_V4
-};
-
-//-----------------------------------------------------------------------------
-// Local functions
-
-static USHORT GetSectorSizeShift(DWORD dwSectorSize)
-{
- USHORT wSectorSizeShift = 0;
-
- while(dwSectorSize > 0x200)
- {
- dwSectorSize >>= 1;
- wSectorSizeShift++;
- }
-
- return wSectorSizeShift;
-}
-
-static int WriteNakedMPQHeader(TMPQArchive * ha)
-{
- TMPQHeader * pHeader = ha->pHeader;
- TMPQHeader Header;
- DWORD dwBytesToWrite = pHeader->dwHeaderSize;
- int nError = ERROR_SUCCESS;
-
- // Prepare the naked MPQ header
- memset(&Header, 0, sizeof(TMPQHeader));
- Header.dwID = pHeader->dwID;
- Header.dwHeaderSize = pHeader->dwHeaderSize;
- Header.dwArchiveSize = pHeader->dwHeaderSize;
- Header.wFormatVersion = pHeader->wFormatVersion;
- Header.wSectorSize = pHeader->wSectorSize;
-
- // Write it to the file
- BSWAP_TMPQHEADER(&Header);
- if(!FileStream_Write(ha->pStream, &ha->MpqPos, &Header, dwBytesToWrite))
- nError = GetLastError();
-
- return nError;
-}
-
-//-----------------------------------------------------------------------------
-// Creates a new MPQ archive.
-
-bool WINAPI SFileCreateArchive(const TCHAR * szMpqName, DWORD dwFlags, DWORD dwMaxFileCount, HANDLE * phMpq)
-{
- SFILE_CREATE_MPQ CreateInfo;
-
- // Fill the create structure
- memset(&CreateInfo, 0, sizeof(SFILE_CREATE_MPQ));
- CreateInfo.cbSize = sizeof(SFILE_CREATE_MPQ);
- CreateInfo.dwMpqVersion = (dwFlags & MPQ_CREATE_ARCHIVE_VMASK) >> FLAGS_TO_FORMAT_SHIFT;
- CreateInfo.dwStreamFlags = STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE;
- CreateInfo.dwAttrFlags = (dwFlags & MPQ_CREATE_ATTRIBUTES) ? MPQ_ATTRIBUTE_ALL : 0;
- CreateInfo.dwSectorSize = (CreateInfo.dwMpqVersion >= MPQ_FORMAT_VERSION_3) ? 0x4000 : 0x1000;
- CreateInfo.dwRawChunkSize = (CreateInfo.dwMpqVersion >= MPQ_FORMAT_VERSION_4) ? 0x4000 : 0;
- CreateInfo.dwMaxFileCount = dwMaxFileCount;
- return SFileCreateArchive2(szMpqName, &CreateInfo, phMpq);
-}
-
-bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCreateInfo, HANDLE * phMpq)
-{
- TFileStream * pStream = NULL; // File stream
- TMPQArchive * ha = NULL; // MPQ archive handle
- ULONGLONG MpqPos = 0; // Position of MPQ header in the file
- HANDLE hMpq = NULL;
- DWORD dwBlockTableSize = 0; // Initial block table size
- DWORD dwHashTableSize = 0;
- DWORD dwMaxFileCount;
- int nError = ERROR_SUCCESS;
-
- // Check the parameters, if they are valid
- if(szMpqName == NULL || *szMpqName == 0 || pCreateInfo == NULL || phMpq == NULL)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return false;
- }
-
- // Verify if all variables in SFILE_CREATE_MPQ are correct
- if((pCreateInfo->cbSize == 0 || pCreateInfo->cbSize > sizeof(SFILE_CREATE_MPQ)) ||
- (pCreateInfo->dwMpqVersion > MPQ_FORMAT_VERSION_4) ||
- (pCreateInfo->pvUserData != NULL || pCreateInfo->cbUserData != 0) ||
- (pCreateInfo->dwAttrFlags & ~MPQ_ATTRIBUTE_ALL) ||
- (pCreateInfo->dwSectorSize & (pCreateInfo->dwSectorSize - 1)) ||
- (pCreateInfo->dwRawChunkSize & (pCreateInfo->dwRawChunkSize - 1)) ||
- (pCreateInfo->dwMaxFileCount < 4))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return false;
- }
-
- // One time initialization of MPQ cryptography
- InitializeMpqCryptography();
-
- // We verify if the file already exists and if it's a MPQ archive.
- // If yes, we won't allow to overwrite it.
- if(SFileOpenArchive(szMpqName, 0, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE | MPQ_OPEN_NO_ATTRIBUTES | MPQ_OPEN_NO_LISTFILE, &hMpq))
- {
- SFileCloseArchive(hMpq);
- SetLastError(ERROR_ALREADY_EXISTS);
- return false;
- }
-
- //
- // At this point, we have to create the archive.
- // - If the file exists, convert it to MPQ archive.
- // - If the file doesn't exist, create new empty file
- //
-
- pStream = FileStream_OpenFile(szMpqName, pCreateInfo->dwStreamFlags);
- if(pStream == NULL)
- {
- pStream = FileStream_CreateFile(szMpqName, pCreateInfo->dwStreamFlags);
- if(pStream == NULL)
- return false;
- }
-
- // Increment the maximum amount of files to have space
- // for listfile and attributes file
- dwMaxFileCount = pCreateInfo->dwMaxFileCount;
- if(pCreateInfo->dwAttrFlags != 0)
- dwMaxFileCount++;
- dwMaxFileCount++;
-
- // If file count is not zero, initialize the hash table size
- dwHashTableSize = GetHashTableSizeForFileCount(dwMaxFileCount);
-
- // Retrieve the file size and round it up to 0x200 bytes
- FileStream_GetSize(pStream, MpqPos);
- MpqPos = (MpqPos + 0x1FF) & (ULONGLONG)0xFFFFFFFFFFFFFE00ULL;
- if(!FileStream_SetSize(pStream, MpqPos))
- nError = GetLastError();
-
-#ifdef _DEBUG
- // Debug code, used for testing StormLib
-// dwBlockTableSize = dwHashTableSize * 2;
-#endif
-
- // Create the archive handle
- if(nError == ERROR_SUCCESS)
- {
- if((ha = STORM_ALLOC(TMPQArchive, 1)) == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Fill the MPQ archive handle structure
- if(nError == ERROR_SUCCESS)
- {
- memset(ha, 0, sizeof(TMPQArchive));
- ha->pStream = pStream;
- ha->dwSectorSize = pCreateInfo->dwSectorSize;
- ha->UserDataPos = MpqPos;
- ha->MpqPos = MpqPos;
- ha->pHeader = (TMPQHeader *)ha->HeaderData;
- ha->dwMaxFileCount = dwMaxFileCount;
- ha->dwFileTableSize = 0;
- ha->dwFileFlags1 = pCreateInfo->dwFileFlags1;
- ha->dwFileFlags2 = pCreateInfo->dwFileFlags2;
- ha->dwFlags = 0;
-
- // Setup the attributes
- ha->dwAttrFlags = pCreateInfo->dwAttrFlags;
- pStream = NULL;
- }
-
- // Fill the MPQ header
- if(nError == ERROR_SUCCESS)
- {
- TMPQHeader * pHeader = ha->pHeader;
-
- // Fill the MPQ header
- memset(pHeader, 0, sizeof(ha->HeaderData));
- pHeader->dwID = ID_MPQ;
- pHeader->dwHeaderSize = MpqHeaderSizes[pCreateInfo->dwMpqVersion];
- pHeader->dwArchiveSize = pHeader->dwHeaderSize + dwHashTableSize * sizeof(TMPQHash);
- pHeader->wFormatVersion = (USHORT)pCreateInfo->dwMpqVersion;
- pHeader->wSectorSize = GetSectorSizeShift(ha->dwSectorSize);
- pHeader->dwHashTablePos = pHeader->dwHeaderSize;
- pHeader->dwHashTableSize = dwHashTableSize;
- pHeader->dwBlockTablePos = pHeader->dwHashTablePos + dwHashTableSize * sizeof(TMPQHash);
- pHeader->dwBlockTableSize = dwBlockTableSize;
-
- // For MPQs version 4 and higher, we set the size of raw data block
- // for calculating MD5
- if(pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_4)
- pHeader->dwRawChunkSize = pCreateInfo->dwRawChunkSize;
-
- // Write the naked MPQ header
- nError = WriteNakedMPQHeader(ha);
-
- // Remember that the (listfile) and (attributes) need to be saved
- ha->dwFlags |= MPQ_FLAG_CHANGED | MPQ_FLAG_INV_LISTFILE | MPQ_FLAG_INV_ATTRIBUTES;
- }
-
- // Create initial HET table, if the caller required an MPQ format 3.0 or newer
- if(nError == ERROR_SUCCESS && pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_3)
- {
- ha->pHetTable = CreateHetTable(ha->dwMaxFileCount, 0x40, true);
- if(ha->pHetTable == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Create initial hash table
- if(nError == ERROR_SUCCESS)
- {
- nError = CreateHashTable(ha, dwHashTableSize);
- }
-
- // Create initial file table
- if(nError == ERROR_SUCCESS)
- {
- ha->pFileTable = STORM_ALLOC(TFileEntry, ha->dwMaxFileCount);
- if(ha->pFileTable != NULL)
- memset(ha->pFileTable, 0x00, sizeof(TFileEntry) * ha->dwMaxFileCount);
- else
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Cleanup : If an error, delete all buffers and return
- if(nError != ERROR_SUCCESS)
- {
- FileStream_Close(pStream);
- FreeMPQArchive(ha);
- SetLastError(nError);
- ha = NULL;
- }
-
- // Return the values
- *phMpq = (HANDLE)ha;
- return (nError == ERROR_SUCCESS);
-}
diff --git a/dep/StormLib/src/SFileExtractFile.cpp b/dep/StormLib/src/SFileExtractFile.cpp
deleted file mode 100644
index c8053ed4e62..00000000000
--- a/dep/StormLib/src/SFileExtractFile.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/*****************************************************************************/
-/* SFileExtractFile.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Simple extracting utility */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 20.06.03 1.00 Lad The first version of SFileExtractFile.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "StormCommon.h"
-
-bool WINAPI SFileExtractFile(HANDLE hMpq, const char * szToExtract, const TCHAR * szExtracted, DWORD dwSearchScope)
-{
- TFileStream * pLocalFile = NULL;
- HANDLE hMpqFile = NULL;
- int nError = ERROR_SUCCESS;
-
- // Open the MPQ file
- if(nError == ERROR_SUCCESS)
- {
- if(!SFileOpenFileEx(hMpq, szToExtract, dwSearchScope, &hMpqFile))
- nError = GetLastError();
- }
-
- // Create the local file
- if(nError == ERROR_SUCCESS)
- {
- pLocalFile = FileStream_CreateFile(szExtracted, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
- if(pLocalFile == NULL)
- nError = GetLastError();
- }
-
- // Copy the file's content
- if(nError == ERROR_SUCCESS)
- {
- char szBuffer[0x1000];
- DWORD dwTransferred;
-
- for(;;)
- {
- // dwTransferred is only set to nonzero if something has been read.
- // nError can be ERROR_SUCCESS or ERROR_HANDLE_EOF
- if(!SFileReadFile(hMpqFile, szBuffer, sizeof(szBuffer), &dwTransferred, NULL))
- nError = GetLastError();
- if(nError == ERROR_HANDLE_EOF)
- nError = ERROR_SUCCESS;
- if(dwTransferred == 0)
- break;
-
- // If something has been actually read, write it
- if(!FileStream_Write(pLocalFile, NULL, szBuffer, dwTransferred))
- nError = GetLastError();
- }
- }
-
- // Close the files
- if(hMpqFile != NULL)
- SFileCloseFile(hMpqFile);
- if(pLocalFile != NULL)
- FileStream_Close(pLocalFile);
- if(nError != ERROR_SUCCESS)
- SetLastError(nError);
- return (nError == ERROR_SUCCESS);
-}
diff --git a/dep/StormLib/src/SFileFindFile.cpp b/dep/StormLib/src/SFileFindFile.cpp
deleted file mode 100644
index 337be7d2c54..00000000000
--- a/dep/StormLib/src/SFileFindFile.cpp
+++ /dev/null
@@ -1,446 +0,0 @@
-/*****************************************************************************/
-/* SFileFindFile.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* A module for file searching within MPQs */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 25.03.03 1.00 Lad The first version of SFileFindFile.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "StormCommon.h"
-
-//-----------------------------------------------------------------------------
-// Defines
-
-#define LISTFILE_CACHE_SIZE 0x1000
-
-//-----------------------------------------------------------------------------
-// Private structure used for file search (search handle)
-
-struct TMPQSearch;
-typedef int (*MPQSEARCH)(TMPQSearch *, SFILE_FIND_DATA *);
-
-// Used by searching in MPQ archives
-struct TMPQSearch
-{
- TMPQArchive * ha; // Handle to MPQ, where the search runs
- TFileEntry ** pSearchTable; // Table for files that have been already found
- DWORD dwSearchTableItems; // Number of items in the search table
- DWORD dwNextIndex; // Next file index to be checked
- DWORD dwFlagMask; // For checking flag mask
- char szSearchMask[1]; // Search mask (variable length)
-};
-
-//-----------------------------------------------------------------------------
-// Local functions
-
-static bool IsValidSearchHandle(TMPQSearch * hs)
-{
- if(hs == NULL)
- return false;
-
- return IsValidMpqHandle(hs->ha);
-}
-
-bool CheckWildCard(const char * szString, const char * szWildCard)
-{
- const char * szSubString;
- int nSubStringLength;
- int nMatchCount = 0;
-
- // When the mask is empty, it never matches
- if(szWildCard == NULL || *szWildCard == 0)
- return false;
-
- // If the wildcard contains just "*", then it always matches
- if(szWildCard[0] == '*' && szWildCard[1] == 0)
- return true;
-
- // Do normal test
- for(;;)
- {
- // If there is '?' in the wildcard, we skip one char
- while(*szWildCard == '?')
- {
- szWildCard++;
- szString++;
- }
-
- // If there is '*', means zero or more chars. We have to
- // find the sequence after '*'
- if(*szWildCard == '*')
- {
- // More stars is equal to one star
- while(*szWildCard == '*' || *szWildCard == '?')
- szWildCard++;
-
- // If we found end of the wildcard, it's a match
- if(*szWildCard == 0)
- return true;
-
- // Determine the length of the substring in szWildCard
- szSubString = szWildCard;
- while(*szSubString != 0 && *szSubString != '?' && *szSubString != '*')
- szSubString++;
- nSubStringLength = (int)(szSubString - szWildCard);
- nMatchCount = 0;
-
- // Now we have to find a substring in szString,
- // that matches the substring in szWildCard
- while(*szString != 0)
- {
- // Calculate match count
- while(nMatchCount < nSubStringLength)
- {
- if(toupper(szString[nMatchCount]) != toupper(szWildCard[nMatchCount]))
- break;
- if(szString[nMatchCount] == 0)
- break;
- nMatchCount++;
- }
-
- // If the match count has reached substring length, we found a match
- if(nMatchCount == nSubStringLength)
- {
- szWildCard += nMatchCount;
- szString += nMatchCount;
- break;
- }
-
- // No match, move to the next char in szString
- nMatchCount = 0;
- szString++;
- }
- }
- else
- {
- // If we came to the end of the string, compare it to the wildcard
- if(toupper(*szString) != toupper(*szWildCard))
- return false;
-
- // If we arrived to the end of the string, it's a match
- if(*szString == 0)
- return true;
-
- // Otherwise, continue in comparing
- szWildCard++;
- szString++;
- }
- }
-}
-
-static DWORD GetSearchTableItems(TMPQArchive * ha)
-{
- DWORD dwMergeItems = 0;
-
- // Loop over all patches
- while(ha != NULL)
- {
- // Append the number of files
- dwMergeItems += (ha->pHetTable != NULL) ? ha->pHetTable->dwMaxFileCount
- : ha->pHeader->dwBlockTableSize;
- // Move to the patched archive
- ha = ha->haPatch;
- }
-
- // Return the double size of number of items
- return (dwMergeItems | 1);
-}
-
-static bool FileWasFoundBefore(
- TMPQArchive * ha,
- TMPQSearch * hs,
- TFileEntry * pFileEntry)
-{
- TFileEntry * pEntry;
- char * szRealFileName = pFileEntry->szFileName;
- DWORD dwStartIndex;
- DWORD dwNameHash;
- DWORD dwIndex;
-
- if(hs->pSearchTable != NULL && szRealFileName != NULL)
- {
- // If we are in patch MPQ, we check if patch prefix matches
- // and then trim the patch prefix
- if(ha->cchPatchPrefix != 0)
- {
- // If the patch prefix doesn't fit, we pretend that the file
- // was there before and it will be skipped
- if(_strnicmp(szRealFileName, ha->szPatchPrefix, ha->cchPatchPrefix))
- return true;
-
- szRealFileName += ha->cchPatchPrefix;
- }
-
- // Calculate the hash to the table
- dwNameHash = HashString(szRealFileName, MPQ_HASH_NAME_A);
- dwStartIndex = dwIndex = (dwNameHash % hs->dwSearchTableItems);
-
- // The file might have been found before
- // only if this is not the first MPQ being searched
- if(ha->haBase != NULL)
- {
- // Enumerate all entries in the search table
- for(;;)
- {
- // Get the file entry at that position
- pEntry = hs->pSearchTable[dwIndex];
- if(pEntry == NULL)
- break;
-
- if(pEntry->szFileName != NULL)
- {
- // Does the name match?
- if(!_stricmp(pEntry->szFileName, szRealFileName))
- return true;
- }
-
- // Move to the next entry
- dwIndex = (dwIndex + 1) % hs->dwSearchTableItems;
- if(dwIndex == dwStartIndex)
- break;
- }
- }
-
- // Put the entry to the table for later use
- hs->pSearchTable[dwIndex] = pFileEntry;
- }
- return false;
-}
-
-static TFileEntry * FindPatchEntry(TMPQArchive * ha, TFileEntry * pFileEntry)
-{
- TFileEntry * pPatchEntry = NULL;
- TFileEntry * pTempEntry;
- char szFileName[MAX_PATH];
- LCID lcLocale = pFileEntry->lcLocale;
-
- // Go while there are patches
- while(ha->haPatch != NULL)
- {
- // Move to the patch archive
- ha = ha->haPatch;
-
- // Prepare the prefix for the file name
- strcpy(szFileName, ha->szPatchPrefix);
- strcat(szFileName, pFileEntry->szFileName);
-
- // Try to find the file there
- pTempEntry = GetFileEntryExact(ha, szFileName, lcLocale);
- if(pTempEntry != NULL)
- pPatchEntry = pTempEntry;
- }
-
- // Return the found patch entry
- return pPatchEntry;
-}
-
-// Performs one MPQ search
-static int DoMPQSearch(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData)
-{
- TMPQArchive * ha = hs->ha;
- TFileEntry * pFileTableEnd;
- TFileEntry * pPatchEntry;
- TFileEntry * pFileEntry;
- const char * szFileName;
- HANDLE hFile;
- char szPseudoName[20];
- DWORD dwBlockIndex;
- size_t nPrefixLength;
-
- // Start searching with base MPQ
- while(ha != NULL)
- {
- // Now parse the file entry table in order to get all files.
- pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
- pFileEntry = ha->pFileTable + hs->dwNextIndex;
-
- // Get the length of the patch prefix (0 if none)
- nPrefixLength = strlen(ha->szPatchPrefix);
-
- // Parse the file table
- while(pFileEntry < pFileTableEnd)
- {
- // Increment the next index for subsequent search
- hs->dwNextIndex++;
-
- // Is it a file and not a patch file?
- if((pFileEntry->dwFlags & hs->dwFlagMask) == MPQ_FILE_EXISTS)
- {
- // Now we have to check if this file was not enumerated before
- if(!FileWasFoundBefore(ha, hs, pFileEntry))
- {
- // Find a patch to this file
- pPatchEntry = FindPatchEntry(ha, pFileEntry);
- if(pPatchEntry == NULL)
- pPatchEntry = pFileEntry;
-
- // Prepare the block index
- dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable);
-
- // Get the file name. If it's not known, we will create pseudo-name
- szFileName = pFileEntry->szFileName;
- if(szFileName == NULL)
- {
- // Open the file by its pseudo-name.
- // This also generates the file name with a proper extension
- sprintf(szPseudoName, "File%08u.xxx", dwBlockIndex);
- if(SFileOpenFileEx((HANDLE)hs->ha, szPseudoName, SFILE_OPEN_FROM_MPQ, &hFile))
- {
- szFileName = (pFileEntry->szFileName != NULL) ? pFileEntry->szFileName : szPseudoName;
- SFileCloseFile(hFile);
- }
- }
-
- // Check the file name against the wildcard
- if(CheckWildCard(szFileName + nPrefixLength, hs->szSearchMask))
- {
- // Fill the found entry
- lpFindFileData->dwHashIndex = pPatchEntry->dwHashIndex;
- lpFindFileData->dwBlockIndex = dwBlockIndex;
- lpFindFileData->dwFileSize = pPatchEntry->dwFileSize;
- lpFindFileData->dwFileFlags = pPatchEntry->dwFlags;
- lpFindFileData->dwCompSize = pPatchEntry->dwCmpSize;
- lpFindFileData->lcLocale = pPatchEntry->lcLocale;
-
- // Fill the filetime
- lpFindFileData->dwFileTimeHi = (DWORD)(pPatchEntry->FileTime >> 32);
- lpFindFileData->dwFileTimeLo = (DWORD)(pPatchEntry->FileTime);
-
- // Fill the file name and plain file name
- strcpy(lpFindFileData->cFileName, szFileName + nPrefixLength);
- lpFindFileData->szPlainName = (char *)GetPlainFileNameA(lpFindFileData->cFileName);
- return ERROR_SUCCESS;
- }
-
- }
- }
-
- pFileEntry++;
- }
-
- // Move to the next patch in the patch chain
- hs->ha = ha = ha->haPatch;
- hs->dwNextIndex = 0;
- }
-
- // No more files found, return error
- return ERROR_NO_MORE_FILES;
-}
-
-static void FreeMPQSearch(TMPQSearch *& hs)
-{
- if(hs != NULL)
- {
- if(hs->pSearchTable != NULL)
- STORM_FREE(hs->pSearchTable);
- STORM_FREE(hs);
- hs = NULL;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Public functions
-
-HANDLE WINAPI SFileFindFirstFile(HANDLE hMpq, const char * szMask, SFILE_FIND_DATA * lpFindFileData, const char * szListFile)
-{
- TMPQArchive * ha = (TMPQArchive *)hMpq;
- TMPQSearch * hs = NULL;
- size_t nSize = 0;
- int nError = ERROR_SUCCESS;
-
- // Check for the valid parameters
- if(!IsValidMpqHandle(ha))
- nError = ERROR_INVALID_HANDLE;
- if(szMask == NULL || lpFindFileData == NULL)
- nError = ERROR_INVALID_PARAMETER;
-
- // Include the listfile into the MPQ's internal listfile
- // Note that if the listfile name is NULL, do nothing because the
- // internal listfile is always included.
- if(nError == ERROR_SUCCESS && szListFile != NULL && *szListFile != 0)
- nError = SFileAddListFile((HANDLE)ha, szListFile);
-
- // Allocate the structure for MPQ search
- if(nError == ERROR_SUCCESS)
- {
- nSize = sizeof(TMPQSearch) + strlen(szMask) + 1;
- if((hs = (TMPQSearch *)STORM_ALLOC(char, nSize)) == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Perform the first search
- if(nError == ERROR_SUCCESS)
- {
- memset(hs, 0, sizeof(TMPQSearch));
- strcpy(&hs->szSearchMask[0], szMask);
- hs->dwFlagMask = MPQ_FILE_EXISTS;
- hs->ha = ha;
-
- // If the archive is patched archive, we have to create a merge table
- // to prevent files being repeated
- if(ha->haPatch != NULL)
- {
- hs->dwSearchTableItems = GetSearchTableItems(ha);
- hs->pSearchTable = STORM_ALLOC(TFileEntry *, hs->dwSearchTableItems);
- hs->dwFlagMask = MPQ_FILE_EXISTS | MPQ_FILE_PATCH_FILE;
- if(hs->pSearchTable != NULL)
- memset(hs->pSearchTable, 0, hs->dwSearchTableItems * sizeof(TFileEntry *));
- else
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
- }
-
- // Perform first item searching
- if(nError == ERROR_SUCCESS)
- {
- nError = DoMPQSearch(hs, lpFindFileData);
- }
-
- // Cleanup
- if(nError != ERROR_SUCCESS)
- {
- FreeMPQSearch(hs);
- SetLastError(nError);
- }
-
- // Return the result value
- return (HANDLE)hs;
-}
-
-bool WINAPI SFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData)
-{
- TMPQSearch * hs = (TMPQSearch *)hFind;
- int nError = ERROR_SUCCESS;
-
- // Check the parameters
- if(!IsValidSearchHandle(hs))
- nError = ERROR_INVALID_HANDLE;
- if(lpFindFileData == NULL)
- nError = ERROR_INVALID_PARAMETER;
-
- if(nError == ERROR_SUCCESS)
- nError = DoMPQSearch(hs, lpFindFileData);
-
- if(nError != ERROR_SUCCESS)
- SetLastError(nError);
- return (nError == ERROR_SUCCESS);
-}
-
-bool WINAPI SFileFindClose(HANDLE hFind)
-{
- TMPQSearch * hs = (TMPQSearch *)hFind;
-
- // Check the parameters
- if(!IsValidSearchHandle(hs))
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return false;
- }
-
- FreeMPQSearch(hs);
- return true;
-}
diff --git a/dep/StormLib/src/SFileListFile.cpp b/dep/StormLib/src/SFileListFile.cpp
deleted file mode 100644
index 4604206ed0a..00000000000
--- a/dep/StormLib/src/SFileListFile.cpp
+++ /dev/null
@@ -1,557 +0,0 @@
-/*****************************************************************************/
-/* SListFile.cpp Copyright (c) Ladislav Zezula 2004 */
-/*---------------------------------------------------------------------------*/
-/* Description: */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 12.06.04 1.00 Lad The first version of SListFile.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "StormCommon.h"
-#include <assert.h>
-
-//-----------------------------------------------------------------------------
-// Listfile entry structure
-
-#define CACHE_BUFFER_SIZE 0x1000 // Size of the cache buffer
-
-struct TListFileCache
-{
- HANDLE hFile; // Stormlib file handle
- char * szMask; // File mask
- DWORD dwFileSize; // Total size of the cached file
- DWORD dwFilePos; // Position of the cache in the file
- BYTE * pBegin; // The begin of the listfile cache
- BYTE * pPos;
- BYTE * pEnd; // The last character in the file cache
-
- BYTE Buffer[CACHE_BUFFER_SIZE]; // Listfile cache itself
-};
-
-//-----------------------------------------------------------------------------
-// Local functions (cache)
-
-static TListFileCache * CreateListFileCache(HANDLE hMpq, const char * szListFile)
-{
- TListFileCache * pCache = NULL;
- HANDLE hListFile = NULL;
- DWORD dwSearchScope = SFILE_OPEN_LOCAL_FILE;
- DWORD dwBytesRead = 0;
- int nError = ERROR_SUCCESS;
-
- // If the szListFile is NULL, it means we have to open internal listfile
- if(szListFile == NULL)
- {
- // Use SFILE_OPEN_ANY_LOCALE for listfile. This will allow us to load
- // the listfile even if there is only non-neutral version of the listfile in the MPQ
- dwSearchScope = SFILE_OPEN_ANY_LOCALE;
- szListFile = LISTFILE_NAME;
- }
-
- // Open the local/internal listfile
- if(SFileOpenFileEx(hMpq, szListFile, dwSearchScope, &hListFile))
- {
- TMPQArchive * ha = (TMPQArchive *)hMpq;
- TMPQFile * hf = (TMPQFile *)hListFile;
-
- // Remember flags for (listfile)
- if(hf->pFileEntry != NULL)
- ha->dwFileFlags1 = hf->pFileEntry->dwFlags;
- }
- else
- nError = GetLastError();
-
- // Allocate cache for one file block
- if(nError == ERROR_SUCCESS)
- {
- pCache = (TListFileCache *)STORM_ALLOC(TListFileCache, 1);
- if(pCache == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- if(nError == ERROR_SUCCESS)
- {
- // Initialize the file cache
- memset(pCache, 0, sizeof(TListFileCache));
- pCache->dwFileSize = SFileGetFileSize(hListFile, NULL);
- pCache->hFile = hListFile;
-
- // Fill the cache
- SFileReadFile(hListFile, pCache->Buffer, CACHE_BUFFER_SIZE, &dwBytesRead, NULL);
- if(dwBytesRead == 0)
- nError = GetLastError();
- }
-
- // Initialize the pointers
- if(nError == ERROR_SUCCESS)
- {
- pCache->pBegin =
- pCache->pPos = &pCache->Buffer[0];
- pCache->pEnd = pCache->pBegin + dwBytesRead;
- }
- else
- {
- SListFileFindClose((HANDLE)pCache);
- SetLastError(nError);
- pCache = NULL;
- }
-
- // Return the cache
- return pCache;
-}
-
-// Reloads the cache. Returns number of characters
-// that has been loaded into the cache.
-static DWORD ReloadListFileCache(TListFileCache * pCache)
-{
- DWORD dwBytesToRead;
- DWORD dwBytesRead = 0;
-
- // Only do something if the cache is empty
- if(pCache->pPos >= pCache->pEnd)
- {
-// __TryReadBlock:
-
- // Move the file position forward
- pCache->dwFilePos += CACHE_BUFFER_SIZE;
- if(pCache->dwFilePos >= pCache->dwFileSize)
- return 0;
-
- // Get the number of bytes remaining
- dwBytesToRead = pCache->dwFileSize - pCache->dwFilePos;
- if(dwBytesToRead > CACHE_BUFFER_SIZE)
- dwBytesToRead = CACHE_BUFFER_SIZE;
-
- // Load the next data chunk to the cache
- SFileSetFilePointer(pCache->hFile, pCache->dwFilePos, NULL, FILE_BEGIN);
- SFileReadFile(pCache->hFile, pCache->Buffer, CACHE_BUFFER_SIZE, &dwBytesRead, NULL);
-
- // If we didn't read anything, it might mean that the block
- // of the file is not available (in case of partial MPQs).
- // We stop reading the file at this point, because the rest
- // of the listfile is unreliable
- if(dwBytesRead == 0)
- return 0;
-
- // Set the buffer pointers
- pCache->pBegin =
- pCache->pPos = &pCache->Buffer[0];
- pCache->pEnd = pCache->pBegin + dwBytesRead;
- }
-
- return dwBytesRead;
-}
-
-static size_t ReadListFileLine(TListFileCache * pCache, char * szLine, int nMaxChars)
-{
- char * szLineBegin = szLine;
- char * szLineEnd = szLine + nMaxChars - 1;
- char * szExtraString = NULL;
-
- // Skip newlines, spaces, tabs and another non-printable stuff
- for(;;)
- {
- // If we need to reload the cache, do it
- if(pCache->pPos == pCache->pEnd)
- {
- if(ReloadListFileCache(pCache) == 0)
- break;
- }
-
- // If we found a non-whitespace character, stop
- if(*pCache->pPos > 0x20)
- break;
-
- // Skip the character
- pCache->pPos++;
- }
-
- // Copy the remaining characters
- while(szLine < szLineEnd)
- {
- // If we need to reload the cache, do it now and resume copying
- if(pCache->pPos == pCache->pEnd)
- {
- if(ReloadListFileCache(pCache) == 0)
- break;
- }
-
- // If we have found a newline, stop loading
- if(*pCache->pPos == 0x0D || *pCache->pPos == 0x0A)
- break;
-
- // Blizzard listfiles can also contain information about patch:
- // Pass1\Files\MacOS\unconditional\user\Background Downloader.app\Contents\Info.plist~Patch(Data#frFR#base-frFR,1326)
- if(*pCache->pPos == '~')
- szExtraString = szLine;
-
- // Copy the character
- *szLine++ = *pCache->pPos++;
- }
-
- // Terminate line with zero
- *szLine = 0;
-
- // If there was extra string after the file name, clear it
- if(szExtraString != NULL)
- {
- if(szExtraString[0] == '~' && szExtraString[1] == 'P')
- {
- szLine = szExtraString;
- *szExtraString = 0;
- }
- }
-
- // Return the length of the line
- return (szLine - szLineBegin);
-}
-
-static int CompareFileNodes(const void * p1, const void * p2)
-{
- char * szFileName1 = *(char **)p1;
- char * szFileName2 = *(char **)p2;
-
- return _stricmp(szFileName1, szFileName2);
-}
-
-static int WriteListFileLine(
- TMPQFile * hf,
- const char * szLine)
-{
- char szNewLine[2] = {0x0D, 0x0A};
- size_t nLength = strlen(szLine);
- int nError;
-
- nError = SFileAddFile_Write(hf, szLine, (DWORD)nLength, MPQ_COMPRESSION_ZLIB);
- if(nError != ERROR_SUCCESS)
- return nError;
-
- return SFileAddFile_Write(hf, szNewLine, sizeof(szNewLine), MPQ_COMPRESSION_ZLIB);
-}
-
-//-----------------------------------------------------------------------------
-// Local functions (listfile nodes)
-
-// Adds a name into the list of all names. For each locale in the MPQ,
-// one entry will be created
-// If the file name is already there, does nothing.
-int SListFileCreateNodeForAllLocales(TMPQArchive * ha, const char * szFileName)
-{
- TMPQHeader * pHeader = ha->pHeader;
- TFileEntry * pFileEntry;
- TMPQHash * pFirstHash;
- TMPQHash * pHash;
- bool bNameEntryCreated = false;
-
- // If we have HET table, use that one
- if(ha->pHetTable != NULL)
- {
- pFileEntry = GetFileEntryAny(ha, szFileName);
- if(pFileEntry != NULL)
- {
- // Allocate file name for the file entry
- AllocateFileName(pFileEntry, szFileName);
- bNameEntryCreated = true;
- }
-
- return ERROR_SUCCESS;
- }
-
- // If we have hash table, we use it
- if(bNameEntryCreated == false && ha->pHashTable != NULL)
- {
- // Look for the first hash table entry for the file
- pFirstHash = pHash = GetFirstHashEntry(ha, szFileName);
-
- // Go while we found something
- while(pHash != NULL)
- {
- // Is it a valid file table index ?
- if(pHash->dwBlockIndex < pHeader->dwBlockTableSize)
- {
- // Allocate file name for the file entry
- AllocateFileName(ha->pFileTable + pHash->dwBlockIndex, szFileName);
- bNameEntryCreated = true;
- }
-
- // Now find the next language version of the file
- pHash = GetNextHashEntry(ha, pFirstHash, pHash);
- }
- }
-
- return ERROR_CAN_NOT_COMPLETE;
-}
-
-// Saves the whole listfile into the MPQ.
-int SListFileSaveToMpq(TMPQArchive * ha)
-{
- TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
- TFileEntry * pFileEntry;
- TMPQFile * hf = NULL;
- char * szPrevItem;
- char ** SortTable = NULL;
- DWORD dwFileSize = 0;
- size_t nFileNodes = 0;
- size_t i;
- int nError = ERROR_SUCCESS;
-
- // Allocate the table for sorting listfile
- SortTable = STORM_ALLOC(char*, ha->dwFileTableSize);
- if(SortTable == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Construct the sort table
- // Note: in MPQs with multiple locale versions of the same file,
- // this code causes adding multiple listfile entries.
- // Since those MPQs were last time used in Starcraft,
- // we leave it as it is.
- for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
- {
- // Only take existing items
- if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) && pFileEntry->szFileName != NULL)
- {
- // Ignore pseudo-names
- if(!IsPseudoFileName(pFileEntry->szFileName, NULL) && !IsInternalMpqFileName(pFileEntry->szFileName))
- {
- SortTable[nFileNodes++] = pFileEntry->szFileName;
- }
- }
- }
-
- // Sort the table
- qsort(SortTable, nFileNodes, sizeof(char *), CompareFileNodes);
-
- // Now parse the table of file names again - remove duplicates
- // and count file size.
- if(nFileNodes != 0)
- {
- // Count the 0-th item
- dwFileSize += (DWORD)strlen(SortTable[0]) + 2;
- szPrevItem = SortTable[0];
-
- // Count all next items
- for(i = 1; i < nFileNodes; i++)
- {
- // If the item is the same like the last one, skip it
- if(_stricmp(SortTable[i], szPrevItem))
- {
- dwFileSize += (DWORD)strlen(SortTable[i]) + 2;
- szPrevItem = SortTable[i];
- }
- }
-
- // Determine the flags for (listfile)
- if(ha->dwFileFlags1 == 0)
- ha->dwFileFlags1 = GetDefaultSpecialFileFlags(ha, dwFileSize);
-
- // Create the listfile in the MPQ
- nError = SFileAddFile_Init(ha, LISTFILE_NAME,
- 0,
- dwFileSize,
- LANG_NEUTRAL,
- ha->dwFileFlags1 | MPQ_FILE_REPLACEEXISTING,
- &hf);
- // Add all file names
- if(nError == ERROR_SUCCESS)
- {
- // Each name is followed by newline ("\x0D\x0A")
- szPrevItem = SortTable[0];
- nError = WriteListFileLine(hf, SortTable[0]);
-
- // Count all next items
- for(i = 1; i < nFileNodes; i++)
- {
- // If the item is the same like the last one, skip it
- if(_stricmp(SortTable[i], szPrevItem))
- {
- WriteListFileLine(hf, SortTable[i]);
- szPrevItem = SortTable[i];
- }
- }
- }
- }
- else
- {
- // Create the listfile in the MPQ
- dwFileSize = (DWORD)strlen(LISTFILE_NAME) + 2;
- nError = SFileAddFile_Init(ha, LISTFILE_NAME,
- 0,
- dwFileSize,
- LANG_NEUTRAL,
- MPQ_FILE_ENCRYPTED | MPQ_FILE_COMPRESS | MPQ_FILE_REPLACEEXISTING,
- &hf);
-
- // Just add "(listfile)" there
- if(nError == ERROR_SUCCESS)
- {
- WriteListFileLine(hf, LISTFILE_NAME);
- }
- }
-
- // Finalize the file in the MPQ
- if(hf != NULL)
- {
- SFileAddFile_Finish(hf);
- }
-
- // Free buffers
- if(nError == ERROR_SUCCESS)
- ha->dwFlags &= ~MPQ_FLAG_INV_LISTFILE;
- if(SortTable != NULL)
- STORM_FREE(SortTable);
- return nError;
-}
-
-//-----------------------------------------------------------------------------
-// File functions
-
-// Adds a listfile into the MPQ archive.
-// Note that the function does not remove the
-int WINAPI SFileAddListFile(HANDLE hMpq, const char * szListFile)
-{
- TListFileCache * pCache = NULL;
- TMPQArchive * ha = (TMPQArchive *)hMpq;
- char szFileName[MAX_PATH];
- size_t nLength = 0;
- int nError = ERROR_SUCCESS;
-
- // Add the listfile for each MPQ in the patch chain
- while(ha != NULL)
- {
- // Load the listfile to cache
- pCache = CreateListFileCache(hMpq, szListFile);
- if(pCache == NULL)
- {
- nError = GetLastError();
- break;
- }
-
- // Load the node list. Add the node for every locale in the archive
- while((nLength = ReadListFileLine(pCache, szFileName, sizeof(szFileName))) > 0)
- SListFileCreateNodeForAllLocales(ha, szFileName);
-
- // Also, add three special files to the listfile:
- // (listfile) itself, (attributes) and (signature)
- SListFileCreateNodeForAllLocales(ha, LISTFILE_NAME);
- SListFileCreateNodeForAllLocales(ha, SIGNATURE_NAME);
- SListFileCreateNodeForAllLocales(ha, ATTRIBUTES_NAME);
-
- // Delete the cache
- SListFileFindClose((HANDLE)pCache);
-
- // Move to the next archive in the chain
- ha = ha->haPatch;
- }
-
- return nError;
-}
-
-//-----------------------------------------------------------------------------
-// Passing through the listfile
-
-HANDLE WINAPI SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData)
-{
- TListFileCache * pCache = NULL;
- size_t nLength = 0;
- int nError = ERROR_SUCCESS;
-
- // Initialize the structure with zeros
- memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA));
-
- // Load the listfile to cache
- pCache = CreateListFileCache(hMpq, szListFile);
- if(pCache == NULL)
- nError = GetLastError();
-
- // Allocate file mask
- if(nError == ERROR_SUCCESS && szMask != NULL)
- {
- pCache->szMask = STORM_ALLOC(char, strlen(szMask) + 1);
- if(pCache->szMask != NULL)
- strcpy(pCache->szMask, szMask);
- else
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Perform file search
- if(nError == ERROR_SUCCESS)
- {
- for(;;)
- {
- // Read the (next) line
- nLength = ReadListFileLine(pCache, lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName));
- if(nLength == 0)
- {
- nError = ERROR_NO_MORE_FILES;
- break;
- }
-
- // If some mask entered, check it
- if(CheckWildCard(lpFindFileData->cFileName, pCache->szMask))
- break;
- }
- }
-
- // Cleanup & exit
- if(nError != ERROR_SUCCESS)
- {
- memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA));
- SListFileFindClose((HANDLE)pCache);
- pCache = NULL;
-
- SetLastError(nError);
- }
- return (HANDLE)pCache;
-}
-
-bool WINAPI SListFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData)
-{
- TListFileCache * pCache = (TListFileCache *)hFind;
- size_t nLength;
- bool bResult = false;
- int nError = ERROR_SUCCESS;
-
- for(;;)
- {
- // Read the (next) line
- nLength = ReadListFileLine(pCache, lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName));
- if(nLength == 0)
- {
- nError = ERROR_NO_MORE_FILES;
- break;
- }
-
- // If some mask entered, check it
- if(CheckWildCard(lpFindFileData->cFileName, pCache->szMask))
- {
- bResult = true;
- break;
- }
- }
-
- if(nError != ERROR_SUCCESS)
- SetLastError(nError);
- return bResult;
-}
-
-bool WINAPI SListFileFindClose(HANDLE hFind)
-{
- TListFileCache * pCache = (TListFileCache *)hFind;
-
- if(pCache != NULL)
- {
- if(pCache->hFile != NULL)
- SFileCloseFile(pCache->hFile);
- if(pCache->szMask != NULL)
- STORM_FREE(pCache->szMask);
-
- STORM_FREE(pCache);
- return true;
- }
-
- return false;
-}
-
diff --git a/dep/StormLib/src/SFileOpenArchive.cpp b/dep/StormLib/src/SFileOpenArchive.cpp
deleted file mode 100644
index b36b7d35ea7..00000000000
--- a/dep/StormLib/src/SFileOpenArchive.cpp
+++ /dev/null
@@ -1,470 +0,0 @@
-/*****************************************************************************/
-/* SFileOpenArchive.cpp Copyright Ladislav Zezula 1999 */
-/* */
-/* Author : Ladislav Zezula */
-/* E-mail : ladik@zezula.net */
-/* WWW : www.zezula.net */
-/*---------------------------------------------------------------------------*/
-/* Archive functions of Storm.dll */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* xx.xx.xx 1.00 Lad The first version of SFileOpenArchive.cpp */
-/* 19.11.03 1.01 Dan Big endian handling */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "StormCommon.h"
-
-/*****************************************************************************/
-/* Local functions */
-/*****************************************************************************/
-
-static bool IsAviFile(void * pvFileBegin)
-{
- LPDWORD AviHeader = (DWORD *)pvFileBegin;
- DWORD DwordValue0 = BSWAP_INT32_UNSIGNED(AviHeader[0]);
- DWORD DwordValue2 = BSWAP_INT32_UNSIGNED(AviHeader[2]);
- DWORD DwordValue3 = BSWAP_INT32_UNSIGNED(AviHeader[3]);
-
- // Test for 'RIFF', 'AVI ' or 'LIST'
- return (DwordValue0 == 0x46464952 && DwordValue2 == 0x20495641 && DwordValue3 == 0x5453494C);
-}
-
-static TFileBitmap * CreateFileBitmap(TMPQArchive * ha, TMPQBitmap * pMpqBitmap, bool bFileIsComplete)
-{
- TFileBitmap * pBitmap;
- size_t nLength;
-
- // Calculate the length of the bitmap in blocks and in bytes
- nLength = (size_t)(((ha->pHeader->ArchiveSize64 - 1) / pMpqBitmap->dwBlockSize) + 1);
- nLength = (size_t)(((nLength - 1) / 8) + 1);
-
- // Allocate the file bitmap
- pBitmap = (TFileBitmap *)STORM_ALLOC(BYTE, sizeof(TFileBitmap) + nLength);
- if(pBitmap != NULL)
- {
- // Fill the structure
- pBitmap->StartOffset = ha->MpqPos;
- pBitmap->EndOffset = ha->MpqPos + ha->pHeader->ArchiveSize64;
- pBitmap->IsComplete = bFileIsComplete ? 1 : 0;
- pBitmap->BitmapSize = (DWORD)nLength;
- pBitmap->BlockSize = pMpqBitmap->dwBlockSize;
- pBitmap->Reserved = 0;
-
- // Copy the file bitmap
- memcpy((pBitmap + 1), (pMpqBitmap + 1), nLength);
- }
-
- return pBitmap;
-}
-
-// This function gets the right positions of the hash table and the block table.
-static int VerifyMpqTablePositions(TMPQArchive * ha, ULONGLONG FileSize)
-{
- TMPQHeader * pHeader = ha->pHeader;
- ULONGLONG ByteOffset;
-
- // Check the begin of HET table
- if(pHeader->HetTablePos64)
- {
- ByteOffset = ha->MpqPos + pHeader->HetTablePos64;
- if(ByteOffset > FileSize)
- return ERROR_BAD_FORMAT;
- }
-
- // Check the begin of BET table
- if(pHeader->BetTablePos64)
- {
- ByteOffset = ha->MpqPos + pHeader->BetTablePos64;
- if(ByteOffset > FileSize)
- return ERROR_BAD_FORMAT;
- }
-
- // Check the begin of hash table
- if(pHeader->wHashTablePosHi || pHeader->dwHashTablePos)
- {
- ByteOffset = ha->MpqPos + MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos);
- if(ByteOffset > FileSize)
- return ERROR_BAD_FORMAT;
- }
-
- // Check the begin of block table
- if(pHeader->wBlockTablePosHi || pHeader->dwBlockTablePos)
- {
- ByteOffset = ha->MpqPos + MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
- if(ByteOffset > FileSize)
- return ERROR_BAD_FORMAT;
- }
-
- // Check the begin of hi-block table
- if(pHeader->HiBlockTablePos64 != 0)
- {
- ByteOffset = ha->MpqPos + pHeader->HiBlockTablePos64;
- if(ByteOffset > FileSize)
- return ERROR_BAD_FORMAT;
- }
-
- // All OK.
- return ERROR_SUCCESS;
-}
-
-
-/*****************************************************************************/
-/* Public functions */
-/*****************************************************************************/
-
-//-----------------------------------------------------------------------------
-// SFileGetLocale and SFileSetLocale
-// Set the locale for all newly opened files
-
-LCID WINAPI SFileGetLocale()
-{
- return lcFileLocale;
-}
-
-LCID WINAPI SFileSetLocale(LCID lcNewLocale)
-{
- lcFileLocale = lcNewLocale;
- return lcFileLocale;
-}
-
-//-----------------------------------------------------------------------------
-// SFileOpenArchive
-//
-// szFileName - MPQ archive file name to open
-// dwPriority - When SFileOpenFileEx called, this contains the search priority for searched archives
-// dwFlags - See MPQ_OPEN_XXX in StormLib.h
-// phMpq - Pointer to store open archive handle
-
-bool WINAPI SFileOpenArchive(
- const TCHAR * szMpqName,
- DWORD dwPriority,
- DWORD dwFlags,
- HANDLE * phMpq)
-{
- TFileStream * pStream = NULL; // Open file stream
- TMPQArchive * ha = NULL; // Archive handle
- ULONGLONG FileSize = 0; // Size of the file
- int nError = ERROR_SUCCESS;
-
- // Verify the parameters
- if(szMpqName == NULL || *szMpqName == 0 || phMpq == NULL)
- nError = ERROR_INVALID_PARAMETER;
-
- // One time initialization of MPQ cryptography
- InitializeMpqCryptography();
- dwPriority = dwPriority;
-
- // Open the MPQ archive file
- if(nError == ERROR_SUCCESS)
- {
- // Initialize the stream
- pStream = FileStream_OpenFile(szMpqName, (dwFlags & STREAM_OPTIONS_MASK));
- if(pStream == NULL)
- nError = GetLastError();
- }
-
- // Allocate the MPQhandle
- if(nError == ERROR_SUCCESS)
- {
- FileStream_GetSize(pStream, FileSize);
- if((ha = STORM_ALLOC(TMPQArchive, 1)) == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Initialize handle structure and allocate structure for MPQ header
- if(nError == ERROR_SUCCESS)
- {
- memset(ha, 0, sizeof(TMPQArchive));
- ha->pStream = pStream;
- pStream = NULL;
-
- // Remember if the archive is open for write
- if(FileStream_IsReadOnly(ha->pStream))
- ha->dwFlags |= MPQ_FLAG_READ_ONLY;
-
- // Also remember if we shall check sector CRCs when reading file
- if(dwFlags & MPQ_OPEN_CHECK_SECTOR_CRC)
- ha->dwFlags |= MPQ_FLAG_CHECK_SECTOR_CRC;
- }
-
- // Find the offset of MPQ header within the file
- if(nError == ERROR_SUCCESS)
- {
- ULONGLONG SearchPos = 0;
- DWORD dwHeaderID;
-
- while(SearchPos < FileSize)
- {
- DWORD dwBytesAvailable = MPQ_HEADER_SIZE_V4;
-
- // Cut the bytes available, if needed
- if((FileSize - SearchPos) < MPQ_HEADER_SIZE_V4)
- dwBytesAvailable = (DWORD)(FileSize - SearchPos);
-
- // Read the eventual MPQ header
- if(!FileStream_Read(ha->pStream, &SearchPos, ha->HeaderData, dwBytesAvailable))
- {
- nError = GetLastError();
- break;
- }
-
- // There are AVI files from Warcraft III with 'MPQ' extension.
- if(SearchPos == 0 && IsAviFile(ha->HeaderData))
- {
- nError = ERROR_AVI_FILE;
- break;
- }
-
- // If there is the MPQ user data signature, process it
- dwHeaderID = BSWAP_INT32_UNSIGNED(*(LPDWORD)ha->HeaderData);
- if(dwHeaderID == ID_MPQ_USERDATA && ha->pUserData == NULL)
- {
- // Ignore the MPQ user data completely if the caller wants to open the MPQ as V1.0
- if((dwFlags & MPQ_OPEN_FORCE_MPQ_V1) == 0)
- {
- // Fill the user data header
- ha->pUserData = &ha->UserData;
- memcpy(ha->pUserData, ha->HeaderData, sizeof(TMPQUserData));
- BSWAP_TMPQUSERDATA(ha->pUserData);
-
- // Remember the position of the user data and continue search
- ha->UserDataPos = SearchPos;
- SearchPos += ha->pUserData->dwHeaderOffs;
- continue;
- }
- }
-
- // There must be MPQ header signature
- if(dwHeaderID == ID_MPQ)
- {
- // Save the position where the MPQ header has been found
- if(ha->pUserData == NULL)
- ha->UserDataPos = SearchPos;
- ha->pHeader = (TMPQHeader *)ha->HeaderData;
- ha->MpqPos = SearchPos;
-
- // Now convert the header to version 4
- BSWAP_TMPQHEADER(ha->pHeader);
- nError = ConvertMpqHeaderToFormat4(ha, FileSize, dwFlags);
- break;
- }
-
- // Move to the next possible offset
- SearchPos += 0x200;
- }
-
- // If we haven't found MPQ header in the file, it's an error
- if(ha->pHeader == NULL)
- nError = ERROR_BAD_FORMAT;
- }
-
- // Fix table positions according to format
- if(nError == ERROR_SUCCESS)
- {
- // Dump the header
-// DumpMpqHeader(ha->pHeader);
-
- // W3x Map Protectors use the fact that War3's Storm.dll ignores the MPQ user data,
- // and probably ignores the MPQ format version as well. The trick is to
- // fake MPQ format 2, with an improper hi-word position of hash table and block table
- // We can overcome such protectors by forcing opening the archive as MPQ v 1.0
- if(dwFlags & MPQ_OPEN_FORCE_MPQ_V1)
- {
- ha->pHeader->wFormatVersion = MPQ_FORMAT_VERSION_1;
- ha->pHeader->dwHeaderSize = MPQ_HEADER_SIZE_V1;
- ha->dwFlags |= MPQ_FLAG_READ_ONLY;
- ha->pUserData = NULL;
- }
-
- // Both MPQ_OPEN_NO_LISTFILE or MPQ_OPEN_NO_ATTRIBUTES trigger read only mode
- if(dwFlags & (MPQ_OPEN_NO_LISTFILE | MPQ_OPEN_NO_ATTRIBUTES))
- ha->dwFlags |= MPQ_FLAG_READ_ONLY;
-
- // Set the size of file sector
- ha->dwSectorSize = (0x200 << ha->pHeader->wSectorSize);
-
- // Verify if any of the tables doesn't start beyond the end of the file
- nError = VerifyMpqTablePositions(ha, FileSize);
- }
-
- // Check if the MPQ has data bitmap. If yes, we can verify if the MPQ is complete
- if(nError == ERROR_SUCCESS && ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_4)
- {
- TFileBitmap * pBitmap;
- bool bFileIsComplete = true;
-
- LoadMpqDataBitmap(ha, FileSize, &bFileIsComplete);
- if(ha->pBitmap != NULL && bFileIsComplete == false)
- {
- // Convert the MPQ bitmap to the file bitmap
- pBitmap = CreateFileBitmap(ha, ha->pBitmap, bFileIsComplete);
-
- // Set the data bitmap into the file stream for additional checks
- FileStream_SetBitmap(ha->pStream, pBitmap);
- ha->dwFlags |= MPQ_FLAG_READ_ONLY;
- }
- }
-
- // Read the hash table. Ignore the result, as hash table is no longer required
- // Read HET table. Ignore the result, as HET table is no longer required
- if(nError == ERROR_SUCCESS)
- {
- nError = LoadAnyHashTable(ha);
- }
-
- // Now, build the file table. It will be built by combining
- // the block table, BET table, hi-block table, (attributes) and (listfile).
- if(nError == ERROR_SUCCESS)
- {
- nError = BuildFileTable(ha, FileSize);
- }
-
- // Verify the file table, if no kind of protection was detected
- if(nError == ERROR_SUCCESS && (ha->dwFlags & MPQ_FLAG_PROTECTED) == 0)
- {
- TFileEntry * pFileTableEnd = ha->pFileTable + ha->pHeader->dwBlockTableSize;
- TFileEntry * pFileEntry = ha->pFileTable;
-// ULONGLONG ArchiveSize = 0;
- ULONGLONG RawFilePos;
-
- // Parse all file entries
- for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
- {
- // If that file entry is valid, check the file position
- if(pFileEntry->dwFlags & MPQ_FILE_EXISTS)
- {
- // Get the 64-bit file position,
- // relative to the begin of the file
- RawFilePos = ha->MpqPos + pFileEntry->ByteOffset;
-
- // Begin of the file must be within range
- if(RawFilePos > FileSize)
- {
- nError = ERROR_FILE_CORRUPT;
- break;
- }
-
- // End of the file must be within range
- RawFilePos += pFileEntry->dwCmpSize;
- if(RawFilePos > FileSize)
- {
- nError = ERROR_FILE_CORRUPT;
- break;
- }
-
- // Also, we remember end of the file
-// if(RawFilePos > ArchiveSize)
-// ArchiveSize = RawFilePos;
- }
- }
- }
-
- // Load the internal listfile and include it to the file table
- if(nError == ERROR_SUCCESS && (dwFlags & MPQ_OPEN_NO_LISTFILE) == 0)
- {
- // Ignore result of the operation. (listfile) is optional.
- SFileAddListFile((HANDLE)ha, NULL);
- }
-
- // Load the "(attributes)" file and merge it to the file table
- if(nError == ERROR_SUCCESS && (dwFlags & MPQ_OPEN_NO_ATTRIBUTES) == 0)
- {
- // Ignore result of the operation. (attributes) is optional.
- SAttrLoadAttributes(ha);
- }
-
- // Cleanup and exit
- if(nError != ERROR_SUCCESS)
- {
- FileStream_Close(pStream);
- FreeMPQArchive(ha);
- SetLastError(nError);
- ha = NULL;
- }
-
- *phMpq = ha;
- return (nError == ERROR_SUCCESS);
-}
-
-//-----------------------------------------------------------------------------
-// SFileGetArchiveBitmap
-
-bool WINAPI SFileGetArchiveBitmap(HANDLE hMpq, TFileBitmap * pBitmap, DWORD Length, LPDWORD LengthNeeded)
-{
- TMPQArchive * ha = (TMPQArchive *)hMpq;
-
- return FileStream_GetBitmap(ha->pStream, pBitmap, Length, LengthNeeded);
-}
-
-//-----------------------------------------------------------------------------
-// bool SFileFlushArchive(HANDLE hMpq)
-//
-// Saves all dirty data into MPQ archive.
-// Has similar effect like SFileCloseArchive, but the archive is not closed.
-// Use on clients who keep MPQ archive open even for write operations,
-// and terminating without calling SFileCloseArchive might corrupt the archive.
-//
-
-bool WINAPI SFileFlushArchive(HANDLE hMpq)
-{
- TMPQArchive * ha = (TMPQArchive *)hMpq;
- int nResultError = ERROR_SUCCESS;
- int nError;
-
- // Do nothing if 'hMpq' is bad parameter
- if(!IsValidMpqHandle(ha))
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return false;
- }
-
- // If the (listfile) has been invalidated, save it
- if(ha->dwFlags & MPQ_FLAG_INV_LISTFILE)
- {
- nError = SListFileSaveToMpq(ha);
- if(nError != ERROR_SUCCESS)
- nResultError = nError;
- }
-
- // If the (attributes) has been invalidated, save it
- if(ha->dwFlags & MPQ_FLAG_INV_ATTRIBUTES)
- {
- nError = SAttrFileSaveToMpq(ha);
- if(nError != ERROR_SUCCESS)
- nResultError = nError;
- }
-
- // Save HET table, BET table, hash table, block table, hi-block table
- if(ha->dwFlags & MPQ_FLAG_CHANGED)
- {
- nError = SaveMPQTables(ha);
- if(nError != ERROR_SUCCESS)
- nResultError = nError;
- }
-
- // Return the error
- if(nResultError != ERROR_SUCCESS)
- SetLastError(nResultError);
- return (nResultError == ERROR_SUCCESS);
-}
-
-//-----------------------------------------------------------------------------
-// bool SFileCloseArchive(HANDLE hMpq);
-//
-
-bool WINAPI SFileCloseArchive(HANDLE hMpq)
-{
- TMPQArchive * ha = (TMPQArchive *)hMpq;
- bool bResult;
-
- // Flush all unsaved data to the storage
- bResult = SFileFlushArchive(hMpq);
-
- // Free all memory used by MPQ archive
- FreeMPQArchive(ha);
- return bResult;
-}
-
diff --git a/dep/StormLib/src/SFileOpenFileEx.cpp b/dep/StormLib/src/SFileOpenFileEx.cpp
deleted file mode 100644
index e03a8b17998..00000000000
--- a/dep/StormLib/src/SFileOpenFileEx.cpp
+++ /dev/null
@@ -1,469 +0,0 @@
-/*****************************************************************************/
-/* SFileOpenFileEx.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Description : */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* xx.xx.99 1.00 Lad The first version of SFileOpenFileEx.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "StormCommon.h"
-
-/*****************************************************************************/
-/* Local functions */
-/*****************************************************************************/
-
-static bool OpenLocalFile(const char * szFileName, HANDLE * phFile)
-{
- TFileStream * pStream;
- TMPQFile * hf = NULL;
-
- // We have to convert the local file name to UNICODE, if needed
-#ifdef _UNICODE
- TCHAR szFileNameT[MAX_PATH];
- int i;
-
- for(i = 0; szFileName[i] != 0; i++)
- szFileNameT[i] = szFileName[i];
- szFileNameT[i] = 0;
- pStream = FileStream_OpenFile(szFileNameT, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
-
-#else
- pStream = FileStream_OpenFile(szFileName, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
-#endif
-
- if(pStream != NULL)
- {
- // Allocate and initialize file handle
- hf = CreateMpqFile(NULL);
- if(hf != NULL)
- {
- hf->pStream = pStream;
- *phFile = hf;
- return true;
- }
- else
- {
- FileStream_Close(pStream);
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- }
- }
- *phFile = NULL;
- return false;
-}
-
-bool OpenPatchedFile(HANDLE hMpq, const char * szFileName, DWORD dwReserved, HANDLE * phFile)
-{
- TMPQArchive * ha = (TMPQArchive *)hMpq;
- TMPQFile * hfPatch; // Pointer to patch file
- TMPQFile * hfBase = NULL; // Pointer to base open file
- TMPQFile * hfLast = NULL; // The highest file in the chain that is not patch file
- TMPQFile * hf = NULL;
- HANDLE hPatchFile;
- char szPatchFileName[MAX_PATH];
-
- // Keep this flag here for future updates
- dwReserved = dwReserved;
-
- // First of all, try to open the original version of the file in any of the patch chain
- while(ha != NULL)
- {
- // Construct the name of the patch file
- strcpy(szPatchFileName, ha->szPatchPrefix);
- strcpy(&szPatchFileName[ha->cchPatchPrefix], szFileName);
- if(SFileOpenFileEx((HANDLE)ha, szPatchFileName, SFILE_OPEN_FROM_MPQ, (HANDLE *)&hfBase))
- {
- // The file must be a base file, i.e. without MPQ_FILE_PATCH_FILE
- if((hfBase->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0)
- {
- hf = hfLast = hfBase;
- break;
- }
-
- SFileCloseFile((HANDLE)hfBase);
- }
-
- // Move to the next file in the patch chain
- ha = ha->haPatch;
- }
-
- // If we couldn't find the file in any of the patches, it doesn't exist
- if(hf == NULL)
- {
- SetLastError(ERROR_FILE_NOT_FOUND);
- return false;
- }
-
- // Now keep going in the patch chain and open every patch file that is there
- for(ha = ha->haPatch; ha != NULL; ha = ha->haPatch)
- {
- // Construct patch file name
- strcpy(szPatchFileName, ha->szPatchPrefix);
- strcpy(&szPatchFileName[ha->cchPatchPrefix], szFileName);
- if(SFileOpenFileEx((HANDLE)ha, szPatchFileName, SFILE_OPEN_FROM_MPQ, &hPatchFile))
- {
- // Remember the new version
- hfPatch = (TMPQFile *)hPatchFile;
-
- // If we encountered a full replacement of the file,
- // we have to remember the highest full file
- if((hfPatch->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0)
- hfLast = hfPatch;
-
- // Set current patch to base file and move on
- hf->hfPatchFile = hfPatch;
- hf = hfPatch;
- }
- }
-
- // Now we need to free all files that are below the highest unpatched version
- while(hfBase != hfLast)
- {
- TMPQFile * hfNext = hfBase->hfPatchFile;
-
- // Free the file below
- hfBase->hfPatchFile = NULL;
- FreeMPQFile(hfBase);
-
- // Move the base to the next file
- hfBase = hfNext;
- }
-
- // Give the updated base MPQ
- if(phFile != NULL)
- *phFile = (HANDLE)hfBase;
- return true;
-}
-
-/*****************************************************************************/
-/* Public functions */
-/*****************************************************************************/
-
-//-----------------------------------------------------------------------------
-// SFileEnumLocales enums all locale versions within MPQ.
-// Functions fills all available language identifiers on a file into the buffer
-// pointed by plcLocales. There must be enough entries to copy the localed,
-// otherwise the function returns ERROR_INSUFFICIENT_BUFFER.
-
-int WINAPI SFileEnumLocales(
- HANDLE hMpq,
- const char * szFileName,
- LCID * plcLocales,
- LPDWORD pdwMaxLocales,
- DWORD dwSearchScope)
-{
- TMPQArchive * ha = (TMPQArchive *)hMpq;
- TFileEntry * pFileEntry;
- TMPQHash * pFirstHash;
- TMPQHash * pHash;
- DWORD dwFileIndex = 0;
- DWORD dwLocales = 0;
-
- // Test the parameters
- if(!IsValidMpqHandle(ha))
- return ERROR_INVALID_HANDLE;
- if(szFileName == NULL || *szFileName == 0)
- return ERROR_INVALID_PARAMETER;
- if(pdwMaxLocales == NULL)
- return ERROR_INVALID_PARAMETER;
-
- // Keep compiler happy
- dwSearchScope = dwSearchScope;
-
- // Parse hash table entries for all locales
- if(!IsPseudoFileName(szFileName, &dwFileIndex))
- {
- // Calculate the number of locales
- pFirstHash = pHash = GetFirstHashEntry(ha, szFileName);
- while(pHash != NULL)
- {
- dwLocales++;
- pHash = GetNextHashEntry(ha, pFirstHash, pHash);
- }
-
- // Test if there is enough space to copy the locales
- if(*pdwMaxLocales < dwLocales)
- {
- *pdwMaxLocales = dwLocales;
- return ERROR_INSUFFICIENT_BUFFER;
- }
-
- // Enum the locales
- pFirstHash = pHash = GetFirstHashEntry(ha, szFileName);
- while(pHash != NULL)
- {
- *plcLocales++ = pHash->lcLocale;
- pHash = GetNextHashEntry(ha, pFirstHash, pHash);
- }
- }
- else
- {
- // There must be space for 1 locale
- if(*pdwMaxLocales < 1)
- {
- *pdwMaxLocales = 1;
- return ERROR_INSUFFICIENT_BUFFER;
- }
-
- // For nameless access, always return 1 locale
- pFileEntry = GetFileEntryByIndex(ha, dwFileIndex);
- pHash = ha->pHashTable + pFileEntry->dwHashIndex;
- *plcLocales = pHash->lcLocale;
- dwLocales = 1;
- }
-
- // Give the caller the total number of found locales
- *pdwMaxLocales = dwLocales;
- return ERROR_SUCCESS;
-}
-
-//-----------------------------------------------------------------------------
-// SFileHasFile
-//
-// hMpq - Handle of opened MPQ archive
-// szFileName - Name of file to look for
-
-bool WINAPI SFileHasFile(HANDLE hMpq, const char * szFileName)
-{
- TMPQArchive * ha = (TMPQArchive *)hMpq;
- TFileEntry * pFileEntry;
- DWORD dwFlagsToCheck = MPQ_FILE_EXISTS;
- DWORD dwFileIndex = 0;
- char szPatchFileName[MAX_PATH];
- bool bIsPseudoName;
- int nError = ERROR_SUCCESS;
-
- if(!IsValidMpqHandle(ha))
- nError = ERROR_INVALID_HANDLE;
- if(szFileName == NULL || *szFileName == 0)
- nError = ERROR_INVALID_PARAMETER;
-
- // Prepare the file opening
- if(nError == ERROR_SUCCESS)
- {
- // Different processing for pseudo-names
- bIsPseudoName = IsPseudoFileName(szFileName, &dwFileIndex);
-
- // Walk through the MPQ and all patches
- while(ha != NULL)
- {
- // Verify presence of the file
- pFileEntry = (bIsPseudoName == false) ? GetFileEntryLocale(ha, szFileName, lcFileLocale)
- : GetFileEntryByIndex(ha, dwFileIndex);
- // Verify the file flags
- if(pFileEntry != NULL && (pFileEntry->dwFlags & dwFlagsToCheck) == MPQ_FILE_EXISTS)
- return true;
-
- // If this is patched archive, go to the patch
- dwFlagsToCheck = MPQ_FILE_EXISTS | MPQ_FILE_PATCH_FILE;
- ha = ha->haPatch;
-
- // Prepare the patched file name
- if(ha != NULL)
- {
- strcpy(szPatchFileName, ha->szPatchPrefix);
- strcat(szPatchFileName, szFileName);
- szFileName = szPatchFileName;
- }
- }
-
- // Not found, sorry
- nError = ERROR_FILE_NOT_FOUND;
- }
-
- // Cleanup
- SetLastError(nError);
- return false;
-}
-
-
-//-----------------------------------------------------------------------------
-// SFileOpenFileEx
-//
-// hMpq - Handle of opened MPQ archive
-// szFileName - Name of file to open
-// dwSearchScope - Where to search
-// phFile - Pointer to store opened file handle
-
-bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope, HANDLE * phFile)
-{
- TMPQArchive * ha = (TMPQArchive *)hMpq;
- TFileEntry * pFileEntry = NULL;
- TMPQFile * hf = NULL;
- DWORD dwFileIndex = 0;
- bool bOpenByIndex = false;
- int nError = ERROR_SUCCESS;
-
- // Don't accept NULL pointer to file handle
- if(phFile == NULL)
- nError = ERROR_INVALID_PARAMETER;
-
- // Prepare the file opening
- if(nError == ERROR_SUCCESS)
- {
- switch(dwSearchScope)
- {
- case SFILE_OPEN_PATCHED_FILE:
-
- // We want to open the updated version of the file
- return OpenPatchedFile(hMpq, szFileName, 0, phFile);
-
- case SFILE_OPEN_FROM_MPQ:
-
- if(!IsValidMpqHandle(ha))
- {
- nError = ERROR_INVALID_HANDLE;
- break;
- }
-
- if(szFileName == NULL || *szFileName == 0)
- {
- nError = ERROR_INVALID_PARAMETER;
- break;
- }
-
- // First of all, check the name as-is
- if(!IsPseudoFileName(szFileName, &dwFileIndex))
- {
- pFileEntry = GetFileEntryLocale(ha, szFileName, lcFileLocale);
- if(pFileEntry == NULL)
- nError = ERROR_FILE_NOT_FOUND;
- }
- else
- {
- bOpenByIndex = true;
- pFileEntry = GetFileEntryByIndex(ha, dwFileIndex);
- if(pFileEntry == NULL)
- nError = ERROR_FILE_NOT_FOUND;
- }
- break;
-
- case SFILE_OPEN_ANY_LOCALE:
-
- // This open option is reserved for opening MPQ internal listfile.
- // No argument validation. Tries to open file with neutral locale first,
- // then any other available.
- dwSearchScope = SFILE_OPEN_FROM_MPQ;
- pFileEntry = GetFileEntryAny(ha, szFileName);
- if(pFileEntry == NULL)
- nError = ERROR_FILE_NOT_FOUND;
- break;
-
- case SFILE_OPEN_LOCAL_FILE:
-
- if(szFileName == NULL || *szFileName == 0)
- {
- nError = ERROR_INVALID_PARAMETER;
- break;
- }
-
- return OpenLocalFile(szFileName, phFile);
-
- default:
-
- // Don't accept any other value
- nError = ERROR_INVALID_PARAMETER;
- break;
- }
-
- // Quick return if something failed
- if(nError != ERROR_SUCCESS)
- {
- SetLastError(nError);
- return false;
- }
- }
-
- // Test if the file was not already deleted.
- if(nError == ERROR_SUCCESS)
- {
- if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) == 0)
- nError = ERROR_FILE_NOT_FOUND;
- if(pFileEntry->dwFlags & ~MPQ_FILE_VALID_FLAGS)
- nError = ERROR_NOT_SUPPORTED;
- }
-
- // Allocate file handle
- if(nError == ERROR_SUCCESS)
- {
- if((hf = STORM_ALLOC(TMPQFile, 1)) == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Initialize file handle
- if(nError == ERROR_SUCCESS)
- {
- memset(hf, 0, sizeof(TMPQFile));
- hf->pFileEntry = pFileEntry;
- hf->dwMagic = ID_MPQ_FILE;
- hf->ha = ha;
-
- hf->MpqFilePos = pFileEntry->ByteOffset;
- hf->RawFilePos = ha->MpqPos + hf->MpqFilePos;
- hf->dwDataSize = pFileEntry->dwFileSize;
-
- // If the MPQ has sector CRC enabled, enable if for the file
- if(ha->dwFlags & MPQ_FLAG_CHECK_SECTOR_CRC)
- hf->bCheckSectorCRCs = true;
-
- // If we know the real file name, copy it to the file entry
- if(bOpenByIndex == false)
- {
- // If there is no file name yet, allocate it
- AllocateFileName(pFileEntry, szFileName);
-
- // If the file is encrypted, we should detect the file key
- if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
- {
- hf->dwFileKey = DecryptFileKey(szFileName,
- pFileEntry->ByteOffset,
- pFileEntry->dwFileSize,
- pFileEntry->dwFlags);
- }
- }
- else
- {
- // Try to auto-detect the file name
- if(!SFileGetFileName(hf, NULL))
- nError = GetLastError();
- }
- }
-
- // If the file is actually a patch file, we have to load the patch file header
- if(nError == ERROR_SUCCESS && pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE)
- {
- assert(hf->pPatchInfo == NULL);
- nError = AllocatePatchInfo(hf, true);
- }
-
- // Cleanup
- if(nError != ERROR_SUCCESS)
- {
- SetLastError(nError);
- FreeMPQFile(hf);
- }
-
- *phFile = hf;
- return (nError == ERROR_SUCCESS);
-}
-
-//-----------------------------------------------------------------------------
-// bool WINAPI SFileCloseFile(HANDLE hFile);
-
-bool WINAPI SFileCloseFile(HANDLE hFile)
-{
- TMPQFile * hf = (TMPQFile *)hFile;
-
- if(!IsValidFileHandle(hf))
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return false;
- }
-
- // Free the structure
- FreeMPQFile(hf);
- return true;
-}
diff --git a/dep/StormLib/src/SFilePatchArchives.cpp b/dep/StormLib/src/SFilePatchArchives.cpp
deleted file mode 100644
index 24ae2c52c37..00000000000
--- a/dep/StormLib/src/SFilePatchArchives.cpp
+++ /dev/null
@@ -1,587 +0,0 @@
-/*****************************************************************************/
-/* SFilePatchArchives.cpp Copyright (c) Ladislav Zezula 2010 */
-/*---------------------------------------------------------------------------*/
-/* Description: */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 18.08.10 1.00 Lad The first version of SFilePatchArchives.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "StormCommon.h"
-
-//-----------------------------------------------------------------------------
-// Local structures
-
-typedef struct _BLIZZARD_BSDIFF40_FILE
-{
- ULONGLONG Signature;
- ULONGLONG CtrlBlockSize;
- ULONGLONG DataBlockSize;
- ULONGLONG NewFileSize;
-} BLIZZARD_BSDIFF40_FILE, *PBLIZZARD_BSDIFF40_FILE;
-
-//-----------------------------------------------------------------------------
-// Local functions
-
-static bool GetDefaultPatchPrefix(
- const TCHAR * szBaseMpqName,
- char * szBuffer)
-{
- const TCHAR * szExtension;
- const TCHAR * szDash;
-
- // Ensure that both names are plain names
- szBaseMpqName = GetPlainFileNameT(szBaseMpqName);
-
- // Patch prefix is for the Cataclysm MPQs, whose names
- // are like "locale-enGB.MPQ" or "speech-enGB.MPQ"
- szExtension = _tcsrchr(szBaseMpqName, _T('.'));
- szDash = _tcsrchr(szBaseMpqName, _T('-'));
- strcpy(szBuffer, "Base");
-
- // If the length of the prefix doesn't match, use default one
- if(szExtension != NULL && szDash != NULL && (szExtension - szDash) == 5)
- {
- // Copy the prefix
- szBuffer[0] = (char)szDash[1];
- szBuffer[1] = (char)szDash[2];
- szBuffer[2] = (char)szDash[3];
- szBuffer[3] = (char)szDash[4];
- szBuffer[4] = 0;
- }
-
- return true;
-}
-
-static void Decompress_RLE(LPBYTE pbDecompressed, DWORD cbDecompressed, LPBYTE pbCompressed, DWORD cbCompressed)
-{
- LPBYTE pbDecompressedEnd = pbDecompressed + cbDecompressed;
- LPBYTE pbCompressedEnd = pbCompressed + cbCompressed;
- BYTE RepeatCount;
- BYTE OneByte;
-
- // Cut the initial DWORD from the compressed chunk
- pbCompressed += sizeof(DWORD);
- cbCompressed -= sizeof(DWORD);
-
- // Pre-fill decompressed buffer with zeros
- memset(pbDecompressed, 0, cbDecompressed);
-
- // Unpack
- while(pbCompressed < pbCompressedEnd && pbDecompressed < pbDecompressedEnd)
- {
- OneByte = *pbCompressed++;
-
- // Is it a repetition byte ?
- if(OneByte & 0x80)
- {
- RepeatCount = (OneByte & 0x7F) + 1;
- for(BYTE i = 0; i < RepeatCount; i++)
- {
- if(pbDecompressed == pbDecompressedEnd || pbCompressed == pbCompressedEnd)
- break;
-
- *pbDecompressed++ = *pbCompressed++;
- }
- }
- else
- {
- pbDecompressed += (OneByte + 1);
- }
- }
-}
-
-static int LoadMpqPatch_COPY(TMPQFile * hf, TPatchHeader * pPatchHeader)
-{
- int nError = ERROR_SUCCESS;
-
- // Allocate space for patch header and compressed data
- hf->pPatchHeader = (TPatchHeader *)STORM_ALLOC(BYTE, pPatchHeader->dwSizeOfPatchData);
- if(hf->pPatchHeader == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
-
- // Load the patch data and decide if they are compressed or not
- if(nError == ERROR_SUCCESS)
- {
- LPBYTE pbPatchFile = (LPBYTE)hf->pPatchHeader;
-
- // Copy the patch header itself
- memcpy(pbPatchFile, pPatchHeader, sizeof(TPatchHeader));
- pbPatchFile += sizeof(TPatchHeader);
-
- // Load the rest of the patch
- if(!SFileReadFile((HANDLE)hf, pbPatchFile, pPatchHeader->dwSizeOfPatchData - sizeof(TPatchHeader)))
- nError = GetLastError();
- }
-
- return nError;
-}
-
-static int LoadMpqPatch_BSD0(TMPQFile * hf, TPatchHeader * pPatchHeader)
-{
- LPBYTE pbDecompressed = NULL;
- LPBYTE pbCompressed = NULL;
- DWORD cbDecompressed = 0;
- DWORD cbCompressed = 0;
- DWORD dwBytesRead = 0;
- int nError = ERROR_SUCCESS;
-
- // Allocate space for compressed data
- cbCompressed = pPatchHeader->dwXfrmBlockSize - SIZE_OF_XFRM_HEADER;
- pbCompressed = STORM_ALLOC(BYTE, cbCompressed);
- if(pbCompressed == NULL)
- nError = ERROR_SUCCESS;
-
- // Read the compressed patch data
- if(nError == ERROR_SUCCESS)
- {
- // Load the rest of the header
- SFileReadFile((HANDLE)hf, pbCompressed, cbCompressed, &dwBytesRead);
- if(dwBytesRead != cbCompressed)
- nError = ERROR_FILE_CORRUPT;
- }
-
- // Get the uncompressed size of the patch
- if(nError == ERROR_SUCCESS)
- {
- cbDecompressed = pPatchHeader->dwSizeOfPatchData - sizeof(TPatchHeader);
- hf->pPatchHeader = (TPatchHeader *)STORM_ALLOC(BYTE, pPatchHeader->dwSizeOfPatchData);
- if(hf->pPatchHeader == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Now decompress the patch data
- if(nError == ERROR_SUCCESS)
- {
- // Copy the patch header
- memcpy(hf->pPatchHeader, pPatchHeader, sizeof(TPatchHeader));
- pbDecompressed = (LPBYTE)hf->pPatchHeader + sizeof(TPatchHeader);
-
- // Uncompress or copy the patch data
- if(cbCompressed < cbDecompressed)
- {
- Decompress_RLE(pbDecompressed, cbDecompressed, pbCompressed, cbCompressed);
- }
- else
- {
- assert(cbCompressed == cbDecompressed);
- memcpy(pbDecompressed, pbCompressed, cbCompressed);
- }
- }
-
- // Free buffers and exit
- if(pbCompressed != NULL)
- STORM_FREE(pbCompressed);
- return nError;
-}
-
-static int ApplyMpqPatch_COPY(
- TMPQFile * hf,
- TPatchHeader * pPatchHeader)
-{
- LPBYTE pbNewFileData;
- DWORD cbNewFileData;
-
- // Allocate space for new file data
- cbNewFileData = pPatchHeader->dwXfrmBlockSize - SIZE_OF_XFRM_HEADER;
- pbNewFileData = STORM_ALLOC(BYTE, cbNewFileData);
- if(pbNewFileData == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Copy the patch data as-is
- memcpy(pbNewFileData, (LPBYTE)pPatchHeader + sizeof(TPatchHeader), cbNewFileData);
-
- // Free the old file data
- STORM_FREE(hf->pbFileData);
-
- // Put the new file data there
- hf->pbFileData = pbNewFileData;
- hf->cbFileData = cbNewFileData;
- return ERROR_SUCCESS;
-}
-
-static int ApplyMpqPatch_BSD0(
- TMPQFile * hf,
- TPatchHeader * pPatchHeader)
-{
- PBLIZZARD_BSDIFF40_FILE pBsdiff;
- LPDWORD pCtrlBlock;
- LPBYTE pbPatchData = (LPBYTE)pPatchHeader + sizeof(TPatchHeader);
- LPBYTE pDataBlock;
- LPBYTE pExtraBlock;
- LPBYTE pbNewData = NULL;
- LPBYTE pbOldData = (LPBYTE)hf->pbFileData;
- DWORD dwNewOffset = 0; // Current position to patch
- DWORD dwOldOffset = 0; // Current source position
- DWORD dwNewSize; // Patched file size
- DWORD dwOldSize = hf->cbFileData; // File size before patch
-
- // Get pointer to the patch header
- // Format of BSDIFF header corresponds to original BSDIFF, which is:
- // 0000 8 bytes signature "BSDIFF40"
- // 0008 8 bytes size of the control block
- // 0010 8 bytes size of the data block
- // 0018 8 bytes new size of the patched file
- pBsdiff = (PBLIZZARD_BSDIFF40_FILE)pbPatchData;
- pbPatchData += sizeof(BLIZZARD_BSDIFF40_FILE);
-
- // Get pointer to the 32-bit BSDIFF control block
- // The control block follows immediately after the BSDIFF header
- // and consists of three 32-bit integers
- // 0000 4 bytes Length to copy from the BSDIFF data block the new file
- // 0004 4 bytes Length to copy from the BSDIFF extra block
- // 0008 4 bytes Size to increment source file offset
- pCtrlBlock = (LPDWORD)pbPatchData;
- pbPatchData += (size_t)BSWAP_INT64_UNSIGNED(pBsdiff->CtrlBlockSize);
-
- // Get the pointer to the data block
- pDataBlock = (LPBYTE)pbPatchData;
- pbPatchData += (size_t)BSWAP_INT64_UNSIGNED(pBsdiff->DataBlockSize);
-
- // Get the pointer to the extra block
- pExtraBlock = (LPBYTE)pbPatchData;
- dwNewSize = (DWORD)BSWAP_INT64_UNSIGNED(pBsdiff->NewFileSize);
-
- // Allocate new buffer
- pbNewData = STORM_ALLOC(BYTE, dwNewSize);
- if(pbNewData == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Now patch the file
- while(dwNewOffset < dwNewSize)
- {
- DWORD dwAddDataLength = BSWAP_INT32_UNSIGNED(pCtrlBlock[0]);
- DWORD dwMovDataLength = BSWAP_INT32_UNSIGNED(pCtrlBlock[1]);
- DWORD dwOldMoveLength = BSWAP_INT32_UNSIGNED(pCtrlBlock[2]);
- DWORD i;
-
- // Sanity check
- if((dwNewOffset + dwAddDataLength) > dwNewSize)
- {
- STORM_FREE(pbNewData);
- return ERROR_FILE_CORRUPT;
- }
-
- // Read the diff string to the target buffer
- memcpy(pbNewData + dwNewOffset, pDataBlock, dwAddDataLength);
- pDataBlock += dwAddDataLength;
-
- // Now combine the patch data with the original file
- for(i = 0; i < dwAddDataLength; i++)
- {
- if(dwOldOffset < dwOldSize)
- pbNewData[dwNewOffset] = pbNewData[dwNewOffset] + pbOldData[dwOldOffset];
-
- dwNewOffset++;
- dwOldOffset++;
- }
-
- // Sanity check
- if((dwNewOffset + dwMovDataLength) > dwNewSize)
- {
- STORM_FREE(pbNewData);
- return ERROR_FILE_CORRUPT;
- }
-
- // Copy the data from the extra block in BSDIFF patch
- memcpy(pbNewData + dwNewOffset, pExtraBlock, dwMovDataLength);
- pExtraBlock += dwMovDataLength;
- dwNewOffset += dwMovDataLength;
-
- // Move the old offset
- if(dwOldMoveLength & 0x80000000)
- dwOldMoveLength = 0x80000000 - dwOldMoveLength;
- dwOldOffset += dwOldMoveLength;
- pCtrlBlock += 3;
- }
-
- // Free the old file data
- STORM_FREE(hf->pbFileData);
-
- // Put the new data to the fil structure
- hf->pbFileData = pbNewData;
- hf->cbFileData = dwNewSize;
- return ERROR_SUCCESS;
-}
-
-
-static int LoadMpqPatch(TMPQFile * hf)
-{
- TPatchHeader PatchHeader;
- DWORD dwBytesRead;
- int nError = ERROR_SUCCESS;
-
- // Read the patch header
- SFileReadFile((HANDLE)hf, &PatchHeader, sizeof(TPatchHeader), &dwBytesRead);
- if(dwBytesRead != sizeof(TPatchHeader))
- nError = ERROR_FILE_CORRUPT;
-
- // Verify the signatures in the patch header
- if(nError == ERROR_SUCCESS)
- {
- // BSWAP the entire header, if needed
- BSWAP_ARRAY32_UNSIGNED(&PatchHeader, sizeof(DWORD) * 6);
- PatchHeader.dwXFRM = BSWAP_INT32_UNSIGNED(PatchHeader.dwXFRM);
- PatchHeader.dwXfrmBlockSize = BSWAP_INT32_UNSIGNED(PatchHeader.dwXfrmBlockSize);
- PatchHeader.dwPatchType = BSWAP_INT32_UNSIGNED(PatchHeader.dwPatchType);
-
- if(PatchHeader.dwSignature != 0x48435450 || PatchHeader.dwMD5 != 0x5f35444d || PatchHeader.dwXFRM != 0x4d524658)
- nError = ERROR_FILE_CORRUPT;
- }
-
- // Read the patch, depending on patch type
- if(nError == ERROR_SUCCESS)
- {
- switch(PatchHeader.dwPatchType)
- {
- case 0x59504f43: // 'COPY'
- nError = LoadMpqPatch_COPY(hf, &PatchHeader);
- break;
-
- case 0x30445342: // 'BSD0'
- nError = LoadMpqPatch_BSD0(hf, &PatchHeader);
- break;
-
- default:
- nError = ERROR_FILE_CORRUPT;
- break;
- }
- }
-
- return nError;
-}
-
-static int ApplyMpqPatch(
- TMPQFile * hf,
- TPatchHeader * pPatchHeader)
-{
- int nError = ERROR_SUCCESS;
-
- // Verify the original file before patching
- if(pPatchHeader->dwSizeBeforePatch != 0)
- {
- if(!VerifyDataBlockHash(hf->pbFileData, hf->cbFileData, pPatchHeader->md5_before_patch))
- nError = ERROR_FILE_CORRUPT;
- }
-
- // Apply the patch
- if(nError == ERROR_SUCCESS)
- {
- switch(pPatchHeader->dwPatchType)
- {
- case 0x59504f43: // 'COPY'
- nError = ApplyMpqPatch_COPY(hf, pPatchHeader);
- break;
-
- case 0x30445342: // 'BSD0'
- nError = ApplyMpqPatch_BSD0(hf, pPatchHeader);
- break;
-
- default:
- nError = ERROR_FILE_CORRUPT;
- break;
- }
- }
-
- // Verify MD5 after patch
- if(nError == ERROR_SUCCESS && pPatchHeader->dwSizeAfterPatch != 0)
- {
- // Verify the patched file
- if(!VerifyDataBlockHash(hf->pbFileData, hf->cbFileData, pPatchHeader->md5_after_patch))
- nError = ERROR_FILE_CORRUPT;
- }
-
- return nError;
-}
-
-//-----------------------------------------------------------------------------
-// Public functions (StormLib internals)
-
-bool IsIncrementalPatchFile(const void * pvData, DWORD cbData, LPDWORD pdwPatchedFileSize)
-{
- TPatchHeader * pPatchHeader = (TPatchHeader *)pvData;
- BLIZZARD_BSDIFF40_FILE DiffFile;
- DWORD dwPatchType;
-
- if(cbData >= sizeof(TPatchHeader) + sizeof(BLIZZARD_BSDIFF40_FILE))
- {
- dwPatchType = BSWAP_INT32_UNSIGNED(pPatchHeader->dwPatchType);
- if(dwPatchType == 0x30445342)
- {
- // Give the caller the patch file size
- if(pdwPatchedFileSize != NULL)
- {
- Decompress_RLE((LPBYTE)&DiffFile, sizeof(BLIZZARD_BSDIFF40_FILE), (LPBYTE)(pPatchHeader + 1), sizeof(BLIZZARD_BSDIFF40_FILE));
- DiffFile.NewFileSize = BSWAP_INT64_UNSIGNED(DiffFile.NewFileSize);
- *pdwPatchedFileSize = (DWORD)DiffFile.NewFileSize;
- return true;
- }
- }
- }
-
- return false;
-}
-
-int PatchFileData(TMPQFile * hf)
-{
- TMPQFile * hfBase = hf;
- int nError = ERROR_SUCCESS;
-
- // Move to the first patch
- hf = hf->hfPatchFile;
-
- // Now go through all patches and patch the original data
- while(hf != NULL)
- {
- // This must be true
- assert(hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE);
-
- // Make sure that the patch data is loaded
- nError = LoadMpqPatch(hf);
- if(nError != ERROR_SUCCESS)
- break;
-
- // Apply the patch
- nError = ApplyMpqPatch(hfBase, hf->pPatchHeader);
- if(nError != ERROR_SUCCESS)
- break;
-
- // Move to the next patch
- hf = hf->hfPatchFile;
- }
-
- return nError;
-}
-
-//-----------------------------------------------------------------------------
-// Public functions
-
-//
-// Patch prefix is the path subdirectory where the patched files are within MPQ.
-//
-// Example 1:
-// Main MPQ: locale-enGB.MPQ
-// Patch MPQ: wow-update-12694.MPQ
-// File in main MPQ: DBFilesClient\Achievement.dbc
-// File in patch MPQ: enGB\DBFilesClient\Achievement.dbc
-// Path prefix: enGB
-//
-// Example 2:
-// Main MPQ: expansion1.MPQ
-// Patch MPQ: wow-update-12694.MPQ
-// File in main MPQ: DBFilesClient\Achievement.dbc
-// File in patch MPQ: Base\DBFilesClient\Achievement.dbc
-// Path prefix: Base
-//
-
-bool WINAPI SFileOpenPatchArchive(
- HANDLE hMpq,
- const TCHAR * szPatchMpqName,
- const char * szPatchPathPrefix,
- DWORD dwFlags)
-{
- TMPQArchive * haPatch;
- TMPQArchive * ha = (TMPQArchive *)hMpq;
- HANDLE hPatchMpq = NULL;
- char szPatchPrefixBuff[MPQ_PATCH_PREFIX_LEN];
- int nError = ERROR_SUCCESS;
-
- // Keep compiler happy
- dwFlags = dwFlags;
-
- // Verify input parameters
- if(!IsValidMpqHandle(ha))
- nError = ERROR_INVALID_HANDLE;
- if(szPatchMpqName == NULL || *szPatchMpqName == 0)
- nError = ERROR_INVALID_PARAMETER;
-
- // If the user didn't give the patch prefix, get default one
- if(szPatchPathPrefix != NULL)
- {
- // Save length of the patch prefix
- if(strlen(szPatchPathPrefix) > MPQ_PATCH_PREFIX_LEN - 2)
- nError = ERROR_INVALID_PARAMETER;
- }
-
- //
- // We don't allow adding patches to archives that have been open for write
- //
- // Error scenario:
- //
- // 1) Open archive for writing
- // 2) Modify or replace a file
- // 3) Add patch archive to the opened MPQ
- // 4) Read patched file
- // 5) Now what ?
- //
-
- if(nError == ERROR_SUCCESS)
- {
- if(!FileStream_IsReadOnly(ha->pStream))
- nError = ERROR_ACCESS_DENIED;
- }
-
- // Open the archive like it is normal archive
- if(nError == ERROR_SUCCESS)
- {
- if(!SFileOpenArchive(szPatchMpqName, 0, MPQ_OPEN_READ_ONLY, &hPatchMpq))
- return false;
- haPatch = (TMPQArchive *)hPatchMpq;
-
- // Older WoW patches (build 13914) used to have
- // several language versions in one patch file
- // Those patches needed to have a path prefix
- // We can distinguish such patches by not having the (patch_metadata) file
- if(szPatchPathPrefix == NULL)
- {
- if(!SFileHasFile(hPatchMpq, PATCH_METADATA_NAME))
- {
- GetDefaultPatchPrefix(FileStream_GetFileName(ha->pStream), szPatchPrefixBuff);
- szPatchPathPrefix = szPatchPrefixBuff;
- }
- }
-
- // Save the prefix for patch file names.
- // Make sure that there is backslash after it
- if(szPatchPathPrefix != NULL && *szPatchPathPrefix != 0)
- {
- strcpy(haPatch->szPatchPrefix, szPatchPathPrefix);
- strcat(haPatch->szPatchPrefix, "\\");
- haPatch->cchPatchPrefix = strlen(haPatch->szPatchPrefix);
- }
-
- // Now add the patch archive to the list of patches to the original MPQ
- while(ha != NULL)
- {
- if(ha->haPatch == NULL)
- {
- haPatch->haBase = ha;
- ha->haPatch = haPatch;
- return true;
- }
-
- // Move to the next archive
- ha = ha->haPatch;
- }
-
- // Should never happen
- nError = ERROR_CAN_NOT_COMPLETE;
- }
-
- SetLastError(nError);
- return false;
-}
-
-bool WINAPI SFileIsPatchedArchive(HANDLE hMpq)
-{
- TMPQArchive * ha = (TMPQArchive *)hMpq;
-
- // Verify input parameters
- if(!IsValidMpqHandle(ha))
- return false;
-
- return (ha->haPatch != NULL);
-}
diff --git a/dep/StormLib/src/SFileReadFile.cpp b/dep/StormLib/src/SFileReadFile.cpp
deleted file mode 100644
index 5570fd466c5..00000000000
--- a/dep/StormLib/src/SFileReadFile.cpp
+++ /dev/null
@@ -1,1183 +0,0 @@
-/*****************************************************************************/
-/* SFileReadFile.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Description : */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* xx.xx.99 1.00 Lad The first version of SFileReadFile.cpp */
-/* 24.03.99 1.00 Lad Added the SFileGetFileInfo function */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "StormCommon.h"
-
-//-----------------------------------------------------------------------------
-// Local structures
-
-struct TFileHeader2Ext
-{
- DWORD dwOffset00Data; // Required data at offset 00 (32-bits)
- DWORD dwOffset00Mask; // Mask for data at offset 00 (32 bits). 0 = data are ignored
- DWORD dwOffset04Data; // Required data at offset 04 (32-bits)
- DWORD dwOffset04Mask; // Mask for data at offset 04 (32 bits). 0 = data are ignored
- const char * szExt; // Supplied extension, if the condition is true
-};
-
-//-----------------------------------------------------------------------------
-// Local functions
-
-static void CopyFileName(char * szTarget, const TCHAR * szSource)
-{
- while(*szSource != 0)
- *szTarget++ = (char)*szSource++;
- *szTarget = 0;
-}
-
-static DWORD GetMpqFileCount(TMPQArchive * ha)
-{
- TFileEntry * pFileTableEnd;
- TFileEntry * pFileEntry;
- DWORD dwFileCount = 0;
-
- // Go through all open MPQs, including patches
- while(ha != NULL)
- {
- // Only count files that are not patch files
- pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
- for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
- {
- // If the file is patch file and this is not primary archive, skip it
- // BUGBUG: This errorneously counts non-patch files that are in both
- // base MPQ and in patches, and increases the number of files by cca 50%
- if((pFileEntry->dwFlags & (MPQ_FILE_EXISTS | MPQ_FILE_PATCH_FILE)) == MPQ_FILE_EXISTS)
- dwFileCount++;
- }
-
- // Move to the next patch archive
- ha = ha->haPatch;
- }
-
- return dwFileCount;
-}
-
-static bool GetFilePatchChain(TMPQFile * hf, void * pvFileInfo, DWORD cbFileInfo, LPDWORD pcbLengthNeeded)
-{
- TMPQFile * hfTemp;
- TCHAR * szPatchChain = (TCHAR *)pvFileInfo;
- TCHAR * szFileName;
- size_t cchCharsNeeded = 1;
- size_t nLength;
- DWORD cbLengthNeeded;
-
- // Check if the "hf" is a MPQ file
- if(hf->pStream != NULL)
- {
- // Calculate the length needed
- szFileName = FileStream_GetFileName(hf->pStream);
- cchCharsNeeded += _tcslen(szFileName) + 1;
- cbLengthNeeded = (DWORD)(cchCharsNeeded * sizeof(TCHAR));
-
- // If we have enough space, copy the file name
- if(cbFileInfo >= cbLengthNeeded)
- {
- nLength = _tcslen(szFileName) + 1;
- memcpy(szPatchChain, szFileName, nLength * sizeof(TCHAR));
- szPatchChain += nLength;
-
- // Terminate the multi-string
- *szPatchChain = 0;
- }
- }
- else
- {
- // Calculate number of characters needed
- for(hfTemp = hf; hfTemp != NULL; hfTemp = hfTemp->hfPatchFile)
- cchCharsNeeded += _tcslen(FileStream_GetFileName(hfTemp->ha->pStream)) + 1;
- cbLengthNeeded = (DWORD)(cchCharsNeeded * sizeof(TCHAR));
-
- // If we have enough space, the copy the patch chain
- if(cbFileInfo >= cbLengthNeeded)
- {
- for(hfTemp = hf; hfTemp != NULL; hfTemp = hfTemp->hfPatchFile)
- {
- szFileName = FileStream_GetFileName(hfTemp->ha->pStream);
- nLength = _tcslen(szFileName) + 1;
- memcpy(szPatchChain, szFileName, nLength * sizeof(TCHAR));
- szPatchChain += nLength;
- }
-
- // Terminate the multi-string
- *szPatchChain = 0;
- }
- }
-
- // Give result length, terminate multi-string and return
- *pcbLengthNeeded = cbLengthNeeded;
- return true;
-}
-
-// hf - MPQ File handle.
-// pbBuffer - Pointer to target buffer to store sectors.
-// dwByteOffset - Position of sector in the file (relative to file begin)
-// dwBytesToRead - Number of bytes to read. Must be multiplier of sector size.
-// pdwBytesRead - Stored number of bytes loaded
-static int ReadMpqSectors(TMPQFile * hf, LPBYTE pbBuffer, DWORD dwByteOffset, DWORD dwBytesToRead, LPDWORD pdwBytesRead)
-{
- ULONGLONG RawFilePos;
- TMPQArchive * ha = hf->ha;
- TFileEntry * pFileEntry = hf->pFileEntry;
- LPBYTE pbRawSector = NULL;
- LPBYTE pbOutSector = pbBuffer;
- LPBYTE pbInSector = pbBuffer;
- DWORD dwRawBytesToRead;
- DWORD dwRawSectorOffset = dwByteOffset;
- DWORD dwSectorsToRead = dwBytesToRead / ha->dwSectorSize;
- DWORD dwSectorIndex = dwByteOffset / ha->dwSectorSize;
- DWORD dwSectorsDone = 0;
- DWORD dwBytesRead = 0;
- int nError = ERROR_SUCCESS;
-
- // Note that dwByteOffset must be aligned to size of one sector
- // Note that dwBytesToRead must be a multiplier of one sector size
- // This is local function, so we won't check if that's true.
- // Note that files stored in single units are processed by a separate function
-
- // If there is not enough bytes remaining, cut dwBytesToRead
- if((dwByteOffset + dwBytesToRead) > hf->dwDataSize)
- dwBytesToRead = hf->dwDataSize - dwByteOffset;
- dwRawBytesToRead = dwBytesToRead;
-
- // Perform all necessary work to do with compressed files
- if(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED)
- {
- // If the sector positions are not loaded yet, do it
- if(hf->SectorOffsets == NULL)
- {
- nError = AllocateSectorOffsets(hf, true);
- if(nError != ERROR_SUCCESS)
- return nError;
- }
-
- // If the sector checksums are not loaded yet, load them now.
- if(hf->SectorChksums == NULL && (pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC) && hf->bLoadedSectorCRCs == false)
- {
- //
- // Sector CRCs is plain crap feature. It is almost never present,
- // often it's empty, or the end offset of sector CRCs is zero.
- // We only try to load sector CRCs once, and regardless if it fails
- // or not, we won't try that again for the given file.
- //
-
- AllocateSectorChecksums(hf, true);
- hf->bLoadedSectorCRCs = true;
- }
-
- // TODO: If the raw data MD5s are not loaded yet, load them now
- // Only do it if the MPQ is of format 4.0
-// if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_4 && ha->pHeader->dwRawChunkSize != 0)
-// {
-// nError = AllocateRawMD5s(hf, true);
-// if(nError != ERROR_SUCCESS)
-// return nError;
-// }
-
- // If the file is compressed, also allocate secondary buffer
- pbInSector = pbRawSector = STORM_ALLOC(BYTE, dwBytesToRead);
- if(pbRawSector == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Assign the temporary buffer as target for read operation
- dwRawSectorOffset = hf->SectorOffsets[dwSectorIndex];
- dwRawBytesToRead = hf->SectorOffsets[dwSectorIndex + dwSectorsToRead] - dwRawSectorOffset;
- }
-
- // Calculate raw file offset where the sector(s) are stored.
- CalculateRawSectorOffset(RawFilePos, hf, dwRawSectorOffset);
-
- // Set file pointer and read all required sectors
- if(!FileStream_Read(ha->pStream, &RawFilePos, pbInSector, dwRawBytesToRead))
- return GetLastError();
- dwBytesRead = 0;
-
- // Now we have to decrypt and decompress all file sectors that have been loaded
- for(DWORD i = 0; i < dwSectorsToRead; i++)
- {
- DWORD dwRawBytesInThisSector = ha->dwSectorSize;
- DWORD dwBytesInThisSector = ha->dwSectorSize;
- DWORD dwIndex = dwSectorIndex + i;
-
- // If there is not enough bytes in the last sector,
- // cut the number of bytes in this sector
- if(dwRawBytesInThisSector > dwBytesToRead)
- dwRawBytesInThisSector = dwBytesToRead;
- if(dwBytesInThisSector > dwBytesToRead)
- dwBytesInThisSector = dwBytesToRead;
-
- // If the file is compressed, we have to adjust the raw sector size
- if(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED)
- dwRawBytesInThisSector = hf->SectorOffsets[dwIndex + 1] - hf->SectorOffsets[dwIndex];
-
- // If the file is encrypted, we have to decrypt the sector
- if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
- {
- BSWAP_ARRAY32_UNSIGNED(pbInSector, dwRawBytesInThisSector);
-
- // If we don't know the key, try to detect it by file content
- if(hf->dwFileKey == 0)
- {
- hf->dwFileKey = DetectFileKeyByContent(pbInSector, dwBytesInThisSector);
- if(hf->dwFileKey == 0)
- {
- nError = ERROR_UNKNOWN_FILE_KEY;
- break;
- }
- }
-
- DecryptMpqBlock(pbInSector, dwRawBytesInThisSector, hf->dwFileKey + dwIndex);
- BSWAP_ARRAY32_UNSIGNED(pbInSector, dwRawBytesInThisSector);
- }
-
- // If the file has sector CRC check turned on, perform it
- if(hf->bCheckSectorCRCs && hf->SectorChksums != NULL)
- {
- DWORD dwAdlerExpected = hf->SectorChksums[dwIndex];
- DWORD dwAdlerValue = 0;
-
- // We can only check sector CRC when it's not zero
- // Neither can we check it if it's 0xFFFFFFFF.
- if(dwAdlerExpected != 0 && dwAdlerExpected != 0xFFFFFFFF)
- {
- dwAdlerValue = adler32(0, pbInSector, dwRawBytesInThisSector);
- if(dwAdlerValue != dwAdlerExpected)
- {
- nError = ERROR_CHECKSUM_ERROR;
- break;
- }
- }
- }
-
- // If the sector is really compressed, decompress it.
- // WARNING : Some sectors may not be compressed, it can be determined only
- // by comparing uncompressed and compressed size !!!
- if(dwRawBytesInThisSector < dwBytesInThisSector)
- {
- int cbOutSector = dwBytesInThisSector;
- int cbInSector = dwRawBytesInThisSector;
- int nResult = 0;
-
- // Is the file compressed by Blizzard's multiple compression ?
- if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS)
- {
- if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2)
- nResult = SCompDecompress2((char *)pbOutSector, &cbOutSector, (char *)pbInSector, cbInSector);
- else
- nResult = SCompDecompress((char *)pbOutSector, &cbOutSector, (char *)pbInSector, cbInSector);
- }
-
- // Is the file compressed by PKWARE Data Compression Library ?
- else if(pFileEntry->dwFlags & MPQ_FILE_IMPLODE)
- {
- nResult = SCompExplode((char *)pbOutSector, &cbOutSector, (char *)pbInSector, cbInSector);
- }
-
- // Did the decompression fail ?
- if(nResult == 0)
- {
- nError = ERROR_FILE_CORRUPT;
- break;
- }
- }
- else
- {
- if(pbOutSector != pbInSector)
- memcpy(pbOutSector, pbInSector, dwBytesInThisSector);
- }
-
- // Move pointers
- dwBytesToRead -= dwBytesInThisSector;
- dwByteOffset += dwBytesInThisSector;
- dwBytesRead += dwBytesInThisSector;
- pbOutSector += dwBytesInThisSector;
- pbInSector += dwRawBytesInThisSector;
- dwSectorsDone++;
- }
-
- // Free all used buffers
- if(pbRawSector != NULL)
- STORM_FREE(pbRawSector);
-
- // Give the caller thenumber of bytes read
- *pdwBytesRead = dwBytesRead;
- return nError;
-}
-
-static int ReadMpqFileSingleUnit(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead)
-{
- ULONGLONG RawFilePos = hf->RawFilePos;
- TMPQArchive * ha = hf->ha;
- TFileEntry * pFileEntry = hf->pFileEntry;
- LPBYTE pbCompressed = NULL;
- LPBYTE pbRawData = NULL;
- int nError = ERROR_SUCCESS;
-
- // If the file buffer is not allocated yet, do it.
- if(hf->pbFileSector == NULL)
- {
- nError = AllocateSectorBuffer(hf);
- if(nError != ERROR_SUCCESS)
- return nError;
- pbRawData = hf->pbFileSector;
- }
-
- // If the file is a patch file, adjust raw data offset
- if(hf->pPatchInfo != NULL)
- RawFilePos += hf->pPatchInfo->dwLength;
-
- // If the file sector is not loaded yet, do it
- if(hf->dwSectorOffs != 0)
- {
- // Is the file compressed?
- if(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED)
- {
- // Allocate space for compressed data
- pbCompressed = STORM_ALLOC(BYTE, pFileEntry->dwCmpSize);
- if(pbCompressed == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
- pbRawData = pbCompressed;
- }
-
- // Load the raw (compressed, encrypted) data
- if(!FileStream_Read(ha->pStream, &RawFilePos, pbRawData, pFileEntry->dwCmpSize))
- {
- STORM_FREE(pbCompressed);
- return GetLastError();
- }
-
- // If the file is encrypted, we have to decrypt the data first
- if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
- {
- BSWAP_ARRAY32_UNSIGNED(pbRawData, pFileEntry->dwCmpSize);
- DecryptMpqBlock(pbRawData, pFileEntry->dwCmpSize, hf->dwFileKey);
- BSWAP_ARRAY32_UNSIGNED(pbRawData, pFileEntry->dwCmpSize);
- }
-
- // If the file is compressed, we have to decompress it now
- if(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED)
- {
- int cbOutBuffer = (int)hf->dwDataSize;
- int cbInBuffer = (int)pFileEntry->dwCmpSize;
- int nResult = 0;
-
- //
- // If the file is an incremental patch, the size of compressed data
- // is determined as pFileEntry->dwCmpSize - sizeof(TPatchInfo)
- //
- // In "wow-update-12694.MPQ" from Wow-Cataclysm BETA:
- //
- // File CmprSize DcmpSize DataSize Compressed?
- // -------------------------------------- ---------- -------- -------- ---------------
- // esES\DBFilesClient\LightSkyBox.dbc 0xBE->0xA2 0xBC 0xBC Yes
- // deDE\DBFilesClient\MountCapability.dbc 0x93->0x77 0x77 0x77 No
- //
-
- if(pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE)
- cbInBuffer = cbInBuffer - sizeof(TPatchInfo);
-
- // Is the file compressed by Blizzard's multiple compression ?
- if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS)
- {
- if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2)
- nResult = SCompDecompress2((char *)hf->pbFileSector, &cbOutBuffer, (char *)pbRawData, cbInBuffer);
- else
- nResult = SCompDecompress((char *)hf->pbFileSector, &cbOutBuffer, (char *)pbRawData, cbInBuffer);
- }
-
- // Is the file compressed by PKWARE Data Compression Library ?
- // Note: Single unit files compressed with IMPLODE are not supported by Blizzard
- else if(pFileEntry->dwFlags & MPQ_FILE_IMPLODE)
- nResult = SCompExplode((char *)hf->pbFileSector, &cbOutBuffer, (char *)pbRawData, cbInBuffer);
-
- nError = (nResult != 0) ? ERROR_SUCCESS : ERROR_FILE_CORRUPT;
- }
- else
- {
- if(pbRawData != hf->pbFileSector)
- memcpy(hf->pbFileSector, pbRawData, hf->dwDataSize);
- }
-
- // Free the decompression buffer.
- if(pbCompressed != NULL)
- STORM_FREE(pbCompressed);
-
- // The file sector is now properly loaded
- hf->dwSectorOffs = 0;
- }
-
- // At this moment, we have the file loaded into the file buffer.
- // Copy as much as the caller wants
- if(nError == ERROR_SUCCESS && hf->dwSectorOffs == 0)
- {
- // File position is greater or equal to file size ?
- if(dwFilePos >= hf->dwDataSize)
- {
- *pdwBytesRead = 0;
- return ERROR_SUCCESS;
- }
-
- // If not enough bytes remaining in the file, cut them
- if((hf->dwDataSize - dwFilePos) < dwToRead)
- dwToRead = (hf->dwDataSize - dwFilePos);
-
- // Copy the bytes
- memcpy(pvBuffer, hf->pbFileSector + dwFilePos, dwToRead);
-
- // Give the number of bytes read
- *pdwBytesRead = dwToRead;
- return ERROR_SUCCESS;
- }
-
- // An error, sorry
- return ERROR_CAN_NOT_COMPLETE;
-}
-
-static int ReadMpqFile(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwBytesToRead, LPDWORD pdwBytesRead)
-{
- TMPQArchive * ha = hf->ha;
- LPBYTE pbBuffer = (BYTE *)pvBuffer;
- DWORD dwTotalBytesRead = 0; // Total bytes read in all three parts
- DWORD dwSectorSizeMask = ha->dwSectorSize - 1; // Mask for block size, usually 0x0FFF
- DWORD dwFileSectorPos; // File offset of the loaded sector
- DWORD dwBytesRead; // Number of bytes read (temporary variable)
- int nError;
-
- // If the file position is at or beyond end of file, do nothing
- if(dwFilePos >= hf->dwDataSize)
- {
- *pdwBytesRead = 0;
- return ERROR_SUCCESS;
- }
-
- // If not enough bytes in the file remaining, cut them
- if(dwBytesToRead > (hf->dwDataSize - dwFilePos))
- dwBytesToRead = (hf->dwDataSize - dwFilePos);
-
- // Compute sector position in the file
- dwFileSectorPos = dwFilePos & ~dwSectorSizeMask; // Position in the block
-
- // If the file sector buffer is not allocated yet, do it now
- if(hf->pbFileSector == NULL)
- {
- nError = AllocateSectorBuffer(hf);
- if(nError != ERROR_SUCCESS)
- return nError;
- }
-
- // Load the first (incomplete) file sector
- if(dwFilePos & dwSectorSizeMask)
- {
- DWORD dwBytesInSector = ha->dwSectorSize;
- DWORD dwBufferOffs = dwFilePos & dwSectorSizeMask;
- DWORD dwToCopy;
-
- // Is the file sector already loaded ?
- if(hf->dwSectorOffs != dwFileSectorPos)
- {
- // Load one MPQ sector into archive buffer
- nError = ReadMpqSectors(hf, hf->pbFileSector, dwFileSectorPos, ha->dwSectorSize, &dwBytesInSector);
- if(nError != ERROR_SUCCESS)
- return nError;
-
- // Remember that the data loaded to the sector have new file offset
- hf->dwSectorOffs = dwFileSectorPos;
- }
- else
- {
- if((dwFileSectorPos + dwBytesInSector) > hf->dwDataSize)
- dwBytesInSector = hf->dwDataSize - dwFileSectorPos;
- }
-
- // Copy the data from the offset in the loaded sector to the end of the sector
- dwToCopy = dwBytesInSector - dwBufferOffs;
- if(dwToCopy > dwBytesToRead)
- dwToCopy = dwBytesToRead;
-
- // Copy data from sector buffer into target buffer
- memcpy(pbBuffer, hf->pbFileSector + dwBufferOffs, dwToCopy);
-
- // Update pointers and byte counts
- dwTotalBytesRead += dwToCopy;
- dwFileSectorPos += dwBytesInSector;
- pbBuffer += dwToCopy;
- dwBytesToRead -= dwToCopy;
- }
-
- // Load the whole ("middle") sectors only if there is at least one full sector to be read
- if(dwBytesToRead >= ha->dwSectorSize)
- {
- DWORD dwBlockBytes = dwBytesToRead & ~dwSectorSizeMask;
-
- // Load all sectors to the output buffer
- nError = ReadMpqSectors(hf, pbBuffer, dwFileSectorPos, dwBlockBytes, &dwBytesRead);
- if(nError != ERROR_SUCCESS)
- return nError;
-
- // Update pointers
- dwTotalBytesRead += dwBytesRead;
- dwFileSectorPos += dwBytesRead;
- pbBuffer += dwBytesRead;
- dwBytesToRead -= dwBytesRead;
- }
-
- // Read the terminating sector
- if(dwBytesToRead > 0)
- {
- DWORD dwToCopy = ha->dwSectorSize;
-
- // Is the file sector already loaded ?
- if(hf->dwSectorOffs != dwFileSectorPos)
- {
- // Load one MPQ sector into archive buffer
- nError = ReadMpqSectors(hf, hf->pbFileSector, dwFileSectorPos, ha->dwSectorSize, &dwBytesRead);
- if(nError != ERROR_SUCCESS)
- return nError;
-
- // Remember that the data loaded to the sector have new file offset
- hf->dwSectorOffs = dwFileSectorPos;
- }
-
- // Check number of bytes read
- if(dwToCopy > dwBytesToRead)
- dwToCopy = dwBytesToRead;
-
- // Copy the data from the cached last sector to the caller's buffer
- memcpy(pbBuffer, hf->pbFileSector, dwToCopy);
-
- // Update pointers
- dwTotalBytesRead += dwToCopy;
- }
-
- // Store total number of bytes read to the caller
- *pdwBytesRead = dwTotalBytesRead;
- return ERROR_SUCCESS;
-}
-
-static int ReadMpqFilePatchFile(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead)
-{
- DWORD dwBytesToRead = dwToRead;
- DWORD dwBytesRead = 0;
- int nError = ERROR_SUCCESS;
-
- // Make sure that the patch file is loaded completely
- if(hf->pbFileData == NULL)
- {
- // Load the original file and store its content to "pbOldData"
- hf->pbFileData = STORM_ALLOC(BYTE, hf->pFileEntry->dwFileSize);
- hf->cbFileData = hf->pFileEntry->dwFileSize;
- if(hf->pbFileData == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Read the file data
- if(hf->pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT)
- nError = ReadMpqFileSingleUnit(hf, hf->pbFileData, 0, hf->cbFileData, &dwBytesRead);
- else
- nError = ReadMpqFile(hf, hf->pbFileData, 0, hf->cbFileData, &dwBytesRead);
-
- // Fix error code
- if(nError == ERROR_SUCCESS && dwBytesRead != hf->cbFileData)
- nError = ERROR_FILE_CORRUPT;
-
- // Patch the file data
- if(nError == ERROR_SUCCESS)
- nError = PatchFileData(hf);
-
- // Reset number of bytes read to zero
- dwBytesRead = 0;
- }
-
- // If there is something to read, do it
- if(nError == ERROR_SUCCESS)
- {
- if(dwFilePos < hf->cbFileData)
- {
- // Make sure we don't copy more than file size
- if((dwFilePos + dwToRead) > hf->cbFileData)
- dwToRead = hf->cbFileData - dwFilePos;
-
- // Copy the appropriate amount of the file data to the caller's buffer
- memcpy(pvBuffer, hf->pbFileData + dwFilePos, dwToRead);
- dwBytesRead = dwToRead;
- }
-
- // Set the proper error code
- nError = (dwBytesRead == dwBytesToRead) ? ERROR_SUCCESS : ERROR_HANDLE_EOF;
- }
-
- // Give the result to the caller
- if(pdwBytesRead != NULL)
- *pdwBytesRead = dwBytesRead;
- return nError;
-}
-
-//-----------------------------------------------------------------------------
-// SFileReadFile
-
-bool WINAPI SFileReadFile(HANDLE hFile, void * pvBuffer, DWORD dwToRead, LPDWORD pdwRead, LPOVERLAPPED lpOverlapped)
-{
- TMPQFile * hf = (TMPQFile *)hFile;
- DWORD dwBytesRead = 0; // Number of bytes read
- int nError = ERROR_SUCCESS;
-
- // Keep compilers happy
- lpOverlapped = lpOverlapped;
-
- // Check valid parameters
- if(!IsValidFileHandle(hf))
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return false;
- }
-
- if(pvBuffer == NULL)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return false;
- }
-
- // If the file is local file, read the data directly from the stream
- if(hf->pStream != NULL)
- {
- ULONGLONG FilePosition1;
- ULONGLONG FilePosition2;
-
- // Because stream I/O functions are designed to read
- // "all or nothing", we compare file position before and after,
- // and if they differ, we assume that number of bytes read
- // is the difference between them
-
- FileStream_GetPos(hf->pStream, FilePosition1);
- if(!FileStream_Read(hf->pStream, NULL, pvBuffer, dwToRead))
- {
- // If not all bytes have been read, then return the number
- // of bytes read
- if((nError = GetLastError()) == ERROR_HANDLE_EOF)
- {
- FileStream_GetPos(hf->pStream, FilePosition2);
- dwBytesRead = (DWORD)(FilePosition2 - FilePosition1);
- }
- else
- {
- nError = GetLastError();
- }
- }
- else
- {
- dwBytesRead = dwToRead;
- }
- }
- else
- {
- // If the file is a patch file, we have to read it special way
- if(hf->hfPatchFile != NULL && (hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0)
- {
- nError = ReadMpqFilePatchFile(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead);
- }
-
- // If the file is single unit file, redirect it to read file
- else if(hf->pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT)
- {
- nError = ReadMpqFileSingleUnit(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead);
- }
-
- // Otherwise read it as sector based MPQ file
- else
- {
- nError = ReadMpqFile(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead);
- }
-
- // Increment the file position
- hf->dwFilePos += dwBytesRead;
- }
-
- // Give the caller the number of bytes read
- if(pdwRead != NULL)
- *pdwRead = dwBytesRead;
-
- // If the read operation succeeded, but not full number of bytes was read,
- // set the last error to ERROR_HANDLE_EOF
- if(nError == ERROR_SUCCESS && (dwBytesRead < dwToRead))
- nError = ERROR_HANDLE_EOF;
-
- // If something failed, set the last error value
- if(nError != ERROR_SUCCESS)
- SetLastError(nError);
- return (nError == ERROR_SUCCESS);
-}
-
-//-----------------------------------------------------------------------------
-// SFileGetFileSize
-
-DWORD WINAPI SFileGetFileSize(HANDLE hFile, LPDWORD pdwFileSizeHigh)
-{
- ULONGLONG FileSize;
- TMPQFile * hf = (TMPQFile *)hFile;
-
- // Validate the file handle before we go on
- if(IsValidFileHandle(hf))
- {
- // Make sure that the variable is initialized
- FileSize = 0;
-
- // If the file is patched file, we have to get the size of the last version
- if(hf->hfPatchFile != NULL)
- {
- // Walk through the entire patch chain, take the last version
- while(hf != NULL)
- {
- // Get the size of the currently pointed version
- FileSize = hf->pFileEntry->dwFileSize;
-
- // Move to the next patch file in the hierarchy
- hf = hf->hfPatchFile;
- }
- }
- else
- {
- // Is it a local file ?
- if(hf->pStream != NULL)
- {
- FileStream_GetSize(hf->pStream, FileSize);
- }
- else
- {
- FileSize = hf->dwDataSize;
- }
- }
-
- // If opened from archive, return file size
- if(pdwFileSizeHigh != NULL)
- *pdwFileSizeHigh = (DWORD)(FileSize >> 32);
- return (DWORD)FileSize;
- }
-
- SetLastError(ERROR_INVALID_HANDLE);
- return SFILE_INVALID_SIZE;
-}
-
-DWORD WINAPI SFileSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * plFilePosHigh, DWORD dwMoveMethod)
-{
- TMPQFile * hf = (TMPQFile *)hFile;
- ULONGLONG FilePosition;
- ULONGLONG MoveOffset;
- DWORD dwFilePosHi;
-
- // If the hFile is not a valid file handle, return an error.
- if(!IsValidFileHandle(hf))
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return SFILE_INVALID_POS;
- }
-
- // Get the relative point where to move from
- switch(dwMoveMethod)
- {
- case FILE_BEGIN:
- FilePosition = 0;
- break;
-
- case FILE_CURRENT:
- if(hf->pStream != NULL)
- {
- FileStream_GetPos(hf->pStream, FilePosition);
- }
- else
- {
- FilePosition = hf->dwFilePos;
- }
- break;
-
- case FILE_END:
- if(hf->pStream != NULL)
- {
- FileStream_GetSize(hf->pStream, FilePosition);
- }
- else
- {
- FilePosition = SFileGetFileSize(hFile, NULL);
- }
- break;
-
- default:
- SetLastError(ERROR_INVALID_PARAMETER);
- return SFILE_INVALID_POS;
- }
-
- // Now get the move offset. Note that both values form
- // a signed 64-bit value (a file pointer can be moved backwards)
- if(plFilePosHigh != NULL)
- dwFilePosHi = *plFilePosHigh;
- else
- dwFilePosHi = (lFilePos & 0x80000000) ? 0xFFFFFFFF : 0;
- MoveOffset = MAKE_OFFSET64(dwFilePosHi, lFilePos);
-
- // Now calculate the new file pointer
- // Do not allow the file pointer to go before the begin of the file
- FilePosition += MoveOffset;
- if(FilePosition < 0)
- FilePosition = 0;
-
- // Now apply the file pointer to the file
- if(hf->pStream != NULL)
- {
- // Apply the new file position
- if(!FileStream_Read(hf->pStream, &FilePosition, NULL, 0))
- return SFILE_INVALID_POS;
-
- // Return the new file position
- if(plFilePosHigh != NULL)
- *plFilePosHigh = (LONG)(FilePosition >> 32);
- return (DWORD)FilePosition;
- }
- else
- {
- // Files in MPQ can't be bigger than 4 GB.
- // We don't allow to go past 4 GB
- if(FilePosition >> 32)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return SFILE_INVALID_POS;
- }
-
- // Change the file position
- hf->dwFilePos = (DWORD)FilePosition;
-
- // Return the new file position
- if(plFilePosHigh != NULL)
- *plFilePosHigh = 0;
- return (DWORD)FilePosition;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Tries to retrieve the file name
-
-static TFileHeader2Ext data2ext[] =
-{
- {0x00005A4D, 0x0000FFFF, 0x00000000, 0x00000000, "exe"}, // EXE files
- {0x00000006, 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, "dc6"}, // EXE files
- {0x1A51504D, 0xFFFFFFFF, 0x00000000, 0x00000000, "mpq"}, // MPQ archive header ID ('MPQ\x1A')
- {0x46464952, 0xFFFFFFFF, 0x00000000, 0x00000000, "wav"}, // WAVE header 'RIFF'
- {0x324B4D53, 0xFFFFFFFF, 0x00000000, 0x00000000, "smk"}, // Old "Smacker Video" files 'SMK2'
- {0x694B4942, 0xFFFFFFFF, 0x00000000, 0x00000000, "bik"}, // Bink video files (new)
- {0x0801050A, 0xFFFFFFFF, 0x00000000, 0x00000000, "pcx"}, // PCX images used in Diablo I
- {0x544E4F46, 0xFFFFFFFF, 0x00000000, 0x00000000, "fnt"}, // Font files used in Diablo II
- {0x6D74683C, 0xFFFFFFFF, 0x00000000, 0x00000000, "html"}, // HTML '<htm'
- {0x4D54483C, 0xFFFFFFFF, 0x00000000, 0x00000000, "html"}, // HTML '<HTM
- {0x216F6F57, 0xFFFFFFFF, 0x00000000, 0x00000000, "tbl"}, // Table files
- {0x31504C42, 0xFFFFFFFF, 0x00000000, 0x00000000, "blp"}, // BLP textures
- {0x32504C42, 0xFFFFFFFF, 0x00000000, 0x00000000, "blp"}, // BLP textures (v2)
- {0x584C444D, 0xFFFFFFFF, 0x00000000, 0x00000000, "mdx"}, // MDX files
- {0x45505954, 0xFFFFFFFF, 0x00000000, 0x00000000, "pud"}, // Warcraft II maps
- {0x38464947, 0xFFFFFFFF, 0x00000000, 0x00000000, "gif"}, // GIF images 'GIF8'
- {0x3032444D, 0xFFFFFFFF, 0x00000000, 0x00000000, "m2"}, // WoW ??? .m2
- {0x43424457, 0xFFFFFFFF, 0x00000000, 0x00000000, "dbc"}, // ??? .dbc
- {0x47585053, 0xFFFFFFFF, 0x00000000, 0x00000000, "bls"}, // WoW pixel shaders
- {0xE0FFD8FF, 0xFFFFFFFF, 0x00000000, 0x00000000, "jpg"}, // JPEG image
- {0x00000000, 0x00000000, 0x00000000, 0x00000000, "xxx"}, // Default extension
- {0, 0, 0, 0, NULL} // Terminator
-};
-
-bool WINAPI SFileGetFileName(HANDLE hFile, char * szFileName)
-{
- TFileEntry * pFileEntry;
- TMPQFile * hf = (TMPQFile *)hFile; // MPQ File handle
- char szPseudoName[20];
- DWORD FirstBytes[2]; // The first 4 bytes of the file
- DWORD dwFilePos; // Saved file position
- int nError = ERROR_SUCCESS;
- int i;
-
- // Pre-zero the output buffer
- if(szFileName != NULL)
- *szFileName = 0;
-
- // Check valid parameters
- if(!IsValidFileHandle(hf))
- nError = ERROR_INVALID_HANDLE;
- pFileEntry = hf->pFileEntry;
-
- // Only do something if the file name is not filled
- if(nError == ERROR_SUCCESS && pFileEntry != NULL && pFileEntry->szFileName == NULL)
- {
- // Read the first 2 DWORDs bytes from the file
- FirstBytes[0] = FirstBytes[1] = 0;
- dwFilePos = SFileSetFilePointer(hf, 0, NULL, FILE_CURRENT);
- SFileReadFile(hFile, FirstBytes, sizeof(FirstBytes), NULL);
- BSWAP_ARRAY32_UNSIGNED(FirstBytes, sizeof(FirstBytes));
- SFileSetFilePointer(hf, dwFilePos, NULL, FILE_BEGIN);
-
- // Try to guess file extension from those 2 DWORDs
- for(i = 0; data2ext[i].szExt != NULL; i++)
- {
- if((FirstBytes[0] & data2ext[i].dwOffset00Mask) == data2ext[i].dwOffset00Data &&
- (FirstBytes[1] & data2ext[i].dwOffset04Mask) == data2ext[i].dwOffset04Data)
- {
- sprintf(szPseudoName, "File%08u.%s", (unsigned int)(pFileEntry - hf->ha->pFileTable), data2ext[i].szExt);
- break;
- }
- }
-
- // Put the file name to the file table
- AllocateFileName(pFileEntry, szPseudoName);
- }
-
- // Now put the file name to the file structure
- if(nError == ERROR_SUCCESS && szFileName != NULL)
- {
- if(pFileEntry != NULL && pFileEntry->szFileName != NULL)
- strcpy(szFileName, pFileEntry->szFileName);
- else if(hf->pStream != NULL)
- CopyFileName(szFileName, FileStream_GetFileName(hf->pStream));
- }
- return (nError == ERROR_SUCCESS);
-}
-
-//-----------------------------------------------------------------------------
-// Retrieves an information about an archive or about a file within the archive
-//
-// hMpqOrFile - Handle to an MPQ archive or to a file
-// dwInfoType - Information to obtain
-
-#define VERIFY_MPQ_HANDLE(h) \
- if(!IsValidMpqHandle(h)) \
- { \
- nError = ERROR_INVALID_HANDLE; \
- break; \
- }
-
-#define VERIFY_FILE_HANDLE(h) \
- if(!IsValidFileHandle(h)) \
- { \
- nError = ERROR_INVALID_HANDLE; \
- break; \
- }
-
-bool WINAPI SFileGetFileInfo(
- HANDLE hMpqOrFile,
- DWORD dwInfoType,
- void * pvFileInfo,
- DWORD cbFileInfo,
- LPDWORD pcbLengthNeeded)
-{
- TMPQArchive * ha = (TMPQArchive *)hMpqOrFile;
- TMPQBlock * pBlock;
- TMPQFile * hf = (TMPQFile *)hMpqOrFile;
- void * pvSrcFileInfo = NULL;
- DWORD cbLengthNeeded = 0;
- DWORD dwIsReadOnly;
- DWORD dwFileCount = 0;
- DWORD dwFileIndex;
- DWORD dwFileKey;
- DWORD i;
- int nError = ERROR_SUCCESS;
-
- switch(dwInfoType)
- {
- case SFILE_INFO_ARCHIVE_NAME:
- VERIFY_MPQ_HANDLE(ha);
-
- // pvFileInfo receives the name of the archive, terminated by 0
- pvSrcFileInfo = FileStream_GetFileName(ha->pStream);
- cbLengthNeeded = (DWORD)(_tcslen((TCHAR *)pvSrcFileInfo) + 1) * sizeof(TCHAR);
- break;
-
- case SFILE_INFO_ARCHIVE_SIZE: // Size of the archive
- VERIFY_MPQ_HANDLE(ha);
- cbLengthNeeded = sizeof(DWORD);
- pvSrcFileInfo = &ha->pHeader->dwArchiveSize;
- break;
-
- case SFILE_INFO_MAX_FILE_COUNT: // Max. number of files in the MPQ
- VERIFY_MPQ_HANDLE(ha);
- cbLengthNeeded = sizeof(DWORD);
- pvSrcFileInfo = &ha->dwMaxFileCount;
- break;
-
- case SFILE_INFO_HASH_TABLE_SIZE: // Size of the hash table
- VERIFY_MPQ_HANDLE(ha);
- cbLengthNeeded = sizeof(DWORD);
- pvSrcFileInfo = &ha->pHeader->dwHashTableSize;
- break;
-
- case SFILE_INFO_BLOCK_TABLE_SIZE: // Size of the block table
- VERIFY_MPQ_HANDLE(ha);
- cbLengthNeeded = sizeof(DWORD);
- pvSrcFileInfo = &ha->pHeader->dwBlockTableSize;
- break;
-
- case SFILE_INFO_SECTOR_SIZE:
- VERIFY_MPQ_HANDLE(ha);
- cbLengthNeeded = sizeof(DWORD);
- pvSrcFileInfo = &ha->dwSectorSize;
- break;
-
- case SFILE_INFO_HASH_TABLE:
- VERIFY_MPQ_HANDLE(ha);
- cbLengthNeeded = ha->pHeader->dwHashTableSize * sizeof(TMPQHash);
- pvSrcFileInfo = ha->pHashTable;
- break;
-
- case SFILE_INFO_BLOCK_TABLE:
- VERIFY_MPQ_HANDLE(ha);
- cbLengthNeeded = ha->dwFileTableSize * sizeof(TMPQBlock);
- if(cbFileInfo < cbLengthNeeded)
- {
- nError = ERROR_INSUFFICIENT_BUFFER;
- break;
- }
-
- // Construct block table from file table size
- pBlock = (TMPQBlock *)pvFileInfo;
- for(i = 0; i < ha->dwFileTableSize; i++)
- {
- pBlock->dwFilePos = (DWORD)ha->pFileTable[i].ByteOffset;
- pBlock->dwFSize = ha->pFileTable[i].dwFileSize;
- pBlock->dwCSize = ha->pFileTable[i].dwCmpSize;
- pBlock->dwFlags = ha->pFileTable[i].dwFlags;
- pBlock++;
- }
- break;
-
- case SFILE_INFO_NUM_FILES:
- VERIFY_MPQ_HANDLE(ha);
- dwFileCount = GetMpqFileCount(ha);
- cbLengthNeeded = sizeof(DWORD);
- pvSrcFileInfo = &dwFileCount;
- break;
-
- case SFILE_INFO_STREAM_FLAGS: // Deprecated
- nError = ERROR_INVALID_PARAMETER;
- break;
-
- case SFILE_INFO_IS_READ_ONLY:
- VERIFY_MPQ_HANDLE(ha);
- dwIsReadOnly = (FileStream_IsReadOnly(ha->pStream) || (ha->dwFlags & MPQ_FLAG_READ_ONLY));
- cbLengthNeeded = sizeof(DWORD);
- pvSrcFileInfo = &dwIsReadOnly;
- break;
-
- case SFILE_INFO_HASH_INDEX:
- VERIFY_FILE_HANDLE(hf);
- cbLengthNeeded = sizeof(DWORD);
- pvSrcFileInfo = &hf->pFileEntry->dwHashIndex;
- break;
-
- case SFILE_INFO_CODENAME1:
- VERIFY_FILE_HANDLE(hf);
- cbLengthNeeded = sizeof(DWORD);
- pvSrcFileInfo = &hf->pFileEntry->dwHashIndex;
- if(ha->pHashTable != NULL)
- pvSrcFileInfo = &ha->pHashTable[hf->pFileEntry->dwHashIndex].dwName1;
- break;
-
- case SFILE_INFO_CODENAME2:
- VERIFY_FILE_HANDLE(hf);
- cbLengthNeeded = sizeof(DWORD);
- if(ha->pHashTable != NULL)
- pvSrcFileInfo = &ha->pHashTable[hf->pFileEntry->dwHashIndex].dwName2;
- break;
-
- case SFILE_INFO_LOCALEID:
- VERIFY_FILE_HANDLE(hf);
- cbLengthNeeded = sizeof(DWORD);
- pvSrcFileInfo = &hf->pFileEntry->lcLocale;
- break;
-
- case SFILE_INFO_BLOCKINDEX:
- VERIFY_FILE_HANDLE(hf);
- dwFileIndex = (DWORD)(hf->pFileEntry - hf->ha->pFileTable);
- cbLengthNeeded = sizeof(DWORD);
- pvSrcFileInfo = &dwFileIndex;
- break;
-
- case SFILE_INFO_FILE_SIZE:
- VERIFY_FILE_HANDLE(hf);
- cbLengthNeeded = sizeof(DWORD);
- pvSrcFileInfo = &hf->pFileEntry->dwFileSize;
- break;
-
- case SFILE_INFO_COMPRESSED_SIZE:
- VERIFY_FILE_HANDLE(hf);
- cbLengthNeeded = sizeof(DWORD);
- pvSrcFileInfo = &hf->pFileEntry->dwCmpSize;
- break;
-
- case SFILE_INFO_FLAGS:
- VERIFY_FILE_HANDLE(hf);
- cbLengthNeeded = sizeof(DWORD);
- pvSrcFileInfo = &hf->pFileEntry->dwFlags;
- break;
-
- case SFILE_INFO_POSITION:
- VERIFY_FILE_HANDLE(hf);
- cbLengthNeeded = sizeof(ULONGLONG);
- pvSrcFileInfo = &hf->pFileEntry->ByteOffset;
- break;
-
- case SFILE_INFO_KEY:
- VERIFY_FILE_HANDLE(hf);
- cbLengthNeeded = sizeof(DWORD);
- pvSrcFileInfo = &hf->dwFileKey;
- break;
-
- case SFILE_INFO_KEY_UNFIXED:
- VERIFY_FILE_HANDLE(hf);
- dwFileKey = hf->dwFileKey;
- if(hf->pFileEntry->dwFlags & MPQ_FILE_FIX_KEY)
- dwFileKey = (dwFileKey ^ hf->pFileEntry->dwFileSize) - (DWORD)hf->MpqFilePos;
- cbLengthNeeded = sizeof(DWORD);
- pvSrcFileInfo = &dwFileKey;
- break;
-
- case SFILE_INFO_FILETIME:
- VERIFY_FILE_HANDLE(hf);
- cbLengthNeeded = sizeof(ULONGLONG);
- pvSrcFileInfo = &hf->pFileEntry->FileTime;
- break;
-
- case SFILE_INFO_PATCH_CHAIN:
- VERIFY_FILE_HANDLE(hf);
- GetFilePatchChain(hf, pvFileInfo, cbFileInfo, &cbLengthNeeded);
- break;
-
- default:
- nError = ERROR_INVALID_PARAMETER;
- break;
- }
-
- // If everything is OK so far, copy the information
- if(nError == ERROR_SUCCESS)
- {
- // Is the output buffer large enough?
- if(cbFileInfo >= cbLengthNeeded)
- {
- // Copy the data
- if(pvSrcFileInfo != NULL)
- memcpy(pvFileInfo, pvSrcFileInfo, cbLengthNeeded);
- }
- else
- {
- nError = ERROR_INSUFFICIENT_BUFFER;
- }
-
- // Give the size to the caller
- if(pcbLengthNeeded != NULL)
- *pcbLengthNeeded = cbLengthNeeded;
- }
-
- // Set the last error value, if needed
- if(nError != ERROR_SUCCESS)
- SetLastError(nError);
- return (nError == ERROR_SUCCESS);
-}
diff --git a/dep/StormLib/src/SFileVerify.cpp b/dep/StormLib/src/SFileVerify.cpp
deleted file mode 100644
index 7457171d88f..00000000000
--- a/dep/StormLib/src/SFileVerify.cpp
+++ /dev/null
@@ -1,921 +0,0 @@
-/*****************************************************************************/
-/* SFileVerify.cpp Copyright (c) Ladislav Zezula 2010 */
-/*---------------------------------------------------------------------------*/
-/* MPQ files and MPQ archives verification. */
-/* */
-/* The MPQ signature verification has been written by Jean-Francois Roy */
-/* <bahamut@macstorm.org> and Justin Olbrantz (Quantam). */
-/* The MPQ public keys have been created by MPQKit, using OpenSSL library. */
-/* */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 04.05.10 1.00 Lad The first version of SFileVerify.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "StormCommon.h"
-
-//-----------------------------------------------------------------------------
-// Local defines
-
-#define SIGNATURE_TYPE_NONE 0
-#define SIGNATURE_TYPE_WEAK 1
-#define SIGNATURE_TYPE_STRONG 2
-
-#define MPQ_DIGEST_UNIT_SIZE 0x10000
-
-typedef struct _MPQ_SIGNATURE_INFO
-{
- ULONGLONG BeginMpqData; // File offset where the hashing starts
- ULONGLONG BeginExclude; // Begin of the excluded area (used for (signature) file)
- ULONGLONG EndExclude; // End of the excluded area (used for (signature) file)
- ULONGLONG EndMpqData; // File offset where the hashing ends
- ULONGLONG EndOfFile; // Size of the entire file
- BYTE Signature[MPQ_STRONG_SIGNATURE_SIZE + 0x10];
- DWORD cbSignatureSize; // Length of the signature
- int nSignatureType; // See SIGNATURE_TYPE_XXX
-
-} MPQ_SIGNATURE_INFO, *PMPQ_SIGNATURE_INFO;
-
-//-----------------------------------------------------------------------------
-// Known Blizzard public keys
-// Created by Jean-Francois Roy using OpenSSL
-
-static const char * szBlizzardWeakPublicKey =
- "-----BEGIN PUBLIC KEY-----"
- "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJJidwS/uILMBSO5DLGsBFknIXWWjQJe"
- "2kfdfEk3G/j66w4KkhZ1V61Rt4zLaMVCYpDun7FLwRjkMDSepO1q2DcCAwEAAQ=="
- "-----END PUBLIC KEY-----";
-
-static const char * szBlizzardStrongPublicKey =
- "-----BEGIN PUBLIC KEY-----"
- "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsQZ+ziT2h8h+J/iMQpgd"
- "tH1HaJzOBE3agjU4yMPcrixaPOZoA4t8bwfey7qczfWywocYo3pleytFF+IuD4HD"
- "Fl9OXN1SFyupSgMx1EGZlgbFAomnbq9MQJyMqQtMhRAjFgg4TndS7YNb+JMSAEKp"
- "kXNqY28n/EVBHD5TsMuVCL579gIenbr61dI92DDEdy790IzIG0VKWLh/KOTcTJfm"
- "Ds/7HQTkGouVW+WUsfekuqNQo7ND9DBnhLjLjptxeFE2AZqYcA1ao3S9LN3GL1tW"
- "lVXFIX9c7fWqaVTQlZ2oNsI/ARVApOK3grNgqvwH6YoVYVXjNJEo5sQJsPsdV/hk"
- "dwIDAQAB"
- "-----END PUBLIC KEY-----";
-
-static const char * szWarcraft3MapPublicKey =
- "-----BEGIN PUBLIC KEY-----"
- "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1BwklUUQ3UvjizOBRoF5"
- "yyOVc7KD+oGOQH5i6eUk1yfs0luCC70kNucNrfqhmviywVtahRse1JtXCPrx2bd3"
- "iN8Dx91fbkxjYIOGTsjYoHKTp0BbaFkJih776fcHgnFSb+7mJcDuJVvJOXxEH6w0"
- "1vo6VtujCqj1arqbyoal+xtAaczF3us5cOEp45sR1zAWTn1+7omN7VWV4QqJPaDS"
- "gBSESc0l1grO0i1VUSumayk7yBKIkb+LBvcG6WnYZHCi7VdLmaxER5m8oZfER66b"
- "heHoiSQIZf9PAY6Guw2DT5BTc54j/AaLQAKf2qcRSgQLVo5kQaddF3rCpsXoB/74"
- "6QIDAQAB"
- "-----END PUBLIC KEY-----";
-
-static const char * szWowPatchPublicKey =
- "-----BEGIN PUBLIC KEY-----"
- "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwOsMV0LagAWPEtEQM6b9"
- "6FHFkUyGbbyda2/Dfc9dyl21E9QvX+Yw7qKRMAKPzA2TlQQLZKvXpnKXF/YIK5xa"
- "5uwg9CEHCEAYolLG4xn0FUOE0E/0PuuytI0p0ICe6rk00PifZzTr8na2wI/l/GnQ"
- "bvnIVF1ck6cslATpQJ5JJVMXzoFlUABS19WESw4MXuJAS3AbMhxNWdEhVv7eO51c"
- "yGjRLy9QjogZODZTY0fSEksgBqQxNCoYVJYI/sF5K2flDsGqrIp0OdJ6teJlzg1Y"
- "UjYnb6bKjlidXoHEXI2TgA/mD6O3XFIt08I9s3crOCTgICq7cgX35qrZiIVWZdRv"
- "TwIDAQAB"
- "-----END PUBLIC KEY-----";
-
-static const char * szWowSurveyPublicKey =
- "-----BEGIN PUBLIC KEY-----"
- "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnIt1DR6nRyyKsy2qahHe"
- "MKLtacatn/KxieHcwH87wLBxKy+jZ0gycTmJ7SaTdBAEMDs/V5IPIXEtoqYnid2c"
- "63TmfGDU92oc3Ph1PWUZ2PWxBhT06HYxRdbrgHw9/I29pNPi/607x+lzPORITOgU"
- "BR6MR8au8HsQP4bn4vkJNgnSgojh48/XQOB/cAln7As1neP61NmVimoLR4Bwi3zt"
- "zfgrZaUpyeNCUrOYJmH09YIjbBySTtXOUidoPHjFrMsCWpr6xs8xbETbs7MJFL6a"
- "vcUfTT67qfIZ9RsuKfnXJTIrV0kwDSjjuNXiPTmWAehSsiHIsrUXX5RNcwsSjClr"
- "nQIDAQAB"
- "-----END PUBLIC KEY-----";
-
-static const char * szStarcraft2MapPublicKey =
- "-----BEGIN PUBLIC KEY-----"
- "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmk4GT8zb+ICC25a17KZB"
- "q/ygKGJ2VSO6IT5PGHJlm1KfnHBA4B6SH3xMlJ4c6eG2k7QevZv+FOhjsAHubyWq"
- "2VKqWbrIFKv2ILc2RfMn8J9EDVRxvcxh6slRrVL69D0w1tfVGjMiKq2Fym5yGoRT"
- "E7CRgDqbAbXP9LBsCNWHiJLwfxMGzHbk8pIl9oia5pvM7ofZamSHchxlpy6xa4GJ"
- "7xKN01YCNvklTL1D7uol3wkwcHc7vrF8QwuJizuA5bSg4poEGtH62BZOYi+UL/z0"
- "31YK+k9CbQyM0X0pJoJoYz1TK+Y5J7vBnXCZtfcTYQ/ZzN6UcxTa57dJaiOlCh9z"
- "nQIDAQAB"
- "-----END PUBLIC KEY-----";
-
-//-----------------------------------------------------------------------------
-// Local functions
-
-static void memrev(unsigned char *buf, size_t count)
-{
- unsigned char *r;
-
- for (r = buf + count - 1; buf < r; buf++, r--)
- {
- *buf ^= *r;
- *r ^= *buf;
- *buf ^= *r;
- }
-}
-
-static bool is_valid_md5(void * pvMd5)
-{
- LPDWORD Md5 = (LPDWORD)pvMd5;
-
- return (Md5[0] | Md5[1] | Md5[2] | Md5[3]) ? true : false;
-}
-
-static bool decode_base64_key(const char * szKeyBase64, rsa_key * key)
-{
- unsigned char decoded_key[0x200];
- const char * szBase64Begin;
- const char * szBase64End;
- unsigned long decoded_length = sizeof(decoded_key);
- unsigned long length;
-
- // Find out the begin of the BASE64 data
- szBase64Begin = szKeyBase64 + strlen("-----BEGIN PUBLIC KEY-----");
- szBase64End = szBase64Begin + strlen(szBase64Begin) - strlen("-----END PUBLIC KEY-----");
- if(szBase64End[0] != '-')
- return false;
-
- // decode the base64 string
- length = (unsigned long)(szBase64End - szBase64Begin);
- if(base64_decode((unsigned char *)szBase64Begin, length, decoded_key, &decoded_length) != CRYPT_OK)
- return false;
-
- // Create RSA key
- if(rsa_import(decoded_key, decoded_length, key) != CRYPT_OK)
- return false;
-
- return true;
-}
-
-static void GetPlainAnsiFileName(
- const TCHAR * szFileName,
- char * szPlainName)
-{
- const TCHAR * szPlainNameT = GetPlainFileNameT(szFileName);
-
- // Convert the plain name to ANSI
- while(*szPlainNameT != 0)
- *szPlainName++ = (char)*szPlainNameT++;
- *szPlainName = 0;
-}
-
-// Calculate begin and end of the MPQ archive
-static void CalculateArchiveRange(
- TMPQArchive * ha,
- PMPQ_SIGNATURE_INFO pSI)
-{
- ULONGLONG TempPos = 0;
- char szMapHeader[0x200];
-
- // Get the MPQ begin
- pSI->BeginMpqData = ha->MpqPos;
-
- // Warcraft III maps are signed from the map header to the end
- if(FileStream_Read(ha->pStream, &TempPos, szMapHeader, sizeof(szMapHeader)))
- {
- // Is it a map header ?
- if(szMapHeader[0] == 'H' && szMapHeader[1] == 'M' && szMapHeader[2] == '3' && szMapHeader[3] == 'W')
- {
- // We will have to hash since the map header
- pSI->BeginMpqData = 0;
- }
- }
-
- // Get the MPQ data end. This is stored in our MPQ header,
- // and it's been already prepared by SFileOpenArchive,
- pSI->EndMpqData = ha->MpqPos + ha->pHeader->ArchiveSize64;
-
- // Get the size of the entire file
- FileStream_GetSize(ha->pStream, pSI->EndOfFile);
-}
-
-static bool QueryMpqSignatureInfo(
- TMPQArchive * ha,
- PMPQ_SIGNATURE_INFO pSI)
-{
- ULONGLONG ExtraBytes;
- TMPQFile * hf;
- HANDLE hFile;
- DWORD dwFileSize;
-
- // Calculate the range of the MPQ
- CalculateArchiveRange(ha, pSI);
-
- // If there is "(signature)" file in the MPQ, it has a weak signature
- if(SFileOpenFileEx((HANDLE)ha, SIGNATURE_NAME, SFILE_OPEN_FROM_MPQ, &hFile))
- {
- // Get the content of the signature
- SFileReadFile(hFile, pSI->Signature, sizeof(pSI->Signature), &pSI->cbSignatureSize);
-
- // Verify the size of the signature
- hf = (TMPQFile *)hFile;
-
- // We have to exclude the signature file from the digest
- pSI->BeginExclude = ha->MpqPos + hf->pFileEntry->ByteOffset;
- pSI->EndExclude = pSI->BeginExclude + hf->pFileEntry->dwCmpSize;
- dwFileSize = hf->dwDataSize;
-
- // Close the file
- SFileCloseFile(hFile);
- pSI->nSignatureType = SIGNATURE_TYPE_WEAK;
- return (dwFileSize == (MPQ_WEAK_SIGNATURE_SIZE + 8)) ? true : false;
- }
-
- // If there is extra bytes beyond the end of the archive,
- // it's the strong signature
- ExtraBytes = pSI->EndOfFile - pSI->EndMpqData;
- if(ExtraBytes >= (MPQ_STRONG_SIGNATURE_SIZE + 4))
- {
- // Read the strong signature
- if(!FileStream_Read(ha->pStream, &pSI->EndMpqData, pSI->Signature, (MPQ_STRONG_SIGNATURE_SIZE + 4)))
- return false;
-
- // Check the signature header "NGIS"
- if(pSI->Signature[0] != 'N' || pSI->Signature[1] != 'G' || pSI->Signature[2] != 'I' || pSI->Signature[3] != 'S')
- return false;
-
- pSI->nSignatureType = SIGNATURE_TYPE_STRONG;
- return true;
- }
-
- // Succeeded, but no known signature found
- return true;
-}
-
-static bool CalculateMpqHashMd5(
- TMPQArchive * ha,
- PMPQ_SIGNATURE_INFO pSI,
- LPBYTE pMd5Digest)
-{
- hash_state md5_state;
- ULONGLONG BeginBuffer;
- ULONGLONG EndBuffer;
- LPBYTE pbDigestBuffer = NULL;
-
- // Allocate buffer for creating the MPQ digest.
- pbDigestBuffer = STORM_ALLOC(BYTE, MPQ_DIGEST_UNIT_SIZE);
- if(pbDigestBuffer == NULL)
- return false;
-
- // Initialize the MD5 hash state
- md5_init(&md5_state);
-
- // Set the byte offset of begin of the data
- BeginBuffer = pSI->BeginMpqData;
-
- // Create the digest
- for(;;)
- {
- ULONGLONG BytesRemaining;
- LPBYTE pbSigBegin = NULL;
- LPBYTE pbSigEnd = NULL;
- DWORD dwToRead = MPQ_DIGEST_UNIT_SIZE;
-
- // Check the number of bytes remaining
- BytesRemaining = pSI->EndMpqData - BeginBuffer;
- if(BytesRemaining < MPQ_DIGEST_UNIT_SIZE)
- dwToRead = (DWORD)BytesRemaining;
- if(dwToRead == 0)
- break;
-
- // Read the next chunk
- if(!FileStream_Read(ha->pStream, &BeginBuffer, pbDigestBuffer, dwToRead))
- {
- STORM_FREE(pbDigestBuffer);
- return false;
- }
-
- // Move the current byte offset
- EndBuffer = BeginBuffer + dwToRead;
-
- // Check if the signature is within the loaded digest
- if(BeginBuffer <= pSI->BeginExclude && pSI->BeginExclude < EndBuffer)
- pbSigBegin = pbDigestBuffer + (size_t)(pSI->BeginExclude - BeginBuffer);
- if(BeginBuffer <= pSI->EndExclude && pSI->EndExclude < EndBuffer)
- pbSigEnd = pbDigestBuffer + (size_t)(pSI->EndExclude - BeginBuffer);
-
- // Zero the part that belongs to the signature
- if(pbSigBegin != NULL || pbSigEnd != NULL)
- {
- if(pbSigBegin == NULL)
- pbSigBegin = pbDigestBuffer;
- if(pbSigEnd == NULL)
- pbSigEnd = pbDigestBuffer + dwToRead;
-
- memset(pbSigBegin, 0, (pbSigEnd - pbSigBegin));
- }
-
- // Pass the buffer to the hashing function
- md5_process(&md5_state, pbDigestBuffer, dwToRead);
-
- // Move pointers
- BeginBuffer += dwToRead;
- }
-
- // Finalize the MD5 hash
- md5_done(&md5_state, pMd5Digest);
- STORM_FREE(pbDigestBuffer);
- return true;
-}
-
-static void AddTailToSha1(
- hash_state * psha1_state,
- const char * szTail)
-{
- unsigned char szUpperCase[0x200];
- unsigned long nLength = 0;
-
- // Convert the tail to uppercase
- // Note that we don't need to terminate the string with zero
- while(*szTail != 0)
- {
- szUpperCase[nLength++] = (unsigned char)toupper(*szTail++);
- }
-
- // Append the tail to the SHA1
- sha1_process(psha1_state, szUpperCase, nLength);
-}
-
-static bool CalculateMpqHashSha1(
- TMPQArchive * ha,
- PMPQ_SIGNATURE_INFO pSI,
- unsigned char * sha1_tail0,
- unsigned char * sha1_tail1,
- unsigned char * sha1_tail2)
-{
- ULONGLONG BeginBuffer;
- hash_state sha1_state_temp;
- hash_state sha1_state;
- LPBYTE pbDigestBuffer = NULL;
- char szPlainName[MAX_PATH];
-
- // Allocate buffer for creating the MPQ digest.
- pbDigestBuffer = STORM_ALLOC(BYTE, MPQ_DIGEST_UNIT_SIZE);
- if(pbDigestBuffer == NULL)
- return false;
-
- // Initialize SHA1 state structure
- sha1_init(&sha1_state);
-
- // Calculate begin of data to be hashed
- BeginBuffer = pSI->BeginMpqData;
-
- // Create the digest
- for(;;)
- {
- ULONGLONG BytesRemaining;
- DWORD dwToRead = MPQ_DIGEST_UNIT_SIZE;
-
- // Check the number of bytes remaining
- BytesRemaining = pSI->EndMpqData - BeginBuffer;
- if(BytesRemaining < MPQ_DIGEST_UNIT_SIZE)
- dwToRead = (DWORD)BytesRemaining;
- if(dwToRead == 0)
- break;
-
- // Read the next chunk
- if(!FileStream_Read(ha->pStream, &BeginBuffer, pbDigestBuffer, dwToRead))
- {
- STORM_FREE(pbDigestBuffer);
- return false;
- }
-
- // Pass the buffer to the hashing function
- sha1_process(&sha1_state, pbDigestBuffer, dwToRead);
-
- // Move pointers
- BeginBuffer += dwToRead;
- }
-
- // Add all three known tails and generate three hashes
- memcpy(&sha1_state_temp, &sha1_state, sizeof(hash_state));
- sha1_done(&sha1_state_temp, sha1_tail0);
-
- memcpy(&sha1_state_temp, &sha1_state, sizeof(hash_state));
- GetPlainAnsiFileName(FileStream_GetFileName(ha->pStream), szPlainName);
- AddTailToSha1(&sha1_state_temp, szPlainName);
- sha1_done(&sha1_state_temp, sha1_tail1);
-
- memcpy(&sha1_state_temp, &sha1_state, sizeof(hash_state));
- AddTailToSha1(&sha1_state_temp, "ARCHIVE");
- sha1_done(&sha1_state_temp, sha1_tail2);
-
- // Finalize the MD5 hash
- STORM_FREE(pbDigestBuffer);
- return true;
-}
-
-static int VerifyRawMpqData(
- TMPQArchive * ha,
- ULONGLONG ByteOffset,
- DWORD dwDataSize)
-{
- ULONGLONG DataOffset = ha->MpqPos + ByteOffset;
- LPBYTE pbDataChunk;
- LPBYTE pbMD5Array1; // Calculated MD5 array
- LPBYTE pbMD5Array2; // MD5 array loaded from the MPQ
- DWORD dwBytesInChunk;
- DWORD dwChunkCount;
- DWORD dwChunkSize = ha->pHeader->dwRawChunkSize;
- DWORD dwMD5Size;
- int nError = ERROR_SUCCESS;
-
- // Don't verify zero-sized blocks
- if(dwDataSize == 0)
- return ERROR_SUCCESS;
-
- // Get the number of data chunks to calculate MD5
- assert(dwChunkSize != 0);
- dwChunkCount = ((dwDataSize - 1) / dwChunkSize) + 1;
- dwMD5Size = dwChunkCount * MD5_DIGEST_SIZE;
-
- // Allocate space for data chunk and for the MD5 array
- pbDataChunk = STORM_ALLOC(BYTE, dwChunkSize);
- if(pbDataChunk == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Allocate space for MD5 array
- pbMD5Array1 = STORM_ALLOC(BYTE, dwMD5Size);
- pbMD5Array2 = STORM_ALLOC(BYTE, dwMD5Size);
- if(pbMD5Array1 == NULL || pbMD5Array2 == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
-
- // Calculate MD5 of each data chunk
- if(nError == ERROR_SUCCESS)
- {
- LPBYTE pbMD5 = pbMD5Array1;
-
- for(DWORD i = 0; i < dwChunkCount; i++)
- {
- // Get the number of bytes in the chunk
- dwBytesInChunk = STORMLIB_MIN(dwChunkSize, dwDataSize);
-
- // Read the data chunk
- if(!FileStream_Read(ha->pStream, &DataOffset, pbDataChunk, dwBytesInChunk))
- {
- nError = ERROR_FILE_CORRUPT;
- break;
- }
-
- // Calculate MD5
- CalculateDataBlockHash(pbDataChunk, dwBytesInChunk, pbMD5);
-
- // Move pointers and offsets
- DataOffset += dwBytesInChunk;
- dwDataSize -= dwBytesInChunk;
- pbMD5 += MD5_DIGEST_SIZE;
- }
- }
-
- // Read the MD5 array
- if(nError == ERROR_SUCCESS)
- {
- // Read the array of MD5
- if(!FileStream_Read(ha->pStream, &DataOffset, pbMD5Array2, dwMD5Size))
- nError = GetLastError();
- }
-
- // Compare the array of MD5
- if(nError == ERROR_SUCCESS)
- {
- // Compare the MD5
- if(memcmp(pbMD5Array1, pbMD5Array2, dwMD5Size))
- nError = ERROR_FILE_CORRUPT;
- }
-
- // Free memory and return result
- if(pbMD5Array2 != NULL)
- STORM_FREE(pbMD5Array2);
- if(pbMD5Array1 != NULL)
- STORM_FREE(pbMD5Array1);
- if(pbDataChunk != NULL)
- STORM_FREE(pbDataChunk);
- return nError;
-}
-
-static DWORD VerifyWeakSignature(
- TMPQArchive * ha,
- PMPQ_SIGNATURE_INFO pSI)
-{
- BYTE RevSignature[MPQ_WEAK_SIGNATURE_SIZE];
- BYTE Md5Digest[MD5_DIGEST_SIZE];
- rsa_key key;
- int hash_idx = find_hash("md5");
- int result = 0;
-
- // Calculate hash of the entire archive, skipping the (signature) file
- if(!CalculateMpqHashMd5(ha, pSI, Md5Digest))
- return ERROR_VERIFY_FAILED;
-
- // Import the Blizzard key in OpenSSL format
- if(!decode_base64_key(szBlizzardWeakPublicKey, &key))
- return ERROR_VERIFY_FAILED;
-
- // Verify the signature
- memcpy(RevSignature, &pSI->Signature[8], MPQ_WEAK_SIGNATURE_SIZE);
- memrev(RevSignature, MPQ_WEAK_SIGNATURE_SIZE);
- rsa_verify_hash_ex(RevSignature, MPQ_WEAK_SIGNATURE_SIZE, Md5Digest, sizeof(Md5Digest), LTC_LTC_PKCS_1_V1_5, hash_idx, 0, &result, &key);
- rsa_free(&key);
-
- // Return the result
- return result ? ERROR_WEAK_SIGNATURE_OK : ERROR_WEAK_SIGNATURE_ERROR;
-}
-
-static DWORD VerifyStrongSignatureWithKey(
- unsigned char * reversed_signature,
- unsigned char * padded_digest,
- const char * szPublicKey)
-{
- rsa_key key;
- int result = 0;
-
- // Import the Blizzard key in OpenSSL format
- if(!decode_base64_key(szPublicKey, &key))
- {
- assert(false);
- return ERROR_VERIFY_FAILED;
- }
-
- // Verify the signature
- if(rsa_verify_simple(reversed_signature, MPQ_STRONG_SIGNATURE_SIZE, padded_digest, MPQ_STRONG_SIGNATURE_SIZE, &result, &key) != CRYPT_OK)
- return ERROR_VERIFY_FAILED;
-
- // Free the key and return result
- rsa_free(&key);
- return result ? ERROR_STRONG_SIGNATURE_OK : ERROR_STRONG_SIGNATURE_ERROR;
-}
-
-static DWORD VerifyStrongSignature(
- TMPQArchive * ha,
- PMPQ_SIGNATURE_INFO pSI)
-{
- unsigned char reversed_signature[MPQ_STRONG_SIGNATURE_SIZE];
- unsigned char Sha1Digest_tail0[SHA1_DIGEST_SIZE];
- unsigned char Sha1Digest_tail1[SHA1_DIGEST_SIZE];
- unsigned char Sha1Digest_tail2[SHA1_DIGEST_SIZE];
- unsigned char padded_digest[MPQ_STRONG_SIGNATURE_SIZE];
- DWORD dwResult;
- size_t digest_offset;
-
- // Calculate SHA1 hash of the archive
- if(!CalculateMpqHashSha1(ha, pSI, Sha1Digest_tail0, Sha1Digest_tail1, Sha1Digest_tail2))
- return ERROR_VERIFY_FAILED;
-
- // Prepare the signature for decryption
- memcpy(reversed_signature, &pSI->Signature[4], MPQ_STRONG_SIGNATURE_SIZE);
- memrev(reversed_signature, MPQ_STRONG_SIGNATURE_SIZE);
-
- // Prepare the padded digest for comparison
- digest_offset = sizeof(padded_digest) - SHA1_DIGEST_SIZE;
- memset(padded_digest, 0xbb, digest_offset);
- padded_digest[0] = 0x0b;
-
- // Try Blizzard Strong public key with no SHA1 tail
- memcpy(padded_digest + digest_offset, Sha1Digest_tail0, SHA1_DIGEST_SIZE);
- memrev(padded_digest + digest_offset, SHA1_DIGEST_SIZE);
- dwResult = VerifyStrongSignatureWithKey(reversed_signature, padded_digest, szBlizzardStrongPublicKey);
- if(dwResult == ERROR_STRONG_SIGNATURE_OK)
- return dwResult;
-
- // Try War 3 map public key with plain file name as SHA1 tail
- memcpy(padded_digest + digest_offset, Sha1Digest_tail1, SHA1_DIGEST_SIZE);
- memrev(padded_digest + digest_offset, SHA1_DIGEST_SIZE);
- dwResult = VerifyStrongSignatureWithKey(reversed_signature, padded_digest, szWarcraft3MapPublicKey);
- if(dwResult == ERROR_STRONG_SIGNATURE_OK)
- return dwResult;
-
- // Try WoW-TBC public key with "ARCHIVE" as SHA1 tail
- memcpy(padded_digest + digest_offset, Sha1Digest_tail2, SHA1_DIGEST_SIZE);
- memrev(padded_digest + digest_offset, SHA1_DIGEST_SIZE);
- dwResult = VerifyStrongSignatureWithKey(reversed_signature, padded_digest, szWowPatchPublicKey);
- if(dwResult == ERROR_STRONG_SIGNATURE_OK)
- return dwResult;
-
- // Try Survey public key with no SHA1 tail
- memcpy(padded_digest + digest_offset, Sha1Digest_tail0, SHA1_DIGEST_SIZE);
- memrev(padded_digest + digest_offset, SHA1_DIGEST_SIZE);
- dwResult = VerifyStrongSignatureWithKey(reversed_signature, padded_digest, szWowSurveyPublicKey);
- if(dwResult == ERROR_STRONG_SIGNATURE_OK)
- return dwResult;
-
- // Try Starcraft II public key with no SHA1 tail
- memcpy(padded_digest + digest_offset, Sha1Digest_tail0, SHA1_DIGEST_SIZE);
- memrev(padded_digest + digest_offset, SHA1_DIGEST_SIZE);
- dwResult = VerifyStrongSignatureWithKey(reversed_signature, padded_digest, szStarcraft2MapPublicKey);
- if(dwResult == ERROR_STRONG_SIGNATURE_OK)
- return dwResult;
-
- return ERROR_STRONG_SIGNATURE_ERROR;
-}
-
-static DWORD VerifyFile(
- HANDLE hMpq,
- const char * szFileName,
- LPDWORD pdwCrc32,
- char * pMD5,
- DWORD dwFlags)
-{
- hash_state md5_state;
- unsigned char * pFileMd5;
- unsigned char md5[MD5_DIGEST_SIZE];
- TFileEntry * pFileEntry;
- TMPQFile * hf;
- BYTE Buffer[0x1000];
- HANDLE hFile = NULL;
- DWORD dwVerifyResult = 0;
- DWORD dwSearchScope = SFILE_OPEN_FROM_MPQ;
- DWORD dwTotalBytes = 0;
- DWORD dwBytesRead;
- DWORD dwCrc32 = 0;
-
- // Fix the open type for patched archives
- if(SFileIsPatchedArchive(hMpq))
- dwSearchScope = SFILE_OPEN_PATCHED_FILE;
-
- // If we have to verify raw data MD5, do it before file open
- if(dwFlags & SFILE_VERIFY_RAW_MD5)
- {
- TMPQArchive * ha = (TMPQArchive *)hMpq;
-
- // Parse the base MPQ and all patches
- while(ha != NULL)
- {
- // Does the archive have support for raw MD5?
- if(ha->pHeader->dwRawChunkSize != 0)
- {
- // The file has raw MD5 if the archive supports it
- dwVerifyResult |= VERIFY_FILE_HAS_RAW_MD5;
-
- // Find file entry for the file
- pFileEntry = GetFileEntryLocale(ha, szFileName, lcFileLocale);
- if(pFileEntry != NULL)
- {
- // If the file's raw MD5 doesn't match, don't bother with more checks
- if(VerifyRawMpqData(ha, pFileEntry->ByteOffset, pFileEntry->dwCmpSize) != ERROR_SUCCESS)
- return dwVerifyResult | VERIFY_FILE_RAW_MD5_ERROR;
- }
- }
-
- // Move to the next patch
- ha = ha->haPatch;
- }
- }
-
- // Attempt to open the file
- if(SFileOpenFileEx(hMpq, szFileName, dwSearchScope, &hFile))
- {
- // Get the file size
- hf = (TMPQFile *)hFile;
- pFileEntry = hf->pFileEntry;
- dwTotalBytes = SFileGetFileSize(hFile, NULL);
-
- // Initialize the CRC32 and MD5 contexts
- md5_init(&md5_state);
- dwCrc32 = crc32(0, Z_NULL, 0);
-
- // Also turn on sector checksum verification
- if(dwFlags & SFILE_VERIFY_SECTOR_CRC)
- hf->bCheckSectorCRCs = true;
-
- // Go through entire file and update both CRC32 and MD5
- for(;;)
- {
- // Read data from file
- SFileReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, NULL);
- if(dwBytesRead == 0)
- {
- if(GetLastError() == ERROR_CHECKSUM_ERROR)
- dwVerifyResult |= VERIFY_FILE_SECTOR_CRC_ERROR;
- break;
- }
-
- // Update CRC32 value
- if(dwFlags & SFILE_VERIFY_FILE_CRC)
- dwCrc32 = crc32(dwCrc32, Buffer, dwBytesRead);
-
- // Update MD5 value
- if(dwFlags & SFILE_VERIFY_FILE_MD5)
- md5_process(&md5_state, Buffer, dwBytesRead);
-
- // Decrement the total size
- dwTotalBytes -= dwBytesRead;
- }
-
- // If the file has sector checksums, indicate it in the flags
- if(dwFlags & SFILE_VERIFY_SECTOR_CRC)
- {
- if((hf->pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC) && hf->SectorChksums != NULL && hf->SectorChksums[0] != 0)
- dwVerifyResult |= VERIFY_FILE_HAS_SECTOR_CRC;
- }
-
- // Check if the entire file has been read
- // No point in checking CRC32 and MD5 if not
- // Skip checksum checks if the file has patches
- if(dwTotalBytes == 0)
- {
- // Check CRC32 and MD5 only if there is no patches
- if(hf->hfPatchFile == NULL)
- {
- // Check if the CRC32 matches.
- if(dwFlags & SFILE_VERIFY_FILE_CRC)
- {
- // Only check the CRC32 if it is valid
- if(pFileEntry->dwCrc32 != 0)
- {
- dwVerifyResult |= VERIFY_FILE_HAS_CHECKSUM;
- if(dwCrc32 != pFileEntry->dwCrc32)
- dwVerifyResult |= VERIFY_FILE_CHECKSUM_ERROR;
- }
- }
-
- // Check if MD5 matches
- if(dwFlags & SFILE_VERIFY_FILE_MD5)
- {
- // Patch files have their MD5 saved in the patch info
- pFileMd5 = (hf->pPatchInfo != NULL) ? hf->pPatchInfo->md5 : pFileEntry->md5;
- md5_done(&md5_state, md5);
-
- // Only check the MD5 if it is valid
- if(is_valid_md5(pFileMd5))
- {
- dwVerifyResult |= VERIFY_FILE_HAS_MD5;
- if(memcmp(md5, pFileMd5, MD5_DIGEST_SIZE))
- dwVerifyResult |= VERIFY_FILE_MD5_ERROR;
- }
- }
- }
- else
- {
- // Patched files are MD5-checked automatically
- dwVerifyResult |= VERIFY_FILE_HAS_MD5;
- }
- }
- else
- {
- dwVerifyResult |= VERIFY_READ_ERROR;
- }
-
- SFileCloseFile(hFile);
- }
- else
- {
- // Remember that the file couldn't be open
- dwVerifyResult |= VERIFY_OPEN_ERROR;
- }
-
- // If the caller required CRC32 and/or MD5, give it to him
- if(pdwCrc32 != NULL)
- *pdwCrc32 = dwCrc32;
- if(pMD5 != NULL)
- memcpy(pMD5, md5, MD5_DIGEST_SIZE);
-
- return dwVerifyResult;
-}
-
-//-----------------------------------------------------------------------------
-// Public (exported) functions
-
-bool WINAPI SFileGetFileChecksums(HANDLE hMpq, const char * szFileName, LPDWORD pdwCrc32, char * pMD5)
-{
- DWORD dwVerifyResult;
- DWORD dwVerifyFlags = 0;
-
- if(pdwCrc32 != NULL)
- dwVerifyFlags |= SFILE_VERIFY_FILE_CRC;
- if(pMD5 != NULL)
- dwVerifyFlags |= SFILE_VERIFY_FILE_MD5;
-
- dwVerifyResult = VerifyFile(hMpq,
- szFileName,
- pdwCrc32,
- pMD5,
- dwVerifyFlags);
-
- // If verification failed, return zero
- if(dwVerifyResult & VERIFY_FILE_ERROR_MASK)
- {
- SetLastError(ERROR_FILE_CORRUPT);
- return false;
- }
-
- return true;
-}
-
-
-DWORD WINAPI SFileVerifyFile(HANDLE hMpq, const char * szFileName, DWORD dwFlags)
-{
- return VerifyFile(hMpq,
- szFileName,
- NULL,
- NULL,
- dwFlags);
-}
-
-// Verifies raw data of the archive Only works for MPQs version 4 or newer
-int WINAPI SFileVerifyRawData(HANDLE hMpq, DWORD dwWhatToVerify, const char * szFileName)
-{
- TMPQArchive * ha = (TMPQArchive *)hMpq;
- TFileEntry * pFileEntry;
- TMPQHeader * pHeader;
-
- // Verify input parameters
- if(!IsValidMpqHandle(ha))
- return ERROR_INVALID_PARAMETER;
- pHeader = ha->pHeader;
-
- // If the archive doesn't have raw data MD5, report it as OK
- if(pHeader->dwRawChunkSize == 0)
- return ERROR_SUCCESS;
-
- // If we have to verify MPQ header, do it
- switch(dwWhatToVerify)
- {
- case SFILE_VERIFY_MPQ_HEADER:
-
- // Only if the header is of version 4 or newer
- if(pHeader->dwHeaderSize >= (MPQ_HEADER_SIZE_V4 - MD5_DIGEST_SIZE))
- return VerifyRawMpqData(ha, 0, MPQ_HEADER_SIZE_V4 - MD5_DIGEST_SIZE);
- return ERROR_SUCCESS;
-
- case SFILE_VERIFY_HET_TABLE:
-
- // Only if we have HET table
- if(pHeader->HetTablePos64 && pHeader->HetTableSize64)
- return VerifyRawMpqData(ha, pHeader->HetTablePos64, (DWORD)pHeader->HetTableSize64);
- return ERROR_SUCCESS;
-
- case SFILE_VERIFY_BET_TABLE:
-
- // Only if we have BET table
- if(pHeader->BetTablePos64 && pHeader->BetTableSize64)
- return VerifyRawMpqData(ha, pHeader->BetTablePos64, (DWORD)pHeader->BetTableSize64);
- return ERROR_SUCCESS;
-
- case SFILE_VERIFY_HASH_TABLE:
-
- // Hash table is not protected by MD5
- return ERROR_SUCCESS;
-
- case SFILE_VERIFY_BLOCK_TABLE:
-
- // Block table is not protected by MD5
- return ERROR_SUCCESS;
-
- case SFILE_VERIFY_HIBLOCK_TABLE:
-
- // It is unknown if the hi-block table is protected my MD5 or not.
- return ERROR_SUCCESS;
-
- case SFILE_VERIFY_FILE:
-
- // Verify parameters
- if(szFileName == NULL || *szFileName == 0)
- return ERROR_INVALID_PARAMETER;
-
- // Get the offset of a file
- pFileEntry = GetFileEntryLocale(ha, szFileName, lcFileLocale);
- if(pFileEntry == NULL)
- return ERROR_FILE_NOT_FOUND;
-
- return VerifyRawMpqData(ha, pFileEntry->ByteOffset, pFileEntry->dwCmpSize);
- }
-
- return ERROR_INVALID_PARAMETER;
-}
-
-
-// Verifies the archive against the signature
-DWORD WINAPI SFileVerifyArchive(HANDLE hMpq)
-{
- MPQ_SIGNATURE_INFO si;
- TMPQArchive * ha = (TMPQArchive *)hMpq;
-
- // Verify input parameters
- if(!IsValidMpqHandle(ha))
- return ERROR_VERIFY_FAILED;
-
- // Get the MPQ signature and signature type
- memset(&si, 0, sizeof(MPQ_SIGNATURE_INFO));
- if(!QueryMpqSignatureInfo(ha, &si))
- return ERROR_VERIFY_FAILED;
-
- // Verify the signature
- switch(si.nSignatureType)
- {
- case SIGNATURE_TYPE_NONE:
- return ERROR_NO_SIGNATURE;
-
- case SIGNATURE_TYPE_WEAK:
- return VerifyWeakSignature(ha, &si);
-
- case SIGNATURE_TYPE_STRONG:
- return VerifyStrongSignature(ha, &si);
- }
-
- return ERROR_VERIFY_FAILED;
-}
diff --git a/dep/StormLib/src/StormCommon.h b/dep/StormLib/src/StormCommon.h
deleted file mode 100644
index 9a85c4bd5ac..00000000000
--- a/dep/StormLib/src/StormCommon.h
+++ /dev/null
@@ -1,274 +0,0 @@
-/*****************************************************************************/
-/* SCommon.h Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Common functions for encryption/decryption from Storm.dll. Included by */
-/* SFile*** functions, do not include and do not use this file directly */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 24.03.03 1.00 Lad The first version of SFileCommon.h */
-/* 12.06.04 1.00 Lad Renamed to SCommon.h */
-/* 06.09.10 1.00 Lad Renamed to StormCommon.h */
-/*****************************************************************************/
-
-#ifndef __STORMCOMMON_H__
-#define __STORMCOMMON_H__
-
-//-----------------------------------------------------------------------------
-// Compression support
-
-// Include functions from Pkware Data Compression Library
-#include "pklib/pklib.h"
-
-// Include functions from Huffmann compression
-#include "huffman/huff.h"
-
-// Include functions from IMA ADPCM compression
-#include "adpcm/adpcm.h"
-
-// Include functions from SPARSE compression
-#include "sparse/sparse.h"
-
-// Include functions from LZMA compression
-#include "lzma/C/LzmaEnc.h"
-#include "lzma/C/LzmaDec.h"
-
-// Include functions from zlib
-#ifndef __SYS_ZLIB
- #include "zlib/zlib.h"
-#else
- #include <zlib.h>
-#endif
-
-// Include functions from bzlib
-#ifndef __SYS_BZLIB
- #include "bzip2/bzlib.h"
-#else
- #include <bzlib.h>
-#endif
-
-//-----------------------------------------------------------------------------
-// Cryptography support
-
-// Headers from LibTomCrypt
-#include "libtomcrypt/src/headers/tomcrypt.h"
-
-// For HashStringJenkins
-#include "jenkins/lookup.h"
-
-//-----------------------------------------------------------------------------
-// StormLib private defines
-
-#define ID_MPQ_FILE 0x46494c45 // Used internally for checking TMPQFile ('FILE')
-
-#define MPQ_WEAK_SIGNATURE_SIZE 64
-#define MPQ_STRONG_SIGNATURE_SIZE 256
-
-// Prevent problems with CRT "min" and "max" functions,
-// as they are not defined on all platforms
-#define STORMLIB_MIN(a, b) ((a < b) ? a : b)
-#define STORMLIB_MAX(a, b) ((a > b) ? a : b)
-
-// Macro for building 64-bit file offset from two 32-bit
-#define MAKE_OFFSET64(hi, lo) (((ULONGLONG)hi << 32) | lo)
-
-//-----------------------------------------------------------------------------
-// Memory management
-//
-// We use our own macros for allocating/freeing memory. If you want
-// to redefine them, please keep the following rules
-//
-// - The memory allocation must return NULL if not enough memory
-// (i.e not to throw exception)
-// - It is not necessary to fill the allocated buffer with zeros
-// - Memory freeing function doesn't have to test the pointer to NULL.
-//
-
-#if defined(_MSC_VER) && defined(_DEBUG)
-__inline void * DebugMalloc(char * /* szFile */, int /* nLine */, size_t nSize)
-{
-// return new BYTE[nSize];
- return HeapAlloc(GetProcessHeap(), 0, nSize);
-}
-
-__inline void DebugFree(void * ptr)
-{
-// delete [] ptr;
- HeapFree(GetProcessHeap(), 0, ptr);
-}
-
-#define STORM_ALLOC(type, nitems) (type *)DebugMalloc(__FILE__, __LINE__, (nitems) * sizeof(type))
-#define STORM_FREE(ptr) DebugFree(ptr)
-#else
-
-#define STORM_ALLOC(type, nitems) (type *)malloc((nitems) * sizeof(type))
-#define STORM_FREE(ptr) free(ptr)
-
-#endif
-
-//-----------------------------------------------------------------------------
-// StormLib internal global variables
-
-extern LCID lcFileLocale; // Preferred file locale
-
-//-----------------------------------------------------------------------------
-// Encryption and decryption functions
-
-#define MPQ_HASH_TABLE_INDEX 0x000
-#define MPQ_HASH_NAME_A 0x100
-#define MPQ_HASH_NAME_B 0x200
-#define MPQ_HASH_FILE_KEY 0x300
-
-DWORD HashString(const char * szFileName, DWORD dwHashType);
-
-void InitializeMpqCryptography();
-
-DWORD GetHashTableSizeForFileCount(DWORD dwFileCount);
-
-bool IsPseudoFileName(const char * szFileName, LPDWORD pdwFileIndex);
-ULONGLONG HashStringJenkins(const char * szFileName);
-
-int ConvertMpqHeaderToFormat4(TMPQArchive * ha, ULONGLONG FileSize, DWORD dwFlags);
-
-DWORD GetDefaultSpecialFileFlags(TMPQArchive * ha, DWORD dwFileSize);
-
-void EncryptMpqBlock(void * pvFileBlock, DWORD dwLength, DWORD dwKey);
-void DecryptMpqBlock(void * pvFileBlock, DWORD dwLength, DWORD dwKey);
-
-DWORD DetectFileKeyBySectorSize(LPDWORD SectorOffsets, DWORD decrypted);
-DWORD DetectFileKeyByContent(void * pvFileContent, DWORD dwFileSize);
-DWORD DecryptFileKey(const char * szFileName, ULONGLONG MpqPos, DWORD dwFileSize, DWORD dwFlags);
-
-bool IsValidMD5(LPBYTE pbMd5);
-bool VerifyDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE expected_md5);
-void CalculateDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE md5_hash);
-
-//-----------------------------------------------------------------------------
-// Handle validation functions
-
-bool IsValidMpqHandle(TMPQArchive * ha);
-bool IsValidFileHandle(TMPQFile * hf);
-
-//-----------------------------------------------------------------------------
-// Hash table and block table manipulation
-
-TMPQHash * GetFirstHashEntry(TMPQArchive * ha, const char * szFileName);
-TMPQHash * GetNextHashEntry(TMPQArchive * ha, TMPQHash * pFirstHash, TMPQHash * pPrevHash);
-DWORD AllocateHashEntry(TMPQArchive * ha, TFileEntry * pFileEntry);
-DWORD AllocateHetEntry(TMPQArchive * ha, TFileEntry * pFileEntry);
-
-void FindFreeMpqSpace(TMPQArchive * ha, ULONGLONG * pFreeSpacePos);
-
-// Functions that loads and verifies MPQ data bitmap
-int LoadMpqDataBitmap(TMPQArchive * ha, ULONGLONG FileSize, bool * pbFileIsComplete);
-
-// Functions that load the HET and BET tables
-int CreateHashTable(TMPQArchive * ha, DWORD dwHashTableSize);
-int LoadAnyHashTable(TMPQArchive * ha);
-int BuildFileTable(TMPQArchive * ha, ULONGLONG FileSize);
-int SaveMPQTables(TMPQArchive * ha);
-
-TMPQHetTable * CreateHetTable(DWORD dwMaxFileCount, DWORD dwHashBitSize, bool bCreateEmpty);
-void FreeHetTable(TMPQHetTable * pHetTable);
-
-TMPQBetTable * CreateBetTable(DWORD dwMaxFileCount);
-void FreeBetTable(TMPQBetTable * pBetTable);
-
-// Functions for finding files in the file table
-TFileEntry * GetFileEntryAny(TMPQArchive * ha, const char * szFileName);
-TFileEntry * GetFileEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale);
-TFileEntry * GetFileEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcLocale);
-TFileEntry * GetFileEntryByIndex(TMPQArchive * ha, DWORD dwIndex);
-
-// Allocates file name in the file entry
-void AllocateFileName(TFileEntry * pFileEntry, const char * szFileName);
-
-// Allocates new file entry in the MPQ tables. Reuses existing, if possible
-TFileEntry * FindFreeFileEntry(TMPQArchive * ha);
-TFileEntry * AllocateFileEntry(TMPQArchive * ha, const char * szFileName, LCID lcLocale);
-int RenameFileEntry(TMPQArchive * ha, TFileEntry * pFileEntry, const char * szNewFileName);
-void ClearFileEntry(TMPQArchive * ha, TFileEntry * pFileEntry);
-int FreeFileEntry(TMPQArchive * ha, TFileEntry * pFileEntry);
-
-// Invalidates entries for (listfile) and (attributes)
-void InvalidateInternalFiles(TMPQArchive * ha);
-
-//-----------------------------------------------------------------------------
-// Common functions - MPQ File
-
-TMPQFile * CreateMpqFile(TMPQArchive * ha);
-int LoadMpqTable(TMPQArchive * ha, ULONGLONG ByteOffset, void * pvTable, DWORD dwCompressedSize, DWORD dwRealSize, DWORD dwKey);
-int AllocateSectorBuffer(TMPQFile * hf);
-int AllocatePatchInfo(TMPQFile * hf, bool bLoadFromFile);
-int AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile);
-int AllocateSectorChecksums(TMPQFile * hf, bool bLoadFromFile);
-void CalculateRawSectorOffset(ULONGLONG & RawFilePos, TMPQFile * hf, DWORD dwSectorOffset);
-int WritePatchInfo(TMPQFile * hf);
-int WriteSectorOffsets(TMPQFile * hf);
-int WriteSectorChecksums(TMPQFile * hf);
-int WriteMemDataMD5(TFileStream * pStream, ULONGLONG RawDataOffs, void * pvRawData, DWORD dwRawDataSize, DWORD dwChunkSize, LPDWORD pcbTotalSize);
-int WriteMpqDataMD5(TFileStream * pStream, ULONGLONG RawDataOffs, DWORD dwRawDataSize, DWORD dwChunkSize);
-void FreeMPQFile(TMPQFile *& hf);
-
-bool IsIncrementalPatchFile(const void * pvData, DWORD cbData, LPDWORD pdwPatchedFileSize);
-int PatchFileData(TMPQFile * hf);
-
-void FreeMPQArchive(TMPQArchive *& ha);
-
-//-----------------------------------------------------------------------------
-// Utility functions
-
-bool CheckWildCard(const char * szString, const char * szWildCard);
-const char * GetPlainFileNameA(const char * szFileName);
-const TCHAR * GetPlainFileNameT(const TCHAR * szFileName);
-bool IsInternalMpqFileName(const char * szFileName);
-
-//-----------------------------------------------------------------------------
-// Support for adding files to the MPQ
-
-int SFileAddFile_Init(
- TMPQArchive * ha,
- const char * szArchivedName,
- ULONGLONG ft,
- DWORD dwFileSize,
- LCID lcLocale,
- DWORD dwFlags,
- TMPQFile ** phf
- );
-
-int SFileAddFile_Write(
- TMPQFile * hf,
- const void * pvData,
- DWORD dwSize,
- DWORD dwCompression
- );
-
-int SFileAddFile_Finish(
- TMPQFile * hf
- );
-
-//-----------------------------------------------------------------------------
-// Attributes support
-
-int SAttrLoadAttributes(TMPQArchive * ha);
-int SAttrFileSaveToMpq(TMPQArchive * ha);
-
-//-----------------------------------------------------------------------------
-// Listfile functions
-
-int SListFileSaveToMpq(TMPQArchive * ha);
-
-//-----------------------------------------------------------------------------
-// Dump data support
-
-#ifdef __STORMLIB_DUMP_DATA__
-void DumpMpqHeader(TMPQHeader * pHeader);
-void DumpHetAndBetTable(TMPQHetTable * pHetTable, TMPQBetTable * pBetTable);
-
-#else
-#define DumpMpqHeader(h) /* */
-#define DumpHetAndBetTable(h, b) /* */
-#endif
-
-#endif // __STORMCOMMON_H__
-
diff --git a/dep/StormLib/src/StormLib.h b/dep/StormLib/src/StormLib.h
deleted file mode 100644
index a07ae46ca48..00000000000
--- a/dep/StormLib/src/StormLib.h
+++ /dev/null
@@ -1,984 +0,0 @@
-/*****************************************************************************/
-/* StormLib.h Copyright (c) Ladislav Zezula 1999-2010 */
-/*---------------------------------------------------------------------------*/
-/* StormLib library v 7.02 */
-/* */
-/* Author : Ladislav Zezula */
-/* E-mail : ladik@zezula.net */
-/* WWW : http://www.zezula.net */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* xx.xx.99 1.00 Lad Created */
-/* 24.03.03 2.50 Lad Version 2.50 */
-/* 02.04.03 3.00 Lad Version 3.00 with compression */
-/* 11.04.03 3.01 Lad Renamed to StormLib.h for compatibility with */
-/* original headers for Storm.dll */
-/* 10.05.03 3.02 Lad Added Pkware DCL compression */
-/* 26.05.03 4.00 Lad Completed all compressions */
-/* 18.06.03 4.01 Lad Added SFileSetFileLocale */
-/* Added SFileExtractFile */
-/* 26.07.03 4.02 Lad Implemented nameless rename and delete */
-/* 26.07.03 4.03 Lad Added support for protected MPQs */
-/* 28.08.03 4.10 Lad Fixed bugs that caused StormLib incorrectly work */
-/* with Diablo I savegames and with files having full */
-/* hash table */
-/* 08.12.03 4.11 DCH Fixed bug in reading file sector larger than 0x1000 */
-/* on certain files. */
-/* Fixed bug in AddFile with MPQ_FILE_REPLACE_EXISTING */
-/* (Thanx Daniel Chiamarello, dchiamarello@madvawes.com)*/
-/* 21.12.03 4.50 Lad Completed port for Mac */
-/* Fixed bug in compacting (if fsize is mul of 0x1000) */
-/* Fixed bug in SCompCompress */
-/* 27.05.04 4.51 Lad Changed memory management from new/delete to our */
-/* own macros */
-/* 22.06.04 4.60 Lad Optimized search. Support for multiple listfiles. */
-/* 30.09.04 4.61 Lad Fixed some bugs (Aaargh !!!) */
-/* Correctly works if HashTableSize > BlockTableSize */
-/* 29.12.04 4.70 Lad Fixed compatibility problem with MPQs from WoW */
-/* 14.07.05 5.00 Lad Added the BZLIB compression support */
-/* Added suport of files stored as single unit */
-/* 17.04.06 5.01 Lad Converted to MS Visual Studio 8.0 */
-/* Fixed issue with protected Warcraft 3 protected maps */
-/* 15.05.06 5.02 Lad Fixed issue with WoW 1.10+ */
-/* 07.09.06 5.10 Lad Fixed processing files longer than 2GB */
-/* 22.11.06 6.00 Lad Support for MPQ archives V2 */
-/* 12.06.07 6.10 Lad Support for (attributes) file */
-/* 10.09.07 6.12 Lad Support for MPQs protected by corrupting hash table */
-/* 03.12.07 6.13 Lad Support for MPQs with hash tbl size > block tbl size */
-/* 07.04.08 6.20 Lad Added SFileFlushArchive */
-/* 09.04.08 Lad Removed FilePointer variable from MPQ handle */
-/* structure, as it caused more problems than benefits */
-/* 12.05.08 6.22 Lad Support for w3xMaster map protector */
-/* 05.10.08 6.23 Lad Support for protectors who set negative values in */
-/* the table of file blocks */
-/* 26.05.09 6.24 Lad Fixed search for multiple lang files with deleted */
-/* entries */
-/* 03.09.09 6.25 Lad Fixed decompression bug in huffmann decompression */
-/* 22.03.10 6.50 Lad New compressions in Starcraft II (LZMA, sparse) */
-/* Fixed compacting MPQs that contain single unit files */
-/* 26.04.10 7.00 Lad Major rewrite */
-/* 08.06.10 7.10 Lad Support for partial MPQs */
-/* 08.07.10 7.11 Lad Support for MPQs v 3.0 */
-/* 20.08.10 7.20 Lad Support for opening multiple MPQs in patch mode */
-/* 20.09.10 8.00 Lad MPQs v 4, HET and BET tables */
-/* 07.01.11 8.01 Lad Write support for MPQs v 3 and 4 */
-/* 15.09.11 8.04 Lad Bug fixes, testing for Diablo III MPQs */
-/* 26.04.12 8.10 Lad Support for data map, added SFileGetArchiveBitmap */
-/*****************************************************************************/
-
-#ifndef __STORMLIB_H__
-#define __STORMLIB_H__
-
-#ifdef _MSC_VER
-#pragma warning(disable:4668) // 'XXX' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'
-#pragma warning(disable:4820) // 'XXX' : '2' bytes padding added after data member 'XXX::yyy'
-#endif
-
-#include "StormPort.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//-----------------------------------------------------------------------------
-// Use the apropriate library
-//
-// The library type is encoded in the library name as the following
-// StormLibXYZ.lib
-//
-// X - D for Debug version, R for Release version
-// Y - A for ANSI version, U for Unicode version
-// Z - S for static-linked CRT library, D for multithreaded DLL CRT library
-//
-
-#if 0 && defined(_MSC_VER) && !defined(__STORMLIB_SELF__)
-
- #ifdef _DEBUG // DEBUG VERSIONS
- #ifndef _UNICODE
- #ifdef _DLL
- #pragma comment(lib, "StormLibDAD.lib") // Debug Ansi CRT-DLL version
- #else
- #pragma comment(lib, "StormLibDAS.lib") // Debug Ansi CRT-LIB version
- #endif
- #else
- #ifdef _DLL
- #pragma comment(lib, "StormLibDUD.lib") // Debug Unicode CRT-DLL version
- #else
- #pragma comment(lib, "StormLibDUS.lib") // Debug Unicode CRT-LIB version
- #endif
- #endif
- #else // RELEASE VERSIONS
- #ifndef _UNICODE
- #ifdef _DLL
- #pragma comment(lib, "StormLibRAD.lib") // Release Ansi CRT-DLL version
- #else
- #pragma comment(lib, "StormLibRAS.lib") // Release Ansi CRT-LIB version
- #endif
- #else
- #ifdef _DLL
- #pragma comment(lib, "StormLibRUD.lib") // Release Unicode CRT-DLL version
- #else
- #pragma comment(lib, "StormLibRUS.lib") // Release Unicode CRT-LIB version
- #endif
- #endif
- #endif
-
-#endif
-
-//-----------------------------------------------------------------------------
-// Defines
-
-#define ID_MPQ 0x1A51504D // MPQ archive header ID ('MPQ\x1A')
-#define ID_MPQ_USERDATA 0x1B51504D // MPQ userdata entry ('MPQ\x1B')
-
-#define ERROR_AVI_FILE 10000 // No MPQ file, but AVI file.
-#define ERROR_UNKNOWN_FILE_KEY 10001 // Returned by SFileReadFile when can't find file key
-#define ERROR_CHECKSUM_ERROR 10002 // Returned by SFileReadFile when sector CRC doesn't match
-#define ERROR_INTERNAL_FILE 10003 // The given operation is not allowed on internal file
-#define ERROR_BASE_FILE_MISSING 10004 // The file is present as incremental patch file, but base file is missing
-#define ERROR_MARKED_FOR_DELETE 10005 // The file was marked as "deleted" in the MPQ
-
-// Values for SFileCreateArchive
-#define HASH_TABLE_SIZE_MIN 0x00000004 // Minimum acceptable hash table size
-#define HASH_TABLE_SIZE_DEFAULT 0x00001000 // Default hash table size for empty MPQs
-#define HASH_TABLE_SIZE_MAX 0x00080000 // Maximum acceptable hash table size
-
-#define HASH_ENTRY_DELETED 0xFFFFFFFE // Block index for deleted entry in the hash table
-#define HASH_ENTRY_FREE 0xFFFFFFFF // Block index for free entry in the hash table
-
-#define HET_ENTRY_DELETED 0x80 // HET hash value for a deleted entry
-#define HET_ENTRY_FREE 0x00 // HET hash value for free entry
-
-#define HASH_STATE_SIZE 0x60 // Size of LibTomCrypt's hash_state structure
-
-#define MPQ_PATCH_PREFIX_LEN 0x20 // Maximum length of the patch prefix
-
-// Values for SFileOpenArchive
-#define SFILE_OPEN_HARD_DISK_FILE 2 // Open the archive on HDD
-#define SFILE_OPEN_CDROM_FILE 3 // Open the archive only if it is on CDROM
-
-// Values for SFileOpenFile
-#define SFILE_OPEN_FROM_MPQ 0x00000000 // Open the file from the MPQ archive
-#define SFILE_OPEN_PATCHED_FILE 0x00000001 // Open the file from the MPQ archive
-#define SFILE_OPEN_ANY_LOCALE 0xFFFFFFFE // Reserved for StormLib internal use
-#define SFILE_OPEN_LOCAL_FILE 0xFFFFFFFF // Open a local file
-
-// Flags for TMPQArchive::dwFlags
-#define MPQ_FLAG_READ_ONLY 0x00000001 // If set, the MPQ has been open for read-only access
-#define MPQ_FLAG_CHANGED 0x00000002 // If set, the MPQ tables have been changed
-#define MPQ_FLAG_PROTECTED 0x00000004 // Set on protected MPQs (like W3M maps)
-#define MPQ_FLAG_CHECK_SECTOR_CRC 0x00000008 // Checking sector CRC when reading files
-#define MPQ_FLAG_NEED_FIX_SIZE 0x00000010 // Used during opening the archive
-#define MPQ_FLAG_INV_LISTFILE 0x00000020 // If set, it means that the (listfile) has been invalidated
-#define MPQ_FLAG_INV_ATTRIBUTES 0x00000040 // If set, it means that the (attributes) has been invalidated
-
-// Return value for SFileGetFileSize and SFileSetFilePointer
-#define SFILE_INVALID_SIZE 0xFFFFFFFF
-#define SFILE_INVALID_POS 0xFFFFFFFF
-#define SFILE_INVALID_ATTRIBUTES 0xFFFFFFFF
-
-// Flags for SFileAddFile
-#define MPQ_FILE_IMPLODE 0x00000100 // Implode method (By PKWARE Data Compression Library)
-#define MPQ_FILE_COMPRESS 0x00000200 // Compress methods (By multiple methods)
-#define MPQ_FILE_COMPRESSED 0x0000FF00 // File is compressed
-#define MPQ_FILE_ENCRYPTED 0x00010000 // Indicates whether file is encrypted
-#define MPQ_FILE_FIX_KEY 0x00020000 // File decryption key has to be fixed
-#define MPQ_FILE_PATCH_FILE 0x00100000 // The file is a patch file. Raw file data begin with TPatchInfo structure
-#define MPQ_FILE_SINGLE_UNIT 0x01000000 // File is stored as a single unit, rather than split into sectors (Thx, Quantam)
-#define MPQ_FILE_DELETE_MARKER 0x02000000 // File is a deletion marker. Used in MPQ patches, indicating that the file no longer exists.
-#define MPQ_FILE_SECTOR_CRC 0x04000000 // File has checksums for each sector.
- // Ignored if file is not compressed or imploded.
-#define MPQ_FILE_EXISTS 0x80000000 // Set if file exists, reset when the file was deleted
-#define MPQ_FILE_REPLACEEXISTING 0x80000000 // Replace when the file exist (SFileAddFile)
-
-#define MPQ_FILE_VALID_FLAGS (MPQ_FILE_IMPLODE | \
- MPQ_FILE_COMPRESS | \
- MPQ_FILE_ENCRYPTED | \
- MPQ_FILE_FIX_KEY | \
- MPQ_FILE_PATCH_FILE | \
- MPQ_FILE_SINGLE_UNIT | \
- MPQ_FILE_DELETE_MARKER | \
- MPQ_FILE_SECTOR_CRC | \
- MPQ_FILE_EXISTS)
-
-// Compression types for multiple compressions
-#define MPQ_COMPRESSION_HUFFMANN 0x01 // Huffmann compression (used on WAVE files only)
-#define MPQ_COMPRESSION_ZLIB 0x02 // ZLIB compression
-#define MPQ_COMPRESSION_PKWARE 0x08 // PKWARE DCL compression
-#define MPQ_COMPRESSION_BZIP2 0x10 // BZIP2 compression (added in Warcraft III)
-#define MPQ_COMPRESSION_SPARSE 0x20 // Sparse compression (added in Starcraft 2)
-#define MPQ_COMPRESSION_ADPCM_MONO 0x40 // IMA ADPCM compression (mono)
-#define MPQ_COMPRESSION_ADPCM_STEREO 0x80 // IMA ADPCM compression (stereo)
-#define MPQ_COMPRESSION_LZMA 0x12 // LZMA compression. Added in Starcraft 2. This value is NOT a combination of flags.
-#define MPQ_COMPRESSION_NEXT_SAME 0xFFFFFFFF // Same compression
-
-// Constants for SFileAddWave
-#define MPQ_WAVE_QUALITY_HIGH 0 // Best quality, the worst compression
-#define MPQ_WAVE_QUALITY_MEDIUM 1 // Medium quality, medium compression
-#define MPQ_WAVE_QUALITY_LOW 2 // Low quality, the best compression
-
-// Signatures for HET and BET table
-#define HET_TABLE_SIGNATURE 0x1A544548 // 'HET\x1a'
-#define BET_TABLE_SIGNATURE 0x1A544542 // 'BET\x1a'
-
-// Decryption keys for MPQ tables
-#define MPQ_KEY_HASH_TABLE 0xC3AF3770 // Obtained by HashString("(hash table)", MPQ_HASH_FILE_KEY)
-#define MPQ_KEY_BLOCK_TABLE 0xEC83B3A3 // Obtained by HashString("(block table)", MPQ_HASH_FILE_KEY)
-
-// Block map defines
-#define MPQ_DATA_BITMAP_SIGNATURE 0x33767470 // Signature of the MPQ data bitmap ('ptv3')
-
-// Constants for SFileGetFileInfo
-#define SFILE_INFO_ARCHIVE_NAME 1 // MPQ size (value from header)
-#define SFILE_INFO_ARCHIVE_SIZE 2 // MPQ size (value from header)
-#define SFILE_INFO_MAX_FILE_COUNT 3 // Max number of files in the MPQ
-#define SFILE_INFO_HASH_TABLE_SIZE 4 // Size of hash table, in entries
-#define SFILE_INFO_BLOCK_TABLE_SIZE 5 // Number of entries in the block table
-#define SFILE_INFO_SECTOR_SIZE 6 // Size of file sector (in bytes)
-#define SFILE_INFO_HASH_TABLE 7 // Pointer to Hash table (TMPQHash *)
-#define SFILE_INFO_BLOCK_TABLE 8 // Pointer to Block Table (TMPQBlock *)
-#define SFILE_INFO_NUM_FILES 9 // Real number of files within archive
-#define SFILE_INFO_STREAM_FLAGS 10 // Stream flags for the MPQ. See STREAM_FLAG_XXX
-#define SFILE_INFO_IS_READ_ONLY 11 // TRUE of the MPQ was open as read only
-//------
-#define SFILE_INFO_HASH_INDEX 100 // Hash index of file in MPQ
-#define SFILE_INFO_CODENAME1 101 // The first codename of the file
-#define SFILE_INFO_CODENAME2 102 // The second codename of the file
-#define SFILE_INFO_LOCALEID 103 // Locale ID of file in MPQ
-#define SFILE_INFO_BLOCKINDEX 104 // Index to Block Table
-#define SFILE_INFO_FILE_SIZE 105 // Original file size (from the block table)
-#define SFILE_INFO_COMPRESSED_SIZE 106 // Compressed file size (from the block table)
-#define SFILE_INFO_FLAGS 107 // File flags
-#define SFILE_INFO_POSITION 108 // File position within archive
-#define SFILE_INFO_KEY 109 // File decryption key
-#define SFILE_INFO_KEY_UNFIXED 110 // Decryption key not fixed to file pos and size
-#define SFILE_INFO_FILETIME 111 // TMPQFileTime
-#define SFILE_INFO_PATCH_CHAIN 112 // Chain of patches
-
-#define LISTFILE_NAME "(listfile)" // Name of internal listfile
-#define SIGNATURE_NAME "(signature)" // Name of internal signature
-#define ATTRIBUTES_NAME "(attributes)" // Name of internal attributes file
-#define PATCH_METADATA_NAME "(patch_metadata)"
-
-#define STORMLIB_VERSION 0x080A // Current version of StormLib (8.10)
-#define STORMLIB_VERSION_STRING "8.10"
-
-#define MPQ_FORMAT_VERSION_1 0 // Up to The Burning Crusade
-#define MPQ_FORMAT_VERSION_2 1 // The Burning Crusade and newer
-#define MPQ_FORMAT_VERSION_3 2 // WoW Cataclysm Beta
-#define MPQ_FORMAT_VERSION_4 3 // WoW Cataclysm and newer
-
-// Flags for MPQ attributes
-#define MPQ_ATTRIBUTE_CRC32 0x00000001 // The "(attributes)" contains CRC32 for each file
-#define MPQ_ATTRIBUTE_FILETIME 0x00000002 // The "(attributes)" contains file time for each file
-#define MPQ_ATTRIBUTE_MD5 0x00000004 // The "(attributes)" contains MD5 for each file
-#define MPQ_ATTRIBUTE_PATCH_BIT 0x00000008 // The "(attributes)" contains a patch bit for each file
-#define MPQ_ATTRIBUTE_ALL 0x0000000F // Summary mask
-
-#define MPQ_ATTRIBUTES_V1 100 // (attributes) format version 1.00
-
-// Flags for SFileOpenArchive
-#define BASE_PROVIDER_FILE 0x00000000 // Base data source is a file
-#define BASE_PROVIDER_MAP 0x00000001 // Base data source is memory-mapped file
-#define BASE_PROVIDER_HTTP 0x00000002 // Base data source is a file on web server
-#define BASE_PROVIDER_MASK 0x0000000F // Mask for base provider value
-
-#define STREAM_PROVIDER_LINEAR 0x00000000 // Stream is linear with no offset mapping
-#define STREAM_PROVIDER_PARTIAL 0x00000010 // Stream is partial file (.part)
-#define STREAM_PROVIDER_ENCRYPTED 0x00000020 // Stream is an encrypted MPQ
-#define STREAM_PROVIDER_MASK 0x000000F0 // Mask for stream provider value
-
-#define STREAM_FLAG_READ_ONLY 0x00000100 // Stream is read only
-#define STREAM_FLAG_WRITE_SHARE 0x00000200 // Allow write sharing when open for write
-#define STREAM_FLAG_MASK 0x0000FF00 // Mask for stream flags
-#define STREAM_OPTIONS_MASK 0x0000FFFF // Mask for all stream options
-
-#define MPQ_OPEN_NO_LISTFILE 0x00010000 // Don't load the internal listfile
-#define MPQ_OPEN_NO_ATTRIBUTES 0x00020000 // Don't open the attributes
-#define MPQ_OPEN_FORCE_MPQ_V1 0x00040000 // Always open the archive as MPQ v 1.00, ignore the "wFormatVersion" variable in the header
-#define MPQ_OPEN_CHECK_SECTOR_CRC 0x00080000 // On files with MPQ_FILE_SECTOR_CRC, the CRC will be checked when reading file
-
-// Deprecated
-#define MPQ_OPEN_READ_ONLY STREAM_FLAG_READ_ONLY
-#define MPQ_OPEN_ENCRYPTED STREAM_PROVIDER_ENCRYPTED
-
-// Flags for SFileCreateArchive
-#define MPQ_CREATE_ATTRIBUTES 0x00100000 // Also add the (attributes) file
-#define MPQ_CREATE_ARCHIVE_V1 0x00000000 // Creates archive of version 1 (size up to 4GB)
-#define MPQ_CREATE_ARCHIVE_V2 0x01000000 // Creates archive of version 2 (larger than 4 GB)
-#define MPQ_CREATE_ARCHIVE_V3 0x02000000 // Creates archive of version 3
-#define MPQ_CREATE_ARCHIVE_V4 0x03000000 // Creates archive of version 4
-#define MPQ_CREATE_ARCHIVE_VMASK 0x0F000000 // Mask for archive version
-
-#define FLAGS_TO_FORMAT_SHIFT 24 // (MPQ_CREATE_ARCHIVE_V4 >> FLAGS_TO_FORMAT_SHIFT) => MPQ_FORMAT_VERSION_4
-
-// Flags for SFileVerifyFile
-#define SFILE_VERIFY_SECTOR_CRC 0x00000001 // Verify sector checksum for the file, if available
-#define SFILE_VERIFY_FILE_CRC 0x00000002 // Verify file CRC, if available
-#define SFILE_VERIFY_FILE_MD5 0x00000004 // Verify file MD5, if available
-#define SFILE_VERIFY_RAW_MD5 0x00000008 // Verify raw file MD5, if available
-#define SFILE_VERIFY_ALL 0x0000000F // Verify every checksum possible
-
-// Return values for SFileVerifyFile
-#define VERIFY_OPEN_ERROR 0x0001 // Failed to open the file
-#define VERIFY_READ_ERROR 0x0002 // Failed to read all data from the file
-#define VERIFY_FILE_HAS_SECTOR_CRC 0x0004 // File has sector CRC
-#define VERIFY_FILE_SECTOR_CRC_ERROR 0x0008 // Sector CRC check failed
-#define VERIFY_FILE_HAS_CHECKSUM 0x0010 // File has CRC32
-#define VERIFY_FILE_CHECKSUM_ERROR 0x0020 // CRC32 check failed
-#define VERIFY_FILE_HAS_MD5 0x0040 // File has data MD5
-#define VERIFY_FILE_MD5_ERROR 0x0080 // MD5 check failed
-#define VERIFY_FILE_HAS_RAW_MD5 0x0100 // File has raw data MD5
-#define VERIFY_FILE_RAW_MD5_ERROR 0x0200 // Raw MD5 check failed
-#define VERIFY_FILE_ERROR_MASK (VERIFY_OPEN_ERROR | VERIFY_READ_ERROR | VERIFY_FILE_SECTOR_CRC_ERROR | VERIFY_FILE_CHECKSUM_ERROR | VERIFY_FILE_MD5_ERROR | VERIFY_FILE_RAW_MD5_ERROR)
-
-// Flags for SFileVerifyRawData (for MPQs version 4.0 or higher)
-#define SFILE_VERIFY_MPQ_HEADER 0x0001 // Verify raw MPQ header
-#define SFILE_VERIFY_HET_TABLE 0x0002 // Verify raw data of the HET table
-#define SFILE_VERIFY_BET_TABLE 0x0003 // Verify raw data of the BET table
-#define SFILE_VERIFY_HASH_TABLE 0x0004 // Verify raw data of the hash table
-#define SFILE_VERIFY_BLOCK_TABLE 0x0005 // Verify raw data of the block table
-#define SFILE_VERIFY_HIBLOCK_TABLE 0x0006 // Verify raw data of the hi-block table
-#define SFILE_VERIFY_FILE 0x0007 // Verify raw data of a file
-
-// Return values for SFileVerifyArchive
-#define ERROR_NO_SIGNATURE 0 // There is no signature in the MPQ
-#define ERROR_VERIFY_FAILED 1 // There was an error during verifying signature (like no memory)
-#define ERROR_WEAK_SIGNATURE_OK 2 // There is a weak signature and sign check passed
-#define ERROR_WEAK_SIGNATURE_ERROR 3 // There is a weak signature but sign check failed
-#define ERROR_STRONG_SIGNATURE_OK 4 // There is a strong signature and sign check passed
-#define ERROR_STRONG_SIGNATURE_ERROR 5 // There is a strong signature but sign check failed
-
-#ifndef MD5_DIGEST_SIZE
-#define MD5_DIGEST_SIZE 0x10
-#endif
-
-#ifndef SHA1_DIGEST_SIZE
-#define SHA1_DIGEST_SIZE 0x14 // 160 bits
-#endif
-
-#ifndef LANG_NEUTRAL
-#define LANG_NEUTRAL 0x00 // Neutral locale
-#endif
-
-//-----------------------------------------------------------------------------
-// Callback functions
-
-// Values for compact callback
-#define CCB_CHECKING_FILES 1 // Checking archive (dwParam1 = current, dwParam2 = total)
-#define CCB_CHECKING_HASH_TABLE 2 // Checking hash table (dwParam1 = current, dwParam2 = total)
-#define CCB_COPYING_NON_MPQ_DATA 3 // Copying non-MPQ data: No params used
-#define CCB_COMPACTING_FILES 4 // Compacting archive (dwParam1 = current, dwParam2 = total)
-#define CCB_CLOSING_ARCHIVE 5 // Closing archive: No params used
-
-typedef void (WINAPI * SFILE_ADDFILE_CALLBACK)(void * pvUserData, DWORD dwBytesWritten, DWORD dwTotalBytes, bool bFinalCall);
-typedef void (WINAPI * SFILE_COMPACT_CALLBACK)(void * pvUserData, DWORD dwWorkType, ULONGLONG BytesProcessed, ULONGLONG TotalBytes);
-
-struct TFileStream;
-
-//-----------------------------------------------------------------------------
-// Structure for bit arrays used for HET and BET tables
-
-struct TBitArray
-{
- void GetBits(unsigned int nBitPosition, unsigned int nBitLength, void * pvBuffer, int nResultSize);
- void SetBits(unsigned int nBitPosition, unsigned int nBitLength, void * pvBuffer, int nResultSize);
-
- DWORD NumberOfBits; // Total number of bits that are available
- BYTE Elements[1]; // Array of elements (variable length)
-};
-
-// Structure for file bitmap. Used by SFileGetArchiveBitmap
-struct TFileBitmap
-{
- ULONGLONG StartOffset; // Starting offset of the file, covered by bitmap
- ULONGLONG EndOffset; // Ending offset of the file, covered by bitmap
- DWORD IsComplete; // If nonzero, no blocks are missing
- DWORD BitmapSize; // Size of the file bitmap (in bytes)
- DWORD BlockSize; // Size of one block, in bytes
- DWORD Reserved; // Alignment
-
- // Followed by file bitmap (variable length), array of BYTEs)
-};
-
-//-----------------------------------------------------------------------------
-// Structures related to MPQ format
-//
-// Note: All structures in this header file are supposed to remain private
-// to StormLib. The structures may (and will) change over time, as the MPQ
-// file format evolves. Programmers directly using these structures need to
-// be aware of this. And the last, but not least, NEVER do any modifications
-// to those structures directly, always use SFile* functions.
-//
-
-#define MPQ_HEADER_SIZE_V1 0x20
-#define MPQ_HEADER_SIZE_V2 0x2C
-#define MPQ_HEADER_SIZE_V3 0x44
-#define MPQ_HEADER_SIZE_V4 0xD0
-
-struct TMPQUserData
-{
- // The ID_MPQ_USERDATA ('MPQ\x1B') signature
- DWORD dwID;
-
- // Maximum size of the user data
- DWORD cbUserDataSize;
-
- // Offset of the MPQ header, relative to the begin of this header
- DWORD dwHeaderOffs;
-
- // Appears to be size of user data header (Starcraft II maps)
- DWORD cbUserDataHeader;
-};
-
-// MPQ file header
-//
-// We have to make sure that the header is packed OK.
-// Reason: A 64-bit integer at the beginning of 3.0 part,
-// which is offset 0x2C
-#pragma pack(push, 1)
-struct TMPQHeader
-{
- // The ID_MPQ ('MPQ\x1A') signature
- DWORD dwID;
-
- // Size of the archive header
- DWORD dwHeaderSize;
-
- // 32-bit size of MPQ archive
- // This field is deprecated in the Burning Crusade MoPaQ format, and the size of the archive
- // is calculated as the size from the beginning of the archive to the end of the hash table,
- // block table, or hi-block table (whichever is largest).
- DWORD dwArchiveSize;
-
- // 0 = Format 1 (up to The Burning Crusade)
- // 1 = Format 2 (The Burning Crusade and newer)
- // 2 = Format 3 (WoW - Cataclysm beta or newer)
- // 3 = Format 4 (WoW - Cataclysm beta or newer)
- USHORT wFormatVersion;
-
- // Power of two exponent specifying the number of 512-byte disk sectors in each file sector
- // in the archive. The size of each file sector in the archive is 512 * 2 ^ wSectorSize.
- USHORT wSectorSize;
-
- // Offset to the beginning of the hash table, relative to the beginning of the archive.
- DWORD dwHashTablePos;
-
- // Offset to the beginning of the block table, relative to the beginning of the archive.
- DWORD dwBlockTablePos;
-
- // Number of entries in the hash table. Must be a power of two, and must be less than 2^16 for
- // the original MoPaQ format, or less than 2^20 for the Burning Crusade format.
- DWORD dwHashTableSize;
-
- // Number of entries in the block table
- DWORD dwBlockTableSize;
-
- //-- MPQ HEADER v 2 -------------------------------------------
-
- // Offset to the beginning of array of 16-bit high parts of file offsets.
- ULONGLONG HiBlockTablePos64;
-
- // High 16 bits of the hash table offset for large archives.
- USHORT wHashTablePosHi;
-
- // High 16 bits of the block table offset for large archives.
- USHORT wBlockTablePosHi;
-
- //-- MPQ HEADER v 3 -------------------------------------------
-
- // 64-bit version of the archive size
- ULONGLONG ArchiveSize64;
-
- // 64-bit position of the BET table
- ULONGLONG BetTablePos64;
-
- // 64-bit position of the HET table
- ULONGLONG HetTablePos64;
-
- //-- MPQ HEADER v 4 -------------------------------------------
-
- // Compressed size of the hash table
- ULONGLONG HashTableSize64;
-
- // Compressed size of the block table
- ULONGLONG BlockTableSize64;
-
- // Compressed size of the hi-block table
- ULONGLONG HiBlockTableSize64;
-
- // Compressed size of the HET block
- ULONGLONG HetTableSize64;
-
- // Compressed size of the BET block
- ULONGLONG BetTableSize64;
-
- // Size of raw data chunk to calculate MD5.
- // MD5 of each data chunk follows the raw file data.
- DWORD dwRawChunkSize;
-
- // MD5 of MPQ tables
- unsigned char MD5_BlockTable[MD5_DIGEST_SIZE]; // MD5 of the block table before decryption
- unsigned char MD5_HashTable[MD5_DIGEST_SIZE]; // MD5 of the hash table before decryption
- unsigned char MD5_HiBlockTable[MD5_DIGEST_SIZE]; // MD5 of the hi-block table
- unsigned char MD5_BetTable[MD5_DIGEST_SIZE]; // MD5 of the BET table before decryption
- unsigned char MD5_HetTable[MD5_DIGEST_SIZE]; // MD5 of the HET table before decryption
- unsigned char MD5_MpqHeader[MD5_DIGEST_SIZE]; // MD5 of the MPQ header from signature to (including) MD5_HetTable
-};
-#pragma pack(pop)
-
-
-// Hash entry. All files in the archive are searched by their hashes.
-struct TMPQHash
-{
- // The hash of the file path, using method A.
- DWORD dwName1;
-
- // The hash of the file path, using method B.
- DWORD dwName2;
-
-#ifdef PLATFORM_LITTLE_ENDIAN
-
- // The language of the file. This is a Windows LANGID data type, and uses the same values.
- // 0 indicates the default language (American English), or that the file is language-neutral.
- USHORT lcLocale;
-
- // The platform the file is used for. 0 indicates the default platform.
- // No other values have been observed.
- // Note: wPlatform is actually just BYTE, but since it has never been used, we don't care.
- USHORT wPlatform;
-
-#else
-
- USHORT wPlatform;
- USHORT lcLocale;
-
-#endif
-
- // If the hash table entry is valid, this is the index into the block table of the file.
- // Otherwise, one of the following two values:
- // - FFFFFFFFh: Hash table entry is empty, and has always been empty.
- // Terminates searches for a given file.
- // - FFFFFFFEh: Hash table entry is empty, but was valid at some point (a deleted file).
- // Does not terminate searches for a given file.
- DWORD dwBlockIndex;
-};
-
-
-// File description block contains informations about the file
-struct TMPQBlock
-{
- // Offset of the beginning of the file, relative to the beginning of the archive.
- DWORD dwFilePos;
-
- // Compressed file size
- DWORD dwCSize;
-
- // Only valid if the block is a file; otherwise meaningless, and should be 0.
- // If the file is compressed, this is the size of the uncompressed file data.
- DWORD dwFSize;
-
- // Flags for the file. See MPQ_FILE_XXXX constants
- DWORD dwFlags;
-};
-
-// Patch file information, preceding the sector offset table
-struct TPatchInfo
-{
- DWORD dwLength; // Length of patch info header, in bytes
- DWORD dwFlags; // Flags. 0x80000000 = MD5 (?)
- DWORD dwDataSize; // Uncompressed size of the patch file
- BYTE md5[0x10]; // MD5 of the entire patch file after decompression
-
- // Followed by the sector table (variable length)
-};
-
-// Header for PTCH files
-struct TPatchHeader
-{
- //-- PATCH header -----------------------------------
- DWORD dwSignature; // 'PTCH'
- DWORD dwSizeOfPatchData; // Size of the entire patch (decompressed)
- DWORD dwSizeBeforePatch; // Size of the file before patch
- DWORD dwSizeAfterPatch; // Size of file after patch
-
- //-- MD5 block --------------------------------------
- DWORD dwMD5; // 'MD5_'
- DWORD dwMd5BlockSize; // Size of the MD5 block, including the signature and size itself
- BYTE md5_before_patch[0x10]; // MD5 of the original (unpached) file
- BYTE md5_after_patch[0x10]; // MD5 of the patched file
-
- //-- XFRM block -------------------------------------
- DWORD dwXFRM; // 'XFRM'
- DWORD dwXfrmBlockSize; // Size of the XFRM block, includes XFRM header and patch data
- DWORD dwPatchType; // Type of patch ('BSD0' or 'COPY')
-
- // Followed by the patch data
-};
-
-#define SIZE_OF_XFRM_HEADER 0x0C
-
-// This is the combined file entry for maintaining file list in the MPQ.
-// This structure is combined from block table, hi-block table,
-// (attributes) file and from (listfile).
-struct TFileEntry
-{
- ULONGLONG ByteOffset; // Position of the file content in the MPQ, relative to the MPQ header
- ULONGLONG FileTime; // FileTime from the (attributes) file. 0 if not present.
- ULONGLONG BetHash; // Lower part of the file name hash. Only used when the MPQ has BET table.
- DWORD dwHashIndex; // Index to the hash table. Only used when the MPQ has classic hash table
- DWORD dwHetIndex; // Index to the HET table. Only used when the MPQ has HET table
- DWORD dwFileSize; // Decompressed size of the file
- DWORD dwCmpSize; // Compressed size of the file (i.e., size of the file data in the MPQ)
- DWORD dwFlags; // File flags (from block table)
- USHORT lcLocale; // Locale ID for the file
- USHORT wPlatform; // Platform ID for the file
- DWORD dwCrc32; // CRC32 from (attributes) file. 0 if not present.
- unsigned char md5[MD5_DIGEST_SIZE]; // File MD5 from the (attributes) file. 0 if not present.
- char * szFileName; // File name. NULL if not known.
-};
-
-// Common header for HET and BET tables
-struct TMPQExtTable
-{
- DWORD dwSignature; // 'HET\x1A' or 'BET\x1A'
- DWORD dwVersion; // Version. Seems to be always 1
- DWORD dwDataSize; // Size of the contained table
-
- // Followed by the table header
- // Followed by the table data
-
-};
-
-//
-// MPQ data bitmap, can be found at (FileSize - sizeof(TMPQBlockMap))
-//
-// There is bit map of the entire MPQ before TMPQBitmap. Each 0x4000-byte
-// block is represented by one bit (including the last, eventually incomplete block).
-//
-struct TMPQBitmap
-{
- DWORD dwSignature; // 'ptv3' (MPQ_BLOCK_MAP_SIGNATURE)
- DWORD dwAlways3; // Unknown, seems to always have value of 3
- DWORD dwBuildNumber; // Game build number for that MPQ
- DWORD dwMapOffsetLo; // Low 32-bits of the offset of the bit map
- DWORD dwMapOffsetHi; // High 32-bits of the offset of the bit map
- DWORD dwBlockSize; // Size of one block (usually 0x4000 bytes)
-};
-
-// Structure for parsed HET table
-struct TMPQHetTable
-{
- TBitArray * pBetIndexes; // Bit array of indexes to BET tables
- LPBYTE pHetHashes; // Array of HET hashes. Each entry has size of 1 byte
- ULONGLONG AndMask64; // AND mask used for calculating file name hash
- ULONGLONG OrMask64; // OR mask used for setting the highest bit of the file name hash
-
- DWORD dwIndexSizeTotal; // Total size of one entry in pBetIndexes (in bits)
- DWORD dwIndexSizeExtra; // Extra bits in the entry in pBetIndexes
- DWORD dwIndexSize; // Effective size of one entry in pBetIndexes (in bits)
- DWORD dwMaxFileCount; // Maximum number of files in the MPQ
- DWORD dwHashTableSize; // Number of entries in pBetHashes
- DWORD dwHashBitSize; // Effective number of bits in the hash
-};
-
-// Structure for parsed BET table
-struct TMPQBetTable
-{
- TBitArray * pBetHashes; // Array of BET hashes
- TBitArray * pFileTable; // Bit-based file table
- LPDWORD pFileFlags; // Array of file flags
-
- DWORD dwTableEntrySize; // Size of one table entry, in bits
- DWORD dwBitIndex_FilePos; // Bit index of the file position in the table entry
- DWORD dwBitIndex_FileSize; // Bit index of the file size in the table entry
- DWORD dwBitIndex_CmpSize; // Bit index of the compressed size in the table entry
- DWORD dwBitIndex_FlagIndex; // Bit index of the flag index in the table entry
- DWORD dwBitIndex_Unknown; // Bit index of ??? in the table entry
- DWORD dwBitCount_FilePos; // Size of file offset (in bits) within table entry
- DWORD dwBitCount_FileSize; // Size of file size (in bits) within table entry
- DWORD dwBitCount_CmpSize; // Size of compressed file size (in bits) within table entry
- DWORD dwBitCount_FlagIndex; // Size of flag index (in bits) within table entry
- DWORD dwBitCount_Unknown; // Size of ??? (in bits) within table entry
- DWORD dwBetHashSizeTotal; // Total size of bet hash
- DWORD dwBetHashSizeExtra; // Extra bits in the bet hash
- DWORD dwBetHashSize; // Effective size of the bet hash
- DWORD dwFileCount; // Number of files (usually equal to maximum number of files)
- DWORD dwFlagCount; // Number of entries in pFileFlags
-};
-
-// Archive handle structure
-struct TMPQArchive
-{
- TFileStream * pStream; // Open stream for the MPQ
-
- ULONGLONG UserDataPos; // Position of user data (relative to the begin of the file)
- ULONGLONG MpqPos; // MPQ header offset (relative to the begin of the file)
-
- TMPQArchive * haPatch; // Pointer to patch archive, if any
- TMPQArchive * haBase; // Pointer to base ("previous version") archive, if any
- char szPatchPrefix[MPQ_PATCH_PREFIX_LEN]; // Prefix for file names in patch MPQs
- size_t cchPatchPrefix; // Length of the patch prefix, in characters
-
- TMPQUserData * pUserData; // MPQ user data (NULL if not present in the file)
- TMPQHeader * pHeader; // MPQ file header
- TMPQBitmap * pBitmap; // MPQ bitmap
- TMPQHash * pHashTable; // Hash table
- TMPQHetTable * pHetTable; // Het table
- TFileEntry * pFileTable; // File table
-
- TMPQUserData UserData; // MPQ user data. Valid only when ID_MPQ_USERDATA has been found
- BYTE HeaderData[MPQ_HEADER_SIZE_V4]; // Storage for MPQ header
-
- DWORD dwHETBlockSize;
- DWORD dwBETBlockSize;
- DWORD dwFileTableSize; // Current size of the file table, e.g. index of the entry past the last occupied one
- DWORD dwMaxFileCount; // Maximum number of files in the MPQ
- DWORD dwSectorSize; // Default size of one file sector
- DWORD dwFileFlags1; // Flags for (listfile)
- DWORD dwFileFlags2; // Flags for (attributes)
- DWORD dwAttrFlags; // Flags for the (attributes) file, see MPQ_ATTRIBUTE_XXX
- DWORD dwFlags; // See MPQ_FLAG_XXXXX
-};
-
-// File handle structure
-struct TMPQFile
-{
- TFileStream * pStream; // File stream. Only used on local files
- TMPQArchive * ha; // Archive handle
- TFileEntry * pFileEntry; // File entry for the file
- DWORD dwFileKey; // Decryption key
- DWORD dwFilePos; // Current file position
- ULONGLONG RawFilePos; // Offset in MPQ archive (relative to file begin)
- ULONGLONG MpqFilePos; // Offset in MPQ archive (relative to MPQ header)
- DWORD dwMagic; // 'FILE'
-
- TMPQFile * hfPatchFile; // Pointer to opened patch file
- TPatchHeader * pPatchHeader; // Patch header. Only used if the file is a patch file
- LPBYTE pbFileData; // Loaded and patched file data. Only used if the file is a patch file
- DWORD cbFileData; // Size of loaded patched data
-
- TPatchInfo * pPatchInfo; // Patch info block, preceding the sector table
- DWORD * SectorOffsets; // Position of each file sector, relative to the begin of the file. Only for compressed files.
- DWORD * SectorChksums; // Array of sector checksums (either ADLER32 or MD5) values for each file sector
- DWORD dwSectorCount; // Number of sectors in the file
- DWORD dwPatchedFileSize; // Size of patched file. Used when saving patch file to the MPQ
- DWORD dwDataSize; // Size of data in the file (on patch files, this differs from file size in block table entry)
-
- LPBYTE pbFileSector; // Last loaded file sector. For single unit files, entire file content
- DWORD dwSectorOffs; // File position of currently loaded file sector
- DWORD dwSectorSize; // Size of the file sector. For single unit files, this is equal to the file size
-
- unsigned char hctx[HASH_STATE_SIZE];// Hash state for MD5. Used when saving file to MPQ
- DWORD dwCrc32; // CRC32 value, used when saving file to MPQ
-
- bool bLoadedSectorCRCs; // If true, we already tried to load sector CRCs
- bool bCheckSectorCRCs; // If true, then SFileReadFile will check sector CRCs when reading the file
- bool bIsWriteHandle; // If true, this handle has been created by SFileCreateFile
- bool bErrorOccured; // If true, then at least one error occured during saving the file to the archive
-};
-
-// Structure for SFileFindFirstFile and SFileFindNextFile
-typedef struct _SFILE_FIND_DATA
-{
- char cFileName[MAX_PATH]; // Full name of the found file
- char * szPlainName; // Plain name of the found file
- DWORD dwHashIndex; // Hash table index for the file
- DWORD dwBlockIndex; // Block table index for the file
- DWORD dwFileSize; // File size in bytes
- DWORD dwFileFlags; // MPQ file flags
- DWORD dwCompSize; // Compressed file size
- DWORD dwFileTimeLo; // Low 32-bits of the file time (0 if not present)
- DWORD dwFileTimeHi; // High 32-bits of the file time (0 if not present)
- LCID lcLocale; // Locale version
-
-} SFILE_FIND_DATA, *PSFILE_FIND_DATA;
-
-typedef struct _SFILE_CREATE_MPQ
-{
- DWORD cbSize; // Size of this structure, in bytes
- DWORD dwMpqVersion; // Version of the MPQ to be created
- void *pvUserData; // Reserved, must be NULL
- DWORD cbUserData; // Reserved, must be 0
- DWORD dwStreamFlags; // Stream flags for creating the MPQ
- DWORD dwFileFlags1; // File flags for (listfile). 0 = default
- DWORD dwFileFlags2; // File flags for (attributes). 0 = default
- DWORD dwAttrFlags; // Flags for the (attributes) file. If 0, no attributes will be created
- DWORD dwSectorSize; // Sector size for compressed files
- DWORD dwRawChunkSize; // Size of raw data chunk
- DWORD dwMaxFileCount; // File limit for the MPQ
-
-} SFILE_CREATE_MPQ, *PSFILE_CREATE_MPQ;
-
-//-----------------------------------------------------------------------------
-// Stream support - functions
-
-TFileStream * FileStream_CreateFile(const TCHAR * szFileName, DWORD dwStreamFlags);
-TFileStream * FileStream_OpenFile(const TCHAR * szFileName, DWORD dwStreamFlags);
-TCHAR * FileStream_GetFileName(TFileStream * pStream);
-bool FileStream_IsReadOnly(TFileStream * pStream);
-bool FileStream_Read(TFileStream * pStream, ULONGLONG * pByteOffset, void * pvBuffer, DWORD dwBytesToRead);
-bool FileStream_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const void * pvBuffer, DWORD dwBytesToWrite);
-bool FileStream_GetPos(TFileStream * pStream, ULONGLONG & ByteOffset);
-bool FileStream_SetPos(TFileStream * pStream, ULONGLONG ByteOffset);
-bool FileStream_GetSize(TFileStream * pStream, ULONGLONG & FileSize);
-bool FileStream_SetSize(TFileStream * pStream, ULONGLONG NewFileSize);
-bool FileStream_GetTime(TFileStream * pStream, ULONGLONG * pFT);
-bool FileStream_Switch(TFileStream * pStream, TFileStream * pTempStream);
-bool FileStream_SetBitmap(TFileStream * pStream, TFileBitmap * pBitmap);
-bool FileStream_GetBitmap(TFileStream * pStream, TFileBitmap * pBitmap, DWORD Length, LPDWORD LengthNeeded);
-void FileStream_Close(TFileStream * pStream);
-
-//-----------------------------------------------------------------------------
-// Functions prototypes for Storm.dll
-
-// Typedefs for functions exported by Storm.dll
-typedef LCID (WINAPI * SFILESETLOCALE)(LCID);
-typedef bool (WINAPI * SFILEOPENARCHIVE)(const char *, DWORD, DWORD, HANDLE *);
-typedef bool (WINAPI * SFILECLOSEARCHIVE)(HANDLE);
-typedef bool (WINAPI * SFILEOPENFILEEX)(HANDLE, const char *, DWORD, HANDLE *);
-typedef bool (WINAPI * SFILECLOSEFILE)(HANDLE);
-typedef DWORD (WINAPI * SFILEGETFILESIZE)(HANDLE, LPDWORD);
-typedef DWORD (WINAPI * SFILESETFILEPOINTER)(HANDLE, LONG, LONG *, DWORD);
-typedef bool (WINAPI * SFILEREADFILE)(HANDLE, void *, DWORD, LPDWORD, LPOVERLAPPED);
-
-//-----------------------------------------------------------------------------
-// Functions for manipulation with StormLib global flags
-
-LCID WINAPI SFileGetLocale();
-LCID WINAPI SFileSetLocale(LCID lcNewLocale);
-
-//-----------------------------------------------------------------------------
-// Functions for archive manipulation
-
-bool WINAPI SFileOpenArchive(const TCHAR * szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE * phMpq);
-bool WINAPI SFileCreateArchive(const TCHAR * szMpqName, DWORD dwFlags, DWORD dwMaxFileCount, HANDLE * phMpq);
-bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCreateInfo, HANDLE * phMpq);
-
-bool WINAPI SFileGetArchiveBitmap(HANDLE hMpq, TFileBitmap * pBitmap, DWORD Length, LPDWORD LengthNeeded);
-bool WINAPI SFileFlushArchive(HANDLE hMpq);
-bool WINAPI SFileCloseArchive(HANDLE hMpq);
-
-// Adds another listfile into MPQ. The currently added listfile(s) remain,
-// so you can use this API to combining more listfiles.
-// Note that this function is internally called by SFileFindFirstFile
-int WINAPI SFileAddListFile(HANDLE hMpq, const char * szListFile);
-
-// Archive compacting
-bool WINAPI SFileSetCompactCallback(HANDLE hMpq, SFILE_COMPACT_CALLBACK CompactCB, void * pvData);
-bool WINAPI SFileCompactArchive(HANDLE hMpq, const char * szListFile = NULL, bool bReserved = 0);
-
-// Changing the maximum file count
-DWORD WINAPI SFileGetMaxFileCount(HANDLE hMpq);
-bool WINAPI SFileSetMaxFileCount(HANDLE hMpq, DWORD dwMaxFileCount);
-
-// Changing (attributes) file
-DWORD WINAPI SFileGetAttributes(HANDLE hMpq);
-bool WINAPI SFileSetAttributes(HANDLE hMpq, DWORD dwFlags);
-bool WINAPI SFileUpdateFileAttributes(HANDLE hMpq, const char * szFileName);
-
-//-----------------------------------------------------------------------------
-// Functions for manipulation with patch archives
-
-bool WINAPI SFileOpenPatchArchive(HANDLE hMpq, const TCHAR * szPatchMpqName, const char * szPatchPathPrefix, DWORD dwFlags);
-bool WINAPI SFileIsPatchedArchive(HANDLE hMpq);
-
-//-----------------------------------------------------------------------------
-// Functions for file manipulation
-
-// Reading from MPQ file
-bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope, HANDLE * phFile);
-DWORD WINAPI SFileGetFileSize(HANDLE hFile, LPDWORD pdwFileSizeHigh = NULL);
-DWORD WINAPI SFileSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * plFilePosHigh, DWORD dwMoveMethod);
-bool WINAPI SFileReadFile(HANDLE hFile, void * lpBuffer, DWORD dwToRead, LPDWORD pdwRead = NULL, LPOVERLAPPED lpOverlapped = NULL);
-bool WINAPI SFileCloseFile(HANDLE hFile);
-
-// Retrieving info about the file
-bool WINAPI SFileHasFile(HANDLE hMpq, const char * szFileName);
-bool WINAPI SFileGetFileName(HANDLE hFile, char * szFileName);
-bool WINAPI SFileGetFileInfo(HANDLE hMpqOrFile, DWORD dwInfoType, void * pvFileInfo, DWORD cbFileInfo, LPDWORD pcbLengthNeeded = NULL);
-
-// High-level extract function
-bool WINAPI SFileExtractFile(HANDLE hMpq, const char * szToExtract, const TCHAR * szExtracted, DWORD dwSearchScope = SFILE_OPEN_FROM_MPQ);
-
-//-----------------------------------------------------------------------------
-// Functions for file and archive verification
-
-// Generates file CRC32
-bool WINAPI SFileGetFileChecksums(HANDLE hMpq, const char * szFileName, LPDWORD pdwCrc32, char * pMD5);
-
-// Verifies file against its checksums stored in (attributes) attributes (depending on dwFlags).
-// For dwFlags, use one or more of MPQ_ATTRIBUTE_MD5
-DWORD WINAPI SFileVerifyFile(HANDLE hMpq, const char * szFileName, DWORD dwFlags);
-
-// Verifies raw data of the archive. Only works for MPQs version 4 or newer
-int WINAPI SFileVerifyRawData(HANDLE hMpq, DWORD dwWhatToVerify, const char * szFileName);
-
-// Verifies the signature, if present
-DWORD WINAPI SFileVerifyArchive(HANDLE hMpq);
-
-//-----------------------------------------------------------------------------
-// Functions for file searching
-
-HANDLE WINAPI SFileFindFirstFile(HANDLE hMpq, const char * szMask, SFILE_FIND_DATA * lpFindFileData, const char * szListFile);
-bool WINAPI SFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData);
-bool WINAPI SFileFindClose(HANDLE hFind);
-
-HANDLE WINAPI SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData);
-bool WINAPI SListFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData);
-bool WINAPI SListFileFindClose(HANDLE hFind);
-
-// Locale support
-int WINAPI SFileEnumLocales(HANDLE hMpq, const char * szFileName, LCID * plcLocales, LPDWORD pdwMaxLocales, DWORD dwSearchScope);
-
-//-----------------------------------------------------------------------------
-// Support for adding files to the MPQ
-
-bool WINAPI SFileCreateFile(HANDLE hMpq, const char * szArchivedName, ULONGLONG FileTime, DWORD dwFileSize, LCID lcLocale, DWORD dwFlags, HANDLE * phFile);
-bool WINAPI SFileWriteFile(HANDLE hFile, const void * pvData, DWORD dwSize, DWORD dwCompression);
-bool WINAPI SFileFinishFile(HANDLE hFile);
-
-bool WINAPI SFileAddFileEx(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags, DWORD dwCompression, DWORD dwCompressionNext = MPQ_COMPRESSION_NEXT_SAME);
-bool WINAPI SFileAddFile(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags);
-bool WINAPI SFileAddWave(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags, DWORD dwQuality);
-bool WINAPI SFileRemoveFile(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope = SFILE_OPEN_FROM_MPQ);
-bool WINAPI SFileRenameFile(HANDLE hMpq, const char * szOldFileName, const char * szNewFileName);
-bool WINAPI SFileSetFileLocale(HANDLE hFile, LCID lcNewLocale);
-bool WINAPI SFileSetDataCompression(DWORD DataCompression);
-
-bool WINAPI SFileSetAddFileCallback(HANDLE hMpq, SFILE_ADDFILE_CALLBACK AddFileCB, void * pvData);
-
-//-----------------------------------------------------------------------------
-// Compression and decompression
-
-int WINAPI SCompImplode (char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer);
-int WINAPI SCompExplode (char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer);
-int WINAPI SCompCompress (char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer, unsigned uCompressionMask, int nCmpType, int nCmpLevel);
-int WINAPI SCompDecompress (char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer);
-int WINAPI SCompDecompress2(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer);
-
-//-----------------------------------------------------------------------------
-// Non-Windows support for SetLastError/GetLastError
-
-#ifndef PLATFORM_WINDOWS
-
-void SetLastError(int err);
-int GetLastError();
-
-#endif
-
-//-----------------------------------------------------------------------------
-// Functions from Storm.dll. They use slightly different names for keeping
-// possibility to use them together with StormLib (StormXXX instead of SFileXXX)
-
-#ifdef __LINK_STORM_DLL__
- #define STORM_ALTERNATE_NAMES // Force storm_dll.h to use alternate fnc names
- #include "..\storm_dll\storm_dll.h"
-#endif // __LINK_STORM_DLL__
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // __STORMLIB_H__
diff --git a/dep/StormLib/src/adpcm/adpcm.cpp b/dep/StormLib/src/adpcm/adpcm.cpp
deleted file mode 100644
index 916fa3811a8..00000000000
--- a/dep/StormLib/src/adpcm/adpcm.cpp
+++ /dev/null
@@ -1,358 +0,0 @@
-/*****************************************************************************/
-/* adpcm.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* This module contains implementation of adpcm decompression method used by */
-/* Storm.dll to decompress WAVE files. Thanks to Tom Amigo for releasing */
-/* his sources. */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 11.03.03 1.00 Lad Splitted from Pkware.cpp */
-/* 20.05.03 2.00 Lad Added compression */
-/* 19.11.03 2.01 Dan Big endian handling */
-/*****************************************************************************/
-
-#include "adpcm.h"
-
-//------------------------------------------------------------------------------
-// Structures
-
-typedef union _BYTE_AND_WORD_PTR
-{
- short * pw;
- unsigned char * pb;
-} BYTE_AND_WORD_PTR;
-
-typedef union _WORD_AND_BYTE_ARRAY
-{
- short w;
- unsigned char b[2];
-} WORD_AND_BYTE_ARRAY;
-
-//-----------------------------------------------------------------------------
-// Tables necessary dor decompression
-
-static long Table1503F120[] =
-{
- 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000006,
- 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007,
- 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007,
- 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000006, 0xFFFFFFFF, 0x00000008
-};
-
-static long step_table[] =
-{
- 0x00000007, 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E,
- 0x00000010, 0x00000011, 0x00000013, 0x00000015, 0x00000017, 0x00000019, 0x0000001C, 0x0000001F,
- 0x00000022, 0x00000025, 0x00000029, 0x0000002D, 0x00000032, 0x00000037, 0x0000003C, 0x00000042,
- 0x00000049, 0x00000050, 0x00000058, 0x00000061, 0x0000006B, 0x00000076, 0x00000082, 0x0000008F,
- 0x0000009D, 0x000000AD, 0x000000BE, 0x000000D1, 0x000000E6, 0x000000FD, 0x00000117, 0x00000133,
- 0x00000151, 0x00000173, 0x00000198, 0x000001C1, 0x000001EE, 0x00000220, 0x00000256, 0x00000292,
- 0x000002D4, 0x0000031C, 0x0000036C, 0x000003C3, 0x00000424, 0x0000048E, 0x00000502, 0x00000583,
- 0x00000610, 0x000006AB, 0x00000756, 0x00000812, 0x000008E0, 0x000009C3, 0x00000ABD, 0x00000BD0,
- 0x00000CFF, 0x00000E4C, 0x00000FBA, 0x0000114C, 0x00001307, 0x000014EE, 0x00001706, 0x00001954,
- 0x00001BDC, 0x00001EA5, 0x000021B6, 0x00002515, 0x000028CA, 0x00002CDF, 0x0000315B, 0x0000364B,
- 0x00003BB9, 0x000041B2, 0x00004844, 0x00004F7E, 0x00005771, 0x0000602F, 0x000069CE, 0x00007462,
- 0x00007FFF
-};
-
-//----------------------------------------------------------------------------
-// CompressWave
-
-// 1500EF70
-int CompressADPCM(unsigned char * pbOutBuffer, int dwOutLength, short * pwInBuffer, int dwInLength, int nChannels, int nCmpLevel)
-// ECX EDX
-{
- WORD_AND_BYTE_ARRAY Wcmp;
- BYTE_AND_WORD_PTR out; // Pointer to the output buffer
- long SInt32Array1[2];
- long SInt32Array2[2];
- long SInt32Array3[2];
- long nBytesRemains = dwOutLength; // Number of bytes remaining
- long nWordsRemains; // Number of words remaining
-// unsigned char * pbSaveOutBuffer; // Copy of output buffer (actually not used)
- unsigned long dwBitBuff;
- unsigned long dwStopBit;
- unsigned long dwBit;
- unsigned long ebx;
- unsigned long esi;
- long nTableValue;
- long nOneWord;
- long var_1C;
- long var_2C;
- int nLength;
- int nIndex;
- int nValue;
- int i, chnl;
-
- // If less than 2 bytes remain, don't decompress anything
-// pbSaveOutBuffer = pbOutBuffer;
- out.pb = pbOutBuffer;
- if(nBytesRemains < 2)
- return 2;
-
- Wcmp.b[1] = (unsigned char)(nCmpLevel - 1);
- Wcmp.b[0] = (unsigned char)0;
-
- *out.pw++ = BSWAP_INT16_SIGNED(Wcmp.w);
- if((out.pb - pbOutBuffer + (nChannels * 2)) > nBytesRemains)
- return (int)(out.pb - pbOutBuffer + (nChannels * 2));
-
- SInt32Array1[0] = SInt32Array1[1] = 0x2C;
-
- for(i = 0; i < nChannels; i++)
- {
- nOneWord = BSWAP_INT16_SIGNED(*pwInBuffer++);
- *out.pw++ = BSWAP_INT16_SIGNED((short)nOneWord);
- SInt32Array2[i] = nOneWord;
- }
-
- // Weird. But it's there
- nLength = dwInLength;
- if(nLength < 0) // mov eax, dwInLength; cdq; sub eax, edx;
- nLength++;
-
- nLength = (nLength / 2) - (int)(out.pb - pbOutBuffer);
- nLength = (nLength < 0) ? 0 : nLength;
-
- nIndex = nChannels - 1; // edi
- nWordsRemains = dwInLength / 2; // eax
-
- // ebx - nChannels
- // ecx - pwOutPos
- for(chnl = nChannels; chnl < nWordsRemains; chnl++)
- {
- // 1500F030
- if((out.pb - pbOutBuffer + 2) > nBytesRemains)
- return (int)(out.pb - pbOutBuffer + 2);
-
- // Switch index
- if(nChannels == 2)
- nIndex = (nIndex == 0) ? 1 : 0;
-
- // Load one word from the input stream
- nOneWord = BSWAP_INT16_SIGNED(*pwInBuffer++); // ecx - nOneWord
- SInt32Array3[nIndex] = nOneWord;
-
- // esi - SInt32Array2[nIndex]
- // eax - nValue
- nValue = nOneWord - SInt32Array2[nIndex];
- nValue = (nValue < 0) ? ((nValue ^ 0xFFFFFFFF) + 1) : nValue;
-
- ebx = (nOneWord >= SInt32Array2[nIndex]) ? 0 : 0x40;
-
- // esi - SInt32Array2[nIndex]
- // edx - step_table[SInt32Array2[nIndex]]
- // edi - (step_table[SInt32Array1[nIndex]] >> nCmpLevel)
- nTableValue = step_table[SInt32Array1[nIndex]];
- dwStopBit = (unsigned long)nCmpLevel;
-
- // edi - nIndex;
- if(nValue < (nTableValue >> nCmpLevel))
- {
- if(SInt32Array1[nIndex] != 0)
- SInt32Array1[nIndex]--;
- *out.pb++ = 0x80;
- }
- else
- {
- while(nValue > nTableValue * 2)
- {
- if(SInt32Array1[nIndex] >= 0x58 || nLength == 0)
- break;
-
- SInt32Array1[nIndex] += 8;
- if(SInt32Array1[nIndex] > 0x58)
- SInt32Array1[nIndex] = 0x58;
-
- nTableValue = step_table[SInt32Array1[nIndex]];
- *out.pb++ = 0x81;
- nLength--;
- }
-
- var_2C = nTableValue >> Wcmp.b[1];
- dwBitBuff = 0;
-
- esi = (1 << (dwStopBit - 2));
- dwStopBit = (esi <= 0x20) ? esi : 0x20;
-
- for(var_1C = 0, dwBit = 1; ; dwBit <<= 1)
- {
-// esi = var_1C + nTableValue;
- if((var_1C + nTableValue) <= nValue)
- {
- var_1C += nTableValue;
- dwBitBuff |= dwBit;
- }
- if(dwBit == dwStopBit)
- break;
-
- nTableValue >>= 1;
- }
-
- nValue = SInt32Array2[nIndex];
- if(ebx != 0)
- {
- nValue -= (var_1C + var_2C);
- if(nValue < -32768)
- nValue = -32768;
- }
- else
- {
- nValue += (var_1C + var_2C);
- if(nValue > 32767)
- nValue = 32767;
- }
-
- SInt32Array2[nIndex] = nValue;
- *out.pb++ = (unsigned char)(dwBitBuff | ebx);
- nTableValue = Table1503F120[dwBitBuff & 0x1F];
- SInt32Array1[nIndex] = SInt32Array1[nIndex] + nTableValue;
- if(SInt32Array1[nIndex] < 0)
- SInt32Array1[nIndex] = 0;
- else if(SInt32Array1[nIndex] > 0x58)
- SInt32Array1[nIndex] = 0x58;
- }
- }
-
- return (int)(out.pb - pbOutBuffer);
-}
-
-//----------------------------------------------------------------------------
-// DecompressADPCM
-
-// 1500F230
-int DecompressADPCM(unsigned char * pbOutBuffer, int dwOutLength, unsigned char * pbInBuffer, int dwInLength, int nChannels)
-{
- BYTE_AND_WORD_PTR out; // Output buffer
- BYTE_AND_WORD_PTR in;
- unsigned char * pbInBufferEnd = (pbInBuffer + dwInLength);
- long SInt32Array1[2];
- long SInt32Array2[2];
- long nOneWord;
- int nIndex;
- int i;
-
- SInt32Array1[0] = SInt32Array1[1] = 0x2C;
- out.pb = pbOutBuffer;
- in.pb = pbInBuffer;
- in.pw++;
-
- // Fill the Uint32Array2 array by channel values.
- for(i = 0; i < nChannels; i++)
- {
- nOneWord = BSWAP_INT16_SIGNED(*in.pw++);
- SInt32Array2[i] = nOneWord;
- if(dwOutLength < 2)
- return (int)(out.pb - pbOutBuffer);
-
- *out.pw++ = BSWAP_INT16_SIGNED((short)nOneWord);
- dwOutLength -= sizeof(short);
- }
-
- // Get the initial index
- nIndex = nChannels - 1;
-
- // Perform the decompression
- while(in.pb < pbInBufferEnd)
- {
- unsigned char nOneByte = *in.pb++;
-
- // Switch index
- if(nChannels == 2)
- nIndex = (nIndex == 0) ? 1 : 0;
-
- // 1500F2A2: Get one byte from input buffer
- if(nOneByte & 0x80)
- {
- switch(nOneByte & 0x7F)
- {
- case 0: // 1500F315
- if(SInt32Array1[nIndex] != 0)
- SInt32Array1[nIndex]--;
-
- if(dwOutLength < 2)
- return (int)(out.pb - pbOutBuffer);
-
- *out.pw++ = BSWAP_INT16_SIGNED((unsigned short)SInt32Array2[nIndex]);
- dwOutLength -= sizeof(unsigned short);
- break;
-
- case 1: // 1500F2E8
- SInt32Array1[nIndex] += 8;
- if(SInt32Array1[nIndex] > 0x58)
- SInt32Array1[nIndex] = 0x58;
-
- if(nChannels == 2)
- nIndex = (nIndex == 0) ? 1 : 0;
- break;
-
- case 2: // 1500F41E
- break;
-
- default: // 1500F2C4
- SInt32Array1[nIndex] -= 8;
- if(SInt32Array1[nIndex] < 0)
- SInt32Array1[nIndex] = 0;
-
- if(nChannels == 2)
- nIndex = (nIndex == 0) ? 1 : 0;
- break;
- }
- }
- else
- {
- // 1500F349
- long temp1 = step_table[SInt32Array1[nIndex]]; // EDI
- long temp2 = temp1 >> pbInBuffer[1]; // ESI
- long temp3 = SInt32Array2[nIndex]; // ECX
-
- if(nOneByte & 0x01) // EBX = nOneByte
- temp2 += (temp1 >> 0);
-
- if(nOneByte & 0x02)
- temp2 += (temp1 >> 1);
-
- if(nOneByte & 0x04)
- temp2 += (temp1 >> 2);
-
- if(nOneByte & 0x08)
- temp2 += (temp1 >> 3);
-
- if(nOneByte & 0x10)
- temp2 += (temp1 >> 4);
-
- if(nOneByte & 0x20)
- temp2 += (temp1 >> 5);
-
- if(nOneByte & 0x40)
- {
- temp3 = temp3 - temp2;
- if(temp3 <= -32768)
- temp3 = -32768;
- }
- else
- {
- temp3 = temp3 + temp2;
- if(temp3 >= 32767)
- temp3 = 32767;
- }
-
- SInt32Array2[nIndex] = temp3;
- if(dwOutLength < 2)
- break;
-
- // Store the output 16-bit value
- *out.pw++ = BSWAP_INT16_SIGNED((short)SInt32Array2[nIndex]);
- dwOutLength -= 2;
-
- SInt32Array1[nIndex] += Table1503F120[nOneByte & 0x1F];
-
- if(SInt32Array1[nIndex] < 0)
- SInt32Array1[nIndex] = 0;
- else if(SInt32Array1[nIndex] > 0x58)
- SInt32Array1[nIndex] = 0x58;
- }
- }
- return (int)(out.pb - pbOutBuffer);
-}
diff --git a/dep/StormLib/src/adpcm/adpcm.h b/dep/StormLib/src/adpcm/adpcm.h
deleted file mode 100644
index beb96159720..00000000000
--- a/dep/StormLib/src/adpcm/adpcm.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*****************************************************************************/
-/* adpcm.h Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Header file for adpcm decompress functions */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 31.03.03 1.00 Lad The first version of adpcm.h */
-/*****************************************************************************/
-
-#ifndef __ADPCM_H__
-#define __ADPCM_H__
-
-//-----------------------------------------------------------------------------
-// Functions
-
-#include "../StormPort.h"
-
-int CompressADPCM (unsigned char * pbOutBuffer, int dwOutLength, short * pwInBuffer, int dwInLength, int nCmpType, int nChannels);
-int DecompressADPCM(unsigned char * pbOutBuffer, int dwOutLength, unsigned char * pbInBuffer, int dwInLength, int nChannels);
-
-#endif // __ADPCM_H__
diff --git a/dep/StormLib/src/bzip2/blocksort.c b/dep/StormLib/src/bzip2/blocksort.c
deleted file mode 100644
index bd2dec157fa..00000000000
--- a/dep/StormLib/src/bzip2/blocksort.c
+++ /dev/null
@@ -1,1094 +0,0 @@
-
-/*-------------------------------------------------------------*/
-/*--- Block sorting machinery ---*/
-/*--- blocksort.c ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
- This file is part of bzip2/libbzip2, a program and library for
- lossless, block-sorting data compression.
-
- bzip2/libbzip2 version 1.0.5 of 10 December 2007
- Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
-
- Please read the WARNING, DISCLAIMER and PATENTS sections in the
- README file.
-
- This program is released under the terms of the license contained
- in the file LICENSE.
- ------------------------------------------------------------------ */
-
-
-#include "bzlib_private.h"
-
-/*---------------------------------------------*/
-/*--- Fallback O(N log(N)^2) sorting ---*/
-/*--- algorithm, for repetitive blocks ---*/
-/*---------------------------------------------*/
-
-/*---------------------------------------------*/
-static
-__inline__
-void fallbackSimpleSort ( UInt32* fmap,
- UInt32* eclass,
- Int32 lo,
- Int32 hi )
-{
- Int32 i, j, tmp;
- UInt32 ec_tmp;
-
- if (lo == hi) return;
-
- if (hi - lo > 3) {
- for ( i = hi-4; i >= lo; i-- ) {
- tmp = fmap[i];
- ec_tmp = eclass[tmp];
- for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
- fmap[j-4] = fmap[j];
- fmap[j-4] = tmp;
- }
- }
-
- for ( i = hi-1; i >= lo; i-- ) {
- tmp = fmap[i];
- ec_tmp = eclass[tmp];
- for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
- fmap[j-1] = fmap[j];
- fmap[j-1] = tmp;
- }
-}
-
-
-/*---------------------------------------------*/
-#define fswap(zz1, zz2) \
- { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
-
-#define fvswap(zzp1, zzp2, zzn) \
-{ \
- Int32 yyp1 = (zzp1); \
- Int32 yyp2 = (zzp2); \
- Int32 yyn = (zzn); \
- while (yyn > 0) { \
- fswap(fmap[yyp1], fmap[yyp2]); \
- yyp1++; yyp2++; yyn--; \
- } \
-}
-
-
-#define fmin(a,b) ((a) < (b)) ? (a) : (b)
-
-#define fpush(lz,hz) { stackLo[sp] = lz; \
- stackHi[sp] = hz; \
- sp++; }
-
-#define fpop(lz,hz) { sp--; \
- lz = stackLo[sp]; \
- hz = stackHi[sp]; }
-
-#define FALLBACK_QSORT_SMALL_THRESH 10
-#define FALLBACK_QSORT_STACK_SIZE 100
-
-
-static
-void fallbackQSort3 ( UInt32* fmap,
- UInt32* eclass,
- Int32 loSt,
- Int32 hiSt )
-{
- Int32 unLo, unHi, ltLo, gtHi, n, m;
- Int32 sp, lo, hi;
- UInt32 med, r, r3;
- Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
- Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
-
- r = 0;
-
- sp = 0;
- fpush ( loSt, hiSt );
-
- while (sp > 0) {
-
- AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 );
-
- fpop ( lo, hi );
- if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
- fallbackSimpleSort ( fmap, eclass, lo, hi );
- continue;
- }
-
- /* Random partitioning. Median of 3 sometimes fails to
- avoid bad cases. Median of 9 seems to help but
- looks rather expensive. This too seems to work but
- is cheaper. Guidance for the magic constants
- 7621 and 32768 is taken from Sedgewick's algorithms
- book, chapter 35.
- */
- r = ((r * 7621) + 1) % 32768;
- r3 = r % 3;
- if (r3 == 0) med = eclass[fmap[lo]]; else
- if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
- med = eclass[fmap[hi]];
-
- unLo = ltLo = lo;
- unHi = gtHi = hi;
-
- while (1) {
- while (1) {
- if (unLo > unHi) break;
- n = (Int32)eclass[fmap[unLo]] - (Int32)med;
- if (n == 0) {
- fswap(fmap[unLo], fmap[ltLo]);
- ltLo++; unLo++;
- continue;
- };
- if (n > 0) break;
- unLo++;
- }
- while (1) {
- if (unLo > unHi) break;
- n = (Int32)eclass[fmap[unHi]] - (Int32)med;
- if (n == 0) {
- fswap(fmap[unHi], fmap[gtHi]);
- gtHi--; unHi--;
- continue;
- };
- if (n < 0) break;
- unHi--;
- }
- if (unLo > unHi) break;
- fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
- }
-
- AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
-
- if (gtHi < ltLo) continue;
-
- n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
- m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
-
- n = lo + unLo - ltLo - 1;
- m = hi - (gtHi - unHi) + 1;
-
- if (n - lo > hi - m) {
- fpush ( lo, n );
- fpush ( m, hi );
- } else {
- fpush ( m, hi );
- fpush ( lo, n );
- }
- }
-}
-
-#undef fmin
-#undef fpush
-#undef fpop
-#undef fswap
-#undef fvswap
-#undef FALLBACK_QSORT_SMALL_THRESH
-#undef FALLBACK_QSORT_STACK_SIZE
-
-
-/*---------------------------------------------*/
-/* Pre:
- nblock > 0
- eclass exists for [0 .. nblock-1]
- ((UChar*)eclass) [0 .. nblock-1] holds block
- ptr exists for [0 .. nblock-1]
-
- Post:
- ((UChar*)eclass) [0 .. nblock-1] holds block
- All other areas of eclass destroyed
- fmap [0 .. nblock-1] holds sorted order
- bhtab [ 0 .. 2+(nblock/32) ] destroyed
-*/
-
-#define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
-#define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
-#define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
-#define WORD_BH(zz) bhtab[(zz) >> 5]
-#define UNALIGNED_BH(zz) ((zz) & 0x01f)
-
-static
-void fallbackSort ( UInt32* fmap,
- UInt32* eclass,
- UInt32* bhtab,
- Int32 nblock,
- Int32 verb )
-{
- Int32 ftab[257];
- Int32 ftabCopy[256];
- Int32 H, i, j, k, l, r, cc, cc1;
- Int32 nNotDone;
- Int32 nBhtab;
- UChar* eclass8 = (UChar*)eclass;
-
- /*--
- Initial 1-char radix sort to generate
- initial fmap and initial BH bits.
- --*/
- if (verb >= 4)
- VPrintf0 ( " bucket sorting ...\n" );
- for (i = 0; i < 257; i++) ftab[i] = 0;
- for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
- for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i];
- for (i = 1; i < 257; i++) ftab[i] += ftab[i-1];
-
- for (i = 0; i < nblock; i++) {
- j = eclass8[i];
- k = ftab[j] - 1;
- ftab[j] = k;
- fmap[k] = i;
- }
-
- nBhtab = 2 + (nblock / 32);
- for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
- for (i = 0; i < 256; i++) SET_BH(ftab[i]);
-
- /*--
- Inductively refine the buckets. Kind-of an
- "exponential radix sort" (!), inspired by the
- Manber-Myers suffix array construction algorithm.
- --*/
-
- /*-- set sentinel bits for block-end detection --*/
- for (i = 0; i < 32; i++) {
- SET_BH(nblock + 2*i);
- CLEAR_BH(nblock + 2*i + 1);
- }
-
- /*-- the log(N) loop --*/
- H = 1;
- while (1) {
-
- if (verb >= 4)
- VPrintf1 ( " depth %6d has ", H );
-
- j = 0;
- for (i = 0; i < nblock; i++) {
- if (ISSET_BH(i)) j = i;
- k = fmap[i] - H; if (k < 0) k += nblock;
- eclass[k] = j;
- }
-
- nNotDone = 0;
- r = -1;
- while (1) {
-
- /*-- find the next non-singleton bucket --*/
- k = r + 1;
- while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
- if (ISSET_BH(k)) {
- while (WORD_BH(k) == 0xffffffff) k += 32;
- while (ISSET_BH(k)) k++;
- }
- l = k - 1;
- if (l >= nblock) break;
- while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
- if (!ISSET_BH(k)) {
- while (WORD_BH(k) == 0x00000000) k += 32;
- while (!ISSET_BH(k)) k++;
- }
- r = k - 1;
- if (r >= nblock) break;
-
- /*-- now [l, r] bracket current bucket --*/
- if (r > l) {
- nNotDone += (r - l + 1);
- fallbackQSort3 ( fmap, eclass, l, r );
-
- /*-- scan bucket and generate header bits-- */
- cc = -1;
- for (i = l; i <= r; i++) {
- cc1 = eclass[fmap[i]];
- if (cc != cc1) { SET_BH(i); cc = cc1; };
- }
- }
- }
-
- if (verb >= 4)
- VPrintf1 ( "%6d unresolved strings\n", nNotDone );
-
- H *= 2;
- if (H > nblock || nNotDone == 0) break;
- }
-
- /*--
- Reconstruct the original block in
- eclass8 [0 .. nblock-1], since the
- previous phase destroyed it.
- --*/
- if (verb >= 4)
- VPrintf0 ( " reconstructing block ...\n" );
- j = 0;
- for (i = 0; i < nblock; i++) {
- while (ftabCopy[j] == 0) j++;
- ftabCopy[j]--;
- eclass8[fmap[i]] = (UChar)j;
- }
- AssertH ( j < 256, 1005 );
-}
-
-#undef SET_BH
-#undef CLEAR_BH
-#undef ISSET_BH
-#undef WORD_BH
-#undef UNALIGNED_BH
-
-
-/*---------------------------------------------*/
-/*--- The main, O(N^2 log(N)) sorting ---*/
-/*--- algorithm. Faster for "normal" ---*/
-/*--- non-repetitive blocks. ---*/
-/*---------------------------------------------*/
-
-/*---------------------------------------------*/
-static
-__inline__
-Bool mainGtU ( UInt32 i1,
- UInt32 i2,
- UChar* block,
- UInt16* quadrant,
- UInt32 nblock,
- Int32* budget )
-{
- Int32 k;
- UChar c1, c2;
- UInt16 s1, s2;
-
- AssertD ( i1 != i2, "mainGtU" );
- /* 1 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 2 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 3 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 4 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 5 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 6 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 7 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 8 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 9 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 10 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 11 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 12 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
-
- k = nblock + 8;
-
- do {
- /* 1 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 2 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 3 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 4 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 5 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 6 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 7 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 8 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
-
- if (i1 >= nblock) i1 -= nblock;
- if (i2 >= nblock) i2 -= nblock;
-
- k -= 8;
- (*budget)--;
- }
- while (k >= 0);
-
- return False;
-}
-
-
-/*---------------------------------------------*/
-/*--
- Knuth's increments seem to work better
- than Incerpi-Sedgewick here. Possibly
- because the number of elems to sort is
- usually small, typically <= 20.
---*/
-static
-Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
- 9841, 29524, 88573, 265720,
- 797161, 2391484 };
-
-static
-void mainSimpleSort ( UInt32* ptr,
- UChar* block,
- UInt16* quadrant,
- Int32 nblock,
- Int32 lo,
- Int32 hi,
- Int32 d,
- Int32* budget )
-{
- Int32 i, j, h, bigN, hp;
- UInt32 v;
-
- bigN = hi - lo + 1;
- if (bigN < 2) return;
-
- hp = 0;
- while (incs[hp] < bigN) hp++;
- hp--;
-
- for (; hp >= 0; hp--) {
- h = incs[hp];
-
- i = lo + h;
- while (True) {
-
- /*-- copy 1 --*/
- if (i > hi) break;
- v = ptr[i];
- j = i;
- while ( mainGtU (
- ptr[j-h]+d, v+d, block, quadrant, nblock, budget
- ) ) {
- ptr[j] = ptr[j-h];
- j = j - h;
- if (j <= (lo + h - 1)) break;
- }
- ptr[j] = v;
- i++;
-
- /*-- copy 2 --*/
- if (i > hi) break;
- v = ptr[i];
- j = i;
- while ( mainGtU (
- ptr[j-h]+d, v+d, block, quadrant, nblock, budget
- ) ) {
- ptr[j] = ptr[j-h];
- j = j - h;
- if (j <= (lo + h - 1)) break;
- }
- ptr[j] = v;
- i++;
-
- /*-- copy 3 --*/
- if (i > hi) break;
- v = ptr[i];
- j = i;
- while ( mainGtU (
- ptr[j-h]+d, v+d, block, quadrant, nblock, budget
- ) ) {
- ptr[j] = ptr[j-h];
- j = j - h;
- if (j <= (lo + h - 1)) break;
- }
- ptr[j] = v;
- i++;
-
- if (*budget < 0) return;
- }
- }
-}
-
-
-/*---------------------------------------------*/
-/*--
- The following is an implementation of
- an elegant 3-way quicksort for strings,
- described in a paper "Fast Algorithms for
- Sorting and Searching Strings", by Robert
- Sedgewick and Jon L. Bentley.
---*/
-
-#define mswap(zz1, zz2) \
- { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
-
-#define mvswap(zzp1, zzp2, zzn) \
-{ \
- Int32 yyp1 = (zzp1); \
- Int32 yyp2 = (zzp2); \
- Int32 yyn = (zzn); \
- while (yyn > 0) { \
- mswap(ptr[yyp1], ptr[yyp2]); \
- yyp1++; yyp2++; yyn--; \
- } \
-}
-
-static
-__inline__
-UChar mmed3 ( UChar a, UChar b, UChar c )
-{
- UChar t;
- if (a > b) { t = a; a = b; b = t; };
- if (b > c) {
- b = c;
- if (a > b) b = a;
- }
- return b;
-}
-
-#define mmin(a,b) ((a) < (b)) ? (a) : (b)
-
-#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
- stackHi[sp] = hz; \
- stackD [sp] = dz; \
- sp++; }
-
-#define mpop(lz,hz,dz) { sp--; \
- lz = stackLo[sp]; \
- hz = stackHi[sp]; \
- dz = stackD [sp]; }
-
-
-#define mnextsize(az) (nextHi[az]-nextLo[az])
-
-#define mnextswap(az,bz) \
- { Int32 tz; \
- tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
- tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
- tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
-
-
-#define MAIN_QSORT_SMALL_THRESH 20
-#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
-#define MAIN_QSORT_STACK_SIZE 100
-
-static
-void mainQSort3 ( UInt32* ptr,
- UChar* block,
- UInt16* quadrant,
- Int32 nblock,
- Int32 loSt,
- Int32 hiSt,
- Int32 dSt,
- Int32* budget )
-{
- Int32 unLo, unHi, ltLo, gtHi, n, m, med;
- Int32 sp, lo, hi, d;
-
- Int32 stackLo[MAIN_QSORT_STACK_SIZE];
- Int32 stackHi[MAIN_QSORT_STACK_SIZE];
- Int32 stackD [MAIN_QSORT_STACK_SIZE];
-
- Int32 nextLo[3];
- Int32 nextHi[3];
- Int32 nextD [3];
-
- sp = 0;
- mpush ( loSt, hiSt, dSt );
-
- while (sp > 0) {
-
- AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 );
-
- mpop ( lo, hi, d );
- if (hi - lo < MAIN_QSORT_SMALL_THRESH ||
- d > MAIN_QSORT_DEPTH_THRESH) {
- mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
- if (*budget < 0) return;
- continue;
- }
-
- med = (Int32)
- mmed3 ( block[ptr[ lo ]+d],
- block[ptr[ hi ]+d],
- block[ptr[ (lo+hi)>>1 ]+d] );
-
- unLo = ltLo = lo;
- unHi = gtHi = hi;
-
- while (True) {
- while (True) {
- if (unLo > unHi) break;
- n = ((Int32)block[ptr[unLo]+d]) - med;
- if (n == 0) {
- mswap(ptr[unLo], ptr[ltLo]);
- ltLo++; unLo++; continue;
- };
- if (n > 0) break;
- unLo++;
- }
- while (True) {
- if (unLo > unHi) break;
- n = ((Int32)block[ptr[unHi]+d]) - med;
- if (n == 0) {
- mswap(ptr[unHi], ptr[gtHi]);
- gtHi--; unHi--; continue;
- };
- if (n < 0) break;
- unHi--;
- }
- if (unLo > unHi) break;
- mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
- }
-
- AssertD ( unHi == unLo-1, "mainQSort3(2)" );
-
- if (gtHi < ltLo) {
- mpush(lo, hi, d+1 );
- continue;
- }
-
- n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
- m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
-
- n = lo + unLo - ltLo - 1;
- m = hi - (gtHi - unHi) + 1;
-
- nextLo[0] = lo; nextHi[0] = n; nextD[0] = d;
- nextLo[1] = m; nextHi[1] = hi; nextD[1] = d;
- nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
-
- if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
- if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
- if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
-
- AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
- AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
-
- mpush (nextLo[0], nextHi[0], nextD[0]);
- mpush (nextLo[1], nextHi[1], nextD[1]);
- mpush (nextLo[2], nextHi[2], nextD[2]);
- }
-}
-
-#undef mswap
-#undef mvswap
-#undef mpush
-#undef mpop
-#undef mmin
-#undef mnextsize
-#undef mnextswap
-#undef MAIN_QSORT_SMALL_THRESH
-#undef MAIN_QSORT_DEPTH_THRESH
-#undef MAIN_QSORT_STACK_SIZE
-
-
-/*---------------------------------------------*/
-/* Pre:
- nblock > N_OVERSHOOT
- block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
- ((UChar*)block32) [0 .. nblock-1] holds block
- ptr exists for [0 .. nblock-1]
-
- Post:
- ((UChar*)block32) [0 .. nblock-1] holds block
- All other areas of block32 destroyed
- ftab [0 .. 65536 ] destroyed
- ptr [0 .. nblock-1] holds sorted order
- if (*budget < 0), sorting was abandoned
-*/
-
-#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
-#define SETMASK (1 << 21)
-#define CLEARMASK (~(SETMASK))
-
-static
-void mainSort ( UInt32* ptr,
- UChar* block,
- UInt16* quadrant,
- UInt32* ftab,
- Int32 nblock,
- Int32 verb,
- Int32* budget )
-{
- Int32 i, j, k, ss, sb;
- Int32 runningOrder[256];
- Bool bigDone[256];
- Int32 copyStart[256];
- Int32 copyEnd [256];
- UChar c1;
- Int32 numQSorted;
- UInt16 s;
- if (verb >= 4) VPrintf0 ( " main sort initialise ...\n" );
-
- /*-- set up the 2-byte frequency table --*/
- for (i = 65536; i >= 0; i--) ftab[i] = 0;
-
- j = block[0] << 8;
- i = nblock-1;
- for (; i >= 3; i -= 4) {
- quadrant[i] = 0;
- j = (j >> 8) | ( ((UInt16)block[i]) << 8);
- ftab[j]++;
- quadrant[i-1] = 0;
- j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
- ftab[j]++;
- quadrant[i-2] = 0;
- j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
- ftab[j]++;
- quadrant[i-3] = 0;
- j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
- ftab[j]++;
- }
- for (; i >= 0; i--) {
- quadrant[i] = 0;
- j = (j >> 8) | ( ((UInt16)block[i]) << 8);
- ftab[j]++;
- }
-
- /*-- (emphasises close relationship of block & quadrant) --*/
- for (i = 0; i < BZ_N_OVERSHOOT; i++) {
- block [nblock+i] = block[i];
- quadrant[nblock+i] = 0;
- }
-
- if (verb >= 4) VPrintf0 ( " bucket sorting ...\n" );
-
- /*-- Complete the initial radix sort --*/
- for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
-
- s = block[0] << 8;
- i = nblock-1;
- for (; i >= 3; i -= 4) {
- s = (s >> 8) | (block[i] << 8);
- j = ftab[s] -1;
- ftab[s] = j;
- ptr[j] = i;
- s = (s >> 8) | (block[i-1] << 8);
- j = ftab[s] -1;
- ftab[s] = j;
- ptr[j] = i-1;
- s = (s >> 8) | (block[i-2] << 8);
- j = ftab[s] -1;
- ftab[s] = j;
- ptr[j] = i-2;
- s = (s >> 8) | (block[i-3] << 8);
- j = ftab[s] -1;
- ftab[s] = j;
- ptr[j] = i-3;
- }
- for (; i >= 0; i--) {
- s = (s >> 8) | (block[i] << 8);
- j = ftab[s] -1;
- ftab[s] = j;
- ptr[j] = i;
- }
-
- /*--
- Now ftab contains the first loc of every small bucket.
- Calculate the running order, from smallest to largest
- big bucket.
- --*/
- for (i = 0; i <= 255; i++) {
- bigDone [i] = False;
- runningOrder[i] = i;
- }
-
- {
- Int32 vv;
- Int32 h = 1;
- do h = 3 * h + 1; while (h <= 256);
- do {
- h = h / 3;
- for (i = h; i <= 255; i++) {
- vv = runningOrder[i];
- j = i;
- while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
- runningOrder[j] = runningOrder[j-h];
- j = j - h;
- if (j <= (h - 1)) goto zero;
- }
- zero:
- runningOrder[j] = vv;
- }
- } while (h != 1);
- }
-
- /*--
- The main sorting loop.
- --*/
-
- numQSorted = 0;
-
- for (i = 0; i <= 255; i++) {
-
- /*--
- Process big buckets, starting with the least full.
- Basically this is a 3-step process in which we call
- mainQSort3 to sort the small buckets [ss, j], but
- also make a big effort to avoid the calls if we can.
- --*/
- ss = runningOrder[i];
-
- /*--
- Step 1:
- Complete the big bucket [ss] by quicksorting
- any unsorted small buckets [ss, j], for j != ss.
- Hopefully previous pointer-scanning phases have already
- completed many of the small buckets [ss, j], so
- we don't have to sort them at all.
- --*/
- for (j = 0; j <= 255; j++) {
- if (j != ss) {
- sb = (ss << 8) + j;
- if ( ! (ftab[sb] & SETMASK) ) {
- Int32 lo = ftab[sb] & CLEARMASK;
- Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
- if (hi > lo) {
- if (verb >= 4)
- VPrintf4 ( " qsort [0x%x, 0x%x] "
- "done %d this %d\n",
- ss, j, numQSorted, hi - lo + 1 );
- mainQSort3 (
- ptr, block, quadrant, nblock,
- lo, hi, BZ_N_RADIX, budget
- );
- numQSorted += (hi - lo + 1);
- if (*budget < 0) return;
- }
- }
- ftab[sb] |= SETMASK;
- }
- }
-
- AssertH ( !bigDone[ss], 1006 );
-
- /*--
- Step 2:
- Now scan this big bucket [ss] so as to synthesise the
- sorted order for small buckets [t, ss] for all t,
- including, magically, the bucket [ss,ss] too.
- This will avoid doing Real Work in subsequent Step 1's.
- --*/
- {
- for (j = 0; j <= 255; j++) {
- copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK;
- copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
- }
- for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
- k = ptr[j]-1; if (k < 0) k += nblock;
- c1 = block[k];
- if (!bigDone[c1])
- ptr[ copyStart[c1]++ ] = k;
- }
- for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
- k = ptr[j]-1; if (k < 0) k += nblock;
- c1 = block[k];
- if (!bigDone[c1])
- ptr[ copyEnd[c1]-- ] = k;
- }
- }
-
- AssertH ( (copyStart[ss]-1 == copyEnd[ss])
- ||
- /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
- Necessity for this case is demonstrated by compressing
- a sequence of approximately 48.5 million of character
- 251; 1.0.0/1.0.1 will then die here. */
- (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
- 1007 )
-
- for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
-
- /*--
- Step 3:
- The [ss] big bucket is now done. Record this fact,
- and update the quadrant descriptors. Remember to
- update quadrants in the overshoot area too, if
- necessary. The "if (i < 255)" test merely skips
- this updating for the last bucket processed, since
- updating for the last bucket is pointless.
-
- The quadrant array provides a way to incrementally
- cache sort orderings, as they appear, so as to
- make subsequent comparisons in fullGtU() complete
- faster. For repetitive blocks this makes a big
- difference (but not big enough to be able to avoid
- the fallback sorting mechanism, exponential radix sort).
-
- The precise meaning is: at all times:
-
- for 0 <= i < nblock and 0 <= j <= nblock
-
- if block[i] != block[j],
-
- then the relative values of quadrant[i] and
- quadrant[j] are meaningless.
-
- else {
- if quadrant[i] < quadrant[j]
- then the string starting at i lexicographically
- precedes the string starting at j
-
- else if quadrant[i] > quadrant[j]
- then the string starting at j lexicographically
- precedes the string starting at i
-
- else
- the relative ordering of the strings starting
- at i and j has not yet been determined.
- }
- --*/
- bigDone[ss] = True;
-
- if (i < 255) {
- Int32 bbStart = ftab[ss << 8] & CLEARMASK;
- Int32 bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
- Int32 shifts = 0;
-
- while ((bbSize >> shifts) > 65534) shifts++;
-
- for (j = bbSize-1; j >= 0; j--) {
- Int32 a2update = ptr[bbStart + j];
- UInt16 qVal = (UInt16)(j >> shifts);
- quadrant[a2update] = qVal;
- if (a2update < BZ_N_OVERSHOOT)
- quadrant[a2update + nblock] = qVal;
- }
- AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
- }
-
- }
-
- if (verb >= 4)
- VPrintf3 ( " %d pointers, %d sorted, %d scanned\n",
- nblock, numQSorted, nblock - numQSorted );
-}
-
-#undef BIGFREQ
-#undef SETMASK
-#undef CLEARMASK
-
-
-/*---------------------------------------------*/
-/* Pre:
- nblock > 0
- arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
- ((UChar*)arr2) [0 .. nblock-1] holds block
- arr1 exists for [0 .. nblock-1]
-
- Post:
- ((UChar*)arr2) [0 .. nblock-1] holds block
- All other areas of block destroyed
- ftab [ 0 .. 65536 ] destroyed
- arr1 [0 .. nblock-1] holds sorted order
-*/
-void BZ2_blockSort ( EState* s )
-{
- UInt32* ptr = s->ptr;
- UChar* block = s->block;
- UInt32* ftab = s->ftab;
- Int32 nblock = s->nblock;
- Int32 verb = s->verbosity;
- Int32 wfact = s->workFactor;
- UInt16* quadrant;
- Int32 budget;
- Int32 budgetInit;
- Int32 i;
-
- if (nblock < 10000) {
- fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
- } else {
- /* Calculate the location for quadrant, remembering to get
- the alignment right. Assumes that &(block[0]) is at least
- 2-byte aligned -- this should be ok since block is really
- the first section of arr2.
- */
- i = nblock+BZ_N_OVERSHOOT;
- if (i & 1) i++;
- quadrant = (UInt16*)(&(block[i]));
-
- /* (wfact-1) / 3 puts the default-factor-30
- transition point at very roughly the same place as
- with v0.1 and v0.9.0.
- Not that it particularly matters any more, since the
- resulting compressed stream is now the same regardless
- of whether or not we use the main sort or fallback sort.
- */
- if (wfact < 1 ) wfact = 1;
- if (wfact > 100) wfact = 100;
- budgetInit = nblock * ((wfact-1) / 3);
- budget = budgetInit;
-
- mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
- if (verb >= 3)
- VPrintf3 ( " %d work, %d block, ratio %5.2f\n",
- budgetInit - budget,
- nblock,
- (float)(budgetInit - budget) /
- (float)(nblock==0 ? 1 : nblock) );
- if (budget < 0) {
- if (verb >= 2)
- VPrintf0 ( " too repetitive; using fallback"
- " sorting algorithm\n" );
- fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
- }
- }
-
- s->origPtr = -1;
- for (i = 0; i < s->nblock; i++)
- if (ptr[i] == 0)
- { s->origPtr = i; break; };
-
- AssertH( s->origPtr != -1, 1003 );
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end blocksort.c ---*/
-/*-------------------------------------------------------------*/
diff --git a/dep/StormLib/src/bzip2/bzlib.c b/dep/StormLib/src/bzip2/bzlib.c
deleted file mode 100644
index b98f3e586bc..00000000000
--- a/dep/StormLib/src/bzip2/bzlib.c
+++ /dev/null
@@ -1,1573 +0,0 @@
-
-/*-------------------------------------------------------------*/
-/*--- Library top-level functions. ---*/
-/*--- bzlib.c ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
- This file is part of bzip2/libbzip2, a program and library for
- lossless, block-sorting data compression.
-
- bzip2/libbzip2 version 1.0.5 of 10 December 2007
- Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
-
- Please read the WARNING, DISCLAIMER and PATENTS sections in the
- README file.
-
- This program is released under the terms of the license contained
- in the file LICENSE.
- ------------------------------------------------------------------ */
-
-/* CHANGES
- 0.9.0 -- original version.
- 0.9.0a/b -- no changes in this file.
- 0.9.0c -- made zero-length BZ_FLUSH work correctly in bzCompress().
- fixed bzWrite/bzRead to ignore zero-length requests.
- fixed bzread to correctly handle read requests after EOF.
- wrong parameter order in call to bzDecompressInit in
- bzBuffToBuffDecompress. Fixed.
-*/
-
-#define _CRT_SECURE_NO_WARNINGS
-#include "bzlib_private.h"
-
-
-/*---------------------------------------------------*/
-/*--- Compression stuff ---*/
-/*---------------------------------------------------*/
-
-
-/*---------------------------------------------------*/
-#ifndef BZ_NO_STDIO
-void BZ2_bz__AssertH__fail ( int errcode )
-{
- fprintf(stderr,
- "\n\nbzip2/libbzip2: internal error number %d.\n"
- "This is a bug in bzip2/libbzip2, %s.\n"
- "Please report it to me at: jseward@bzip.org. If this happened\n"
- "when you were using some program which uses libbzip2 as a\n"
- "component, you should also report this bug to the author(s)\n"
- "of that program. Please make an effort to report this bug;\n"
- "timely and accurate bug reports eventually lead to higher\n"
- "quality software. Thanks. Julian Seward, 10 December 2007.\n\n",
- errcode,
- BZ2_bzlibVersion()
- );
-
- if (errcode == 1007) {
- fprintf(stderr,
- "\n*** A special note about internal error number 1007 ***\n"
- "\n"
- "Experience suggests that a common cause of i.e. 1007\n"
- "is unreliable memory or other hardware. The 1007 assertion\n"
- "just happens to cross-check the results of huge numbers of\n"
- "memory reads/writes, and so acts (unintendedly) as a stress\n"
- "test of your memory system.\n"
- "\n"
- "I suggest the following: try compressing the file again,\n"
- "possibly monitoring progress in detail with the -vv flag.\n"
- "\n"
- "* If the error cannot be reproduced, and/or happens at different\n"
- " points in compression, you may have a flaky memory system.\n"
- " Try a memory-test program. I have used Memtest86\n"
- " (www.memtest86.com). At the time of writing it is free (GPLd).\n"
- " Memtest86 tests memory much more thorougly than your BIOSs\n"
- " power-on test, and may find failures that the BIOS doesn't.\n"
- "\n"
- "* If the error can be repeatably reproduced, this is a bug in\n"
- " bzip2, and I would very much like to hear about it. Please\n"
- " let me know, and, ideally, save a copy of the file causing the\n"
- " problem -- without which I will be unable to investigate it.\n"
- "\n"
- );
- }
-
- exit(3);
-}
-#endif
-
-
-/*---------------------------------------------------*/
-static
-int bz_config_ok ( void )
-{
- if (sizeof(int) != 4) return 0;
- if (sizeof(short) != 2) return 0;
- if (sizeof(char) != 1) return 0;
- return 1;
-}
-
-
-/*---------------------------------------------------*/
-static
-void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
-{
- void* v = malloc ( items * size );
- return v;
-}
-
-static
-void default_bzfree ( void* opaque, void* addr )
-{
- if (addr != NULL) free ( addr );
-}
-
-
-/*---------------------------------------------------*/
-static
-void prepare_new_block ( EState* s )
-{
- Int32 i;
- s->nblock = 0;
- s->numZ = 0;
- s->state_out_pos = 0;
- BZ_INITIALISE_CRC ( s->blockCRC );
- for (i = 0; i < 256; i++) s->inUse[i] = False;
- s->blockNo++;
-}
-
-
-/*---------------------------------------------------*/
-static
-void init_RL ( EState* s )
-{
- s->state_in_ch = 256;
- s->state_in_len = 0;
-}
-
-
-static
-Bool isempty_RL ( EState* s )
-{
- if (s->state_in_ch < 256 && s->state_in_len > 0)
- return False; else
- return True;
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzCompressInit)
- ( bz_stream* strm,
- int blockSize100k,
- int verbosity,
- int workFactor )
-{
- Int32 n;
- EState* s;
-
- if (!bz_config_ok()) return BZ_CONFIG_ERROR;
-
- if (strm == NULL ||
- blockSize100k < 1 || blockSize100k > 9 ||
- workFactor < 0 || workFactor > 250)
- return BZ_PARAM_ERROR;
-
- if (workFactor == 0) workFactor = 30;
- if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
- if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
-
- s = BZALLOC( sizeof(EState) );
- if (s == NULL) return BZ_MEM_ERROR;
- s->strm = strm;
-
- s->arr1 = NULL;
- s->arr2 = NULL;
- s->ftab = NULL;
-
- n = 100000 * blockSize100k;
- s->arr1 = BZALLOC( n * sizeof(UInt32) );
- s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
- s->ftab = BZALLOC( 65537 * sizeof(UInt32) );
-
- if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
- if (s->arr1 != NULL) BZFREE(s->arr1);
- if (s->arr2 != NULL) BZFREE(s->arr2);
- if (s->ftab != NULL) BZFREE(s->ftab);
- if (s != NULL) BZFREE(s);
- return BZ_MEM_ERROR;
- }
-
- s->blockNo = 0;
- s->state = BZ_S_INPUT;
- s->mode = BZ_M_RUNNING;
- s->combinedCRC = 0;
- s->blockSize100k = blockSize100k;
- s->nblockMAX = 100000 * blockSize100k - 19;
- s->verbosity = verbosity;
- s->workFactor = workFactor;
-
- s->block = (UChar*)s->arr2;
- s->mtfv = (UInt16*)s->arr1;
- s->zbits = NULL;
- s->ptr = (UInt32*)s->arr1;
-
- strm->state = s;
- strm->total_in_lo32 = 0;
- strm->total_in_hi32 = 0;
- strm->total_out_lo32 = 0;
- strm->total_out_hi32 = 0;
- init_RL ( s );
- prepare_new_block ( s );
- return BZ_OK;
-}
-
-
-/*---------------------------------------------------*/
-static
-void add_pair_to_block ( EState* s )
-{
- Int32 i;
- UChar ch = (UChar)(s->state_in_ch);
- for (i = 0; i < s->state_in_len; i++) {
- BZ_UPDATE_CRC( s->blockCRC, ch );
- }
- s->inUse[s->state_in_ch] = True;
- switch (s->state_in_len) {
- case 1:
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- break;
- case 2:
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- break;
- case 3:
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- break;
- default:
- s->inUse[s->state_in_len-4] = True;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = ((UChar)(s->state_in_len-4));
- s->nblock++;
- break;
- }
-}
-
-
-/*---------------------------------------------------*/
-static
-void flush_RL ( EState* s )
-{
- if (s->state_in_ch < 256) add_pair_to_block ( s );
- init_RL ( s );
-}
-
-
-/*---------------------------------------------------*/
-#define ADD_CHAR_TO_BLOCK(zs,zchh0) \
-{ \
- UInt32 zchh = (UInt32)(zchh0); \
- /*-- fast track the common case --*/ \
- if (zchh != zs->state_in_ch && \
- zs->state_in_len == 1) { \
- UChar ch = (UChar)(zs->state_in_ch); \
- BZ_UPDATE_CRC( zs->blockCRC, ch ); \
- zs->inUse[zs->state_in_ch] = True; \
- zs->block[zs->nblock] = (UChar)ch; \
- zs->nblock++; \
- zs->state_in_ch = zchh; \
- } \
- else \
- /*-- general, uncommon cases --*/ \
- if (zchh != zs->state_in_ch || \
- zs->state_in_len == 255) { \
- if (zs->state_in_ch < 256) \
- add_pair_to_block ( zs ); \
- zs->state_in_ch = zchh; \
- zs->state_in_len = 1; \
- } else { \
- zs->state_in_len++; \
- } \
-}
-
-
-/*---------------------------------------------------*/
-static
-Bool copy_input_until_stop ( EState* s )
-{
- Bool progress_in = False;
-
- if (s->mode == BZ_M_RUNNING) {
-
- /*-- fast track the common case --*/
- while (True) {
- /*-- block full? --*/
- if (s->nblock >= s->nblockMAX) break;
- /*-- no input? --*/
- if (s->strm->avail_in == 0) break;
- progress_in = True;
- ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
- s->strm->next_in++;
- s->strm->avail_in--;
- s->strm->total_in_lo32++;
- if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
- }
-
- } else {
-
- /*-- general, uncommon case --*/
- while (True) {
- /*-- block full? --*/
- if (s->nblock >= s->nblockMAX) break;
- /*-- no input? --*/
- if (s->strm->avail_in == 0) break;
- /*-- flush/finish end? --*/
- if (s->avail_in_expect == 0) break;
- progress_in = True;
- ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
- s->strm->next_in++;
- s->strm->avail_in--;
- s->strm->total_in_lo32++;
- if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
- s->avail_in_expect--;
- }
- }
- return progress_in;
-}
-
-
-/*---------------------------------------------------*/
-static
-Bool copy_output_until_stop ( EState* s )
-{
- Bool progress_out = False;
-
- while (True) {
-
- /*-- no output space? --*/
- if (s->strm->avail_out == 0) break;
-
- /*-- block done? --*/
- if (s->state_out_pos >= s->numZ) break;
-
- progress_out = True;
- *(s->strm->next_out) = s->zbits[s->state_out_pos];
- s->state_out_pos++;
- s->strm->avail_out--;
- s->strm->next_out++;
- s->strm->total_out_lo32++;
- if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
- }
-
- return progress_out;
-}
-
-
-/*---------------------------------------------------*/
-static
-Bool handle_compress ( bz_stream* strm )
-{
- Bool progress_in = False;
- Bool progress_out = False;
- EState* s = strm->state;
-
- while (True) {
-
- if (s->state == BZ_S_OUTPUT) {
- progress_out |= copy_output_until_stop ( s );
- if (s->state_out_pos < s->numZ) break;
- if (s->mode == BZ_M_FINISHING &&
- s->avail_in_expect == 0 &&
- isempty_RL(s)) break;
- prepare_new_block ( s );
- s->state = BZ_S_INPUT;
- if (s->mode == BZ_M_FLUSHING &&
- s->avail_in_expect == 0 &&
- isempty_RL(s)) break;
- }
-
- if (s->state == BZ_S_INPUT) {
- progress_in |= copy_input_until_stop ( s );
- if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
- flush_RL ( s );
- BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
- s->state = BZ_S_OUTPUT;
- }
- else
- if (s->nblock >= s->nblockMAX) {
- BZ2_compressBlock ( s, False );
- s->state = BZ_S_OUTPUT;
- }
- else
- if (s->strm->avail_in == 0) {
- break;
- }
- }
-
- }
-
- return progress_in || progress_out;
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
-{
- Bool progress;
- EState* s;
- if (strm == NULL) return BZ_PARAM_ERROR;
- s = strm->state;
- if (s == NULL) return BZ_PARAM_ERROR;
- if (s->strm != strm) return BZ_PARAM_ERROR;
-
- preswitch:
- switch (s->mode) {
-
- case BZ_M_IDLE:
- return BZ_SEQUENCE_ERROR;
-
- case BZ_M_RUNNING:
- if (action == BZ_RUN) {
- progress = handle_compress ( strm );
- return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
- }
- else
- if (action == BZ_FLUSH) {
- s->avail_in_expect = strm->avail_in;
- s->mode = BZ_M_FLUSHING;
- goto preswitch;
- }
- else
- if (action == BZ_FINISH) {
- s->avail_in_expect = strm->avail_in;
- s->mode = BZ_M_FINISHING;
- goto preswitch;
- }
- else
- return BZ_PARAM_ERROR;
-
- case BZ_M_FLUSHING:
- if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
- if (s->avail_in_expect != s->strm->avail_in)
- return BZ_SEQUENCE_ERROR;
- progress = handle_compress ( strm );
- if (s->avail_in_expect > 0 || !isempty_RL(s) ||
- s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
- s->mode = BZ_M_RUNNING;
- return BZ_RUN_OK;
-
- case BZ_M_FINISHING:
- if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
- if (s->avail_in_expect != s->strm->avail_in)
- return BZ_SEQUENCE_ERROR;
- progress = handle_compress ( strm );
- if (!progress) return BZ_SEQUENCE_ERROR;
- if (s->avail_in_expect > 0 || !isempty_RL(s) ||
- s->state_out_pos < s->numZ) return BZ_FINISH_OK;
- s->mode = BZ_M_IDLE;
- return BZ_STREAM_END;
- }
- return BZ_OK; /*--not reached--*/
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzCompressEnd) ( bz_stream *strm )
-{
- EState* s;
- if (strm == NULL) return BZ_PARAM_ERROR;
- s = strm->state;
- if (s == NULL) return BZ_PARAM_ERROR;
- if (s->strm != strm) return BZ_PARAM_ERROR;
-
- if (s->arr1 != NULL) BZFREE(s->arr1);
- if (s->arr2 != NULL) BZFREE(s->arr2);
- if (s->ftab != NULL) BZFREE(s->ftab);
- BZFREE(strm->state);
-
- strm->state = NULL;
-
- return BZ_OK;
-}
-
-
-/*---------------------------------------------------*/
-/*--- Decompression stuff ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzDecompressInit)
- ( bz_stream* strm,
- int verbosity,
- int small )
-{
- DState* s;
-
- if (!bz_config_ok()) return BZ_CONFIG_ERROR;
-
- if (strm == NULL) return BZ_PARAM_ERROR;
- if (small != 0 && small != 1) return BZ_PARAM_ERROR;
- if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
-
- if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
- if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
-
- s = BZALLOC( sizeof(DState) );
- if (s == NULL) return BZ_MEM_ERROR;
- s->strm = strm;
- strm->state = s;
- s->state = BZ_X_MAGIC_1;
- s->bsLive = 0;
- s->bsBuff = 0;
- s->calculatedCombinedCRC = 0;
- strm->total_in_lo32 = 0;
- strm->total_in_hi32 = 0;
- strm->total_out_lo32 = 0;
- strm->total_out_hi32 = 0;
- s->smallDecompress = (Bool)small;
- s->ll4 = NULL;
- s->ll16 = NULL;
- s->tt = NULL;
- s->currBlockNo = 0;
- s->verbosity = verbosity;
-
- return BZ_OK;
-}
-
-
-/*---------------------------------------------------*/
-/* Return True iff data corruption is discovered.
- Returns False if there is no problem.
-*/
-static
-Bool unRLE_obuf_to_output_FAST ( DState* s )
-{
- UChar k1;
-
- if (s->blockRandomised) {
-
- while (True) {
- /* try to finish existing run */
- while (True) {
- if (s->strm->avail_out == 0) return False;
- if (s->state_out_len == 0) break;
- *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
- BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
- s->state_out_len--;
- s->strm->next_out++;
- s->strm->avail_out--;
- s->strm->total_out_lo32++;
- if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
- }
-
- /* can a new run be started? */
- if (s->nblock_used == s->save_nblock+1) return False;
-
- /* Only caused by corrupt data stream? */
- if (s->nblock_used > s->save_nblock+1)
- return True;
-
- s->state_out_len = 1;
- s->state_out_ch = s->k0;
- BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 2;
- BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 3;
- BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- s->state_out_len = ((Int32)k1) + 4;
- BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
- s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
- }
-
- } else {
-
- /* restore */
- UInt32 c_calculatedBlockCRC = s->calculatedBlockCRC;
- UChar c_state_out_ch = s->state_out_ch;
- Int32 c_state_out_len = s->state_out_len;
- Int32 c_nblock_used = s->nblock_used;
- Int32 c_k0 = s->k0;
- UInt32* c_tt = s->tt;
- UInt32 c_tPos = s->tPos;
- char* cs_next_out = s->strm->next_out;
- unsigned int cs_avail_out = s->strm->avail_out;
- Int32 ro_blockSize100k = s->blockSize100k;
- /* end restore */
-
- UInt32 avail_out_INIT = cs_avail_out;
- Int32 s_save_nblockPP = s->save_nblock+1;
- unsigned int total_out_lo32_old;
-
- while (True) {
-
- /* try to finish existing run */
- if (c_state_out_len > 0) {
- while (True) {
- if (cs_avail_out == 0) goto return_notr;
- if (c_state_out_len == 1) break;
- *( (UChar*)(cs_next_out) ) = c_state_out_ch;
- BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
- c_state_out_len--;
- cs_next_out++;
- cs_avail_out--;
- }
- s_state_out_len_eq_one:
- {
- if (cs_avail_out == 0) {
- c_state_out_len = 1; goto return_notr;
- };
- *( (UChar*)(cs_next_out) ) = c_state_out_ch;
- BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
- cs_next_out++;
- cs_avail_out--;
- }
- }
- /* Only caused by corrupt data stream? */
- if (c_nblock_used > s_save_nblockPP)
- return True;
-
- /* can a new run be started? */
- if (c_nblock_used == s_save_nblockPP) {
- c_state_out_len = 0; goto return_notr;
- };
- c_state_out_ch = c_k0;
- BZ_GET_FAST_C(k1); c_nblock_used++;
- if (k1 != c_k0) {
- c_k0 = k1; goto s_state_out_len_eq_one;
- };
- if (c_nblock_used == s_save_nblockPP)
- goto s_state_out_len_eq_one;
-
- c_state_out_len = 2;
- BZ_GET_FAST_C(k1); c_nblock_used++;
- if (c_nblock_used == s_save_nblockPP) continue;
- if (k1 != c_k0) { c_k0 = k1; continue; };
-
- c_state_out_len = 3;
- BZ_GET_FAST_C(k1); c_nblock_used++;
- if (c_nblock_used == s_save_nblockPP) continue;
- if (k1 != c_k0) { c_k0 = k1; continue; };
-
- BZ_GET_FAST_C(k1); c_nblock_used++;
- c_state_out_len = ((Int32)k1) + 4;
- BZ_GET_FAST_C(c_k0); c_nblock_used++;
- }
-
- return_notr:
- total_out_lo32_old = s->strm->total_out_lo32;
- s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
- if (s->strm->total_out_lo32 < total_out_lo32_old)
- s->strm->total_out_hi32++;
-
- /* save */
- s->calculatedBlockCRC = c_calculatedBlockCRC;
- s->state_out_ch = c_state_out_ch;
- s->state_out_len = c_state_out_len;
- s->nblock_used = c_nblock_used;
- s->k0 = c_k0;
- s->tt = c_tt;
- s->tPos = c_tPos;
- s->strm->next_out = cs_next_out;
- s->strm->avail_out = cs_avail_out;
- /* end save */
- }
- return False;
-}
-
-
-
-/*---------------------------------------------------*/
-__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
-{
- Int32 nb, na, mid;
- nb = 0;
- na = 256;
- do {
- mid = (nb + na) >> 1;
- if (indx >= cftab[mid]) nb = mid; else na = mid;
- }
- while (na - nb != 1);
- return nb;
-}
-
-
-/*---------------------------------------------------*/
-/* Return True iff data corruption is discovered.
- Returns False if there is no problem.
-*/
-static
-Bool unRLE_obuf_to_output_SMALL ( DState* s )
-{
- UChar k1;
-
- if (s->blockRandomised) {
-
- while (True) {
- /* try to finish existing run */
- while (True) {
- if (s->strm->avail_out == 0) return False;
- if (s->state_out_len == 0) break;
- *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
- BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
- s->state_out_len--;
- s->strm->next_out++;
- s->strm->avail_out--;
- s->strm->total_out_lo32++;
- if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
- }
-
- /* can a new run be started? */
- if (s->nblock_used == s->save_nblock+1) return False;
-
- /* Only caused by corrupt data stream? */
- if (s->nblock_used > s->save_nblock+1)
- return True;
-
- s->state_out_len = 1;
- s->state_out_ch = s->k0;
- BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 2;
- BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 3;
- BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- s->state_out_len = ((Int32)k1) + 4;
- BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
- s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
- }
-
- } else {
-
- while (True) {
- /* try to finish existing run */
- while (True) {
- if (s->strm->avail_out == 0) return False;
- if (s->state_out_len == 0) break;
- *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
- BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
- s->state_out_len--;
- s->strm->next_out++;
- s->strm->avail_out--;
- s->strm->total_out_lo32++;
- if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
- }
-
- /* can a new run be started? */
- if (s->nblock_used == s->save_nblock+1) return False;
-
- /* Only caused by corrupt data stream? */
- if (s->nblock_used > s->save_nblock+1)
- return True;
-
- s->state_out_len = 1;
- s->state_out_ch = s->k0;
- BZ_GET_SMALL(k1); s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 2;
- BZ_GET_SMALL(k1); s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 3;
- BZ_GET_SMALL(k1); s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- BZ_GET_SMALL(k1); s->nblock_used++;
- s->state_out_len = ((Int32)k1) + 4;
- BZ_GET_SMALL(s->k0); s->nblock_used++;
- }
-
- }
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
-{
- Bool corrupt;
- DState* s;
- if (strm == NULL) return BZ_PARAM_ERROR;
- s = strm->state;
- if (s == NULL) return BZ_PARAM_ERROR;
- if (s->strm != strm) return BZ_PARAM_ERROR;
-
- while (True) {
- if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
- if (s->state == BZ_X_OUTPUT) {
- if (s->smallDecompress)
- corrupt = unRLE_obuf_to_output_SMALL ( s ); else
- corrupt = unRLE_obuf_to_output_FAST ( s );
- if (corrupt) return BZ_DATA_ERROR;
- if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
- BZ_FINALISE_CRC ( s->calculatedBlockCRC );
- if (s->verbosity >= 3)
- VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC,
- s->calculatedBlockCRC );
- if (s->verbosity >= 2) VPrintf0 ( "]" );
- if (s->calculatedBlockCRC != s->storedBlockCRC)
- return BZ_DATA_ERROR;
- s->calculatedCombinedCRC
- = (s->calculatedCombinedCRC << 1) |
- (s->calculatedCombinedCRC >> 31);
- s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
- s->state = BZ_X_BLKHDR_1;
- } else {
- return BZ_OK;
- }
- }
- if (s->state >= BZ_X_MAGIC_1) {
- Int32 r = BZ2_decompress ( s );
- if (r == BZ_STREAM_END) {
- if (s->verbosity >= 3)
- VPrintf2 ( "\n combined CRCs: stored = 0x%08x, computed = 0x%08x",
- s->storedCombinedCRC, s->calculatedCombinedCRC );
- if (s->calculatedCombinedCRC != s->storedCombinedCRC)
- return BZ_DATA_ERROR;
- return r;
- }
- if (s->state != BZ_X_OUTPUT) return r;
- }
- }
-
- AssertH ( 0, 6001 );
-
- return 0; /*NOTREACHED*/
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm )
-{
- DState* s;
- if (strm == NULL) return BZ_PARAM_ERROR;
- s = strm->state;
- if (s == NULL) return BZ_PARAM_ERROR;
- if (s->strm != strm) return BZ_PARAM_ERROR;
-
- if (s->tt != NULL) BZFREE(s->tt);
- if (s->ll16 != NULL) BZFREE(s->ll16);
- if (s->ll4 != NULL) BZFREE(s->ll4);
-
- BZFREE(strm->state);
- strm->state = NULL;
-
- return BZ_OK;
-}
-
-
-#ifndef BZ_NO_STDIO
-/*---------------------------------------------------*/
-/*--- File I/O stuff ---*/
-/*---------------------------------------------------*/
-
-#define BZ_SETERR(eee) \
-{ \
- if (bzerror != NULL) *bzerror = eee; \
- if (bzf != NULL) bzf->lastErr = eee; \
-}
-
-typedef
- struct {
- FILE* handle;
- Char buf[BZ_MAX_UNUSED];
- Int32 bufN;
- Bool writing;
- bz_stream strm;
- Int32 lastErr;
- Bool initialisedOk;
- }
- bzFile;
-
-
-/*---------------------------------------------*/
-static Bool myfeof ( FILE* f )
-{
- Int32 c = fgetc ( f );
- if (c == EOF) return True;
- ungetc ( c, f );
- return False;
-}
-
-
-/*---------------------------------------------------*/
-BZFILE* BZ_API(BZ2_bzWriteOpen)
- ( int* bzerror,
- FILE* f,
- int blockSize100k,
- int verbosity,
- int workFactor )
-{
- Int32 ret;
- bzFile* bzf = NULL;
-
- BZ_SETERR(BZ_OK);
-
- if (f == NULL ||
- (blockSize100k < 1 || blockSize100k > 9) ||
- (workFactor < 0 || workFactor > 250) ||
- (verbosity < 0 || verbosity > 4))
- { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
-
- if (ferror(f))
- { BZ_SETERR(BZ_IO_ERROR); return NULL; };
-
- bzf = malloc ( sizeof(bzFile) );
- if (bzf == NULL)
- { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
-
- BZ_SETERR(BZ_OK);
- bzf->initialisedOk = False;
- bzf->bufN = 0;
- bzf->handle = f;
- bzf->writing = True;
- bzf->strm.bzalloc = NULL;
- bzf->strm.bzfree = NULL;
- bzf->strm.opaque = NULL;
-
- if (workFactor == 0) workFactor = 30;
- ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
- verbosity, workFactor );
- if (ret != BZ_OK)
- { BZ_SETERR(ret); free(bzf); return NULL; };
-
- bzf->strm.avail_in = 0;
- bzf->initialisedOk = True;
- return bzf;
-}
-
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzWrite)
- ( int* bzerror,
- BZFILE* b,
- void* buf,
- int len )
-{
- Int32 n, n2, ret;
- bzFile* bzf = (bzFile*)b;
-
- BZ_SETERR(BZ_OK);
- if (bzf == NULL || buf == NULL || len < 0)
- { BZ_SETERR(BZ_PARAM_ERROR); return; };
- if (!(bzf->writing))
- { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
- if (ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return; };
-
- if (len == 0)
- { BZ_SETERR(BZ_OK); return; };
-
- bzf->strm.avail_in = len;
- bzf->strm.next_in = buf;
-
- while (True) {
- bzf->strm.avail_out = BZ_MAX_UNUSED;
- bzf->strm.next_out = bzf->buf;
- ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
- if (ret != BZ_RUN_OK)
- { BZ_SETERR(ret); return; };
-
- if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
- n = BZ_MAX_UNUSED - bzf->strm.avail_out;
- n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
- n, bzf->handle );
- if (n != n2 || ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return; };
- }
-
- if (bzf->strm.avail_in == 0)
- { BZ_SETERR(BZ_OK); return; };
- }
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzWriteClose)
- ( int* bzerror,
- BZFILE* b,
- int abandon,
- unsigned int* nbytes_in,
- unsigned int* nbytes_out )
-{
- BZ2_bzWriteClose64 ( bzerror, b, abandon,
- nbytes_in, NULL, nbytes_out, NULL );
-}
-
-
-void BZ_API(BZ2_bzWriteClose64)
- ( int* bzerror,
- BZFILE* b,
- int abandon,
- unsigned int* nbytes_in_lo32,
- unsigned int* nbytes_in_hi32,
- unsigned int* nbytes_out_lo32,
- unsigned int* nbytes_out_hi32 )
-{
- Int32 n, n2, ret;
- bzFile* bzf = (bzFile*)b;
-
- if (bzf == NULL)
- { BZ_SETERR(BZ_OK); return; };
- if (!(bzf->writing))
- { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
- if (ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return; };
-
- if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
- if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
- if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
- if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
-
- if ((!abandon) && bzf->lastErr == BZ_OK) {
- while (True) {
- bzf->strm.avail_out = BZ_MAX_UNUSED;
- bzf->strm.next_out = bzf->buf;
- ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
- if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
- { BZ_SETERR(ret); return; };
-
- if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
- n = BZ_MAX_UNUSED - bzf->strm.avail_out;
- n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
- n, bzf->handle );
- if (n != n2 || ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return; };
- }
-
- if (ret == BZ_STREAM_END) break;
- }
- }
-
- if ( !abandon && !ferror ( bzf->handle ) ) {
- fflush ( bzf->handle );
- if (ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return; };
- }
-
- if (nbytes_in_lo32 != NULL)
- *nbytes_in_lo32 = bzf->strm.total_in_lo32;
- if (nbytes_in_hi32 != NULL)
- *nbytes_in_hi32 = bzf->strm.total_in_hi32;
- if (nbytes_out_lo32 != NULL)
- *nbytes_out_lo32 = bzf->strm.total_out_lo32;
- if (nbytes_out_hi32 != NULL)
- *nbytes_out_hi32 = bzf->strm.total_out_hi32;
-
- BZ_SETERR(BZ_OK);
- BZ2_bzCompressEnd ( &(bzf->strm) );
- free ( bzf );
-}
-
-
-/*---------------------------------------------------*/
-BZFILE* BZ_API(BZ2_bzReadOpen)
- ( int* bzerror,
- FILE* f,
- int verbosity,
- int small,
- void* unused,
- int nUnused )
-{
- bzFile* bzf = NULL;
- int ret;
-
- BZ_SETERR(BZ_OK);
-
- if (f == NULL ||
- (small != 0 && small != 1) ||
- (verbosity < 0 || verbosity > 4) ||
- (unused == NULL && nUnused != 0) ||
- (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
- { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
-
- if (ferror(f))
- { BZ_SETERR(BZ_IO_ERROR); return NULL; };
-
- bzf = malloc ( sizeof(bzFile) );
- if (bzf == NULL)
- { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
-
- BZ_SETERR(BZ_OK);
-
- bzf->initialisedOk = False;
- bzf->handle = f;
- bzf->bufN = 0;
- bzf->writing = False;
- bzf->strm.bzalloc = NULL;
- bzf->strm.bzfree = NULL;
- bzf->strm.opaque = NULL;
-
- while (nUnused > 0) {
- bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
- unused = ((void*)( 1 + ((UChar*)(unused)) ));
- nUnused--;
- }
-
- ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
- if (ret != BZ_OK)
- { BZ_SETERR(ret); free(bzf); return NULL; };
-
- bzf->strm.avail_in = bzf->bufN;
- bzf->strm.next_in = bzf->buf;
-
- bzf->initialisedOk = True;
- return bzf;
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
-{
- bzFile* bzf = (bzFile*)b;
-
- BZ_SETERR(BZ_OK);
- if (bzf == NULL)
- { BZ_SETERR(BZ_OK); return; };
-
- if (bzf->writing)
- { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
-
- if (bzf->initialisedOk)
- (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
- free ( bzf );
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzRead)
- ( int* bzerror,
- BZFILE* b,
- void* buf,
- int len )
-{
- Int32 n, ret;
- bzFile* bzf = (bzFile*)b;
-
- BZ_SETERR(BZ_OK);
-
- if (bzf == NULL || buf == NULL || len < 0)
- { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
-
- if (bzf->writing)
- { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
-
- if (len == 0)
- { BZ_SETERR(BZ_OK); return 0; };
-
- bzf->strm.avail_out = len;
- bzf->strm.next_out = buf;
-
- while (True) {
-
- if (ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return 0; };
-
- if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
- n = fread ( bzf->buf, sizeof(UChar),
- BZ_MAX_UNUSED, bzf->handle );
- if (ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return 0; };
- bzf->bufN = n;
- bzf->strm.avail_in = bzf->bufN;
- bzf->strm.next_in = bzf->buf;
- }
-
- ret = BZ2_bzDecompress ( &(bzf->strm) );
-
- if (ret != BZ_OK && ret != BZ_STREAM_END)
- { BZ_SETERR(ret); return 0; };
-
- if (ret == BZ_OK && myfeof(bzf->handle) &&
- bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
- { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
-
- if (ret == BZ_STREAM_END)
- { BZ_SETERR(BZ_STREAM_END);
- return len - bzf->strm.avail_out; };
- if (bzf->strm.avail_out == 0)
- { BZ_SETERR(BZ_OK); return len; };
-
- }
-
- return 0; /*not reached*/
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzReadGetUnused)
- ( int* bzerror,
- BZFILE* b,
- void** unused,
- int* nUnused )
-{
- bzFile* bzf = (bzFile*)b;
- if (bzf == NULL)
- { BZ_SETERR(BZ_PARAM_ERROR); return; };
- if (bzf->lastErr != BZ_STREAM_END)
- { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
- if (unused == NULL || nUnused == NULL)
- { BZ_SETERR(BZ_PARAM_ERROR); return; };
-
- BZ_SETERR(BZ_OK);
- *nUnused = bzf->strm.avail_in;
- *unused = bzf->strm.next_in;
-}
-#endif
-
-
-/*---------------------------------------------------*/
-/*--- Misc convenience stuff ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzBuffToBuffCompress)
- ( char* dest,
- unsigned int* destLen,
- char* source,
- unsigned int sourceLen,
- int blockSize100k,
- int verbosity,
- int workFactor )
-{
- bz_stream strm;
- int ret;
-
- if (dest == NULL || destLen == NULL ||
- source == NULL ||
- blockSize100k < 1 || blockSize100k > 9 ||
- verbosity < 0 || verbosity > 4 ||
- workFactor < 0 || workFactor > 250)
- return BZ_PARAM_ERROR;
-
- if (workFactor == 0) workFactor = 30;
- strm.bzalloc = NULL;
- strm.bzfree = NULL;
- strm.opaque = NULL;
- ret = BZ2_bzCompressInit ( &strm, blockSize100k,
- verbosity, workFactor );
- if (ret != BZ_OK) return ret;
-
- strm.next_in = source;
- strm.next_out = dest;
- strm.avail_in = sourceLen;
- strm.avail_out = *destLen;
-
- ret = BZ2_bzCompress ( &strm, BZ_FINISH );
- if (ret == BZ_FINISH_OK) goto output_overflow;
- if (ret != BZ_STREAM_END) goto errhandler;
-
- /* normal termination */
- *destLen -= strm.avail_out;
- BZ2_bzCompressEnd ( &strm );
- return BZ_OK;
-
- output_overflow:
- BZ2_bzCompressEnd ( &strm );
- return BZ_OUTBUFF_FULL;
-
- errhandler:
- BZ2_bzCompressEnd ( &strm );
- return ret;
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzBuffToBuffDecompress)
- ( char* dest,
- unsigned int* destLen,
- char* source,
- unsigned int sourceLen,
- int small,
- int verbosity )
-{
- bz_stream strm;
- int ret;
-
- if (dest == NULL || destLen == NULL ||
- source == NULL ||
- (small != 0 && small != 1) ||
- verbosity < 0 || verbosity > 4)
- return BZ_PARAM_ERROR;
-
- strm.bzalloc = NULL;
- strm.bzfree = NULL;
- strm.opaque = NULL;
- ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
- if (ret != BZ_OK) return ret;
-
- strm.next_in = source;
- strm.next_out = dest;
- strm.avail_in = sourceLen;
- strm.avail_out = *destLen;
-
- ret = BZ2_bzDecompress ( &strm );
- if (ret == BZ_OK) goto output_overflow_or_eof;
- if (ret != BZ_STREAM_END) goto errhandler;
-
- /* normal termination */
- *destLen -= strm.avail_out;
- BZ2_bzDecompressEnd ( &strm );
- return BZ_OK;
-
- output_overflow_or_eof:
- if (strm.avail_out > 0) {
- BZ2_bzDecompressEnd ( &strm );
- return BZ_UNEXPECTED_EOF;
- } else {
- BZ2_bzDecompressEnd ( &strm );
- return BZ_OUTBUFF_FULL;
- };
-
- errhandler:
- BZ2_bzDecompressEnd ( &strm );
- return ret;
-}
-
-
-/*---------------------------------------------------*/
-/*--
- Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
- to support better zlib compatibility.
- This code is not _officially_ part of libbzip2 (yet);
- I haven't tested it, documented it, or considered the
- threading-safeness of it.
- If this code breaks, please contact both Yoshioka and me.
---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-/*--
- return version like "0.9.5d, 4-Sept-1999".
---*/
-const char * BZ_API(BZ2_bzlibVersion)(void)
-{
- return BZ_VERSION;
-}
-
-
-#ifndef BZ_NO_STDIO
-/*---------------------------------------------------*/
-
-#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
-# include <fcntl.h>
-# include <io.h>
-# define SET_BINARY_MODE(file) _setmode(_fileno(file),O_BINARY)
-#else
-# define SET_BINARY_MODE(file)
-#endif
-static
-BZFILE * bzopen_or_bzdopen
- ( const char *path, /* no use when bzdopen */
- int fd, /* no use when bzdopen */
- const char *mode,
- int open_mode) /* bzopen: 0, bzdopen:1 */
-{
- int bzerr;
- char unused[BZ_MAX_UNUSED];
- int blockSize100k = 9;
- int writing = 0;
- char mode2[10] = "";
- FILE *fp = NULL;
- BZFILE *bzfp = NULL;
- int verbosity = 0;
- int workFactor = 30;
- int smallMode = 0;
- int nUnused = 0;
-
- if (mode == NULL) return NULL;
- while (*mode) {
- switch (*mode) {
- case 'r':
- writing = 0; break;
- case 'w':
- writing = 1; break;
- case 's':
- smallMode = 1; break;
- default:
- if (isdigit((int)(*mode))) {
- blockSize100k = *mode-BZ_HDR_0;
- }
- }
- mode++;
- }
- strcat(mode2, writing ? "w" : "r" );
- strcat(mode2,"b"); /* binary mode */
-
- if (open_mode==0) {
- if (path==NULL || strcmp(path,"")==0) {
- fp = (writing ? stdout : stdin);
- SET_BINARY_MODE(fp);
- } else {
- fp = fopen(path,mode2);
- }
- } else {
-#ifdef BZ_STRICT_ANSI
- fp = NULL;
-#else
- fp = _fdopen(fd,mode2);
-#endif
- }
- if (fp == NULL) return NULL;
-
- if (writing) {
- /* Guard against total chaos and anarchy -- JRS */
- if (blockSize100k < 1) blockSize100k = 1;
- if (blockSize100k > 9) blockSize100k = 9;
- bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
- verbosity,workFactor);
- } else {
- bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
- unused,nUnused);
- }
- if (bzfp == NULL) {
- if (fp != stdin && fp != stdout) fclose(fp);
- return NULL;
- }
- return bzfp;
-}
-
-
-/*---------------------------------------------------*/
-/*--
- open file for read or write.
- ex) bzopen("file","w9")
- case path="" or NULL => use stdin or stdout.
---*/
-BZFILE * BZ_API(BZ2_bzopen)
- ( const char *path,
- const char *mode )
-{
- return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
-}
-
-
-/*---------------------------------------------------*/
-BZFILE * BZ_API(BZ2_bzdopen)
- ( int fd,
- const char *mode )
-{
- return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
-{
- int bzerr, nread;
- if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
- nread = BZ2_bzRead(&bzerr,b,buf,len);
- if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
- return nread;
- } else {
- return -1;
- }
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
-{
- int bzerr;
-
- BZ2_bzWrite(&bzerr,b,buf,len);
- if(bzerr == BZ_OK){
- return len;
- }else{
- return -1;
- }
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzflush) (BZFILE *b)
-{
- /* do nothing now... */
- return 0;
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzclose) (BZFILE* b)
-{
- int bzerr;
- FILE *fp;
-
- if (b==NULL) {return;}
- fp = ((bzFile *)b)->handle;
- if(((bzFile*)b)->writing){
- BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
- if(bzerr != BZ_OK){
- BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
- }
- }else{
- BZ2_bzReadClose(&bzerr,b);
- }
- if(fp!=stdin && fp!=stdout){
- fclose(fp);
- }
-}
-
-
-/*---------------------------------------------------*/
-/*--
- return last error code
---*/
-static const char *bzerrorstrings[] = {
- "OK"
- ,"SEQUENCE_ERROR"
- ,"PARAM_ERROR"
- ,"MEM_ERROR"
- ,"DATA_ERROR"
- ,"DATA_ERROR_MAGIC"
- ,"IO_ERROR"
- ,"UNEXPECTED_EOF"
- ,"OUTBUFF_FULL"
- ,"CONFIG_ERROR"
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
-};
-
-
-const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
-{
- int err = ((bzFile *)b)->lastErr;
-
- if(err>0) err = 0;
- *errnum = err;
- return bzerrorstrings[err*-1];
-}
-#endif
-
-
-/*-------------------------------------------------------------*/
-/*--- end bzlib.c ---*/
-/*-------------------------------------------------------------*/
diff --git a/dep/StormLib/src/bzip2/bzlib.h b/dep/StormLib/src/bzip2/bzlib.h
deleted file mode 100644
index c5b75d6d8ff..00000000000
--- a/dep/StormLib/src/bzip2/bzlib.h
+++ /dev/null
@@ -1,282 +0,0 @@
-
-/*-------------------------------------------------------------*/
-/*--- Public header file for the library. ---*/
-/*--- bzlib.h ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
- This file is part of bzip2/libbzip2, a program and library for
- lossless, block-sorting data compression.
-
- bzip2/libbzip2 version 1.0.5 of 10 December 2007
- Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
-
- Please read the WARNING, DISCLAIMER and PATENTS sections in the
- README file.
-
- This program is released under the terms of the license contained
- in the file LICENSE.
- ------------------------------------------------------------------ */
-
-
-#ifndef _BZLIB_H
-#define _BZLIB_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define BZ_RUN 0
-#define BZ_FLUSH 1
-#define BZ_FINISH 2
-
-#define BZ_OK 0
-#define BZ_RUN_OK 1
-#define BZ_FLUSH_OK 2
-#define BZ_FINISH_OK 3
-#define BZ_STREAM_END 4
-#define BZ_SEQUENCE_ERROR (-1)
-#define BZ_PARAM_ERROR (-2)
-#define BZ_MEM_ERROR (-3)
-#define BZ_DATA_ERROR (-4)
-#define BZ_DATA_ERROR_MAGIC (-5)
-#define BZ_IO_ERROR (-6)
-#define BZ_UNEXPECTED_EOF (-7)
-#define BZ_OUTBUFF_FULL (-8)
-#define BZ_CONFIG_ERROR (-9)
-
-typedef
- struct {
- char *next_in;
- unsigned int avail_in;
- unsigned int total_in_lo32;
- unsigned int total_in_hi32;
-
- char *next_out;
- unsigned int avail_out;
- unsigned int total_out_lo32;
- unsigned int total_out_hi32;
-
- void *state;
-
- void *(*bzalloc)(void *,int,int);
- void (*bzfree)(void *,void *);
- void *opaque;
- }
- bz_stream;
-
-
-#ifndef BZ_IMPORT
-#define BZ_EXPORT
-#endif
-
-#ifndef BZ_NO_STDIO
-/* Need a definitition for FILE */
-#include <stdio.h>
-#endif
-
-#ifdef _WIN32
-# include <windows.h>
-# ifdef small
- /* windows.h define small to char */
-# undef small
-# endif
-# ifdef BZ_EXPORT
-# define BZ_API(func) WINAPI func
-# define BZ_EXTERN extern
-# else
- /* import windows dll dynamically */
-# define BZ_API(func) (WINAPI * func)
-# define BZ_EXTERN
-# endif
-#else
-# define BZ_API(func) func
-# define BZ_EXTERN extern
-#endif
-
-
-/*-- Core (low-level) library functions --*/
-
-BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
- bz_stream* strm,
- int blockSize100k,
- int verbosity,
- int workFactor
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzCompress) (
- bz_stream* strm,
- int action
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
- bz_stream* strm
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
- bz_stream *strm,
- int verbosity,
- int small
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
- bz_stream* strm
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
- bz_stream *strm
- );
-
-
-
-/*-- High(er) level library functions --*/
-
-#ifndef BZ_NO_STDIO
-#define BZ_MAX_UNUSED 5000
-
-typedef void BZFILE;
-
-BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
- int* bzerror,
- FILE* f,
- int verbosity,
- int small,
- void* unused,
- int nUnused
- );
-
-BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
- int* bzerror,
- BZFILE* b
- );
-
-BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
- int* bzerror,
- BZFILE* b,
- void** unused,
- int* nUnused
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzRead) (
- int* bzerror,
- BZFILE* b,
- void* buf,
- int len
- );
-
-BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
- int* bzerror,
- FILE* f,
- int blockSize100k,
- int verbosity,
- int workFactor
- );
-
-BZ_EXTERN void BZ_API(BZ2_bzWrite) (
- int* bzerror,
- BZFILE* b,
- void* buf,
- int len
- );
-
-BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
- int* bzerror,
- BZFILE* b,
- int abandon,
- unsigned int* nbytes_in,
- unsigned int* nbytes_out
- );
-
-BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
- int* bzerror,
- BZFILE* b,
- int abandon,
- unsigned int* nbytes_in_lo32,
- unsigned int* nbytes_in_hi32,
- unsigned int* nbytes_out_lo32,
- unsigned int* nbytes_out_hi32
- );
-#endif
-
-
-/*-- Utility functions --*/
-
-BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
- char* dest,
- unsigned int* destLen,
- char* source,
- unsigned int sourceLen,
- int blockSize100k,
- int verbosity,
- int workFactor
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
- char* dest,
- unsigned int* destLen,
- char* source,
- unsigned int sourceLen,
- int small,
- int verbosity
- );
-
-
-/*--
- Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
- to support better zlib compatibility.
- This code is not _officially_ part of libbzip2 (yet);
- I haven't tested it, documented it, or considered the
- threading-safeness of it.
- If this code breaks, please contact both Yoshioka and me.
---*/
-
-BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
- void
- );
-
-#ifndef BZ_NO_STDIO
-BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
- const char *path,
- const char *mode
- );
-
-BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
- int fd,
- const char *mode
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzread) (
- BZFILE* b,
- void* buf,
- int len
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzwrite) (
- BZFILE* b,
- void* buf,
- int len
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzflush) (
- BZFILE* b
- );
-
-BZ_EXTERN void BZ_API(BZ2_bzclose) (
- BZFILE* b
- );
-
-BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
- BZFILE *b,
- int *errnum
- );
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-/*-------------------------------------------------------------*/
-/*--- end bzlib.h ---*/
-/*-------------------------------------------------------------*/
diff --git a/dep/StormLib/src/bzip2/bzlib_private.h b/dep/StormLib/src/bzip2/bzlib_private.h
deleted file mode 100644
index 23427879b18..00000000000
--- a/dep/StormLib/src/bzip2/bzlib_private.h
+++ /dev/null
@@ -1,509 +0,0 @@
-
-/*-------------------------------------------------------------*/
-/*--- Private header file for the library. ---*/
-/*--- bzlib_private.h ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
- This file is part of bzip2/libbzip2, a program and library for
- lossless, block-sorting data compression.
-
- bzip2/libbzip2 version 1.0.5 of 10 December 2007
- Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
-
- Please read the WARNING, DISCLAIMER and PATENTS sections in the
- README file.
-
- This program is released under the terms of the license contained
- in the file LICENSE.
- ------------------------------------------------------------------ */
-
-
-#ifndef _BZLIB_PRIVATE_H
-#define _BZLIB_PRIVATE_H
-
-#include <stdlib.h>
-
-#ifndef BZ_NO_STDIO
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#endif
-
-#include "bzlib.h"
-
-
-
-/*-- General stuff. --*/
-
-#define BZ_VERSION "1.0.5, 10-Dec-2007"
-
-typedef char Char;
-typedef unsigned char Bool;
-typedef unsigned char UChar;
-typedef int Int32;
-typedef unsigned int UInt32;
-typedef short Int16;
-typedef unsigned short UInt16;
-
-#define True ((Bool)1)
-#define False ((Bool)0)
-
-#ifndef __GNUC__
-#define __inline__ /* */
-#endif
-
-#ifndef BZ_NO_STDIO
-
-extern void BZ2_bz__AssertH__fail ( int errcode );
-#define AssertH(cond,errcode) \
- { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
-
-#if BZ_DEBUG
-#define AssertD(cond,msg) \
- { if (!(cond)) { \
- fprintf ( stderr, \
- "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
- exit(1); \
- }}
-#else
-#define AssertD(cond,msg) /* */
-#endif
-
-#define VPrintf0(zf) \
- fprintf(stderr,zf)
-#define VPrintf1(zf,za1) \
- fprintf(stderr,zf,za1)
-#define VPrintf2(zf,za1,za2) \
- fprintf(stderr,zf,za1,za2)
-#define VPrintf3(zf,za1,za2,za3) \
- fprintf(stderr,zf,za1,za2,za3)
-#define VPrintf4(zf,za1,za2,za3,za4) \
- fprintf(stderr,zf,za1,za2,za3,za4)
-#define VPrintf5(zf,za1,za2,za3,za4,za5) \
- fprintf(stderr,zf,za1,za2,za3,za4,za5)
-
-#else
-
-extern void bz_internal_error ( int errcode );
-#define AssertH(cond,errcode) \
- { if (!(cond)) bz_internal_error ( errcode ); }
-#define AssertD(cond,msg) do { } while (0)
-#define VPrintf0(zf) do { } while (0)
-#define VPrintf1(zf,za1) do { } while (0)
-#define VPrintf2(zf,za1,za2) do { } while (0)
-#define VPrintf3(zf,za1,za2,za3) do { } while (0)
-#define VPrintf4(zf,za1,za2,za3,za4) do { } while (0)
-#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
-
-#endif
-
-
-#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
-#define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp))
-
-
-/*-- Header bytes. --*/
-
-#define BZ_HDR_B 0x42 /* 'B' */
-#define BZ_HDR_Z 0x5a /* 'Z' */
-#define BZ_HDR_h 0x68 /* 'h' */
-#define BZ_HDR_0 0x30 /* '0' */
-
-/*-- Constants for the back end. --*/
-
-#define BZ_MAX_ALPHA_SIZE 258
-#define BZ_MAX_CODE_LEN 23
-
-#define BZ_RUNA 0
-#define BZ_RUNB 1
-
-#define BZ_N_GROUPS 6
-#define BZ_G_SIZE 50
-#define BZ_N_ITERS 4
-
-#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
-
-
-
-/*-- Stuff for randomising repetitive blocks. --*/
-
-extern Int32 BZ2_rNums[512];
-
-#define BZ_RAND_DECLS \
- Int32 rNToGo; \
- Int32 rTPos \
-
-#define BZ_RAND_INIT_MASK \
- s->rNToGo = 0; \
- s->rTPos = 0 \
-
-#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
-
-#define BZ_RAND_UPD_MASK \
- if (s->rNToGo == 0) { \
- s->rNToGo = BZ2_rNums[s->rTPos]; \
- s->rTPos++; \
- if (s->rTPos == 512) s->rTPos = 0; \
- } \
- s->rNToGo--;
-
-
-
-/*-- Stuff for doing CRCs. --*/
-
-extern UInt32 BZ2_crc32Table[256];
-
-#define BZ_INITIALISE_CRC(crcVar) \
-{ \
- crcVar = 0xffffffffL; \
-}
-
-#define BZ_FINALISE_CRC(crcVar) \
-{ \
- crcVar = ~(crcVar); \
-}
-
-#define BZ_UPDATE_CRC(crcVar,cha) \
-{ \
- crcVar = (crcVar << 8) ^ \
- BZ2_crc32Table[(crcVar >> 24) ^ \
- ((UChar)cha)]; \
-}
-
-
-
-/*-- States and modes for compression. --*/
-
-#define BZ_M_IDLE 1
-#define BZ_M_RUNNING 2
-#define BZ_M_FLUSHING 3
-#define BZ_M_FINISHING 4
-
-#define BZ_S_OUTPUT 1
-#define BZ_S_INPUT 2
-
-#define BZ_N_RADIX 2
-#define BZ_N_QSORT 12
-#define BZ_N_SHELL 18
-#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
-
-
-
-
-/*-- Structure holding all the compression-side stuff. --*/
-
-typedef
- struct {
- /* pointer back to the struct bz_stream */
- bz_stream* strm;
-
- /* mode this stream is in, and whether inputting */
- /* or outputting data */
- Int32 mode;
- Int32 state;
-
- /* remembers avail_in when flush/finish requested */
- UInt32 avail_in_expect;
-
- /* for doing the block sorting */
- UInt32* arr1;
- UInt32* arr2;
- UInt32* ftab;
- Int32 origPtr;
-
- /* aliases for arr1 and arr2 */
- UInt32* ptr;
- UChar* block;
- UInt16* mtfv;
- UChar* zbits;
-
- /* for deciding when to use the fallback sorting algorithm */
- Int32 workFactor;
-
- /* run-length-encoding of the input */
- UInt32 state_in_ch;
- Int32 state_in_len;
- BZ_RAND_DECLS;
-
- /* input and output limits and current posns */
- Int32 nblock;
- Int32 nblockMAX;
- Int32 numZ;
- Int32 state_out_pos;
-
- /* map of bytes used in block */
- Int32 nInUse;
- Bool inUse[256];
- UChar unseqToSeq[256];
-
- /* the buffer for bit stream creation */
- UInt32 bsBuff;
- Int32 bsLive;
-
- /* block and combined CRCs */
- UInt32 blockCRC;
- UInt32 combinedCRC;
-
- /* misc administratium */
- Int32 verbosity;
- Int32 blockNo;
- Int32 blockSize100k;
-
- /* stuff for coding the MTF values */
- Int32 nMTF;
- Int32 mtfFreq [BZ_MAX_ALPHA_SIZE];
- UChar selector [BZ_MAX_SELECTORS];
- UChar selectorMtf[BZ_MAX_SELECTORS];
-
- UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- /* second dimension: only 3 needed; 4 makes index calculations faster */
- UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4];
-
- }
- EState;
-
-
-
-/*-- externs for compression. --*/
-
-extern void
-BZ2_blockSort ( EState* );
-
-extern void
-BZ2_compressBlock ( EState*, Bool );
-
-extern void
-BZ2_bsInitWrite ( EState* );
-
-extern void
-BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
-
-extern void
-BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
-
-
-
-/*-- states for decompression. --*/
-
-#define BZ_X_IDLE 1
-#define BZ_X_OUTPUT 2
-
-#define BZ_X_MAGIC_1 10
-#define BZ_X_MAGIC_2 11
-#define BZ_X_MAGIC_3 12
-#define BZ_X_MAGIC_4 13
-#define BZ_X_BLKHDR_1 14
-#define BZ_X_BLKHDR_2 15
-#define BZ_X_BLKHDR_3 16
-#define BZ_X_BLKHDR_4 17
-#define BZ_X_BLKHDR_5 18
-#define BZ_X_BLKHDR_6 19
-#define BZ_X_BCRC_1 20
-#define BZ_X_BCRC_2 21
-#define BZ_X_BCRC_3 22
-#define BZ_X_BCRC_4 23
-#define BZ_X_RANDBIT 24
-#define BZ_X_ORIGPTR_1 25
-#define BZ_X_ORIGPTR_2 26
-#define BZ_X_ORIGPTR_3 27
-#define BZ_X_MAPPING_1 28
-#define BZ_X_MAPPING_2 29
-#define BZ_X_SELECTOR_1 30
-#define BZ_X_SELECTOR_2 31
-#define BZ_X_SELECTOR_3 32
-#define BZ_X_CODING_1 33
-#define BZ_X_CODING_2 34
-#define BZ_X_CODING_3 35
-#define BZ_X_MTF_1 36
-#define BZ_X_MTF_2 37
-#define BZ_X_MTF_3 38
-#define BZ_X_MTF_4 39
-#define BZ_X_MTF_5 40
-#define BZ_X_MTF_6 41
-#define BZ_X_ENDHDR_2 42
-#define BZ_X_ENDHDR_3 43
-#define BZ_X_ENDHDR_4 44
-#define BZ_X_ENDHDR_5 45
-#define BZ_X_ENDHDR_6 46
-#define BZ_X_CCRC_1 47
-#define BZ_X_CCRC_2 48
-#define BZ_X_CCRC_3 49
-#define BZ_X_CCRC_4 50
-
-
-
-/*-- Constants for the fast MTF decoder. --*/
-
-#define MTFA_SIZE 4096
-#define MTFL_SIZE 16
-
-
-
-/*-- Structure holding all the decompression-side stuff. --*/
-
-typedef
- struct {
- /* pointer back to the struct bz_stream */
- bz_stream* strm;
-
- /* state indicator for this stream */
- Int32 state;
-
- /* for doing the final run-length decoding */
- UChar state_out_ch;
- Int32 state_out_len;
- Bool blockRandomised;
- BZ_RAND_DECLS;
-
- /* the buffer for bit stream reading */
- UInt32 bsBuff;
- Int32 bsLive;
-
- /* misc administratium */
- Int32 blockSize100k;
- Bool smallDecompress;
- Int32 currBlockNo;
- Int32 verbosity;
-
- /* for undoing the Burrows-Wheeler transform */
- Int32 origPtr;
- UInt32 tPos;
- Int32 k0;
- Int32 unzftab[256];
- Int32 nblock_used;
- Int32 cftab[257];
- Int32 cftabCopy[257];
-
- /* for undoing the Burrows-Wheeler transform (FAST) */
- UInt32 *tt;
-
- /* for undoing the Burrows-Wheeler transform (SMALL) */
- UInt16 *ll16;
- UChar *ll4;
-
- /* stored and calculated CRCs */
- UInt32 storedBlockCRC;
- UInt32 storedCombinedCRC;
- UInt32 calculatedBlockCRC;
- UInt32 calculatedCombinedCRC;
-
- /* map of bytes used in block */
- Int32 nInUse;
- Bool inUse[256];
- Bool inUse16[16];
- UChar seqToUnseq[256];
-
- /* for decoding the MTF values */
- UChar mtfa [MTFA_SIZE];
- Int32 mtfbase[256 / MTFL_SIZE];
- UChar selector [BZ_MAX_SELECTORS];
- UChar selectorMtf[BZ_MAX_SELECTORS];
- UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
-
- Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- Int32 minLens[BZ_N_GROUPS];
-
- /* save area for scalars in the main decompress code */
- Int32 save_i;
- Int32 save_j;
- Int32 save_t;
- Int32 save_alphaSize;
- Int32 save_nGroups;
- Int32 save_nSelectors;
- Int32 save_EOB;
- Int32 save_groupNo;
- Int32 save_groupPos;
- Int32 save_nextSym;
- Int32 save_nblockMAX;
- Int32 save_nblock;
- Int32 save_es;
- Int32 save_N;
- Int32 save_curr;
- Int32 save_zt;
- Int32 save_zn;
- Int32 save_zvec;
- Int32 save_zj;
- Int32 save_gSel;
- Int32 save_gMinlen;
- Int32* save_gLimit;
- Int32* save_gBase;
- Int32* save_gPerm;
-
- }
- DState;
-
-
-
-/*-- Macros for decompression. --*/
-
-#define BZ_GET_FAST(cccc) \
- /* c_tPos is unsigned, hence test < 0 is pointless. */ \
- if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
- s->tPos = s->tt[s->tPos]; \
- cccc = (UChar)(s->tPos & 0xff); \
- s->tPos >>= 8;
-
-#define BZ_GET_FAST_C(cccc) \
- /* c_tPos is unsigned, hence test < 0 is pointless. */ \
- if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
- c_tPos = c_tt[c_tPos]; \
- cccc = (UChar)(c_tPos & 0xff); \
- c_tPos >>= 8;
-
-#define SET_LL4(i,n) \
- { if (((i) & 0x1) == 0) \
- s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \
- s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \
- }
-
-#define GET_LL4(i) \
- ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
-
-#define SET_LL(i,n) \
- { s->ll16[i] = (UInt16)(n & 0x0000ffff); \
- SET_LL4(i, n >> 16); \
- }
-
-#define GET_LL(i) \
- (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
-
-#define BZ_GET_SMALL(cccc) \
- /* c_tPos is unsigned, hence test < 0 is pointless. */ \
- if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
- cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
- s->tPos = GET_LL(s->tPos);
-
-
-/*-- externs for decompression. --*/
-
-extern Int32
-BZ2_indexIntoF ( Int32, Int32* );
-
-extern Int32
-BZ2_decompress ( DState* );
-
-extern void
-BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
- Int32, Int32, Int32 );
-
-
-#endif
-
-
-/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
-
-#ifdef BZ_NO_STDIO
-#ifndef NULL
-#define NULL 0
-#endif
-#endif
-
-
-/*-------------------------------------------------------------*/
-/*--- end bzlib_private.h ---*/
-/*-------------------------------------------------------------*/
diff --git a/dep/StormLib/src/bzip2/compress.c b/dep/StormLib/src/bzip2/compress.c
deleted file mode 100644
index 8c80a079700..00000000000
--- a/dep/StormLib/src/bzip2/compress.c
+++ /dev/null
@@ -1,672 +0,0 @@
-
-/*-------------------------------------------------------------*/
-/*--- Compression machinery (not incl block sorting) ---*/
-/*--- compress.c ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
- This file is part of bzip2/libbzip2, a program and library for
- lossless, block-sorting data compression.
-
- bzip2/libbzip2 version 1.0.5 of 10 December 2007
- Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
-
- Please read the WARNING, DISCLAIMER and PATENTS sections in the
- README file.
-
- This program is released under the terms of the license contained
- in the file LICENSE.
- ------------------------------------------------------------------ */
-
-
-/* CHANGES
- 0.9.0 -- original version.
- 0.9.0a/b -- no changes in this file.
- 0.9.0c -- changed setting of nGroups in sendMTFValues()
- so as to do a bit better on small files
-*/
-
-#include "bzlib_private.h"
-
-
-/*---------------------------------------------------*/
-/*--- Bit stream I/O ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-void BZ2_bsInitWrite ( EState* s )
-{
- s->bsLive = 0;
- s->bsBuff = 0;
-}
-
-
-/*---------------------------------------------------*/
-static
-void bsFinishWrite ( EState* s )
-{
- while (s->bsLive > 0) {
- s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
- s->numZ++;
- s->bsBuff <<= 8;
- s->bsLive -= 8;
- }
-}
-
-
-/*---------------------------------------------------*/
-#define bsNEEDW(nz) \
-{ \
- while (s->bsLive >= 8) { \
- s->zbits[s->numZ] \
- = (UChar)(s->bsBuff >> 24); \
- s->numZ++; \
- s->bsBuff <<= 8; \
- s->bsLive -= 8; \
- } \
-}
-
-
-/*---------------------------------------------------*/
-static
-__inline__
-void bsW ( EState* s, Int32 n, UInt32 v )
-{
- bsNEEDW ( n );
- s->bsBuff |= (v << (32 - s->bsLive - n));
- s->bsLive += n;
-}
-
-
-/*---------------------------------------------------*/
-static
-void bsPutUInt32 ( EState* s, UInt32 u )
-{
- bsW ( s, 8, (u >> 24) & 0xffL );
- bsW ( s, 8, (u >> 16) & 0xffL );
- bsW ( s, 8, (u >> 8) & 0xffL );
- bsW ( s, 8, u & 0xffL );
-}
-
-
-/*---------------------------------------------------*/
-static
-void bsPutUChar ( EState* s, UChar c )
-{
- bsW( s, 8, (UInt32)c );
-}
-
-
-/*---------------------------------------------------*/
-/*--- The back end proper ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-static
-void makeMaps_e ( EState* s )
-{
- Int32 i;
- s->nInUse = 0;
- for (i = 0; i < 256; i++)
- if (s->inUse[i]) {
- s->unseqToSeq[i] = s->nInUse;
- s->nInUse++;
- }
-}
-
-
-/*---------------------------------------------------*/
-static
-void generateMTFValues ( EState* s )
-{
- UChar yy[256];
- Int32 i, j;
- Int32 zPend;
- Int32 wr;
- Int32 EOB;
-
- /*
- After sorting (eg, here),
- s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
- and
- ((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
- holds the original block data.
-
- The first thing to do is generate the MTF values,
- and put them in
- ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
- Because there are strictly fewer or equal MTF values
- than block values, ptr values in this area are overwritten
- with MTF values only when they are no longer needed.
-
- The final compressed bitstream is generated into the
- area starting at
- (UChar*) (&((UChar*)s->arr2)[s->nblock])
-
- These storage aliases are set up in bzCompressInit(),
- except for the last one, which is arranged in
- compressBlock().
- */
- UInt32* ptr = s->ptr;
- UChar* block = s->block;
- UInt16* mtfv = s->mtfv;
-
- makeMaps_e ( s );
- EOB = s->nInUse+1;
-
- for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
-
- wr = 0;
- zPend = 0;
- for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
-
- for (i = 0; i < s->nblock; i++) {
- UChar ll_i;
- AssertD ( wr <= i, "generateMTFValues(1)" );
- j = ptr[i]-1; if (j < 0) j += s->nblock;
- ll_i = s->unseqToSeq[block[j]];
- AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
-
- if (yy[0] == ll_i) {
- zPend++;
- } else {
-
- if (zPend > 0) {
- zPend--;
- while (True) {
- if (zPend & 1) {
- mtfv[wr] = BZ_RUNB; wr++;
- s->mtfFreq[BZ_RUNB]++;
- } else {
- mtfv[wr] = BZ_RUNA; wr++;
- s->mtfFreq[BZ_RUNA]++;
- }
- if (zPend < 2) break;
- zPend = (zPend - 2) / 2;
- };
- zPend = 0;
- }
- {
- register UChar rtmp;
- register UChar* ryy_j;
- register UChar rll_i;
- rtmp = yy[1];
- yy[1] = yy[0];
- ryy_j = &(yy[1]);
- rll_i = ll_i;
- while ( rll_i != rtmp ) {
- register UChar rtmp2;
- ryy_j++;
- rtmp2 = rtmp;
- rtmp = *ryy_j;
- *ryy_j = rtmp2;
- };
- yy[0] = rtmp;
- j = ryy_j - &(yy[0]);
- mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
- }
-
- }
- }
-
- if (zPend > 0) {
- zPend--;
- while (True) {
- if (zPend & 1) {
- mtfv[wr] = BZ_RUNB; wr++;
- s->mtfFreq[BZ_RUNB]++;
- } else {
- mtfv[wr] = BZ_RUNA; wr++;
- s->mtfFreq[BZ_RUNA]++;
- }
- if (zPend < 2) break;
- zPend = (zPend - 2) / 2;
- };
- zPend = 0;
- }
-
- mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
-
- s->nMTF = wr;
-}
-
-
-/*---------------------------------------------------*/
-#define BZ_LESSER_ICOST 0
-#define BZ_GREATER_ICOST 15
-
-static
-void sendMTFValues ( EState* s )
-{
- Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
- Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
- Int32 nGroups, nBytes;
-
- /*--
- UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- is a global since the decoder also needs it.
-
- Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- are also globals only used in this proc.
- Made global to keep stack frame size small.
- --*/
-
-
- UInt16 cost[BZ_N_GROUPS];
- Int32 fave[BZ_N_GROUPS];
-
- UInt16* mtfv = s->mtfv;
-
- if (s->verbosity >= 3)
- VPrintf3( " %d in block, %d after MTF & 1-2 coding, "
- "%d+2 syms in use\n",
- s->nblock, s->nMTF, s->nInUse );
-
- alphaSize = s->nInUse+2;
- for (t = 0; t < BZ_N_GROUPS; t++)
- for (v = 0; v < alphaSize; v++)
- s->len[t][v] = BZ_GREATER_ICOST;
-
- /*--- Decide how many coding tables to use ---*/
- AssertH ( s->nMTF > 0, 3001 );
- if (s->nMTF < 200) nGroups = 2; else
- if (s->nMTF < 600) nGroups = 3; else
- if (s->nMTF < 1200) nGroups = 4; else
- if (s->nMTF < 2400) nGroups = 5; else
- nGroups = 6;
-
- /*--- Generate an initial set of coding tables ---*/
- {
- Int32 nPart, remF, tFreq, aFreq;
-
- nPart = nGroups;
- remF = s->nMTF;
- gs = 0;
- while (nPart > 0) {
- tFreq = remF / nPart;
- ge = gs-1;
- aFreq = 0;
- while (aFreq < tFreq && ge < alphaSize-1) {
- ge++;
- aFreq += s->mtfFreq[ge];
- }
-
- if (ge > gs
- && nPart != nGroups && nPart != 1
- && ((nGroups-nPart) % 2 == 1)) {
- aFreq -= s->mtfFreq[ge];
- ge--;
- }
-
- if (s->verbosity >= 3)
- VPrintf5( " initial group %d, [%d .. %d], "
- "has %d syms (%4.1f%%)\n",
- nPart, gs, ge, aFreq,
- (100.0 * (float)aFreq) / (float)(s->nMTF) );
-
- for (v = 0; v < alphaSize; v++)
- if (v >= gs && v <= ge)
- s->len[nPart-1][v] = BZ_LESSER_ICOST; else
- s->len[nPart-1][v] = BZ_GREATER_ICOST;
-
- nPart--;
- gs = ge+1;
- remF -= aFreq;
- }
- }
-
- /*---
- Iterate up to BZ_N_ITERS times to improve the tables.
- ---*/
- for (iter = 0; iter < BZ_N_ITERS; iter++) {
-
- for (t = 0; t < nGroups; t++) fave[t] = 0;
-
- for (t = 0; t < nGroups; t++)
- for (v = 0; v < alphaSize; v++)
- s->rfreq[t][v] = 0;
-
- /*---
- Set up an auxiliary length table which is used to fast-track
- the common case (nGroups == 6).
- ---*/
- if (nGroups == 6) {
- for (v = 0; v < alphaSize; v++) {
- s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
- s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
- s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
- }
- }
-
- nSelectors = 0;
- totc = 0;
- gs = 0;
- while (True) {
-
- /*--- Set group start & end marks. --*/
- if (gs >= s->nMTF) break;
- ge = gs + BZ_G_SIZE - 1;
- if (ge >= s->nMTF) ge = s->nMTF-1;
-
- /*--
- Calculate the cost of this group as coded
- by each of the coding tables.
- --*/
- for (t = 0; t < nGroups; t++) cost[t] = 0;
-
- if (nGroups == 6 && 50 == ge-gs+1) {
- /*--- fast track the common case ---*/
- register UInt32 cost01, cost23, cost45;
- register UInt16 icv;
- cost01 = cost23 = cost45 = 0;
-
-# define BZ_ITER(nn) \
- icv = mtfv[gs+(nn)]; \
- cost01 += s->len_pack[icv][0]; \
- cost23 += s->len_pack[icv][1]; \
- cost45 += s->len_pack[icv][2]; \
-
- BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4);
- BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9);
- BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
- BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
- BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
- BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
- BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
- BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
- BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
- BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
-
-# undef BZ_ITER
-
- cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
- cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
- cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
-
- } else {
- /*--- slow version which correctly handles all situations ---*/
- for (i = gs; i <= ge; i++) {
- UInt16 icv = mtfv[i];
- for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
- }
- }
-
- /*--
- Find the coding table which is best for this group,
- and record its identity in the selector table.
- --*/
- bc = 999999999; bt = -1;
- for (t = 0; t < nGroups; t++)
- if (cost[t] < bc) { bc = cost[t]; bt = t; };
- totc += bc;
- fave[bt]++;
- s->selector[nSelectors] = bt;
- nSelectors++;
-
- /*--
- Increment the symbol frequencies for the selected table.
- --*/
- if (nGroups == 6 && 50 == ge-gs+1) {
- /*--- fast track the common case ---*/
-
-# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
-
- BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4);
- BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9);
- BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
- BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
- BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
- BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
- BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
- BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
- BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
- BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
-
-# undef BZ_ITUR
-
- } else {
- /*--- slow version which correctly handles all situations ---*/
- for (i = gs; i <= ge; i++)
- s->rfreq[bt][ mtfv[i] ]++;
- }
-
- gs = ge+1;
- }
- if (s->verbosity >= 3) {
- VPrintf2 ( " pass %d: size is %d, grp uses are ",
- iter+1, totc/8 );
- for (t = 0; t < nGroups; t++)
- VPrintf1 ( "%d ", fave[t] );
- VPrintf0 ( "\n" );
- }
-
- /*--
- Recompute the tables based on the accumulated frequencies.
- --*/
- /* maxLen was changed from 20 to 17 in bzip2-1.0.3. See
- comment in huffman.c for details. */
- for (t = 0; t < nGroups; t++)
- BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
- alphaSize, 17 /*20*/ );
- }
-
-
- AssertH( nGroups < 8, 3002 );
- AssertH( nSelectors < 32768 &&
- nSelectors <= (2 + (900000 / BZ_G_SIZE)),
- 3003 );
-
-
- /*--- Compute MTF values for the selectors. ---*/
- {
- UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
- for (i = 0; i < nGroups; i++) pos[i] = i;
- for (i = 0; i < nSelectors; i++) {
- ll_i = s->selector[i];
- j = 0;
- tmp = pos[j];
- while ( ll_i != tmp ) {
- j++;
- tmp2 = tmp;
- tmp = pos[j];
- pos[j] = tmp2;
- };
- pos[0] = tmp;
- s->selectorMtf[i] = j;
- }
- };
-
- /*--- Assign actual codes for the tables. --*/
- for (t = 0; t < nGroups; t++) {
- minLen = 32;
- maxLen = 0;
- for (i = 0; i < alphaSize; i++) {
- if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
- if (s->len[t][i] < minLen) minLen = s->len[t][i];
- }
- AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
- AssertH ( !(minLen < 1), 3005 );
- BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
- minLen, maxLen, alphaSize );
- }
-
- /*--- Transmit the mapping table. ---*/
- {
- Bool inUse16[16];
- for (i = 0; i < 16; i++) {
- inUse16[i] = False;
- for (j = 0; j < 16; j++)
- if (s->inUse[i * 16 + j]) inUse16[i] = True;
- }
-
- nBytes = s->numZ;
- for (i = 0; i < 16; i++)
- if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
-
- for (i = 0; i < 16; i++)
- if (inUse16[i])
- for (j = 0; j < 16; j++) {
- if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
- }
-
- if (s->verbosity >= 3)
- VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes );
- }
-
- /*--- Now the selectors. ---*/
- nBytes = s->numZ;
- bsW ( s, 3, nGroups );
- bsW ( s, 15, nSelectors );
- for (i = 0; i < nSelectors; i++) {
- for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
- bsW(s,1,0);
- }
- if (s->verbosity >= 3)
- VPrintf1( "selectors %d, ", s->numZ-nBytes );
-
- /*--- Now the coding tables. ---*/
- nBytes = s->numZ;
-
- for (t = 0; t < nGroups; t++) {
- Int32 curr = s->len[t][0];
- bsW ( s, 5, curr );
- for (i = 0; i < alphaSize; i++) {
- while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
- while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
- bsW ( s, 1, 0 );
- }
- }
-
- if (s->verbosity >= 3)
- VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
-
- /*--- And finally, the block data proper ---*/
- nBytes = s->numZ;
- selCtr = 0;
- gs = 0;
- while (True) {
- if (gs >= s->nMTF) break;
- ge = gs + BZ_G_SIZE - 1;
- if (ge >= s->nMTF) ge = s->nMTF-1;
- AssertH ( s->selector[selCtr] < nGroups, 3006 );
-
- if (nGroups == 6 && 50 == ge-gs+1) {
- /*--- fast track the common case ---*/
- UInt16 mtfv_i;
- UChar* s_len_sel_selCtr
- = &(s->len[s->selector[selCtr]][0]);
- Int32* s_code_sel_selCtr
- = &(s->code[s->selector[selCtr]][0]);
-
-# define BZ_ITAH(nn) \
- mtfv_i = mtfv[gs+(nn)]; \
- bsW ( s, \
- s_len_sel_selCtr[mtfv_i], \
- s_code_sel_selCtr[mtfv_i] )
-
- BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4);
- BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9);
- BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
- BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
- BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
- BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
- BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
- BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
- BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
- BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
-
-# undef BZ_ITAH
-
- } else {
- /*--- slow version which correctly handles all situations ---*/
- for (i = gs; i <= ge; i++) {
- bsW ( s,
- s->len [s->selector[selCtr]] [mtfv[i]],
- s->code [s->selector[selCtr]] [mtfv[i]] );
- }
- }
-
-
- gs = ge+1;
- selCtr++;
- }
- AssertH( selCtr == nSelectors, 3007 );
-
- if (s->verbosity >= 3)
- VPrintf1( "codes %d\n", s->numZ-nBytes );
-}
-
-
-/*---------------------------------------------------*/
-void BZ2_compressBlock ( EState* s, Bool is_last_block )
-{
- if (s->nblock > 0) {
-
- BZ_FINALISE_CRC ( s->blockCRC );
- s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
- s->combinedCRC ^= s->blockCRC;
- if (s->blockNo > 1) s->numZ = 0;
-
- if (s->verbosity >= 2)
- VPrintf4( " block %d: crc = 0x%08x, "
- "combined CRC = 0x%08x, size = %d\n",
- s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
-
- BZ2_blockSort ( s );
- }
-
- s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
-
- /*-- If this is the first block, create the stream header. --*/
- if (s->blockNo == 1) {
- BZ2_bsInitWrite ( s );
- bsPutUChar ( s, BZ_HDR_B );
- bsPutUChar ( s, BZ_HDR_Z );
- bsPutUChar ( s, BZ_HDR_h );
- bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
- }
-
- if (s->nblock > 0) {
-
- bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
- bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
- bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
-
- /*-- Now the block's CRC, so it is in a known place. --*/
- bsPutUInt32 ( s, s->blockCRC );
-
- /*--
- Now a single bit indicating (non-)randomisation.
- As of version 0.9.5, we use a better sorting algorithm
- which makes randomisation unnecessary. So always set
- the randomised bit to 'no'. Of course, the decoder
- still needs to be able to handle randomised blocks
- so as to maintain backwards compatibility with
- older versions of bzip2.
- --*/
- bsW(s,1,0);
-
- bsW ( s, 24, s->origPtr );
- generateMTFValues ( s );
- sendMTFValues ( s );
- }
-
-
- /*-- If this is the last block, add the stream trailer. --*/
- if (is_last_block) {
-
- bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
- bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
- bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
- bsPutUInt32 ( s, s->combinedCRC );
- if (s->verbosity >= 2)
- VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC );
- bsFinishWrite ( s );
- }
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end compress.c ---*/
-/*-------------------------------------------------------------*/
diff --git a/dep/StormLib/src/bzip2/crctable.c b/dep/StormLib/src/bzip2/crctable.c
deleted file mode 100644
index 215687b2c05..00000000000
--- a/dep/StormLib/src/bzip2/crctable.c
+++ /dev/null
@@ -1,104 +0,0 @@
-
-/*-------------------------------------------------------------*/
-/*--- Table for doing CRCs ---*/
-/*--- crctable.c ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
- This file is part of bzip2/libbzip2, a program and library for
- lossless, block-sorting data compression.
-
- bzip2/libbzip2 version 1.0.5 of 10 December 2007
- Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
-
- Please read the WARNING, DISCLAIMER and PATENTS sections in the
- README file.
-
- This program is released under the terms of the license contained
- in the file LICENSE.
- ------------------------------------------------------------------ */
-
-
-#include "bzlib_private.h"
-
-/*--
- I think this is an implementation of the AUTODIN-II,
- Ethernet & FDDI 32-bit CRC standard. Vaguely derived
- from code by Rob Warnock, in Section 51 of the
- comp.compression FAQ.
---*/
-
-UInt32 BZ2_crc32Table[256] = {
-
- /*-- Ugly, innit? --*/
-
- 0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
- 0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
- 0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
- 0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
- 0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
- 0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
- 0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
- 0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
- 0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
- 0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
- 0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
- 0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
- 0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
- 0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
- 0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
- 0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
- 0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
- 0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
- 0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
- 0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
- 0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
- 0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
- 0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
- 0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
- 0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
- 0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
- 0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
- 0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
- 0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
- 0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
- 0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
- 0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
- 0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
- 0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
- 0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
- 0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
- 0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
- 0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
- 0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
- 0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
- 0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
- 0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
- 0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
- 0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
- 0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
- 0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
- 0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
- 0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
- 0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
- 0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
- 0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
- 0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
- 0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
- 0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
- 0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
- 0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
- 0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
- 0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
- 0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
- 0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
- 0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
- 0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
- 0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
- 0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
-};
-
-
-/*-------------------------------------------------------------*/
-/*--- end crctable.c ---*/
-/*-------------------------------------------------------------*/
diff --git a/dep/StormLib/src/bzip2/decompress.c b/dep/StormLib/src/bzip2/decompress.c
deleted file mode 100644
index bba5e0fa36d..00000000000
--- a/dep/StormLib/src/bzip2/decompress.c
+++ /dev/null
@@ -1,626 +0,0 @@
-
-/*-------------------------------------------------------------*/
-/*--- Decompression machinery ---*/
-/*--- decompress.c ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
- This file is part of bzip2/libbzip2, a program and library for
- lossless, block-sorting data compression.
-
- bzip2/libbzip2 version 1.0.5 of 10 December 2007
- Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
-
- Please read the WARNING, DISCLAIMER and PATENTS sections in the
- README file.
-
- This program is released under the terms of the license contained
- in the file LICENSE.
- ------------------------------------------------------------------ */
-
-
-#include "bzlib_private.h"
-
-
-/*---------------------------------------------------*/
-static
-void makeMaps_d ( DState* s )
-{
- Int32 i;
- s->nInUse = 0;
- for (i = 0; i < 256; i++)
- if (s->inUse[i]) {
- s->seqToUnseq[s->nInUse] = i;
- s->nInUse++;
- }
-}
-
-
-/*---------------------------------------------------*/
-#define RETURN(rrr) \
- { retVal = rrr; goto save_state_and_return; };
-
-#define GET_BITS(lll,vvv,nnn) \
- case lll: s->state = lll; \
- while (True) { \
- if (s->bsLive >= nnn) { \
- UInt32 v; \
- v = (s->bsBuff >> \
- (s->bsLive-nnn)) & ((1 << nnn)-1); \
- s->bsLive -= nnn; \
- vvv = v; \
- break; \
- } \
- if (s->strm->avail_in == 0) RETURN(BZ_OK); \
- s->bsBuff \
- = (s->bsBuff << 8) | \
- ((UInt32) \
- (*((UChar*)(s->strm->next_in)))); \
- s->bsLive += 8; \
- s->strm->next_in++; \
- s->strm->avail_in--; \
- s->strm->total_in_lo32++; \
- if (s->strm->total_in_lo32 == 0) \
- s->strm->total_in_hi32++; \
- }
-
-#define GET_UCHAR(lll,uuu) \
- GET_BITS(lll,uuu,8)
-
-#define GET_BIT(lll,uuu) \
- GET_BITS(lll,uuu,1)
-
-/*---------------------------------------------------*/
-#define GET_MTF_VAL(label1,label2,lval) \
-{ \
- if (groupPos == 0) { \
- groupNo++; \
- if (groupNo >= nSelectors) \
- RETURN(BZ_DATA_ERROR); \
- groupPos = BZ_G_SIZE; \
- gSel = s->selector[groupNo]; \
- gMinlen = s->minLens[gSel]; \
- gLimit = &(s->limit[gSel][0]); \
- gPerm = &(s->perm[gSel][0]); \
- gBase = &(s->base[gSel][0]); \
- } \
- groupPos--; \
- zn = gMinlen; \
- GET_BITS(label1, zvec, zn); \
- while (1) { \
- if (zn > 20 /* the longest code */) \
- RETURN(BZ_DATA_ERROR); \
- if (zvec <= gLimit[zn]) break; \
- zn++; \
- GET_BIT(label2, zj); \
- zvec = (zvec << 1) | zj; \
- }; \
- if (zvec - gBase[zn] < 0 \
- || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
- RETURN(BZ_DATA_ERROR); \
- lval = gPerm[zvec - gBase[zn]]; \
-}
-
-
-/*---------------------------------------------------*/
-Int32 BZ2_decompress ( DState* s )
-{
- UChar uc;
- Int32 retVal;
- Int32 minLen, maxLen;
- bz_stream* strm = s->strm;
-
- /* stuff that needs to be saved/restored */
- Int32 i;
- Int32 j;
- Int32 t;
- Int32 alphaSize;
- Int32 nGroups;
- Int32 nSelectors;
- Int32 EOB;
- Int32 groupNo;
- Int32 groupPos;
- Int32 nextSym;
- Int32 nblockMAX;
- Int32 nblock;
- Int32 es;
- Int32 N;
- Int32 curr;
- Int32 zt;
- Int32 zn;
- Int32 zvec;
- Int32 zj;
- Int32 gSel;
- Int32 gMinlen;
- Int32* gLimit;
- Int32* gBase;
- Int32* gPerm;
-
- if (s->state == BZ_X_MAGIC_1) {
- /*initialise the save area*/
- s->save_i = 0;
- s->save_j = 0;
- s->save_t = 0;
- s->save_alphaSize = 0;
- s->save_nGroups = 0;
- s->save_nSelectors = 0;
- s->save_EOB = 0;
- s->save_groupNo = 0;
- s->save_groupPos = 0;
- s->save_nextSym = 0;
- s->save_nblockMAX = 0;
- s->save_nblock = 0;
- s->save_es = 0;
- s->save_N = 0;
- s->save_curr = 0;
- s->save_zt = 0;
- s->save_zn = 0;
- s->save_zvec = 0;
- s->save_zj = 0;
- s->save_gSel = 0;
- s->save_gMinlen = 0;
- s->save_gLimit = NULL;
- s->save_gBase = NULL;
- s->save_gPerm = NULL;
- }
-
- /*restore from the save area*/
- i = s->save_i;
- j = s->save_j;
- t = s->save_t;
- alphaSize = s->save_alphaSize;
- nGroups = s->save_nGroups;
- nSelectors = s->save_nSelectors;
- EOB = s->save_EOB;
- groupNo = s->save_groupNo;
- groupPos = s->save_groupPos;
- nextSym = s->save_nextSym;
- nblockMAX = s->save_nblockMAX;
- nblock = s->save_nblock;
- es = s->save_es;
- N = s->save_N;
- curr = s->save_curr;
- zt = s->save_zt;
- zn = s->save_zn;
- zvec = s->save_zvec;
- zj = s->save_zj;
- gSel = s->save_gSel;
- gMinlen = s->save_gMinlen;
- gLimit = s->save_gLimit;
- gBase = s->save_gBase;
- gPerm = s->save_gPerm;
-
- retVal = BZ_OK;
-
- switch (s->state) {
-
- GET_UCHAR(BZ_X_MAGIC_1, uc);
- if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
-
- GET_UCHAR(BZ_X_MAGIC_2, uc);
- if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
-
- GET_UCHAR(BZ_X_MAGIC_3, uc)
- if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
-
- GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
- if (s->blockSize100k < (BZ_HDR_0 + 1) ||
- s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
- s->blockSize100k -= BZ_HDR_0;
-
- if (s->smallDecompress) {
- s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
- s->ll4 = BZALLOC(
- ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
- );
- if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
- } else {
- s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
- if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
- }
-
- GET_UCHAR(BZ_X_BLKHDR_1, uc);
-
- if (uc == 0x17) goto endhdr_2;
- if (uc != 0x31) RETURN(BZ_DATA_ERROR);
- GET_UCHAR(BZ_X_BLKHDR_2, uc);
- if (uc != 0x41) RETURN(BZ_DATA_ERROR);
- GET_UCHAR(BZ_X_BLKHDR_3, uc);
- if (uc != 0x59) RETURN(BZ_DATA_ERROR);
- GET_UCHAR(BZ_X_BLKHDR_4, uc);
- if (uc != 0x26) RETURN(BZ_DATA_ERROR);
- GET_UCHAR(BZ_X_BLKHDR_5, uc);
- if (uc != 0x53) RETURN(BZ_DATA_ERROR);
- GET_UCHAR(BZ_X_BLKHDR_6, uc);
- if (uc != 0x59) RETURN(BZ_DATA_ERROR);
-
- s->currBlockNo++;
- if (s->verbosity >= 2)
- VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo );
-
- s->storedBlockCRC = 0;
- GET_UCHAR(BZ_X_BCRC_1, uc);
- s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
- GET_UCHAR(BZ_X_BCRC_2, uc);
- s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
- GET_UCHAR(BZ_X_BCRC_3, uc);
- s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
- GET_UCHAR(BZ_X_BCRC_4, uc);
- s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
-
- GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
-
- s->origPtr = 0;
- GET_UCHAR(BZ_X_ORIGPTR_1, uc);
- s->origPtr = (s->origPtr << 8) | ((Int32)uc);
- GET_UCHAR(BZ_X_ORIGPTR_2, uc);
- s->origPtr = (s->origPtr << 8) | ((Int32)uc);
- GET_UCHAR(BZ_X_ORIGPTR_3, uc);
- s->origPtr = (s->origPtr << 8) | ((Int32)uc);
-
- if (s->origPtr < 0)
- RETURN(BZ_DATA_ERROR);
- if (s->origPtr > 10 + 100000*s->blockSize100k)
- RETURN(BZ_DATA_ERROR);
-
- /*--- Receive the mapping table ---*/
- for (i = 0; i < 16; i++) {
- GET_BIT(BZ_X_MAPPING_1, uc);
- if (uc == 1)
- s->inUse16[i] = True; else
- s->inUse16[i] = False;
- }
-
- for (i = 0; i < 256; i++) s->inUse[i] = False;
-
- for (i = 0; i < 16; i++)
- if (s->inUse16[i])
- for (j = 0; j < 16; j++) {
- GET_BIT(BZ_X_MAPPING_2, uc);
- if (uc == 1) s->inUse[i * 16 + j] = True;
- }
- makeMaps_d ( s );
- if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
- alphaSize = s->nInUse+2;
-
- /*--- Now the selectors ---*/
- GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
- if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
- GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
- if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
- for (i = 0; i < nSelectors; i++) {
- j = 0;
- while (True) {
- GET_BIT(BZ_X_SELECTOR_3, uc);
- if (uc == 0) break;
- j++;
- if (j >= nGroups) RETURN(BZ_DATA_ERROR);
- }
- s->selectorMtf[i] = j;
- }
-
- /*--- Undo the MTF values for the selectors. ---*/
- {
- UChar pos[BZ_N_GROUPS], tmp, v;
- for (v = 0; v < nGroups; v++) pos[v] = v;
-
- for (i = 0; i < nSelectors; i++) {
- v = s->selectorMtf[i];
- tmp = pos[v];
- while (v > 0) { pos[v] = pos[v-1]; v--; }
- pos[0] = tmp;
- s->selector[i] = tmp;
- }
- }
-
- /*--- Now the coding tables ---*/
- for (t = 0; t < nGroups; t++) {
- GET_BITS(BZ_X_CODING_1, curr, 5);
- for (i = 0; i < alphaSize; i++) {
- while (True) {
- if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
- GET_BIT(BZ_X_CODING_2, uc);
- if (uc == 0) break;
- GET_BIT(BZ_X_CODING_3, uc);
- if (uc == 0) curr++; else curr--;
- }
- s->len[t][i] = curr;
- }
- }
-
- /*--- Create the Huffman decoding tables ---*/
- for (t = 0; t < nGroups; t++) {
- minLen = 32;
- maxLen = 0;
- for (i = 0; i < alphaSize; i++) {
- if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
- if (s->len[t][i] < minLen) minLen = s->len[t][i];
- }
- BZ2_hbCreateDecodeTables (
- &(s->limit[t][0]),
- &(s->base[t][0]),
- &(s->perm[t][0]),
- &(s->len[t][0]),
- minLen, maxLen, alphaSize
- );
- s->minLens[t] = minLen;
- }
-
- /*--- Now the MTF values ---*/
-
- EOB = s->nInUse+1;
- nblockMAX = 100000 * s->blockSize100k;
- groupNo = -1;
- groupPos = 0;
-
- for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
-
- /*-- MTF init --*/
- {
- Int32 ii, jj, kk;
- kk = MTFA_SIZE-1;
- for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
- for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
- s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
- kk--;
- }
- s->mtfbase[ii] = kk + 1;
- }
- }
- /*-- end MTF init --*/
-
- nblock = 0;
- GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
-
- while (True) {
-
- if (nextSym == EOB) break;
-
- if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
-
- es = -1;
- N = 1;
- do {
- if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
- if (nextSym == BZ_RUNB) es = es + (1+1) * N;
- N = N * 2;
- GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
- }
- while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
-
- es++;
- uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
- s->unzftab[uc] += es;
-
- if (s->smallDecompress)
- while (es > 0) {
- if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
- s->ll16[nblock] = (UInt16)uc;
- nblock++;
- es--;
- }
- else
- while (es > 0) {
- if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
- s->tt[nblock] = (UInt32)uc;
- nblock++;
- es--;
- };
-
- continue;
-
- } else {
-
- if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
-
- /*-- uc = MTF ( nextSym-1 ) --*/
- {
- Int32 ii, jj, kk, pp, lno, off;
- UInt32 nn;
- nn = (UInt32)(nextSym - 1);
-
- if (nn < MTFL_SIZE) {
- /* avoid general-case expense */
- pp = s->mtfbase[0];
- uc = s->mtfa[pp+nn];
- while (nn > 3) {
- Int32 z = pp+nn;
- s->mtfa[(z) ] = s->mtfa[(z)-1];
- s->mtfa[(z)-1] = s->mtfa[(z)-2];
- s->mtfa[(z)-2] = s->mtfa[(z)-3];
- s->mtfa[(z)-3] = s->mtfa[(z)-4];
- nn -= 4;
- }
- while (nn > 0) {
- s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
- };
- s->mtfa[pp] = uc;
- } else {
- /* general case */
- lno = nn / MTFL_SIZE;
- off = nn % MTFL_SIZE;
- pp = s->mtfbase[lno] + off;
- uc = s->mtfa[pp];
- while (pp > s->mtfbase[lno]) {
- s->mtfa[pp] = s->mtfa[pp-1]; pp--;
- };
- s->mtfbase[lno]++;
- while (lno > 0) {
- s->mtfbase[lno]--;
- s->mtfa[s->mtfbase[lno]]
- = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
- lno--;
- }
- s->mtfbase[0]--;
- s->mtfa[s->mtfbase[0]] = uc;
- if (s->mtfbase[0] == 0) {
- kk = MTFA_SIZE-1;
- for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
- for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
- s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
- kk--;
- }
- s->mtfbase[ii] = kk + 1;
- }
- }
- }
- }
- /*-- end uc = MTF ( nextSym-1 ) --*/
-
- s->unzftab[s->seqToUnseq[uc]]++;
- if (s->smallDecompress)
- s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
- s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
- nblock++;
-
- GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
- continue;
- }
- }
-
- /* Now we know what nblock is, we can do a better sanity
- check on s->origPtr.
- */
- if (s->origPtr < 0 || s->origPtr >= nblock)
- RETURN(BZ_DATA_ERROR);
-
- /*-- Set up cftab to facilitate generation of T^(-1) --*/
- s->cftab[0] = 0;
- for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
- for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
- for (i = 0; i <= 256; i++) {
- if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
- /* s->cftab[i] can legitimately be == nblock */
- RETURN(BZ_DATA_ERROR);
- }
- }
-
- s->state_out_len = 0;
- s->state_out_ch = 0;
- BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
- s->state = BZ_X_OUTPUT;
- if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
-
- if (s->smallDecompress) {
-
- /*-- Make a copy of cftab, used in generation of T --*/
- for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
-
- /*-- compute the T vector --*/
- for (i = 0; i < nblock; i++) {
- uc = (UChar)(s->ll16[i]);
- SET_LL(i, s->cftabCopy[uc]);
- s->cftabCopy[uc]++;
- }
-
- /*-- Compute T^(-1) by pointer reversal on T --*/
- i = s->origPtr;
- j = GET_LL(i);
- do {
- Int32 tmp = GET_LL(j);
- SET_LL(j, i);
- i = j;
- j = tmp;
- }
- while (i != s->origPtr);
-
- s->tPos = s->origPtr;
- s->nblock_used = 0;
- if (s->blockRandomised) {
- BZ_RAND_INIT_MASK;
- BZ_GET_SMALL(s->k0); s->nblock_used++;
- BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
- } else {
- BZ_GET_SMALL(s->k0); s->nblock_used++;
- }
-
- } else {
-
- /*-- compute the T^(-1) vector --*/
- for (i = 0; i < nblock; i++) {
- uc = (UChar)(s->tt[i] & 0xff);
- s->tt[s->cftab[uc]] |= (i << 8);
- s->cftab[uc]++;
- }
-
- s->tPos = s->tt[s->origPtr] >> 8;
- s->nblock_used = 0;
- if (s->blockRandomised) {
- BZ_RAND_INIT_MASK;
- BZ_GET_FAST(s->k0); s->nblock_used++;
- BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
- } else {
- BZ_GET_FAST(s->k0); s->nblock_used++;
- }
-
- }
-
- RETURN(BZ_OK);
-
-
-
- endhdr_2:
-
- GET_UCHAR(BZ_X_ENDHDR_2, uc);
- if (uc != 0x72) RETURN(BZ_DATA_ERROR);
- GET_UCHAR(BZ_X_ENDHDR_3, uc);
- if (uc != 0x45) RETURN(BZ_DATA_ERROR);
- GET_UCHAR(BZ_X_ENDHDR_4, uc);
- if (uc != 0x38) RETURN(BZ_DATA_ERROR);
- GET_UCHAR(BZ_X_ENDHDR_5, uc);
- if (uc != 0x50) RETURN(BZ_DATA_ERROR);
- GET_UCHAR(BZ_X_ENDHDR_6, uc);
- if (uc != 0x90) RETURN(BZ_DATA_ERROR);
-
- s->storedCombinedCRC = 0;
- GET_UCHAR(BZ_X_CCRC_1, uc);
- s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
- GET_UCHAR(BZ_X_CCRC_2, uc);
- s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
- GET_UCHAR(BZ_X_CCRC_3, uc);
- s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
- GET_UCHAR(BZ_X_CCRC_4, uc);
- s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
-
- s->state = BZ_X_IDLE;
- RETURN(BZ_STREAM_END);
-
- default: AssertH ( False, 4001 );
- }
-
- AssertH ( False, 4002 );
-
- save_state_and_return:
-
- s->save_i = i;
- s->save_j = j;
- s->save_t = t;
- s->save_alphaSize = alphaSize;
- s->save_nGroups = nGroups;
- s->save_nSelectors = nSelectors;
- s->save_EOB = EOB;
- s->save_groupNo = groupNo;
- s->save_groupPos = groupPos;
- s->save_nextSym = nextSym;
- s->save_nblockMAX = nblockMAX;
- s->save_nblock = nblock;
- s->save_es = es;
- s->save_N = N;
- s->save_curr = curr;
- s->save_zt = zt;
- s->save_zn = zn;
- s->save_zvec = zvec;
- s->save_zj = zj;
- s->save_gSel = gSel;
- s->save_gMinlen = gMinlen;
- s->save_gLimit = gLimit;
- s->save_gBase = gBase;
- s->save_gPerm = gPerm;
-
- return retVal;
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end decompress.c ---*/
-/*-------------------------------------------------------------*/
diff --git a/dep/StormLib/src/bzip2/huffman.c b/dep/StormLib/src/bzip2/huffman.c
deleted file mode 100644
index 87e79e38af0..00000000000
--- a/dep/StormLib/src/bzip2/huffman.c
+++ /dev/null
@@ -1,205 +0,0 @@
-
-/*-------------------------------------------------------------*/
-/*--- Huffman coding low-level stuff ---*/
-/*--- huffman.c ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
- This file is part of bzip2/libbzip2, a program and library for
- lossless, block-sorting data compression.
-
- bzip2/libbzip2 version 1.0.5 of 10 December 2007
- Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
-
- Please read the WARNING, DISCLAIMER and PATENTS sections in the
- README file.
-
- This program is released under the terms of the license contained
- in the file LICENSE.
- ------------------------------------------------------------------ */
-
-
-#include "bzlib_private.h"
-
-/*---------------------------------------------------*/
-#define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
-#define DEPTHOF(zz1) ((zz1) & 0x000000ff)
-#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
-
-#define ADDWEIGHTS(zw1,zw2) \
- (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
- (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
-
-#define UPHEAP(z) \
-{ \
- Int32 zz, tmp; \
- zz = z; tmp = heap[zz]; \
- while (weight[tmp] < weight[heap[zz >> 1]]) { \
- heap[zz] = heap[zz >> 1]; \
- zz >>= 1; \
- } \
- heap[zz] = tmp; \
-}
-
-#define DOWNHEAP(z) \
-{ \
- Int32 zz, yy, tmp; \
- zz = z; tmp = heap[zz]; \
- while (True) { \
- yy = zz << 1; \
- if (yy > nHeap) break; \
- if (yy < nHeap && \
- weight[heap[yy+1]] < weight[heap[yy]]) \
- yy++; \
- if (weight[tmp] < weight[heap[yy]]) break; \
- heap[zz] = heap[yy]; \
- zz = yy; \
- } \
- heap[zz] = tmp; \
-}
-
-
-/*---------------------------------------------------*/
-void BZ2_hbMakeCodeLengths ( UChar *len,
- Int32 *freq,
- Int32 alphaSize,
- Int32 maxLen )
-{
- /*--
- Nodes and heap entries run from 1. Entry 0
- for both the heap and nodes is a sentinel.
- --*/
- Int32 nNodes, nHeap, n1, n2, i, j, k;
- Bool tooLong;
-
- Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ];
- Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
- Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
-
- for (i = 0; i < alphaSize; i++)
- weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
-
- while (True) {
-
- nNodes = alphaSize;
- nHeap = 0;
-
- heap[0] = 0;
- weight[0] = 0;
- parent[0] = -2;
-
- for (i = 1; i <= alphaSize; i++) {
- parent[i] = -1;
- nHeap++;
- heap[nHeap] = i;
- UPHEAP(nHeap);
- }
-
- AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
-
- while (nHeap > 1) {
- n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
- n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
- nNodes++;
- parent[n1] = parent[n2] = nNodes;
- weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
- parent[nNodes] = -1;
- nHeap++;
- heap[nHeap] = nNodes;
- UPHEAP(nHeap);
- }
-
- AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
-
- tooLong = False;
- for (i = 1; i <= alphaSize; i++) {
- j = 0;
- k = i;
- while (parent[k] >= 0) { k = parent[k]; j++; }
- len[i-1] = j;
- if (j > maxLen) tooLong = True;
- }
-
- if (! tooLong) break;
-
- /* 17 Oct 04: keep-going condition for the following loop used
- to be 'i < alphaSize', which missed the last element,
- theoretically leading to the possibility of the compressor
- looping. However, this count-scaling step is only needed if
- one of the generated Huffman code words is longer than
- maxLen, which up to and including version 1.0.2 was 20 bits,
- which is extremely unlikely. In version 1.0.3 maxLen was
- changed to 17 bits, which has minimal effect on compression
- ratio, but does mean this scaling step is used from time to
- time, enough to verify that it works.
-
- This means that bzip2-1.0.3 and later will only produce
- Huffman codes with a maximum length of 17 bits. However, in
- order to preserve backwards compatibility with bitstreams
- produced by versions pre-1.0.3, the decompressor must still
- handle lengths of up to 20. */
-
- for (i = 1; i <= alphaSize; i++) {
- j = weight[i] >> 8;
- j = 1 + (j / 2);
- weight[i] = j << 8;
- }
- }
-}
-
-
-/*---------------------------------------------------*/
-void BZ2_hbAssignCodes ( Int32 *code,
- UChar *length,
- Int32 minLen,
- Int32 maxLen,
- Int32 alphaSize )
-{
- Int32 n, vec, i;
-
- vec = 0;
- for (n = minLen; n <= maxLen; n++) {
- for (i = 0; i < alphaSize; i++)
- if (length[i] == n) { code[i] = vec; vec++; };
- vec <<= 1;
- }
-}
-
-
-/*---------------------------------------------------*/
-void BZ2_hbCreateDecodeTables ( Int32 *limit,
- Int32 *base,
- Int32 *perm,
- UChar *length,
- Int32 minLen,
- Int32 maxLen,
- Int32 alphaSize )
-{
- Int32 pp, i, j, vec;
-
- pp = 0;
- for (i = minLen; i <= maxLen; i++)
- for (j = 0; j < alphaSize; j++)
- if (length[j] == i) { perm[pp] = j; pp++; };
-
- for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
- for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
-
- for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
-
- for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
- vec = 0;
-
- for (i = minLen; i <= maxLen; i++) {
- vec += (base[i+1] - base[i]);
- limit[i] = vec-1;
- vec <<= 1;
- }
- for (i = minLen + 1; i <= maxLen; i++)
- base[i] = ((limit[i-1] + 1) << 1) - base[i];
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end huffman.c ---*/
-/*-------------------------------------------------------------*/
diff --git a/dep/StormLib/src/bzip2/randtable.c b/dep/StormLib/src/bzip2/randtable.c
deleted file mode 100644
index 068b76367bc..00000000000
--- a/dep/StormLib/src/bzip2/randtable.c
+++ /dev/null
@@ -1,84 +0,0 @@
-
-/*-------------------------------------------------------------*/
-/*--- Table for randomising repetitive blocks ---*/
-/*--- randtable.c ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
- This file is part of bzip2/libbzip2, a program and library for
- lossless, block-sorting data compression.
-
- bzip2/libbzip2 version 1.0.5 of 10 December 2007
- Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
-
- Please read the WARNING, DISCLAIMER and PATENTS sections in the
- README file.
-
- This program is released under the terms of the license contained
- in the file LICENSE.
- ------------------------------------------------------------------ */
-
-
-#include "bzlib_private.h"
-
-
-/*---------------------------------------------*/
-Int32 BZ2_rNums[512] = {
- 619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
- 985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
- 733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
- 419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
- 878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
- 862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
- 150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
- 170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
- 73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
- 909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
- 641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
- 161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
- 382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
- 98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
- 227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
- 469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
- 184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
- 715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
- 951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
- 652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
- 645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
- 609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
- 653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
- 411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
- 170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
- 857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
- 669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
- 944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
- 344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
- 897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
- 433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
- 686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
- 946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
- 978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
- 680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
- 707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
- 297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
- 134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
- 343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
- 140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
- 170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
- 369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
- 804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
- 896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
- 661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
- 768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
- 61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
- 372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
- 780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
- 920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
- 645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
- 936, 638
-};
-
-
-/*-------------------------------------------------------------*/
-/*--- end randtable.c ---*/
-/*-------------------------------------------------------------*/
diff --git a/dep/StormLib/src/huffman/huff.cpp b/dep/StormLib/src/huffman/huff.cpp
deleted file mode 100644
index 66a46b3fa55..00000000000
--- a/dep/StormLib/src/huffman/huff.cpp
+++ /dev/null
@@ -1,1303 +0,0 @@
-/*****************************************************************************/
-/* huffman.cpp Copyright (c) Ladislav Zezula 1998-2003 */
-/*---------------------------------------------------------------------------*/
-/* This module contains Huffmann (de)compression methods */
-/* */
-/* Authors : Ladislav Zezula (ladik@zezula.net) */
-/* ShadowFlare (BlakFlare@hotmail.com) */
-/* */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* xx.xx.xx 1.00 Lad The first version of dcmp.cpp */
-/* 03.05.03 1.00 Lad Added compression methods */
-/* 19.11.03 1.01 Dan Big endian handling */
-/* 08.12.03 2.01 Dan High-memory handling (> 0x80000000) */
-/*****************************************************************************/
-
-#include <assert.h>
-#include <string.h>
-
-#include "huff.h"
-
-// Special for Mac - we have to know if normal pointer greater or less
-// than 0x80000000. This variable is used in the PTR_VALID and PTR_INVALID
-// macros
-static long mul = 1;
-
-#define PTR_VALID(ptr) (((LONG_PTR)(ptr) * mul) > 0)
-#define PTR_INVALID(ptr) (((LONG_PTR)(ptr) * mul) < 0)
-#define PTR_INVALID_OR_NULL(ptr) (((LONG_PTR)(ptr) * mul) <= 0)
-
-
-//-----------------------------------------------------------------------------
-// Methods of the THTreeItem struct
-
-// 1501DB70
-THTreeItem * THTreeItem::Call1501DB70(THTreeItem * pLast)
-{
- if(pLast == NULL)
- pLast = this + 1;
- return pLast;
-}
-
-// Gets previous Huffman tree item (?)
-THTreeItem * THTreeItem::GetPrevItem(LONG_PTR value)
-{
- if(PTR_INVALID(prev))
- return PTR_NOT(prev);
-
- if(value == -1 || PTR_INVALID(value))
- value = (LONG_PTR)(this - next->prev);
- return prev + value;
-
-// OLD VERSION
-// if(PTR_INT(value) < 0)
-// value = PTR_INT((item - item->next->prev));
-// return (THTreeItem *)((char *)prev + value);
-}
-
-// 1500F5E0
-void THTreeItem::ClearItemLinks()
-{
- next = prev = NULL;
-}
-
-// 1500BC90
-void THTreeItem::RemoveItem()
-{
- THTreeItem * pTemp; // EDX
-
- if(next != NULL)
- {
- pTemp = prev;
-
- if(PTR_INVALID_OR_NULL(pTemp))
- pTemp = PTR_NOT(pTemp);
- else
- pTemp += (this - next->prev);
-
- pTemp->next = next;
- next->prev = prev;
- next = prev = NULL;
- }
-}
-
-/*
-// OLD VERSION : Removes item from the tree (?)
-static void RemoveItem(THTreeItem * item)
-{
- THTreeItem * next = item->next; // ESI
- THTreeItem * prev = item->prev; // EDX
-
- if(next == NULL)
- return;
-
- if(PTR_INT(prev) < 0)
- prev = PTR_NOT(prev);
- else
- // ??? usually item == next->prev, so what is it ?
- prev = (THTreeItem *)((unsigned char *)prev + (unsigned long)((unsigned char *)item - (unsigned char *)(next->prev)));
-
- // Remove HTree item from the chain
- prev->next = next; // Sets the 'first' pointer
- next->prev = item->prev;
-
- // Invalidate pointers
- item->next = NULL;
- item->prev = NULL;
-}
-*/
-
-//-----------------------------------------------------------------------------
-// TOutputStream functions
-
-void TOutputStream::PutBits(unsigned long dwBuff, unsigned int nPutBits)
-{
- dwBitBuff |= (dwBuff << nBits);
- nBits += nPutBits;
-
- // Flush completed bytes
- while(nBits >= 8)
- {
- if(cbOutSize != 0)
- {
- *pbOutPos++ = (unsigned char)dwBitBuff;
- cbOutSize--;
- }
-
- dwBitBuff >>= 8;
- nBits -= 8;
- }
-}
-
-//-----------------------------------------------------------------------------
-// TInputStream functions
-
-// Gets one bit from input stream
-unsigned long TInputStream::GetBit()
-{
- unsigned long dwOneBit = 0;
-
- // Ensure that the input stream is reloaded, if there are no bits left
- if(BitCount == 0)
- {
- // Refill the bit buffer
- BitBuffer = *pbInBuffer++;
- BitCount = 8;
- }
-
- // Copy the bit from bit buffer to the variable
- dwOneBit = (BitBuffer & 0x01);
- BitBuffer >>= 1;
- BitCount--;
-
- return dwOneBit;
-}
-
-// Gets 7 bits from the stream. DOES NOT remove the bits from input stream
-unsigned long TInputStream::Get7Bits()
-{
- unsigned long dwReloadByte = 0;
-
- // If there is not enough bits to get the value,
- // we have to add 8 more bits from the input buffer
- if(BitCount < 7)
- {
- dwReloadByte = *pbInBuffer++;
- BitBuffer |= dwReloadByte << BitCount;
- BitCount += 8;
- }
-
- // Return the first available 7 bits. DO NOT remove them from the input stream
- return (BitBuffer & 0x7F);
-}
-
-// Gets the whole byte from the input stream.
-unsigned long TInputStream::Get8Bits()
-{
- unsigned long dwReloadByte = 0;
- unsigned long dwOneByte = 0;
-
- // If there is not enough bits to get the value,
- // we have to add 8 more bits from the input buffer
- if(BitCount < 8)
- {
- dwReloadByte = *pbInBuffer++;
- BitBuffer |= dwReloadByte << BitCount;
- BitCount += 8;
- }
-
- // Return the lowest 8 its
- dwOneByte = (BitBuffer & 0xFF);
- BitBuffer >>= 8;
- BitCount -= 8;
- return dwOneByte;
-}
-
-void TInputStream::SkipBits(unsigned int dwBitsToSkip)
-{
- unsigned long dwReloadByte = 0;
-
- // If there is not enough bits in the buffer,
- // we have to add 8 more bits from the input buffer
- if(BitCount < dwBitsToSkip)
- {
- dwReloadByte = *pbInBuffer++;
- BitBuffer |= dwReloadByte << BitCount;
- BitCount += 8;
- }
-
- // Skip the remaining bits
- BitBuffer >>= dwBitsToSkip;
- BitCount -= dwBitsToSkip;
-}
-
-//-----------------------------------------------------------------------------
-// Functions for huffmann tree items
-
-// Inserts item into the tree (?)
-static void InsertItem(THTreeItem ** itemPtr, THTreeItem * item, unsigned long nWhere, THTreeItem * item2)
-{
- THTreeItem * next = item->next; // EDI - next to the first item
- THTreeItem * prev = item->prev; // ESI - prev to the first item
- THTreeItem * prev2; // Pointer to previous item
- LONG_PTR next2; // Pointer to the next item
-
- // The same code like in RemoveItem(item);
- if(next != 0) // If the first item already has next one
- {
- if(PTR_INVALID(prev))
- prev = PTR_NOT(prev);
- else
- prev += (item - next->prev);
-
- // 150083C1
- // Remove the item from the tree
- prev->next = next;
- next->prev = prev;
-
- // Invalidate 'prev' and 'next' pointer
- item->next = 0;
- item->prev = 0;
- }
-
- if(item2 == NULL) // EDX - If the second item is not entered,
- item2 = PTR_PTR(&itemPtr[1]); // take the first tree item
-
- switch(nWhere)
- {
- case SWITCH_ITEMS : // Switch the two items
- item->next = item2->next; // item2->next (Pointer to pointer to first)
- item->prev = item2->next->prev;
- item2->next->prev = item;
- item2->next = item; // Set the first item
- return;
-
- case INSERT_ITEM: // Insert as the last item
- item->next = item2; // Set next item (or pointer to pointer to first item)
- item->prev = item2->prev; // Set prev item (or last item in the tree)
-
- next2 = PTR_INT(itemPtr[0]);// Usually NULL
- prev2 = item2->prev; // Prev item to the second (or last tree item)
-
- if(PTR_INVALID(prev2))
- {
- if(prev != NULL)
- {
- prev2 = PTR_NOT(prev);
- if(prev2 != NULL)
- {
- prev2->next = item;
- item2->prev = item; // Next after last item
- }
- }
- return;
- }
-
- if(PTR_INVALID(next2))
- next2 = (LONG_PTR)(item2 - item2->next->prev);
-// next2 = (THTreeItem *)(unsigned long)((unsigned char *)item2 - (unsigned char *)(item2->next->prev));
-
-// prev2 = (THTreeItem *)((char *)prev2 + (unsigned long)next2);// ???
- prev2 += next2;
- prev2->next = item;
- item2->prev = item; // Set the next/last item
- return;
-
- default:
- return;
- }
-}
-
-//-----------------------------------------------------------------------------
-// THuffmannTree class functions
-
-THuffmannTree::THuffmannTree()
-{
- // We have to check if the "this" pointer is less than zero
- if((LONG_PTR)this < 0)
- mul = -1;
-}
-
-void THuffmannTree::InitTree(bool bCompression)
-{
- THTreeItem * pItem;
- unsigned int nCount;
-
- // Clear links for all the items in the tree
- for(pItem = items0008, nCount = 0x203; nCount != 0; pItem++, nCount--)
- pItem->ClearItemLinks();
-
- pItem3050 = NULL;
- pItem3054 = PTR_PTR(&pItem3054);
- pItem3058 = PTR_NOT(pItem3054);
-
- pItem305C = NULL;
- pFirst = PTR_PTR(&pFirst);
- pLast = PTR_NOT(pFirst);
-
- offs0004 = 1;
- nItems = 0;
-
- // Clear all TQDecompress items. Do this only if preparing for decompression
- if(bCompression == false)
- {
- for(nCount = 0; nCount < sizeof(qd3474) / sizeof(TQDecompress); nCount++)
- qd3474[nCount].offs00 = 0;
- }
-}
-
-// Builds Huffman tree. Called with the first 8 bits loaded from input stream
-void THuffmannTree::BuildTree(unsigned int nCmpType)
-{
- unsigned long maxByte; // [ESP+10] - The greatest character found in table
- THTreeItem ** itemPtr; // [ESP+14] - Pointer to Huffman tree item pointer array
- unsigned char * byteArray; // [ESP+1C] - Pointer to unsigned char in Table1502A630
- THTreeItem * child1;
- unsigned long i; // egcs in linux doesn't like multiple for loops without an explicit i
-
- // Loop while pointer has a valid value
- while(PTR_VALID(pLast)) // ESI - Last entry
- {
- THTreeItem * temp; // EAX
-
- if(pLast->next != NULL) // ESI->next
- pLast->RemoveItem();
- // EDI = &offs3054
- pItem3058 = PTR_PTR(&pItem3054); // [EDI+4]
- pLast->prev = pItem3058; // EAX
-
- temp = PTR_PTR(&pItem3054)->GetPrevItem(PTR_INT(&pItem3050));
-
- temp->next = pLast;
- pItem3054 = pLast;
- }
-
- // Clear all pointers in HTree item array
- memset(items306C, 0, sizeof(items306C));
-
- maxByte = 0; // Greatest character found init to zero.
- itemPtr = (THTreeItem **)&items306C; // Pointer to current entry in HTree item pointer array
-
- // Ensure we have low 8 bits only
- nCmpType &= 0xFF;
- byteArray = Table1502A630 + nCmpType * 258; // EDI also
-
- for(i = 0; i < 0x100; i++, itemPtr++)
- {
- THTreeItem * item = pItem3058; // Item to be created
- THTreeItem * pItem3 = pItem3058;
- unsigned char oneByte = byteArray[i];
-
- // Skip all the bytes which are zero.
- if(byteArray[i] == 0)
- continue;
-
- // If not valid pointer, take the first available item in the array
- if(PTR_INVALID_OR_NULL(item))
- item = &items0008[nItems++];
-
- // Insert this item as the top of the tree
- InsertItem(&pItem305C, item, SWITCH_ITEMS, NULL);
-
- item->parent = NULL; // Invalidate child and parent
- item->child = NULL;
- *itemPtr = item; // Store pointer into pointer array
-
- item->dcmpByte = i; // Store counter
- item->byteValue = oneByte; // Store byte value
- if(oneByte >= maxByte)
- {
- maxByte = oneByte;
- continue;
- }
-
- // Find the first item which has byte value greater than current one byte
- if(PTR_VALID(pItem3 = pLast)) // EDI - Pointer to the last item
- {
- // 15006AF7
- if(pItem3 != NULL)
- {
- do // 15006AFB
- {
- if(pItem3->byteValue >= oneByte)
- goto _15006B09;
- pItem3 = pItem3->prev;
- }
- while(PTR_VALID(pItem3));
- }
- }
- pItem3 = NULL;
-
- // 15006B09
- _15006B09:
- if(item->next != NULL)
- item->RemoveItem();
-
- // 15006B15
- if(pItem3 == NULL)
- pItem3 = PTR_PTR(&pFirst);
-
- // 15006B1F
- item->next = pItem3->next;
- item->prev = pItem3->next->prev;
- pItem3->next->prev = item;
- pItem3->next = item;
- }
-
- // 15006B4A
- for(; i < 0x102; i++)
- {
- THTreeItem ** itemPtr = &items306C[i]; // EDI
-
- // 15006B59
- THTreeItem * item = pItem3058; // ESI
- if(PTR_INVALID_OR_NULL(item))
- item = &items0008[nItems++];
-
- InsertItem(&pItem305C, item, INSERT_ITEM, NULL);
-
- // 15006B89
- item->dcmpByte = i;
- item->byteValue = 1;
- item->parent = NULL;
- item->child = NULL;
- *itemPtr++ = item;
- }
-
- // 15006BAA
- if(PTR_VALID(child1 = pLast)) // EDI - last item (first child to item
- {
- THTreeItem * child2; // EBP
- THTreeItem * item; // ESI
-
- // 15006BB8
- while(PTR_VALID(child2 = child1->prev))
- {
- if(PTR_INVALID_OR_NULL(item = pItem3058))
- item = &items0008[nItems++];
-
- // 15006BE3
- InsertItem(&pItem305C, item, SWITCH_ITEMS, NULL);
-
- // 15006BF3
- item->parent = NULL;
- item->child = NULL;
-
- //EDX = child2->byteValue + child1->byteValue;
- //EAX = child1->byteValue;
- //ECX = maxByte; // The greatest character (0xFF usually)
-
- item->byteValue = child1->byteValue + child2->byteValue; // 0x02
- item->child = child1; // Prev item in the
- child1->parent = item;
- child2->parent = item;
-
- // EAX = item->byteValue;
- if(item->byteValue >= maxByte)
- maxByte = item->byteValue;
- else
- {
- THTreeItem * pItem2 = child2->prev; // EDI
-
- // 15006C2D
- while(PTR_VALID(pItem2))
- {
- if(pItem2->byteValue >= item->byteValue)
- goto _15006C3B;
- pItem2 = pItem2->prev;
- }
- pItem2 = NULL;
-
- _15006C3B:
- if(item->next != 0)
- {
- THTreeItem * temp4 = item->GetPrevItem(-1);
-
- temp4->next = item->next; // The first item changed
- item->next->prev = item->prev; // First->prev changed to negative value
- item->next = NULL;
- item->prev = NULL;
- }
-
- // 15006C62
- if(pItem2 == NULL)
- pItem2 = PTR_PTR(&pFirst);
-
- item->next = pItem2->next; // Set item with 0x100 byte value
- item->prev = pItem2->next->prev; // Set item with 0x17 byte value
- pItem2->next->prev = item; // Changed prev of item with
- pItem2->next = item;
- }
-
- // 15006C7B
- if(PTR_INVALID_OR_NULL(child1 = child2->prev))
- break;
- }
- }
- // 15006C88
- offs0004 = 1;
-}
-/*
-// Modifies Huffman tree. Adds new item and changes
-void THuffmannTree::ModifyTree(unsigned long dwIndex)
-{
- THTreeItem * pItem1 = pItem3058; // ESI
- THTreeItem * pSaveLast = (PTR_INT(pLast) <= 0) ? NULL : pLast; // EBX
- THTreeItem * temp; // EAX
-
- // Prepare the first item to insert to the tree
- if(PTR_INT(pItem1) <= 0)
- pItem1 = &items0008[nItems++];
-
- // If item has any next item, remove it from the chain
- if(pItem1->next != NULL)
- {
- THTreeItem * temp = pItem1->GetPrevItem(-1); // EAX
-
- temp->next = pItem1->next;
- pItem1->next->prev = pItem1->prev;
- pItem1->next = NULL;
- pItem1->prev = NULL;
- }
-
- pItem1->next = PTR_PTR(&pFirst);
- pItem1->prev = pLast;
- temp = pItem1->next->GetPrevItem(PTR_INT(pItem305C));
-
- // 150068E9
- temp->next = pItem1;
- pLast = pItem1;
-
- pItem1->parent = NULL;
- pItem1->child = NULL;
-
- // 150068F6
- pItem1->dcmpByte = pSaveLast->dcmpByte; // Copy item index
- pItem1->byteValue = pSaveLast->byteValue; // Copy item byte value
- pItem1->parent = pSaveLast; // Set parent to last item
- items306C[pSaveLast->dcmpByte] = pItem1; // Insert item into item pointer array
-
- // Prepare the second item to insert into the tree
- if(PTR_INT((pItem1 = pItem3058)) <= 0)
- pItem1 = &items0008[nItems++];
-
- // 1500692E
- if(pItem1->next != NULL)
- {
- temp = pItem1->GetPrevItem(-1); // EAX
-
- temp->next = pItem1->next;
- pItem1->next->prev = pItem1->prev;
- pItem1->next = NULL;
- pItem1->prev = NULL;
- }
- // 1500694C
- pItem1->next = PTR_PTR(&pFirst);
- pItem1->prev = pLast;
- temp = pItem1->next->GetPrevItem(PTR_INT(pItem305C));
-
- // 15006968
- temp->next = pItem1;
- pLast = pItem1;
-
- // 1500696E
- pItem1->child = NULL;
- pItem1->dcmpByte = dwIndex;
- pItem1->byteValue = 0;
- pItem1->parent = pSaveLast;
- pSaveLast->child = pItem1;
- items306C[dwIndex] = pItem1;
-
- do
- {
- THTreeItem * pItem2 = pItem1;
- THTreeItem * pItem3;
- unsigned long byteValue;
-
- // 15006993
- byteValue = ++pItem1->byteValue;
-
- // Pass through all previous which have its value greater than byteValue
- while(PTR_INT((pItem3 = pItem2->prev)) > 0) // EBX
- {
- if(pItem3->byteValue >= byteValue)
- goto _150069AE;
-
- pItem2 = pItem2->prev;
- }
- // 150069AC
- pItem3 = NULL;
-
- _150069AE:
- if(pItem2 == pItem1)
- continue;
-
- // 150069B2
- // Switch pItem2 with item
- InsertItem(&pItem305C, pItem2, SWITCH_ITEMS, pItem1);
- InsertItem(&pItem305C, pItem1, SWITCH_ITEMS, pItem3);
-
- // 150069D0
- // Switch parents of pItem1 and pItem2
- temp = pItem2->parent->child;
- if(pItem1 == pItem1->parent->child)
- pItem1->parent->child = pItem2;
-
- if(pItem2 == temp)
- pItem2->parent->child = pItem1;
-
- // 150069ED
- // Switch parents of pItem1 and pItem3
- temp = pItem1->parent;
- pItem1 ->parent = pItem2->parent;
- pItem2->parent = temp;
- offs0004++;
- }
- while(PTR_INT((pItem1 = pItem1->parent)) > 0);
-}
-
-void THuffmannTree::UninitTree()
-{
- while(PTR_INT(pLast) > 0)
- {
- pItem = pItem305C->Call1501DB70(pLast);
- pItem->RemoveItem();
- }
-
- for(pItem = pFirst; PTR_INT(pItem3058) > 0; pItem = pItem3058)
- pItem->RemoveItem();
- PTR_PTR(&pItem3054)->RemoveItem();
-
- for(pItem = items0008 + 0x203, nCount = 0x203; nCount != 0; nCount--)
- {
- pItem--;
- pItem->RemoveItem();
- pItem->RemoveItem();
- }
-}
-*/
-
-THTreeItem * THuffmannTree::Call1500E740(unsigned int nValue)
-{
- THTreeItem * pItem1 = pItem3058; // EDX
- THTreeItem * pItem2; // EAX
- THTreeItem * pNext;
- THTreeItem * pPrev;
- THTreeItem ** ppItem;
-
- if(PTR_INVALID_OR_NULL(pItem1) || (pItem2 = pItem1) == NULL)
- {
- if((pItem2 = &items0008[nItems++]) != NULL)
- pItem1 = pItem2;
- else
- pItem1 = pFirst;
- }
- else
- pItem1 = pItem2;
-
- pNext = pItem1->next;
- if(pNext != NULL)
- {
- pPrev = pItem1->prev;
- if(PTR_INVALID_OR_NULL(pPrev))
- pPrev = PTR_NOT(pPrev);
- else
- pPrev += (pItem1 - pItem1->next->prev);
-
- pPrev->next = pNext;
- pNext->prev = pPrev;
- pItem1->next = NULL;
- pItem1->prev = NULL;
- }
-
- ppItem = &pFirst; // esi
- if(nValue > 1)
- {
- // ecx = pFirst->next;
- pItem1->next = *ppItem;
- pItem1->prev = (*ppItem)->prev;
-
- (*ppItem)->prev = pItem2;
- *ppItem = pItem1;
-
- pItem2->parent = NULL;
- pItem2->child = NULL;
- }
- else
- {
- pItem1->next = (THTreeItem *)ppItem;
- pItem1->prev = ppItem[1];
- // edi = pItem305C;
- pPrev = ppItem[1]; // ecx
- if(PTR_INVALID_OR_NULL(pPrev))
- {
- pPrev = PTR_NOT(pPrev);
- pPrev->next = pItem1;
- pPrev->prev = pItem2;
-
- pItem2->parent = NULL;
- pItem2->child = NULL;
- }
- else
- {
- if(PTR_INVALID(pItem305C))
- pPrev += (THTreeItem *)ppItem - (*ppItem)->prev;
- else
- pPrev += PTR_INT(pItem305C);
-
- pPrev->next = pItem1;
- ppItem[1] = pItem2;
- pItem2->parent = NULL;
- pItem2->child = NULL;
- }
- }
- return pItem2;
-}
-
-void THuffmannTree::Call1500E820(THTreeItem * pItem)
-{
- THTreeItem * pItem1; // edi
- THTreeItem * pItem2 = NULL; // eax
- THTreeItem * pItem3; // edx
- THTreeItem * pPrev; // ebx
-
- for(; pItem != NULL; pItem = pItem->parent)
- {
- pItem->byteValue++;
-
- for(pItem1 = pItem; ; pItem1 = pPrev)
- {
- pPrev = pItem1->prev;
- if(PTR_INVALID_OR_NULL(pPrev))
- {
- pPrev = NULL;
- break;
- }
-
- if(pPrev->byteValue >= pItem->byteValue)
- break;
- }
-
- if(pItem1 == pItem)
- continue;
-
- if(pItem1->next != NULL)
- {
- pItem2 = pItem1->GetPrevItem(-1);
- pItem2->next = pItem1->next;
- pItem1->next->prev = pItem1->prev;
- pItem1->next = NULL;
- pItem1->prev = NULL;
- }
-
- pItem2 = pItem->next;
- pItem1->next = pItem2;
- pItem1->prev = pItem2->prev;
- pItem2->prev = pItem1;
- pItem->next = pItem1;
- if((pItem2 = pItem1) != NULL)
- {
- pItem2 = pItem->GetPrevItem(-1);
- pItem2->next = pItem->next;
- pItem->next->prev = pItem->prev;
- pItem->next = NULL;
- pItem->prev = NULL;
- }
-
- if(pPrev == NULL)
- pPrev = PTR_PTR(&pFirst);
-
- pItem2 = pPrev->next;
- pItem->next = pItem2;
- pItem->prev = pItem2->prev;
- pItem2->prev = pItem;
- pPrev->next = pItem;
-
- pItem3 = pItem1->parent->child;
- pItem2 = pItem->parent;
- if(pItem2->child == pItem)
- pItem2->child = pItem1;
- if(pItem3 == pItem1)
- pItem1->parent->child = pItem;
-
- pItem2 = pItem->parent;
- pItem->parent = pItem1->parent;
- pItem1->parent = pItem2;
- offs0004++;
- }
-}
-
-// 1500E920
-unsigned int THuffmannTree::DoCompression(TOutputStream * os, unsigned char * pbInBuffer, int nInLength, int nCmpType)
-{
- THTreeItem * pItem1;
- THTreeItem * pItem2;
- THTreeItem * pItem3;
- THTreeItem * pTemp;
- unsigned long dwBitBuff;
- unsigned int nBits;
- unsigned int nBit;
-
- BuildTree(nCmpType);
- bIsCmp0 = (nCmpType == 0);
-
- // Store the compression type into output buffer
- os->dwBitBuff |= (nCmpType << os->nBits);
- os->nBits += 8;
-
- // Flush completed bytes
- while(os->nBits >= 8)
- {
- if(os->cbOutSize != 0)
- {
- *os->pbOutPos++ = (unsigned char)os->dwBitBuff;
- os->cbOutSize--;
- }
-
- os->dwBitBuff >>= 8;
- os->nBits -= 8;
- }
-
- for(; nInLength != 0; nInLength--)
- {
- unsigned char bOneByte = *pbInBuffer++;
-
- if((pItem1 = items306C[bOneByte]) == NULL)
- {
- pItem2 = items306C[0x101]; // ecx
- pItem3 = pItem2->parent; // eax
- dwBitBuff = 0;
- nBits = 0;
-
- for(; pItem3 != NULL; pItem3 = pItem3->parent)
- {
- nBit = (pItem3->child != pItem2) ? 1 : 0;
- dwBitBuff = (dwBitBuff << 1) | nBit;
- nBits++;
- pItem2 = pItem3;
- }
- os->PutBits(dwBitBuff, nBits);
-
- // Store the loaded byte into output stream
- os->dwBitBuff |= (bOneByte << os->nBits);
- os->nBits += 8;
-
- // Flush the whole byte(s)
- while(os->nBits >= 8)
- {
- if(os->cbOutSize != 0)
- {
- *os->pbOutPos++ = (unsigned char)os->dwBitBuff;
- os->cbOutSize--;
- }
- os->dwBitBuff >>= 8;
- os->nBits -= 8;
- }
-
- pItem1 = (PTR_INVALID_OR_NULL(pLast)) ? NULL : pLast;
- pItem2 = Call1500E740(1);
- pItem2->dcmpByte = pItem1->dcmpByte;
- pItem2->byteValue = pItem1->byteValue;
- pItem2->parent = pItem1;
- items306C[pItem2->dcmpByte] = pItem2;
-
- pItem2 = Call1500E740(1);
- pItem2->dcmpByte = bOneByte;
- pItem2->byteValue = 0;
- pItem2->parent = pItem1;
- items306C[pItem2->dcmpByte] = pItem2;
- pItem1->child = pItem2;
-
- Call1500E820(pItem2);
-
- if(bIsCmp0 != 0)
- {
- Call1500E820(items306C[bOneByte]);
- continue;
- }
-
- for(pItem1 = items306C[bOneByte]; pItem1 != NULL; pItem1 = pItem1->parent)
- {
- pItem1->byteValue++;
- pItem2 = pItem1;
-
- for(;;)
- {
- pItem3 = pItem2->prev;
- if(PTR_INVALID_OR_NULL(pItem3))
- {
- pItem3 = NULL;
- break;
- }
- if(pItem3->byteValue >= pItem1->byteValue)
- break;
- pItem2 = pItem3;
- }
-
- if(pItem2 != pItem1)
- {
- InsertItem(&pItem305C, pItem2, SWITCH_ITEMS, pItem1);
- InsertItem(&pItem305C, pItem1, SWITCH_ITEMS, pItem3);
-
- pItem3 = pItem2->parent->child;
- if(pItem1->parent->child == pItem1)
- pItem1->parent->child = pItem2;
-
- if(pItem3 == pItem2)
- pItem2->parent->child = pItem1;
-
- pTemp = pItem1->parent;
- pItem1->parent = pItem2->parent;
- pItem2->parent = pTemp;
- offs0004++;
- }
- }
- }
-// 1500EB62
- else
- {
- dwBitBuff = 0;
- nBits = 0;
- for(pItem2 = pItem1->parent; pItem2 != NULL; pItem2 = pItem2->parent)
- {
- nBit = (pItem2->child != pItem1) ? 1 : 0;
- dwBitBuff = (dwBitBuff << 1) | nBit;
- nBits++;
- pItem1 = pItem2;
- }
- os->PutBits(dwBitBuff, nBits);
- }
-
-// 1500EB98
- if(bIsCmp0 != 0)
- Call1500E820(items306C[bOneByte]); // 1500EB9D
-// 1500EBAF
- } // for(; nInLength != 0; nInLength--)
-
-// 1500EBB8
- pItem1 = items306C[0x100];
- dwBitBuff = 0;
- nBits = 0;
- for(pItem2 = pItem1->parent; pItem2 != NULL; pItem2 = pItem2->parent)
- {
- nBit = (pItem2->child != pItem1) ? 1 : 0;
- dwBitBuff = (dwBitBuff << 1) | nBit;
- nBits++;
- pItem1 = pItem2;
- }
-
-// 1500EBE6
- os->PutBits(dwBitBuff, nBits);
-
-// 1500EBEF
- // Flush the remaining bits
- while(os->nBits != 0)
- {
- if(os->cbOutSize != 0)
- {
- *os->pbOutPos++ = (unsigned char)os->dwBitBuff;
- os->cbOutSize--;
- }
- os->dwBitBuff >>= 8;
- os->nBits -= ((os->nBits > 8) ? 8 : os->nBits);
- }
-
- return (unsigned int)(os->pbOutPos - os->pbOutBuffer);
-}
-
-// Decompression using Huffman tree (1500E450)
-unsigned int THuffmannTree::DoDecompression(unsigned char * pbOutBuffer, unsigned int dwOutLength, TInputStream * is)
-{
- TQDecompress * qd;
- THTreeItem * pItem1;
- THTreeItem * pItem2;
- unsigned char * pbOutPos = pbOutBuffer;
- unsigned long nBitCount;
- unsigned int nDcmpByte = 0;
- unsigned int n8Bits; // 8 bits loaded from input stream
- unsigned int n7Bits; // 7 bits loaded from input stream
- bool bHasQdEntry;
-
- // Test the output length. Must not be NULL.
- if(dwOutLength == 0)
- return 0;
-
- // Get the compression type from the input stream
- n8Bits = is->Get8Bits();
-
- // Build the Huffman tree
- BuildTree(n8Bits);
- bIsCmp0 = (n8Bits == 0) ? 1 : 0;
-
- for(;;)
- {
- // Security check: If we are at the end of the input buffer,
- // it means that the data is corrupt
- if(is->BitCount == 0 && is->pbInBuffer >= is->pbInBufferEnd)
- return 0;
-
- // Get 7 bits from input stream
- n7Bits = is->Get7Bits();
-
- // Try to use quick decompression. Check TQDecompress array for corresponding item.
- // If found, ise the result byte instead.
- qd = &qd3474[n7Bits];
-
- // If there is a quick-pass possible (ebx)
- bHasQdEntry = (qd->offs00 >= offs0004) ? true : false;
-
- // If we can use quick decompress, use it.
- if(bHasQdEntry)
- {
- if(qd->nBits > 7)
- {
- is->SkipBits(7);
- pItem1 = qd->pItem;
- goto _1500E549;
- }
- is->SkipBits(qd->nBits);
- nDcmpByte = qd->dcmpByte;
- }
- else
- {
- pItem1 = pFirst->next->prev;
- if(PTR_INVALID_OR_NULL(pItem1))
- pItem1 = NULL;
-_1500E549:
- nBitCount = 0;
- pItem2 = NULL;
-
- do
- {
- if(pItem1 == NULL)
- return 0;
-
- pItem1 = pItem1->child; // Move down by one level
- if(is->GetBit()) // If current bit is set, move to previous
- pItem1 = pItem1->prev;
-
- if(++nBitCount == 7) // If we are at 7th bit, save current HTree item.
- pItem2 = pItem1;
- }
- while(pItem1->child != NULL); // Walk until tree has no deeper level
-
- if(bHasQdEntry == false)
- {
- if(nBitCount > 7)
- {
- qd->offs00 = offs0004;
- qd->nBits = nBitCount;
- qd->pItem = pItem2;
- }
- else
- {
- unsigned long nIndex = n7Bits & (0xFFFFFFFF >> (32 - nBitCount));
- unsigned long nAdd = (1 << nBitCount);
-
- for(qd = &qd3474[nIndex]; nIndex <= 0x7F; nIndex += nAdd, qd += nAdd)
- {
- qd->offs00 = offs0004;
- qd->nBits = nBitCount;
- qd->dcmpByte = pItem1->dcmpByte;
- }
- }
- }
- nDcmpByte = pItem1->dcmpByte;
- }
-
- if(nDcmpByte == 0x101) // Huffman tree needs to be modified
- {
- n8Bits = is->Get8Bits();
- pItem1 = (PTR_INVALID_OR_NULL(pLast)) ? NULL : pLast;
-
- pItem2 = Call1500E740(1);
- pItem2->parent = pItem1;
- pItem2->dcmpByte = pItem1->dcmpByte;
- pItem2->byteValue = pItem1->byteValue;
- items306C[pItem2->dcmpByte] = pItem2;
-
- pItem2 = Call1500E740(1);
- pItem2->parent = pItem1;
- pItem2->dcmpByte = n8Bits;
- pItem2->byteValue = 0;
- items306C[pItem2->dcmpByte] = pItem2;
-
- pItem1->child = pItem2;
- Call1500E820(pItem2);
- if(bIsCmp0 == 0)
- Call1500E820(items306C[n8Bits]);
-
- nDcmpByte = n8Bits;
- }
-
- if(nDcmpByte == 0x100)
- break;
-
- *pbOutPos++ = (unsigned char)nDcmpByte;
- if(--dwOutLength == 0)
- break;
-
- if(bIsCmp0)
- Call1500E820(items306C[nDcmpByte]);
- }
-
- return (unsigned int)(pbOutPos - pbOutBuffer);
-}
-
-
-// Table for (de)compression. Every compression type has 258 entries
-unsigned char THuffmannTree::Table1502A630[] =
-{
- // Data for compression type 0x00
- 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00,
-
- // Data for compression type 0x01
- 0x54, 0x16, 0x16, 0x0D, 0x0C, 0x08, 0x06, 0x05, 0x06, 0x05, 0x06, 0x03, 0x04, 0x04, 0x03, 0x05,
- 0x0E, 0x0B, 0x14, 0x13, 0x13, 0x09, 0x0B, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02,
- 0x0D, 0x07, 0x09, 0x06, 0x06, 0x04, 0x03, 0x02, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02,
- 0x09, 0x06, 0x04, 0x04, 0x04, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x04,
- 0x08, 0x03, 0x04, 0x07, 0x09, 0x05, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02,
- 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02,
- 0x06, 0x0A, 0x08, 0x08, 0x06, 0x07, 0x04, 0x03, 0x04, 0x04, 0x02, 0x02, 0x04, 0x02, 0x03, 0x03,
- 0x04, 0x03, 0x07, 0x07, 0x09, 0x06, 0x04, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x0A, 0x02, 0x02, 0x03, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x03, 0x05, 0x02, 0x03,
- 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01, 0x01,
- 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x09, 0x08, 0x0C, 0x02,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03,
- 0x04, 0x01, 0x02, 0x04, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
- 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x4B,
- 0x00, 0x00,
-
- // Data for compression type 0x02
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x27, 0x00, 0x00, 0x23, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x06, 0x0E, 0x10, 0x04,
- 0x06, 0x08, 0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01,
- 0x01, 0x04, 0x02, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0x02, 0x03, 0x03, 0x02,
- 0x03, 0x01, 0x03, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01,
- 0x01, 0x29, 0x07, 0x16, 0x12, 0x40, 0x0A, 0x0A, 0x11, 0x25, 0x01, 0x03, 0x17, 0x10, 0x26, 0x2A,
- 0x10, 0x01, 0x23, 0x23, 0x2F, 0x10, 0x06, 0x07, 0x02, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
- // Data for compression type 0x03
- 0xFF, 0x0B, 0x07, 0x05, 0x0B, 0x02, 0x02, 0x02, 0x06, 0x02, 0x02, 0x01, 0x04, 0x02, 0x01, 0x03,
- 0x09, 0x01, 0x01, 0x01, 0x03, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
- 0x05, 0x01, 0x01, 0x01, 0x0D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
- 0x0A, 0x04, 0x02, 0x01, 0x06, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01,
- 0x05, 0x02, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x03, 0x03,
- 0x01, 0x03, 0x01, 0x01, 0x02, 0x05, 0x01, 0x01, 0x04, 0x03, 0x05, 0x01, 0x03, 0x01, 0x03, 0x03,
- 0x02, 0x01, 0x04, 0x03, 0x0A, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x02, 0x01, 0x0A, 0x02, 0x05, 0x01, 0x01, 0x02, 0x07, 0x02, 0x17, 0x01, 0x05, 0x01, 0x01,
- 0x0E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x06, 0x02, 0x01, 0x04, 0x05, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11,
- 0x00, 0x00,
-
- // Data for compression type 0x04
- 0xFF, 0xFB, 0x98, 0x9A, 0x84, 0x85, 0x63, 0x64, 0x3E, 0x3E, 0x22, 0x22, 0x13, 0x13, 0x18, 0x17,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
- // Data for compression type 0x05
- 0xFF, 0xF1, 0x9D, 0x9E, 0x9A, 0x9B, 0x9A, 0x97, 0x93, 0x93, 0x8C, 0x8E, 0x86, 0x88, 0x80, 0x82,
- 0x7C, 0x7C, 0x72, 0x73, 0x69, 0x6B, 0x5F, 0x60, 0x55, 0x56, 0x4A, 0x4B, 0x40, 0x41, 0x37, 0x37,
- 0x2F, 0x2F, 0x27, 0x27, 0x21, 0x21, 0x1B, 0x1C, 0x17, 0x17, 0x13, 0x13, 0x10, 0x10, 0x0D, 0x0D,
- 0x0B, 0x0B, 0x09, 0x09, 0x08, 0x08, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x04, 0x04, 0x19, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
- // Data for compression type 0x06
- 0xC3, 0xCB, 0xF5, 0x41, 0xFF, 0x7B, 0xF7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xBF, 0xCC, 0xF2, 0x40, 0xFD, 0x7C, 0xF7, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x7A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
- // Data for compression type 0x07
- 0xC3, 0xD9, 0xEF, 0x3D, 0xF9, 0x7C, 0xE9, 0x1E, 0xFD, 0xAB, 0xF1, 0x2C, 0xFC, 0x5B, 0xFE, 0x17,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xBD, 0xD9, 0xEC, 0x3D, 0xF5, 0x7D, 0xE8, 0x1D, 0xFB, 0xAE, 0xF0, 0x2C, 0xFB, 0x5C, 0xFF, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x70, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
- // Data for compression type 0x08
- 0xBA, 0xC5, 0xDA, 0x33, 0xE3, 0x6D, 0xD8, 0x18, 0xE5, 0x94, 0xDA, 0x23, 0xDF, 0x4A, 0xD1, 0x10,
- 0xEE, 0xAF, 0xE4, 0x2C, 0xEA, 0x5A, 0xDE, 0x15, 0xF4, 0x87, 0xE9, 0x21, 0xF6, 0x43, 0xFC, 0x12,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xB0, 0xC7, 0xD8, 0x33, 0xE3, 0x6B, 0xD6, 0x18, 0xE7, 0x95, 0xD8, 0x23, 0xDB, 0x49, 0xD0, 0x11,
- 0xE9, 0xB2, 0xE2, 0x2B, 0xE8, 0x5C, 0xDD, 0x15, 0xF1, 0x87, 0xE7, 0x20, 0xF7, 0x44, 0xFF, 0x13,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x5F, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00
-};
diff --git a/dep/StormLib/src/huffman/huff.h b/dep/StormLib/src/huffman/huff.h
deleted file mode 100644
index 83e9b2cdad0..00000000000
--- a/dep/StormLib/src/huffman/huff.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*****************************************************************************/
-/* huffman.h Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Description : */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* xx.xx.xx 1.00 Lad The first version of huffman.h */
-/* 03.05.03 2.00 Lad Added compression */
-/* 08.12.03 2.01 Dan High-memory handling (> 0x80000000) */
-/*****************************************************************************/
-
-#ifndef __HUFFMAN_H__
-#define __HUFFMAN_H__
-
-#include "../StormPort.h"
-
-//-----------------------------------------------------------------------------
-// Defines
-
-#define INSERT_ITEM 1
-#define SWITCH_ITEMS 2 // Switch the item1 and item2
-
-#define PTR_NOT(ptr) (THTreeItem *)(~(DWORD_PTR)(ptr))
-#define PTR_PTR(ptr) ((THTreeItem *)(ptr))
-#define PTR_INT(ptr) (INT_PTR)(ptr)
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-//-----------------------------------------------------------------------------
-// Structures and classes
-
-// Input stream for Huffmann decompression
-class TInputStream
-{
- public:
-
- unsigned long GetBit();
- unsigned long Get7Bits();
- unsigned long Get8Bits();
- void SkipBits(unsigned int BitCount);
-
- unsigned char * pbInBuffer; // Input data
- unsigned char * pbInBufferEnd; // End of the input buffer
- unsigned long BitBuffer; // Input bit buffer
- unsigned int BitCount; // Number of bits remaining in 'dwBitBuff'
-};
-
-// Output stream for Huffmann compression
-class TOutputStream
-{
- public:
-
- void PutBits(unsigned long dwBuff, unsigned int nPutBits);
-
- unsigned char * pbOutBuffer; // 00 : Output buffer
- unsigned long cbOutSize; // 04 : Size of output buffer
- unsigned char * pbOutPos; // 08 : Current output position
- unsigned long dwBitBuff; // 0C : Bit buffer
- unsigned long nBits; // 10 : Number of bits in the bit buffer
-};
-
-// Huffmann tree item (?)
-struct THTreeItem
-{
- THTreeItem * Call1501DB70(THTreeItem * pLast);
- THTreeItem * GetPrevItem(LONG_PTR value);
- void ClearItemLinks();
- void RemoveItem();
-
- THTreeItem * next; // 00 - Pointer to next THTreeItem
- THTreeItem * prev; // 04 - Pointer to prev THTreeItem (< 0 if none)
- unsigned long dcmpByte; // 08 - Index of this item in item pointer array, decompressed byte value
- unsigned long byteValue; // 0C - Some byte value
- THTreeItem * parent; // 10 - Pointer to parent THTreeItem (NULL if none)
- THTreeItem * child; // 14 - Pointer to child THTreeItem
- int addressMultiplier; // -1 if object on negative address (>0x80000000), +1 if positive
-};
-
-// Structure used for quick decompress. The 'bitCount' contains number of bits
-// and byte value contains result decompressed byte value.
-// After each walk through Huffman tree are filled all entries which are
-// multiplies of number of bits loaded from input stream. These entries
-// contain number of bits and result value. At the next 7 bits is tested this
-// structure first. If corresponding entry found, decompression routine will
-// not walk through Huffman tree and directly stores output byte to output stream.
-struct TQDecompress
-{
- unsigned long offs00; // 00 - 1 if resolved
- unsigned long nBits; // 04 - Bit count
- union
- {
- unsigned long dcmpByte; // 08 - Byte value for decompress (if bitCount <= 7)
- THTreeItem * pItem; // 08 - THTreeItem (if number of bits is greater than 7
- };
-};
-
-// Structure for Huffman tree (Size 0x3674 bytes). Because I'm not expert
-// for the decompression, I do not know actually if the class is really a Hufmann
-// tree. If someone knows the decompression details, please let me know
-class THuffmannTree
-{
- public:
-
- THuffmannTree();
- void InitTree(bool bCompression);
- void BuildTree(unsigned int nCmpType);
-// void ModifyTree(unsigned long dwIndex);
-// void UninitTree();
-
-// void Call15007010(Bit32 dwInLength, THTreeItem * item);
- THTreeItem * Call1500E740(unsigned int nValue);
- void Call1500E820(THTreeItem * pItem);
- unsigned int DoCompression(TOutputStream * os, unsigned char * pbInBuffer, int nInLength, int nCmpType);
- unsigned int DoDecompression(unsigned char * pbOutBuffer, unsigned int dwOutLength, TInputStream * is);
-
- unsigned long bIsCmp0; // 0000 - 1 if compression type 0
- unsigned long offs0004; // 0004 - Some flag
- THTreeItem items0008[0x203]; // 0008 - HTree items
-
- //- Sometimes used as HTree item -----------
- THTreeItem * pItem3050; // 3050 - Always NULL (?)
- THTreeItem * pItem3054; // 3054 - Pointer to Huffman tree item
- THTreeItem * pItem3058; // 3058 - Pointer to Huffman tree item (< 0 if invalid)
-
- //- Sometimes used as HTree item -----------
- THTreeItem * pItem305C; // 305C - Usually NULL
- THTreeItem * pFirst; // 3060 - Pointer to top (first) Huffman tree item
- THTreeItem * pLast; // 3064 - Pointer to bottom (last) Huffman tree item (< 0 if invalid)
- unsigned long nItems; // 3068 - Number of used HTree items
-
- //-------------------------------------------
- THTreeItem * items306C[0x102]; // 306C - THTreeItem pointer array
- TQDecompress qd3474[0x80]; // 3474 - Array for quick decompression
- int addressMultiplier; // -1 if object on negative address (>0x80000000), +1 if positive
-
- static unsigned char Table1502A630[];// Some table
-};
-
-#endif // __HUFFMAN_H__
diff --git a/dep/StormLib/src/huffman/huff_patch.cpp b/dep/StormLib/src/huffman/huff_patch.cpp
deleted file mode 100644
index 6176a9b1f77..00000000000
--- a/dep/StormLib/src/huffman/huff_patch.cpp
+++ /dev/null
@@ -1,1120 +0,0 @@
-/*****************************************************************************/
-/* huffman.cpp Copyright (c) Ladislav Zezula 1998-2003 */
-/*---------------------------------------------------------------------------*/
-/* This module contains Huffmann (de)compression methods */
-/* */
-/* Authors : Ladislav Zezula (ladik@zezula.net) */
-/* ShadowFlare (BlakFlare@hotmail.com) */
-/* */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* xx.xx.xx 1.00 Lad The first version of dcmp.cpp */
-/* 03.05.03 1.00 Lad Added compression methods */
-/* 19.11.03 1.01 Dan Big endian handling */
-/* 08.12.03 2.01 Dan High-memory handling (> 0x80000000) */
-/*****************************************************************************/
-
-#include <assert.h>
-#include <string.h>
-
-#include "huff.h"
-
-THTreeItem * gcpFirst, * gpFirst, * gcpItem3054, * gpItem3054;
-
-#define PTR_VALID(ptr) ((ptr) != gcpFirst && (ptr) != gcpItem3054)
-#define PTR_INVALID(ptr) (!PTR_VALID(ptr))
-#define PTR_INVALID_OR_NULL(ptr) (0 == (ptr) || PTR_INVALID(ptr))
-
-//-----------------------------------------------------------------------------
-// Methods of the THTreeItem struct
-
-// 1501DB70
-THTreeItem * THTreeItem::Call1501DB70(THTreeItem * pLast)
-{
- if(pLast == NULL)
- pLast = this + 1;
- return pLast;
-}
-
-// Gets previous Huffman tree item (?)
-THTreeItem * THTreeItem::GetPrevItem(SIntPtr value)
-{
- if(PTR_INVALID(prev))
- return PTR_NOT(prev);
-
- if(value == -1 || PTR_INVALID((THTreeItem *) value))
- value = (SIntPtr)(this - next->prev);
- return prev + value;
-}
-
-// 1500F5E0
-void THTreeItem::ClearItemLinks()
-{
- next = prev = NULL;
-}
-
-// 1500BC90
-void THTreeItem::RemoveItem()
-{
- THTreeItem * pTemp; // EDX
-
- if(next != NULL)
- {
- pTemp = prev;
-
- if(PTR_INVALID(pTemp))
- pTemp = PTR_NOT(pTemp);
- else
- pTemp += (this - next->prev);
-
- pTemp->next = next;
- next->prev = prev;
- next = prev = NULL;
- }
-}
-
-//-----------------------------------------------------------------------------
-// TOutputStream functions
-
-void TOutputStream::PutBits(unsigned long dwBuff, unsigned int nPutBits)
-{
- dwBitBuff |= (dwBuff << nBits);
- nBits += nPutBits;
-
- // Flush completed bytes
- while(nBits >= 8)
- {
- if(cbOutSize != 0)
- {
- *pbOutPos++ = (unsigned char)dwBitBuff;
- cbOutSize--;
- }
-
- dwBitBuff >>= 8;
- nBits -= 8;
- }
-}
-
-//-----------------------------------------------------------------------------
-// TInputStream functions
-
-// Gets one bit from input stream
-unsigned long TInputStream::GetBit()
-{
- unsigned long dwOneBit = 0;
-
- // Ensure that the input stream is reloaded, if there are no bits left
- if(BitCount == 0)
- {
- // Refill the bit buffer
- BitBuffer = *pbInBuffer++;
- BitCount = 8;
- }
-
- // Copy the bit from bit buffer to the variable
- dwOneBit = (BitBuffer & 0x01);
- BitBuffer >>= 1;
- BitCount--;
-
- return dwOneBit;
-}
-
-// Gets 7 bits from the stream. DOES NOT remove the bits from input stream
-unsigned long TInputStream::Get7Bits()
-{
- unsigned long dwReloadByte = 0;
-
- // If there is not enough bits to get the value,
- // we have to add 8 more bits from the input buffer
- if(BitCount < 7)
- {
- dwReloadByte = *pbInBuffer++;
- BitBuffer |= dwReloadByte << BitCount;
- BitCount += 8;
- }
-
- // Return the first available 7 bits. DO NOT remove them from the input stream
- return (BitBuffer & 0x7F);
-}
-
-// Gets the whole byte from the input stream.
-unsigned long TInputStream::Get8Bits()
-{
- unsigned long dwReloadByte = 0;
- unsigned long dwOneByte = 0;
-
- // If there is not enough bits to get the value,
- // we have to add 8 more bits from the input buffer
- if(BitCount < 8)
- {
- dwReloadByte = *pbInBuffer++;
- BitBuffer |= dwReloadByte << BitCount;
- BitCount += 8;
- }
-
- // Return the lowest 8 its
- dwOneByte = (BitBuffer & 0xFF);
- BitBuffer >>= 8;
- BitCount -= 8;
- return dwOneByte;
-}
-
-void TInputStream::SkipBits(unsigned int dwBitsToSkip)
-{
- unsigned long dwReloadByte = 0;
-
- // If there is not enough bits in the buffer,
- // we have to add 8 more bits from the input buffer
- if(BitCount < dwBitsToSkip)
- {
- dwReloadByte = *pbInBuffer++;
- BitBuffer |= dwReloadByte << BitCount;
- BitCount += 8;
- }
-
- // Skip the remaining bits
- BitBuffer >>= dwBitsToSkip;
- BitCount -= dwBitsToSkip;
-}
-
-//-----------------------------------------------------------------------------
-// Functions for huffmann tree items
-
-// Inserts item into the tree (?)
-static void InsertItem(THTreeItem ** itemPtr, THTreeItem * item, unsigned long where, THTreeItem * item2)
-{
- THTreeItem * next = item->next; // EDI - next to the first item
- THTreeItem * prev = item->prev; // ESI - prev to the first item
- THTreeItem * prev2; // Pointer to previous item
- THTreeItem * next2; // Pointer to the next item
-
- // The same code like in RemoveItem(item);
- if(next != 0) // If the first item already has next one
- {
- if(PTR_INVALID(prev))
- prev = PTR_NOT(prev);
- else
- prev += (item - next->prev);
-
- // 150083C1
- // Remove the item from the tree
- prev->next = next;
- next->prev = prev;
-
- // Invalidate 'prev' and 'next' pointer
- item->next = 0;
- item->prev = 0;
- }
-
- if(item2 == NULL) // EDX - If the second item is not entered,
- item2 = PTR_PTR(&itemPtr[1]); // take the first tree item
-
- switch(where)
- {
- case SWITCH_ITEMS : // Switch the two items
- item->next = item2->next; // item2->next (Pointer to pointer to first)
- item->prev = item2->next->prev;
- item2->next->prev = item;
- item2->next = item; // Set the first item
- return;
-
- case INSERT_ITEM: // Insert as the last item
- item->next = item2; // Set next item (or pointer to pointer to first item)
- item->prev = item2->prev; // Set prev item (or last item in the tree)
-
- next2 = itemPtr[0];// Usually NULL
- prev2 = item2->prev; // Prev item to the second (or last tree item)
-
- if(PTR_INVALID(prev2))
- {
- prev2 = PTR_NOT(prev);
-
- prev2->next = item;
- item2->prev = item; // Next after last item
- return;
- }
-
- if(PTR_INVALID(next2))
- next2 = (THTreeItem *)(item2 - item2->next->prev);
-
- prev2 += (long) next2;
- prev2->next = item;
- item2->prev = item; // Set the next/last item
- return;
-
- default:
- return;
- }
-}
-
-//-----------------------------------------------------------------------------
-// THuffmannTree class functions
-
-THuffmannTree::THuffmannTree()
-{
-}
-
-void THuffmannTree::InitTree(bool bCompression)
-{
- THTreeItem * pItem;
- unsigned int nCount;
-
- // Clear links for all the items in the tree
- for(pItem = items0008, nCount = 0x203; nCount != 0; pItem++, nCount--)
- pItem->ClearItemLinks();
-
- gcpItem3054 = (THTreeItem *) &gcpItem3054;
- pItem3050 = NULL;
- pItem3054 = PTR_PTR(&pItem3054);
- pItem3058 = gcpItem3054;
- gpItem3054 = pItem3054;
-
- gcpFirst = (THTreeItem *) &gcpFirst;
- pItem305C = NULL;
- pFirst = PTR_PTR(&pFirst);
- pLast = gcpFirst;
- gpFirst = pFirst;
-
- offs0004 = 1;
- nItems = 0;
-
- // Clear all TQDecompress items. Do this only if preparing for decompression
- if(bCompression == false)
- {
- for(nCount = 0; nCount < sizeof(qd3474) / sizeof(TQDecompress); nCount++)
- qd3474[nCount].offs00 = 0;
- }
-}
-
-// Builds Huffman tree. Called with the first 8 bits loaded from input stream
-void THuffmannTree::BuildTree(unsigned int nCmpType)
-{
- unsigned long maxByte; // [ESP+10] - The greatest character found in table
- THTreeItem ** itemPtr; // [ESP+14] - Pointer to Huffman tree item pointer array
- unsigned char * byteArray; // [ESP+1C] - Pointer to unsigned char in Table1502A630
- THTreeItem * child1;
- unsigned long i; // egcs in linux doesn't like multiple for loops without an explicit i
-
- // Loop while pointer has a valid value
- while(PTR_VALID(pLast)) // ESI - Last entry
- {
- THTreeItem * temp; // EAX
-
- if(pLast->next != NULL) // ESI->next
- pLast->RemoveItem();
- // EDI = &offs3054
- pItem3058 = PTR_PTR(&pItem3054); // [EDI+4]
- pLast->prev = pItem3058; // EAX
-
- temp = PTR_PTR(&pItem3054)->GetPrevItem((SIntPtr)(&pItem3050));
-
- temp->next = pLast;
- pItem3054 = pLast;
- }
-
- // Clear all pointers in HTree item array
- memset(items306C, 0, sizeof(items306C));
-
- maxByte = 0; // Greatest character found init to zero.
- itemPtr = (THTreeItem **)&items306C; // Pointer to current entry in HTree item pointer array
-
- // Ensure we have low 8 bits only
- nCmpType &= 0xFF;
- byteArray = Table1502A630 + nCmpType * 258; // EDI also
-
- for(i = 0; i < 0x100; i++, itemPtr++)
- {
- THTreeItem * item = pItem3058; // Item to be created
- THTreeItem * pItem3 = pItem3058;
- unsigned char oneByte = byteArray[i];
-
- // Skip all the bytes which are zero.
- if(byteArray[i] == 0)
- continue;
-
- // If not valid pointer, take the first available item in the array
- if(PTR_INVALID_OR_NULL(item))
- item = &items0008[nItems++];
-
- // Insert this item as the top of the tree
- InsertItem(&pItem305C, item, SWITCH_ITEMS, NULL);
-
- item->parent = NULL; // Invalidate child and parent
- item->child = NULL;
- *itemPtr = item; // Store pointer into pointer array
-
- item->dcmpByte = i; // Store counter
- item->byteValue = oneByte; // Store byte value
- if(oneByte >= maxByte)
- {
- maxByte = oneByte;
- continue;
- }
-
- // Find the first item which has byte value greater than current one byte
- if(PTR_VALID(pItem3 = pLast)) // EDI - Pointer to the last item
- {
- // 15006AF7
- if(pItem3 != NULL)
- {
- do // 15006AFB
- {
- if(pItem3->byteValue >= oneByte)
- goto _15006B09;
- pItem3 = pItem3->prev;
- }
- while(PTR_VALID(pItem3));
- }
- }
- pItem3 = NULL;
-
- // 15006B09
- _15006B09:
- if(item->next != NULL)
- item->RemoveItem();
-
- // 15006B15
- if(pItem3 == NULL)
- pItem3 = PTR_PTR(&pFirst);
-
- // 15006B1F
- item->next = pItem3->next;
- item->prev = pItem3->next->prev;
- pItem3->next->prev = item;
- pItem3->next = item;
- }
-
- // 15006B4A
- for(; i < 0x102; i++)
- {
- THTreeItem ** itemPtr = &items306C[i]; // EDI
-
- // 15006B59
- THTreeItem * item = pItem3058; // ESI
- if(PTR_INVALID_OR_NULL(item))
- item = &items0008[nItems++];
-
- InsertItem(&pItem305C, item, INSERT_ITEM, NULL);
-
- // 15006B89
- item->dcmpByte = i;
- item->byteValue = 1;
- item->parent = NULL;
- item->child = NULL;
- *itemPtr++ = item;
- }
-
- // 15006BAA
- if(PTR_VALID(child1 = pLast)) // EDI - last item (first child to item
- {
- THTreeItem * child2; // EBP
- THTreeItem * item; // ESI
-
- // 15006BB8
- while(PTR_VALID(child2 = child1->prev))
- {
- if(PTR_INVALID_OR_NULL(item = pItem3058))
- item = &items0008[nItems++];
-
- // 15006BE3
- InsertItem(&pItem305C, item, SWITCH_ITEMS, NULL);
-
- // 15006BF3
- item->parent = NULL;
- item->child = NULL;
-
- //EDX = child2->byteValue + child1->byteValue;
- //EAX = child1->byteValue;
- //ECX = maxByte; // The greatest character (0xFF usually)
-
- item->byteValue = child1->byteValue + child2->byteValue; // 0x02
- item->child = child1; // Prev item in the
- child1->parent = item;
- child2->parent = item;
-
- // EAX = item->byteValue;
- if(item->byteValue >= maxByte)
- maxByte = item->byteValue;
- else
- {
- THTreeItem * pItem2 = child2->prev; // EDI
-
- // 15006C2D
- while(PTR_VALID(pItem2))
- {
- if(pItem2->byteValue >= item->byteValue)
- goto _15006C3B;
- pItem2 = pItem2->prev;
- }
- pItem2 = NULL;
-
- _15006C3B:
- if(item->next != 0)
- {
- THTreeItem * temp4 = item->GetPrevItem(-1);
-
- temp4->next = item->next; // The first item changed
- item->next->prev = item->prev; // First->prev changed to negative value
- item->next = NULL;
- item->prev = NULL;
- }
-
- // 15006C62
- if(pItem2 == NULL)
- pItem2 = PTR_PTR(&pFirst);
-
- item->next = pItem2->next; // Set item with 0x100 byte value
- item->prev = pItem2->next->prev; // Set item with 0x17 byte value
- pItem2->next->prev = item; // Changed prev of item with
- pItem2->next = item;
- }
-
- // 15006C7B
- if(PTR_INVALID_OR_NULL(child1 = child2->prev))
- break;
- }
- }
- // 15006C88
- offs0004 = 1;
-}
-
-THTreeItem * THuffmannTree::Call1500E740(unsigned int nValue)
-{
- THTreeItem * pItem1 = pItem3058; // EDX
- THTreeItem * pItem2; // EAX
- THTreeItem * pNext;
- THTreeItem * pPrev;
- THTreeItem ** ppItem;
-
- if(PTR_INVALID_OR_NULL(pItem1) || (pItem2 = pItem1) == NULL)
- {
- if((pItem2 = &items0008[nItems++]) != NULL)
- pItem1 = pItem2;
- else
- pItem1 = pFirst;
- }
- else
- pItem1 = pItem2;
-
- pNext = pItem1->next;
- if(pNext != NULL)
- {
- pPrev = pItem1->prev;
- if(PTR_INVALID(pPrev))
- pPrev = PTR_NOT(pPrev);
- else
- pPrev += (pItem1 - pItem1->next->prev);
-
- pPrev->next = pNext;
- pNext->prev = pPrev;
- pItem1->next = NULL;
- pItem1->prev = NULL;
- }
-
- ppItem = &pFirst; // esi
- if(nValue > 1)
- {
- // ecx = pFirst->next;
- pItem1->next = *ppItem;
- pItem1->prev = (*ppItem)->prev;
-
- (*ppItem)->prev = pItem2;
- *ppItem = pItem1;
-
- pItem2->parent = NULL;
- pItem2->child = NULL;
- }
- else
- {
- pItem1->next = (THTreeItem *)ppItem;
- pItem1->prev = ppItem[1];
- // edi = pItem305C;
- pPrev = ppItem[1]; // ecx
- if(PTR_INVALID(pPrev))
- {
- pPrev = PTR_NOT(pPrev);
- pPrev->next = pItem1;
- pPrev->prev = pItem2;
-
- pItem2->parent = NULL;
- pItem2->child = NULL;
- }
- else
- {
- if(PTR_INVALID(pItem305C))
- pPrev += (THTreeItem *)ppItem - (*ppItem)->prev;
- else
- pPrev += (long)pItem305C;
-
- pPrev->next = pItem1;
- ppItem[1] = pItem2;
- pItem2->parent = NULL;
- pItem2->child = NULL;
- }
- }
- return pItem2;
-}
-
-void THuffmannTree::Call1500E820(THTreeItem * pItem)
-{
- THTreeItem * pItem1; // edi
- THTreeItem * pItem2 = NULL; // eax
- THTreeItem * pItem3; // edx
- THTreeItem * pPrev; // ebx
-
- for(; pItem != NULL; pItem = pItem->parent)
- {
- pItem->byteValue++;
-
- for(pItem1 = pItem; ; pItem1 = pPrev)
- {
- pPrev = pItem1->prev;
- if(PTR_INVALID_OR_NULL(pPrev))
- {
- pPrev = NULL;
- break;
- }
-
- if(pPrev->byteValue >= pItem->byteValue)
- break;
- }
-
- if(pItem1 == pItem)
- continue;
-
- if(pItem1->next != NULL)
- {
- pItem2 = pItem1->GetPrevItem(-1);
- pItem2->next = pItem1->next;
- pItem1->next->prev = pItem1->prev;
- pItem1->next = NULL;
- pItem1->prev = NULL;
- }
-
- pItem2 = pItem->next;
- pItem1->next = pItem2;
- pItem1->prev = pItem2->prev;
- pItem2->prev = pItem1;
- pItem->next = pItem1;
- if((pItem2 = pItem1) != NULL)
- {
- pItem2 = pItem->GetPrevItem(-1);
- pItem2->next = pItem->next;
- pItem->next->prev = pItem->prev;
- pItem->next = NULL;
- pItem->prev = NULL;
- }
-
- if(pPrev == NULL)
- pPrev = PTR_PTR(&pFirst);
-
- pItem2 = pPrev->next;
- pItem->next = pItem2;
- pItem->prev = pItem2->prev;
- pItem2->prev = pItem;
- pPrev->next = pItem;
-
- pItem3 = pItem1->parent->child;
- pItem2 = pItem->parent;
- if(pItem2->child == pItem)
- pItem2->child = pItem1;
- if(pItem3 == pItem1)
- pItem1->parent->child = pItem;
-
- pItem2 = pItem->parent;
- pItem->parent = pItem1->parent;
- pItem1->parent = pItem2;
- offs0004++;
- }
-}
-
-// 1500E920
-unsigned int THuffmannTree::DoCompression(TOutputStream * os, unsigned char * pbInBuffer, int nInLength, int nCmpType)
-{
- THTreeItem * pItem1;
- THTreeItem * pItem2;
- THTreeItem * pItem3;
- THTreeItem * pTemp;
- unsigned long dwBitBuff;
- unsigned int nBits;
- unsigned int nBit;
-
- BuildTree(nCmpType);
- bIsCmp0 = (nCmpType == 0);
-
- // Store the compression type into output buffer
- os->dwBitBuff |= (nCmpType << os->nBits);
- os->nBits += 8;
-
- // Flush completed bytes
- while(os->nBits >= 8)
- {
- if(os->cbOutSize != 0)
- {
- *os->pbOutPos++ = (unsigned char)os->dwBitBuff;
- os->cbOutSize--;
- }
-
- os->dwBitBuff >>= 8;
- os->nBits -= 8;
- }
-
- for(; nInLength != 0; nInLength--)
- {
- unsigned char bOneByte = *pbInBuffer++;
-
- if((pItem1 = items306C[bOneByte]) == NULL)
- {
- pItem2 = items306C[0x101]; // ecx
- pItem3 = pItem2->parent; // eax
- dwBitBuff = 0;
- nBits = 0;
-
- for(; pItem3 != NULL; pItem3 = pItem3->parent)
- {
- nBit = (pItem3->child != pItem2) ? 1 : 0;
- dwBitBuff = (dwBitBuff << 1) | nBit;
- nBits++;
- pItem2 = pItem3;
- }
- os->PutBits(dwBitBuff, nBits);
-
- // Store the loaded byte into output stream
- os->dwBitBuff |= (bOneByte << os->nBits);
- os->nBits += 8;
-
- // Flush the whole byte(s)
- while(os->nBits >= 8)
- {
- if(os->cbOutSize != 0)
- {
- *os->pbOutPos++ = (unsigned char)os->dwBitBuff;
- os->cbOutSize--;
- }
- os->dwBitBuff >>= 8;
- os->nBits -= 8;
- }
-
- pItem1 = (PTR_INVALID_OR_NULL(pLast)) ? NULL : pLast;
- pItem2 = Call1500E740(1);
- pItem2->dcmpByte = pItem1->dcmpByte;
- pItem2->byteValue = pItem1->byteValue;
- pItem2->parent = pItem1;
- items306C[pItem2->dcmpByte] = pItem2;
-
- pItem2 = Call1500E740(1);
- pItem2->dcmpByte = bOneByte;
- pItem2->byteValue = 0;
- pItem2->parent = pItem1;
- items306C[pItem2->dcmpByte] = pItem2;
- pItem1->child = pItem2;
-
- Call1500E820(pItem2);
-
- if(bIsCmp0 != 0)
- {
- Call1500E820(items306C[bOneByte]);
- continue;
- }
-
- for(pItem1 = items306C[bOneByte]; pItem1 != NULL; pItem1 = pItem1->parent)
- {
- pItem1->byteValue++;
- pItem2 = pItem1;
-
- for(;;)
- {
- pItem3 = pItem2->prev;
- if(PTR_INVALID_OR_NULL(pItem3))
- {
- pItem3 = NULL;
- break;
- }
- if(pItem3->byteValue >= pItem1->byteValue)
- break;
- pItem2 = pItem3;
- }
-
- if(pItem2 != pItem1)
- {
- InsertItem(&pItem305C, pItem2, SWITCH_ITEMS, pItem1);
- InsertItem(&pItem305C, pItem1, SWITCH_ITEMS, pItem3);
-
- pItem3 = pItem2->parent->child;
- if(pItem1->parent->child == pItem1)
- pItem1->parent->child = pItem2;
-
- if(pItem3 == pItem2)
- pItem2->parent->child = pItem1;
-
- pTemp = pItem1->parent;
- pItem1->parent = pItem2->parent;
- pItem2->parent = pTemp;
- offs0004++;
- }
- }
- }
-// 1500EB62
- else
- {
- dwBitBuff = 0;
- nBits = 0;
- for(pItem2 = pItem1->parent; pItem2 != NULL; pItem2 = pItem2->parent)
- {
- nBit = (pItem2->child != pItem1) ? 1 : 0;
- dwBitBuff = (dwBitBuff << 1) | nBit;
- nBits++;
- pItem1 = pItem2;
- }
- os->PutBits(dwBitBuff, nBits);
- }
-
-// 1500EB98
- if(bIsCmp0 != 0)
- Call1500E820(items306C[bOneByte]); // 1500EB9D
-// 1500EBAF
- } // for(; nInLength != 0; nInLength--)
-
-// 1500EBB8
- pItem1 = items306C[0x100];
- dwBitBuff = 0;
- nBits = 0;
- for(pItem2 = pItem1->parent; pItem2 != NULL; pItem2 = pItem2->parent)
- {
- nBit = (pItem2->child != pItem1) ? 1 : 0;
- dwBitBuff = (dwBitBuff << 1) | nBit;
- nBits++;
- pItem1 = pItem2;
- }
-
-// 1500EBE6
- os->PutBits(dwBitBuff, nBits);
-
-// 1500EBEF
- // Flush the remaining bits
- while(os->nBits != 0)
- {
- if(os->cbOutSize != 0)
- {
- *os->pbOutPos++ = (unsigned char)os->dwBitBuff;
- os->cbOutSize--;
- }
- os->dwBitBuff >>= 8;
- os->nBits -= ((os->nBits > 8) ? 8 : os->nBits);
- }
-
- return (unsigned int)(os->pbOutPos - os->pbOutBuffer);
-}
-
-// Decompression using Huffman tree (1500E450)
-unsigned int THuffmannTree::DoDecompression(unsigned char * pbOutBuffer, unsigned int dwOutLength, TInputStream * is)
-{
- TQDecompress * qd;
- THTreeItem * pItem1;
- THTreeItem * pItem2;
- unsigned char * pbOutPos = pbOutBuffer;
- unsigned long nBitCount;
- unsigned int nDcmpByte = 0;
- unsigned int n8Bits; // 8 bits loaded from input stream
- unsigned int n7Bits; // 7 bits loaded from input stream
- bool bHasQdEntry;
-
- // Test the output length. Must not be NULL.
- if(dwOutLength == 0)
- return 0;
-
- // Get the compression type from the input stream
- n8Bits = is->Get8Bits();
-
- // Build the Huffman tree
- BuildTree(n8Bits);
- bIsCmp0 = (n8Bits == 0) ? 1 : 0;
-
- for(;;)
- {
- // Security check: If we are at the end of the input buffer,
- // it means that the data are corrupt.
- if(is->pbInBuffer > is->pbInBufferEnd)
- return 0;
-
- // Get 7 bits from input stream
- n7Bits = is->Get7Bits();
-
- // Try to use quick decompression. Check TQDecompress array for corresponding item.
- // If found, ise the result byte instead.
- qd = &qd3474[n7Bits];
-
- // If there is a quick-pass possible (ebx)
- bHasQdEntry = (qd->offs00 >= offs0004) ? true : false;
-
- // If we can use quick decompress, use it.
- if(bHasQdEntry)
- {
- if(qd->nBits > 7)
- {
- is->SkipBits(7);
- pItem1 = qd->pItem;
- goto _1500E549;
- }
- is->SkipBits(qd->nBits);
- nDcmpByte = qd->dcmpByte;
- }
- else
- {
- pItem1 = pFirst->next->prev;
- if(PTR_INVALID_OR_NULL(pItem1))
- pItem1 = NULL;
-_1500E549:
- nBitCount = 0;
- pItem2 = NULL;
-
- do
- {
- pItem1 = pItem1->child; // Move down by one level
- if(is->GetBit()) // If current bit is set, move to previous
- pItem1 = pItem1->prev;
-
- if(++nBitCount == 7) // If we are at 7th bit, save current HTree item.
- pItem2 = pItem1;
- }
- while(pItem1->child != NULL); // Walk until tree has no deeper level
-
- if(bHasQdEntry == false)
- {
- if(nBitCount > 7)
- {
- qd->offs00 = offs0004;
- qd->nBits = nBitCount;
- qd->pItem = pItem2;
- }
- else
- {
- unsigned long nIndex = n7Bits & (0xFFFFFFFF >> (32 - nBitCount));
- unsigned long nAdd = (1 << nBitCount);
-
- for(qd = &qd3474[nIndex]; nIndex <= 0x7F; nIndex += nAdd, qd += nAdd)
- {
- qd->offs00 = offs0004;
- qd->nBits = nBitCount;
- qd->dcmpByte = pItem1->dcmpByte;
- }
- }
- }
- nDcmpByte = pItem1->dcmpByte;
- }
-
- if(nDcmpByte == 0x101) // Huffman tree needs to be modified
- {
- n8Bits = is->Get8Bits();
- pItem1 = (PTR_INVALID_OR_NULL(pLast)) ? NULL : pLast;
-
- pItem2 = Call1500E740(1);
- pItem2->parent = pItem1;
- pItem2->dcmpByte = pItem1->dcmpByte;
- pItem2->byteValue = pItem1->byteValue;
- items306C[pItem2->dcmpByte] = pItem2;
-
- pItem2 = Call1500E740(1);
- pItem2->parent = pItem1;
- pItem2->dcmpByte = n8Bits;
- pItem2->byteValue = 0;
- items306C[pItem2->dcmpByte] = pItem2;
-
- pItem1->child = pItem2;
- Call1500E820(pItem2);
- if(bIsCmp0 == 0)
- Call1500E820(items306C[n8Bits]);
-
- nDcmpByte = n8Bits;
- }
-
- if(nDcmpByte == 0x100)
- break;
-
- *pbOutPos++ = (unsigned char)nDcmpByte;
- if(--dwOutLength == 0)
- break;
-
- if(bIsCmp0)
- Call1500E820(items306C[nDcmpByte]);
- }
-
- return (unsigned int)(pbOutPos - pbOutBuffer);
-}
-
-
-// Table for (de)compression. Every compression type has 258 entries
-unsigned char THuffmannTree::Table1502A630[] =
-{
- // Data for compression type 0x00
- 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00,
-
- // Data for compression type 0x01
- 0x54, 0x16, 0x16, 0x0D, 0x0C, 0x08, 0x06, 0x05, 0x06, 0x05, 0x06, 0x03, 0x04, 0x04, 0x03, 0x05,
- 0x0E, 0x0B, 0x14, 0x13, 0x13, 0x09, 0x0B, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02,
- 0x0D, 0x07, 0x09, 0x06, 0x06, 0x04, 0x03, 0x02, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02,
- 0x09, 0x06, 0x04, 0x04, 0x04, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x04,
- 0x08, 0x03, 0x04, 0x07, 0x09, 0x05, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02,
- 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02,
- 0x06, 0x0A, 0x08, 0x08, 0x06, 0x07, 0x04, 0x03, 0x04, 0x04, 0x02, 0x02, 0x04, 0x02, 0x03, 0x03,
- 0x04, 0x03, 0x07, 0x07, 0x09, 0x06, 0x04, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x0A, 0x02, 0x02, 0x03, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x03, 0x05, 0x02, 0x03,
- 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01, 0x01,
- 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x09, 0x08, 0x0C, 0x02,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03,
- 0x04, 0x01, 0x02, 0x04, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
- 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x4B,
- 0x00, 0x00,
-
- // Data for compression type 0x02
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x27, 0x00, 0x00, 0x23, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x06, 0x0E, 0x10, 0x04,
- 0x06, 0x08, 0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01,
- 0x01, 0x04, 0x02, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0x02, 0x03, 0x03, 0x02,
- 0x03, 0x01, 0x03, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01,
- 0x01, 0x29, 0x07, 0x16, 0x12, 0x40, 0x0A, 0x0A, 0x11, 0x25, 0x01, 0x03, 0x17, 0x10, 0x26, 0x2A,
- 0x10, 0x01, 0x23, 0x23, 0x2F, 0x10, 0x06, 0x07, 0x02, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
- // Data for compression type 0x03
- 0xFF, 0x0B, 0x07, 0x05, 0x0B, 0x02, 0x02, 0x02, 0x06, 0x02, 0x02, 0x01, 0x04, 0x02, 0x01, 0x03,
- 0x09, 0x01, 0x01, 0x01, 0x03, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
- 0x05, 0x01, 0x01, 0x01, 0x0D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
- 0x0A, 0x04, 0x02, 0x01, 0x06, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01,
- 0x05, 0x02, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x03, 0x03,
- 0x01, 0x03, 0x01, 0x01, 0x02, 0x05, 0x01, 0x01, 0x04, 0x03, 0x05, 0x01, 0x03, 0x01, 0x03, 0x03,
- 0x02, 0x01, 0x04, 0x03, 0x0A, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x02, 0x01, 0x0A, 0x02, 0x05, 0x01, 0x01, 0x02, 0x07, 0x02, 0x17, 0x01, 0x05, 0x01, 0x01,
- 0x0E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x06, 0x02, 0x01, 0x04, 0x05, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11,
- 0x00, 0x00,
-
- // Data for compression type 0x04
- 0xFF, 0xFB, 0x98, 0x9A, 0x84, 0x85, 0x63, 0x64, 0x3E, 0x3E, 0x22, 0x22, 0x13, 0x13, 0x18, 0x17,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
- // Data for compression type 0x05
- 0xFF, 0xF1, 0x9D, 0x9E, 0x9A, 0x9B, 0x9A, 0x97, 0x93, 0x93, 0x8C, 0x8E, 0x86, 0x88, 0x80, 0x82,
- 0x7C, 0x7C, 0x72, 0x73, 0x69, 0x6B, 0x5F, 0x60, 0x55, 0x56, 0x4A, 0x4B, 0x40, 0x41, 0x37, 0x37,
- 0x2F, 0x2F, 0x27, 0x27, 0x21, 0x21, 0x1B, 0x1C, 0x17, 0x17, 0x13, 0x13, 0x10, 0x10, 0x0D, 0x0D,
- 0x0B, 0x0B, 0x09, 0x09, 0x08, 0x08, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x04, 0x04, 0x19, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
- // Data for compression type 0x06
- 0xC3, 0xCB, 0xF5, 0x41, 0xFF, 0x7B, 0xF7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xBF, 0xCC, 0xF2, 0x40, 0xFD, 0x7C, 0xF7, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x7A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
- // Data for compression type 0x07
- 0xC3, 0xD9, 0xEF, 0x3D, 0xF9, 0x7C, 0xE9, 0x1E, 0xFD, 0xAB, 0xF1, 0x2C, 0xFC, 0x5B, 0xFE, 0x17,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xBD, 0xD9, 0xEC, 0x3D, 0xF5, 0x7D, 0xE8, 0x1D, 0xFB, 0xAE, 0xF0, 0x2C, 0xFB, 0x5C, 0xFF, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x70, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
- // Data for compression type 0x08
- 0xBA, 0xC5, 0xDA, 0x33, 0xE3, 0x6D, 0xD8, 0x18, 0xE5, 0x94, 0xDA, 0x23, 0xDF, 0x4A, 0xD1, 0x10,
- 0xEE, 0xAF, 0xE4, 0x2C, 0xEA, 0x5A, 0xDE, 0x15, 0xF4, 0x87, 0xE9, 0x21, 0xF6, 0x43, 0xFC, 0x12,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xB0, 0xC7, 0xD8, 0x33, 0xE3, 0x6B, 0xD6, 0x18, 0xE7, 0x95, 0xD8, 0x23, 0xDB, 0x49, 0xD0, 0x11,
- 0xE9, 0xB2, 0xE2, 0x2B, 0xE8, 0x5C, 0xDD, 0x15, 0xF1, 0x87, 0xE7, 0x20, 0xF7, 0x44, 0xFF, 0x13,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x5F, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00
-};
diff --git a/dep/StormLib/src/huffman/huff_patch.h b/dep/StormLib/src/huffman/huff_patch.h
deleted file mode 100644
index c1c03e67860..00000000000
--- a/dep/StormLib/src/huffman/huff_patch.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*****************************************************************************/
-/* huffman.h Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Description : */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* xx.xx.xx 1.00 Lad The first version of huffman.h */
-/* 03.05.03 2.00 Lad Added compression */
-/* 08.12.03 2.01 Dan High-memory handling (> 0x80000000) */
-/*****************************************************************************/
-
-#ifndef __HUFFMAN_H__
-#define __HUFFMAN_H__
-
-#include <stdint.h>
-
-#define SIntPtr intptr_t
-
-//-----------------------------------------------------------------------------
-// Defines
-
-#define INSERT_ITEM 1
-#define SWITCH_ITEMS 2 // Switch the item1 and item2
-
-#define PTR_NOT(ptr) ((ptr) == gcpFirst ? gpFirst : gpItem3054)
-#define PTR_PTR(ptr) ((THTreeItem *)(ptr))
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-//-----------------------------------------------------------------------------
-// Structures and classes
-
-// Input stream for Huffmann decompression
-class TInputStream
-{
- public:
-
- unsigned long GetBit();
- unsigned long Get7Bits();
- unsigned long Get8Bits();
- void SkipBits(unsigned int BitCount);
-
- unsigned char * pbInBuffer; // Input data
- unsigned char * pbInBufferEnd; // End of the input buffer
- unsigned long BitBuffer; // Input bit buffer
- unsigned int BitCount; // Number of bits remaining in 'dwBitBuff'
-};
-
-// Output stream for Huffmann compression
-class TOutputStream
-{
- public:
-
- void PutBits(unsigned long dwBuff, unsigned int nPutBits);
-
- unsigned char * pbOutBuffer; // 00 : Output buffer
- unsigned long cbOutSize; // 04 : Size of output buffer
- unsigned char * pbOutPos; // 08 : Current output position
- unsigned long dwBitBuff; // 0C : Bit buffer
- unsigned long nBits; // 10 : Number of bits in the bit buffer
-};
-
-// Huffmann tree item (?)
-struct THTreeItem
-{
- public:
-
- THTreeItem * Call1501DB70(THTreeItem * pLast);
- THTreeItem * GetPrevItem(SIntPtr value);
- void ClearItemLinks();
- void RemoveItem();
-
- THTreeItem * next; // 00 - Pointer to next THTreeItem
- THTreeItem * prev; // 04 - Pointer to prev THTreeItem (< 0 if none)
- unsigned long dcmpByte; // 08 - Index of this item in item pointer array, decompressed byte value
- unsigned long byteValue; // 0C - Some byte value
- THTreeItem * parent; // 10 - Pointer to parent THTreeItem (NULL if none)
- THTreeItem * child; // 14 - Pointer to child THTreeItem
- int addressMultiplier; // -1 if object on negative address (>0x80000000), +1 if positive
-};
-
-// Structure used for quick decompress. The 'bitCount' contains number of bits
-// and byte value contains result decompressed byte value.
-// After each walk through Huffman tree are filled all entries which are
-// multiplies of number of bits loaded from input stream. These entries
-// contain number of bits and result value. At the next 7 bits is tested this
-// structure first. If corresponding entry found, decompression routine will
-// not walk through Huffman tree and directly stores output byte to output stream.
-struct TQDecompress
-{
- unsigned long offs00; // 00 - 1 if resolved
- unsigned long nBits; // 04 - Bit count
- union
- {
- unsigned long dcmpByte; // 08 - Byte value for decompress (if bitCount <= 7)
- THTreeItem * pItem; // 08 - THTreeItem (if number of bits is greater than 7
- };
-};
-
-// Structure for Huffman tree (Size 0x3674 bytes). Because I'm not expert
-// for the decompression, I do not know actually if the class is really a Hufmann
-// tree. If someone knows the decompression details, please let me know
-class THuffmannTree
-{
- public:
-
- THuffmannTree();
- void InitTree(bool bCompression);
- void BuildTree(unsigned int nCmpType);
-// void ModifyTree(unsigned long dwIndex);
-// void UninitTree();
-
-// void Call15007010(Bit32 dwInLength, THTreeItem * item);
- THTreeItem * Call1500E740(unsigned int nValue);
- void Call1500E820(THTreeItem * pItem);
- unsigned int DoCompression(TOutputStream * os, unsigned char * pbInBuffer, int nInLength, int nCmpType);
- unsigned int DoDecompression(unsigned char * pbOutBuffer, unsigned int dwOutLength, TInputStream * is);
-
- unsigned long bIsCmp0; // 0000 - 1 if compression type 0
- unsigned long offs0004; // 0004 - Some flag
- THTreeItem items0008[0x203]; // 0008 - HTree items
-
- //- Sometimes used as HTree item -----------
- THTreeItem * pItem3050; // 3050 - Always NULL (?)
- THTreeItem * pItem3054; // 3054 - Pointer to Huffman tree item
- THTreeItem * pItem3058; // 3058 - Pointer to Huffman tree item (< 0 if invalid)
-
- //- Sometimes used as HTree item -----------
- THTreeItem * pItem305C; // 305C - Usually NULL
- THTreeItem * pFirst; // 3060 - Pointer to top (first) Huffman tree item
- THTreeItem * pLast; // 3064 - Pointer to bottom (last) Huffman tree item (< 0 if invalid)
- unsigned long nItems; // 3068 - Number of used HTree items
-
- //-------------------------------------------
- THTreeItem * items306C[0x102]; // 306C - THTreeItem pointer array
- TQDecompress qd3474[0x80]; // 3474 - Array for quick decompression
- int addressMultiplier; // -1 if object on negative address (>0x80000000), +1 if positive
-
- static unsigned char Table1502A630[];// Some table
-};
-
-#endif // __HUFFMAN_H__
diff --git a/dep/StormLib/src/libtomcrypt/src/hashes/sha1.c b/dep/StormLib/src/libtomcrypt/src/hashes/sha1.c
deleted file mode 100644
index 409d0954241..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/hashes/sha1.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../headers/tomcrypt.h"
-
-/**
- @file sha1.c
- LTC_SHA1 code by Tom St Denis
-*/
-
-
-#ifdef LTC_SHA1
-
-const struct ltc_hash_descriptor sha1_desc =
-{
- "sha1",
- 2,
- 20,
- 64,
-
- /* OID */
- { 1, 3, 14, 3, 2, 26, },
- 6,
-
- &sha1_init,
- &sha1_process,
- &sha1_done,
- &sha1_test,
- NULL
-};
-
-#define F0(x,y,z) (z ^ (x & (y ^ z)))
-#define F1(x,y,z) (x ^ y ^ z)
-#define F2(x,y,z) ((x & y) | (z & (x | y)))
-#define F3(x,y,z) (x ^ y ^ z)
-
-#ifdef LTC_CLEAN_STACK
-static int _sha1_compress(hash_state *md, unsigned char *buf)
-#else
-static int sha1_compress(hash_state *md, unsigned char *buf)
-#endif
-{
- ulong32 a,b,c,d,e,W[80],i;
-#ifdef LTC_SMALL_CODE
- ulong32 t;
-#endif
-
- /* copy the state into 512-bits into W[0..15] */
- for (i = 0; i < 16; i++) {
- LOAD32H(W[i], buf + (4*i));
- }
-
- /* copy state */
- a = md->sha1.state[0];
- b = md->sha1.state[1];
- c = md->sha1.state[2];
- d = md->sha1.state[3];
- e = md->sha1.state[4];
-
- /* expand it */
- for (i = 16; i < 80; i++) {
- W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
- }
-
- /* compress */
- /* round one */
- #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30);
- #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30);
- #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30);
- #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30);
-
-#ifdef LTC_SMALL_CODE
-
- for (i = 0; i < 20; ) {
- FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
- }
-
- for (; i < 40; ) {
- FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
- }
-
- for (; i < 60; ) {
- FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
- }
-
- for (; i < 80; ) {
- FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
- }
-
-#else
-
- for (i = 0; i < 20; ) {
- FF0(a,b,c,d,e,i++);
- FF0(e,a,b,c,d,i++);
- FF0(d,e,a,b,c,i++);
- FF0(c,d,e,a,b,i++);
- FF0(b,c,d,e,a,i++);
- }
-
- /* round two */
- for (; i < 40; ) {
- FF1(a,b,c,d,e,i++);
- FF1(e,a,b,c,d,i++);
- FF1(d,e,a,b,c,i++);
- FF1(c,d,e,a,b,i++);
- FF1(b,c,d,e,a,i++);
- }
-
- /* round three */
- for (; i < 60; ) {
- FF2(a,b,c,d,e,i++);
- FF2(e,a,b,c,d,i++);
- FF2(d,e,a,b,c,i++);
- FF2(c,d,e,a,b,i++);
- FF2(b,c,d,e,a,i++);
- }
-
- /* round four */
- for (; i < 80; ) {
- FF3(a,b,c,d,e,i++);
- FF3(e,a,b,c,d,i++);
- FF3(d,e,a,b,c,i++);
- FF3(c,d,e,a,b,i++);
- FF3(b,c,d,e,a,i++);
- }
-#endif
-
- #undef FF0
- #undef FF1
- #undef FF2
- #undef FF3
-
- /* store */
- md->sha1.state[0] = md->sha1.state[0] + a;
- md->sha1.state[1] = md->sha1.state[1] + b;
- md->sha1.state[2] = md->sha1.state[2] + c;
- md->sha1.state[3] = md->sha1.state[3] + d;
- md->sha1.state[4] = md->sha1.state[4] + e;
-
- return CRYPT_OK;
-}
-
-#ifdef LTC_CLEAN_STACK
-static int sha1_compress(hash_state *md, unsigned char *buf)
-{
- int err;
- err = _sha1_compress(md, buf);
- burn_stack(sizeof(ulong32) * 87);
- return err;
-}
-#endif
-
-/**
- Initialize the hash state
- @param md The hash state you wish to initialize
- @return CRYPT_OK if successful
-*/
-int sha1_init(hash_state * md)
-{
- LTC_ARGCHK(md != NULL);
- md->sha1.state[0] = 0x67452301UL;
- md->sha1.state[1] = 0xefcdab89UL;
- md->sha1.state[2] = 0x98badcfeUL;
- md->sha1.state[3] = 0x10325476UL;
- md->sha1.state[4] = 0xc3d2e1f0UL;
- md->sha1.curlen = 0;
- md->sha1.length = 0;
- return CRYPT_OK;
-}
-
-/**
- Process a block of memory though the hash
- @param md The hash state
- @param in The data to hash
- @param inlen The length of the data (octets)
- @return CRYPT_OK if successful
-*/
-HASH_PROCESS(sha1_process, sha1_compress, sha1, 64)
-
-/**
- Terminate the hash to get the digest
- @param md The hash state
- @param out [out] The destination of the hash (20 bytes)
- @return CRYPT_OK if successful
-*/
-int sha1_done(hash_state * md, unsigned char *out)
-{
- int i;
-
- LTC_ARGCHK(md != NULL);
- LTC_ARGCHK(out != NULL);
-
- if (md->sha1.curlen >= sizeof(md->sha1.buf)) {
- return CRYPT_INVALID_ARG;
- }
-
- /* increase the length of the message */
- md->sha1.length += md->sha1.curlen * 8;
-
- /* append the '1' bit */
- md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80;
-
- /* if the length is currently above 56 bytes we append zeros
- * then compress. Then we can fall back to padding zeros and length
- * encoding like normal.
- */
- if (md->sha1.curlen > 56) {
- while (md->sha1.curlen < 64) {
- md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
- }
- sha1_compress(md, md->sha1.buf);
- md->sha1.curlen = 0;
- }
-
- /* pad upto 56 bytes of zeroes */
- while (md->sha1.curlen < 56) {
- md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
- }
-
- /* store length */
- STORE64H(md->sha1.length, md->sha1.buf+56);
- sha1_compress(md, md->sha1.buf);
-
- /* copy output */
- for (i = 0; i < 5; i++) {
- STORE32H(md->sha1.state[i], out+(4*i));
- }
-#ifdef LTC_CLEAN_STACK
- zeromem(md, sizeof(hash_state));
-#endif
- return CRYPT_OK;
-}
-
-/**
- Self-test the hash
- @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
-*/
-int sha1_test(void)
-{
- #ifndef LTC_TEST
- return CRYPT_NOP;
- #else
- static const struct {
- char *msg;
- unsigned char hash[20];
- } tests[] = {
- { "abc",
- { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
- 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
- 0x9c, 0xd0, 0xd8, 0x9d }
- },
- { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
- { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
- 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
- 0xE5, 0x46, 0x70, 0xF1 }
- }
- };
-
- int i;
- unsigned char tmp[20];
- hash_state md;
-
- for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
- sha1_init(&md);
- sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
- sha1_done(&md, tmp);
- if (XMEMCMP(tmp, tests[i].hash, 20) != 0) {
- return CRYPT_FAIL_TESTVECTOR;
- }
- }
- return CRYPT_OK;
- #endif
-}
-
-#endif
-
-
-
-/* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha1.c,v $ */
-/* $Revision: 1.10 $ */
-/* $Date: 2007/05/12 14:25:28 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/math/ltm_desc.c b/dep/StormLib/src/libtomcrypt/src/math/ltm_desc.c
deleted file mode 100644
index 25dc0b32279..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/math/ltm_desc.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-#define DESC_DEF_ONLY
-#include "../headers/tomcrypt.h"
-
-#ifdef LTM_DESC
-
-#include "../../../libtommath/tommath.h"
-
-static const struct {
- int mpi_code, ltc_code;
-} mpi_to_ltc_codes[] = {
- { MP_OKAY , CRYPT_OK},
- { MP_MEM , CRYPT_MEM},
- { MP_VAL , CRYPT_INVALID_ARG},
-};
-
-/**
- Convert a MPI error to a LTC error (Possibly the most powerful function ever! Oh wait... no)
- @param err The error to convert
- @return The equivalent LTC error code or CRYPT_ERROR if none found
-*/
-static int mpi_to_ltc_error(int err)
-{
- int x;
-
- for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) {
- if (err == mpi_to_ltc_codes[x].mpi_code) {
- return mpi_to_ltc_codes[x].ltc_code;
- }
- }
- return CRYPT_ERROR;
-}
-
-static int init(void **a)
-{
- int err;
-
- LTC_ARGCHK(a != NULL);
-
- *a = XCALLOC(1, sizeof(mp_int));
- if (*a == NULL) {
- return CRYPT_MEM;
- }
-
- if ((err = mpi_to_ltc_error(mp_init(*a))) != CRYPT_OK) {
- XFREE(*a);
- }
- return err;
-}
-
-static void deinit(void *a)
-{
- LTC_ARGCHKVD(a != NULL);
- mp_clear(a);
- XFREE(a);
-}
-
-static int neg(void *a, void *b)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- return mpi_to_ltc_error(mp_neg(a, b));
-}
-
-static int copy(void *a, void *b)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- return mpi_to_ltc_error(mp_copy(a, b));
-}
-
-static int init_copy(void **a, void *b)
-{
- if (init(a) != CRYPT_OK) {
- return CRYPT_MEM;
- }
- return copy(b, *a);
-}
-
-/* ---- trivial ---- */
-static int set_int(void *a, unsigned long b)
-{
- LTC_ARGCHK(a != NULL);
- return mpi_to_ltc_error(mp_set_int(a, b));
-}
-
-static unsigned long get_int(void *a)
-{
- LTC_ARGCHK(a != NULL);
- return mp_get_int(a);
-}
-
-static unsigned long get_digit(void *a, int n)
-{
- mp_int *A;
- LTC_ARGCHK(a != NULL);
- A = a;
- return (n >= A->used || n < 0) ? 0 : A->dp[n];
-}
-
-static int get_digit_count(void *a)
-{
- mp_int *A;
- LTC_ARGCHK(a != NULL);
- A = a;
- return A->used;
-}
-
-static int compare(void *a, void *b)
-{
- int ret;
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- ret = mp_cmp(a, b);
- switch (ret) {
- case MP_LT: return LTC_MP_LT;
- case MP_EQ: return LTC_MP_EQ;
- case MP_GT: return LTC_MP_GT;
- }
- return 0;
-}
-
-static int compare_d(void *a, unsigned long b)
-{
- int ret;
- LTC_ARGCHK(a != NULL);
- ret = mp_cmp_d(a, b);
- switch (ret) {
- case MP_LT: return LTC_MP_LT;
- case MP_EQ: return LTC_MP_EQ;
- case MP_GT: return LTC_MP_GT;
- }
- return 0;
-}
-
-static int count_bits(void *a)
-{
- LTC_ARGCHK(a != NULL);
- return mp_count_bits(a);
-}
-
-static int count_lsb_bits(void *a)
-{
- LTC_ARGCHK(a != NULL);
- return mp_cnt_lsb(a);
-}
-
-
-static int twoexpt(void *a, int n)
-{
- LTC_ARGCHK(a != NULL);
- return mpi_to_ltc_error(mp_2expt(a, n));
-}
-
-/* ---- conversions ---- */
-
-/* read ascii string */
-static int read_radix(void *a, const char *b, int radix)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- return mpi_to_ltc_error(mp_read_radix(a, b, radix));
-}
-
-/* write one */
-static int write_radix(void *a, char *b, int radix)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- return mpi_to_ltc_error(mp_toradix(a, b, radix));
-}
-
-/* get size as unsigned char string */
-static unsigned long unsigned_size(void *a)
-{
- LTC_ARGCHK(a != NULL);
- return mp_unsigned_bin_size(a);
-}
-
-/* store */
-static int unsigned_write(void *a, unsigned char *b)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- return mpi_to_ltc_error(mp_to_unsigned_bin(a, b));
-}
-
-/* read */
-static int unsigned_read(void *a, unsigned char *b, unsigned long len)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- return mpi_to_ltc_error(mp_read_unsigned_bin(a, b, len));
-}
-
-/* add */
-static int add(void *a, void *b, void *c)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- LTC_ARGCHK(c != NULL);
- return mpi_to_ltc_error(mp_add(a, b, c));
-}
-
-static int addi(void *a, unsigned long b, void *c)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(c != NULL);
- return mpi_to_ltc_error(mp_add_d(a, b, c));
-}
-
-/* sub */
-static int sub(void *a, void *b, void *c)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- LTC_ARGCHK(c != NULL);
- return mpi_to_ltc_error(mp_sub(a, b, c));
-}
-
-static int subi(void *a, unsigned long b, void *c)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(c != NULL);
- return mpi_to_ltc_error(mp_sub_d(a, b, c));
-}
-
-/* mul */
-static int mul(void *a, void *b, void *c)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- LTC_ARGCHK(c != NULL);
- return mpi_to_ltc_error(mp_mul(a, b, c));
-}
-
-static int muli(void *a, unsigned long b, void *c)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(c != NULL);
- return mpi_to_ltc_error(mp_mul_d(a, b, c));
-}
-
-/* sqr */
-static int sqr(void *a, void *b)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- return mpi_to_ltc_error(mp_sqr(a, b));
-}
-
-/* div */
-static int divide(void *a, void *b, void *c, void *d)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- return mpi_to_ltc_error(mp_div(a, b, c, d));
-}
-
-static int div_2(void *a, void *b)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- return mpi_to_ltc_error(mp_div_2(a, b));
-}
-
-/* modi */
-static int modi(void *a, unsigned long b, unsigned long *c)
-{
- mp_digit tmp;
- int err;
-
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(c != NULL);
-
- if ((err = mpi_to_ltc_error(mp_mod_d(a, b, &tmp))) != CRYPT_OK) {
- return err;
- }
- *c = tmp;
- return CRYPT_OK;
-}
-
-/* gcd */
-static int gcd(void *a, void *b, void *c)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- LTC_ARGCHK(c != NULL);
- return mpi_to_ltc_error(mp_gcd(a, b, c));
-}
-
-/* lcm */
-static int lcm(void *a, void *b, void *c)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- LTC_ARGCHK(c != NULL);
- return mpi_to_ltc_error(mp_lcm(a, b, c));
-}
-
-static int mulmod(void *a, void *b, void *c, void *d)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- LTC_ARGCHK(c != NULL);
- LTC_ARGCHK(d != NULL);
- return mpi_to_ltc_error(mp_mulmod(a,b,c,d));
-}
-
-static int sqrmod(void *a, void *b, void *c)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- LTC_ARGCHK(c != NULL);
- return mpi_to_ltc_error(mp_sqrmod(a,b,c));
-}
-
-/* invmod */
-static int invmod(void *a, void *b, void *c)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- LTC_ARGCHK(c != NULL);
- return mpi_to_ltc_error(mp_invmod(a, b, c));
-}
-
-/* setup */
-static int montgomery_setup(void *a, void **b)
-{
- int err;
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- *b = XCALLOC(1, sizeof(mp_digit));
- if (*b == NULL) {
- return CRYPT_MEM;
- }
- if ((err = mpi_to_ltc_error(mp_montgomery_setup(a, (mp_digit *)*b))) != CRYPT_OK) {
- XFREE(*b);
- }
- return err;
-}
-
-/* get normalization value */
-static int montgomery_normalization(void *a, void *b)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- return mpi_to_ltc_error(mp_montgomery_calc_normalization(a, b));
-}
-
-/* reduce */
-static int montgomery_reduce(void *a, void *b, void *c)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- LTC_ARGCHK(c != NULL);
- return mpi_to_ltc_error(mp_montgomery_reduce(a, b, *((mp_digit *)c)));
-}
-
-/* clean up */
-static void montgomery_deinit(void *a)
-{
- XFREE(a);
-}
-
-static int exptmod(void *a, void *b, void *c, void *d)
-{
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- LTC_ARGCHK(c != NULL);
- LTC_ARGCHK(d != NULL);
- return mpi_to_ltc_error(mp_exptmod(a,b,c,d));
-}
-
-static int isprime(void *a, int *b)
-{
- int err;
- LTC_ARGCHK(a != NULL);
- LTC_ARGCHK(b != NULL);
- err = mpi_to_ltc_error(mp_prime_is_prime(a, 8, b));
- *b = (*b == MP_YES) ? LTC_MP_YES : LTC_MP_NO;
- return err;
-}
-
-const ltc_math_descriptor ltm_desc = {
-
- "LibTomMath",
- (int)DIGIT_BIT,
-
- &init,
- &init_copy,
- &deinit,
-
- &neg,
- &copy,
-
- &set_int,
- &get_int,
- &get_digit,
- &get_digit_count,
- &compare,
- &compare_d,
- &count_bits,
- &count_lsb_bits,
- &twoexpt,
-
- &read_radix,
- &write_radix,
- &unsigned_size,
- &unsigned_write,
- &unsigned_read,
-
- &add,
- &addi,
- &sub,
- &subi,
- &mul,
- &muli,
- &sqr,
- &divide,
- &div_2,
- &modi,
- &gcd,
- &lcm,
-
- &mulmod,
- &sqrmod,
- &invmod,
-
- &montgomery_setup,
- &montgomery_normalization,
- &montgomery_reduce,
- &montgomery_deinit,
-
- &exptmod,
- &isprime,
-
-#ifdef LTC_MECC
-#ifdef LTC_MECC_FP
- &ltc_ecc_fp_mulmod,
-#else
- &ltc_ecc_mulmod,
-#endif
- &ltc_ecc_projective_add_point,
- &ltc_ecc_projective_dbl_point,
- &ltc_ecc_map,
-#ifdef LTC_ECC_SHAMIR
-#ifdef LTC_MECC_FP
- &ltc_ecc_fp_mul2add,
-#else
- &ltc_ecc_mul2add,
-#endif /* LTC_MECC_FP */
-#else
- NULL,
-#endif /* LTC_ECC_SHAMIR */
-#else
- NULL, NULL, NULL, NULL, NULL,
-#endif /* LTC_MECC */
-
-#ifdef LTC_MRSA
- &rsa_make_key,
- &rsa_exptmod,
-#else
- NULL, NULL
-#endif
-};
-
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/math/ltm_desc.c,v $ */
-/* $Revision: 1.31 $ */
-/* $Date: 2007/05/12 14:32:35 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/math/multi.c b/dep/StormLib/src/libtomcrypt/src/math/multi.c
deleted file mode 100644
index 7d40040a1de..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/math/multi.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../headers/tomcrypt.h"
-
-#ifdef MPI
-#include <stdarg.h>
-
-int ltc_init_multi(void **a, ...)
-{
- void **cur = a;
- int np = 0;
- va_list args;
-
- va_start(args, a);
- while (cur != NULL) {
- if (mp_init(cur) != CRYPT_OK) {
- /* failed */
- va_list clean_list;
-
- va_start(clean_list, a);
- cur = a;
- while (np--) {
- mp_clear(*cur);
- cur = va_arg(clean_list, void**);
- }
- va_end(clean_list);
- return CRYPT_MEM;
- }
- ++np;
- cur = va_arg(args, void**);
- }
- va_end(args);
- return CRYPT_OK;
-}
-
-void ltc_deinit_multi(void *a, ...)
-{
- void *cur = a;
- va_list args;
-
- va_start(args, a);
- while (cur != NULL) {
- mp_clear(cur);
- cur = va_arg(args, void *);
- }
- va_end(args);
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/math/multi.c,v $ */
-/* $Revision: 1.6 $ */
-/* $Date: 2006/12/28 01:27:23 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/math/rand_prime.c b/dep/StormLib/src/libtomcrypt/src/math/rand_prime.c
deleted file mode 100644
index 913fa95a4a3..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/math/rand_prime.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../headers/tomcrypt.h"
-
-/**
- @file rand_prime.c
- Generate a random prime, Tom St Denis
-*/
-
-#define USE_BBS 1
-
-int rand_prime(void *N, long len, prng_state *prng, int wprng)
-{
- int err, res, type;
- unsigned char *buf;
-
- LTC_ARGCHK(N != NULL);
-
- /* get type */
- if (len < 0) {
- type = USE_BBS;
- len = -len;
- } else {
- type = 0;
- }
-
- /* allow sizes between 2 and 512 bytes for a prime size */
- if (len < 2 || len > 512) {
- return CRYPT_INVALID_PRIME_SIZE;
- }
-
- /* valid PRNG? Better be! */
- if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
- return err;
- }
-
- /* allocate buffer to work with */
- buf = XCALLOC(1, len);
- if (buf == NULL) {
- return CRYPT_MEM;
- }
-
- do {
- /* generate value */
- if (prng_descriptor[wprng].read(buf, len, prng) != (unsigned long)len) {
- XFREE(buf);
- return CRYPT_ERROR_READPRNG;
- }
-
- /* munge bits */
- buf[0] |= 0x80 | 0x40;
- buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00);
-
- /* load value */
- if ((err = mp_read_unsigned_bin(N, buf, len)) != CRYPT_OK) {
- XFREE(buf);
- return err;
- }
-
- /* test */
- if ((err = mp_prime_is_prime(N, 8, &res)) != CRYPT_OK) {
- XFREE(buf);
- return err;
- }
- } while (res == LTC_MP_NO);
-
-#ifdef LTC_CLEAN_STACK
- zeromem(buf, len);
-#endif
-
- XFREE(buf);
- return CRYPT_OK;
-}
-
-
-
-/* $Source: /cvs/libtom/libtomcrypt/src/math/rand_prime.c,v $ */
-/* $Revision: 1.7 $ */
-/* $Date: 2006/12/28 01:27:23 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/misc/base64_decode.c b/dep/StormLib/src/libtomcrypt/src/misc/base64_decode.c
deleted file mode 100644
index 3d13393a1dc..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/misc/base64_decode.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../headers/tomcrypt.h"
-
-/**
- @file base64_decode.c
- Compliant base64 code donated by Wayne Scott (wscott@bitmover.com)
-*/
-
-
-#ifdef LTC_BASE64
-
-static const unsigned char map[256] = {
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
-255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
-255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
- 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255 };
-
-/**
- base64 decode a block of memory
- @param in The base64 data to decode
- @param inlen The length of the base64 data
- @param out [out] The destination of the binary decoded data
- @param outlen [in/out] The max size and resulting size of the decoded data
- @return CRYPT_OK if successful
-*/
-int base64_decode(const unsigned char *in, unsigned long inlen,
- unsigned char *out, unsigned long *outlen)
-{
- unsigned long t, x, y, z;
- unsigned char c;
- int g;
-
- LTC_ARGCHK(in != NULL);
- LTC_ARGCHK(out != NULL);
- LTC_ARGCHK(outlen != NULL);
-
- g = 3;
- for (x = y = z = t = 0; x < inlen; x++) {
- c = map[in[x]&0xFF];
- if (c == 255) continue;
- /* the final = symbols are read and used to trim the remaining bytes */
- if (c == 254) {
- c = 0;
- /* prevent g < 0 which would potentially allow an overflow later */
- if (--g < 0) {
- return CRYPT_INVALID_PACKET;
- }
- } else if (g != 3) {
- /* we only allow = to be at the end */
- return CRYPT_INVALID_PACKET;
- }
-
- t = (t<<6)|c;
-
- if (++y == 4) {
- if (z + g > *outlen) {
- return CRYPT_BUFFER_OVERFLOW;
- }
- out[z++] = (unsigned char)((t>>16)&255);
- if (g > 1) out[z++] = (unsigned char)((t>>8)&255);
- if (g > 2) out[z++] = (unsigned char)(t&255);
- y = t = 0;
- }
- }
- if (y != 0) {
- return CRYPT_INVALID_PACKET;
- }
- *outlen = z;
- return CRYPT_OK;
-}
-
-#endif
-
-
-/* $Source: /cvs/libtom/libtomcrypt/src/misc/base64/base64_decode.c,v $ */
-/* $Revision: 1.6 $ */
-/* $Date: 2007/05/12 14:32:35 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_find_hash.c b/dep/StormLib/src/libtomcrypt/src/misc/crypt_find_hash.c
deleted file mode 100644
index fef2d8cca32..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_find_hash.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../headers/tomcrypt.h"
-
-/**
- @file crypt_find_hash.c
- Find a hash, Tom St Denis
-*/
-
-/**
- Find a registered hash by name
- @param name The name of the hash to look for
- @return >= 0 if found, -1 if not present
-*/
-int find_hash(const char *name)
-{
- int x;
- LTC_ARGCHK(name != NULL);
- LTC_MUTEX_LOCK(&ltc_hash_mutex);
- for (x = 0; x < TAB_SIZE; x++) {
- if (hash_descriptor[x].name != NULL && XSTRCMP(hash_descriptor[x].name, name) == 0) {
- LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
- return x;
- }
- }
- LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
- return -1;
-}
-
-/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_hash.c,v $ */
-/* $Revision: 1.7 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_find_prng.c b/dep/StormLib/src/libtomcrypt/src/misc/crypt_find_prng.c
deleted file mode 100644
index fafbb0e226f..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_find_prng.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../headers/tomcrypt.h"
-
-/**
- @file crypt_find_prng.c
- Find a PRNG, Tom St Denis
-*/
-
-/**
- Find a registered PRNG by name
- @param name The name of the PRNG to look for
- @return >= 0 if found, -1 if not present
-*/
-int find_prng(const char *name)
-{
- int x;
- LTC_ARGCHK(name != NULL);
- LTC_MUTEX_LOCK(&ltc_prng_mutex);
- for (x = 0; x < TAB_SIZE; x++) {
- if ((prng_descriptor[x].name != NULL) && XSTRCMP(prng_descriptor[x].name, name) == 0) {
- LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
- return x;
- }
- }
- LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
- return -1;
-}
-
-
-/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_prng.c,v $ */
-/* $Revision: 1.7 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c b/dep/StormLib/src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c
deleted file mode 100644
index 91ba9d162d2..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c
+++ /dev/null
@@ -1,13 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../headers/tomcrypt.h"
-
-ltc_math_descriptor ltc_mp;
diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_prng_descriptor.c b/dep/StormLib/src/libtomcrypt/src/misc/crypt_prng_descriptor.c
deleted file mode 100644
index c5b39e0c26f..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_prng_descriptor.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../headers/tomcrypt.h"
-
-/**
- @file crypt_prng_descriptor.c
- Stores the PRNG descriptors, Tom St Denis
-*/
-struct ltc_prng_descriptor prng_descriptor[TAB_SIZE] = {
-{ NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-LTC_MUTEX_GLOBAL(ltc_prng_mutex)
-
-
-/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_prng_descriptor.c,v $ */
-/* $Revision: 1.8 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_prng_is_valid.c b/dep/StormLib/src/libtomcrypt/src/misc/crypt_prng_is_valid.c
deleted file mode 100644
index d38fd3a3c9d..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_prng_is_valid.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../headers/tomcrypt.h"
-
-/**
- @file crypt_prng_is_valid.c
- Determine if PRNG is valid, Tom St Denis
-*/
-
-/*
- Test if a PRNG index is valid
- @param idx The index of the PRNG to search for
- @return CRYPT_OK if valid
-*/
-int prng_is_valid(int idx)
-{
- LTC_MUTEX_LOCK(&ltc_prng_mutex);
- if (idx < 0 || idx >= TAB_SIZE || prng_descriptor[idx].name == NULL) {
- LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
- return CRYPT_INVALID_PRNG;
- }
- LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
- return CRYPT_OK;
-}
-
-/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_prng_is_valid.c,v $ */
-/* $Revision: 1.6 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_register_hash.c b/dep/StormLib/src/libtomcrypt/src/misc/crypt_register_hash.c
deleted file mode 100644
index 17300915487..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_register_hash.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../headers/tomcrypt.h"
-
-/**
- @file crypt_register_hash.c
- Register a HASH, Tom St Denis
-*/
-
-/**
- Register a hash with the descriptor table
- @param hash The hash you wish to register
- @return value >= 0 if successfully added (or already present), -1 if unsuccessful
-*/
-int register_hash(const struct ltc_hash_descriptor *hash)
-{
- int x;
-
- LTC_ARGCHK(hash != NULL);
-
- /* is it already registered? */
- LTC_MUTEX_LOCK(&ltc_hash_mutex);
- for (x = 0; x < TAB_SIZE; x++) {
- if (XMEMCMP(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) {
- LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
- return x;
- }
- }
-
- /* find a blank spot */
- for (x = 0; x < TAB_SIZE; x++) {
- if (hash_descriptor[x].name == NULL) {
- XMEMCPY(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor));
- LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
- return x;
- }
- }
-
- /* no spot */
- LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
- return -1;
-}
-
-/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_register_hash.c,v $ */
-/* $Revision: 1.7 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_register_prng.c b/dep/StormLib/src/libtomcrypt/src/misc/crypt_register_prng.c
deleted file mode 100644
index 29fc9bdf63d..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_register_prng.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../headers/tomcrypt.h"
-
-/**
- @file crypt_register_prng.c
- Register a PRNG, Tom St Denis
-*/
-
-/**
- Register a PRNG with the descriptor table
- @param prng The PRNG you wish to register
- @return value >= 0 if successfully added (or already present), -1 if unsuccessful
-*/
-int register_prng(const struct ltc_prng_descriptor *prng)
-{
- int x;
-
- LTC_ARGCHK(prng != NULL);
-
- /* is it already registered? */
- LTC_MUTEX_LOCK(&ltc_prng_mutex);
- for (x = 0; x < TAB_SIZE; x++) {
- if (XMEMCMP(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) == 0) {
- LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
- return x;
- }
- }
-
- /* find a blank spot */
- for (x = 0; x < TAB_SIZE; x++) {
- if (prng_descriptor[x].name == NULL) {
- XMEMCPY(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor));
- LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
- return x;
- }
- }
-
- /* no spot */
- LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
- return -1;
-}
-
-/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_register_prng.c,v $ */
-/* $Revision: 1.8 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/misc/zeromem.c b/dep/StormLib/src/libtomcrypt/src/misc/zeromem.c
deleted file mode 100644
index faa0efa7842..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/misc/zeromem.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../headers/tomcrypt.h"
-
-/**
- @file zeromem.c
- Zero a block of memory, Tom St Denis
-*/
-
-/**
- Zero a block of memory
- @param out The destination of the area to zero
- @param outlen The length of the area to zero (octets)
-*/
-void zeromem(void *out, size_t outlen)
-{
- unsigned char *mem = out;
- LTC_ARGCHKVD(out != NULL);
- while (outlen-- > 0) {
- *mem++ = 0;
- }
-}
-
-/* $Source: /cvs/libtom/libtomcrypt/src/misc/zeromem.c,v $ */
-/* $Revision: 1.7 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c
deleted file mode 100644
index e53686750fd..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_decode_bit_string.c
- ASN.1 DER, encode a BIT STRING, Tom St Denis
-*/
-
-
-#ifdef LTC_DER
-
-/**
- Store a BIT STRING
- @param in The DER encoded BIT STRING
- @param inlen The size of the DER BIT STRING
- @param out [out] The array of bits stored (one per char)
- @param outlen [in/out] The number of bits stored
- @return CRYPT_OK if successful
-*/
-int der_decode_bit_string(const unsigned char *in, unsigned long inlen,
- unsigned char *out, unsigned long *outlen)
-{
- unsigned long dlen, blen, x, y;
-
- LTC_ARGCHK(in != NULL);
- LTC_ARGCHK(out != NULL);
- LTC_ARGCHK(outlen != NULL);
-
- /* packet must be at least 4 bytes */
- if (inlen < 4) {
- return CRYPT_INVALID_ARG;
- }
-
- /* check for 0x03 */
- if ((in[0]&0x1F) != 0x03) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* offset in the data */
- x = 1;
-
- /* get the length of the data */
- if (in[x] & 0x80) {
- /* long format get number of length bytes */
- y = in[x++] & 0x7F;
-
- /* invalid if 0 or > 2 */
- if (y == 0 || y > 2) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* read the data len */
- dlen = 0;
- while (y--) {
- dlen = (dlen << 8) | (unsigned long)in[x++];
- }
- } else {
- /* short format */
- dlen = in[x++] & 0x7F;
- }
-
- /* is the data len too long or too short? */
- if ((dlen == 0) || (dlen + x > inlen)) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* get padding count */
- blen = ((dlen - 1) << 3) - (in[x++] & 7);
-
- /* too many bits? */
- if (blen > *outlen) {
- *outlen = blen;
- return CRYPT_BUFFER_OVERFLOW;
- }
-
- /* decode/store the bits */
- for (y = 0; y < blen; y++) {
- out[y] = (in[x] & (1 << (7 - (y & 7)))) ? 1 : 0;
- if ((y & 7) == 7) {
- ++x;
- }
- }
-
- /* we done */
- *outlen = blen;
- return CRYPT_OK;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c,v $ */
-/* $Revision: 1.5 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_boolean.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_boolean.c
deleted file mode 100644
index 617d4e8611d..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_boolean.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_decode_boolean.c
- ASN.1 DER, decode a BOOLEAN, Tom St Denis
-*/
-
-
-#ifdef LTC_DER
-
-/**
- Read a BOOLEAN
- @param in The destination for the DER encoded BOOLEAN
- @param inlen The size of the DER BOOLEAN
- @param out [out] The boolean to decode
- @return CRYPT_OK if successful
-*/
-int der_decode_boolean(const unsigned char *in, unsigned long inlen,
- int *out)
-{
- LTC_ARGCHK(in != NULL);
- LTC_ARGCHK(out != NULL);
-
- if (inlen != 3 || in[0] != 0x01 || in[1] != 0x01 || (in[2] != 0x00 && in[2] != 0xFF)) {
- return CRYPT_INVALID_ARG;
- }
-
- *out = (in[2]==0xFF) ? 1 : 0;
-
- return CRYPT_OK;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/boolean/der_decode_boolean.c,v $ */
-/* $Revision: 1.2 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_choice.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_choice.c
deleted file mode 100644
index 44a0891bead..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_choice.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_decode_choice.c
- ASN.1 DER, decode a CHOICE, Tom St Denis
-*/
-
-#ifdef LTC_DER
-
-/**
- Decode a CHOICE
- @param in The DER encoded input
- @param inlen [in/out] The size of the input and resulting size of read type
- @param list The list of items to decode
- @param outlen The number of items in the list
- @return CRYPT_OK on success
-*/
-int der_decode_choice(const unsigned char *in, unsigned long *inlen,
- ltc_asn1_list *list, unsigned long outlen)
-{
- unsigned long size, x, z;
- void *data;
-
- LTC_ARGCHK(in != NULL);
- LTC_ARGCHK(inlen != NULL);
- LTC_ARGCHK(list != NULL);
-
- /* get blk size */
- if (*inlen < 2) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* set all of the "used" flags to zero */
- for (x = 0; x < outlen; x++) {
- list[x].used = 0;
- }
-
- /* now scan until we have a winner */
- for (x = 0; x < outlen; x++) {
- size = list[x].size;
- data = list[x].data;
-
- switch (list[x].type) {
- case LTC_ASN1_INTEGER:
- if (der_decode_integer(in, *inlen, data) == CRYPT_OK) {
- if (der_length_integer(data, &z) == CRYPT_OK) {
- list[x].used = 1;
- *inlen = z;
- return CRYPT_OK;
- }
- }
- break;
-
- case LTC_ASN1_SHORT_INTEGER:
- if (der_decode_short_integer(in, *inlen, data) == CRYPT_OK) {
- if (der_length_short_integer(size, &z) == CRYPT_OK) {
- list[x].used = 1;
- *inlen = z;
- return CRYPT_OK;
- }
- }
- break;
-
- case LTC_ASN1_BIT_STRING:
- if (der_decode_bit_string(in, *inlen, data, &size) == CRYPT_OK) {
- if (der_length_bit_string(size, &z) == CRYPT_OK) {
- list[x].used = 1;
- list[x].size = size;
- *inlen = z;
- return CRYPT_OK;
- }
- }
- break;
-
- case LTC_ASN1_OCTET_STRING:
- if (der_decode_octet_string(in, *inlen, data, &size) == CRYPT_OK) {
- if (der_length_octet_string(size, &z) == CRYPT_OK) {
- list[x].used = 1;
- list[x].size = size;
- *inlen = z;
- return CRYPT_OK;
- }
- }
- break;
-
- case LTC_ASN1_NULL:
- if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) {
- *inlen = 2;
- list[x].used = 1;
- return CRYPT_OK;
- }
- break;
-
- case LTC_ASN1_OBJECT_IDENTIFIER:
- if (der_decode_object_identifier(in, *inlen, data, &size) == CRYPT_OK) {
- if (der_length_object_identifier(data, size, &z) == CRYPT_OK) {
- list[x].used = 1;
- list[x].size = size;
- *inlen = z;
- return CRYPT_OK;
- }
- }
- break;
-
- case LTC_ASN1_IA5_STRING:
- if (der_decode_ia5_string(in, *inlen, data, &size) == CRYPT_OK) {
- if (der_length_ia5_string(data, size, &z) == CRYPT_OK) {
- list[x].used = 1;
- list[x].size = size;
- *inlen = z;
- return CRYPT_OK;
- }
- }
- break;
-
-
- case LTC_ASN1_PRINTABLE_STRING:
- if (der_decode_printable_string(in, *inlen, data, &size) == CRYPT_OK) {
- if (der_length_printable_string(data, size, &z) == CRYPT_OK) {
- list[x].used = 1;
- list[x].size = size;
- *inlen = z;
- return CRYPT_OK;
- }
- }
- break;
-
- case LTC_ASN1_UTF8_STRING:
- if (der_decode_utf8_string(in, *inlen, data, &size) == CRYPT_OK) {
- if (der_length_utf8_string(data, size, &z) == CRYPT_OK) {
- list[x].used = 1;
- list[x].size = size;
- *inlen = z;
- return CRYPT_OK;
- }
- }
- break;
-
- case LTC_ASN1_UTCTIME:
- z = *inlen;
- if (der_decode_utctime(in, &z, data) == CRYPT_OK) {
- list[x].used = 1;
- *inlen = z;
- return CRYPT_OK;
- }
- break;
-
- case LTC_ASN1_SET:
- case LTC_ASN1_SETOF:
- case LTC_ASN1_SEQUENCE:
- if (der_decode_sequence(in, *inlen, data, size) == CRYPT_OK) {
- if (der_length_sequence(data, size, &z) == CRYPT_OK) {
- list[x].used = 1;
- *inlen = z;
- return CRYPT_OK;
- }
- }
- break;
-
- default:
- return CRYPT_INVALID_ARG;
- }
- }
-
- return CRYPT_INVALID_PACKET;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c,v $ */
-/* $Revision: 1.9 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c
deleted file mode 100644
index f2e073b8d84..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_decode_ia5_string.c
- ASN.1 DER, encode a IA5 STRING, Tom St Denis
-*/
-
-
-#ifdef LTC_DER
-
-/**
- Store a IA5 STRING
- @param in The DER encoded IA5 STRING
- @param inlen The size of the DER IA5 STRING
- @param out [out] The array of octets stored (one per char)
- @param outlen [in/out] The number of octets stored
- @return CRYPT_OK if successful
-*/
-int der_decode_ia5_string(const unsigned char *in, unsigned long inlen,
- unsigned char *out, unsigned long *outlen)
-{
- unsigned long x, y, len;
- int t;
-
- LTC_ARGCHK(in != NULL);
- LTC_ARGCHK(out != NULL);
- LTC_ARGCHK(outlen != NULL);
-
- /* must have header at least */
- if (inlen < 2) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* check for 0x16 */
- if ((in[0] & 0x1F) != 0x16) {
- return CRYPT_INVALID_PACKET;
- }
- x = 1;
-
- /* decode the length */
- if (in[x] & 0x80) {
- /* valid # of bytes in length are 1,2,3 */
- y = in[x] & 0x7F;
- if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* read the length in */
- len = 0;
- ++x;
- while (y--) {
- len = (len << 8) | in[x++];
- }
- } else {
- len = in[x++] & 0x7F;
- }
-
- /* is it too long? */
- if (len > *outlen) {
- *outlen = len;
- return CRYPT_BUFFER_OVERFLOW;
- }
-
- if (len + x > inlen) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* read the data */
- for (y = 0; y < len; y++) {
- t = der_ia5_value_decode(in[x++]);
- if (t == -1) {
- return CRYPT_INVALID_ARG;
- }
- out[y] = t;
- }
-
- *outlen = y;
-
- return CRYPT_OK;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_decode_ia5_string.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_integer.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_integer.c
deleted file mode 100644
index cca27451963..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_integer.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_decode_integer.c
- ASN.1 DER, decode an integer, Tom St Denis
-*/
-
-
-#ifdef LTC_DER
-
-/**
- Read a mp_int integer
- @param in The DER encoded data
- @param inlen Size of DER encoded data
- @param num The first mp_int to decode
- @return CRYPT_OK if successful
-*/
-int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num)
-{
- unsigned long x, y, z;
- int err;
-
- LTC_ARGCHK(num != NULL);
- LTC_ARGCHK(in != NULL);
-
- /* min DER INTEGER is 0x02 01 00 == 0 */
- if (inlen < (1 + 1 + 1)) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* ok expect 0x02 when we AND with 0001 1111 [1F] */
- x = 0;
- if ((in[x++] & 0x1F) != 0x02) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* now decode the len stuff */
- z = in[x++];
-
- if ((z & 0x80) == 0x00) {
- /* short form */
-
- /* will it overflow? */
- if (x + z > inlen) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* no so read it */
- if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, z)) != CRYPT_OK) {
- return err;
- }
- } else {
- /* long form */
- z &= 0x7F;
-
- /* will number of length bytes overflow? (or > 4) */
- if (((x + z) > inlen) || (z > 4) || (z == 0)) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* now read it in */
- y = 0;
- while (z--) {
- y = ((unsigned long)(in[x++])) | (y << 8);
- }
-
- /* now will reading y bytes overrun? */
- if ((x + y) > inlen) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* no so read it */
- if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, y)) != CRYPT_OK) {
- return err;
- }
- }
-
- /* see if it's negative */
- if (in[x] & 0x80) {
- void *tmp;
- if (mp_init(&tmp) != CRYPT_OK) {
- return CRYPT_MEM;
- }
-
- if (mp_2expt(tmp, mp_count_bits(num)) != CRYPT_OK || mp_sub(num, tmp, num) != CRYPT_OK) {
- mp_clear(tmp);
- return CRYPT_MEM;
- }
- mp_clear(tmp);
- }
-
- return CRYPT_OK;
-
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c,v $ */
-/* $Revision: 1.5 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c
deleted file mode 100644
index e7baae88e0c..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_decode_object_identifier.c
- ASN.1 DER, Decode Object Identifier, Tom St Denis
-*/
-
-#ifdef LTC_DER
-/**
- Decode OID data and store the array of integers in words
- @param in The OID DER encoded data
- @param inlen The length of the OID data
- @param words [out] The destination of the OID words
- @param outlen [in/out] The number of OID words
- @return CRYPT_OK if successful
-*/
-int der_decode_object_identifier(const unsigned char *in, unsigned long inlen,
- unsigned long *words, unsigned long *outlen)
-{
- unsigned long x, y, t, len;
-
- LTC_ARGCHK(in != NULL);
- LTC_ARGCHK(words != NULL);
- LTC_ARGCHK(outlen != NULL);
-
- /* header is at least 3 bytes */
- if (inlen < 3) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* must be room for at least two words */
- if (*outlen < 2) {
- return CRYPT_BUFFER_OVERFLOW;
- }
-
- /* decode the packet header */
- x = 0;
- if ((in[x++] & 0x1F) != 0x06) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* get the length */
- if (in[x] < 128) {
- len = in[x++];
- } else {
- if (in[x] < 0x81 || in[x] > 0x82) {
- return CRYPT_INVALID_PACKET;
- }
- y = in[x++] & 0x7F;
- len = 0;
- while (y--) {
- len = (len << 8) | (unsigned long)in[x++];
- }
- }
-
- if (len < 1 || (len + x) > inlen) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* decode words */
- y = 0;
- t = 0;
- while (len--) {
- t = (t << 7) | (in[x] & 0x7F);
- if (!(in[x++] & 0x80)) {
- /* store t */
- if (y >= *outlen) {
- return CRYPT_BUFFER_OVERFLOW;
- }
- if (y == 0) {
- words[0] = t / 40;
- words[1] = t % 40;
- y = 2;
- } else {
- words[y++] = t;
- }
- t = 0;
- }
- }
-
- *outlen = y;
- return CRYPT_OK;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c,v $ */
-/* $Revision: 1.6 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c
deleted file mode 100644
index 523d0baa057..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_decode_octet_string.c
- ASN.1 DER, encode a OCTET STRING, Tom St Denis
-*/
-
-
-#ifdef LTC_DER
-
-/**
- Store a OCTET STRING
- @param in The DER encoded OCTET STRING
- @param inlen The size of the DER OCTET STRING
- @param out [out] The array of octets stored (one per char)
- @param outlen [in/out] The number of octets stored
- @return CRYPT_OK if successful
-*/
-int der_decode_octet_string(const unsigned char *in, unsigned long inlen,
- unsigned char *out, unsigned long *outlen)
-{
- unsigned long x, y, len;
-
- LTC_ARGCHK(in != NULL);
- LTC_ARGCHK(out != NULL);
- LTC_ARGCHK(outlen != NULL);
-
- /* must have header at least */
- if (inlen < 2) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* check for 0x04 */
- if ((in[0] & 0x1F) != 0x04) {
- return CRYPT_INVALID_PACKET;
- }
- x = 1;
-
- /* decode the length */
- if (in[x] & 0x80) {
- /* valid # of bytes in length are 1,2,3 */
- y = in[x] & 0x7F;
- if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* read the length in */
- len = 0;
- ++x;
- while (y--) {
- len = (len << 8) | in[x++];
- }
- } else {
- len = in[x++] & 0x7F;
- }
-
- /* is it too long? */
- if (len > *outlen) {
- *outlen = len;
- return CRYPT_BUFFER_OVERFLOW;
- }
-
- if (len + x > inlen) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* read the data */
- for (y = 0; y < len; y++) {
- out[y] = in[x++];
- }
-
- *outlen = y;
-
- return CRYPT_OK;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_decode_octet_string.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c
deleted file mode 100644
index f8325934395..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_decode_printable_string.c
- ASN.1 DER, encode a printable STRING, Tom St Denis
-*/
-
-
-#ifdef LTC_DER
-
-/**
- Store a printable STRING
- @param in The DER encoded printable STRING
- @param inlen The size of the DER printable STRING
- @param out [out] The array of octets stored (one per char)
- @param outlen [in/out] The number of octets stored
- @return CRYPT_OK if successful
-*/
-int der_decode_printable_string(const unsigned char *in, unsigned long inlen,
- unsigned char *out, unsigned long *outlen)
-{
- unsigned long x, y, len;
- int t;
-
- LTC_ARGCHK(in != NULL);
- LTC_ARGCHK(out != NULL);
- LTC_ARGCHK(outlen != NULL);
-
- /* must have header at least */
- if (inlen < 2) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* check for 0x13 */
- if ((in[0] & 0x1F) != 0x13) {
- return CRYPT_INVALID_PACKET;
- }
- x = 1;
-
- /* decode the length */
- if (in[x] & 0x80) {
- /* valid # of bytes in length are 1,2,3 */
- y = in[x] & 0x7F;
- if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* read the length in */
- len = 0;
- ++x;
- while (y--) {
- len = (len << 8) | in[x++];
- }
- } else {
- len = in[x++] & 0x7F;
- }
-
- /* is it too long? */
- if (len > *outlen) {
- *outlen = len;
- return CRYPT_BUFFER_OVERFLOW;
- }
-
- if (len + x > inlen) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* read the data */
- for (y = 0; y < len; y++) {
- t = der_printable_value_decode(in[x++]);
- if (t == -1) {
- return CRYPT_INVALID_ARG;
- }
- out[y] = t;
- }
-
- *outlen = y;
-
- return CRYPT_OK;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_decode_printable_string.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c
deleted file mode 100644
index 9b00f61b09a..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-#include <stdarg.h>
-
-
-/**
- @file der_decode_sequence_ex.c
- ASN.1 DER, decode a SEQUENCE, Tom St Denis
-*/
-
-#ifdef LTC_DER
-
-/**
- Decode a SEQUENCE
- @param in The DER encoded input
- @param inlen The size of the input
- @param list The list of items to decode
- @param outlen The number of items in the list
- @param ordered Search an unordeded or ordered list
- @return CRYPT_OK on success
-*/
-int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
- ltc_asn1_list *list, unsigned long outlen, int ordered)
-{
- int err, type;
- unsigned long size, x, y, z, i, blksize;
- void *data;
-
- LTC_ARGCHK(in != NULL);
- LTC_ARGCHK(list != NULL);
-
- /* get blk size */
- if (inlen < 2) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */
- x = 0;
- if (in[x] != 0x30 && in[x] != 0x31) {
- return CRYPT_INVALID_PACKET;
- }
- ++x;
-
- if (in[x] < 128) {
- blksize = in[x++];
- } else if (in[x] & 0x80) {
- if (in[x] < 0x81 || in[x] > 0x83) {
- return CRYPT_INVALID_PACKET;
- }
- y = in[x++] & 0x7F;
-
- /* would reading the len bytes overrun? */
- if (x + y > inlen) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* read len */
- blksize = 0;
- while (y--) {
- blksize = (blksize << 8) | (unsigned long)in[x++];
- }
- }
-
- /* would this blksize overflow? */
- if (x + blksize > inlen) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* mark all as unused */
- for (i = 0; i < outlen; i++) {
- list[i].used = 0;
- }
-
- /* ok read data */
- inlen = blksize;
- for (i = 0; i < outlen; i++) {
- z = 0;
- type = list[i].type;
- size = list[i].size;
- data = list[i].data;
- if (!ordered && list[i].used == 1) { continue; }
-
- if (type == LTC_ASN1_EOL) {
- break;
- }
-
- switch (type) {
- case LTC_ASN1_BOOLEAN:
- z = inlen;
- if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) {
- goto LBL_ERR;
- }
- if ((err = der_length_boolean(&z)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- break;
-
- case LTC_ASN1_INTEGER:
- z = inlen;
- if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) {
- if (!ordered) { continue; }
- goto LBL_ERR;
- }
- if ((err = der_length_integer(data, &z)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- break;
-
- case LTC_ASN1_SHORT_INTEGER:
- z = inlen;
- if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) {
- if (!ordered) { continue; }
- goto LBL_ERR;
- }
- if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) {
- goto LBL_ERR;
- }
-
- break;
-
- case LTC_ASN1_BIT_STRING:
- z = inlen;
- if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
- if (!ordered) { continue; }
- goto LBL_ERR;
- }
- list[i].size = size;
- if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- break;
-
- case LTC_ASN1_OCTET_STRING:
- z = inlen;
- if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) {
- if (!ordered) { continue; }
- goto LBL_ERR;
- }
- list[i].size = size;
- if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- break;
-
- case LTC_ASN1_NULL:
- if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) {
- if (!ordered) { continue; }
- err = CRYPT_INVALID_PACKET;
- goto LBL_ERR;
- }
- z = 2;
- break;
-
- case LTC_ASN1_OBJECT_IDENTIFIER:
- z = inlen;
- if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) {
- if (!ordered) { continue; }
- goto LBL_ERR;
- }
- list[i].size = size;
- if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- break;
-
- case LTC_ASN1_IA5_STRING:
- z = inlen;
- if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) {
- if (!ordered) { continue; }
- goto LBL_ERR;
- }
- list[i].size = size;
- if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- break;
-
-
- case LTC_ASN1_PRINTABLE_STRING:
- z = inlen;
- if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) {
- if (!ordered) { continue; }
- goto LBL_ERR;
- }
- list[i].size = size;
- if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- break;
-
- case LTC_ASN1_UTF8_STRING:
- z = inlen;
- if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) {
- if (!ordered) { continue; }
- goto LBL_ERR;
- }
- list[i].size = size;
- if ((err = der_length_utf8_string(data, size, &z)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- break;
-
- case LTC_ASN1_UTCTIME:
- z = inlen;
- if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) {
- if (!ordered) { continue; }
- goto LBL_ERR;
- }
- break;
-
- case LTC_ASN1_SET:
- z = inlen;
- if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) {
- if (!ordered) { continue; }
- goto LBL_ERR;
- }
- if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- break;
-
- case LTC_ASN1_SETOF:
- case LTC_ASN1_SEQUENCE:
- /* detect if we have the right type */
- if ((type == LTC_ASN1_SETOF && (in[x] & 0x3F) != 0x31) || (type == LTC_ASN1_SEQUENCE && (in[x] & 0x3F) != 0x30)) {
- err = CRYPT_INVALID_PACKET;
- goto LBL_ERR;
- }
-
- z = inlen;
- if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) {
- if (!ordered) { continue; }
- goto LBL_ERR;
- }
- if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- break;
-
-
- case LTC_ASN1_CHOICE:
- z = inlen;
- if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) {
- if (!ordered) { continue; }
- goto LBL_ERR;
- }
- break;
-
- default:
- err = CRYPT_INVALID_ARG;
- goto LBL_ERR;
- }
- x += z;
- inlen -= z;
- list[i].used = 1;
- if (!ordered) {
- /* restart the decoder */
- i = -1;
- }
- }
-
- for (i = 0; i < outlen; i++) {
- if (list[i].used == 0) {
- err = CRYPT_INVALID_PACKET;
- goto LBL_ERR;
- }
- }
- err = CRYPT_OK;
-
-LBL_ERR:
- return err;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c,v $ */
-/* $Revision: 1.16 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c
deleted file mode 100644
index 9c648bc89c6..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_decode_sequence_flexi.c
- ASN.1 DER, decode an array of ASN.1 types with a flexi parser, Tom St Denis
-*/
-
-#ifdef LTC_DER
-
-static unsigned long fetch_length(const unsigned char *in, unsigned long inlen)
-{
- unsigned long x, y, z;
-
- y = 0;
-
- /* skip type and read len */
- if (inlen < 2) {
- return 0xFFFFFFFF;
- }
- ++in; ++y;
-
- /* read len */
- x = *in++; ++y;
-
- /* <128 means literal */
- if (x < 128) {
- return x+y;
- }
- x &= 0x7F; /* the lower 7 bits are the length of the length */
- inlen -= 2;
-
- /* len means len of len! */
- if (x == 0 || x > 4 || x > inlen) {
- return 0xFFFFFFFF;
- }
-
- y += x;
- z = 0;
- while (x--) {
- z = (z<<8) | ((unsigned long)*in);
- ++in;
- }
- return z+y;
-}
-
-/**
- ASN.1 DER Flexi(ble) decoder will decode arbitrary DER packets and create a linked list of the decoded elements.
- @param in The input buffer
- @param inlen [in/out] The length of the input buffer and on output the amount of decoded data
- @param out [out] A pointer to the linked list
- @return CRYPT_OK on success.
-*/
-int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out)
-{
- ltc_asn1_list *l;
- unsigned long err, type, len, totlen, x, y;
- void *realloc_tmp;
-
- LTC_ARGCHK(in != NULL);
- LTC_ARGCHK(inlen != NULL);
- LTC_ARGCHK(out != NULL);
-
- l = NULL;
- totlen = 0;
-
- /* scan the input and and get lengths and what not */
- while (*inlen) {
- /* read the type byte */
- type = *in;
-
- /* fetch length */
- len = fetch_length(in, *inlen);
- if (len > *inlen) {
- err = CRYPT_INVALID_PACKET;
- goto error;
- }
-
- /* alloc new link */
- if (l == NULL) {
- l = XCALLOC(1, sizeof(*l));
- if (l == NULL) {
- err = CRYPT_MEM;
- goto error;
- }
- } else {
- l->next = XCALLOC(1, sizeof(*l));
- if (l->next == NULL) {
- err = CRYPT_MEM;
- goto error;
- }
- l->next->prev = l;
- l = l->next;
- }
-
- /* now switch on type */
- switch (type) {
- case 0x01: /* BOOLEAN */
- l->type = LTC_ASN1_BOOLEAN;
- l->size = 1;
- l->data = XCALLOC(1, sizeof(int));
-
- if ((err = der_decode_boolean(in, *inlen, l->data)) != CRYPT_OK) {
- goto error;
- }
-
- if ((err = der_length_boolean(&len)) != CRYPT_OK) {
- goto error;
- }
- break;
-
- case 0x02: /* INTEGER */
- /* init field */
- l->type = LTC_ASN1_INTEGER;
- l->size = 1;
- if ((err = mp_init(&l->data)) != CRYPT_OK) {
- goto error;
- }
-
- /* decode field */
- if ((err = der_decode_integer(in, *inlen, l->data)) != CRYPT_OK) {
- goto error;
- }
-
- /* calc length of object */
- if ((err = der_length_integer(l->data, &len)) != CRYPT_OK) {
- goto error;
- }
- break;
-
- case 0x03: /* BIT */
- /* init field */
- l->type = LTC_ASN1_BIT_STRING;
- l->size = len * 8; /* *8 because we store decoded bits one per char and they are encoded 8 per char. */
-
- if ((l->data = XCALLOC(1, l->size)) == NULL) {
- err = CRYPT_MEM;
- goto error;
- }
-
- if ((err = der_decode_bit_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
- goto error;
- }
-
- if ((err = der_length_bit_string(l->size, &len)) != CRYPT_OK) {
- goto error;
- }
- break;
-
- case 0x04: /* OCTET */
-
- /* init field */
- l->type = LTC_ASN1_OCTET_STRING;
- l->size = len;
-
- if ((l->data = XCALLOC(1, l->size)) == NULL) {
- err = CRYPT_MEM;
- goto error;
- }
-
- if ((err = der_decode_octet_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
- goto error;
- }
-
- if ((err = der_length_octet_string(l->size, &len)) != CRYPT_OK) {
- goto error;
- }
- break;
-
- case 0x05: /* NULL */
-
- /* valid NULL is 0x05 0x00 */
- if (in[0] != 0x05 || in[1] != 0x00) {
- err = CRYPT_INVALID_PACKET;
- goto error;
- }
-
- /* simple to store ;-) */
- l->type = LTC_ASN1_NULL;
- l->data = NULL;
- l->size = 0;
- len = 2;
-
- break;
-
- case 0x06: /* OID */
-
- /* init field */
- l->type = LTC_ASN1_OBJECT_IDENTIFIER;
- l->size = len;
-
- if ((l->data = XCALLOC(len, sizeof(unsigned long))) == NULL) {
- err = CRYPT_MEM;
- goto error;
- }
-
- if ((err = der_decode_object_identifier(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
- goto error;
- }
-
- if ((err = der_length_object_identifier(l->data, l->size, &len)) != CRYPT_OK) {
- goto error;
- }
-
- /* resize it to save a bunch of mem */
- if ((realloc_tmp = XREALLOC(l->data, l->size * sizeof(unsigned long))) == NULL) {
- /* out of heap but this is not an error */
- break;
- }
- l->data = realloc_tmp;
- break;
-
- case 0x0C: /* UTF8 */
-
- /* init field */
- l->type = LTC_ASN1_UTF8_STRING;
- l->size = len;
-
- if ((l->data = XCALLOC(sizeof(wchar_t), l->size)) == NULL) {
- err = CRYPT_MEM;
- goto error;
- }
-
- if ((err = der_decode_utf8_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
- goto error;
- }
-
- if ((err = der_length_utf8_string(l->data, l->size, &len)) != CRYPT_OK) {
- goto error;
- }
- break;
-
- case 0x13: /* PRINTABLE */
-
- /* init field */
- l->type = LTC_ASN1_PRINTABLE_STRING;
- l->size = len;
-
- if ((l->data = XCALLOC(1, l->size)) == NULL) {
- err = CRYPT_MEM;
- goto error;
- }
-
- if ((err = der_decode_printable_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
- goto error;
- }
-
- if ((err = der_length_printable_string(l->data, l->size, &len)) != CRYPT_OK) {
- goto error;
- }
- break;
-
- case 0x16: /* IA5 */
-
- /* init field */
- l->type = LTC_ASN1_IA5_STRING;
- l->size = len;
-
- if ((l->data = XCALLOC(1, l->size)) == NULL) {
- err = CRYPT_MEM;
- goto error;
- }
-
- if ((err = der_decode_ia5_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
- goto error;
- }
-
- if ((err = der_length_ia5_string(l->data, l->size, &len)) != CRYPT_OK) {
- goto error;
- }
- break;
-
- case 0x17: /* UTC TIME */
-
- /* init field */
- l->type = LTC_ASN1_UTCTIME;
- l->size = 1;
-
- if ((l->data = XCALLOC(1, sizeof(ltc_utctime))) == NULL) {
- err = CRYPT_MEM;
- goto error;
- }
-
- len = *inlen;
- if ((err = der_decode_utctime(in, &len, l->data)) != CRYPT_OK) {
- goto error;
- }
-
- if ((err = der_length_utctime(l->data, &len)) != CRYPT_OK) {
- goto error;
- }
- break;
-
- case 0x30: /* SEQUENCE */
- case 0x31: /* SET */
-
- /* init field */
- l->type = (type == 0x30) ? LTC_ASN1_SEQUENCE : LTC_ASN1_SET;
-
- /* we have to decode the SEQUENCE header and get it's length */
-
- /* move past type */
- ++in; --(*inlen);
-
- /* read length byte */
- x = *in++; --(*inlen);
-
- /* smallest SEQUENCE/SET header */
- y = 2;
-
- /* now if it's > 127 the next bytes are the length of the length */
- if (x > 128) {
- x &= 0x7F;
- in += x;
- *inlen -= x;
-
- /* update sequence header len */
- y += x;
- }
-
- /* Sequence elements go as child */
- len = len - y;
- if ((err = der_decode_sequence_flexi(in, &len, &(l->child))) != CRYPT_OK) {
- goto error;
- }
-
- /* len update */
- totlen += y;
-
- /* link them up y0 */
- l->child->parent = l;
-
- break;
- default:
- /* invalid byte ... this is a soft error */
- /* remove link */
- l = l->prev;
- XFREE(l->next);
- l->next = NULL;
- goto outside;
- }
-
- /* advance pointers */
- totlen += len;
- in += len;
- *inlen -= len;
- }
-
-outside:
-
- /* rewind l please */
- while (l->prev != NULL || l->parent != NULL) {
- if (l->parent != NULL) {
- l = l->parent;
- } else {
- l = l->prev;
- }
- }
-
- /* return */
- *out = l;
- *inlen = totlen;
- return CRYPT_OK;
-
-error:
- /* free list */
- der_sequence_free(l);
-
- return err;
-}
-
-#endif
-
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c,v $ */
-/* $Revision: 1.26 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c
deleted file mode 100644
index ff633df3511..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-#include <stdarg.h>
-
-
-/**
- @file der_decode_sequence_multi.c
- ASN.1 DER, decode a SEQUENCE, Tom St Denis
-*/
-
-#ifdef LTC_DER
-
-/**
- Decode a SEQUENCE type using a VA list
- @param in Input buffer
- @param inlen Length of input in octets
- @remark <...> is of the form <type, size, data> (int, unsigned long, void*)
- @return CRYPT_OK on success
-*/
-int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
-{
- int err, type;
- unsigned long size, x;
- void *data;
- va_list args;
- ltc_asn1_list *list;
-
- LTC_ARGCHK(in != NULL);
-
- /* get size of output that will be required */
- va_start(args, inlen);
- x = 0;
- for (;;) {
- type = va_arg(args, int);
- size = va_arg(args, unsigned long);
- data = va_arg(args, void*);
-
- if (type == LTC_ASN1_EOL) {
- break;
- }
-
- switch (type) {
- case LTC_ASN1_BOOLEAN:
- case LTC_ASN1_INTEGER:
- case LTC_ASN1_SHORT_INTEGER:
- case LTC_ASN1_BIT_STRING:
- case LTC_ASN1_OCTET_STRING:
- case LTC_ASN1_NULL:
- case LTC_ASN1_OBJECT_IDENTIFIER:
- case LTC_ASN1_IA5_STRING:
- case LTC_ASN1_PRINTABLE_STRING:
- case LTC_ASN1_UTF8_STRING:
- case LTC_ASN1_UTCTIME:
- case LTC_ASN1_SET:
- case LTC_ASN1_SETOF:
- case LTC_ASN1_SEQUENCE:
- case LTC_ASN1_CHOICE:
- ++x;
- break;
-
- default:
- va_end(args);
- return CRYPT_INVALID_ARG;
- }
- }
- va_end(args);
-
- /* allocate structure for x elements */
- if (x == 0) {
- return CRYPT_NOP;
- }
-
- list = XCALLOC(sizeof(*list), x);
- if (list == NULL) {
- return CRYPT_MEM;
- }
-
- /* fill in the structure */
- va_start(args, inlen);
- x = 0;
- for (;;) {
- type = va_arg(args, int);
- size = va_arg(args, unsigned long);
- data = va_arg(args, void*);
-
- if (type == LTC_ASN1_EOL) {
- break;
- }
-
- switch (type) {
- case LTC_ASN1_BOOLEAN:
- case LTC_ASN1_INTEGER:
- case LTC_ASN1_SHORT_INTEGER:
- case LTC_ASN1_BIT_STRING:
- case LTC_ASN1_OCTET_STRING:
- case LTC_ASN1_NULL:
- case LTC_ASN1_OBJECT_IDENTIFIER:
- case LTC_ASN1_IA5_STRING:
- case LTC_ASN1_PRINTABLE_STRING:
- case LTC_ASN1_UTF8_STRING:
- case LTC_ASN1_UTCTIME:
- case LTC_ASN1_SEQUENCE:
- case LTC_ASN1_SET:
- case LTC_ASN1_SETOF:
- case LTC_ASN1_CHOICE:
- list[x].type = type;
- list[x].size = size;
- list[x++].data = data;
- break;
-
- default:
- va_end(args);
- err = CRYPT_INVALID_ARG;
- goto LBL_ERR;
- }
- }
- va_end(args);
-
- err = der_decode_sequence(in, inlen, list, x);
-LBL_ERR:
- XFREE(list);
- return err;
-}
-
-#endif
-
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c,v $ */
-/* $Revision: 1.13 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c
deleted file mode 100644
index 907e4e1c3bb..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_decode_short_integer.c
- ASN.1 DER, decode an integer, Tom St Denis
-*/
-
-
-#ifdef LTC_DER
-
-/**
- Read a short integer
- @param in The DER encoded data
- @param inlen Size of data
- @param num [out] The integer to decode
- @return CRYPT_OK if successful
-*/
-int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num)
-{
- unsigned long len, x, y;
-
- LTC_ARGCHK(num != NULL);
- LTC_ARGCHK(in != NULL);
-
- /* check length */
- if (inlen < 2) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* check header */
- x = 0;
- if ((in[x++] & 0x1F) != 0x02) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* get the packet len */
- len = in[x++];
-
- if (x + len > inlen) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* read number */
- y = 0;
- while (len--) {
- y = (y<<8) | (unsigned long)in[x++];
- }
- *num = y;
-
- return CRYPT_OK;
-
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_decode_short_integer.c,v $ */
-/* $Revision: 1.7 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utctime.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utctime.c
deleted file mode 100644
index 7f3f0d76683..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utctime.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_decode_utctime.c
- ASN.1 DER, decode a UTCTIME, Tom St Denis
-*/
-
-#ifdef LTC_DER
-
-static int char_to_int(unsigned char x)
-{
- switch (x) {
- case '0': return 0;
- case '1': return 1;
- case '2': return 2;
- case '3': return 3;
- case '4': return 4;
- case '5': return 5;
- case '6': return 6;
- case '7': return 7;
- case '8': return 8;
- case '9': return 9;
- }
- return 100;
-}
-
-#define DECODE_V(y, max) \
- y = char_to_int(buf[x])*10 + char_to_int(buf[x+1]); \
- if (y >= max) return CRYPT_INVALID_PACKET; \
- x += 2;
-
-/**
- Decodes a UTC time structure in DER format (reads all 6 valid encoding formats)
- @param in Input buffer
- @param inlen Length of input buffer in octets
- @param out [out] Destination of UTC time structure
- @return CRYPT_OK if successful
-*/
-int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
- ltc_utctime *out)
-{
- unsigned char buf[32];
- unsigned long x;
- int y;
-
- LTC_ARGCHK(in != NULL);
- LTC_ARGCHK(inlen != NULL);
- LTC_ARGCHK(out != NULL);
-
- /* check header */
- if (*inlen < 2UL || (in[1] >= sizeof(buf)) || ((in[1] + 2UL) > *inlen)) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* decode the string */
- for (x = 0; x < in[1]; x++) {
- y = der_ia5_value_decode(in[x+2]);
- if (y == -1) {
- return CRYPT_INVALID_PACKET;
- }
- buf[x] = y;
- }
- *inlen = 2 + x;
-
-
- /* possible encodings are
-YYMMDDhhmmZ
-YYMMDDhhmm+hh'mm'
-YYMMDDhhmm-hh'mm'
-YYMMDDhhmmssZ
-YYMMDDhhmmss+hh'mm'
-YYMMDDhhmmss-hh'mm'
-
- So let's do a trivial decode upto [including] mm
- */
-
- x = 0;
- DECODE_V(out->YY, 100);
- DECODE_V(out->MM, 13);
- DECODE_V(out->DD, 32);
- DECODE_V(out->hh, 24);
- DECODE_V(out->mm, 60);
-
- /* clear timezone and seconds info */
- out->off_dir = out->off_hh = out->off_mm = out->ss = 0;
-
- /* now is it Z, +, - or 0-9 */
- if (buf[x] == 'Z') {
- return CRYPT_OK;
- } else if (buf[x] == '+' || buf[x] == '-') {
- out->off_dir = (buf[x++] == '+') ? 0 : 1;
- DECODE_V(out->off_hh, 24);
- DECODE_V(out->off_mm, 60);
- return CRYPT_OK;
- }
-
- /* decode seconds */
- DECODE_V(out->ss, 60);
-
- /* now is it Z, +, - */
- if (buf[x] == 'Z') {
- return CRYPT_OK;
- } else if (buf[x] == '+' || buf[x] == '-') {
- out->off_dir = (buf[x++] == '+') ? 0 : 1;
- DECODE_V(out->off_hh, 24);
- DECODE_V(out->off_mm, 60);
- return CRYPT_OK;
- } else {
- return CRYPT_INVALID_PACKET;
- }
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c,v $ */
-/* $Revision: 1.9 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c
deleted file mode 100644
index 898d6cd2a76..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_decode_utf8_string.c
- ASN.1 DER, encode a UTF8 STRING, Tom St Denis
-*/
-
-
-#ifdef LTC_DER
-
-/**
- Store a UTF8 STRING
- @param in The DER encoded UTF8 STRING
- @param inlen The size of the DER UTF8 STRING
- @param out [out] The array of utf8s stored (one per char)
- @param outlen [in/out] The number of utf8s stored
- @return CRYPT_OK if successful
-*/
-int der_decode_utf8_string(const unsigned char *in, unsigned long inlen,
- wchar_t *out, unsigned long *outlen)
-{
- wchar_t tmp;
- unsigned long x, y, z, len;
-
- LTC_ARGCHK(in != NULL);
- LTC_ARGCHK(out != NULL);
- LTC_ARGCHK(outlen != NULL);
-
- /* must have header at least */
- if (inlen < 2) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* check for 0x0C */
- if ((in[0] & 0x1F) != 0x0C) {
- return CRYPT_INVALID_PACKET;
- }
- x = 1;
-
- /* decode the length */
- if (in[x] & 0x80) {
- /* valid # of bytes in length are 1,2,3 */
- y = in[x] & 0x7F;
- if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* read the length in */
- len = 0;
- ++x;
- while (y--) {
- len = (len << 8) | in[x++];
- }
- } else {
- len = in[x++] & 0x7F;
- }
-
- if (len + x > inlen) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* proceed to decode */
- for (y = 0; x < inlen; ) {
- /* get first byte */
- tmp = in[x++];
-
- /* count number of bytes */
- for (z = 0; (tmp & 0x80) && (z <= 4); z++, tmp = (tmp << 1) & 0xFF);
-
- if (z > 4 || (x + (z - 1) > inlen)) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* decode, grab upper bits */
- tmp >>= z;
-
- /* grab remaining bytes */
- if (z > 1) { --z; }
- while (z-- != 0) {
- if ((in[x] & 0xC0) != 0x80) {
- return CRYPT_INVALID_PACKET;
- }
- tmp = (tmp << 6) | ((wchar_t)in[x++] & 0x3F);
- }
-
- if (y > *outlen) {
- *outlen = y;
- return CRYPT_BUFFER_OVERFLOW;
- }
- out[y++] = tmp;
- }
- *outlen = y;
-
- return CRYPT_OK;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utf8/der_decode_utf8_string.c,v $ */
-/* $Revision: 1.8 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_bit_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_bit_string.c
deleted file mode 100644
index 2bffa3b6341..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_bit_string.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_length_bit_string.c
- ASN.1 DER, get length of BIT STRING, Tom St Denis
-*/
-
-#ifdef LTC_DER
-/**
- Gets length of DER encoding of BIT STRING
- @param nbits The number of bits in the string to encode
- @param outlen [out] The length of the DER encoding for the given string
- @return CRYPT_OK if successful
-*/
-int der_length_bit_string(unsigned long nbits, unsigned long *outlen)
-{
- unsigned long nbytes;
- LTC_ARGCHK(outlen != NULL);
-
- /* get the number of the bytes */
- nbytes = (nbits >> 3) + ((nbits & 7) ? 1 : 0) + 1;
-
- if (nbytes < 128) {
- /* 03 LL PP DD DD DD ... */
- *outlen = 2 + nbytes;
- } else if (nbytes < 256) {
- /* 03 81 LL PP DD DD DD ... */
- *outlen = 3 + nbytes;
- } else if (nbytes < 65536) {
- /* 03 82 LL LL PP DD DD DD ... */
- *outlen = 4 + nbytes;
- } else {
- return CRYPT_INVALID_ARG;
- }
-
- return CRYPT_OK;
-}
-
-#endif
-
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_length_bit_string.c,v $ */
-/* $Revision: 1.3 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_boolean.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_boolean.c
deleted file mode 100644
index e34ce5c65d8..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_boolean.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_length_boolean.c
- ASN.1 DER, get length of a BOOLEAN, Tom St Denis
-*/
-
-#ifdef LTC_DER
-/**
- Gets length of DER encoding of a BOOLEAN
- @param outlen [out] The length of the DER encoding
- @return CRYPT_OK if successful
-*/
-int der_length_boolean(unsigned long *outlen)
-{
- LTC_ARGCHK(outlen != NULL);
- *outlen = 3;
- return CRYPT_OK;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/boolean/der_length_boolean.c,v $ */
-/* $Revision: 1.3 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c
deleted file mode 100644
index 473bc793257..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_length_ia5_string.c
- ASN.1 DER, get length of IA5 STRING, Tom St Denis
-*/
-
-#ifdef LTC_DER
-
-static const struct {
- int code, value;
-} ia5_table[] = {
-{ '\0', 0 },
-{ '\a', 7 },
-{ '\b', 8 },
-{ '\t', 9 },
-{ '\n', 10 },
-{ '\f', 12 },
-{ '\r', 13 },
-{ ' ', 32 },
-{ '!', 33 },
-{ '"', 34 },
-{ '#', 35 },
-{ '$', 36 },
-{ '%', 37 },
-{ '&', 38 },
-{ '\'', 39 },
-{ '(', 40 },
-{ ')', 41 },
-{ '*', 42 },
-{ '+', 43 },
-{ ',', 44 },
-{ '-', 45 },
-{ '.', 46 },
-{ '/', 47 },
-{ '0', 48 },
-{ '1', 49 },
-{ '2', 50 },
-{ '3', 51 },
-{ '4', 52 },
-{ '5', 53 },
-{ '6', 54 },
-{ '7', 55 },
-{ '8', 56 },
-{ '9', 57 },
-{ ':', 58 },
-{ ';', 59 },
-{ '<', 60 },
-{ '=', 61 },
-{ '>', 62 },
-{ '?', 63 },
-{ '@', 64 },
-{ 'A', 65 },
-{ 'B', 66 },
-{ 'C', 67 },
-{ 'D', 68 },
-{ 'E', 69 },
-{ 'F', 70 },
-{ 'G', 71 },
-{ 'H', 72 },
-{ 'I', 73 },
-{ 'J', 74 },
-{ 'K', 75 },
-{ 'L', 76 },
-{ 'M', 77 },
-{ 'N', 78 },
-{ 'O', 79 },
-{ 'P', 80 },
-{ 'Q', 81 },
-{ 'R', 82 },
-{ 'S', 83 },
-{ 'T', 84 },
-{ 'U', 85 },
-{ 'V', 86 },
-{ 'W', 87 },
-{ 'X', 88 },
-{ 'Y', 89 },
-{ 'Z', 90 },
-{ '[', 91 },
-{ '\\', 92 },
-{ ']', 93 },
-{ '^', 94 },
-{ '_', 95 },
-{ '`', 96 },
-{ 'a', 97 },
-{ 'b', 98 },
-{ 'c', 99 },
-{ 'd', 100 },
-{ 'e', 101 },
-{ 'f', 102 },
-{ 'g', 103 },
-{ 'h', 104 },
-{ 'i', 105 },
-{ 'j', 106 },
-{ 'k', 107 },
-{ 'l', 108 },
-{ 'm', 109 },
-{ 'n', 110 },
-{ 'o', 111 },
-{ 'p', 112 },
-{ 'q', 113 },
-{ 'r', 114 },
-{ 's', 115 },
-{ 't', 116 },
-{ 'u', 117 },
-{ 'v', 118 },
-{ 'w', 119 },
-{ 'x', 120 },
-{ 'y', 121 },
-{ 'z', 122 },
-{ '{', 123 },
-{ '|', 124 },
-{ '}', 125 },
-{ '~', 126 }
-};
-
-int der_ia5_char_encode(int c)
-{
- int x;
- for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) {
- if (ia5_table[x].code == c) {
- return ia5_table[x].value;
- }
- }
- return -1;
-}
-
-int der_ia5_value_decode(int v)
-{
- int x;
- for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) {
- if (ia5_table[x].value == v) {
- return ia5_table[x].code;
- }
- }
- return -1;
-}
-
-/**
- Gets length of DER encoding of IA5 STRING
- @param octets The values you want to encode
- @param noctets The number of octets in the string to encode
- @param outlen [out] The length of the DER encoding for the given string
- @return CRYPT_OK if successful
-*/
-int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen)
-{
- unsigned long x;
-
- LTC_ARGCHK(outlen != NULL);
- LTC_ARGCHK(octets != NULL);
-
- /* scan string for validity */
- for (x = 0; x < noctets; x++) {
- if (der_ia5_char_encode(octets[x]) == -1) {
- return CRYPT_INVALID_ARG;
- }
- }
-
- if (noctets < 128) {
- /* 16 LL DD DD DD ... */
- *outlen = 2 + noctets;
- } else if (noctets < 256) {
- /* 16 81 LL DD DD DD ... */
- *outlen = 3 + noctets;
- } else if (noctets < 65536UL) {
- /* 16 82 LL LL DD DD DD ... */
- *outlen = 4 + noctets;
- } else if (noctets < 16777216UL) {
- /* 16 83 LL LL LL DD DD DD ... */
- *outlen = 5 + noctets;
- } else {
- return CRYPT_INVALID_ARG;
- }
-
- return CRYPT_OK;
-}
-
-#endif
-
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_length_ia5_string.c,v $ */
-/* $Revision: 1.3 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_integer.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_integer.c
deleted file mode 100644
index 540d205f028..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_integer.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_length_integer.c
- ASN.1 DER, get length of encoding, Tom St Denis
-*/
-
-
-#ifdef LTC_DER
-/**
- Gets length of DER encoding of num
- @param num The int to get the size of
- @param outlen [out] The length of the DER encoding for the given integer
- @return CRYPT_OK if successful
-*/
-int der_length_integer(void *num, unsigned long *outlen)
-{
- unsigned long z, len;
- int leading_zero;
-
- LTC_ARGCHK(num != NULL);
- LTC_ARGCHK(outlen != NULL);
-
- if (mp_cmp_d(num, 0) != LTC_MP_LT) {
- /* positive */
-
- /* we only need a leading zero if the msb of the first byte is one */
- if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) {
- leading_zero = 1;
- } else {
- leading_zero = 0;
- }
-
- /* size for bignum */
- z = len = leading_zero + mp_unsigned_bin_size(num);
- } else {
- /* it's negative */
- /* find power of 2 that is a multiple of eight and greater than count bits */
- leading_zero = 0;
- z = mp_count_bits(num);
- z = z + (8 - (z & 7));
- if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --z;
- len = z = z >> 3;
- }
-
- /* now we need a length */
- if (z < 128) {
- /* short form */
- ++len;
- } else {
- /* long form (relies on z != 0), assumes length bytes < 128 */
- ++len;
-
- while (z) {
- ++len;
- z >>= 8;
- }
- }
-
- /* we need a 0x02 to indicate it's INTEGER */
- ++len;
-
- /* return length */
- *outlen = len;
- return CRYPT_OK;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c,v $ */
-/* $Revision: 1.5 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c
deleted file mode 100644
index 94c326f7cac..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_length_object_identifier.c
- ASN.1 DER, get length of Object Identifier, Tom St Denis
-*/
-
-#ifdef LTC_DER
-
-unsigned long der_object_identifier_bits(unsigned long x)
-{
- unsigned long c;
- x &= 0xFFFFFFFF;
- c = 0;
- while (x) {
- ++c;
- x >>= 1;
- }
- return c;
-}
-
-
-/**
- Gets length of DER encoding of Object Identifier
- @param nwords The number of OID words
- @param words The actual OID words to get the size of
- @param outlen [out] The length of the DER encoding for the given string
- @return CRYPT_OK if successful
-*/
-int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen)
-{
- unsigned long y, z, t, wordbuf;
-
- LTC_ARGCHK(words != NULL);
- LTC_ARGCHK(outlen != NULL);
-
-
- /* must be >= 2 words */
- if (nwords < 2) {
- return CRYPT_INVALID_ARG;
- }
-
- /* word1 = 0,1,2,3 and word2 0..39 */
- if (words[0] > 3 || (words[0] < 2 && words[1] > 39)) {
- return CRYPT_INVALID_ARG;
- }
-
- /* leading word is the first two */
- z = 0;
- wordbuf = words[0] * 40 + words[1];
- for (y = 1; y < nwords; y++) {
- t = der_object_identifier_bits(wordbuf);
- z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0);
- if (y < nwords - 1) {
- /* grab next word */
- wordbuf = words[y+1];
- }
- }
-
- /* now depending on the length our length encoding changes */
- if (z < 128) {
- z += 2;
- } else if (z < 256) {
- z += 3;
- } else if (z < 65536UL) {
- z += 4;
- } else {
- return CRYPT_INVALID_ARG;
- }
-
- *outlen = z;
- return CRYPT_OK;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_length_object_identifier.c,v $ */
-/* $Revision: 1.5 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_octet_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_octet_string.c
deleted file mode 100644
index acd4053c16a..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_octet_string.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_length_octet_string.c
- ASN.1 DER, get length of OCTET STRING, Tom St Denis
-*/
-
-#ifdef LTC_DER
-/**
- Gets length of DER encoding of OCTET STRING
- @param noctets The number of octets in the string to encode
- @param outlen [out] The length of the DER encoding for the given string
- @return CRYPT_OK if successful
-*/
-int der_length_octet_string(unsigned long noctets, unsigned long *outlen)
-{
- LTC_ARGCHK(outlen != NULL);
-
- if (noctets < 128) {
- /* 04 LL DD DD DD ... */
- *outlen = 2 + noctets;
- } else if (noctets < 256) {
- /* 04 81 LL DD DD DD ... */
- *outlen = 3 + noctets;
- } else if (noctets < 65536UL) {
- /* 04 82 LL LL DD DD DD ... */
- *outlen = 4 + noctets;
- } else if (noctets < 16777216UL) {
- /* 04 83 LL LL LL DD DD DD ... */
- *outlen = 5 + noctets;
- } else {
- return CRYPT_INVALID_ARG;
- }
-
- return CRYPT_OK;
-}
-
-#endif
-
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_length_octet_string.c,v $ */
-/* $Revision: 1.3 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_printable_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_printable_string.c
deleted file mode 100644
index ef1ed0ede37..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_printable_string.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_length_printable_string.c
- ASN.1 DER, get length of Printable STRING, Tom St Denis
-*/
-
-#ifdef LTC_DER
-
-static const struct {
- int code, value;
-} printable_table[] = {
-{ ' ', 32 },
-{ '\'', 39 },
-{ '(', 40 },
-{ ')', 41 },
-{ '+', 43 },
-{ ',', 44 },
-{ '-', 45 },
-{ '.', 46 },
-{ '/', 47 },
-{ '0', 48 },
-{ '1', 49 },
-{ '2', 50 },
-{ '3', 51 },
-{ '4', 52 },
-{ '5', 53 },
-{ '6', 54 },
-{ '7', 55 },
-{ '8', 56 },
-{ '9', 57 },
-{ ':', 58 },
-{ '=', 61 },
-{ '?', 63 },
-{ 'A', 65 },
-{ 'B', 66 },
-{ 'C', 67 },
-{ 'D', 68 },
-{ 'E', 69 },
-{ 'F', 70 },
-{ 'G', 71 },
-{ 'H', 72 },
-{ 'I', 73 },
-{ 'J', 74 },
-{ 'K', 75 },
-{ 'L', 76 },
-{ 'M', 77 },
-{ 'N', 78 },
-{ 'O', 79 },
-{ 'P', 80 },
-{ 'Q', 81 },
-{ 'R', 82 },
-{ 'S', 83 },
-{ 'T', 84 },
-{ 'U', 85 },
-{ 'V', 86 },
-{ 'W', 87 },
-{ 'X', 88 },
-{ 'Y', 89 },
-{ 'Z', 90 },
-{ 'a', 97 },
-{ 'b', 98 },
-{ 'c', 99 },
-{ 'd', 100 },
-{ 'e', 101 },
-{ 'f', 102 },
-{ 'g', 103 },
-{ 'h', 104 },
-{ 'i', 105 },
-{ 'j', 106 },
-{ 'k', 107 },
-{ 'l', 108 },
-{ 'm', 109 },
-{ 'n', 110 },
-{ 'o', 111 },
-{ 'p', 112 },
-{ 'q', 113 },
-{ 'r', 114 },
-{ 's', 115 },
-{ 't', 116 },
-{ 'u', 117 },
-{ 'v', 118 },
-{ 'w', 119 },
-{ 'x', 120 },
-{ 'y', 121 },
-{ 'z', 122 },
-};
-
-int der_printable_char_encode(int c)
-{
- int x;
- for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) {
- if (printable_table[x].code == c) {
- return printable_table[x].value;
- }
- }
- return -1;
-}
-
-int der_printable_value_decode(int v)
-{
- int x;
- for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) {
- if (printable_table[x].value == v) {
- return printable_table[x].code;
- }
- }
- return -1;
-}
-
-/**
- Gets length of DER encoding of Printable STRING
- @param octets The values you want to encode
- @param noctets The number of octets in the string to encode
- @param outlen [out] The length of the DER encoding for the given string
- @return CRYPT_OK if successful
-*/
-int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen)
-{
- unsigned long x;
-
- LTC_ARGCHK(outlen != NULL);
- LTC_ARGCHK(octets != NULL);
-
- /* scan string for validity */
- for (x = 0; x < noctets; x++) {
- if (der_printable_char_encode(octets[x]) == -1) {
- return CRYPT_INVALID_ARG;
- }
- }
-
- if (noctets < 128) {
- /* 16 LL DD DD DD ... */
- *outlen = 2 + noctets;
- } else if (noctets < 256) {
- /* 16 81 LL DD DD DD ... */
- *outlen = 3 + noctets;
- } else if (noctets < 65536UL) {
- /* 16 82 LL LL DD DD DD ... */
- *outlen = 4 + noctets;
- } else if (noctets < 16777216UL) {
- /* 16 83 LL LL LL DD DD DD ... */
- *outlen = 5 + noctets;
- } else {
- return CRYPT_INVALID_ARG;
- }
-
- return CRYPT_OK;
-}
-
-#endif
-
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_length_printable_string.c,v $ */
-/* $Revision: 1.3 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_sequence.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_sequence.c
deleted file mode 100644
index e75ed7e7eeb..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_sequence.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_length_sequence.c
- ASN.1 DER, length a SEQUENCE, Tom St Denis
-*/
-
-#ifdef LTC_DER
-
-/**
- Get the length of a DER sequence
- @param list The sequences of items in the SEQUENCE
- @param inlen The number of items
- @param outlen [out] The length required in octets to store it
- @return CRYPT_OK on success
-*/
-int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
- unsigned long *outlen)
-{
- int err, type;
- unsigned long size, x, y, z, i;
- void *data;
-
- LTC_ARGCHK(list != NULL);
- LTC_ARGCHK(outlen != NULL);
-
- /* get size of output that will be required */
- y = 0;
- for (i = 0; i < inlen; i++) {
- type = list[i].type;
- size = list[i].size;
- data = list[i].data;
-
- if (type == LTC_ASN1_EOL) {
- break;
- }
-
- switch (type) {
- case LTC_ASN1_BOOLEAN:
- if ((err = der_length_boolean(&x)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- y += x;
- break;
-
- case LTC_ASN1_INTEGER:
- if ((err = der_length_integer(data, &x)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- y += x;
- break;
-
- case LTC_ASN1_SHORT_INTEGER:
- if ((err = der_length_short_integer(*((unsigned long *)data), &x)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- y += x;
- break;
-
- case LTC_ASN1_BIT_STRING:
- if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- y += x;
- break;
-
- case LTC_ASN1_OCTET_STRING:
- if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- y += x;
- break;
-
- case LTC_ASN1_NULL:
- y += 2;
- break;
-
- case LTC_ASN1_OBJECT_IDENTIFIER:
- if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- y += x;
- break;
-
- case LTC_ASN1_IA5_STRING:
- if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- y += x;
- break;
-
- case LTC_ASN1_PRINTABLE_STRING:
- if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- y += x;
- break;
-
- case LTC_ASN1_UTCTIME:
- if ((err = der_length_utctime(data, &x)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- y += x;
- break;
-
- case LTC_ASN1_UTF8_STRING:
- if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- y += x;
- break;
-
- case LTC_ASN1_SET:
- case LTC_ASN1_SETOF:
- case LTC_ASN1_SEQUENCE:
- if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- y += x;
- break;
-
-
- default:
- err = CRYPT_INVALID_ARG;
- goto LBL_ERR;
- }
- }
-
- /* calc header size */
- z = y;
- if (y < 128) {
- y += 2;
- } else if (y < 256) {
- /* 0x30 0x81 LL */
- y += 3;
- } else if (y < 65536UL) {
- /* 0x30 0x82 LL LL */
- y += 4;
- } else if (y < 16777216UL) {
- /* 0x30 0x83 LL LL LL */
- y += 5;
- } else {
- err = CRYPT_INVALID_ARG;
- goto LBL_ERR;
- }
-
- /* store size */
- *outlen = y;
- err = CRYPT_OK;
-
-LBL_ERR:
- return err;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_length_sequence.c,v $ */
-/* $Revision: 1.14 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_short_integer.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_short_integer.c
deleted file mode 100644
index afa6dd0ee61..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_short_integer.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_length_short_integer.c
- ASN.1 DER, get length of encoding, Tom St Denis
-*/
-
-
-#ifdef LTC_DER
-/**
- Gets length of DER encoding of num
- @param num The integer to get the size of
- @param outlen [out] The length of the DER encoding for the given integer
- @return CRYPT_OK if successful
-*/
-int der_length_short_integer(unsigned long num, unsigned long *outlen)
-{
- unsigned long z, y, len;
-
- LTC_ARGCHK(outlen != NULL);
-
- /* force to 32 bits */
- num &= 0xFFFFFFFFUL;
-
- /* get the number of bytes */
- z = 0;
- y = num;
- while (y) {
- ++z;
- y >>= 8;
- }
-
- /* handle zero */
- if (z == 0) {
- z = 1;
- }
-
- /* we need a 0x02 to indicate it's INTEGER */
- len = 1;
-
- /* length byte */
- ++len;
-
- /* bytes in value */
- len += z;
-
- /* see if msb is set */
- len += (num&(1UL<<((z<<3) - 1))) ? 1 : 0;
-
- /* return length */
- *outlen = len;
-
- return CRYPT_OK;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_length_short_integer.c,v $ */
-/* $Revision: 1.6 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utctime.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utctime.c
deleted file mode 100644
index 1296babbadf..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utctime.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_length_utctime.c
- ASN.1 DER, get length of UTCTIME, Tom St Denis
-*/
-
-#ifdef LTC_DER
-
-/**
- Gets length of DER encoding of UTCTIME
- @param utctime The UTC time structure to get the size of
- @param outlen [out] The length of the DER encoding
- @return CRYPT_OK if successful
-*/
-int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen)
-{
- LTC_ARGCHK(outlen != NULL);
- LTC_ARGCHK(utctime != NULL);
-
- if (utctime->off_hh == 0 && utctime->off_mm == 0) {
- /* we encode as YYMMDDhhmmssZ */
- *outlen = 2 + 13;
- } else {
- /* we encode as YYMMDDhhmmss{+|-}hh'mm' */
- *outlen = 2 + 17;
- }
-
- return CRYPT_OK;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c,v $ */
-/* $Revision: 1.5 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c
deleted file mode 100644
index 514db8450ef..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_length_utf8_string.c
- ASN.1 DER, get length of UTF8 STRING, Tom St Denis
-*/
-
-#ifdef LTC_DER
-
-/** Return the size in bytes of a UTF-8 character
- @param c The UTF-8 character to measure
- @return The size in bytes
-*/
-unsigned long der_utf8_charsize(const wchar_t c)
-{
- if (c <= 0x7F) {
- return 1;
- } else if (c <= 0x7FF) {
- return 2;
- } else if (c <= 0xFFFF) {
- return 3;
- } else {
- return 4;
- }
-}
-
-/**
- Gets length of DER encoding of UTF8 STRING
- @param in The characters to measure the length of
- @param noctets The number of octets in the string to encode
- @param outlen [out] The length of the DER encoding for the given string
- @return CRYPT_OK if successful
-*/
-int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen)
-{
- unsigned long x, len;
-
- LTC_ARGCHK(in != NULL);
- LTC_ARGCHK(outlen != NULL);
-
- len = 0;
- for (x = 0; x < noctets; x++) {
- if (in[x] < 0 || in[x] > 0x10FFFF) {
- return CRYPT_INVALID_ARG;
- }
- len += der_utf8_charsize(in[x]);
- }
-
- if (len < 128) {
- /* 0C LL DD DD DD ... */
- *outlen = 2 + len;
- } else if (len < 256) {
- /* 0C 81 LL DD DD DD ... */
- *outlen = 3 + len;
- } else if (len < 65536UL) {
- /* 0C 82 LL LL DD DD DD ... */
- *outlen = 4 + len;
- } else if (len < 16777216UL) {
- /* 0C 83 LL LL LL DD DD DD ... */
- *outlen = 5 + len;
- } else {
- return CRYPT_INVALID_ARG;
- }
-
- return CRYPT_OK;
-}
-
-#endif
-
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utf8/der_length_utf8_string.c,v $ */
-/* $Revision: 1.6 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_sequence_free.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_sequence_free.c
deleted file mode 100644
index 4887215397f..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_sequence_free.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file der_sequence_free.c
- ASN.1 DER, free's a structure allocated by der_decode_sequence_flexi(), Tom St Denis
-*/
-
-#ifdef LTC_DER
-
-/**
- Free memory allocated by der_decode_sequence_flexi()
- @param in The list to free
-*/
-void der_sequence_free(ltc_asn1_list *in)
-{
- ltc_asn1_list *l;
-
- /* walk to the start of the chain */
- while (in->prev != NULL || in->parent != NULL) {
- if (in->parent != NULL) {
- in = in->parent;
- } else {
- in = in->prev;
- }
- }
-
- /* now walk the list and free stuff */
- while (in != NULL) {
- /* is there a child? */
- if (in->child) {
- /* disconnect */
- in->child->parent = NULL;
- der_sequence_free(in->child);
- }
-
- switch (in->type) {
- case LTC_ASN1_SET:
- case LTC_ASN1_SETOF:
- case LTC_ASN1_SEQUENCE: break;
- case LTC_ASN1_INTEGER : if (in->data != NULL) { mp_clear(in->data); } break;
- default : if (in->data != NULL) { XFREE(in->data); }
- }
-
- /* move to next and free current */
- l = in->next;
- free(in);
- in = l;
- }
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_sequence_free.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:27:24 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c b/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c
deleted file mode 100644
index 5a1324c4986..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
- *
- * All curves taken from NIST recommendation paper of July 1999
- * Available at http://csrc.nist.gov/cryptval/dss.htm
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file ltc_ecc_map.c
- ECC Crypto, Tom St Denis
-*/
-
-#ifdef LTC_MECC
-
-/**
- Map a projective jacbobian point back to affine space
- @param P [in/out] The point to map
- @param modulus The modulus of the field the ECC curve is in
- @param mp The "b" value from montgomery_setup()
- @return CRYPT_OK on success
-*/
-int ltc_ecc_map(ecc_point *P, void *modulus, void *mp)
-{
- void *t1, *t2;
- int err;
-
- LTC_ARGCHK(P != NULL);
- LTC_ARGCHK(modulus != NULL);
- LTC_ARGCHK(mp != NULL);
-
- if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) {
- return CRYPT_MEM;
- }
-
- /* first map z back to normal */
- if ((err = mp_montgomery_reduce(P->z, modulus, mp)) != CRYPT_OK) { goto done; }
-
- /* get 1/z */
- if ((err = mp_invmod(P->z, modulus, t1)) != CRYPT_OK) { goto done; }
-
- /* get 1/z^2 and 1/z^3 */
- if ((err = mp_sqr(t1, t2)) != CRYPT_OK) { goto done; }
- if ((err = mp_mod(t2, modulus, t2)) != CRYPT_OK) { goto done; }
- if ((err = mp_mul(t1, t2, t1)) != CRYPT_OK) { goto done; }
- if ((err = mp_mod(t1, modulus, t1)) != CRYPT_OK) { goto done; }
-
- /* multiply against x/y */
- if ((err = mp_mul(P->x, t2, P->x)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(P->x, modulus, mp)) != CRYPT_OK) { goto done; }
- if ((err = mp_mul(P->y, t1, P->y)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(P->y, modulus, mp)) != CRYPT_OK) { goto done; }
- if ((err = mp_set(P->z, 1)) != CRYPT_OK) { goto done; }
-
- err = CRYPT_OK;
-done:
- mp_clear_multi(t1, t2, NULL);
- return err;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_map.c,v $ */
-/* $Revision: 1.7 $ */
-/* $Date: 2007/05/12 14:32:35 $ */
-
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c b/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c
deleted file mode 100644
index 2c468eaafa1..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
- *
- * All curves taken from NIST recommendation paper of July 1999
- * Available at http://csrc.nist.gov/cryptval/dss.htm
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file ltc_ecc_mul2add.c
- ECC Crypto, Shamir's Trick, Tom St Denis
-*/
-
-#ifdef LTC_MECC
-
-#ifdef LTC_ECC_SHAMIR
-
-/** Computes kA*A + kB*B = C using Shamir's Trick
- @param A First point to multiply
- @param kA What to multiple A by
- @param B Second point to multiply
- @param kB What to multiple B by
- @param C [out] Destination point (can overlap with A or B
- @param modulus Modulus for curve
- @return CRYPT_OK on success
-*/
-int ltc_ecc_mul2add(ecc_point *A, void *kA,
- ecc_point *B, void *kB,
- ecc_point *C,
- void *modulus)
-{
- ecc_point *precomp[16];
- unsigned bitbufA, bitbufB, lenA, lenB, len, x, y, nA, nB, nibble;
- unsigned char *tA, *tB;
- int err, first;
- void *mp, *mu;
-
- /* argchks */
- LTC_ARGCHK(A != NULL);
- LTC_ARGCHK(B != NULL);
- LTC_ARGCHK(C != NULL);
- LTC_ARGCHK(kA != NULL);
- LTC_ARGCHK(kB != NULL);
- LTC_ARGCHK(modulus != NULL);
-
- /* allocate memory */
- tA = XCALLOC(1, ECC_BUF_SIZE);
- if (tA == NULL) {
- return CRYPT_MEM;
- }
- tB = XCALLOC(1, ECC_BUF_SIZE);
- if (tB == NULL) {
- XFREE(tA);
- return CRYPT_MEM;
- }
-
- /* get sizes */
- lenA = mp_unsigned_bin_size(kA);
- lenB = mp_unsigned_bin_size(kB);
- len = MAX(lenA, lenB);
-
- /* sanity check */
- if ((lenA > ECC_BUF_SIZE) || (lenB > ECC_BUF_SIZE)) {
- err = CRYPT_INVALID_ARG;
- goto ERR_T;
- }
-
- /* extract and justify kA */
- mp_to_unsigned_bin(kA, (len - lenA) + tA);
-
- /* extract and justify kB */
- mp_to_unsigned_bin(kB, (len - lenB) + tB);
-
- /* allocate the table */
- for (x = 0; x < 16; x++) {
- precomp[x] = ltc_ecc_new_point();
- if (precomp[x] == NULL) {
- for (y = 0; y < x; ++y) {
- ltc_ecc_del_point(precomp[y]);
- }
- err = CRYPT_MEM;
- goto ERR_T;
- }
- }
-
- /* init montgomery reduction */
- if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) {
- goto ERR_P;
- }
- if ((err = mp_init(&mu)) != CRYPT_OK) {
- goto ERR_MP;
- }
- if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
- goto ERR_MU;
- }
-
- /* copy ones ... */
- if ((err = mp_mulmod(A->x, mu, modulus, precomp[1]->x)) != CRYPT_OK) { goto ERR_MU; }
- if ((err = mp_mulmod(A->y, mu, modulus, precomp[1]->y)) != CRYPT_OK) { goto ERR_MU; }
- if ((err = mp_mulmod(A->z, mu, modulus, precomp[1]->z)) != CRYPT_OK) { goto ERR_MU; }
-
- if ((err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x)) != CRYPT_OK) { goto ERR_MU; }
- if ((err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y)) != CRYPT_OK) { goto ERR_MU; }
- if ((err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z)) != CRYPT_OK) { goto ERR_MU; }
-
- /* precomp [i,0](A + B) table */
- if ((err = ltc_mp.ecc_ptdbl(precomp[1], precomp[2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
- if ((err = ltc_mp.ecc_ptadd(precomp[1], precomp[2], precomp[3], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
-
- /* precomp [0,i](A + B) table */
- if ((err = ltc_mp.ecc_ptdbl(precomp[1<<2], precomp[2<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
- if ((err = ltc_mp.ecc_ptadd(precomp[1<<2], precomp[2<<2], precomp[3<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
-
- /* precomp [i,j](A + B) table (i != 0, j != 0) */
- for (x = 1; x < 4; x++) {
- for (y = 1; y < 4; y++) {
- if ((err = ltc_mp.ecc_ptadd(precomp[x], precomp[(y<<2)], precomp[x+(y<<2)], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
- }
- }
-
- nibble = 3;
- first = 1;
- bitbufA = tA[0];
- bitbufB = tB[0];
-
- /* for every byte of the multiplicands */
- for (x = -1;; ) {
- /* grab a nibble */
- if (++nibble == 4) {
- ++x; if (x == len) break;
- bitbufA = tA[x];
- bitbufB = tB[x];
- nibble = 0;
- }
-
- /* extract two bits from both, shift/update */
- nA = (bitbufA >> 6) & 0x03;
- nB = (bitbufB >> 6) & 0x03;
- bitbufA = (bitbufA << 2) & 0xFF;
- bitbufB = (bitbufB << 2) & 0xFF;
-
- /* if both zero, if first, continue */
- if ((nA == 0) && (nB == 0) && (first == 1)) {
- continue;
- }
-
- /* double twice, only if this isn't the first */
- if (first == 0) {
- /* double twice */
- if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
- if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
- }
-
- /* if not both zero */
- if ((nA != 0) || (nB != 0)) {
- if (first == 1) {
- /* if first, copy from table */
- first = 0;
- if ((err = mp_copy(precomp[nA + (nB<<2)]->x, C->x)) != CRYPT_OK) { goto ERR_MU; }
- if ((err = mp_copy(precomp[nA + (nB<<2)]->y, C->y)) != CRYPT_OK) { goto ERR_MU; }
- if ((err = mp_copy(precomp[nA + (nB<<2)]->z, C->z)) != CRYPT_OK) { goto ERR_MU; }
- } else {
- /* if not first, add from table */
- if ((err = ltc_mp.ecc_ptadd(C, precomp[nA + (nB<<2)], C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
- }
- }
- }
-
- /* reduce to affine */
- err = ltc_ecc_map(C, modulus, mp);
-
- /* clean up */
-ERR_MU:
- mp_clear(mu);
-ERR_MP:
- mp_montgomery_free(mp);
-ERR_P:
- for (x = 0; x < 16; x++) {
- ltc_ecc_del_point(precomp[x]);
- }
-ERR_T:
-#ifdef LTC_CLEAN_STACK
- zeromem(tA, ECC_BUF_SIZE);
- zeromem(tB, ECC_BUF_SIZE);
-#endif
- XFREE(tA);
- XFREE(tB);
-
- return err;
-}
-
-#endif
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c,v $ */
-/* $Revision: 1.8 $ */
-/* $Date: 2007/05/12 14:32:35 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c b/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c
deleted file mode 100644
index f9d0cad832d..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
- *
- * All curves taken from NIST recommendation paper of July 1999
- * Available at http://csrc.nist.gov/cryptval/dss.htm
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file ltc_ecc_mulmod.c
- ECC Crypto, Tom St Denis
-*/
-
-#ifdef LTC_MECC
-#ifndef LTC_ECC_TIMING_RESISTANT
-
-/* size of sliding window, don't change this! */
-#define WINSIZE 4
-
-/**
- Perform a point multiplication
- @param k The scalar to multiply by
- @param G The base point
- @param R [out] Destination for kG
- @param modulus The modulus of the field the ECC curve is in
- @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective)
- @return CRYPT_OK on success
-*/
-int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
-{
- ecc_point *tG, *M[8];
- int i, j, err;
- void *mu, *mp;
- unsigned long buf;
- int first, bitbuf, bitcpy, bitcnt, mode, digidx;
-
- LTC_ARGCHK(k != NULL);
- LTC_ARGCHK(G != NULL);
- LTC_ARGCHK(R != NULL);
- LTC_ARGCHK(modulus != NULL);
-
- /* init montgomery reduction */
- if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) {
- return err;
- }
- if ((err = mp_init(&mu)) != CRYPT_OK) {
- mp_montgomery_free(mp);
- return err;
- }
- if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
- mp_montgomery_free(mp);
- mp_clear(mu);
- return err;
- }
-
- /* alloc ram for window temps */
- for (i = 0; i < 8; i++) {
- M[i] = ltc_ecc_new_point();
- if (M[i] == NULL) {
- for (j = 0; j < i; j++) {
- ltc_ecc_del_point(M[j]);
- }
- mp_montgomery_free(mp);
- mp_clear(mu);
- return CRYPT_MEM;
- }
- }
-
- /* make a copy of G incase R==G */
- tG = ltc_ecc_new_point();
- if (tG == NULL) { err = CRYPT_MEM; goto done; }
-
- /* tG = G and convert to montgomery */
- if (mp_cmp_d(mu, 1) == LTC_MP_EQ) {
- if ((err = mp_copy(G->x, tG->x)) != CRYPT_OK) { goto done; }
- if ((err = mp_copy(G->y, tG->y)) != CRYPT_OK) { goto done; }
- if ((err = mp_copy(G->z, tG->z)) != CRYPT_OK) { goto done; }
- } else {
- if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK) { goto done; }
- if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK) { goto done; }
- if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK) { goto done; }
- }
- mp_clear(mu);
- mu = NULL;
-
- /* calc the M tab, which holds kG for k==8..15 */
- /* M[0] == 8G */
- if ((err = ltc_mp.ecc_ptdbl(tG, M[0], modulus, mp)) != CRYPT_OK) { goto done; }
- if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; }
- if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; }
-
- /* now find (8+k)G for k=1..7 */
- for (j = 9; j < 16; j++) {
- if ((err = ltc_mp.ecc_ptadd(M[j-9], tG, M[j-8], modulus, mp)) != CRYPT_OK) { goto done; }
- }
-
- /* setup sliding window */
- mode = 0;
- bitcnt = 1;
- buf = 0;
- digidx = mp_get_digit_count(k) - 1;
- bitcpy = bitbuf = 0;
- first = 1;
-
- /* perform ops */
- for (;;) {
- /* grab next digit as required */
- if (--bitcnt == 0) {
- if (digidx == -1) {
- break;
- }
- buf = mp_get_digit(k, digidx);
- bitcnt = (int) ltc_mp.bits_per_digit;
- --digidx;
- }
-
- /* grab the next msb from the ltiplicand */
- i = (buf >> (ltc_mp.bits_per_digit - 1)) & 1;
- buf <<= 1;
-
- /* skip leading zero bits */
- if (mode == 0 && i == 0) {
- continue;
- }
-
- /* if the bit is zero and mode == 1 then we double */
- if (mode == 1 && i == 0) {
- if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; }
- continue;
- }
-
- /* else we add it to the window */
- bitbuf |= (i << (WINSIZE - ++bitcpy));
- mode = 2;
-
- if (bitcpy == WINSIZE) {
- /* if this is the first window we do a simple copy */
- if (first == 1) {
- /* R = kG [k = first window] */
- if ((err = mp_copy(M[bitbuf-8]->x, R->x)) != CRYPT_OK) { goto done; }
- if ((err = mp_copy(M[bitbuf-8]->y, R->y)) != CRYPT_OK) { goto done; }
- if ((err = mp_copy(M[bitbuf-8]->z, R->z)) != CRYPT_OK) { goto done; }
- first = 0;
- } else {
- /* normal window */
- /* ok window is filled so double as required and add */
- /* double first */
- for (j = 0; j < WINSIZE; j++) {
- if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; }
- }
-
- /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
- if ((err = ltc_mp.ecc_ptadd(R, M[bitbuf-8], R, modulus, mp)) != CRYPT_OK) { goto done; }
- }
- /* empty window and reset */
- bitcpy = bitbuf = 0;
- mode = 1;
- }
- }
-
- /* if bits remain then double/add */
- if (mode == 2 && bitcpy > 0) {
- /* double then add */
- for (j = 0; j < bitcpy; j++) {
- /* only double if we have had at least one add first */
- if (first == 0) {
- if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; }
- }
-
- bitbuf <<= 1;
- if ((bitbuf & (1 << WINSIZE)) != 0) {
- if (first == 1){
- /* first add, so copy */
- if ((err = mp_copy(tG->x, R->x)) != CRYPT_OK) { goto done; }
- if ((err = mp_copy(tG->y, R->y)) != CRYPT_OK) { goto done; }
- if ((err = mp_copy(tG->z, R->z)) != CRYPT_OK) { goto done; }
- first = 0;
- } else {
- /* then add */
- if ((err = ltc_mp.ecc_ptadd(R, tG, R, modulus, mp)) != CRYPT_OK) { goto done; }
- }
- }
- }
- }
-
- /* map R back from projective space */
- if (map) {
- err = ltc_ecc_map(R, modulus, mp);
- } else {
- err = CRYPT_OK;
- }
-done:
- if (mu != NULL) {
- mp_clear(mu);
- }
- mp_montgomery_free(mp);
- ltc_ecc_del_point(tG);
- for (i = 0; i < 8; i++) {
- ltc_ecc_del_point(M[i]);
- }
- return err;
-}
-
-#endif
-
-#undef WINSIZE
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c,v $ */
-/* $Revision: 1.26 $ */
-/* $Date: 2007/05/12 14:32:35 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c b/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c
deleted file mode 100644
index f5a4acb4c5a..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
- *
- * All curves taken from NIST recommendation paper of July 1999
- * Available at http://csrc.nist.gov/cryptval/dss.htm
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file ltc_ecc_points.c
- ECC Crypto, Tom St Denis
-*/
-
-#ifdef LTC_MECC
-
-/**
- Allocate a new ECC point
- @return A newly allocated point or NULL on error
-*/
-ecc_point *ltc_ecc_new_point(void)
-{
- ecc_point *p;
- p = XCALLOC(1, sizeof(*p));
- if (p == NULL) {
- return NULL;
- }
- if (mp_init_multi(&p->x, &p->y, &p->z, NULL) != CRYPT_OK) {
- XFREE(p);
- return NULL;
- }
- return p;
-}
-
-/** Free an ECC point from memory
- @param p The point to free
-*/
-void ltc_ecc_del_point(ecc_point *p)
-{
- /* prevents free'ing null arguments */
- if (p != NULL) {
- mp_clear_multi(p->x, p->y, p->z, NULL); /* note: p->z may be NULL but that's ok with this function anyways */
- XFREE(p);
- }
-}
-
-#endif
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_points.c,v $ */
-/* $Revision: 1.7 $ */
-/* $Date: 2007/05/12 14:32:35 $ */
-
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c b/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c
deleted file mode 100644
index b4416fc77de..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
- *
- * All curves taken from NIST recommendation paper of July 1999
- * Available at http://csrc.nist.gov/cryptval/dss.htm
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file ltc_ecc_projective_add_point.c
- ECC Crypto, Tom St Denis
-*/
-
-#if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC))
-
-/**
- Add two ECC points
- @param P The point to add
- @param Q The point to add
- @param R [out] The destination of the double
- @param modulus The modulus of the field the ECC curve is in
- @param mp The "b" value from montgomery_setup()
- @return CRYPT_OK on success
-*/
-int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp)
-{
- void *t1, *t2, *x, *y, *z;
- int err;
-
- LTC_ARGCHK(P != NULL);
- LTC_ARGCHK(Q != NULL);
- LTC_ARGCHK(R != NULL);
- LTC_ARGCHK(modulus != NULL);
- LTC_ARGCHK(mp != NULL);
-
- if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != CRYPT_OK) {
- return err;
- }
-
- /* should we dbl instead? */
- if ((err = mp_sub(modulus, Q->y, t1)) != CRYPT_OK) { goto done; }
-
- if ( (mp_cmp(P->x, Q->x) == LTC_MP_EQ) &&
- (Q->z != NULL && mp_cmp(P->z, Q->z) == LTC_MP_EQ) &&
- (mp_cmp(P->y, Q->y) == LTC_MP_EQ || mp_cmp(P->y, t1) == LTC_MP_EQ)) {
- mp_clear_multi(t1, t2, x, y, z, NULL);
- return ltc_ecc_projective_dbl_point(P, R, modulus, mp);
- }
-
- if ((err = mp_copy(P->x, x)) != CRYPT_OK) { goto done; }
- if ((err = mp_copy(P->y, y)) != CRYPT_OK) { goto done; }
- if ((err = mp_copy(P->z, z)) != CRYPT_OK) { goto done; }
-
- /* if Z is one then these are no-operations */
- if (Q->z != NULL) {
- /* T1 = Z' * Z' */
- if ((err = mp_sqr(Q->z, t1)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
- /* X = X * T1 */
- if ((err = mp_mul(t1, x, x)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; }
- /* T1 = Z' * T1 */
- if ((err = mp_mul(Q->z, t1, t1)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
- /* Y = Y * T1 */
- if ((err = mp_mul(t1, y, y)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(y, modulus, mp)) != CRYPT_OK) { goto done; }
- }
-
- /* T1 = Z*Z */
- if ((err = mp_sqr(z, t1)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
- /* T2 = X' * T1 */
- if ((err = mp_mul(Q->x, t1, t2)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
- /* T1 = Z * T1 */
- if ((err = mp_mul(z, t1, t1)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
- /* T1 = Y' * T1 */
- if ((err = mp_mul(Q->y, t1, t1)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
-
- /* Y = Y - T1 */
- if ((err = mp_sub(y, t1, y)) != CRYPT_OK) { goto done; }
- if (mp_cmp_d(y, 0) == LTC_MP_LT) {
- if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; }
- }
- /* T1 = 2T1 */
- if ((err = mp_add(t1, t1, t1)) != CRYPT_OK) { goto done; }
- if (mp_cmp(t1, modulus) != LTC_MP_LT) {
- if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
- }
- /* T1 = Y + T1 */
- if ((err = mp_add(t1, y, t1)) != CRYPT_OK) { goto done; }
- if (mp_cmp(t1, modulus) != LTC_MP_LT) {
- if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
- }
- /* X = X - T2 */
- if ((err = mp_sub(x, t2, x)) != CRYPT_OK) { goto done; }
- if (mp_cmp_d(x, 0) == LTC_MP_LT) {
- if ((err = mp_add(x, modulus, x)) != CRYPT_OK) { goto done; }
- }
- /* T2 = 2T2 */
- if ((err = mp_add(t2, t2, t2)) != CRYPT_OK) { goto done; }
- if (mp_cmp(t2, modulus) != LTC_MP_LT) {
- if ((err = mp_sub(t2, modulus, t2)) != CRYPT_OK) { goto done; }
- }
- /* T2 = X + T2 */
- if ((err = mp_add(t2, x, t2)) != CRYPT_OK) { goto done; }
- if (mp_cmp(t2, modulus) != LTC_MP_LT) {
- if ((err = mp_sub(t2, modulus, t2)) != CRYPT_OK) { goto done; }
- }
-
- /* if Z' != 1 */
- if (Q->z != NULL) {
- /* Z = Z * Z' */
- if ((err = mp_mul(z, Q->z, z)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(z, modulus, mp)) != CRYPT_OK) { goto done; }
- }
-
- /* Z = Z * X */
- if ((err = mp_mul(z, x, z)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(z, modulus, mp)) != CRYPT_OK) { goto done; }
-
- /* T1 = T1 * X */
- if ((err = mp_mul(t1, x, t1)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
- /* X = X * X */
- if ((err = mp_sqr(x, x)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; }
- /* T2 = T2 * x */
- if ((err = mp_mul(t2, x, t2)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
- /* T1 = T1 * X */
- if ((err = mp_mul(t1, x, t1)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
-
- /* X = Y*Y */
- if ((err = mp_sqr(y, x)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; }
- /* X = X - T2 */
- if ((err = mp_sub(x, t2, x)) != CRYPT_OK) { goto done; }
- if (mp_cmp_d(x, 0) == LTC_MP_LT) {
- if ((err = mp_add(x, modulus, x)) != CRYPT_OK) { goto done; }
- }
-
- /* T2 = T2 - X */
- if ((err = mp_sub(t2, x, t2)) != CRYPT_OK) { goto done; }
- if (mp_cmp_d(t2, 0) == LTC_MP_LT) {
- if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; }
- }
- /* T2 = T2 - X */
- if ((err = mp_sub(t2, x, t2)) != CRYPT_OK) { goto done; }
- if (mp_cmp_d(t2, 0) == LTC_MP_LT) {
- if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; }
- }
- /* T2 = T2 * Y */
- if ((err = mp_mul(t2, y, t2)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
- /* Y = T2 - T1 */
- if ((err = mp_sub(t2, t1, y)) != CRYPT_OK) { goto done; }
- if (mp_cmp_d(y, 0) == LTC_MP_LT) {
- if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; }
- }
- /* Y = Y/2 */
- if (mp_isodd(y)) {
- if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; }
- }
- if ((err = mp_div_2(y, y)) != CRYPT_OK) { goto done; }
-
- if ((err = mp_copy(x, R->x)) != CRYPT_OK) { goto done; }
- if ((err = mp_copy(y, R->y)) != CRYPT_OK) { goto done; }
- if ((err = mp_copy(z, R->z)) != CRYPT_OK) { goto done; }
-
- err = CRYPT_OK;
-done:
- mp_clear_multi(t1, t2, x, y, z, NULL);
- return err;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c,v $ */
-/* $Revision: 1.16 $ */
-/* $Date: 2007/05/12 14:32:35 $ */
-
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c b/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c
deleted file mode 100644
index b990e0a14aa..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
- *
- * All curves taken from NIST recommendation paper of July 1999
- * Available at http://csrc.nist.gov/cryptval/dss.htm
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file ltc_ecc_projective_dbl_point.c
- ECC Crypto, Tom St Denis
-*/
-
-#if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC))
-
-/**
- Double an ECC point
- @param P The point to double
- @param R [out] The destination of the double
- @param modulus The modulus of the field the ECC curve is in
- @param mp The "b" value from montgomery_setup()
- @return CRYPT_OK on success
-*/
-int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp)
-{
- void *t1, *t2;
- int err;
-
- LTC_ARGCHK(P != NULL);
- LTC_ARGCHK(R != NULL);
- LTC_ARGCHK(modulus != NULL);
- LTC_ARGCHK(mp != NULL);
-
- if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) {
- return err;
- }
-
- if (P != R) {
- if ((err = mp_copy(P->x, R->x)) != CRYPT_OK) { goto done; }
- if ((err = mp_copy(P->y, R->y)) != CRYPT_OK) { goto done; }
- if ((err = mp_copy(P->z, R->z)) != CRYPT_OK) { goto done; }
- }
-
- /* t1 = Z * Z */
- if ((err = mp_sqr(R->z, t1)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; }
- /* Z = Y * Z */
- if ((err = mp_mul(R->z, R->y, R->z)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(R->z, modulus, mp)) != CRYPT_OK) { goto done; }
- /* Z = 2Z */
- if ((err = mp_add(R->z, R->z, R->z)) != CRYPT_OK) { goto done; }
- if (mp_cmp(R->z, modulus) != LTC_MP_LT) {
- if ((err = mp_sub(R->z, modulus, R->z)) != CRYPT_OK) { goto done; }
- }
-
- /* T2 = X - T1 */
- if ((err = mp_sub(R->x, t1, t2)) != CRYPT_OK) { goto done; }
- if (mp_cmp_d(t2, 0) == LTC_MP_LT) {
- if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; }
- }
- /* T1 = X + T1 */
- if ((err = mp_add(t1, R->x, t1)) != CRYPT_OK) { goto done; }
- if (mp_cmp(t1, modulus) != LTC_MP_LT) {
- if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
- }
- /* T2 = T1 * T2 */
- if ((err = mp_mul(t1, t2, t2)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
- /* T1 = 2T2 */
- if ((err = mp_add(t2, t2, t1)) != CRYPT_OK) { goto done; }
- if (mp_cmp(t1, modulus) != LTC_MP_LT) {
- if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
- }
- /* T1 = T1 + T2 */
- if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; }
- if (mp_cmp(t1, modulus) != LTC_MP_LT) {
- if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
- }
-
- /* Y = 2Y */
- if ((err = mp_add(R->y, R->y, R->y)) != CRYPT_OK) { goto done; }
- if (mp_cmp(R->y, modulus) != LTC_MP_LT) {
- if ((err = mp_sub(R->y, modulus, R->y)) != CRYPT_OK) { goto done; }
- }
- /* Y = Y * Y */
- if ((err = mp_sqr(R->y, R->y)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; }
- /* T2 = Y * Y */
- if ((err = mp_sqr(R->y, t2)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
- /* T2 = T2/2 */
- if (mp_isodd(t2)) {
- if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; }
- }
- if ((err = mp_div_2(t2, t2)) != CRYPT_OK) { goto done; }
- /* Y = Y * X */
- if ((err = mp_mul(R->y, R->x, R->y)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; }
-
- /* X = T1 * T1 */
- if ((err = mp_sqr(t1, R->x)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(R->x, modulus, mp)) != CRYPT_OK) { goto done; }
- /* X = X - Y */
- if ((err = mp_sub(R->x, R->y, R->x)) != CRYPT_OK) { goto done; }
- if (mp_cmp_d(R->x, 0) == LTC_MP_LT) {
- if ((err = mp_add(R->x, modulus, R->x)) != CRYPT_OK) { goto done; }
- }
- /* X = X - Y */
- if ((err = mp_sub(R->x, R->y, R->x)) != CRYPT_OK) { goto done; }
- if (mp_cmp_d(R->x, 0) == LTC_MP_LT) {
- if ((err = mp_add(R->x, modulus, R->x)) != CRYPT_OK) { goto done; }
- }
-
- /* Y = Y - X */
- if ((err = mp_sub(R->y, R->x, R->y)) != CRYPT_OK) { goto done; }
- if (mp_cmp_d(R->y, 0) == LTC_MP_LT) {
- if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; }
- }
- /* Y = Y * T1 */
- if ((err = mp_mul(R->y, t1, R->y)) != CRYPT_OK) { goto done; }
- if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; }
- /* Y = Y - T2 */
- if ((err = mp_sub(R->y, t2, R->y)) != CRYPT_OK) { goto done; }
- if (mp_cmp_d(R->y, 0) == LTC_MP_LT) {
- if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; }
- }
-
- err = CRYPT_OK;
-done:
- mp_clear_multi(t1, t2, NULL);
- return err;
-}
-#endif
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c,v $ */
-/* $Revision: 1.11 $ */
-/* $Date: 2007/05/12 14:32:35 $ */
-
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c b/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c
deleted file mode 100644
index e8f6418067c..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file pkcs_1_mgf1.c
- The Mask Generation Function (MGF1) for LTC_PKCS #1, Tom St Denis
-*/
-
-#ifdef LTC_PKCS_1
-
-/**
- Perform LTC_PKCS #1 MGF1 (internal)
- @param seed The seed for MGF1
- @param seedlen The length of the seed
- @param hash_idx The index of the hash desired
- @param mask [out] The destination
- @param masklen The length of the mask desired
- @return CRYPT_OK if successful
-*/
-int pkcs_1_mgf1(int hash_idx,
- const unsigned char *seed, unsigned long seedlen,
- unsigned char *mask, unsigned long masklen)
-{
- unsigned long hLen, x;
- ulong32 counter;
- int err;
- hash_state *md;
- unsigned char *buf;
-
- LTC_ARGCHK(seed != NULL);
- LTC_ARGCHK(mask != NULL);
-
- /* ensure valid hash */
- if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
- return err;
- }
-
- /* get hash output size */
- hLen = hash_descriptor[hash_idx].hashsize;
-
- /* allocate memory */
- md = XMALLOC(sizeof(hash_state));
- buf = XMALLOC(hLen);
- if (md == NULL || buf == NULL) {
- if (md != NULL) {
- XFREE(md);
- }
- if (buf != NULL) {
- XFREE(buf);
- }
- return CRYPT_MEM;
- }
-
- /* start counter */
- counter = 0;
-
- while (masklen > 0) {
- /* handle counter */
- STORE32H(counter, buf);
- ++counter;
-
- /* get hash of seed || counter */
- if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- if ((err = hash_descriptor[hash_idx].process(md, seed, seedlen)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- if ((err = hash_descriptor[hash_idx].process(md, buf, 4)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- if ((err = hash_descriptor[hash_idx].done(md, buf)) != CRYPT_OK) {
- goto LBL_ERR;
- }
-
- /* store it */
- for (x = 0; x < hLen && masklen > 0; x++, masklen--) {
- *mask++ = buf[x];
- }
- }
-
- err = CRYPT_OK;
-LBL_ERR:
-#ifdef LTC_CLEAN_STACK
- zeromem(buf, hLen);
- zeromem(md, sizeof(hash_state));
-#endif
-
- XFREE(buf);
- XFREE(md);
-
- return err;
-}
-
-#endif /* LTC_PKCS_1 */
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c,v $ */
-/* $Revision: 1.8 $ */
-/* $Date: 2007/05/12 14:32:35 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c b/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c
deleted file mode 100644
index 709ab8a8cd2..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file pkcs_1_oaep_decode.c
- OAEP Padding for LTC_PKCS #1, Tom St Denis
-*/
-
-#ifdef LTC_PKCS_1
-
-/**
- LTC_PKCS #1 v2.00 OAEP decode
- @param msg The encoded data to decode
- @param msglen The length of the encoded data (octets)
- @param lparam The session or system data (can be NULL)
- @param lparamlen The length of the lparam
- @param modulus_bitlen The bit length of the RSA modulus
- @param hash_idx The index of the hash desired
- @param out [out] Destination of decoding
- @param outlen [in/out] The max size and resulting size of the decoding
- @param res [out] Result of decoding, 1==valid, 0==invalid
- @return CRYPT_OK if successful (even if invalid)
-*/
-int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
- const unsigned char *lparam, unsigned long lparamlen,
- unsigned long modulus_bitlen, int hash_idx,
- unsigned char *out, unsigned long *outlen,
- int *res)
-{
- unsigned char *DB, *seed, *mask;
- unsigned long hLen, x, y, modulus_len;
- int err;
-
- LTC_ARGCHK(msg != NULL);
- LTC_ARGCHK(out != NULL);
- LTC_ARGCHK(outlen != NULL);
- LTC_ARGCHK(res != NULL);
-
- /* default to invalid packet */
- *res = 0;
-
- /* test valid hash */
- if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
- return err;
- }
- hLen = hash_descriptor[hash_idx].hashsize;
- modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
-
- /* test hash/message size */
- if ((2*hLen >= (modulus_len - 2)) || (msglen != modulus_len)) {
- return CRYPT_PK_INVALID_SIZE;
- }
-
- /* allocate ram for DB/mask/salt of size modulus_len */
- DB = XMALLOC(modulus_len);
- mask = XMALLOC(modulus_len);
- seed = XMALLOC(hLen);
- if (DB == NULL || mask == NULL || seed == NULL) {
- if (DB != NULL) {
- XFREE(DB);
- }
- if (mask != NULL) {
- XFREE(mask);
- }
- if (seed != NULL) {
- XFREE(seed);
- }
- return CRYPT_MEM;
- }
-
- /* ok so it's now in the form
-
- 0x00 || maskedseed || maskedDB
-
- 1 || hLen || modulus_len - hLen - 1
-
- */
-
- /* must have leading 0x00 byte */
- if (msg[0] != 0x00) {
- err = CRYPT_OK;
- goto LBL_ERR;
- }
-
- /* now read the masked seed */
- x = 1;
- XMEMCPY(seed, msg + x, hLen);
- x += hLen;
-
- /* now read the masked DB */
- XMEMCPY(DB, msg + x, modulus_len - hLen - 1);
- x += modulus_len - hLen - 1;
-
- /* compute MGF1 of maskedDB (hLen) */
- if ((err = pkcs_1_mgf1(hash_idx, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) {
- goto LBL_ERR;
- }
-
- /* XOR against seed */
- for (y = 0; y < hLen; y++) {
- seed[y] ^= mask[y];
- }
-
- /* compute MGF1 of seed (k - hlen - 1) */
- if ((err = pkcs_1_mgf1(hash_idx, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) {
- goto LBL_ERR;
- }
-
- /* xor against DB */
- for (y = 0; y < (modulus_len - hLen - 1); y++) {
- DB[y] ^= mask[y];
- }
-
- /* now DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */
-
- /* compute lhash and store it in seed [reuse temps!] */
- x = modulus_len;
- if (lparam != NULL) {
- if ((err = hash_memory(hash_idx, lparam, lparamlen, seed, &x)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- } else {
- /* can't pass hash_memory a NULL so use DB with zero length */
- if ((err = hash_memory(hash_idx, DB, 0, seed, &x)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- }
-
- /* compare the lhash'es */
- if (XMEMCMP(seed, DB, hLen) != 0) {
- err = CRYPT_OK;
- goto LBL_ERR;
- }
-
- /* now zeroes before a 0x01 */
- for (x = hLen; x < (modulus_len - hLen - 1) && DB[x] == 0x00; x++) {
- /* step... */
- }
-
- /* error out if wasn't 0x01 */
- if (x == (modulus_len - hLen - 1) || DB[x] != 0x01) {
- err = CRYPT_INVALID_PACKET;
- goto LBL_ERR;
- }
-
- /* rest is the message (and skip 0x01) */
- if ((modulus_len - hLen - 1 - ++x) > *outlen) {
- *outlen = modulus_len - hLen - 1 - x;
- err = CRYPT_BUFFER_OVERFLOW;
- goto LBL_ERR;
- }
-
- /* copy message */
- *outlen = modulus_len - hLen - 1 - x;
- XMEMCPY(out, DB + x, modulus_len - hLen - 1 - x);
- x += modulus_len - hLen - 1;
-
- /* valid packet */
- *res = 1;
-
- err = CRYPT_OK;
-LBL_ERR:
-#ifdef LTC_CLEAN_STACK
- zeromem(DB, modulus_len);
- zeromem(seed, hLen);
- zeromem(mask, modulus_len);
-#endif
-
- XFREE(seed);
- XFREE(mask);
- XFREE(DB);
-
- return err;
-}
-
-#endif /* LTC_PKCS_1 */
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c,v $ */
-/* $Revision: 1.13 $ */
-/* $Date: 2007/05/12 14:32:35 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c b/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c
deleted file mode 100644
index c3a7211ef9c..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file pkcs_1_pss_decode.c
- LTC_PKCS #1 PSS Signature Padding, Tom St Denis
-*/
-
-#ifdef LTC_PKCS_1
-
-/**
- LTC_PKCS #1 v2.00 PSS decode
- @param msghash The hash to verify
- @param msghashlen The length of the hash (octets)
- @param sig The signature data (encoded data)
- @param siglen The length of the signature data (octets)
- @param saltlen The length of the salt used (octets)
- @param hash_idx The index of the hash desired
- @param modulus_bitlen The bit length of the RSA modulus
- @param res [out] The result of the comparison, 1==valid, 0==invalid
- @return CRYPT_OK if successful (even if the comparison failed)
-*/
-int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
- const unsigned char *sig, unsigned long siglen,
- unsigned long saltlen, int hash_idx,
- unsigned long modulus_bitlen, int *res)
-{
- unsigned char *DB, *mask, *salt, *hash;
- unsigned long x, y, hLen, modulus_len;
- int err;
- hash_state md;
-
- LTC_ARGCHK(msghash != NULL);
- LTC_ARGCHK(res != NULL);
-
- /* default to invalid */
- *res = 0;
-
- /* ensure hash is valid */
- if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
- return err;
- }
-
- hLen = hash_descriptor[hash_idx].hashsize;
- modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0);
-
- /* check sizes */
- if ((saltlen > modulus_len) ||
- (modulus_len < hLen + saltlen + 2) || (siglen != modulus_len)) {
- return CRYPT_PK_INVALID_SIZE;
- }
-
- /* allocate ram for DB/mask/salt/hash of size modulus_len */
- DB = XMALLOC(modulus_len);
- mask = XMALLOC(modulus_len);
- salt = XMALLOC(modulus_len);
- hash = XMALLOC(modulus_len);
- if (DB == NULL || mask == NULL || salt == NULL || hash == NULL) {
- if (DB != NULL) {
- XFREE(DB);
- }
- if (mask != NULL) {
- XFREE(mask);
- }
- if (salt != NULL) {
- XFREE(salt);
- }
- if (hash != NULL) {
- XFREE(hash);
- }
- return CRYPT_MEM;
- }
-
- /* ensure the 0xBC byte */
- if (sig[siglen-1] != 0xBC) {
- err = CRYPT_INVALID_PACKET;
- goto LBL_ERR;
- }
-
- /* copy out the DB */
- x = 0;
- XMEMCPY(DB, sig + x, modulus_len - hLen - 1);
- x += modulus_len - hLen - 1;
-
- /* copy out the hash */
- XMEMCPY(hash, sig + x, hLen);
- x += hLen;
-
- /* check the MSB */
- if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)))) != 0) {
- err = CRYPT_INVALID_PACKET;
- goto LBL_ERR;
- }
-
- /* generate mask of length modulus_len - hLen - 1 from hash */
- if ((err = pkcs_1_mgf1(hash_idx, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) {
- goto LBL_ERR;
- }
-
- /* xor against DB */
- for (y = 0; y < (modulus_len - hLen - 1); y++) {
- DB[y] ^= mask[y];
- }
-
- /* now clear the first byte [make sure smaller than modulus] */
- DB[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1));
-
- /* DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */
-
- /* check for zeroes and 0x01 */
- for (x = 0; x < modulus_len - saltlen - hLen - 2; x++) {
- if (DB[x] != 0x00) {
- err = CRYPT_INVALID_PACKET;
- goto LBL_ERR;
- }
- }
-
- /* check for the 0x01 */
- if (DB[x++] != 0x01) {
- err = CRYPT_INVALID_PACKET;
- goto LBL_ERR;
- }
-
- /* M = (eight) 0x00 || msghash || salt, mask = H(M) */
- if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- zeromem(mask, 8);
- if ((err = hash_descriptor[hash_idx].process(&md, mask, 8)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- if ((err = hash_descriptor[hash_idx].process(&md, DB+x, saltlen)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- if ((err = hash_descriptor[hash_idx].done(&md, mask)) != CRYPT_OK) {
- goto LBL_ERR;
- }
-
- /* mask == hash means valid signature */
- if (XMEMCMP(mask, hash, hLen) == 0) {
- *res = 1;
- }
-
- err = CRYPT_OK;
-LBL_ERR:
-#ifdef LTC_CLEAN_STACK
- zeromem(DB, modulus_len);
- zeromem(mask, modulus_len);
- zeromem(salt, modulus_len);
- zeromem(hash, modulus_len);
-#endif
-
- XFREE(hash);
- XFREE(salt);
- XFREE(mask);
- XFREE(DB);
-
- return err;
-}
-
-#endif /* LTC_PKCS_1 */
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c,v $ */
-/* $Revision: 1.11 $ */
-/* $Date: 2007/05/12 14:32:35 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c b/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c
deleted file mode 100644
index 7c3711c17c9..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/** @file pkcs_1_v1_5_decode.c
- *
- * LTC_PKCS #1 v1.5 Padding. (Andreas Lange)
- */
-
-#ifdef LTC_PKCS_1
-
-/** @brief LTC_PKCS #1 v1.5 decode.
- *
- * @param msg The encoded data to decode
- * @param msglen The length of the encoded data (octets)
- * @param block_type Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks)
- * @param modulus_bitlen The bit length of the RSA modulus
- * @param out [out] Destination of decoding
- * @param outlen [in/out] The max size and resulting size of the decoding
- * @param is_valid [out] Boolean whether the padding was valid
- *
- * @return CRYPT_OK if successful (even if invalid)
- */
-int pkcs_1_v1_5_decode(const unsigned char *msg,
- unsigned long msglen,
- int block_type,
- unsigned long modulus_bitlen,
- unsigned char *out,
- unsigned long *outlen,
- int *is_valid)
-{
- unsigned long modulus_len, ps_len, i;
- int result;
-
- /* default to invalid packet */
- *is_valid = 0;
-
- modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
-
- /* test message size */
-
- if ((msglen > modulus_len) || (modulus_len < 11)) {
- return CRYPT_PK_INVALID_SIZE;
- }
-
- /* separate encoded message */
-
- if ((msg[0] != 0x00) || (msg[1] != (unsigned char)block_type)) {
- result = CRYPT_INVALID_PACKET;
- goto bail;
- }
-
- if (block_type == LTC_LTC_PKCS_1_EME) {
- for (i = 2; i < modulus_len; i++) {
- /* separator */
- if (msg[i] == 0x00) { break; }
- }
- ps_len = i++ - 2;
-
- if ((i >= modulus_len) || (ps_len < 8)) {
- /* There was no octet with hexadecimal value 0x00 to separate ps from m,
- * or the length of ps is less than 8 octets.
- */
- result = CRYPT_INVALID_PACKET;
- goto bail;
- }
- } else {
- for (i = 2; i < modulus_len - 1; i++) {
- if (msg[i] != 0xFF) { break; }
- }
-
- /* separator check */
- if (msg[i] != 0) {
- /* There was no octet with hexadecimal value 0x00 to separate ps from m. */
- result = CRYPT_INVALID_PACKET;
- goto bail;
- }
-
- ps_len = i - 2;
- }
-
- if (*outlen < (msglen - (2 + ps_len + 1))) {
- *outlen = msglen - (2 + ps_len + 1);
- result = CRYPT_BUFFER_OVERFLOW;
- goto bail;
- }
-
- *outlen = (msglen - (2 + ps_len + 1));
- XMEMCPY(out, &msg[2 + ps_len + 1], *outlen);
-
- /* valid packet */
- *is_valid = 1;
- result = CRYPT_OK;
-bail:
- return result;
-} /* pkcs_1_v1_5_decode */
-
-#endif /* #ifdef LTC_PKCS_1 */
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c,v $ */
-/* $Revision: 1.7 $ */
-/* $Date: 2007/05/12 14:32:35 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_exptmod.c b/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_exptmod.c
deleted file mode 100644
index ba44106f2b7..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_exptmod.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file rsa_exptmod.c
- RSA LTC_PKCS exptmod, Tom St Denis
-*/
-
-#ifdef LTC_MRSA
-
-/**
- Compute an RSA modular exponentiation
- @param in The input data to send into RSA
- @param inlen The length of the input (octets)
- @param out [out] The destination
- @param outlen [in/out] The max size and resulting size of the output
- @param which Which exponent to use, e.g. PK_PRIVATE or PK_PUBLIC
- @param key The RSA key to use
- @return CRYPT_OK if successful
-*/
-int rsa_exptmod(const unsigned char *in, unsigned long inlen,
- unsigned char *out, unsigned long *outlen, int which,
- rsa_key *key)
-{
- void *tmp, *tmpa, *tmpb;
- unsigned long x;
- int err;
-
- LTC_ARGCHK(in != NULL);
- LTC_ARGCHK(out != NULL);
- LTC_ARGCHK(outlen != NULL);
- LTC_ARGCHK(key != NULL);
-
- /* is the key of the right type for the operation? */
- if (which == PK_PRIVATE && (key->type != PK_PRIVATE)) {
- return CRYPT_PK_NOT_PRIVATE;
- }
-
- /* must be a private or public operation */
- if (which != PK_PRIVATE && which != PK_PUBLIC) {
- return CRYPT_PK_INVALID_TYPE;
- }
-
- /* init and copy into tmp */
- if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, NULL)) != CRYPT_OK) { return err; }
- if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto error; }
-
- /* sanity check on the input */
- if (mp_cmp(key->N, tmp) == LTC_MP_LT) {
- err = CRYPT_PK_INVALID_SIZE;
- goto error;
- }
-
- /* are we using the private exponent and is the key optimized? */
- if (which == PK_PRIVATE) {
- /* tmpa = tmp^dP mod p */
- if ((err = mp_exptmod(tmp, key->dP, key->p, tmpa)) != CRYPT_OK) { goto error; }
-
- /* tmpb = tmp^dQ mod q */
- if ((err = mp_exptmod(tmp, key->dQ, key->q, tmpb)) != CRYPT_OK) { goto error; }
-
- /* tmp = (tmpa - tmpb) * qInv (mod p) */
- if ((err = mp_sub(tmpa, tmpb, tmp)) != CRYPT_OK) { goto error; }
- if ((err = mp_mulmod(tmp, key->qP, key->p, tmp)) != CRYPT_OK) { goto error; }
-
- /* tmp = tmpb + q * tmp */
- if ((err = mp_mul(tmp, key->q, tmp)) != CRYPT_OK) { goto error; }
- if ((err = mp_add(tmp, tmpb, tmp)) != CRYPT_OK) { goto error; }
- } else {
- /* exptmod it */
- if ((err = mp_exptmod(tmp, key->e, key->N, tmp)) != CRYPT_OK) { goto error; }
- }
-
- /* read it back */
- x = (unsigned long)mp_unsigned_bin_size(key->N);
- if (x > *outlen) {
- *outlen = x;
- err = CRYPT_BUFFER_OVERFLOW;
- goto error;
- }
-
- /* this should never happen ... */
- if (mp_unsigned_bin_size(tmp) > mp_unsigned_bin_size(key->N)) {
- err = CRYPT_ERROR;
- goto error;
- }
- *outlen = x;
-
- /* convert it */
- zeromem(out, x);
- if ((err = mp_to_unsigned_bin(tmp, out+(x-mp_unsigned_bin_size(tmp)))) != CRYPT_OK) { goto error; }
-
- /* clean up and return */
- err = CRYPT_OK;
-error:
- mp_clear_multi(tmp, tmpa, tmpb, NULL);
- return err;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_exptmod.c,v $ */
-/* $Revision: 1.18 $ */
-/* $Date: 2007/05/12 14:32:35 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_free.c b/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_free.c
deleted file mode 100644
index a10ed5928ce..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_free.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file rsa_free.c
- Free an RSA key, Tom St Denis
-*/
-
-#ifdef LTC_MRSA
-
-/**
- Free an RSA key from memory
- @param key The RSA key to free
-*/
-void rsa_free(rsa_key *key)
-{
- LTC_ARGCHKVD(key != NULL);
- mp_clear_multi(key->e, key->d, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_free.c,v $ */
-/* $Revision: 1.10 $ */
-/* $Date: 2007/05/12 14:32:35 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_import.c b/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_import.c
deleted file mode 100644
index 6254fd7ff86..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_import.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file rsa_import.c
- Import a LTC_PKCS RSA key, Tom St Denis
-*/
-
-#ifdef LTC_MRSA
-
-/**
- Import an RSAPublicKey or RSAPrivateKey [two-prime only, only support >= 1024-bit keys, defined in LTC_PKCS #1 v2.1]
- @param in The packet to import from
- @param inlen It's length (octets)
- @param key [out] Destination for newly imported key
- @return CRYPT_OK if successful, upon error allocated memory is freed
-*/
-int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
-{
- int err;
- void *zero;
- unsigned char *tmpbuf;
- unsigned long t, x, y, z, tmpoid[16];
- ltc_asn1_list ssl_pubkey_hashoid[2];
- ltc_asn1_list ssl_pubkey[2];
-
- LTC_ARGCHK(in != NULL);
- LTC_ARGCHK(key != NULL);
- LTC_ARGCHK(ltc_mp.name != NULL);
-
- /* init key */
- if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ,
- &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) {
- return err;
- }
-
- /* see if the OpenSSL DER format RSA public key will work */
- tmpbuf = XCALLOC(1, MAX_RSA_SIZE*8);
- if (tmpbuf == NULL) {
- err = CRYPT_MEM;
- goto LBL_ERR;
- }
-
- /* this includes the internal hash ID and optional params (NULL in this case) */
- LTC_SET_ASN1(ssl_pubkey_hashoid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0]));
- LTC_SET_ASN1(ssl_pubkey_hashoid, 1, LTC_ASN1_NULL, NULL, 0);
-
- /* the actual format of the SSL DER key is odd, it stores a RSAPublicKey in a **BIT** string ... so we have to extract it
- then proceed to convert bit to octet
- */
- LTC_SET_ASN1(ssl_pubkey, 0, LTC_ASN1_SEQUENCE, &ssl_pubkey_hashoid, 2);
- LTC_SET_ASN1(ssl_pubkey, 1, LTC_ASN1_BIT_STRING, tmpbuf, MAX_RSA_SIZE*8);
-
- if (der_decode_sequence(in, inlen,
- ssl_pubkey, 2UL) == CRYPT_OK) {
-
- /* ok now we have to reassemble the BIT STRING to an OCTET STRING. Thanks OpenSSL... */
- for (t = y = z = x = 0; x < ssl_pubkey[1].size; x++) {
- y = (y << 1) | tmpbuf[x];
- if (++z == 8) {
- tmpbuf[t++] = (unsigned char)y;
- y = 0;
- z = 0;
- }
- }
-
- /* now it should be SEQUENCE { INTEGER, INTEGER } */
- if ((err = der_decode_sequence_multi(tmpbuf, t,
- LTC_ASN1_INTEGER, 1UL, key->N,
- LTC_ASN1_INTEGER, 1UL, key->e,
- LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
- XFREE(tmpbuf);
- goto LBL_ERR;
- }
- XFREE(tmpbuf);
- key->type = PK_PUBLIC;
- return CRYPT_OK;
- }
- XFREE(tmpbuf);
-
- /* not SSL public key, try to match against LTC_PKCS #1 standards */
- if ((err = der_decode_sequence_multi(in, inlen,
- LTC_ASN1_INTEGER, 1UL, key->N,
- LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
- goto LBL_ERR;
- }
-
- if (mp_cmp_d(key->N, 0) == LTC_MP_EQ) {
- if ((err = mp_init(&zero)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- /* it's a private key */
- if ((err = der_decode_sequence_multi(in, inlen,
- LTC_ASN1_INTEGER, 1UL, zero,
- LTC_ASN1_INTEGER, 1UL, key->N,
- LTC_ASN1_INTEGER, 1UL, key->e,
- LTC_ASN1_INTEGER, 1UL, key->d,
- LTC_ASN1_INTEGER, 1UL, key->p,
- LTC_ASN1_INTEGER, 1UL, key->q,
- LTC_ASN1_INTEGER, 1UL, key->dP,
- LTC_ASN1_INTEGER, 1UL, key->dQ,
- LTC_ASN1_INTEGER, 1UL, key->qP,
- LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
- mp_clear(zero);
- goto LBL_ERR;
- }
- mp_clear(zero);
- key->type = PK_PRIVATE;
- } else if (mp_cmp_d(key->N, 1) == LTC_MP_EQ) {
- /* we don't support multi-prime RSA */
- err = CRYPT_PK_INVALID_TYPE;
- goto LBL_ERR;
- } else {
- /* it's a public key and we lack e */
- if ((err = der_decode_sequence_multi(in, inlen,
- LTC_ASN1_INTEGER, 1UL, key->N,
- LTC_ASN1_INTEGER, 1UL, key->e,
- LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- key->type = PK_PUBLIC;
- }
- return CRYPT_OK;
-LBL_ERR:
- mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
- return err;
-}
-
-#endif /* LTC_MRSA */
-
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_import.c,v $ */
-/* $Revision: 1.23 $ */
-/* $Date: 2007/05/12 14:32:35 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_make_key.c b/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_make_key.c
deleted file mode 100644
index bd37b4ae1cb..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_make_key.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file rsa_make_key.c
- RSA key generation, Tom St Denis
-*/
-
-#ifdef LTC_MRSA
-
-/**
- Create an RSA key
- @param prng An active PRNG state
- @param wprng The index of the PRNG desired
- @param size The size of the modulus (key size) desired (octets)
- @param e The "e" value (public key). e==65537 is a good choice
- @param key [out] Destination of a newly created private key pair
- @return CRYPT_OK if successful, upon error all allocated ram is freed
-*/
-int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
-{
- void *p, *q, *tmp1, *tmp2, *tmp3;
- int err;
-
- LTC_ARGCHK(ltc_mp.name != NULL);
- LTC_ARGCHK(key != NULL);
-
- if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) {
- return CRYPT_INVALID_KEYSIZE;
- }
-
- if ((e < 3) || ((e & 1) == 0)) {
- return CRYPT_INVALID_ARG;
- }
-
- if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
- return err;
- }
-
- if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != CRYPT_OK) {
- return err;
- }
-
- /* make primes p and q (optimization provided by Wayne Scott) */
- if ((err = mp_set_int(tmp3, e)) != CRYPT_OK) { goto errkey; } /* tmp3 = e */
-
- /* make prime "p" */
- do {
- if ((err = rand_prime( p, size/2, prng, wprng)) != CRYPT_OK) { goto errkey; }
- if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = p-1 */
- if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = gcd(p-1, e) */
- } while (mp_cmp_d( tmp2, 1) != 0); /* while e divides p-1 */
-
- /* make prime "q" */
- do {
- if ((err = rand_prime( q, size/2, prng, wprng)) != CRYPT_OK) { goto errkey; }
- if ((err = mp_sub_d( q, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = q-1 */
- if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = gcd(q-1, e) */
- } while (mp_cmp_d( tmp2, 1) != 0); /* while e divides q-1 */
-
- /* tmp1 = lcm(p-1, q-1) */
- if ((err = mp_sub_d( p, 1, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = p-1 */
- /* tmp1 = q-1 (previous do/while loop) */
- if ((err = mp_lcm( tmp1, tmp2, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = lcm(p-1, q-1) */
-
- /* make key */
- if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) {
- goto errkey;
- }
-
- if ((err = mp_set_int( key->e, e)) != CRYPT_OK) { goto errkey; } /* key->e = e */
- if ((err = mp_invmod( key->e, tmp1, key->d)) != CRYPT_OK) { goto errkey; } /* key->d = 1/e mod lcm(p-1,q-1) */
- if ((err = mp_mul( p, q, key->N)) != CRYPT_OK) { goto errkey; } /* key->N = pq */
-
- /* optimize for CRT now */
- /* find d mod q-1 and d mod p-1 */
- if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = q-1 */
- if ((err = mp_sub_d( q, 1, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = p-1 */
- if ((err = mp_mod( key->d, tmp1, key->dP)) != CRYPT_OK) { goto errkey; } /* dP = d mod p-1 */
- if ((err = mp_mod( key->d, tmp2, key->dQ)) != CRYPT_OK) { goto errkey; } /* dQ = d mod q-1 */
- if ((err = mp_invmod( q, p, key->qP)) != CRYPT_OK) { goto errkey; } /* qP = 1/q mod p */
-
- if ((err = mp_copy( p, key->p)) != CRYPT_OK) { goto errkey; }
- if ((err = mp_copy( q, key->q)) != CRYPT_OK) { goto errkey; }
-
- /* set key type (in this case it's CRT optimized) */
- key->type = PK_PRIVATE;
-
- /* return ok and free temps */
- err = CRYPT_OK;
- goto cleanup;
-errkey:
- mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
-cleanup:
- mp_clear_multi(tmp3, tmp2, tmp1, p, q, NULL);
- return err;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_make_key.c,v $ */
-/* $Revision: 1.16 $ */
-/* $Date: 2007/05/12 14:32:35 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c b/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c
deleted file mode 100644
index 103ae2f5303..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file rsa_verify_hash.c
- RSA LTC_PKCS #1 v1.5 or v2 PSS signature verification, Tom St Denis and Andreas Lange
-*/
-
-#ifdef LTC_MRSA
-
-/**
- LTC_PKCS #1 de-sign then v1.5 or PSS depad
- @param sig The signature data
- @param siglen The length of the signature data (octets)
- @param hash The hash of the message that was signed
- @param hashlen The length of the hash of the message that was signed (octets)
- @param padding Type of padding (LTC_LTC_PKCS_1_PSS or LTC_LTC_PKCS_1_V1_5)
- @param hash_idx The index of the desired hash
- @param saltlen The length of the salt used during signature
- @param stat [out] The result of the signature comparison, 1==valid, 0==invalid
- @param key The public RSA key corresponding to the key that performed the signature
- @return CRYPT_OK on success (even if the signature is invalid)
-*/
-int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
- const unsigned char *hash, unsigned long hashlen,
- int padding,
- int hash_idx, unsigned long saltlen,
- int *stat, rsa_key *key)
-{
- unsigned long modulus_bitlen, modulus_bytelen, x;
- int err;
- unsigned char *tmpbuf;
-
- LTC_ARGCHK(hash != NULL);
- LTC_ARGCHK(sig != NULL);
- LTC_ARGCHK(stat != NULL);
- LTC_ARGCHK(key != NULL);
-
- /* default to invalid */
- *stat = 0;
-
- /* valid padding? */
-
- if ((padding != LTC_LTC_PKCS_1_V1_5) &&
- (padding != LTC_LTC_PKCS_1_PSS)) {
- return CRYPT_PK_INVALID_PADDING;
- }
-
- if (padding == LTC_LTC_PKCS_1_PSS) {
- /* valid hash ? */
- if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
- return err;
- }
- }
-
- /* get modulus len in bits */
- modulus_bitlen = mp_count_bits( (key->N));
-
- /* outlen must be at least the size of the modulus */
- modulus_bytelen = mp_unsigned_bin_size( (key->N));
- if (modulus_bytelen != siglen) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* allocate temp buffer for decoded sig */
- tmpbuf = XMALLOC(siglen);
- if (tmpbuf == NULL) {
- return CRYPT_MEM;
- }
-
- /* RSA decode it */
- x = siglen;
- if ((err = ltc_mp.rsa_me(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) {
- XFREE(tmpbuf);
- return err;
- }
-
- /* make sure the output is the right size */
- if (x != siglen) {
- XFREE(tmpbuf);
- return CRYPT_INVALID_PACKET;
- }
-
- if (padding == LTC_LTC_PKCS_1_PSS) {
- /* PSS decode and verify it */
- err = pkcs_1_pss_decode(hash, hashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat);
- } else {
- /* LTC_PKCS #1 v1.5 decode it */
- unsigned char *out;
- unsigned long outlen, loid[16];
- int decoded;
- ltc_asn1_list digestinfo[2], siginfo[2];
-
- /* not all hashes have OIDs... so sad */
- if (hash_descriptor[hash_idx].OIDlen == 0) {
- err = CRYPT_INVALID_ARG;
- goto bail_2;
- }
-
- /* allocate temp buffer for decoded hash */
- outlen = ((modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0)) - 3;
- out = XMALLOC(outlen);
- if (out == NULL) {
- err = CRYPT_MEM;
- goto bail_2;
- }
-
- if ((err = pkcs_1_v1_5_decode(tmpbuf, x, LTC_LTC_PKCS_1_EMSA, modulus_bitlen, out, &outlen, &decoded)) != CRYPT_OK) {
- XFREE(out);
- goto bail_2;
- }
-
- /* now we must decode out[0...outlen-1] using ASN.1, test the OID and then test the hash */
- /* construct the SEQUENCE
- SEQUENCE {
- SEQUENCE {hashoid OID
- blah NULL
- }
- hash OCTET STRING
- }
- */
- LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, sizeof(loid)/sizeof(loid[0]));
- LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0);
- LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2);
- LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen);
-
- if ((err = der_decode_sequence(out, outlen, siginfo, 2)) != CRYPT_OK) {
- XFREE(out);
- goto bail_2;
- }
-
- /* test OID */
- if ((digestinfo[0].size == hash_descriptor[hash_idx].OIDlen) &&
- (XMEMCMP(digestinfo[0].data, hash_descriptor[hash_idx].OID, sizeof(unsigned long) * hash_descriptor[hash_idx].OIDlen) == 0) &&
- (siginfo[1].size == hashlen) &&
- (XMEMCMP(siginfo[1].data, hash, hashlen) == 0)) {
- *stat = 1;
- }
-
-#ifdef LTC_CLEAN_STACK
- zeromem(out, outlen);
-#endif
- XFREE(out);
- }
-
-bail_2:
-#ifdef LTC_CLEAN_STACK
- zeromem(tmpbuf, siglen);
-#endif
- XFREE(tmpbuf);
- return err;
-}
-
-#endif /* LTC_MRSA */
-
-/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_verify_hash.c,v $ */
-/* $Revision: 1.13 $ */
-/* $Date: 2007/05/12 14:32:35 $ */
diff --git a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c b/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c
deleted file mode 100644
index 6d8888c858d..00000000000
--- a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include "../../headers/tomcrypt.h"
-
-/**
- @file rsa_verify_simple.c
- Created by Ladislav Zezula (zezula@volny.cz) as modification
- for Blizzard strong signature verification
-*/
-
-#ifdef LTC_MRSA
-
-/**
- Simple RSA decryption
- @param sig The signature data
- @param siglen The length of the signature data (octets)
- @param hash The hash of the message that was signed
- @param hashlen The length of the hash of the message that was signed (octets)
- @param stat [out] The result of the signature comparison, 1==valid, 0==invalid
- @param key The public RSA key corresponding
- @return Error code
-*/
-int rsa_verify_simple(const unsigned char *sig, unsigned long siglen,
- const unsigned char *hash, unsigned long hashlen,
- int *stat,
- rsa_key *key)
-{
- unsigned long modulus_bitlen, modulus_bytelen, x;
- unsigned char *tmpbuf;
- int err;
-
- LTC_ARGCHK(sig != NULL);
- LTC_ARGCHK(hash != NULL);
- LTC_ARGCHK(stat != NULL);
- LTC_ARGCHK(key != NULL);
-
- /* default to invalid */
- *stat = 0;
-
- /* get modulus len in bits */
- modulus_bitlen = mp_count_bits( (key->N));
-
- /* outlen must be at least the size of the modulus */
- modulus_bytelen = mp_unsigned_bin_size( (key->N));
- if (modulus_bytelen != siglen) {
- return CRYPT_INVALID_PACKET;
- }
-
- /* allocate temp buffer for decoded sig */
- tmpbuf = XMALLOC(siglen);
- if (tmpbuf == NULL) {
- return CRYPT_MEM;
- }
-
- /* RSA decode it */
- x = siglen;
- if ((err = ltc_mp.rsa_me(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) {
- XFREE(tmpbuf);
- return err;
- }
-
- /* make sure the output is the right size */
- if (x != siglen) {
- XFREE(tmpbuf);
- return CRYPT_INVALID_PACKET;
- }
-
- /* compare the decrypted signature with the given hash */
- if(x == hashlen && XMEMCMP(tmpbuf, hash, hashlen) == 0)
- *stat = 1;
-
-#ifdef LTC_CLEAN_STACK
- zeromem(tmpbuf, siglen);
-#endif
- XFREE(tmpbuf);
- return CRYPT_OK;
-}
-
-#endif /* LTC_MRSA */
diff --git a/dep/StormLib/src/libtommath/bn_fast_mp_invmod.c b/dep/StormLib/src/libtommath/bn_fast_mp_invmod.c
deleted file mode 100644
index 597d7a9b5fa..00000000000
--- a/dep/StormLib/src/libtommath/bn_fast_mp_invmod.c
+++ /dev/null
@@ -1,148 +0,0 @@
-#include "tommath.h"
-#ifdef BN_FAST_MP_INVMOD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* computes the modular inverse via binary extended euclidean algorithm,
- * that is c = 1/a mod b
- *
- * Based on slow invmod except this is optimized for the case where b is
- * odd as per HAC Note 14.64 on pp. 610
- */
-int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
-{
- mp_int x, y, u, v, B, D;
- int res, neg;
-
- /* 2. [modified] b must be odd */
- if (mp_iseven (b) == 1) {
- return MP_VAL;
- }
-
- /* init all our temps */
- if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) {
- return res;
- }
-
- /* x == modulus, y == value to invert */
- if ((res = mp_copy (b, &x)) != MP_OKAY) {
- goto LBL_ERR;
- }
-
- /* we need y = |a| */
- if ((res = mp_mod (a, b, &y)) != MP_OKAY) {
- goto LBL_ERR;
- }
-
- /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
- if ((res = mp_copy (&x, &u)) != MP_OKAY) {
- goto LBL_ERR;
- }
- if ((res = mp_copy (&y, &v)) != MP_OKAY) {
- goto LBL_ERR;
- }
- mp_set (&D, 1);
-
-top:
- /* 4. while u is even do */
- while (mp_iseven (&u) == 1) {
- /* 4.1 u = u/2 */
- if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
- goto LBL_ERR;
- }
- /* 4.2 if B is odd then */
- if (mp_isodd (&B) == 1) {
- if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
- goto LBL_ERR;
- }
- }
- /* B = B/2 */
- if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
- goto LBL_ERR;
- }
- }
-
- /* 5. while v is even do */
- while (mp_iseven (&v) == 1) {
- /* 5.1 v = v/2 */
- if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
- goto LBL_ERR;
- }
- /* 5.2 if D is odd then */
- if (mp_isodd (&D) == 1) {
- /* D = (D-x)/2 */
- if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
- goto LBL_ERR;
- }
- }
- /* D = D/2 */
- if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
- goto LBL_ERR;
- }
- }
-
- /* 6. if u >= v then */
- if (mp_cmp (&u, &v) != MP_LT) {
- /* u = u - v, B = B - D */
- if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
- goto LBL_ERR;
- }
-
- if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
- goto LBL_ERR;
- }
- } else {
- /* v - v - u, D = D - B */
- if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
- goto LBL_ERR;
- }
-
- if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
- goto LBL_ERR;
- }
- }
-
- /* if not zero goto step 4 */
- if (mp_iszero (&u) == 0) {
- goto top;
- }
-
- /* now a = C, b = D, gcd == g*v */
-
- /* if v != 1 then there is no inverse */
- if (mp_cmp_d (&v, 1) != MP_EQ) {
- res = MP_VAL;
- goto LBL_ERR;
- }
-
- /* b is now the inverse */
- neg = a->sign;
- while (D.sign == MP_NEG) {
- if ((res = mp_add (&D, b, &D)) != MP_OKAY) {
- goto LBL_ERR;
- }
- }
- mp_exch (&D, c);
- c->sign = neg;
- res = MP_OKAY;
-
-LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL);
- return res;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_fast_mp_invmod.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_fast_mp_montgomery_reduce.c b/dep/StormLib/src/libtommath/bn_fast_mp_montgomery_reduce.c
deleted file mode 100644
index 65eed7da1fe..00000000000
--- a/dep/StormLib/src/libtommath/bn_fast_mp_montgomery_reduce.c
+++ /dev/null
@@ -1,172 +0,0 @@
-#include "tommath.h"
-#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* computes xR**-1 == x (mod N) via Montgomery Reduction
- *
- * This is an optimized implementation of montgomery_reduce
- * which uses the comba method to quickly calculate the columns of the
- * reduction.
- *
- * Based on Algorithm 14.32 on pp.601 of HAC.
-*/
-int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
-{
- int ix, res, olduse;
- mp_word W[MP_WARRAY];
-
- /* get old used count */
- olduse = x->used;
-
- /* grow a as required */
- if (x->alloc < n->used + 1) {
- if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) {
- return res;
- }
- }
-
- /* first we have to get the digits of the input into
- * an array of double precision words W[...]
- */
- {
- register mp_word *_W;
- register mp_digit *tmpx;
-
- /* alias for the W[] array */
- _W = W;
-
- /* alias for the digits of x*/
- tmpx = x->dp;
-
- /* copy the digits of a into W[0..a->used-1] */
- for (ix = 0; ix < x->used; ix++) {
- *_W++ = *tmpx++;
- }
-
- /* zero the high words of W[a->used..m->used*2] */
- for (; ix < n->used * 2 + 1; ix++) {
- *_W++ = 0;
- }
- }
-
- /* now we proceed to zero successive digits
- * from the least significant upwards
- */
- for (ix = 0; ix < n->used; ix++) {
- /* mu = ai * m' mod b
- *
- * We avoid a double precision multiplication (which isn't required)
- * by casting the value down to a mp_digit. Note this requires
- * that W[ix-1] have the carry cleared (see after the inner loop)
- */
- register mp_digit mu;
- mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);
-
- /* a = a + mu * m * b**i
- *
- * This is computed in place and on the fly. The multiplication
- * by b**i is handled by offseting which columns the results
- * are added to.
- *
- * Note the comba method normally doesn't handle carries in the
- * inner loop In this case we fix the carry from the previous
- * column since the Montgomery reduction requires digits of the
- * result (so far) [see above] to work. This is
- * handled by fixing up one carry after the inner loop. The
- * carry fixups are done in order so after these loops the
- * first m->used words of W[] have the carries fixed
- */
- {
- register int iy;
- register mp_digit *tmpn;
- register mp_word *_W;
-
- /* alias for the digits of the modulus */
- tmpn = n->dp;
-
- /* Alias for the columns set by an offset of ix */
- _W = W + ix;
-
- /* inner loop */
- for (iy = 0; iy < n->used; iy++) {
- *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++);
- }
- }
-
- /* now fix carry for next digit, W[ix+1] */
- W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT);
- }
-
- /* now we have to propagate the carries and
- * shift the words downward [all those least
- * significant digits we zeroed].
- */
- {
- register mp_digit *tmpx;
- register mp_word *_W, *_W1;
-
- /* nox fix rest of carries */
-
- /* alias for current word */
- _W1 = W + ix;
-
- /* alias for next word, where the carry goes */
- _W = W + ++ix;
-
- for (; ix <= n->used * 2 + 1; ix++) {
- *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT);
- }
-
- /* copy out, A = A/b**n
- *
- * The result is A/b**n but instead of converting from an
- * array of mp_word to mp_digit than calling mp_rshd
- * we just copy them in the right order
- */
-
- /* alias for destination word */
- tmpx = x->dp;
-
- /* alias for shifted double precision result */
- _W = W + n->used;
-
- for (ix = 0; ix < n->used + 1; ix++) {
- *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK));
- }
-
- /* zero oldused digits, if the input a was larger than
- * m->used+1 we'll have to clear the digits
- */
- for (; ix < olduse; ix++) {
- *tmpx++ = 0;
- }
- }
-
- /* set the max used and clamp */
- x->used = n->used + 1;
- mp_clamp (x);
-
- /* if A >= m then A = A - m */
- if (mp_cmp_mag (x, n) != MP_LT) {
- return s_mp_sub (x, n, x);
- }
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_fast_mp_montgomery_reduce.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_fast_s_mp_mul_digs.c b/dep/StormLib/src/libtommath/bn_fast_s_mp_mul_digs.c
deleted file mode 100644
index df83f89ecab..00000000000
--- a/dep/StormLib/src/libtommath/bn_fast_s_mp_mul_digs.c
+++ /dev/null
@@ -1,107 +0,0 @@
-#include "tommath.h"
-#ifdef BN_FAST_S_MP_MUL_DIGS_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* Fast (comba) multiplier
- *
- * This is the fast column-array [comba] multiplier. It is
- * designed to compute the columns of the product first
- * then handle the carries afterwards. This has the effect
- * of making the nested loops that compute the columns very
- * simple and schedulable on super-scalar processors.
- *
- * This has been modified to produce a variable number of
- * digits of output so if say only a half-product is required
- * you don't have to compute the upper half (a feature
- * required for fast Barrett reduction).
- *
- * Based on Algorithm 14.12 on pp.595 of HAC.
- *
- */
-int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
-{
- int olduse, res, pa, ix, iz;
- mp_digit W[MP_WARRAY];
- register mp_word _W;
-
- /* grow the destination as required */
- if (c->alloc < digs) {
- if ((res = mp_grow (c, digs)) != MP_OKAY) {
- return res;
- }
- }
-
- /* number of output digits to produce */
- pa = MIN(digs, a->used + b->used);
-
- /* clear the carry */
- _W = 0;
- for (ix = 0; ix < pa; ix++) {
- int tx, ty;
- int iy;
- mp_digit *tmpx, *tmpy;
-
- /* get offsets into the two bignums */
- ty = MIN(b->used-1, ix);
- tx = ix - ty;
-
- /* setup temp aliases */
- tmpx = a->dp + tx;
- tmpy = b->dp + ty;
-
- /* this is the number of times the loop will iterrate, essentially
- while (tx++ < a->used && ty-- >= 0) { ... }
- */
- iy = MIN(a->used-tx, ty+1);
-
- /* execute loop */
- for (iz = 0; iz < iy; ++iz) {
- _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
-
- }
-
- /* store term */
- W[ix] = ((mp_digit)_W) & MP_MASK;
-
- /* make next carry */
- _W = _W >> ((mp_word)DIGIT_BIT);
- }
-
- /* setup dest */
- olduse = c->used;
- c->used = pa;
-
- {
- register mp_digit *tmpc;
- tmpc = c->dp;
- for (ix = 0; ix < pa+1; ix++) {
- /* now extract the previous digit [below the carry] */
- *tmpc++ = W[ix];
- }
-
- /* clear unused digits [that existed in the old copy of c] */
- for (; ix < olduse; ix++) {
- *tmpc++ = 0;
- }
- }
- mp_clamp (c);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_fast_s_mp_mul_digs.c,v $ */
-/* $Revision: 1.8 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_fast_s_mp_mul_high_digs.c b/dep/StormLib/src/libtommath/bn_fast_s_mp_mul_high_digs.c
deleted file mode 100644
index 6866aab7529..00000000000
--- a/dep/StormLib/src/libtommath/bn_fast_s_mp_mul_high_digs.c
+++ /dev/null
@@ -1,98 +0,0 @@
-#include "tommath.h"
-#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* this is a modified version of fast_s_mul_digs that only produces
- * output digits *above* digs. See the comments for fast_s_mul_digs
- * to see how it works.
- *
- * This is used in the Barrett reduction since for one of the multiplications
- * only the higher digits were needed. This essentially halves the work.
- *
- * Based on Algorithm 14.12 on pp.595 of HAC.
- */
-int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
-{
- int olduse, res, pa, ix, iz;
- mp_digit W[MP_WARRAY];
- mp_word _W;
-
- /* grow the destination as required */
- pa = a->used + b->used;
- if (c->alloc < pa) {
- if ((res = mp_grow (c, pa)) != MP_OKAY) {
- return res;
- }
- }
-
- /* number of output digits to produce */
- pa = a->used + b->used;
- _W = 0;
- for (ix = digs; ix < pa; ix++) {
- int tx, ty, iy;
- mp_digit *tmpx, *tmpy;
-
- /* get offsets into the two bignums */
- ty = MIN(b->used-1, ix);
- tx = ix - ty;
-
- /* setup temp aliases */
- tmpx = a->dp + tx;
- tmpy = b->dp + ty;
-
- /* this is the number of times the loop will iterrate, essentially its
- while (tx++ < a->used && ty-- >= 0) { ... }
- */
- iy = MIN(a->used-tx, ty+1);
-
- /* execute loop */
- for (iz = 0; iz < iy; iz++) {
- _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
- }
-
- /* store term */
- W[ix] = ((mp_digit)_W) & MP_MASK;
-
- /* make next carry */
- _W = _W >> ((mp_word)DIGIT_BIT);
- }
-
- /* setup dest */
- olduse = c->used;
- c->used = pa;
-
- {
- register mp_digit *tmpc;
-
- tmpc = c->dp + digs;
- for (ix = digs; ix < pa; ix++) {
- /* now extract the previous digit [below the carry] */
- *tmpc++ = W[ix];
- }
-
- /* clear unused digits [that existed in the old copy of c] */
- for (; ix < olduse; ix++) {
- *tmpc++ = 0;
- }
- }
- mp_clamp (c);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_fast_s_mp_mul_high_digs.c,v $ */
-/* $Revision: 1.6 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_fast_s_mp_sqr.c b/dep/StormLib/src/libtommath/bn_fast_s_mp_sqr.c
deleted file mode 100644
index 5f9d58cac62..00000000000
--- a/dep/StormLib/src/libtommath/bn_fast_s_mp_sqr.c
+++ /dev/null
@@ -1,114 +0,0 @@
-#include "tommath.h"
-#ifdef BN_FAST_S_MP_SQR_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* the jist of squaring...
- * you do like mult except the offset of the tmpx [one that
- * starts closer to zero] can't equal the offset of tmpy.
- * So basically you set up iy like before then you min it with
- * (ty-tx) so that it never happens. You double all those
- * you add in the inner loop
-
-After that loop you do the squares and add them in.
-*/
-
-int fast_s_mp_sqr (mp_int * a, mp_int * b)
-{
- int olduse, res, pa, ix, iz;
- mp_digit W[MP_WARRAY], *tmpx;
- mp_word W1;
-
- /* grow the destination as required */
- pa = a->used + a->used;
- if (b->alloc < pa) {
- if ((res = mp_grow (b, pa)) != MP_OKAY) {
- return res;
- }
- }
-
- /* number of output digits to produce */
- W1 = 0;
- for (ix = 0; ix < pa; ix++) {
- int tx, ty, iy;
- mp_word _W;
- mp_digit *tmpy;
-
- /* clear counter */
- _W = 0;
-
- /* get offsets into the two bignums */
- ty = MIN(a->used-1, ix);
- tx = ix - ty;
-
- /* setup temp aliases */
- tmpx = a->dp + tx;
- tmpy = a->dp + ty;
-
- /* this is the number of times the loop will iterrate, essentially
- while (tx++ < a->used && ty-- >= 0) { ... }
- */
- iy = MIN(a->used-tx, ty+1);
-
- /* now for squaring tx can never equal ty
- * we halve the distance since they approach at a rate of 2x
- * and we have to round because odd cases need to be executed
- */
- iy = MIN(iy, (ty-tx+1)>>1);
-
- /* execute loop */
- for (iz = 0; iz < iy; iz++) {
- _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
- }
-
- /* double the inner product and add carry */
- _W = _W + _W + W1;
-
- /* even columns have the square term in them */
- if ((ix&1) == 0) {
- _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]);
- }
-
- /* store it */
- W[ix] = (mp_digit)(_W & MP_MASK);
-
- /* make next carry */
- W1 = _W >> ((mp_word)DIGIT_BIT);
- }
-
- /* setup dest */
- olduse = b->used;
- b->used = a->used+a->used;
-
- {
- mp_digit *tmpb;
- tmpb = b->dp;
- for (ix = 0; ix < pa; ix++) {
- *tmpb++ = W[ix] & MP_MASK;
- }
-
- /* clear unused digits [that existed in the old copy of c] */
- for (; ix < olduse; ix++) {
- *tmpb++ = 0;
- }
- }
- mp_clamp (b);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_fast_s_mp_sqr.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_2expt.c b/dep/StormLib/src/libtommath/bn_mp_2expt.c
deleted file mode 100644
index f899eaee43e..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_2expt.c
+++ /dev/null
@@ -1,48 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_2EXPT_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* computes a = 2**b
- *
- * Simple algorithm which zeroes the int, grows it then just sets one bit
- * as required.
- */
-int
-mp_2expt (mp_int * a, int b)
-{
- int res;
-
- /* zero a as per default */
- mp_zero (a);
-
- /* grow a to accomodate the single bit */
- if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) {
- return res;
- }
-
- /* set the used count of where the bit will go */
- a->used = b / DIGIT_BIT + 1;
-
- /* put the single bit in its place */
- a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT);
-
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_2expt.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_abs.c b/dep/StormLib/src/libtommath/bn_mp_abs.c
deleted file mode 100644
index 14f3a7e074d..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_abs.c
+++ /dev/null
@@ -1,43 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_ABS_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* b = |a|
- *
- * Simple function copies the input and fixes the sign to positive
- */
-int
-mp_abs (mp_int * a, mp_int * b)
-{
- int res;
-
- /* copy a to b */
- if (a != b) {
- if ((res = mp_copy (a, b)) != MP_OKAY) {
- return res;
- }
- }
-
- /* force the sign of b to positive */
- b->sign = MP_ZPOS;
-
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_abs.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_add.c b/dep/StormLib/src/libtommath/bn_mp_add.c
deleted file mode 100644
index b368b21c7cb..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_add.c
+++ /dev/null
@@ -1,53 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_ADD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* high level addition (handles signs) */
-int mp_add (mp_int * a, mp_int * b, mp_int * c)
-{
- int sa, sb, res;
-
- /* get sign of both inputs */
- sa = a->sign;
- sb = b->sign;
-
- /* handle two cases, not four */
- if (sa == sb) {
- /* both positive or both negative */
- /* add their magnitudes, copy the sign */
- c->sign = sa;
- res = s_mp_add (a, b, c);
- } else {
- /* one positive, the other negative */
- /* subtract the one with the greater magnitude from */
- /* the one of the lesser magnitude. The result gets */
- /* the sign of the one with the greater magnitude. */
- if (mp_cmp_mag (a, b) == MP_LT) {
- c->sign = sb;
- res = s_mp_sub (b, a, c);
- } else {
- c->sign = sa;
- res = s_mp_sub (a, b, c);
- }
- }
- return res;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_add.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_add_d.c b/dep/StormLib/src/libtommath/bn_mp_add_d.c
deleted file mode 100644
index c147554bdb8..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_add_d.c
+++ /dev/null
@@ -1,112 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_ADD_D_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* single digit addition */
-int
-mp_add_d (mp_int * a, mp_digit b, mp_int * c)
-{
- int res, ix, oldused;
- mp_digit *tmpa, *tmpc, mu;
-
- /* grow c as required */
- if (c->alloc < a->used + 1) {
- if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
- return res;
- }
- }
-
- /* if a is negative and |a| >= b, call c = |a| - b */
- if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) {
- /* temporarily fix sign of a */
- a->sign = MP_ZPOS;
-
- /* c = |a| - b */
- res = mp_sub_d(a, b, c);
-
- /* fix sign */
- a->sign = c->sign = MP_NEG;
-
- /* clamp */
- mp_clamp(c);
-
- return res;
- }
-
- /* old number of used digits in c */
- oldused = c->used;
-
- /* sign always positive */
- c->sign = MP_ZPOS;
-
- /* source alias */
- tmpa = a->dp;
-
- /* destination alias */
- tmpc = c->dp;
-
- /* if a is positive */
- if (a->sign == MP_ZPOS) {
- /* add digit, after this we're propagating
- * the carry.
- */
- *tmpc = *tmpa++ + b;
- mu = *tmpc >> DIGIT_BIT;
- *tmpc++ &= MP_MASK;
-
- /* now handle rest of the digits */
- for (ix = 1; ix < a->used; ix++) {
- *tmpc = *tmpa++ + mu;
- mu = *tmpc >> DIGIT_BIT;
- *tmpc++ &= MP_MASK;
- }
- /* set final carry */
- ix++;
- *tmpc++ = mu;
-
- /* setup size */
- c->used = a->used + 1;
- } else {
- /* a was negative and |a| < b */
- c->used = 1;
-
- /* the result is a single digit */
- if (a->used == 1) {
- *tmpc++ = b - a->dp[0];
- } else {
- *tmpc++ = b;
- }
-
- /* setup count so the clearing of oldused
- * can fall through correctly
- */
- ix = 1;
- }
-
- /* now zero to oldused */
- while (ix++ < oldused) {
- *tmpc++ = 0;
- }
- mp_clamp(c);
-
- return MP_OKAY;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_add_d.c,v $ */
-/* $Revision: 1.5 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_addmod.c b/dep/StormLib/src/libtommath/bn_mp_addmod.c
deleted file mode 100644
index 0a21f62e9a6..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_addmod.c
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_ADDMOD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* d = a + b (mod c) */
-int
-mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
-{
- int res;
- mp_int t;
-
- if ((res = mp_init (&t)) != MP_OKAY) {
- return res;
- }
-
- if ((res = mp_add (a, b, &t)) != MP_OKAY) {
- mp_clear (&t);
- return res;
- }
- res = mp_mod (&t, c, d);
- mp_clear (&t);
- return res;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_addmod.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_and.c b/dep/StormLib/src/libtommath/bn_mp_and.c
deleted file mode 100644
index 6b7afc104a8..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_and.c
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_AND_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* AND two ints together */
-int
-mp_and (mp_int * a, mp_int * b, mp_int * c)
-{
- int res, ix, px;
- mp_int t, *x;
-
- if (a->used > b->used) {
- if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
- return res;
- }
- px = b->used;
- x = b;
- } else {
- if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
- return res;
- }
- px = a->used;
- x = a;
- }
-
- for (ix = 0; ix < px; ix++) {
- t.dp[ix] &= x->dp[ix];
- }
-
- /* zero digits above the last from the smallest mp_int */
- for (; ix < t.used; ix++) {
- t.dp[ix] = 0;
- }
-
- mp_clamp (&t);
- mp_exch (c, &t);
- mp_clear (&t);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_and.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_clamp.c b/dep/StormLib/src/libtommath/bn_mp_clamp.c
deleted file mode 100644
index d3cc21c3eff..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_clamp.c
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_CLAMP_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* trim unused digits
- *
- * This is used to ensure that leading zero digits are
- * trimed and the leading "used" digit will be non-zero
- * Typically very fast. Also fixes the sign if there
- * are no more leading digits
- */
-void
-mp_clamp (mp_int * a)
-{
- /* decrease used while the most significant digit is
- * zero.
- */
- while (a->used > 0 && a->dp[a->used - 1] == 0) {
- --(a->used);
- }
-
- /* reset the sign flag if used == 0 */
- if (a->used == 0) {
- a->sign = MP_ZPOS;
- }
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_clamp.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_clear.c b/dep/StormLib/src/libtommath/bn_mp_clear.c
deleted file mode 100644
index 7644c382512..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_clear.c
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_CLEAR_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* clear one (frees) */
-void
-mp_clear (mp_int * a)
-{
- int i;
-
- /* only do anything if a hasn't been freed previously */
- if (a->dp != NULL) {
- /* first zero the digits */
- for (i = 0; i < a->used; i++) {
- a->dp[i] = 0;
- }
-
- /* free ram */
- XFREE(a->dp);
-
- /* reset members to make debugging easier */
- a->dp = NULL;
- a->alloc = a->used = 0;
- a->sign = MP_ZPOS;
- }
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_clear.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_clear_multi.c b/dep/StormLib/src/libtommath/bn_mp_clear_multi.c
deleted file mode 100644
index a1076243675..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_clear_multi.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_CLEAR_MULTI_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include <stdarg.h>
-
-void mp_clear_multi(mp_int *mp, ...)
-{
- mp_int* next_mp = mp;
- va_list args;
- va_start(args, mp);
- while (next_mp != NULL) {
- mp_clear(next_mp);
- next_mp = va_arg(args, mp_int*);
- }
- va_end(args);
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_clear_multi.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_cmp.c b/dep/StormLib/src/libtommath/bn_mp_cmp.c
deleted file mode 100644
index 761d2b0dc75..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_cmp.c
+++ /dev/null
@@ -1,43 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_CMP_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* compare two ints (signed)*/
-int
-mp_cmp (mp_int * a, mp_int * b)
-{
- /* compare based on sign */
- if (a->sign != b->sign) {
- if (a->sign == MP_NEG) {
- return MP_LT;
- } else {
- return MP_GT;
- }
- }
-
- /* compare digits */
- if (a->sign == MP_NEG) {
- /* if negative compare opposite direction */
- return mp_cmp_mag(b, a);
- } else {
- return mp_cmp_mag(a, b);
- }
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_cmp.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_cmp_d.c b/dep/StormLib/src/libtommath/bn_mp_cmp_d.c
deleted file mode 100644
index 420dfd31aa1..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_cmp_d.c
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_CMP_D_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* compare a digit */
-int mp_cmp_d(mp_int * a, mp_digit b)
-{
- /* compare based on sign */
- if (a->sign == MP_NEG) {
- return MP_LT;
- }
-
- /* compare based on magnitude */
- if (a->used > 1) {
- return MP_GT;
- }
-
- /* compare the only digit of a to b */
- if (a->dp[0] > b) {
- return MP_GT;
- } else if (a->dp[0] < b) {
- return MP_LT;
- } else {
- return MP_EQ;
- }
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_cmp_d.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_cmp_mag.c b/dep/StormLib/src/libtommath/bn_mp_cmp_mag.c
deleted file mode 100644
index 92565a3b896..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_cmp_mag.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_CMP_MAG_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* compare maginitude of two ints (unsigned) */
-int mp_cmp_mag (mp_int * a, mp_int * b)
-{
- int n;
- mp_digit *tmpa, *tmpb;
-
- /* compare based on # of non-zero digits */
- if (a->used > b->used) {
- return MP_GT;
- }
-
- if (a->used < b->used) {
- return MP_LT;
- }
-
- /* alias for a */
- tmpa = a->dp + (a->used - 1);
-
- /* alias for b */
- tmpb = b->dp + (a->used - 1);
-
- /* compare based on digits */
- for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
- if (*tmpa > *tmpb) {
- return MP_GT;
- }
-
- if (*tmpa < *tmpb) {
- return MP_LT;
- }
- }
- return MP_EQ;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_cmp_mag.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_cnt_lsb.c b/dep/StormLib/src/libtommath/bn_mp_cnt_lsb.c
deleted file mode 100644
index 60406610ed6..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_cnt_lsb.c
+++ /dev/null
@@ -1,53 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_CNT_LSB_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-static const int lnz[16] = {
- 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
-};
-
-/* Counts the number of lsbs which are zero before the first zero bit */
-int mp_cnt_lsb(mp_int *a)
-{
- int x;
- mp_digit q, qq;
-
- /* easy out */
- if (mp_iszero(a) == 1) {
- return 0;
- }
-
- /* scan lower digits until non-zero */
- for (x = 0; x < a->used && a->dp[x] == 0; x++);
- q = a->dp[x];
- x *= DIGIT_BIT;
-
- /* now scan this digit until a 1 is found */
- if ((q & 1) == 0) {
- do {
- qq = q & 15;
- x += lnz[qq];
- q >>= 4;
- } while (qq == 0);
- }
- return x;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_cnt_lsb.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_copy.c b/dep/StormLib/src/libtommath/bn_mp_copy.c
deleted file mode 100644
index 7828592da5d..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_copy.c
+++ /dev/null
@@ -1,68 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_COPY_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* copy, b = a */
-int
-mp_copy (mp_int * a, mp_int * b)
-{
- int res, n;
-
- /* if dst == src do nothing */
- if (a == b) {
- return MP_OKAY;
- }
-
- /* grow dest */
- if (b->alloc < a->used) {
- if ((res = mp_grow (b, a->used)) != MP_OKAY) {
- return res;
- }
- }
-
- /* zero b and copy the parameters over */
- {
- register mp_digit *tmpa, *tmpb;
-
- /* pointer aliases */
-
- /* source */
- tmpa = a->dp;
-
- /* destination */
- tmpb = b->dp;
-
- /* copy all the digits */
- for (n = 0; n < a->used; n++) {
- *tmpb++ = *tmpa++;
- }
-
- /* clear high digits */
- for (; n < b->used; n++) {
- *tmpb++ = 0;
- }
- }
-
- /* copy used count and sign */
- b->used = a->used;
- b->sign = a->sign;
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_copy.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_count_bits.c b/dep/StormLib/src/libtommath/bn_mp_count_bits.c
deleted file mode 100644
index 9d8640fdfce..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_count_bits.c
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_COUNT_BITS_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* returns the number of bits in an int */
-int
-mp_count_bits (mp_int * a)
-{
- int r;
- mp_digit q;
-
- /* shortcut */
- if (a->used == 0) {
- return 0;
- }
-
- /* get number of digits and add that */
- r = (a->used - 1) * DIGIT_BIT;
-
- /* take the last digit and count the bits in it */
- q = a->dp[a->used - 1];
- while (q > ((mp_digit) 0)) {
- ++r;
- q >>= ((mp_digit) 1);
- }
- return r;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_count_bits.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_div.c b/dep/StormLib/src/libtommath/bn_mp_div.c
deleted file mode 100644
index 3004a3ea016..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_div.c
+++ /dev/null
@@ -1,292 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_DIV_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-#ifdef BN_MP_DIV_SMALL
-
-/* slower bit-bang division... also smaller */
-int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d)
-{
- mp_int ta, tb, tq, q;
- int res, n, n2;
-
- /* is divisor zero ? */
- if (mp_iszero (b) == 1) {
- return MP_VAL;
- }
-
- /* if a < b then q=0, r = a */
- if (mp_cmp_mag (a, b) == MP_LT) {
- if (d != NULL) {
- res = mp_copy (a, d);
- } else {
- res = MP_OKAY;
- }
- if (c != NULL) {
- mp_zero (c);
- }
- return res;
- }
-
- /* init our temps */
- if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) {
- return res;
- }
-
-
- mp_set(&tq, 1);
- n = mp_count_bits(a) - mp_count_bits(b);
- if (((res = mp_abs(a, &ta)) != MP_OKAY) ||
- ((res = mp_abs(b, &tb)) != MP_OKAY) ||
- ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
- ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
- goto LBL_ERR;
- }
-
- while (n-- >= 0) {
- if (mp_cmp(&tb, &ta) != MP_GT) {
- if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
- ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {
- goto LBL_ERR;
- }
- }
- if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
- ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
- goto LBL_ERR;
- }
- }
-
- /* now q == quotient and ta == remainder */
- n = a->sign;
- n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG);
- if (c != NULL) {
- mp_exch(c, &q);
- c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;
- }
- if (d != NULL) {
- mp_exch(d, &ta);
- d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;
- }
-LBL_ERR:
- mp_clear_multi(&ta, &tb, &tq, &q, NULL);
- return res;
-}
-
-#else
-
-/* integer signed division.
- * c*b + d == a [e.g. a/b, c=quotient, d=remainder]
- * HAC pp.598 Algorithm 14.20
- *
- * Note that the description in HAC is horribly
- * incomplete. For example, it doesn't consider
- * the case where digits are removed from 'x' in
- * the inner loop. It also doesn't consider the
- * case that y has fewer than three digits, etc..
- *
- * The overall algorithm is as described as
- * 14.20 from HAC but fixed to treat these cases.
-*/
-int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
-{
- mp_int q, x, y, t1, t2;
- int res, n, t, i, norm, neg;
-
- /* is divisor zero ? */
- if (mp_iszero (b) == 1) {
- return MP_VAL;
- }
-
- /* if a < b then q=0, r = a */
- if (mp_cmp_mag (a, b) == MP_LT) {
- if (d != NULL) {
- res = mp_copy (a, d);
- } else {
- res = MP_OKAY;
- }
- if (c != NULL) {
- mp_zero (c);
- }
- return res;
- }
-
- if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) {
- return res;
- }
- q.used = a->used + 2;
-
- if ((res = mp_init (&t1)) != MP_OKAY) {
- goto LBL_Q;
- }
-
- if ((res = mp_init (&t2)) != MP_OKAY) {
- goto LBL_T1;
- }
-
- if ((res = mp_init_copy (&x, a)) != MP_OKAY) {
- goto LBL_T2;
- }
-
- if ((res = mp_init_copy (&y, b)) != MP_OKAY) {
- goto LBL_X;
- }
-
- /* fix the sign */
- neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
- x.sign = y.sign = MP_ZPOS;
-
- /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
- norm = mp_count_bits(&y) % DIGIT_BIT;
- if (norm < (int)(DIGIT_BIT-1)) {
- norm = (DIGIT_BIT-1) - norm;
- if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) {
- goto LBL_Y;
- }
- if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) {
- goto LBL_Y;
- }
- } else {
- norm = 0;
- }
-
- /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
- n = x.used - 1;
- t = y.used - 1;
-
- /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
- if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */
- goto LBL_Y;
- }
-
- while (mp_cmp (&x, &y) != MP_LT) {
- ++(q.dp[n - t]);
- if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) {
- goto LBL_Y;
- }
- }
-
- /* reset y by shifting it back down */
- mp_rshd (&y, n - t);
-
- /* step 3. for i from n down to (t + 1) */
- for (i = n; i >= (t + 1); i--) {
- if (i > x.used) {
- continue;
- }
-
- /* step 3.1 if xi == yt then set q{i-t-1} to b-1,
- * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
- if (x.dp[i] == y.dp[t]) {
- q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1);
- } else {
- mp_word tmp;
- tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT);
- tmp |= ((mp_word) x.dp[i - 1]);
- tmp /= ((mp_word) y.dp[t]);
- if (tmp > (mp_word) MP_MASK)
- tmp = MP_MASK;
- q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK));
- }
-
- /* while (q{i-t-1} * (yt * b + y{t-1})) >
- xi * b**2 + xi-1 * b + xi-2
-
- do q{i-t-1} -= 1;
- */
- q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK;
- do {
- q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK;
-
- /* find left hand */
- mp_zero (&t1);
- t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1];
- t1.dp[1] = y.dp[t];
- t1.used = 2;
- if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) {
- goto LBL_Y;
- }
-
- /* find right hand */
- t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2];
- t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1];
- t2.dp[2] = x.dp[i];
- t2.used = 3;
- } while (mp_cmp_mag(&t1, &t2) == MP_GT);
-
- /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
- if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) {
- goto LBL_Y;
- }
-
- if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) {
- goto LBL_Y;
- }
-
- if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) {
- goto LBL_Y;
- }
-
- /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
- if (x.sign == MP_NEG) {
- if ((res = mp_copy (&y, &t1)) != MP_OKAY) {
- goto LBL_Y;
- }
- if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) {
- goto LBL_Y;
- }
- if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) {
- goto LBL_Y;
- }
-
- q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK;
- }
- }
-
- /* now q is the quotient and x is the remainder
- * [which we have to normalize]
- */
-
- /* get sign before writing to c */
- x.sign = x.used == 0 ? MP_ZPOS : a->sign;
-
- if (c != NULL) {
- mp_clamp (&q);
- mp_exch (&q, c);
- c->sign = neg;
- }
-
- if (d != NULL) {
- mp_div_2d (&x, norm, &x, NULL);
- mp_exch (&x, d);
- }
-
- res = MP_OKAY;
-
-LBL_Y:mp_clear (&y);
-LBL_X:mp_clear (&x);
-LBL_T2:mp_clear (&t2);
-LBL_T1:mp_clear (&t1);
-LBL_Q:mp_clear (&q);
- return res;
-}
-
-#endif
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_div.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_div_2.c b/dep/StormLib/src/libtommath/bn_mp_div_2.c
deleted file mode 100644
index f3b9d16fa37..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_div_2.c
+++ /dev/null
@@ -1,68 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_DIV_2_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* b = a/2 */
-int mp_div_2(mp_int * a, mp_int * b)
-{
- int x, res, oldused;
-
- /* copy */
- if (b->alloc < a->used) {
- if ((res = mp_grow (b, a->used)) != MP_OKAY) {
- return res;
- }
- }
-
- oldused = b->used;
- b->used = a->used;
- {
- register mp_digit r, rr, *tmpa, *tmpb;
-
- /* source alias */
- tmpa = a->dp + b->used - 1;
-
- /* dest alias */
- tmpb = b->dp + b->used - 1;
-
- /* carry */
- r = 0;
- for (x = b->used - 1; x >= 0; x--) {
- /* get the carry for the next iteration */
- rr = *tmpa & 1;
-
- /* shift the current digit, add in carry and store */
- *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
-
- /* forward carry to next iteration */
- r = rr;
- }
-
- /* zero excess digits */
- tmpb = b->dp + b->used;
- for (x = b->used; x < oldused; x++) {
- *tmpb++ = 0;
- }
- }
- b->sign = a->sign;
- mp_clamp (b);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_div_2.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_div_2d.c b/dep/StormLib/src/libtommath/bn_mp_div_2d.c
deleted file mode 100644
index 861ea23a31a..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_div_2d.c
+++ /dev/null
@@ -1,97 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_DIV_2D_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* shift right by a certain bit count (store quotient in c, optional remainder in d) */
-int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
-{
- mp_digit D, r, rr;
- int x, res;
- mp_int t;
-
-
- /* if the shift count is <= 0 then we do no work */
- if (b <= 0) {
- res = mp_copy (a, c);
- if (d != NULL) {
- mp_zero (d);
- }
- return res;
- }
-
- if ((res = mp_init (&t)) != MP_OKAY) {
- return res;
- }
-
- /* get the remainder */
- if (d != NULL) {
- if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) {
- mp_clear (&t);
- return res;
- }
- }
-
- /* copy */
- if ((res = mp_copy (a, c)) != MP_OKAY) {
- mp_clear (&t);
- return res;
- }
-
- /* shift by as many digits in the bit count */
- if (b >= (int)DIGIT_BIT) {
- mp_rshd (c, b / DIGIT_BIT);
- }
-
- /* shift any bit count < DIGIT_BIT */
- D = (mp_digit) (b % DIGIT_BIT);
- if (D != 0) {
- register mp_digit *tmpc, mask, shift;
-
- /* mask */
- mask = (((mp_digit)1) << D) - 1;
-
- /* shift for lsb */
- shift = DIGIT_BIT - D;
-
- /* alias */
- tmpc = c->dp + (c->used - 1);
-
- /* carry */
- r = 0;
- for (x = c->used - 1; x >= 0; x--) {
- /* get the lower bits of this word in a temp */
- rr = *tmpc & mask;
-
- /* shift the current word and mix in the carry bits from the previous word */
- *tmpc = (*tmpc >> D) | (r << shift);
- --tmpc;
-
- /* set the carry to the carry bits of the current word found above */
- r = rr;
- }
- }
- mp_clamp (c);
- if (d != NULL) {
- mp_exch (&t, d);
- }
- mp_clear (&t);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_div_2d.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_div_3.c b/dep/StormLib/src/libtommath/bn_mp_div_3.c
deleted file mode 100644
index 4fc08fc4da4..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_div_3.c
+++ /dev/null
@@ -1,79 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_DIV_3_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* divide by three (based on routine from MPI and the GMP manual) */
-int
-mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
-{
- mp_int q;
- mp_word w, t;
- mp_digit b;
- int res, ix;
-
- /* b = 2**DIGIT_BIT / 3 */
- b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3);
-
- if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
- return res;
- }
-
- q.used = a->used;
- q.sign = a->sign;
- w = 0;
- for (ix = a->used - 1; ix >= 0; ix--) {
- w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
-
- if (w >= 3) {
- /* multiply w by [1/3] */
- t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
-
- /* now subtract 3 * [w/3] from w, to get the remainder */
- w -= t+t+t;
-
- /* fixup the remainder as required since
- * the optimization is not exact.
- */
- while (w >= 3) {
- t += 1;
- w -= 3;
- }
- } else {
- t = 0;
- }
- q.dp[ix] = (mp_digit)t;
- }
-
- /* [optional] store the remainder */
- if (d != NULL) {
- *d = (mp_digit)w;
- }
-
- /* [optional] store the quotient */
- if (c != NULL) {
- mp_clamp(&q);
- mp_exch(&q, c);
- }
- mp_clear(&q);
-
- return res;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_div_3.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_div_d.c b/dep/StormLib/src/libtommath/bn_mp_div_d.c
deleted file mode 100644
index c0318a4a1be..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_div_d.c
+++ /dev/null
@@ -1,115 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_DIV_D_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-static int s_is_power_of_two(mp_digit b, int *p)
-{
- int x;
-
- /* fast return if no power of two */
- if ((b==0) || (b & (b-1))) {
- return 0;
- }
-
- for (x = 0; x < DIGIT_BIT; x++) {
- if (b == (((mp_digit)1)<<x)) {
- *p = x;
- return 1;
- }
- }
- return 0;
-}
-
-/* single digit division (based on routine from MPI) */
-int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
-{
- mp_int q;
- mp_word w;
- mp_digit t;
- int res, ix;
-
- /* cannot divide by zero */
- if (b == 0) {
- return MP_VAL;
- }
-
- /* quick outs */
- if (b == 1 || mp_iszero(a) == 1) {
- if (d != NULL) {
- *d = 0;
- }
- if (c != NULL) {
- return mp_copy(a, c);
- }
- return MP_OKAY;
- }
-
- /* power of two ? */
- if (s_is_power_of_two(b, &ix) == 1) {
- if (d != NULL) {
- *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1);
- }
- if (c != NULL) {
- return mp_div_2d(a, ix, c, NULL);
- }
- return MP_OKAY;
- }
-
-#ifdef BN_MP_DIV_3_C
- /* three? */
- if (b == 3) {
- return mp_div_3(a, c, d);
- }
-#endif
-
- /* no easy answer [c'est la vie]. Just division */
- if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
- return res;
- }
-
- q.used = a->used;
- q.sign = a->sign;
- w = 0;
- for (ix = a->used - 1; ix >= 0; ix--) {
- w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
-
- if (w >= b) {
- t = (mp_digit)(w / b);
- w -= ((mp_word)t) * ((mp_word)b);
- } else {
- t = 0;
- }
- q.dp[ix] = (mp_digit)t;
- }
-
- if (d != NULL) {
- *d = (mp_digit)w;
- }
-
- if (c != NULL) {
- mp_clamp(&q);
- mp_exch(&q, c);
- }
- mp_clear(&q);
-
- return res;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_div_d.c,v $ */
-/* $Revision: 1.5 $ */
-/* $Date: 2007/01/09 04:44:32 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_dr_is_modulus.c b/dep/StormLib/src/libtommath/bn_mp_dr_is_modulus.c
deleted file mode 100644
index 22ba5df3d0a..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_dr_is_modulus.c
+++ /dev/null
@@ -1,43 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_DR_IS_MODULUS_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* determines if a number is a valid DR modulus */
-int mp_dr_is_modulus(mp_int *a)
-{
- int ix;
-
- /* must be at least two digits */
- if (a->used < 2) {
- return 0;
- }
-
- /* must be of the form b**k - a [a <= b] so all
- * but the first digit must be equal to -1 (mod b).
- */
- for (ix = 1; ix < a->used; ix++) {
- if (a->dp[ix] != MP_MASK) {
- return 0;
- }
- }
- return 1;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_dr_is_modulus.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_dr_reduce.c b/dep/StormLib/src/libtommath/bn_mp_dr_reduce.c
deleted file mode 100644
index 0afac941fca..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_dr_reduce.c
+++ /dev/null
@@ -1,94 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_DR_REDUCE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
- *
- * Based on algorithm from the paper
- *
- * "Generating Efficient Primes for Discrete Log Cryptosystems"
- * Chae Hoon Lim, Pil Joong Lee,
- * POSTECH Information Research Laboratories
- *
- * The modulus must be of a special format [see manual]
- *
- * Has been modified to use algorithm 7.10 from the LTM book instead
- *
- * Input x must be in the range 0 <= x <= (n-1)**2
- */
-int
-mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
-{
- int err, i, m;
- mp_word r;
- mp_digit mu, *tmpx1, *tmpx2;
-
- /* m = digits in modulus */
- m = n->used;
-
- /* ensure that "x" has at least 2m digits */
- if (x->alloc < m + m) {
- if ((err = mp_grow (x, m + m)) != MP_OKAY) {
- return err;
- }
- }
-
-/* top of loop, this is where the code resumes if
- * another reduction pass is required.
- */
-top:
- /* aliases for digits */
- /* alias for lower half of x */
- tmpx1 = x->dp;
-
- /* alias for upper half of x, or x/B**m */
- tmpx2 = x->dp + m;
-
- /* set carry to zero */
- mu = 0;
-
- /* compute (x mod B**m) + k * [x/B**m] inline and inplace */
- for (i = 0; i < m; i++) {
- r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu;
- *tmpx1++ = (mp_digit)(r & MP_MASK);
- mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
- }
-
- /* set final carry */
- *tmpx1++ = mu;
-
- /* zero words above m */
- for (i = m + 1; i < x->used; i++) {
- *tmpx1++ = 0;
- }
-
- /* clamp, sub and return */
- mp_clamp (x);
-
- /* if x >= n then subtract and reduce again
- * Each successive "recursion" makes the input smaller and smaller.
- */
- if (mp_cmp_mag (x, n) != MP_LT) {
- s_mp_sub(x, n, x);
- goto top;
- }
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_dr_reduce.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_dr_setup.c b/dep/StormLib/src/libtommath/bn_mp_dr_setup.c
deleted file mode 100644
index a5152f713bd..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_dr_setup.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_DR_SETUP_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* determines the setup value */
-void mp_dr_setup(mp_int *a, mp_digit *d)
-{
- /* the casts are required if DIGIT_BIT is one less than
- * the number of bits in a mp_digit [e.g. DIGIT_BIT==31]
- */
- *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) -
- ((mp_word)a->dp[0]));
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_dr_setup.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_exch.c b/dep/StormLib/src/libtommath/bn_mp_exch.c
deleted file mode 100644
index e5ec7f57730..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_exch.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_EXCH_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* swap the elements of two integers, for cases where you can't simply swap the
- * mp_int pointers around
- */
-void
-mp_exch (mp_int * a, mp_int * b)
-{
- mp_int t;
-
- t = *a;
- *a = *b;
- *b = t;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_exch.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_expt_d.c b/dep/StormLib/src/libtommath/bn_mp_expt_d.c
deleted file mode 100644
index 7bf371ce6ae..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_expt_d.c
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_EXPT_D_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* calculate c = a**b using a square-multiply algorithm */
-int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
-{
- int res, x;
- mp_int g;
-
- if ((res = mp_init_copy (&g, a)) != MP_OKAY) {
- return res;
- }
-
- /* set initial result */
- mp_set (c, 1);
-
- for (x = 0; x < (int) DIGIT_BIT; x++) {
- /* square */
- if ((res = mp_sqr (c, c)) != MP_OKAY) {
- mp_clear (&g);
- return res;
- }
-
- /* if the bit is set multiply */
- if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) {
- if ((res = mp_mul (c, &g, c)) != MP_OKAY) {
- mp_clear (&g);
- return res;
- }
- }
-
- /* shift to next bit */
- b <<= 1;
- }
-
- mp_clear (&g);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_expt_d.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_exptmod.c b/dep/StormLib/src/libtommath/bn_mp_exptmod.c
deleted file mode 100644
index 27c46ea0ab2..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_exptmod.c
+++ /dev/null
@@ -1,112 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_EXPTMOD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-
-/* this is a shell function that calls either the normal or Montgomery
- * exptmod functions. Originally the call to the montgomery code was
- * embedded in the normal function but that wasted alot of stack space
- * for nothing (since 99% of the time the Montgomery code would be called)
- */
-int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
-{
- int dr;
-
- /* modulus P must be positive */
- if (P->sign == MP_NEG) {
- return MP_VAL;
- }
-
- /* if exponent X is negative we have to recurse */
- if (X->sign == MP_NEG) {
-#ifdef BN_MP_INVMOD_C
- mp_int tmpG, tmpX;
- int err;
-
- /* first compute 1/G mod P */
- if ((err = mp_init(&tmpG)) != MP_OKAY) {
- return err;
- }
- if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
- mp_clear(&tmpG);
- return err;
- }
-
- /* now get |X| */
- if ((err = mp_init(&tmpX)) != MP_OKAY) {
- mp_clear(&tmpG);
- return err;
- }
- if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
- mp_clear_multi(&tmpG, &tmpX, NULL);
- return err;
- }
-
- /* and now compute (1/G)**|X| instead of G**X [X < 0] */
- err = mp_exptmod(&tmpG, &tmpX, P, Y);
- mp_clear_multi(&tmpG, &tmpX, NULL);
- return err;
-#else
- /* no invmod */
- return MP_VAL;
-#endif
- }
-
-/* modified diminished radix reduction */
-#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C)
- if (mp_reduce_is_2k_l(P) == MP_YES) {
- return s_mp_exptmod(G, X, P, Y, 1);
- }
-#endif
-
-#ifdef BN_MP_DR_IS_MODULUS_C
- /* is it a DR modulus? */
- dr = mp_dr_is_modulus(P);
-#else
- /* default to no */
- dr = 0;
-#endif
-
-#ifdef BN_MP_REDUCE_IS_2K_C
- /* if not, is it a unrestricted DR modulus? */
- if (dr == 0) {
- dr = mp_reduce_is_2k(P) << 1;
- }
-#endif
-
- /* if the modulus is odd or dr != 0 use the montgomery method */
-#ifdef BN_MP_EXPTMOD_FAST_C
- if (mp_isodd (P) == 1 || dr != 0) {
- return mp_exptmod_fast (G, X, P, Y, dr);
- } else {
-#endif
-#ifdef BN_S_MP_EXPTMOD_C
- /* otherwise use the generic Barrett reduction technique */
- return s_mp_exptmod (G, X, P, Y, 0);
-#else
- /* no exptmod for evens */
- return MP_VAL;
-#endif
-#ifdef BN_MP_EXPTMOD_FAST_C
- }
-#endif
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_exptmod.c,v $ */
-/* $Revision: 1.5 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_exptmod_fast.c b/dep/StormLib/src/libtommath/bn_mp_exptmod_fast.c
deleted file mode 100644
index 31205d4e20c..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_exptmod_fast.c
+++ /dev/null
@@ -1,321 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_EXPTMOD_FAST_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
- *
- * Uses a left-to-right k-ary sliding window to compute the modular exponentiation.
- * The value of k changes based on the size of the exponent.
- *
- * Uses Montgomery or Diminished Radix reduction [whichever appropriate]
- */
-
-#ifdef MP_LOW_MEM
- #define TAB_SIZE 32
-#else
- #define TAB_SIZE 256
-#endif
-
-int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
-{
- mp_int M[TAB_SIZE], res;
- mp_digit buf, mp;
- int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
-
- /* use a pointer to the reduction algorithm. This allows us to use
- * one of many reduction algorithms without modding the guts of
- * the code with if statements everywhere.
- */
- int (*redux)(mp_int*,mp_int*,mp_digit);
-
- /* find window size */
- x = mp_count_bits (X);
- if (x <= 7) {
- winsize = 2;
- } else if (x <= 36) {
- winsize = 3;
- } else if (x <= 140) {
- winsize = 4;
- } else if (x <= 450) {
- winsize = 5;
- } else if (x <= 1303) {
- winsize = 6;
- } else if (x <= 3529) {
- winsize = 7;
- } else {
- winsize = 8;
- }
-
-#ifdef MP_LOW_MEM
- if (winsize > 5) {
- winsize = 5;
- }
-#endif
-
- /* init M array */
- /* init first cell */
- if ((err = mp_init(&M[1])) != MP_OKAY) {
- return err;
- }
-
- /* now init the second half of the array */
- for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
- if ((err = mp_init(&M[x])) != MP_OKAY) {
- for (y = 1<<(winsize-1); y < x; y++) {
- mp_clear (&M[y]);
- }
- mp_clear(&M[1]);
- return err;
- }
- }
-
- /* determine and setup reduction code */
- if (redmode == 0) {
-#ifdef BN_MP_MONTGOMERY_SETUP_C
- /* now setup montgomery */
- if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) {
- goto LBL_M;
- }
-#else
- err = MP_VAL;
- goto LBL_M;
-#endif
-
- /* automatically pick the comba one if available (saves quite a few calls/ifs) */
-#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
- if (((P->used * 2 + 1) < MP_WARRAY) &&
- P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
- redux = fast_mp_montgomery_reduce;
- } else
-#endif
- {
-#ifdef BN_MP_MONTGOMERY_REDUCE_C
- /* use slower baseline Montgomery method */
- redux = mp_montgomery_reduce;
-#else
- err = MP_VAL;
- goto LBL_M;
-#endif
- }
- } else if (redmode == 1) {
-#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C)
- /* setup DR reduction for moduli of the form B**k - b */
- mp_dr_setup(P, &mp);
- redux = mp_dr_reduce;
-#else
- err = MP_VAL;
- goto LBL_M;
-#endif
- } else {
-#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)
- /* setup DR reduction for moduli of the form 2**k - b */
- if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
- goto LBL_M;
- }
- redux = mp_reduce_2k;
-#else
- err = MP_VAL;
- goto LBL_M;
-#endif
- }
-
- /* setup result */
- if ((err = mp_init (&res)) != MP_OKAY) {
- goto LBL_M;
- }
-
- /* create M table
- *
-
- *
- * The first half of the table is not computed though accept for M[0] and M[1]
- */
-
- if (redmode == 0) {
-#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
- /* now we need R mod m */
- if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) {
- goto LBL_RES;
- }
-#else
- err = MP_VAL;
- goto LBL_RES;
-#endif
-
- /* now set M[1] to G * R mod m */
- if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) {
- goto LBL_RES;
- }
- } else {
- mp_set(&res, 1);
- if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
- goto LBL_RES;
- }
- }
-
- /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
- if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
- goto LBL_RES;
- }
-
- for (x = 0; x < (winsize - 1); x++) {
- if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) {
- goto LBL_RES;
- }
- if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) {
- goto LBL_RES;
- }
- }
-
- /* create upper table */
- for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
- if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
- goto LBL_RES;
- }
- if ((err = redux (&M[x], P, mp)) != MP_OKAY) {
- goto LBL_RES;
- }
- }
-
- /* set initial mode and bit cnt */
- mode = 0;
- bitcnt = 1;
- buf = 0;
- digidx = X->used - 1;
- bitcpy = 0;
- bitbuf = 0;
-
- for (;;) {
- /* grab next digit as required */
- if (--bitcnt == 0) {
- /* if digidx == -1 we are out of digits so break */
- if (digidx == -1) {
- break;
- }
- /* read next digit and reset bitcnt */
- buf = X->dp[digidx--];
- bitcnt = (int)DIGIT_BIT;
- }
-
- /* grab the next msb from the exponent */
- y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1;
- buf <<= (mp_digit)1;
-
- /* if the bit is zero and mode == 0 then we ignore it
- * These represent the leading zero bits before the first 1 bit
- * in the exponent. Technically this opt is not required but it
- * does lower the # of trivial squaring/reductions used
- */
- if (mode == 0 && y == 0) {
- continue;
- }
-
- /* if the bit is zero and mode == 1 then we square */
- if (mode == 1 && y == 0) {
- if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
- goto LBL_RES;
- }
- if ((err = redux (&res, P, mp)) != MP_OKAY) {
- goto LBL_RES;
- }
- continue;
- }
-
- /* else we add it to the window */
- bitbuf |= (y << (winsize - ++bitcpy));
- mode = 2;
-
- if (bitcpy == winsize) {
- /* ok window is filled so square as required and multiply */
- /* square first */
- for (x = 0; x < winsize; x++) {
- if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
- goto LBL_RES;
- }
- if ((err = redux (&res, P, mp)) != MP_OKAY) {
- goto LBL_RES;
- }
- }
-
- /* then multiply */
- if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
- goto LBL_RES;
- }
- if ((err = redux (&res, P, mp)) != MP_OKAY) {
- goto LBL_RES;
- }
-
- /* empty window and reset */
- bitcpy = 0;
- bitbuf = 0;
- mode = 1;
- }
- }
-
- /* if bits remain then square/multiply */
- if (mode == 2 && bitcpy > 0) {
- /* square then multiply if the bit is set */
- for (x = 0; x < bitcpy; x++) {
- if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
- goto LBL_RES;
- }
- if ((err = redux (&res, P, mp)) != MP_OKAY) {
- goto LBL_RES;
- }
-
- /* get next bit of the window */
- bitbuf <<= 1;
- if ((bitbuf & (1 << winsize)) != 0) {
- /* then multiply */
- if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
- goto LBL_RES;
- }
- if ((err = redux (&res, P, mp)) != MP_OKAY) {
- goto LBL_RES;
- }
- }
- }
- }
-
- if (redmode == 0) {
- /* fixup result if Montgomery reduction is used
- * recall that any value in a Montgomery system is
- * actually multiplied by R mod n. So we have
- * to reduce one more time to cancel out the factor
- * of R.
- */
- if ((err = redux(&res, P, mp)) != MP_OKAY) {
- goto LBL_RES;
- }
- }
-
- /* swap res with Y */
- mp_exch (&res, Y);
- err = MP_OKAY;
-LBL_RES:mp_clear (&res);
-LBL_M:
- mp_clear(&M[1]);
- for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
- mp_clear (&M[x]);
- }
- return err;
-}
-#endif
-
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_exptmod_fast.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_exteuclid.c b/dep/StormLib/src/libtommath/bn_mp_exteuclid.c
deleted file mode 100644
index 9881d6edc80..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_exteuclid.c
+++ /dev/null
@@ -1,82 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_EXTEUCLID_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* Extended euclidean algorithm of (a, b) produces
- a*u1 + b*u2 = u3
- */
-int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
-{
- mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp;
- int err;
-
- if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) {
- return err;
- }
-
- /* initialize, (u1,u2,u3) = (1,0,a) */
- mp_set(&u1, 1);
- if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto _ERR; }
-
- /* initialize, (v1,v2,v3) = (0,1,b) */
- mp_set(&v2, 1);
- if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto _ERR; }
-
- /* loop while v3 != 0 */
- while (mp_iszero(&v3) == MP_NO) {
- /* q = u3/v3 */
- if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; }
-
- /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
- if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; }
- if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; }
- if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; }
- if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; }
- if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; }
- if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; }
-
- /* (u1,u2,u3) = (v1,v2,v3) */
- if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; }
- if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; }
- if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; }
-
- /* (v1,v2,v3) = (t1,t2,t3) */
- if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; }
- if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; }
- if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; }
- }
-
- /* make sure U3 >= 0 */
- if (u3.sign == MP_NEG) {
- mp_neg(&u1, &u1);
- mp_neg(&u2, &u2);
- mp_neg(&u3, &u3);
- }
-
- /* copy result out */
- if (U1 != NULL) { mp_exch(U1, &u1); }
- if (U2 != NULL) { mp_exch(U2, &u2); }
- if (U3 != NULL) { mp_exch(U3, &u3); }
-
- err = MP_OKAY;
-_ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL);
- return err;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_exteuclid.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_fread.c b/dep/StormLib/src/libtommath/bn_mp_fread.c
deleted file mode 100644
index 2976b30aa68..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_fread.c
+++ /dev/null
@@ -1,67 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_FREAD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* read a bigint from a file stream in ASCII */
-int mp_fread(mp_int *a, int radix, FILE *stream)
-{
- int err, ch, neg, y;
-
- /* clear a */
- mp_zero(a);
-
- /* if first digit is - then set negative */
- ch = fgetc(stream);
- if (ch == '-') {
- neg = MP_NEG;
- ch = fgetc(stream);
- } else {
- neg = MP_ZPOS;
- }
-
- for (;;) {
- /* find y in the radix map */
- for (y = 0; y < radix; y++) {
- if (mp_s_rmap[y] == ch) {
- break;
- }
- }
- if (y == radix) {
- break;
- }
-
- /* shift up and add */
- if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) {
- return err;
- }
- if ((err = mp_add_d(a, y, a)) != MP_OKAY) {
- return err;
- }
-
- ch = fgetc(stream);
- }
- if (mp_cmp_d(a, 0) != MP_EQ) {
- a->sign = neg;
- }
-
- return MP_OKAY;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_fread.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_fwrite.c b/dep/StormLib/src/libtommath/bn_mp_fwrite.c
deleted file mode 100644
index 6782b2e19f7..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_fwrite.c
+++ /dev/null
@@ -1,52 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_FWRITE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-int mp_fwrite(mp_int *a, int radix, FILE *stream)
-{
- char *buf;
- int err, len, x;
-
- if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
- return err;
- }
-
- buf = OPT_CAST(char) XMALLOC (len);
- if (buf == NULL) {
- return MP_MEM;
- }
-
- if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) {
- XFREE (buf);
- return err;
- }
-
- for (x = 0; x < len; x++) {
- if (fputc(buf[x], stream) == EOF) {
- XFREE (buf);
- return MP_VAL;
- }
- }
-
- XFREE (buf);
- return MP_OKAY;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_fwrite.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_gcd.c b/dep/StormLib/src/libtommath/bn_mp_gcd.c
deleted file mode 100644
index ce980eb6bb0..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_gcd.c
+++ /dev/null
@@ -1,105 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_GCD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* Greatest Common Divisor using the binary method */
-int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
-{
- mp_int u, v;
- int k, u_lsb, v_lsb, res;
-
- /* either zero than gcd is the largest */
- if (mp_iszero (a) == MP_YES) {
- return mp_abs (b, c);
- }
- if (mp_iszero (b) == MP_YES) {
- return mp_abs (a, c);
- }
-
- /* get copies of a and b we can modify */
- if ((res = mp_init_copy (&u, a)) != MP_OKAY) {
- return res;
- }
-
- if ((res = mp_init_copy (&v, b)) != MP_OKAY) {
- goto LBL_U;
- }
-
- /* must be positive for the remainder of the algorithm */
- u.sign = v.sign = MP_ZPOS;
-
- /* B1. Find the common power of two for u and v */
- u_lsb = mp_cnt_lsb(&u);
- v_lsb = mp_cnt_lsb(&v);
- k = MIN(u_lsb, v_lsb);
-
- if (k > 0) {
- /* divide the power of two out */
- if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) {
- goto LBL_V;
- }
-
- if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) {
- goto LBL_V;
- }
- }
-
- /* divide any remaining factors of two out */
- if (u_lsb != k) {
- if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) {
- goto LBL_V;
- }
- }
-
- if (v_lsb != k) {
- if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) {
- goto LBL_V;
- }
- }
-
- while (mp_iszero(&v) == 0) {
- /* make sure v is the largest */
- if (mp_cmp_mag(&u, &v) == MP_GT) {
- /* swap u and v to make sure v is >= u */
- mp_exch(&u, &v);
- }
-
- /* subtract smallest from largest */
- if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) {
- goto LBL_V;
- }
-
- /* Divide out all factors of two */
- if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) {
- goto LBL_V;
- }
- }
-
- /* multiply by 2**k which we divided out at the beginning */
- if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) {
- goto LBL_V;
- }
- c->sign = MP_ZPOS;
- res = MP_OKAY;
-LBL_V:mp_clear (&u);
-LBL_U:mp_clear (&v);
- return res;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_gcd.c,v $ */
-/* $Revision: 1.5 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_get_int.c b/dep/StormLib/src/libtommath/bn_mp_get_int.c
deleted file mode 100644
index d9c76d0d15c..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_get_int.c
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_GET_INT_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* get the lower 32-bits of an mp_int */
-unsigned long mp_get_int(mp_int * a)
-{
- int i;
- unsigned long res;
-
- if (a->used == 0) {
- return 0;
- }
-
- /* get number of digits of the lsb we have to read */
- i = MIN(a->used,(int)((sizeof(unsigned long)*CHAR_BIT+DIGIT_BIT-1)/DIGIT_BIT))-1;
-
- /* get most significant digit of result */
- res = DIGIT(a,i);
-
- while (--i >= 0) {
- res = (res << DIGIT_BIT) | DIGIT(a,i);
- }
-
- /* force result to 32-bits always so it is consistent on non 32-bit platforms */
- return res & 0xFFFFFFFFUL;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_get_int.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_grow.c b/dep/StormLib/src/libtommath/bn_mp_grow.c
deleted file mode 100644
index a05dad73bc1..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_grow.c
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_GROW_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* grow as required */
-int mp_grow (mp_int * a, int size)
-{
- int i;
- mp_digit *tmp;
-
- /* if the alloc size is smaller alloc more ram */
- if (a->alloc < size) {
- /* ensure there are always at least MP_PREC digits extra on top */
- size += (MP_PREC * 2) - (size % MP_PREC);
-
- /* reallocate the array a->dp
- *
- * We store the return in a temporary variable
- * in case the operation failed we don't want
- * to overwrite the dp member of a.
- */
- tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size);
- if (tmp == NULL) {
- /* reallocation failed but "a" is still valid [can be freed] */
- return MP_MEM;
- }
-
- /* reallocation succeeded so set a->dp */
- a->dp = tmp;
-
- /* zero excess digits */
- i = a->alloc;
- a->alloc = size;
- for (; i < a->alloc; i++) {
- a->dp[i] = 0;
- }
- }
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_grow.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_init.c b/dep/StormLib/src/libtommath/bn_mp_init.c
deleted file mode 100644
index 107d98be6e8..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_init.c
+++ /dev/null
@@ -1,46 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_INIT_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* init a new mp_int */
-int mp_init (mp_int * a)
-{
- int i;
-
- /* allocate memory required and clear it */
- a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC);
- if (a->dp == NULL) {
- return MP_MEM;
- }
-
- /* set the digits to zero */
- for (i = 0; i < MP_PREC; i++) {
- a->dp[i] = 0;
- }
-
- /* set the used to zero, allocated digits to the default precision
- * and sign to positive */
- a->used = 0;
- a->alloc = MP_PREC;
- a->sign = MP_ZPOS;
-
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_init.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_init_copy.c b/dep/StormLib/src/libtommath/bn_mp_init_copy.c
deleted file mode 100644
index 3ca1186ce1d..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_init_copy.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_INIT_COPY_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* creates "a" then copies b into it */
-int mp_init_copy (mp_int * a, mp_int * b)
-{
- int res;
-
- if ((res = mp_init (a)) != MP_OKAY) {
- return res;
- }
- return mp_copy (b, a);
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_init_copy.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_init_multi.c b/dep/StormLib/src/libtommath/bn_mp_init_multi.c
deleted file mode 100644
index 4f6f367ffd5..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_init_multi.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_INIT_MULTI_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#include <stdarg.h>
-
-int mp_init_multi(mp_int *mp, ...)
-{
- mp_err res = MP_OKAY; /* Assume ok until proven otherwise */
- int n = 0; /* Number of ok inits */
- mp_int* cur_arg = mp;
- va_list args;
-
- va_start(args, mp); /* init args to next argument from caller */
- while (cur_arg != NULL) {
- if (mp_init(cur_arg) != MP_OKAY) {
- /* Oops - error! Back-track and mp_clear what we already
- succeeded in init-ing, then return error.
- */
- va_list clean_args;
-
- /* end the current list */
- va_end(args);
-
- /* now start cleaning up */
- cur_arg = mp;
- va_start(clean_args, mp);
- while (n--) {
- mp_clear(cur_arg);
- cur_arg = va_arg(clean_args, mp_int*);
- }
- va_end(clean_args);
- res = MP_MEM;
- break;
- }
- n++;
- cur_arg = va_arg(args, mp_int*);
- }
- va_end(args);
- return res; /* Assumed ok, if error flagged above. */
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_init_multi.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_init_set.c b/dep/StormLib/src/libtommath/bn_mp_init_set.c
deleted file mode 100644
index 853323f3aaa..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_init_set.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_INIT_SET_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* initialize and set a digit */
-int mp_init_set (mp_int * a, mp_digit b)
-{
- int err;
- if ((err = mp_init(a)) != MP_OKAY) {
- return err;
- }
- mp_set(a, b);
- return err;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_init_set.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_init_set_int.c b/dep/StormLib/src/libtommath/bn_mp_init_set_int.c
deleted file mode 100644
index b2f8727e336..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_init_set_int.c
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_INIT_SET_INT_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* initialize and set a digit */
-int mp_init_set_int (mp_int * a, unsigned long b)
-{
- int err;
- if ((err = mp_init(a)) != MP_OKAY) {
- return err;
- }
- return mp_set_int(a, b);
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_init_set_int.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_init_size.c b/dep/StormLib/src/libtommath/bn_mp_init_size.c
deleted file mode 100644
index 17b8d9fceb0..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_init_size.c
+++ /dev/null
@@ -1,48 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_INIT_SIZE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* init an mp_init for a given size */
-int mp_init_size (mp_int * a, int size)
-{
- int x;
-
- /* pad size so there are always extra digits */
- size += (MP_PREC * 2) - (size % MP_PREC);
-
- /* alloc mem */
- a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size);
- if (a->dp == NULL) {
- return MP_MEM;
- }
-
- /* set the members */
- a->used = 0;
- a->alloc = size;
- a->sign = MP_ZPOS;
-
- /* zero the digits */
- for (x = 0; x < size; x++) {
- a->dp[x] = 0;
- }
-
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_init_size.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_invmod.c b/dep/StormLib/src/libtommath/bn_mp_invmod.c
deleted file mode 100644
index 038e584a25c..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_invmod.c
+++ /dev/null
@@ -1,43 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_INVMOD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* hac 14.61, pp608 */
-int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
-{
- /* b cannot be negative */
- if (b->sign == MP_NEG || mp_iszero(b) == 1) {
- return MP_VAL;
- }
-
-#ifdef BN_FAST_MP_INVMOD_C
- /* if the modulus is odd we can use a faster routine instead */
- if (mp_isodd (b) == 1) {
- return fast_mp_invmod (a, b, c);
- }
-#endif
-
-#ifdef BN_MP_INVMOD_SLOW_C
- return mp_invmod_slow(a, b, c);
-#endif
-
- return MP_VAL;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_invmod.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_invmod_slow.c b/dep/StormLib/src/libtommath/bn_mp_invmod_slow.c
deleted file mode 100644
index 3792a4c2333..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_invmod_slow.c
+++ /dev/null
@@ -1,175 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_INVMOD_SLOW_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* hac 14.61, pp608 */
-int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c)
-{
- mp_int x, y, u, v, A, B, C, D;
- int res;
-
- /* b cannot be negative */
- if (b->sign == MP_NEG || mp_iszero(b) == 1) {
- return MP_VAL;
- }
-
- /* init temps */
- if ((res = mp_init_multi(&x, &y, &u, &v,
- &A, &B, &C, &D, NULL)) != MP_OKAY) {
- return res;
- }
-
- /* x = a, y = b */
- if ((res = mp_mod(a, b, &x)) != MP_OKAY) {
- goto LBL_ERR;
- }
- if ((res = mp_copy (b, &y)) != MP_OKAY) {
- goto LBL_ERR;
- }
-
- /* 2. [modified] if x,y are both even then return an error! */
- if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) {
- res = MP_VAL;
- goto LBL_ERR;
- }
-
- /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
- if ((res = mp_copy (&x, &u)) != MP_OKAY) {
- goto LBL_ERR;
- }
- if ((res = mp_copy (&y, &v)) != MP_OKAY) {
- goto LBL_ERR;
- }
- mp_set (&A, 1);
- mp_set (&D, 1);
-
-top:
- /* 4. while u is even do */
- while (mp_iseven (&u) == 1) {
- /* 4.1 u = u/2 */
- if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
- goto LBL_ERR;
- }
- /* 4.2 if A or B is odd then */
- if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) {
- /* A = (A+y)/2, B = (B-x)/2 */
- if ((res = mp_add (&A, &y, &A)) != MP_OKAY) {
- goto LBL_ERR;
- }
- if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
- goto LBL_ERR;
- }
- }
- /* A = A/2, B = B/2 */
- if ((res = mp_div_2 (&A, &A)) != MP_OKAY) {
- goto LBL_ERR;
- }
- if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
- goto LBL_ERR;
- }
- }
-
- /* 5. while v is even do */
- while (mp_iseven (&v) == 1) {
- /* 5.1 v = v/2 */
- if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
- goto LBL_ERR;
- }
- /* 5.2 if C or D is odd then */
- if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) {
- /* C = (C+y)/2, D = (D-x)/2 */
- if ((res = mp_add (&C, &y, &C)) != MP_OKAY) {
- goto LBL_ERR;
- }
- if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
- goto LBL_ERR;
- }
- }
- /* C = C/2, D = D/2 */
- if ((res = mp_div_2 (&C, &C)) != MP_OKAY) {
- goto LBL_ERR;
- }
- if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
- goto LBL_ERR;
- }
- }
-
- /* 6. if u >= v then */
- if (mp_cmp (&u, &v) != MP_LT) {
- /* u = u - v, A = A - C, B = B - D */
- if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
- goto LBL_ERR;
- }
-
- if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) {
- goto LBL_ERR;
- }
-
- if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
- goto LBL_ERR;
- }
- } else {
- /* v - v - u, C = C - A, D = D - B */
- if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
- goto LBL_ERR;
- }
-
- if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) {
- goto LBL_ERR;
- }
-
- if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
- goto LBL_ERR;
- }
- }
-
- /* if not zero goto step 4 */
- if (mp_iszero (&u) == 0)
- goto top;
-
- /* now a = C, b = D, gcd == g*v */
-
- /* if v != 1 then there is no inverse */
- if (mp_cmp_d (&v, 1) != MP_EQ) {
- res = MP_VAL;
- goto LBL_ERR;
- }
-
- /* if its too low */
- while (mp_cmp_d(&C, 0) == MP_LT) {
- if ((res = mp_add(&C, b, &C)) != MP_OKAY) {
- goto LBL_ERR;
- }
- }
-
- /* too big */
- while (mp_cmp_mag(&C, b) != MP_LT) {
- if ((res = mp_sub(&C, b, &C)) != MP_OKAY) {
- goto LBL_ERR;
- }
- }
-
- /* C is now the inverse */
- mp_exch (&C, c);
- res = MP_OKAY;
-LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL);
- return res;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_invmod_slow.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_is_square.c b/dep/StormLib/src/libtommath/bn_mp_is_square.c
deleted file mode 100644
index 5d2fa072ce9..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_is_square.c
+++ /dev/null
@@ -1,109 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_IS_SQUARE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* Check if remainders are possible squares - fast exclude non-squares */
-static const char rem_128[128] = {
- 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1
-};
-
-static const char rem_105[105] = {
- 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
- 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
- 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
- 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1,
- 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1
-};
-
-/* Store non-zero to ret if arg is square, and zero if not */
-int mp_is_square(mp_int *arg,int *ret)
-{
- int res;
- mp_digit c;
- mp_int t;
- unsigned long r;
-
- /* Default to Non-square :) */
- *ret = MP_NO;
-
- if (arg->sign == MP_NEG) {
- return MP_VAL;
- }
-
- /* digits used? (TSD) */
- if (arg->used == 0) {
- return MP_OKAY;
- }
-
- /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */
- if (rem_128[127 & DIGIT(arg,0)] == 1) {
- return MP_OKAY;
- }
-
- /* Next check mod 105 (3*5*7) */
- if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) {
- return res;
- }
- if (rem_105[c] == 1) {
- return MP_OKAY;
- }
-
-
- if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) {
- return res;
- }
- if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) {
- goto ERR;
- }
- r = mp_get_int(&t);
- /* Check for other prime modules, note it's not an ERROR but we must
- * free "t" so the easiest way is to goto ERR. We know that res
- * is already equal to MP_OKAY from the mp_mod call
- */
- if ( (1L<<(r%11)) & 0x5C4L ) goto ERR;
- if ( (1L<<(r%13)) & 0x9E4L ) goto ERR;
- if ( (1L<<(r%17)) & 0x5CE8L ) goto ERR;
- if ( (1L<<(r%19)) & 0x4F50CL ) goto ERR;
- if ( (1L<<(r%23)) & 0x7ACCA0L ) goto ERR;
- if ( (1L<<(r%29)) & 0xC2EDD0CL ) goto ERR;
- if ( (1L<<(r%31)) & 0x6DE2B848L ) goto ERR;
-
- /* Final check - is sqr(sqrt(arg)) == arg ? */
- if ((res = mp_sqrt(arg,&t)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_sqr(&t,&t)) != MP_OKAY) {
- goto ERR;
- }
-
- *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO;
-ERR:mp_clear(&t);
- return res;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_is_square.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_jacobi.c b/dep/StormLib/src/libtommath/bn_mp_jacobi.c
deleted file mode 100644
index c70b946f316..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_jacobi.c
+++ /dev/null
@@ -1,105 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_JACOBI_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* computes the jacobi c = (a | n) (or Legendre if n is prime)
- * HAC pp. 73 Algorithm 2.149
- */
-int mp_jacobi (mp_int * a, mp_int * p, int *c)
-{
- mp_int a1, p1;
- int k, s, r, res;
- mp_digit residue;
-
- /* if p <= 0 return MP_VAL */
- if (mp_cmp_d(p, 0) != MP_GT) {
- return MP_VAL;
- }
-
- /* step 1. if a == 0, return 0 */
- if (mp_iszero (a) == 1) {
- *c = 0;
- return MP_OKAY;
- }
-
- /* step 2. if a == 1, return 1 */
- if (mp_cmp_d (a, 1) == MP_EQ) {
- *c = 1;
- return MP_OKAY;
- }
-
- /* default */
- s = 0;
-
- /* step 3. write a = a1 * 2**k */
- if ((res = mp_init_copy (&a1, a)) != MP_OKAY) {
- return res;
- }
-
- if ((res = mp_init (&p1)) != MP_OKAY) {
- goto LBL_A1;
- }
-
- /* divide out larger power of two */
- k = mp_cnt_lsb(&a1);
- if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) {
- goto LBL_P1;
- }
-
- /* step 4. if e is even set s=1 */
- if ((k & 1) == 0) {
- s = 1;
- } else {
- /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */
- residue = p->dp[0] & 7;
-
- if (residue == 1 || residue == 7) {
- s = 1;
- } else if (residue == 3 || residue == 5) {
- s = -1;
- }
- }
-
- /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */
- if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) {
- s = -s;
- }
-
- /* if a1 == 1 we're done */
- if (mp_cmp_d (&a1, 1) == MP_EQ) {
- *c = s;
- } else {
- /* n1 = n mod a1 */
- if ((res = mp_mod (p, &a1, &p1)) != MP_OKAY) {
- goto LBL_P1;
- }
- if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) {
- goto LBL_P1;
- }
- *c = s * r;
- }
-
- /* done */
- res = MP_OKAY;
-LBL_P1:mp_clear (&p1);
-LBL_A1:mp_clear (&a1);
- return res;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_jacobi.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_karatsuba_mul.c b/dep/StormLib/src/libtommath/bn_mp_karatsuba_mul.c
deleted file mode 100644
index b15ec24966b..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_karatsuba_mul.c
+++ /dev/null
@@ -1,167 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_KARATSUBA_MUL_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* c = |a| * |b| using Karatsuba Multiplication using
- * three half size multiplications
- *
- * Let B represent the radix [e.g. 2**DIGIT_BIT] and
- * let n represent half of the number of digits in
- * the min(a,b)
- *
- * a = a1 * B**n + a0
- * b = b1 * B**n + b0
- *
- * Then, a * b =>
- a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0
- *
- * Note that a1b1 and a0b0 are used twice and only need to be
- * computed once. So in total three half size (half # of
- * digit) multiplications are performed, a0b0, a1b1 and
- * (a1+b1)(a0+b0)
- *
- * Note that a multiplication of half the digits requires
- * 1/4th the number of single precision multiplications so in
- * total after one call 25% of the single precision multiplications
- * are saved. Note also that the call to mp_mul can end up back
- * in this function if the a0, a1, b0, or b1 are above the threshold.
- * This is known as divide-and-conquer and leads to the famous
- * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than
- * the standard O(N**2) that the baseline/comba methods use.
- * Generally though the overhead of this method doesn't pay off
- * until a certain size (N ~ 80) is reached.
- */
-int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c)
-{
- mp_int x0, x1, y0, y1, t1, x0y0, x1y1;
- int B, err;
-
- /* default the return code to an error */
- err = MP_MEM;
-
- /* min # of digits */
- B = MIN (a->used, b->used);
-
- /* now divide in two */
- B = B >> 1;
-
- /* init copy all the temps */
- if (mp_init_size (&x0, B) != MP_OKAY)
- goto ERR;
- if (mp_init_size (&x1, a->used - B) != MP_OKAY)
- goto X0;
- if (mp_init_size (&y0, B) != MP_OKAY)
- goto X1;
- if (mp_init_size (&y1, b->used - B) != MP_OKAY)
- goto Y0;
-
- /* init temps */
- if (mp_init_size (&t1, B * 2) != MP_OKAY)
- goto Y1;
- if (mp_init_size (&x0y0, B * 2) != MP_OKAY)
- goto T1;
- if (mp_init_size (&x1y1, B * 2) != MP_OKAY)
- goto X0Y0;
-
- /* now shift the digits */
- x0.used = y0.used = B;
- x1.used = a->used - B;
- y1.used = b->used - B;
-
- {
- register int x;
- register mp_digit *tmpa, *tmpb, *tmpx, *tmpy;
-
- /* we copy the digits directly instead of using higher level functions
- * since we also need to shift the digits
- */
- tmpa = a->dp;
- tmpb = b->dp;
-
- tmpx = x0.dp;
- tmpy = y0.dp;
- for (x = 0; x < B; x++) {
- *tmpx++ = *tmpa++;
- *tmpy++ = *tmpb++;
- }
-
- tmpx = x1.dp;
- for (x = B; x < a->used; x++) {
- *tmpx++ = *tmpa++;
- }
-
- tmpy = y1.dp;
- for (x = B; x < b->used; x++) {
- *tmpy++ = *tmpb++;
- }
- }
-
- /* only need to clamp the lower words since by definition the
- * upper words x1/y1 must have a known number of digits
- */
- mp_clamp (&x0);
- mp_clamp (&y0);
-
- /* now calc the products x0y0 and x1y1 */
- /* after this x0 is no longer required, free temp [x0==t2]! */
- if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY)
- goto X1Y1; /* x0y0 = x0*y0 */
- if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY)
- goto X1Y1; /* x1y1 = x1*y1 */
-
- /* now calc x1+x0 and y1+y0 */
- if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
- goto X1Y1; /* t1 = x1 - x0 */
- if (s_mp_add (&y1, &y0, &x0) != MP_OKAY)
- goto X1Y1; /* t2 = y1 - y0 */
- if (mp_mul (&t1, &x0, &t1) != MP_OKAY)
- goto X1Y1; /* t1 = (x1 + x0) * (y1 + y0) */
-
- /* add x0y0 */
- if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY)
- goto X1Y1; /* t2 = x0y0 + x1y1 */
- if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY)
- goto X1Y1; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */
-
- /* shift by B */
- if (mp_lshd (&t1, B) != MP_OKAY)
- goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */
- if (mp_lshd (&x1y1, B * 2) != MP_OKAY)
- goto X1Y1; /* x1y1 = x1y1 << 2*B */
-
- if (mp_add (&x0y0, &t1, &t1) != MP_OKAY)
- goto X1Y1; /* t1 = x0y0 + t1 */
- if (mp_add (&t1, &x1y1, c) != MP_OKAY)
- goto X1Y1; /* t1 = x0y0 + t1 + x1y1 */
-
- /* Algorithm succeeded set the return code to MP_OKAY */
- err = MP_OKAY;
-
-X1Y1:mp_clear (&x1y1);
-X0Y0:mp_clear (&x0y0);
-T1:mp_clear (&t1);
-Y1:mp_clear (&y1);
-Y0:mp_clear (&y0);
-X1:mp_clear (&x1);
-X0:mp_clear (&x0);
-ERR:
- return err;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_karatsuba_mul.c,v $ */
-/* $Revision: 1.6 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_karatsuba_sqr.c b/dep/StormLib/src/libtommath/bn_mp_karatsuba_sqr.c
deleted file mode 100644
index b3a45abf70e..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_karatsuba_sqr.c
+++ /dev/null
@@ -1,121 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_KARATSUBA_SQR_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* Karatsuba squaring, computes b = a*a using three
- * half size squarings
- *
- * See comments of karatsuba_mul for details. It
- * is essentially the same algorithm but merely
- * tuned to perform recursive squarings.
- */
-int mp_karatsuba_sqr (mp_int * a, mp_int * b)
-{
- mp_int x0, x1, t1, t2, x0x0, x1x1;
- int B, err;
-
- err = MP_MEM;
-
- /* min # of digits */
- B = a->used;
-
- /* now divide in two */
- B = B >> 1;
-
- /* init copy all the temps */
- if (mp_init_size (&x0, B) != MP_OKAY)
- goto ERR;
- if (mp_init_size (&x1, a->used - B) != MP_OKAY)
- goto X0;
-
- /* init temps */
- if (mp_init_size (&t1, a->used * 2) != MP_OKAY)
- goto X1;
- if (mp_init_size (&t2, a->used * 2) != MP_OKAY)
- goto T1;
- if (mp_init_size (&x0x0, B * 2) != MP_OKAY)
- goto T2;
- if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY)
- goto X0X0;
-
- {
- register int x;
- register mp_digit *dst, *src;
-
- src = a->dp;
-
- /* now shift the digits */
- dst = x0.dp;
- for (x = 0; x < B; x++) {
- *dst++ = *src++;
- }
-
- dst = x1.dp;
- for (x = B; x < a->used; x++) {
- *dst++ = *src++;
- }
- }
-
- x0.used = B;
- x1.used = a->used - B;
-
- mp_clamp (&x0);
-
- /* now calc the products x0*x0 and x1*x1 */
- if (mp_sqr (&x0, &x0x0) != MP_OKAY)
- goto X1X1; /* x0x0 = x0*x0 */
- if (mp_sqr (&x1, &x1x1) != MP_OKAY)
- goto X1X1; /* x1x1 = x1*x1 */
-
- /* now calc (x1+x0)**2 */
- if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
- goto X1X1; /* t1 = x1 - x0 */
- if (mp_sqr (&t1, &t1) != MP_OKAY)
- goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */
-
- /* add x0y0 */
- if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY)
- goto X1X1; /* t2 = x0x0 + x1x1 */
- if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY)
- goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */
-
- /* shift by B */
- if (mp_lshd (&t1, B) != MP_OKAY)
- goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */
- if (mp_lshd (&x1x1, B * 2) != MP_OKAY)
- goto X1X1; /* x1x1 = x1x1 << 2*B */
-
- if (mp_add (&x0x0, &t1, &t1) != MP_OKAY)
- goto X1X1; /* t1 = x0x0 + t1 */
- if (mp_add (&t1, &x1x1, b) != MP_OKAY)
- goto X1X1; /* t1 = x0x0 + t1 + x1x1 */
-
- err = MP_OKAY;
-
-X1X1:mp_clear (&x1x1);
-X0X0:mp_clear (&x0x0);
-T2:mp_clear (&t2);
-T1:mp_clear (&t1);
-X1:mp_clear (&x1);
-X0:mp_clear (&x0);
-ERR:
- return err;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_karatsuba_sqr.c,v $ */
-/* $Revision: 1.6 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_lcm.c b/dep/StormLib/src/libtommath/bn_mp_lcm.c
deleted file mode 100644
index af7ae23729e..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_lcm.c
+++ /dev/null
@@ -1,60 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_LCM_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* computes least common multiple as |a*b|/(a, b) */
-int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
-{
- int res;
- mp_int t1, t2;
-
-
- if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) {
- return res;
- }
-
- /* t1 = get the GCD of the two inputs */
- if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) {
- goto LBL_T;
- }
-
- /* divide the smallest by the GCD */
- if (mp_cmp_mag(a, b) == MP_LT) {
- /* store quotient in t2 such that t2 * b is the LCM */
- if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {
- goto LBL_T;
- }
- res = mp_mul(b, &t2, c);
- } else {
- /* store quotient in t2 such that t2 * a is the LCM */
- if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {
- goto LBL_T;
- }
- res = mp_mul(a, &t2, c);
- }
-
- /* fix the sign to positive */
- c->sign = MP_ZPOS;
-
-LBL_T:
- mp_clear_multi (&t1, &t2, NULL);
- return res;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_lcm.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_lshd.c b/dep/StormLib/src/libtommath/bn_mp_lshd.c
deleted file mode 100644
index ffb0defd06b..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_lshd.c
+++ /dev/null
@@ -1,67 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_LSHD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* shift left a certain amount of digits */
-int mp_lshd (mp_int * a, int b)
-{
- int x, res;
-
- /* if its less than zero return */
- if (b <= 0) {
- return MP_OKAY;
- }
-
- /* grow to fit the new digits */
- if (a->alloc < a->used + b) {
- if ((res = mp_grow (a, a->used + b)) != MP_OKAY) {
- return res;
- }
- }
-
- {
- register mp_digit *top, *bottom;
-
- /* increment the used by the shift amount then copy upwards */
- a->used += b;
-
- /* top */
- top = a->dp + a->used - 1;
-
- /* base */
- bottom = a->dp + a->used - 1 - b;
-
- /* much like mp_rshd this is implemented using a sliding window
- * except the window goes the otherway around. Copying from
- * the bottom to the top. see bn_mp_rshd.c for more info.
- */
- for (x = a->used - 1; x >= b; x--) {
- *top-- = *bottom--;
- }
-
- /* zero the lower digits */
- top = a->dp;
- for (x = 0; x < b; x++) {
- *top++ = 0;
- }
- }
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_lshd.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_mod.c b/dep/StormLib/src/libtommath/bn_mp_mod.c
deleted file mode 100644
index b24c71f9d95..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_mod.c
+++ /dev/null
@@ -1,48 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_MOD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* c = a mod b, 0 <= c < b */
-int
-mp_mod (mp_int * a, mp_int * b, mp_int * c)
-{
- mp_int t;
- int res;
-
- if ((res = mp_init (&t)) != MP_OKAY) {
- return res;
- }
-
- if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) {
- mp_clear (&t);
- return res;
- }
-
- if (t.sign != b->sign) {
- res = mp_add (b, &t, c);
- } else {
- res = MP_OKAY;
- mp_exch (&t, c);
- }
-
- mp_clear (&t);
- return res;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_mod.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_mod_2d.c b/dep/StormLib/src/libtommath/bn_mp_mod_2d.c
deleted file mode 100644
index a54a0242644..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_mod_2d.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_MOD_2D_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* calc a value mod 2**b */
-int
-mp_mod_2d (mp_int * a, int b, mp_int * c)
-{
- int x, res;
-
- /* if b is <= 0 then zero the int */
- if (b <= 0) {
- mp_zero (c);
- return MP_OKAY;
- }
-
- /* if the modulus is larger than the value than return */
- if (b >= (int) (a->used * DIGIT_BIT)) {
- res = mp_copy (a, c);
- return res;
- }
-
- /* copy */
- if ((res = mp_copy (a, c)) != MP_OKAY) {
- return res;
- }
-
- /* zero digits above the last digit of the modulus */
- for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) {
- c->dp[x] = 0;
- }
- /* clear the digit that is not completely outside/inside the modulus */
- c->dp[b / DIGIT_BIT] &=
- (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1));
- mp_clamp (c);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_mod_2d.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_mod_d.c b/dep/StormLib/src/libtommath/bn_mp_mod_d.c
deleted file mode 100644
index 59886e7734a..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_mod_d.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_MOD_D_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-int
-mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
-{
- return mp_div_d(a, b, NULL, c);
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_mod_d.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_montgomery_calc_normalization.c b/dep/StormLib/src/libtommath/bn_mp_montgomery_calc_normalization.c
deleted file mode 100644
index fdefcbd99d2..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_montgomery_calc_normalization.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/*
- * shifts with subtractions when the result is greater than b.
- *
- * The method is slightly modified to shift B unconditionally upto just under
- * the leading bit of b. This saves alot of multiple precision shifting.
- */
-int mp_montgomery_calc_normalization (mp_int * a, mp_int * b)
-{
- int x, bits, res;
-
- /* how many bits of last digit does b use */
- bits = mp_count_bits (b) % DIGIT_BIT;
-
- if (b->used > 1) {
- if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) {
- return res;
- }
- } else {
- mp_set(a, 1);
- bits = 1;
- }
-
-
- /* now compute C = A * B mod b */
- for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
- if ((res = mp_mul_2 (a, a)) != MP_OKAY) {
- return res;
- }
- if (mp_cmp_mag (a, b) != MP_LT) {
- if ((res = s_mp_sub (a, b, a)) != MP_OKAY) {
- return res;
- }
- }
- }
-
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_montgomery_calc_normalization.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_montgomery_reduce.c b/dep/StormLib/src/libtommath/bn_mp_montgomery_reduce.c
deleted file mode 100644
index 173848e0ac8..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_montgomery_reduce.c
+++ /dev/null
@@ -1,118 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_MONTGOMERY_REDUCE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* computes xR**-1 == x (mod N) via Montgomery Reduction */
-int
-mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
-{
- int ix, res, digs;
- mp_digit mu;
-
- /* can the fast reduction [comba] method be used?
- *
- * Note that unlike in mul you're safely allowed *less*
- * than the available columns [255 per default] since carries
- * are fixed up in the inner loop.
- */
- digs = n->used * 2 + 1;
- if ((digs < MP_WARRAY) &&
- n->used <
- (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
- return fast_mp_montgomery_reduce (x, n, rho);
- }
-
- /* grow the input as required */
- if (x->alloc < digs) {
- if ((res = mp_grow (x, digs)) != MP_OKAY) {
- return res;
- }
- }
- x->used = digs;
-
- for (ix = 0; ix < n->used; ix++) {
- /* mu = ai * rho mod b
- *
- * The value of rho must be precalculated via
- * montgomery_setup() such that
- * it equals -1/n0 mod b this allows the
- * following inner loop to reduce the
- * input one digit at a time
- */
- mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK);
-
- /* a = a + mu * m * b**i */
- {
- register int iy;
- register mp_digit *tmpn, *tmpx, u;
- register mp_word r;
-
- /* alias for digits of the modulus */
- tmpn = n->dp;
-
- /* alias for the digits of x [the input] */
- tmpx = x->dp + ix;
-
- /* set the carry to zero */
- u = 0;
-
- /* Multiply and add in place */
- for (iy = 0; iy < n->used; iy++) {
- /* compute product and sum */
- r = ((mp_word)mu) * ((mp_word)*tmpn++) +
- ((mp_word) u) + ((mp_word) * tmpx);
-
- /* get carry */
- u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
-
- /* fix digit */
- *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));
- }
- /* At this point the ix'th digit of x should be zero */
-
-
- /* propagate carries upwards as required*/
- while (u) {
- *tmpx += u;
- u = *tmpx >> DIGIT_BIT;
- *tmpx++ &= MP_MASK;
- }
- }
- }
-
- /* at this point the n.used'th least
- * significant digits of x are all zero
- * which means we can shift x to the
- * right by n.used digits and the
- * residue is unchanged.
- */
-
- /* x = x/b**n.used */
- mp_clamp(x);
- mp_rshd (x, n->used);
-
- /* if x >= n then x = x - n */
- if (mp_cmp_mag (x, n) != MP_LT) {
- return s_mp_sub (x, n, x);
- }
-
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_montgomery_reduce.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_montgomery_setup.c b/dep/StormLib/src/libtommath/bn_mp_montgomery_setup.c
deleted file mode 100644
index 6f277320eb7..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_montgomery_setup.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_MONTGOMERY_SETUP_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* setups the montgomery reduction stuff */
-int
-mp_montgomery_setup (mp_int * n, mp_digit * rho)
-{
- mp_digit x, b;
-
-/* fast inversion mod 2**k
- *
- * Based on the fact that
- *
- * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n)
- * => 2*X*A - X*X*A*A = 1
- * => 2*(1) - (1) = 1
- */
- b = n->dp[0];
-
- if ((b & 1) == 0) {
- return MP_VAL;
- }
-
- x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
- x *= 2 - b * x; /* here x*a==1 mod 2**8 */
-#if !defined(MP_8BIT)
- x *= 2 - b * x; /* here x*a==1 mod 2**16 */
-#endif
-#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT))
- x *= 2 - b * x; /* here x*a==1 mod 2**32 */
-#endif
-#ifdef MP_64BIT
- x *= 2 - b * x; /* here x*a==1 mod 2**64 */
-#endif
-
- /* rho = -1/m mod b */
- *rho = (unsigned long)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK;
-
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_montgomery_setup.c,v $ */
-/* $Revision: 1.5 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_mul.c b/dep/StormLib/src/libtommath/bn_mp_mul.c
deleted file mode 100644
index a1315dac30c..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_mul.c
+++ /dev/null
@@ -1,66 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_MUL_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* high level multiplication (handles sign) */
-int mp_mul (mp_int * a, mp_int * b, mp_int * c)
-{
- int res, neg;
- neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
-
- /* use Toom-Cook? */
-#ifdef BN_MP_TOOM_MUL_C
- if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) {
- res = mp_toom_mul(a, b, c);
- } else
-#endif
-#ifdef BN_MP_KARATSUBA_MUL_C
- /* use Karatsuba? */
- if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) {
- res = mp_karatsuba_mul (a, b, c);
- } else
-#endif
- {
- /* can we use the fast multiplier?
- *
- * The fast multiplier can be used if the output will
- * have less than MP_WARRAY digits and the number of
- * digits won't affect carry propagation
- */
- int digs = a->used + b->used + 1;
-
-#ifdef BN_FAST_S_MP_MUL_DIGS_C
- if ((digs < MP_WARRAY) &&
- MIN(a->used, b->used) <=
- (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
- res = fast_s_mp_mul_digs (a, b, c, digs);
- } else
-#endif
-#ifdef BN_S_MP_MUL_DIGS_C
- res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */
-#else
- res = MP_VAL;
-#endif
-
- }
- c->sign = (c->used > 0) ? neg : MP_ZPOS;
- return res;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_mul.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_mul_2.c b/dep/StormLib/src/libtommath/bn_mp_mul_2.c
deleted file mode 100644
index 3315744f1ec..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_mul_2.c
+++ /dev/null
@@ -1,82 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_MUL_2_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* b = a*2 */
-int mp_mul_2(mp_int * a, mp_int * b)
-{
- int x, res, oldused;
-
- /* grow to accomodate result */
- if (b->alloc < a->used + 1) {
- if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) {
- return res;
- }
- }
-
- oldused = b->used;
- b->used = a->used;
-
- {
- register mp_digit r, rr, *tmpa, *tmpb;
-
- /* alias for source */
- tmpa = a->dp;
-
- /* alias for dest */
- tmpb = b->dp;
-
- /* carry */
- r = 0;
- for (x = 0; x < a->used; x++) {
-
- /* get what will be the *next* carry bit from the
- * MSB of the current digit
- */
- rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1));
-
- /* now shift up this digit, add in the carry [from the previous] */
- *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK;
-
- /* copy the carry that would be from the source
- * digit into the next iteration
- */
- r = rr;
- }
-
- /* new leading digit? */
- if (r != 0) {
- /* add a MSB which is always 1 at this point */
- *tmpb = 1;
- ++(b->used);
- }
-
- /* now zero any excess digits on the destination
- * that we didn't write to
- */
- tmpb = b->dp + b->used;
- for (x = b->used; x < oldused; x++) {
- *tmpb++ = 0;
- }
- }
- b->sign = a->sign;
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_mul_2.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_mul_2d.c b/dep/StormLib/src/libtommath/bn_mp_mul_2d.c
deleted file mode 100644
index c636c179884..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_mul_2d.c
+++ /dev/null
@@ -1,85 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_MUL_2D_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* shift left by a certain bit count */
-int mp_mul_2d (mp_int * a, int b, mp_int * c)
-{
- mp_digit d;
- int res;
-
- /* copy */
- if (a != c) {
- if ((res = mp_copy (a, c)) != MP_OKAY) {
- return res;
- }
- }
-
- if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) {
- if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) {
- return res;
- }
- }
-
- /* shift by as many digits in the bit count */
- if (b >= (int)DIGIT_BIT) {
- if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {
- return res;
- }
- }
-
- /* shift any bit count < DIGIT_BIT */
- d = (mp_digit) (b % DIGIT_BIT);
- if (d != 0) {
- register mp_digit *tmpc, shift, mask, r, rr;
- register int x;
-
- /* bitmask for carries */
- mask = (((mp_digit)1) << d) - 1;
-
- /* shift for msbs */
- shift = DIGIT_BIT - d;
-
- /* alias */
- tmpc = c->dp;
-
- /* carry */
- r = 0;
- for (x = 0; x < c->used; x++) {
- /* get the higher bits of the current word */
- rr = (*tmpc >> shift) & mask;
-
- /* shift the current word and OR in the carry */
- *tmpc = ((*tmpc << d) | r) & MP_MASK;
- ++tmpc;
-
- /* set the carry to the carry bits of the current word */
- r = rr;
- }
-
- /* set final carry */
- if (r != 0) {
- c->dp[(c->used)++] = r;
- }
- }
- mp_clamp (c);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_mul_2d.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_mul_d.c b/dep/StormLib/src/libtommath/bn_mp_mul_d.c
deleted file mode 100644
index a36a76bbacf..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_mul_d.c
+++ /dev/null
@@ -1,79 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_MUL_D_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* multiply by a digit */
-int
-mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
-{
- mp_digit u, *tmpa, *tmpc;
- mp_word r;
- int ix, res, olduse;
-
- /* make sure c is big enough to hold a*b */
- if (c->alloc < a->used + 1) {
- if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) {
- return res;
- }
- }
-
- /* get the original destinations used count */
- olduse = c->used;
-
- /* set the sign */
- c->sign = a->sign;
-
- /* alias for a->dp [source] */
- tmpa = a->dp;
-
- /* alias for c->dp [dest] */
- tmpc = c->dp;
-
- /* zero carry */
- u = 0;
-
- /* compute columns */
- for (ix = 0; ix < a->used; ix++) {
- /* compute product and carry sum for this term */
- r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b);
-
- /* mask off higher bits to get a single digit */
- *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK));
-
- /* send carry into next iteration */
- u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
- }
-
- /* store final carry [if any] and increment ix offset */
- *tmpc++ = u;
- ++ix;
-
- /* now zero digits above the top */
- while (ix++ < olduse) {
- *tmpc++ = 0;
- }
-
- /* set used count */
- c->used = a->used + 1;
- mp_clamp(c);
-
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_mul_d.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_mulmod.c b/dep/StormLib/src/libtommath/bn_mp_mulmod.c
deleted file mode 100644
index 8ec98bbddb2..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_mulmod.c
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_MULMOD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* d = a * b (mod c) */
-int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
-{
- int res;
- mp_int t;
-
- if ((res = mp_init (&t)) != MP_OKAY) {
- return res;
- }
-
- if ((res = mp_mul (a, b, &t)) != MP_OKAY) {
- mp_clear (&t);
- return res;
- }
- res = mp_mod (&t, c, d);
- mp_clear (&t);
- return res;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_mulmod.c,v $ */
-/* $Revision: 1.5 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_n_root.c b/dep/StormLib/src/libtommath/bn_mp_n_root.c
deleted file mode 100644
index f188f5255b3..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_n_root.c
+++ /dev/null
@@ -1,132 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_N_ROOT_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* find the n'th root of an integer
- *
- * Result found such that (c)**b <= a and (c+1)**b > a
- *
- * This algorithm uses Newton's approximation
- * x[i+1] = x[i] - f(x[i])/f'(x[i])
- * which will find the root in log(N) time where
- * each step involves a fair bit. This is not meant to
- * find huge roots [square and cube, etc].
- */
-int mp_n_root (mp_int * a, mp_digit b, mp_int * c)
-{
- mp_int t1, t2, t3;
- int res, neg;
-
- /* input must be positive if b is even */
- if ((b & 1) == 0 && a->sign == MP_NEG) {
- return MP_VAL;
- }
-
- if ((res = mp_init (&t1)) != MP_OKAY) {
- return res;
- }
-
- if ((res = mp_init (&t2)) != MP_OKAY) {
- goto LBL_T1;
- }
-
- if ((res = mp_init (&t3)) != MP_OKAY) {
- goto LBL_T2;
- }
-
- /* if a is negative fudge the sign but keep track */
- neg = a->sign;
- a->sign = MP_ZPOS;
-
- /* t2 = 2 */
- mp_set (&t2, 2);
-
- do {
- /* t1 = t2 */
- if ((res = mp_copy (&t2, &t1)) != MP_OKAY) {
- goto LBL_T3;
- }
-
- /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */
-
- /* t3 = t1**(b-1) */
- if ((res = mp_expt_d (&t1, b - 1, &t3)) != MP_OKAY) {
- goto LBL_T3;
- }
-
- /* numerator */
- /* t2 = t1**b */
- if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) {
- goto LBL_T3;
- }
-
- /* t2 = t1**b - a */
- if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) {
- goto LBL_T3;
- }
-
- /* denominator */
- /* t3 = t1**(b-1) * b */
- if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) {
- goto LBL_T3;
- }
-
- /* t3 = (t1**b - a)/(b * t1**(b-1)) */
- if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) {
- goto LBL_T3;
- }
-
- if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) {
- goto LBL_T3;
- }
- } while (mp_cmp (&t1, &t2) != MP_EQ);
-
- /* result can be off by a few so check */
- for (;;) {
- if ((res = mp_expt_d (&t1, b, &t2)) != MP_OKAY) {
- goto LBL_T3;
- }
-
- if (mp_cmp (&t2, a) == MP_GT) {
- if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) {
- goto LBL_T3;
- }
- } else {
- break;
- }
- }
-
- /* reset the sign of a first */
- a->sign = neg;
-
- /* set the result */
- mp_exch (&t1, c);
-
- /* set the sign of the result */
- c->sign = neg;
-
- res = MP_OKAY;
-
-LBL_T3:mp_clear (&t3);
-LBL_T2:mp_clear (&t2);
-LBL_T1:mp_clear (&t1);
- return res;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_n_root.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_neg.c b/dep/StormLib/src/libtommath/bn_mp_neg.c
deleted file mode 100644
index 87a8b500449..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_neg.c
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_NEG_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* b = -a */
-int mp_neg (mp_int * a, mp_int * b)
-{
- int res;
- if (a != b) {
- if ((res = mp_copy (a, b)) != MP_OKAY) {
- return res;
- }
- }
-
- if (mp_iszero(b) != MP_YES) {
- b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS;
- } else {
- b->sign = MP_ZPOS;
- }
-
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_neg.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_or.c b/dep/StormLib/src/libtommath/bn_mp_or.c
deleted file mode 100644
index 12601eaf78e..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_or.c
+++ /dev/null
@@ -1,50 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_OR_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* OR two ints together */
-int mp_or (mp_int * a, mp_int * b, mp_int * c)
-{
- int res, ix, px;
- mp_int t, *x;
-
- if (a->used > b->used) {
- if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
- return res;
- }
- px = b->used;
- x = b;
- } else {
- if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
- return res;
- }
- px = a->used;
- x = a;
- }
-
- for (ix = 0; ix < px; ix++) {
- t.dp[ix] |= x->dp[ix];
- }
- mp_clamp (&t);
- mp_exch (c, &t);
- mp_clear (&t);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_or.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_prime_fermat.c b/dep/StormLib/src/libtommath/bn_mp_prime_fermat.c
deleted file mode 100644
index 297e13c7960..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_prime_fermat.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_PRIME_FERMAT_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* performs one Fermat test.
- *
- * If "a" were prime then b**a == b (mod a) since the order of
- * the multiplicative sub-group would be phi(a) = a-1. That means
- * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a).
- *
- * Sets result to 1 if the congruence holds, or zero otherwise.
- */
-int mp_prime_fermat (mp_int * a, mp_int * b, int *result)
-{
- mp_int t;
- int err;
-
- /* default to composite */
- *result = MP_NO;
-
- /* ensure b > 1 */
- if (mp_cmp_d(b, 1) != MP_GT) {
- return MP_VAL;
- }
-
- /* init t */
- if ((err = mp_init (&t)) != MP_OKAY) {
- return err;
- }
-
- /* compute t = b**a mod a */
- if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) {
- goto LBL_T;
- }
-
- /* is it equal to b? */
- if (mp_cmp (&t, b) == MP_EQ) {
- *result = MP_YES;
- }
-
- err = MP_OKAY;
-LBL_T:mp_clear (&t);
- return err;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_prime_fermat.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_prime_is_divisible.c b/dep/StormLib/src/libtommath/bn_mp_prime_is_divisible.c
deleted file mode 100644
index 0ae64983512..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_prime_is_divisible.c
+++ /dev/null
@@ -1,50 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_PRIME_IS_DIVISIBLE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* determines if an integers is divisible by one
- * of the first PRIME_SIZE primes or not
- *
- * sets result to 0 if not, 1 if yes
- */
-int mp_prime_is_divisible (mp_int * a, int *result)
-{
- int err, ix;
- mp_digit res;
-
- /* default to not */
- *result = MP_NO;
-
- for (ix = 0; ix < PRIME_SIZE; ix++) {
- /* what is a mod LBL_prime_tab[ix] */
- if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) {
- return err;
- }
-
- /* is the residue zero? */
- if (res == 0) {
- *result = MP_YES;
- return MP_OKAY;
- }
- }
-
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_prime_is_divisible.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_prime_is_prime.c b/dep/StormLib/src/libtommath/bn_mp_prime_is_prime.c
deleted file mode 100644
index 0e1e94bad5b..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_prime_is_prime.c
+++ /dev/null
@@ -1,83 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_PRIME_IS_PRIME_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* performs a variable number of rounds of Miller-Rabin
- *
- * Probability of error after t rounds is no more than
-
- *
- * Sets result to 1 if probably prime, 0 otherwise
- */
-int mp_prime_is_prime (mp_int * a, int t, int *result)
-{
- mp_int b;
- int ix, err, res;
-
- /* default to no */
- *result = MP_NO;
-
- /* valid value of t? */
- if (t <= 0 || t > PRIME_SIZE) {
- return MP_VAL;
- }
-
- /* is the input equal to one of the primes in the table? */
- for (ix = 0; ix < PRIME_SIZE; ix++) {
- if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) {
- *result = 1;
- return MP_OKAY;
- }
- }
-
- /* first perform trial division */
- if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) {
- return err;
- }
-
- /* return if it was trivially divisible */
- if (res == MP_YES) {
- return MP_OKAY;
- }
-
- /* now perform the miller-rabin rounds */
- if ((err = mp_init (&b)) != MP_OKAY) {
- return err;
- }
-
- for (ix = 0; ix < t; ix++) {
- /* set the prime */
- mp_set (&b, ltm_prime_tab[ix]);
-
- if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) {
- goto LBL_B;
- }
-
- if (res == MP_NO) {
- goto LBL_B;
- }
- }
-
- /* passed the test */
- *result = MP_YES;
-LBL_B:mp_clear (&b);
- return err;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_prime_is_prime.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_prime_miller_rabin.c b/dep/StormLib/src/libtommath/bn_mp_prime_miller_rabin.c
deleted file mode 100644
index 47385bc815c..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_prime_miller_rabin.c
+++ /dev/null
@@ -1,103 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_PRIME_MILLER_RABIN_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* Miller-Rabin test of "a" to the base of "b" as described in
- * HAC pp. 139 Algorithm 4.24
- *
- * Sets result to 0 if definitely composite or 1 if probably prime.
- * Randomly the chance of error is no more than 1/4 and often
- * very much lower.
- */
-int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
-{
- mp_int n1, y, r;
- int s, j, err;
-
- /* default */
- *result = MP_NO;
-
- /* ensure b > 1 */
- if (mp_cmp_d(b, 1) != MP_GT) {
- return MP_VAL;
- }
-
- /* get n1 = a - 1 */
- if ((err = mp_init_copy (&n1, a)) != MP_OKAY) {
- return err;
- }
- if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) {
- goto LBL_N1;
- }
-
- /* set 2**s * r = n1 */
- if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) {
- goto LBL_N1;
- }
-
- /* count the number of least significant bits
- * which are zero
- */
- s = mp_cnt_lsb(&r);
-
- /* now divide n - 1 by 2**s */
- if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) {
- goto LBL_R;
- }
-
- /* compute y = b**r mod a */
- if ((err = mp_init (&y)) != MP_OKAY) {
- goto LBL_R;
- }
- if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) {
- goto LBL_Y;
- }
-
- /* if y != 1 and y != n1 do */
- if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) {
- j = 1;
- /* while j <= s-1 and y != n1 */
- while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) {
- if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) {
- goto LBL_Y;
- }
-
- /* if y == 1 then composite */
- if (mp_cmp_d (&y, 1) == MP_EQ) {
- goto LBL_Y;
- }
-
- ++j;
- }
-
- /* if y != n1 then composite */
- if (mp_cmp (&y, &n1) != MP_EQ) {
- goto LBL_Y;
- }
- }
-
- /* probably prime now */
- *result = MP_YES;
-LBL_Y:mp_clear (&y);
-LBL_R:mp_clear (&r);
-LBL_N1:mp_clear (&n1);
- return err;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_prime_miller_rabin.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_prime_next_prime.c b/dep/StormLib/src/libtommath/bn_mp_prime_next_prime.c
deleted file mode 100644
index 833992bac48..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_prime_next_prime.c
+++ /dev/null
@@ -1,170 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_PRIME_NEXT_PRIME_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* finds the next prime after the number "a" using "t" trials
- * of Miller-Rabin.
- *
- * bbs_style = 1 means the prime must be congruent to 3 mod 4
- */
-int mp_prime_next_prime(mp_int *a, int t, int bbs_style)
-{
- int err, res, x, y;
- mp_digit res_tab[PRIME_SIZE], step, kstep;
- mp_int b;
-
- /* ensure t is valid */
- if (t <= 0 || t > PRIME_SIZE) {
- return MP_VAL;
- }
-
- /* force positive */
- a->sign = MP_ZPOS;
-
- /* simple algo if a is less than the largest prime in the table */
- if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) {
- /* find which prime it is bigger than */
- for (x = PRIME_SIZE - 2; x >= 0; x--) {
- if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) {
- if (bbs_style == 1) {
- /* ok we found a prime smaller or
- * equal [so the next is larger]
- *
- * however, the prime must be
- * congruent to 3 mod 4
- */
- if ((ltm_prime_tab[x + 1] & 3) != 3) {
- /* scan upwards for a prime congruent to 3 mod 4 */
- for (y = x + 1; y < PRIME_SIZE; y++) {
- if ((ltm_prime_tab[y] & 3) == 3) {
- mp_set(a, ltm_prime_tab[y]);
- return MP_OKAY;
- }
- }
- }
- } else {
- mp_set(a, ltm_prime_tab[x + 1]);
- return MP_OKAY;
- }
- }
- }
- /* at this point a maybe 1 */
- if (mp_cmp_d(a, 1) == MP_EQ) {
- mp_set(a, 2);
- return MP_OKAY;
- }
- /* fall through to the sieve */
- }
-
- /* generate a prime congruent to 3 mod 4 or 1/3 mod 4? */
- if (bbs_style == 1) {
- kstep = 4;
- } else {
- kstep = 2;
- }
-
- /* at this point we will use a combination of a sieve and Miller-Rabin */
-
- if (bbs_style == 1) {
- /* if a mod 4 != 3 subtract the correct value to make it so */
- if ((a->dp[0] & 3) != 3) {
- if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; };
- }
- } else {
- if (mp_iseven(a) == 1) {
- /* force odd */
- if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) {
- return err;
- }
- }
- }
-
- /* generate the restable */
- for (x = 1; x < PRIME_SIZE; x++) {
- if ((err = mp_mod_d(a, ltm_prime_tab[x], res_tab + x)) != MP_OKAY) {
- return err;
- }
- }
-
- /* init temp used for Miller-Rabin Testing */
- if ((err = mp_init(&b)) != MP_OKAY) {
- return err;
- }
-
- for (;;) {
- /* skip to the next non-trivially divisible candidate */
- step = 0;
- do {
- /* y == 1 if any residue was zero [e.g. cannot be prime] */
- y = 0;
-
- /* increase step to next candidate */
- step += kstep;
-
- /* compute the new residue without using division */
- for (x = 1; x < PRIME_SIZE; x++) {
- /* add the step to each residue */
- res_tab[x] += kstep;
-
- /* subtract the modulus [instead of using division] */
- if (res_tab[x] >= ltm_prime_tab[x]) {
- res_tab[x] -= ltm_prime_tab[x];
- }
-
- /* set flag if zero */
- if (res_tab[x] == 0) {
- y = 1;
- }
- }
- } while (y == 1 && step < ((((mp_digit)1)<<DIGIT_BIT) - kstep));
-
- /* add the step */
- if ((err = mp_add_d(a, step, a)) != MP_OKAY) {
- goto LBL_ERR;
- }
-
- /* if didn't pass sieve and step == MAX then skip test */
- if (y == 1 && step >= ((((mp_digit)1)<<DIGIT_BIT) - kstep)) {
- continue;
- }
-
- /* is this prime? */
- for (x = 0; x < t; x++) {
- mp_set(&b, ltm_prime_tab[t]);
- if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
- goto LBL_ERR;
- }
- if (res == MP_NO) {
- break;
- }
- }
-
- if (res == MP_YES) {
- break;
- }
- }
-
- err = MP_OKAY;
-LBL_ERR:
- mp_clear(&b);
- return err;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_prime_next_prime.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_prime_rabin_miller_trials.c b/dep/StormLib/src/libtommath/bn_mp_prime_rabin_miller_trials.c
deleted file mode 100644
index 3f7608aa7f3..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_prime_rabin_miller_trials.c
+++ /dev/null
@@ -1,52 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_PRIME_RABIN_MILLER_TRIALS_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-
-static const struct {
- int k, t;
-} sizes[] = {
-{ 128, 28 },
-{ 256, 16 },
-{ 384, 10 },
-{ 512, 7 },
-{ 640, 6 },
-{ 768, 5 },
-{ 896, 4 },
-{ 1024, 4 }
-};
-
-/* returns # of RM trials required for a given bit size */
-int mp_prime_rabin_miller_trials(int size)
-{
- int x;
-
- for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) {
- if (sizes[x].k == size) {
- return sizes[x].t;
- } else if (sizes[x].k > size) {
- return (x == 0) ? sizes[0].t : sizes[x - 1].t;
- }
- }
- return sizes[x-1].t + 1;
-}
-
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_prime_rabin_miller_trials.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_prime_random_ex.c b/dep/StormLib/src/libtommath/bn_mp_prime_random_ex.c
deleted file mode 100644
index 4eec3f69e3e..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_prime_random_ex.c
+++ /dev/null
@@ -1,125 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_PRIME_RANDOM_EX_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* makes a truly random prime of a given size (bits),
- *
- * Flags are as follows:
- *
- * LTM_PRIME_BBS - make prime congruent to 3 mod 4
- * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS)
- * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero
- * LTM_PRIME_2MSB_ON - make the 2nd highest bit one
- *
- * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
- * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
- * so it can be NULL
- *
- */
-
-/* This is possibly the mother of all prime generation functions, muahahahahaha! */
-int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat)
-{
- unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb;
- int res, err, bsize, maskOR_msb_offset;
-
- /* sanity check the input */
- if (size <= 1 || t <= 0) {
- return MP_VAL;
- }
-
- /* LTM_PRIME_SAFE implies LTM_PRIME_BBS */
- if (flags & LTM_PRIME_SAFE) {
- flags |= LTM_PRIME_BBS;
- }
-
- /* calc the byte size */
- bsize = (size>>3) + ((size&7)?1:0);
-
- /* we need a buffer of bsize bytes */
- tmp = OPT_CAST(unsigned char) XMALLOC(bsize);
- if (tmp == NULL) {
- return MP_MEM;
- }
-
- /* calc the maskAND value for the MSbyte*/
- maskAND = ((size&7) == 0) ? 0xFF : (0xFF >> (8 - (size & 7)));
-
- /* calc the maskOR_msb */
- maskOR_msb = 0;
- maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0;
- if (flags & LTM_PRIME_2MSB_ON) {
- maskOR_msb |= 0x80 >> ((9 - size) & 7);
- }
-
- /* get the maskOR_lsb */
- maskOR_lsb = 1;
- if (flags & LTM_PRIME_BBS) {
- maskOR_lsb |= 3;
- }
-
- do {
- /* read the bytes */
- if (cb(tmp, bsize, dat) != bsize) {
- err = MP_VAL;
- goto error;
- }
-
- /* work over the MSbyte */
- tmp[0] &= maskAND;
- tmp[0] |= 1 << ((size - 1) & 7);
-
- /* mix in the maskORs */
- tmp[maskOR_msb_offset] |= maskOR_msb;
- tmp[bsize-1] |= maskOR_lsb;
-
- /* read it in */
- if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) { goto error; }
-
- /* is it prime? */
- if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; }
- if (res == MP_NO) {
- continue;
- }
-
- if (flags & LTM_PRIME_SAFE) {
- /* see if (a-1)/2 is prime */
- if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { goto error; }
- if ((err = mp_div_2(a, a)) != MP_OKAY) { goto error; }
-
- /* is it prime? */
- if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; }
- }
- } while (res == MP_NO);
-
- if (flags & LTM_PRIME_SAFE) {
- /* restore a to the original value */
- if ((err = mp_mul_2(a, a)) != MP_OKAY) { goto error; }
- if ((err = mp_add_d(a, 1, a)) != MP_OKAY) { goto error; }
- }
-
- err = MP_OKAY;
-error:
- XFREE(tmp);
- return err;
-}
-
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_prime_random_ex.c,v $ */
-/* $Revision: 1.5 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_radix_size.c b/dep/StormLib/src/libtommath/bn_mp_radix_size.c
deleted file mode 100644
index 2378f1fc1ac..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_radix_size.c
+++ /dev/null
@@ -1,78 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_RADIX_SIZE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* returns size of ASCII reprensentation */
-int mp_radix_size (mp_int * a, int radix, int *size)
-{
- int res, digs;
- mp_int t;
- mp_digit d;
-
- *size = 0;
-
- /* special case for binary */
- if (radix == 2) {
- *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
- return MP_OKAY;
- }
-
- /* make sure the radix is in range */
- if (radix < 2 || radix > 64) {
- return MP_VAL;
- }
-
- if (mp_iszero(a) == MP_YES) {
- *size = 2;
- return MP_OKAY;
- }
-
- /* digs is the digit count */
- digs = 0;
-
- /* if it's negative add one for the sign */
- if (a->sign == MP_NEG) {
- ++digs;
- }
-
- /* init a copy of the input */
- if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
- return res;
- }
-
- /* force temp to positive */
- t.sign = MP_ZPOS;
-
- /* fetch out all of the digits */
- while (mp_iszero (&t) == MP_NO) {
- if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
- mp_clear (&t);
- return res;
- }
- ++digs;
- }
- mp_clear (&t);
-
- /* return digs + 1, the 1 is for the NULL byte that would be required. */
- *size = digs + 1;
- return MP_OKAY;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_radix_size.c,v $ */
-/* $Revision: 1.5 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_radix_smap.c b/dep/StormLib/src/libtommath/bn_mp_radix_smap.c
deleted file mode 100644
index 5cbe9520b5b..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_radix_smap.c
+++ /dev/null
@@ -1,24 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_RADIX_SMAP_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* chars used in radix conversions */
-const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_radix_smap.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_rand.c b/dep/StormLib/src/libtommath/bn_mp_rand.c
deleted file mode 100644
index e1241785e88..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_rand.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_RAND_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* makes a pseudo-random int of a given size */
-int
-mp_rand (mp_int * a, int digits)
-{
- int res;
- mp_digit d;
-
- mp_zero (a);
- if (digits <= 0) {
- return MP_OKAY;
- }
-
- /* first place a random non-zero digit */
- do {
- d = ((mp_digit) abs (rand ())) & MP_MASK;
- } while (d == 0);
-
- if ((res = mp_add_d (a, d, a)) != MP_OKAY) {
- return res;
- }
-
- while (--digits > 0) {
- if ((res = mp_lshd (a, 1)) != MP_OKAY) {
- return res;
- }
-
- if ((res = mp_add_d (a, ((mp_digit) abs (rand ())), a)) != MP_OKAY) {
- return res;
- }
- }
-
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_rand.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_read_radix.c b/dep/StormLib/src/libtommath/bn_mp_read_radix.c
deleted file mode 100644
index 6869668fb88..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_read_radix.c
+++ /dev/null
@@ -1,85 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_READ_RADIX_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* read a string [ASCII] in a given radix */
-int mp_read_radix (mp_int * a, const char *str, int radix)
-{
- int y, res, neg;
- char ch;
-
- /* zero the digit bignum */
- mp_zero(a);
-
- /* make sure the radix is ok */
- if (radix < 2 || radix > 64) {
- return MP_VAL;
- }
-
- /* if the leading digit is a
- * minus set the sign to negative.
- */
- if (*str == '-') {
- ++str;
- neg = MP_NEG;
- } else {
- neg = MP_ZPOS;
- }
-
- /* set the integer to the default of zero */
- mp_zero (a);
-
- /* process each digit of the string */
- while (*str) {
- /* if the radix < 36 the conversion is case insensitive
- * this allows numbers like 1AB and 1ab to represent the same value
- * [e.g. in hex]
- */
- ch = (char) ((radix < 36) ? toupper (*str) : *str);
- for (y = 0; y < 64; y++) {
- if (ch == mp_s_rmap[y]) {
- break;
- }
- }
-
- /* if the char was found in the map
- * and is less than the given radix add it
- * to the number, otherwise exit the loop.
- */
- if (y < radix) {
- if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) {
- return res;
- }
- if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) {
- return res;
- }
- } else {
- break;
- }
- ++str;
- }
-
- /* set the sign only if a != 0 */
- if (mp_iszero(a) != 1) {
- a->sign = neg;
- }
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_read_radix.c,v $ */
-/* $Revision: 1.5 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_read_signed_bin.c b/dep/StormLib/src/libtommath/bn_mp_read_signed_bin.c
deleted file mode 100644
index e9a780c28aa..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_read_signed_bin.c
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_READ_SIGNED_BIN_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* read signed bin, big endian, first byte is 0==positive or 1==negative */
-int mp_read_signed_bin (mp_int * a, const unsigned char *b, int c)
-{
- int res;
-
- /* read magnitude */
- if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) {
- return res;
- }
-
- /* first byte is 0 for positive, non-zero for negative */
- if (b[0] == 0) {
- a->sign = MP_ZPOS;
- } else {
- a->sign = MP_NEG;
- }
-
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_read_signed_bin.c,v $ */
-/* $Revision: 1.5 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_read_unsigned_bin.c b/dep/StormLib/src/libtommath/bn_mp_read_unsigned_bin.c
deleted file mode 100644
index 7d35370418c..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_read_unsigned_bin.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_READ_UNSIGNED_BIN_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* reads a unsigned char array, assumes the msb is stored first [big endian] */
-int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c)
-{
- int res;
-
- /* make sure there are at least two digits */
- if (a->alloc < 2) {
- if ((res = mp_grow(a, 2)) != MP_OKAY) {
- return res;
- }
- }
-
- /* zero the int */
- mp_zero (a);
-
- /* read the bytes in */
- while (c-- > 0) {
- if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {
- return res;
- }
-
-#ifndef MP_8BIT
- a->dp[0] |= *b++;
- a->used += 1;
-#else
- a->dp[0] = (*b & MP_MASK);
- a->dp[1] |= ((*b++ >> 7U) & 1);
- a->used += 2;
-#endif
- }
- mp_clamp (a);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_read_unsigned_bin.c,v $ */
-/* $Revision: 1.5 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_reduce.c b/dep/StormLib/src/libtommath/bn_mp_reduce.c
deleted file mode 100644
index 3a6bb5aca90..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_reduce.c
+++ /dev/null
@@ -1,100 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_REDUCE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* reduces x mod m, assumes 0 < x < m**2, mu is
- * precomputed via mp_reduce_setup.
- * From HAC pp.604 Algorithm 14.42
- */
-int mp_reduce (mp_int * x, mp_int * m, mp_int * mu)
-{
- mp_int q;
- int res, um = m->used;
-
- /* q = x */
- if ((res = mp_init_copy (&q, x)) != MP_OKAY) {
- return res;
- }
-
- /* q1 = x / b**(k-1) */
- mp_rshd (&q, um - 1);
-
- /* according to HAC this optimization is ok */
- if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) {
- if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) {
- goto CLEANUP;
- }
- } else {
-#ifdef BN_S_MP_MUL_HIGH_DIGS_C
- if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
- goto CLEANUP;
- }
-#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
- if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
- goto CLEANUP;
- }
-#else
- {
- res = MP_VAL;
- goto CLEANUP;
- }
-#endif
- }
-
- /* q3 = q2 / b**(k+1) */
- mp_rshd (&q, um + 1);
-
- /* x = x mod b**(k+1), quick (no division) */
- if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) {
- goto CLEANUP;
- }
-
- /* q = q * m mod b**(k+1), quick (no division) */
- if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) {
- goto CLEANUP;
- }
-
- /* x = x - q */
- if ((res = mp_sub (x, &q, x)) != MP_OKAY) {
- goto CLEANUP;
- }
-
- /* If x < 0, add b**(k+1) to it */
- if (mp_cmp_d (x, 0) == MP_LT) {
- mp_set (&q, 1);
- if ((res = mp_lshd (&q, um + 1)) != MP_OKAY)
- goto CLEANUP;
- if ((res = mp_add (x, &q, x)) != MP_OKAY)
- goto CLEANUP;
- }
-
- /* Back off if it's too big */
- while (mp_cmp (x, m) != MP_LT) {
- if ((res = s_mp_sub (x, m, x)) != MP_OKAY) {
- goto CLEANUP;
- }
- }
-
-CLEANUP:
- mp_clear (&q);
-
- return res;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_reduce.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_reduce_2k.c b/dep/StormLib/src/libtommath/bn_mp_reduce_2k.c
deleted file mode 100644
index 3191d829179..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_reduce_2k.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_REDUCE_2K_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* reduces a modulo n where n is of the form 2**p - d */
-int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d)
-{
- mp_int q;
- int p, res;
-
- if ((res = mp_init(&q)) != MP_OKAY) {
- return res;
- }
-
- p = mp_count_bits(n);
-top:
- /* q = a/2**p, a = a mod 2**p */
- if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
- goto ERR;
- }
-
- if (d != 1) {
- /* q = q * d */
- if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) {
- goto ERR;
- }
- }
-
- /* a = a + q */
- if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
- goto ERR;
- }
-
- if (mp_cmp_mag(a, n) != MP_LT) {
- s_mp_sub(a, n, a);
- goto top;
- }
-
-ERR:
- mp_clear(&q);
- return res;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_reduce_2k_l.c b/dep/StormLib/src/libtommath/bn_mp_reduce_2k_l.c
deleted file mode 100644
index 49b7e344ed9..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_reduce_2k_l.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_REDUCE_2K_L_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* reduces a modulo n where n is of the form 2**p - d
- This differs from reduce_2k since "d" can be larger
- than a single digit.
-*/
-int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d)
-{
- mp_int q;
- int p, res;
-
- if ((res = mp_init(&q)) != MP_OKAY) {
- return res;
- }
-
- p = mp_count_bits(n);
-top:
- /* q = a/2**p, a = a mod 2**p */
- if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
- goto ERR;
- }
-
- /* q = q * d */
- if ((res = mp_mul(&q, d, &q)) != MP_OKAY) {
- goto ERR;
- }
-
- /* a = a + q */
- if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
- goto ERR;
- }
-
- if (mp_cmp_mag(a, n) != MP_LT) {
- s_mp_sub(a, n, a);
- goto top;
- }
-
-ERR:
- mp_clear(&q);
- return res;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k_l.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_reduce_2k_setup.c b/dep/StormLib/src/libtommath/bn_mp_reduce_2k_setup.c
deleted file mode 100644
index aa3b3bad8db..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_reduce_2k_setup.c
+++ /dev/null
@@ -1,47 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_REDUCE_2K_SETUP_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* determines the setup value */
-int mp_reduce_2k_setup(mp_int *a, mp_digit *d)
-{
- int res, p;
- mp_int tmp;
-
- if ((res = mp_init(&tmp)) != MP_OKAY) {
- return res;
- }
-
- p = mp_count_bits(a);
- if ((res = mp_2expt(&tmp, p)) != MP_OKAY) {
- mp_clear(&tmp);
- return res;
- }
-
- if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) {
- mp_clear(&tmp);
- return res;
- }
-
- *d = tmp.dp[0];
- mp_clear(&tmp);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k_setup.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_reduce_2k_setup_l.c b/dep/StormLib/src/libtommath/bn_mp_reduce_2k_setup_l.c
deleted file mode 100644
index 4eca87040bc..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_reduce_2k_setup_l.c
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_REDUCE_2K_SETUP_L_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* determines the setup value */
-int mp_reduce_2k_setup_l(mp_int *a, mp_int *d)
-{
- int res;
- mp_int tmp;
-
- if ((res = mp_init(&tmp)) != MP_OKAY) {
- return res;
- }
-
- if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) {
- goto ERR;
- }
-
- if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) {
- goto ERR;
- }
-
-ERR:
- mp_clear(&tmp);
- return res;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k_setup_l.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_reduce_is_2k.c b/dep/StormLib/src/libtommath/bn_mp_reduce_is_2k.c
deleted file mode 100644
index b9ede978964..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_reduce_is_2k.c
+++ /dev/null
@@ -1,52 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_REDUCE_IS_2K_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* determines if mp_reduce_2k can be used */
-int mp_reduce_is_2k(mp_int *a)
-{
- int ix, iy, iw;
- mp_digit iz;
-
- if (a->used == 0) {
- return MP_NO;
- } else if (a->used == 1) {
- return MP_YES;
- } else if (a->used > 1) {
- iy = mp_count_bits(a);
- iz = 1;
- iw = 1;
-
- /* Test every bit from the second digit up, must be 1 */
- for (ix = DIGIT_BIT; ix < iy; ix++) {
- if ((a->dp[iw] & iz) == 0) {
- return MP_NO;
- }
- iz <<= 1;
- if (iz > (mp_digit)MP_MASK) {
- ++iw;
- iz = 1;
- }
- }
- }
- return MP_YES;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_is_2k.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_reduce_is_2k_l.c b/dep/StormLib/src/libtommath/bn_mp_reduce_is_2k_l.c
deleted file mode 100644
index 787875f8bbb..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_reduce_is_2k_l.c
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_REDUCE_IS_2K_L_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* determines if reduce_2k_l can be used */
-int mp_reduce_is_2k_l(mp_int *a)
-{
- int ix, iy;
-
- if (a->used == 0) {
- return MP_NO;
- } else if (a->used == 1) {
- return MP_YES;
- } else if (a->used > 1) {
- /* if more than half of the digits are -1 we're sold */
- for (iy = ix = 0; ix < a->used; ix++) {
- if (a->dp[ix] == MP_MASK) {
- ++iy;
- }
- }
- return (iy >= (a->used/2)) ? MP_YES : MP_NO;
-
- }
- return MP_NO;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_is_2k_l.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_reduce_setup.c b/dep/StormLib/src/libtommath/bn_mp_reduce_setup.c
deleted file mode 100644
index 00e0a62b9bd..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_reduce_setup.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_REDUCE_SETUP_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* pre-calculate the value required for Barrett reduction
- * For a given modulus "b" it calulates the value required in "a"
- */
-int mp_reduce_setup (mp_int * a, mp_int * b)
-{
- int res;
-
- if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) {
- return res;
- }
- return mp_div (a, b, a, NULL);
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_setup.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_rshd.c b/dep/StormLib/src/libtommath/bn_mp_rshd.c
deleted file mode 100644
index eac6721baf0..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_rshd.c
+++ /dev/null
@@ -1,72 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_RSHD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* shift right a certain amount of digits */
-void mp_rshd (mp_int * a, int b)
-{
- int x;
-
- /* if b <= 0 then ignore it */
- if (b <= 0) {
- return;
- }
-
- /* if b > used then simply zero it and return */
- if (a->used <= b) {
- mp_zero (a);
- return;
- }
-
- {
- register mp_digit *bottom, *top;
-
- /* shift the digits down */
-
- /* bottom */
- bottom = a->dp;
-
- /* top [offset into digits] */
- top = a->dp + b;
-
- /* this is implemented as a sliding window where
- * the window is b-digits long and digits from
- * the top of the window are copied to the bottom
- *
- * e.g.
-
- b-2 | b-1 | b0 | b1 | b2 | ... | bb | ---->
- /\ | ---->
- \-------------------/ ---->
- */
- for (x = 0; x < (a->used - b); x++) {
- *bottom++ = *top++;
- }
-
- /* zero the top digits */
- for (; x < a->used; x++) {
- *bottom++ = 0;
- }
- }
-
- /* remove excess digits */
- a->used -= b;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_rshd.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_set.c b/dep/StormLib/src/libtommath/bn_mp_set.c
deleted file mode 100644
index d76d5bbd324..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_set.c
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_SET_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* set to a digit */
-void mp_set (mp_int * a, mp_digit b)
-{
- mp_zero (a);
- a->dp[0] = b & MP_MASK;
- a->used = (a->dp[0] != 0) ? 1 : 0;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_set.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_set_int.c b/dep/StormLib/src/libtommath/bn_mp_set_int.c
deleted file mode 100644
index 68cf0e32b27..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_set_int.c
+++ /dev/null
@@ -1,48 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_SET_INT_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* set a 32-bit const */
-int mp_set_int (mp_int * a, unsigned long b)
-{
- int x, res;
-
- mp_zero (a);
-
- /* set four bits at a time */
- for (x = 0; x < 8; x++) {
- /* shift the number up four bits */
- if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) {
- return res;
- }
-
- /* OR in the top four bits of the source */
- a->dp[0] |= (b >> 28) & 15;
-
- /* shift the source up to the next four bits */
- b <<= 4;
-
- /* ensure that digits are not clamped off */
- a->used += 1;
- }
- mp_clamp (a);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_set_int.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_shrink.c b/dep/StormLib/src/libtommath/bn_mp_shrink.c
deleted file mode 100644
index 54920d1400a..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_shrink.c
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_SHRINK_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* shrink a bignum */
-int mp_shrink (mp_int * a)
-{
- mp_digit *tmp;
- if (a->alloc != a->used && a->used > 0) {
- if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * a->used)) == NULL) {
- return MP_MEM;
- }
- a->dp = tmp;
- a->alloc = a->used;
- }
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_shrink.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_signed_bin_size.c b/dep/StormLib/src/libtommath/bn_mp_signed_bin_size.c
deleted file mode 100644
index b9492a5e5ed..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_signed_bin_size.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_SIGNED_BIN_SIZE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* get the size for an signed equivalent */
-int mp_signed_bin_size (mp_int * a)
-{
- return 1 + mp_unsigned_bin_size (a);
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_signed_bin_size.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_sqr.c b/dep/StormLib/src/libtommath/bn_mp_sqr.c
deleted file mode 100644
index c10fa6f3b6e..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_sqr.c
+++ /dev/null
@@ -1,58 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_SQR_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* computes b = a*a */
-int
-mp_sqr (mp_int * a, mp_int * b)
-{
- int res;
-
-#ifdef BN_MP_TOOM_SQR_C
- /* use Toom-Cook? */
- if (a->used >= TOOM_SQR_CUTOFF) {
- res = mp_toom_sqr(a, b);
- /* Karatsuba? */
- } else
-#endif
-#ifdef BN_MP_KARATSUBA_SQR_C
-if (a->used >= KARATSUBA_SQR_CUTOFF) {
- res = mp_karatsuba_sqr (a, b);
- } else
-#endif
- {
-#ifdef BN_FAST_S_MP_SQR_C
- /* can we use the fast comba multiplier? */
- if ((a->used * 2 + 1) < MP_WARRAY &&
- a->used <
- (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) {
- res = fast_s_mp_sqr (a, b);
- } else
-#endif
-#ifdef BN_S_MP_SQR_C
- res = s_mp_sqr (a, b);
-#else
- res = MP_VAL;
-#endif
- }
- b->sign = MP_ZPOS;
- return res;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_sqr.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_sqrmod.c b/dep/StormLib/src/libtommath/bn_mp_sqrmod.c
deleted file mode 100644
index 5f4b2f3d663..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_sqrmod.c
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_SQRMOD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* c = a * a (mod b) */
-int
-mp_sqrmod (mp_int * a, mp_int * b, mp_int * c)
-{
- int res;
- mp_int t;
-
- if ((res = mp_init (&t)) != MP_OKAY) {
- return res;
- }
-
- if ((res = mp_sqr (a, &t)) != MP_OKAY) {
- mp_clear (&t);
- return res;
- }
- res = mp_mod (&t, b, c);
- mp_clear (&t);
- return res;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_sqrmod.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_sqrt.c b/dep/StormLib/src/libtommath/bn_mp_sqrt.c
deleted file mode 100644
index e15ba98ca88..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_sqrt.c
+++ /dev/null
@@ -1,81 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_SQRT_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* this function is less generic than mp_n_root, simpler and faster */
-int mp_sqrt(mp_int *arg, mp_int *ret)
-{
- int res;
- mp_int t1,t2;
-
- /* must be positive */
- if (arg->sign == MP_NEG) {
- return MP_VAL;
- }
-
- /* easy out */
- if (mp_iszero(arg) == MP_YES) {
- mp_zero(ret);
- return MP_OKAY;
- }
-
- if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) {
- return res;
- }
-
- if ((res = mp_init(&t2)) != MP_OKAY) {
- goto E2;
- }
-
- /* First approx. (not very bad for large arg) */
- mp_rshd (&t1,t1.used/2);
-
- /* t1 > 0 */
- if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
- goto E1;
- }
- if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
- goto E1;
- }
- if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
- goto E1;
- }
- /* And now t1 > sqrt(arg) */
- do {
- if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
- goto E1;
- }
- if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
- goto E1;
- }
- if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
- goto E1;
- }
- /* t1 >= sqrt(arg) >= t2 at this point */
- } while (mp_cmp_mag(&t1,&t2) == MP_GT);
-
- mp_exch(&t1,ret);
-
-E1: mp_clear(&t2);
-E2: mp_clear(&t1);
- return res;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_sqrt.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_sub.c b/dep/StormLib/src/libtommath/bn_mp_sub.c
deleted file mode 100644
index 6e72138610f..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_sub.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_SUB_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* high level subtraction (handles signs) */
-int
-mp_sub (mp_int * a, mp_int * b, mp_int * c)
-{
- int sa, sb, res;
-
- sa = a->sign;
- sb = b->sign;
-
- if (sa != sb) {
- /* subtract a negative from a positive, OR */
- /* subtract a positive from a negative. */
- /* In either case, ADD their magnitudes, */
- /* and use the sign of the first number. */
- c->sign = sa;
- res = s_mp_add (a, b, c);
- } else {
- /* subtract a positive from a positive, OR */
- /* subtract a negative from a negative. */
- /* First, take the difference between their */
- /* magnitudes, then... */
- if (mp_cmp_mag (a, b) != MP_LT) {
- /* Copy the sign from the first */
- c->sign = sa;
- /* The first has a larger or equal magnitude */
- res = s_mp_sub (a, b, c);
- } else {
- /* The result has the *opposite* sign from */
- /* the first number. */
- c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
- /* The second has a larger magnitude */
- res = s_mp_sub (b, a, c);
- }
- }
- return res;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_sub.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_sub_d.c b/dep/StormLib/src/libtommath/bn_mp_sub_d.c
deleted file mode 100644
index aa08e31b30b..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_sub_d.c
+++ /dev/null
@@ -1,93 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_SUB_D_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* single digit subtraction */
-int
-mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
-{
- mp_digit *tmpa, *tmpc, mu;
- int res, ix, oldused;
-
- /* grow c as required */
- if (c->alloc < a->used + 1) {
- if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
- return res;
- }
- }
-
- /* if a is negative just do an unsigned
- * addition [with fudged signs]
- */
- if (a->sign == MP_NEG) {
- a->sign = MP_ZPOS;
- res = mp_add_d(a, b, c);
- a->sign = c->sign = MP_NEG;
-
- /* clamp */
- mp_clamp(c);
-
- return res;
- }
-
- /* setup regs */
- oldused = c->used;
- tmpa = a->dp;
- tmpc = c->dp;
-
- /* if a <= b simply fix the single digit */
- if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) {
- if (a->used == 1) {
- *tmpc++ = b - *tmpa;
- } else {
- *tmpc++ = b;
- }
- ix = 1;
-
- /* negative/1digit */
- c->sign = MP_NEG;
- c->used = 1;
- } else {
- /* positive/size */
- c->sign = MP_ZPOS;
- c->used = a->used;
-
- /* subtract first digit */
- *tmpc = *tmpa++ - b;
- mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
- *tmpc++ &= MP_MASK;
-
- /* handle rest of the digits */
- for (ix = 1; ix < a->used; ix++) {
- *tmpc = *tmpa++ - mu;
- mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
- *tmpc++ &= MP_MASK;
- }
- }
-
- /* zero excess digits */
- while (ix++ < oldused) {
- *tmpc++ = 0;
- }
- mp_clamp(c);
- return MP_OKAY;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_sub_d.c,v $ */
-/* $Revision: 1.6 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_submod.c b/dep/StormLib/src/libtommath/bn_mp_submod.c
deleted file mode 100644
index 6617ff42ceb..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_submod.c
+++ /dev/null
@@ -1,42 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_SUBMOD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* d = a - b (mod c) */
-int
-mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
-{
- int res;
- mp_int t;
-
-
- if ((res = mp_init (&t)) != MP_OKAY) {
- return res;
- }
-
- if ((res = mp_sub (a, b, &t)) != MP_OKAY) {
- mp_clear (&t);
- return res;
- }
- res = mp_mod (&t, c, d);
- mp_clear (&t);
- return res;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_submod.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_to_signed_bin.c b/dep/StormLib/src/libtommath/bn_mp_to_signed_bin.c
deleted file mode 100644
index 154f64b5667..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_to_signed_bin.c
+++ /dev/null
@@ -1,33 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_TO_SIGNED_BIN_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* store in signed [big endian] format */
-int mp_to_signed_bin (mp_int * a, unsigned char *b)
-{
- int res;
-
- if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) {
- return res;
- }
- b[0] = (unsigned char) ((a->sign == MP_ZPOS) ? 0 : 1);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_to_signed_bin.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_to_signed_bin_n.c b/dep/StormLib/src/libtommath/bn_mp_to_signed_bin_n.c
deleted file mode 100644
index e119c380a91..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_to_signed_bin_n.c
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_TO_SIGNED_BIN_N_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* store in signed [big endian] format */
-int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen)
-{
- if (*outlen < (unsigned long)mp_signed_bin_size(a)) {
- return MP_VAL;
- }
- *outlen = mp_signed_bin_size(a);
- return mp_to_signed_bin(a, b);
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_to_signed_bin_n.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_to_unsigned_bin.c b/dep/StormLib/src/libtommath/bn_mp_to_unsigned_bin.c
deleted file mode 100644
index ce69e5bf364..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_to_unsigned_bin.c
+++ /dev/null
@@ -1,48 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_TO_UNSIGNED_BIN_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* store in unsigned [big endian] format */
-int mp_to_unsigned_bin (mp_int * a, unsigned char *b)
-{
- int x, res;
- mp_int t;
-
- if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
- return res;
- }
-
- x = 0;
- while (mp_iszero (&t) == 0) {
-#ifndef MP_8BIT
- b[x++] = (unsigned char) (t.dp[0] & 255);
-#else
- b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7));
-#endif
- if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) {
- mp_clear (&t);
- return res;
- }
- }
- bn_reverse (b, x);
- mp_clear (&t);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_to_unsigned_bin.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_to_unsigned_bin_n.c b/dep/StormLib/src/libtommath/bn_mp_to_unsigned_bin_n.c
deleted file mode 100644
index dfa27c41bab..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_to_unsigned_bin_n.c
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_TO_UNSIGNED_BIN_N_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* store in unsigned [big endian] format */
-int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen)
-{
- if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) {
- return MP_VAL;
- }
- *outlen = mp_unsigned_bin_size(a);
- return mp_to_unsigned_bin(a, b);
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_to_unsigned_bin_n.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_toom_mul.c b/dep/StormLib/src/libtommath/bn_mp_toom_mul.c
deleted file mode 100644
index e48c6b355c0..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_toom_mul.c
+++ /dev/null
@@ -1,284 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_TOOM_MUL_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* multiplication using the Toom-Cook 3-way algorithm
- *
- * Much more complicated than Karatsuba but has a lower
- * asymptotic running time of O(N**1.464). This algorithm is
- * only particularly useful on VERY large inputs
- * (we're talking 1000s of digits here...).
-*/
-int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
-{
- mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2;
- int res, B;
-
- /* init temps */
- if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4,
- &a0, &a1, &a2, &b0, &b1,
- &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) {
- return res;
- }
-
- /* B */
- B = MIN(a->used, b->used) / 3;
-
- /* a = a2 * B**2 + a1 * B + a0 */
- if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
- goto ERR;
- }
-
- if ((res = mp_copy(a, &a1)) != MP_OKAY) {
- goto ERR;
- }
- mp_rshd(&a1, B);
- mp_mod_2d(&a1, DIGIT_BIT * B, &a1);
-
- if ((res = mp_copy(a, &a2)) != MP_OKAY) {
- goto ERR;
- }
- mp_rshd(&a2, B*2);
-
- /* b = b2 * B**2 + b1 * B + b0 */
- if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) {
- goto ERR;
- }
-
- if ((res = mp_copy(b, &b1)) != MP_OKAY) {
- goto ERR;
- }
- mp_rshd(&b1, B);
- mp_mod_2d(&b1, DIGIT_BIT * B, &b1);
-
- if ((res = mp_copy(b, &b2)) != MP_OKAY) {
- goto ERR;
- }
- mp_rshd(&b2, B*2);
-
- /* w0 = a0*b0 */
- if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) {
- goto ERR;
- }
-
- /* w4 = a2 * b2 */
- if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) {
- goto ERR;
- }
-
- /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */
- if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
-
- if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) {
- goto ERR;
- }
-
- if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) {
- goto ERR;
- }
-
- /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */
- if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
-
- if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
- goto ERR;
- }
-
- if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) {
- goto ERR;
- }
-
-
- /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */
- if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) {
- goto ERR;
- }
-
- /* now solve the matrix
-
- 0 0 0 0 1
- 1 2 4 8 16
- 1 1 1 1 1
- 16 8 4 2 1
- 1 0 0 0 0
-
- using 12 subtractions, 4 shifts,
- 2 small divisions and 1 small multiplication
- */
-
- /* r1 - r4 */
- if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
- goto ERR;
- }
- /* r3 - r0 */
- if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
- goto ERR;
- }
- /* r1/2 */
- if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
- goto ERR;
- }
- /* r3/2 */
- if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
- goto ERR;
- }
- /* r2 - r0 - r4 */
- if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
- goto ERR;
- }
- /* r1 - r2 */
- if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
- goto ERR;
- }
- /* r3 - r2 */
- if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
- goto ERR;
- }
- /* r1 - 8r0 */
- if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
- goto ERR;
- }
- /* r3 - 8r4 */
- if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
- goto ERR;
- }
- /* 3r2 - r1 - r3 */
- if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
- goto ERR;
- }
- /* r1 - r2 */
- if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
- goto ERR;
- }
- /* r3 - r2 */
- if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
- goto ERR;
- }
- /* r1/3 */
- if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
- goto ERR;
- }
- /* r3/3 */
- if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
- goto ERR;
- }
-
- /* at this point shift W[n] by B*n */
- if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
- goto ERR;
- }
-
- if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) {
- goto ERR;
- }
-
-ERR:
- mp_clear_multi(&w0, &w1, &w2, &w3, &w4,
- &a0, &a1, &a2, &b0, &b1,
- &b2, &tmp1, &tmp2, NULL);
- return res;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_toom_mul.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_toom_sqr.c b/dep/StormLib/src/libtommath/bn_mp_toom_sqr.c
deleted file mode 100644
index fd8bc672a1a..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_toom_sqr.c
+++ /dev/null
@@ -1,226 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_TOOM_SQR_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* squaring using Toom-Cook 3-way algorithm */
-int
-mp_toom_sqr(mp_int *a, mp_int *b)
-{
- mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2;
- int res, B;
-
- /* init temps */
- if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) {
- return res;
- }
-
- /* B */
- B = a->used / 3;
-
- /* a = a2 * B**2 + a1 * B + a0 */
- if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
- goto ERR;
- }
-
- if ((res = mp_copy(a, &a1)) != MP_OKAY) {
- goto ERR;
- }
- mp_rshd(&a1, B);
- mp_mod_2d(&a1, DIGIT_BIT * B, &a1);
-
- if ((res = mp_copy(a, &a2)) != MP_OKAY) {
- goto ERR;
- }
- mp_rshd(&a2, B*2);
-
- /* w0 = a0*a0 */
- if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) {
- goto ERR;
- }
-
- /* w4 = a2 * a2 */
- if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) {
- goto ERR;
- }
-
- /* w1 = (a2 + 2(a1 + 2a0))**2 */
- if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
-
- if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) {
- goto ERR;
- }
-
- /* w3 = (a0 + 2(a1 + 2a2))**2 */
- if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
-
- if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) {
- goto ERR;
- }
-
-
- /* w2 = (a2 + a1 + a0)**2 */
- if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) {
- goto ERR;
- }
-
- /* now solve the matrix
-
- 0 0 0 0 1
- 1 2 4 8 16
- 1 1 1 1 1
- 16 8 4 2 1
- 1 0 0 0 0
-
- using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication.
- */
-
- /* r1 - r4 */
- if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
- goto ERR;
- }
- /* r3 - r0 */
- if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
- goto ERR;
- }
- /* r1/2 */
- if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
- goto ERR;
- }
- /* r3/2 */
- if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
- goto ERR;
- }
- /* r2 - r0 - r4 */
- if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
- goto ERR;
- }
- /* r1 - r2 */
- if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
- goto ERR;
- }
- /* r3 - r2 */
- if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
- goto ERR;
- }
- /* r1 - 8r0 */
- if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
- goto ERR;
- }
- /* r3 - 8r4 */
- if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
- goto ERR;
- }
- /* 3r2 - r1 - r3 */
- if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
- goto ERR;
- }
- /* r1 - r2 */
- if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
- goto ERR;
- }
- /* r3 - r2 */
- if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
- goto ERR;
- }
- /* r1/3 */
- if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
- goto ERR;
- }
- /* r3/3 */
- if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
- goto ERR;
- }
-
- /* at this point shift W[n] by B*n */
- if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
- goto ERR;
- }
-
- if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
- goto ERR;
- }
- if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) {
- goto ERR;
- }
-
-ERR:
- mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL);
- return res;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_toom_sqr.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_toradix.c b/dep/StormLib/src/libtommath/bn_mp_toradix.c
deleted file mode 100644
index 539abe9ba6d..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_toradix.c
+++ /dev/null
@@ -1,75 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_TORADIX_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* stores a bignum as a ASCII string in a given radix (2..64) */
-int mp_toradix (mp_int * a, char *str, int radix)
-{
- int res, digs;
- mp_int t;
- mp_digit d;
- char *_s = str;
-
- /* check range of the radix */
- if (radix < 2 || radix > 64) {
- return MP_VAL;
- }
-
- /* quick out if its zero */
- if (mp_iszero(a) == 1) {
- *str++ = '0';
- *str = '\0';
- return MP_OKAY;
- }
-
- if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
- return res;
- }
-
- /* if it is negative output a - */
- if (t.sign == MP_NEG) {
- ++_s;
- *str++ = '-';
- t.sign = MP_ZPOS;
- }
-
- digs = 0;
- while (mp_iszero (&t) == 0) {
- if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
- mp_clear (&t);
- return res;
- }
- *str++ = mp_s_rmap[d];
- ++digs;
- }
-
- /* reverse the digits of the string. In this case _s points
- * to the first digit [exluding the sign] of the number]
- */
- bn_reverse ((unsigned char *)_s, digs);
-
- /* append a NULL so the string is properly terminated */
- *str = '\0';
-
- mp_clear (&t);
- return MP_OKAY;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_toradix.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_toradix_n.c b/dep/StormLib/src/libtommath/bn_mp_toradix_n.c
deleted file mode 100644
index 0322f8d4b2a..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_toradix_n.c
+++ /dev/null
@@ -1,88 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_TORADIX_N_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* stores a bignum as a ASCII string in a given radix (2..64)
- *
- * Stores upto maxlen-1 chars and always a NULL byte
- */
-int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen)
-{
- int res, digs;
- mp_int t;
- mp_digit d;
- char *_s = str;
-
- /* check range of the maxlen, radix */
- if (maxlen < 2 || radix < 2 || radix > 64) {
- return MP_VAL;
- }
-
- /* quick out if its zero */
- if (mp_iszero(a) == MP_YES) {
- *str++ = '0';
- *str = '\0';
- return MP_OKAY;
- }
-
- if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
- return res;
- }
-
- /* if it is negative output a - */
- if (t.sign == MP_NEG) {
- /* we have to reverse our digits later... but not the - sign!! */
- ++_s;
-
- /* store the flag and mark the number as positive */
- *str++ = '-';
- t.sign = MP_ZPOS;
-
- /* subtract a char */
- --maxlen;
- }
-
- digs = 0;
- while (mp_iszero (&t) == 0) {
- if (--maxlen < 1) {
- /* no more room */
- break;
- }
- if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
- mp_clear (&t);
- return res;
- }
- *str++ = mp_s_rmap[d];
- ++digs;
- }
-
- /* reverse the digits of the string. In this case _s points
- * to the first digit [exluding the sign] of the number
- */
- bn_reverse ((unsigned char *)_s, digs);
-
- /* append a NULL so the string is properly terminated */
- *str = '\0';
-
- mp_clear (&t);
- return MP_OKAY;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_toradix_n.c,v $ */
-/* $Revision: 1.5 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_unsigned_bin_size.c b/dep/StormLib/src/libtommath/bn_mp_unsigned_bin_size.c
deleted file mode 100644
index 88f3e92dde8..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_unsigned_bin_size.c
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_UNSIGNED_BIN_SIZE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* get the size for an unsigned equivalent */
-int mp_unsigned_bin_size (mp_int * a)
-{
- int size = mp_count_bits (a);
- return (size / 8 + ((size & 7) != 0 ? 1 : 0));
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_unsigned_bin_size.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_xor.c b/dep/StormLib/src/libtommath/bn_mp_xor.c
deleted file mode 100644
index bf0446ecfe8..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_xor.c
+++ /dev/null
@@ -1,51 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_XOR_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* XOR two ints together */
-int
-mp_xor (mp_int * a, mp_int * b, mp_int * c)
-{
- int res, ix, px;
- mp_int t, *x;
-
- if (a->used > b->used) {
- if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
- return res;
- }
- px = b->used;
- x = b;
- } else {
- if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
- return res;
- }
- px = a->used;
- x = a;
- }
-
- for (ix = 0; ix < px; ix++) {
- t.dp[ix] ^= x->dp[ix];
- }
- mp_clamp (&t);
- mp_exch (c, &t);
- mp_clear (&t);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_xor.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_mp_zero.c b/dep/StormLib/src/libtommath/bn_mp_zero.c
deleted file mode 100644
index f21db5ed589..00000000000
--- a/dep/StormLib/src/libtommath/bn_mp_zero.c
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "tommath.h"
-#ifdef BN_MP_ZERO_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* set to zero */
-void mp_zero (mp_int * a)
-{
- int n;
- mp_digit *tmp;
-
- a->sign = MP_ZPOS;
- a->used = 0;
-
- tmp = a->dp;
- for (n = 0; n < a->alloc; n++) {
- *tmp++ = 0;
- }
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_zero.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_prime_tab.c b/dep/StormLib/src/libtommath/bn_prime_tab.c
deleted file mode 100644
index 7d306dd56a6..00000000000
--- a/dep/StormLib/src/libtommath/bn_prime_tab.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#include "tommath.h"
-#ifdef BN_PRIME_TAB_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-const mp_digit ltm_prime_tab[] = {
- 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
- 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
- 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
- 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F,
-#ifndef MP_8BIT
- 0x0083,
- 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
- 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
- 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
- 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
-
- 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
- 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
- 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
- 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
- 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
- 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
- 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
- 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
-
- 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
- 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
- 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
- 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
- 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
- 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
- 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
- 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
-
- 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
- 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
- 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
- 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
- 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
- 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
- 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
- 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
-#endif
-};
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_prime_tab.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_reverse.c b/dep/StormLib/src/libtommath/bn_reverse.c
deleted file mode 100644
index d4a919af486..00000000000
--- a/dep/StormLib/src/libtommath/bn_reverse.c
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "tommath.h"
-#ifdef BN_REVERSE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* reverse an array, used for radix code */
-void
-bn_reverse (unsigned char *s, int len)
-{
- int ix, iy;
- unsigned char t;
-
- ix = 0;
- iy = len - 1;
- while (ix < iy) {
- t = s[ix];
- s[ix] = s[iy];
- s[iy] = t;
- ++ix;
- --iy;
- }
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_reverse.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_s_mp_add.c b/dep/StormLib/src/libtommath/bn_s_mp_add.c
deleted file mode 100644
index 5ea9c6d205c..00000000000
--- a/dep/StormLib/src/libtommath/bn_s_mp_add.c
+++ /dev/null
@@ -1,109 +0,0 @@
-#include "tommath.h"
-#ifdef BN_S_MP_ADD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* low level addition, based on HAC pp.594, Algorithm 14.7 */
-int
-s_mp_add (mp_int * a, mp_int * b, mp_int * c)
-{
- mp_int *x;
- int olduse, res, min, max;
-
- /* find sizes, we let |a| <= |b| which means we have to sort
- * them. "x" will point to the input with the most digits
- */
- if (a->used > b->used) {
- min = b->used;
- max = a->used;
- x = a;
- } else {
- min = a->used;
- max = b->used;
- x = b;
- }
-
- /* init result */
- if (c->alloc < max + 1) {
- if ((res = mp_grow (c, max + 1)) != MP_OKAY) {
- return res;
- }
- }
-
- /* get old used digit count and set new one */
- olduse = c->used;
- c->used = max + 1;
-
- {
- register mp_digit u, *tmpa, *tmpb, *tmpc;
- register int i;
-
- /* alias for digit pointers */
-
- /* first input */
- tmpa = a->dp;
-
- /* second input */
- tmpb = b->dp;
-
- /* destination */
- tmpc = c->dp;
-
- /* zero the carry */
- u = 0;
- for (i = 0; i < min; i++) {
- /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
- *tmpc = *tmpa++ + *tmpb++ + u;
-
- /* U = carry bit of T[i] */
- u = *tmpc >> ((mp_digit)DIGIT_BIT);
-
- /* take away carry bit from T[i] */
- *tmpc++ &= MP_MASK;
- }
-
- /* now copy higher words if any, that is in A+B
- * if A or B has more digits add those in
- */
- if (min != max) {
- for (; i < max; i++) {
- /* T[i] = X[i] + U */
- *tmpc = x->dp[i] + u;
-
- /* U = carry bit of T[i] */
- u = *tmpc >> ((mp_digit)DIGIT_BIT);
-
- /* take away carry bit from T[i] */
- *tmpc++ &= MP_MASK;
- }
- }
-
- /* add carry */
- *tmpc++ = u;
-
- /* clear digits above oldused */
- for (i = c->used; i < olduse; i++) {
- *tmpc++ = 0;
- }
- }
-
- mp_clamp (c);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_s_mp_add.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_s_mp_exptmod.c b/dep/StormLib/src/libtommath/bn_s_mp_exptmod.c
deleted file mode 100644
index 9fb2da8fd21..00000000000
--- a/dep/StormLib/src/libtommath/bn_s_mp_exptmod.c
+++ /dev/null
@@ -1,252 +0,0 @@
-#include "tommath.h"
-#ifdef BN_S_MP_EXPTMOD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-#ifdef MP_LOW_MEM
- #define TAB_SIZE 32
-#else
- #define TAB_SIZE 256
-#endif
-
-int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
-{
- mp_int M[TAB_SIZE], res, mu;
- mp_digit buf;
- int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
- int (*redux)(mp_int*,mp_int*,mp_int*);
-
- /* find window size */
- x = mp_count_bits (X);
- if (x <= 7) {
- winsize = 2;
- } else if (x <= 36) {
- winsize = 3;
- } else if (x <= 140) {
- winsize = 4;
- } else if (x <= 450) {
- winsize = 5;
- } else if (x <= 1303) {
- winsize = 6;
- } else if (x <= 3529) {
- winsize = 7;
- } else {
- winsize = 8;
- }
-
-#ifdef MP_LOW_MEM
- if (winsize > 5) {
- winsize = 5;
- }
-#endif
-
- /* init M array */
- /* init first cell */
- if ((err = mp_init(&M[1])) != MP_OKAY) {
- return err;
- }
-
- /* now init the second half of the array */
- for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
- if ((err = mp_init(&M[x])) != MP_OKAY) {
- for (y = 1<<(winsize-1); y < x; y++) {
- mp_clear (&M[y]);
- }
- mp_clear(&M[1]);
- return err;
- }
- }
-
- /* create mu, used for Barrett reduction */
- if ((err = mp_init (&mu)) != MP_OKAY) {
- goto LBL_M;
- }
-
- if (redmode == 0) {
- if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) {
- goto LBL_MU;
- }
- redux = mp_reduce;
- } else {
- if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) {
- goto LBL_MU;
- }
- redux = mp_reduce_2k_l;
- }
-
- /* create M table
- *
- * The M table contains powers of the base,
- * e.g. M[x] = G**x mod P
- *
- * The first half of the table is not
- * computed though accept for M[0] and M[1]
- */
- if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) {
- goto LBL_MU;
- }
-
- /* compute the value at M[1<<(winsize-1)] by squaring
- * M[1] (winsize-1) times
- */
- if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
- goto LBL_MU;
- }
-
- for (x = 0; x < (winsize - 1); x++) {
- /* square it */
- if ((err = mp_sqr (&M[1 << (winsize - 1)],
- &M[1 << (winsize - 1)])) != MP_OKAY) {
- goto LBL_MU;
- }
-
- /* reduce modulo P */
- if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) {
- goto LBL_MU;
- }
- }
-
- /* create upper table, that is M[x] = M[x-1] * M[1] (mod P)
- * for x = (2**(winsize - 1) + 1) to (2**winsize - 1)
- */
- for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
- if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
- goto LBL_MU;
- }
- if ((err = redux (&M[x], P, &mu)) != MP_OKAY) {
- goto LBL_MU;
- }
- }
-
- /* setup result */
- if ((err = mp_init (&res)) != MP_OKAY) {
- goto LBL_MU;
- }
- mp_set (&res, 1);
-
- /* set initial mode and bit cnt */
- mode = 0;
- bitcnt = 1;
- buf = 0;
- digidx = X->used - 1;
- bitcpy = 0;
- bitbuf = 0;
-
- for (;;) {
- /* grab next digit as required */
- if (--bitcnt == 0) {
- /* if digidx == -1 we are out of digits */
- if (digidx == -1) {
- break;
- }
- /* read next digit and reset the bitcnt */
- buf = X->dp[digidx--];
- bitcnt = (int) DIGIT_BIT;
- }
-
- /* grab the next msb from the exponent */
- y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1;
- buf <<= (mp_digit)1;
-
- /* if the bit is zero and mode == 0 then we ignore it
- * These represent the leading zero bits before the first 1 bit
- * in the exponent. Technically this opt is not required but it
- * does lower the # of trivial squaring/reductions used
- */
- if (mode == 0 && y == 0) {
- continue;
- }
-
- /* if the bit is zero and mode == 1 then we square */
- if (mode == 1 && y == 0) {
- if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
- goto LBL_RES;
- }
- if ((err = redux (&res, P, &mu)) != MP_OKAY) {
- goto LBL_RES;
- }
- continue;
- }
-
- /* else we add it to the window */
- bitbuf |= (y << (winsize - ++bitcpy));
- mode = 2;
-
- if (bitcpy == winsize) {
- /* ok window is filled so square as required and multiply */
- /* square first */
- for (x = 0; x < winsize; x++) {
- if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
- goto LBL_RES;
- }
- if ((err = redux (&res, P, &mu)) != MP_OKAY) {
- goto LBL_RES;
- }
- }
-
- /* then multiply */
- if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
- goto LBL_RES;
- }
- if ((err = redux (&res, P, &mu)) != MP_OKAY) {
- goto LBL_RES;
- }
-
- /* empty window and reset */
- bitcpy = 0;
- bitbuf = 0;
- mode = 1;
- }
- }
-
- /* if bits remain then square/multiply */
- if (mode == 2 && bitcpy > 0) {
- /* square then multiply if the bit is set */
- for (x = 0; x < bitcpy; x++) {
- if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
- goto LBL_RES;
- }
- if ((err = redux (&res, P, &mu)) != MP_OKAY) {
- goto LBL_RES;
- }
-
- bitbuf <<= 1;
- if ((bitbuf & (1 << winsize)) != 0) {
- /* then multiply */
- if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
- goto LBL_RES;
- }
- if ((err = redux (&res, P, &mu)) != MP_OKAY) {
- goto LBL_RES;
- }
- }
- }
- }
-
- mp_exch (&res, Y);
- err = MP_OKAY;
-LBL_RES:mp_clear (&res);
-LBL_MU:mp_clear (&mu);
-LBL_M:
- mp_clear(&M[1]);
- for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
- mp_clear (&M[x]);
- }
- return err;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_s_mp_exptmod.c,v $ */
-/* $Revision: 1.5 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_s_mp_mul_digs.c b/dep/StormLib/src/libtommath/bn_s_mp_mul_digs.c
deleted file mode 100644
index f04dacfb9ea..00000000000
--- a/dep/StormLib/src/libtommath/bn_s_mp_mul_digs.c
+++ /dev/null
@@ -1,90 +0,0 @@
-#include "tommath.h"
-#ifdef BN_S_MP_MUL_DIGS_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* multiplies |a| * |b| and only computes upto digs digits of result
- * HAC pp. 595, Algorithm 14.12 Modified so you can control how
- * many digits of output are created.
- */
-int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
-{
- mp_int t;
- int res, pa, pb, ix, iy;
- mp_digit u;
- mp_word r;
- mp_digit tmpx, *tmpt, *tmpy;
-
- /* can we use the fast multiplier? */
- if (((digs) < MP_WARRAY) &&
- MIN (a->used, b->used) <
- (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
- return fast_s_mp_mul_digs (a, b, c, digs);
- }
-
- if ((res = mp_init_size (&t, digs)) != MP_OKAY) {
- return res;
- }
- t.used = digs;
-
- /* compute the digits of the product directly */
- pa = a->used;
- for (ix = 0; ix < pa; ix++) {
- /* set the carry to zero */
- u = 0;
-
- /* limit ourselves to making digs digits of output */
- pb = MIN (b->used, digs - ix);
-
- /* setup some aliases */
- /* copy of the digit from a used within the nested loop */
- tmpx = a->dp[ix];
-
- /* an alias for the destination shifted ix places */
- tmpt = t.dp + ix;
-
- /* an alias for the digits of b */
- tmpy = b->dp;
-
- /* compute the columns of the output and propagate the carry */
- for (iy = 0; iy < pb; iy++) {
- /* compute the column as a mp_word */
- r = ((mp_word)*tmpt) +
- ((mp_word)tmpx) * ((mp_word)*tmpy++) +
- ((mp_word) u);
-
- /* the new column is the lower part of the result */
- *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
-
- /* get the carry word from the result */
- u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
- }
- /* set carry if it is placed below digs */
- if (ix + iy < digs) {
- *tmpt = u;
- }
- }
-
- mp_clamp (&t);
- mp_exch (&t, c);
-
- mp_clear (&t);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_s_mp_mul_digs.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_s_mp_mul_high_digs.c b/dep/StormLib/src/libtommath/bn_s_mp_mul_high_digs.c
deleted file mode 100644
index b1d019925a6..00000000000
--- a/dep/StormLib/src/libtommath/bn_s_mp_mul_high_digs.c
+++ /dev/null
@@ -1,81 +0,0 @@
-#include "tommath.h"
-#ifdef BN_S_MP_MUL_HIGH_DIGS_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* multiplies |a| * |b| and does not compute the lower digs digits
- * [meant to get the higher part of the product]
- */
-int
-s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
-{
- mp_int t;
- int res, pa, pb, ix, iy;
- mp_digit u;
- mp_word r;
- mp_digit tmpx, *tmpt, *tmpy;
-
- /* can we use the fast multiplier? */
-#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
- if (((a->used + b->used + 1) < MP_WARRAY)
- && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
- return fast_s_mp_mul_high_digs (a, b, c, digs);
- }
-#endif
-
- if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) {
- return res;
- }
- t.used = a->used + b->used + 1;
-
- pa = a->used;
- pb = b->used;
- for (ix = 0; ix < pa; ix++) {
- /* clear the carry */
- u = 0;
-
- /* left hand side of A[ix] * B[iy] */
- tmpx = a->dp[ix];
-
- /* alias to the address of where the digits will be stored */
- tmpt = &(t.dp[digs]);
-
- /* alias for where to read the right hand side from */
- tmpy = b->dp + (digs - ix);
-
- for (iy = digs - ix; iy < pb; iy++) {
- /* calculate the double precision result */
- r = ((mp_word)*tmpt) +
- ((mp_word)tmpx) * ((mp_word)*tmpy++) +
- ((mp_word) u);
-
- /* get the lower part */
- *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
-
- /* carry the carry */
- u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
- }
- *tmpt = u;
- }
- mp_clamp (&t);
- mp_exch (&t, c);
- mp_clear (&t);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_s_mp_mul_high_digs.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_s_mp_sqr.c b/dep/StormLib/src/libtommath/bn_s_mp_sqr.c
deleted file mode 100644
index c1e994efddf..00000000000
--- a/dep/StormLib/src/libtommath/bn_s_mp_sqr.c
+++ /dev/null
@@ -1,84 +0,0 @@
-#include "tommath.h"
-#ifdef BN_S_MP_SQR_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
-int s_mp_sqr (mp_int * a, mp_int * b)
-{
- mp_int t;
- int res, ix, iy, pa;
- mp_word r;
- mp_digit u, tmpx, *tmpt;
-
- pa = a->used;
- if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
- return res;
- }
-
- /* default used is maximum possible size */
- t.used = 2*pa + 1;
-
- for (ix = 0; ix < pa; ix++) {
- /* first calculate the digit at 2*ix */
- /* calculate double precision result */
- r = ((mp_word) t.dp[2*ix]) +
- ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]);
-
- /* store lower part in result */
- t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK));
-
- /* get the carry */
- u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
-
- /* left hand side of A[ix] * A[iy] */
- tmpx = a->dp[ix];
-
- /* alias for where to store the results */
- tmpt = t.dp + (2*ix + 1);
-
- for (iy = ix + 1; iy < pa; iy++) {
- /* first calculate the product */
- r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);
-
- /* now calculate the double precision result, note we use
- * addition instead of *2 since it's easier to optimize
- */
- r = ((mp_word) *tmpt) + r + r + ((mp_word) u);
-
- /* store lower part */
- *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
-
- /* get carry */
- u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
- }
- /* propagate upwards */
- while (u != ((mp_digit) 0)) {
- r = ((mp_word) *tmpt) + ((mp_word) u);
- *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
- u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
- }
- }
-
- mp_clamp (&t);
- mp_exch (&t, b);
- mp_clear (&t);
- return MP_OKAY;
-}
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_s_mp_sqr.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bn_s_mp_sub.c b/dep/StormLib/src/libtommath/bn_s_mp_sub.c
deleted file mode 100644
index 0ae91cc4d17..00000000000
--- a/dep/StormLib/src/libtommath/bn_s_mp_sub.c
+++ /dev/null
@@ -1,89 +0,0 @@
-#include "tommath.h"
-#ifdef BN_S_MP_SUB_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
-int
-s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
-{
- int olduse, res, min, max;
-
- /* find sizes */
- min = b->used;
- max = a->used;
-
- /* init result */
- if (c->alloc < max) {
- if ((res = mp_grow (c, max)) != MP_OKAY) {
- return res;
- }
- }
- olduse = c->used;
- c->used = max;
-
- {
- register mp_digit u, *tmpa, *tmpb, *tmpc;
- register int i;
-
- /* alias for digit pointers */
- tmpa = a->dp;
- tmpb = b->dp;
- tmpc = c->dp;
-
- /* set carry to zero */
- u = 0;
- for (i = 0; i < min; i++) {
- /* T[i] = A[i] - B[i] - U */
- *tmpc = *tmpa++ - *tmpb++ - u;
-
- /* U = carry bit of T[i]
- * Note this saves performing an AND operation since
- * if a carry does occur it will propagate all the way to the
- * MSB. As a result a single shift is enough to get the carry
- */
- u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
-
- /* Clear carry from T[i] */
- *tmpc++ &= MP_MASK;
- }
-
- /* now copy higher words if any, e.g. if A has more digits than B */
- for (; i < max; i++) {
- /* T[i] = A[i] - U */
- *tmpc = *tmpa++ - u;
-
- /* U = carry bit of T[i] */
- u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
-
- /* Clear carry from T[i] */
- *tmpc++ &= MP_MASK;
- }
-
- /* clear digits above used (since we may not have grown result above) */
- for (i = c->used; i < olduse; i++) {
- *tmpc++ = 0;
- }
- }
-
- mp_clamp (c);
- return MP_OKAY;
-}
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bn_s_mp_sub.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/bncore.c b/dep/StormLib/src/libtommath/bncore.c
deleted file mode 100644
index ad7347f8424..00000000000
--- a/dep/StormLib/src/libtommath/bncore.c
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "tommath.h"
-#ifdef BNCORE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-/* Known optimal configurations
-
- CPU /Compiler /MUL CUTOFF/SQR CUTOFF
--------------------------------------------------------------
- Intel P4 Northwood /GCC v3.4.1 / 88/ 128/LTM 0.32 ;-)
- AMD Athlon64 /GCC v3.4.4 / 80/ 120/LTM 0.35
-
-*/
-
-int KARATSUBA_MUL_CUTOFF = 80, /* Min. number of digits before Karatsuba multiplication is used. */
- KARATSUBA_SQR_CUTOFF = 120, /* Min. number of digits before Karatsuba squaring is used. */
-
- TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */
- TOOM_SQR_CUTOFF = 400;
-#endif
-
-/* $Source: /cvs/libtom/libtommath/bncore.c,v $ */
-/* $Revision: 1.5 $ */
-/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/dep/StormLib/src/libtommath/tommath.h b/dep/StormLib/src/libtommath/tommath.h
deleted file mode 100644
index 1ead3d04bf5..00000000000
--- a/dep/StormLib/src/libtommath/tommath.h
+++ /dev/null
@@ -1,584 +0,0 @@
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
- */
-#ifndef BN_H_
-#define BN_H_
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <limits.h>
-
-#include "tommath_class.h"
-
-#ifndef MIN
- #define MIN(x,y) ((x)<(y)?(x):(y))
-#endif
-
-#ifndef MAX
- #define MAX(x,y) ((x)>(y)?(x):(y))
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-
-/* C++ compilers don't like assigning void * to mp_digit * */
-#define OPT_CAST(x) (x *)
-
-#else
-
-/* C on the other hand doesn't care */
-#define OPT_CAST(x)
-
-#endif
-
-
-/* detect 64-bit mode if possible */
-#if defined(__x86_64__)
- #if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT))
- #define MP_64BIT
- #endif
-#endif
-
-/* some default configurations.
- *
- * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits
- * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits
- *
- * At the very least a mp_digit must be able to hold 7 bits
- * [any size beyond that is ok provided it doesn't overflow the data type]
- */
-#ifdef MP_8BIT
- typedef unsigned char mp_digit;
- typedef unsigned short mp_word;
-#elif defined(MP_16BIT)
- typedef unsigned short mp_digit;
- typedef unsigned long mp_word;
-#elif defined(MP_64BIT)
- /* for GCC only on supported platforms */
-#ifndef CRYPT
- typedef unsigned long long ulong64;
- typedef signed long long long64;
-#endif
-
- typedef unsigned long mp_digit;
- typedef unsigned long mp_word __attribute__ ((mode(TI)));
-
- #define DIGIT_BIT 60
-#else
- /* this is the default case, 28-bit digits */
-
- /* this is to make porting into LibTomCrypt easier :-) */
-#ifndef CRYPT
- #if defined(_MSC_VER) || defined(__BORLANDC__)
- typedef unsigned __int64 ulong64;
- typedef signed __int64 long64;
- #else
- typedef unsigned long long ulong64;
- typedef signed long long long64;
- #endif
-#endif
-
- typedef unsigned long mp_digit;
- typedef ulong64 mp_word;
-
-#ifdef MP_31BIT
- /* this is an extension that uses 31-bit digits */
- #define DIGIT_BIT 31
-#else
- /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */
- #define DIGIT_BIT 28
- #define MP_28BIT
-#endif
-#endif
-
-/* define heap macros */
-#ifndef CRYPT
- /* default to libc stuff */
- #ifndef XMALLOC
- #define XMALLOC malloc
- #define XFREE free
- #define XREALLOC realloc
- #define XCALLOC calloc
- #else
- /* prototypes for our heap functions */
- extern void *XMALLOC(size_t n);
- extern void *XREALLOC(void *p, size_t n);
- extern void *XCALLOC(size_t n, size_t s);
- extern void XFREE(void *p);
- #endif
-#endif
-
-
-/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */
-#ifndef DIGIT_BIT
- #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) /* bits per digit */
-#endif
-
-#define MP_DIGIT_BIT DIGIT_BIT
-#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))
-#define MP_DIGIT_MAX MP_MASK
-
-/* equalities */
-#define MP_LT -1 /* less than */
-#define MP_EQ 0 /* equal to */
-#define MP_GT 1 /* greater than */
-
-#define MP_ZPOS 0 /* positive integer */
-#define MP_NEG 1 /* negative */
-
-#define MP_OKAY 0 /* ok result */
-#define MP_MEM -2 /* out of mem */
-#define MP_VAL -3 /* invalid input */
-#define MP_RANGE MP_VAL
-
-#define MP_YES 1 /* yes response */
-#define MP_NO 0 /* no response */
-
-/* Primality generation flags */
-#define LTM_PRIME_BBS 0x0001 /* BBS style prime */
-#define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */
-#define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */
-
-typedef int mp_err;
-
-/* you'll have to tune these... */
-extern int KARATSUBA_MUL_CUTOFF,
- KARATSUBA_SQR_CUTOFF,
- TOOM_MUL_CUTOFF,
- TOOM_SQR_CUTOFF;
-
-/* define this to use lower memory usage routines (exptmods mostly) */
-/* #define MP_LOW_MEM */
-
-/* default precision */
-#ifndef MP_PREC
- #ifndef MP_LOW_MEM
- #define MP_PREC 32 /* default digits of precision */
- #else
- #define MP_PREC 8 /* default digits of precision */
- #endif
-#endif
-
-/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */
-#define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))
-
-/* the infamous mp_int structure */
-typedef struct {
- int used, alloc, sign;
- mp_digit *dp;
-} mp_int;
-
-/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */
-typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);
-
-
-#define USED(m) ((m)->used)
-#define DIGIT(m,k) ((m)->dp[(k)])
-#define SIGN(m) ((m)->sign)
-
-/* error code to char* string */
-char *mp_error_to_string(int code);
-
-/* ---> init and deinit bignum functions <--- */
-/* init a bignum */
-int mp_init(mp_int *a);
-
-/* free a bignum */
-void mp_clear(mp_int *a);
-
-/* init a null terminated series of arguments */
-int mp_init_multi(mp_int *mp, ...);
-
-/* clear a null terminated series of arguments */
-void mp_clear_multi(mp_int *mp, ...);
-
-/* exchange two ints */
-void mp_exch(mp_int *a, mp_int *b);
-
-/* shrink ram required for a bignum */
-int mp_shrink(mp_int *a);
-
-/* grow an int to a given size */
-int mp_grow(mp_int *a, int size);
-
-/* init to a given number of digits */
-int mp_init_size(mp_int *a, int size);
-
-/* ---> Basic Manipulations <--- */
-#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
-#define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO)
-#define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO)
-
-/* set to zero */
-void mp_zero(mp_int *a);
-
-/* set to a digit */
-void mp_set(mp_int *a, mp_digit b);
-
-/* set a 32-bit const */
-int mp_set_int(mp_int *a, unsigned long b);
-
-/* get a 32-bit value */
-unsigned long mp_get_int(mp_int * a);
-
-/* initialize and set a digit */
-int mp_init_set (mp_int * a, mp_digit b);
-
-/* initialize and set 32-bit value */
-int mp_init_set_int (mp_int * a, unsigned long b);
-
-/* copy, b = a */
-int mp_copy(mp_int *a, mp_int *b);
-
-/* inits and copies, a = b */
-int mp_init_copy(mp_int *a, mp_int *b);
-
-/* trim unused digits */
-void mp_clamp(mp_int *a);
-
-/* ---> digit manipulation <--- */
-
-/* right shift by "b" digits */
-void mp_rshd(mp_int *a, int b);
-
-/* left shift by "b" digits */
-int mp_lshd(mp_int *a, int b);
-
-/* c = a / 2**b */
-int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d);
-
-/* b = a/2 */
-int mp_div_2(mp_int *a, mp_int *b);
-
-/* c = a * 2**b */
-int mp_mul_2d(mp_int *a, int b, mp_int *c);
-
-/* b = a*2 */
-int mp_mul_2(mp_int *a, mp_int *b);
-
-/* c = a mod 2**d */
-int mp_mod_2d(mp_int *a, int b, mp_int *c);
-
-/* computes a = 2**b */
-int mp_2expt(mp_int *a, int b);
-
-/* Counts the number of lsbs which are zero before the first zero bit */
-int mp_cnt_lsb(mp_int *a);
-
-/* I Love Earth! */
-
-/* makes a pseudo-random int of a given size */
-int mp_rand(mp_int *a, int digits);
-
-/* ---> binary operations <--- */
-/* c = a XOR b */
-int mp_xor(mp_int *a, mp_int *b, mp_int *c);
-
-/* c = a OR b */
-int mp_or(mp_int *a, mp_int *b, mp_int *c);
-
-/* c = a AND b */
-int mp_and(mp_int *a, mp_int *b, mp_int *c);
-
-/* ---> Basic arithmetic <--- */
-
-/* b = -a */
-int mp_neg(mp_int *a, mp_int *b);
-
-/* b = |a| */
-int mp_abs(mp_int *a, mp_int *b);
-
-/* compare a to b */
-int mp_cmp(mp_int *a, mp_int *b);
-
-/* compare |a| to |b| */
-int mp_cmp_mag(mp_int *a, mp_int *b);
-
-/* c = a + b */
-int mp_add(mp_int *a, mp_int *b, mp_int *c);
-
-/* c = a - b */
-int mp_sub(mp_int *a, mp_int *b, mp_int *c);
-
-/* c = a * b */
-int mp_mul(mp_int *a, mp_int *b, mp_int *c);
-
-/* b = a*a */
-int mp_sqr(mp_int *a, mp_int *b);
-
-/* a/b => cb + d == a */
-int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
-
-/* c = a mod b, 0 <= c < b */
-int mp_mod(mp_int *a, mp_int *b, mp_int *c);
-
-/* ---> single digit functions <--- */
-
-/* compare against a single digit */
-int mp_cmp_d(mp_int *a, mp_digit b);
-
-/* c = a + b */
-int mp_add_d(mp_int *a, mp_digit b, mp_int *c);
-
-/* c = a - b */
-int mp_sub_d(mp_int *a, mp_digit b, mp_int *c);
-
-/* c = a * b */
-int mp_mul_d(mp_int *a, mp_digit b, mp_int *c);
-
-/* a/b => cb + d == a */
-int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
-
-/* a/3 => 3c + d == a */
-int mp_div_3(mp_int *a, mp_int *c, mp_digit *d);
-
-/* c = a**b */
-int mp_expt_d(mp_int *a, mp_digit b, mp_int *c);
-
-/* c = a mod b, 0 <= c < b */
-int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c);
-
-/* ---> number theory <--- */
-
-/* d = a + b (mod c) */
-int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
-
-/* d = a - b (mod c) */
-int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
-
-/* d = a * b (mod c) */
-int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
-
-/* c = a * a (mod b) */
-int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c);
-
-/* c = 1/a (mod b) */
-int mp_invmod(mp_int *a, mp_int *b, mp_int *c);
-
-/* c = (a, b) */
-int mp_gcd(mp_int *a, mp_int *b, mp_int *c);
-
-/* produces value such that U1*a + U2*b = U3 */
-int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3);
-
-/* c = [a, b] or (a*b)/(a, b) */
-int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
-
-/* finds one of the b'th root of a, such that |c|**b <= |a|
- *
- * returns error if a < 0 and b is even
- */
-int mp_n_root(mp_int *a, mp_digit b, mp_int *c);
-
-/* special sqrt algo */
-int mp_sqrt(mp_int *arg, mp_int *ret);
-
-/* is number a square? */
-int mp_is_square(mp_int *arg, int *ret);
-
-/* computes the jacobi c = (a | n) (or Legendre if b is prime) */
-int mp_jacobi(mp_int *a, mp_int *n, int *c);
-
-/* used to setup the Barrett reduction for a given modulus b */
-int mp_reduce_setup(mp_int *a, mp_int *b);
-
-/* Barrett Reduction, computes a (mod b) with a precomputed value c
- *
- * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely
- * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code].
- */
-int mp_reduce(mp_int *a, mp_int *b, mp_int *c);
-
-/* setups the montgomery reduction */
-int mp_montgomery_setup(mp_int *a, mp_digit *mp);
-
-/* computes a = B**n mod b without division or multiplication useful for
- * normalizing numbers in a Montgomery system.
- */
-int mp_montgomery_calc_normalization(mp_int *a, mp_int *b);
-
-/* computes x/R == x (mod N) via Montgomery Reduction */
-int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
-
-/* returns 1 if a is a valid DR modulus */
-int mp_dr_is_modulus(mp_int *a);
-
-/* sets the value of "d" required for mp_dr_reduce */
-void mp_dr_setup(mp_int *a, mp_digit *d);
-
-/* reduces a modulo b using the Diminished Radix method */
-int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp);
-
-/* returns true if a can be reduced with mp_reduce_2k */
-int mp_reduce_is_2k(mp_int *a);
-
-/* determines k value for 2k reduction */
-int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
-
-/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
-int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d);
-
-/* returns true if a can be reduced with mp_reduce_2k_l */
-int mp_reduce_is_2k_l(mp_int *a);
-
-/* determines k value for 2k reduction */
-int mp_reduce_2k_setup_l(mp_int *a, mp_int *d);
-
-/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
-int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d);
-
-/* d = a**b (mod c) */
-int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
-
-/* ---> Primes <--- */
-
-/* number of primes */
-#ifdef MP_8BIT
- #define PRIME_SIZE 31
-#else
- #define PRIME_SIZE 256
-#endif
-
-/* table of first PRIME_SIZE primes */
-extern const mp_digit ltm_prime_tab[];
-
-/* result=1 if a is divisible by one of the first PRIME_SIZE primes */
-int mp_prime_is_divisible(mp_int *a, int *result);
-
-/* performs one Fermat test of "a" using base "b".
- * Sets result to 0 if composite or 1 if probable prime
- */
-int mp_prime_fermat(mp_int *a, mp_int *b, int *result);
-
-/* performs one Miller-Rabin test of "a" using base "b".
- * Sets result to 0 if composite or 1 if probable prime
- */
-int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result);
-
-/* This gives [for a given bit size] the number of trials required
- * such that Miller-Rabin gives a prob of failure lower than 2^-96
- */
-int mp_prime_rabin_miller_trials(int size);
-
-/* performs t rounds of Miller-Rabin on "a" using the first
- * t prime bases. Also performs an initial sieve of trial
- * division. Determines if "a" is prime with probability
- * of error no more than (1/4)**t.
- *
- * Sets result to 1 if probably prime, 0 otherwise
- */
-int mp_prime_is_prime(mp_int *a, int t, int *result);
-
-/* finds the next prime after the number "a" using "t" trials
- * of Miller-Rabin.
- *
- * bbs_style = 1 means the prime must be congruent to 3 mod 4
- */
-int mp_prime_next_prime(mp_int *a, int t, int bbs_style);
-
-/* makes a truly random prime of a given size (bytes),
- * call with bbs = 1 if you want it to be congruent to 3 mod 4
- *
- * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
- * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
- * so it can be NULL
- *
- * The prime generated will be larger than 2^(8*size).
- */
-#define mp_prime_random(a, t, size, bbs, cb, dat) mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat)
-
-/* makes a truly random prime of a given size (bits),
- *
- * Flags are as follows:
- *
- * LTM_PRIME_BBS - make prime congruent to 3 mod 4
- * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS)
- * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero
- * LTM_PRIME_2MSB_ON - make the 2nd highest bit one
- *
- * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
- * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
- * so it can be NULL
- *
- */
-int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat);
-
-/* ---> radix conversion <--- */
-int mp_count_bits(mp_int *a);
-
-int mp_unsigned_bin_size(mp_int *a);
-int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c);
-int mp_to_unsigned_bin(mp_int *a, unsigned char *b);
-int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
-
-int mp_signed_bin_size(mp_int *a);
-int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c);
-int mp_to_signed_bin(mp_int *a, unsigned char *b);
-int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
-
-int mp_read_radix(mp_int *a, const char *str, int radix);
-int mp_toradix(mp_int *a, char *str, int radix);
-int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen);
-int mp_radix_size(mp_int *a, int radix, int *size);
-
-int mp_fread(mp_int *a, int radix, FILE *stream);
-int mp_fwrite(mp_int *a, int radix, FILE *stream);
-
-#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
-#define mp_raw_size(mp) mp_signed_bin_size(mp)
-#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str))
-#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len))
-#define mp_mag_size(mp) mp_unsigned_bin_size(mp)
-#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str))
-
-#define mp_tobinary(M, S) mp_toradix((M), (S), 2)
-#define mp_tooctal(M, S) mp_toradix((M), (S), 8)
-#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
-#define mp_tohex(M, S) mp_toradix((M), (S), 16)
-
-/* lowlevel functions, do not call! */
-int s_mp_add(mp_int *a, mp_int *b, mp_int *c);
-int s_mp_sub(mp_int *a, mp_int *b, mp_int *c);
-#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1)
-int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
-int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
-int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
-int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
-int fast_s_mp_sqr(mp_int *a, mp_int *b);
-int s_mp_sqr(mp_int *a, mp_int *b);
-int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c);
-int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c);
-int mp_karatsuba_sqr(mp_int *a, mp_int *b);
-int mp_toom_sqr(mp_int *a, mp_int *b);
-int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c);
-int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c);
-int fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
-int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode);
-int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int mode);
-void bn_reverse(unsigned char *s, int len);
-
-extern const char *mp_s_rmap;
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif
-
-
-/* $Source: /cvs/libtom/libtommath/tommath.h,v $ */
-/* $Revision: 1.8 $ */
-/* $Date: 2006/03/31 14:18:44 $ */
diff --git a/dep/StormLib/src/libtommath/tommath_class.h b/dep/StormLib/src/libtommath/tommath_class.h
deleted file mode 100644
index 18d1553dee7..00000000000
--- a/dep/StormLib/src/libtommath/tommath_class.h
+++ /dev/null
@@ -1,999 +0,0 @@
-#if !(defined(LTM1) && defined(LTM2) && defined(LTM3))
-#if defined(LTM2)
-#define LTM3
-#endif
-#if defined(LTM1)
-#define LTM2
-#endif
-#define LTM1
-
-#if defined(LTM_ALL)
-#define BN_ERROR_C
-#define BN_FAST_MP_INVMOD_C
-#define BN_FAST_MP_MONTGOMERY_REDUCE_C
-#define BN_FAST_S_MP_MUL_DIGS_C
-#define BN_FAST_S_MP_MUL_HIGH_DIGS_C
-#define BN_FAST_S_MP_SQR_C
-#define BN_MP_2EXPT_C
-#define BN_MP_ABS_C
-#define BN_MP_ADD_C
-#define BN_MP_ADD_D_C
-#define BN_MP_ADDMOD_C
-#define BN_MP_AND_C
-#define BN_MP_CLAMP_C
-#define BN_MP_CLEAR_C
-#define BN_MP_CLEAR_MULTI_C
-#define BN_MP_CMP_C
-#define BN_MP_CMP_D_C
-#define BN_MP_CMP_MAG_C
-#define BN_MP_CNT_LSB_C
-#define BN_MP_COPY_C
-#define BN_MP_COUNT_BITS_C
-#define BN_MP_DIV_C
-#define BN_MP_DIV_2_C
-#define BN_MP_DIV_2D_C
-#define BN_MP_DIV_3_C
-#define BN_MP_DIV_D_C
-#define BN_MP_DR_IS_MODULUS_C
-#define BN_MP_DR_REDUCE_C
-#define BN_MP_DR_SETUP_C
-#define BN_MP_EXCH_C
-#define BN_MP_EXPT_D_C
-#define BN_MP_EXPTMOD_C
-#define BN_MP_EXPTMOD_FAST_C
-#define BN_MP_EXTEUCLID_C
-#define BN_MP_FREAD_C
-#define BN_MP_FWRITE_C
-#define BN_MP_GCD_C
-#define BN_MP_GET_INT_C
-#define BN_MP_GROW_C
-#define BN_MP_INIT_C
-#define BN_MP_INIT_COPY_C
-#define BN_MP_INIT_MULTI_C
-#define BN_MP_INIT_SET_C
-#define BN_MP_INIT_SET_INT_C
-#define BN_MP_INIT_SIZE_C
-#define BN_MP_INVMOD_C
-#define BN_MP_INVMOD_SLOW_C
-#define BN_MP_IS_SQUARE_C
-#define BN_MP_JACOBI_C
-#define BN_MP_KARATSUBA_MUL_C
-#define BN_MP_KARATSUBA_SQR_C
-#define BN_MP_LCM_C
-#define BN_MP_LSHD_C
-#define BN_MP_MOD_C
-#define BN_MP_MOD_2D_C
-#define BN_MP_MOD_D_C
-#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
-#define BN_MP_MONTGOMERY_REDUCE_C
-#define BN_MP_MONTGOMERY_SETUP_C
-#define BN_MP_MUL_C
-#define BN_MP_MUL_2_C
-#define BN_MP_MUL_2D_C
-#define BN_MP_MUL_D_C
-#define BN_MP_MULMOD_C
-#define BN_MP_N_ROOT_C
-#define BN_MP_NEG_C
-#define BN_MP_OR_C
-#define BN_MP_PRIME_FERMAT_C
-#define BN_MP_PRIME_IS_DIVISIBLE_C
-#define BN_MP_PRIME_IS_PRIME_C
-#define BN_MP_PRIME_MILLER_RABIN_C
-#define BN_MP_PRIME_NEXT_PRIME_C
-#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
-#define BN_MP_PRIME_RANDOM_EX_C
-#define BN_MP_RADIX_SIZE_C
-#define BN_MP_RADIX_SMAP_C
-#define BN_MP_RAND_C
-#define BN_MP_READ_RADIX_C
-#define BN_MP_READ_SIGNED_BIN_C
-#define BN_MP_READ_UNSIGNED_BIN_C
-#define BN_MP_REDUCE_C
-#define BN_MP_REDUCE_2K_C
-#define BN_MP_REDUCE_2K_L_C
-#define BN_MP_REDUCE_2K_SETUP_C
-#define BN_MP_REDUCE_2K_SETUP_L_C
-#define BN_MP_REDUCE_IS_2K_C
-#define BN_MP_REDUCE_IS_2K_L_C
-#define BN_MP_REDUCE_SETUP_C
-#define BN_MP_RSHD_C
-#define BN_MP_SET_C
-#define BN_MP_SET_INT_C
-#define BN_MP_SHRINK_C
-#define BN_MP_SIGNED_BIN_SIZE_C
-#define BN_MP_SQR_C
-#define BN_MP_SQRMOD_C
-#define BN_MP_SQRT_C
-#define BN_MP_SUB_C
-#define BN_MP_SUB_D_C
-#define BN_MP_SUBMOD_C
-#define BN_MP_TO_SIGNED_BIN_C
-#define BN_MP_TO_SIGNED_BIN_N_C
-#define BN_MP_TO_UNSIGNED_BIN_C
-#define BN_MP_TO_UNSIGNED_BIN_N_C
-#define BN_MP_TOOM_MUL_C
-#define BN_MP_TOOM_SQR_C
-#define BN_MP_TORADIX_C
-#define BN_MP_TORADIX_N_C
-#define BN_MP_UNSIGNED_BIN_SIZE_C
-#define BN_MP_XOR_C
-#define BN_MP_ZERO_C
-#define BN_PRIME_TAB_C
-#define BN_REVERSE_C
-#define BN_S_MP_ADD_C
-#define BN_S_MP_EXPTMOD_C
-#define BN_S_MP_MUL_DIGS_C
-#define BN_S_MP_MUL_HIGH_DIGS_C
-#define BN_S_MP_SQR_C
-#define BN_S_MP_SUB_C
-#define BNCORE_C
-#endif
-
-#if defined(BN_ERROR_C)
- #define BN_MP_ERROR_TO_STRING_C
-#endif
-
-#if defined(BN_FAST_MP_INVMOD_C)
- #define BN_MP_ISEVEN_C
- #define BN_MP_INIT_MULTI_C
- #define BN_MP_COPY_C
- #define BN_MP_MOD_C
- #define BN_MP_SET_C
- #define BN_MP_DIV_2_C
- #define BN_MP_ISODD_C
- #define BN_MP_SUB_C
- #define BN_MP_CMP_C
- #define BN_MP_ISZERO_C
- #define BN_MP_CMP_D_C
- #define BN_MP_ADD_C
- #define BN_MP_EXCH_C
- #define BN_MP_CLEAR_MULTI_C
-#endif
-
-#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C)
- #define BN_MP_GROW_C
- #define BN_MP_RSHD_C
- #define BN_MP_CLAMP_C
- #define BN_MP_CMP_MAG_C
- #define BN_S_MP_SUB_C
-#endif
-
-#if defined(BN_FAST_S_MP_MUL_DIGS_C)
- #define BN_MP_GROW_C
- #define BN_MP_CLAMP_C
-#endif
-
-#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
- #define BN_MP_GROW_C
- #define BN_MP_CLAMP_C
-#endif
-
-#if defined(BN_FAST_S_MP_SQR_C)
- #define BN_MP_GROW_C
- #define BN_MP_CLAMP_C
-#endif
-
-#if defined(BN_MP_2EXPT_C)
- #define BN_MP_ZERO_C
- #define BN_MP_GROW_C
-#endif
-
-#if defined(BN_MP_ABS_C)
- #define BN_MP_COPY_C
-#endif
-
-#if defined(BN_MP_ADD_C)
- #define BN_S_MP_ADD_C
- #define BN_MP_CMP_MAG_C
- #define BN_S_MP_SUB_C
-#endif
-
-#if defined(BN_MP_ADD_D_C)
- #define BN_MP_GROW_C
- #define BN_MP_SUB_D_C
- #define BN_MP_CLAMP_C
-#endif
-
-#if defined(BN_MP_ADDMOD_C)
- #define BN_MP_INIT_C
- #define BN_MP_ADD_C
- #define BN_MP_CLEAR_C
- #define BN_MP_MOD_C
-#endif
-
-#if defined(BN_MP_AND_C)
- #define BN_MP_INIT_COPY_C
- #define BN_MP_CLAMP_C
- #define BN_MP_EXCH_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_CLAMP_C)
-#endif
-
-#if defined(BN_MP_CLEAR_C)
-#endif
-
-#if defined(BN_MP_CLEAR_MULTI_C)
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_CMP_C)
- #define BN_MP_CMP_MAG_C
-#endif
-
-#if defined(BN_MP_CMP_D_C)
-#endif
-
-#if defined(BN_MP_CMP_MAG_C)
-#endif
-
-#if defined(BN_MP_CNT_LSB_C)
- #define BN_MP_ISZERO_C
-#endif
-
-#if defined(BN_MP_COPY_C)
- #define BN_MP_GROW_C
-#endif
-
-#if defined(BN_MP_COUNT_BITS_C)
-#endif
-
-#if defined(BN_MP_DIV_C)
- #define BN_MP_ISZERO_C
- #define BN_MP_CMP_MAG_C
- #define BN_MP_COPY_C
- #define BN_MP_ZERO_C
- #define BN_MP_INIT_MULTI_C
- #define BN_MP_SET_C
- #define BN_MP_COUNT_BITS_C
- #define BN_MP_ABS_C
- #define BN_MP_MUL_2D_C
- #define BN_MP_CMP_C
- #define BN_MP_SUB_C
- #define BN_MP_ADD_C
- #define BN_MP_DIV_2D_C
- #define BN_MP_EXCH_C
- #define BN_MP_CLEAR_MULTI_C
- #define BN_MP_INIT_SIZE_C
- #define BN_MP_INIT_C
- #define BN_MP_INIT_COPY_C
- #define BN_MP_LSHD_C
- #define BN_MP_RSHD_C
- #define BN_MP_MUL_D_C
- #define BN_MP_CLAMP_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_DIV_2_C)
- #define BN_MP_GROW_C
- #define BN_MP_CLAMP_C
-#endif
-
-#if defined(BN_MP_DIV_2D_C)
- #define BN_MP_COPY_C
- #define BN_MP_ZERO_C
- #define BN_MP_INIT_C
- #define BN_MP_MOD_2D_C
- #define BN_MP_CLEAR_C
- #define BN_MP_RSHD_C
- #define BN_MP_CLAMP_C
- #define BN_MP_EXCH_C
-#endif
-
-#if defined(BN_MP_DIV_3_C)
- #define BN_MP_INIT_SIZE_C
- #define BN_MP_CLAMP_C
- #define BN_MP_EXCH_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_DIV_D_C)
- #define BN_MP_ISZERO_C
- #define BN_MP_COPY_C
- #define BN_MP_DIV_2D_C
- #define BN_MP_DIV_3_C
- #define BN_MP_INIT_SIZE_C
- #define BN_MP_CLAMP_C
- #define BN_MP_EXCH_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_DR_IS_MODULUS_C)
-#endif
-
-#if defined(BN_MP_DR_REDUCE_C)
- #define BN_MP_GROW_C
- #define BN_MP_CLAMP_C
- #define BN_MP_CMP_MAG_C
- #define BN_S_MP_SUB_C
-#endif
-
-#if defined(BN_MP_DR_SETUP_C)
-#endif
-
-#if defined(BN_MP_EXCH_C)
-#endif
-
-#if defined(BN_MP_EXPT_D_C)
- #define BN_MP_INIT_COPY_C
- #define BN_MP_SET_C
- #define BN_MP_SQR_C
- #define BN_MP_CLEAR_C
- #define BN_MP_MUL_C
-#endif
-
-#if defined(BN_MP_EXPTMOD_C)
- #define BN_MP_INIT_C
- #define BN_MP_INVMOD_C
- #define BN_MP_CLEAR_C
- #define BN_MP_ABS_C
- #define BN_MP_CLEAR_MULTI_C
- #define BN_MP_REDUCE_IS_2K_L_C
- #define BN_S_MP_EXPTMOD_C
- #define BN_MP_DR_IS_MODULUS_C
- #define BN_MP_REDUCE_IS_2K_C
- #define BN_MP_ISODD_C
- #define BN_MP_EXPTMOD_FAST_C
-#endif
-
-#if defined(BN_MP_EXPTMOD_FAST_C)
- #define BN_MP_COUNT_BITS_C
- #define BN_MP_INIT_C
- #define BN_MP_CLEAR_C
- #define BN_MP_MONTGOMERY_SETUP_C
- #define BN_FAST_MP_MONTGOMERY_REDUCE_C
- #define BN_MP_MONTGOMERY_REDUCE_C
- #define BN_MP_DR_SETUP_C
- #define BN_MP_DR_REDUCE_C
- #define BN_MP_REDUCE_2K_SETUP_C
- #define BN_MP_REDUCE_2K_C
- #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
- #define BN_MP_MULMOD_C
- #define BN_MP_SET_C
- #define BN_MP_MOD_C
- #define BN_MP_COPY_C
- #define BN_MP_SQR_C
- #define BN_MP_MUL_C
- #define BN_MP_EXCH_C
-#endif
-
-#if defined(BN_MP_EXTEUCLID_C)
- #define BN_MP_INIT_MULTI_C
- #define BN_MP_SET_C
- #define BN_MP_COPY_C
- #define BN_MP_ISZERO_C
- #define BN_MP_DIV_C
- #define BN_MP_MUL_C
- #define BN_MP_SUB_C
- #define BN_MP_NEG_C
- #define BN_MP_EXCH_C
- #define BN_MP_CLEAR_MULTI_C
-#endif
-
-#if defined(BN_MP_FREAD_C)
- #define BN_MP_ZERO_C
- #define BN_MP_S_RMAP_C
- #define BN_MP_MUL_D_C
- #define BN_MP_ADD_D_C
- #define BN_MP_CMP_D_C
-#endif
-
-#if defined(BN_MP_FWRITE_C)
- #define BN_MP_RADIX_SIZE_C
- #define BN_MP_TORADIX_C
-#endif
-
-#if defined(BN_MP_GCD_C)
- #define BN_MP_ISZERO_C
- #define BN_MP_ABS_C
- #define BN_MP_ZERO_C
- #define BN_MP_INIT_COPY_C
- #define BN_MP_CNT_LSB_C
- #define BN_MP_DIV_2D_C
- #define BN_MP_CMP_MAG_C
- #define BN_MP_EXCH_C
- #define BN_S_MP_SUB_C
- #define BN_MP_MUL_2D_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_GET_INT_C)
-#endif
-
-#if defined(BN_MP_GROW_C)
-#endif
-
-#if defined(BN_MP_INIT_C)
-#endif
-
-#if defined(BN_MP_INIT_COPY_C)
- #define BN_MP_COPY_C
-#endif
-
-#if defined(BN_MP_INIT_MULTI_C)
- #define BN_MP_ERR_C
- #define BN_MP_INIT_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_INIT_SET_C)
- #define BN_MP_INIT_C
- #define BN_MP_SET_C
-#endif
-
-#if defined(BN_MP_INIT_SET_INT_C)
- #define BN_MP_INIT_C
- #define BN_MP_SET_INT_C
-#endif
-
-#if defined(BN_MP_INIT_SIZE_C)
- #define BN_MP_INIT_C
-#endif
-
-#if defined(BN_MP_INVMOD_C)
- #define BN_MP_ISZERO_C
- #define BN_MP_ISODD_C
- #define BN_FAST_MP_INVMOD_C
- #define BN_MP_INVMOD_SLOW_C
-#endif
-
-#if defined(BN_MP_INVMOD_SLOW_C)
- #define BN_MP_ISZERO_C
- #define BN_MP_INIT_MULTI_C
- #define BN_MP_MOD_C
- #define BN_MP_COPY_C
- #define BN_MP_ISEVEN_C
- #define BN_MP_SET_C
- #define BN_MP_DIV_2_C
- #define BN_MP_ISODD_C
- #define BN_MP_ADD_C
- #define BN_MP_SUB_C
- #define BN_MP_CMP_C
- #define BN_MP_CMP_D_C
- #define BN_MP_CMP_MAG_C
- #define BN_MP_EXCH_C
- #define BN_MP_CLEAR_MULTI_C
-#endif
-
-#if defined(BN_MP_IS_SQUARE_C)
- #define BN_MP_MOD_D_C
- #define BN_MP_INIT_SET_INT_C
- #define BN_MP_MOD_C
- #define BN_MP_GET_INT_C
- #define BN_MP_SQRT_C
- #define BN_MP_SQR_C
- #define BN_MP_CMP_MAG_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_JACOBI_C)
- #define BN_MP_CMP_D_C
- #define BN_MP_ISZERO_C
- #define BN_MP_INIT_COPY_C
- #define BN_MP_CNT_LSB_C
- #define BN_MP_DIV_2D_C
- #define BN_MP_MOD_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_KARATSUBA_MUL_C)
- #define BN_MP_MUL_C
- #define BN_MP_INIT_SIZE_C
- #define BN_MP_CLAMP_C
- #define BN_MP_SUB_C
- #define BN_MP_ADD_C
- #define BN_MP_LSHD_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_KARATSUBA_SQR_C)
- #define BN_MP_INIT_SIZE_C
- #define BN_MP_CLAMP_C
- #define BN_MP_SQR_C
- #define BN_MP_SUB_C
- #define BN_S_MP_ADD_C
- #define BN_MP_LSHD_C
- #define BN_MP_ADD_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_LCM_C)
- #define BN_MP_INIT_MULTI_C
- #define BN_MP_GCD_C
- #define BN_MP_CMP_MAG_C
- #define BN_MP_DIV_C
- #define BN_MP_MUL_C
- #define BN_MP_CLEAR_MULTI_C
-#endif
-
-#if defined(BN_MP_LSHD_C)
- #define BN_MP_GROW_C
- #define BN_MP_RSHD_C
-#endif
-
-#if defined(BN_MP_MOD_C)
- #define BN_MP_INIT_C
- #define BN_MP_DIV_C
- #define BN_MP_CLEAR_C
- #define BN_MP_ADD_C
- #define BN_MP_EXCH_C
-#endif
-
-#if defined(BN_MP_MOD_2D_C)
- #define BN_MP_ZERO_C
- #define BN_MP_COPY_C
- #define BN_MP_CLAMP_C
-#endif
-
-#if defined(BN_MP_MOD_D_C)
- #define BN_MP_DIV_D_C
-#endif
-
-#if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C)
- #define BN_MP_COUNT_BITS_C
- #define BN_MP_2EXPT_C
- #define BN_MP_SET_C
- #define BN_MP_MUL_2_C
- #define BN_MP_CMP_MAG_C
- #define BN_S_MP_SUB_C
-#endif
-
-#if defined(BN_MP_MONTGOMERY_REDUCE_C)
- #define BN_FAST_MP_MONTGOMERY_REDUCE_C
- #define BN_MP_GROW_C
- #define BN_MP_CLAMP_C
- #define BN_MP_RSHD_C
- #define BN_MP_CMP_MAG_C
- #define BN_S_MP_SUB_C
-#endif
-
-#if defined(BN_MP_MONTGOMERY_SETUP_C)
-#endif
-
-#if defined(BN_MP_MUL_C)
- #define BN_MP_TOOM_MUL_C
- #define BN_MP_KARATSUBA_MUL_C
- #define BN_FAST_S_MP_MUL_DIGS_C
- #define BN_S_MP_MUL_C
- #define BN_S_MP_MUL_DIGS_C
-#endif
-
-#if defined(BN_MP_MUL_2_C)
- #define BN_MP_GROW_C
-#endif
-
-#if defined(BN_MP_MUL_2D_C)
- #define BN_MP_COPY_C
- #define BN_MP_GROW_C
- #define BN_MP_LSHD_C
- #define BN_MP_CLAMP_C
-#endif
-
-#if defined(BN_MP_MUL_D_C)
- #define BN_MP_GROW_C
- #define BN_MP_CLAMP_C
-#endif
-
-#if defined(BN_MP_MULMOD_C)
- #define BN_MP_INIT_C
- #define BN_MP_MUL_C
- #define BN_MP_CLEAR_C
- #define BN_MP_MOD_C
-#endif
-
-#if defined(BN_MP_N_ROOT_C)
- #define BN_MP_INIT_C
- #define BN_MP_SET_C
- #define BN_MP_COPY_C
- #define BN_MP_EXPT_D_C
- #define BN_MP_MUL_C
- #define BN_MP_SUB_C
- #define BN_MP_MUL_D_C
- #define BN_MP_DIV_C
- #define BN_MP_CMP_C
- #define BN_MP_SUB_D_C
- #define BN_MP_EXCH_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_NEG_C)
- #define BN_MP_COPY_C
- #define BN_MP_ISZERO_C
-#endif
-
-#if defined(BN_MP_OR_C)
- #define BN_MP_INIT_COPY_C
- #define BN_MP_CLAMP_C
- #define BN_MP_EXCH_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_PRIME_FERMAT_C)
- #define BN_MP_CMP_D_C
- #define BN_MP_INIT_C
- #define BN_MP_EXPTMOD_C
- #define BN_MP_CMP_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_PRIME_IS_DIVISIBLE_C)
- #define BN_MP_MOD_D_C
-#endif
-
-#if defined(BN_MP_PRIME_IS_PRIME_C)
- #define BN_MP_CMP_D_C
- #define BN_MP_PRIME_IS_DIVISIBLE_C
- #define BN_MP_INIT_C
- #define BN_MP_SET_C
- #define BN_MP_PRIME_MILLER_RABIN_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_PRIME_MILLER_RABIN_C)
- #define BN_MP_CMP_D_C
- #define BN_MP_INIT_COPY_C
- #define BN_MP_SUB_D_C
- #define BN_MP_CNT_LSB_C
- #define BN_MP_DIV_2D_C
- #define BN_MP_EXPTMOD_C
- #define BN_MP_CMP_C
- #define BN_MP_SQRMOD_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_PRIME_NEXT_PRIME_C)
- #define BN_MP_CMP_D_C
- #define BN_MP_SET_C
- #define BN_MP_SUB_D_C
- #define BN_MP_ISEVEN_C
- #define BN_MP_MOD_D_C
- #define BN_MP_INIT_C
- #define BN_MP_ADD_D_C
- #define BN_MP_PRIME_MILLER_RABIN_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C)
-#endif
-
-#if defined(BN_MP_PRIME_RANDOM_EX_C)
- #define BN_MP_READ_UNSIGNED_BIN_C
- #define BN_MP_PRIME_IS_PRIME_C
- #define BN_MP_SUB_D_C
- #define BN_MP_DIV_2_C
- #define BN_MP_MUL_2_C
- #define BN_MP_ADD_D_C
-#endif
-
-#if defined(BN_MP_RADIX_SIZE_C)
- #define BN_MP_COUNT_BITS_C
- #define BN_MP_INIT_COPY_C
- #define BN_MP_ISZERO_C
- #define BN_MP_DIV_D_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_RADIX_SMAP_C)
- #define BN_MP_S_RMAP_C
-#endif
-
-#if defined(BN_MP_RAND_C)
- #define BN_MP_ZERO_C
- #define BN_MP_ADD_D_C
- #define BN_MP_LSHD_C
-#endif
-
-#if defined(BN_MP_READ_RADIX_C)
- #define BN_MP_ZERO_C
- #define BN_MP_S_RMAP_C
- #define BN_MP_RADIX_SMAP_C
- #define BN_MP_MUL_D_C
- #define BN_MP_ADD_D_C
- #define BN_MP_ISZERO_C
-#endif
-
-#if defined(BN_MP_READ_SIGNED_BIN_C)
- #define BN_MP_READ_UNSIGNED_BIN_C
-#endif
-
-#if defined(BN_MP_READ_UNSIGNED_BIN_C)
- #define BN_MP_GROW_C
- #define BN_MP_ZERO_C
- #define BN_MP_MUL_2D_C
- #define BN_MP_CLAMP_C
-#endif
-
-#if defined(BN_MP_REDUCE_C)
- #define BN_MP_REDUCE_SETUP_C
- #define BN_MP_INIT_COPY_C
- #define BN_MP_RSHD_C
- #define BN_MP_MUL_C
- #define BN_S_MP_MUL_HIGH_DIGS_C
- #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
- #define BN_MP_MOD_2D_C
- #define BN_S_MP_MUL_DIGS_C
- #define BN_MP_SUB_C
- #define BN_MP_CMP_D_C
- #define BN_MP_SET_C
- #define BN_MP_LSHD_C
- #define BN_MP_ADD_C
- #define BN_MP_CMP_C
- #define BN_S_MP_SUB_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_REDUCE_2K_C)
- #define BN_MP_INIT_C
- #define BN_MP_COUNT_BITS_C
- #define BN_MP_DIV_2D_C
- #define BN_MP_MUL_D_C
- #define BN_S_MP_ADD_C
- #define BN_MP_CMP_MAG_C
- #define BN_S_MP_SUB_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_REDUCE_2K_L_C)
- #define BN_MP_INIT_C
- #define BN_MP_COUNT_BITS_C
- #define BN_MP_DIV_2D_C
- #define BN_MP_MUL_C
- #define BN_S_MP_ADD_C
- #define BN_MP_CMP_MAG_C
- #define BN_S_MP_SUB_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_REDUCE_2K_SETUP_C)
- #define BN_MP_INIT_C
- #define BN_MP_COUNT_BITS_C
- #define BN_MP_2EXPT_C
- #define BN_MP_CLEAR_C
- #define BN_S_MP_SUB_C
-#endif
-
-#if defined(BN_MP_REDUCE_2K_SETUP_L_C)
- #define BN_MP_INIT_C
- #define BN_MP_2EXPT_C
- #define BN_MP_COUNT_BITS_C
- #define BN_S_MP_SUB_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_REDUCE_IS_2K_C)
- #define BN_MP_REDUCE_2K_C
- #define BN_MP_COUNT_BITS_C
-#endif
-
-#if defined(BN_MP_REDUCE_IS_2K_L_C)
-#endif
-
-#if defined(BN_MP_REDUCE_SETUP_C)
- #define BN_MP_2EXPT_C
- #define BN_MP_DIV_C
-#endif
-
-#if defined(BN_MP_RSHD_C)
- #define BN_MP_ZERO_C
-#endif
-
-#if defined(BN_MP_SET_C)
- #define BN_MP_ZERO_C
-#endif
-
-#if defined(BN_MP_SET_INT_C)
- #define BN_MP_ZERO_C
- #define BN_MP_MUL_2D_C
- #define BN_MP_CLAMP_C
-#endif
-
-#if defined(BN_MP_SHRINK_C)
-#endif
-
-#if defined(BN_MP_SIGNED_BIN_SIZE_C)
- #define BN_MP_UNSIGNED_BIN_SIZE_C
-#endif
-
-#if defined(BN_MP_SQR_C)
- #define BN_MP_TOOM_SQR_C
- #define BN_MP_KARATSUBA_SQR_C
- #define BN_FAST_S_MP_SQR_C
- #define BN_S_MP_SQR_C
-#endif
-
-#if defined(BN_MP_SQRMOD_C)
- #define BN_MP_INIT_C
- #define BN_MP_SQR_C
- #define BN_MP_CLEAR_C
- #define BN_MP_MOD_C
-#endif
-
-#if defined(BN_MP_SQRT_C)
- #define BN_MP_N_ROOT_C
- #define BN_MP_ISZERO_C
- #define BN_MP_ZERO_C
- #define BN_MP_INIT_COPY_C
- #define BN_MP_RSHD_C
- #define BN_MP_DIV_C
- #define BN_MP_ADD_C
- #define BN_MP_DIV_2_C
- #define BN_MP_CMP_MAG_C
- #define BN_MP_EXCH_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_SUB_C)
- #define BN_S_MP_ADD_C
- #define BN_MP_CMP_MAG_C
- #define BN_S_MP_SUB_C
-#endif
-
-#if defined(BN_MP_SUB_D_C)
- #define BN_MP_GROW_C
- #define BN_MP_ADD_D_C
- #define BN_MP_CLAMP_C
-#endif
-
-#if defined(BN_MP_SUBMOD_C)
- #define BN_MP_INIT_C
- #define BN_MP_SUB_C
- #define BN_MP_CLEAR_C
- #define BN_MP_MOD_C
-#endif
-
-#if defined(BN_MP_TO_SIGNED_BIN_C)
- #define BN_MP_TO_UNSIGNED_BIN_C
-#endif
-
-#if defined(BN_MP_TO_SIGNED_BIN_N_C)
- #define BN_MP_SIGNED_BIN_SIZE_C
- #define BN_MP_TO_SIGNED_BIN_C
-#endif
-
-#if defined(BN_MP_TO_UNSIGNED_BIN_C)
- #define BN_MP_INIT_COPY_C
- #define BN_MP_ISZERO_C
- #define BN_MP_DIV_2D_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_TO_UNSIGNED_BIN_N_C)
- #define BN_MP_UNSIGNED_BIN_SIZE_C
- #define BN_MP_TO_UNSIGNED_BIN_C
-#endif
-
-#if defined(BN_MP_TOOM_MUL_C)
- #define BN_MP_INIT_MULTI_C
- #define BN_MP_MOD_2D_C
- #define BN_MP_COPY_C
- #define BN_MP_RSHD_C
- #define BN_MP_MUL_C
- #define BN_MP_MUL_2_C
- #define BN_MP_ADD_C
- #define BN_MP_SUB_C
- #define BN_MP_DIV_2_C
- #define BN_MP_MUL_2D_C
- #define BN_MP_MUL_D_C
- #define BN_MP_DIV_3_C
- #define BN_MP_LSHD_C
- #define BN_MP_CLEAR_MULTI_C
-#endif
-
-#if defined(BN_MP_TOOM_SQR_C)
- #define BN_MP_INIT_MULTI_C
- #define BN_MP_MOD_2D_C
- #define BN_MP_COPY_C
- #define BN_MP_RSHD_C
- #define BN_MP_SQR_C
- #define BN_MP_MUL_2_C
- #define BN_MP_ADD_C
- #define BN_MP_SUB_C
- #define BN_MP_DIV_2_C
- #define BN_MP_MUL_2D_C
- #define BN_MP_MUL_D_C
- #define BN_MP_DIV_3_C
- #define BN_MP_LSHD_C
- #define BN_MP_CLEAR_MULTI_C
-#endif
-
-#if defined(BN_MP_TORADIX_C)
- #define BN_MP_ISZERO_C
- #define BN_MP_INIT_COPY_C
- #define BN_MP_DIV_D_C
- #define BN_MP_CLEAR_C
- #define BN_MP_S_RMAP_C
-#endif
-
-#if defined(BN_MP_TORADIX_N_C)
- #define BN_MP_ISZERO_C
- #define BN_MP_INIT_COPY_C
- #define BN_MP_DIV_D_C
- #define BN_MP_CLEAR_C
- #define BN_MP_S_RMAP_C
-#endif
-
-#if defined(BN_MP_UNSIGNED_BIN_SIZE_C)
- #define BN_MP_COUNT_BITS_C
-#endif
-
-#if defined(BN_MP_XOR_C)
- #define BN_MP_INIT_COPY_C
- #define BN_MP_CLAMP_C
- #define BN_MP_EXCH_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_MP_ZERO_C)
-#endif
-
-#if defined(BN_PRIME_TAB_C)
-#endif
-
-#if defined(BN_REVERSE_C)
-#endif
-
-#if defined(BN_S_MP_ADD_C)
- #define BN_MP_GROW_C
- #define BN_MP_CLAMP_C
-#endif
-
-#if defined(BN_S_MP_EXPTMOD_C)
- #define BN_MP_COUNT_BITS_C
- #define BN_MP_INIT_C
- #define BN_MP_CLEAR_C
- #define BN_MP_REDUCE_SETUP_C
- #define BN_MP_REDUCE_C
- #define BN_MP_REDUCE_2K_SETUP_L_C
- #define BN_MP_REDUCE_2K_L_C
- #define BN_MP_MOD_C
- #define BN_MP_COPY_C
- #define BN_MP_SQR_C
- #define BN_MP_MUL_C
- #define BN_MP_SET_C
- #define BN_MP_EXCH_C
-#endif
-
-#if defined(BN_S_MP_MUL_DIGS_C)
- #define BN_FAST_S_MP_MUL_DIGS_C
- #define BN_MP_INIT_SIZE_C
- #define BN_MP_CLAMP_C
- #define BN_MP_EXCH_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_S_MP_MUL_HIGH_DIGS_C)
- #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
- #define BN_MP_INIT_SIZE_C
- #define BN_MP_CLAMP_C
- #define BN_MP_EXCH_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_S_MP_SQR_C)
- #define BN_MP_INIT_SIZE_C
- #define BN_MP_CLAMP_C
- #define BN_MP_EXCH_C
- #define BN_MP_CLEAR_C
-#endif
-
-#if defined(BN_S_MP_SUB_C)
- #define BN_MP_GROW_C
- #define BN_MP_CLAMP_C
-#endif
-
-#if defined(BNCORE_C)
-#endif
-
-#ifdef LTM3
-#define LTM_LAST
-#endif
-#include "tommath_superclass.h"
-#include "tommath_class.h"
-#else
-#define LTM_LAST
-#endif
-
-/* $Source: /cvs/libtom/libtommath/tommath_class.h,v $ */
-/* $Revision: 1.3 $ */
-/* $Date: 2005/07/28 11:59:32 $ */
diff --git a/dep/StormLib/src/libtommath/tommath_superclass.h b/dep/StormLib/src/libtommath/tommath_superclass.h
deleted file mode 100644
index 2fdebe6838f..00000000000
--- a/dep/StormLib/src/libtommath/tommath_superclass.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* super class file for PK algos */
-
-/* default ... include all MPI */
-#define LTM_ALL
-
-/* RSA only (does not support DH/DSA/ECC) */
-/* #define SC_RSA_1 */
-
-/* For reference.... On an Athlon64 optimizing for speed...
-
- LTM's mpi.o with all functions [striped] is 142KiB in size.
-
-*/
-
-/* Works for RSA only, mpi.o is 68KiB */
-#ifdef SC_RSA_1
- #define BN_MP_SHRINK_C
- #define BN_MP_LCM_C
- #define BN_MP_PRIME_RANDOM_EX_C
- #define BN_MP_INVMOD_C
- #define BN_MP_GCD_C
- #define BN_MP_MOD_C
- #define BN_MP_MULMOD_C
- #define BN_MP_ADDMOD_C
- #define BN_MP_EXPTMOD_C
- #define BN_MP_SET_INT_C
- #define BN_MP_INIT_MULTI_C
- #define BN_MP_CLEAR_MULTI_C
- #define BN_MP_UNSIGNED_BIN_SIZE_C
- #define BN_MP_TO_UNSIGNED_BIN_C
- #define BN_MP_MOD_D_C
- #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
- #define BN_REVERSE_C
- #define BN_PRIME_TAB_C
-
- /* other modifiers */
- #define BN_MP_DIV_SMALL /* Slower division, not critical */
-
- /* here we are on the last pass so we turn things off. The functions classes are still there
- * but we remove them specifically from the build. This also invokes tweaks in functions
- * like removing support for even moduli, etc...
- */
-#ifdef LTM_LAST
- #undef BN_MP_TOOM_MUL_C
- #undef BN_MP_TOOM_SQR_C
- #undef BN_MP_KARATSUBA_MUL_C
- #undef BN_MP_KARATSUBA_SQR_C
- #undef BN_MP_REDUCE_C
- #undef BN_MP_REDUCE_SETUP_C
- #undef BN_MP_DR_IS_MODULUS_C
- #undef BN_MP_DR_SETUP_C
- #undef BN_MP_DR_REDUCE_C
- #undef BN_MP_REDUCE_IS_2K_C
- #undef BN_MP_REDUCE_2K_SETUP_C
- #undef BN_MP_REDUCE_2K_C
- #undef BN_S_MP_EXPTMOD_C
- #undef BN_MP_DIV_3_C
- #undef BN_S_MP_MUL_HIGH_DIGS_C
- #undef BN_FAST_S_MP_MUL_HIGH_DIGS_C
- #undef BN_FAST_MP_INVMOD_C
-
- /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold
- * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines]
- * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without
- * trouble.
- */
- #undef BN_S_MP_MUL_DIGS_C
- #undef BN_S_MP_SQR_C
- #undef BN_MP_MONTGOMERY_REDUCE_C
-#endif
-
-#endif
-
-/* $Source: /cvs/libtom/libtommath/tommath_superclass.h,v $ */
-/* $Revision: 1.3 $ */
-/* $Date: 2005/05/14 13:29:17 $ */
diff --git a/dep/StormLib/src/lzma/C/LzFind.c b/dep/StormLib/src/lzma/C/LzFind.c
deleted file mode 100644
index e3ecb05420e..00000000000
--- a/dep/StormLib/src/lzma/C/LzFind.c
+++ /dev/null
@@ -1,761 +0,0 @@
-/* LzFind.c -- Match finder for LZ algorithms
-2009-04-22 : Igor Pavlov : Public domain */
-
-#include <string.h>
-
-#include "LzFind.h"
-#include "LzHash.h"
-
-#define kEmptyHashValue 0
-#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
-#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
-#define kNormalizeMask (~(kNormalizeStepMin - 1))
-#define kMaxHistorySize ((UInt32)3 << 30)
-
-#define kStartMaxLen 3
-
-static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
-{
- if (!p->directInput)
- {
- alloc->Free(alloc, p->bufferBase);
- p->bufferBase = 0;
- }
-}
-
-/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
-
-static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
-{
- UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
- if (p->directInput)
- {
- p->blockSize = blockSize;
- return 1;
- }
- if (p->bufferBase == 0 || p->blockSize != blockSize)
- {
- LzInWindow_Free(p, alloc);
- p->blockSize = blockSize;
- p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
- }
- return (p->bufferBase != 0);
-}
-
-Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
-Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
-
-UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
-
-void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
-{
- p->posLimit -= subValue;
- p->pos -= subValue;
- p->streamPos -= subValue;
-}
-
-static void MatchFinder_ReadBlock(CMatchFinder *p)
-{
- if (p->streamEndWasReached || p->result != SZ_OK)
- return;
- if (p->directInput)
- {
- UInt32 curSize = 0xFFFFFFFF - p->streamPos;
- if (curSize > p->directInputRem)
- curSize = (UInt32)p->directInputRem;
- p->directInputRem -= curSize;
- p->streamPos += curSize;
- if (p->directInputRem == 0)
- p->streamEndWasReached = 1;
- return;
- }
- for (;;)
- {
- Byte *dest = p->buffer + (p->streamPos - p->pos);
- size_t size = (p->bufferBase + p->blockSize - dest);
- if (size == 0)
- return;
- p->result = p->stream->Read(p->stream, dest, &size);
- if (p->result != SZ_OK)
- return;
- if (size == 0)
- {
- p->streamEndWasReached = 1;
- return;
- }
- p->streamPos += (UInt32)size;
- if (p->streamPos - p->pos > p->keepSizeAfter)
- return;
- }
-}
-
-void MatchFinder_MoveBlock(CMatchFinder *p)
-{
- memmove(p->bufferBase,
- p->buffer - p->keepSizeBefore,
- (size_t)(p->streamPos - p->pos + p->keepSizeBefore));
- p->buffer = p->bufferBase + p->keepSizeBefore;
-}
-
-int MatchFinder_NeedMove(CMatchFinder *p)
-{
- if (p->directInput)
- return 0;
- /* if (p->streamEndWasReached) return 0; */
- return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
-}
-
-void MatchFinder_ReadIfRequired(CMatchFinder *p)
-{
- if (p->streamEndWasReached)
- return;
- if (p->keepSizeAfter >= p->streamPos - p->pos)
- MatchFinder_ReadBlock(p);
-}
-
-static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
-{
- if (MatchFinder_NeedMove(p))
- MatchFinder_MoveBlock(p);
- MatchFinder_ReadBlock(p);
-}
-
-static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
-{
- p->cutValue = 32;
- p->btMode = 1;
- p->numHashBytes = 4;
- p->bigHash = 0;
-}
-
-#define kCrcPoly 0xEDB88320
-
-void MatchFinder_Construct(CMatchFinder *p)
-{
- UInt32 i;
- p->bufferBase = 0;
- p->directInput = 0;
- p->hash = 0;
- MatchFinder_SetDefaultSettings(p);
-
- for (i = 0; i < 256; i++)
- {
- UInt32 r = i;
- int j;
- for (j = 0; j < 8; j++)
- r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
- p->crc[i] = r;
- }
-}
-
-static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
-{
- alloc->Free(alloc, p->hash);
- p->hash = 0;
-}
-
-void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
-{
- MatchFinder_FreeThisClassMemory(p, alloc);
- LzInWindow_Free(p, alloc);
-}
-
-static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
-{
- size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
- if (sizeInBytes / sizeof(CLzRef) != num)
- return 0;
- return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
-}
-
-int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
- UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
- ISzAlloc *alloc)
-{
- UInt32 sizeReserv;
- if (historySize > kMaxHistorySize)
- {
- MatchFinder_Free(p, alloc);
- return 0;
- }
- sizeReserv = historySize >> 1;
- if (historySize > ((UInt32)2 << 30))
- sizeReserv = historySize >> 2;
- sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
-
- p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
- p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
- /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
- if (LzInWindow_Create(p, sizeReserv, alloc))
- {
- UInt32 newCyclicBufferSize = historySize + 1;
- UInt32 hs;
- p->matchMaxLen = matchMaxLen;
- {
- p->fixedHashSize = 0;
- if (p->numHashBytes == 2)
- hs = (1 << 16) - 1;
- else
- {
- hs = historySize - 1;
- hs |= (hs >> 1);
- hs |= (hs >> 2);
- hs |= (hs >> 4);
- hs |= (hs >> 8);
- hs >>= 1;
- hs |= 0xFFFF; /* don't change it! It's required for Deflate */
- if (hs > (1 << 24))
- {
- if (p->numHashBytes == 3)
- hs = (1 << 24) - 1;
- else
- hs >>= 1;
- }
- }
- p->hashMask = hs;
- hs++;
- if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
- if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
- if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
- hs += p->fixedHashSize;
- }
-
- {
- UInt32 prevSize = p->hashSizeSum + p->numSons;
- UInt32 newSize;
- p->historySize = historySize;
- p->hashSizeSum = hs;
- p->cyclicBufferSize = newCyclicBufferSize;
- p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
- newSize = p->hashSizeSum + p->numSons;
- if (p->hash != 0 && prevSize == newSize)
- return 1;
- MatchFinder_FreeThisClassMemory(p, alloc);
- p->hash = AllocRefs(newSize, alloc);
- if (p->hash != 0)
- {
- p->son = p->hash + p->hashSizeSum;
- return 1;
- }
- }
- }
- MatchFinder_Free(p, alloc);
- return 0;
-}
-
-static void MatchFinder_SetLimits(CMatchFinder *p)
-{
- UInt32 limit = kMaxValForNormalize - p->pos;
- UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
- if (limit2 < limit)
- limit = limit2;
- limit2 = p->streamPos - p->pos;
- if (limit2 <= p->keepSizeAfter)
- {
- if (limit2 > 0)
- limit2 = 1;
- }
- else
- limit2 -= p->keepSizeAfter;
- if (limit2 < limit)
- limit = limit2;
- {
- UInt32 lenLimit = p->streamPos - p->pos;
- if (lenLimit > p->matchMaxLen)
- lenLimit = p->matchMaxLen;
- p->lenLimit = lenLimit;
- }
- p->posLimit = p->pos + limit;
-}
-
-void MatchFinder_Init(CMatchFinder *p)
-{
- UInt32 i;
- for (i = 0; i < p->hashSizeSum; i++)
- p->hash[i] = kEmptyHashValue;
- p->cyclicBufferPos = 0;
- p->buffer = p->bufferBase;
- p->pos = p->streamPos = p->cyclicBufferSize;
- p->result = SZ_OK;
- p->streamEndWasReached = 0;
- MatchFinder_ReadBlock(p);
- MatchFinder_SetLimits(p);
-}
-
-static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
-{
- return (p->pos - p->historySize - 1) & kNormalizeMask;
-}
-
-void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
-{
- UInt32 i;
- for (i = 0; i < numItems; i++)
- {
- UInt32 value = items[i];
- if (value <= subValue)
- value = kEmptyHashValue;
- else
- value -= subValue;
- items[i] = value;
- }
-}
-
-static void MatchFinder_Normalize(CMatchFinder *p)
-{
- UInt32 subValue = MatchFinder_GetSubValue(p);
- MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
- MatchFinder_ReduceOffsets(p, subValue);
-}
-
-static void MatchFinder_CheckLimits(CMatchFinder *p)
-{
- if (p->pos == kMaxValForNormalize)
- MatchFinder_Normalize(p);
- if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
- MatchFinder_CheckAndMoveAndRead(p);
- if (p->cyclicBufferPos == p->cyclicBufferSize)
- p->cyclicBufferPos = 0;
- MatchFinder_SetLimits(p);
-}
-
-static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
- UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
- UInt32 *distances, UInt32 maxLen)
-{
- son[_cyclicBufferPos] = curMatch;
- for (;;)
- {
- UInt32 delta = pos - curMatch;
- if (cutValue-- == 0 || delta >= _cyclicBufferSize)
- return distances;
- {
- const Byte *pb = cur - delta;
- curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
- if (pb[maxLen] == cur[maxLen] && *pb == *cur)
- {
- UInt32 len = 0;
- while (++len != lenLimit)
- if (pb[len] != cur[len])
- break;
- if (maxLen < len)
- {
- *distances++ = maxLen = len;
- *distances++ = delta - 1;
- if (len == lenLimit)
- return distances;
- }
- }
- }
- }
-}
-
-UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
- UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
- UInt32 *distances, UInt32 maxLen)
-{
- CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
- CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
- UInt32 len0 = 0, len1 = 0;
- for (;;)
- {
- UInt32 delta = pos - curMatch;
- if (cutValue-- == 0 || delta >= _cyclicBufferSize)
- {
- *ptr0 = *ptr1 = kEmptyHashValue;
- return distances;
- }
- {
- CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
- const Byte *pb = cur - delta;
- UInt32 len = (len0 < len1 ? len0 : len1);
- if (pb[len] == cur[len])
- {
- if (++len != lenLimit && pb[len] == cur[len])
- while (++len != lenLimit)
- if (pb[len] != cur[len])
- break;
- if (maxLen < len)
- {
- *distances++ = maxLen = len;
- *distances++ = delta - 1;
- if (len == lenLimit)
- {
- *ptr1 = pair[0];
- *ptr0 = pair[1];
- return distances;
- }
- }
- }
- if (pb[len] < cur[len])
- {
- *ptr1 = curMatch;
- ptr1 = pair + 1;
- curMatch = *ptr1;
- len1 = len;
- }
- else
- {
- *ptr0 = curMatch;
- ptr0 = pair;
- curMatch = *ptr0;
- len0 = len;
- }
- }
- }
-}
-
-static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
- UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
-{
- CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
- CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
- UInt32 len0 = 0, len1 = 0;
- for (;;)
- {
- UInt32 delta = pos - curMatch;
- if (cutValue-- == 0 || delta >= _cyclicBufferSize)
- {
- *ptr0 = *ptr1 = kEmptyHashValue;
- return;
- }
- {
- CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
- const Byte *pb = cur - delta;
- UInt32 len = (len0 < len1 ? len0 : len1);
- if (pb[len] == cur[len])
- {
- while (++len != lenLimit)
- if (pb[len] != cur[len])
- break;
- {
- if (len == lenLimit)
- {
- *ptr1 = pair[0];
- *ptr0 = pair[1];
- return;
- }
- }
- }
- if (pb[len] < cur[len])
- {
- *ptr1 = curMatch;
- ptr1 = pair + 1;
- curMatch = *ptr1;
- len1 = len;
- }
- else
- {
- *ptr0 = curMatch;
- ptr0 = pair;
- curMatch = *ptr0;
- len0 = len;
- }
- }
- }
-}
-
-#define MOVE_POS \
- ++p->cyclicBufferPos; \
- p->buffer++; \
- if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
-
-#define MOVE_POS_RET MOVE_POS return offset;
-
-static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
-
-#define GET_MATCHES_HEADER2(minLen, ret_op) \
- UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
- lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
- cur = p->buffer;
-
-#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
-#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue)
-
-#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
-
-#define GET_MATCHES_FOOTER(offset, maxLen) \
- offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
- distances + offset, maxLen) - distances); MOVE_POS_RET;
-
-#define SKIP_FOOTER \
- SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
-
-static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-{
- UInt32 offset;
- GET_MATCHES_HEADER(2)
- HASH2_CALC;
- curMatch = p->hash[hashValue];
- p->hash[hashValue] = p->pos;
- offset = 0;
- GET_MATCHES_FOOTER(offset, 1)
-}
-
-UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-{
- UInt32 offset;
- GET_MATCHES_HEADER(3)
- HASH_ZIP_CALC;
- curMatch = p->hash[hashValue];
- p->hash[hashValue] = p->pos;
- offset = 0;
- GET_MATCHES_FOOTER(offset, 2)
-}
-
-static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-{
- UInt32 hash2Value, delta2, maxLen, offset;
- GET_MATCHES_HEADER(3)
-
- HASH3_CALC;
-
- delta2 = p->pos - p->hash[hash2Value];
- curMatch = p->hash[kFix3HashSize + hashValue];
-
- p->hash[hash2Value] =
- p->hash[kFix3HashSize + hashValue] = p->pos;
-
-
- maxLen = 2;
- offset = 0;
- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
- {
- for (; maxLen != lenLimit; maxLen++)
- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
- break;
- distances[0] = maxLen;
- distances[1] = delta2 - 1;
- offset = 2;
- if (maxLen == lenLimit)
- {
- SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
- MOVE_POS_RET;
- }
- }
- GET_MATCHES_FOOTER(offset, maxLen)
-}
-
-static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-{
- UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
- GET_MATCHES_HEADER(4)
-
- HASH4_CALC;
-
- delta2 = p->pos - p->hash[ hash2Value];
- delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
- curMatch = p->hash[kFix4HashSize + hashValue];
-
- p->hash[ hash2Value] =
- p->hash[kFix3HashSize + hash3Value] =
- p->hash[kFix4HashSize + hashValue] = p->pos;
-
- maxLen = 1;
- offset = 0;
- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
- {
- distances[0] = maxLen = 2;
- distances[1] = delta2 - 1;
- offset = 2;
- }
- if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
- {
- maxLen = 3;
- distances[offset + 1] = delta3 - 1;
- offset += 2;
- delta2 = delta3;
- }
- if (offset != 0)
- {
- for (; maxLen != lenLimit; maxLen++)
- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
- break;
- distances[offset - 2] = maxLen;
- if (maxLen == lenLimit)
- {
- SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
- MOVE_POS_RET;
- }
- }
- if (maxLen < 3)
- maxLen = 3;
- GET_MATCHES_FOOTER(offset, maxLen)
-}
-
-static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-{
- UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
- GET_MATCHES_HEADER(4)
-
- HASH4_CALC;
-
- delta2 = p->pos - p->hash[ hash2Value];
- delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
- curMatch = p->hash[kFix4HashSize + hashValue];
-
- p->hash[ hash2Value] =
- p->hash[kFix3HashSize + hash3Value] =
- p->hash[kFix4HashSize + hashValue] = p->pos;
-
- maxLen = 1;
- offset = 0;
- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
- {
- distances[0] = maxLen = 2;
- distances[1] = delta2 - 1;
- offset = 2;
- }
- if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
- {
- maxLen = 3;
- distances[offset + 1] = delta3 - 1;
- offset += 2;
- delta2 = delta3;
- }
- if (offset != 0)
- {
- for (; maxLen != lenLimit; maxLen++)
- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
- break;
- distances[offset - 2] = maxLen;
- if (maxLen == lenLimit)
- {
- p->son[p->cyclicBufferPos] = curMatch;
- MOVE_POS_RET;
- }
- }
- if (maxLen < 3)
- maxLen = 3;
- offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
- distances + offset, maxLen) - (distances));
- MOVE_POS_RET
-}
-
-UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-{
- UInt32 offset;
- GET_MATCHES_HEADER(3)
- HASH_ZIP_CALC;
- curMatch = p->hash[hashValue];
- p->hash[hashValue] = p->pos;
- offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
- distances, 2) - (distances));
- MOVE_POS_RET
-}
-
-static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-{
- do
- {
- SKIP_HEADER(2)
- HASH2_CALC;
- curMatch = p->hash[hashValue];
- p->hash[hashValue] = p->pos;
- SKIP_FOOTER
- }
- while (--num != 0);
-}
-
-void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-{
- do
- {
- SKIP_HEADER(3)
- HASH_ZIP_CALC;
- curMatch = p->hash[hashValue];
- p->hash[hashValue] = p->pos;
- SKIP_FOOTER
- }
- while (--num != 0);
-}
-
-static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-{
- do
- {
- UInt32 hash2Value;
- SKIP_HEADER(3)
- HASH3_CALC;
- curMatch = p->hash[kFix3HashSize + hashValue];
- p->hash[hash2Value] =
- p->hash[kFix3HashSize + hashValue] = p->pos;
- SKIP_FOOTER
- }
- while (--num != 0);
-}
-
-static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-{
- do
- {
- UInt32 hash2Value, hash3Value;
- SKIP_HEADER(4)
- HASH4_CALC;
- curMatch = p->hash[kFix4HashSize + hashValue];
- p->hash[ hash2Value] =
- p->hash[kFix3HashSize + hash3Value] = p->pos;
- p->hash[kFix4HashSize + hashValue] = p->pos;
- SKIP_FOOTER
- }
- while (--num != 0);
-}
-
-static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-{
- do
- {
- UInt32 hash2Value, hash3Value;
- SKIP_HEADER(4)
- HASH4_CALC;
- curMatch = p->hash[kFix4HashSize + hashValue];
- p->hash[ hash2Value] =
- p->hash[kFix3HashSize + hash3Value] =
- p->hash[kFix4HashSize + hashValue] = p->pos;
- p->son[p->cyclicBufferPos] = curMatch;
- MOVE_POS
- }
- while (--num != 0);
-}
-
-void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-{
- do
- {
- SKIP_HEADER(3)
- HASH_ZIP_CALC;
- curMatch = p->hash[hashValue];
- p->hash[hashValue] = p->pos;
- p->son[p->cyclicBufferPos] = curMatch;
- MOVE_POS
- }
- while (--num != 0);
-}
-
-void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
-{
- vTable->Init = (Mf_Init_Func)MatchFinder_Init;
- vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
- vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
- vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
- if (!p->btMode)
- {
- vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
- vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
- }
- else if (p->numHashBytes == 2)
- {
- vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
- vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
- }
- else if (p->numHashBytes == 3)
- {
- vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
- vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
- }
- else
- {
- vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
- vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
- }
-}
diff --git a/dep/StormLib/src/lzma/C/LzFind.h b/dep/StormLib/src/lzma/C/LzFind.h
deleted file mode 100644
index 010c4b92ba3..00000000000
--- a/dep/StormLib/src/lzma/C/LzFind.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* LzFind.h -- Match finder for LZ algorithms
-2009-04-22 : Igor Pavlov : Public domain */
-
-#ifndef __LZ_FIND_H
-#define __LZ_FIND_H
-
-#include "Types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef UInt32 CLzRef;
-
-typedef struct _CMatchFinder
-{
- Byte *buffer;
- UInt32 pos;
- UInt32 posLimit;
- UInt32 streamPos;
- UInt32 lenLimit;
-
- UInt32 cyclicBufferPos;
- UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
-
- UInt32 matchMaxLen;
- CLzRef *hash;
- CLzRef *son;
- UInt32 hashMask;
- UInt32 cutValue;
-
- Byte *bufferBase;
- ISeqInStream *stream;
- int streamEndWasReached;
-
- UInt32 blockSize;
- UInt32 keepSizeBefore;
- UInt32 keepSizeAfter;
-
- UInt32 numHashBytes;
- int directInput;
- size_t directInputRem;
- int btMode;
- int bigHash;
- UInt32 historySize;
- UInt32 fixedHashSize;
- UInt32 hashSizeSum;
- UInt32 numSons;
- SRes result;
- UInt32 crc[256];
-} CMatchFinder;
-
-#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
-#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
-
-#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
-
-int MatchFinder_NeedMove(CMatchFinder *p);
-Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
-void MatchFinder_MoveBlock(CMatchFinder *p);
-void MatchFinder_ReadIfRequired(CMatchFinder *p);
-
-void MatchFinder_Construct(CMatchFinder *p);
-
-/* Conditions:
- historySize <= 3 GB
- keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
-*/
-int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
- UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
- ISzAlloc *alloc);
-void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
-void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
-void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
-
-UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
- UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
- UInt32 *distances, UInt32 maxLen);
-
-/*
-Conditions:
- Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
- Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
-*/
-
-typedef void (*Mf_Init_Func)(void *object);
-typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
-typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
-typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
-typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
-typedef void (*Mf_Skip_Func)(void *object, UInt32);
-
-typedef struct _IMatchFinder
-{
- Mf_Init_Func Init;
- Mf_GetIndexByte_Func GetIndexByte;
- Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
- Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
- Mf_GetMatches_Func GetMatches;
- Mf_Skip_Func Skip;
-} IMatchFinder;
-
-void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
-
-void MatchFinder_Init(CMatchFinder *p);
-UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
-UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
-void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
-void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/dep/StormLib/src/lzma/C/LzFindMt.c b/dep/StormLib/src/lzma/C/LzFindMt.c
deleted file mode 100644
index aa41ed98a57..00000000000
--- a/dep/StormLib/src/lzma/C/LzFindMt.c
+++ /dev/null
@@ -1,793 +0,0 @@
-/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
-2009-09-20 : Igor Pavlov : Public domain */
-
-#include "LzHash.h"
-
-#include "LzFindMt.h"
-
-void MtSync_Construct(CMtSync *p)
-{
- p->wasCreated = False;
- p->csWasInitialized = False;
- p->csWasEntered = False;
- Thread_Construct(&p->thread);
- Event_Construct(&p->canStart);
- Event_Construct(&p->wasStarted);
- Event_Construct(&p->wasStopped);
- Semaphore_Construct(&p->freeSemaphore);
- Semaphore_Construct(&p->filledSemaphore);
-}
-
-void MtSync_GetNextBlock(CMtSync *p)
-{
- if (p->needStart)
- {
- p->numProcessedBlocks = 1;
- p->needStart = False;
- p->stopWriting = False;
- p->exit = False;
- Event_Reset(&p->wasStarted);
- Event_Reset(&p->wasStopped);
-
- Event_Set(&p->canStart);
- Event_Wait(&p->wasStarted);
- }
- else
- {
- CriticalSection_Leave(&p->cs);
- p->csWasEntered = False;
- p->numProcessedBlocks++;
- Semaphore_Release1(&p->freeSemaphore);
- }
- Semaphore_Wait(&p->filledSemaphore);
- CriticalSection_Enter(&p->cs);
- p->csWasEntered = True;
-}
-
-/* MtSync_StopWriting must be called if Writing was started */
-
-void MtSync_StopWriting(CMtSync *p)
-{
- UInt32 myNumBlocks = p->numProcessedBlocks;
- if (!Thread_WasCreated(&p->thread) || p->needStart)
- return;
- p->stopWriting = True;
- if (p->csWasEntered)
- {
- CriticalSection_Leave(&p->cs);
- p->csWasEntered = False;
- }
- Semaphore_Release1(&p->freeSemaphore);
-
- Event_Wait(&p->wasStopped);
-
- while (myNumBlocks++ != p->numProcessedBlocks)
- {
- Semaphore_Wait(&p->filledSemaphore);
- Semaphore_Release1(&p->freeSemaphore);
- }
- p->needStart = True;
-}
-
-void MtSync_Destruct(CMtSync *p)
-{
- if (Thread_WasCreated(&p->thread))
- {
- MtSync_StopWriting(p);
- p->exit = True;
- if (p->needStart)
- Event_Set(&p->canStart);
- Thread_Wait(&p->thread);
- Thread_Close(&p->thread);
- }
- if (p->csWasInitialized)
- {
- CriticalSection_Delete(&p->cs);
- p->csWasInitialized = False;
- }
-
- Event_Close(&p->canStart);
- Event_Close(&p->wasStarted);
- Event_Close(&p->wasStopped);
- Semaphore_Close(&p->freeSemaphore);
- Semaphore_Close(&p->filledSemaphore);
-
- p->wasCreated = False;
-}
-
-#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
-
-static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)
-{
- if (p->wasCreated)
- return SZ_OK;
-
- RINOK_THREAD(CriticalSection_Init(&p->cs));
- p->csWasInitialized = True;
-
- RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canStart));
- RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStarted));
- RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStopped));
-
- RINOK_THREAD(Semaphore_Create(&p->freeSemaphore, numBlocks, numBlocks));
- RINOK_THREAD(Semaphore_Create(&p->filledSemaphore, 0, numBlocks));
-
- p->needStart = True;
-
- RINOK_THREAD(Thread_Create(&p->thread, startAddress, obj));
- p->wasCreated = True;
- return SZ_OK;
-}
-
-static SRes MtSync_Create(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)
-{
- SRes res = MtSync_Create2(p, startAddress, obj, numBlocks);
- if (res != SZ_OK)
- MtSync_Destruct(p);
- return res;
-}
-
-void MtSync_Init(CMtSync *p) { p->needStart = True; }
-
-#define kMtMaxValForNormalize 0xFFFFFFFF
-
-#define DEF_GetHeads2(name, v, action) \
-static void GetHeads ## name(const Byte *p, UInt32 pos, \
-UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
-{ action; for (; numHeads != 0; numHeads--) { \
-const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } }
-
-#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;)
-
-DEF_GetHeads2(2, (p[0] | ((UInt32)p[1] << 8)), hashMask = hashMask; crc = crc; )
-DEF_GetHeads(3, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask)
-DEF_GetHeads(4, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask)
-DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask)
-/* DEF_GetHeads(5, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask) */
-
-void HashThreadFunc(CMatchFinderMt *mt)
-{
- CMtSync *p = &mt->hashSync;
- for (;;)
- {
- UInt32 numProcessedBlocks = 0;
- Event_Wait(&p->canStart);
- Event_Set(&p->wasStarted);
- for (;;)
- {
- if (p->exit)
- return;
- if (p->stopWriting)
- {
- p->numProcessedBlocks = numProcessedBlocks;
- Event_Set(&p->wasStopped);
- break;
- }
-
- {
- CMatchFinder *mf = mt->MatchFinder;
- if (MatchFinder_NeedMove(mf))
- {
- CriticalSection_Enter(&mt->btSync.cs);
- CriticalSection_Enter(&mt->hashSync.cs);
- {
- const Byte *beforePtr = MatchFinder_GetPointerToCurrentPos(mf);
- const Byte *afterPtr;
- MatchFinder_MoveBlock(mf);
- afterPtr = MatchFinder_GetPointerToCurrentPos(mf);
- mt->pointerToCurPos -= beforePtr - afterPtr;
- mt->buffer -= beforePtr - afterPtr;
- }
- CriticalSection_Leave(&mt->btSync.cs);
- CriticalSection_Leave(&mt->hashSync.cs);
- continue;
- }
-
- Semaphore_Wait(&p->freeSemaphore);
-
- MatchFinder_ReadIfRequired(mf);
- if (mf->pos > (kMtMaxValForNormalize - kMtHashBlockSize))
- {
- UInt32 subValue = (mf->pos - mf->historySize - 1);
- MatchFinder_ReduceOffsets(mf, subValue);
- MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, mf->hashMask + 1);
- }
- {
- UInt32 *heads = mt->hashBuf + ((numProcessedBlocks++) & kMtHashNumBlocksMask) * kMtHashBlockSize;
- UInt32 num = mf->streamPos - mf->pos;
- heads[0] = 2;
- heads[1] = num;
- if (num >= mf->numHashBytes)
- {
- num = num - mf->numHashBytes + 1;
- if (num > kMtHashBlockSize - 2)
- num = kMtHashBlockSize - 2;
- mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc);
- heads[0] += num;
- }
- mf->pos += num;
- mf->buffer += num;
- }
- }
-
- Semaphore_Release1(&p->filledSemaphore);
- }
- }
-}
-
-void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
-{
- MtSync_GetNextBlock(&p->hashSync);
- p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize;
- p->hashBufPosLimit += p->hashBuf[p->hashBufPos++];
- p->hashNumAvail = p->hashBuf[p->hashBufPos++];
-}
-
-#define kEmptyHashValue 0
-
-/* #define MFMT_GM_INLINE */
-
-#ifdef MFMT_GM_INLINE
-
-#define NO_INLINE MY_FAST_CALL
-
-Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
- UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
- UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes)
-{
- do
- {
- UInt32 *distances = _distances + 1;
- UInt32 curMatch = pos - *hash++;
-
- CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
- CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
- UInt32 len0 = 0, len1 = 0;
- UInt32 cutValue = _cutValue;
- UInt32 maxLen = _maxLen;
- for (;;)
- {
- UInt32 delta = pos - curMatch;
- if (cutValue-- == 0 || delta >= _cyclicBufferSize)
- {
- *ptr0 = *ptr1 = kEmptyHashValue;
- break;
- }
- {
- CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
- const Byte *pb = cur - delta;
- UInt32 len = (len0 < len1 ? len0 : len1);
- if (pb[len] == cur[len])
- {
- if (++len != lenLimit && pb[len] == cur[len])
- while (++len != lenLimit)
- if (pb[len] != cur[len])
- break;
- if (maxLen < len)
- {
- *distances++ = maxLen = len;
- *distances++ = delta - 1;
- if (len == lenLimit)
- {
- *ptr1 = pair[0];
- *ptr0 = pair[1];
- break;
- }
- }
- }
- if (pb[len] < cur[len])
- {
- *ptr1 = curMatch;
- ptr1 = pair + 1;
- curMatch = *ptr1;
- len1 = len;
- }
- else
- {
- *ptr0 = curMatch;
- ptr0 = pair;
- curMatch = *ptr0;
- len0 = len;
- }
- }
- }
- pos++;
- _cyclicBufferPos++;
- cur++;
- {
- UInt32 num = (UInt32)(distances - _distances);
- *_distances = num - 1;
- _distances += num;
- limit -= num;
- }
- }
- while (limit > 0 && --size != 0);
- *posRes = pos;
- return limit;
-}
-
-#endif
-
-void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
-{
- UInt32 numProcessed = 0;
- UInt32 curPos = 2;
- UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2);
- distances[1] = p->hashNumAvail;
- while (curPos < limit)
- {
- if (p->hashBufPos == p->hashBufPosLimit)
- {
- MatchFinderMt_GetNextBlock_Hash(p);
- distances[1] = numProcessed + p->hashNumAvail;
- if (p->hashNumAvail >= p->numHashBytes)
- continue;
- for (; p->hashNumAvail != 0; p->hashNumAvail--)
- distances[curPos++] = 0;
- break;
- }
- {
- UInt32 size = p->hashBufPosLimit - p->hashBufPos;
- UInt32 lenLimit = p->matchMaxLen;
- UInt32 pos = p->pos;
- UInt32 cyclicBufferPos = p->cyclicBufferPos;
- if (lenLimit >= p->hashNumAvail)
- lenLimit = p->hashNumAvail;
- {
- UInt32 size2 = p->hashNumAvail - lenLimit + 1;
- if (size2 < size)
- size = size2;
- size2 = p->cyclicBufferSize - cyclicBufferPos;
- if (size2 < size)
- size = size2;
- }
- #ifndef MFMT_GM_INLINE
- while (curPos < limit && size-- != 0)
- {
- UInt32 *startDistances = distances + curPos;
- UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++],
- pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
- startDistances + 1, p->numHashBytes - 1) - startDistances);
- *startDistances = num - 1;
- curPos += num;
- cyclicBufferPos++;
- pos++;
- p->buffer++;
- }
- #else
- {
- UInt32 posRes;
- curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
- distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos) , size, &posRes);
- p->hashBufPos += posRes - pos;
- cyclicBufferPos += posRes - pos;
- p->buffer += posRes - pos;
- pos = posRes;
- }
- #endif
-
- numProcessed += pos - p->pos;
- p->hashNumAvail -= pos - p->pos;
- p->pos = pos;
- if (cyclicBufferPos == p->cyclicBufferSize)
- cyclicBufferPos = 0;
- p->cyclicBufferPos = cyclicBufferPos;
- }
- }
- distances[0] = curPos;
-}
-
-void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
-{
- CMtSync *sync = &p->hashSync;
- if (!sync->needStart)
- {
- CriticalSection_Enter(&sync->cs);
- sync->csWasEntered = True;
- }
-
- BtGetMatches(p, p->btBuf + (globalBlockIndex & kMtBtNumBlocksMask) * kMtBtBlockSize);
-
- if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize)
- {
- UInt32 subValue = p->pos - p->cyclicBufferSize;
- MatchFinder_Normalize3(subValue, p->son, p->cyclicBufferSize * 2);
- p->pos -= subValue;
- }
-
- if (!sync->needStart)
- {
- CriticalSection_Leave(&sync->cs);
- sync->csWasEntered = False;
- }
-}
-
-void BtThreadFunc(CMatchFinderMt *mt)
-{
- CMtSync *p = &mt->btSync;
- for (;;)
- {
- UInt32 blockIndex = 0;
- Event_Wait(&p->canStart);
- Event_Set(&p->wasStarted);
- for (;;)
- {
- if (p->exit)
- return;
- if (p->stopWriting)
- {
- p->numProcessedBlocks = blockIndex;
- MtSync_StopWriting(&mt->hashSync);
- Event_Set(&p->wasStopped);
- break;
- }
- Semaphore_Wait(&p->freeSemaphore);
- BtFillBlock(mt, blockIndex++);
- Semaphore_Release1(&p->filledSemaphore);
- }
- }
-}
-
-void MatchFinderMt_Construct(CMatchFinderMt *p)
-{
- p->hashBuf = 0;
- MtSync_Construct(&p->hashSync);
- MtSync_Construct(&p->btSync);
-}
-
-void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
-{
- alloc->Free(alloc, p->hashBuf);
- p->hashBuf = 0;
-}
-
-void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
-{
- MtSync_Destruct(&p->hashSync);
- MtSync_Destruct(&p->btSync);
- MatchFinderMt_FreeMem(p, alloc);
-}
-
-#define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks)
-#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks)
-
-static unsigned MY_STD_CALL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
-static unsigned MY_STD_CALL BtThreadFunc2(void *p)
-{
- Byte allocaDummy[0x180];
- int i = 0;
- for (i = 0; i < 16; i++)
- allocaDummy[i] = (Byte)i;
- BtThreadFunc((CMatchFinderMt *)p);
- return 0;
-}
-
-SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
- UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc)
-{
- CMatchFinder *mf = p->MatchFinder;
- p->historySize = historySize;
- if (kMtBtBlockSize <= matchMaxLen * 4)
- return SZ_ERROR_PARAM;
- if (p->hashBuf == 0)
- {
- p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
- if (p->hashBuf == 0)
- return SZ_ERROR_MEM;
- p->btBuf = p->hashBuf + kHashBufferSize;
- }
- keepAddBufferBefore += (kHashBufferSize + kBtBufferSize);
- keepAddBufferAfter += kMtHashBlockSize;
- if (!MatchFinder_Create(mf, historySize, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter, alloc))
- return SZ_ERROR_MEM;
-
- RINOK(MtSync_Create(&p->hashSync, HashThreadFunc2, p, kMtHashNumBlocks));
- RINOK(MtSync_Create(&p->btSync, BtThreadFunc2, p, kMtBtNumBlocks));
- return SZ_OK;
-}
-
-/* Call it after ReleaseStream / SetStream */
-void MatchFinderMt_Init(CMatchFinderMt *p)
-{
- CMatchFinder *mf = p->MatchFinder;
- p->btBufPos = p->btBufPosLimit = 0;
- p->hashBufPos = p->hashBufPosLimit = 0;
- MatchFinder_Init(mf);
- p->pointerToCurPos = MatchFinder_GetPointerToCurrentPos(mf);
- p->btNumAvailBytes = 0;
- p->lzPos = p->historySize + 1;
-
- p->hash = mf->hash;
- p->fixedHashSize = mf->fixedHashSize;
- p->crc = mf->crc;
-
- p->son = mf->son;
- p->matchMaxLen = mf->matchMaxLen;
- p->numHashBytes = mf->numHashBytes;
- p->pos = mf->pos;
- p->buffer = mf->buffer;
- p->cyclicBufferPos = mf->cyclicBufferPos;
- p->cyclicBufferSize = mf->cyclicBufferSize;
- p->cutValue = mf->cutValue;
-}
-
-/* ReleaseStream is required to finish multithreading */
-void MatchFinderMt_ReleaseStream(CMatchFinderMt *p)
-{
- MtSync_StopWriting(&p->btSync);
- /* p->MatchFinder->ReleaseStream(); */
-}
-
-void MatchFinderMt_Normalize(CMatchFinderMt *p)
-{
- MatchFinder_Normalize3(p->lzPos - p->historySize - 1, p->hash, p->fixedHashSize);
- p->lzPos = p->historySize + 1;
-}
-
-void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
-{
- UInt32 blockIndex;
- MtSync_GetNextBlock(&p->btSync);
- blockIndex = ((p->btSync.numProcessedBlocks - 1) & kMtBtNumBlocksMask);
- p->btBufPosLimit = p->btBufPos = blockIndex * kMtBtBlockSize;
- p->btBufPosLimit += p->btBuf[p->btBufPos++];
- p->btNumAvailBytes = p->btBuf[p->btBufPos++];
- if (p->lzPos >= kMtMaxValForNormalize - kMtBtBlockSize)
- MatchFinderMt_Normalize(p);
-}
-
-const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
-{
- return p->pointerToCurPos;
-}
-
-#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p);
-
-UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p)
-{
- GET_NEXT_BLOCK_IF_REQUIRED;
- return p->btNumAvailBytes;
-}
-
-Byte MatchFinderMt_GetIndexByte(CMatchFinderMt *p, Int32 index)
-{
- return p->pointerToCurPos[index];
-}
-
-UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
-{
- UInt32 hash2Value, curMatch2;
- UInt32 *hash = p->hash;
- const Byte *cur = p->pointerToCurPos;
- UInt32 lzPos = p->lzPos;
- MT_HASH2_CALC
-
- curMatch2 = hash[hash2Value];
- hash[hash2Value] = lzPos;
-
- if (curMatch2 >= matchMinPos)
- if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
- {
- *distances++ = 2;
- *distances++ = lzPos - curMatch2 - 1;
- }
- return distances;
-}
-
-UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
-{
- UInt32 hash2Value, hash3Value, curMatch2, curMatch3;
- UInt32 *hash = p->hash;
- const Byte *cur = p->pointerToCurPos;
- UInt32 lzPos = p->lzPos;
- MT_HASH3_CALC
-
- curMatch2 = hash[ hash2Value];
- curMatch3 = hash[kFix3HashSize + hash3Value];
-
- hash[ hash2Value] =
- hash[kFix3HashSize + hash3Value] =
- lzPos;
-
- if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
- {
- distances[1] = lzPos - curMatch2 - 1;
- if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
- {
- distances[0] = 3;
- return distances + 2;
- }
- distances[0] = 2;
- distances += 2;
- }
- if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
- {
- *distances++ = 3;
- *distances++ = lzPos - curMatch3 - 1;
- }
- return distances;
-}
-
-/*
-UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
-{
- UInt32 hash2Value, hash3Value, hash4Value, curMatch2, curMatch3, curMatch4;
- UInt32 *hash = p->hash;
- const Byte *cur = p->pointerToCurPos;
- UInt32 lzPos = p->lzPos;
- MT_HASH4_CALC
-
- curMatch2 = hash[ hash2Value];
- curMatch3 = hash[kFix3HashSize + hash3Value];
- curMatch4 = hash[kFix4HashSize + hash4Value];
-
- hash[ hash2Value] =
- hash[kFix3HashSize + hash3Value] =
- hash[kFix4HashSize + hash4Value] =
- lzPos;
-
- if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
- {
- distances[1] = lzPos - curMatch2 - 1;
- if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
- {
- distances[0] = (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3;
- return distances + 2;
- }
- distances[0] = 2;
- distances += 2;
- }
- if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
- {
- distances[1] = lzPos - curMatch3 - 1;
- if (cur[(ptrdiff_t)curMatch3 - lzPos + 3] == cur[3])
- {
- distances[0] = 4;
- return distances + 2;
- }
- distances[0] = 3;
- distances += 2;
- }
-
- if (curMatch4 >= matchMinPos)
- if (
- cur[(ptrdiff_t)curMatch4 - lzPos] == cur[0] &&
- cur[(ptrdiff_t)curMatch4 - lzPos + 3] == cur[3]
- )
- {
- *distances++ = 4;
- *distances++ = lzPos - curMatch4 - 1;
- }
- return distances;
-}
-*/
-
-#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++;
-
-UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
-{
- const UInt32 *btBuf = p->btBuf + p->btBufPos;
- UInt32 len = *btBuf++;
- p->btBufPos += 1 + len;
- p->btNumAvailBytes--;
- {
- UInt32 i;
- for (i = 0; i < len; i += 2)
- {
- *distances++ = *btBuf++;
- *distances++ = *btBuf++;
- }
- }
- INCREASE_LZ_POS
- return len;
-}
-
-UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
-{
- const UInt32 *btBuf = p->btBuf + p->btBufPos;
- UInt32 len = *btBuf++;
- p->btBufPos += 1 + len;
-
- if (len == 0)
- {
- if (p->btNumAvailBytes-- >= 4)
- len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances));
- }
- else
- {
- /* Condition: there are matches in btBuf with length < p->numHashBytes */
- UInt32 *distances2;
- p->btNumAvailBytes--;
- distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances);
- do
- {
- *distances2++ = *btBuf++;
- *distances2++ = *btBuf++;
- }
- while ((len -= 2) != 0);
- len = (UInt32)(distances2 - (distances));
- }
- INCREASE_LZ_POS
- return len;
-}
-
-#define SKIP_HEADER2_MT do { GET_NEXT_BLOCK_IF_REQUIRED
-#define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash;
-#define SKIP_FOOTER_MT } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0);
-
-void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num)
-{
- SKIP_HEADER2_MT { p->btNumAvailBytes--;
- SKIP_FOOTER_MT
-}
-
-void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
-{
- SKIP_HEADER_MT(2)
- UInt32 hash2Value;
- MT_HASH2_CALC
- hash[hash2Value] = p->lzPos;
- SKIP_FOOTER_MT
-}
-
-void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
-{
- SKIP_HEADER_MT(3)
- UInt32 hash2Value, hash3Value;
- MT_HASH3_CALC
- hash[kFix3HashSize + hash3Value] =
- hash[ hash2Value] =
- p->lzPos;
- SKIP_FOOTER_MT
-}
-
-/*
-void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
-{
- SKIP_HEADER_MT(4)
- UInt32 hash2Value, hash3Value, hash4Value;
- MT_HASH4_CALC
- hash[kFix4HashSize + hash4Value] =
- hash[kFix3HashSize + hash3Value] =
- hash[ hash2Value] =
- p->lzPos;
- SKIP_FOOTER_MT
-}
-*/
-
-void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
-{
- vTable->Init = (Mf_Init_Func)MatchFinderMt_Init;
- vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinderMt_GetIndexByte;
- vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes;
- vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos;
- vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches;
- switch(p->MatchFinder->numHashBytes)
- {
- case 2:
- p->GetHeadsFunc = GetHeads2;
- p->MixMatchesFunc = (Mf_Mix_Matches)0;
- vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip;
- vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches;
- break;
- case 3:
- p->GetHeadsFunc = GetHeads3;
- p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches2;
- vTable->Skip = (Mf_Skip_Func)MatchFinderMt2_Skip;
- break;
- default:
- /* case 4: */
- p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4;
- /* p->GetHeadsFunc = GetHeads4; */
- p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3;
- vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip;
- break;
- /*
- default:
- p->GetHeadsFunc = GetHeads5;
- p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches4;
- vTable->Skip = (Mf_Skip_Func)MatchFinderMt4_Skip;
- break;
- */
- }
-}
diff --git a/dep/StormLib/src/lzma/C/LzFindMt.h b/dep/StormLib/src/lzma/C/LzFindMt.h
deleted file mode 100644
index b985af5fee2..00000000000
--- a/dep/StormLib/src/lzma/C/LzFindMt.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
-2009-02-07 : Igor Pavlov : Public domain */
-
-#ifndef __LZ_FIND_MT_H
-#define __LZ_FIND_MT_H
-
-#include "LzFind.h"
-#include "Threads.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define kMtHashBlockSize (1 << 13)
-#define kMtHashNumBlocks (1 << 3)
-#define kMtHashNumBlocksMask (kMtHashNumBlocks - 1)
-
-#define kMtBtBlockSize (1 << 14)
-#define kMtBtNumBlocks (1 << 6)
-#define kMtBtNumBlocksMask (kMtBtNumBlocks - 1)
-
-typedef struct _CMtSync
-{
- Bool wasCreated;
- Bool needStart;
- Bool exit;
- Bool stopWriting;
-
- CThread thread;
- CAutoResetEvent canStart;
- CAutoResetEvent wasStarted;
- CAutoResetEvent wasStopped;
- CSemaphore freeSemaphore;
- CSemaphore filledSemaphore;
- Bool csWasInitialized;
- Bool csWasEntered;
- CCriticalSection cs;
- UInt32 numProcessedBlocks;
-} CMtSync;
-
-typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances);
-
-/* kMtCacheLineDummy must be >= size_of_CPU_cache_line */
-#define kMtCacheLineDummy 128
-
-typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos,
- UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc);
-
-typedef struct _CMatchFinderMt
-{
- /* LZ */
- const Byte *pointerToCurPos;
- UInt32 *btBuf;
- UInt32 btBufPos;
- UInt32 btBufPosLimit;
- UInt32 lzPos;
- UInt32 btNumAvailBytes;
-
- UInt32 *hash;
- UInt32 fixedHashSize;
- UInt32 historySize;
- const UInt32 *crc;
-
- Mf_Mix_Matches MixMatchesFunc;
-
- /* LZ + BT */
- CMtSync btSync;
- Byte btDummy[kMtCacheLineDummy];
-
- /* BT */
- UInt32 *hashBuf;
- UInt32 hashBufPos;
- UInt32 hashBufPosLimit;
- UInt32 hashNumAvail;
-
- CLzRef *son;
- UInt32 matchMaxLen;
- UInt32 numHashBytes;
- UInt32 pos;
- Byte *buffer;
- UInt32 cyclicBufferPos;
- UInt32 cyclicBufferSize; /* it must be historySize + 1 */
- UInt32 cutValue;
-
- /* BT + Hash */
- CMtSync hashSync;
- /* Byte hashDummy[kMtCacheLineDummy]; */
-
- /* Hash */
- Mf_GetHeads GetHeadsFunc;
- CMatchFinder *MatchFinder;
-} CMatchFinderMt;
-
-void MatchFinderMt_Construct(CMatchFinderMt *p);
-void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc);
-SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
- UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc);
-void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
-void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/dep/StormLib/src/lzma/C/LzHash.h b/dep/StormLib/src/lzma/C/LzHash.h
deleted file mode 100644
index f3e89966cc7..00000000000
--- a/dep/StormLib/src/lzma/C/LzHash.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* LzHash.h -- HASH functions for LZ algorithms
-2009-02-07 : Igor Pavlov : Public domain */
-
-#ifndef __LZ_HASH_H
-#define __LZ_HASH_H
-
-#define kHash2Size (1 << 10)
-#define kHash3Size (1 << 16)
-#define kHash4Size (1 << 20)
-
-#define kFix3HashSize (kHash2Size)
-#define kFix4HashSize (kHash2Size + kHash3Size)
-#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
-
-#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
-
-#define HASH3_CALC { \
- UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
- hash2Value = temp & (kHash2Size - 1); \
- hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
-
-#define HASH4_CALC { \
- UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
- hash2Value = temp & (kHash2Size - 1); \
- hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
- hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
-
-#define HASH5_CALC { \
- UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
- hash2Value = temp & (kHash2Size - 1); \
- hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
- hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
- hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
- hash4Value &= (kHash4Size - 1); }
-
-/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
-#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
-
-
-#define MT_HASH2_CALC \
- hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
-
-#define MT_HASH3_CALC { \
- UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
- hash2Value = temp & (kHash2Size - 1); \
- hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
-
-#define MT_HASH4_CALC { \
- UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
- hash2Value = temp & (kHash2Size - 1); \
- hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
- hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
-
-#endif
diff --git a/dep/StormLib/src/lzma/C/LzmaDec.c b/dep/StormLib/src/lzma/C/LzmaDec.c
deleted file mode 100644
index 2036761bf14..00000000000
--- a/dep/StormLib/src/lzma/C/LzmaDec.c
+++ /dev/null
@@ -1,999 +0,0 @@
-/* LzmaDec.c -- LZMA Decoder
-2009-09-20 : Igor Pavlov : Public domain */
-
-#include "LzmaDec.h"
-
-#include <string.h>
-
-#define kNumTopBits 24
-#define kTopValue ((UInt32)1 << kNumTopBits)
-
-#define kNumBitModelTotalBits 11
-#define kBitModelTotal (1 << kNumBitModelTotalBits)
-#define kNumMoveBits 5
-
-#define RC_INIT_SIZE 5
-
-#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
-
-#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
-#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
-#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
-#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
- { UPDATE_0(p); i = (i + i); A0; } else \
- { UPDATE_1(p); i = (i + i) + 1; A1; }
-#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
-
-#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
-#define TREE_DECODE(probs, limit, i) \
- { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
-
-/* #define _LZMA_SIZE_OPT */
-
-#ifdef _LZMA_SIZE_OPT
-#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
-#else
-#define TREE_6_DECODE(probs, i) \
- { i = 1; \
- TREE_GET_BIT(probs, i); \
- TREE_GET_BIT(probs, i); \
- TREE_GET_BIT(probs, i); \
- TREE_GET_BIT(probs, i); \
- TREE_GET_BIT(probs, i); \
- TREE_GET_BIT(probs, i); \
- i -= 0x40; }
-#endif
-
-#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
-
-#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
-#define UPDATE_0_CHECK range = bound;
-#define UPDATE_1_CHECK range -= bound; code -= bound;
-#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
- { UPDATE_0_CHECK; i = (i + i); A0; } else \
- { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
-#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
-#define TREE_DECODE_CHECK(probs, limit, i) \
- { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
-
-
-#define kNumPosBitsMax 4
-#define kNumPosStatesMax (1 << kNumPosBitsMax)
-
-#define kLenNumLowBits 3
-#define kLenNumLowSymbols (1 << kLenNumLowBits)
-#define kLenNumMidBits 3
-#define kLenNumMidSymbols (1 << kLenNumMidBits)
-#define kLenNumHighBits 8
-#define kLenNumHighSymbols (1 << kLenNumHighBits)
-
-#define LenChoice 0
-#define LenChoice2 (LenChoice + 1)
-#define LenLow (LenChoice2 + 1)
-#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
-#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
-#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
-
-
-#define kNumStates 12
-#define kNumLitStates 7
-
-#define kStartPosModelIndex 4
-#define kEndPosModelIndex 14
-#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
-
-#define kNumPosSlotBits 6
-#define kNumLenToPosStates 4
-
-#define kNumAlignBits 4
-#define kAlignTableSize (1 << kNumAlignBits)
-
-#define kMatchMinLen 2
-#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
-
-#define IsMatch 0
-#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
-#define IsRepG0 (IsRep + kNumStates)
-#define IsRepG1 (IsRepG0 + kNumStates)
-#define IsRepG2 (IsRepG1 + kNumStates)
-#define IsRep0Long (IsRepG2 + kNumStates)
-#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
-#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
-#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
-#define LenCoder (Align + kAlignTableSize)
-#define RepLenCoder (LenCoder + kNumLenProbs)
-#define Literal (RepLenCoder + kNumLenProbs)
-
-#define LZMA_BASE_SIZE 1846
-#define LZMA_LIT_SIZE 768
-
-#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
-
-#if Literal != LZMA_BASE_SIZE
-StopCompilingDueBUG
-#endif
-
-#define LZMA_DIC_MIN (1 << 12)
-
-/* First LZMA-symbol is always decoded.
-And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
-Out:
- Result:
- SZ_OK - OK
- SZ_ERROR_DATA - Error
- p->remainLen:
- < kMatchSpecLenStart : normal remain
- = kMatchSpecLenStart : finished
- = kMatchSpecLenStart + 1 : Flush marker
- = kMatchSpecLenStart + 2 : State Init Marker
-*/
-
-static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
-{
- CLzmaProb *probs = p->probs;
-
- unsigned state = p->state;
- UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
- unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
- unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
- unsigned lc = p->prop.lc;
-
- Byte *dic = p->dic;
- SizeT dicBufSize = p->dicBufSize;
- SizeT dicPos = p->dicPos;
-
- UInt32 processedPos = p->processedPos;
- UInt32 checkDicSize = p->checkDicSize;
- unsigned len = 0;
-
- const Byte *buf = p->buf;
- UInt32 range = p->range;
- UInt32 code = p->code;
-
- do
- {
- CLzmaProb *prob;
- UInt32 bound;
- unsigned ttt;
- unsigned posState = processedPos & pbMask;
-
- prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
- IF_BIT_0(prob)
- {
- unsigned symbol;
- UPDATE_0(prob);
- prob = probs + Literal;
- if (checkDicSize != 0 || processedPos != 0)
- prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
- (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
-
- if (state < kNumLitStates)
- {
- state -= (state < 4) ? state : 3;
- symbol = 1;
- do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
- }
- else
- {
- unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
- unsigned offs = 0x100;
- state -= (state < 10) ? 3 : 6;
- symbol = 1;
- do
- {
- unsigned bit;
- CLzmaProb *probLit;
- matchByte <<= 1;
- bit = (matchByte & offs);
- probLit = prob + offs + bit + symbol;
- GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
- }
- while (symbol < 0x100);
- }
- dic[dicPos++] = (Byte)symbol;
- processedPos++;
- continue;
- }
- else
- {
- UPDATE_1(prob);
- prob = probs + IsRep + state;
- IF_BIT_0(prob)
- {
- UPDATE_0(prob);
- state += kNumStates;
- prob = probs + LenCoder;
- }
- else
- {
- UPDATE_1(prob);
- if (checkDicSize == 0 && processedPos == 0)
- return SZ_ERROR_DATA;
- prob = probs + IsRepG0 + state;
- IF_BIT_0(prob)
- {
- UPDATE_0(prob);
- prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
- IF_BIT_0(prob)
- {
- UPDATE_0(prob);
- dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
- dicPos++;
- processedPos++;
- state = state < kNumLitStates ? 9 : 11;
- continue;
- }
- UPDATE_1(prob);
- }
- else
- {
- UInt32 distance;
- UPDATE_1(prob);
- prob = probs + IsRepG1 + state;
- IF_BIT_0(prob)
- {
- UPDATE_0(prob);
- distance = rep1;
- }
- else
- {
- UPDATE_1(prob);
- prob = probs + IsRepG2 + state;
- IF_BIT_0(prob)
- {
- UPDATE_0(prob);
- distance = rep2;
- }
- else
- {
- UPDATE_1(prob);
- distance = rep3;
- rep3 = rep2;
- }
- rep2 = rep1;
- }
- rep1 = rep0;
- rep0 = distance;
- }
- state = state < kNumLitStates ? 8 : 11;
- prob = probs + RepLenCoder;
- }
- {
- unsigned limit, offset;
- CLzmaProb *probLen = prob + LenChoice;
- IF_BIT_0(probLen)
- {
- UPDATE_0(probLen);
- probLen = prob + LenLow + (posState << kLenNumLowBits);
- offset = 0;
- limit = (1 << kLenNumLowBits);
- }
- else
- {
- UPDATE_1(probLen);
- probLen = prob + LenChoice2;
- IF_BIT_0(probLen)
- {
- UPDATE_0(probLen);
- probLen = prob + LenMid + (posState << kLenNumMidBits);
- offset = kLenNumLowSymbols;
- limit = (1 << kLenNumMidBits);
- }
- else
- {
- UPDATE_1(probLen);
- probLen = prob + LenHigh;
- offset = kLenNumLowSymbols + kLenNumMidSymbols;
- limit = (1 << kLenNumHighBits);
- }
- }
- TREE_DECODE(probLen, limit, len);
- len += offset;
- }
-
- if (state >= kNumStates)
- {
- UInt32 distance;
- prob = probs + PosSlot +
- ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
- TREE_6_DECODE(prob, distance);
- if (distance >= kStartPosModelIndex)
- {
- unsigned posSlot = (unsigned)distance;
- int numDirectBits = (int)(((distance >> 1) - 1));
- distance = (2 | (distance & 1));
- if (posSlot < kEndPosModelIndex)
- {
- distance <<= numDirectBits;
- prob = probs + SpecPos + distance - posSlot - 1;
- {
- UInt32 mask = 1;
- unsigned i = 1;
- do
- {
- GET_BIT2(prob + i, i, ; , distance |= mask);
- mask <<= 1;
- }
- while (--numDirectBits != 0);
- }
- }
- else
- {
- numDirectBits -= kNumAlignBits;
- do
- {
- NORMALIZE
- range >>= 1;
-
- {
- UInt32 t;
- code -= range;
- t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
- distance = (distance << 1) + (t + 1);
- code += range & t;
- }
- /*
- distance <<= 1;
- if (code >= range)
- {
- code -= range;
- distance |= 1;
- }
- */
- }
- while (--numDirectBits != 0);
- prob = probs + Align;
- distance <<= kNumAlignBits;
- {
- unsigned i = 1;
- GET_BIT2(prob + i, i, ; , distance |= 1);
- GET_BIT2(prob + i, i, ; , distance |= 2);
- GET_BIT2(prob + i, i, ; , distance |= 4);
- GET_BIT2(prob + i, i, ; , distance |= 8);
- }
- if (distance == (UInt32)0xFFFFFFFF)
- {
- len += kMatchSpecLenStart;
- state -= kNumStates;
- break;
- }
- }
- }
- rep3 = rep2;
- rep2 = rep1;
- rep1 = rep0;
- rep0 = distance + 1;
- if (checkDicSize == 0)
- {
- if (distance >= processedPos)
- return SZ_ERROR_DATA;
- }
- else if (distance >= checkDicSize)
- return SZ_ERROR_DATA;
- state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
- }
-
- len += kMatchMinLen;
-
- if (limit == dicPos)
- return SZ_ERROR_DATA;
- {
- SizeT rem = limit - dicPos;
- unsigned curLen = ((rem < len) ? (unsigned)rem : len);
- SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
-
- processedPos += curLen;
-
- len -= curLen;
- if (pos + curLen <= dicBufSize)
- {
- Byte *dest = dic + dicPos;
- ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
- const Byte *lim = dest + curLen;
- dicPos += curLen;
- do
- *(dest) = (Byte)*(dest + src);
- while (++dest != lim);
- }
- else
- {
- do
- {
- dic[dicPos++] = dic[pos];
- if (++pos == dicBufSize)
- pos = 0;
- }
- while (--curLen != 0);
- }
- }
- }
- }
- while (dicPos < limit && buf < bufLimit);
- NORMALIZE;
- p->buf = buf;
- p->range = range;
- p->code = code;
- p->remainLen = len;
- p->dicPos = dicPos;
- p->processedPos = processedPos;
- p->reps[0] = rep0;
- p->reps[1] = rep1;
- p->reps[2] = rep2;
- p->reps[3] = rep3;
- p->state = state;
-
- return SZ_OK;
-}
-
-static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
-{
- if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
- {
- Byte *dic = p->dic;
- SizeT dicPos = p->dicPos;
- SizeT dicBufSize = p->dicBufSize;
- unsigned len = p->remainLen;
- UInt32 rep0 = p->reps[0];
- if (limit - dicPos < len)
- len = (unsigned)(limit - dicPos);
-
- if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
- p->checkDicSize = p->prop.dicSize;
-
- p->processedPos += len;
- p->remainLen -= len;
- while (len-- != 0)
- {
- dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
- dicPos++;
- }
- p->dicPos = dicPos;
- }
-}
-
-static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
-{
- do
- {
- SizeT limit2 = limit;
- if (p->checkDicSize == 0)
- {
- UInt32 rem = p->prop.dicSize - p->processedPos;
- if (limit - p->dicPos > rem)
- limit2 = p->dicPos + rem;
- }
- RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
- if (p->processedPos >= p->prop.dicSize)
- p->checkDicSize = p->prop.dicSize;
- LzmaDec_WriteRem(p, limit);
- }
- while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
-
- if (p->remainLen > kMatchSpecLenStart)
- {
- p->remainLen = kMatchSpecLenStart;
- }
- return 0;
-}
-
-typedef enum
-{
- DUMMY_ERROR, /* unexpected end of input stream */
- DUMMY_LIT,
- DUMMY_MATCH,
- DUMMY_REP
-} ELzmaDummy;
-
-static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
-{
- UInt32 range = p->range;
- UInt32 code = p->code;
- const Byte *bufLimit = buf + inSize;
- CLzmaProb *probs = p->probs;
- unsigned state = p->state;
- ELzmaDummy res;
-
- {
- CLzmaProb *prob;
- UInt32 bound;
- unsigned ttt;
- unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
-
- prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
- IF_BIT_0_CHECK(prob)
- {
- UPDATE_0_CHECK
-
- /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
-
- prob = probs + Literal;
- if (p->checkDicSize != 0 || p->processedPos != 0)
- prob += (LZMA_LIT_SIZE *
- ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
- (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
-
- if (state < kNumLitStates)
- {
- unsigned symbol = 1;
- do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
- }
- else
- {
- unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
- ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
- unsigned offs = 0x100;
- unsigned symbol = 1;
- do
- {
- unsigned bit;
- CLzmaProb *probLit;
- matchByte <<= 1;
- bit = (matchByte & offs);
- probLit = prob + offs + bit + symbol;
- GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
- }
- while (symbol < 0x100);
- }
- res = DUMMY_LIT;
- }
- else
- {
- unsigned len;
- UPDATE_1_CHECK;
-
- prob = probs + IsRep + state;
- IF_BIT_0_CHECK(prob)
- {
- UPDATE_0_CHECK;
- state = 0;
- prob = probs + LenCoder;
- res = DUMMY_MATCH;
- }
- else
- {
- UPDATE_1_CHECK;
- res = DUMMY_REP;
- prob = probs + IsRepG0 + state;
- IF_BIT_0_CHECK(prob)
- {
- UPDATE_0_CHECK;
- prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
- IF_BIT_0_CHECK(prob)
- {
- UPDATE_0_CHECK;
- NORMALIZE_CHECK;
- return DUMMY_REP;
- }
- else
- {
- UPDATE_1_CHECK;
- }
- }
- else
- {
- UPDATE_1_CHECK;
- prob = probs + IsRepG1 + state;
- IF_BIT_0_CHECK(prob)
- {
- UPDATE_0_CHECK;
- }
- else
- {
- UPDATE_1_CHECK;
- prob = probs + IsRepG2 + state;
- IF_BIT_0_CHECK(prob)
- {
- UPDATE_0_CHECK;
- }
- else
- {
- UPDATE_1_CHECK;
- }
- }
- }
- state = kNumStates;
- prob = probs + RepLenCoder;
- }
- {
- unsigned limit, offset;
- CLzmaProb *probLen = prob + LenChoice;
- IF_BIT_0_CHECK(probLen)
- {
- UPDATE_0_CHECK;
- probLen = prob + LenLow + (posState << kLenNumLowBits);
- offset = 0;
- limit = 1 << kLenNumLowBits;
- }
- else
- {
- UPDATE_1_CHECK;
- probLen = prob + LenChoice2;
- IF_BIT_0_CHECK(probLen)
- {
- UPDATE_0_CHECK;
- probLen = prob + LenMid + (posState << kLenNumMidBits);
- offset = kLenNumLowSymbols;
- limit = 1 << kLenNumMidBits;
- }
- else
- {
- UPDATE_1_CHECK;
- probLen = prob + LenHigh;
- offset = kLenNumLowSymbols + kLenNumMidSymbols;
- limit = 1 << kLenNumHighBits;
- }
- }
- TREE_DECODE_CHECK(probLen, limit, len);
- len += offset;
- }
-
- if (state < 4)
- {
- unsigned posSlot;
- prob = probs + PosSlot +
- ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
- kNumPosSlotBits);
- TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
- if (posSlot >= kStartPosModelIndex)
- {
- int numDirectBits = ((posSlot >> 1) - 1);
-
- /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
-
- if (posSlot < kEndPosModelIndex)
- {
- prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
- }
- else
- {
- numDirectBits -= kNumAlignBits;
- do
- {
- NORMALIZE_CHECK
- range >>= 1;
- code -= range & (((code - range) >> 31) - 1);
- /* if (code >= range) code -= range; */
- }
- while (--numDirectBits != 0);
- prob = probs + Align;
- numDirectBits = kNumAlignBits;
- }
- {
- unsigned i = 1;
- do
- {
- GET_BIT_CHECK(prob + i, i);
- }
- while (--numDirectBits != 0);
- }
- }
- }
- }
- }
- NORMALIZE_CHECK;
- return res;
-}
-
-
-static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
-{
- p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
- p->range = 0xFFFFFFFF;
- p->needFlush = 0;
-}
-
-void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
-{
- p->needFlush = 1;
- p->remainLen = 0;
- p->tempBufSize = 0;
-
- if (initDic)
- {
- p->processedPos = 0;
- p->checkDicSize = 0;
- p->needInitState = 1;
- }
- if (initState)
- p->needInitState = 1;
-}
-
-void LzmaDec_Init(CLzmaDec *p)
-{
- p->dicPos = 0;
- LzmaDec_InitDicAndState(p, True, True);
-}
-
-static void LzmaDec_InitStateReal(CLzmaDec *p)
-{
- UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
- UInt32 i;
- CLzmaProb *probs = p->probs;
- for (i = 0; i < numProbs; i++)
- probs[i] = kBitModelTotal >> 1;
- p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
- p->state = 0;
- p->needInitState = 0;
-}
-
-SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
- ELzmaFinishMode finishMode, ELzmaStatus *status)
-{
- SizeT inSize = *srcLen;
- (*srcLen) = 0;
- LzmaDec_WriteRem(p, dicLimit);
-
- *status = LZMA_STATUS_NOT_SPECIFIED;
-
- while (p->remainLen != kMatchSpecLenStart)
- {
- int checkEndMarkNow;
-
- if (p->needFlush != 0)
- {
- for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
- p->tempBuf[p->tempBufSize++] = *src++;
- if (p->tempBufSize < RC_INIT_SIZE)
- {
- *status = LZMA_STATUS_NEEDS_MORE_INPUT;
- return SZ_OK;
- }
- if (p->tempBuf[0] != 0)
- return SZ_ERROR_DATA;
-
- LzmaDec_InitRc(p, p->tempBuf);
- p->tempBufSize = 0;
- }
-
- checkEndMarkNow = 0;
- if (p->dicPos >= dicLimit)
- {
- if (p->remainLen == 0 && p->code == 0)
- {
- *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
- return SZ_OK;
- }
- if (finishMode == LZMA_FINISH_ANY)
- {
- *status = LZMA_STATUS_NOT_FINISHED;
- return SZ_OK;
- }
- if (p->remainLen != 0)
- {
- *status = LZMA_STATUS_NOT_FINISHED;
- return SZ_ERROR_DATA;
- }
- checkEndMarkNow = 1;
- }
-
- if (p->needInitState)
- LzmaDec_InitStateReal(p);
-
- if (p->tempBufSize == 0)
- {
- SizeT processed;
- const Byte *bufLimit;
- if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
- {
- int dummyRes = LzmaDec_TryDummy(p, src, inSize);
- if (dummyRes == DUMMY_ERROR)
- {
- memcpy(p->tempBuf, src, inSize);
- p->tempBufSize = (unsigned)inSize;
- (*srcLen) += inSize;
- *status = LZMA_STATUS_NEEDS_MORE_INPUT;
- return SZ_OK;
- }
- if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
- {
- *status = LZMA_STATUS_NOT_FINISHED;
- return SZ_ERROR_DATA;
- }
- bufLimit = src;
- }
- else
- bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
- p->buf = src;
- if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
- return SZ_ERROR_DATA;
- processed = (SizeT)(p->buf - src);
- (*srcLen) += processed;
- src += processed;
- inSize -= processed;
- }
- else
- {
- unsigned rem = p->tempBufSize, lookAhead = 0;
- while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
- p->tempBuf[rem++] = src[lookAhead++];
- p->tempBufSize = rem;
- if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
- {
- int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
- if (dummyRes == DUMMY_ERROR)
- {
- (*srcLen) += lookAhead;
- *status = LZMA_STATUS_NEEDS_MORE_INPUT;
- return SZ_OK;
- }
- if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
- {
- *status = LZMA_STATUS_NOT_FINISHED;
- return SZ_ERROR_DATA;
- }
- }
- p->buf = p->tempBuf;
- if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
- return SZ_ERROR_DATA;
- lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
- (*srcLen) += lookAhead;
- src += lookAhead;
- inSize -= lookAhead;
- p->tempBufSize = 0;
- }
- }
- if (p->code == 0)
- *status = LZMA_STATUS_FINISHED_WITH_MARK;
- return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
-}
-
-SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
-{
- SizeT outSize = *destLen;
- SizeT inSize = *srcLen;
- *srcLen = *destLen = 0;
- for (;;)
- {
- SizeT inSizeCur = inSize, outSizeCur, dicPos;
- ELzmaFinishMode curFinishMode;
- SRes res;
- if (p->dicPos == p->dicBufSize)
- p->dicPos = 0;
- dicPos = p->dicPos;
- if (outSize > p->dicBufSize - dicPos)
- {
- outSizeCur = p->dicBufSize;
- curFinishMode = LZMA_FINISH_ANY;
- }
- else
- {
- outSizeCur = dicPos + outSize;
- curFinishMode = finishMode;
- }
-
- res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
- src += inSizeCur;
- inSize -= inSizeCur;
- *srcLen += inSizeCur;
- outSizeCur = p->dicPos - dicPos;
- memcpy(dest, p->dic + dicPos, outSizeCur);
- dest += outSizeCur;
- outSize -= outSizeCur;
- *destLen += outSizeCur;
- if (res != 0)
- return res;
- if (outSizeCur == 0 || outSize == 0)
- return SZ_OK;
- }
-}
-
-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
-{
- alloc->Free(alloc, p->probs);
- p->probs = 0;
-}
-
-static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
-{
- alloc->Free(alloc, p->dic);
- p->dic = 0;
-}
-
-void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
-{
- LzmaDec_FreeProbs(p, alloc);
- LzmaDec_FreeDict(p, alloc);
-}
-
-SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
-{
- UInt32 dicSize;
- Byte d;
-
- if (size < LZMA_PROPS_SIZE)
- return SZ_ERROR_UNSUPPORTED;
- else
- dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
-
- if (dicSize < LZMA_DIC_MIN)
- dicSize = LZMA_DIC_MIN;
- p->dicSize = dicSize;
-
- d = data[0];
- if (d >= (9 * 5 * 5))
- return SZ_ERROR_UNSUPPORTED;
-
- p->lc = d % 9;
- d /= 9;
- p->pb = d / 5;
- p->lp = d % 5;
-
- return SZ_OK;
-}
-
-static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
-{
- UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
- if (p->probs == 0 || numProbs != p->numProbs)
- {
- LzmaDec_FreeProbs(p, alloc);
- p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
- p->numProbs = numProbs;
- if (p->probs == 0)
- return SZ_ERROR_MEM;
- }
- return SZ_OK;
-}
-
-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
-{
- CLzmaProps propNew;
- RINOK(LzmaProps_Decode(&propNew, props, propsSize));
- RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
- p->prop = propNew;
- return SZ_OK;
-}
-
-SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
-{
- CLzmaProps propNew;
- SizeT dicBufSize;
- RINOK(LzmaProps_Decode(&propNew, props, propsSize));
- RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
- dicBufSize = propNew.dicSize;
- if (p->dic == 0 || dicBufSize != p->dicBufSize)
- {
- LzmaDec_FreeDict(p, alloc);
- p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
- if (p->dic == 0)
- {
- LzmaDec_FreeProbs(p, alloc);
- return SZ_ERROR_MEM;
- }
- }
- p->dicBufSize = dicBufSize;
- p->prop = propNew;
- return SZ_OK;
-}
-
-SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
- const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
- ELzmaStatus *status, ISzAlloc *alloc)
-{
- CLzmaDec p;
- SRes res;
- SizeT inSize = *srcLen;
- SizeT outSize = *destLen;
- *srcLen = *destLen = 0;
- if (inSize < RC_INIT_SIZE)
- return SZ_ERROR_INPUT_EOF;
-
- LzmaDec_Construct(&p);
- res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
- if (res != 0)
- return res;
- p.dic = dest;
- p.dicBufSize = outSize;
-
- LzmaDec_Init(&p);
-
- *srcLen = inSize;
- res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
-
- if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
- res = SZ_ERROR_INPUT_EOF;
-
- (*destLen) = p.dicPos;
- LzmaDec_FreeProbs(&p, alloc);
- return res;
-}
diff --git a/dep/StormLib/src/lzma/C/LzmaDec.h b/dep/StormLib/src/lzma/C/LzmaDec.h
deleted file mode 100644
index bf7f084ba3d..00000000000
--- a/dep/StormLib/src/lzma/C/LzmaDec.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/* LzmaDec.h -- LZMA Decoder
-2009-02-07 : Igor Pavlov : Public domain */
-
-#ifndef __LZMA_DEC_H
-#define __LZMA_DEC_H
-
-#include "Types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* #define _LZMA_PROB32 */
-/* _LZMA_PROB32 can increase the speed on some CPUs,
- but memory usage for CLzmaDec::probs will be doubled in that case */
-
-#ifdef _LZMA_PROB32
-#define CLzmaProb UInt32
-#else
-#define CLzmaProb UInt16
-#endif
-
-
-/* ---------- LZMA Properties ---------- */
-
-#define LZMA_PROPS_SIZE 5
-
-typedef struct _CLzmaProps
-{
- unsigned lc, lp, pb;
- UInt32 dicSize;
-} CLzmaProps;
-
-/* LzmaProps_Decode - decodes properties
-Returns:
- SZ_OK
- SZ_ERROR_UNSUPPORTED - Unsupported properties
-*/
-
-SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
-
-
-/* ---------- LZMA Decoder state ---------- */
-
-/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
- Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
-
-#define LZMA_REQUIRED_INPUT_MAX 20
-
-typedef struct
-{
- CLzmaProps prop;
- CLzmaProb *probs;
- Byte *dic;
- const Byte *buf;
- UInt32 range, code;
- SizeT dicPos;
- SizeT dicBufSize;
- UInt32 processedPos;
- UInt32 checkDicSize;
- unsigned state;
- UInt32 reps[4];
- unsigned remainLen;
- int needFlush;
- int needInitState;
- UInt32 numProbs;
- unsigned tempBufSize;
- Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
-} CLzmaDec;
-
-#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
-
-void LzmaDec_Init(CLzmaDec *p);
-
-/* There are two types of LZMA streams:
- 0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
- 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
-
-typedef enum
-{
- LZMA_FINISH_ANY, /* finish at any point */
- LZMA_FINISH_END /* block must be finished at the end */
-} ELzmaFinishMode;
-
-/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
-
- You must use LZMA_FINISH_END, when you know that current output buffer
- covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
-
- If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
- and output value of destLen will be less than output buffer size limit.
- You can check status result also.
-
- You can use multiple checks to test data integrity after full decompression:
- 1) Check Result and "status" variable.
- 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
- 3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
- You must use correct finish mode in that case. */
-
-typedef enum
-{
- LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
- LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
- LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
- LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
- LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
-} ELzmaStatus;
-
-/* ELzmaStatus is used only as output value for function call */
-
-
-/* ---------- Interfaces ---------- */
-
-/* There are 3 levels of interfaces:
- 1) Dictionary Interface
- 2) Buffer Interface
- 3) One Call Interface
- You can select any of these interfaces, but don't mix functions from different
- groups for same object. */
-
-
-/* There are two variants to allocate state for Dictionary Interface:
- 1) LzmaDec_Allocate / LzmaDec_Free
- 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
- You can use variant 2, if you set dictionary buffer manually.
- For Buffer Interface you must always use variant 1.
-
-LzmaDec_Allocate* can return:
- SZ_OK
- SZ_ERROR_MEM - Memory allocation error
- SZ_ERROR_UNSUPPORTED - Unsupported properties
-*/
-
-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
-
-SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
-void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
-
-/* ---------- Dictionary Interface ---------- */
-
-/* You can use it, if you want to eliminate the overhead for data copying from
- dictionary to some other external buffer.
- You must work with CLzmaDec variables directly in this interface.
-
- STEPS:
- LzmaDec_Constr()
- LzmaDec_Allocate()
- for (each new stream)
- {
- LzmaDec_Init()
- while (it needs more decompression)
- {
- LzmaDec_DecodeToDic()
- use data from CLzmaDec::dic and update CLzmaDec::dicPos
- }
- }
- LzmaDec_Free()
-*/
-
-/* LzmaDec_DecodeToDic
-
- The decoding to internal dictionary buffer (CLzmaDec::dic).
- You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
-
-finishMode:
- It has meaning only if the decoding reaches output limit (dicLimit).
- LZMA_FINISH_ANY - Decode just dicLimit bytes.
- LZMA_FINISH_END - Stream must be finished after dicLimit.
-
-Returns:
- SZ_OK
- status:
- LZMA_STATUS_FINISHED_WITH_MARK
- LZMA_STATUS_NOT_FINISHED
- LZMA_STATUS_NEEDS_MORE_INPUT
- LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
- SZ_ERROR_DATA - Data error
-*/
-
-SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
-
-
-/* ---------- Buffer Interface ---------- */
-
-/* It's zlib-like interface.
- See LzmaDec_DecodeToDic description for information about STEPS and return results,
- but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
- to work with CLzmaDec variables manually.
-
-finishMode:
- It has meaning only if the decoding reaches output limit (*destLen).
- LZMA_FINISH_ANY - Decode just destLen bytes.
- LZMA_FINISH_END - Stream must be finished after (*destLen).
-*/
-
-SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
-
-
-/* ---------- One Call Interface ---------- */
-
-/* LzmaDecode
-
-finishMode:
- It has meaning only if the decoding reaches output limit (*destLen).
- LZMA_FINISH_ANY - Decode just destLen bytes.
- LZMA_FINISH_END - Stream must be finished after (*destLen).
-
-Returns:
- SZ_OK
- status:
- LZMA_STATUS_FINISHED_WITH_MARK
- LZMA_STATUS_NOT_FINISHED
- LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
- SZ_ERROR_DATA - Data error
- SZ_ERROR_MEM - Memory allocation error
- SZ_ERROR_UNSUPPORTED - Unsupported properties
- SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
-*/
-
-SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
- const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
- ELzmaStatus *status, ISzAlloc *alloc);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/dep/StormLib/src/lzma/C/LzmaEnc.c b/dep/StormLib/src/lzma/C/LzmaEnc.c
deleted file mode 100644
index 169d4f4639e..00000000000
--- a/dep/StormLib/src/lzma/C/LzmaEnc.c
+++ /dev/null
@@ -1,2268 +0,0 @@
-/* LzmaEnc.c -- LZMA Encoder
-2009-11-24 : Igor Pavlov : Public domain */
-
-#include <string.h>
-
-/* #define SHOW_STAT */
-/* #define SHOW_STAT2 */
-
-#if defined(SHOW_STAT) || defined(SHOW_STAT2)
-#include <stdio.h>
-#endif
-
-#include "LzmaEnc.h"
-
-#include "LzFind.h"
-#ifndef _7ZIP_ST
-#include "LzFindMt.h"
-#endif
-
-#ifdef SHOW_STAT
-static int ttt = 0;
-#endif
-
-#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
-
-#define kBlockSize (9 << 10)
-#define kUnpackBlockSize (1 << 18)
-#define kMatchArraySize (1 << 21)
-#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX)
-
-#define kNumMaxDirectBits (31)
-
-#define kNumTopBits 24
-#define kTopValue ((UInt32)1 << kNumTopBits)
-
-#define kNumBitModelTotalBits 11
-#define kBitModelTotal (1 << kNumBitModelTotalBits)
-#define kNumMoveBits 5
-#define kProbInitValue (kBitModelTotal >> 1)
-
-#define kNumMoveReducingBits 4
-#define kNumBitPriceShiftBits 4
-#define kBitPrice (1 << kNumBitPriceShiftBits)
-
-void LzmaEncProps_Init(CLzmaEncProps *p)
-{
- p->level = 5;
- p->dictSize = p->mc = 0;
- p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
- p->writeEndMark = 0;
-}
-
-void LzmaEncProps_Normalize(CLzmaEncProps *p)
-{
- int level = p->level;
- if (level < 0) level = 5;
- p->level = level;
- if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
- if (p->lc < 0) p->lc = 3;
- if (p->lp < 0) p->lp = 0;
- if (p->pb < 0) p->pb = 2;
- if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
- if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
- if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
- if (p->numHashBytes < 0) p->numHashBytes = 4;
- if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
- if (p->numThreads < 0)
- p->numThreads =
- #ifndef _7ZIP_ST
- ((p->btMode && p->algo) ? 2 : 1);
- #else
- 1;
- #endif
-}
-
-UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
-{
- CLzmaEncProps props = *props2;
- LzmaEncProps_Normalize(&props);
- return props.dictSize;
-}
-
-/* #define LZMA_LOG_BSR */
-/* Define it for Intel's CPU */
-
-
-#ifdef LZMA_LOG_BSR
-
-#define kDicLogSizeMaxCompress 30
-
-#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
-
-UInt32 GetPosSlot1(UInt32 pos)
-{
- UInt32 res;
- BSR2_RET(pos, res);
- return res;
-}
-#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
-#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); }
-
-#else
-
-#define kNumLogBits (9 + (int)sizeof(size_t) / 2)
-#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
-
-void LzmaEnc_FastPosInit(Byte *g_FastPos)
-{
- int c = 2, slotFast;
- g_FastPos[0] = 0;
- g_FastPos[1] = 1;
-
- for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)
- {
- UInt32 k = (1 << ((slotFast >> 1) - 1));
- UInt32 j;
- for (j = 0; j < k; j++, c++)
- g_FastPos[c] = (Byte)slotFast;
- }
-}
-
-#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
- (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
- res = p->g_FastPos[pos >> i] + (i * 2); }
-/*
-#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
- p->g_FastPos[pos >> 6] + 12 : \
- p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; }
-*/
-
-#define GetPosSlot1(pos) p->g_FastPos[pos]
-#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
-#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); }
-
-#endif
-
-
-#define LZMA_NUM_REPS 4
-
-typedef unsigned CState;
-
-typedef struct
-{
- UInt32 price;
-
- CState state;
- int prev1IsChar;
- int prev2;
-
- UInt32 posPrev2;
- UInt32 backPrev2;
-
- UInt32 posPrev;
- UInt32 backPrev;
- UInt32 backs[LZMA_NUM_REPS];
-} COptimal;
-
-#define kNumOpts (1 << 12)
-
-#define kNumLenToPosStates 4
-#define kNumPosSlotBits 6
-#define kDicLogSizeMin 0
-#define kDicLogSizeMax 32
-#define kDistTableSizeMax (kDicLogSizeMax * 2)
-
-
-#define kNumAlignBits 4
-#define kAlignTableSize (1 << kNumAlignBits)
-#define kAlignMask (kAlignTableSize - 1)
-
-#define kStartPosModelIndex 4
-#define kEndPosModelIndex 14
-#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex)
-
-#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
-
-#ifdef _LZMA_PROB32
-#define CLzmaProb UInt32
-#else
-#define CLzmaProb UInt16
-#endif
-
-#define LZMA_PB_MAX 4
-#define LZMA_LC_MAX 8
-#define LZMA_LP_MAX 4
-
-#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)
-
-
-#define kLenNumLowBits 3
-#define kLenNumLowSymbols (1 << kLenNumLowBits)
-#define kLenNumMidBits 3
-#define kLenNumMidSymbols (1 << kLenNumMidBits)
-#define kLenNumHighBits 8
-#define kLenNumHighSymbols (1 << kLenNumHighBits)
-
-#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
-
-#define LZMA_MATCH_LEN_MIN 2
-#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
-
-#define kNumStates 12
-
-typedef struct
-{
- CLzmaProb choice;
- CLzmaProb choice2;
- CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits];
- CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits];
- CLzmaProb high[kLenNumHighSymbols];
-} CLenEnc;
-
-typedef struct
-{
- CLenEnc p;
- UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
- UInt32 tableSize;
- UInt32 counters[LZMA_NUM_PB_STATES_MAX];
-} CLenPriceEnc;
-
-typedef struct
-{
- UInt32 range;
- Byte cache;
- UInt64 low;
- UInt64 cacheSize;
- Byte *buf;
- Byte *bufLim;
- Byte *bufBase;
- ISeqOutStream *outStream;
- UInt64 processed;
- SRes res;
-} CRangeEnc;
-
-typedef struct
-{
- CLzmaProb *litProbs;
-
- CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
- CLzmaProb isRep[kNumStates];
- CLzmaProb isRepG0[kNumStates];
- CLzmaProb isRepG1[kNumStates];
- CLzmaProb isRepG2[kNumStates];
- CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
-
- CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
- CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
- CLzmaProb posAlignEncoder[1 << kNumAlignBits];
-
- CLenPriceEnc lenEnc;
- CLenPriceEnc repLenEnc;
-
- UInt32 reps[LZMA_NUM_REPS];
- UInt32 state;
-} CSaveState;
-
-typedef struct
-{
- IMatchFinder matchFinder;
- void *matchFinderObj;
-
- #ifndef _7ZIP_ST
- Bool mtMode;
- CMatchFinderMt matchFinderMt;
- #endif
-
- CMatchFinder matchFinderBase;
-
- #ifndef _7ZIP_ST
- Byte pad[128];
- #endif
-
- UInt32 optimumEndIndex;
- UInt32 optimumCurrentIndex;
-
- UInt32 longestMatchLength;
- UInt32 numPairs;
- UInt32 numAvail;
- COptimal opt[kNumOpts];
-
- #ifndef LZMA_LOG_BSR
- Byte g_FastPos[1 << kNumLogBits];
- #endif
-
- UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
- UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
- UInt32 numFastBytes;
- UInt32 additionalOffset;
- UInt32 reps[LZMA_NUM_REPS];
- UInt32 state;
-
- UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
- UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
- UInt32 alignPrices[kAlignTableSize];
- UInt32 alignPriceCount;
-
- UInt32 distTableSize;
-
- unsigned lc, lp, pb;
- unsigned lpMask, pbMask;
-
- CLzmaProb *litProbs;
-
- CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
- CLzmaProb isRep[kNumStates];
- CLzmaProb isRepG0[kNumStates];
- CLzmaProb isRepG1[kNumStates];
- CLzmaProb isRepG2[kNumStates];
- CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
-
- CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
- CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
- CLzmaProb posAlignEncoder[1 << kNumAlignBits];
-
- CLenPriceEnc lenEnc;
- CLenPriceEnc repLenEnc;
-
- unsigned lclp;
-
- Bool fastMode;
-
- CRangeEnc rc;
-
- Bool writeEndMark;
- UInt64 nowPos64;
- UInt32 matchPriceCount;
- Bool finished;
- Bool multiThread;
-
- SRes result;
- UInt32 dictSize;
- UInt32 matchFinderCycles;
-
- int needInit;
-
- CSaveState saveState;
-} CLzmaEnc;
-
-void LzmaEnc_SaveState(CLzmaEncHandle pp)
-{
- CLzmaEnc *p = (CLzmaEnc *)pp;
- CSaveState *dest = &p->saveState;
- int i;
- dest->lenEnc = p->lenEnc;
- dest->repLenEnc = p->repLenEnc;
- dest->state = p->state;
-
- for (i = 0; i < kNumStates; i++)
- {
- memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
- memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
- }
- for (i = 0; i < kNumLenToPosStates; i++)
- memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
- memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
- memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
- memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
- memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
- memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
- memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
- memcpy(dest->reps, p->reps, sizeof(p->reps));
- memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
-}
-
-void LzmaEnc_RestoreState(CLzmaEncHandle pp)
-{
- CLzmaEnc *dest = (CLzmaEnc *)pp;
- const CSaveState *p = &dest->saveState;
- int i;
- dest->lenEnc = p->lenEnc;
- dest->repLenEnc = p->repLenEnc;
- dest->state = p->state;
-
- for (i = 0; i < kNumStates; i++)
- {
- memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
- memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
- }
- for (i = 0; i < kNumLenToPosStates; i++)
- memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
- memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
- memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
- memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
- memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
- memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
- memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
- memcpy(dest->reps, p->reps, sizeof(p->reps));
- memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb));
-}
-
-SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
-{
- CLzmaEnc *p = (CLzmaEnc *)pp;
- CLzmaEncProps props = *props2;
- LzmaEncProps_Normalize(&props);
-
- if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
- props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30))
- return SZ_ERROR_PARAM;
- p->dictSize = props.dictSize;
- p->matchFinderCycles = props.mc;
- {
- unsigned fb = props.fb;
- if (fb < 5)
- fb = 5;
- if (fb > LZMA_MATCH_LEN_MAX)
- fb = LZMA_MATCH_LEN_MAX;
- p->numFastBytes = fb;
- }
- p->lc = props.lc;
- p->lp = props.lp;
- p->pb = props.pb;
- p->fastMode = (props.algo == 0);
- p->matchFinderBase.btMode = props.btMode;
- {
- UInt32 numHashBytes = 4;
- if (props.btMode)
- {
- if (props.numHashBytes < 2)
- numHashBytes = 2;
- else if (props.numHashBytes < 4)
- numHashBytes = props.numHashBytes;
- }
- p->matchFinderBase.numHashBytes = numHashBytes;
- }
-
- p->matchFinderBase.cutValue = props.mc;
-
- p->writeEndMark = props.writeEndMark;
-
- #ifndef _7ZIP_ST
- /*
- if (newMultiThread != _multiThread)
- {
- ReleaseMatchFinder();
- _multiThread = newMultiThread;
- }
- */
- p->multiThread = (props.numThreads > 1);
- #endif
-
- return SZ_OK;
-}
-
-static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
-static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
-static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
-static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
-
-#define IsCharState(s) ((s) < 7)
-
-#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
-
-#define kInfinityPrice (1 << 30)
-
-static void RangeEnc_Construct(CRangeEnc *p)
-{
- p->outStream = 0;
- p->bufBase = 0;
-}
-
-#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
-
-#define RC_BUF_SIZE (1 << 16)
-static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
-{
- if (p->bufBase == 0)
- {
- p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
- if (p->bufBase == 0)
- return 0;
- p->bufLim = p->bufBase + RC_BUF_SIZE;
- }
- return 1;
-}
-
-static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)
-{
- alloc->Free(alloc, p->bufBase);
- p->bufBase = 0;
-}
-
-static void RangeEnc_Init(CRangeEnc *p)
-{
- /* Stream.Init(); */
- p->low = 0;
- p->range = 0xFFFFFFFF;
- p->cacheSize = 1;
- p->cache = 0;
-
- p->buf = p->bufBase;
-
- p->processed = 0;
- p->res = SZ_OK;
-}
-
-static void RangeEnc_FlushStream(CRangeEnc *p)
-{
- size_t num;
- if (p->res != SZ_OK)
- return;
- num = p->buf - p->bufBase;
- if (num != p->outStream->Write(p->outStream, p->bufBase, num))
- p->res = SZ_ERROR_WRITE;
- p->processed += num;
- p->buf = p->bufBase;
-}
-
-static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
-{
- if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0)
- {
- Byte temp = p->cache;
- do
- {
- Byte *buf = p->buf;
- *buf++ = (Byte)(temp + (Byte)(p->low >> 32));
- p->buf = buf;
- if (buf == p->bufLim)
- RangeEnc_FlushStream(p);
- temp = 0xFF;
- }
- while (--p->cacheSize != 0);
- p->cache = (Byte)((UInt32)p->low >> 24);
- }
- p->cacheSize++;
- p->low = (UInt32)p->low << 8;
-}
-
-static void RangeEnc_FlushData(CRangeEnc *p)
-{
- int i;
- for (i = 0; i < 5; i++)
- RangeEnc_ShiftLow(p);
-}
-
-static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits)
-{
- do
- {
- p->range >>= 1;
- p->low += p->range & (0 - ((value >> --numBits) & 1));
- if (p->range < kTopValue)
- {
- p->range <<= 8;
- RangeEnc_ShiftLow(p);
- }
- }
- while (numBits != 0);
-}
-
-static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol)
-{
- UInt32 ttt = *prob;
- UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt;
- if (symbol == 0)
- {
- p->range = newBound;
- ttt += (kBitModelTotal - ttt) >> kNumMoveBits;
- }
- else
- {
- p->low += newBound;
- p->range -= newBound;
- ttt -= ttt >> kNumMoveBits;
- }
- *prob = (CLzmaProb)ttt;
- if (p->range < kTopValue)
- {
- p->range <<= 8;
- RangeEnc_ShiftLow(p);
- }
-}
-
-static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol)
-{
- symbol |= 0x100;
- do
- {
- RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);
- symbol <<= 1;
- }
- while (symbol < 0x10000);
-}
-
-static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte)
-{
- UInt32 offs = 0x100;
- symbol |= 0x100;
- do
- {
- matchByte <<= 1;
- RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);
- symbol <<= 1;
- offs &= ~(matchByte ^ symbol);
- }
- while (symbol < 0x10000);
-}
-
-void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
-{
- UInt32 i;
- for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
- {
- const int kCyclesBits = kNumBitPriceShiftBits;
- UInt32 w = i;
- UInt32 bitCount = 0;
- int j;
- for (j = 0; j < kCyclesBits; j++)
- {
- w = w * w;
- bitCount <<= 1;
- while (w >= ((UInt32)1 << 16))
- {
- w >>= 1;
- bitCount++;
- }
- }
- ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
- }
-}
-
-
-#define GET_PRICE(prob, symbol) \
- p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
-
-#define GET_PRICEa(prob, symbol) \
- ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
-
-#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
-#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
-
-#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
-#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
-
-static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices)
-{
- UInt32 price = 0;
- symbol |= 0x100;
- do
- {
- price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1);
- symbol <<= 1;
- }
- while (symbol < 0x10000);
- return price;
-}
-
-static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)
-{
- UInt32 price = 0;
- UInt32 offs = 0x100;
- symbol |= 0x100;
- do
- {
- matchByte <<= 1;
- price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1);
- symbol <<= 1;
- offs &= ~(matchByte ^ symbol);
- }
- while (symbol < 0x10000);
- return price;
-}
-
-
-static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
-{
- UInt32 m = 1;
- int i;
- for (i = numBitLevels; i != 0;)
- {
- UInt32 bit;
- i--;
- bit = (symbol >> i) & 1;
- RangeEnc_EncodeBit(rc, probs + m, bit);
- m = (m << 1) | bit;
- }
-}
-
-static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
-{
- UInt32 m = 1;
- int i;
- for (i = 0; i < numBitLevels; i++)
- {
- UInt32 bit = symbol & 1;
- RangeEnc_EncodeBit(rc, probs + m, bit);
- m = (m << 1) | bit;
- symbol >>= 1;
- }
-}
-
-static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
-{
- UInt32 price = 0;
- symbol |= (1 << numBitLevels);
- while (symbol != 1)
- {
- price += GET_PRICEa(probs[symbol >> 1], symbol & 1);
- symbol >>= 1;
- }
- return price;
-}
-
-static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
-{
- UInt32 price = 0;
- UInt32 m = 1;
- int i;
- for (i = numBitLevels; i != 0; i--)
- {
- UInt32 bit = symbol & 1;
- symbol >>= 1;
- price += GET_PRICEa(probs[m], bit);
- m = (m << 1) | bit;
- }
- return price;
-}
-
-
-static void LenEnc_Init(CLenEnc *p)
-{
- unsigned i;
- p->choice = p->choice2 = kProbInitValue;
- for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++)
- p->low[i] = kProbInitValue;
- for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++)
- p->mid[i] = kProbInitValue;
- for (i = 0; i < kLenNumHighSymbols; i++)
- p->high[i] = kProbInitValue;
-}
-
-static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState)
-{
- if (symbol < kLenNumLowSymbols)
- {
- RangeEnc_EncodeBit(rc, &p->choice, 0);
- RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol);
- }
- else
- {
- RangeEnc_EncodeBit(rc, &p->choice, 1);
- if (symbol < kLenNumLowSymbols + kLenNumMidSymbols)
- {
- RangeEnc_EncodeBit(rc, &p->choice2, 0);
- RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols);
- }
- else
- {
- RangeEnc_EncodeBit(rc, &p->choice2, 1);
- RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols);
- }
- }
-}
-
-static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices)
-{
- UInt32 a0 = GET_PRICE_0a(p->choice);
- UInt32 a1 = GET_PRICE_1a(p->choice);
- UInt32 b0 = a1 + GET_PRICE_0a(p->choice2);
- UInt32 b1 = a1 + GET_PRICE_1a(p->choice2);
- UInt32 i = 0;
- for (i = 0; i < kLenNumLowSymbols; i++)
- {
- if (i >= numSymbols)
- return;
- prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices);
- }
- for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++)
- {
- if (i >= numSymbols)
- return;
- prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices);
- }
- for (; i < numSymbols; i++)
- prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
-}
-
-static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices)
-{
- LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
- p->counters[posState] = p->tableSize;
-}
-
-static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices)
-{
- UInt32 posState;
- for (posState = 0; posState < numPosStates; posState++)
- LenPriceEnc_UpdateTable(p, posState, ProbPrices);
-}
-
-static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices)
-{
- LenEnc_Encode(&p->p, rc, symbol, posState);
- if (updatePrice)
- if (--p->counters[posState] == 0)
- LenPriceEnc_UpdateTable(p, posState, ProbPrices);
-}
-
-
-
-
-static void MovePos(CLzmaEnc *p, UInt32 num)
-{
- #ifdef SHOW_STAT
- ttt += num;
- printf("\n MovePos %d", num);
- #endif
- if (num != 0)
- {
- p->additionalOffset += num;
- p->matchFinder.Skip(p->matchFinderObj, num);
- }
-}
-
-static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
-{
- UInt32 lenRes = 0, numPairs;
- p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
- numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
- #ifdef SHOW_STAT
- printf("\n i = %d numPairs = %d ", ttt, numPairs / 2);
- ttt++;
- {
- UInt32 i;
- for (i = 0; i < numPairs; i += 2)
- printf("%2d %6d | ", p->matches[i], p->matches[i + 1]);
- }
- #endif
- if (numPairs > 0)
- {
- lenRes = p->matches[numPairs - 2];
- if (lenRes == p->numFastBytes)
- {
- const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
- UInt32 distance = p->matches[numPairs - 1] + 1;
- UInt32 numAvail = p->numAvail;
- if (numAvail > LZMA_MATCH_LEN_MAX)
- numAvail = LZMA_MATCH_LEN_MAX;
- {
- const Byte *pby2 = pby - distance;
- for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
- }
- }
- }
- p->additionalOffset++;
- *numDistancePairsRes = numPairs;
- return lenRes;
-}
-
-
-#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False;
-#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False;
-#define IsShortRep(p) ((p)->backPrev == 0)
-
-static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState)
-{
- return
- GET_PRICE_0(p->isRepG0[state]) +
- GET_PRICE_0(p->isRep0Long[state][posState]);
-}
-
-static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState)
-{
- UInt32 price;
- if (repIndex == 0)
- {
- price = GET_PRICE_0(p->isRepG0[state]);
- price += GET_PRICE_1(p->isRep0Long[state][posState]);
- }
- else
- {
- price = GET_PRICE_1(p->isRepG0[state]);
- if (repIndex == 1)
- price += GET_PRICE_0(p->isRepG1[state]);
- else
- {
- price += GET_PRICE_1(p->isRepG1[state]);
- price += GET_PRICE(p->isRepG2[state], repIndex - 2);
- }
- }
- return price;
-}
-
-static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
-{
- return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +
- GetPureRepPrice(p, repIndex, state, posState);
-}
-
-static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
-{
- UInt32 posMem = p->opt[cur].posPrev;
- UInt32 backMem = p->opt[cur].backPrev;
- p->optimumEndIndex = cur;
- do
- {
- if (p->opt[cur].prev1IsChar)
- {
- MakeAsChar(&p->opt[posMem])
- p->opt[posMem].posPrev = posMem - 1;
- if (p->opt[cur].prev2)
- {
- p->opt[posMem - 1].prev1IsChar = False;
- p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;
- p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;
- }
- }
- {
- UInt32 posPrev = posMem;
- UInt32 backCur = backMem;
-
- backMem = p->opt[posPrev].backPrev;
- posMem = p->opt[posPrev].posPrev;
-
- p->opt[posPrev].backPrev = backCur;
- p->opt[posPrev].posPrev = cur;
- cur = posPrev;
- }
- }
- while (cur != 0);
- *backRes = p->opt[0].backPrev;
- p->optimumCurrentIndex = p->opt[0].posPrev;
- return p->optimumCurrentIndex;
-}
-
-#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300)
-
-static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
-{
- UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur;
- UInt32 matchPrice, repMatchPrice, normalMatchPrice;
- UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
- UInt32 *matches;
- const Byte *data;
- Byte curByte, matchByte;
- if (p->optimumEndIndex != p->optimumCurrentIndex)
- {
- const COptimal *opt = &p->opt[p->optimumCurrentIndex];
- UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex;
- *backRes = opt->backPrev;
- p->optimumCurrentIndex = opt->posPrev;
- return lenRes;
- }
- p->optimumCurrentIndex = p->optimumEndIndex = 0;
-
- if (p->additionalOffset == 0)
- mainLen = ReadMatchDistances(p, &numPairs);
- else
- {
- mainLen = p->longestMatchLength;
- numPairs = p->numPairs;
- }
-
- numAvail = p->numAvail;
- if (numAvail < 2)
- {
- *backRes = (UInt32)(-1);
- return 1;
- }
- if (numAvail > LZMA_MATCH_LEN_MAX)
- numAvail = LZMA_MATCH_LEN_MAX;
-
- data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
- repMaxIndex = 0;
- for (i = 0; i < LZMA_NUM_REPS; i++)
- {
- UInt32 lenTest;
- const Byte *data2;
- reps[i] = p->reps[i];
- data2 = data - (reps[i] + 1);
- if (data[0] != data2[0] || data[1] != data2[1])
- {
- repLens[i] = 0;
- continue;
- }
- for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
- repLens[i] = lenTest;
- if (lenTest > repLens[repMaxIndex])
- repMaxIndex = i;
- }
- if (repLens[repMaxIndex] >= p->numFastBytes)
- {
- UInt32 lenRes;
- *backRes = repMaxIndex;
- lenRes = repLens[repMaxIndex];
- MovePos(p, lenRes - 1);
- return lenRes;
- }
-
- matches = p->matches;
- if (mainLen >= p->numFastBytes)
- {
- *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
- MovePos(p, mainLen - 1);
- return mainLen;
- }
- curByte = *data;
- matchByte = *(data - (reps[0] + 1));
-
- if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2)
- {
- *backRes = (UInt32)-1;
- return 1;
- }
-
- p->opt[0].state = (CState)p->state;
-
- posState = (position & p->pbMask);
-
- {
- const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
- p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
- (!IsCharState(p->state) ?
- LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
- LitEnc_GetPrice(probs, curByte, p->ProbPrices));
- }
-
- MakeAsChar(&p->opt[1]);
-
- matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
- repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
-
- if (matchByte == curByte)
- {
- UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState);
- if (shortRepPrice < p->opt[1].price)
- {
- p->opt[1].price = shortRepPrice;
- MakeAsShortRep(&p->opt[1]);
- }
- }
- lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]);
-
- if (lenEnd < 2)
- {
- *backRes = p->opt[1].backPrev;
- return 1;
- }
-
- p->opt[1].posPrev = 0;
- for (i = 0; i < LZMA_NUM_REPS; i++)
- p->opt[0].backs[i] = reps[i];
-
- len = lenEnd;
- do
- p->opt[len--].price = kInfinityPrice;
- while (len >= 2);
-
- for (i = 0; i < LZMA_NUM_REPS; i++)
- {
- UInt32 repLen = repLens[i];
- UInt32 price;
- if (repLen < 2)
- continue;
- price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
- do
- {
- UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2];
- COptimal *opt = &p->opt[repLen];
- if (curAndLenPrice < opt->price)
- {
- opt->price = curAndLenPrice;
- opt->posPrev = 0;
- opt->backPrev = i;
- opt->prev1IsChar = False;
- }
- }
- while (--repLen >= 2);
- }
-
- normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
-
- len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
- if (len <= mainLen)
- {
- UInt32 offs = 0;
- while (len > matches[offs])
- offs += 2;
- for (; ; len++)
- {
- COptimal *opt;
- UInt32 distance = matches[offs + 1];
-
- UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];
- UInt32 lenToPosState = GetLenToPosState(len);
- if (distance < kNumFullDistances)
- curAndLenPrice += p->distancesPrices[lenToPosState][distance];
- else
- {
- UInt32 slot;
- GetPosSlot2(distance, slot);
- curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot];
- }
- opt = &p->opt[len];
- if (curAndLenPrice < opt->price)
- {
- opt->price = curAndLenPrice;
- opt->posPrev = 0;
- opt->backPrev = distance + LZMA_NUM_REPS;
- opt->prev1IsChar = False;
- }
- if (len == matches[offs])
- {
- offs += 2;
- if (offs == numPairs)
- break;
- }
- }
- }
-
- cur = 0;
-
- #ifdef SHOW_STAT2
- if (position >= 0)
- {
- unsigned i;
- printf("\n pos = %4X", position);
- for (i = cur; i <= lenEnd; i++)
- printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price);
- }
- #endif
-
- for (;;)
- {
- UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
- UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
- Bool nextIsChar;
- Byte curByte, matchByte;
- const Byte *data;
- COptimal *curOpt;
- COptimal *nextOpt;
-
- cur++;
- if (cur == lenEnd)
- return Backward(p, backRes, cur);
-
- newLen = ReadMatchDistances(p, &numPairs);
- if (newLen >= p->numFastBytes)
- {
- p->numPairs = numPairs;
- p->longestMatchLength = newLen;
- return Backward(p, backRes, cur);
- }
- position++;
- curOpt = &p->opt[cur];
- posPrev = curOpt->posPrev;
- if (curOpt->prev1IsChar)
- {
- posPrev--;
- if (curOpt->prev2)
- {
- state = p->opt[curOpt->posPrev2].state;
- if (curOpt->backPrev2 < LZMA_NUM_REPS)
- state = kRepNextStates[state];
- else
- state = kMatchNextStates[state];
- }
- else
- state = p->opt[posPrev].state;
- state = kLiteralNextStates[state];
- }
- else
- state = p->opt[posPrev].state;
- if (posPrev == cur - 1)
- {
- if (IsShortRep(curOpt))
- state = kShortRepNextStates[state];
- else
- state = kLiteralNextStates[state];
- }
- else
- {
- UInt32 pos;
- const COptimal *prevOpt;
- if (curOpt->prev1IsChar && curOpt->prev2)
- {
- posPrev = curOpt->posPrev2;
- pos = curOpt->backPrev2;
- state = kRepNextStates[state];
- }
- else
- {
- pos = curOpt->backPrev;
- if (pos < LZMA_NUM_REPS)
- state = kRepNextStates[state];
- else
- state = kMatchNextStates[state];
- }
- prevOpt = &p->opt[posPrev];
- if (pos < LZMA_NUM_REPS)
- {
- UInt32 i;
- reps[0] = prevOpt->backs[pos];
- for (i = 1; i <= pos; i++)
- reps[i] = prevOpt->backs[i - 1];
- for (; i < LZMA_NUM_REPS; i++)
- reps[i] = prevOpt->backs[i];
- }
- else
- {
- UInt32 i;
- reps[0] = (pos - LZMA_NUM_REPS);
- for (i = 1; i < LZMA_NUM_REPS; i++)
- reps[i] = prevOpt->backs[i - 1];
- }
- }
- curOpt->state = (CState)state;
-
- curOpt->backs[0] = reps[0];
- curOpt->backs[1] = reps[1];
- curOpt->backs[2] = reps[2];
- curOpt->backs[3] = reps[3];
-
- curPrice = curOpt->price;
- nextIsChar = False;
- data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
- curByte = *data;
- matchByte = *(data - (reps[0] + 1));
-
- posState = (position & p->pbMask);
-
- curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]);
- {
- const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
- curAnd1Price +=
- (!IsCharState(state) ?
- LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
- LitEnc_GetPrice(probs, curByte, p->ProbPrices));
- }
-
- nextOpt = &p->opt[cur + 1];
-
- if (curAnd1Price < nextOpt->price)
- {
- nextOpt->price = curAnd1Price;
- nextOpt->posPrev = cur;
- MakeAsChar(nextOpt);
- nextIsChar = True;
- }
-
- matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);
- repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
-
- if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))
- {
- UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);
- if (shortRepPrice <= nextOpt->price)
- {
- nextOpt->price = shortRepPrice;
- nextOpt->posPrev = cur;
- MakeAsShortRep(nextOpt);
- nextIsChar = True;
- }
- }
- numAvailFull = p->numAvail;
- {
- UInt32 temp = kNumOpts - 1 - cur;
- if (temp < numAvailFull)
- numAvailFull = temp;
- }
-
- if (numAvailFull < 2)
- continue;
- numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes);
-
- if (!nextIsChar && matchByte != curByte) /* speed optimization */
- {
- /* try Literal + rep0 */
- UInt32 temp;
- UInt32 lenTest2;
- const Byte *data2 = data - (reps[0] + 1);
- UInt32 limit = p->numFastBytes + 1;
- if (limit > numAvailFull)
- limit = numAvailFull;
-
- for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);
- lenTest2 = temp - 1;
- if (lenTest2 >= 2)
- {
- UInt32 state2 = kLiteralNextStates[state];
- UInt32 posStateNext = (position + 1) & p->pbMask;
- UInt32 nextRepMatchPrice = curAnd1Price +
- GET_PRICE_1(p->isMatch[state2][posStateNext]) +
- GET_PRICE_1(p->isRep[state2]);
- /* for (; lenTest2 >= 2; lenTest2--) */
- {
- UInt32 curAndLenPrice;
- COptimal *opt;
- UInt32 offset = cur + 1 + lenTest2;
- while (lenEnd < offset)
- p->opt[++lenEnd].price = kInfinityPrice;
- curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
- opt = &p->opt[offset];
- if (curAndLenPrice < opt->price)
- {
- opt->price = curAndLenPrice;
- opt->posPrev = cur + 1;
- opt->backPrev = 0;
- opt->prev1IsChar = True;
- opt->prev2 = False;
- }
- }
- }
- }
-
- startLen = 2; /* speed optimization */
- {
- UInt32 repIndex;
- for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++)
- {
- UInt32 lenTest;
- UInt32 lenTestTemp;
- UInt32 price;
- const Byte *data2 = data - (reps[repIndex] + 1);
- if (data[0] != data2[0] || data[1] != data2[1])
- continue;
- for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
- while (lenEnd < cur + lenTest)
- p->opt[++lenEnd].price = kInfinityPrice;
- lenTestTemp = lenTest;
- price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
- do
- {
- UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];
- COptimal *opt = &p->opt[cur + lenTest];
- if (curAndLenPrice < opt->price)
- {
- opt->price = curAndLenPrice;
- opt->posPrev = cur;
- opt->backPrev = repIndex;
- opt->prev1IsChar = False;
- }
- }
- while (--lenTest >= 2);
- lenTest = lenTestTemp;
-
- if (repIndex == 0)
- startLen = lenTest + 1;
-
- /* if (_maxMode) */
- {
- UInt32 lenTest2 = lenTest + 1;
- UInt32 limit = lenTest2 + p->numFastBytes;
- UInt32 nextRepMatchPrice;
- if (limit > numAvailFull)
- limit = numAvailFull;
- for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
- lenTest2 -= lenTest + 1;
- if (lenTest2 >= 2)
- {
- UInt32 state2 = kRepNextStates[state];
- UInt32 posStateNext = (position + lenTest) & p->pbMask;
- UInt32 curAndLenCharPrice =
- price + p->repLenEnc.prices[posState][lenTest - 2] +
- GET_PRICE_0(p->isMatch[state2][posStateNext]) +
- LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
- data[lenTest], data2[lenTest], p->ProbPrices);
- state2 = kLiteralNextStates[state2];
- posStateNext = (position + lenTest + 1) & p->pbMask;
- nextRepMatchPrice = curAndLenCharPrice +
- GET_PRICE_1(p->isMatch[state2][posStateNext]) +
- GET_PRICE_1(p->isRep[state2]);
-
- /* for (; lenTest2 >= 2; lenTest2--) */
- {
- UInt32 curAndLenPrice;
- COptimal *opt;
- UInt32 offset = cur + lenTest + 1 + lenTest2;
- while (lenEnd < offset)
- p->opt[++lenEnd].price = kInfinityPrice;
- curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
- opt = &p->opt[offset];
- if (curAndLenPrice < opt->price)
- {
- opt->price = curAndLenPrice;
- opt->posPrev = cur + lenTest + 1;
- opt->backPrev = 0;
- opt->prev1IsChar = True;
- opt->prev2 = True;
- opt->posPrev2 = cur;
- opt->backPrev2 = repIndex;
- }
- }
- }
- }
- }
- }
- /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */
- if (newLen > numAvail)
- {
- newLen = numAvail;
- for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2);
- matches[numPairs] = newLen;
- numPairs += 2;
- }
- if (newLen >= startLen)
- {
- UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);
- UInt32 offs, curBack, posSlot;
- UInt32 lenTest;
- while (lenEnd < cur + newLen)
- p->opt[++lenEnd].price = kInfinityPrice;
-
- offs = 0;
- while (startLen > matches[offs])
- offs += 2;
- curBack = matches[offs + 1];
- GetPosSlot2(curBack, posSlot);
- for (lenTest = /*2*/ startLen; ; lenTest++)
- {
- UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
- UInt32 lenToPosState = GetLenToPosState(lenTest);
- COptimal *opt;
- if (curBack < kNumFullDistances)
- curAndLenPrice += p->distancesPrices[lenToPosState][curBack];
- else
- curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];
-
- opt = &p->opt[cur + lenTest];
- if (curAndLenPrice < opt->price)
- {
- opt->price = curAndLenPrice;
- opt->posPrev = cur;
- opt->backPrev = curBack + LZMA_NUM_REPS;
- opt->prev1IsChar = False;
- }
-
- if (/*_maxMode && */lenTest == matches[offs])
- {
- /* Try Match + Literal + Rep0 */
- const Byte *data2 = data - (curBack + 1);
- UInt32 lenTest2 = lenTest + 1;
- UInt32 limit = lenTest2 + p->numFastBytes;
- UInt32 nextRepMatchPrice;
- if (limit > numAvailFull)
- limit = numAvailFull;
- for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
- lenTest2 -= lenTest + 1;
- if (lenTest2 >= 2)
- {
- UInt32 state2 = kMatchNextStates[state];
- UInt32 posStateNext = (position + lenTest) & p->pbMask;
- UInt32 curAndLenCharPrice = curAndLenPrice +
- GET_PRICE_0(p->isMatch[state2][posStateNext]) +
- LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
- data[lenTest], data2[lenTest], p->ProbPrices);
- state2 = kLiteralNextStates[state2];
- posStateNext = (posStateNext + 1) & p->pbMask;
- nextRepMatchPrice = curAndLenCharPrice +
- GET_PRICE_1(p->isMatch[state2][posStateNext]) +
- GET_PRICE_1(p->isRep[state2]);
-
- /* for (; lenTest2 >= 2; lenTest2--) */
- {
- UInt32 offset = cur + lenTest + 1 + lenTest2;
- UInt32 curAndLenPrice;
- COptimal *opt;
- while (lenEnd < offset)
- p->opt[++lenEnd].price = kInfinityPrice;
- curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
- opt = &p->opt[offset];
- if (curAndLenPrice < opt->price)
- {
- opt->price = curAndLenPrice;
- opt->posPrev = cur + lenTest + 1;
- opt->backPrev = 0;
- opt->prev1IsChar = True;
- opt->prev2 = True;
- opt->posPrev2 = cur;
- opt->backPrev2 = curBack + LZMA_NUM_REPS;
- }
- }
- }
- offs += 2;
- if (offs == numPairs)
- break;
- curBack = matches[offs + 1];
- if (curBack >= kNumFullDistances)
- GetPosSlot2(curBack, posSlot);
- }
- }
- }
- }
-}
-
-#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
-
-static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
-{
- UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i;
- const Byte *data;
- const UInt32 *matches;
-
- if (p->additionalOffset == 0)
- mainLen = ReadMatchDistances(p, &numPairs);
- else
- {
- mainLen = p->longestMatchLength;
- numPairs = p->numPairs;
- }
-
- numAvail = p->numAvail;
- *backRes = (UInt32)-1;
- if (numAvail < 2)
- return 1;
- if (numAvail > LZMA_MATCH_LEN_MAX)
- numAvail = LZMA_MATCH_LEN_MAX;
- data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-
- repLen = repIndex = 0;
- for (i = 0; i < LZMA_NUM_REPS; i++)
- {
- UInt32 len;
- const Byte *data2 = data - (p->reps[i] + 1);
- if (data[0] != data2[0] || data[1] != data2[1])
- continue;
- for (len = 2; len < numAvail && data[len] == data2[len]; len++);
- if (len >= p->numFastBytes)
- {
- *backRes = i;
- MovePos(p, len - 1);
- return len;
- }
- if (len > repLen)
- {
- repIndex = i;
- repLen = len;
- }
- }
-
- matches = p->matches;
- if (mainLen >= p->numFastBytes)
- {
- *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
- MovePos(p, mainLen - 1);
- return mainLen;
- }
-
- mainDist = 0; /* for GCC */
- if (mainLen >= 2)
- {
- mainDist = matches[numPairs - 1];
- while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1)
- {
- if (!ChangePair(matches[numPairs - 3], mainDist))
- break;
- numPairs -= 2;
- mainLen = matches[numPairs - 2];
- mainDist = matches[numPairs - 1];
- }
- if (mainLen == 2 && mainDist >= 0x80)
- mainLen = 1;
- }
-
- if (repLen >= 2 && (
- (repLen + 1 >= mainLen) ||
- (repLen + 2 >= mainLen && mainDist >= (1 << 9)) ||
- (repLen + 3 >= mainLen && mainDist >= (1 << 15))))
- {
- *backRes = repIndex;
- MovePos(p, repLen - 1);
- return repLen;
- }
-
- if (mainLen < 2 || numAvail <= 2)
- return 1;
-
- p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);
- if (p->longestMatchLength >= 2)
- {
- UInt32 newDistance = matches[p->numPairs - 1];
- if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||
- (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||
- (p->longestMatchLength > mainLen + 1) ||
- (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist)))
- return 1;
- }
-
- data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
- for (i = 0; i < LZMA_NUM_REPS; i++)
- {
- UInt32 len, limit;
- const Byte *data2 = data - (p->reps[i] + 1);
- if (data[0] != data2[0] || data[1] != data2[1])
- continue;
- limit = mainLen - 1;
- for (len = 2; len < limit && data[len] == data2[len]; len++);
- if (len >= limit)
- return 1;
- }
- *backRes = mainDist + LZMA_NUM_REPS;
- MovePos(p, mainLen - 2);
- return mainLen;
-}
-
-static void WriteEndMarker(CLzmaEnc *p, UInt32 posState)
-{
- UInt32 len;
- RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
- RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
- p->state = kMatchNextStates[p->state];
- len = LZMA_MATCH_LEN_MIN;
- LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
- RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1);
- RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits);
- RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
-}
-
-static SRes CheckErrors(CLzmaEnc *p)
-{
- if (p->result != SZ_OK)
- return p->result;
- if (p->rc.res != SZ_OK)
- p->result = SZ_ERROR_WRITE;
- if (p->matchFinderBase.result != SZ_OK)
- p->result = SZ_ERROR_READ;
- if (p->result != SZ_OK)
- p->finished = True;
- return p->result;
-}
-
-static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
-{
- /* ReleaseMFStream(); */
- p->finished = True;
- if (p->writeEndMark)
- WriteEndMarker(p, nowPos & p->pbMask);
- RangeEnc_FlushData(&p->rc);
- RangeEnc_FlushStream(&p->rc);
- return CheckErrors(p);
-}
-
-static void FillAlignPrices(CLzmaEnc *p)
-{
- UInt32 i;
- for (i = 0; i < kAlignTableSize; i++)
- p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
- p->alignPriceCount = 0;
-}
-
-static void FillDistancesPrices(CLzmaEnc *p)
-{
- UInt32 tempPrices[kNumFullDistances];
- UInt32 i, lenToPosState;
- for (i = kStartPosModelIndex; i < kNumFullDistances; i++)
- {
- UInt32 posSlot = GetPosSlot1(i);
- UInt32 footerBits = ((posSlot >> 1) - 1);
- UInt32 base = ((2 | (posSlot & 1)) << footerBits);
- tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices);
- }
-
- for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
- {
- UInt32 posSlot;
- const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState];
- UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState];
- for (posSlot = 0; posSlot < p->distTableSize; posSlot++)
- posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);
- for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++)
- posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
-
- {
- UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
- UInt32 i;
- for (i = 0; i < kStartPosModelIndex; i++)
- distancesPrices[i] = posSlotPrices[i];
- for (; i < kNumFullDistances; i++)
- distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i];
- }
- }
- p->matchPriceCount = 0;
-}
-
-void LzmaEnc_Construct(CLzmaEnc *p)
-{
- RangeEnc_Construct(&p->rc);
- MatchFinder_Construct(&p->matchFinderBase);
- #ifndef _7ZIP_ST
- MatchFinderMt_Construct(&p->matchFinderMt);
- p->matchFinderMt.MatchFinder = &p->matchFinderBase;
- #endif
-
- {
- CLzmaEncProps props;
- LzmaEncProps_Init(&props);
- LzmaEnc_SetProps(p, &props);
- }
-
- #ifndef LZMA_LOG_BSR
- LzmaEnc_FastPosInit(p->g_FastPos);
- #endif
-
- LzmaEnc_InitPriceTables(p->ProbPrices);
- p->litProbs = 0;
- p->saveState.litProbs = 0;
-}
-
-CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
-{
- void *p;
- p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
- if (p != 0)
- LzmaEnc_Construct((CLzmaEnc *)p);
- return p;
-}
-
-void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
-{
- alloc->Free(alloc, p->litProbs);
- alloc->Free(alloc, p->saveState.litProbs);
- p->litProbs = 0;
- p->saveState.litProbs = 0;
-}
-
-void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
-{
- #ifndef _7ZIP_ST
- MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
- #endif
- MatchFinder_Free(&p->matchFinderBase, allocBig);
- LzmaEnc_FreeLits(p, alloc);
- RangeEnc_Free(&p->rc, alloc);
-}
-
-void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
-{
- LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
- alloc->Free(alloc, p);
-}
-
-static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
-{
- UInt32 nowPos32, startPos32;
- if (p->needInit)
- {
- p->matchFinder.Init(p->matchFinderObj);
- p->needInit = 0;
- }
-
- if (p->finished)
- return p->result;
- RINOK(CheckErrors(p));
-
- nowPos32 = (UInt32)p->nowPos64;
- startPos32 = nowPos32;
-
- if (p->nowPos64 == 0)
- {
- UInt32 numPairs;
- Byte curByte;
- if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
- return Flush(p, nowPos32);
- ReadMatchDistances(p, &numPairs);
- RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
- p->state = kLiteralNextStates[p->state];
- curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset);
- LitEnc_Encode(&p->rc, p->litProbs, curByte);
- p->additionalOffset--;
- nowPos32++;
- }
-
- if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)
- for (;;)
- {
- UInt32 pos, len, posState;
-
- if (p->fastMode)
- len = GetOptimumFast(p, &pos);
- else
- len = GetOptimum(p, nowPos32, &pos);
-
- #ifdef SHOW_STAT2
- printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos);
- #endif
-
- posState = nowPos32 & p->pbMask;
- if (len == 1 && pos == (UInt32)-1)
- {
- Byte curByte;
- CLzmaProb *probs;
- const Byte *data;
-
- RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0);
- data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
- curByte = *data;
- probs = LIT_PROBS(nowPos32, *(data - 1));
- if (IsCharState(p->state))
- LitEnc_Encode(&p->rc, probs, curByte);
- else
- LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1));
- p->state = kLiteralNextStates[p->state];
- }
- else
- {
- RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
- if (pos < LZMA_NUM_REPS)
- {
- RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1);
- if (pos == 0)
- {
- RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0);
- RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1));
- }
- else
- {
- UInt32 distance = p->reps[pos];
- RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1);
- if (pos == 1)
- RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0);
- else
- {
- RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1);
- RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2);
- if (pos == 3)
- p->reps[3] = p->reps[2];
- p->reps[2] = p->reps[1];
- }
- p->reps[1] = p->reps[0];
- p->reps[0] = distance;
- }
- if (len == 1)
- p->state = kShortRepNextStates[p->state];
- else
- {
- LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
- p->state = kRepNextStates[p->state];
- }
- }
- else
- {
- UInt32 posSlot;
- RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
- p->state = kMatchNextStates[p->state];
- LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
- pos -= LZMA_NUM_REPS;
- GetPosSlot(pos, posSlot);
- RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
-
- if (posSlot >= kStartPosModelIndex)
- {
- UInt32 footerBits = ((posSlot >> 1) - 1);
- UInt32 base = ((2 | (posSlot & 1)) << footerBits);
- UInt32 posReduced = pos - base;
-
- if (posSlot < kEndPosModelIndex)
- RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced);
- else
- {
- RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
- RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
- p->alignPriceCount++;
- }
- }
- p->reps[3] = p->reps[2];
- p->reps[2] = p->reps[1];
- p->reps[1] = p->reps[0];
- p->reps[0] = pos;
- p->matchPriceCount++;
- }
- }
- p->additionalOffset -= len;
- nowPos32 += len;
- if (p->additionalOffset == 0)
- {
- UInt32 processed;
- if (!p->fastMode)
- {
- if (p->matchPriceCount >= (1 << 7))
- FillDistancesPrices(p);
- if (p->alignPriceCount >= kAlignTableSize)
- FillAlignPrices(p);
- }
- if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
- break;
- processed = nowPos32 - startPos32;
- if (useLimits)
- {
- if (processed + kNumOpts + 300 >= maxUnpackSize ||
- RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
- break;
- }
- else if (processed >= (1 << 15))
- {
- p->nowPos64 += nowPos32 - startPos32;
- return CheckErrors(p);
- }
- }
- }
- p->nowPos64 += nowPos32 - startPos32;
- return Flush(p, nowPos32);
-}
-
-#define kBigHashDicLimit ((UInt32)1 << 24)
-
-static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
-{
- UInt32 beforeSize = kNumOpts;
- Bool btMode;
- if (!RangeEnc_Alloc(&p->rc, alloc))
- return SZ_ERROR_MEM;
- btMode = (p->matchFinderBase.btMode != 0);
- #ifndef _7ZIP_ST
- p->mtMode = (p->multiThread && !p->fastMode && btMode);
- #endif
-
- {
- unsigned lclp = p->lc + p->lp;
- if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
- {
- LzmaEnc_FreeLits(p, alloc);
- p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
- p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
- if (p->litProbs == 0 || p->saveState.litProbs == 0)
- {
- LzmaEnc_FreeLits(p, alloc);
- return SZ_ERROR_MEM;
- }
- p->lclp = lclp;
- }
- }
-
- p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);
-
- if (beforeSize + p->dictSize < keepWindowSize)
- beforeSize = keepWindowSize - p->dictSize;
-
- #ifndef _7ZIP_ST
- if (p->mtMode)
- {
- RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
- p->matchFinderObj = &p->matchFinderMt;
- MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
- }
- else
- #endif
- {
- if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig))
- return SZ_ERROR_MEM;
- p->matchFinderObj = &p->matchFinderBase;
- MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
- }
- return SZ_OK;
-}
-
-void LzmaEnc_Init(CLzmaEnc *p)
-{
- UInt32 i;
- p->state = 0;
- for (i = 0 ; i < LZMA_NUM_REPS; i++)
- p->reps[i] = 0;
-
- RangeEnc_Init(&p->rc);
-
-
- for (i = 0; i < kNumStates; i++)
- {
- UInt32 j;
- for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
- {
- p->isMatch[i][j] = kProbInitValue;
- p->isRep0Long[i][j] = kProbInitValue;
- }
- p->isRep[i] = kProbInitValue;
- p->isRepG0[i] = kProbInitValue;
- p->isRepG1[i] = kProbInitValue;
- p->isRepG2[i] = kProbInitValue;
- }
-
- {
- UInt32 num = 0x300 << (p->lp + p->lc);
- for (i = 0; i < num; i++)
- p->litProbs[i] = kProbInitValue;
- }
-
- {
- for (i = 0; i < kNumLenToPosStates; i++)
- {
- CLzmaProb *probs = p->posSlotEncoder[i];
- UInt32 j;
- for (j = 0; j < (1 << kNumPosSlotBits); j++)
- probs[j] = kProbInitValue;
- }
- }
- {
- for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
- p->posEncoders[i] = kProbInitValue;
- }
-
- LenEnc_Init(&p->lenEnc.p);
- LenEnc_Init(&p->repLenEnc.p);
-
- for (i = 0; i < (1 << kNumAlignBits); i++)
- p->posAlignEncoder[i] = kProbInitValue;
-
- p->optimumEndIndex = 0;
- p->optimumCurrentIndex = 0;
- p->additionalOffset = 0;
-
- p->pbMask = (1 << p->pb) - 1;
- p->lpMask = (1 << p->lp) - 1;
-}
-
-void LzmaEnc_InitPrices(CLzmaEnc *p)
-{
- if (!p->fastMode)
- {
- FillDistancesPrices(p);
- FillAlignPrices(p);
- }
-
- p->lenEnc.tableSize =
- p->repLenEnc.tableSize =
- p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
- LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices);
- LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
-}
-
-static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
-{
- UInt32 i;
- for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
- if (p->dictSize <= ((UInt32)1 << i))
- break;
- p->distTableSize = i * 2;
-
- p->finished = False;
- p->result = SZ_OK;
- RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig));
- LzmaEnc_Init(p);
- LzmaEnc_InitPrices(p);
- p->nowPos64 = 0;
- return SZ_OK;
-}
-
-static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream,
- ISzAlloc *alloc, ISzAlloc *allocBig)
-{
- CLzmaEnc *p = (CLzmaEnc *)pp;
- p->matchFinderBase.stream = inStream;
- p->needInit = 1;
- p->rc.outStream = outStream;
- return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
-}
-
-SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
- ISeqInStream *inStream, UInt32 keepWindowSize,
- ISzAlloc *alloc, ISzAlloc *allocBig)
-{
- CLzmaEnc *p = (CLzmaEnc *)pp;
- p->matchFinderBase.stream = inStream;
- p->needInit = 1;
- return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
-}
-
-static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
-{
- p->matchFinderBase.directInput = 1;
- p->matchFinderBase.bufferBase = (Byte *)src;
- p->matchFinderBase.directInputRem = srcLen;
-}
-
-SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
- UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
-{
- CLzmaEnc *p = (CLzmaEnc *)pp;
- LzmaEnc_SetInputBuf(p, src, srcLen);
- p->needInit = 1;
-
- return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
-}
-
-void LzmaEnc_Finish(CLzmaEncHandle pp)
-{
- #ifndef _7ZIP_ST
- CLzmaEnc *p = (CLzmaEnc *)pp;
- if (p->mtMode)
- MatchFinderMt_ReleaseStream(&p->matchFinderMt);
- #else
- pp = pp;
- #endif
-}
-
-typedef struct
-{
- ISeqOutStream funcTable;
- Byte *data;
- SizeT rem;
- Bool overflow;
-} CSeqOutStreamBuf;
-
-static size_t MyWrite(void *pp, const void *data, size_t size)
-{
- CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;
- if (p->rem < size)
- {
- size = p->rem;
- p->overflow = True;
- }
- memcpy(p->data, data, size);
- p->rem -= size;
- p->data += size;
- return size;
-}
-
-
-UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
-{
- const CLzmaEnc *p = (CLzmaEnc *)pp;
- return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
-}
-
-const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
-{
- const CLzmaEnc *p = (CLzmaEnc *)pp;
- return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
-}
-
-SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
- Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
-{
- CLzmaEnc *p = (CLzmaEnc *)pp;
- UInt64 nowPos64;
- SRes res;
- CSeqOutStreamBuf outStream;
-
- outStream.funcTable.Write = MyWrite;
- outStream.data = dest;
- outStream.rem = *destLen;
- outStream.overflow = False;
-
- p->writeEndMark = False;
- p->finished = False;
- p->result = SZ_OK;
-
- if (reInit)
- LzmaEnc_Init(p);
- LzmaEnc_InitPrices(p);
- nowPos64 = p->nowPos64;
- RangeEnc_Init(&p->rc);
- p->rc.outStream = &outStream.funcTable;
-
- res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);
-
- *unpackSize = (UInt32)(p->nowPos64 - nowPos64);
- *destLen -= outStream.rem;
- if (outStream.overflow)
- return SZ_ERROR_OUTPUT_EOF;
-
- return res;
-}
-
-static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
-{
- SRes res = SZ_OK;
-
- #ifndef _7ZIP_ST
- Byte allocaDummy[0x300];
- int i = 0;
- for (i = 0; i < 16; i++)
- allocaDummy[i] = (Byte)i;
- #endif
-
- for (;;)
- {
- res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
- if (res != SZ_OK || p->finished != 0)
- break;
- if (progress != 0)
- {
- res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
- if (res != SZ_OK)
- {
- res = SZ_ERROR_PROGRESS;
- break;
- }
- }
- }
- LzmaEnc_Finish(p);
- return res;
-}
-
-SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
- ISzAlloc *alloc, ISzAlloc *allocBig)
-{
- RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig));
- return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
-}
-
-SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
-{
- CLzmaEnc *p = (CLzmaEnc *)pp;
- int i;
- UInt32 dictSize = p->dictSize;
- if (*size < LZMA_PROPS_SIZE)
- return SZ_ERROR_PARAM;
- *size = LZMA_PROPS_SIZE;
- props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
-
- for (i = 11; i <= 30; i++)
- {
- if (dictSize <= ((UInt32)2 << i))
- {
- dictSize = (2 << i);
- break;
- }
- if (dictSize <= ((UInt32)3 << i))
- {
- dictSize = (3 << i);
- break;
- }
- }
-
- for (i = 0; i < 4; i++)
- props[1 + i] = (Byte)(dictSize >> (8 * i));
- return SZ_OK;
-}
-
-SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
- int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
-{
- SRes res;
- CLzmaEnc *p = (CLzmaEnc *)pp;
-
- CSeqOutStreamBuf outStream;
-
- LzmaEnc_SetInputBuf(p, src, srcLen);
-
- outStream.funcTable.Write = MyWrite;
- outStream.data = dest;
- outStream.rem = *destLen;
- outStream.overflow = False;
-
- p->writeEndMark = writeEndMark;
-
- p->rc.outStream = &outStream.funcTable;
- res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
- if (res == SZ_OK)
- res = LzmaEnc_Encode2(p, progress);
-
- *destLen -= outStream.rem;
- if (outStream.overflow)
- return SZ_ERROR_OUTPUT_EOF;
- return res;
-}
-
-SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
- const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
-{
- CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
- SRes res;
- if (p == 0)
- return SZ_ERROR_MEM;
-
- res = LzmaEnc_SetProps(p, props);
- if (res == SZ_OK)
- {
- res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize);
- if (res == SZ_OK)
- res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen,
- writeEndMark, progress, alloc, allocBig);
- }
-
- LzmaEnc_Destroy(p, alloc, allocBig);
- return res;
-}
diff --git a/dep/StormLib/src/lzma/C/LzmaEnc.h b/dep/StormLib/src/lzma/C/LzmaEnc.h
deleted file mode 100644
index 200d60eb83c..00000000000
--- a/dep/StormLib/src/lzma/C/LzmaEnc.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* LzmaEnc.h -- LZMA Encoder
-2009-02-07 : Igor Pavlov : Public domain */
-
-#ifndef __LZMA_ENC_H
-#define __LZMA_ENC_H
-
-#include "Types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define LZMA_PROPS_SIZE 5
-
-typedef struct _CLzmaEncProps
-{
- int level; /* 0 <= level <= 9 */
- UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
- (1 << 12) <= dictSize <= (1 << 30) for 64-bit version
- default = (1 << 24) */
- int lc; /* 0 <= lc <= 8, default = 3 */
- int lp; /* 0 <= lp <= 4, default = 0 */
- int pb; /* 0 <= pb <= 4, default = 2 */
- int algo; /* 0 - fast, 1 - normal, default = 1 */
- int fb; /* 5 <= fb <= 273, default = 32 */
- int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
- int numHashBytes; /* 2, 3 or 4, default = 4 */
- UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
- unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
- int numThreads; /* 1 or 2, default = 2 */
-} CLzmaEncProps;
-
-void LzmaEncProps_Init(CLzmaEncProps *p);
-void LzmaEncProps_Normalize(CLzmaEncProps *p);
-UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
-
-
-/* ---------- CLzmaEncHandle Interface ---------- */
-
-/* LzmaEnc_* functions can return the following exit codes:
-Returns:
- SZ_OK - OK
- SZ_ERROR_MEM - Memory allocation error
- SZ_ERROR_PARAM - Incorrect paramater in props
- SZ_ERROR_WRITE - Write callback error.
- SZ_ERROR_PROGRESS - some break from progress callback
- SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
-*/
-
-typedef void * CLzmaEncHandle;
-
-CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
-void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
-SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
-SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
-SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
-SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
- int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
-
-/* ---------- One Call Interface ---------- */
-
-/* LzmaEncode
-Return code:
- SZ_OK - OK
- SZ_ERROR_MEM - Memory allocation error
- SZ_ERROR_PARAM - Incorrect paramater
- SZ_ERROR_OUTPUT_EOF - output buffer overflow
- SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
-*/
-
-SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
- const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/dep/StormLib/src/lzma/C/Threads.c b/dep/StormLib/src/lzma/C/Threads.c
deleted file mode 100644
index 7af1da2e26e..00000000000
--- a/dep/StormLib/src/lzma/C/Threads.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/* Threads.c -- multithreading library
-2009-09-20 : Igor Pavlov : Public domain */
-
-#ifndef _WIN32_WCE
-#include <process.h>
-#endif
-
-#include "Threads.h"
-
-static WRes GetError()
-{
- DWORD res = GetLastError();
- return (res) ? (WRes)(res) : 1;
-}
-
-WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); }
-WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }
-
-WRes HandlePtr_Close(HANDLE *p)
-{
- if (*p != NULL)
- if (!CloseHandle(*p))
- return GetError();
- *p = NULL;
- return 0;
-}
-
-WRes Handle_WaitObject(HANDLE h) { return (WRes)WaitForSingleObject(h, INFINITE); }
-
-WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
-{
- unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
- *p =
- #ifdef UNDER_CE
- CreateThread(0, 0, func, param, 0, &threadId);
- #else
- (HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId);
- #endif
- /* maybe we must use errno here, but probably GetLastError() is also OK. */
- return HandleToWRes(*p);
-}
-
-WRes Event_Create(CEvent *p, BOOL manualReset, int signaled)
-{
- *p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL);
- return HandleToWRes(*p);
-}
-
-WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(*p)); }
-WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(*p)); }
-
-WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled) { return Event_Create(p, TRUE, signaled); }
-WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled) { return Event_Create(p, FALSE, signaled); }
-WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) { return ManualResetEvent_Create(p, 0); }
-WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) { return AutoResetEvent_Create(p, 0); }
-
-
-WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount)
-{
- *p = CreateSemaphore(NULL, (LONG)initCount, (LONG)maxCount, NULL);
- return HandleToWRes(*p);
-}
-
-static WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount)
- { return BOOLToWRes(ReleaseSemaphore(*p, releaseCount, previousCount)); }
-WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num)
- { return Semaphore_Release(p, (LONG)num, NULL); }
-WRes Semaphore_Release1(CSemaphore *p) { return Semaphore_ReleaseN(p, 1); }
-
-WRes CriticalSection_Init(CCriticalSection *p)
-{
- /* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */
- #ifdef _MSC_VER
- __try
- #endif
- {
- InitializeCriticalSection(p);
- /* InitializeCriticalSectionAndSpinCount(p, 0); */
- }
- #ifdef _MSC_VER
- __except (EXCEPTION_EXECUTE_HANDLER) { return 1; }
- #endif
- return 0;
-}
diff --git a/dep/StormLib/src/lzma/C/Threads.h b/dep/StormLib/src/lzma/C/Threads.h
deleted file mode 100644
index d0ddd80e227..00000000000
--- a/dep/StormLib/src/lzma/C/Threads.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Threads.h -- multithreading library
-2009-03-27 : Igor Pavlov : Public domain */
-
-#ifndef __7Z_THREADS_H
-#define __7Z_THREADS_H
-
-#include "Types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-WRes HandlePtr_Close(HANDLE *h);
-WRes Handle_WaitObject(HANDLE h);
-
-typedef HANDLE CThread;
-#define Thread_Construct(p) *(p) = NULL
-#define Thread_WasCreated(p) (*(p) != NULL)
-#define Thread_Close(p) HandlePtr_Close(p)
-#define Thread_Wait(p) Handle_WaitObject(*(p))
-typedef unsigned THREAD_FUNC_RET_TYPE;
-#define THREAD_FUNC_CALL_TYPE MY_STD_CALL
-#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
-typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *);
-WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param);
-
-typedef HANDLE CEvent;
-typedef CEvent CAutoResetEvent;
-typedef CEvent CManualResetEvent;
-#define Event_Construct(p) *(p) = NULL
-#define Event_IsCreated(p) (*(p) != NULL)
-#define Event_Close(p) HandlePtr_Close(p)
-#define Event_Wait(p) Handle_WaitObject(*(p))
-WRes Event_Set(CEvent *p);
-WRes Event_Reset(CEvent *p);
-WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled);
-WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p);
-WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled);
-WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p);
-
-typedef HANDLE CSemaphore;
-#define Semaphore_Construct(p) (*p) = NULL
-#define Semaphore_Close(p) HandlePtr_Close(p)
-#define Semaphore_Wait(p) Handle_WaitObject(*(p))
-WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);
-WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);
-WRes Semaphore_Release1(CSemaphore *p);
-
-typedef CRITICAL_SECTION CCriticalSection;
-WRes CriticalSection_Init(CCriticalSection *p);
-#define CriticalSection_Delete(p) DeleteCriticalSection(p)
-#define CriticalSection_Enter(p) EnterCriticalSection(p)
-#define CriticalSection_Leave(p) LeaveCriticalSection(p)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/dep/StormLib/src/lzma/C/Types.h b/dep/StormLib/src/lzma/C/Types.h
deleted file mode 100644
index 0526cb47b6e..00000000000
--- a/dep/StormLib/src/lzma/C/Types.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/* Types.h -- Basic types
-2010-03-11 : Igor Pavlov : Public domain */
-
-#ifndef __7Z_TYPES_H
-#define __7Z_TYPES_H
-
-#include <stddef.h>
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-#ifndef EXTERN_C_BEGIN
-#ifdef __cplusplus
-#define EXTERN_C_BEGIN extern "C" {
-#define EXTERN_C_END }
-#else
-#define EXTERN_C_BEGIN
-#define EXTERN_C_END
-#endif
-#endif
-
-EXTERN_C_BEGIN
-
-#define SZ_OK 0
-
-#define SZ_ERROR_DATA 1
-#define SZ_ERROR_MEM 2
-#define SZ_ERROR_CRC 3
-#define SZ_ERROR_UNSUPPORTED 4
-#define SZ_ERROR_PARAM 5
-#define SZ_ERROR_INPUT_EOF 6
-#define SZ_ERROR_OUTPUT_EOF 7
-#define SZ_ERROR_READ 8
-#define SZ_ERROR_WRITE 9
-#define SZ_ERROR_PROGRESS 10
-#define SZ_ERROR_FAIL 11
-#define SZ_ERROR_THREAD 12
-
-#define SZ_ERROR_ARCHIVE 16
-#define SZ_ERROR_NO_ARCHIVE 17
-
-typedef int SRes;
-
-#ifdef _WIN32
-typedef DWORD WRes;
-#else
-typedef int WRes;
-#endif
-
-#ifndef RINOK
-#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
-#endif
-
-typedef unsigned char Byte;
-typedef short Int16;
-typedef unsigned short UInt16;
-
-#ifdef _LZMA_UINT32_IS_ULONG
-typedef long Int32;
-typedef unsigned long UInt32;
-#else
-typedef int Int32;
-typedef unsigned int UInt32;
-#endif
-
-#ifdef _SZ_NO_INT_64
-
-/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
- NOTES: Some code will work incorrectly in that case! */
-
-typedef long Int64;
-typedef unsigned long UInt64;
-
-#else
-
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-typedef __int64 Int64;
-typedef unsigned __int64 UInt64;
-#else
-typedef long long int Int64;
-typedef unsigned long long int UInt64;
-#endif
-
-#endif
-
-#ifdef _LZMA_NO_SYSTEM_SIZE_T
-typedef UInt32 SizeT;
-#else
-typedef size_t SizeT;
-#endif
-
-typedef int Bool;
-#define True 1
-#define False 0
-
-
-#ifdef _WIN32
-#define MY_STD_CALL __stdcall
-#else
-#define MY_STD_CALL
-#endif
-
-#ifdef _MSC_VER
-
-#if _MSC_VER >= 1300
-#define MY_NO_INLINE __declspec(noinline)
-#else
-#define MY_NO_INLINE
-#endif
-
-#define MY_CDECL __cdecl
-#define MY_FAST_CALL __fastcall
-
-#else
-
-#define MY_CDECL
-#define MY_FAST_CALL
-
-#endif
-
-
-/* The following interfaces use first parameter as pointer to structure */
-
-typedef struct
-{
- Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
-} IByteIn;
-
-typedef struct
-{
- void (*Write)(void *p, Byte b);
-} IByteOut;
-
-typedef struct
-{
- SRes (*Read)(void *p, void *buf, size_t *size);
- /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
- (output(*size) < input(*size)) is allowed */
-} ISeqInStream;
-
-/* it can return SZ_ERROR_INPUT_EOF */
-SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
-SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
-SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
-
-typedef struct
-{
- size_t (*Write)(void *p, const void *buf, size_t size);
- /* Returns: result - the number of actually written bytes.
- (result < size) means error */
-} ISeqOutStream;
-
-typedef enum
-{
- SZ_SEEK_SET = 0,
- SZ_SEEK_CUR = 1,
- SZ_SEEK_END = 2
-} ESzSeek;
-
-typedef struct
-{
- SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
- SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
-} ISeekInStream;
-
-typedef struct
-{
- SRes (*Look)(void *p, const void **buf, size_t *size);
- /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
- (output(*size) > input(*size)) is not allowed
- (output(*size) < input(*size)) is allowed */
- SRes (*Skip)(void *p, size_t offset);
- /* offset must be <= output(*size) of Look */
-
- SRes (*Read)(void *p, void *buf, size_t *size);
- /* reads directly (without buffer). It's same as ISeqInStream::Read */
- SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
-} ILookInStream;
-
-SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
-SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
-
-/* reads via ILookInStream::Read */
-SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
-SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
-
-#define LookToRead_BUF_SIZE (1 << 14)
-
-typedef struct
-{
- ILookInStream s;
- ISeekInStream *realStream;
- size_t pos;
- size_t size;
- Byte buf[LookToRead_BUF_SIZE];
-} CLookToRead;
-
-void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
-void LookToRead_Init(CLookToRead *p);
-
-typedef struct
-{
- ISeqInStream s;
- ILookInStream *realStream;
-} CSecToLook;
-
-void SecToLook_CreateVTable(CSecToLook *p);
-
-typedef struct
-{
- ISeqInStream s;
- ILookInStream *realStream;
-} CSecToRead;
-
-void SecToRead_CreateVTable(CSecToRead *p);
-
-typedef struct
-{
- SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
- /* Returns: result. (result != SZ_OK) means break.
- Value (UInt64)(Int64)-1 for size means unknown value. */
-} ICompressProgress;
-
-typedef struct
-{
- void *(*Alloc)(void *p, size_t size);
- void (*Free)(void *p, void *address); /* address can be 0 */
-} ISzAlloc;
-
-#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
-#define IAlloc_Free(p, a) (p)->Free((p), a)
-
-EXTERN_C_END
-
-#endif
diff --git a/dep/StormLib/src/lzma/info.txt b/dep/StormLib/src/lzma/info.txt
deleted file mode 100644
index 4cee86e3542..00000000000
--- a/dep/StormLib/src/lzma/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Taken from LZMA SDK v 9.11 \ No newline at end of file
diff --git a/dep/StormLib/src/pklib/crc32.c b/dep/StormLib/src/pklib/crc32.c
deleted file mode 100644
index cd47b1d4a9b..00000000000
--- a/dep/StormLib/src/pklib/crc32.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*****************************************************************************/
-/* crc32.c Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Pkware Data Compression Library Version 1.11 */
-/* Dissassembled method crc32 - cdecl version */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 09.04.03 1.00 Lad The first version of crc32.c */
-/* 02.05.03 1.00 Lad Stress test done */
-/*****************************************************************************/
-
-#include "pklib.h"
-
-static unsigned long crc_table[] =
-{
- 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
- 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
- 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
- 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
- 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
- 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
- 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
- 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
- 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
- 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
- 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
- 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
- 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
- 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
- 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
- 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
- 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
- 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
- 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
- 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
- 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
- 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
- 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
- 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
- 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
- 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
- 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
- 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
- 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
- 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
- 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
- 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
-};
-
-
-unsigned long PKEXPORT crc32_pklib(char * buffer, unsigned int * psize, unsigned long * old_crc)
-{
- unsigned int size = *psize;
- unsigned long ch;
- unsigned long crc_value = *old_crc;
-
- while(size-- != 0)
- {
- ch = *buffer++ ^ (char)crc_value;
- crc_value >>= 8;
-
- crc_value = crc_table[ch & 0x0FF] ^ crc_value;
- }
- return crc_value;
-}
diff --git a/dep/StormLib/src/pklib/explode.c b/dep/StormLib/src/pklib/explode.c
deleted file mode 100644
index 0d327a5da84..00000000000
--- a/dep/StormLib/src/pklib/explode.c
+++ /dev/null
@@ -1,522 +0,0 @@
-/*****************************************************************************/
-/* explode.c Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Implode function of PKWARE Data Compression library */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 11.03.03 1.00 Lad Splitted from Pkware.cpp */
-/* 08.04.03 1.01 Lad Renamed to explode.c to be compatible with pklib */
-/* 02.05.03 1.01 Lad Stress test done */
-/* 22.04.10 1.01 Lad Documented */
-/*****************************************************************************/
-
-#include <assert.h>
-#include <string.h>
-
-#include "pklib.h"
-
-#define PKDCL_OK 0
-#define PKDCL_STREAM_END 1 // All data from the input stream is read
-#define PKDCL_NEED_DICT 2 // Need more data (dictionary)
-#define PKDCL_CONTINUE 10 // Internal flag, not returned to user
-#define PKDCL_GET_INPUT 11 // Internal flag, not returned to user
-
-char CopyrightPkware[] = "PKWARE Data Compression Library for Win32\r\n"
- "Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n"
- "Patent No. 5,051,745\r\n"
- "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n"
- "Version 1.11\r\n";
-
-//-----------------------------------------------------------------------------
-// Tables
-
-static unsigned char DistBits[] =
-{
- 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
-};
-
-static unsigned char DistCode[] =
-{
- 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A,
- 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C,
- 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08,
- 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00
-};
-
-static unsigned char ExLenBits[] =
-{
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
-};
-
-static unsigned short LenBase[] =
-{
- 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
- 0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106
-};
-
-static unsigned char LenBits[] =
-{
- 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07
-};
-
-static unsigned char LenCode[] =
-{
- 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00
-};
-
-static unsigned char ChBitsAsc[] =
-{
- 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08,
- 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B,
- 0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06,
- 0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08,
- 0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05,
- 0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D,
- 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D
-};
-
-static unsigned short ChCodeAsc[] =
-{
- 0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0,
- 0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0,
- 0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360,
- 0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60,
- 0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8,
- 0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098,
- 0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C,
- 0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710,
- 0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8,
- 0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E,
- 0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8,
- 0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088,
- 0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A,
- 0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D,
- 0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078,
- 0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0,
- 0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040,
- 0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380,
- 0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180,
- 0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280,
- 0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080,
- 0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300,
- 0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0,
- 0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320,
- 0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220,
- 0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0,
- 0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0,
- 0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340,
- 0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900,
- 0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600,
- 0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200,
- 0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000
-};
-
-//-----------------------------------------------------------------------------
-// Local functions
-
-static void GenDecodeTabs(
- unsigned char * positions, // [out] Table of positions
- unsigned char * start_indexes, // [in] Table of start indexes
- unsigned char * length_bits, // [in] Table of lengths. Each length is stored as number of bits
- size_t elements) // [in] Number of elements in start_indexes and length_bits
-{
- unsigned long index;
- unsigned long length;
- size_t i;
-
- for(i = 0; i < elements; i++)
- {
- length = 1 << length_bits[i]; // Get the length in bytes
-
- for(index = start_indexes[i]; index < 0x100; index += length)
- {
- positions[index] = (unsigned char)i;
- }
- }
-}
-
-static void GenAscTabs(TDcmpStruct * pWork)
-{
- unsigned short * pChCodeAsc = &ChCodeAsc[0xFF];
- unsigned long acc, add;
- unsigned short count;
-
- for(count = 0x00FF; pChCodeAsc >= ChCodeAsc; pChCodeAsc--, count--)
- {
- unsigned char * pChBitsAsc = pWork->ChBitsAsc + count;
- unsigned char bits_asc = *pChBitsAsc;
-
- if(bits_asc <= 8)
- {
- add = (1 << bits_asc);
- acc = *pChCodeAsc;
-
- do
- {
- pWork->offs2C34[acc] = (unsigned char)count;
- acc += add;
- }
- while(acc < 0x100);
- }
- else if((acc = (*pChCodeAsc & 0xFF)) != 0)
- {
- pWork->offs2C34[acc] = 0xFF;
-
- if(*pChCodeAsc & 0x3F)
- {
- bits_asc -= 4;
- *pChBitsAsc = bits_asc;
-
- add = (1 << bits_asc);
- acc = *pChCodeAsc >> 4;
- do
- {
- pWork->offs2D34[acc] = (unsigned char)count;
- acc += add;
- }
- while(acc < 0x100);
- }
- else
- {
- bits_asc -= 6;
- *pChBitsAsc = bits_asc;
-
- add = (1 << bits_asc);
- acc = *pChCodeAsc >> 6;
- do
- {
- pWork->offs2E34[acc] = (unsigned char)count;
- acc += add;
- }
- while(acc < 0x80);
- }
- }
- else
- {
- bits_asc -= 8;
- *pChBitsAsc = bits_asc;
-
- add = (1 << bits_asc);
- acc = *pChCodeAsc >> 8;
- do
- {
- pWork->offs2EB4[acc] = (unsigned char)count;
- acc += add;
- }
- while(acc < 0x100);
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Removes given number of bits in the bit buffer. New bits are reloaded from
-// the input buffer, if needed.
-// Returns: PKDCL_OK: Operation was successful
-// PKDCL_STREAM_END: There are no more bits in the input buffer
-
-static int WasteBits(TDcmpStruct * pWork, unsigned long nBits)
-{
- // If number of bits required is less than number of (bits in the buffer) ?
- if(nBits <= pWork->extra_bits)
- {
- pWork->extra_bits -= nBits;
- pWork->bit_buff >>= nBits;
- return PKDCL_OK;
- }
-
- // Load input buffer if necessary
- pWork->bit_buff >>= pWork->extra_bits;
- if(pWork->in_pos == pWork->in_bytes)
- {
- pWork->in_pos = sizeof(pWork->in_buff);
- if((pWork->in_bytes = pWork->read_buf((char *)pWork->in_buff, &pWork->in_pos, pWork->param)) == 0)
- return PKDCL_STREAM_END;
- pWork->in_pos = 0;
- }
-
- // Update bit buffer
- pWork->bit_buff |= (pWork->in_buff[pWork->in_pos++] << 8);
- pWork->bit_buff >>= (nBits - pWork->extra_bits);
- pWork->extra_bits = (pWork->extra_bits - nBits) + 8;
- return PKDCL_OK;
-}
-
-//-----------------------------------------------------------------------------
-// Decodes next literal from the input (compressed) data.
-// Returns : 0x000: One byte 0x00
-// 0x001: One byte 0x01
-// ...
-// 0x0FF: One byte 0xFF
-// 0x100: Repetition, length of 0x02 bytes
-// 0x101: Repetition, length of 0x03 bytes
-// ...
-// 0x304: Repetition, length of 0x206 bytes
-// 0x305: End of stream
-// 0x306: Error
-
-static unsigned long DecodeLit(TDcmpStruct * pWork)
-{
- unsigned long extra_length_bits; // Number of bits of extra literal length
- unsigned long length_code; // Length code
- unsigned long value;
-
- // Test the current bit in byte buffer. If is not set, simply return the next 8 bits.
- if(pWork->bit_buff & 1)
- {
- // Remove one bit from the input data
- if(WasteBits(pWork, 1))
- return 0x306;
-
- // The next 8 bits hold the index to the length code table
- length_code = pWork->LengthCodes[pWork->bit_buff & 0xFF];
-
- // Remove the apropriate number of bits
- if(WasteBits(pWork, pWork->LenBits[length_code]))
- return 0x306;
-
- // Are there some extra bits for the obtained length code ?
- if((extra_length_bits = pWork->ExLenBits[length_code]) != 0)
- {
- unsigned long extra_length = pWork->bit_buff & ((1 << extra_length_bits) - 1);
-
- if(WasteBits(pWork, extra_length_bits))
- {
- if((length_code + extra_length) != 0x10E)
- return 0x306;
- }
- length_code = pWork->LenBase[length_code] + extra_length;
- }
-
- // In order to distinguish uncompressed byte from repetition length,
- // we have to add 0x100 to the length.
- return length_code + 0x100;
- }
-
- // Remove one bit from the input data
- if(WasteBits(pWork, 1))
- return 0x306;
-
- // If the binary compression type, read 8 bits and return them as one byte.
- if(pWork->ctype == CMP_BINARY)
- {
- unsigned long uncompressed_byte = pWork->bit_buff & 0xFF;
-
- if(WasteBits(pWork, 8))
- return 0x306;
- return uncompressed_byte;
- }
-
- // When ASCII compression ...
- if(pWork->bit_buff & 0xFF)
- {
- value = pWork->offs2C34[pWork->bit_buff & 0xFF];
-
- if(value == 0xFF)
- {
- if(pWork->bit_buff & 0x3F)
- {
- if(WasteBits(pWork, 4))
- return 0x306;
-
- value = pWork->offs2D34[pWork->bit_buff & 0xFF];
- }
- else
- {
- if(WasteBits(pWork, 6))
- return 0x306;
-
- value = pWork->offs2E34[pWork->bit_buff & 0x7F];
- }
- }
- }
- else
- {
- if(WasteBits(pWork, 8))
- return 0x306;
-
- value = pWork->offs2EB4[pWork->bit_buff & 0xFF];
- }
-
- return WasteBits(pWork, pWork->ChBitsAsc[value]) ? 0x306 : value;
-}
-
-//-----------------------------------------------------------------------------
-// Decodes the distance of the repetition, backwards relative to the
-// current output buffer position
-
-static unsigned long DecodeDist(TDcmpStruct * pWork, unsigned long rep_length)
-{
- unsigned long dist_pos_code; // Distance position code
- unsigned long dist_pos_bits; // Number of bits of distance position
- unsigned long distance; // Distance position
-
- // Next 2-8 bits in the input buffer is the distance position code
- dist_pos_code = pWork->DistPosCodes[pWork->bit_buff & 0xFF];
- dist_pos_bits = pWork->DistBits[dist_pos_code];
- if(WasteBits(pWork, dist_pos_bits))
- return 0;
-
- if(rep_length == 2)
- {
- // If the repetition is only 2 bytes length,
- // then take 2 bits from the stream in order to get the distance
- distance = (dist_pos_code << 2) | (pWork->bit_buff & 0x03);
- if(WasteBits(pWork, 2))
- return 0;
- }
- else
- {
- // If the repetition is more than 2 bytes length,
- // then take "dsize_bits" bits in order to get the distance
- distance = (dist_pos_code << pWork->dsize_bits) | (pWork->bit_buff & pWork->dsize_mask);
- if(WasteBits(pWork, pWork->dsize_bits))
- return 0;
- }
- return distance + 1;
-}
-
-static unsigned long Expand(TDcmpStruct * pWork)
-{
- unsigned long next_literal; // Literal decoded from the compressed data
- unsigned long result; // Value to be returned
- unsigned int copyBytes; // Number of bytes to copy to the output buffer
-
- pWork->outputPos = 0x1000; // Initialize output buffer position
-
- // Decode the next literal from the input data.
- // The returned literal can either be an uncompressed byte (next_literal < 0x100)
- // or an encoded length of the repeating byte sequence that
- // is to be copied to the current buffer position
- while((result = next_literal = DecodeLit(pWork)) < 0x305)
- {
- // If the literal is greater than 0x100, it holds length
- // of repeating byte sequence
- // literal of 0x100 means repeating sequence of 0x2 bytes
- // literal of 0x101 means repeating sequence of 0x3 bytes
- // ...
- // literal of 0x305 means repeating sequence of 0x207 bytes
- if(next_literal >= 0x100)
- {
- unsigned char * source;
- unsigned char * target;
- unsigned long rep_length; // Length of the repetition, in bytes
- unsigned long minus_dist; // Backward distance to the repetition, relative to the current buffer position
-
- // Get the length of the repeating sequence.
- // Note that the repeating block may overlap the current output position,
- // for example if there was a sequence of equal bytes
- rep_length = next_literal - 0xFE;
-
- // Get backward distance to the repetition
- if((minus_dist = DecodeDist(pWork, rep_length)) == 0)
- {
- result = 0x306;
- break;
- }
-
- // Target and source pointer
- target = &pWork->out_buff[pWork->outputPos];
- source = target - minus_dist;
-
- // Update buffer output position
- pWork->outputPos += rep_length;
-
- // Copy the repeating sequence
- while(rep_length-- > 0)
- *target++ = *source++;
- }
- else
- {
- pWork->out_buff[pWork->outputPos++] = (unsigned char)next_literal;
- }
-
- // Flush the output buffer, if number of extracted bytes has reached the end
- if(pWork->outputPos >= 0x2000)
- {
- // Copy decompressed data into user buffer
- copyBytes = 0x1000;
- pWork->write_buf((char *)&pWork->out_buff[0x1000], &copyBytes, pWork->param);
-
- // Now copy the decompressed data to the first half of the buffer.
- // This is needed because the decompression might reuse them as repetitions.
- // Note that if the output buffer overflowed previously, the extra decompressed bytes
- // are stored in "out_buff_overflow", and they will now be
- // within decompressed part of the output buffer.
- memcpy(pWork->out_buff, &pWork->out_buff[0x1000], pWork->outputPos - 0x1000);
- pWork->outputPos -= 0x1000;
- }
- }
-
- // Flush any remaining decompressed bytes
- copyBytes = pWork->outputPos - 0x1000;
- pWork->write_buf((char *)&pWork->out_buff[0x1000], &copyBytes, pWork->param);
- return result;
-}
-
-
-//-----------------------------------------------------------------------------
-// Main exploding function.
-
-unsigned int explode(
- unsigned int (*read_buf)(char *buf, unsigned int *size, void *param),
- void (*write_buf)(char *buf, unsigned int *size, void *param),
- char *work_buf,
- void *param)
-{
- TDcmpStruct * pWork = (TDcmpStruct *)work_buf;
-
- // Initialize work struct and load compressed data
- // Note: The caller must zero the "work_buff" before passing it to explode
- pWork->read_buf = read_buf;
- pWork->write_buf = write_buf;
- pWork->param = param;
- pWork->in_pos = sizeof(pWork->in_buff);
- pWork->in_bytes = pWork->read_buf((char *)pWork->in_buff, &pWork->in_pos, pWork->param);
- if(pWork->in_bytes <= 4)
- return CMP_BAD_DATA;
-
- pWork->ctype = pWork->in_buff[0]; // Get the compression type (CMP_BINARY or CMP_ASCII)
- pWork->dsize_bits = pWork->in_buff[1]; // Get the dictionary size
- pWork->bit_buff = pWork->in_buff[2]; // Initialize 16-bit bit buffer
- pWork->extra_bits = 0; // Extra (over 8) bits
- pWork->in_pos = 3; // Position in input buffer
-
- // Test for the valid dictionary size
- if(4 > pWork->dsize_bits || pWork->dsize_bits > 6)
- return CMP_INVALID_DICTSIZE;
-
- pWork->dsize_mask = 0xFFFF >> (0x10 - pWork->dsize_bits); // Shifted by 'sar' instruction
-
- if(pWork->ctype != CMP_BINARY)
- {
- if(pWork->ctype != CMP_ASCII)
- return CMP_INVALID_MODE;
-
- memcpy(pWork->ChBitsAsc, ChBitsAsc, sizeof(pWork->ChBitsAsc));
- GenAscTabs(pWork);
- }
-
- memcpy(pWork->LenBits, LenBits, sizeof(pWork->LenBits));
- GenDecodeTabs(pWork->LengthCodes, LenCode, pWork->LenBits, sizeof(pWork->LenBits));
- memcpy(pWork->ExLenBits, ExLenBits, sizeof(pWork->ExLenBits));
- memcpy(pWork->LenBase, LenBase, sizeof(pWork->LenBase));
- memcpy(pWork->DistBits, DistBits, sizeof(pWork->DistBits));
- GenDecodeTabs(pWork->DistPosCodes, DistCode, pWork->DistBits, sizeof(pWork->DistBits));
- if(Expand(pWork) != 0x306)
- return CMP_NO_ERROR;
-
- return CMP_ABORT;
-}
diff --git a/dep/StormLib/src/pklib/implode.c b/dep/StormLib/src/pklib/implode.c
deleted file mode 100644
index 1771b1862a0..00000000000
--- a/dep/StormLib/src/pklib/implode.c
+++ /dev/null
@@ -1,769 +0,0 @@
-/*****************************************************************************/
-/* implode.c Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Implode function of PKWARE Data Compression library */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 11.04.03 1.00 Lad First version of implode.c */
-/* 02.05.03 1.00 Lad Stress test done */
-/* 22.04.10 1.01 Lad Documented */
-/*****************************************************************************/
-
-#include <assert.h>
-#include <string.h>
-
-#include "pklib.h"
-
-#if ((1200 < _MSC_VER) && (_MSC_VER < 1400))
-#pragma optimize("", off) // Fucking Microsoft VS.NET 2003 compiler !!! (_MSC_VER=1310)
-#endif
-
-//-----------------------------------------------------------------------------
-// Defines
-
-#define MAX_REP_LENGTH 0x204 // The longest allowed repetition
-
-//-----------------------------------------------------------------------------
-// Tables
-
-static unsigned char DistBits[] =
-{
- 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
-};
-
-static unsigned char DistCode[] =
-{
- 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A,
- 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C,
- 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08,
- 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00
-};
-
-static unsigned char ExLenBits[] =
-{
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
-};
-
-static unsigned char LenBits[] =
-{
- 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07
-};
-
-static unsigned char LenCode[] =
-{
- 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00
-};
-
-static unsigned char ChBitsAsc[] =
-{
- 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08,
- 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B,
- 0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06,
- 0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08,
- 0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05,
- 0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D,
- 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D
-};
-
-static unsigned short ChCodeAsc[] =
-{
- 0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0,
- 0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0,
- 0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360,
- 0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60,
- 0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8,
- 0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098,
- 0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C,
- 0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710,
- 0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8,
- 0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E,
- 0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8,
- 0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088,
- 0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A,
- 0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D,
- 0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078,
- 0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0,
- 0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040,
- 0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380,
- 0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180,
- 0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280,
- 0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080,
- 0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300,
- 0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0,
- 0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320,
- 0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220,
- 0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0,
- 0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0,
- 0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340,
- 0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900,
- 0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600,
- 0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200,
- 0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000
-};
-
-//-----------------------------------------------------------------------------
-// Macros
-
-// Macro for calculating hash of the current byte pair.
-// Note that most exact byte pair hash would be buffer[0] + buffer[1] << 0x08,
-// but even this way gives nice indication of equal byte pairs, with significantly
-// smaller size of the array that holds numbers of those hashes
-#define BYTE_PAIR_HASH(buffer) ((buffer[0] * 4) + (buffer[1] * 5))
-
-//-----------------------------------------------------------------------------
-// Local functions
-
-// Builds the "hash_to_index" table and "pair_hash_offsets" table.
-// Every element of "hash_to_index" will contain lowest index to the
-// "pair_hash_offsets" table, effectively giving offset of the first
-// occurence of the given PAIR_HASH in the input data.
-static void SortBuffer(TCmpStruct * pWork, unsigned char * buffer_begin, unsigned char * buffer_end)
-{
- unsigned short * phash_to_index;
- unsigned char * buffer_ptr;
- unsigned short total_sum = 0;
- unsigned long byte_pair_hash; // Hash value of the byte pair
- unsigned short byte_pair_offs; // Offset of the byte pair, relative to "work_buff"
-
- // Zero the entire "phash_to_index" table
- memset(pWork->phash_to_index, 0, sizeof(pWork->phash_to_index));
-
- // Step 1: Count amount of each PAIR_HASH in the input buffer
- // The table will look like this:
- // offs 0x000: Number of occurences of PAIR_HASH 0
- // offs 0x001: Number of occurences of PAIR_HASH 1
- // ...
- // offs 0x8F7: Number of occurences of PAIR_HASH 0x8F7 (the highest hash value)
- for(buffer_ptr = buffer_begin; buffer_ptr < buffer_end; buffer_ptr++)
- pWork->phash_to_index[BYTE_PAIR_HASH(buffer_ptr)]++;
-
- // Step 2: Convert the table to the array of PAIR_HASH amounts.
- // Each element contains count of PAIR_HASHes that is less or equal
- // to element index
- // The table will look like this:
- // offs 0x000: Number of occurences of PAIR_HASH 0 or lower
- // offs 0x001: Number of occurences of PAIR_HASH 1 or lower
- // ...
- // offs 0x8F7: Number of occurences of PAIR_HASH 0x8F7 or lower
- for(phash_to_index = pWork->phash_to_index; phash_to_index < &pWork->phash_to_index_end; phash_to_index++)
- {
- total_sum = total_sum + phash_to_index[0];
- phash_to_index[0] = total_sum;
- }
-
- // Step 3: Convert the table to the array of indexes.
- // Now, each element contains index to the first occurence of given PAIR_HASH
- for(buffer_end--; buffer_end >= buffer_begin; buffer_end--)
- {
- byte_pair_hash = BYTE_PAIR_HASH(buffer_end);
- byte_pair_offs = (unsigned short)(buffer_end - pWork->work_buff);
-
- pWork->phash_to_index[byte_pair_hash]--;
- pWork->phash_offs[pWork->phash_to_index[byte_pair_hash]] = byte_pair_offs;
- }
-}
-
-static void FlushBuf(TCmpStruct * pWork)
-{
- unsigned char save_ch1;
- unsigned char save_ch2;
- unsigned int size = 0x800;
-
- pWork->write_buf(pWork->out_buff, &size, pWork->param);
-
- save_ch1 = pWork->out_buff[0x800];
- save_ch2 = pWork->out_buff[pWork->out_bytes];
- pWork->out_bytes -= 0x800;
-
- memset(pWork->out_buff, 0, sizeof(pWork->out_buff));
-
- if(pWork->out_bytes != 0)
- pWork->out_buff[0] = save_ch1;
- if(pWork->out_bits != 0)
- pWork->out_buff[pWork->out_bytes] = save_ch2;
-}
-
-static void OutputBits(TCmpStruct * pWork, unsigned int nbits, unsigned long bit_buff)
-{
- unsigned int out_bits;
-
- // If more than 8 bits to output, do recursion
- if(nbits > 8)
- {
- OutputBits(pWork, 8, bit_buff);
- bit_buff >>= 8;
- nbits -= 8;
- }
-
- // Add bits to the last out byte in out_buff;
- out_bits = pWork->out_bits;
- pWork->out_buff[pWork->out_bytes] |= (unsigned char)(bit_buff << out_bits);
- pWork->out_bits += nbits;
-
- // If 8 or more bits, increment number of bytes
- if(pWork->out_bits > 8)
- {
- pWork->out_bytes++;
- bit_buff >>= (8 - out_bits);
-
- pWork->out_buff[pWork->out_bytes] = (unsigned char)bit_buff;
- pWork->out_bits &= 7;
- }
- else
- {
- pWork->out_bits &= 7;
- if(pWork->out_bits == 0)
- pWork->out_bytes++;
- }
-
- // If there is enough compressed bytes, flush them
- if(pWork->out_bytes >= 0x800)
- FlushBuf(pWork);
-}
-
-// This function searches for a repetition
-// (a previous occurence of the current byte sequence)
-// Returns length of the repetition, and stores the backward distance
-// to pWork structure.
-static unsigned int FindRep(TCmpStruct * pWork, unsigned char * input_data)
-{
- unsigned short * phash_to_index; // Pointer into pWork->phash_to_index table
- unsigned short * phash_offs; // Pointer to the table containing offsets of each PAIR_HASH
- unsigned char * repetition_limit; // An eventual repetition must be at position below this pointer
- unsigned char * prev_repetition; // Pointer to the previous occurence of the current PAIR_HASH
- unsigned char * prev_rep_end; // End of the previous repetition
- unsigned char * input_data_ptr;
- unsigned short phash_offs_index; // Index to the table with PAIR_HASH positions
- unsigned short min_phash_offs; // The lowest allowed hash offset
- unsigned short offs_in_rep; // Offset within found repetition
- unsigned int equal_byte_count; // Number of bytes that are equal to the previous occurence
- unsigned int rep_length = 1; // Length of the found repetition
- unsigned int rep_length2; // Secondary repetition
- unsigned char pre_last_byte; // Last but one byte from a repetion
- unsigned short di_val;
-
- // Calculate the previous position of the PAIR_HASH
- phash_to_index = pWork->phash_to_index + BYTE_PAIR_HASH(input_data);
- min_phash_offs = (unsigned short)((input_data - pWork->work_buff) - pWork->dsize_bytes + 1);
- phash_offs_index = phash_to_index[0];
-
- // If the PAIR_HASH offset is below the limit, find a next one
- phash_offs = pWork->phash_offs + phash_offs_index;
- if(*phash_offs < min_phash_offs)
- {
- while(*phash_offs < min_phash_offs)
- {
- phash_offs_index++;
- phash_offs++;
- }
- *phash_to_index = phash_offs_index;
- }
-
- // Get the first location of the PAIR_HASH,
- // and thus the first eventual location of byte repetition
- phash_offs = pWork->phash_offs + phash_offs_index;
- prev_repetition = pWork->work_buff + phash_offs[0];
- repetition_limit = input_data - 1;
-
- // If the current PAIR_HASH was not encountered before,
- // we haven't found a repetition.
- if(prev_repetition >= repetition_limit)
- return 0;
-
- // We have found a match of a PAIR_HASH. Now we have to make sure
- // that it is also a byte match, because PAIR_HASH is not unique.
- // We compare the bytes and count the length of the repetition
- input_data_ptr = input_data;
- for(;;)
- {
- // If the first byte of the repetition and the so-far-last byte
- // of the repetition are equal, we will compare the blocks.
- if(*input_data_ptr == *prev_repetition && input_data_ptr[rep_length-1] == prev_repetition[rep_length-1])
- {
- // Skip the current byte
- prev_repetition++;
- input_data_ptr++;
- equal_byte_count = 2;
-
- // Now count how many more bytes are equal
- while(equal_byte_count < MAX_REP_LENGTH)
- {
- prev_repetition++;
- input_data_ptr++;
-
- // Are the bytes different ?
- if(*prev_repetition != *input_data_ptr)
- break;
-
- equal_byte_count++;
- }
-
- // If we found a repetition of at least the same length, take it.
- // If there are multiple repetitions in the input buffer, this will
- // make sure that we find the most recent one, which in turn allows
- // us to store backward length in less amount of bits
- input_data_ptr = input_data;
- if(equal_byte_count >= rep_length)
- {
- // Calculate the backward distance of the repetition.
- // Note that the distance is stored as decremented by 1
- pWork->distance = (unsigned int)(input_data - prev_repetition + equal_byte_count - 1);
-
- // Repetitions longer than 10 bytes will be stored in more bits,
- // so they need a bit different handling
- if((rep_length = equal_byte_count) > 10)
- break;
- }
- }
-
- // Move forward in the table of PAIR_HASH repetitions.
- // There might be a more recent occurence of the same repetition.
- phash_offs_index++;
- phash_offs++;
- prev_repetition = pWork->work_buff + phash_offs[0];
-
- // If the next repetition is beyond the minimum allowed repetition, we are done.
- if(prev_repetition >= repetition_limit)
- {
- // A repetition must have at least 2 bytes, otherwise it's not worth it
- return (rep_length >= 2) ? rep_length : 0;
- }
- }
-
- // If the repetition has max length of 0x204 bytes, we can't go any fuhrter
- if(equal_byte_count == MAX_REP_LENGTH)
- {
- pWork->distance--;
- return equal_byte_count;
- }
-
- // Check for possibility of a repetition that occurs at more recent position
- phash_offs = pWork->phash_offs + phash_offs_index;
- if(pWork->work_buff + phash_offs[1] >= repetition_limit)
- return rep_length;
-
- //
- // The following part checks if there isn't a longer repetition at
- // a latter offset, that would lead to better compression.
- //
- // Example of data that can trigger this optimization:
- //
- // "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEQQQQQQQQQQQQ"
- // "XYZ"
- // "EEEEEEEEEEEEEEEEQQQQQQQQQQQQ";
- //
- // Description of data in this buffer
- // [0x00] Single byte "E"
- // [0x01] Single byte "E"
- // [0x02] Repeat 0x1E bytes from [0x00]
- // [0x20] Single byte "X"
- // [0x21] Single byte "Y"
- // [0x22] Single byte "Z"
- // [0x23] 17 possible previous repetitions of length at least 0x10 bytes:
- // - Repetition of 0x10 bytes from [0x00] "EEEEEEEEEEEEEEEE"
- // - Repetition of 0x10 bytes from [0x01] "EEEEEEEEEEEEEEEE"
- // - Repetition of 0x10 bytes from [0x02] "EEEEEEEEEEEEEEEE"
- // ...
- // - Repetition of 0x10 bytes from [0x0F] "EEEEEEEEEEEEEEEE"
- // - Repetition of 0x1C bytes from [0x10] "EEEEEEEEEEEEEEEEQQQQQQQQQQQQ"
- // The last repetition is the best one.
- //
-
- pWork->offs09BC[0] = 0xFFFF;
- pWork->offs09BC[1] = 0x0000;
- di_val = 0;
-
- // Note: I failed to figure out what does the table "offs09BC" mean.
- // If anyone has an idea, let me know to zezula_at_volny_dot_cz
- for(offs_in_rep = 1; offs_in_rep < rep_length; )
- {
- if(input_data[offs_in_rep] != input_data[di_val])
- {
- di_val = pWork->offs09BC[di_val];
- if(di_val != 0xFFFF)
- continue;
- }
- pWork->offs09BC[++offs_in_rep] = ++di_val;
- }
-
- //
- // Now go through all the repetitions from the first found one
- // to the current input data, and check if any of them migh be
- // a start of a greater sequence match.
- //
-
- prev_repetition = pWork->work_buff + phash_offs[0];
- prev_rep_end = prev_repetition + rep_length;
- rep_length2 = rep_length;
-
- for(;;)
- {
- rep_length2 = pWork->offs09BC[rep_length2];
- if(rep_length2 == 0xFFFF)
- rep_length2 = 0;
-
- // Get the pointer to the previous repetition
- phash_offs = pWork->phash_offs + phash_offs_index;
-
- // Skip those repetitions that don't reach the end
- // of the first found repetition
- do
- {
- phash_offs++;
- phash_offs_index++;
- prev_repetition = pWork->work_buff + *phash_offs;
- if(prev_repetition >= repetition_limit)
- return rep_length;
- }
- while(prev_repetition + rep_length2 < prev_rep_end);
-
- // Verify if the last but one byte from the repetition matches
- // the last but one byte from the input data.
- // If not, find a next repetition
- pre_last_byte = input_data[rep_length - 2];
- if(pre_last_byte == prev_repetition[rep_length - 2])
- {
- // If the new repetition reaches beyond the end
- // of previously found repetition, reset the repetition length to zero.
- if(prev_repetition + rep_length2 != prev_rep_end)
- {
- prev_rep_end = prev_repetition;
- rep_length2 = 0;
- }
- }
- else
- {
- phash_offs = pWork->phash_offs + phash_offs_index;
- do
- {
- phash_offs++;
- phash_offs_index++;
- prev_repetition = pWork->work_buff + *phash_offs;
- if(prev_repetition >= repetition_limit)
- return rep_length;
- }
- while(prev_repetition[rep_length - 2] != pre_last_byte || prev_repetition[0] != input_data[0]);
-
- // Reset the length of the repetition to 2 bytes only
- prev_rep_end = prev_repetition + 2;
- rep_length2 = 2;
- }
-
- // Find out how many more characters are equal to the first repetition.
- while(*prev_rep_end == input_data[rep_length2])
- {
- if(++rep_length2 >= 0x204)
- break;
- prev_rep_end++;
- }
-
- // Is the newly found repetion at least as long as the previous one ?
- if(rep_length2 >= rep_length)
- {
- // Calculate the distance of the new repetition
- pWork->distance = (unsigned int)(input_data - prev_repetition - 1);
- if((rep_length = rep_length2) == 0x204)
- return rep_length;
-
- // Update the additional elements in the "offs09BC" table
- // to reflect new rep length
- while(offs_in_rep < rep_length2)
- {
- if(input_data[offs_in_rep] != input_data[di_val])
- {
- di_val = pWork->offs09BC[di_val];
- if(di_val != 0xFFFF)
- continue;
- }
- pWork->offs09BC[++offs_in_rep] = ++di_val;
- }
- }
- }
-}
-
-static void WriteCmpData(TCmpStruct * pWork)
-{
- unsigned char * input_data_end; // Pointer to the end of the input data
- unsigned char * input_data = pWork->work_buff + pWork->dsize_bytes + 0x204;
- unsigned int input_data_ended = 0; // If 1, then all data from the input stream have been already loaded
- unsigned int save_rep_length; // Saved length of current repetition
- unsigned int save_distance = 0; // Saved distance of current repetition
- unsigned int rep_length; // Length of the found repetition
- unsigned int phase = 0; //
-
- // Store the compression type and dictionary size
- pWork->out_buff[0] = (char)pWork->ctype;
- pWork->out_buff[1] = (char)pWork->dsize_bits;
- pWork->out_bytes = 2;
-
- // Reset output buffer to zero
- memset(&pWork->out_buff[2], 0, sizeof(pWork->out_buff) - 2);
- pWork->out_bits = 0;
-
- while(input_data_ended == 0)
- {
- unsigned int bytes_to_load = 0x1000;
- int total_loaded = 0;
- int bytes_loaded;
-
- // Load the bytes from the input stream, up to 0x1000 bytes
- while(bytes_to_load != 0)
- {
- bytes_loaded = pWork->read_buf((char *)pWork->work_buff + pWork->dsize_bytes + 0x204 + total_loaded,
- &bytes_to_load,
- pWork->param);
- if(bytes_loaded == 0)
- {
- if(total_loaded == 0 && phase == 0)
- goto __Exit;
- input_data_ended = 1;
- break;
- }
- else
- {
- bytes_to_load -= bytes_loaded;
- total_loaded += bytes_loaded;
- }
- }
-
- input_data_end = pWork->work_buff + pWork->dsize_bytes + total_loaded;
- if(input_data_ended)
- input_data_end += 0x204;
-
- //
- // Warning: The end of the buffer passed to "SortBuffer" is actually 2 bytes beyond
- // valid data. It is questionable if this is actually a bug or not,
- // but it might cause the compressed data output to be dependent on random bytes
- // that are in the buffer.
- // To prevent that, the calling application must always zero the compression
- // buffer before passing it to "implode"
- //
-
- // Search the PAIR_HASHes of the loaded blocks. Also, include
- // previously compressed data, if any.
- switch(phase)
- {
- case 0:
- SortBuffer(pWork, input_data, input_data_end + 1);
- phase++;
- if(pWork->dsize_bytes != 0x1000)
- phase++;
- break;
-
- case 1:
- SortBuffer(pWork, input_data - pWork->dsize_bytes + 0x204, input_data_end + 1);
- phase++;
- break;
-
- default:
- SortBuffer(pWork, input_data - pWork->dsize_bytes, input_data_end + 1);
- break;
- }
-
- // Perform the compression of the current block
- while(input_data < input_data_end)
- {
- // Find if the current byte sequence wasn't there before.
- rep_length = FindRep(pWork, input_data);
- while(rep_length != 0)
- {
- // If we found repetition of 2 bytes, that is 0x100 or fuhrter back,
- // don't bother. Storing the distance of 0x100 bytes would actually
- // take more space than storing the 2 bytes as-is.
- if(rep_length == 2 && pWork->distance >= 0x100)
- break;
-
- // When we are at the end of the input data, we cannot allow
- // the repetition to go past the end of the input data.
- if(input_data_ended && input_data + rep_length > input_data_end)
- {
- // Shorten the repetition length so that it only covers valid data
- rep_length = (unsigned long)(input_data_end - input_data);
- if(rep_length < 2)
- break;
-
- // If we got repetition of 2 bytes, that is 0x100 or more backward, don't bother
- if(rep_length == 2 && pWork->distance >= 0x100)
- break;
- goto __FlushRepetition;
- }
-
- if(rep_length >= 8 || input_data + 1 >= input_data_end)
- goto __FlushRepetition;
-
- // Try to find better repetition 1 byte later.
- // Example: "ARROCKFORT" "AROCKFORT"
- // When "input_data" points to the second string, FindRep
- // returns the occurence of "AR". But there is longer repetition "ROCKFORT",
- // beginning 1 byte after.
- save_rep_length = rep_length;
- save_distance = pWork->distance;
- rep_length = FindRep(pWork, input_data + 1);
-
- // Only use the new repetition if it's length is greater than the previous one
- if(rep_length > save_rep_length)
- {
- // If the new repetition if only 1 byte better
- // and the previous distance is less than 0x80 bytes, use the previous repetition
- if(rep_length > save_rep_length + 1 || save_distance > 0x80)
- {
- // Flush one byte, so that input_data will point to the secondary repetition
- OutputBits(pWork, pWork->nChBits[*input_data], pWork->nChCodes[*input_data]);
- input_data++;
- continue;
- }
- }
-
- // Revert to the previous repetition
- rep_length = save_rep_length;
- pWork->distance = save_distance;
-
- __FlushRepetition:
-
- OutputBits(pWork, pWork->nChBits[rep_length + 0xFE], pWork->nChCodes[rep_length + 0xFE]);
- if(rep_length == 2)
- {
- OutputBits(pWork, pWork->dist_bits[pWork->distance >> 2],
- pWork->dist_codes[pWork->distance >> 2]);
- OutputBits(pWork, 2, pWork->distance & 3);
- }
- else
- {
- OutputBits(pWork, pWork->dist_bits[pWork->distance >> pWork->dsize_bits],
- pWork->dist_codes[pWork->distance >> pWork->dsize_bits]);
- OutputBits(pWork, pWork->dsize_bits, pWork->dsize_mask & pWork->distance);
- }
-
- // Move the begin of the input data by the length of the repetition
- input_data += rep_length;
- goto _00402252;
- }
-
- // If there was no previous repetition for the current position in the input data,
- // just output the 9-bit literal for the one character
- OutputBits(pWork, pWork->nChBits[*input_data], pWork->nChCodes[*input_data]);
- input_data++;
-_00402252:;
- }
-
- if(input_data_ended == 0)
- {
- input_data -= 0x1000;
- memcpy(pWork->work_buff, pWork->work_buff + 0x1000, pWork->dsize_bytes + 0x204);
- }
- }
-
-__Exit:
-
- // Write the termination literal
- OutputBits(pWork, pWork->nChBits[0x305], pWork->nChCodes[0x305]);
- if(pWork->out_bits != 0)
- pWork->out_bytes++;
- pWork->write_buf(pWork->out_buff, &pWork->out_bytes, pWork->param);
- return;
-}
-
-//-----------------------------------------------------------------------------
-// Main imploding function
-
-unsigned int PKEXPORT implode(
- unsigned int (*read_buf)(char *buf, unsigned int *size, void *param),
- void (*write_buf)(char *buf, unsigned int *size, void *param),
- char *work_buf,
- void *param,
- unsigned int *type,
- unsigned int *dsize)
-{
- TCmpStruct * pWork = (TCmpStruct *)work_buf;
- unsigned int nChCode;
- unsigned int nCount;
- unsigned int i;
- int nCount2;
-
- // Fill the work buffer information
- // Note: The caller must zero the "work_buff" before passing it to implode
- pWork->read_buf = read_buf;
- pWork->write_buf = write_buf;
- pWork->dsize_bytes = *dsize;
- pWork->ctype = *type;
- pWork->param = param;
- pWork->dsize_bits = 4;
- pWork->dsize_mask = 0x0F;
-
- // Test dictionary size
- switch(*dsize)
- {
- case CMP_IMPLODE_DICT_SIZE3: // 0x1000 bytes
- pWork->dsize_bits++;
- pWork->dsize_mask |= 0x20;
- // No break here !!!
-
- case CMP_IMPLODE_DICT_SIZE2: // 0x800 bytes
- pWork->dsize_bits++;
- pWork->dsize_mask |= 0x10;
- // No break here !!!
-
- case CMP_IMPLODE_DICT_SIZE1: // 0x400
- break;
-
- default:
- return CMP_INVALID_DICTSIZE;
- }
-
- // Test the compression type
- switch(*type)
- {
- case CMP_BINARY: // We will compress data with binary compression type
- for(nChCode = 0, nCount = 0; nCount < 0x100; nCount++)
- {
- pWork->nChBits[nCount] = 9;
- pWork->nChCodes[nCount] = (unsigned short)nChCode;
- nChCode = (nChCode & 0x0000FFFF) + 2;
- }
- break;
-
-
- case CMP_ASCII: // We will compress data with ASCII compression type
- for(nCount = 0; nCount < 0x100; nCount++)
- {
- pWork->nChBits[nCount] = (unsigned char )(ChBitsAsc[nCount] + 1);
- pWork->nChCodes[nCount] = (unsigned short)(ChCodeAsc[nCount] * 2);
- }
- break;
-
- default:
- return CMP_INVALID_MODE;
- }
-
- for(i = 0; i < 0x10; i++)
- {
- if(1 << ExLenBits[i])
- {
- for(nCount2 = 0; nCount2 < (1 << ExLenBits[i]); nCount2++)
- {
- pWork->nChBits[nCount] = (unsigned char)(ExLenBits[i] + LenBits[i] + 1);
- pWork->nChCodes[nCount] = (unsigned short)((nCount2 << (LenBits[i] + 1)) | ((LenCode[i] & 0xFFFF00FF) * 2) | 1);
- nCount++;
- }
- }
- }
-
- // Copy the distance codes and distance bits and perform the compression
- memcpy(&pWork->dist_codes, DistCode, sizeof(DistCode));
- memcpy(&pWork->dist_bits, DistBits, sizeof(DistBits));
- WriteCmpData(pWork);
- return CMP_NO_ERROR;
-}
diff --git a/dep/StormLib/src/pklib/pklib.h b/dep/StormLib/src/pklib/pklib.h
deleted file mode 100644
index f43da153be6..00000000000
--- a/dep/StormLib/src/pklib/pklib.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*****************************************************************************/
-/* pklib.h Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Header file for PKWARE Data Compression Library */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 31.03.03 1.00 Lad The first version of pkware.h */
-/*****************************************************************************/
-
-#ifndef __PKLIB_H__
-#define __PKLIB_H__
-
-#include "../StormPort.h"
-
-//-----------------------------------------------------------------------------
-// Defines
-
-#define CMP_BINARY 0 // Binary compression
-#define CMP_ASCII 1 // Ascii compression
-
-#define CMP_NO_ERROR 0
-#define CMP_INVALID_DICTSIZE 1
-#define CMP_INVALID_MODE 2
-#define CMP_BAD_DATA 3
-#define CMP_ABORT 4
-
-#define CMP_IMPLODE_DICT_SIZE1 1024 // Dictionary size of 1024
-#define CMP_IMPLODE_DICT_SIZE2 2048 // Dictionary size of 2048
-#define CMP_IMPLODE_DICT_SIZE3 4096 // Dictionary size of 4096
-
-//-----------------------------------------------------------------------------
-// Define calling convention
-
-#ifndef PKEXPORT
-#ifdef WIN32
-#define PKEXPORT __cdecl // Use for normal __cdecl calling
-#else
-#define PKEXPORT
-#endif
-#endif
-
-//-----------------------------------------------------------------------------
-// Internal structures
-
-// Compression structure
-typedef struct
-{
- unsigned int distance; // 0000: Backward distance of the currently found repetition, decreased by 1
- unsigned int out_bytes; // 0004: # bytes available in out_buff
- unsigned int out_bits; // 0008: # of bits available in the last out byte
- unsigned int dsize_bits; // 000C: Number of bits needed for dictionary size. 4 = 0x400, 5 = 0x800, 6 = 0x1000
- unsigned int dsize_mask; // 0010: Bit mask for dictionary. 0x0F = 0x400, 0x1F = 0x800, 0x3F = 0x1000
- unsigned int ctype; // 0014: Compression type (CMP_ASCII or CMP_BINARY)
- unsigned int dsize_bytes; // 0018: Dictionary size in bytes
- unsigned char dist_bits[0x40]; // 001C: Distance bits
- unsigned char dist_codes[0x40]; // 005C: Distance codes
- unsigned char nChBits[0x306]; // 009C: Table of literal bit lengths to be put to the output stream
- unsigned short nChCodes[0x306]; // 03A2: Table of literal codes to be put to the output stream
- unsigned short offs09AE; // 09AE:
-
- void * param; // 09B0: User parameter
- unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); // 9B4
- void (*write_buf)(char *buf, unsigned int *size, void *param); // 9B8
-
- unsigned short offs09BC[0x204]; // 09BC:
- unsigned long offs0DC4; // 0DC4:
- unsigned short phash_to_index[0x900]; // 0DC8: Array of indexes (one for each PAIR_HASH) to the "pair_hash_offsets" table
- unsigned short phash_to_index_end; // 1FC8: End marker for "phash_to_index" table
- char out_buff[0x802]; // 1FCA: Compressed data
- unsigned char work_buff[0x2204]; // 27CC: Work buffer
- // + DICT_OFFSET => Dictionary
- // + UNCMP_OFFSET => Uncompressed data
- unsigned short phash_offs[0x2204]; // 49D0: Table of offsets for each PAIR_HASH
-} TCmpStruct;
-
-#define CMP_BUFFER_SIZE sizeof(TCmpStruct) // Size of compression structure.
- // Defined as 36312 in pkware header file
-
-
-// Decompression structure
-typedef struct
-{
- unsigned long offs0000; // 0000
- unsigned long ctype; // 0004: Compression type (CMP_BINARY or CMP_ASCII)
- unsigned long outputPos; // 0008: Position in output buffer
- unsigned long dsize_bits; // 000C: Dict size (4, 5, 6 for 0x400, 0x800, 0x1000)
- unsigned long dsize_mask; // 0010: Dict size bitmask (0x0F, 0x1F, 0x3F for 0x400, 0x800, 0x1000)
- unsigned long bit_buff; // 0014: 16-bit buffer for processing input data
- unsigned long extra_bits; // 0018: Number of extra (above 8) bits in bit buffer
- unsigned int in_pos; // 001C: Position in in_buff
- unsigned long in_bytes; // 0020: Number of bytes in input buffer
- void * param; // 0024: Custom parameter
- unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); // Pointer to function that reads data from the input stream
- void (*write_buf)(char *buf, unsigned int *size, void *param);// Pointer to function that writes data to the output stream
-
- unsigned char out_buff[0x2204]; // 0030: Output circle buffer.
- // 0x0000 - 0x0FFF: Previous uncompressed data, kept for repetitions
- // 0x1000 - 0x1FFF: Currently decompressed data
- // 0x2000 - 0x2203: Reserve space for the longest possible repetition
- unsigned char in_buff[0x800]; // 2234: Buffer for data to be decompressed
- unsigned char DistPosCodes[0x100]; // 2A34: Table of distance position codes
- unsigned char LengthCodes[0x100]; // 2B34: Table of length codes
- unsigned char offs2C34[0x100]; // 2C34: Buffer for
- unsigned char offs2D34[0x100]; // 2D34: Buffer for
- unsigned char offs2E34[0x80]; // 2EB4: Buffer for
- unsigned char offs2EB4[0x100]; // 2EB4: Buffer for
- unsigned char ChBitsAsc[0x100]; // 2FB4: Buffer for
- unsigned char DistBits[0x40]; // 30B4: Numbers of bytes to skip copied block length
- unsigned char LenBits[0x10]; // 30F4: Numbers of bits for skip copied block length
- unsigned char ExLenBits[0x10]; // 3104: Number of valid bits for copied block
- unsigned short LenBase[0x10]; // 3114: Buffer for
-} TDcmpStruct;
-
-#define EXP_BUFFER_SIZE sizeof(TDcmpStruct) // Size of decompression structure
- // Defined as 12596 in pkware headers
-
-//-----------------------------------------------------------------------------
-// Public functions
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-unsigned int PKEXPORT implode(
- unsigned int (*read_buf)(char *buf, unsigned int *size, void *param),
- void (*write_buf)(char *buf, unsigned int *size, void *param),
- char *work_buf,
- void *param,
- unsigned int *type,
- unsigned int *dsize);
-
-
-unsigned int PKEXPORT explode(
- unsigned int (*read_buf)(char *buf, unsigned int *size, void *param),
- void (*write_buf)(char *buf, unsigned int *size, void *param),
- char *work_buf,
- void *param);
-
-// The original name "crc32" was changed to "crc32pk" due
-// to compatibility with zlib
-unsigned long PKEXPORT crc32_pklib(char *buffer, unsigned int *size, unsigned long *old_crc);
-
-#ifdef __cplusplus
- } // End of 'extern "C"' declaration
-#endif
-
-#endif // __PKLIB_H__
diff --git a/dep/StormLib/src/sparse/sparse.cpp b/dep/StormLib/src/sparse/sparse.cpp
deleted file mode 100644
index 6df7021fc8a..00000000000
--- a/dep/StormLib/src/sparse/sparse.cpp
+++ /dev/null
@@ -1,292 +0,0 @@
-/*****************************************************************************/
-/* huffman.cpp Copyright (c) Ladislav Zezula 1998-2003 */
-/*---------------------------------------------------------------------------*/
-/* This module contains Huffmann (de)compression methods */
-/* */
-/* Authors : Ladislav Zezula (ladik.zezula.net) */
-/* ShadowFlare (BlakFlare@hotmail.com) */
-/* */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* xx.xx.xx 1.00 Lad The first version of dcmp.cpp */
-/* 03.05.03 1.00 Lad Added compression methods */
-/* 19.11.03 1.01 Dan Big endian handling */
-/* 08.12.03 2.01 Dan High-memory handling (> 0x80000000) */
-/*****************************************************************************/
-
-#include <assert.h>
-#include <string.h>
-
-#include "sparse.h"
-
-//-----------------------------------------------------------------------------
-// Public functions
-
-void CompressSparse(unsigned char * pbOutBuffer, int * pcbOutBuffer, unsigned char * pbInBuffer, int cbInBuffer)
-{
- unsigned char * pbOutBufferEnd = pbOutBuffer + *pcbOutBuffer;
- unsigned char * pbInBufferEnd = pbInBuffer + cbInBuffer;
- unsigned char * pbLastNonZero = pbInBuffer;
- unsigned char * pbOutBuffer0 = pbOutBuffer;
- unsigned char * pbInBuffPtr = pbInBuffer;
- size_t NumberOfNonZeros;
- size_t NumberOfZeros;
-
- // There must be at least 4 bytes of free space in the output buffer now
- if((pbInBuffer + 4) >= pbInBufferEnd)
- return;
-
- // Put the original data length (in little endian)
- *pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x18);
- *pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x10);
- *pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x08);
- *pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x00);
-
- // If there is at least 3 bytes in the input buffer, do this loop
- while(pbInBuffer < (pbInBufferEnd - 3))
- {
- // Reset the zero count and frontal pointer
- pbLastNonZero = pbInBuffer;
- pbInBuffPtr = pbInBuffer;
- NumberOfZeros = 0;
-
- if(pbInBuffPtr < pbInBufferEnd)
- {
- do
- {
- // Count number of zeros
- if(*pbInBuffPtr == 0)
- {
- NumberOfZeros++;
- }
- else
- {
- // Were there at least 3 zeros before? If yes, we need to flush the data
- if(NumberOfZeros >= 3)
- break;
- pbLastNonZero = pbInBuffPtr + 1;
- NumberOfZeros = 0;
- }
- }
- while(++pbInBuffPtr < pbInBufferEnd);
- }
-
- // Get number of nonzeros that we found so far and flush them
- NumberOfNonZeros = pbLastNonZero - pbInBuffer;
- if(NumberOfNonZeros != 0)
- {
- // Process blocks that are longer than 0x81 nonzero bytes
- while(NumberOfNonZeros > 0x81)
- {
- // Verify if we still have enough space in output buffer
- if((pbOutBuffer + 0x81) >= pbOutBufferEnd)
- return;
-
- // Put marker that means "0x80 of nonzeros"
- *pbOutBuffer++ = 0xFF;
- memcpy(pbOutBuffer, pbInBuffer, 0x80);
-
- // Adjust counter of nonzeros and both pointers
- NumberOfNonZeros -= 0x80;
- pbOutBuffer += 0x80;
- pbInBuffer += 0x80;
- }
-
- // BUGBUG: The following code will be triggered if the NumberOfNonZeros
- // was 0x81 before. It will copy just one byte. This seems like a bug to me,
- // but since I want StormLib to be exact like Blizzard code is, I will keep
- // it that way here
- if(NumberOfNonZeros > 0x80)
- {
- // Verify if we still have enough space in output buffer
- if((pbOutBuffer + 2) >= pbOutBufferEnd)
- return;
-
- // Put marker that means "1 nonzero byte"
- *pbOutBuffer++ = 0x80;
- memcpy(pbOutBuffer, pbInBuffer, 1);
-
- // Adjust counter of nonzeros and both pointers
- NumberOfNonZeros--;
- pbOutBuffer++;
- pbInBuffer++;
- }
-
- // If there is 1 nonzero or more, put the block
- if(NumberOfNonZeros >= 0x01)
- {
- // Verify if we still have enough space in output buffer
- if((pbOutBuffer + NumberOfNonZeros + 1) >= pbOutBufferEnd)
- return;
-
- // Put marker that means "Several nonzero bytes"
- *pbOutBuffer++ = (unsigned char)(0x80 | (NumberOfNonZeros - 1));
- memcpy(pbOutBuffer, pbInBuffer, NumberOfNonZeros);
-
- // Adjust pointers
- pbOutBuffer += NumberOfNonZeros;
- pbInBuffer += NumberOfNonZeros;
- }
- else
- {
- // Verify if we still have enough space in output buffer
- if((pbOutBuffer + 2) >= pbOutBufferEnd)
- return;
-
- // Put marker that means "1 nonzero byte"
- *pbOutBuffer++ = 0x80;
- memcpy(pbOutBuffer, pbInBuffer, 1);
-
- // Adjust pointers
- pbOutBuffer++;
- pbInBuffer++;
- }
- }
-
- // Now flush all zero bytes
- while(NumberOfZeros > 0x85)
- {
- // Do we have at least 2 bytes in the output buffer ?
- if((pbOutBuffer + 1) >= pbOutBufferEnd)
- return;
-
- // Put marker that means "0x82 zeros"
- *pbOutBuffer++ = 0x7F;
-
- // Adjust zero counter and input pointer
- NumberOfZeros -= 0x82;
- pbInBuffer += 0x82;
- }
-
- // If we got more than 0x82 zeros, flush 3 of them now
- if(NumberOfZeros > 0x82)
- {
- // Do we have at least 2 bytes in the output buffer ?
- if((pbOutBuffer + 1) >= pbOutBufferEnd)
- return;
-
- // Put marker that means "0x03 zeros"
- *pbOutBuffer++ = 0;
-
- // Adjust zero counter and input pointer
- NumberOfZeros -= 0x03;
- pbInBuffer += 0x03;
- }
-
- // Is there at least three zeros ?
- if(NumberOfZeros >= 3)
- {
- // Do we have at least 2 bytes in the output buffer ?
- if((pbOutBuffer + 1) >= pbOutBufferEnd)
- return;
-
- // Put marker that means "Several zeros"
- *pbOutBuffer++ = (unsigned char)(NumberOfZeros - 3);
-
- // Adjust pointer
- pbInBuffer += NumberOfZeros;
- }
- }
-
- // Flush last three bytes
- if(pbInBuffer < pbInBufferEnd)
- {
- pbInBuffPtr = pbInBuffer;
-
- for(;;)
- {
- if(*pbInBuffPtr++ != 0)
- {
- // Get number of bytes remaining
- NumberOfNonZeros = (pbInBufferEnd - pbInBuffer);
-
- // Not enough space in the output buffer ==> exit
- if((pbOutBuffer + NumberOfNonZeros + 1) >= pbOutBufferEnd)
- return;
-
- // Terminate with a marker that means "0x80 of nonzeros"
- *pbOutBuffer++ = 0xFF;
- memcpy(pbOutBuffer, pbInBuffer, NumberOfNonZeros);
-
- // Adjust pointer
- pbOutBuffer += NumberOfNonZeros;
- break;
- }
- else
- {
- // Is there are more chars in the input buffer
- if(pbInBuffPtr < pbInBufferEnd)
- continue;
-
- // If the compression will not compress it by even 1 byte, do nothing
- if((pbOutBuffer + 1) >= pbOutBufferEnd)
- return;
-
- // Terminate with a chunk that means "0x82 of zeros"
- *pbOutBuffer++ = 0x7F;
- break;
- }
- }
- }
-
- // Out the length of the output buffer
- *pcbOutBuffer = (int)(pbOutBuffer - pbOutBuffer0);
-}
-
-int DecompressSparse(unsigned char * pbOutBuffer, int * pcbOutBuffer, unsigned char * pbInBuffer, int cbInBuffer)
-{
- unsigned char * pbInBufferEnd = pbInBuffer + cbInBuffer;
- unsigned int cbChunkSize;
- unsigned int cbOutBuffer = 0;
- unsigned int OneByte;
-
- // Don't decompress anything that is shorter than 5 bytes
- if(cbInBuffer < 5)
- return 0;
-
- // Get the 32-bits from the input stream
- OneByte = *pbInBuffer++;
- cbOutBuffer |= (OneByte << 0x18);
- OneByte = *pbInBuffer++;
- cbOutBuffer |= (OneByte << 0x10);
- OneByte = *pbInBuffer++;
- cbOutBuffer |= (OneByte << 0x08);
- OneByte = *pbInBuffer++;
- cbOutBuffer |= (OneByte << 0x00);
-
- // Verify the size of the stream against the output buffer size
- if(cbOutBuffer > *pcbOutBuffer)
- return 0;
-
- // Put the output size to the buffer
- *pcbOutBuffer = cbOutBuffer;
-
- // Process the input buffer
- while(pbInBuffer < pbInBufferEnd)
- {
- // Get (next) byte from the stream
- OneByte = *pbInBuffer++;
-
- // If highest bit, it means that that normal data follow
- if(OneByte & 0x80)
- {
- cbChunkSize = (OneByte & 0x7F) + 1;
- cbChunkSize = (cbChunkSize < cbOutBuffer) ? cbChunkSize : cbOutBuffer;
- memcpy(pbOutBuffer, pbInBuffer, cbChunkSize);
- pbInBuffer += cbChunkSize;
- }
- else
- {
- cbChunkSize = (OneByte & 0x7F) + 3;
- cbChunkSize = (cbChunkSize < cbOutBuffer) ? cbChunkSize : cbOutBuffer;
- memset(pbOutBuffer, 0, cbChunkSize);
- }
-
- // Increment output buffer pointer
- pbOutBuffer += cbChunkSize;
- cbOutBuffer -= cbChunkSize;
- }
-
- return 1;
-}
diff --git a/dep/StormLib/src/sparse/sparse.h b/dep/StormLib/src/sparse/sparse.h
deleted file mode 100644
index 032395f0b94..00000000000
--- a/dep/StormLib/src/sparse/sparse.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*****************************************************************************/
-/* sparse.h Copyright (c) Ladislav Zezula 2010 */
-/*---------------------------------------------------------------------------*/
-/* implementation of Sparse compression, used in Starcraft II */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 05.03.10 1.00 Lad The first version of sparse.h */
-/*****************************************************************************/
-
-#ifndef __SPARSE_H__
-#define __SPARSE_H__
-
-#include "../StormPort.h"
-
-void CompressSparse(unsigned char * pbOutBuffer, int * pcbOutLength, unsigned char * pbInBuffer, int cbInLength);
-int DecompressSparse(unsigned char * pbOutBuffer, int * pcbOutLength, unsigned char * pbInBuffer, int cbInLength);
-
-#endif // __SPARSE_H__
diff --git a/dep/StormLib/src/zlib/adler32.c b/dep/StormLib/src/zlib/adler32.c
deleted file mode 100644
index 007ba26277c..00000000000
--- a/dep/StormLib/src/zlib/adler32.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-2004 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#define ZLIB_INTERNAL
-#include "zlib.h"
-
-#define BASE 65521UL /* largest prime smaller than 65536 */
-#define NMAX 5552
-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
-#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
-#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
-#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
-#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
-#define DO16(buf) DO8(buf,0); DO8(buf,8);
-
-/* use NO_DIVIDE if your processor does not do division in hardware */
-#ifdef NO_DIVIDE
-# define MOD(a) \
- do { \
- if (a >= (BASE << 16)) a -= (BASE << 16); \
- if (a >= (BASE << 15)) a -= (BASE << 15); \
- if (a >= (BASE << 14)) a -= (BASE << 14); \
- if (a >= (BASE << 13)) a -= (BASE << 13); \
- if (a >= (BASE << 12)) a -= (BASE << 12); \
- if (a >= (BASE << 11)) a -= (BASE << 11); \
- if (a >= (BASE << 10)) a -= (BASE << 10); \
- if (a >= (BASE << 9)) a -= (BASE << 9); \
- if (a >= (BASE << 8)) a -= (BASE << 8); \
- if (a >= (BASE << 7)) a -= (BASE << 7); \
- if (a >= (BASE << 6)) a -= (BASE << 6); \
- if (a >= (BASE << 5)) a -= (BASE << 5); \
- if (a >= (BASE << 4)) a -= (BASE << 4); \
- if (a >= (BASE << 3)) a -= (BASE << 3); \
- if (a >= (BASE << 2)) a -= (BASE << 2); \
- if (a >= (BASE << 1)) a -= (BASE << 1); \
- if (a >= BASE) a -= BASE; \
- } while (0)
-# define MOD4(a) \
- do { \
- if (a >= (BASE << 4)) a -= (BASE << 4); \
- if (a >= (BASE << 3)) a -= (BASE << 3); \
- if (a >= (BASE << 2)) a -= (BASE << 2); \
- if (a >= (BASE << 1)) a -= (BASE << 1); \
- if (a >= BASE) a -= BASE; \
- } while (0)
-#else
-# define MOD(a) a %= BASE
-# define MOD4(a) a %= BASE
-#endif
-
-/* ========================================================================= */
-uLong ZEXPORT adler32(adler, buf, len)
- uLong adler;
- const Bytef *buf;
- uInt len;
-{
- unsigned long sum2;
- unsigned n;
-
- /* split Adler-32 into component sums */
- sum2 = (adler >> 16) & 0xffff;
- adler &= 0xffff;
-
- /* in case user likes doing a byte at a time, keep it fast */
- if (len == 1) {
- adler += buf[0];
- if (adler >= BASE)
- adler -= BASE;
- sum2 += adler;
- if (sum2 >= BASE)
- sum2 -= BASE;
- return adler | (sum2 << 16);
- }
-
- /* initial Adler-32 value (deferred check for len == 1 speed) */
- if (buf == Z_NULL)
- return 1L;
-
- /* in case short lengths are provided, keep it somewhat fast */
- if (len < 16) {
- while (len--) {
- adler += *buf++;
- sum2 += adler;
- }
- if (adler >= BASE)
- adler -= BASE;
- MOD4(sum2); /* only added so many BASE's */
- return adler | (sum2 << 16);
- }
-
- /* do length NMAX blocks -- requires just one modulo operation */
- while (len >= NMAX) {
- len -= NMAX;
- n = NMAX / 16; /* NMAX is divisible by 16 */
- do {
- DO16(buf); /* 16 sums unrolled */
- buf += 16;
- } while (--n);
- MOD(adler);
- MOD(sum2);
- }
-
- /* do remaining bytes (less than NMAX, still just one modulo) */
- if (len) { /* avoid modulos if none remaining */
- while (len >= 16) {
- len -= 16;
- DO16(buf);
- buf += 16;
- }
- while (len--) {
- adler += *buf++;
- sum2 += adler;
- }
- MOD(adler);
- MOD(sum2);
- }
-
- /* return recombined sums */
- return adler | (sum2 << 16);
-}
-
-/* ========================================================================= */
-uLong ZEXPORT adler32_combine(adler1, adler2, len2)
- uLong adler1;
- uLong adler2;
- z_off_t len2;
-{
- unsigned long sum1;
- unsigned long sum2;
- unsigned rem;
-
- /* the derivation of this formula is left as an exercise for the reader */
- rem = (unsigned)(len2 % BASE);
- sum1 = adler1 & 0xffff;
- sum2 = rem * sum1;
- MOD(sum2);
- sum1 += (adler2 & 0xffff) + BASE - 1;
- sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
- if (sum1 > BASE) sum1 -= BASE;
- if (sum1 > BASE) sum1 -= BASE;
- if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
- if (sum2 > BASE) sum2 -= BASE;
- return sum1 | (sum2 << 16);
-}
diff --git a/dep/StormLib/src/zlib/compress2.c b/dep/StormLib/src/zlib/compress2.c
deleted file mode 100644
index df04f0148e6..00000000000
--- a/dep/StormLib/src/zlib/compress2.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/* compress.c -- compress a memory buffer
- * Copyright (C) 1995-2003 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#define ZLIB_INTERNAL
-#include "zlib.h"
-
-/* ===========================================================================
- Compresses the source buffer into the destination buffer. The level
- parameter has the same meaning as in deflateInit. sourceLen is the byte
- length of the source buffer. Upon entry, destLen is the total size of the
- destination buffer, which must be at least 0.1% larger than sourceLen plus
- 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
-
- compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_BUF_ERROR if there was not enough room in the output buffer,
- Z_STREAM_ERROR if the level parameter is invalid.
-*/
-int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
- int level;
-{
- z_stream stream;
- int err;
-
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
-#ifdef MAXSEG_64K
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-#endif
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
- stream.opaque = (voidpf)0;
-
- err = deflateInit(&stream, level);
- if (err != Z_OK) return err;
-
- err = deflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- deflateEnd(&stream);
- return err == Z_OK ? Z_BUF_ERROR : err;
- }
- *destLen = stream.total_out;
-
- err = deflateEnd(&stream);
- return err;
-}
-
-/* ===========================================================================
- */
-int ZEXPORT compress (dest, destLen, source, sourceLen)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
-{
- return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
-}
-
-/* ===========================================================================
- If the default memLevel or windowBits for deflateInit() is changed, then
- this function needs to be updated.
- */
-uLong ZEXPORT compressBound (sourceLen)
- uLong sourceLen;
-{
- return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
-}
diff --git a/dep/StormLib/src/zlib/crc32.c b/dep/StormLib/src/zlib/crc32.c
deleted file mode 100644
index f658a9ef55e..00000000000
--- a/dep/StormLib/src/zlib/crc32.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- *
- * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
- * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
- * tables for updating the shift register in one step with three exclusive-ors
- * instead of four steps with four exclusive-ors. This results in about a
- * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
- */
-
-/* @(#) $Id$ */
-
-/*
- Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
- protection on the static variables used to control the first-use generation
- of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
- first call get_crc_table() to initialize the tables before allowing more than
- one thread to use crc32().
- */
-
-#ifdef MAKECRCH
-# include <stdio.h>
-# ifndef DYNAMIC_CRC_TABLE
-# define DYNAMIC_CRC_TABLE
-# endif /* !DYNAMIC_CRC_TABLE */
-#endif /* MAKECRCH */
-
-#include "zutil.h" /* for STDC and FAR definitions */
-
-#define local static
-
-/* Find a four-byte integer type for crc32_little() and crc32_big(). */
-#ifndef NOBYFOUR
-# ifdef STDC /* need ANSI C limits.h to determine sizes */
-# include <limits.h>
-# define BYFOUR
-# if (UINT_MAX == 0xffffffffUL)
- typedef unsigned int u4;
-# else
-# if (ULONG_MAX == 0xffffffffUL)
- typedef unsigned long u4;
-# else
-# if (USHRT_MAX == 0xffffffffUL)
- typedef unsigned short u4;
-# else
-# undef BYFOUR /* can't find a four-byte integer type! */
-# endif
-# endif
-# endif
-# endif /* STDC */
-#endif /* !NOBYFOUR */
-
-/* Definitions for doing the crc four data bytes at a time. */
-#ifdef BYFOUR
-# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
- (((w)&0xff00)<<8)+(((w)&0xff)<<24))
- local unsigned long crc32_little OF((unsigned long,
- const unsigned char FAR *, unsigned));
- local unsigned long crc32_big OF((unsigned long,
- const unsigned char FAR *, unsigned));
-# define TBLS 8
-#else
-# define TBLS 1
-#endif /* BYFOUR */
-
-/* Local functions for crc concatenation */
-local unsigned long gf2_matrix_times OF((unsigned long *mat,
- unsigned long vec));
-local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
-
-#ifdef DYNAMIC_CRC_TABLE
-
-local volatile int crc_table_empty = 1;
-local unsigned long FAR crc_table[TBLS][256];
-local void make_crc_table OF((void));
-#ifdef MAKECRCH
- local void write_table OF((FILE *, const unsigned long FAR *));
-#endif /* MAKECRCH */
-/*
- Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
- x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
-
- Polynomials over GF(2) are represented in binary, one bit per coefficient,
- with the lowest powers in the most significant bit. Then adding polynomials
- is just exclusive-or, and multiplying a polynomial by x is a right shift by
- one. If we call the above polynomial p, and represent a byte as the
- polynomial q, also with the lowest power in the most significant bit (so the
- byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
- where a mod b means the remainder after dividing a by b.
-
- This calculation is done using the shift-register method of multiplying and
- taking the remainder. The register is initialized to zero, and for each
- incoming bit, x^32 is added mod p to the register if the bit is a one (where
- x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
- x (which is shifting right by one and adding x^32 mod p if the bit shifted
- out is a one). We start with the highest power (least significant bit) of
- q and repeat for all eight bits of q.
-
- The first table is simply the CRC of all possible eight bit values. This is
- all the information needed to generate CRCs on data a byte at a time for all
- combinations of CRC register values and incoming bytes. The remaining tables
- allow for word-at-a-time CRC calculation for both big-endian and little-
- endian machines, where a word is four bytes.
-*/
-local void make_crc_table()
-{
- unsigned long c;
- int n, k;
- unsigned long poly; /* polynomial exclusive-or pattern */
- /* terms of polynomial defining this crc (except x^32): */
- static volatile int first = 1; /* flag to limit concurrent making */
- static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
-
- /* See if another task is already doing this (not thread-safe, but better
- than nothing -- significantly reduces duration of vulnerability in
- case the advice about DYNAMIC_CRC_TABLE is ignored) */
- if (first) {
- first = 0;
-
- /* make exclusive-or pattern from polynomial (0xedb88320UL) */
- poly = 0UL;
- for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
- poly |= 1UL << (31 - p[n]);
-
- /* generate a crc for every 8-bit value */
- for (n = 0; n < 256; n++) {
- c = (unsigned long)n;
- for (k = 0; k < 8; k++)
- c = c & 1 ? poly ^ (c >> 1) : c >> 1;
- crc_table[0][n] = c;
- }
-
-#ifdef BYFOUR
- /* generate crc for each value followed by one, two, and three zeros,
- and then the byte reversal of those as well as the first table */
- for (n = 0; n < 256; n++) {
- c = crc_table[0][n];
- crc_table[4][n] = REV(c);
- for (k = 1; k < 4; k++) {
- c = crc_table[0][c & 0xff] ^ (c >> 8);
- crc_table[k][n] = c;
- crc_table[k + 4][n] = REV(c);
- }
- }
-#endif /* BYFOUR */
-
- crc_table_empty = 0;
- }
- else { /* not first */
- /* wait for the other guy to finish (not efficient, but rare) */
- while (crc_table_empty)
- ;
- }
-
-#ifdef MAKECRCH
- /* write out CRC tables to crc32.h */
- {
- FILE *out;
-
- out = fopen("crc32.h", "w");
- if (out == NULL) return;
- fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
- fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
- fprintf(out, "local const unsigned long FAR ");
- fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
- write_table(out, crc_table[0]);
-# ifdef BYFOUR
- fprintf(out, "#ifdef BYFOUR\n");
- for (k = 1; k < 8; k++) {
- fprintf(out, " },\n {\n");
- write_table(out, crc_table[k]);
- }
- fprintf(out, "#endif\n");
-# endif /* BYFOUR */
- fprintf(out, " }\n};\n");
- fclose(out);
- }
-#endif /* MAKECRCH */
-}
-
-#ifdef MAKECRCH
-local void write_table(out, table)
- FILE *out;
- const unsigned long FAR *table;
-{
- int n;
-
- for (n = 0; n < 256; n++)
- fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
- n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
-}
-#endif /* MAKECRCH */
-
-#else /* !DYNAMIC_CRC_TABLE */
-/* ========================================================================
- * Tables of CRC-32s of all single-byte values, made by make_crc_table().
- */
-#include "crc32.h"
-#endif /* DYNAMIC_CRC_TABLE */
-
-/* =========================================================================
- * This function can be used by asm versions of crc32()
- */
-const unsigned long FAR * ZEXPORT get_crc_table()
-{
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty)
- make_crc_table();
-#endif /* DYNAMIC_CRC_TABLE */
- return (const unsigned long FAR *)crc_table;
-}
-
-/* ========================================================================= */
-#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
-#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
-
-/* ========================================================================= */
-unsigned long ZEXPORT crc32(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- unsigned len;
-{
- if (buf == Z_NULL) return 0UL;
-
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty)
- make_crc_table();
-#endif /* DYNAMIC_CRC_TABLE */
-
-#ifdef BYFOUR
- if (sizeof(void *) == sizeof(ptrdiff_t)) {
- u4 endian;
-
- endian = 1;
- if (*((unsigned char *)(&endian)))
- return crc32_little(crc, buf, len);
- else
- return crc32_big(crc, buf, len);
- }
-#endif /* BYFOUR */
- crc = crc ^ 0xffffffffUL;
- while (len >= 8) {
- DO8;
- len -= 8;
- }
- if (len) do {
- DO1;
- } while (--len);
- return crc ^ 0xffffffffUL;
-}
-
-#ifdef BYFOUR
-
-/* ========================================================================= */
-#define DOLIT4 c ^= *buf4++; \
- c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
- crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
-#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
-
-/* ========================================================================= */
-local unsigned long crc32_little(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- unsigned len;
-{
- register u4 c;
- register const u4 FAR *buf4;
-
- c = (u4)crc;
- c = ~c;
- while (len && ((ptrdiff_t)buf & 3)) {
- c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
- len--;
- }
-
- buf4 = (const u4 FAR *)(const void FAR *)buf;
- while (len >= 32) {
- DOLIT32;
- len -= 32;
- }
- while (len >= 4) {
- DOLIT4;
- len -= 4;
- }
- buf = (const unsigned char FAR *)buf4;
-
- if (len) do {
- c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
- } while (--len);
- c = ~c;
- return (unsigned long)c;
-}
-
-/* ========================================================================= */
-#define DOBIG4 c ^= *++buf4; \
- c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
- crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
-#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
-
-/* ========================================================================= */
-local unsigned long crc32_big(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- unsigned len;
-{
- register u4 c;
- register const u4 FAR *buf4;
-
- c = REV((u4)crc);
- c = ~c;
- while (len && ((ptrdiff_t)buf & 3)) {
- c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
- len--;
- }
-
- buf4 = (const u4 FAR *)(const void FAR *)buf;
- buf4--;
- while (len >= 32) {
- DOBIG32;
- len -= 32;
- }
- while (len >= 4) {
- DOBIG4;
- len -= 4;
- }
- buf4++;
- buf = (const unsigned char FAR *)buf4;
-
- if (len) do {
- c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
- } while (--len);
- c = ~c;
- return (unsigned long)(REV(c));
-}
-
-#endif /* BYFOUR */
-
-#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
-
-/* ========================================================================= */
-local unsigned long gf2_matrix_times(mat, vec)
- unsigned long *mat;
- unsigned long vec;
-{
- unsigned long sum;
-
- sum = 0;
- while (vec) {
- if (vec & 1)
- sum ^= *mat;
- vec >>= 1;
- mat++;
- }
- return sum;
-}
-
-/* ========================================================================= */
-local void gf2_matrix_square(square, mat)
- unsigned long *square;
- unsigned long *mat;
-{
- int n;
-
- for (n = 0; n < GF2_DIM; n++)
- square[n] = gf2_matrix_times(mat, mat[n]);
-}
-
-/* ========================================================================= */
-uLong ZEXPORT crc32_combine(crc1, crc2, len2)
- uLong crc1;
- uLong crc2;
- z_off_t len2;
-{
- int n;
- unsigned long row;
- unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
- unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
-
- /* degenerate case */
- if (len2 == 0)
- return crc1;
-
- /* put operator for one zero bit in odd */
- odd[0] = 0xedb88320L; /* CRC-32 polynomial */
- row = 1;
- for (n = 1; n < GF2_DIM; n++) {
- odd[n] = row;
- row <<= 1;
- }
-
- /* put operator for two zero bits in even */
- gf2_matrix_square(even, odd);
-
- /* put operator for four zero bits in odd */
- gf2_matrix_square(odd, even);
-
- /* apply len2 zeros to crc1 (first square will put the operator for one
- zero byte, eight zero bits, in even) */
- do {
- /* apply zeros operator for this bit of len2 */
- gf2_matrix_square(even, odd);
- if (len2 & 1)
- crc1 = gf2_matrix_times(even, crc1);
- len2 >>= 1;
-
- /* if no more bits set, then done */
- if (len2 == 0)
- break;
-
- /* another iteration of the loop with odd and even swapped */
- gf2_matrix_square(odd, even);
- if (len2 & 1)
- crc1 = gf2_matrix_times(odd, crc1);
- len2 >>= 1;
-
- /* if no more bits set, then done */
- } while (len2 != 0);
-
- /* return combined crc */
- crc1 ^= crc2;
- return crc1;
-}
diff --git a/dep/StormLib/src/zlib/crc32.h b/dep/StormLib/src/zlib/crc32.h
deleted file mode 100644
index 8053b6117c0..00000000000
--- a/dep/StormLib/src/zlib/crc32.h
+++ /dev/null
@@ -1,441 +0,0 @@
-/* crc32.h -- tables for rapid CRC calculation
- * Generated automatically by crc32.c
- */
-
-local const unsigned long FAR crc_table[TBLS][256] =
-{
- {
- 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
- 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
- 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
- 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
- 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
- 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
- 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
- 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
- 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
- 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
- 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
- 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
- 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
- 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
- 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
- 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
- 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
- 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
- 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
- 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
- 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
- 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
- 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
- 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
- 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
- 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
- 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
- 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
- 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
- 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
- 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
- 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
- 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
- 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
- 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
- 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
- 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
- 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
- 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
- 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
- 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
- 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
- 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
- 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
- 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
- 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
- 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
- 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
- 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
- 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
- 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
- 0x2d02ef8dUL
-#ifdef BYFOUR
- },
- {
- 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
- 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
- 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
- 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
- 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
- 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
- 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
- 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
- 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
- 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
- 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
- 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
- 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
- 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
- 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
- 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
- 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
- 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
- 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
- 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
- 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
- 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
- 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
- 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
- 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
- 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
- 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
- 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
- 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
- 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
- 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
- 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
- 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
- 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
- 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
- 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
- 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
- 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
- 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
- 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
- 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
- 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
- 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
- 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
- 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
- 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
- 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
- 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
- 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
- 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
- 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
- 0x9324fd72UL
- },
- {
- 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
- 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
- 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
- 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
- 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
- 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
- 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
- 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
- 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
- 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
- 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
- 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
- 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
- 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
- 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
- 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
- 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
- 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
- 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
- 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
- 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
- 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
- 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
- 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
- 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
- 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
- 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
- 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
- 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
- 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
- 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
- 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
- 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
- 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
- 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
- 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
- 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
- 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
- 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
- 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
- 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
- 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
- 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
- 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
- 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
- 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
- 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
- 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
- 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
- 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
- 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
- 0xbe9834edUL
- },
- {
- 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
- 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
- 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
- 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
- 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
- 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
- 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
- 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
- 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
- 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
- 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
- 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
- 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
- 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
- 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
- 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
- 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
- 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
- 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
- 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
- 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
- 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
- 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
- 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
- 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
- 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
- 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
- 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
- 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
- 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
- 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
- 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
- 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
- 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
- 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
- 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
- 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
- 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
- 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
- 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
- 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
- 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
- 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
- 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
- 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
- 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
- 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
- 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
- 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
- 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
- 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
- 0xde0506f1UL
- },
- {
- 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
- 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
- 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
- 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
- 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
- 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
- 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
- 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
- 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
- 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
- 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
- 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
- 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
- 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
- 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
- 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
- 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
- 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
- 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
- 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
- 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
- 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
- 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
- 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
- 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
- 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
- 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
- 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
- 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
- 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
- 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
- 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
- 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
- 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
- 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
- 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
- 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
- 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
- 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
- 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
- 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
- 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
- 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
- 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
- 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
- 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
- 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
- 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
- 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
- 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
- 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
- 0x8def022dUL
- },
- {
- 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
- 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
- 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
- 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
- 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
- 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
- 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
- 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
- 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
- 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
- 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
- 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
- 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
- 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
- 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
- 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
- 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
- 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
- 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
- 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
- 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
- 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
- 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
- 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
- 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
- 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
- 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
- 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
- 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
- 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
- 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
- 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
- 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
- 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
- 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
- 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
- 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
- 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
- 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
- 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
- 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
- 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
- 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
- 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
- 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
- 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
- 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
- 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
- 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
- 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
- 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
- 0x72fd2493UL
- },
- {
- 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
- 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
- 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
- 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
- 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
- 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
- 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
- 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
- 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
- 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
- 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
- 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
- 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
- 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
- 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
- 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
- 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
- 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
- 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
- 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
- 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
- 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
- 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
- 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
- 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
- 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
- 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
- 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
- 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
- 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
- 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
- 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
- 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
- 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
- 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
- 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
- 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
- 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
- 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
- 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
- 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
- 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
- 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
- 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
- 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
- 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
- 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
- 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
- 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
- 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
- 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
- 0xed3498beUL
- },
- {
- 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
- 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
- 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
- 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
- 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
- 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
- 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
- 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
- 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
- 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
- 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
- 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
- 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
- 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
- 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
- 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
- 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
- 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
- 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
- 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
- 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
- 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
- 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
- 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
- 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
- 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
- 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
- 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
- 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
- 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
- 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
- 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
- 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
- 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
- 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
- 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
- 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
- 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
- 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
- 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
- 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
- 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
- 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
- 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
- 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
- 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
- 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
- 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
- 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
- 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
- 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
- 0xf10605deUL
-#endif
- }
-};
diff --git a/dep/StormLib/src/zlib/deflate.c b/dep/StormLib/src/zlib/deflate.c
deleted file mode 100644
index 29ce1f64a57..00000000000
--- a/dep/StormLib/src/zlib/deflate.c
+++ /dev/null
@@ -1,1736 +0,0 @@
-/* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * ALGORITHM
- *
- * The "deflation" process depends on being able to identify portions
- * of the input text which are identical to earlier input (within a
- * sliding window trailing behind the input currently being processed).
- *
- * The most straightforward technique turns out to be the fastest for
- * most input files: try all possible matches and select the longest.
- * The key feature of this algorithm is that insertions into the string
- * dictionary are very simple and thus fast, and deletions are avoided
- * completely. Insertions are performed at each input character, whereas
- * string matches are performed only when the previous match ends. So it
- * is preferable to spend more time in matches to allow very fast string
- * insertions and avoid deletions. The matching algorithm for small
- * strings is inspired from that of Rabin & Karp. A brute force approach
- * is used to find longer strings when a small match has been found.
- * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
- * (by Leonid Broukhis).
- * A previous version of this file used a more sophisticated algorithm
- * (by Fiala and Greene) which is guaranteed to run in linear amortized
- * time, but has a larger average cost, uses more memory and is patented.
- * However the F&G algorithm may be faster for some highly redundant
- * files if the parameter max_chain_length (described below) is too large.
- *
- * ACKNOWLEDGEMENTS
- *
- * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
- * I found it in 'freeze' written by Leonid Broukhis.
- * Thanks to many people for bug reports and testing.
- *
- * REFERENCES
- *
- * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
- * Available in http://www.ietf.org/rfc/rfc1951.txt
- *
- * A description of the Rabin and Karp algorithm is given in the book
- * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
- *
- * Fiala,E.R., and Greene,D.H.
- * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
- *
- */
-
-/* @(#) $Id$ */
-
-#include "deflate.h"
-
-const char deflate_copyright[] =
- " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
-/*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-
-/* ===========================================================================
- * Function prototypes.
- */
-typedef enum {
- need_more, /* block not completed, need more input or more output */
- block_done, /* block flush performed */
- finish_started, /* finish started, need only more output at next deflate */
- finish_done /* finish done, accept no more input or output */
-} block_state;
-
-typedef block_state (*compress_func) OF((deflate_state *s, int flush));
-/* Compression function. Returns the block state after the call. */
-
-local void fill_window OF((deflate_state *s));
-local block_state deflate_stored OF((deflate_state *s, int flush));
-local block_state deflate_fast OF((deflate_state *s, int flush));
-#ifndef FASTEST
-local block_state deflate_slow OF((deflate_state *s, int flush));
-#endif
-local void lm_init OF((deflate_state *s));
-local void putShortMSB OF((deflate_state *s, uInt b));
-local void flush_pending OF((z_streamp strm));
-local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
-#ifndef FASTEST
-#ifdef ASMV
- void match_init OF((void)); /* asm code initialization */
- uInt longest_match OF((deflate_state *s, IPos cur_match));
-#else
-local uInt longest_match OF((deflate_state *s, IPos cur_match));
-#endif
-#endif
-local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
-
-#ifdef DEBUG
-local void check_match OF((deflate_state *s, IPos start, IPos match,
- int length));
-#endif
-
-/* ===========================================================================
- * Local data
- */
-
-#define NIL 0
-/* Tail of hash chains */
-
-#ifndef TOO_FAR
-# define TOO_FAR 4096
-#endif
-/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-/* Values for max_lazy_match, good_match and max_chain_length, depending on
- * the desired pack level (0..9). The values given below have been tuned to
- * exclude worst case performance for pathological files. Better values may be
- * found for specific files.
- */
-typedef struct config_s {
- ush good_length; /* reduce lazy search above this match length */
- ush max_lazy; /* do not perform lazy search above this match length */
- ush nice_length; /* quit search above this match length */
- ush max_chain;
- compress_func func;
-} config;
-
-#ifdef FASTEST
-local const config configuration_table[2] = {
-/* good lazy nice chain */
-/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
-/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
-#else
-local const config configuration_table[10] = {
-/* good lazy nice chain */
-/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
-/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
-/* 2 */ {4, 5, 16, 8, deflate_fast},
-/* 3 */ {4, 6, 32, 32, deflate_fast},
-
-/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
-/* 5 */ {8, 16, 32, 32, deflate_slow},
-/* 6 */ {8, 16, 128, 128, deflate_slow},
-/* 7 */ {8, 32, 128, 256, deflate_slow},
-/* 8 */ {32, 128, 258, 1024, deflate_slow},
-/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
-#endif
-
-/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
- * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
- * meaning.
- */
-
-#define EQUAL 0
-/* result of memcmp for equal strings */
-
-#ifndef NO_DUMMY_DECL
-struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
-#endif
-
-/* ===========================================================================
- * Update a hash value with the given input byte
- * IN assertion: all calls to to UPDATE_HASH are made with consecutive
- * input characters, so that a running hash key can be computed from the
- * previous key instead of complete recalculation each time.
- */
-#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
-
-
-/* ===========================================================================
- * Insert string str in the dictionary and set match_head to the previous head
- * of the hash chain (the most recent string with same hash key). Return
- * the previous length of the hash chain.
- * If this file is compiled with -DFASTEST, the compression level is forced
- * to 1, and no hash chains are maintained.
- * IN assertion: all calls to to INSERT_STRING are made with consecutive
- * input characters and the first MIN_MATCH bytes of str are valid
- * (except for the last MIN_MATCH-1 bytes of the input file).
- */
-#ifdef FASTEST
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- match_head = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#else
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#endif
-
-/* ===========================================================================
- * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
- * prev[] will be initialized on the fly.
- */
-#define CLEAR_HASH(s) \
- s->head[s->hash_size-1] = NIL; \
- zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
-
-/* ========================================================================= */
-int ZEXPORT deflateInit_(strm, level, version, stream_size)
- z_streamp strm;
- int level;
- const char *version;
- int stream_size;
-{
- return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
- Z_DEFAULT_STRATEGY, version, stream_size);
- /* To do: ignore strm->next_in if we use it as window */
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
- version, stream_size)
- z_streamp strm;
- int level;
- int method;
- int windowBits;
- int memLevel;
- int strategy;
- const char *version;
- int stream_size;
-{
- deflate_state *s;
- int wrap = 1;
- static const char my_version[] = ZLIB_VERSION;
-
- ushf *overlay;
- /* We overlay pending_buf and d_buf+l_buf. This works since the average
- * output size for (length,distance) codes is <= 24 bits.
- */
-
- if (version == Z_NULL || version[0] != my_version[0] ||
- stream_size != sizeof(z_stream)) {
- return Z_VERSION_ERROR;
- }
- if (strm == Z_NULL) return Z_STREAM_ERROR;
-
- strm->msg = Z_NULL;
- if (strm->zalloc == (alloc_func)0) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
-
-#ifdef FASTEST
- if (level != 0) level = 1;
-#else
- if (level == Z_DEFAULT_COMPRESSION) level = 6;
-#endif
-
- if (windowBits < 0) { /* suppress zlib wrapper */
- wrap = 0;
- windowBits = -windowBits;
- }
-#ifdef GZIP
- else if (windowBits > 15) {
- wrap = 2; /* write gzip wrapper instead */
- windowBits -= 16;
- }
-#endif
- if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
- windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
- strategy < 0 || strategy > Z_FIXED) {
- return Z_STREAM_ERROR;
- }
- if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
- s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
- if (s == Z_NULL) return Z_MEM_ERROR;
- strm->state = (struct internal_state FAR *)s;
- s->strm = strm;
-
- s->wrap = wrap;
- s->gzhead = Z_NULL;
- s->w_bits = windowBits;
- s->w_size = 1 << s->w_bits;
- s->w_mask = s->w_size - 1;
-
- s->hash_bits = memLevel + 7;
- s->hash_size = 1 << s->hash_bits;
- s->hash_mask = s->hash_size - 1;
- s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
-
- s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
- s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
- s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
-
- s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
-
- overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
- s->pending_buf = (uchf *) overlay;
- s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
-
- if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
- s->pending_buf == Z_NULL) {
- s->status = FINISH_STATE;
- strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
- deflateEnd (strm);
- return Z_MEM_ERROR;
- }
- s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
- s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
-
- s->level = level;
- s->strategy = strategy;
- s->method = (Byte)method;
-
- return deflateReset(strm);
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
- z_streamp strm;
- const Bytef *dictionary;
- uInt dictLength;
-{
- deflate_state *s;
- uInt length = dictLength;
- uInt n;
- IPos hash_head = 0;
-
- if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
- strm->state->wrap == 2 ||
- (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
- return Z_STREAM_ERROR;
-
- s = strm->state;
- if (s->wrap)
- strm->adler = adler32(strm->adler, dictionary, dictLength);
-
- if (length < MIN_MATCH) return Z_OK;
- if (length > MAX_DIST(s)) {
- length = MAX_DIST(s);
- dictionary += dictLength - length; /* use the tail of the dictionary */
- }
- zmemcpy(s->window, dictionary, length);
- s->strstart = length;
- s->block_start = (long)length;
-
- /* Insert all strings in the hash table (except for the last two bytes).
- * s->lookahead stays null, so s->ins_h will be recomputed at the next
- * call of fill_window.
- */
- s->ins_h = s->window[0];
- UPDATE_HASH(s, s->ins_h, s->window[1]);
- for (n = 0; n <= length - MIN_MATCH; n++) {
- INSERT_STRING(s, n, hash_head);
- }
- if (hash_head) hash_head = 0; /* to make compiler happy */
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateReset (strm)
- z_streamp strm;
-{
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
- return Z_STREAM_ERROR;
- }
-
- strm->total_in = strm->total_out = 0;
- strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
- strm->data_type = Z_UNKNOWN;
-
- s = (deflate_state *)strm->state;
- s->pending = 0;
- s->pending_out = s->pending_buf;
-
- if (s->wrap < 0) {
- s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
- }
- s->status = s->wrap ? INIT_STATE : BUSY_STATE;
- strm->adler =
-#ifdef GZIP
- s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
-#endif
- adler32(0L, Z_NULL, 0);
- s->last_flush = Z_NO_FLUSH;
-
- _tr_init(s);
- lm_init(s);
-
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateSetHeader (strm, head)
- z_streamp strm;
- gz_headerp head;
-{
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- if (strm->state->wrap != 2) return Z_STREAM_ERROR;
- strm->state->gzhead = head;
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflatePrime (strm, bits, value)
- z_streamp strm;
- int bits;
- int value;
-{
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- strm->state->bi_valid = bits;
- strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateParams(strm, level, strategy)
- z_streamp strm;
- int level;
- int strategy;
-{
- deflate_state *s;
- compress_func func;
- int err = Z_OK;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- s = strm->state;
-
-#ifdef FASTEST
- if (level != 0) level = 1;
-#else
- if (level == Z_DEFAULT_COMPRESSION) level = 6;
-#endif
- if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
- return Z_STREAM_ERROR;
- }
- func = configuration_table[s->level].func;
-
- if (func != configuration_table[level].func && strm->total_in != 0) {
- /* Flush the last buffer: */
- err = deflate(strm, Z_PARTIAL_FLUSH);
- }
- if (s->level != level) {
- s->level = level;
- s->max_lazy_match = configuration_table[level].max_lazy;
- s->good_match = configuration_table[level].good_length;
- s->nice_match = configuration_table[level].nice_length;
- s->max_chain_length = configuration_table[level].max_chain;
- }
- s->strategy = strategy;
- return err;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
- z_streamp strm;
- int good_length;
- int max_lazy;
- int nice_length;
- int max_chain;
-{
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- s = strm->state;
- s->good_match = good_length;
- s->max_lazy_match = max_lazy;
- s->nice_match = nice_length;
- s->max_chain_length = max_chain;
- return Z_OK;
-}
-
-/* =========================================================================
- * For the default windowBits of 15 and memLevel of 8, this function returns
- * a close to exact, as well as small, upper bound on the compressed size.
- * They are coded as constants here for a reason--if the #define's are
- * changed, then this function needs to be changed as well. The return
- * value for 15 and 8 only works for those exact settings.
- *
- * For any setting other than those defaults for windowBits and memLevel,
- * the value returned is a conservative worst case for the maximum expansion
- * resulting from using fixed blocks instead of stored blocks, which deflate
- * can emit on compressed data for some combinations of the parameters.
- *
- * This function could be more sophisticated to provide closer upper bounds
- * for every combination of windowBits and memLevel, as well as wrap.
- * But even the conservative upper bound of about 14% expansion does not
- * seem onerous for output buffer allocation.
- */
-uLong ZEXPORT deflateBound(strm, sourceLen)
- z_streamp strm;
- uLong sourceLen;
-{
- deflate_state *s;
- uLong destLen;
-
- /* conservative upper bound */
- destLen = sourceLen +
- ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
-
- /* if can't get parameters, return conservative bound */
- if (strm == Z_NULL || strm->state == Z_NULL)
- return destLen;
-
- /* if not default parameters, return conservative bound */
- s = strm->state;
- if (s->w_bits != 15 || s->hash_bits != 8 + 7)
- return destLen;
-
- /* default settings: return tight bound for that case */
- return compressBound(sourceLen);
-}
-
-/* =========================================================================
- * Put a short in the pending buffer. The 16-bit value is put in MSB order.
- * IN assertion: the stream state is correct and there is enough room in
- * pending_buf.
- */
-local void putShortMSB (s, b)
- deflate_state *s;
- uInt b;
-{
- put_byte(s, (Byte)(b >> 8));
- put_byte(s, (Byte)(b & 0xff));
-}
-
-/* =========================================================================
- * Flush as much pending output as possible. All deflate() output goes
- * through this function so some applications may wish to modify it
- * to avoid allocating a large strm->next_out buffer and copying into it.
- * (See also read_buf()).
- */
-local void flush_pending(strm)
- z_streamp strm;
-{
- unsigned len = strm->state->pending;
-
- if (len > strm->avail_out) len = strm->avail_out;
- if (len == 0) return;
-
- zmemcpy(strm->next_out, strm->state->pending_out, len);
- strm->next_out += len;
- strm->state->pending_out += len;
- strm->total_out += len;
- strm->avail_out -= len;
- strm->state->pending -= len;
- if (strm->state->pending == 0) {
- strm->state->pending_out = strm->state->pending_buf;
- }
-}
-
-/* ========================================================================= */
-int ZEXPORT deflate (strm, flush)
- z_streamp strm;
- int flush;
-{
- int old_flush; /* value of flush param for previous deflate call */
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- flush > Z_FINISH || flush < 0) {
- return Z_STREAM_ERROR;
- }
- s = strm->state;
-
- if (strm->next_out == Z_NULL ||
- (strm->next_in == Z_NULL && strm->avail_in != 0) ||
- (s->status == FINISH_STATE && flush != Z_FINISH)) {
- ERR_RETURN(strm, Z_STREAM_ERROR);
- }
- if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
-
- s->strm = strm; /* just in case */
- old_flush = s->last_flush;
- s->last_flush = flush;
-
- /* Write the header */
- if (s->status == INIT_STATE) {
-#ifdef GZIP
- if (s->wrap == 2) {
- strm->adler = crc32(0L, Z_NULL, 0);
- put_byte(s, 31);
- put_byte(s, 139);
- put_byte(s, 8);
- if (s->gzhead == NULL) {
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, s->level == 9 ? 2 :
- (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
- 4 : 0));
- put_byte(s, OS_CODE);
- s->status = BUSY_STATE;
- }
- else {
- put_byte(s, (s->gzhead->text ? 1 : 0) +
- (s->gzhead->hcrc ? 2 : 0) +
- (s->gzhead->extra == Z_NULL ? 0 : 4) +
- (s->gzhead->name == Z_NULL ? 0 : 8) +
- (s->gzhead->comment == Z_NULL ? 0 : 16)
- );
- put_byte(s, (Byte)(s->gzhead->time & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
- put_byte(s, s->level == 9 ? 2 :
- (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
- 4 : 0));
- put_byte(s, s->gzhead->os & 0xff);
- if (s->gzhead->extra != NULL) {
- put_byte(s, s->gzhead->extra_len & 0xff);
- put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
- }
- if (s->gzhead->hcrc)
- strm->adler = crc32(strm->adler, s->pending_buf,
- s->pending);
- s->gzindex = 0;
- s->status = EXTRA_STATE;
- }
- }
- else
-#endif
- {
- uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
- uInt level_flags;
-
- if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
- level_flags = 0;
- else if (s->level < 6)
- level_flags = 1;
- else if (s->level == 6)
- level_flags = 2;
- else
- level_flags = 3;
- header |= (level_flags << 6);
- if (s->strstart != 0) header |= PRESET_DICT;
- header += 31 - (header % 31);
-
- s->status = BUSY_STATE;
- putShortMSB(s, header);
-
- /* Save the adler32 of the preset dictionary: */
- if (s->strstart != 0) {
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- }
- strm->adler = adler32(0L, Z_NULL, 0);
- }
- }
-#ifdef GZIP
- if (s->status == EXTRA_STATE) {
- if (s->gzhead->extra != NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
-
- while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
- if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size)
- break;
- }
- put_byte(s, s->gzhead->extra[s->gzindex]);
- s->gzindex++;
- }
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (s->gzindex == s->gzhead->extra_len) {
- s->gzindex = 0;
- s->status = NAME_STATE;
- }
- }
- else
- s->status = NAME_STATE;
- }
- if (s->status == NAME_STATE) {
- if (s->gzhead->name != NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
- int val;
-
- do {
- if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size) {
- val = 1;
- break;
- }
- }
- val = s->gzhead->name[s->gzindex++];
- put_byte(s, val);
- } while (val != 0);
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (val == 0) {
- s->gzindex = 0;
- s->status = COMMENT_STATE;
- }
- }
- else
- s->status = COMMENT_STATE;
- }
- if (s->status == COMMENT_STATE) {
- if (s->gzhead->comment != NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
- int val;
-
- do {
- if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size) {
- val = 1;
- break;
- }
- }
- val = s->gzhead->comment[s->gzindex++];
- put_byte(s, val);
- } while (val != 0);
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (val == 0)
- s->status = HCRC_STATE;
- }
- else
- s->status = HCRC_STATE;
- }
- if (s->status == HCRC_STATE) {
- if (s->gzhead->hcrc) {
- if (s->pending + 2 > s->pending_buf_size)
- flush_pending(strm);
- if (s->pending + 2 <= s->pending_buf_size) {
- put_byte(s, (Byte)(strm->adler & 0xff));
- put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
- strm->adler = crc32(0L, Z_NULL, 0);
- s->status = BUSY_STATE;
- }
- }
- else
- s->status = BUSY_STATE;
- }
-#endif
-
- /* Flush as much pending output as possible */
- if (s->pending != 0) {
- flush_pending(strm);
- if (strm->avail_out == 0) {
- /* Since avail_out is 0, deflate will be called again with
- * more output space, but possibly with both pending and
- * avail_in equal to zero. There won't be anything to do,
- * but this is not an error situation so make sure we
- * return OK instead of BUF_ERROR at next call of deflate:
- */
- s->last_flush = -1;
- return Z_OK;
- }
-
- /* Make sure there is something to do and avoid duplicate consecutive
- * flushes. For repeated and useless calls with Z_FINISH, we keep
- * returning Z_STREAM_END instead of Z_BUF_ERROR.
- */
- } else if (strm->avail_in == 0 && flush <= old_flush &&
- flush != Z_FINISH) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* User must not provide more input after the first FINISH: */
- if (s->status == FINISH_STATE && strm->avail_in != 0) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* Start a new block or continue the current one.
- */
- if (strm->avail_in != 0 || s->lookahead != 0 ||
- (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
- block_state bstate;
-
- bstate = (*(configuration_table[s->level].func))(s, flush);
-
- if (bstate == finish_started || bstate == finish_done) {
- s->status = FINISH_STATE;
- }
- if (bstate == need_more || bstate == finish_started) {
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
- }
- return Z_OK;
- /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
- * of deflate should use the same flush parameter to make sure
- * that the flush is complete. So we don't have to output an
- * empty block here, this will be done at next call. This also
- * ensures that for a very small output buffer, we emit at most
- * one empty block.
- */
- }
- if (bstate == block_done) {
- if (flush == Z_PARTIAL_FLUSH) {
- _tr_align(s);
- } else { /* FULL_FLUSH or SYNC_FLUSH */
- _tr_stored_block(s, (char*)0, 0L, 0);
- /* For a full flush, this empty block will be recognized
- * as a special marker by inflate_sync().
- */
- if (flush == Z_FULL_FLUSH) {
- CLEAR_HASH(s); /* forget history */
- }
- }
- flush_pending(strm);
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
- return Z_OK;
- }
- }
- }
- Assert(strm->avail_out > 0, "bug2");
-
- if (flush != Z_FINISH) return Z_OK;
- if (s->wrap <= 0) return Z_STREAM_END;
-
- /* Write the trailer */
-#ifdef GZIP
- if (s->wrap == 2) {
- put_byte(s, (Byte)(strm->adler & 0xff));
- put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
- put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
- put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
- put_byte(s, (Byte)(strm->total_in & 0xff));
- put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
- put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
- put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
- }
- else
-#endif
- {
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- }
- flush_pending(strm);
- /* If avail_out is zero, the application will call deflate again
- * to flush the rest.
- */
- if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
- return s->pending != 0 ? Z_OK : Z_STREAM_END;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateEnd (strm)
- z_streamp strm;
-{
- int status;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-
- status = strm->state->status;
- if (status != INIT_STATE &&
- status != EXTRA_STATE &&
- status != NAME_STATE &&
- status != COMMENT_STATE &&
- status != HCRC_STATE &&
- status != BUSY_STATE &&
- status != FINISH_STATE) {
- return Z_STREAM_ERROR;
- }
-
- /* Deallocate in reverse order of allocations: */
- TRY_FREE(strm, strm->state->pending_buf);
- TRY_FREE(strm, strm->state->head);
- TRY_FREE(strm, strm->state->prev);
- TRY_FREE(strm, strm->state->window);
-
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
-
- return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
-}
-
-/* =========================================================================
- * Copy the source state to the destination state.
- * To simplify the source, this is not supported for 16-bit MSDOS (which
- * doesn't have enough memory anyway to duplicate compression states).
- */
-int ZEXPORT deflateCopy (dest, source)
- z_streamp dest;
- z_streamp source;
-{
-#ifdef MAXSEG_64K
- return Z_STREAM_ERROR;
-#else
- deflate_state *ds;
- deflate_state *ss;
- ushf *overlay;
-
-
- if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
- return Z_STREAM_ERROR;
- }
-
- ss = source->state;
-
- zmemcpy(dest, source, sizeof(z_stream));
-
- ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
- if (ds == Z_NULL) return Z_MEM_ERROR;
- dest->state = (struct internal_state FAR *) ds;
- zmemcpy(ds, ss, sizeof(deflate_state));
- ds->strm = dest;
-
- ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
- ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
- ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
- overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
- ds->pending_buf = (uchf *) overlay;
-
- if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
- ds->pending_buf == Z_NULL) {
- deflateEnd (dest);
- return Z_MEM_ERROR;
- }
- /* following zmemcpy do not work for 16-bit MSDOS */
- zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
- zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
- zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
- zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
-
- ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
- ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
- ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
-
- ds->l_desc.dyn_tree = ds->dyn_ltree;
- ds->d_desc.dyn_tree = ds->dyn_dtree;
- ds->bl_desc.dyn_tree = ds->bl_tree;
-
- return Z_OK;
-#endif /* MAXSEG_64K */
-}
-
-/* ===========================================================================
- * Read a new buffer from the current input stream, update the adler32
- * and total number of bytes read. All deflate() input goes through
- * this function so some applications may wish to modify it to avoid
- * allocating a large strm->next_in buffer and copying from it.
- * (See also flush_pending()).
- */
-local int read_buf(strm, buf, size)
- z_streamp strm;
- Bytef *buf;
- unsigned size;
-{
- unsigned len = strm->avail_in;
-
- if (len > size) len = size;
- if (len == 0) return 0;
-
- strm->avail_in -= len;
-
- if (strm->state->wrap == 1) {
- strm->adler = adler32(strm->adler, strm->next_in, len);
- }
-#ifdef GZIP
- else if (strm->state->wrap == 2) {
- strm->adler = crc32(strm->adler, strm->next_in, len);
- }
-#endif
- zmemcpy(buf, strm->next_in, len);
- strm->next_in += len;
- strm->total_in += len;
-
- return (int)len;
-}
-
-/* ===========================================================================
- * Initialize the "longest match" routines for a new zlib stream
- */
-local void lm_init (s)
- deflate_state *s;
-{
- s->window_size = (ulg)2L*s->w_size;
-
- CLEAR_HASH(s);
-
- /* Set the default configuration parameters:
- */
- s->max_lazy_match = configuration_table[s->level].max_lazy;
- s->good_match = configuration_table[s->level].good_length;
- s->nice_match = configuration_table[s->level].nice_length;
- s->max_chain_length = configuration_table[s->level].max_chain;
-
- s->strstart = 0;
- s->block_start = 0L;
- s->lookahead = 0;
- s->match_length = s->prev_length = MIN_MATCH-1;
- s->match_available = 0;
- s->ins_h = 0;
-#ifndef FASTEST
-#ifdef ASMV
- match_init(); /* initialize the asm code */
-#endif
-#endif
-}
-
-#ifndef FASTEST
-/* ===========================================================================
- * Set match_start to the longest match starting at the given string and
- * return its length. Matches shorter or equal to prev_length are discarded,
- * in which case the result is equal to prev_length and match_start is
- * garbage.
- * IN assertions: cur_match is the head of the hash chain for the current
- * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
- * OUT assertion: the match length is not greater than s->lookahead.
- */
-#ifndef ASMV
-/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
- * match.S. The code will be functionally equivalent.
- */
-local uInt longest_match(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- unsigned chain_length = s->max_chain_length;/* max hash chain length */
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- int best_len = s->prev_length; /* best match length so far */
- int nice_match = s->nice_match; /* stop if match long enough */
- IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
- s->strstart - (IPos)MAX_DIST(s) : NIL;
- /* Stop when cur_match becomes <= limit. To simplify the code,
- * we prevent matches with the string of window index 0.
- */
- Posf *prev = s->prev;
- uInt wmask = s->w_mask;
-
-#ifdef UNALIGNED_OK
- /* Compare two bytes at a time. Note: this is not always beneficial.
- * Try with and without -DUNALIGNED_OK to check.
- */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
- register ush scan_start = *(ushf*)scan;
- register ush scan_end = *(ushf*)(scan+best_len-1);
-#else
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
- register Byte scan_end1 = scan[best_len-1];
- register Byte scan_end = scan[best_len];
-#endif
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- /* Do not waste too much time if we already have a good match: */
- if (s->prev_length >= s->good_match) {
- chain_length >>= 2;
- }
- /* Do not look for matches beyond the end of the input. This is necessary
- * to make deflate deterministic.
- */
- if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- do {
- Assert(cur_match < s->strstart, "no future");
- match = s->window + cur_match;
-
- /* Skip to next match if the match length cannot increase
- * or if the match length is less than 2. Note that the checks below
- * for insufficient lookahead only occur occasionally for performance
- * reasons. Therefore uninitialized memory will be accessed, and
- * conditional jumps will be made that depend on those values.
- * However the length of the match is limited to the lookahead, so
- * the output of deflate is not affected by the uninitialized values.
- */
-#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
- /* This code assumes sizeof(unsigned short) == 2. Do not use
- * UNALIGNED_OK if your compiler uses a different size.
- */
- if (*(ushf*)(match+best_len-1) != scan_end ||
- *(ushf*)match != scan_start) continue;
-
- /* It is not necessary to compare scan[2] and match[2] since they are
- * always equal when the other bytes match, given that the hash keys
- * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
- * strstart+3, +5, ... up to strstart+257. We check for insufficient
- * lookahead only every 4th comparison; the 128th check will be made
- * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
- * necessary to put more guard bytes at the end of the window, or
- * to check more often for insufficient lookahead.
- */
- Assert(scan[2] == match[2], "scan[2]?");
- scan++, match++;
- do {
- } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- scan < strend);
- /* The funny "do {}" generates better code on most compilers */
-
- /* Here, scan <= window+strstart+257 */
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
- if (*scan == *match) scan++;
-
- len = (MAX_MATCH - 1) - (int)(strend-scan);
- scan = strend - (MAX_MATCH-1);
-
-#else /* UNALIGNED_OK */
-
- if (match[best_len] != scan_end ||
- match[best_len-1] != scan_end1 ||
- *match != *scan ||
- *++match != scan[1]) continue;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match++;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
- scan = strend - MAX_MATCH;
-
-#endif /* UNALIGNED_OK */
-
- if (len > best_len) {
- s->match_start = cur_match;
- best_len = len;
- if (len >= nice_match) break;
-#ifdef UNALIGNED_OK
- scan_end = *(ushf*)(scan+best_len-1);
-#else
- scan_end1 = scan[best_len-1];
- scan_end = scan[best_len];
-#endif
- }
- } while ((cur_match = prev[cur_match & wmask]) > limit
- && --chain_length != 0);
-
- if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
- return s->lookahead;
-}
-#endif /* ASMV */
-#endif /* FASTEST */
-
-/* ---------------------------------------------------------------------------
- * Optimized version for level == 1 or strategy == Z_RLE only
- */
-local uInt longest_match_fast(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- Assert(cur_match < s->strstart, "no future");
-
- match = s->window + cur_match;
-
- /* Return failure if the match length is less than 2:
- */
- if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match += 2;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
-
- if (len < MIN_MATCH) return MIN_MATCH - 1;
-
- s->match_start = cur_match;
- return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
-}
-
-#ifdef DEBUG
-/* ===========================================================================
- * Check that the match at match_start is indeed a match.
- */
-local void check_match(s, start, match, length)
- deflate_state *s;
- IPos start, match;
- int length;
-{
- /* check that the match is indeed a match */
- if (zmemcmp(s->window + match,
- s->window + start, length) != EQUAL) {
- fprintf(stderr, " start %u, match %u, length %d\n",
- start, match, length);
- do {
- fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
- } while (--length != 0);
- z_error("invalid match");
- }
- if (z_verbose > 1) {
- fprintf(stderr,"\\[%d,%d]", start-match, length);
- do { putc(s->window[start++], stderr); } while (--length != 0);
- }
-}
-#else
-# define check_match(s, start, match, length)
-#endif /* DEBUG */
-
-/* ===========================================================================
- * Fill the window when the lookahead becomes insufficient.
- * Updates strstart and lookahead.
- *
- * IN assertion: lookahead < MIN_LOOKAHEAD
- * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
- * At least one byte has been read, or avail_in == 0; reads are
- * performed for at least two bytes (required for the zip translate_eol
- * option -- not supported here).
- */
-local void fill_window(s)
- deflate_state *s;
-{
- register unsigned n, m;
- register Posf *p;
- unsigned more; /* Amount of free space at the end of the window. */
- uInt wsize = s->w_size;
-
- do {
- more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
-
- /* Deal with !@#$% 64K limit: */
- if (sizeof(int) <= 2) {
- if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
- more = wsize;
-
- } else if (more == (unsigned)(-1)) {
- /* Very unlikely, but possible on 16 bit machine if
- * strstart == 0 && lookahead == 1 (input done a byte at time)
- */
- more--;
- }
- }
-
- /* If the window is almost full and there is insufficient lookahead,
- * move the upper half to the lower one to make room in the upper half.
- */
- if (s->strstart >= wsize+MAX_DIST(s)) {
-
- zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
- s->match_start -= wsize;
- s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
- s->block_start -= (long) wsize;
-
- /* Slide the hash table (could be avoided with 32 bit values
- at the expense of memory usage). We slide even when level == 0
- to keep the hash table consistent if we switch back to level > 0
- later. (Using level 0 permanently is not an optimal usage of
- zlib, so we don't care about this pathological case.)
- */
- /* %%% avoid this when Z_RLE */
- n = s->hash_size;
- p = &s->head[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- } while (--n);
-
- n = wsize;
-#ifndef FASTEST
- p = &s->prev[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- /* If n is not on any hash chain, prev[n] is garbage but
- * its value will never be used.
- */
- } while (--n);
-#endif
- more += wsize;
- }
- if (s->strm->avail_in == 0) return;
-
- /* If there was no sliding:
- * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
- * more == window_size - lookahead - strstart
- * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
- * => more >= window_size - 2*WSIZE + 2
- * In the BIG_MEM or MMAP case (not yet supported),
- * window_size == input_size + MIN_LOOKAHEAD &&
- * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
- * Otherwise, window_size == 2*WSIZE so more >= 2.
- * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
- */
- Assert(more >= 2, "more < 2");
-
- n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
- s->lookahead += n;
-
- /* Initialize the hash value now that we have some input: */
- if (s->lookahead >= MIN_MATCH) {
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
- }
- /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
- * but this is not important since only literal bytes will be emitted.
- */
-
- } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
-}
-
-/* ===========================================================================
- * Flush the current block, with given end-of-file flag.
- * IN assertion: strstart is set to the end of the current match.
- */
-#define FLUSH_BLOCK_ONLY(s, eof) { \
- _tr_flush_block(s, (s->block_start >= 0L ? \
- (charf *)&s->window[(unsigned)s->block_start] : \
- (charf *)Z_NULL), \
- (ulg)((long)s->strstart - s->block_start), \
- (eof)); \
- s->block_start = s->strstart; \
- flush_pending(s->strm); \
- Tracev((stderr,"[FLUSH]")); \
-}
-
-/* Same but force premature exit if necessary. */
-#define FLUSH_BLOCK(s, eof) { \
- FLUSH_BLOCK_ONLY(s, eof); \
- if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
-}
-
-/* ===========================================================================
- * Copy without compression as much as possible from the input stream, return
- * the current block state.
- * This function does not insert new strings in the dictionary since
- * uncompressible data is probably not useful. This function is used
- * only for the level=0 compression option.
- * NOTE: this function should be optimized to avoid extra copying from
- * window to pending_buf.
- */
-local block_state deflate_stored(s, flush)
- deflate_state *s;
- int flush;
-{
- /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
- * to pending_buf_size, and each stored block has a 5 byte header:
- */
- ulg max_block_size = 0xffff;
- ulg max_start;
-
- if (max_block_size > s->pending_buf_size - 5) {
- max_block_size = s->pending_buf_size - 5;
- }
-
- /* Copy as much as possible from input to output: */
- for (;;) {
- /* Fill the window as much as possible: */
- if (s->lookahead <= 1) {
-
- Assert(s->strstart < s->w_size+MAX_DIST(s) ||
- s->block_start >= (long)s->w_size, "slide too late");
-
- fill_window(s);
- if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
-
- if (s->lookahead == 0) break; /* flush the current block */
- }
- Assert(s->block_start >= 0L, "block gone");
-
- s->strstart += s->lookahead;
- s->lookahead = 0;
-
- /* Emit a stored block if pending_buf will be full: */
- max_start = s->block_start + max_block_size;
- if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
- /* strstart == 0 is possible when wraparound on 16-bit machine */
- s->lookahead = (uInt)(s->strstart - max_start);
- s->strstart = (uInt)max_start;
- FLUSH_BLOCK(s, 0);
- }
- /* Flush if we may have to slide, otherwise block_start may become
- * negative and the data will be gone:
- */
- if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
- FLUSH_BLOCK(s, 0);
- }
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-
-/* ===========================================================================
- * Compress as much as possible from the input stream, return the current
- * block state.
- * This function does not perform lazy evaluation of matches and inserts
- * new strings in the dictionary only for unmatched strings or for short
- * matches. It is used only for the fast compression options.
- */
-local block_state deflate_fast(s, flush)
- deflate_state *s;
- int flush;
-{
- IPos hash_head = NIL; /* head of the hash chain */
- int bflush; /* set if current block must be flushed */
-
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- * At this point we have always match_length < MIN_MATCH
- */
- if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
-#ifdef FASTEST
- if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
- (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
- s->match_length = longest_match_fast (s, hash_head);
- }
-#else
- if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
- s->match_length = longest_match (s, hash_head);
- } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
- s->match_length = longest_match_fast (s, hash_head);
- }
-#endif
- /* longest_match() or longest_match_fast() sets match_start */
- }
- if (s->match_length >= MIN_MATCH) {
- check_match(s, s->strstart, s->match_start, s->match_length);
-
- _tr_tally_dist(s, s->strstart - s->match_start,
- s->match_length - MIN_MATCH, bflush);
-
- s->lookahead -= s->match_length;
-
- /* Insert new strings in the hash table only if the match length
- * is not too large. This saves time but degrades compression.
- */
-#ifndef FASTEST
- if (s->match_length <= s->max_insert_length &&
- s->lookahead >= MIN_MATCH) {
- s->match_length--; /* string at strstart already in table */
- do {
- s->strstart++;
- INSERT_STRING(s, s->strstart, hash_head);
- /* strstart never exceeds WSIZE-MAX_MATCH, so there are
- * always MIN_MATCH bytes ahead.
- */
- } while (--s->match_length != 0);
- s->strstart++;
- } else
-#endif
- {
- s->strstart += s->match_length;
- s->match_length = 0;
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
- /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
- * matter since it will be recomputed at next deflate call.
- */
- }
- } else {
- /* No match, output a literal byte */
- Tracevv((stderr,"%c", s->window[s->strstart]));
- _tr_tally_lit (s, s->window[s->strstart], bflush);
- s->lookahead--;
- s->strstart++;
- }
- if (bflush) FLUSH_BLOCK(s, 0);
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-
-#ifndef FASTEST
-/* ===========================================================================
- * Same as above, but achieves better compression. We use a lazy
- * evaluation for matches: a match is finally adopted only if there is
- * no better match at the next window position.
- */
-local block_state deflate_slow(s, flush)
- deflate_state *s;
- int flush;
-{
- IPos hash_head = NIL; /* head of hash chain */
- int bflush; /* set if current block must be flushed */
-
- /* Process the input block. */
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- */
- s->prev_length = s->match_length, s->prev_match = s->match_start;
- s->match_length = MIN_MATCH-1;
-
- if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
- s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
- if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
- s->match_length = longest_match (s, hash_head);
- } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
- s->match_length = longest_match_fast (s, hash_head);
- }
- /* longest_match() or longest_match_fast() sets match_start */
-
- if (s->match_length <= 5 && (s->strategy == Z_FILTERED
-#if TOO_FAR <= 32767
- || (s->match_length == MIN_MATCH &&
- s->strstart - s->match_start > TOO_FAR)
-#endif
- )) {
-
- /* If prev_match is also MIN_MATCH, match_start is garbage
- * but we will ignore the current match anyway.
- */
- s->match_length = MIN_MATCH-1;
- }
- }
- /* If there was a match at the previous step and the current
- * match is not better, output the previous match:
- */
- if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
- uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
- /* Do not insert strings in hash table beyond this. */
-
- check_match(s, s->strstart-1, s->prev_match, s->prev_length);
-
- _tr_tally_dist(s, s->strstart -1 - s->prev_match,
- s->prev_length - MIN_MATCH, bflush);
-
- /* Insert in hash table all strings up to the end of the match.
- * strstart-1 and strstart are already inserted. If there is not
- * enough lookahead, the last two strings are not inserted in
- * the hash table.
- */
- s->lookahead -= s->prev_length-1;
- s->prev_length -= 2;
- do {
- if (++s->strstart <= max_insert) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
- } while (--s->prev_length != 0);
- s->match_available = 0;
- s->match_length = MIN_MATCH-1;
- s->strstart++;
-
- if (bflush) FLUSH_BLOCK(s, 0);
-
- } else if (s->match_available) {
- /* If there was no match at the previous position, output a
- * single literal. If there was a match but the current match
- * is longer, truncate the previous match to a single literal.
- */
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- if (bflush) {
- FLUSH_BLOCK_ONLY(s, 0);
- }
- s->strstart++;
- s->lookahead--;
- if (s->strm->avail_out == 0) return need_more;
- } else {
- /* There is no previous match to compare with, wait for
- * the next step to decide.
- */
- s->match_available = 1;
- s->strstart++;
- s->lookahead--;
- }
- }
- Assert (flush != Z_NO_FLUSH, "no flush?");
- if (s->match_available) {
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- s->match_available = 0;
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-#endif /* FASTEST */
-
-#if 0
-/* ===========================================================================
- * For Z_RLE, simply look for runs of bytes, generate matches only of distance
- * one. Do not maintain a hash table. (It will be regenerated if this run of
- * deflate switches away from Z_RLE.)
- */
-local block_state deflate_rle(s, flush)
- deflate_state *s;
- int flush;
-{
- int bflush; /* set if current block must be flushed */
- uInt run; /* length of run */
- uInt max; /* maximum length of run */
- uInt prev; /* byte at distance one to match */
- Bytef *scan; /* scan for end of run */
-
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the longest encodable run.
- */
- if (s->lookahead < MAX_MATCH) {
- fill_window(s);
- if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* See how many times the previous byte repeats */
- run = 0;
- if (s->strstart > 0) { /* if there is a previous byte, that is */
- max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
- scan = s->window + s->strstart - 1;
- prev = *scan++;
- do {
- if (*scan++ != prev)
- break;
- } while (++run < max);
- }
-
- /* Emit match if have run of MIN_MATCH or longer, else emit literal */
- if (run >= MIN_MATCH) {
- check_match(s, s->strstart, s->strstart - 1, run);
- _tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
- s->lookahead -= run;
- s->strstart += run;
- } else {
- /* No match, output a literal byte */
- Tracevv((stderr,"%c", s->window[s->strstart]));
- _tr_tally_lit (s, s->window[s->strstart], bflush);
- s->lookahead--;
- s->strstart++;
- }
- if (bflush) FLUSH_BLOCK(s, 0);
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-#endif
diff --git a/dep/StormLib/src/zlib/deflate.h b/dep/StormLib/src/zlib/deflate.h
deleted file mode 100644
index 05a5ab3a2c1..00000000000
--- a/dep/StormLib/src/zlib/deflate.h
+++ /dev/null
@@ -1,331 +0,0 @@
-/* deflate.h -- internal compression state
- * Copyright (C) 1995-2004 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id$ */
-
-#ifndef DEFLATE_H
-#define DEFLATE_H
-
-#include "zutil.h"
-
-/* define NO_GZIP when compiling if you want to disable gzip header and
- trailer creation by deflate(). NO_GZIP would be used to avoid linking in
- the crc code when it is not needed. For shared libraries, gzip encoding
- should be left enabled. */
-#ifndef NO_GZIP
-# define GZIP
-#endif
-
-/* ===========================================================================
- * Internal compression state.
- */
-
-#define LENGTH_CODES 29
-/* number of length codes, not counting the special END_BLOCK code */
-
-#define LITERALS 256
-/* number of literal bytes 0..255 */
-
-#define L_CODES (LITERALS+1+LENGTH_CODES)
-/* number of Literal or Length codes, including the END_BLOCK code */
-
-#define D_CODES 30
-/* number of distance codes */
-
-#define BL_CODES 19
-/* number of codes used to transfer the bit lengths */
-
-#define HEAP_SIZE (2*L_CODES+1)
-/* maximum heap size */
-
-#define MAX_BITS 15
-/* All codes must not exceed MAX_BITS bits */
-
-#define INIT_STATE 42
-#define EXTRA_STATE 69
-#define NAME_STATE 73
-#define COMMENT_STATE 91
-#define HCRC_STATE 103
-#define BUSY_STATE 113
-#define FINISH_STATE 666
-/* Stream status */
-
-
-/* Data structure describing a single value and its code string. */
-typedef struct ct_data_s {
- union {
- ush freq; /* frequency count */
- ush code; /* bit string */
- } fc;
- union {
- ush dad; /* father node in Huffman tree */
- ush len; /* length of bit string */
- } dl;
-} FAR ct_data;
-
-#define Freq fc.freq
-#define Code fc.code
-#define Dad dl.dad
-#define Len dl.len
-
-typedef struct static_tree_desc_s static_tree_desc;
-
-typedef struct tree_desc_s {
- ct_data *dyn_tree; /* the dynamic tree */
- int max_code; /* largest code with non zero frequency */
- static_tree_desc *stat_desc; /* the corresponding static tree */
-} FAR tree_desc;
-
-typedef ush Pos;
-typedef Pos FAR Posf;
-typedef unsigned IPos;
-
-/* A Pos is an index in the character window. We use short instead of int to
- * save space in the various tables. IPos is used only for parameter passing.
- */
-
-typedef struct internal_state {
- z_streamp strm; /* pointer back to this zlib stream */
- int status; /* as the name implies */
- Bytef *pending_buf; /* output still pending */
- ulg pending_buf_size; /* size of pending_buf */
- Bytef *pending_out; /* next pending byte to output to the stream */
- uInt pending; /* nb of bytes in the pending buffer */
- int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
- gz_headerp gzhead; /* gzip header information to write */
- uInt gzindex; /* where in extra, name, or comment */
- Byte method; /* STORED (for zip only) or DEFLATED */
- int last_flush; /* value of flush param for previous deflate call */
-
- /* used by deflate.c: */
-
- uInt w_size; /* LZ77 window size (32K by default) */
- uInt w_bits; /* log2(w_size) (8..16) */
- uInt w_mask; /* w_size - 1 */
-
- Bytef *window;
- /* Sliding window. Input bytes are read into the second half of the window,
- * and move to the first half later to keep a dictionary of at least wSize
- * bytes. With this organization, matches are limited to a distance of
- * wSize-MAX_MATCH bytes, but this ensures that IO is always
- * performed with a length multiple of the block size. Also, it limits
- * the window size to 64K, which is quite useful on MSDOS.
- * To do: use the user input buffer as sliding window.
- */
-
- ulg window_size;
- /* Actual size of window: 2*wSize, except when the user input buffer
- * is directly used as sliding window.
- */
-
- Posf *prev;
- /* Link to older string with same hash index. To limit the size of this
- * array to 64K, this link is maintained only for the last 32K strings.
- * An index in this array is thus a window index modulo 32K.
- */
-
- Posf *head; /* Heads of the hash chains or NIL. */
-
- uInt ins_h; /* hash index of string to be inserted */
- uInt hash_size; /* number of elements in hash table */
- uInt hash_bits; /* log2(hash_size) */
- uInt hash_mask; /* hash_size-1 */
-
- uInt hash_shift;
- /* Number of bits by which ins_h must be shifted at each input
- * step. It must be such that after MIN_MATCH steps, the oldest
- * byte no longer takes part in the hash key, that is:
- * hash_shift * MIN_MATCH >= hash_bits
- */
-
- long block_start;
- /* Window position at the beginning of the current output block. Gets
- * negative when the window is moved backwards.
- */
-
- uInt match_length; /* length of best match */
- IPos prev_match; /* previous match */
- int match_available; /* set if previous match exists */
- uInt strstart; /* start of string to insert */
- uInt match_start; /* start of matching string */
- uInt lookahead; /* number of valid bytes ahead in window */
-
- uInt prev_length;
- /* Length of the best match at previous step. Matches not greater than this
- * are discarded. This is used in the lazy match evaluation.
- */
-
- uInt max_chain_length;
- /* To speed up deflation, hash chains are never searched beyond this
- * length. A higher limit improves compression ratio but degrades the
- * speed.
- */
-
- uInt max_lazy_match;
- /* Attempt to find a better match only when the current match is strictly
- * smaller than this value. This mechanism is used only for compression
- * levels >= 4.
- */
-# define max_insert_length max_lazy_match
- /* Insert new strings in the hash table only if the match length is not
- * greater than this length. This saves time but degrades compression.
- * max_insert_length is used only for compression levels <= 3.
- */
-
- int level; /* compression level (1..9) */
- int strategy; /* favor or force Huffman coding*/
-
- uInt good_match;
- /* Use a faster search when the previous match is longer than this */
-
- int nice_match; /* Stop searching when current match exceeds this */
-
- /* used by trees.c: */
- /* Didn't use ct_data typedef below to supress compiler warning */
- struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
- struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
- struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
-
- struct tree_desc_s l_desc; /* desc. for literal tree */
- struct tree_desc_s d_desc; /* desc. for distance tree */
- struct tree_desc_s bl_desc; /* desc. for bit length tree */
-
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
- int heap_len; /* number of elements in the heap */
- int heap_max; /* element of largest frequency */
- /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
- * The same heap array is used to build all trees.
- */
-
- uch depth[2*L_CODES+1];
- /* Depth of each subtree used as tie breaker for trees of equal frequency
- */
-
- uchf *l_buf; /* buffer for literals or lengths */
-
- uInt lit_bufsize;
- /* Size of match buffer for literals/lengths. There are 4 reasons for
- * limiting lit_bufsize to 64K:
- * - frequencies can be kept in 16 bit counters
- * - if compression is not successful for the first block, all input
- * data is still in the window so we can still emit a stored block even
- * when input comes from standard input. (This can also be done for
- * all blocks if lit_bufsize is not greater than 32K.)
- * - if compression is not successful for a file smaller than 64K, we can
- * even emit a stored file instead of a stored block (saving 5 bytes).
- * This is applicable only for zip (not gzip or zlib).
- * - creating new Huffman trees less frequently may not provide fast
- * adaptation to changes in the input data statistics. (Take for
- * example a binary file with poorly compressible code followed by
- * a highly compressible string table.) Smaller buffer sizes give
- * fast adaptation but have of course the overhead of transmitting
- * trees more frequently.
- * - I can't count above 4
- */
-
- uInt last_lit; /* running index in l_buf */
-
- ushf *d_buf;
- /* Buffer for distances. To simplify the code, d_buf and l_buf have
- * the same number of elements. To use different lengths, an extra flag
- * array would be necessary.
- */
-
- ulg opt_len; /* bit length of current block with optimal trees */
- ulg static_len; /* bit length of current block with static trees */
- uInt matches; /* number of string matches in current block */
- int last_eob_len; /* bit length of EOB code for last block */
-
-#ifdef DEBUG
- ulg compressed_len; /* total bit length of compressed file mod 2^32 */
- ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
-#endif
-
- ush bi_buf;
- /* Output buffer. bits are inserted starting at the bottom (least
- * significant bits).
- */
- int bi_valid;
- /* Number of valid bits in bi_buf. All bits above the last valid bit
- * are always zero.
- */
-
-} FAR deflate_state;
-
-/* Output a byte on the stream.
- * IN assertion: there is enough room in pending_buf.
- */
-#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
-
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
-/* In order to simplify the code, particularly on 16 bit machines, match
- * distances are limited to MAX_DIST instead of WSIZE.
- */
-
- /* in trees.c */
-void _tr_init OF((deflate_state *s));
-int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
-void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-void _tr_align OF((deflate_state *s));
-void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-
-#define d_code(dist) \
- ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
-/* Mapping from a distance to a distance code. dist is the distance - 1 and
- * must not have side effects. _dist_code[256] and _dist_code[257] are never
- * used.
- */
-
-#ifndef DEBUG
-/* Inline versions of _tr_tally for speed: */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
- extern uch _length_code[];
- extern uch _dist_code[];
-#else
- extern const uch _length_code[];
- extern const uch _dist_code[];
-#endif
-
-# define _tr_tally_lit(s, c, flush) \
- { uch cc = (c); \
- s->d_buf[s->last_lit] = 0; \
- s->l_buf[s->last_lit++] = cc; \
- s->dyn_ltree[cc].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-# define _tr_tally_dist(s, distance, length, flush) \
- { uch len = (length); \
- ush dist = (distance); \
- s->d_buf[s->last_lit] = dist; \
- s->l_buf[s->last_lit++] = len; \
- dist--; \
- s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
- s->dyn_dtree[d_code(dist)].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-#else
-# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
-# define _tr_tally_dist(s, distance, length, flush) \
- flush = _tr_tally(s, distance, length)
-#endif
-
-#endif /* DEFLATE_H */
diff --git a/dep/StormLib/src/zlib/inffast.c b/dep/StormLib/src/zlib/inffast.c
deleted file mode 100644
index bbee92ed1e6..00000000000
--- a/dep/StormLib/src/zlib/inffast.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/* inffast.c -- fast decoding
- * Copyright (C) 1995-2004 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "inflate.h"
-#include "inffast.h"
-
-#ifndef ASMINF
-
-/* Allow machine dependent optimization for post-increment or pre-increment.
- Based on testing to date,
- Pre-increment preferred for:
- - PowerPC G3 (Adler)
- - MIPS R5000 (Randers-Pehrson)
- Post-increment preferred for:
- - none
- No measurable difference:
- - Pentium III (Anderson)
- - M68060 (Nikl)
- */
-#ifdef POSTINC
-# define OFF 0
-# define PUP(a) *(a)++
-#else
-# define OFF 1
-# define PUP(a) *++(a)
-#endif
-
-/*
- Decode literal, length, and distance codes and write out the resulting
- literal and match bytes until either not enough input or output is
- available, an end-of-block is encountered, or a data error is encountered.
- When large enough input and output buffers are supplied to inflate(), for
- example, a 16K input buffer and a 64K output buffer, more than 95% of the
- inflate execution time is spent in this routine.
-
- Entry assumptions:
-
- state->mode == LEN
- strm->avail_in >= 6
- strm->avail_out >= 258
- start >= strm->avail_out
- state->bits < 8
-
- On return, state->mode is one of:
-
- LEN -- ran out of enough output space or enough available input
- TYPE -- reached end of block code, inflate() to interpret next block
- BAD -- error in block data
-
- Notes:
-
- - The maximum input bits used by a length/distance pair is 15 bits for the
- length code, 5 bits for the length extra, 15 bits for the distance code,
- and 13 bits for the distance extra. This totals 48 bits, or six bytes.
- Therefore if strm->avail_in >= 6, then there is enough input to avoid
- checking for available input while decoding.
-
- - The maximum bytes that a single length/distance pair can output is 258
- bytes, which is the maximum length that can be coded. inflate_fast()
- requires strm->avail_out >= 258 for each loop to avoid checking for
- output space.
- */
-void inflate_fast(strm, start)
-z_streamp strm;
-unsigned start; /* inflate()'s starting value for strm->avail_out */
-{
- struct inflate_state FAR *state;
- unsigned char FAR *in; /* local strm->next_in */
- unsigned char FAR *last; /* while in < last, enough input available */
- unsigned char FAR *out; /* local strm->next_out */
- unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
- unsigned char FAR *end; /* while out < end, enough space available */
-#ifdef INFLATE_STRICT
- unsigned dmax; /* maximum distance from zlib header */
-#endif
- unsigned wsize; /* window size or zero if not using window */
- unsigned whave; /* valid bytes in the window */
- unsigned write; /* window write index */
- unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
- unsigned long hold; /* local strm->hold */
- unsigned bits; /* local strm->bits */
- code const FAR *lcode; /* local strm->lencode */
- code const FAR *dcode; /* local strm->distcode */
- unsigned lmask; /* mask for first level of length codes */
- unsigned dmask; /* mask for first level of distance codes */
- code this; /* retrieved table entry */
- unsigned op; /* code bits, operation, extra bits, or */
- /* window position, window bytes to copy */
- unsigned len; /* match length, unused bytes */
- unsigned dist; /* match distance */
- unsigned char FAR *from; /* where to copy match from */
-
- /* copy state to local variables */
- state = (struct inflate_state FAR *)strm->state;
- in = strm->next_in - OFF;
- last = in + (strm->avail_in - 5);
- out = strm->next_out - OFF;
- beg = out - (start - strm->avail_out);
- end = out + (strm->avail_out - 257);
-#ifdef INFLATE_STRICT
- dmax = state->dmax;
-#endif
- wsize = state->wsize;
- whave = state->whave;
- write = state->write;
- window = state->window;
- hold = state->hold;
- bits = state->bits;
- lcode = state->lencode;
- dcode = state->distcode;
- lmask = (1U << state->lenbits) - 1;
- dmask = (1U << state->distbits) - 1;
-
- /* decode literals and length/distances until end-of-block or not enough
- input data or output space */
- do {
- if (bits < 15) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- this = lcode[hold & lmask];
- dolen:
- op = (unsigned)(this.bits);
- hold >>= op;
- bits -= op;
- op = (unsigned)(this.op);
- if (op == 0) { /* literal */
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", this.val));
- PUP(out) = (unsigned char)(this.val);
- }
- else if (op & 16) { /* length base */
- len = (unsigned)(this.val);
- op &= 15; /* number of extra bits */
- if (op) {
- if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- len += (unsigned)hold & ((1U << op) - 1);
- hold >>= op;
- bits -= op;
- }
- Tracevv((stderr, "inflate: length %u\n", len));
- if (bits < 15) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- this = dcode[hold & dmask];
- dodist:
- op = (unsigned)(this.bits);
- hold >>= op;
- bits -= op;
- op = (unsigned)(this.op);
- if (op & 16) { /* distance base */
- dist = (unsigned)(this.val);
- op &= 15; /* number of extra bits */
- if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- }
- dist += (unsigned)hold & ((1U << op) - 1);
-#ifdef INFLATE_STRICT
- if (dist > dmax) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
-#endif
- hold >>= op;
- bits -= op;
- Tracevv((stderr, "inflate: distance %u\n", dist));
- op = (unsigned)(out - beg); /* max distance in output */
- if (dist > op) { /* see if copy from window */
- op = dist - op; /* distance back in window */
- if (op > whave) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
- from = window - OFF;
- if (write == 0) { /* very common case */
- from += wsize - op;
- if (op < len) { /* some from window */
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = out - dist; /* rest from output */
- }
- }
- else if (write < op) { /* wrap around window */
- from += wsize + write - op;
- op -= write;
- if (op < len) { /* some from end of window */
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = window - OFF;
- if (write < len) { /* some from start of window */
- op = write;
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = out - dist; /* rest from output */
- }
- }
- }
- else { /* contiguous in window */
- from += write - op;
- if (op < len) { /* some from window */
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = out - dist; /* rest from output */
- }
- }
- while (len > 2) {
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- len -= 3;
- }
- if (len) {
- PUP(out) = PUP(from);
- if (len > 1)
- PUP(out) = PUP(from);
- }
- }
- else {
- from = out - dist; /* copy direct from output */
- do { /* minimum length is three */
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- len -= 3;
- } while (len > 2);
- if (len) {
- PUP(out) = PUP(from);
- if (len > 1)
- PUP(out) = PUP(from);
- }
- }
- }
- else if ((op & 64) == 0) { /* 2nd level distance code */
- this = dcode[this.val + (hold & ((1U << op) - 1))];
- goto dodist;
- }
- else {
- strm->msg = (char *)"invalid distance code";
- state->mode = BAD;
- break;
- }
- }
- else if ((op & 64) == 0) { /* 2nd level length code */
- this = lcode[this.val + (hold & ((1U << op) - 1))];
- goto dolen;
- }
- else if (op & 32) { /* end-of-block */
- Tracevv((stderr, "inflate: end of block\n"));
- state->mode = TYPE;
- break;
- }
- else {
- strm->msg = (char *)"invalid literal/length code";
- state->mode = BAD;
- break;
- }
- } while (in < last && out < end);
-
- /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
- len = bits >> 3;
- in -= len;
- bits -= len << 3;
- hold &= (1U << bits) - 1;
-
- /* update state and return */
- strm->next_in = in + OFF;
- strm->next_out = out + OFF;
- strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
- strm->avail_out = (unsigned)(out < end ?
- 257 + (end - out) : 257 - (out - end));
- state->hold = hold;
- state->bits = bits;
- return;
-}
-
-/*
- inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
- - Using bit fields for code structure
- - Different op definition to avoid & for extra bits (do & for table bits)
- - Three separate decoding do-loops for direct, window, and write == 0
- - Special case for distance > 1 copies to do overlapped load and store copy
- - Explicit branch predictions (based on measured branch probabilities)
- - Deferring match copy and interspersed it with decoding subsequent codes
- - Swapping literal/length else
- - Swapping window/direct else
- - Larger unrolled copy loops (three is about right)
- - Moving len -= 3 statement into middle of loop
- */
-
-#endif /* !ASMINF */
diff --git a/dep/StormLib/src/zlib/inffast.h b/dep/StormLib/src/zlib/inffast.h
deleted file mode 100644
index 1e88d2d97b5..00000000000
--- a/dep/StormLib/src/zlib/inffast.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* inffast.h -- header to use inffast.c
- * Copyright (C) 1995-2003 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-void inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/dep/StormLib/src/zlib/inffixed.h b/dep/StormLib/src/zlib/inffixed.h
deleted file mode 100644
index 75ed4b5978d..00000000000
--- a/dep/StormLib/src/zlib/inffixed.h
+++ /dev/null
@@ -1,94 +0,0 @@
- /* inffixed.h -- table for decoding fixed codes
- * Generated automatically by makefixed().
- */
-
- /* WARNING: this file should *not* be used by applications. It
- is part of the implementation of the compression library and
- is subject to change. Applications should only use zlib.h.
- */
-
- static const code lenfix[512] = {
- {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
- {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
- {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
- {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
- {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
- {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
- {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
- {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
- {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
- {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
- {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
- {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
- {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
- {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
- {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
- {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
- {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
- {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
- {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
- {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
- {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
- {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
- {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
- {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
- {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
- {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
- {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
- {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
- {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
- {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
- {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
- {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
- {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
- {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
- {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
- {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
- {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
- {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
- {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
- {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
- {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
- {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
- {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
- {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
- {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
- {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
- {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
- {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
- {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
- {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
- {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
- {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
- {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
- {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
- {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
- {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
- {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
- {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
- {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
- {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
- {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
- {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
- {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
- {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
- {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
- {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
- {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
- {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
- {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
- {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
- {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
- {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
- {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
- {0,9,255}
- };
-
- static const code distfix[32] = {
- {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
- {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
- {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
- {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
- {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
- {22,5,193},{64,5,0}
- };
diff --git a/dep/StormLib/src/zlib/inflate.c b/dep/StormLib/src/zlib/inflate.c
deleted file mode 100644
index 792fdee8e9c..00000000000
--- a/dep/StormLib/src/zlib/inflate.c
+++ /dev/null
@@ -1,1368 +0,0 @@
-/* inflate.c -- zlib decompression
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * Change history:
- *
- * 1.2.beta0 24 Nov 2002
- * - First version -- complete rewrite of inflate to simplify code, avoid
- * creation of window when not needed, minimize use of window when it is
- * needed, make inffast.c even faster, implement gzip decoding, and to
- * improve code readability and style over the previous zlib inflate code
- *
- * 1.2.beta1 25 Nov 2002
- * - Use pointers for available input and output checking in inffast.c
- * - Remove input and output counters in inffast.c
- * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
- * - Remove unnecessary second byte pull from length extra in inffast.c
- * - Unroll direct copy to three copies per loop in inffast.c
- *
- * 1.2.beta2 4 Dec 2002
- * - Change external routine names to reduce potential conflicts
- * - Correct filename to inffixed.h for fixed tables in inflate.c
- * - Make hbuf[] unsigned char to match parameter type in inflate.c
- * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
- * to avoid negation problem on Alphas (64 bit) in inflate.c
- *
- * 1.2.beta3 22 Dec 2002
- * - Add comments on state->bits assertion in inffast.c
- * - Add comments on op field in inftrees.h
- * - Fix bug in reuse of allocated window after inflateReset()
- * - Remove bit fields--back to byte structure for speed
- * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
- * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
- * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
- * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
- * - Use local copies of stream next and avail values, as well as local bit
- * buffer and bit count in inflate()--for speed when inflate_fast() not used
- *
- * 1.2.beta4 1 Jan 2003
- * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
- * - Move a comment on output buffer sizes from inffast.c to inflate.c
- * - Add comments in inffast.c to introduce the inflate_fast() routine
- * - Rearrange window copies in inflate_fast() for speed and simplification
- * - Unroll last copy for window match in inflate_fast()
- * - Use local copies of window variables in inflate_fast() for speed
- * - Pull out common write == 0 case for speed in inflate_fast()
- * - Make op and len in inflate_fast() unsigned for consistency
- * - Add FAR to lcode and dcode declarations in inflate_fast()
- * - Simplified bad distance check in inflate_fast()
- * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
- * source file infback.c to provide a call-back interface to inflate for
- * programs like gzip and unzip -- uses window as output buffer to avoid
- * window copying
- *
- * 1.2.beta5 1 Jan 2003
- * - Improved inflateBack() interface to allow the caller to provide initial
- * input in strm.
- * - Fixed stored blocks bug in inflateBack()
- *
- * 1.2.beta6 4 Jan 2003
- * - Added comments in inffast.c on effectiveness of POSTINC
- * - Typecasting all around to reduce compiler warnings
- * - Changed loops from while (1) or do {} while (1) to for (;;), again to
- * make compilers happy
- * - Changed type of window in inflateBackInit() to unsigned char *
- *
- * 1.2.beta7 27 Jan 2003
- * - Changed many types to unsigned or unsigned short to avoid warnings
- * - Added inflateCopy() function
- *
- * 1.2.0 9 Mar 2003
- * - Changed inflateBack() interface to provide separate opaque descriptors
- * for the in() and out() functions
- * - Changed inflateBack() argument and in_func typedef to swap the length
- * and buffer address return values for the input function
- * - Check next_in and next_out for Z_NULL on entry to inflate()
- *
- * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "inflate.h"
-#include "inffast.h"
-
-#ifdef MAKEFIXED
-# ifndef BUILDFIXED
-# define BUILDFIXED
-# endif
-#endif
-
-/* function prototypes */
-local void fixedtables OF((struct inflate_state FAR *state));
-local int updatewindow OF((z_streamp strm, unsigned out));
-#ifdef BUILDFIXED
- void makefixed OF((void));
-#endif
-local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
- unsigned len));
-
-int ZEXPORT inflateReset(strm)
-z_streamp strm;
-{
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- strm->total_in = strm->total_out = state->total = 0;
- strm->msg = Z_NULL;
- strm->adler = 1; /* to support ill-conceived Java test suite */
- state->mode = HEAD;
- state->last = 0;
- state->havedict = 0;
- state->dmax = 32768U;
- state->head = Z_NULL;
- state->wsize = 0;
- state->whave = 0;
- state->write = 0;
- state->hold = 0;
- state->bits = 0;
- state->lencode = state->distcode = state->next = state->codes;
- Tracev((stderr, "inflate: reset\n"));
- return Z_OK;
-}
-
-int ZEXPORT inflatePrime(strm, bits, value)
-z_streamp strm;
-int bits;
-int value;
-{
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
- value &= (1L << bits) - 1;
- state->hold += value << state->bits;
- state->bits += bits;
- return Z_OK;
-}
-
-int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
-z_streamp strm;
-int windowBits;
-const char *version;
-int stream_size;
-{
- struct inflate_state FAR *state;
-
- if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
- stream_size != (int)(sizeof(z_stream)))
- return Z_VERSION_ERROR;
- if (strm == Z_NULL) return Z_STREAM_ERROR;
- strm->msg = Z_NULL; /* in case we return an error */
- if (strm->zalloc == (alloc_func)0) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
- state = (struct inflate_state FAR *)
- ZALLOC(strm, 1, sizeof(struct inflate_state));
- if (state == Z_NULL) return Z_MEM_ERROR;
- Tracev((stderr, "inflate: allocated\n"));
- strm->state = (struct internal_state FAR *)state;
- if (windowBits < 0) {
- state->wrap = 0;
- windowBits = -windowBits;
- }
- else {
- state->wrap = (windowBits >> 4) + 1;
-#ifdef GUNZIP
- if (windowBits < 48) windowBits &= 15;
-#endif
- }
- if (windowBits < 8 || windowBits > 15) {
- ZFREE(strm, state);
- strm->state = Z_NULL;
- return Z_STREAM_ERROR;
- }
- state->wbits = (unsigned)windowBits;
- state->window = Z_NULL;
- return inflateReset(strm);
-}
-
-int ZEXPORT inflateInit_(strm, version, stream_size)
-z_streamp strm;
-const char *version;
-int stream_size;
-{
- return inflateInit2_(strm, DEF_WBITS, version, stream_size);
-}
-
-/*
- Return state with length and distance decoding tables and index sizes set to
- fixed code decoding. Normally this returns fixed tables from inffixed.h.
- If BUILDFIXED is defined, then instead this routine builds the tables the
- first time it's called, and returns those tables the first time and
- thereafter. This reduces the size of the code by about 2K bytes, in
- exchange for a little execution time. However, BUILDFIXED should not be
- used for threaded applications, since the rewriting of the tables and virgin
- may not be thread-safe.
- */
-local void fixedtables(state)
-struct inflate_state FAR *state;
-{
-#ifdef BUILDFIXED
- static int virgin = 1;
- static code *lenfix, *distfix;
- static code fixed[544];
-
- /* build fixed huffman tables if first call (may not be thread safe) */
- if (virgin) {
- unsigned sym, bits;
- static code *next;
-
- /* literal/length table */
- sym = 0;
- while (sym < 144) state->lens[sym++] = 8;
- while (sym < 256) state->lens[sym++] = 9;
- while (sym < 280) state->lens[sym++] = 7;
- while (sym < 288) state->lens[sym++] = 8;
- next = fixed;
- lenfix = next;
- bits = 9;
- inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
-
- /* distance table */
- sym = 0;
- while (sym < 32) state->lens[sym++] = 5;
- distfix = next;
- bits = 5;
- inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
-
- /* do this just once */
- virgin = 0;
- }
-#else /* !BUILDFIXED */
-# include "inffixed.h"
-#endif /* BUILDFIXED */
- state->lencode = lenfix;
- state->lenbits = 9;
- state->distcode = distfix;
- state->distbits = 5;
-}
-
-#ifdef MAKEFIXED
-#include <stdio.h>
-
-/*
- Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
- defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
- those tables to stdout, which would be piped to inffixed.h. A small program
- can simply call makefixed to do this:
-
- void makefixed(void);
-
- int main(void)
- {
- makefixed();
- return 0;
- }
-
- Then that can be linked with zlib built with MAKEFIXED defined and run:
-
- a.out > inffixed.h
- */
-void makefixed()
-{
- unsigned low, size;
- struct inflate_state state;
-
- fixedtables(&state);
- puts(" /* inffixed.h -- table for decoding fixed codes");
- puts(" * Generated automatically by makefixed().");
- puts(" */");
- puts("");
- puts(" /* WARNING: this file should *not* be used by applications.");
- puts(" It is part of the implementation of this library and is");
- puts(" subject to change. Applications should only use zlib.h.");
- puts(" */");
- puts("");
- size = 1U << 9;
- printf(" static const code lenfix[%u] = {", size);
- low = 0;
- for (;;) {
- if ((low % 7) == 0) printf("\n ");
- printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
- state.lencode[low].val);
- if (++low == size) break;
- putchar(',');
- }
- puts("\n };");
- size = 1U << 5;
- printf("\n static const code distfix[%u] = {", size);
- low = 0;
- for (;;) {
- if ((low % 6) == 0) printf("\n ");
- printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
- state.distcode[low].val);
- if (++low == size) break;
- putchar(',');
- }
- puts("\n };");
-}
-#endif /* MAKEFIXED */
-
-/*
- Update the window with the last wsize (normally 32K) bytes written before
- returning. If window does not exist yet, create it. This is only called
- when a window is already in use, or when output has been written during this
- inflate call, but the end of the deflate stream has not been reached yet.
- It is also called to create a window for dictionary data when a dictionary
- is loaded.
-
- Providing output buffers larger than 32K to inflate() should provide a speed
- advantage, since only the last 32K of output is copied to the sliding window
- upon return from inflate(), and since all distances after the first 32K of
- output will fall in the output data, making match copies simpler and faster.
- The advantage may be dependent on the size of the processor's data caches.
- */
-local int updatewindow(strm, out)
-z_streamp strm;
-unsigned out;
-{
- struct inflate_state FAR *state;
- unsigned copy, dist;
-
- state = (struct inflate_state FAR *)strm->state;
-
- /* if it hasn't been done already, allocate space for the window */
- if (state->window == Z_NULL) {
- state->window = (unsigned char FAR *)
- ZALLOC(strm, 1U << state->wbits,
- sizeof(unsigned char));
- if (state->window == Z_NULL) return 1;
- }
-
- /* if window not in use yet, initialize */
- if (state->wsize == 0) {
- state->wsize = 1U << state->wbits;
- state->write = 0;
- state->whave = 0;
- }
-
- /* copy state->wsize or less output bytes into the circular window */
- copy = out - strm->avail_out;
- if (copy >= state->wsize) {
- zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
- state->write = 0;
- state->whave = state->wsize;
- }
- else {
- dist = state->wsize - state->write;
- if (dist > copy) dist = copy;
- zmemcpy(state->window + state->write, strm->next_out - copy, dist);
- copy -= dist;
- if (copy) {
- zmemcpy(state->window, strm->next_out - copy, copy);
- state->write = copy;
- state->whave = state->wsize;
- }
- else {
- state->write += dist;
- if (state->write == state->wsize) state->write = 0;
- if (state->whave < state->wsize) state->whave += dist;
- }
- }
- return 0;
-}
-
-/* Macros for inflate(): */
-
-/* check function to use adler32() for zlib or crc32() for gzip */
-#ifdef GUNZIP
-# define UPDATE(check, buf, len) \
- (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
-#else
-# define UPDATE(check, buf, len) adler32(check, buf, len)
-#endif
-
-/* check macros for header crc */
-#ifdef GUNZIP
-# define CRC2(check, word) \
- do { \
- hbuf[0] = (unsigned char)(word); \
- hbuf[1] = (unsigned char)((word) >> 8); \
- check = crc32(check, hbuf, 2); \
- } while (0)
-
-# define CRC4(check, word) \
- do { \
- hbuf[0] = (unsigned char)(word); \
- hbuf[1] = (unsigned char)((word) >> 8); \
- hbuf[2] = (unsigned char)((word) >> 16); \
- hbuf[3] = (unsigned char)((word) >> 24); \
- check = crc32(check, hbuf, 4); \
- } while (0)
-#endif
-
-/* Load registers with state in inflate() for speed */
-#define LOAD() \
- do { \
- put = strm->next_out; \
- left = strm->avail_out; \
- next = strm->next_in; \
- have = strm->avail_in; \
- hold = state->hold; \
- bits = state->bits; \
- } while (0)
-
-/* Restore state from registers in inflate() */
-#define RESTORE() \
- do { \
- strm->next_out = put; \
- strm->avail_out = left; \
- strm->next_in = next; \
- strm->avail_in = have; \
- state->hold = hold; \
- state->bits = bits; \
- } while (0)
-
-/* Clear the input bit accumulator */
-#define INITBITS() \
- do { \
- hold = 0; \
- bits = 0; \
- } while (0)
-
-/* Get a byte of input into the bit accumulator, or return from inflate()
- if there is no input available. */
-#define PULLBYTE() \
- do { \
- if (have == 0) goto inf_leave; \
- have--; \
- hold += (unsigned long)(*next++) << bits; \
- bits += 8; \
- } while (0)
-
-/* Assure that there are at least n bits in the bit accumulator. If there is
- not enough available input to do that, then return from inflate(). */
-#define NEEDBITS(n) \
- do { \
- while (bits < (unsigned)(n)) \
- PULLBYTE(); \
- } while (0)
-
-/* Return the low n bits of the bit accumulator (n < 16) */
-#define BITS(n) \
- ((unsigned)hold & ((1U << (n)) - 1))
-
-/* Remove n bits from the bit accumulator */
-#define DROPBITS(n) \
- do { \
- hold >>= (n); \
- bits -= (unsigned)(n); \
- } while (0)
-
-/* Remove zero to seven bits as needed to go to a byte boundary */
-#define BYTEBITS() \
- do { \
- hold >>= bits & 7; \
- bits -= bits & 7; \
- } while (0)
-
-/* Reverse the bytes in a 32-bit value */
-#define REVERSE(q) \
- ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
- (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
-
-/*
- inflate() uses a state machine to process as much input data and generate as
- much output data as possible before returning. The state machine is
- structured roughly as follows:
-
- for (;;) switch (state) {
- ...
- case STATEn:
- if (not enough input data or output space to make progress)
- return;
- ... make progress ...
- state = STATEm;
- break;
- ...
- }
-
- so when inflate() is called again, the same case is attempted again, and
- if the appropriate resources are provided, the machine proceeds to the
- next state. The NEEDBITS() macro is usually the way the state evaluates
- whether it can proceed or should return. NEEDBITS() does the return if
- the requested bits are not available. The typical use of the BITS macros
- is:
-
- NEEDBITS(n);
- ... do something with BITS(n) ...
- DROPBITS(n);
-
- where NEEDBITS(n) either returns from inflate() if there isn't enough
- input left to load n bits into the accumulator, or it continues. BITS(n)
- gives the low n bits in the accumulator. When done, DROPBITS(n) drops
- the low n bits off the accumulator. INITBITS() clears the accumulator
- and sets the number of available bits to zero. BYTEBITS() discards just
- enough bits to put the accumulator on a byte boundary. After BYTEBITS()
- and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
-
- NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
- if there is no input available. The decoding of variable length codes uses
- PULLBYTE() directly in order to pull just enough bytes to decode the next
- code, and no more.
-
- Some states loop until they get enough input, making sure that enough
- state information is maintained to continue the loop where it left off
- if NEEDBITS() returns in the loop. For example, want, need, and keep
- would all have to actually be part of the saved state in case NEEDBITS()
- returns:
-
- case STATEw:
- while (want < need) {
- NEEDBITS(n);
- keep[want++] = BITS(n);
- DROPBITS(n);
- }
- state = STATEx;
- case STATEx:
-
- As shown above, if the next state is also the next case, then the break
- is omitted.
-
- A state may also return if there is not enough output space available to
- complete that state. Those states are copying stored data, writing a
- literal byte, and copying a matching string.
-
- When returning, a "goto inf_leave" is used to update the total counters,
- update the check value, and determine whether any progress has been made
- during that inflate() call in order to return the proper return code.
- Progress is defined as a change in either strm->avail_in or strm->avail_out.
- When there is a window, goto inf_leave will update the window with the last
- output written. If a goto inf_leave occurs in the middle of decompression
- and there is no window currently, goto inf_leave will create one and copy
- output to the window for the next call of inflate().
-
- In this implementation, the flush parameter of inflate() only affects the
- return code (per zlib.h). inflate() always writes as much as possible to
- strm->next_out, given the space available and the provided input--the effect
- documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
- the allocation of and copying into a sliding window until necessary, which
- provides the effect documented in zlib.h for Z_FINISH when the entire input
- stream available. So the only thing the flush parameter actually does is:
- when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
- will return Z_BUF_ERROR if it has not reached the end of the stream.
- */
-
-int ZEXPORT inflate(strm, flush)
-z_streamp strm;
-int flush;
-{
- struct inflate_state FAR *state;
- unsigned char FAR *next; /* next input */
- unsigned char FAR *put; /* next output */
- unsigned have, left; /* available input and output */
- unsigned long hold; /* bit buffer */
- unsigned bits; /* bits in bit buffer */
- unsigned in, out; /* save starting available input and output */
- unsigned copy; /* number of stored or match bytes to copy */
- unsigned char FAR *from; /* where to copy match bytes from */
- code this; /* current decoding table entry */
- code last; /* parent table entry */
- unsigned len; /* length to copy for repeats, bits to drop */
- int ret; /* return code */
-#ifdef GUNZIP
- unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
-#endif
- static const unsigned short order[19] = /* permutation of code lengths */
- {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
- if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
- (strm->next_in == Z_NULL && strm->avail_in != 0))
- return Z_STREAM_ERROR;
-
- state = (struct inflate_state FAR *)strm->state;
- if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
- LOAD();
- in = have;
- out = left;
- ret = Z_OK;
- for (;;)
- switch (state->mode) {
- case HEAD:
- if (state->wrap == 0) {
- state->mode = TYPEDO;
- break;
- }
- NEEDBITS(16);
-#ifdef GUNZIP
- if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
- state->check = crc32(0L, Z_NULL, 0);
- CRC2(state->check, hold);
- INITBITS();
- state->mode = FLAGS;
- break;
- }
- state->flags = 0; /* expect zlib header */
- if (state->head != Z_NULL)
- state->head->done = -1;
- if (!(state->wrap & 1) || /* check if zlib header allowed */
-#else
- if (
-#endif
- ((BITS(8) << 8) + (hold >> 8)) % 31) {
- strm->msg = (char *)"incorrect header check";
- state->mode = BAD;
- break;
- }
- if (BITS(4) != Z_DEFLATED) {
- strm->msg = (char *)"unknown compression method";
- state->mode = BAD;
- break;
- }
- DROPBITS(4);
- len = BITS(4) + 8;
- if (len > state->wbits) {
- strm->msg = (char *)"invalid window size";
- state->mode = BAD;
- break;
- }
- state->dmax = 1U << len;
- Tracev((stderr, "inflate: zlib header ok\n"));
- strm->adler = state->check = adler32(0L, Z_NULL, 0);
- state->mode = hold & 0x200 ? DICTID : TYPE;
- INITBITS();
- break;
-#ifdef GUNZIP
- case FLAGS:
- NEEDBITS(16);
- state->flags = (int)(hold);
- if ((state->flags & 0xff) != Z_DEFLATED) {
- strm->msg = (char *)"unknown compression method";
- state->mode = BAD;
- break;
- }
- if (state->flags & 0xe000) {
- strm->msg = (char *)"unknown header flags set";
- state->mode = BAD;
- break;
- }
- if (state->head != Z_NULL)
- state->head->text = (int)((hold >> 8) & 1);
- if (state->flags & 0x0200) CRC2(state->check, hold);
- INITBITS();
- state->mode = TIME;
- case TIME:
- NEEDBITS(32);
- if (state->head != Z_NULL)
- state->head->time = hold;
- if (state->flags & 0x0200) CRC4(state->check, hold);
- INITBITS();
- state->mode = OS;
- case OS:
- NEEDBITS(16);
- if (state->head != Z_NULL) {
- state->head->xflags = (int)(hold & 0xff);
- state->head->os = (int)(hold >> 8);
- }
- if (state->flags & 0x0200) CRC2(state->check, hold);
- INITBITS();
- state->mode = EXLEN;
- case EXLEN:
- if (state->flags & 0x0400) {
- NEEDBITS(16);
- state->length = (unsigned)(hold);
- if (state->head != Z_NULL)
- state->head->extra_len = (unsigned)hold;
- if (state->flags & 0x0200) CRC2(state->check, hold);
- INITBITS();
- }
- else if (state->head != Z_NULL)
- state->head->extra = Z_NULL;
- state->mode = EXTRA;
- case EXTRA:
- if (state->flags & 0x0400) {
- copy = state->length;
- if (copy > have) copy = have;
- if (copy) {
- if (state->head != Z_NULL &&
- state->head->extra != Z_NULL) {
- len = state->head->extra_len - state->length;
- zmemcpy(state->head->extra + len, next,
- len + copy > state->head->extra_max ?
- state->head->extra_max - len : copy);
- }
- if (state->flags & 0x0200)
- state->check = crc32(state->check, next, copy);
- have -= copy;
- next += copy;
- state->length -= copy;
- }
- if (state->length) goto inf_leave;
- }
- state->length = 0;
- state->mode = NAME;
- case NAME:
- if (state->flags & 0x0800) {
- if (have == 0) goto inf_leave;
- copy = 0;
- do {
- len = (unsigned)(next[copy++]);
- if (state->head != Z_NULL &&
- state->head->name != Z_NULL &&
- state->length < state->head->name_max)
- state->head->name[state->length++] = len;
- } while (len && copy < have);
- if (state->flags & 0x0200)
- state->check = crc32(state->check, next, copy);
- have -= copy;
- next += copy;
- if (len) goto inf_leave;
- }
- else if (state->head != Z_NULL)
- state->head->name = Z_NULL;
- state->length = 0;
- state->mode = COMMENT;
- case COMMENT:
- if (state->flags & 0x1000) {
- if (have == 0) goto inf_leave;
- copy = 0;
- do {
- len = (unsigned)(next[copy++]);
- if (state->head != Z_NULL &&
- state->head->comment != Z_NULL &&
- state->length < state->head->comm_max)
- state->head->comment[state->length++] = len;
- } while (len && copy < have);
- if (state->flags & 0x0200)
- state->check = crc32(state->check, next, copy);
- have -= copy;
- next += copy;
- if (len) goto inf_leave;
- }
- else if (state->head != Z_NULL)
- state->head->comment = Z_NULL;
- state->mode = HCRC;
- case HCRC:
- if (state->flags & 0x0200) {
- NEEDBITS(16);
- if (hold != (state->check & 0xffff)) {
- strm->msg = (char *)"header crc mismatch";
- state->mode = BAD;
- break;
- }
- INITBITS();
- }
- if (state->head != Z_NULL) {
- state->head->hcrc = (int)((state->flags >> 9) & 1);
- state->head->done = 1;
- }
- strm->adler = state->check = crc32(0L, Z_NULL, 0);
- state->mode = TYPE;
- break;
-#endif
- case DICTID:
- NEEDBITS(32);
- strm->adler = state->check = REVERSE(hold);
- INITBITS();
- state->mode = DICT;
- case DICT:
- if (state->havedict == 0) {
- RESTORE();
- return Z_NEED_DICT;
- }
- strm->adler = state->check = adler32(0L, Z_NULL, 0);
- state->mode = TYPE;
- case TYPE:
- if (flush == Z_BLOCK) goto inf_leave;
- case TYPEDO:
- if (state->last) {
- BYTEBITS();
- state->mode = CHECK;
- break;
- }
- NEEDBITS(3);
- state->last = BITS(1);
- DROPBITS(1);
- switch (BITS(2)) {
- case 0: /* stored block */
- Tracev((stderr, "inflate: stored block%s\n",
- state->last ? " (last)" : ""));
- state->mode = STORED;
- break;
- case 1: /* fixed block */
- fixedtables(state);
- Tracev((stderr, "inflate: fixed codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = LEN; /* decode codes */
- break;
- case 2: /* dynamic block */
- Tracev((stderr, "inflate: dynamic codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = TABLE;
- break;
- case 3:
- strm->msg = (char *)"invalid block type";
- state->mode = BAD;
- }
- DROPBITS(2);
- break;
- case STORED:
- BYTEBITS(); /* go to byte boundary */
- NEEDBITS(32);
- if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
- strm->msg = (char *)"invalid stored block lengths";
- state->mode = BAD;
- break;
- }
- state->length = (unsigned)hold & 0xffff;
- Tracev((stderr, "inflate: stored length %u\n",
- state->length));
- INITBITS();
- state->mode = COPY;
- case COPY:
- copy = state->length;
- if (copy) {
- if (copy > have) copy = have;
- if (copy > left) copy = left;
- if (copy == 0) goto inf_leave;
- zmemcpy(put, next, copy);
- have -= copy;
- next += copy;
- left -= copy;
- put += copy;
- state->length -= copy;
- break;
- }
- Tracev((stderr, "inflate: stored end\n"));
- state->mode = TYPE;
- break;
- case TABLE:
- NEEDBITS(14);
- state->nlen = BITS(5) + 257;
- DROPBITS(5);
- state->ndist = BITS(5) + 1;
- DROPBITS(5);
- state->ncode = BITS(4) + 4;
- DROPBITS(4);
-#ifndef PKZIP_BUG_WORKAROUND
- if (state->nlen > 286 || state->ndist > 30) {
- strm->msg = (char *)"too many length or distance symbols";
- state->mode = BAD;
- break;
- }
-#endif
- Tracev((stderr, "inflate: table sizes ok\n"));
- state->have = 0;
- state->mode = LENLENS;
- case LENLENS:
- while (state->have < state->ncode) {
- NEEDBITS(3);
- state->lens[order[state->have++]] = (unsigned short)BITS(3);
- DROPBITS(3);
- }
- while (state->have < 19)
- state->lens[order[state->have++]] = 0;
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 7;
- ret = inflate_table(CODES, state->lens, 19, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid code lengths set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: code lengths ok\n"));
- state->have = 0;
- state->mode = CODELENS;
- case CODELENS:
- while (state->have < state->nlen + state->ndist) {
- for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if (this.val < 16) {
- NEEDBITS(this.bits);
- DROPBITS(this.bits);
- state->lens[state->have++] = this.val;
- }
- else {
- if (this.val == 16) {
- NEEDBITS(this.bits + 2);
- DROPBITS(this.bits);
- if (state->have == 0) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- len = state->lens[state->have - 1];
- copy = 3 + BITS(2);
- DROPBITS(2);
- }
- else if (this.val == 17) {
- NEEDBITS(this.bits + 3);
- DROPBITS(this.bits);
- len = 0;
- copy = 3 + BITS(3);
- DROPBITS(3);
- }
- else {
- NEEDBITS(this.bits + 7);
- DROPBITS(this.bits);
- len = 0;
- copy = 11 + BITS(7);
- DROPBITS(7);
- }
- if (state->have + copy > state->nlen + state->ndist) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- while (copy--)
- state->lens[state->have++] = (unsigned short)len;
- }
- }
-
- /* handle error breaks in while */
- if (state->mode == BAD) break;
-
- /* build code tables */
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 9;
- ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid literal/lengths set";
- state->mode = BAD;
- break;
- }
- state->distcode = (code const FAR *)(state->next);
- state->distbits = 6;
- ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
- &(state->next), &(state->distbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid distances set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: codes ok\n"));
- state->mode = LEN;
- case LEN:
- if (have >= 6 && left >= 258) {
- RESTORE();
- inflate_fast(strm, out);
- LOAD();
- break;
- }
- for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if (this.op && (this.op & 0xf0) == 0) {
- last = this;
- for (;;) {
- this = state->lencode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(this.bits);
- state->length = (unsigned)this.val;
- if ((int)(this.op) == 0) {
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", this.val));
- state->mode = LIT;
- break;
- }
- if (this.op & 32) {
- Tracevv((stderr, "inflate: end of block\n"));
- state->mode = TYPE;
- break;
- }
- if (this.op & 64) {
- strm->msg = (char *)"invalid literal/length code";
- state->mode = BAD;
- break;
- }
- state->extra = (unsigned)(this.op) & 15;
- state->mode = LENEXT;
- case LENEXT:
- if (state->extra) {
- NEEDBITS(state->extra);
- state->length += BITS(state->extra);
- DROPBITS(state->extra);
- }
- Tracevv((stderr, "inflate: length %u\n", state->length));
- state->mode = DIST;
- case DIST:
- for (;;) {
- this = state->distcode[BITS(state->distbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if ((this.op & 0xf0) == 0) {
- last = this;
- for (;;) {
- this = state->distcode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(this.bits);
- if (this.op & 64) {
- strm->msg = (char *)"invalid distance code";
- state->mode = BAD;
- break;
- }
- state->offset = (unsigned)this.val;
- state->extra = (unsigned)(this.op) & 15;
- state->mode = DISTEXT;
- case DISTEXT:
- if (state->extra) {
- NEEDBITS(state->extra);
- state->offset += BITS(state->extra);
- DROPBITS(state->extra);
- }
-#ifdef INFLATE_STRICT
- if (state->offset > state->dmax) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
-#endif
- if (state->offset > state->whave + out - left) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
- Tracevv((stderr, "inflate: distance %u\n", state->offset));
- state->mode = MATCH;
- case MATCH:
- if (left == 0) goto inf_leave;
- copy = out - left;
- if (state->offset > copy) { /* copy from window */
- copy = state->offset - copy;
- if (copy > state->write) {
- copy -= state->write;
- from = state->window + (state->wsize - copy);
- }
- else
- from = state->window + (state->write - copy);
- if (copy > state->length) copy = state->length;
- }
- else { /* copy from output */
- from = put - state->offset;
- copy = state->length;
- }
- if (copy > left) copy = left;
- left -= copy;
- state->length -= copy;
- do {
- *put++ = *from++;
- } while (--copy);
- if (state->length == 0) state->mode = LEN;
- break;
- case LIT:
- if (left == 0) goto inf_leave;
- *put++ = (unsigned char)(state->length);
- left--;
- state->mode = LEN;
- break;
- case CHECK:
- if (state->wrap) {
- NEEDBITS(32);
- out -= left;
- strm->total_out += out;
- state->total += out;
- if (out)
- strm->adler = state->check =
- UPDATE(state->check, put - out, out);
- out = left;
- if ((
-#ifdef GUNZIP
- state->flags ? hold :
-#endif
- REVERSE(hold)) != state->check) {
- strm->msg = (char *)"incorrect data check";
- state->mode = BAD;
- break;
- }
- INITBITS();
- Tracev((stderr, "inflate: check matches trailer\n"));
- }
-#ifdef GUNZIP
- state->mode = LENGTH;
- case LENGTH:
- if (state->wrap && state->flags) {
- NEEDBITS(32);
- if (hold != (state->total & 0xffffffffUL)) {
- strm->msg = (char *)"incorrect length check";
- state->mode = BAD;
- break;
- }
- INITBITS();
- Tracev((stderr, "inflate: length matches trailer\n"));
- }
-#endif
- state->mode = DONE;
- case DONE:
- ret = Z_STREAM_END;
- goto inf_leave;
- case BAD:
- ret = Z_DATA_ERROR;
- goto inf_leave;
- case MEM:
- return Z_MEM_ERROR;
- case SYNC:
- default:
- return Z_STREAM_ERROR;
- }
-
- /*
- Return from inflate(), updating the total counts and the check value.
- If there was no progress during the inflate() call, return a buffer
- error. Call updatewindow() to create and/or update the window state.
- Note: a memory error from inflate() is non-recoverable.
- */
- inf_leave:
- RESTORE();
- if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
- if (updatewindow(strm, out)) {
- state->mode = MEM;
- return Z_MEM_ERROR;
- }
- in -= strm->avail_in;
- out -= strm->avail_out;
- strm->total_in += in;
- strm->total_out += out;
- state->total += out;
- if (state->wrap && out)
- strm->adler = state->check =
- UPDATE(state->check, strm->next_out - out, out);
- strm->data_type = state->bits + (state->last ? 64 : 0) +
- (state->mode == TYPE ? 128 : 0);
- if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
- ret = Z_BUF_ERROR;
- return ret;
-}
-
-int ZEXPORT inflateEnd(strm)
-z_streamp strm;
-{
- struct inflate_state FAR *state;
- if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
- return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (state->window != Z_NULL) ZFREE(strm, state->window);
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
- Tracev((stderr, "inflate: end\n"));
- return Z_OK;
-}
-
-int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
-z_streamp strm;
-const Bytef *dictionary;
-uInt dictLength;
-{
- struct inflate_state FAR *state;
- unsigned long id;
-
- /* check state */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (state->wrap != 0 && state->mode != DICT)
- return Z_STREAM_ERROR;
-
- /* check for correct dictionary id */
- if (state->mode == DICT) {
- id = adler32(0L, Z_NULL, 0);
- id = adler32(id, dictionary, dictLength);
- if (id != state->check)
- return Z_DATA_ERROR;
- }
-
- /* copy dictionary to window */
- if (updatewindow(strm, strm->avail_out)) {
- state->mode = MEM;
- return Z_MEM_ERROR;
- }
- if (dictLength > state->wsize) {
- zmemcpy(state->window, dictionary + dictLength - state->wsize,
- state->wsize);
- state->whave = state->wsize;
- }
- else {
- zmemcpy(state->window + state->wsize - dictLength, dictionary,
- dictLength);
- state->whave = dictLength;
- }
- state->havedict = 1;
- Tracev((stderr, "inflate: dictionary set\n"));
- return Z_OK;
-}
-
-int ZEXPORT inflateGetHeader(strm, head)
-z_streamp strm;
-gz_headerp head;
-{
- struct inflate_state FAR *state;
-
- /* check state */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
-
- /* save header structure */
- state->head = head;
- head->done = 0;
- return Z_OK;
-}
-
-/*
- Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
- or when out of input. When called, *have is the number of pattern bytes
- found in order so far, in 0..3. On return *have is updated to the new
- state. If on return *have equals four, then the pattern was found and the
- return value is how many bytes were read including the last byte of the
- pattern. If *have is less than four, then the pattern has not been found
- yet and the return value is len. In the latter case, syncsearch() can be
- called again with more data and the *have state. *have is initialized to
- zero for the first call.
- */
-local unsigned syncsearch(have, buf, len)
-unsigned FAR *have;
-unsigned char FAR *buf;
-unsigned len;
-{
- unsigned got;
- unsigned next;
-
- got = *have;
- next = 0;
- while (next < len && got < 4) {
- if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
- got++;
- else if (buf[next])
- got = 0;
- else
- got = 4 - got;
- next++;
- }
- *have = got;
- return next;
-}
-
-int ZEXPORT inflateSync(strm)
-z_streamp strm;
-{
- unsigned len; /* number of bytes to look at or looked at */
- unsigned long in, out; /* temporary to save total_in and total_out */
- unsigned char buf[4]; /* to restore bit buffer to byte string */
- struct inflate_state FAR *state;
-
- /* check parameters */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
-
- /* if first time, start search in bit buffer */
- if (state->mode != SYNC) {
- state->mode = SYNC;
- state->hold <<= state->bits & 7;
- state->bits -= state->bits & 7;
- len = 0;
- while (state->bits >= 8) {
- buf[len++] = (unsigned char)(state->hold);
- state->hold >>= 8;
- state->bits -= 8;
- }
- state->have = 0;
- syncsearch(&(state->have), buf, len);
- }
-
- /* search available input */
- len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
- strm->avail_in -= len;
- strm->next_in += len;
- strm->total_in += len;
-
- /* return no joy or set up to restart inflate() on a new block */
- if (state->have != 4) return Z_DATA_ERROR;
- in = strm->total_in; out = strm->total_out;
- inflateReset(strm);
- strm->total_in = in; strm->total_out = out;
- state->mode = TYPE;
- return Z_OK;
-}
-
-/*
- Returns true if inflate is currently at the end of a block generated by
- Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
- implementation to provide an additional safety check. PPP uses
- Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
- block. When decompressing, PPP checks that at the end of input packet,
- inflate is waiting for these length bytes.
- */
-int ZEXPORT inflateSyncPoint(strm)
-z_streamp strm;
-{
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- return state->mode == STORED && state->bits == 0;
-}
-
-int ZEXPORT inflateCopy(dest, source)
-z_streamp dest;
-z_streamp source;
-{
- struct inflate_state FAR *state;
- struct inflate_state FAR *copy;
- unsigned char FAR *window;
- unsigned wsize;
-
- /* check input */
- if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
- source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
- return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)source->state;
-
- /* allocate space */
- copy = (struct inflate_state FAR *)
- ZALLOC(source, 1, sizeof(struct inflate_state));
- if (copy == Z_NULL) return Z_MEM_ERROR;
- window = Z_NULL;
- if (state->window != Z_NULL) {
- window = (unsigned char FAR *)
- ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
- if (window == Z_NULL) {
- ZFREE(source, copy);
- return Z_MEM_ERROR;
- }
- }
-
- /* copy state */
- zmemcpy(dest, source, sizeof(z_stream));
- zmemcpy(copy, state, sizeof(struct inflate_state));
- if (state->lencode >= state->codes &&
- state->lencode <= state->codes + ENOUGH - 1) {
- copy->lencode = copy->codes + (state->lencode - state->codes);
- copy->distcode = copy->codes + (state->distcode - state->codes);
- }
- copy->next = copy->codes + (state->next - state->codes);
- if (window != Z_NULL) {
- wsize = 1U << state->wbits;
- zmemcpy(window, state->window, wsize);
- }
- copy->window = window;
- dest->state = (struct internal_state FAR *)copy;
- return Z_OK;
-}
diff --git a/dep/StormLib/src/zlib/inflate.h b/dep/StormLib/src/zlib/inflate.h
deleted file mode 100644
index 07bd3e78a7c..00000000000
--- a/dep/StormLib/src/zlib/inflate.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* inflate.h -- internal inflate state definition
- * Copyright (C) 1995-2004 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* define NO_GZIP when compiling if you want to disable gzip header and
- trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
- the crc code when it is not needed. For shared libraries, gzip decoding
- should be left enabled. */
-#ifndef NO_GZIP
-# define GUNZIP
-#endif
-
-/* Possible inflate modes between inflate() calls */
-typedef enum {
- HEAD, /* i: waiting for magic header */
- FLAGS, /* i: waiting for method and flags (gzip) */
- TIME, /* i: waiting for modification time (gzip) */
- OS, /* i: waiting for extra flags and operating system (gzip) */
- EXLEN, /* i: waiting for extra length (gzip) */
- EXTRA, /* i: waiting for extra bytes (gzip) */
- NAME, /* i: waiting for end of file name (gzip) */
- COMMENT, /* i: waiting for end of comment (gzip) */
- HCRC, /* i: waiting for header crc (gzip) */
- DICTID, /* i: waiting for dictionary check value */
- DICT, /* waiting for inflateSetDictionary() call */
- TYPE, /* i: waiting for type bits, including last-flag bit */
- TYPEDO, /* i: same, but skip check to exit inflate on new block */
- STORED, /* i: waiting for stored size (length and complement) */
- COPY, /* i/o: waiting for input or output to copy stored block */
- TABLE, /* i: waiting for dynamic block table lengths */
- LENLENS, /* i: waiting for code length code lengths */
- CODELENS, /* i: waiting for length/lit and distance code lengths */
- LEN, /* i: waiting for length/lit code */
- LENEXT, /* i: waiting for length extra bits */
- DIST, /* i: waiting for distance code */
- DISTEXT, /* i: waiting for distance extra bits */
- MATCH, /* o: waiting for output space to copy string */
- LIT, /* o: waiting for output space to write literal */
- CHECK, /* i: waiting for 32-bit check value */
- LENGTH, /* i: waiting for 32-bit length (gzip) */
- DONE, /* finished check, done -- remain here until reset */
- BAD, /* got a data error -- remain here until reset */
- MEM, /* got an inflate() memory error -- remain here until reset */
- SYNC /* looking for synchronization bytes to restart inflate() */
-} inflate_mode;
-
-/*
- State transitions between above modes -
-
- (most modes can go to the BAD or MEM mode -- not shown for clarity)
-
- Process header:
- HEAD -> (gzip) or (zlib)
- (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
- NAME -> COMMENT -> HCRC -> TYPE
- (zlib) -> DICTID or TYPE
- DICTID -> DICT -> TYPE
- Read deflate blocks:
- TYPE -> STORED or TABLE or LEN or CHECK
- STORED -> COPY -> TYPE
- TABLE -> LENLENS -> CODELENS -> LEN
- Read deflate codes:
- LEN -> LENEXT or LIT or TYPE
- LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
- LIT -> LEN
- Process trailer:
- CHECK -> LENGTH -> DONE
- */
-
-/* state maintained between inflate() calls. Approximately 7K bytes. */
-struct inflate_state {
- inflate_mode mode; /* current inflate mode */
- int last; /* true if processing last block */
- int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
- int havedict; /* true if dictionary provided */
- int flags; /* gzip header method and flags (0 if zlib) */
- unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
- unsigned long check; /* protected copy of check value */
- unsigned long total; /* protected copy of output count */
- gz_headerp head; /* where to save gzip header information */
- /* sliding window */
- unsigned wbits; /* log base 2 of requested window size */
- unsigned wsize; /* window size or zero if not using window */
- unsigned whave; /* valid bytes in the window */
- unsigned write; /* window write index */
- unsigned char FAR *window; /* allocated sliding window, if needed */
- /* bit accumulator */
- unsigned long hold; /* input bit accumulator */
- unsigned bits; /* number of bits in "in" */
- /* for string and stored block copying */
- unsigned length; /* literal or length of data to copy */
- unsigned offset; /* distance back to copy string from */
- /* for table and code decoding */
- unsigned extra; /* extra bits needed */
- /* fixed and dynamic code tables */
- code const FAR *lencode; /* starting table for length/literal codes */
- code const FAR *distcode; /* starting table for distance codes */
- unsigned lenbits; /* index bits for lencode */
- unsigned distbits; /* index bits for distcode */
- /* dynamic table building */
- unsigned ncode; /* number of code length code lengths */
- unsigned nlen; /* number of length code lengths */
- unsigned ndist; /* number of distance code lengths */
- unsigned have; /* number of code lengths in lens[] */
- code FAR *next; /* next available space in codes[] */
- unsigned short lens[320]; /* temporary storage for code lengths */
- unsigned short work[288]; /* work area for code table building */
- code codes[ENOUGH]; /* space for code tables */
-};
diff --git a/dep/StormLib/src/zlib/inftrees.c b/dep/StormLib/src/zlib/inftrees.c
deleted file mode 100644
index 8a9c13ff03d..00000000000
--- a/dep/StormLib/src/zlib/inftrees.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-
-#define MAXBITS 15
-
-const char inflate_copyright[] =
- " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
-/*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-
-/*
- Build a set of tables to decode the provided canonical Huffman code.
- The code lengths are lens[0..codes-1]. The result starts at *table,
- whose indices are 0..2^bits-1. work is a writable array of at least
- lens shorts, which is used as a work area. type is the type of code
- to be generated, CODES, LENS, or DISTS. On return, zero is success,
- -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
- on return points to the next available entry's address. bits is the
- requested root table index bits, and on return it is the actual root
- table index bits. It will differ if the request is greater than the
- longest code or if it is less than the shortest code.
- */
-int inflate_table(type, lens, codes, table, bits, work)
-codetype type;
-unsigned short FAR *lens;
-unsigned codes;
-code FAR * FAR *table;
-unsigned FAR *bits;
-unsigned short FAR *work;
-{
- unsigned len; /* a code's length in bits */
- unsigned sym; /* index of code symbols */
- unsigned min, max; /* minimum and maximum code lengths */
- unsigned root; /* number of index bits for root table */
- unsigned curr; /* number of index bits for current table */
- unsigned drop; /* code bits to drop for sub-table */
- int left; /* number of prefix codes available */
- unsigned used; /* code entries in table used */
- unsigned huff; /* Huffman code */
- unsigned incr; /* for incrementing code, index */
- unsigned fill; /* index for replicating entries */
- unsigned low; /* low bits for current root entry */
- unsigned mask; /* mask for low root bits */
- code this; /* table entry for duplication */
- code FAR *next; /* next available space in table */
- const unsigned short FAR *base; /* base value table to use */
- const unsigned short FAR *extra; /* extra bits table to use */
- int end; /* use base and extra for symbol > end */
- unsigned short count[MAXBITS+1]; /* number of codes of each length */
- unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
- static const unsigned short lbase[31] = { /* Length codes 257..285 base */
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
- 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
- static const unsigned short lext[31] = { /* Length codes 257..285 extra */
- 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
- 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
- static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
- 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
- 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
- 8193, 12289, 16385, 24577, 0, 0};
- static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
- 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
- 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
- 28, 28, 29, 29, 64, 64};
-
- /*
- Process a set of code lengths to create a canonical Huffman code. The
- code lengths are lens[0..codes-1]. Each length corresponds to the
- symbols 0..codes-1. The Huffman code is generated by first sorting the
- symbols by length from short to long, and retaining the symbol order
- for codes with equal lengths. Then the code starts with all zero bits
- for the first code of the shortest length, and the codes are integer
- increments for the same length, and zeros are appended as the length
- increases. For the deflate format, these bits are stored backwards
- from their more natural integer increment ordering, and so when the
- decoding tables are built in the large loop below, the integer codes
- are incremented backwards.
-
- This routine assumes, but does not check, that all of the entries in
- lens[] are in the range 0..MAXBITS. The caller must assure this.
- 1..MAXBITS is interpreted as that code length. zero means that that
- symbol does not occur in this code.
-
- The codes are sorted by computing a count of codes for each length,
- creating from that a table of starting indices for each length in the
- sorted table, and then entering the symbols in order in the sorted
- table. The sorted table is work[], with that space being provided by
- the caller.
-
- The length counts are used for other purposes as well, i.e. finding
- the minimum and maximum length codes, determining if there are any
- codes at all, checking for a valid set of lengths, and looking ahead
- at length counts to determine sub-table sizes when building the
- decoding tables.
- */
-
- /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
- for (len = 0; len <= MAXBITS; len++)
- count[len] = 0;
- for (sym = 0; sym < codes; sym++)
- count[lens[sym]]++;
-
- /* bound code lengths, force root to be within code lengths */
- root = *bits;
- for (max = MAXBITS; max >= 1; max--)
- if (count[max] != 0) break;
- if (root > max) root = max;
- if (max == 0) { /* no symbols to code at all */
- this.op = (unsigned char)64; /* invalid code marker */
- this.bits = (unsigned char)1;
- this.val = (unsigned short)0;
- *(*table)++ = this; /* make a table to force an error */
- *(*table)++ = this;
- *bits = 1;
- return 0; /* no symbols, but wait for decoding to report error */
- }
- for (min = 1; min <= MAXBITS; min++)
- if (count[min] != 0) break;
- if (root < min) root = min;
-
- /* check for an over-subscribed or incomplete set of lengths */
- left = 1;
- for (len = 1; len <= MAXBITS; len++) {
- left <<= 1;
- left -= count[len];
- if (left < 0) return -1; /* over-subscribed */
- }
- if (left > 0 && (type == CODES || max != 1))
- return -1; /* incomplete set */
-
- /* generate offsets into symbol table for each length for sorting */
- offs[1] = 0;
- for (len = 1; len < MAXBITS; len++)
- offs[len + 1] = offs[len] + count[len];
-
- /* sort symbols by length, by symbol order within each length */
- for (sym = 0; sym < codes; sym++)
- if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
-
- /*
- Create and fill in decoding tables. In this loop, the table being
- filled is at next and has curr index bits. The code being used is huff
- with length len. That code is converted to an index by dropping drop
- bits off of the bottom. For codes where len is less than drop + curr,
- those top drop + curr - len bits are incremented through all values to
- fill the table with replicated entries.
-
- root is the number of index bits for the root table. When len exceeds
- root, sub-tables are created pointed to by the root entry with an index
- of the low root bits of huff. This is saved in low to check for when a
- new sub-table should be started. drop is zero when the root table is
- being filled, and drop is root when sub-tables are being filled.
-
- When a new sub-table is needed, it is necessary to look ahead in the
- code lengths to determine what size sub-table is needed. The length
- counts are used for this, and so count[] is decremented as codes are
- entered in the tables.
-
- used keeps track of how many table entries have been allocated from the
- provided *table space. It is checked when a LENS table is being made
- against the space in *table, ENOUGH, minus the maximum space needed by
- the worst case distance code, MAXD. This should never happen, but the
- sufficiency of ENOUGH has not been proven exhaustively, hence the check.
- This assumes that when type == LENS, bits == 9.
-
- sym increments through all symbols, and the loop terminates when
- all codes of length max, i.e. all codes, have been processed. This
- routine permits incomplete codes, so another loop after this one fills
- in the rest of the decoding tables with invalid code markers.
- */
-
- /* set up for code type */
- switch (type) {
- case CODES:
- base = extra = work; /* dummy value--not used */
- end = 19;
- break;
- case LENS:
- base = lbase;
- base -= 257;
- extra = lext;
- extra -= 257;
- end = 256;
- break;
- default: /* DISTS */
- base = dbase;
- extra = dext;
- end = -1;
- }
-
- /* initialize state for loop */
- huff = 0; /* starting code */
- sym = 0; /* starting code symbol */
- len = min; /* starting code length */
- next = *table; /* current table to fill in */
- curr = root; /* current table index bits */
- drop = 0; /* current bits to drop from code for index */
- low = (unsigned)(-1); /* trigger new sub-table when len > root */
- used = 1U << root; /* use root table entries */
- mask = used - 1; /* mask for comparing low */
-
- /* check available table space */
- if (type == LENS && used >= ENOUGH - MAXD)
- return 1;
-
- /* process all codes and make table entries */
- for (;;) {
- /* create table entry */
- this.bits = (unsigned char)(len - drop);
- if ((int)(work[sym]) < end) {
- this.op = (unsigned char)0;
- this.val = work[sym];
- }
- else if ((int)(work[sym]) > end) {
- this.op = (unsigned char)(extra[work[sym]]);
- this.val = base[work[sym]];
- }
- else {
- this.op = (unsigned char)(32 + 64); /* end of block */
- this.val = 0;
- }
-
- /* replicate for those indices with low len bits equal to huff */
- incr = 1U << (len - drop);
- fill = 1U << curr;
- min = fill; /* save offset to next table */
- do {
- fill -= incr;
- next[(huff >> drop) + fill] = this;
- } while (fill != 0);
-
- /* backwards increment the len-bit code huff */
- incr = 1U << (len - 1);
- while (huff & incr)
- incr >>= 1;
- if (incr != 0) {
- huff &= incr - 1;
- huff += incr;
- }
- else
- huff = 0;
-
- /* go to next symbol, update count, len */
- sym++;
- if (--(count[len]) == 0) {
- if (len == max) break;
- len = lens[work[sym]];
- }
-
- /* create new sub-table if needed */
- if (len > root && (huff & mask) != low) {
- /* if first time, transition to sub-tables */
- if (drop == 0)
- drop = root;
-
- /* increment past last table */
- next += min; /* here min is 1 << curr */
-
- /* determine length of next table */
- curr = len - drop;
- left = (int)(1 << curr);
- while (curr + drop < max) {
- left -= count[curr + drop];
- if (left <= 0) break;
- curr++;
- left <<= 1;
- }
-
- /* check for enough space */
- used += 1U << curr;
- if (type == LENS && used >= ENOUGH - MAXD)
- return 1;
-
- /* point entry in root table to sub-table */
- low = huff & mask;
- (*table)[low].op = (unsigned char)curr;
- (*table)[low].bits = (unsigned char)root;
- (*table)[low].val = (unsigned short)(next - *table);
- }
- }
-
- /*
- Fill in rest of table for incomplete codes. This loop is similar to the
- loop above in incrementing huff for table indices. It is assumed that
- len is equal to curr + drop, so there is no loop needed to increment
- through high index bits. When the current sub-table is filled, the loop
- drops back to the root table to fill in any remaining entries there.
- */
- this.op = (unsigned char)64; /* invalid code marker */
- this.bits = (unsigned char)(len - drop);
- this.val = (unsigned short)0;
- while (huff != 0) {
- /* when done with sub-table, drop back to root table */
- if (drop != 0 && (huff & mask) != low) {
- drop = 0;
- len = root;
- next = *table;
- this.bits = (unsigned char)len;
- }
-
- /* put invalid code marker in table */
- next[huff >> drop] = this;
-
- /* backwards increment the len-bit code huff */
- incr = 1U << (len - 1);
- while (huff & incr)
- incr >>= 1;
- if (incr != 0) {
- huff &= incr - 1;
- huff += incr;
- }
- else
- huff = 0;
- }
-
- /* set return parameters */
- *table += used;
- *bits = root;
- return 0;
-}
diff --git a/dep/StormLib/src/zlib/inftrees.h b/dep/StormLib/src/zlib/inftrees.h
deleted file mode 100644
index b1104c87e76..00000000000
--- a/dep/StormLib/src/zlib/inftrees.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* Structure for decoding tables. Each entry provides either the
- information needed to do the operation requested by the code that
- indexed that table entry, or it provides a pointer to another
- table that indexes more bits of the code. op indicates whether
- the entry is a pointer to another table, a literal, a length or
- distance, an end-of-block, or an invalid code. For a table
- pointer, the low four bits of op is the number of index bits of
- that table. For a length or distance, the low four bits of op
- is the number of extra bits to get after the code. bits is
- the number of bits in this code or part of the code to drop off
- of the bit buffer. val is the actual byte to output in the case
- of a literal, the base length or distance, or the offset from
- the current table to the next table. Each entry is four bytes. */
-typedef struct {
- unsigned char op; /* operation, extra bits, table bits */
- unsigned char bits; /* bits in this part of the code */
- unsigned short val; /* offset in table or code value */
-} code;
-
-/* op values as set by inflate_table():
- 00000000 - literal
- 0000tttt - table link, tttt != 0 is the number of table index bits
- 0001eeee - length or distance, eeee is the number of extra bits
- 01100000 - end of block
- 01000000 - invalid code
- */
-
-/* Maximum size of dynamic tree. The maximum found in a long but non-
- exhaustive search was 1444 code structures (852 for length/literals
- and 592 for distances, the latter actually the result of an
- exhaustive search). The true maximum is not known, but the value
- below is more than safe. */
-#define ENOUGH 2048
-#define MAXD 592
-
-/* Type of code to build for inftable() */
-typedef enum {
- CODES,
- LENS,
- DISTS
-} codetype;
-
-extern int inflate_table OF((codetype type, unsigned short FAR *lens,
- unsigned codes, code FAR * FAR *table,
- unsigned FAR *bits, unsigned short FAR *work));
diff --git a/dep/StormLib/src/zlib/trees.c b/dep/StormLib/src/zlib/trees.c
deleted file mode 100644
index 395e4e16814..00000000000
--- a/dep/StormLib/src/zlib/trees.c
+++ /dev/null
@@ -1,1219 +0,0 @@
-/* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-2005 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * ALGORITHM
- *
- * The "deflation" process uses several Huffman trees. The more
- * common source values are represented by shorter bit sequences.
- *
- * Each code tree is stored in a compressed form which is itself
- * a Huffman encoding of the lengths of all the code strings (in
- * ascending order by source values). The actual code strings are
- * reconstructed from the lengths in the inflate process, as described
- * in the deflate specification.
- *
- * REFERENCES
- *
- * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
- * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
- *
- * Storer, James A.
- * Data Compression: Methods and Theory, pp. 49-50.
- * Computer Science Press, 1988. ISBN 0-7167-8156-5.
- *
- * Sedgewick, R.
- * Algorithms, p290.
- * Addison-Wesley, 1983. ISBN 0-201-06672-6.
- */
-
-/* @(#) $Id$ */
-
-/* #define GEN_TREES_H */
-
-#include "deflate.h"
-
-#ifdef DEBUG
-# include <ctype.h>
-#endif
-
-/* ===========================================================================
- * Constants
- */
-
-#define MAX_BL_BITS 7
-/* Bit length codes must not exceed MAX_BL_BITS bits */
-
-#define END_BLOCK 256
-/* end of block literal code */
-
-#define REP_3_6 16
-/* repeat previous bit length 3-6 times (2 bits of repeat count) */
-
-#define REPZ_3_10 17
-/* repeat a zero length 3-10 times (3 bits of repeat count) */
-
-#define REPZ_11_138 18
-/* repeat a zero length 11-138 times (7 bits of repeat count) */
-
-local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
- = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
-
-local const int extra_dbits[D_CODES] /* extra bits for each distance code */
- = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
-
-local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
- = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
-
-local const uch bl_order[BL_CODES]
- = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
-/* The lengths of the bit length codes are sent in order of decreasing
- * probability, to avoid transmitting the lengths for unused bit length codes.
- */
-
-#define Buf_size (8 * 2*sizeof(char))
-/* Number of bits used within bi_buf. (bi_buf might be implemented on
- * more than 16 bits on some systems.)
- */
-
-/* ===========================================================================
- * Local data. These are initialized only once.
- */
-
-#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
-/* non ANSI compilers may not accept trees.h */
-
-local ct_data static_ltree[L_CODES+2];
-/* The static literal tree. Since the bit lengths are imposed, there is no
- * need for the L_CODES extra codes used during heap construction. However
- * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
- * below).
- */
-
-local ct_data static_dtree[D_CODES];
-/* The static distance tree. (Actually a trivial tree since all codes use
- * 5 bits.)
- */
-
-uch _dist_code[DIST_CODE_LEN];
-/* Distance codes. The first 256 values correspond to the distances
- * 3 .. 258, the last 256 values correspond to the top 8 bits of
- * the 15 bit distances.
- */
-
-uch _length_code[MAX_MATCH-MIN_MATCH+1];
-/* length code for each normalized match length (0 == MIN_MATCH) */
-
-local int base_length[LENGTH_CODES];
-/* First normalized length for each code (0 = MIN_MATCH) */
-
-local int base_dist[D_CODES];
-/* First normalized distance for each code (0 = distance of 1) */
-
-#else
-# include "trees.h"
-#endif /* GEN_TREES_H */
-
-struct static_tree_desc_s {
- const ct_data *static_tree; /* static tree or NULL */
- const intf *extra_bits; /* extra bits for each code or NULL */
- int extra_base; /* base index for extra_bits */
- int elems; /* max number of elements in the tree */
- int max_length; /* max bit length for the codes */
-};
-
-local static_tree_desc static_l_desc =
-{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
-
-local static_tree_desc static_d_desc =
-{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
-
-local static_tree_desc static_bl_desc =
-{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
-
-/* ===========================================================================
- * Local (static) routines in this file.
- */
-
-local void tr_static_init OF((void));
-local void init_block OF((deflate_state *s));
-local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
-local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
-local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
-local void build_tree OF((deflate_state *s, tree_desc *desc));
-local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
-local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
-local int build_bl_tree OF((deflate_state *s));
-local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
- int blcodes));
-local void compress_block OF((deflate_state *s, ct_data *ltree,
- ct_data *dtree));
-local void set_data_type OF((deflate_state *s));
-local unsigned bi_reverse OF((unsigned value, int length));
-local void bi_windup OF((deflate_state *s));
-local void bi_flush OF((deflate_state *s));
-local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
- int header));
-
-#ifdef GEN_TREES_H
-local void gen_trees_header OF((void));
-#endif
-
-#ifndef DEBUG
-# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
- /* Send a code of the given tree. c and tree must not have side effects */
-
-#else /* DEBUG */
-# define send_code(s, c, tree) \
- { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
- send_bits(s, tree[c].Code, tree[c].Len); }
-#endif
-
-/* ===========================================================================
- * Output a short LSB first on the stream.
- * IN assertion: there is enough room in pendingBuf.
- */
-#define put_short(s, w) { \
- put_byte(s, (uch)((w) & 0xff)); \
- put_byte(s, (uch)((ush)(w) >> 8)); \
-}
-
-/* ===========================================================================
- * Send a value on a given number of bits.
- * IN assertion: length <= 16 and value fits in length bits.
- */
-#ifdef DEBUG
-local void send_bits OF((deflate_state *s, int value, int length));
-
-local void send_bits(s, value, length)
- deflate_state *s;
- int value; /* value to send */
- int length; /* number of bits */
-{
- Tracevv((stderr," l %2d v %4x ", length, value));
- Assert(length > 0 && length <= 15, "invalid length");
- s->bits_sent += (ulg)length;
-
- /* If not enough room in bi_buf, use (valid) bits from bi_buf and
- * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
- * unused bits in value.
- */
- if (s->bi_valid > (int)Buf_size - length) {
- s->bi_buf |= (value << s->bi_valid);
- put_short(s, s->bi_buf);
- s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
- s->bi_valid += length - Buf_size;
- } else {
- s->bi_buf |= value << s->bi_valid;
- s->bi_valid += length;
- }
-}
-#else /* !DEBUG */
-
-#define send_bits(s, value, length) \
-{ int len = length;\
- if (s->bi_valid > (int)Buf_size - len) {\
- int val = value;\
- s->bi_buf |= (val << s->bi_valid);\
- put_short(s, s->bi_buf);\
- s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
- s->bi_valid += len - Buf_size;\
- } else {\
- s->bi_buf |= (value) << s->bi_valid;\
- s->bi_valid += len;\
- }\
-}
-#endif /* DEBUG */
-
-
-/* the arguments must not have side effects */
-
-/* ===========================================================================
- * Initialize the various 'constant' tables.
- */
-local void tr_static_init()
-{
-#if defined(GEN_TREES_H) || !defined(STDC)
- static int static_init_done = 0;
- int n; /* iterates over tree elements */
- int bits; /* bit counter */
- int length; /* length value */
- int code; /* code value */
- int dist; /* distance index */
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- if (static_init_done) return;
-
- /* For some embedded targets, global variables are not initialized: */
- static_l_desc.static_tree = static_ltree;
- static_l_desc.extra_bits = extra_lbits;
- static_d_desc.static_tree = static_dtree;
- static_d_desc.extra_bits = extra_dbits;
- static_bl_desc.extra_bits = extra_blbits;
-
- /* Initialize the mapping length (0..255) -> length code (0..28) */
- length = 0;
- for (code = 0; code < LENGTH_CODES-1; code++) {
- base_length[code] = length;
- for (n = 0; n < (1<<extra_lbits[code]); n++) {
- _length_code[length++] = (uch)code;
- }
- }
- Assert (length == 256, "tr_static_init: length != 256");
- /* Note that the length 255 (match length 258) can be represented
- * in two different ways: code 284 + 5 bits or code 285, so we
- * overwrite length_code[255] to use the best encoding:
- */
- _length_code[length-1] = (uch)code;
-
- /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
- dist = 0;
- for (code = 0 ; code < 16; code++) {
- base_dist[code] = dist;
- for (n = 0; n < (1<<extra_dbits[code]); n++) {
- _dist_code[dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: dist != 256");
- dist >>= 7; /* from now on, all distances are divided by 128 */
- for ( ; code < D_CODES; code++) {
- base_dist[code] = dist << 7;
- for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
- _dist_code[256 + dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: 256+dist != 512");
-
- /* Construct the codes of the static literal tree */
- for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
- n = 0;
- while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
- while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
- while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
- while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
- /* Codes 286 and 287 do not exist, but we must include them in the
- * tree construction to get a canonical Huffman tree (longest code
- * all ones)
- */
- gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
-
- /* The static distance tree is trivial: */
- for (n = 0; n < D_CODES; n++) {
- static_dtree[n].Len = 5;
- static_dtree[n].Code = bi_reverse((unsigned)n, 5);
- }
- static_init_done = 1;
-
-# ifdef GEN_TREES_H
- gen_trees_header();
-# endif
-#endif /* defined(GEN_TREES_H) || !defined(STDC) */
-}
-
-/* ===========================================================================
- * Genererate the file trees.h describing the static trees.
- */
-#ifdef GEN_TREES_H
-# ifndef DEBUG
-# include <stdio.h>
-# endif
-
-# define SEPARATOR(i, last, width) \
- ((i) == (last)? "\n};\n\n" : \
- ((i) % (width) == (width)-1 ? ",\n" : ", "))
-
-void gen_trees_header()
-{
- FILE *header = fopen("trees.h", "w");
- int i;
-
- Assert (header != NULL, "Can't open trees.h");
- fprintf(header,
- "/* header created automatically with -DGEN_TREES_H */\n\n");
-
- fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
- for (i = 0; i < L_CODES+2; i++) {
- fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
- static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
- }
-
- fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
- for (i = 0; i < D_CODES; i++) {
- fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
- static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
- }
-
- fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
- for (i = 0; i < DIST_CODE_LEN; i++) {
- fprintf(header, "%2u%s", _dist_code[i],
- SEPARATOR(i, DIST_CODE_LEN-1, 20));
- }
-
- fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
- for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
- fprintf(header, "%2u%s", _length_code[i],
- SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
- }
-
- fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
- for (i = 0; i < LENGTH_CODES; i++) {
- fprintf(header, "%1u%s", base_length[i],
- SEPARATOR(i, LENGTH_CODES-1, 20));
- }
-
- fprintf(header, "local const int base_dist[D_CODES] = {\n");
- for (i = 0; i < D_CODES; i++) {
- fprintf(header, "%5u%s", base_dist[i],
- SEPARATOR(i, D_CODES-1, 10));
- }
-
- fclose(header);
-}
-#endif /* GEN_TREES_H */
-
-/* ===========================================================================
- * Initialize the tree data structures for a new zlib stream.
- */
-void _tr_init(s)
- deflate_state *s;
-{
- tr_static_init();
-
- s->l_desc.dyn_tree = s->dyn_ltree;
- s->l_desc.stat_desc = &static_l_desc;
-
- s->d_desc.dyn_tree = s->dyn_dtree;
- s->d_desc.stat_desc = &static_d_desc;
-
- s->bl_desc.dyn_tree = s->bl_tree;
- s->bl_desc.stat_desc = &static_bl_desc;
-
- s->bi_buf = 0;
- s->bi_valid = 0;
- s->last_eob_len = 8; /* enough lookahead for inflate */
-#ifdef DEBUG
- s->compressed_len = 0L;
- s->bits_sent = 0L;
-#endif
-
- /* Initialize the first block of the first file: */
- init_block(s);
-}
-
-/* ===========================================================================
- * Initialize a new block.
- */
-local void init_block(s)
- deflate_state *s;
-{
- int n; /* iterates over tree elements */
-
- /* Initialize the trees. */
- for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
- for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
- for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
-
- s->dyn_ltree[END_BLOCK].Freq = 1;
- s->opt_len = s->static_len = 0L;
- s->last_lit = s->matches = 0;
-}
-
-#define SMALLEST 1
-/* Index within the heap array of least frequent node in the Huffman tree */
-
-
-/* ===========================================================================
- * Remove the smallest element from the heap and recreate the heap with
- * one less element. Updates heap and heap_len.
- */
-#define pqremove(s, tree, top) \
-{\
- top = s->heap[SMALLEST]; \
- s->heap[SMALLEST] = s->heap[s->heap_len--]; \
- pqdownheap(s, tree, SMALLEST); \
-}
-
-/* ===========================================================================
- * Compares to subtrees, using the tree depth as tie breaker when
- * the subtrees have equal frequency. This minimizes the worst case length.
- */
-#define smaller(tree, n, m, depth) \
- (tree[n].Freq < tree[m].Freq || \
- (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
-
-/* ===========================================================================
- * Restore the heap property by moving down the tree starting at node k,
- * exchanging a node with the smallest of its two sons if necessary, stopping
- * when the heap property is re-established (each father smaller than its
- * two sons).
- */
-local void pqdownheap(s, tree, k)
- deflate_state *s;
- ct_data *tree; /* the tree to restore */
- int k; /* node to move down */
-{
- int v = s->heap[k];
- int j = k << 1; /* left son of k */
- while (j <= s->heap_len) {
- /* Set j to the smallest of the two sons: */
- if (j < s->heap_len &&
- smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
- j++;
- }
- /* Exit if v is smaller than both sons */
- if (smaller(tree, v, s->heap[j], s->depth)) break;
-
- /* Exchange v with the smallest son */
- s->heap[k] = s->heap[j]; k = j;
-
- /* And continue down the tree, setting j to the left son of k */
- j <<= 1;
- }
- s->heap[k] = v;
-}
-
-/* ===========================================================================
- * Compute the optimal bit lengths for a tree and update the total bit length
- * for the current block.
- * IN assertion: the fields freq and dad are set, heap[heap_max] and
- * above are the tree nodes sorted by increasing frequency.
- * OUT assertions: the field len is set to the optimal bit length, the
- * array bl_count contains the frequencies for each bit length.
- * The length opt_len is updated; static_len is also updated if stree is
- * not null.
- */
-local void gen_bitlen(s, desc)
- deflate_state *s;
- tree_desc *desc; /* the tree descriptor */
-{
- ct_data *tree = desc->dyn_tree;
- int max_code = desc->max_code;
- const ct_data *stree = desc->stat_desc->static_tree;
- const intf *extra = desc->stat_desc->extra_bits;
- int base = desc->stat_desc->extra_base;
- int max_length = desc->stat_desc->max_length;
- int h; /* heap index */
- int n, m; /* iterate over the tree elements */
- int bits; /* bit length */
- int xbits; /* extra bits */
- ush f; /* frequency */
- int overflow = 0; /* number of elements with bit length too large */
-
- for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
-
- /* In a first pass, compute the optimal bit lengths (which may
- * overflow in the case of the bit length tree).
- */
- tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
-
- for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
- n = s->heap[h];
- bits = tree[tree[n].Dad].Len + 1;
- if (bits > max_length) bits = max_length, overflow++;
- tree[n].Len = (ush)bits;
- /* We overwrite tree[n].Dad which is no longer needed */
-
- if (n > max_code) continue; /* not a leaf node */
-
- s->bl_count[bits]++;
- xbits = 0;
- if (n >= base) xbits = extra[n-base];
- f = tree[n].Freq;
- s->opt_len += (ulg)f * (bits + xbits);
- if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
- }
- if (overflow == 0) return;
-
- Trace((stderr,"\nbit length overflow\n"));
- /* This happens for example on obj2 and pic of the Calgary corpus */
-
- /* Find the first bit length which could increase: */
- do {
- bits = max_length-1;
- while (s->bl_count[bits] == 0) bits--;
- s->bl_count[bits]--; /* move one leaf down the tree */
- s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
- s->bl_count[max_length]--;
- /* The brother of the overflow item also moves one step up,
- * but this does not affect bl_count[max_length]
- */
- overflow -= 2;
- } while (overflow > 0);
-
- /* Now recompute all bit lengths, scanning in increasing frequency.
- * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
- * lengths instead of fixing only the wrong ones. This idea is taken
- * from 'ar' written by Haruhiko Okumura.)
- */
- for (bits = max_length; bits != 0; bits--) {
- n = s->bl_count[bits];
- while (n != 0) {
- m = s->heap[--h];
- if (m > max_code) continue;
- if ((unsigned) tree[m].Len != (unsigned) bits) {
- Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
- s->opt_len += ((long)bits - (long)tree[m].Len)
- *(long)tree[m].Freq;
- tree[m].Len = (ush)bits;
- }
- n--;
- }
- }
-}
-
-/* ===========================================================================
- * Generate the codes for a given tree and bit counts (which need not be
- * optimal).
- * IN assertion: the array bl_count contains the bit length statistics for
- * the given tree and the field len is set for all tree elements.
- * OUT assertion: the field code is set for all tree elements of non
- * zero code length.
- */
-local void gen_codes (tree, max_code, bl_count)
- ct_data *tree; /* the tree to decorate */
- int max_code; /* largest code with non zero frequency */
- ushf *bl_count; /* number of codes at each bit length */
-{
- ush next_code[MAX_BITS+1]; /* next code value for each bit length */
- ush code = 0; /* running code value */
- int bits; /* bit index */
- int n; /* code index */
-
- /* The distribution counts are first used to generate the code values
- * without bit reversal.
- */
- for (bits = 1; bits <= MAX_BITS; bits++) {
- next_code[bits] = code = (code + bl_count[bits-1]) << 1;
- }
- /* Check that the bit counts in bl_count are consistent. The last code
- * must be all ones.
- */
- Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
- "inconsistent bit counts");
- Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-
- for (n = 0; n <= max_code; n++) {
- int len = tree[n].Len;
- if (len == 0) continue;
- /* Now reverse the bits */
- tree[n].Code = bi_reverse(next_code[len]++, len);
-
- Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
- n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
- }
-}
-
-/* ===========================================================================
- * Construct one Huffman tree and assigns the code bit strings and lengths.
- * Update the total bit length for the current block.
- * IN assertion: the field freq is set for all tree elements.
- * OUT assertions: the fields len and code are set to the optimal bit length
- * and corresponding code. The length opt_len is updated; static_len is
- * also updated if stree is not null. The field max_code is set.
- */
-local void build_tree(s, desc)
- deflate_state *s;
- tree_desc *desc; /* the tree descriptor */
-{
- ct_data *tree = desc->dyn_tree;
- const ct_data *stree = desc->stat_desc->static_tree;
- int elems = desc->stat_desc->elems;
- int n, m; /* iterate over heap elements */
- int max_code = -1; /* largest code with non zero frequency */
- int node; /* new node being created */
-
- /* Construct the initial heap, with least frequent element in
- * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
- * heap[0] is not used.
- */
- s->heap_len = 0, s->heap_max = HEAP_SIZE;
-
- for (n = 0; n < elems; n++) {
- if (tree[n].Freq != 0) {
- s->heap[++(s->heap_len)] = max_code = n;
- s->depth[n] = 0;
- } else {
- tree[n].Len = 0;
- }
- }
-
- /* The pkzip format requires that at least one distance code exists,
- * and that at least one bit should be sent even if there is only one
- * possible code. So to avoid special checks later on we force at least
- * two codes of non zero frequency.
- */
- while (s->heap_len < 2) {
- node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
- tree[node].Freq = 1;
- s->depth[node] = 0;
- s->opt_len--; if (stree) s->static_len -= stree[node].Len;
- /* node is 0 or 1 so it does not have extra bits */
- }
- desc->max_code = max_code;
-
- /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
- * establish sub-heaps of increasing lengths:
- */
- for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
-
- /* Construct the Huffman tree by repeatedly combining the least two
- * frequent nodes.
- */
- node = elems; /* next internal node of the tree */
- do {
- pqremove(s, tree, n); /* n = node of least frequency */
- m = s->heap[SMALLEST]; /* m = node of next least frequency */
-
- s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
- s->heap[--(s->heap_max)] = m;
-
- /* Create a new node father of n and m */
- tree[node].Freq = tree[n].Freq + tree[m].Freq;
- s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
- s->depth[n] : s->depth[m]) + 1);
- tree[n].Dad = tree[m].Dad = (ush)node;
-#ifdef DUMP_BL_TREE
- if (tree == s->bl_tree) {
- fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
- node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
- }
-#endif
- /* and insert the new node in the heap */
- s->heap[SMALLEST] = node++;
- pqdownheap(s, tree, SMALLEST);
-
- } while (s->heap_len >= 2);
-
- s->heap[--(s->heap_max)] = s->heap[SMALLEST];
-
- /* At this point, the fields freq and dad are set. We can now
- * generate the bit lengths.
- */
- gen_bitlen(s, (tree_desc *)desc);
-
- /* The field len is now set, we can generate the bit codes */
- gen_codes ((ct_data *)tree, max_code, s->bl_count);
-}
-
-/* ===========================================================================
- * Scan a literal or distance tree to determine the frequencies of the codes
- * in the bit length tree.
- */
-local void scan_tree (s, tree, max_code)
- deflate_state *s;
- ct_data *tree; /* the tree to be scanned */
- int max_code; /* and its largest code of non zero frequency */
-{
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- if (nextlen == 0) max_count = 138, min_count = 3;
- tree[max_code+1].Len = (ush)0xffff; /* guard */
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- s->bl_tree[curlen].Freq += count;
- } else if (curlen != 0) {
- if (curlen != prevlen) s->bl_tree[curlen].Freq++;
- s->bl_tree[REP_3_6].Freq++;
- } else if (count <= 10) {
- s->bl_tree[REPZ_3_10].Freq++;
- } else {
- s->bl_tree[REPZ_11_138].Freq++;
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
-}
-
-/* ===========================================================================
- * Send a literal or distance tree in compressed form, using the codes in
- * bl_tree.
- */
-local void send_tree (s, tree, max_code)
- deflate_state *s;
- ct_data *tree; /* the tree to be scanned */
- int max_code; /* and its largest code of non zero frequency */
-{
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- /* tree[max_code+1].Len = -1; */ /* guard already set */
- if (nextlen == 0) max_count = 138, min_count = 3;
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
-
- } else if (curlen != 0) {
- if (curlen != prevlen) {
- send_code(s, curlen, s->bl_tree); count--;
- }
- Assert(count >= 3 && count <= 6, " 3_6?");
- send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
-
- } else if (count <= 10) {
- send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
-
- } else {
- send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
-}
-
-/* ===========================================================================
- * Construct the Huffman tree for the bit lengths and return the index in
- * bl_order of the last bit length code to send.
- */
-local int build_bl_tree(s)
- deflate_state *s;
-{
- int max_blindex; /* index of last bit length code of non zero freq */
-
- /* Determine the bit length frequencies for literal and distance trees */
- scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
- scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
-
- /* Build the bit length tree: */
- build_tree(s, (tree_desc *)(&(s->bl_desc)));
- /* opt_len now includes the length of the tree representations, except
- * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
- */
-
- /* Determine the number of bit length codes to send. The pkzip format
- * requires that at least 4 bit length codes be sent. (appnote.txt says
- * 3 but the actual value used is 4.)
- */
- for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
- if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
- }
- /* Update opt_len to include the bit length tree and counts */
- s->opt_len += 3*(max_blindex+1) + 5+5+4;
- Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
- s->opt_len, s->static_len));
-
- return max_blindex;
-}
-
-/* ===========================================================================
- * Send the header for a block using dynamic Huffman trees: the counts, the
- * lengths of the bit length codes, the literal tree and the distance tree.
- * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
- */
-local void send_all_trees(s, lcodes, dcodes, blcodes)
- deflate_state *s;
- int lcodes, dcodes, blcodes; /* number of codes for each tree */
-{
- int rank; /* index in bl_order */
-
- Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
- Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
- "too many codes");
- Tracev((stderr, "\nbl counts: "));
- send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
- send_bits(s, dcodes-1, 5);
- send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
- for (rank = 0; rank < blcodes; rank++) {
- Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
- send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
- }
- Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
- Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
- Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
-}
-
-/* ===========================================================================
- * Send a stored block
- */
-void _tr_stored_block(s, buf, stored_len, eof)
- deflate_state *s;
- charf *buf; /* input block */
- ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
-{
- send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
-#ifdef DEBUG
- s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
- s->compressed_len += (stored_len + 4) << 3;
-#endif
- copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
-}
-
-/* ===========================================================================
- * Send one empty static block to give enough lookahead for inflate.
- * This takes 10 bits, of which 7 may remain in the bit buffer.
- * The current inflate code requires 9 bits of lookahead. If the
- * last two codes for the previous block (real code plus EOB) were coded
- * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
- * the last real code. In this case we send two empty static blocks instead
- * of one. (There are no problems if the previous block is stored or fixed.)
- * To simplify the code, we assume the worst case of last real code encoded
- * on one bit only.
- */
-void _tr_align(s)
- deflate_state *s;
-{
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
-#endif
- bi_flush(s);
- /* Of the 10 bits for the empty block, we have already sent
- * (10 - bi_valid) bits. The lookahead for the last real code (before
- * the EOB of the previous block) was thus at least one plus the length
- * of the EOB plus what we have just sent of the empty static block.
- */
- if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L;
-#endif
- bi_flush(s);
- }
- s->last_eob_len = 7;
-}
-
-/* ===========================================================================
- * Determine the best encoding for the current block: dynamic trees, static
- * trees or store, and output the encoded block to the zip file.
- */
-void _tr_flush_block(s, buf, stored_len, eof)
- deflate_state *s;
- charf *buf; /* input block, or NULL if too old */
- ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
-{
- ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
- int max_blindex = 0; /* index of last bit length code of non zero freq */
-
- /* Build the Huffman trees unless a stored block is forced */
- if (s->level > 0) {
-
- /* Check if the file is binary or text */
- if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
- set_data_type(s);
-
- /* Construct the literal and distance trees */
- build_tree(s, (tree_desc *)(&(s->l_desc)));
- Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
-
- build_tree(s, (tree_desc *)(&(s->d_desc)));
- Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
- /* At this point, opt_len and static_len are the total bit lengths of
- * the compressed block data, excluding the tree representations.
- */
-
- /* Build the bit length tree for the above two trees, and get the index
- * in bl_order of the last bit length code to send.
- */
- max_blindex = build_bl_tree(s);
-
- /* Determine the best encoding. Compute the block lengths in bytes. */
- opt_lenb = (s->opt_len+3+7)>>3;
- static_lenb = (s->static_len+3+7)>>3;
-
- Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
- opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
- s->last_lit));
-
- if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
-
- } else {
- Assert(buf != (char*)0, "lost buf");
- opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
- }
-
-#ifdef FORCE_STORED
- if (buf != (char*)0) { /* force stored block */
-#else
- if (stored_len+4 <= opt_lenb && buf != (char*)0) {
- /* 4: two words for the lengths */
-#endif
- /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
- * Otherwise we can't have processed more than WSIZE input bytes since
- * the last block flush, because compression would have been
- * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
- * transform a block into a stored block.
- */
- _tr_stored_block(s, buf, stored_len, eof);
-
-#ifdef FORCE_STATIC
- } else if (static_lenb >= 0) { /* force static trees */
-#else
- } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
-#endif
- send_bits(s, (STATIC_TREES<<1)+eof, 3);
- compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
-#ifdef DEBUG
- s->compressed_len += 3 + s->static_len;
-#endif
- } else {
- send_bits(s, (DYN_TREES<<1)+eof, 3);
- send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
- max_blindex+1);
- compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
-#ifdef DEBUG
- s->compressed_len += 3 + s->opt_len;
-#endif
- }
- Assert (s->compressed_len == s->bits_sent, "bad compressed size");
- /* The above check is made mod 2^32, for files larger than 512 MB
- * and uLong implemented on 32 bits.
- */
- init_block(s);
-
- if (eof) {
- bi_windup(s);
-#ifdef DEBUG
- s->compressed_len += 7; /* align on byte boundary */
-#endif
- }
- Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
- s->compressed_len-7*eof));
-}
-
-/* ===========================================================================
- * Save the match info and tally the frequency counts. Return true if
- * the current block must be flushed.
- */
-int _tr_tally (s, dist, lc)
- deflate_state *s;
- unsigned dist; /* distance of matched string */
- unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
-{
- s->d_buf[s->last_lit] = (ush)dist;
- s->l_buf[s->last_lit++] = (uch)lc;
- if (dist == 0) {
- /* lc is the unmatched char */
- s->dyn_ltree[lc].Freq++;
- } else {
- s->matches++;
- /* Here, lc is the match length - MIN_MATCH */
- dist--; /* dist = match distance - 1 */
- Assert((ush)dist < (ush)MAX_DIST(s) &&
- (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
- (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
-
- s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
- s->dyn_dtree[d_code(dist)].Freq++;
- }
-
-#ifdef TRUNCATE_BLOCK
- /* Try to guess if it is profitable to stop the current block here */
- if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
- /* Compute an upper bound for the compressed length */
- ulg out_length = (ulg)s->last_lit*8L;
- ulg in_length = (ulg)((long)s->strstart - s->block_start);
- int dcode;
- for (dcode = 0; dcode < D_CODES; dcode++) {
- out_length += (ulg)s->dyn_dtree[dcode].Freq *
- (5L+extra_dbits[dcode]);
- }
- out_length >>= 3;
- Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
- s->last_lit, in_length, out_length,
- 100L - out_length*100L/in_length));
- if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
- }
-#endif
- return (s->last_lit == s->lit_bufsize-1);
- /* We avoid equality with lit_bufsize because of wraparound at 64K
- * on 16 bit machines and because stored blocks are restricted to
- * 64K-1 bytes.
- */
-}
-
-/* ===========================================================================
- * Send the block data compressed using the given Huffman trees
- */
-local void compress_block(s, ltree, dtree)
- deflate_state *s;
- ct_data *ltree; /* literal tree */
- ct_data *dtree; /* distance tree */
-{
- unsigned dist; /* distance of matched string */
- int lc; /* match length or unmatched char (if dist == 0) */
- unsigned lx = 0; /* running index in l_buf */
- unsigned code; /* the code to send */
- int extra; /* number of extra bits to send */
-
- if (s->last_lit != 0) do {
- dist = s->d_buf[lx];
- lc = s->l_buf[lx++];
- if (dist == 0) {
- send_code(s, lc, ltree); /* send a literal byte */
- Tracecv(isgraph(lc), (stderr," '%c' ", lc));
- } else {
- /* Here, lc is the match length - MIN_MATCH */
- code = _length_code[lc];
- send_code(s, code+LITERALS+1, ltree); /* send the length code */
- extra = extra_lbits[code];
- if (extra != 0) {
- lc -= base_length[code];
- send_bits(s, lc, extra); /* send the extra length bits */
- }
- dist--; /* dist is now the match distance - 1 */
- code = d_code(dist);
- Assert (code < D_CODES, "bad d_code");
-
- send_code(s, code, dtree); /* send the distance code */
- extra = extra_dbits[code];
- if (extra != 0) {
- dist -= base_dist[code];
- send_bits(s, dist, extra); /* send the extra distance bits */
- }
- } /* literal or match pair ? */
-
- /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
- Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
- "pendingBuf overflow");
-
- } while (lx < s->last_lit);
-
- send_code(s, END_BLOCK, ltree);
- s->last_eob_len = ltree[END_BLOCK].Len;
-}
-
-/* ===========================================================================
- * Set the data type to BINARY or TEXT, using a crude approximation:
- * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
- * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
- * IN assertion: the fields Freq of dyn_ltree are set.
- */
-local void set_data_type(s)
- deflate_state *s;
-{
- int n;
-
- for (n = 0; n < 9; n++)
- if (s->dyn_ltree[n].Freq != 0)
- break;
- if (n == 9)
- for (n = 14; n < 32; n++)
- if (s->dyn_ltree[n].Freq != 0)
- break;
- s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
-}
-
-/* ===========================================================================
- * Reverse the first len bits of a code, using straightforward code (a faster
- * method would use a table)
- * IN assertion: 1 <= len <= 15
- */
-local unsigned bi_reverse(code, len)
- unsigned code; /* the value to invert */
- int len; /* its bit length */
-{
- register unsigned res = 0;
- do {
- res |= code & 1;
- code >>= 1, res <<= 1;
- } while (--len > 0);
- return res >> 1;
-}
-
-/* ===========================================================================
- * Flush the bit buffer, keeping at most 7 bits in it.
- */
-local void bi_flush(s)
- deflate_state *s;
-{
- if (s->bi_valid == 16) {
- put_short(s, s->bi_buf);
- s->bi_buf = 0;
- s->bi_valid = 0;
- } else if (s->bi_valid >= 8) {
- put_byte(s, (Byte)s->bi_buf);
- s->bi_buf >>= 8;
- s->bi_valid -= 8;
- }
-}
-
-/* ===========================================================================
- * Flush the bit buffer and align the output on a byte boundary
- */
-local void bi_windup(s)
- deflate_state *s;
-{
- if (s->bi_valid > 8) {
- put_short(s, s->bi_buf);
- } else if (s->bi_valid > 0) {
- put_byte(s, (Byte)s->bi_buf);
- }
- s->bi_buf = 0;
- s->bi_valid = 0;
-#ifdef DEBUG
- s->bits_sent = (s->bits_sent+7) & ~7;
-#endif
-}
-
-/* ===========================================================================
- * Copy a stored block, storing first the length and its
- * one's complement if requested.
- */
-local void copy_block(s, buf, len, header)
- deflate_state *s;
- charf *buf; /* the input data */
- unsigned len; /* its length */
- int header; /* true if block header must be written */
-{
- bi_windup(s); /* align on byte boundary */
- s->last_eob_len = 8; /* enough lookahead for inflate */
-
- if (header) {
- put_short(s, (ush)len);
- put_short(s, (ush)~len);
-#ifdef DEBUG
- s->bits_sent += 2*16;
-#endif
- }
-#ifdef DEBUG
- s->bits_sent += (ulg)len<<3;
-#endif
- while (len--) {
- put_byte(s, *buf++);
- }
-}
diff --git a/dep/StormLib/src/zlib/trees.h b/dep/StormLib/src/zlib/trees.h
deleted file mode 100644
index 72facf900f7..00000000000
--- a/dep/StormLib/src/zlib/trees.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* header created automatically with -DGEN_TREES_H */
-
-local const ct_data static_ltree[L_CODES+2] = {
-{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
-{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
-{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
-{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
-{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
-{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
-{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
-{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
-{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
-{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
-{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
-{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
-{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
-{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
-{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
-{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
-{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
-{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
-{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
-{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
-{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
-{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
-{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
-{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
-{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
-{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
-{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
-{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
-{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
-{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
-{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
-{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
-{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
-{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
-{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
-{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
-{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
-{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
-{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
-{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
-{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
-{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
-{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
-{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
-{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
-{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
-{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
-{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
-{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
-{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
-{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
-{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
-{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
-{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
-{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
-{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
-{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
-{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
-};
-
-local const ct_data static_dtree[D_CODES] = {
-{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
-{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
-{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
-{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
-{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
-{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
-};
-
-const uch _dist_code[DIST_CODE_LEN] = {
- 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
- 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
-10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
-13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
-18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
-23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
-};
-
-const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
-13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
-17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
-19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
-22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
-23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
-};
-
-local const int base_length[LENGTH_CODES] = {
-0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
-64, 80, 96, 112, 128, 160, 192, 224, 0
-};
-
-local const int base_dist[D_CODES] = {
- 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
- 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
- 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
-};
-
diff --git a/dep/StormLib/src/zlib/zconf.h b/dep/StormLib/src/zlib/zconf.h
deleted file mode 100644
index 03a9431c8be..00000000000
--- a/dep/StormLib/src/zlib/zconf.h
+++ /dev/null
@@ -1,332 +0,0 @@
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#ifndef ZCONF_H
-#define ZCONF_H
-
-/*
- * If you *really* need a unique prefix for all types and library functions,
- * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
- */
-#ifdef Z_PREFIX
-# define deflateInit_ z_deflateInit_
-# define deflate z_deflate
-# define deflateEnd z_deflateEnd
-# define inflateInit_ z_inflateInit_
-# define inflate z_inflate
-# define inflateEnd z_inflateEnd
-# define deflateInit2_ z_deflateInit2_
-# define deflateSetDictionary z_deflateSetDictionary
-# define deflateCopy z_deflateCopy
-# define deflateReset z_deflateReset
-# define deflateParams z_deflateParams
-# define deflateBound z_deflateBound
-# define deflatePrime z_deflatePrime
-# define inflateInit2_ z_inflateInit2_
-# define inflateSetDictionary z_inflateSetDictionary
-# define inflateSync z_inflateSync
-# define inflateSyncPoint z_inflateSyncPoint
-# define inflateCopy z_inflateCopy
-# define inflateReset z_inflateReset
-# define inflateBack z_inflateBack
-# define inflateBackEnd z_inflateBackEnd
-# define compress z_compress
-# define compress2 z_compress2
-# define compressBound z_compressBound
-# define uncompress z_uncompress
-# define adler32 z_adler32
-# define crc32 z_crc32
-# define get_crc_table z_get_crc_table
-# define zError z_zError
-
-# define alloc_func z_alloc_func
-# define free_func z_free_func
-# define in_func z_in_func
-# define out_func z_out_func
-# define Byte z_Byte
-# define uInt z_uInt
-# define uLong z_uLong
-# define Bytef z_Bytef
-# define charf z_charf
-# define intf z_intf
-# define uIntf z_uIntf
-# define uLongf z_uLongf
-# define voidpf z_voidpf
-# define voidp z_voidp
-#endif
-
-#if defined(__MSDOS__) && !defined(MSDOS)
-# define MSDOS
-#endif
-#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
-# define OS2
-#endif
-#if defined(_WINDOWS) && !defined(WINDOWS)
-# define WINDOWS
-#endif
-#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
-# ifndef WIN32
-# define WIN32
-# endif
-#endif
-#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
-# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
-# ifndef SYS16BIT
-# define SYS16BIT
-# endif
-# endif
-#endif
-
-/*
- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
- * than 64k bytes at a time (needed on systems with 16-bit int).
- */
-#ifdef SYS16BIT
-# define MAXSEG_64K
-#endif
-#ifdef MSDOS
-# define UNALIGNED_OK
-#endif
-
-#ifdef __STDC_VERSION__
-# ifndef STDC
-# define STDC
-# endif
-# if __STDC_VERSION__ >= 199901L
-# ifndef STDC99
-# define STDC99
-# endif
-# endif
-#endif
-#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
-# define STDC
-#endif
-
-#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
-# define STDC
-#endif
-
-#ifndef STDC
-# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-# define const /* note: need a more gentle solution here */
-# endif
-#endif
-
-/* Some Mac compilers merge all .h files incorrectly: */
-#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
-# define NO_DUMMY_DECL
-#endif
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-# ifdef MAXSEG_64K
-# define MAX_MEM_LEVEL 8
-# else
-# define MAX_MEM_LEVEL 9
-# endif
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2.
- * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
- * created by gzip. (Files created by minigzip can still be extracted by
- * gzip.)
- */
-#ifndef MAX_WBITS
-# define MAX_WBITS 15 /* 32K LZ77 window */
-#endif
-
-/* The memory requirements for deflate are (in bytes):
- (1 << (windowBits+2)) + (1 << (memLevel+9))
- that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
- make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
- The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
-*/
-
- /* Type declarations */
-
-#ifndef OF /* function prototypes */
-# ifdef STDC
-# define OF(args) args
-# else
-# define OF(args) ()
-# endif
-#endif
-
-/* The following definitions for FAR are needed only for MSDOS mixed
- * model programming (small or medium model with some far allocations).
- * This was tested only with MSC; for other MSDOS compilers you may have
- * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
- * just define FAR to be empty.
- */
-#ifdef SYS16BIT
-# if defined(M_I86SM) || defined(M_I86MM)
- /* MSC small or medium model */
-# define SMALL_MEDIUM
-# ifdef _MSC_VER
-# define FAR _far
-# else
-# define FAR far
-# endif
-# endif
-# if (defined(__SMALL__) || defined(__MEDIUM__))
- /* Turbo C small or medium model */
-# define SMALL_MEDIUM
-# ifdef __BORLANDC__
-# define FAR _far
-# else
-# define FAR far
-# endif
-# endif
-#endif
-
-#if defined(WINDOWS) || defined(WIN32)
- /* If building or using zlib as a DLL, define ZLIB_DLL.
- * This is not mandatory, but it offers a little performance increase.
- */
-# ifdef ZLIB_DLL
-# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
-# ifdef ZLIB_INTERNAL
-# define ZEXTERN extern __declspec(dllexport)
-# else
-# define ZEXTERN extern __declspec(dllimport)
-# endif
-# endif
-# endif /* ZLIB_DLL */
- /* If building or using zlib with the WINAPI/WINAPIV calling convention,
- * define ZLIB_WINAPI.
- * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
- */
-# ifdef ZLIB_WINAPI
-# ifdef FAR
-# undef FAR
-# endif
-# include <windows.h>
- /* No need for _export, use ZLIB.DEF instead. */
- /* For complete Windows compatibility, use WINAPI, not __stdcall. */
-# define ZEXPORT WINAPI
-# ifdef WIN32
-# define ZEXPORTVA WINAPIV
-# else
-# define ZEXPORTVA FAR CDECL
-# endif
-# endif
-#endif
-
-#if defined (__BEOS__)
-# ifdef ZLIB_DLL
-# ifdef ZLIB_INTERNAL
-# define ZEXPORT __declspec(dllexport)
-# define ZEXPORTVA __declspec(dllexport)
-# else
-# define ZEXPORT __declspec(dllimport)
-# define ZEXPORTVA __declspec(dllimport)
-# endif
-# endif
-#endif
-
-#ifndef ZEXTERN
-# define ZEXTERN extern
-#endif
-#ifndef ZEXPORT
-# define ZEXPORT
-#endif
-#ifndef ZEXPORTVA
-# define ZEXPORTVA
-#endif
-
-#ifndef FAR
-# define FAR
-#endif
-
-#if !defined(__MACTYPES__)
-typedef unsigned char Byte; /* 8 bits */
-#endif
-typedef unsigned int uInt; /* 16 bits or more */
-typedef unsigned long uLong; /* 32 bits or more */
-
-#ifdef SMALL_MEDIUM
- /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
-# define Bytef Byte FAR
-#else
- typedef Byte FAR Bytef;
-#endif
-typedef char FAR charf;
-typedef int FAR intf;
-typedef uInt FAR uIntf;
-typedef uLong FAR uLongf;
-
-#ifdef STDC
- typedef void const *voidpc;
- typedef void FAR *voidpf;
- typedef void *voidp;
-#else
- typedef Byte const *voidpc;
- typedef Byte FAR *voidpf;
- typedef Byte *voidp;
-#endif
-
-#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
-# include <sys/types.h> /* for off_t */
-# include <unistd.h> /* for SEEK_* and off_t */
-# ifdef VMS
-# include <unixio.h> /* for off_t */
-# endif
-# define z_off_t off_t
-#endif
-#ifndef SEEK_SET
-# define SEEK_SET 0 /* Seek from beginning of file. */
-# define SEEK_CUR 1 /* Seek from current position. */
-# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
-#endif
-#ifndef z_off_t
-# define z_off_t long
-#endif
-
-#if defined(__OS400__)
-# define NO_vsnprintf
-#endif
-
-#if defined(__MVS__)
-# define NO_vsnprintf
-# ifdef FAR
-# undef FAR
-# endif
-#endif
-
-/* MVS linker does not support external names larger than 8 bytes */
-#if defined(__MVS__)
-# pragma map(deflateInit_,"DEIN")
-# pragma map(deflateInit2_,"DEIN2")
-# pragma map(deflateEnd,"DEEND")
-# pragma map(deflateBound,"DEBND")
-# pragma map(inflateInit_,"ININ")
-# pragma map(inflateInit2_,"ININ2")
-# pragma map(inflateEnd,"INEND")
-# pragma map(inflateSync,"INSY")
-# pragma map(inflateSetDictionary,"INSEDI")
-# pragma map(compressBound,"CMBND")
-# pragma map(inflate_table,"INTABL")
-# pragma map(inflate_fast,"INFA")
-# pragma map(inflate_copyright,"INCOPY")
-#endif
-
-#endif /* ZCONF_H */
diff --git a/dep/StormLib/src/zlib/zlib.h b/dep/StormLib/src/zlib/zlib.h
deleted file mode 100644
index 022817927ce..00000000000
--- a/dep/StormLib/src/zlib/zlib.h
+++ /dev/null
@@ -1,1357 +0,0 @@
-/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 1.2.3, July 18th, 2005
-
- Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jean-loup Gailly Mark Adler
- jloup@gzip.org madler@alumni.caltech.edu
-
-
- The data format used by the zlib library is described by RFCs (Request for
- Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
- (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
-*/
-
-#ifndef ZLIB_H
-#define ZLIB_H
-
-#include "zconf.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ZLIB_VERSION "1.2.3"
-#define ZLIB_VERNUM 0x1230
-
-/*
- The 'zlib' compression library provides in-memory compression and
- decompression functions, including integrity checks of the uncompressed
- data. This version of the library supports only one compression method
- (deflation) but other algorithms will be added later and will have the same
- stream interface.
-
- Compression can be done in a single step if the buffers are large
- enough (for example if an input file is mmap'ed), or can be done by
- repeated calls of the compression function. In the latter case, the
- application must provide more input and/or consume the output
- (providing more output space) before each call.
-
- The compressed data format used by default by the in-memory functions is
- the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
- around a deflate stream, which is itself documented in RFC 1951.
-
- The library also supports reading and writing files in gzip (.gz) format
- with an interface similar to that of stdio using the functions that start
- with "gz". The gzip format is different from the zlib format. gzip is a
- gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
-
- This library can optionally read and write gzip streams in memory as well.
-
- The zlib format was designed to be compact and fast for use in memory
- and on communications channels. The gzip format was designed for single-
- file compression on file systems, has a larger header than zlib to maintain
- directory information, and uses a different, slower check method than zlib.
-
- The library does not install any signal handler. The decoder checks
- the consistency of the compressed data, so the library should never
- crash even in case of corrupted input.
-*/
-
-typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-typedef void (*free_func) OF((voidpf opaque, voidpf address));
-
-struct internal_state;
-
-typedef struct z_stream_s {
- Bytef *next_in; /* next input byte */
- uInt avail_in; /* number of bytes available at next_in */
- uLong total_in; /* total nb of input bytes read so far */
-
- Bytef *next_out; /* next output byte should be put there */
- uInt avail_out; /* remaining free space at next_out */
- uLong total_out; /* total nb of bytes output so far */
-
- char *msg; /* last error message, NULL if no error */
- struct internal_state FAR *state; /* not visible by applications */
-
- alloc_func zalloc; /* used to allocate the internal state */
- free_func zfree; /* used to free the internal state */
- voidpf opaque; /* private data object passed to zalloc and zfree */
-
- int data_type; /* best guess about the data type: binary or text */
- uLong adler; /* adler32 value of the uncompressed data */
- uLong reserved; /* reserved for future use */
-} z_stream;
-
-typedef z_stream FAR *z_streamp;
-
-/*
- gzip header information passed to and from zlib routines. See RFC 1952
- for more details on the meanings of these fields.
-*/
-typedef struct gz_header_s {
- int text; /* true if compressed data believed to be text */
- uLong time; /* modification time */
- int xflags; /* extra flags (not used when writing a gzip file) */
- int os; /* operating system */
- Bytef *extra; /* pointer to extra field or Z_NULL if none */
- uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
- uInt extra_max; /* space at extra (only when reading header) */
- Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
- uInt name_max; /* space at name (only when reading header) */
- Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
- uInt comm_max; /* space at comment (only when reading header) */
- int hcrc; /* true if there was or will be a header crc */
- int done; /* true when done reading gzip header (not used
- when writing a gzip file) */
-} gz_header;
-
-typedef gz_header FAR *gz_headerp;
-
-/*
- The application must update next_in and avail_in when avail_in has
- dropped to zero. It must update next_out and avail_out when avail_out
- has dropped to zero. The application must initialize zalloc, zfree and
- opaque before calling the init function. All other fields are set by the
- compression library and must not be updated by the application.
-
- The opaque value provided by the application will be passed as the first
- parameter for calls of zalloc and zfree. This can be useful for custom
- memory management. The compression library attaches no meaning to the
- opaque value.
-
- zalloc must return Z_NULL if there is not enough memory for the object.
- If zlib is used in a multi-threaded application, zalloc and zfree must be
- thread safe.
-
- On 16-bit systems, the functions zalloc and zfree must be able to allocate
- exactly 65536 bytes, but will not be required to allocate more than this
- if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
- pointers returned by zalloc for objects of exactly 65536 bytes *must*
- have their offset normalized to zero. The default allocation function
- provided by this library ensures this (see zutil.c). To reduce memory
- requirements and avoid any allocation of 64K objects, at the expense of
- compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-
- The fields total_in and total_out can be used for statistics or
- progress reports. After compression, total_in holds the total size of
- the uncompressed data and may be saved for use in the decompressor
- (particularly if the decompressor wants to decompress everything in
- a single step).
-*/
-
- /* constants */
-
-#define Z_NO_FLUSH 0
-#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
-#define Z_SYNC_FLUSH 2
-#define Z_FULL_FLUSH 3
-#define Z_FINISH 4
-#define Z_BLOCK 5
-/* Allowed flush values; see deflate() and inflate() below for details */
-
-#define Z_OK 0
-#define Z_STREAM_END 1
-#define Z_NEED_DICT 2
-#define Z_ERRNO (-1)
-#define Z_STREAM_ERROR (-2)
-#define Z_DATA_ERROR (-3)
-#define Z_MEM_ERROR (-4)
-#define Z_BUF_ERROR (-5)
-#define Z_VERSION_ERROR (-6)
-/* Return codes for the compression/decompression functions. Negative
- * values are errors, positive values are used for special but normal events.
- */
-
-#define Z_NO_COMPRESSION 0
-#define Z_BEST_SPEED 1
-#define Z_BEST_COMPRESSION 9
-#define Z_DEFAULT_COMPRESSION (-1)
-/* compression levels */
-
-#define Z_FILTERED 1
-#define Z_HUFFMAN_ONLY 2
-#define Z_RLE 3
-#define Z_FIXED 4
-#define Z_DEFAULT_STRATEGY 0
-/* compression strategy; see deflateInit2() below for details */
-
-#define Z_BINARY 0
-#define Z_TEXT 1
-#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
-#define Z_UNKNOWN 2
-/* Possible values of the data_type field (though see inflate()) */
-
-#define Z_DEFLATED 8
-/* The deflate compression method (the only one supported in this version) */
-
-#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-
-#define zlib_version zlibVersion()
-/* for compatibility with versions < 1.0.2 */
-
- /* basic functions */
-
-ZEXTERN const char * ZEXPORT zlibVersion OF((void));
-/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
- If the first character differs, the library code actually used is
- not compatible with the zlib.h header file used by the application.
- This check is automatically made by deflateInit and inflateInit.
- */
-
-/*
-ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
-
- Initializes the internal stream state for compression. The fields
- zalloc, zfree and opaque must be initialized before by the caller.
- If zalloc and zfree are set to Z_NULL, deflateInit updates them to
- use default allocation functions.
-
- The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
- 1 gives best speed, 9 gives best compression, 0 gives no compression at
- all (the input data is simply copied a block at a time).
- Z_DEFAULT_COMPRESSION requests a default compromise between speed and
- compression (currently equivalent to level 6).
-
- deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if level is not a valid compression level,
- Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
- with the version assumed by the caller (ZLIB_VERSION).
- msg is set to null if there is no error message. deflateInit does not
- perform any compression: this will be done by deflate().
-*/
-
-
-ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
-/*
- deflate compresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce some
- output latency (reading input without producing any output) except when
- forced to flush.
-
- The detailed semantics are as follows. deflate performs one or both of the
- following actions:
-
- - Compress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in and avail_in are updated and
- processing will resume at this point for the next call of deflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. This action is forced if the parameter flush is non zero.
- Forcing flush frequently degrades the compression ratio, so this parameter
- should be set only when necessary (in interactive applications).
- Some output may be provided even if flush is not set.
-
- Before the call of deflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating avail_in or avail_out accordingly; avail_out
- should never be zero before the call. The application can consume the
- compressed output when it wants, for example when the output buffer is full
- (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
- and with zero avail_out, it must be called again after making room in the
- output buffer because there might be more output pending.
-
- Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
- decide how much data to accumualte before producing output, in order to
- maximize compression.
-
- If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
- flushed to the output buffer and the output is aligned on a byte boundary, so
- that the decompressor can get all input data available so far. (In particular
- avail_in is zero after the call if enough output space has been provided
- before the call.) Flushing may degrade compression for some compression
- algorithms and so it should be used only when necessary.
-
- If flush is set to Z_FULL_FLUSH, all output is flushed as with
- Z_SYNC_FLUSH, and the compression state is reset so that decompression can
- restart from this point if previous compressed data has been damaged or if
- random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
- compression.
-
- If deflate returns with avail_out == 0, this function must be called again
- with the same value of the flush parameter and more output space (updated
- avail_out), until the flush is complete (deflate returns with non-zero
- avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
- avail_out is greater than six to avoid repeated flush markers due to
- avail_out == 0 on return.
-
- If the parameter flush is set to Z_FINISH, pending input is processed,
- pending output is flushed and deflate returns with Z_STREAM_END if there
- was enough output space; if deflate returns with Z_OK, this function must be
- called again with Z_FINISH and more output space (updated avail_out) but no
- more input data, until it returns with Z_STREAM_END or an error. After
- deflate has returned Z_STREAM_END, the only possible operations on the
- stream are deflateReset or deflateEnd.
-
- Z_FINISH can be used immediately after deflateInit if all the compression
- is to be done in a single step. In this case, avail_out must be at least
- the value returned by deflateBound (see below). If deflate does not return
- Z_STREAM_END, then it must be called again as described above.
-
- deflate() sets strm->adler to the adler32 checksum of all input read
- so far (that is, total_in bytes).
-
- deflate() may update strm->data_type if it can make a good guess about
- the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
- binary. This field is only for information purposes and does not affect
- the compression algorithm in any manner.
-
- deflate() returns Z_OK if some progress has been made (more input
- processed or more output produced), Z_STREAM_END if all input has been
- consumed and all output has been produced (only when flush is set to
- Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
- if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
- (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
- fatal, and deflate() can be called again with more input and more output
- space to continue compressing.
-*/
-
-
-ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
- stream state was inconsistent, Z_DATA_ERROR if the stream was freed
- prematurely (some input or output was discarded). In the error case,
- msg may be set but then points to a static string (which must not be
- deallocated).
-*/
-
-
-/*
-ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
-
- Initializes the internal stream state for decompression. The fields
- next_in, avail_in, zalloc, zfree and opaque must be initialized before by
- the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
- value depends on the compression method), inflateInit determines the
- compression method from the zlib header and allocates all data structures
- accordingly; otherwise the allocation will be deferred to the first call of
- inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
- use default allocation functions.
-
- inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
- version assumed by the caller. msg is set to null if there is no error
- message. inflateInit does not perform any decompression apart from reading
- the zlib header if present: this will be done by inflate(). (So next_in and
- avail_in may be modified, but next_out and avail_out are unchanged.)
-*/
-
-
-ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
-/*
- inflate decompresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce
- some output latency (reading input without producing any output) except when
- forced to flush.
-
- The detailed semantics are as follows. inflate performs one or both of the
- following actions:
-
- - Decompress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in is updated and processing
- will resume at this point for the next call of inflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. inflate() provides as much output as possible, until there
- is no more input data or no more space in the output buffer (see below
- about the flush parameter).
-
- Before the call of inflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating the next_* and avail_* values accordingly.
- The application can consume the uncompressed output when it wants, for
- example when the output buffer is full (avail_out == 0), or after each
- call of inflate(). If inflate returns Z_OK and with zero avail_out, it
- must be called again after making room in the output buffer because there
- might be more output pending.
-
- The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
- Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
- output as possible to the output buffer. Z_BLOCK requests that inflate() stop
- if and when it gets to the next deflate block boundary. When decoding the
- zlib or gzip format, this will cause inflate() to return immediately after
- the header and before the first block. When doing a raw inflate, inflate()
- will go ahead and process the first block, and will return when it gets to
- the end of that block, or when it runs out of data.
-
- The Z_BLOCK option assists in appending to or combining deflate streams.
- Also to assist in this, on return inflate() will set strm->data_type to the
- number of unused bits in the last byte taken from strm->next_in, plus 64
- if inflate() is currently decoding the last block in the deflate stream,
- plus 128 if inflate() returned immediately after decoding an end-of-block
- code or decoding the complete header up to just before the first byte of the
- deflate stream. The end-of-block will not be indicated until all of the
- uncompressed data from that block has been written to strm->next_out. The
- number of unused bits may in general be greater than seven, except when
- bit 7 of data_type is set, in which case the number of unused bits will be
- less than eight.
-
- inflate() should normally be called until it returns Z_STREAM_END or an
- error. However if all decompression is to be performed in a single step
- (a single call of inflate), the parameter flush should be set to
- Z_FINISH. In this case all pending input is processed and all pending
- output is flushed; avail_out must be large enough to hold all the
- uncompressed data. (The size of the uncompressed data may have been saved
- by the compressor for this purpose.) The next operation on this stream must
- be inflateEnd to deallocate the decompression state. The use of Z_FINISH
- is never required, but can be used to inform inflate that a faster approach
- may be used for the single inflate() call.
-
- In this implementation, inflate() always flushes as much output as
- possible to the output buffer, and always uses the faster approach on the
- first call. So the only effect of the flush parameter in this implementation
- is on the return value of inflate(), as noted below, or when it returns early
- because Z_BLOCK is used.
-
- If a preset dictionary is needed after this call (see inflateSetDictionary
- below), inflate sets strm->adler to the adler32 checksum of the dictionary
- chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
- strm->adler to the adler32 checksum of all output produced so far (that is,
- total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
- below. At the end of the stream, inflate() checks that its computed adler32
- checksum is equal to that saved by the compressor and returns Z_STREAM_END
- only if the checksum is correct.
-
- inflate() will decompress and check either zlib-wrapped or gzip-wrapped
- deflate data. The header type is detected automatically. Any information
- contained in the gzip header is not retained, so applications that need that
- information should instead use raw inflate, see inflateInit2() below, or
- inflateBack() and perform their own processing of the gzip header and
- trailer.
-
- inflate() returns Z_OK if some progress has been made (more input processed
- or more output produced), Z_STREAM_END if the end of the compressed data has
- been reached and all uncompressed output has been produced, Z_NEED_DICT if a
- preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
- corrupted (input stream not conforming to the zlib format or incorrect check
- value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
- if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
- Z_BUF_ERROR if no progress is possible or if there was not enough room in the
- output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
- inflate() can be called again with more input and more output space to
- continue decompressing. If Z_DATA_ERROR is returned, the application may then
- call inflateSync() to look for a good compression block if a partial recovery
- of the data is desired.
-*/
-
-
-ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
- was inconsistent. In the error case, msg may be set but then points to a
- static string (which must not be deallocated).
-*/
-
- /* Advanced functions */
-
-/*
- The following functions are needed only in some special applications.
-*/
-
-/*
-ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
- int level,
- int method,
- int windowBits,
- int memLevel,
- int strategy));
-
- This is another version of deflateInit with more compression options. The
- fields next_in, zalloc, zfree and opaque must be initialized before by
- the caller.
-
- The method parameter is the compression method. It must be Z_DEFLATED in
- this version of the library.
-
- The windowBits parameter is the base two logarithm of the window size
- (the size of the history buffer). It should be in the range 8..15 for this
- version of the library. Larger values of this parameter result in better
- compression at the expense of memory usage. The default value is 15 if
- deflateInit is used instead.
-
- windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
- determines the window size. deflate() will then generate raw deflate data
- with no zlib header or trailer, and will not compute an adler32 check value.
-
- windowBits can also be greater than 15 for optional gzip encoding. Add
- 16 to windowBits to write a simple gzip header and trailer around the
- compressed data instead of a zlib wrapper. The gzip header will have no
- file name, no extra data, no comment, no modification time (set to zero),
- no header crc, and the operating system will be set to 255 (unknown). If a
- gzip stream is being written, strm->adler is a crc32 instead of an adler32.
-
- The memLevel parameter specifies how much memory should be allocated
- for the internal compression state. memLevel=1 uses minimum memory but
- is slow and reduces compression ratio; memLevel=9 uses maximum memory
- for optimal speed. The default value is 8. See zconf.h for total memory
- usage as a function of windowBits and memLevel.
-
- The strategy parameter is used to tune the compression algorithm. Use the
- value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
- filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
- string match), or Z_RLE to limit match distances to one (run-length
- encoding). Filtered data consists mostly of small values with a somewhat
- random distribution. In this case, the compression algorithm is tuned to
- compress them better. The effect of Z_FILTERED is to force more Huffman
- coding and less string matching; it is somewhat intermediate between
- Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
- Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
- parameter only affects the compression ratio but not the correctness of the
- compressed output even if it is not set appropriately. Z_FIXED prevents the
- use of dynamic Huffman codes, allowing for a simpler decoder for special
- applications.
-
- deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
- method). msg is set to null if there is no error message. deflateInit2 does
- not perform any compression: this will be done by deflate().
-*/
-
-ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength));
-/*
- Initializes the compression dictionary from the given byte sequence
- without producing any compressed output. This function must be called
- immediately after deflateInit, deflateInit2 or deflateReset, before any
- call of deflate. The compressor and decompressor must use exactly the same
- dictionary (see inflateSetDictionary).
-
- The dictionary should consist of strings (byte sequences) that are likely
- to be encountered later in the data to be compressed, with the most commonly
- used strings preferably put towards the end of the dictionary. Using a
- dictionary is most useful when the data to be compressed is short and can be
- predicted with good accuracy; the data can then be compressed better than
- with the default empty dictionary.
-
- Depending on the size of the compression data structures selected by
- deflateInit or deflateInit2, a part of the dictionary may in effect be
- discarded, for example if the dictionary is larger than the window size in
- deflate or deflate2. Thus the strings most likely to be useful should be
- put at the end of the dictionary, not at the front. In addition, the
- current implementation of deflate will use at most the window size minus
- 262 bytes of the provided dictionary.
-
- Upon return of this function, strm->adler is set to the adler32 value
- of the dictionary; the decompressor may later use this value to determine
- which dictionary has been used by the compressor. (The adler32 value
- applies to the whole dictionary even if only a subset of the dictionary is
- actually used by the compressor.) If a raw deflate was requested, then the
- adler32 value is not computed and strm->adler is not set.
-
- deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state is
- inconsistent (for example if deflate has already been called for this stream
- or if the compression method is bsort). deflateSetDictionary does not
- perform any compression: this will be done by deflate().
-*/
-
-ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
- z_streamp source));
-/*
- Sets the destination stream as a complete copy of the source stream.
-
- This function can be useful when several compression strategies will be
- tried, for example when there are several ways of pre-processing the input
- data with a filter. The streams that will be discarded should then be freed
- by calling deflateEnd. Note that deflateCopy duplicates the internal
- compression state which can be quite large, so this strategy is slow and
- can consume lots of memory.
-
- deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being NULL). msg is left unchanged in both source and
- destination.
-*/
-
-ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
-/*
- This function is equivalent to deflateEnd followed by deflateInit,
- but does not free and reallocate all the internal compression state.
- The stream will keep the same compression level and any other attributes
- that may have been set by deflateInit2.
-
- deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
- int level,
- int strategy));
-/*
- Dynamically update the compression level and compression strategy. The
- interpretation of level and strategy is as in deflateInit2. This can be
- used to switch between compression and straight copy of the input data, or
- to switch to a different kind of input data requiring a different
- strategy. If the compression level is changed, the input available so far
- is compressed with the old level (and may be flushed); the new level will
- take effect only at the next call of deflate().
-
- Before the call of deflateParams, the stream state must be set as for
- a call of deflate(), since the currently available input may have to
- be compressed and flushed. In particular, strm->avail_out must be non-zero.
-
- deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
- stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
- if strm->avail_out was zero.
-*/
-
-ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
- int good_length,
- int max_lazy,
- int nice_length,
- int max_chain));
-/*
- Fine tune deflate's internal compression parameters. This should only be
- used by someone who understands the algorithm used by zlib's deflate for
- searching for the best matching string, and even then only by the most
- fanatic optimizer trying to squeeze out the last compressed bit for their
- specific input data. Read the deflate.c source code for the meaning of the
- max_lazy, good_length, nice_length, and max_chain parameters.
-
- deflateTune() can be called after deflateInit() or deflateInit2(), and
- returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
- */
-
-ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
- uLong sourceLen));
-/*
- deflateBound() returns an upper bound on the compressed size after
- deflation of sourceLen bytes. It must be called after deflateInit()
- or deflateInit2(). This would be used to allocate an output buffer
- for deflation in a single pass, and so would be called before deflate().
-*/
-
-ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
- int bits,
- int value));
-/*
- deflatePrime() inserts bits in the deflate output stream. The intent
- is that this function is used to start off the deflate output with the
- bits leftover from a previous deflate stream when appending to it. As such,
- this function can only be used for raw deflate, and must be used before the
- first deflate() call after a deflateInit2() or deflateReset(). bits must be
- less than or equal to 16, and that many of the least significant bits of
- value will be inserted in the output.
-
- deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
- gz_headerp head));
-/*
- deflateSetHeader() provides gzip header information for when a gzip
- stream is requested by deflateInit2(). deflateSetHeader() may be called
- after deflateInit2() or deflateReset() and before the first call of
- deflate(). The text, time, os, extra field, name, and comment information
- in the provided gz_header structure are written to the gzip header (xflag is
- ignored -- the extra flags are set according to the compression level). The
- caller must assure that, if not Z_NULL, name and comment are terminated with
- a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
- available there. If hcrc is true, a gzip header crc is included. Note that
- the current versions of the command-line version of gzip (up through version
- 1.3.x) do not support header crc's, and will report that it is a "multi-part
- gzip file" and give up.
-
- If deflateSetHeader is not used, the default gzip header has text false,
- the time set to zero, and os set to 255, with no extra, name, or comment
- fields. The gzip header is returned to the default state by deflateReset().
-
- deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-/*
-ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
- int windowBits));
-
- This is another version of inflateInit with an extra parameter. The
- fields next_in, avail_in, zalloc, zfree and opaque must be initialized
- before by the caller.
-
- The windowBits parameter is the base two logarithm of the maximum window
- size (the size of the history buffer). It should be in the range 8..15 for
- this version of the library. The default value is 15 if inflateInit is used
- instead. windowBits must be greater than or equal to the windowBits value
- provided to deflateInit2() while compressing, or it must be equal to 15 if
- deflateInit2() was not used. If a compressed stream with a larger window
- size is given as input, inflate() will return with the error code
- Z_DATA_ERROR instead of trying to allocate a larger window.
-
- windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
- determines the window size. inflate() will then process raw deflate data,
- not looking for a zlib or gzip header, not generating a check value, and not
- looking for any check values for comparison at the end of the stream. This
- is for use with other formats that use the deflate compressed data format
- such as zip. Those formats provide their own check values. If a custom
- format is developed using the raw deflate format for compressed data, it is
- recommended that a check value such as an adler32 or a crc32 be applied to
- the uncompressed data as is done in the zlib, gzip, and zip formats. For
- most applications, the zlib format should be used as is. Note that comments
- above on the use in deflateInit2() applies to the magnitude of windowBits.
-
- windowBits can also be greater than 15 for optional gzip decoding. Add
- 32 to windowBits to enable zlib and gzip decoding with automatic header
- detection, or add 16 to decode only the gzip format (the zlib format will
- return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
- a crc32 instead of an adler32.
-
- inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
- is set to null if there is no error message. inflateInit2 does not perform
- any decompression apart from reading the zlib header if present: this will
- be done by inflate(). (So next_in and avail_in may be modified, but next_out
- and avail_out are unchanged.)
-*/
-
-ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength));
-/*
- Initializes the decompression dictionary from the given uncompressed byte
- sequence. This function must be called immediately after a call of inflate,
- if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
- can be determined from the adler32 value returned by that call of inflate.
- The compressor and decompressor must use exactly the same dictionary (see
- deflateSetDictionary). For raw inflate, this function can be called
- immediately after inflateInit2() or inflateReset() and before any call of
- inflate() to set the dictionary. The application must insure that the
- dictionary that was used for compression is provided.
-
- inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state is
- inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
- expected one (incorrect adler32 value). inflateSetDictionary does not
- perform any decompression: this will be done by subsequent calls of
- inflate().
-*/
-
-ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
-/*
- Skips invalid compressed data until a full flush point (see above the
- description of deflate with Z_FULL_FLUSH) can be found, or until all
- available input is skipped. No output is provided.
-
- inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
- if no more input was provided, Z_DATA_ERROR if no flush point has been found,
- or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
- case, the application may save the current current value of total_in which
- indicates where valid compressed data was found. In the error case, the
- application may repeatedly call inflateSync, providing more input each time,
- until success or end of the input data.
-*/
-
-ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
- z_streamp source));
-/*
- Sets the destination stream as a complete copy of the source stream.
-
- This function can be useful when randomly accessing a large stream. The
- first pass through the stream can periodically record the inflate state,
- allowing restarting inflate at those points when randomly accessing the
- stream.
-
- inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being NULL). msg is left unchanged in both source and
- destination.
-*/
-
-ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
-/*
- This function is equivalent to inflateEnd followed by inflateInit,
- but does not free and reallocate all the internal decompression state.
- The stream will keep attributes that may have been set by inflateInit2.
-
- inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
- int bits,
- int value));
-/*
- This function inserts bits in the inflate input stream. The intent is
- that this function is used to start inflating at a bit position in the
- middle of a byte. The provided bits will be used before any bytes are used
- from next_in. This function should only be used with raw inflate, and
- should be used before the first inflate() call after inflateInit2() or
- inflateReset(). bits must be less than or equal to 16, and that many of the
- least significant bits of value will be inserted in the input.
-
- inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
- gz_headerp head));
-/*
- inflateGetHeader() requests that gzip header information be stored in the
- provided gz_header structure. inflateGetHeader() may be called after
- inflateInit2() or inflateReset(), and before the first call of inflate().
- As inflate() processes the gzip stream, head->done is zero until the header
- is completed, at which time head->done is set to one. If a zlib stream is
- being decoded, then head->done is set to -1 to indicate that there will be
- no gzip header information forthcoming. Note that Z_BLOCK can be used to
- force inflate() to return immediately after header processing is complete
- and before any actual data is decompressed.
-
- The text, time, xflags, and os fields are filled in with the gzip header
- contents. hcrc is set to true if there is a header CRC. (The header CRC
- was valid if done is set to one.) If extra is not Z_NULL, then extra_max
- contains the maximum number of bytes to write to extra. Once done is true,
- extra_len contains the actual extra field length, and extra contains the
- extra field, or that field truncated if extra_max is less than extra_len.
- If name is not Z_NULL, then up to name_max characters are written there,
- terminated with a zero unless the length is greater than name_max. If
- comment is not Z_NULL, then up to comm_max characters are written there,
- terminated with a zero unless the length is greater than comm_max. When
- any of extra, name, or comment are not Z_NULL and the respective field is
- not present in the header, then that field is set to Z_NULL to signal its
- absence. This allows the use of deflateSetHeader() with the returned
- structure to duplicate the header. However if those fields are set to
- allocated memory, then the application will need to save those pointers
- elsewhere so that they can be eventually freed.
-
- If inflateGetHeader is not used, then the header information is simply
- discarded. The header is always checked for validity, including the header
- CRC if present. inflateReset() will reset the process to discard the header
- information. The application would need to call inflateGetHeader() again to
- retrieve the header from the next gzip stream.
-
- inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-/*
-ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
- unsigned char FAR *window));
-
- Initialize the internal stream state for decompression using inflateBack()
- calls. The fields zalloc, zfree and opaque in strm must be initialized
- before the call. If zalloc and zfree are Z_NULL, then the default library-
- derived memory allocation routines are used. windowBits is the base two
- logarithm of the window size, in the range 8..15. window is a caller
- supplied buffer of that size. Except for special applications where it is
- assured that deflate was used with small window sizes, windowBits must be 15
- and a 32K byte window must be supplied to be able to decompress general
- deflate streams.
-
- See inflateBack() for the usage of these routines.
-
- inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
- the paramaters are invalid, Z_MEM_ERROR if the internal state could not
- be allocated, or Z_VERSION_ERROR if the version of the library does not
- match the version of the header file.
-*/
-
-typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
-typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
-
-ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
- in_func in, void FAR *in_desc,
- out_func out, void FAR *out_desc));
-/*
- inflateBack() does a raw inflate with a single call using a call-back
- interface for input and output. This is more efficient than inflate() for
- file i/o applications in that it avoids copying between the output and the
- sliding window by simply making the window itself the output buffer. This
- function trusts the application to not change the output buffer passed by
- the output function, at least until inflateBack() returns.
-
- inflateBackInit() must be called first to allocate the internal state
- and to initialize the state with the user-provided window buffer.
- inflateBack() may then be used multiple times to inflate a complete, raw
- deflate stream with each call. inflateBackEnd() is then called to free
- the allocated state.
-
- A raw deflate stream is one with no zlib or gzip header or trailer.
- This routine would normally be used in a utility that reads zip or gzip
- files and writes out uncompressed files. The utility would decode the
- header and process the trailer on its own, hence this routine expects
- only the raw deflate stream to decompress. This is different from the
- normal behavior of inflate(), which expects either a zlib or gzip header and
- trailer around the deflate stream.
-
- inflateBack() uses two subroutines supplied by the caller that are then
- called by inflateBack() for input and output. inflateBack() calls those
- routines until it reads a complete deflate stream and writes out all of the
- uncompressed data, or until it encounters an error. The function's
- parameters and return types are defined above in the in_func and out_func
- typedefs. inflateBack() will call in(in_desc, &buf) which should return the
- number of bytes of provided input, and a pointer to that input in buf. If
- there is no input available, in() must return zero--buf is ignored in that
- case--and inflateBack() will return a buffer error. inflateBack() will call
- out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
- should return zero on success, or non-zero on failure. If out() returns
- non-zero, inflateBack() will return with an error. Neither in() nor out()
- are permitted to change the contents of the window provided to
- inflateBackInit(), which is also the buffer that out() uses to write from.
- The length written by out() will be at most the window size. Any non-zero
- amount of input may be provided by in().
-
- For convenience, inflateBack() can be provided input on the first call by
- setting strm->next_in and strm->avail_in. If that input is exhausted, then
- in() will be called. Therefore strm->next_in must be initialized before
- calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
- immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
- must also be initialized, and then if strm->avail_in is not zero, input will
- initially be taken from strm->next_in[0 .. strm->avail_in - 1].
-
- The in_desc and out_desc parameters of inflateBack() is passed as the
- first parameter of in() and out() respectively when they are called. These
- descriptors can be optionally used to pass any information that the caller-
- supplied in() and out() functions need to do their job.
-
- On return, inflateBack() will set strm->next_in and strm->avail_in to
- pass back any unused input that was provided by the last in() call. The
- return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
- if in() or out() returned an error, Z_DATA_ERROR if there was a format
- error in the deflate stream (in which case strm->msg is set to indicate the
- nature of the error), or Z_STREAM_ERROR if the stream was not properly
- initialized. In the case of Z_BUF_ERROR, an input or output error can be
- distinguished using strm->next_in which will be Z_NULL only if in() returned
- an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
- out() returning non-zero. (in() will always be called before out(), so
- strm->next_in is assured to be defined if out() returns non-zero.) Note
- that inflateBack() cannot return Z_OK.
-*/
-
-ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
-/*
- All memory allocated by inflateBackInit() is freed.
-
- inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
- state was inconsistent.
-*/
-
-ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
-/* Return flags indicating compile-time options.
-
- Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
- 1.0: size of uInt
- 3.2: size of uLong
- 5.4: size of voidpf (pointer)
- 7.6: size of z_off_t
-
- Compiler, assembler, and debug options:
- 8: DEBUG
- 9: ASMV or ASMINF -- use ASM code
- 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
- 11: 0 (reserved)
-
- One-time table building (smaller code, but not thread-safe if true):
- 12: BUILDFIXED -- build static block decoding tables when needed
- 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
- 14,15: 0 (reserved)
-
- Library content (indicates missing functionality):
- 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
- deflate code when not needed)
- 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
- and decode gzip streams (to avoid linking crc code)
- 18-19: 0 (reserved)
-
- Operation variations (changes in library functionality):
- 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
- 21: FASTEST -- deflate algorithm with only one, lowest compression level
- 22,23: 0 (reserved)
-
- The sprintf variant used by gzprintf (zero is best):
- 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
- 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
- 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
-
- Remainder:
- 27-31: 0 (reserved)
- */
-
-
- /* utility functions */
-
-/*
- The following utility functions are implemented on top of the
- basic stream-oriented functions. To simplify the interface, some
- default options are assumed (compression level and memory usage,
- standard memory allocation functions). The source code of these
- utility functions can easily be modified if you need special options.
-*/
-
-ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen));
-/*
- Compresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be at least the value returned
- by compressBound(sourceLen). Upon exit, destLen is the actual size of the
- compressed buffer.
- This function can be used to compress a whole file at once if the
- input file is mmap'ed.
- compress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer.
-*/
-
-ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen,
- int level));
-/*
- Compresses the source buffer into the destination buffer. The level
- parameter has the same meaning as in deflateInit. sourceLen is the byte
- length of the source buffer. Upon entry, destLen is the total size of the
- destination buffer, which must be at least the value returned by
- compressBound(sourceLen). Upon exit, destLen is the actual size of the
- compressed buffer.
-
- compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_BUF_ERROR if there was not enough room in the output buffer,
- Z_STREAM_ERROR if the level parameter is invalid.
-*/
-
-ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
-/*
- compressBound() returns an upper bound on the compressed size after
- compress() or compress2() on sourceLen bytes. It would be used before
- a compress() or compress2() call to allocate the destination buffer.
-*/
-
-ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen));
-/*
- Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be large enough to hold the
- entire uncompressed data. (The size of the uncompressed data must have
- been saved previously by the compressor and transmitted to the decompressor
- by some mechanism outside the scope of this compression library.)
- Upon exit, destLen is the actual size of the compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
-
- uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
-*/
-
-
-typedef voidp gzFile;
-
-ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
-/*
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb") but can also include a compression level
- ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
- Huffman only compression as in "wb1h", or 'R' for run-length encoding
- as in "wb1R". (See the description of deflateInit2 for more information
- about the strategy parameter.)
-
- gzopen can be used to read a file which is not in gzip format; in this
- case gzread will directly read from the file without decompression.
-
- gzopen returns NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR). */
-
-ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
-/*
- gzdopen() associates a gzFile with the file descriptor fd. File
- descriptors are obtained from calls like open, dup, creat, pipe or
- fileno (in the file has been previously opened with fopen).
- The mode parameter is as in gzopen.
- The next call of gzclose on the returned gzFile will also close the
- file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
- descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
- gzdopen returns NULL if there was insufficient memory to allocate
- the (de)compression state.
-*/
-
-ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
-/*
- Dynamically update the compression level or strategy. See the description
- of deflateInit2 for the meaning of these parameters.
- gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
- opened for writing.
-*/
-
-ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
-/*
- Reads the given number of uncompressed bytes from the compressed file.
- If the input file was not in gzip format, gzread copies the given number
- of bytes into the buffer.
- gzread returns the number of uncompressed bytes actually read (0 for
- end of file, -1 for error). */
-
-ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
- voidpc buf, unsigned len));
-/*
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of uncompressed bytes actually written
- (0 in case of error).
-*/
-
-ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
-/*
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written (0 in case of error). The number of
- uncompressed bytes written is limited to 4095. The caller should assure that
- this limit is not exceeded. If it is exceeded, then gzprintf() will return
- return an error (0) with nothing written. In this case, there may also be a
- buffer overflow with unpredictable consequences, which is possible only if
- zlib was compiled with the insecure functions sprintf() or vsprintf()
- because the secure snprintf() or vsnprintf() functions were not available.
-*/
-
-ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
-/*
- Writes the given null-terminated string to the compressed file, excluding
- the terminating null character.
- gzputs returns the number of characters written, or -1 in case of error.
-*/
-
-ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
-/*
- Reads bytes from the compressed file until len-1 characters are read, or
- a newline character is read and transferred to buf, or an end-of-file
- condition is encountered. The string is then terminated with a null
- character.
- gzgets returns buf, or Z_NULL in case of error.
-*/
-
-ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
-/*
- Writes c, converted to an unsigned char, into the compressed file.
- gzputc returns the value that was written, or -1 in case of error.
-*/
-
-ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
-/*
- Reads one byte from the compressed file. gzgetc returns this byte
- or -1 in case of end of file or error.
-*/
-
-ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
-/*
- Push one character back onto the stream to be read again later.
- Only one character of push-back is allowed. gzungetc() returns the
- character pushed, or -1 on failure. gzungetc() will fail if a
- character has been pushed but not read yet, or if c is -1. The pushed
- character will be discarded if the stream is repositioned with gzseek()
- or gzrewind().
-*/
-
-ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
-/*
- Flushes all pending output into the compressed file. The parameter
- flush is as in the deflate() function. The return value is the zlib
- error number (see function gzerror below). gzflush returns Z_OK if
- the flush parameter is Z_FINISH and all output could be flushed.
- gzflush should be called only when strictly necessary because it can
- degrade compression.
-*/
-
-ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
- z_off_t offset, int whence));
-/*
- Sets the starting position for the next gzread or gzwrite on the
- given compressed file. The offset represents a number of bytes in the
- uncompressed data stream. The whence parameter is defined as in lseek(2);
- the value SEEK_END is not supported.
- If the file is opened for reading, this function is emulated but can be
- extremely slow. If the file is opened for writing, only forward seeks are
- supported; gzseek then compresses a sequence of zeroes up to the new
- starting position.
-
- gzseek returns the resulting offset location as measured in bytes from
- the beginning of the uncompressed stream, or -1 in case of error, in
- particular if the file is opened for writing and the new starting position
- would be before the current position.
-*/
-
-ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
-/*
- Rewinds the given file. This function is supported only for reading.
-
- gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
-*/
-
-ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
-/*
- Returns the starting position for the next gzread or gzwrite on the
- given compressed file. This position represents a number of bytes in the
- uncompressed data stream.
-
- gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
-*/
-
-ZEXTERN int ZEXPORT gzeof OF((gzFile file));
-/*
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
-*/
-
-ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
-/*
- Returns 1 if file is being read directly without decompression, otherwise
- zero.
-*/
-
-ZEXTERN int ZEXPORT gzclose OF((gzFile file));
-/*
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state. The return value is the zlib
- error number (see function gzerror below).
-*/
-
-ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
-/*
- Returns the error message for the last error which occurred on the
- given compressed file. errnum is set to zlib error number. If an
- error occurred in the file system and not in the compression library,
- errnum is set to Z_ERRNO and the application may consult errno
- to get the exact error code.
-*/
-
-ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
-/*
- Clears the error and end-of-file flags for file. This is analogous to the
- clearerr() function in stdio. This is useful for continuing to read a gzip
- file that is being written concurrently.
-*/
-
- /* checksum functions */
-
-/*
- These functions are not related to compression but are exported
- anyway because they might be useful in applications using the
- compression library.
-*/
-
-ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
-/*
- Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is NULL, this function returns
- the required initial value for the checksum.
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster. Usage example:
-
- uLong adler = adler32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- adler = adler32(adler, buffer, length);
- }
- if (adler != original_adler) error();
-*/
-
-ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
- z_off_t len2));
-/*
- Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
- and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
- each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
- seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
-*/
-
-ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
-/*
- Update a running CRC-32 with the bytes buf[0..len-1] and return the
- updated CRC-32. If buf is NULL, this function returns the required initial
- value for the for the crc. Pre- and post-conditioning (one's complement) is
- performed within this function so it shouldn't be done by the application.
- Usage example:
-
- uLong crc = crc32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- crc = crc32(crc, buffer, length);
- }
- if (crc != original_crc) error();
-*/
-
-ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
-
-/*
- Combine two CRC-32 check values into one. For two sequences of bytes,
- seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
- calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
- check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
- len2.
-*/
-
-
- /* various hacks, don't look :) */
-
-/* deflateInit and inflateInit are macros to allow checking the zlib version
- * and the compiler's view of z_stream:
- */
-ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
- const char *version, int stream_size));
-ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
- const char *version, int stream_size));
-ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
- int windowBits, int memLevel,
- int strategy, const char *version,
- int stream_size));
-ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
- const char *version, int stream_size));
-ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
- unsigned char FAR *window,
- const char *version,
- int stream_size));
-#define deflateInit(strm, level) \
- deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit(strm) \
- inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
-#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
- deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
- (strategy), ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit2(strm, windowBits) \
- inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
-#define inflateBackInit(strm, windowBits, window) \
- inflateBackInit_((strm), (windowBits), (window), \
- ZLIB_VERSION, sizeof(z_stream))
-
-
-#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
- struct internal_state {int dummy;}; /* hack for buggy compilers */
-#endif
-
-ZEXTERN const char * ZEXPORT zError OF((int));
-ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
-ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ZLIB_H */
diff --git a/dep/StormLib/src/zlib/zutil.c b/dep/StormLib/src/zlib/zutil.c
deleted file mode 100644
index d55f5948a37..00000000000
--- a/dep/StormLib/src/zlib/zutil.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#include "zutil.h"
-
-#ifndef NO_DUMMY_DECL
-struct internal_state {int dummy;}; /* for buggy compilers */
-#endif
-
-const char * const z_errmsg[10] = {
-"need dictionary", /* Z_NEED_DICT 2 */
-"stream end", /* Z_STREAM_END 1 */
-"", /* Z_OK 0 */
-"file error", /* Z_ERRNO (-1) */
-"stream error", /* Z_STREAM_ERROR (-2) */
-"data error", /* Z_DATA_ERROR (-3) */
-"insufficient memory", /* Z_MEM_ERROR (-4) */
-"buffer error", /* Z_BUF_ERROR (-5) */
-"incompatible version",/* Z_VERSION_ERROR (-6) */
-""};
-
-
-const char * ZEXPORT zlibVersion()
-{
- return ZLIB_VERSION;
-}
-
-uLong ZEXPORT zlibCompileFlags()
-{
- uLong flags;
-
- flags = 0;
- switch (sizeof(uInt)) {
- case 2: break;
- case 4: flags += 1; break;
- case 8: flags += 2; break;
- default: flags += 3;
- }
- switch (sizeof(uLong)) {
- case 2: break;
- case 4: flags += 1 << 2; break;
- case 8: flags += 2 << 2; break;
- default: flags += 3 << 2;
- }
- switch (sizeof(voidpf)) {
- case 2: break;
- case 4: flags += 1 << 4; break;
- case 8: flags += 2 << 4; break;
- default: flags += 3 << 4;
- }
- switch (sizeof(z_off_t)) {
- case 2: break;
- case 4: flags += 1 << 6; break;
- case 8: flags += 2 << 6; break;
- default: flags += 3 << 6;
- }
-#ifdef DEBUG
- flags += 1 << 8;
-#endif
-#if defined(ASMV) || defined(ASMINF)
- flags += 1 << 9;
-#endif
-#ifdef ZLIB_WINAPI
- flags += 1 << 10;
-#endif
-#ifdef BUILDFIXED
- flags += 1 << 12;
-#endif
-#ifdef DYNAMIC_CRC_TABLE
- flags += 1 << 13;
-#endif
-#ifdef NO_GZCOMPRESS
- flags += 1L << 16;
-#endif
-#ifdef NO_GZIP
- flags += 1L << 17;
-#endif
-#ifdef PKZIP_BUG_WORKAROUND
- flags += 1L << 20;
-#endif
-#ifdef FASTEST
- flags += 1L << 21;
-#endif
-#ifdef STDC
-# ifdef NO_vsnprintf
- flags += 1L << 25;
-# ifdef HAS_vsprintf_void
- flags += 1L << 26;
-# endif
-# else
-# ifdef HAS_vsnprintf_void
- flags += 1L << 26;
-# endif
-# endif
-#else
- flags += 1L << 24;
-# ifdef NO_snprintf
- flags += 1L << 25;
-# ifdef HAS_sprintf_void
- flags += 1L << 26;
-# endif
-# else
-# ifdef HAS_snprintf_void
- flags += 1L << 26;
-# endif
-# endif
-#endif
- return flags;
-}
-
-#ifdef DEBUG
-
-# ifndef verbose
-# define verbose 0
-# endif
-int z_verbose = verbose;
-
-void z_error (m)
- char *m;
-{
- fprintf(stderr, "%s\n", m);
- exit(1);
-}
-#endif
-
-/* exported to allow conversion of error code to string for compress() and
- * uncompress()
- */
-const char * ZEXPORT zError(err)
- int err;
-{
- return ERR_MSG(err);
-}
-
-#if defined(_WIN32_WCE)
- /* The Microsoft C Run-Time Library for Windows CE doesn't have
- * errno. We define it as a global variable to simplify porting.
- * Its value is always 0 and should not be used.
- */
- int errno = 0;
-#endif
-
-#ifndef HAVE_MEMCPY
-
-void zmemcpy(dest, source, len)
- Bytef* dest;
- const Bytef* source;
- uInt len;
-{
- if (len == 0) return;
- do {
- *dest++ = *source++; /* ??? to be unrolled */
- } while (--len != 0);
-}
-
-int zmemcmp(s1, s2, len)
- const Bytef* s1;
- const Bytef* s2;
- uInt len;
-{
- uInt j;
-
- for (j = 0; j < len; j++) {
- if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
- }
- return 0;
-}
-
-void zmemzero(dest, len)
- Bytef* dest;
- uInt len;
-{
- if (len == 0) return;
- do {
- *dest++ = 0; /* ??? to be unrolled */
- } while (--len != 0);
-}
-#endif
-
-
-#ifdef SYS16BIT
-
-#ifdef __TURBOC__
-/* Turbo C in 16-bit mode */
-
-# define MY_ZCALLOC
-
-/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
- * and farmalloc(64K) returns a pointer with an offset of 8, so we
- * must fix the pointer. Warning: the pointer must be put back to its
- * original form in order to free it, use zcfree().
- */
-
-#define MAX_PTR 10
-/* 10*64K = 640K */
-
-local int next_ptr = 0;
-
-typedef struct ptr_table_s {
- voidpf org_ptr;
- voidpf new_ptr;
-} ptr_table;
-
-local ptr_table table[MAX_PTR];
-/* This table is used to remember the original form of pointers
- * to large buffers (64K). Such pointers are normalized with a zero offset.
- * Since MSDOS is not a preemptive multitasking OS, this table is not
- * protected from concurrent access. This hack doesn't work anyway on
- * a protected system like OS/2. Use Microsoft C instead.
- */
-
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-{
- voidpf buf = opaque; /* just to make some compilers happy */
- ulg bsize = (ulg)items*size;
-
- /* If we allocate less than 65520 bytes, we assume that farmalloc
- * will return a usable pointer which doesn't have to be normalized.
- */
- if (bsize < 65520L) {
- buf = farmalloc(bsize);
- if (*(ush*)&buf != 0) return buf;
- } else {
- buf = farmalloc(bsize + 16L);
- }
- if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
- table[next_ptr].org_ptr = buf;
-
- /* Normalize the pointer to seg:0 */
- *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
- *(ush*)&buf = 0;
- table[next_ptr++].new_ptr = buf;
- return buf;
-}
-
-void zcfree (voidpf opaque, voidpf ptr)
-{
- int n;
- if (*(ush*)&ptr != 0) { /* object < 64K */
- farfree(ptr);
- return;
- }
- /* Find the original pointer */
- for (n = 0; n < next_ptr; n++) {
- if (ptr != table[n].new_ptr) continue;
-
- farfree(table[n].org_ptr);
- while (++n < next_ptr) {
- table[n-1] = table[n];
- }
- next_ptr--;
- return;
- }
- ptr = opaque; /* just to make some compilers happy */
- Assert(0, "zcfree: ptr not found");
-}
-
-#endif /* __TURBOC__ */
-
-
-#ifdef M_I86
-/* Microsoft C in 16-bit mode */
-
-# define MY_ZCALLOC
-
-#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
-# define _halloc halloc
-# define _hfree hfree
-#endif
-
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-{
- if (opaque) opaque = 0; /* to make compiler happy */
- return _halloc((long)items, size);
-}
-
-void zcfree (voidpf opaque, voidpf ptr)
-{
- if (opaque) opaque = 0; /* to make compiler happy */
- _hfree(ptr);
-}
-
-#endif /* M_I86 */
-
-#endif /* SYS16BIT */
-
-
-#ifndef MY_ZCALLOC /* Any system without a special alloc function */
-
-#ifndef STDC
-extern voidp malloc OF((uInt size));
-extern voidp calloc OF((uInt items, uInt size));
-extern void free OF((voidpf ptr));
-#endif
-
-voidpf zcalloc (opaque, items, size)
- voidpf opaque;
- unsigned items;
- unsigned size;
-{
- if (opaque) items += size - size; /* make compiler happy */
- return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
- (voidpf)calloc(items, size);
-}
-
-void zcfree (opaque, ptr)
- voidpf opaque;
- voidpf ptr;
-{
- free(ptr);
- if (opaque) return; /* make compiler happy */
-}
-
-#endif /* MY_ZCALLOC */
diff --git a/dep/StormLib/src/zlib/zutil.h b/dep/StormLib/src/zlib/zutil.h
deleted file mode 100644
index b7d5eff81b6..00000000000
--- a/dep/StormLib/src/zlib/zutil.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id$ */
-
-#ifndef ZUTIL_H
-#define ZUTIL_H
-
-#define ZLIB_INTERNAL
-#include "zlib.h"
-
-#ifdef STDC
-# ifndef _WIN32_WCE
-# include <stddef.h>
-# endif
-# include <string.h>
-# include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
-# ifdef _WIN32_WCE
- /* The Microsoft C Run-Time Library for Windows CE doesn't have
- * errno. We define it as a global variable to simplify porting.
- * Its value is always 0 and should not be used. We rename it to
- * avoid conflict with other libraries that use the same workaround.
- */
-# define errno z_errno
-# endif
- extern int errno;
-#else
-# ifndef _WIN32_WCE
-# include <errno.h>
-# endif
-#endif
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-typedef unsigned char uch;
-typedef uch FAR uchf;
-typedef unsigned short ush;
-typedef ush FAR ushf;
-typedef unsigned long ulg;
-
-extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
-/* (size given to avoid silly warnings with Visual C++) */
-
-#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
-
-#define ERR_RETURN(strm,err) \
- return (strm->msg = (char*)ERR_MSG(err), (err))
-/* To be used only when the state is known to be valid */
-
- /* common constants */
-
-#ifndef DEF_WBITS
-# define DEF_WBITS MAX_WBITS
-#endif
-/* default windowBits for decompression. MAX_WBITS is for compression only */
-
-#if MAX_MEM_LEVEL >= 8
-# define DEF_MEM_LEVEL 8
-#else
-# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-#endif
-/* default memLevel */
-
-#define STORED_BLOCK 0
-#define STATIC_TREES 1
-#define DYN_TREES 2
-/* The three kinds of block type */
-
-#define MIN_MATCH 3
-#define MAX_MATCH 258
-/* The minimum and maximum match lengths */
-
-#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
-
- /* target dependencies */
-
-#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
-# define OS_CODE 0x00
-# if defined(__TURBOC__) || defined(__BORLANDC__)
-# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
- /* Allow compilation with ANSI keywords only enabled */
- void _Cdecl farfree( void *block );
- void *_Cdecl farmalloc( unsigned long nbytes );
-# else
-# include <alloc.h>
-# endif
-# else /* MSC or DJGPP */
-# include <malloc.h>
-# endif
-#endif
-
-#ifdef AMIGA
-# define OS_CODE 0x01
-#endif
-
-#if defined(VAXC) || defined(VMS)
-# define OS_CODE 0x02
-# define F_OPEN(name, mode) \
- fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
-#endif
-
-#if defined(ATARI) || defined(atarist)
-# define OS_CODE 0x05
-#endif
-
-#ifdef OS2
-# define OS_CODE 0x06
-# ifdef M_I86
- #include <malloc.h>
-# endif
-#endif
-
-#if defined(MACOS) || defined(TARGET_OS_MAC)
-# define OS_CODE 0x07
-# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
-# include <unix.h> /* for fdopen */
-# else
-# ifndef fdopen
-# define fdopen(fd,mode) NULL /* No fdopen() */
-# endif
-# endif
-#endif
-
-#ifdef TOPS20
-# define OS_CODE 0x0a
-#endif
-
-#ifdef WIN32
-# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
-# define OS_CODE 0x0b
-# endif
-#endif
-
-#ifdef __50SERIES /* Prime/PRIMOS */
-# define OS_CODE 0x0f
-#endif
-
-#if defined(_BEOS_) || defined(RISCOS)
-# define fdopen(fd,mode) NULL /* No fdopen() */
-#endif
-
-#if (defined(_MSC_VER) && (_MSC_VER > 600))
-# if defined(_WIN32_WCE)
-# define fdopen(fd,mode) NULL /* No fdopen() */
-# ifndef _PTRDIFF_T_DEFINED
- typedef int ptrdiff_t;
-# define _PTRDIFF_T_DEFINED
-# endif
-# else
-# define fdopen(fd,type) _fdopen(fd,type)
-# endif
-#endif
-
- /* common defaults */
-
-#ifndef OS_CODE
-# define OS_CODE 0x03 /* assume Unix */
-#endif
-
-#ifndef F_OPEN
-# define F_OPEN(name, mode) fopen((name), (mode))
-#endif
-
- /* functions */
-
-#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
-# ifndef HAVE_VSNPRINTF
-# define HAVE_VSNPRINTF
-# endif
-#endif
-#if defined(__CYGWIN__)
-# ifndef HAVE_VSNPRINTF
-# define HAVE_VSNPRINTF
-# endif
-#endif
-#ifndef HAVE_VSNPRINTF
-# ifdef MSDOS
- /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
- but for now we just assume it doesn't. */
-# define NO_vsnprintf
-# endif
-# ifdef __TURBOC__
-# define NO_vsnprintf
-# endif
-# ifdef WIN32
- /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
-# if !defined(vsnprintf) && !defined(NO_vsnprintf)
-# define vsnprintf _vsnprintf
-# endif
-# endif
-# ifdef __SASC
-# define NO_vsnprintf
-# endif
-#endif
-#ifdef VMS
-# define NO_vsnprintf
-#endif
-
-#if defined(pyr)
-# define NO_MEMCPY
-#endif
-#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
- /* Use our own functions for small and medium model with MSC <= 5.0.
- * You may have to use the same strategy for Borland C (untested).
- * The __SC__ check is for Symantec.
- */
-# define NO_MEMCPY
-#endif
-#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
-# define HAVE_MEMCPY
-#endif
-#ifdef HAVE_MEMCPY
-# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
-# define zmemcpy _fmemcpy
-# define zmemcmp _fmemcmp
-# define zmemzero(dest, len) _fmemset(dest, 0, len)
-# else
-# define zmemcpy memcpy
-# define zmemcmp memcmp
-# define zmemzero(dest, len) memset(dest, 0, len)
-# endif
-#else
- extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
- extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
- extern void zmemzero OF((Bytef* dest, uInt len));
-#endif
-
-/* Diagnostic functions */
-#ifdef DEBUG
-# include <stdio.h>
- extern int z_verbose;
- extern void z_error OF((char *m));
-# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-# define Trace(x) {if (z_verbose>=0) fprintf x ;}
-# define Tracev(x) {if (z_verbose>0) fprintf x ;}
-# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
-# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
-# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
-#else
-# define Assert(cond,msg)
-# define Trace(x)
-# define Tracev(x)
-# define Tracevv(x)
-# define Tracec(c,x)
-# define Tracecv(c,x)
-#endif
-
-
-voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
-void zcfree OF((voidpf opaque, voidpf ptr));
-
-#define ZALLOC(strm, items, size) \
- (*((strm)->zalloc))((strm)->opaque, (items), (size))
-#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
-#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
-
-#endif /* ZUTIL_H */
diff --git a/dep/StormLib/storm_dll/storm_dll.cpp b/dep/StormLib/storm_dll/storm_dll.cpp
deleted file mode 100644
index 2941f2a37f5..00000000000
--- a/dep/StormLib/storm_dll/storm_dll.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/*****************************************************************************/
-/* Storm.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* This is just a dummy module for building import library for Storm.dll */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 11.04.03 1.00 Lad The first version of Storm.cpp */
-/*****************************************************************************/
-
-#include <windows.h>
-
-#define BUILDING_STORM_CPP
-#define STORM_ALTERNATE_NAMES
-#include "storm_dll.h"
-
-BOOL WINAPI SFILE(OpenArchive)(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags, HANDLE *hMPQ)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(CloseArchive)(HANDLE hMPQ)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(GetArchiveName)(HANDLE hMPQ, LPCSTR lpBuffer, DWORD dwBufferLength)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(OpenFile)(LPCSTR lpFileName, HANDLE *hFile)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(OpenFileEx)(HANDLE hMPQ, LPCSTR lpFileName, DWORD dwSearchScope, HANDLE *hFile)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(CloseFile)(HANDLE hFile)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-DWORD WINAPI SFILE(GetFileSize)(HANDLE hFile, LPDWORD lpFileSizeHigh)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(GetFileArchive)(HANDLE hFile, HANDLE *hMPQ)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(GetFileName)(HANDLE hFile, LPCSTR lpBuffer, DWORD dwBufferLength)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-DWORD WINAPI SFILE(SetFilePointer)(HANDLE hFile, long lDistanceToMove, PLONG lplDistanceToMoveHigh, DWORD dwMoveMethod)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(ReadFile)(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-LCID WINAPI SFILE(SetLocale)(LCID nNewLocale)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(GetBasePath)(LPCSTR lpBuffer, DWORD dwBufferLength)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(SetBasePath)(LPCSTR lpNewBasePath)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(Destroy)()
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SCOMP(Compress)(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int uCmp, int uCmpType, int nCmpLevel)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SCOMP(Decompress)(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
diff --git a/dep/StormLib/storm_dll/storm_dll.def b/dep/StormLib/storm_dll/storm_dll.def
deleted file mode 100644
index 8de88f5db3d..00000000000
--- a/dep/StormLib/storm_dll/storm_dll.def
+++ /dev/null
@@ -1,25 +0,0 @@
-; Storm definition file with alternate Storm.dll names
-LIBRARY "Storm"
-
-EXPORTS
- StormCloseArchive @252 ; 0x0FC
- StormCloseFile @253 ; 0x0FD
- StormDestroy @262 ; 0x106
- StormGetFileArchive @264 ; 0x108
- StormGetFileSize @265 ; 0x109
- StormOpenArchive @266 ; 0x10A
- StormOpenFile @267 ; 0x10B
- StormOpenFileEx @268 ; 0x10C
- StormReadFile @269 ; 0x10D
- StormSetBasePath @270 ; 0x10E
- StormSetFilePointer @271 ; 0x10F
- StormSetLocale @272 ; 0x110
- StormGetBasePath @273 ; 0x111
- StormGetArchiveName @275 ; 0x113
- StormGetFileName @276 ; 0x114
-
-; StormSetLastError @465 ; 0x
-
- StormCompress @551 ; 0x227
- StormDecompress @552 ; 0x228
- \ No newline at end of file
diff --git a/dep/StormLib/storm_dll/storm_dll.h b/dep/StormLib/storm_dll/storm_dll.h
deleted file mode 100644
index 6d67820a22f..00000000000
--- a/dep/StormLib/storm_dll/storm_dll.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*****************************************************************************/
-/* Storm.h Copyright Justin Olbrantz(Quantam) 2000 */
-/*---------------------------------------------------------------------------*/
-/* Storm Interface Library v1.0 for Windows */
-/* */
-/* Author : Justin Olbrantz(Quantam) */
-/* E-mail : omega@dragonfire.net */
-/* WWW : www.campaigncreations.com/starcraft/mpq2k/inside_mopaq/ */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* xx.xx.00 1.00 Qua The first version of Storm.h */
-/* 11.04.03 1.00 Lad Added some functions */
-/*****************************************************************************/
-
-// We need the Windows data types for the Storm prototypes
-#include <windows.h>
-
-#ifndef __STORM_H__
-#define __STORM_H__
-
-// Somethimes is necessary to change the function names so they
-// will not conflict with other MPQ tools.
-#ifdef STORM_ALTERNATE_NAMES
- #define SFILE(Name) Storm##Name
- #define SCOMP(Name) Storm##Name
-#else
- #define SFILE(Name) SFile##Name
- #define SCOMP(Name) SComp##Name
-#endif
-
-
-// Just in case anyone is still using C out there
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Storm file function prototypes
-BOOL WINAPI SFILE(OpenArchive)(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags, HANDLE *hMPQ);
-BOOL WINAPI SFILE(CloseArchive)(HANDLE hMPQ);
-BOOL WINAPI SFILE(GetArchiveName)(HANDLE hMPQ, LPCSTR lpBuffer, DWORD dwBufferLength);
-BOOL WINAPI SFILE(OpenFile)(LPCSTR lpFileName, HANDLE *hFile);
-BOOL WINAPI SFILE(OpenFileEx)(HANDLE hMPQ, LPCSTR lpFileName, DWORD dwSearchScope, HANDLE *hFile);
-BOOL WINAPI SFILE(CloseFile)(HANDLE hFile);
-DWORD WINAPI SFILE(GetFileSize)(HANDLE hFile, LPDWORD lpFileSizeHigh);
-BOOL WINAPI SFILE(GetFileArchive)(HANDLE hFile, HANDLE *hMPQ);
-BOOL WINAPI SFILE(GetFileName)(HANDLE hFile, LPCSTR lpBuffer, DWORD dwBufferLength);
-DWORD WINAPI SFILE(SetFilePointer)(HANDLE hFile, long lDistanceToMove, PLONG lplDistanceToMoveHigh, DWORD dwMoveMethod);
-BOOL WINAPI SFILE(ReadFile)(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped);
-LCID WINAPI SFILE(SetLocale)(LCID nNewLocale);
-BOOL WINAPI SFILE(GetBasePath)(LPCSTR lpBuffer, DWORD dwBufferLength);
-BOOL WINAPI SFILE(SetBasePath)(LPCSTR lpNewBasePath);
-
-// Storm (de)compression functions
-BOOL WINAPI SCOMP(Compress) (char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int uCmp, int uCmpType, int nCmpLevel);
-BOOL WINAPI SCOMP(Decompress)(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength);
-
-
-#if defined(_MSC_VER) && !defined(BUILDING_STORM_CPP)
-#pragma comment(lib, "Storm.lib") // Force linking Storm.lib and thus Storm.dll
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __STORM_H__
diff --git a/dep/StormLib/stormlib_dll/DllMain.c b/dep/StormLib/stormlib_dll/DllMain.c
deleted file mode 100644
index cbfa84a08a8..00000000000
--- a/dep/StormLib/stormlib_dll/DllMain.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/*****************************************************************************/
-/* DllMain.c Copyright (c) Ladislav Zezula 2006 */
-/*---------------------------------------------------------------------------*/
-/* Description: DllMain for the StormLib.dll library */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 23.11.06 1.00 Lad The first version of DllMain.c */
-/*****************************************************************************/
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-//-----------------------------------------------------------------------------
-// DllMain
-
-DWORD WINAPI DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved)
-{
- UNREFERENCED_PARAMETER(hInst);
- UNREFERENCED_PARAMETER(dwReason);
- UNREFERENCED_PARAMETER(lpReserved);
-
- return TRUE;
-}
diff --git a/dep/StormLib/stormlib_dll/StormLib.def b/dep/StormLib/stormlib_dll/StormLib.def
deleted file mode 100644
index 0ba91884313..00000000000
--- a/dep/StormLib/stormlib_dll/StormLib.def
+++ /dev/null
@@ -1,76 +0,0 @@
-;
-; Export file for Windows
-; Copyright (c) 2007-2010 Ladislav Zezula
-; ladik@zezula.net
-;
-
-LIBRARY StormLib.dll
-
-EXPORTS
-
- SFileSetLocale
- SFileGetLocale
-
- SFileOpenArchive
- SFileCreateArchive
- SFileGetArchiveBitmap
- SFileFlushArchive
- SFileCloseArchive
-
- SFileAddListFile
-
- SFileSetCompactCallback
- SFileCompactArchive
-
- SFileGetMaxFileCount
- SFileSetMaxFileCount
-
- SFileGetAttributes
- SFileSetAttributes
- SFileUpdateFileAttributes
-
- SFileOpenPatchArchive
- SFileIsPatchedArchive
-
- SFileOpenFileEx
- SFileGetFileSize
- SFileSetFilePointer
- SFileReadFile
- SFileCloseFile
-
- SFileHasFile
- SFileGetFileName
- SFileGetFileInfo
-
- SFileExtractFile
-
- SFileVerifyFile
- SFileVerifyRawData
- SFileVerifyArchive
-
- SFileFindFirstFile
- SFileFindNextFile
- SFileFindClose
-
- SListFileFindFirstFile
- SListFileFindNextFile
- SListFileFindClose
-
- SFileEnumLocales
-
- SFileCreateFile
- SFileWriteFile
- SFileFinishFile
- SFileAddFileEx
- SFileAddFile
- SFileAddWave
- SFileRemoveFile
- SFileRenameFile
- SFileSetFileLocale
- SFileSetDataCompression
- SFileSetAddFileCallback
-
- SCompImplode
- SCompExplode
- SCompCompress
- SCompDecompress
diff --git a/dep/StormLib/stormlib_dll/StormLib.exp b/dep/StormLib/stormlib_dll/StormLib.exp
deleted file mode 100644
index aa18edb7aab..00000000000
--- a/dep/StormLib/stormlib_dll/StormLib.exp
+++ /dev/null
@@ -1,75 +0,0 @@
-#
-# Export file for Mac OS X
-# Copyright (c) 2009 Sam Wilkins
-# swilkins1337@gmail.com
-#
-
-_SFileSetLocale
-_SFileGetLocale
-
-_SFileOpenArchive
-_SFileCreateArchive
-_SFileGetArchiveBitmap
-_SFileFlushArchive
-_SFileCloseArchive
-
-_SFileAddListFile
-
-_SFileSetCompactCallback
-_SFileCompactArchive
-
-_SFileGetMaxFileCount
-_SFileSetMaxFileCount
-
-_SFileGetAttributes
-_SFileSetAttributes
-_SFileUpdateFileAttributes
-
-_SFileOpenPatchArchive
-_SFileIsPatchedArchive
-
-_SFileOpenFileEx
-_SFileGetFileSize
-_SFileSetFilePointer
-_SFileReadFile
-_SFileCloseFile
-
-_SFileHasFile
-_SFileGetFileName
-_SFileGetFileInfo
-
-_SFileExtractFile
-
-_SFileVerifyFile
-_SFileVerifyRawData
-_SFileVerifyArchive
-
-_SFileFindFirstFile
-_SFileFindNextFile
-_SFileFindClose
-
-_SListFileFindFirstFile
-_SListFileFindNextFile
-_SListFileFindClose
-
-_SFileEnumLocales
-
-_SFileCreateFile
-_SFileWriteFile
-_SFileFinishFile
-_SFileAddFileEx
-_SFileAddFile
-_SFileAddWave
-_SFileRemoveFile
-_SFileRenameFile
-_SFileSetFileLocale
-_SFileSetDataCompression
-_SFileSetAddFileCallback
-
-_SCompImplode
-_SCompExplode
-_SCompCompress
-_SCompDecompress
-
-_SetLastError
-_GetLastError
diff --git a/dep/StormLib/test/Test.cpp b/dep/StormLib/test/Test.cpp
deleted file mode 100644
index e31c15fee29..00000000000
--- a/dep/StormLib/test/Test.cpp
+++ /dev/null
@@ -1,1892 +0,0 @@
-/*****************************************************************************/
-/* StormLibTest.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Test module for StormLib */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 25.03.03 1.00 Lad The first version of StormLibTest.cpp */
-/*****************************************************************************/
-
-#define _CRT_SECURE_NO_DEPRECATE
-#define __INCLUDE_CRYPTOGRAPHY__
-#define __STORMLIB_SELF__ // Don't use StormLib.lib
-#include <stdio.h>
-
-#ifdef _MSC_VER
-#include <crtdbg.h>
-#endif
-
-#include "../src/StormLib.h"
-#include "../src/StormCommon.h"
-
-#ifdef _MSC_VER
-#pragma warning(disable: 4505) // 'XXX' : unreferenced local function has been removed
-#endif
-
-//------------------------------------------------------------------------------
-// Defines
-
-#ifdef PLATFORM_WINDOWS
-#define WORK_PATH_ROOT "E:\\Multimedia\\MPQs\\"
-#endif
-
-#ifdef PLATFORM_LINUX
-#define WORK_PATH_ROOT "/home/user/MPQs/"
-#endif
-
-#ifdef PLATFORM_MAC
-#define WORK_PATH_ROOT "/Users/sam/StormLib/test"
-#endif
-
-#ifndef LANG_CZECH
-#define LANG_CZECH 0x0405
-#endif
-
-#define MPQ_SECTOR_SIZE 0x1000
-
-#define MAKE_PATH(path) _T(WORK_PATH_ROOT) _T(path)
-
-// Unicode MPQ names
-/* Czech */ static const wchar_t szUnicodeName1[] = {0x010C, 0x0065, 0x0073, 0x006B, 0x00FD, _T('.'), _T('m'), _T('p'), _T('q'), 0};
-/* Russian */ static const wchar_t szUnicodeName2[] = {0x0420, 0x0443, 0x0441, 0x0441, 0x043A, 0x0438, 0x0439, _T('.'), _T('m'), _T('p'), _T('q'), 0};
-/* Greece */ static const wchar_t szUnicodeName3[] = {0x03B5, 0x03BB, 0x03BB, 0x03B7, 0x03BD, 0x03B9, 0x03BA, 0x03AC, _T('.'), _T('m'), _T('p'), _T('q'), 0};
-/* Chinese */ static const wchar_t szUnicodeName4[] = {0x65E5, 0x672C, 0x8A9E, _T('.'), _T('m'), _T('p'), _T('q'), 0};
-/* Japanese */ static const wchar_t szUnicodeName5[] = {0x7B80, 0x4F53, 0x4E2D, 0x6587, _T('.'), _T('m'), _T('p'), _T('q'), 0};
-/* Arabic */ static const wchar_t szUnicodeName6[] = {0x0627, 0x0644, 0x0639, 0x0639, 0x0631, 0x0628, 0x064A, 0x0629, _T('.'), _T('m'), _T('p'), _T('q'), 0};
-
-//-----------------------------------------------------------------------------
-// Constants
-
-static const TCHAR * szWorkDir = MAKE_PATH("Work");
-
-static unsigned int AddFlags[] =
-{
-// Compression Encryption Fixed key Single Unit Sector CRC
- 0 | 0 | 0 | 0 | 0,
- 0 | MPQ_FILE_ENCRYPTED | 0 | 0 | 0,
- 0 | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY | 0 | 0,
- 0 | 0 | 0 | MPQ_FILE_SINGLE_UNIT | 0,
- 0 | MPQ_FILE_ENCRYPTED | 0 | MPQ_FILE_SINGLE_UNIT | 0,
- 0 | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY | MPQ_FILE_SINGLE_UNIT | 0,
- MPQ_FILE_IMPLODE | 0 | 0 | 0 | 0,
- MPQ_FILE_IMPLODE | MPQ_FILE_ENCRYPTED | 0 | 0 | 0,
- MPQ_FILE_IMPLODE | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY | 0 | 0,
- MPQ_FILE_IMPLODE | 0 | 0 | MPQ_FILE_SINGLE_UNIT | 0,
- MPQ_FILE_IMPLODE | MPQ_FILE_ENCRYPTED | 0 | MPQ_FILE_SINGLE_UNIT | 0,
- MPQ_FILE_IMPLODE | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY | MPQ_FILE_SINGLE_UNIT | 0,
- MPQ_FILE_IMPLODE | 0 | 0 | 0 | MPQ_FILE_SECTOR_CRC,
- MPQ_FILE_IMPLODE | MPQ_FILE_ENCRYPTED | 0 | 0 | MPQ_FILE_SECTOR_CRC,
- MPQ_FILE_IMPLODE | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY | 0 | MPQ_FILE_SECTOR_CRC,
- MPQ_FILE_COMPRESS | 0 | 0 | 0 | 0,
- MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED | 0 | 0 | 0,
- MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY | 0 | 0,
- MPQ_FILE_COMPRESS | 0 | 0 | MPQ_FILE_SINGLE_UNIT | 0,
- MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED | 0 | MPQ_FILE_SINGLE_UNIT | 0,
- MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY | MPQ_FILE_SINGLE_UNIT | 0,
- MPQ_FILE_COMPRESS | 0 | 0 | 0 | MPQ_FILE_SECTOR_CRC,
- MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED | 0 | 0 | MPQ_FILE_SECTOR_CRC,
- MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY | 0 | MPQ_FILE_SECTOR_CRC,
- 0xFFFFFFFF
-};
-
-//-----------------------------------------------------------------------------
-// Local testing functions
-
-static void clreol()
-{
-#ifdef PLATFORM_WINDOWS
- CONSOLE_SCREEN_BUFFER_INFO ScreenInfo;
- HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
- LPTSTR szConsoleLine;
- int nConsoleChars;
- int i = 0;
-
- GetConsoleScreenBufferInfo(hConsole, &ScreenInfo);
- nConsoleChars = (ScreenInfo.srWindow.Right - ScreenInfo.srWindow.Left);
- if(nConsoleChars > 0)
- {
- szConsoleLine = new TCHAR[nConsoleChars + 3];
- if(szConsoleLine != NULL)
- {
- szConsoleLine[i++] = '\r';
- for(; i < nConsoleChars; i++)
- szConsoleLine[i] = ' ';
- szConsoleLine[i++] = '\r';
- szConsoleLine[i] = 0;
-
- _tprintf(szConsoleLine);
- delete [] szConsoleLine;
- }
- }
-#endif // PLATFORM_WINDOWS
-}
-
-static void PrintfTA(const TCHAR * szFormat, const TCHAR * szStrT, const char * szStrA, int lcLocale = 0)
-{
- TCHAR * szTemp;
- TCHAR szBuffer[MAX_PATH];
-
- // Convert ANSI string to TCHAR
- for(szTemp = szBuffer; *szStrA != 0; szTemp++, szStrA++)
- szTemp[0] = szStrA[0];
- szTemp[0] = 0;
-
- _tprintf(szFormat, szStrT, szBuffer, lcLocale);
-}
-
-static void MergeLocalPath(TCHAR * szBuffer, const TCHAR * szPart1, const char * szPart2)
-{
- // Copy directory name
- while(*szPart1 != 0)
- *szBuffer++ = *szPart1++;
-
- // Add separator
- *szBuffer++ = _T('/');
-
- // Copy file name
- while(*szPart2 != 0)
- *szBuffer++ = *szPart2++;
-
- // Terminate the string
- *szBuffer = 0;
-}
-
-int GetFirstDiffer(void * ptr1, void * ptr2, int nSize)
-{
- char * buff1 = (char *)ptr1;
- char * buff2 = (char *)ptr2;
- int nDiffer;
-
- for(nDiffer = 0; nDiffer < nSize; nDiffer++)
- {
- if(*buff1++ != *buff2++)
- return nDiffer;
- }
- return -1;
-}
-
-static void WINAPI CompactCB(void * /* lpParam */, DWORD dwWork, ULONGLONG BytesDone, ULONGLONG TotalBytes)
-{
- clreol();
-
- _tprintf(_T("%u of %u "), (DWORD)BytesDone, (DWORD)TotalBytes);
- switch(dwWork)
- {
- case CCB_CHECKING_FILES:
- _tprintf(_T("Checking files in archive ...\r"));
- break;
-
- case CCB_CHECKING_HASH_TABLE:
- _tprintf(_T("Checking hash table ...\r"));
- break;
-
- case CCB_COPYING_NON_MPQ_DATA:
- _tprintf(_T("Copying non-MPQ data ...\r"));
- break;
-
- case CCB_COMPACTING_FILES:
- _tprintf(_T("Compacting archive ...\r"));
- break;
-
- case CCB_CLOSING_ARCHIVE:
- _tprintf(_T("Closing archive ...\r"));
- break;
- }
-}
-
-static void GenerateRandomDataBlock(LPBYTE pbBuffer, DWORD cbBuffer)
-{
- LPBYTE pbBufferEnd = pbBuffer + cbBuffer;
- LPBYTE pbPtr = pbBuffer;
- DWORD cbBytesToPut = 0;
- BYTE ByteToPut = 0;
- bool bRandomData = false;
-
- while(pbPtr < pbBufferEnd)
- {
- // If there are no bytes to put, we will generate new byte and length
- if(cbBytesToPut == 0)
- {
- bRandomData = false;
- switch(rand() % 10)
- {
- case 0: // A short sequence of zeros
- cbBytesToPut = rand() % 0x08;
- ByteToPut = 0;
- break;
-
- case 1: // A long sequence of zeros
- cbBytesToPut = rand() % 0x80;
- ByteToPut = 0;
- break;
-
- case 2: // A short sequence of non-zeros
- cbBytesToPut = rand() % 0x08;
- ByteToPut = (BYTE)(rand() % 0x100);
- break;
-
- case 3: // A long sequence of non-zeros
- cbBytesToPut = rand() % 0x80;
- ByteToPut = (BYTE)(rand() % 0x100);
- break;
-
- case 4: // A short random data
- cbBytesToPut = rand() % 0x08;
- bRandomData = true;
- break;
-
- case 5: // A long random data
- cbBytesToPut = rand() % 0x80;
- bRandomData = true;
- break;
-
- default: // A single random byte
- cbBytesToPut = 1;
- ByteToPut = (BYTE)(rand() % 0x100);
- break;
- }
- }
-
- // Generate random byte, if needed
- if(bRandomData)
- ByteToPut = (BYTE)(rand() % 0x100);
-
- // Put next byte to the output buffer
- *pbPtr++ = ByteToPut;
- cbBytesToPut--;
- }
-}
-
-static bool CompareArchivedFiles(const char * szFileName, HANDLE hFile1, HANDLE hFile2, DWORD dwBlockSize)
-{
- LPBYTE pbBuffer1 = NULL;
- LPBYTE pbBuffer2 = NULL;
- DWORD dwRead1; // Number of bytes read (Storm.dll)
- DWORD dwRead2; // Number of bytes read (StormLib)
- bool bResult1 = false; // Result from Storm.dll
- bool bResult2 = false; // Result from StormLib
- bool bResult = true;
- int nDiff;
-
- szFileName = szFileName;
-
- // Allocate buffers
- pbBuffer1 = new BYTE[dwBlockSize];
- pbBuffer2 = new BYTE[dwBlockSize];
-
- for(;;)
- {
- // Read the file's content by both methods and compare the result
- memset(pbBuffer1, 0, dwBlockSize);
- memset(pbBuffer2, 0, dwBlockSize);
- bResult1 = SFileReadFile(hFile1, pbBuffer1, dwBlockSize, &dwRead1, NULL);
- bResult2 = SFileReadFile(hFile2, pbBuffer2, dwBlockSize, &dwRead2, NULL);
- if(bResult1 != bResult2)
- {
- _tprintf(_T("Different results from SFileReadFile, Mpq1 %u, Mpq2 %u\n"), bResult1, bResult2);
- bResult = false;
- break;
- }
-
- // Test the number of bytes read
- if(dwRead1 != dwRead2)
- {
- _tprintf(_T("Different bytes read from SFileReadFile, Mpq1 %u, Mpq2 %u\n"), dwRead1, dwRead2);
- bResult = false;
- break;
- }
-
- // No more bytes ==> OK
- if(dwRead1 == 0)
- break;
-
- // Test the content
- if((nDiff = GetFirstDiffer(pbBuffer1, pbBuffer2, dwRead1)) != -1)
- {
- bResult = false;
- break;
- }
- }
-
- delete [] pbBuffer2;
- delete [] pbBuffer1;
- return bResult;
-}
-
-// Random read version
-static bool CompareArchivedFilesRR(const char * /* szFileName */, HANDLE hFile1, HANDLE hFile2, DWORD dwBlockSize)
-{
- const char * szPositions[3] = {"FILE_BEGIN ", "FILE_CURRENT", "FILE_END "};
- LPBYTE pbBuffer1 = NULL;
- LPBYTE pbBuffer2 = NULL;
- DWORD dwFileSize1; // File size (Storm.dll)
- DWORD dwFileSize2; // File size (StormLib)
- DWORD dwRead1; // Number of bytes read (Storm.dll)
- DWORD dwRead2; // Number of bytes read (StormLib)
- bool bResult1 = false; // Result from Storm.dll
- bool bResult2 = false; // Result from StormLib
- int nError = ERROR_SUCCESS;
-
- // Test the file size
- dwFileSize1 = SFileGetFileSize(hFile1, NULL);
- dwFileSize2 = SFileGetFileSize(hFile2, NULL);
- if(dwFileSize1 != dwFileSize2)
- {
- _tprintf(_T("Different size from SFileGetFileSize (file1: %u, file2: %u)\n"), dwFileSize1, dwFileSize2);
- return false;
- }
-
- if(dwFileSize1 != 0)
- {
- for(int i = 0; i < 10000; i++)
- {
- DWORD dwRandom = rand() * rand();
- DWORD dwMoveMethod = dwRandom % 3;
- DWORD dwPosition = dwRandom % dwFileSize1;
- DWORD dwToRead = dwRandom % dwBlockSize;
-
- // Also test negative seek
- if(rand() & 1)
- {
- int nPosition = (int)dwPosition;
- dwPosition = (DWORD)(-nPosition);
- }
-
- // Allocate buffers
- pbBuffer1 = new BYTE[dwToRead];
- pbBuffer2 = new BYTE[dwToRead];
-
- // Set the file pointer
- _tprintf(_T("RndRead (%u): pos %8i from %s, size %u ...\r"), i, dwPosition, szPositions[dwMoveMethod], dwToRead);
- dwRead1 = SFileSetFilePointer(hFile1, dwPosition, NULL, dwMoveMethod);
- dwRead2 = SFileSetFilePointer(hFile2, dwPosition, NULL, dwMoveMethod);
- if(dwRead1 != dwRead2)
- {
- _tprintf(_T("Difference returned by SFileSetFilePointer (file1: %u, file2: %u)\n"), dwRead1, dwRead2);
- nError = ERROR_CAN_NOT_COMPLETE;
- break;
- }
-
- // Read the file's content by both methods and compare the result
- bResult1 = SFileReadFile(hFile1, pbBuffer1, dwToRead, &dwRead1, NULL);
- bResult2 = SFileReadFile(hFile2, pbBuffer2, dwToRead, &dwRead2, NULL);
- if(bResult1 != bResult2)
- {
- _tprintf(_T("Different results from SFileReadFile (file1: %u, file2: %u)\n\n"), bResult1, bResult2);
- nError = ERROR_CAN_NOT_COMPLETE;
- break;
- }
-
- // Test the number of bytes read
- if(dwRead1 != dwRead2)
- {
- _tprintf(_T("Different bytes read from SFileReadFile (file1: %u, file2: %u)\n\n"), dwRead1, dwRead2);
- nError = ERROR_CAN_NOT_COMPLETE;
- break;
- }
-
- // Test the content
- if(dwRead1 != 0 && memcmp(pbBuffer1, pbBuffer2, dwRead1))
- {
- _tprintf(_T("Different data content from SFileReadFile\n"));
- nError = ERROR_CAN_NOT_COMPLETE;
- break;
- }
-
- delete [] pbBuffer2;
- delete [] pbBuffer1;
- }
- }
- clreol();
- return (nError == ERROR_SUCCESS) ? true : false;
-}
-
-//-----------------------------------------------------------------------------
-// Opening local file
-
-static int TestOpenLocalFile(const char * szFileName)
-{
- HANDLE hFile;
- char szRetrievedName[MAX_PATH];
-
- if(SFileOpenFileEx(NULL, szFileName, SFILE_OPEN_LOCAL_FILE, &hFile))
- {
- SFileGetFileName(hFile, szRetrievedName);
- SFileCloseFile(hFile);
- }
-
- return ERROR_SUCCESS;
-}
-
-//-----------------------------------------------------------------------------
-// Partial file reading
-
-static int TestPartFileRead(const TCHAR * szFileName)
-{
- ULONGLONG ByteOffset;
- ULONGLONG FileSize = 0;
- TFileStream * pStream;
- BYTE BigBuffer[0x7000];
- BYTE Buffer[0x100];
- int nError = ERROR_SUCCESS;
-
- // Open the partial file
- pStream = FileStream_OpenFile(szFileName, false);
- if(pStream == NULL)
- nError = GetLastError();
-
- // Get the size of the stream
- if(nError == ERROR_SUCCESS)
- {
- if(!FileStream_GetSize(pStream, FileSize))
- nError = GetLastError();
- }
-
- // Read the last 0x7000 bytes
- if(nError == ERROR_SUCCESS)
- {
- ByteOffset = FileSize - sizeof(BigBuffer);
- if(!FileStream_Read(pStream, &ByteOffset, BigBuffer, sizeof(BigBuffer)))
- nError = GetLastError();
- }
-
- // Read the last 0x100 bytes
- if(nError == ERROR_SUCCESS)
- {
- ByteOffset = FileSize - sizeof(Buffer);
- if(!FileStream_Read(pStream, &ByteOffset, Buffer, sizeof(Buffer)))
- nError = GetLastError();
- }
-
- // Read 0x100 bytes from position (FileSize - 0xFF)
- if(nError == ERROR_SUCCESS)
- {
- ByteOffset = FileSize - sizeof(Buffer) + 1;
- if(!FileStream_Read(pStream, &ByteOffset, Buffer, sizeof(Buffer)))
- nError = GetLastError();
- }
-
- FileStream_Close(pStream);
- return nError;
-}
-
-//-----------------------------------------------------------------------------
-// Compare PKLIB decompression
-
-BYTE pbCompressed1[] = {0x00, 0x04, 0x00, 0x00, 0x04, 0xF0, 0x1F, 0x7B, 0x01, 0xFF};
-BYTE pbCompressed2[] = {0x00, 0x04, 0x00, 0x00, 0x04, 0xF0, 0x1F, 0x00, 0x00, 0x04, 0xFC, 0x03};
-
-static int ComparePklibCompressions()
-{
- char Decompressed[0x1000];
- char Compressed[0x1000];
- int cbDecompressed = 0x208;
- int cbCompressed = sizeof(Compressed);
-
- memset(Decompressed, 0, cbDecompressed);
- SCompImplode(Compressed, &cbCompressed, Decompressed, cbDecompressed);
-
- cbDecompressed = sizeof(Decompressed);
- SCompExplode(Decompressed, &cbDecompressed, Compressed, cbCompressed);
-
-
- return ERROR_SUCCESS;
-}
-
-//-----------------------------------------------------------------------------
-// Compare LZMA decompression
-
-#ifdef PLATFORM_WINDOWS
-typedef void * (*ALLOC_MEMORY)(size_t);
-typedef void (*FREE_MEMORY)(void *);
-typedef int (GIVE_DATA)(void *);
-
-extern "C" int starcraft_decompress_lzma(char * pbInBuffer, int cbInBuffer, char * pbOutBuffer, int cbOutBuffer, int * pcbOutBuffer, ALLOC_MEMORY pfnAllocMemory, FREE_MEMORY pfnFreeMemory);
-extern "C" int starcraft_compress_lzma(char * pbInBuffer, int cbInBuffer, int dummy1, char * pbOutBuffer, int cbOutBuffer, int dummy2, int * pcbOutBuffer, ALLOC_MEMORY pfnAllocMemory, FREE_MEMORY pfnFreeMemory, GIVE_DATA pfnGiveData);
-void Compress_LZMA(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer, int *, int);
-int Decompress_LZMA(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer);
-
-extern "C" void * operator_new(size_t sz)
-{
- return malloc(sz);
-}
-
-void * Memory_Allocate(size_t byte_size)
-{
- return malloc(byte_size);
-}
-
-void Memory_Free(void * address)
-{
- if(address != NULL)
- free(address);
-}
-
-int GiveData(void *)
-{
- return 0;
-}
-
-static int StarcraftCompress_LZMA(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer)
-{
- return starcraft_compress_lzma(pbInBuffer,
- cbInBuffer,
- 0,
- pbOutBuffer,
- *pcbOutBuffer,
- 0,
- pcbOutBuffer,
- Memory_Allocate,
- Memory_Free,
- GiveData);
-}
-
-static int StarcraftDecompress_LZMA(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer)
-{
- return starcraft_decompress_lzma(pbInBuffer,
- cbInBuffer,
- pbOutBuffer,
- *pcbOutBuffer,
- pcbOutBuffer,
- Memory_Allocate,
- Memory_Free);
-}
-
-static int CompareLzmaCompressions(int nSectorSize)
-{
- LPBYTE pbCompressed1 = NULL; // Compressed by our code
- LPBYTE pbCompressed2 = NULL; // Compressed by Blizzard's code
- LPBYTE pbDecompressed1 = NULL; // Decompressed by our code
- LPBYTE pbDecompressed2 = NULL; // Decompressed by Blizzard's code
- LPBYTE pbOriginalData = NULL;
- int nError = ERROR_SUCCESS;
-
- // Allocate buffers
- // Must allocate twice blocks due to probable bug in Storm.dll.
- // Storm.dll corrupts stack when uncompresses data with PKWARE DCL
- // and no compression occurs.
- pbDecompressed1 = new BYTE [nSectorSize];
- pbDecompressed2 = new BYTE [nSectorSize];
- pbCompressed1 = new BYTE [nSectorSize];
- pbCompressed2 = new BYTE [nSectorSize];
- pbOriginalData = new BYTE[nSectorSize];
- if(!pbDecompressed1 || !pbDecompressed2 || !pbCompressed1 || !pbCompressed2 || !pbOriginalData)
- nError = ERROR_NOT_ENOUGH_MEMORY;
-
- if(nError == ERROR_SUCCESS)
- {
- for(int i = 0; i < 100000; i++)
- {
- int nDcmpLength1;
- int nDcmpLength2;
- int nCmpLength1;
- int nCmpLength2;
- int nDiff;
-
- clreol();
- _tprintf(_T("Testing compression of sector %u\r"), i + 1);
-
- // Generate random data sector
- GenerateRandomDataBlock(pbOriginalData, nSectorSize);
-
- // Compress the sector by both methods
- nCmpLength1 = nCmpLength2 = nSectorSize;
-// Compress_LZMA((char *)pbCompressed1, &nCmpLength1, (char *)pbOriginalData, nSectorSize, 0, 0);
- StarcraftCompress_LZMA((char *)pbCompressed1, &nCmpLength2, (char *)pbOriginalData, nSectorSize);
-
-__TryToDecompress:
-
- // Only test decompression when the compression actually succeeded
- if(nCmpLength1 < nSectorSize)
- {
- // Decompress both data
- nDcmpLength2 = nDcmpLength1 = nSectorSize;
-// Decompress_LZMA((char *)pbDecompressed1, &nDcmpLength1, (char *)pbCompressed1, nCmpLength1);
- StarcraftDecompress_LZMA((char *)pbDecompressed2, &nDcmpLength2, (char *)pbCompressed1, nCmpLength1);
-
- // Compare the length of the output data
- if(nDcmpLength1 != nDcmpLength2)
- {
- _tprintf(_T("Difference in compressed blocks lengths (%u vs %u)\n"), nDcmpLength1, nDcmpLength2);
- goto __TryToDecompress;
- }
-
- // Compare the output
- if((nDiff = GetFirstDiffer(pbDecompressed1, pbDecompressed2, nDcmpLength1)) != -1)
- {
- _tprintf(_T("Difference in decompressed blocks (offset 0x%08X)\n"), nDiff);
- goto __TryToDecompress;
- }
-
- // Check for data overflow
- if(pbDecompressed1[nSectorSize] != 0xFD || pbDecompressed1[nSectorSize] != 0xFD)
- {
- _tprintf(_T("Damage after decompressed sector !!!\n"));
- goto __TryToDecompress;
- }
-
- // Compare the decompressed data against original data
- if((nDiff = GetFirstDiffer(pbDecompressed1, pbOriginalData, nDcmpLength1)) != -1)
- {
- _tprintf(_T("Difference between original data and decompressed data (offset 0x%08X)\n"), nDiff);
- goto __TryToDecompress;
- }
- }
- }
- }
-
- // Cleanup
- if(pbOriginalData != NULL)
- delete [] pbOriginalData;
- if(pbCompressed2 != NULL)
- delete [] pbCompressed2;
- if(pbCompressed1 != NULL)
- delete [] pbCompressed1;
- if(pbDecompressed2 != NULL)
- delete [] pbDecompressed2;
- if(pbDecompressed1 != NULL)
- delete [] pbDecompressed1;
- clreol();
- return nError;
-}
-#endif // PLATFORM_WINDOWS
-
-//-----------------------------------------------------------------------------
-// Compression method test
-
-static int TestSectorCompress(int nSectorSize)
-{
- LPBYTE pbDecompressed = NULL;
- LPBYTE pbCompressed = NULL;
- LPBYTE pbOriginal = NULL;
- int nError = ERROR_SUCCESS;
-
- // Allocate buffers
- pbDecompressed = new BYTE[nSectorSize];
- pbCompressed = new BYTE[nSectorSize];
- pbOriginal = new BYTE[nSectorSize];
- if(!pbDecompressed || !pbCompressed || !pbOriginal)
- nError = ERROR_NOT_ENOUGH_MEMORY;
-
- if(nError == ERROR_SUCCESS)
- {
- for(int i = 0; i < 100000; i++)
- {
- int nOriginalLength = nSectorSize % (rand() + 1);
- int nCompressedLength;
- int nDecompressedLength;
- int nCmp = MPQ_COMPRESSION_SPARSE | MPQ_COMPRESSION_ZLIB | MPQ_COMPRESSION_BZIP2 | MPQ_COMPRESSION_PKWARE;
- int nDiff;
-
- clreol();
- _tprintf(_T("Testing compression of sector %u\r"), i + 1);
-
- // Generate random data sector
- GenerateRandomDataBlock(pbOriginal, nOriginalLength);
- if(nOriginalLength == 0x123)
- nOriginalLength = 0;
-
-__TryAgain:
-
- // Compress the sector
- nCompressedLength = nOriginalLength;
- SCompCompress((char *)pbCompressed, &nCompressedLength, (char *)pbOriginal, nOriginalLength, nCmp, 0, -1);
-// SCompImplode((char *)pbCompressed, &nCompressedLength, (char *)pbOriginal, nOriginalLength);
-
- // When the method was unable to compress data,
- // the compressed data must be identical to original data
- if(nCompressedLength == nOriginalLength)
- {
- if((nDiff = GetFirstDiffer(pbCompressed, pbOriginal, nOriginalLength)) != -1)
- {
- _tprintf(_T("Compression error: Fail when unable to compress the data (Offset 0x%08X).\n"), nDiff);
- goto __TryAgain;
- }
- }
-
- // Uncompress the sector
- nDecompressedLength = nOriginalLength;
- SCompDecompress((char *)pbDecompressed, &nDecompressedLength, (char *)pbCompressed, nCompressedLength);
-// SCompExplode((char *)pbDecompressed, &nDecompressedLength, (char *)pbCompressed, nCompressedLength);
-
- // Check the decompressed length against original length
- if(nDecompressedLength != nOriginalLength)
- {
- _tprintf(_T("Length of uncompressed data does not agree with original data length !!!\n"));
- goto __TryAgain;
- }
-
- // Check decompressed block against original block
- if((nDiff = GetFirstDiffer(pbDecompressed, pbOriginal, nOriginalLength)) != -1)
- {
- _tprintf(_T("Decompressed sector does not agree with the original data !!! (Offset 0x%08X)\n"), nDiff);
- goto __TryAgain;
- }
- }
- }
-
- // Cleanup
- delete [] pbOriginal;
- delete [] pbCompressed;
- delete [] pbDecompressed;
- clreol();
- return nError;
-}
-
-static int TestArchiveOpenAndClose(const TCHAR * szMpqName)
-{
- const char * szFileName1 = "DBFilesClient\\Item.dbc";
-// const char * szFileName2 = "items\\map\\mapz_deleted.cel";
- TMPQArchive * ha = NULL;
- HANDLE hFile1 = NULL;
-// HANDLE hFile2 = NULL;
- HANDLE hMpq = NULL;
- int nError = ERROR_SUCCESS;
-
- if(nError == ERROR_SUCCESS)
- {
- _tprintf(_T("Opening archive %s ...\n"), szMpqName);
- if(!SFileOpenArchive(szMpqName, 0, STREAM_PROVIDER_ENCRYPTED | BASE_PROVIDER_FILE, &hMpq))
- nError = GetLastError();
- ha = (TMPQArchive *)hMpq;
- }
-/*
- // Test for TBitArray
- if(nError == ERROR_SUCCESS && ha->pHetTable != NULL)
- {
- TBitArray * pBitArray = ha->pHetTable->pBetIndexes;
-
- for(ULONG i = 0; i < 0x10000; i++)
- {
- BYTE LoadedBits[0x20];
- BYTE SaveBits[0x40];
- unsigned int nBitPosition = (i >> 0x08);
- unsigned int nBitCount = (i & 0xFF);
-
- memset(LoadedBits, 0, sizeof(LoadedBits));
- memcpy(SaveBits, pBitArray->Elements, sizeof(SaveBits));
-
- // Load the index to the BET table
- pBitArray->GetBits(nBitPosition, nBitCount, LoadedBits, sizeof(LoadedBits));
-
- // Load the index to the BET table
- pBitArray->SetBits(nBitPosition, nBitCount, LoadedBits, sizeof(LoadedBits));
-
- // Verify the bits
- if(memcmp(SaveBits, pBitArray->Elements, sizeof(SaveBits)))
- assert(false);
- }
- }
-*/
- // Verify the raw data in the archive
- if(nError == ERROR_SUCCESS)
- {
- // Verify the archive
- SFileVerifyRawData(hMpq, SFILE_VERIFY_FILE, szFileName1);
-
- // Try to open a file
- if(!SFileOpenFileEx(hMpq, szFileName1, SFILE_OPEN_FROM_MPQ, &hFile1))
- {
- nError = GetLastError();
- printf("%s - file not found in the MPQ\n", szFileName1);
- }
- }
-
- // Dummy read from the file
- if(nError == ERROR_SUCCESS)
- {
- DWORD dwBytesRead = 0;
- BYTE Buffer[0x1000];
-
- SFileSetFileLocale(hFile1, 0x405);
- SFileReadFile(hFile1, Buffer, sizeof(Buffer), &dwBytesRead);
- }
-/*
- // Verify the MPQ listfile
- if(nError == ERROR_SUCCESS)
- {
- SFileVerifyFile(hMpq, szFileName1, 0xFFFFFFFF);
- if(!CompareArchivedFilesRR(szFileName1, hFile1, hFile2, 0x100000))
- nError = ERROR_CAN_NOT_COMPLETE;
- }
-*/
- if(hFile1 != NULL)
- SFileCloseFile(hFile1);
- if(hMpq != NULL)
- SFileCloseArchive(hMpq);
- return nError;
-}
-
-static int TestFindFiles(const TCHAR * szMpqName)
-{
- TMPQFile * hf;
- HANDLE hFile;
- HANDLE hMpq = NULL;
- BYTE Buffer[100];
- int nError = ERROR_SUCCESS;
- int nFiles = 0;
- int nFound = 0;
-
- // Open the archive
- if(nError == ERROR_SUCCESS)
- {
- _tprintf(_T("Opening \"%s\" for finding files ...\n"), szMpqName);
- if(!SFileOpenArchive(szMpqName, 0, 0, &hMpq))
- nError = GetLastError();
- }
-
- // Compact the archive
- if(nError == ERROR_SUCCESS)
- {
- SFILE_FIND_DATA sf;
- HANDLE hFind;
- DWORD dwExtraDataSize;
- bool bFound = true;
-
- hFind = SFileFindFirstFile(hMpq, "*", &sf, "c:\\Tools32\\ListFiles\\ListFile.txt");
- while(hFind != NULL && bFound != false)
- {
- if(SFileOpenFileEx(hMpq, sf.cFileName, 0, &hFile))
- {
- hf = (TMPQFile *)hFile;
- SFileReadFile(hFile, Buffer, sizeof(Buffer));
- nFiles++;
-
- if(sf.dwFileFlags & MPQ_FILE_SECTOR_CRC)
- {
- dwExtraDataSize = hf->SectorOffsets[hf->dwSectorCount + 1] - hf->SectorOffsets[hf->dwSectorCount];
- if(dwExtraDataSize != 0)
- nFound++;
- }
-
- SFileCloseFile(hFile);
- }
-
- bFound = SFileFindNextFile(hFind, &sf);
- }
- }
-
- if(hMpq != NULL)
- SFileCloseArchive(hMpq);
- if(nError == ERROR_SUCCESS)
- _tprintf(_T("Search complete\n"));
- return nError;
-}
-
-static int TestMpqCompacting(const TCHAR * szMpqName)
-{
- HANDLE hMpq = NULL;
- int nError = ERROR_SUCCESS;
-
- // Open the archive
- if(nError == ERROR_SUCCESS)
- {
- _tprintf(_T("Opening \"%s\" for compacting ...\n"), szMpqName);
- if(!SFileOpenArchive(szMpqName, 0, 0, &hMpq))
- nError = GetLastError();
- }
-
- if(nError == ERROR_SUCCESS)
- {
- const char * szFileName = "Shaders\\Effects\\shadowmap.wfx";
-
- printf("Deleting file %s ...\r", szFileName);
- if(!SFileRemoveFile(hMpq, szFileName))
- nError = GetLastError();
- }
-/*
- // Compact the archive
- if(nError == ERROR_SUCCESS)
- {
- _tprintf(_T("Compacting archive ...\r"));
- SFileSetCompactCallback(hMpq, CompactCB, NULL);
- if(!SFileCompactArchive(hMpq, "c:\\Tools32\\ListFiles\\ListFile.txt"))
- nError = GetLastError();
- }
-*/
- if(hMpq != NULL)
- SFileCloseArchive(hMpq);
- if(nError == ERROR_SUCCESS)
- _tprintf(_T("Compacting complete (No errors)\n"));
- return nError;
-}
-
-static int TestCreateArchive(const TCHAR * szMpqName)
-{
- TFileStream * pStream;
- const TCHAR * szFileName1 = MAKE_PATH("FileTest.exe");
- const TCHAR * szFileName2 = MAKE_PATH("ZeroSize.txt");
- HANDLE hMpq = NULL; // Handle of created archive
- DWORD dwVerifyResult;
- DWORD dwFileCount = 0;
- LCID LocaleIDs[] = {0x000, 0x405, 0x406, 0x407, 0xFFFF};
- char szMpqFileName[MAX_PATH];
- int nError = ERROR_SUCCESS;
- int i;
-
- // Create the new file
- _tprintf(_T("Creating %s ...\n"), szMpqName);
- pStream = FileStream_CreateFile(szMpqName, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
- if(pStream == NULL)
- nError = GetLastError();
-
- // Write some data
- if(nError == ERROR_SUCCESS)
- {
- ULONGLONG FileSize = 0x100000;
-
- FileStream_SetSize(pStream, FileSize);
- FileStream_Close(pStream);
- }
-
- // Well, now create the MPQ archive
- if(nError == ERROR_SUCCESS)
- {
- if(!SFileCreateArchive(szMpqName,
- MPQ_CREATE_ARCHIVE_V4 | MPQ_CREATE_ATTRIBUTES,
- 17,
- &hMpq))
- {
- nError = GetLastError();
- }
- }
-
- // Add the same file multiple times
- if(nError == ERROR_SUCCESS)
- {
- // Add FileTest.exe
- for(i = 0; AddFlags[i] != 0xFFFFFFFF; i++)
- {
- sprintf(szMpqFileName, "FileTest_%02u.exe", i);
- PrintfTA(_T("Adding %s as %s ...\n"), szFileName1, szMpqFileName);
- if(SFileAddFileEx(hMpq, szFileName1, szMpqFileName, AddFlags[i], MPQ_COMPRESSION_ZLIB))
- {
- dwVerifyResult = SFileVerifyFile(hMpq, szMpqFileName, MPQ_ATTRIBUTE_CRC32 | MPQ_ATTRIBUTE_MD5);
- if(dwVerifyResult & (VERIFY_OPEN_ERROR | VERIFY_READ_ERROR | VERIFY_FILE_SECTOR_CRC_ERROR | VERIFY_FILE_CHECKSUM_ERROR | VERIFY_FILE_MD5_ERROR))
- printf("CRC error on \"%s\"\n", szMpqFileName);
- dwFileCount++;
- }
- else
- {
- printf("Failed to add the file \"%s\".\n", szMpqFileName);
- }
- }
-
-
- // Delete a file in the middle of the file table
- SFileRemoveFile(hMpq, "FileTest_10.exe");
- SFileAddFileEx(hMpq, szFileName1, "FileTest_xx.exe", MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED, MPQ_COMPRESSION_ZLIB);
-
- // Try to decrement max file count
- dwFileCount = SFileGetMaxFileCount(hMpq);
- SFileSetMaxFileCount(hMpq, dwFileCount - 1);
-
- // Add ZeroSize.txt (1)
- sprintf(szMpqFileName, "ZeroSize_1.txt");
- for(i = 0; LocaleIDs[i] != 0xFFFF; i++)
- {
- PrintfTA(_T("Adding %s as %s (locale %04x) ...\n"), szFileName2, szMpqFileName, LocaleIDs[i]);
- SFileSetLocale(LocaleIDs[i]);
- if(!SFileAddFileEx(hMpq, szFileName2, szMpqFileName, MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED, MPQ_COMPRESSION_ZLIB))
- printf("Cannot add the file\n");
- }
-
- // Add ZeroSize.txt (1)
- sprintf(szMpqFileName, "ZeroSize_2.txt");
- for(int i = 0; LocaleIDs[i] != 0xFFFF; i++)
- {
- PrintfTA(_T("Adding %s as %s (locale %04x) ...\n"), szFileName2, szMpqFileName, LocaleIDs[i]);
- SFileSetLocale(LocaleIDs[i]);
- if(!SFileAddFileEx(hMpq, szFileName2, szMpqFileName, MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED, MPQ_COMPRESSION_ZLIB))
- printf("Cannot add the file\n");
- }
- }
-
- // Test rename function
- if(nError == ERROR_SUCCESS)
- {
- _tprintf(_T("Testing rename files ...\n"));
- SFileSetLocale(LANG_NEUTRAL);
- if(!SFileRenameFile(hMpq, "FileTest_08.exe", "FileTest_08a.exe"))
- {
- nError = GetLastError();
- _tprintf(_T("Failed to rename the file\n"));
- }
-
- if(!SFileRenameFile(hMpq, "FileTest_08a.exe", "FileTest_08.exe"))
- {
- nError = GetLastError();
- _tprintf(_T("Failed to rename the file\n"));
- }
-
- if(!SFileRenameFile(hMpq, "FileTest_10.exe", "FileTest_10a.exe"))
- {
- nError = GetLastError();
- _tprintf(_T("Failed to rename the file\n"));
- }
-
- if(!SFileRenameFile(hMpq, "FileTest_10a.exe", "FileTest_10.exe"))
- {
- nError = GetLastError();
- _tprintf(_T("Failed to rename the file\n"));
- }
-
- if(nError == ERROR_SUCCESS)
- _tprintf(_T("Rename test succeeded.\n\n"));
- else
- _tprintf(_T("Rename test failed.\n\n"));
- }
-
- // Compact the archive
-// if(nError == ERROR_SUCCESS)
-// SFileCompactArchive(hMpq);
-
- // Test changing hash table size
- if(nError == ERROR_SUCCESS)
- SFileSetMaxFileCount(hMpq, 0x95);
-
- if(hMpq != NULL)
- SFileCloseArchive(hMpq);
-
- // Try to reopen the archive
- if(SFileOpenArchive(szMpqName, 0, 0, &hMpq))
- SFileCloseArchive(hMpq);
-
- _tprintf(_T("\n"));
- return nError;
-}
-
-static int TestCreateArchive_PaliRoharBug(const TCHAR * szMpqName)
-{
- const TCHAR * szFileName = MAKE_PATH("FileTest.exe");
- HANDLE hMpq = NULL; // Handle of created archive
- DWORD dwMaxFileCount = 0;
- DWORD dwMpqFlags = MPQ_FILE_ENCRYPTED | MPQ_FILE_COMPRESS;
- char szMpqFileName[MAX_PATH];
- int nError = ERROR_SUCCESS;
- int i;
-
- _tremove(szMpqName);
- if(SFileCreateArchive(szMpqName,
- MPQ_CREATE_ARCHIVE_V4 | MPQ_CREATE_ATTRIBUTES,
- 1,
- &hMpq))
- {
- // Add the file there
- SFileAddFileEx(hMpq, szFileName, "FileTest_base.exe", dwMpqFlags, MPQ_COMPRESSION_ZLIB);
- SFileFlushArchive(hMpq);
- SFileCloseArchive(hMpq);
-
- // Add the same file 10 times
- for(i = 0; i < 10; i++)
- {
- if(SFileOpenArchive(szMpqName, 0, 0, &hMpq))
- {
- dwMaxFileCount = SFileGetMaxFileCount(hMpq) + 1;
- _tprintf(_T("Increasing max file count to %u ...\n"), dwMaxFileCount);
- SFileSetMaxFileCount(hMpq, dwMaxFileCount);
-
- sprintf(szMpqFileName, "FileTest_%02u.exe", dwMaxFileCount);
- PrintfTA(_T("Adding %s as %s\n"), szFileName, szMpqFileName);
- if(!SFileAddFileEx(hMpq, szFileName, szMpqFileName, dwMpqFlags, MPQ_COMPRESSION_ZLIB))
- {
- printf("Failed to add the file \"%s\".\n", szMpqFileName);
- break;
- }
-
- SFileFlushArchive(hMpq);
- SFileCompactArchive(hMpq);
- SFileCloseArchive(hMpq);
- }
- }
- }
-
- _tprintf(_T("\n"));
- return nError;
-}
-
-
-static int TestAddFilesToMpq(
- const TCHAR * szMpqName,
- ...
- )
-{
- const TCHAR * szFileName;
- const TCHAR * szSrc;
- char * szTrg;
- HANDLE hMpq;
- va_list argList;
- char szMpqFileName[MAX_PATH];
- int nError = ERROR_SUCCESS;
-
- if(!SFileOpenArchive(szMpqName, 0, 0, &hMpq))
- return GetLastError();
-
- va_start(argList, szMpqName);
- while((szFileName = va_arg(argList, const TCHAR *)) != NULL)
- {
- // Convert the plain name to ANSI
- szSrc = GetPlainFileNameT(szFileName);
- szTrg = szMpqFileName;
- while(*szSrc != 0)
- *szTrg++ = (char)*szSrc++;
- *szTrg = 0;
-
- // Add the file to MPQ
- if(!SFileAddFileEx(hMpq, szFileName,
- szMpqFileName,
- MPQ_FILE_COMPRESS,
- MPQ_COMPRESSION_ZLIB))
- {
- nError = GetLastError();
- printf("Failed to add the file \"%s\"\n", szFileName);
- }
- }
-
- SFileCloseArchive(hMpq);
- return nError;
-}
-
-static int TestCreateArchiveFromMemory(const TCHAR * szMpqName)
-{
-#define FILE_SIZE 65535
-
- HANDLE hFile;
- HANDLE hMPQ;
- char* data = new char [FILE_SIZE]; // random memory data
- char szFileName[100];
- int i;
-
- // Create an mpq file for testing
- if(SFileCreateArchive(szMpqName, MPQ_CREATE_ARCHIVE_V2|MPQ_CREATE_ATTRIBUTES, 0x100000, &hMPQ))
- {
- for(i = 0; i < 1000; i++)
- {
- sprintf(szFileName, "File%03u.bin", i);
- printf("Adding file %s\r", szFileName);
-
- if(SFileCreateFile(hMPQ, szFileName, 0, FILE_SIZE, 0, MPQ_FILE_COMPRESS, &hFile))
- {
- SFileWriteFile(hFile, data, FILE_SIZE, MPQ_COMPRESSION_ZLIB);
- SFileFinishFile(hFile);
- }
- }
- }
- SFileCloseArchive(hMPQ);
- delete [] data;
- return ERROR_SUCCESS;
-}
-
-static int TestFileReadAndWrite(
- const TCHAR * szMpqName,
- const char * szFileName)
-{
- LPBYTE pvFile = NULL;
- HANDLE hFile = NULL;
- HANDLE hMpq = NULL;
- DWORD dwBytesRead;
- DWORD dwFileSize = 0;
- int nError = ERROR_SUCCESS;
-
- if(!SFileOpenArchive(szMpqName, 0, 0, &hMpq))
- {
- nError = GetLastError();
- _tprintf(_T("Failed to open the archive %s (%u).\n"), szMpqName, nError);
- }
-
- if(nError == ERROR_SUCCESS)
- {
- if(!SFileOpenFileEx(hMpq, szFileName, 0, &hFile))
- {
- nError = GetLastError();
- printf("Failed to open the file %s (%u).\n", szFileName, nError);
- }
- }
-
- if(nError == ERROR_SUCCESS)
- {
- if(!SFileGetFileInfo(hFile, SFILE_INFO_FILE_SIZE, &dwFileSize, sizeof(DWORD)))
- {
- nError = GetLastError();
- _tprintf(_T("Failed to get the file size (%u).\n"), nError);
- }
- }
-
- if(nError == ERROR_SUCCESS)
- {
- pvFile = new BYTE[dwFileSize];
- if(pvFile == NULL)
- {
- nError = ERROR_NOT_ENOUGH_MEMORY;
- printf("Failed to allocate buffer for the file (%u).\n", nError);
- }
- }
-
- if(nError == ERROR_SUCCESS)
- {
- if(!SFileReadFile(hFile, pvFile, dwFileSize, &dwBytesRead))
- {
- nError = GetLastError();
- printf("Failed to read file (%u).\n", nError);
- }
- }
-
- if(hFile != NULL)
- {
- SFileCloseFile(hFile);
- hFile = NULL;
- }
-
- if(nError == ERROR_SUCCESS)
- {
- if(!SFileCreateFile(hMpq, szFileName, 0, dwFileSize, 0, MPQ_FILE_REPLACEEXISTING, &hFile))
- {
- nError = GetLastError();
- printf("Failed to create %s in the archive (%u).\n", szFileName, nError);
- }
- }
-
- if(nError == ERROR_SUCCESS)
- {
- if(!SFileWriteFile(hFile, pvFile, dwFileSize, 0))
- {
- nError = GetLastError();
- printf("Failed to write the data to the MPQ (%u).\n", nError);
- }
- }
-
- if(hFile != NULL)
- {
- if(!SFileFinishFile(hFile))
- {
- nError = GetLastError();
- printf("Failed to finalize file creation (%u).\n", nError);
- }
- }
-
- if(pvFile != NULL)
- delete [] pvFile;
- if(hMpq != NULL)
- SFileCloseArchive(hMpq);
- return nError;
-}
-
-static int TestSignatureVerify(const TCHAR * szMpqName)
-{
- HANDLE hMpq;
-
- if(SFileOpenArchive(szMpqName, 0, 0, &hMpq))
- {
- _tprintf(_T("Verifying digital signature in %s:\n"), szMpqName);
- switch(SFileVerifyArchive(hMpq))
- {
- case ERROR_NO_SIGNATURE:
- _tprintf(_T("No digital signature present.\n"));
- break;
-
- case ERROR_VERIFY_FAILED:
- _tprintf(_T("Failed to verify signature.\n"));
- break;
-
- case ERROR_WEAK_SIGNATURE_OK:
- _tprintf(_T("Weak signature is OK.\n"));
- break;
-
- case ERROR_WEAK_SIGNATURE_ERROR:
- _tprintf(_T("Weak signature mismatch.\n"));
- break;
-
- case ERROR_STRONG_SIGNATURE_OK:
- _tprintf(_T("Strong signature is OK.\n"));
- break;
-
- case ERROR_STRONG_SIGNATURE_ERROR:
- _tprintf(_T("Strong signature mismatch.\n"));
- break;
- }
-
- SFileCloseArchive(hMpq);
- _tprintf(_T("\n"));
- }
-
- return 0;
-}
-
-
-static int TestCreateArchiveCopy(const TCHAR * szMpqName, const TCHAR * szMpqCopyName, const char * szListFile)
-{
- TFileStream * pStream;
- TCHAR szLocalFile[MAX_PATH];
- HANDLE hMpq1 = NULL; // Handle of existing archive
- HANDLE hMpq2 = NULL; // Handle of created archive
- DWORD dwHashTableSize = 0;
- int nError = ERROR_SUCCESS;
-
- // If no listfile or an empty one, use NULL
- if(szListFile == NULL || *szListFile == 0)
- szListFile = NULL;
-
- // Create the new file
- pStream = FileStream_CreateFile(szMpqCopyName, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
- if(pStream == NULL)
- nError = GetLastError();
-
- // Write some data
- if(nError == ERROR_SUCCESS)
- {
- ULONGLONG FileSize = 0x100000;
-
- FileStream_SetSize(pStream, FileSize);
- FileStream_Close(pStream);
- }
-
- // Open the existing MPQ archive
- if(nError == ERROR_SUCCESS)
- {
- _tprintf(_T("Opening %s ...\n"), szMpqName);
- if(!SFileOpenArchive(szMpqName, 0, 0, &hMpq1))
- nError = GetLastError();
- }
-
- // Well, now create the MPQ archive
- if(nError == ERROR_SUCCESS)
- {
- _tprintf(_T("Creating %s ...\n"), szMpqCopyName);
- SFileGetFileInfo(hMpq1, SFILE_INFO_HASH_TABLE_SIZE, &dwHashTableSize, 4);
- if(!SFileCreateArchive(szMpqCopyName, 0, dwHashTableSize, &hMpq2))
- nError = GetLastError();
- }
-
- // Copy all files from one archive to another
- if(nError == ERROR_SUCCESS)
- {
- SFILE_FIND_DATA sf;
- HANDLE hFind = SFileFindFirstFile(hMpq1, "*", &sf, szListFile);
- bool bResult = true;
-
- _tprintf(_T("Copying files ...\n"));
-
- if(hFind != NULL)
- {
- while(bResult)
- {
- if(strcmp(sf.cFileName, LISTFILE_NAME) && strcmp(sf.cFileName, ATTRIBUTES_NAME))
- {
- SFileSetLocale(sf.lcLocale);
-
- // Create the local file name
- MergeLocalPath(szLocalFile, szWorkDir, sf.szPlainName);
- if(SFileExtractFile(hMpq1, sf.cFileName, szLocalFile))
- {
- printf("Extracting %s ... OK\n", sf.cFileName);
- if(!SFileAddFile(hMpq2, szLocalFile, sf.cFileName, sf.dwFileFlags))
- {
- nError = GetLastError();
- printf("Adding %s ... Failed\n\n", sf.cFileName);
- _tremove(szLocalFile);
- break;
- }
- else
- {
- printf("Adding %s ... OK\n", sf.cFileName);
- }
- }
- else
- {
- printf("Extracting %s ... Failed\n", sf.cFileName);
- }
-
- // Delete the added file
- _tremove(szLocalFile);
- }
-
- // Find the next file
- bResult = SFileFindNextFile(hFind, &sf);
- }
-
- // Close the search handle
- SFileFindClose(hFind);
- printf("\n");
- }
- }
-
- // Close both archives
- if(hMpq2 != NULL)
- SFileCloseArchive(hMpq2);
- if(hMpq1 != NULL)
- SFileCloseArchive(hMpq1);
- return nError;
-}
-
-static int TestOpenPatchedArchive(const TCHAR * szMpqName, ...)
-{
- TFileStream * pStream;
- HANDLE hFile = NULL;
- HANDLE hMpq = NULL;
- va_list argList;
- const char * szFileName = "World\\Minimaps\\Azeroth\\noLiquid_map20_44.blp";
- TCHAR szLocFileName[MAX_PATH];
- LPBYTE pbFullFile = NULL;
- DWORD dwFileSize;
- int nError = ERROR_SUCCESS;
-
- // Open the primary MPQ
- _tprintf(_T("Opening %s ...\n"), szMpqName);
- if(!SFileOpenArchive(szMpqName, 0, MPQ_OPEN_READ_ONLY, &hMpq))
- {
- nError = GetLastError();
- _tprintf(_T("Failed to open the archive %s ...\n"), szMpqName);
- }
-
- // Add all patches
- if(nError == ERROR_SUCCESS)
- {
- va_start(argList, szMpqName);
- while((szMpqName = va_arg(argList, const TCHAR *)) != NULL)
- {
- _tprintf(_T("Adding patch %s ...\n"), szMpqName);
- if(!SFileOpenPatchArchive(hMpq, szMpqName, NULL, 0))
- {
- nError = GetLastError();
- printf("Failed to add patch %s ...\n", szMpqName);
- }
- }
- va_end(argList);
- }
-
- // Now search all files
- if(nError == ERROR_SUCCESS)
- {
- SFILE_FIND_DATA sf;
- HANDLE hFind;
- bool bResult = true;
-
- hFind = SFileFindFirstFile(hMpq, "World\\Minimaps\\Azeroth\\noLiquid_map20_44.*", &sf, NULL);
- while(hFind && bResult)
- {
- printf("%s\n", sf.cFileName);
- bResult = SFileFindNextFile(hFind, &sf);
- }
- }
-
- // Now try to open patched version of a file
- if(nError == ERROR_SUCCESS)
- {
- SFileExtractFile(hMpq, szFileName, _T("E:\\noLiquid_map20_44.blp"));
- }
-
- // Now try to open patched version of "Achievement.dbc"
- if(nError == ERROR_SUCCESS)
- {
- printf("Opening patched file \"%s\" ...\n", szFileName);
- SFileVerifyFile(hMpq, szFileName, SFILE_VERIFY_RAW_MD5);
- if(!SFileOpenFileEx(hMpq, szFileName, SFILE_OPEN_PATCHED_FILE, &hFile))
- {
- nError = GetLastError();
- printf("Failed to open patched file \"%s\"\n", szFileName);
- }
- }
-
- // Verify of the patched version is correct
- if(nError == ERROR_SUCCESS)
- {
- TCHAR * szPatchChain = NULL;
- DWORD cbPatchChain = 0;
-
- // Get the patch chain
- SFileGetFileInfo(hFile, SFILE_INFO_PATCH_CHAIN, szPatchChain, cbPatchChain, &cbPatchChain);
- szPatchChain = (TCHAR *)(new BYTE[cbPatchChain]);
- SFileGetFileInfo(hFile, SFILE_INFO_PATCH_CHAIN, szPatchChain, cbPatchChain, &cbPatchChain);
- delete [] szPatchChain;
-
- // Get the size of the full patched file
- dwFileSize = SFileGetFileSize(hFile, NULL);
- if(dwFileSize != 0)
- {
- DWORD dwBytesRead = 0;
- BYTE TempData[0x100];
-
- SFileReadFile(hFile, TempData, sizeof(TempData), &dwBytesRead);
- SFileSetFilePointer(hFile, 0, NULL, FILE_BEGIN);
-
- // Allocate space for the full file
- pbFullFile = new BYTE[dwFileSize];
- if(pbFullFile != NULL)
- {
- if(!SFileReadFile(hFile, pbFullFile, dwFileSize))
- {
- nError = GetLastError();
- printf("Failed to read full patched file data \"%s\"\n", szFileName);
- }
-
- if(nError == ERROR_SUCCESS)
- {
- MergeLocalPath(szLocFileName, MAKE_PATH("Work//"), GetPlainFileNameA(szFileName));
- pStream = FileStream_CreateFile(szLocFileName, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
- if(pStream != NULL)
- {
- FileStream_Write(pStream, NULL, pbFullFile, dwFileSize);
- FileStream_Close(pStream);
- }
- }
-
- delete [] pbFullFile;
- }
- }
- }
-
- // Close handles
- if(hFile != NULL)
- SFileCloseFile(hFile);
- if(hMpq != NULL)
- SFileCloseArchive(hMpq);
- return nError;
-}
-
-static int TestCompareTwoArchives(
- const TCHAR * szMpqName1,
- const TCHAR * szMpqName2,
- const char * szListFile,
- DWORD dwBlockSize)
-{
- TMPQArchive * ha1 = NULL;
- TMPQArchive * ha2 = NULL;
- HANDLE hMpq1 = NULL; // Handle of the first archive
- HANDLE hMpq2 = NULL; // Handle of the second archive
- HANDLE hFile1 = NULL;
- HANDLE hFile2 = NULL;
- int nError = ERROR_SUCCESS;
-
- // If no listfile or an empty one, use NULL
- if(szListFile == NULL || *szListFile == 0)
- szListFile = NULL;
-
- _tprintf(_T("=============== Comparing MPQ archives ===============\n"));
-
- // Open the first MPQ archive
- if(nError == ERROR_SUCCESS && szMpqName1 != NULL)
- {
- _tprintf(_T("Opening %s ...\n"), szMpqName1);
- if(!SFileOpenArchive(szMpqName1, 0, 0, &hMpq1))
- nError = GetLastError();
- ha1 = (TMPQArchive *)hMpq1;
- }
-
- // Open the second MPQ archive
- if(nError == ERROR_SUCCESS && szMpqName2 != NULL)
- {
- _tprintf(_T("Opening %s ...\n"), szMpqName2);
- if(!SFileOpenArchive(szMpqName2, 0, 0, &hMpq2))
- nError = GetLastError();
- ha2 = (TMPQArchive *)hMpq2;
- }
-
- // Compare the header
- if(nError == ERROR_SUCCESS && (ha1 != NULL && ha2 != NULL))
- {
- if(ha1->pHeader->dwHeaderSize != ha2->pHeader->dwHeaderSize)
- printf(" - Header size is different\n");
- if(ha1->pHeader->wFormatVersion != ha2->pHeader->wFormatVersion)
- printf(" - Format version is different\n");
- if(ha1->pHeader->wSectorSize != ha2->pHeader->wSectorSize)
- printf(" - Sector size is different\n");
- if(ha1->pHeader->HetTableSize64 != ha2->pHeader->HetTableSize64)
- printf(" - HET table size is different\n");
- if(ha1->pHeader->BetTableSize64 != ha2->pHeader->BetTableSize64)
- printf(" - BET table size is different\n");
- if(ha1->pHeader->dwHashTableSize != ha2->pHeader->dwHashTableSize)
- printf(" - Hash table size is different\n");
- if(ha1->pHeader->dwBlockTableSize != ha2->pHeader->dwBlockTableSize)
- printf(" - Block table size is different\n");
- }
-
- // Find all files in the first archive and compare them
- if(nError == ERROR_SUCCESS)
- {
- SFILE_FIND_DATA sf;
- TMPQFile * hf1;
- TMPQFile * hf2;
- HANDLE hFind = SFileFindFirstFile(hMpq1, "*", &sf, szListFile);
- bool bResult = true;
-
- while(hFind != NULL && bResult == true)
- {
-// printf("%s \r", sf.cFileName);
- SFileSetLocale(sf.lcLocale);
-
- // Open the first file
- if(!SFileOpenFileEx(hMpq1, sf.cFileName, 0, &hFile1))
- printf("Failed to open the file %s in the first archive\n", sf.cFileName);
-
- if(!SFileOpenFileEx(hMpq2, sf.cFileName, 0, &hFile2))
- printf("Failed to open the file %s in the second archive\n", sf.cFileName);
-
- if(hFile1 != NULL && hFile2 != NULL)
- {
- // Get the TMPQFile pointers
- hf1 = (TMPQFile *)hFile1;
- hf2 = (TMPQFile *)hFile2;
-
- // Compare the file sizes
- if(hf1->pFileEntry->dwFileSize != hf2->pFileEntry->dwFileSize)
- printf("Different file size: %s (%u x %u)\n", sf.cFileName, hf1->pFileEntry->dwFileSize, hf2->pFileEntry->dwFileSize);
-
- if(hf1->pFileEntry->dwCmpSize != hf2->pFileEntry->dwCmpSize)
- printf("Different cmpr size: %s (%u x %u)\n", sf.cFileName, hf1->pFileEntry->dwCmpSize, hf2->pFileEntry->dwCmpSize);
-
- if(hf1->pFileEntry->dwFlags != hf2->pFileEntry->dwFlags)
- printf("Different mpq flags: %s (%08X x %08X)\n", sf.cFileName, hf1->pFileEntry->dwFlags, hf2->pFileEntry->dwFlags);
-
- if(!CompareArchivedFiles(sf.cFileName, hFile1, hFile2, dwBlockSize))
- printf("Different file data: %s\n", sf.cFileName);
-
-// if(!CompareArchivedFilesRR(sf.cFileName, hFile1, hFile2, dwBlockSize))
-// printf("Different file data: %s\n", sf.cFileName);
- }
-
- // Close both files
- if(hFile2 != NULL)
- SFileCloseFile(hFile2);
- if(hFile1 != NULL)
- SFileCloseFile(hFile1);
- hFile2 = hFile1 = NULL;
-
- // Find the next file
- bResult = SFileFindNextFile(hFind, &sf);
- }
-
- // Close the find handle
- if(hFind != NULL)
- SFileFindClose(hFind);
- }
-
- // Close both archives
- clreol();
- printf("================ MPQ compare complete ================\n");
- if(hMpq2 != NULL)
- SFileCloseArchive(hMpq2);
- if(hMpq1 != NULL)
- SFileCloseArchive(hMpq1);
- return nError;
-}
-
-//-----------------------------------------------------------------------------
-// Searching all known MPQs
-
-#ifdef _WIN32
-static int TestSearchOneArchive(const TCHAR * szMpqName)
-{
- SFILE_FIND_DATA sf;
- HANDLE hFind;
- HANDLE hMpq;
- const TCHAR * szExtension;
- bool bFound = true;
-
- // Get the file extension
- szExtension = _tcsrchr(szMpqName, _T('.'));
- if(szExtension == NULL)
- return ERROR_SUCCESS;
-
- // Only search defined extensions
- if(_tcsicmp(szExtension, _T(".mpq")) && _tcsnicmp(szExtension, _T(".SC2"), 4))
- return ERROR_SUCCESS;
-
- _tprintf(_T("Searching %s ...\n"), szMpqName);
-
- // Try to open the MPQ
- if(SFileOpenArchive(szMpqName, 0, MPQ_OPEN_READ_ONLY, &hMpq))
- {
- hFind = SFileFindFirstFile(hMpq, "*", &sf, NULL);
- if(hFind != NULL)
- {
- while(bFound)
- {
- if(sf.dwFileFlags & MPQ_FILE_DELETE_MARKER)
- _tprintf(_T("Delete marker: %s:%hs\n"), szMpqName, sf.cFileName);
-
- bFound = SFileFindNextFile(hFind, &sf);
- }
- }
-
- SFileCloseArchive(hMpq);
- }
-
- return ERROR_SUCCESS;
-}
-
-static int TestSearchAllArchives(const TCHAR * szSearchMask)
-{
- WIN32_FIND_DATA wf;
- LPTSTR szFilePart;
- HANDLE hFind;
- TCHAR szFullPath[MAX_PATH];
- BOOL bFound = TRUE;
-
- // Initiate search
- _tcscpy(szFullPath, szSearchMask);
- szFilePart = _tcschr(szFullPath, _T('*'));
- assert(szFilePart != NULL);
-
- // Begin search
- hFind = FindFirstFile(szSearchMask, &wf);
- if(hFind != INVALID_HANDLE_VALUE)
- {
- while(bFound)
- {
- // Eliminate "." and ".."
- if(wf.cFileName[0] != _T('.'))
- {
- // Construct the full path
- _tcscpy(szFilePart, wf.cFileName);
-
- // If it a directory?
- if(wf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- {
- _tcscat(szFullPath, _T("\\*"));
- TestSearchAllArchives(szFullPath);
- }
- else
- {
- TestSearchOneArchive(szFullPath);
- }
- }
- bFound = FindNextFile(hFind, &wf);
- }
- FindClose(hFind);
- }
-
- return ERROR_SUCCESS;
-}
-#endif
-
-//-----------------------------------------------------------------------------
-// Main
-//
-
-int main(void)
-{
- int nError = ERROR_SUCCESS;
-
-#if defined(_MSC_VER) && defined(_DEBUG)
- _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
-#endif // defined(_MSC_VER) && defined(_DEBUG)
-
-// FileStream_OpenEncrypted(_T("e:\\Multimedia\\MPQs\\2010 - Starcraft II\\Installer UI 2 deDE.MPQE"));
-
- // Mix the random number generator
-// srand(GetTickCount());
-
- // Test structure sizes
-// if(nError == ERROR_SUCCESS)
-// nError = TestStructureSizes();
-
-// if(nError == ERROR_SUCCESS)
-// nError = TestOpenLocalFile("C:\\autoexec.bat");
-
- // Test reading partial file
-// if(nError == ERROR_SUCCESS)
-// nError = TestPartFileRead(MAKE_PATH("2009 - PartialMPQs/patch.MPQ.part"));
-
-// if(nError == ERROR_SUCCESS)
-// nError = ComparePklibCompressions();
-
- // Test LZMA compression method against the code ripped from Starcraft II
-// if(nError == ERROR_SUCCESS)
-// nError = CompareLzmaCompressions(MPQ_SECTOR_SIZE);
-
- // Test compression methods
-// if(nError == ERROR_SUCCESS)
-// nError = TestSectorCompress(MPQ_SECTOR_SIZE);
-
- // Test the archive open and close
-// if(nError == ERROR_SUCCESS)
-// nError = TestArchiveOpenAndClose(_T("d:\\Install\\Blizzard\\Diablo III\\Diablo-III-8370-enGB-Installer\\Installer Tome 1.MPQE"));
-// nError = TestArchiveOpenAndClose(MAKE_PATH("2011 - WoW BETA/wow-update-13202.MPQ"));
-// nError = TestArchiveOpenAndClose(MAKE_PATH("2002 - Warcraft III/ProtectedMap_HashTable_FakeValid.w3x"));
-// nError = TestArchiveOpenAndClose(MAKE_PATH("2010 - Starcraft II/Installer Tome 1 enGB.MPQE"));
-// nError = TestArchiveOpenAndClose(MAKE_PATH("1997 - Diablo I/DIABDAT_orig.MPQ"));
-// nError = TestArchiveOpenAndClose(MAKE_PATH("2004 - World of Warcraft/SoundCache-enUS.MPQ"));
-// nError = TestArchiveOpenAndClose(MAKE_PATH("smpq.mpq "));
-
-// if(nError == ERROR_SUCCESS)
-// nError = TestFindFiles(MAKE_PATH("2002 - Warcraft III/HumanEd.mpq"));
-
- // Create a big MPQ archive
-// if(nError == ERROR_SUCCESS)
-// nError = TestCreateArchive_PaliRoharBug(MAKE_PATH("Test.mpq"));
-// nError = TestCreateArchive(MAKE_PATH("Test.mpq"));
-// nError = TestCreateArchive((const TCHAR*)szUnicodeName1);
-// nError = TestCreateArchive((const TCHAR*)szUnicodeName2);
-// nError = TestCreateArchive((const TCHAR*)szUnicodeName3);
-// nError = TestCreateArchive((const TCHAR*)szUnicodeName4);
-// nError = TestCreateArchive((const TCHAR*)szUnicodeName5);
-// nError = TestCreateArchive((const TCHAR*)szUnicodeName6);
-
-// if(nError == ERROR_SUCCESS)
-// nError = TestAddFilesToMpq(MAKE_PATH("wow-update-13202.MPQ"),
-// "c:\\Tools32\\Arj32.exe",
-// "c:\\Tools32\\autoruns.chm",
-// "c:\\Tools32\\CPUEater.exe",
-// "c:\\Tools32\\dumpbin.exe",
-// "c:\\Tools32\\editbin.exe",
-// "c:\\Tools32\\fsg.ini",
-// "c:\\Tools32\\hiew8.ini",
-// "c:\\Tools32\\ida.bat",
-// "c:\\Tools32\\mp3.ini",
-// NULL);
-
-// if(nError == ERROR_SUCCESS)
-// nError = TestCreateArchiveFromMemory(MAKE_PATH("Test-leak.mpq"));
-
-// if(nError == ERROR_SUCCESS)
-// nError = TestFileReadAndWrite(MAKE_PATH("2002 - Warcraft III/(10)DustwallowKeys.w3m"), "war3map.j");
-
- // Verify the archive signature
-// if(nError == ERROR_SUCCESS)
-// nError = TestSignatureVerify(MAKE_PATH("1998 - Starcraft/BW-1152.exe"));
-// nError = TestSignatureVerify(MAKE_PATH("2002 - Warcraft III/(10)DustwallowKeys.w3m"));
-// nError = TestSignatureVerify(MAKE_PATH("2002 - Warcraft III/War3TFT_121b_English.exe"));
-// nError = TestSignatureVerify(MAKE_PATH("2004 - World of Warcraft/WoW-2.3.3.7799-to-2.4.0.8089-enUS-patch.exe"));
-// nError = TestSignatureVerify(MAKE_PATH("2004 - World of Warcraft/standalone.MPQ"));
-
- // Compact the archive
-// if(nError == ERROR_SUCCESS)
-// nError = TestMpqCompacting(MAKE_PATH("wow-update-base-14333.MPQ"));
-
- // Create copy of the archive, appending some bytes before the MPQ header
-// if(nError == ERROR_SUCCESS)
-// nError = TestCreateArchiveCopy(MAKE_PATH("PartialMPQs/interface.MPQ.part"), MAKE_PATH("PartialMPQs/interface-copy.MPQ.part"), NULL);
-
-/*
- if(nError == ERROR_SUCCESS)
- {
- nError = TestOpenPatchedArchive(MAKE_PATH("2011 - WoW 4.x/locale-enGB.MPQ"),
- MAKE_PATH("2011 - WoW 4.x/wow-update-13164.MPQ"),
- MAKE_PATH("2011 - WoW 4.x/wow-update-13205.MPQ"),
- MAKE_PATH("2011 - WoW 4.x/wow-update-13287.MPQ"),
- MAKE_PATH("2011 - WoW 4.x/wow-update-13329.MPQ"),
- MAKE_PATH("2011 - WoW 4.x/wow-update-13596.MPQ"),
- MAKE_PATH("2011 - WoW 4.x/wow-update-13623.MPQ"),
- MAKE_PATH("2011 - WoW 4.x/wow-update-enGB-13914.MPQ"),
- MAKE_PATH("2011 - WoW 4.x/wow-update-enGB-14007.MPQ"),
- MAKE_PATH("2011 - WoW 4.x/wow-update-enGB-14333.MPQ"),
- MAKE_PATH("2011 - WoW 4.x/wow-update-enGB-14480.MPQ"),
- NULL);
- }
-*/
-
- if(nError == ERROR_SUCCESS)
- {
- nError = TestCompareTwoArchives(MAKE_PATH("Sound-copy.mpq"),
- MAKE_PATH("Sound.mpq"),
- NULL,
- 0x1001);
- }
-
-
-// if(nError == ERROR_SUCCESS)
-// nError = TestSearchAllArchives(MAKE_PATH("*"));
-
- return nError;
-}
diff --git a/dep/StormLib/test/x86_ripped_code.asm b/dep/StormLib/test/x86_ripped_code.asm
deleted file mode 100644
index 4b4be328a6c..00000000000
--- a/dep/StormLib/test/x86_ripped_code.asm
+++ /dev/null
@@ -1,1231 +0,0 @@
-.686P
-.MODEL FLAT
-ASSUME FS: NOTHING
-.CODE
-
-extrn _memset:PROC
-extrn _memcpy:PROC
-extrn _memmove:PROC
-
-;------------------------------------------------------------------------------
-; Structures
-;
-
-;------------------------------------------------------------------------------
-; Functions
-;
-
-_aullrem proc near ; CODE XREF: sub_6CC140+3Ap
- ; sub_6CC1E0+57p ...
-
-DividendLo = dword ptr 8
-DividendHi = dword ptr 0Ch
-DivisorLo = dword ptr 10h
-DivisorHi = dword ptr 14h
-
- push ebx
- mov eax, [esp+DivisorHi]
- or eax, eax
- jnz short loc_8F8FE1
- mov ecx, [esp+DivisorLo]
- mov eax, [esp+DividendHi]
- xor edx, edx
- div ecx
- mov eax, [esp+DividendLo]
- div ecx
- mov eax, edx
- xor edx, edx
- jmp short loc_8F9031
-; ---------------------------------------------------------------------------
-
-loc_8F8FE1: ; CODE XREF: _aullrem+7j
- mov ecx, eax
- mov ebx, [esp+DivisorLo]
- mov edx, [esp+DividendHi]
- mov eax, [esp+DividendLo]
-
-loc_8F8FEF: ; CODE XREF: _aullrem+39j
- shr ecx, 1
- rcr ebx, 1
- shr edx, 1
- rcr eax, 1
- or ecx, ecx
- jnz short loc_8F8FEF
- div ebx
- mov ecx, eax
- mul [esp+DivisorHi]
- xchg eax, ecx
- mul [esp+DivisorLo]
- add edx, ecx
- jb short loc_8F901A
- cmp edx, [esp+DividendHi]
- ja short loc_8F901A
- jb short loc_8F9022
- cmp eax, [esp+DividendLo]
- jbe short loc_8F9022
-
-loc_8F901A: ; CODE XREF: _aullrem+4Aj
- ; _aullrem+50j
- sub eax, [esp+DivisorLo]
- sbb edx, [esp+DivisorHi]
-
-loc_8F9022: ; CODE XREF: _aullrem+52j
- ; _aullrem+58j
- sub eax, [esp+DividendLo]
- sbb edx, [esp+DividendHi]
- neg edx
- neg eax
- sbb edx, 0
-
-loc_8F9031: ; CODE XREF: _aullrem+1Fj
- pop ebx
- retn 10h
-_aullrem endp
-
-_aullshr proc near ; CODE XREF: sub_40E2B6+1ECp
- ; sub_40E2B6+240p ...
- cmp cl, 40h
- jnb short loc_414BDA
- cmp cl, 20h
- jnb short loc_414BD0
- shrd eax, edx, cl
- shr edx, cl
- retn
-; ---------------------------------------------------------------------------
-
-loc_414BD0: ; CODE XREF: _aullshr+8j
- mov eax, edx
- xor edx, edx
- and cl, 1Fh
- shr eax, cl
- retn
-; ---------------------------------------------------------------------------
-
-loc_414BDA: ; CODE XREF: _aullshr+3j
- xor eax, eax
- xor edx, edx
- retn
-_aullshr endp
-
-
-; =============== S U B R O U T I N E =======================================
-
-; Attributes: bp-based frame
-
-SFileDecryptMpqHeader proc near ; CODE XREF: sub_6D00E0+AEp
- ; sub_6D00E0+D3p
-
-EncryptedDataAligned= dword ptr -88h
-var_48 = dword ptr -48h
-DecryptBuffer = dword ptr -44h
-var_40 = dword ptr -40h
-var_3C = dword ptr -3Ch
-var_38 = dword ptr -38h
-var_34 = dword ptr -34h
-var_30 = dword ptr -30h
-var_2C = dword ptr -2Ch
-var_28 = dword ptr -28h
-var_24 = dword ptr -24h
-var_20 = dword ptr -20h
-var_1C = dword ptr -1Ch
-var_18 = dword ptr -18h
-var_14 = dword ptr -14h
-var_10 = dword ptr -10h
-var_0C = dword ptr -0Ch
-var_8 = dword ptr -8
-var_4 = dword ptr -4
-arg_FFFFFFF8 = dword ptr 0
-arg_FFFFFFFC = dword ptr 4
-arg_0 = dword ptr 8
-
- push ebp
- mov ebp, esp
- sub esp, 88h
- mov eax, [ecx+8]
- mov edx, [ecx+14h]
- push ebx
- mov ebx, [ecx+10h]
- mov [ebp+var_0C], eax
- mov eax, [ebp+arg_0]
- push esi
- push edi
- mov edi, [ecx+0Ch]
- mov [ebp+DecryptBuffer], ecx
- mov [ebp+var_10], edx
- test al, 3
- jz short loc_6C9F03
- mov ecx, [eax]
- mov [ebp+EncryptedDataAligned], ecx
- mov ecx, [eax+4]
- mov [ebp+EncryptedDataAligned+4], ecx
- mov ecx, [eax+8]
- mov [ebp+EncryptedDataAligned+8], ecx
- mov ecx, [eax+0Ch]
- mov [ebp+EncryptedDataAligned+0Ch], ecx
- mov ecx, [eax+10h]
- mov [ebp+EncryptedDataAligned+10h], ecx
- mov ecx, [eax+14h]
- mov [ebp+EncryptedDataAligned+14h], ecx
- mov ecx, [eax+18h]
- mov [ebp+EncryptedDataAligned+18h], ecx
- mov ecx, [eax+1Ch]
- mov [ebp+EncryptedDataAligned+1Ch], ecx
- mov ecx, [eax+20h]
- mov [ebp+EncryptedDataAligned+20h], ecx
- mov ecx, [eax+24h]
- mov [ebp+EncryptedDataAligned+24h], ecx
- mov ecx, [eax+28h]
- mov [ebp+EncryptedDataAligned+28h], ecx
- mov ecx, [eax+2Ch]
- mov [ebp+EncryptedDataAligned+2Ch], ecx
- mov ecx, [eax+30h]
- mov [ebp+EncryptedDataAligned+30h], ecx
- mov ecx, [eax+34h]
- mov [ebp+EncryptedDataAligned+34h], ecx
- mov ecx, [eax+38h]
- mov eax, [eax+3Ch]
- mov [ebp+EncryptedDataAligned+3Ch], eax
- mov [ebp+EncryptedDataAligned+38h], ecx
- lea eax, [ebp+EncryptedDataAligned]
-
-loc_6C9F03: ; CODE XREF: SFileDecryptMpqHeader+26j
- mov ecx, [eax]
- mov [ebp+var_30], ecx
- mov esi, edi
- not esi
- and esi, edx
- mov edx, ebx
- and edx, edi
- or esi, edx
- add esi, ecx
- mov ecx, [ebp+var_0C]
- lea edx, [esi+ecx-28955B88h]
- mov ecx, [eax+4]
- rol edx, 7
- add edx, edi
- mov [ebp+var_2C], ecx
- mov ecx, edx
- not ecx
- and ecx, ebx
- mov esi, edi
- and esi, edx
- or ecx, esi
- add ecx, [ebp+var_2C]
- mov esi, [ebp+var_10]
- lea esi, [ecx+esi-173848AAh]
- mov ecx, [eax+8]
- mov [ebp+var_40], ecx
- rol esi, 0Ch
- add esi, edx
- mov ecx, esi
- not ecx
- and ecx, edi
- mov edi, esi
- and edi, edx
- or ecx, edi
- add ecx, [ebp+var_40]
- lea edi, [ecx+ebx+242070DBh]
- mov ecx, [eax+0Ch]
- ror edi, 0Fh
- add edi, esi
- mov [ebp+var_1C], ecx
- mov ebx, edi
- not ebx
- and ebx, edx
- mov ecx, esi
- and ecx, edi
- or ebx, ecx
- add ebx, [ebp+var_1C]
- mov ecx, [ebp+DecryptBuffer]
- mov ecx, [ecx+0Ch]
- lea ecx, [ebx+ecx-3E423112h]
- ror ecx, 0Ah
- add ecx, edi
- mov [ebp+var_4], edi
- and edi, ecx
- mov ebx, ecx
- not ebx
- and ebx, esi
- or ebx, edi
- mov edi, [eax+10h]
- add ebx, edi
- lea edx, [ebx+edx-0A83F051h]
- rol edx, 7
- add edx, ecx
- mov [ebp+arg_0], edx
- not edx
- and edx, [ebp+var_4]
- mov ebx, ecx
- and ebx, [ebp+arg_0]
- mov [ebp+var_10], edi
- mov edi, [eax+14h]
- or edx, ebx
- add edx, edi
- lea esi, [edx+esi+4787C62Ah]
- mov edx, [eax+18h]
- mov [ebp+var_34], edi
- mov edi, [ebp+arg_0]
- rol esi, 0Ch
- add esi, edi
- mov [ebp+var_20], edx
- mov edx, esi
- not edx
- and edx, ecx
- mov ebx, esi
- and ebx, edi
- or edx, ebx
- add edx, [ebp+var_20]
- mov ebx, [ebp+var_4]
- lea edx, [edx+ebx-57CFB9EDh]
- ror edx, 0Fh
- add edx, esi
- mov ebx, edx
- not ebx
- and ebx, edi
- mov edi, esi
- and edi, edx
- or ebx, edi
- mov edi, [eax+1Ch]
- add ebx, edi
- lea ecx, [ebx+ecx-2B96AFFh]
- ror ecx, 0Ah
- add ecx, edx
- mov [ebp+var_3C], edi
- mov edi, [eax+20h]
- mov [ebp+var_14], edi
- mov edi, ecx
- not edi
- and edi, esi
- mov ebx, edx
- and ebx, ecx
- or edi, ebx
- add edi, [ebp+var_14]
- mov ebx, [ebp+arg_0]
- lea edi, [edi+ebx+698098D8h]
- mov [ebp+var_8], ecx
- rol edi, 7
- add edi, ecx
- and ecx, edi
- mov ebx, edi
- not ebx
- and ebx, edx
- or ebx, ecx
- mov ecx, [eax+24h]
- add ebx, ecx
- mov [ebp+var_0C], ecx
- mov ecx, [eax+28h]
- lea esi, [ebx+esi-74BB0851h]
- mov [ebp+var_24], ecx
- rol esi, 0Ch
- add esi, edi
- mov ecx, esi
- not ecx
- and ecx, [ebp+var_8]
- mov ebx, esi
- and ebx, edi
- or ecx, ebx
- add ecx, [ebp+var_24]
- mov ebx, esi
- lea edx, [ecx+edx-0A44Fh]
- mov ecx, [eax+2Ch]
- ror edx, 0Fh
- add edx, esi
- mov [ebp+var_18], ecx
- and ebx, edx
- mov ecx, edx
- not ecx
- and ecx, edi
- or ecx, ebx
- add ecx, [ebp+var_18]
- mov ebx, [ebp+var_8]
- lea ecx, [ecx+ebx-76A32842h]
- ror ecx, 0Ah
- add ecx, edx
- mov ebx, ecx
- not ebx
- mov [ebp+var_4], edx
- and edx, ecx
- and ebx, esi
- or ebx, edx
- mov edx, [eax+30h]
- add ebx, edx
- mov [ebp+var_38], edx
- lea edi, [ebx+edi+6B901122h]
- mov edx, [eax+34h]
- rol edi, 7
- add edi, ecx
- mov [ebp+arg_0], edi
- not edi
- and edi, [ebp+var_4]
- mov ebx, ecx
- and ebx, [ebp+arg_0]
- mov [ebp+var_8], edx
- or edi, ebx
- add edi, edx
- mov edx, [eax+38h]
- mov eax, [eax+3Ch]
- lea esi, [edi+esi-2678E6Dh]
- rol esi, 0Ch
- add esi, [ebp+arg_0]
- mov [ebp+var_28], edx
- mov edi, esi
- not edi
- mov edx, edi
- and edx, ecx
- mov ebx, esi
- and ebx, [ebp+arg_0]
- or edx, ebx
- add edx, [ebp+var_28]
- mov ebx, [ebp+var_4]
- lea edx, [edx+ebx-5986BC72h]
- mov [ebp+var_4], eax
- ror edx, 0Fh
- add edx, esi
- mov ebx, edx
- not ebx
- mov [ebp+var_48], ebx
- and ebx, [ebp+arg_0]
- mov eax, esi
- and eax, edx
- or ebx, eax
- add ebx, [ebp+var_4]
- and edi, edx
- lea ecx, [ebx+ecx+49B40821h]
- ror ecx, 0Ah
- add ecx, edx
- mov eax, esi
- and eax, ecx
- or edi, eax
- add edi, [ebp+var_2C]
- mov eax, [ebp+arg_0]
- lea edi, [edi+eax-9E1DA9Eh]
- mov eax, [ebp+var_48]
- and eax, ecx
- rol edi, 5
- add edi, ecx
- mov ebx, edx
- and ebx, edi
- or eax, ebx
- add eax, [ebp+var_20]
- lea esi, [eax+esi-3FBF4CC0h]
- rol esi, 9
- add esi, edi
- mov eax, ecx
- not eax
- and eax, edi
- mov ebx, esi
- and ebx, ecx
- or eax, ebx
- add eax, [ebp+var_18]
- lea edx, [eax+edx+265E5A51h]
- rol edx, 0Eh
- add edx, esi
- mov eax, edi
- not eax
- and eax, esi
- mov ebx, edx
- and ebx, edi
- or eax, ebx
- add eax, [ebp+var_30]
- lea ecx, [eax+ecx-16493856h]
- ror ecx, 0Ch
- mov eax, esi
- add ecx, edx
- not eax
- and eax, edx
- mov ebx, esi
- and ebx, ecx
- or eax, ebx
- add eax, [ebp+var_34]
- lea edi, [eax+edi-29D0EFA3h]
- rol edi, 5
- add edi, ecx
- mov [ebp+arg_0], edi
- mov eax, edx
- not eax
- and eax, ecx
- mov edi, edx
- and edi, [ebp+arg_0]
- or eax, edi
- add eax, [ebp+var_24]
- mov edi, ecx
- lea esi, [eax+esi+2441453h]
- mov eax, [ebp+arg_0]
- not edi
- and edi, eax
- rol esi, 9
- add esi, eax
- not eax
- and eax, esi
- mov ebx, esi
- and ebx, ecx
- or edi, ebx
- add edi, [ebp+var_4]
- lea edx, [edi+edx-275E197Fh]
- rol edx, 0Eh
- add edx, esi
- mov edi, edx
- and edi, [ebp+arg_0]
- or eax, edi
- add eax, [ebp+var_10]
- mov edi, esi
- lea ecx, [eax+ecx-182C0438h]
- ror ecx, 0Ch
- add ecx, edx
- and edi, ecx
- mov eax, esi
- not eax
- and eax, edx
- or eax, edi
- add eax, [ebp+var_0C]
- mov edi, [ebp+arg_0]
- lea eax, [eax+edi+21E1CDE6h]
- rol eax, 5
- add eax, ecx
- mov [ebp+arg_0], eax
- mov eax, edx
- not eax
- and eax, ecx
- mov edi, edx
- and edi, [ebp+arg_0]
- or eax, edi
- add eax, [ebp+var_28]
- mov edi, ecx
- lea esi, [eax+esi-3CC8F82Ah]
- mov eax, [ebp+arg_0]
- rol esi, 9
- add esi, eax
- not edi
- and edi, eax
- mov ebx, esi
- and ebx, ecx
- or edi, ebx
- add edi, [ebp+var_1C]
- not eax
- lea edx, [edi+edx-0B2AF279h]
- rol edx, 0Eh
- add edx, esi
- and eax, esi
- mov edi, edx
- and edi, [ebp+arg_0]
- or eax, edi
- add eax, [ebp+var_14]
- lea ecx, [eax+ecx+455A14EDh]
- ror ecx, 0Ch
- add ecx, edx
- mov eax, esi
- not eax
- and eax, edx
- mov edi, esi
- and edi, ecx
- or eax, edi
- add eax, [ebp+var_8]
- mov edi, [ebp+arg_0]
- lea eax, [eax+edi-561C16FBh]
- rol eax, 5
- add eax, ecx
- mov [ebp+arg_0], eax
- mov eax, edx
- not eax
- and eax, ecx
- mov edi, edx
- and edi, [ebp+arg_0]
- or eax, edi
- add eax, [ebp+var_40]
- mov edi, ecx
- lea esi, [eax+esi-3105C08h]
- mov eax, [ebp+arg_0]
- not edi
- and edi, eax
- rol esi, 9
- add esi, eax
- mov ebx, esi
- and ebx, ecx
- or edi, ebx
- add edi, [ebp+var_3C]
- not eax
- lea edx, [edi+edx+676F02D9h]
- and eax, esi
- rol edx, 0Eh
- add edx, esi
- mov edi, edx
- and edi, [ebp+arg_0]
- or eax, edi
- add eax, [ebp+var_38]
- mov edi, [ebp+arg_0]
- lea ecx, [eax+ecx-72D5B376h]
- ror ecx, 0Ch
- add ecx, edx
- mov eax, esi
- xor eax, edx
- xor eax, ecx
- add eax, [ebp+var_34]
- lea eax, [eax+edi-5C6BEh]
- rol eax, 4
- add eax, ecx
- mov edi, edx
- xor edi, ecx
- xor edi, eax
- add edi, [ebp+var_14]
- lea esi, [edi+esi-788E097Fh]
- rol esi, 0Bh
- add esi, eax
- mov edi, esi
- xor edi, ecx
- xor edi, eax
- add edi, [ebp+var_18]
- lea edx, [edi+edx+6D9D6122h]
- rol edx, 10h
- add edx, esi
- mov edi, esi
- xor edi, edx
- mov ebx, edi
- xor ebx, eax
- add ebx, [ebp+var_28]
- lea ecx, [ebx+ecx-21AC7F4h]
- ror ecx, 9
- add ecx, edx
- xor edi, ecx
- add edi, [ebp+var_2C]
- lea eax, [edi+eax-5B4115BCh]
- rol eax, 4
- mov edi, edx
- add eax, ecx
- xor edi, ecx
- xor edi, eax
- add edi, [ebp+var_10]
- lea esi, [edi+esi+4BDECFA9h]
- rol esi, 0Bh
- add esi, eax
- mov edi, esi
- xor edi, ecx
- xor edi, eax
- add edi, [ebp+var_3C]
- lea edx, [edi+edx-944B4A0h]
- rol edx, 10h
- add edx, esi
- mov edi, esi
- xor edi, edx
- mov ebx, edi
- xor ebx, eax
- add ebx, [ebp+var_24]
- lea ecx, [ebx+ecx-41404390h]
- ror ecx, 9
- add ecx, edx
- xor edi, ecx
- add edi, [ebp+var_8]
- lea eax, [edi+eax+289B7EC6h]
- rol eax, 4
- add eax, ecx
- mov edi, edx
- xor edi, ecx
- xor edi, eax
- add edi, [ebp+var_30]
- lea esi, [edi+esi-155ED806h]
- rol esi, 0Bh
- add esi, eax
- mov edi, esi
- xor edi, ecx
- xor edi, eax
- add edi, [ebp+var_1C]
- lea edi, [edi+edx-2B10CF7Bh]
- rol edi, 10h
- add edi, esi
- mov edx, esi
- xor edx, edi
- mov ebx, edx
- xor ebx, eax
- add ebx, [ebp+var_20]
- lea ecx, [ebx+ecx+4881D05h]
- ror ecx, 9
- add ecx, edi
- xor edx, ecx
- add edx, [ebp+var_0C]
- lea eax, [edx+eax-262B2FC7h]
- rol eax, 4
- add eax, ecx
- mov edx, edi
- xor edx, ecx
- xor edx, eax
- add edx, [ebp+var_38]
- lea edx, [edx+esi-1924661Bh]
- rol edx, 0Bh
- add edx, eax
- mov esi, edx
- xor esi, ecx
- xor esi, eax
- add esi, [ebp+var_4]
- mov ebx, edx
- lea esi, [esi+edi+1FA27CF8h]
- mov edi, [ebp+var_40]
- rol esi, 10h
- add esi, edx
- xor ebx, esi
- xor ebx, eax
- add ebx, edi
- lea ecx, [ebx+ecx-3B53A99Bh]
- ror ecx, 9
- add ecx, esi
- mov ebx, edx
- not ebx
- or ebx, ecx
- xor ebx, esi
- add ebx, [ebp+var_30]
- lea eax, [ebx+eax-0BD6DDBCh]
- rol eax, 6
- add eax, ecx
- mov ebx, esi
- not ebx
- or ebx, eax
- xor ebx, ecx
- add ebx, [ebp+var_3C]
- lea edx, [ebx+edx+432AFF97h]
- rol edx, 0Ah
- add edx, eax
- mov ebx, ecx
- not ebx
- or ebx, edx
- xor ebx, eax
- add ebx, [ebp+var_28]
- lea esi, [ebx+esi-546BDC59h]
- rol esi, 0Fh
- add esi, edx
- mov ebx, eax
- not ebx
- or ebx, esi
- xor ebx, edx
- add ebx, [ebp+var_34]
- lea ecx, [ebx+ecx-36C5FC7h]
- ror ecx, 0Bh
- add ecx, esi
- mov ebx, edx
- not ebx
- or ebx, ecx
- xor ebx, esi
- add ebx, [ebp+var_38]
- lea eax, [ebx+eax+655B59C3h]
- rol eax, 6
- add eax, ecx
- mov ebx, esi
- not ebx
- or ebx, eax
- xor ebx, ecx
- add ebx, [ebp+var_1C]
- lea edx, [ebx+edx-70F3336Eh]
- rol edx, 0Ah
- add edx, eax
- mov ebx, ecx
- not ebx
- or ebx, edx
- xor ebx, eax
- add ebx, [ebp+var_24]
- lea esi, [ebx+esi-100B83h]
- rol esi, 0Fh
- add esi, edx
- mov ebx, eax
- not ebx
- or ebx, esi
- xor ebx, edx
- add ebx, [ebp+var_2C]
- lea ecx, [ebx+ecx-7A7BA22Fh]
- ror ecx, 0Bh
- add ecx, esi
- mov ebx, edx
- not ebx
- or ebx, ecx
- xor ebx, esi
- add ebx, [ebp+var_14]
- lea eax, [ebx+eax+6FA87E4Fh]
- rol eax, 6
- add eax, ecx
- mov ebx, esi
- not ebx
- or ebx, eax
- xor ebx, ecx
- add ebx, [ebp+var_4]
- lea edx, [ebx+edx-1D31920h]
- rol edx, 0Ah
- add edx, eax
- mov ebx, ecx
- not ebx
- or ebx, edx
- xor ebx, eax
- add ebx, [ebp+var_20]
- lea esi, [ebx+esi-5CFEBCECh]
- rol esi, 0Fh
- mov ebx, eax
- add esi, edx
- not ebx
- or ebx, esi
- xor ebx, edx
- add ebx, [ebp+var_8]
- lea ecx, [ebx+ecx+4E0811A1h]
- ror ecx, 0Bh
- add ecx, esi
- mov ebx, edx
- not ebx
- or ebx, ecx
- xor ebx, esi
- add ebx, [ebp+var_10]
- lea eax, [ebx+eax-8AC817Eh]
- rol eax, 6
- add eax, ecx
- mov ebx, esi
- not ebx
- or ebx, eax
- xor ebx, ecx
- add ebx, [ebp+var_18]
- lea edx, [ebx+edx-42C50DCBh]
- rol edx, 0Ah
- add edx, eax
- mov ebx, ecx
- not ebx
- or ebx, edx
- xor ebx, eax
- add ebx, edi
- lea esi, [ebx+esi+2AD7D2BBh]
- mov edi, eax
- not edi
- rol esi, 0Fh
- add esi, edx
- or edi, esi
- xor edi, edx
- add edi, [ebp+var_0C]
- lea edi, [edi+ecx-14792C6Fh]
- mov ecx, [ebp+DecryptBuffer]
- mov ebx, [ecx+8]
- add ebx, eax
- mov eax, [ecx+10h]
- ror edi, 0Bh
- add edi, [ecx+0Ch]
- add eax, esi
- add edi, esi
- mov [ecx+10h], eax
- mov eax, [ecx+14h]
- mov [ecx+0Ch], edi
- pop edi
- add eax, edx
- pop esi
- mov [ecx+8], ebx
- mov [ecx+14h], eax
- pop ebx
- mov esp, ebp
- pop ebp
- retn 4
-SFileDecryptMpqHeader endp
-
-; ---------------------------------------------------------------------------
-
-; ---------------------------------------------------------------------------
-
-sub_6D00E0 proc near ; CODE XREF: sub_6D0210+59p
- ; sub_6D0210+66p ...
-
-var_10 = dword ptr -10h
-pbMpqHeader = dword ptr -4
-pMpqHeader = dword ptr 8
-dwSize = dword ptr 0Ch
-
- push ebp
- mov ebp, esp
- push ecx
- mov eax, [ebp+pMpqHeader] ; EAX = MPQ Header
- push ebx
- mov ebx, [ebp+dwSize] ; EBX - size of MPQ Header
- push esi
- push edi
- mov esi, ecx ; ESI - decryption buffer (6 DWORDs)
- mov edi, [esi]
- shr edi, 3
- and edi, 3Fh
- mov [ebp+pbMpqHeader], eax
- lea ecx, ds:0[ebx*8] ; ECX = sizeof header * 8
- test ebx, ebx
- jbe loc_6D01F8
- add [esi], ecx
- mov edx, ebx ; EDX = size of header
- shr edx, 1Dh
- add [esi+4], edx
- mov edx, [esi+4]
- cmp [esi], ecx
- jnb short loc_6D011E
- inc edx
- mov [esi+4], edx
-
-loc_6D011E: ; CODE XREF: sub_6D00E0+38j
- test edi, edi
- jz short loc_6D0196
- lea eax, [edi+ebx]
- cmp eax, 40h
- jbe short loc_6D0136
- mov eax, 40h
- sub eax, edi
- mov [ebp+dwSize], eax
- jmp short loc_6D013B
-; ---------------------------------------------------------------------------
-
-loc_6D0136: ; CODE XREF: sub_6D00E0+48j
- mov [ebp+dwSize], ebx
- mov eax, ebx
-
-loc_6D013B: ; CODE XREF: sub_6D00E0+54j
- mov edx, [ebp+pMpqHeader]
- add edx, eax
- lea ecx, [edi+esi+18h]
- mov [ebp+pbMpqHeader], edx
- cmp ecx, edx
- jnb short loc_6D0163
- lea edx, [ecx+eax]
- mov ecx, [ebp+pMpqHeader]
- cmp edx, ecx
- jbe short loc_6D0166
- push eax
- push ecx
- lea eax, [edi+esi+18h]
- push eax
- call _memmove
- jmp short loc_6D0172
-; ---------------------------------------------------------------------------
-
-loc_6D0163: ; CODE XREF: sub_6D00E0+69j
- mov ecx, [ebp+pMpqHeader]
-
-loc_6D0166: ; CODE XREF: sub_6D00E0+73j
- push eax
- push ecx
- lea eax, [edi+esi+18h]
- push eax
- call _memcpy
-
-loc_6D0172: ; CODE XREF: sub_6D00E0+81j
- mov eax, [ebp+dwSize]
- lea ecx, [eax+edi]
- add esp, 0Ch
- cmp ecx, 40h
- jl short loc_6D01F8
- mov edx, [ebp+pbMpqHeader]
- sub ebx, eax
- lea eax, [esi+18h]
- push eax
- mov ecx, esi
- mov [ebp+pbMpqHeader], edx
- call SFileDecryptMpqHeader
- mov eax, [ebp+pbMpqHeader]
-
-loc_6D0196: ; CODE XREF: sub_6D00E0+40j
- cmp ebx, 40h
- jl short loc_6D01C4
- mov edi, ebx
- shr edi, 6
- mov ecx, edi
- neg ecx
- shl ecx, 6
- add ebx, ecx
- lea esp, [esp+0]
-
-loc_6D01B0: ; CODE XREF: sub_6D00E0+E2j
- push eax
- mov ecx, esi
- call SFileDecryptMpqHeader
- add [ebp+pbMpqHeader], 40h
- sub edi, 1
- mov eax, [ebp+pbMpqHeader]
- jnz short loc_6D01B0
-
-loc_6D01C4: ; CODE XREF: sub_6D00E0+B9j
- test ebx, ebx
- jz short loc_6D01F8
- add esi, 18h
- lea edx, [ebx+eax]
- cmp esi, edx
- jnb short loc_6D01ED
- lea ecx, [esi+ebx]
- cmp ecx, eax
- jbe short loc_6D01ED
- push ebx
- push eax
- push esi
- call _memmove
- add esp, 0Ch
- pop edi
- pop esi
- pop ebx
- mov esp, ebp
- pop ebp
- retn 8
-; ---------------------------------------------------------------------------
-
-loc_6D01ED: ; CODE XREF: sub_6D00E0+F0j
- ; sub_6D00E0+F7j
- push ebx
- push eax
- push esi
- call _memcpy
- add esp, 0Ch
-
-loc_6D01F8: ; CODE XREF: sub_6D00E0+23j
- ; sub_6D00E0+9Ej ...
- pop edi
- pop esi
- pop ebx
- mov esp, ebp
- pop ebp
- retn 8
-sub_6D00E0 endp
-
-aA_1: ; DATA XREF: sub_6249D0+68o
- ; sub_6D0210+4Fo ...
- dw 80h, 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
- db 0
-
-sub_6D0210 proc near ; CODE XREF: SFileVerifyMpqHeaderMD5+42p
- ; sub_6D2D60+A9p ...
-
-var_8 = byte ptr -8
-var_6 = byte ptr -6
-var_5 = byte ptr -5
-var_4 = byte ptr -4
-var_3 = byte ptr -3
-var_2 = byte ptr -2
-var_1 = byte ptr -1
-arg_0 = dword ptr 8
-
- push ebp
- mov ebp, esp
- sub esp, 8
- push esi
- mov esi, ecx ; Source address
- mov eax, [esi]
- mov ecx, eax
- shr ecx, 8
- mov [ebp-7], cl
- mov ecx, eax
- shr ecx, 18h
- mov [ebp+var_5], cl
- mov ecx, [esi+4]
- mov edx, eax
- shr edx, 10h
- mov [ebp+var_6], dl
- mov edx, ecx
- mov [ebp+var_4], cl
- shr edx, 8
- mov [ebp+var_3], dl
- mov edx, ecx
- shr ecx, 18h
- mov [ebp+var_1], cl
- mov [ebp+var_8], al
- shr eax, 3
- mov ecx, 0FFFFFFF7h
- sub ecx, eax
- and ecx, 3Fh
- push edi
- inc ecx
- push ecx
- shr edx, 10h
- push offset aA_1 ; ""
- mov ecx, esi
- mov [ebp+var_2], dl
- call sub_6D00E0
- push 8
- lea edx, [ebp+var_8]
- push edx
- mov ecx, esi
- call sub_6D00E0
- mov edi, [ebp+arg_0]
- xor eax, eax
-
-loc_6D0280: ; CODE XREF: sub_6D0210+8Ej
- mov ecx, eax
- and ecx, 3
- add ecx, ecx
- mov edx, eax
- sar edx, 2
- mov edx, [esi+edx*4+8]
- add ecx, ecx
- add ecx, ecx
- shr edx, cl
- inc eax
- cmp eax, 10h
- mov [eax+edi-1], dl
- jl short loc_6D0280
- pop edi
- pop esi
- mov esp, ebp
- pop ebp
- retn 4
-sub_6D0210 endp
-
-
-sub_6CEBE0 proc near ; CODE XREF: sub_4A72D0+49p
- ; SFileVerifyMpqHeaderMD5+51p ...
-
-var_4 = dword ptr -4
-arg_0 = dword ptr 8
-
- push ebp
- mov ebp, esp
- mov edx, [ebp+arg_0]
- mov eax, 10h
- push esi
- lea esp, [esp+0]
-
-loc_6CEBF0: ; CODE XREF: sub_6CEBE0+22j
- mov esi, [ecx]
- cmp esi, [edx]
- jnz short loc_6CEC14
- sub eax, 4
- add edx, 4
- add ecx, 4
- cmp eax, 4
- jnb short loc_6CEBF0
- xor eax, eax
- xor edx, edx
- test eax, eax
- setz dl
- mov al, dl
- pop esi
- pop ebp
- retn 4
-; ---------------------------------------------------------------------------
-
-loc_6CEC14: ; CODE XREF: sub_6CEBE0+14j
- movzx eax, byte ptr [ecx]
- movzx esi, byte ptr [edx]
- sub eax, esi
- jnz short loc_6CEC40
- movzx eax, byte ptr [ecx+1]
- movzx esi, byte ptr [edx+1]
- sub eax, esi
- jnz short loc_6CEC40
- movzx eax, byte ptr [ecx+2]
- movzx esi, byte ptr [edx+2]
- sub eax, esi
- jnz short loc_6CEC40
- movzx eax, byte ptr [ecx+3]
- movzx ecx, byte ptr [edx+3]
- sub eax, ecx
-
-loc_6CEC40: ; CODE XREF: sub_6CEBE0+3Cj
- ; sub_6CEBE0+48j ...
- sar eax, 1Fh
- or eax, 1
- xor edx, edx
- test eax, eax
- setz dl
- mov al, dl
- pop esi
- pop ebp
- retn 4
-sub_6CEBE0 endp
-
-SFileVerifyMpqHeaderMD5 proc near ; CODE XREF: SFileVerifyMpqHeader+6Bp
-
-var_68 = dword ptr -68h
-var_64 = dword ptr -64h
-var_60 = dword ptr -60h
-var_5C = dword ptr -5Ch
-var_58 = dword ptr -58h
-var_54 = dword ptr -54h
-var_10 = dword ptr -10h
-
- push ebp
- mov ebp, esp
- sub esp, 68h
- push esi
- mov esi, eax ; ESI = pointer to MPQ Header
- xor eax, eax
- push 0C0h
- push esi
- lea ecx, [ebp+var_68]
- mov [ebp+var_64], eax
- mov [ebp+var_68], eax
- mov [ebp+var_60], 67452301h
- mov [ebp+var_5C], 0EFCDAB89h
- mov [ebp+var_58], 98BADCFEh
- mov [ebp+var_54], 10325476h
- call sub_6D00E0
- lea eax, [ebp+var_10]
- push eax
- lea ecx, [ebp+var_68]
- call sub_6D0210
- add esi, 0C0h
- push esi
- lea ecx, [ebp+var_10]
- call sub_6CEBE0
- pop esi
- mov esp, ebp
- pop ebp
- retn
-SFileVerifyMpqHeaderMD5 endp
-
-
-_wow_SFileVerifyMpqHeaderMD5 proc
- push ebp
- mov ebp, esp
- mov eax, [ebp+8]
- call SFileVerifyMpqHeaderMD5
- mov esp, ebp
- pop ebp
- retn
-_wow_SFileVerifyMpqHeaderMD5 endp
-
-END
diff --git a/dep/StormLib/test/x86_starcraft_lzma.asm b/dep/StormLib/test/x86_starcraft_lzma.asm
deleted file mode 100644
index bb13200b432..00000000000
--- a/dep/StormLib/test/x86_starcraft_lzma.asm
+++ /dev/null
@@ -1,11066 +0,0 @@
-;
-; LZMA compression code ripped from Starctaft II BEta
-; Used while StormLib's LZMA implementation was tested against Starcraft compression
-; Not used in StormLib.
-;
-
-.686P
-.MODEL FLAT
-ASSUME FS: NOTHING
-
-.DATA
-
-;---------------------------------------------------------------------------
-; Data
-
-byte_4CB248 db 0, 0Bh, 0Bh, 0Bh ; indirect table for switch statement
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 1, 2, 3, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 4, 5, 6, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 7, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 8, 9, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Bh, 0Bh, 0Bh, 0Bh
- db 0Ah
- align 10h
-
-dword_544960 dd 0BB40E64Eh ; DATA XREF: sub_401C72+B
-dword_553598 dd ? ; DATA XREF: sub_4CB8A0+9
-
-off_50CD3C dd offset sub_4A0605 ; DATA XREF: sub_4A05F7+1o
- ; .data:off_52A004o ...
-dword_50CD40 dd 0E06D7363h ; DATA XREF: _CxxThrowException(x,x)+Eo
- dd 1
- dd 0
- dd 0
- dd 3
- dd 19930520h
- dd 0
- dd 0
-
-; ---------------------------------------------------------------------------
-
-off_546E20 dd offset sub_4CDD70 ; DATA XREF: sub_4D0270:loc_4D0324o
-off_546E24 dd offset sub_4CDD90 ; DATA XREF: sub_4CF810+53r
-off_546E28 dd offset off_50CD3C ; DATA XREF: .rdata:off_51B888o
- dd 0
- db '.?AUISequentialInStream@@',0
- db 0
- db 0
-off_546E4C dd offset off_50CD3C ; DATA XREF: .rdata:off_51B8C0o
- dd 0
- db '.?AUISequentialOutStream@@',0
- db 0
-off_546E70 dd offset off_50CD3C ; DATA XREF: .rdata:off_51B8F8o
- dd 0
- db '.?AUICompressCoder@@',0
- db 0
- db 0
- db 0
-off_546E90 dd offset off_50CD3C ; DATA XREF: .rdata:off_51B944o
- dd 0
- db '.?AUICompressSetOutStream@@',0
-off_546EB4 dd offset off_50CD3C ; DATA XREF: .rdata:0051B96Co
- dd 0
- db '.?AUICompressSetCoderProperties@@',0
- db 0
- db 0
-off_546EE0 dd offset off_50CD3C ; DATA XREF: .rdata:0051B9B8o
- dd 0
- db '.?AUICompressWriteCoderProperties@@',0
- dd offset off_50CD3C
- dd 0
- db '.?AUCSystemException@@',0
- db 0
- dd offset off_50CD3C
- dd 0
- db '.?AUCOutBufferException@@',0
- db 0
- db 0
-off_546F50 dd offset off_50CD3C ; DATA XREF: .rdata:0051BA04o
- dd 0
- db '.?AVCInStreamMemory@@',0
- db 0
- db 0
-off_546F70 dd offset off_50CD3C ; DATA XREF: .rdata:off_51BA4Co
- dd 0
- db '.?AVCMyUnknownImp@@',0
-off_546F8C dd offset off_50CD3C ; DATA XREF: .rdata:0051BAA8o
- dd 0
- db '.?AVCOutStreamMemory@@',0
- db 0
-off_546FAC dd offset off_50CD3C ; DATA XREF: .rdata:0051BAFCo
- dd 0
- db '.?AVCEncoder@NLZMA@NCompress@@',0
- db 0
-off_546FD4 dd offset off_50CD3C ; DATA XREF: .rdata:off_51BBECo
- dd 0
- db '.?AVCBaseState@NLZMA@NCompress@@',0
- db 0
- db 0
- db 0
-
-; ---------------------------------------------------------------------------
-
-dword_51B960 dd 0 ; DATA XREF: .rdata:00517A64o
- dd 0
- dd 0
- dd offset off_546EB4
- dd 0 ; offset dword_51B974
-
-dword_51B9AC dd 0 ; DATA XREF: .rdata:00517A78o
- dd 0
- dd 0
- dd offset off_546EE0
- dd 0 ;offset dword_51B9C0
-
-dword_51B9F8 dd 0 ; DATA XREF: .rdata:00517A8Co
- dd 0
- dd 0
- dd offset off_546F50
- dd 0 ; offset dword_51BA0C
-
-dword_51BA9C dd 0 ; DATA XREF: .rdata:00517AA0o
- dd 0
- dd 0
- dd offset off_546F8C
- dd 0 ; offset dword_51BAB0
-
-dword_51BAF0 dd 0 ; DATA XREF: .rdata:00517AF8o
- dd 0
- dd 0
- dd offset off_546FAC
- dd 0 ; offset dword_51BB04
-
-dword_51BC58 dd 0 ; DATA XREF: .rdata:00517AE0o
- dd 4
- dd 0
- dd offset off_546FAC
- dd 0 ; offset dword_51BB04
-
-dword_51BC6C dd 0 ; DATA XREF: .rdata:00517ACCo
- dd 8
- dd 0
- dd offset off_546FAC
- dd 0 ; offset dword_51BB04
-
-dword_51BC80 dd 0 ; DATA XREF: .rdata:00517AB8o
- dd 0Ch
- dd 0
- dd offset off_546FAC
- dd 0 ; offset dword_51BB04
-
-; ---------------------------------------------------------------------------
-
-dword_512730 dd 0 ; DATA XREF: sub_48DB4D+B9o
-dword_512734 dd 0 ; DATA XREF: CCmdTarget::GetInterface(void const *)+2Dr
-dword_512738 dd 0C0h ; DATA XREF: CCmdTarget::GetInterface(void const *)+38r
-dword_51273C dd 46000000h ; DATA XREF: CCmdTarget::GetInterface(void const *)+43r
-
-dword_5535A0 dd ? ; DATA XREF: sub_4CF900:loc_4CF94Co
-dword_5535A4 dd ? ; DATA XREF: .text:004DAF37w
-dword_5535A8 dd ? ; DATA XREF: .text:004DAF3Cw
-dword_5535AC dd ? ; DATA XREF: .text:004DAF41w
-
-dword_5535B0 dd ? ; DATA XREF: sub_4CF900+5Eo
-dword_5535B4 dd ? ; DATA XREF: .text:004DAF17w
-dword_5535B8 dd ? ; DATA XREF: .text:004DAF1Cw
-dword_5535BC dd ? ; DATA XREF: .text:004DAF21w
-
-dword_5535C0 dd ? ; DATA XREF: sub_4CF900:loc_4CF98Fo
-dword_5535C4 dd ? ; DATA XREF: .text:004DAEF7w
-dword_5535C8 dd ? ; DATA XREF: .text:004DAEFCw
-dword_5535CC dd ? ; DATA XREF: .text:004DAF01w
-
-
-dword_526DD0 dd 0 ; DATA XREF: .text:loc_4CF6CBo
- dd 0
- dd 0
- dd 0 ; offset dword_526DE0
-
-kLiteralNextStates db 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5
-kMatchNextStates db 7, 7, 7, 7, 7, 7, 7, 0Ah, 0Ah, 0Ah, 0Ah, 0Ah
-kRepNextStates db 8, 8, 8, 8, 8, 8, 8, 0Bh, 0Bh, 0Bh, 0Bh, 0Bh
-kShortRepNextStates db 9, 9, 9, 9, 9, 9, 9, 0Bh, 0Bh, 0Bh, 0Bh, 0Bh
-
-dword_550998 dd 200h dup(?)
-dword_551198 dd 800h dup(?)
-dword_553198 dd 100h dup(?)
-
-ICompressSetOutStream_vftable dd offset __purecall ; DATA XREF: NCompress_NLZMA_CEncoder_CEncoder+2o
- dd offset __purecall
- dd offset __purecall
- dd offset __purecall
- dd offset __purecall
- dd offset dword_51B960
-ICompressSetCoderProperties_vftable dd offset __purecall ; DATA XREF: NCompress_NLZMA_CEncoder_CEncoder+9o
- dd offset __purecall
- dd offset __purecall
- dd offset __purecall
- dd offset dword_51B9AC
-ICompressWriteCoderProperties_vftable dd offset __purecall ; DATA XREF: NCompress_NLZMA_CEncoder_CEncoder+10o
- dd offset __purecall
- dd offset __purecall
- dd offset __purecall
- dd offset dword_51B9F8
-off_517A90 dd offset Interface1_QueryInterface
- dd offset Interface1_AddRef
- dd offset Interface1_Release
- dd offset sub_4CCB20
- dd offset dword_51BA9C
-off_517AA4 dd offset Interface1_QueryInterface ; DATA XREF: sub_4CF610+Eo
- dd offset Interface1_AddRef
- dd offset Interface2_Release
- dd offset sub_4CCB90
- dd offset sub_4CF590
- dd offset dword_51BC80
-NCompress_NLZMA_CEncoder_vftable_ICompressWriteCoderProperties dd offset sub_4CFA50 ; DATA XREF: sub_4CF810+3Do
- dd offset sub_4CFA10
- dd offset sub_4CFA70
- dd offset sub_4CDDB0
- dd offset dword_51BC6C
-NCompress_NLZMA_CEncoder_vftable_ICompressSetCoderProperties dd offset ICompressSetCoderProperties_QueryInterface ; DATA XREF: sub_4CF810+36o
- dd offset ICompressSetCoderProperties_AddRef
- dd offset ICompressSetCoderProperties_Release
- dd offset ICompressSetCoderProperties_SetCoderProperties
- dd offset dword_51BC58
-NCompress_NLZMA_CEncoder_vftable_ICompressSetOutStream dd offset sub_4CFA20 ; DATA XREF: sub_4CF810+2Fo
- dd offset sub_4CFA80
- dd offset sub_4CFA40
- dd offset sub_4CFA90
- dd offset sub_4CDE70
- dd offset dword_51BAF0
-NCompress_NLZMA_CEncoder_vftable dd offset sub_4CF900 ; DATA XREF: sub_4CF810+29o
- dd offset sub_4CF9D0
- dd offset sub_4CF9E0
- dd offset CEncoder_Code
- dd offset sub_4D0250
-
-.CODE
-
-extrn _operator_new:PROC
-extrn __allshr: PROC
-extrn _free: PROC
-extrn _memcmp: PROC
-extrn _memcpy: PROC
-extrn _memset: PROC
-extrn ___report_gsfailure: PROC
-extrn __purecall: PROC
-VirtualAlloc PROTO STDCALL :DWORD,:DWORD,:DWORD,:DWORD
-VirtualFree PROTO STDCALL :DWORD,:DWORD,:DWORD
-
-; ---------------------------------------------------------------------------
-
-; void __cdecl j__free(void *Memory)
-; 004843B8
-j__free proc near ; CODE XREF: sub_401048+16p
- ; .text:004010CFp ...
- jmp _free
-j__free endp
-
-
-; ---------------------------------------------------------------------------
-
-; int __cdecl unknown_libname_324(void *Buf1, void *Buf2)
-unknown_libname_324 proc near
-; sub_48B7BA
-
-Buf1 = dword ptr 4
-Buf2 = dword ptr 8
-
- push 10h ; Size
- push [esp+4+Buf2] ; Buf2
- push [esp+8+Buf1] ; Buf1
- call _memcmp
- add esp, 0Ch
- neg eax
- sbb eax, eax
- inc eax
- retn
-unknown_libname_324 endp
-
-; ---------------------------------------------------------------------------
-
-sub_4A05F7 proc near ; CODE XREF: sub_4A0605+3p
- push ecx
- mov dword ptr [ecx], offset off_50CD3C
- call sub_4A98B8
- pop ecx
- retn
-sub_4A05F7 endp
-
-; ---------------------------------------------------------------------------
-
-; int __thiscall sub_4A0605(void *Memory, char)
-sub_4A0605 proc near ; DATA XREF: .rdata:off_50CD3Co
-
-arg_0 = byte ptr 4
-
- push esi
- mov esi, ecx
- call sub_4A05F7
- test [esp+4+arg_0], 1
- jz short loc_4A061B
- push esi ; Memory
- call j__free
- pop ecx
-
-loc_4A061B: ; CODE XREF: sub_4A0605+Dj
- mov eax, esi
- pop esi
- retn 4
-sub_4A0605 endp
-
-; ---------------------------------------------------------------------------
-
-sub_4A0686 proc near ; CODE XREF: sub_401C72+49p
- ; sub_40222F+15Cp ...
- cmp ecx, dword_544960
- jnz short loc_4A0690
- retn
-loc_4A0690: ; CODE XREF: sub_4A0686+6j
- jmp ___report_gsfailure
-sub_4A0686 endp
-
-; ---------------------------------------------------------------------------
-
-sub_4A98B8 proc near ; CODE XREF: sub_4A05F7+7p
-
- int 3
- retn
-sub_4A98B8 endp
-
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CAEC0 proc near ; CODE XREF: CEncoder_GetOptimum+514p
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-arg_8 = dword ptr 0Ch
-
- push esi
- push edi
- mov edi, [esp+8+arg_4]
- lea eax, [edi-2]
- cmp eax, 4
- mov esi, ecx
- jb short loc_4CAED5
- mov eax, 3
-
-loc_4CAED5: ; CODE XREF: sub_4CAEC0+Ej
- mov edx, [esp+8+arg_0]
- cmp edx, 80h
- jnb short loc_4CAEEF
- shl eax, 7
- add eax, edx
- mov ecx, [esi+eax*4+33314h]
- jmp short loc_4CAF25
-; ---------------------------------------------------------------------------
-
-loc_4CAEEF: ; CODE XREF: sub_4CAEC0+1Fj
- mov ecx, 7FFFFh
- sub ecx, edx
- sar ecx, 1Fh
- push ebx
- and ecx, 0Ch
- add ecx, 6
- mov ebx, edx
- shr ebx, cl
- shl eax, 5
- add eax, ecx
- and edx, 0Fh
- movzx ebx, byte ptr dword_551198[ebx]
- lea eax, [ebx+eax*2]
- mov ecx, [esi+eax*4+32F14h]
- add ecx, [esi+edx*4+33B14h]
- pop ebx
-
-loc_4CAF25: ; CODE XREF: sub_4CAEC0+2Dj
- mov edx, [esp+8+arg_8]
- imul edx, 110h
- add edx, edi
- mov eax, [esi+edx*4+295B8h]
- pop edi
- add eax, ecx
- pop esi
- retn 0Ch
-sub_4CAEC0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CAF40: ; CODE XREF: .text:004DAED5j
- push ecx
- push ebx
- push ebp
- push esi
- mov ebp, 2
- mov bl, 2
- push edi
- mov byte ptr dword_551198, 0
- mov byte ptr dword_551198+1, 1
- mov [esp+10h], bl
- mov edi, ebp
-
-loc_4CAF60: ; CODE XREF: .text:004CAF96j
- mov ecx, edi
- shr ecx, 1
- sub ecx, 1
- mov esi, 1
- shl esi, cl
- test esi, esi
- jbe short loc_4CAF89
- mov ecx, [esp+10h]
- push esi
- lea eax, dword_551198[ebp]
- push ecx
- push eax
- call _memset
- add esp, 0Ch
- add ebp, esi
-
-loc_4CAF89: ; CODE XREF: .text:004CAF70j
- add bl, 1
- add edi, 1
- cmp bl, 1Ah
- mov [esp+10h], bl
- jb short loc_4CAF60
- pop edi
- pop esi
- pop ebp
- pop ebx
- pop ecx
- retn
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CAFA0 proc near ; CODE XREF: sub_4CAFC0+90p
-
-arg_0 = dword ptr 4
-
- mov eax, [esp+arg_0]
- lea ecx, [eax-61h]
- cmp cx, 19h
- ja short locret_4CAFB2
- add eax, 0FFE0h
-
-locret_4CAFB2: ; CODE XREF: sub_4CAFA0+Bj
- retn
-sub_4CAFA0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-; =============== S U B R O U T I N E =======================================
-
-sub_4CAFC0 proc near ; CODE XREF: ICompressSetCoderProperties_SetCoderProperties+A5p
- movzx ecx, word ptr [eax]
- lea edx, [ecx-61h]
- cmp dx, 19h
- ja short loc_4CAFD2
- add ecx, 0FFE0h
-
-loc_4CAFD2: ; CODE XREF: sub_4CAFC0+Aj
- add eax, 2
- cmp cx, 48h
- jnz short loc_4CB01B
- movzx ecx, word ptr [eax]
- lea edx, [ecx-61h]
- cmp dx, 19h
- ja short loc_4CAFED
- add ecx, 0FFE0h
-
-loc_4CAFED: ; CODE XREF: sub_4CAFC0+25j
- add eax, 2
- cmp cx, 43h
- jz short loc_4CAFF9
-
-loc_4CAFF6: ; CODE XREF: sub_4CAFC0+44j
- ; sub_4CAFC0+4Bj ...
- xor eax, eax
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CAFF9: ; CODE XREF: sub_4CAFC0+34j
- movzx ecx, word ptr [eax]
- sub ecx, 30h
- lea edx, [ecx-4]
- test edx, edx
- ja short loc_4CAFF6
- cmp word ptr [eax+2], 0
- jnz short loc_4CAFF6
- mov dword ptr [ebx], 0
- mov [edi], ecx
- mov eax, 1
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CB01B: ; CODE XREF: sub_4CAFC0+19j
- cmp cx, 42h
- jnz short loc_4CAFF6
- movzx ecx, word ptr [eax]
- lea edx, [ecx-61h]
- cmp dx, 19h
- ja short loc_4CB033
- add ecx, 0FFE0h
-
-loc_4CB033: ; CODE XREF: sub_4CAFC0+6Bj
- add eax, 2
- cmp cx, 54h
- jnz short loc_4CAFF6
- push esi
- movzx esi, word ptr [eax]
- sub esi, 30h
- lea ecx, [esi-2]
- cmp ecx, 2
- ja short loc_4CB06C
- movzx eax, word ptr [eax+2]
- push eax
- call sub_4CAFA0
- add esp, 4
- test ax, ax
- jnz short loc_4CB06C
- mov dword ptr [ebx], 1
- mov [edi], esi
- mov eax, 1
- pop esi
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CB06C: ; CODE XREF: sub_4CAFC0+89j
- ; sub_4CAFC0+9Bj
- xor eax, eax
- pop esi
- retn
-sub_4CAFC0 endp
-
-
-ICompressSetCoderProperties_SetCoderProperties proc near ; DATA XREF: .rdata:00517ADCo
-
-var_4 = dword ptr -4
-pThis = dword ptr 4
-propIDs = dword ptr 8
-properties = dword ptr 0Ch
-numProperties = dword ptr 10h
-
- push ecx
- push ebx
- push ebp
- xor edx, edx
- cmp [esp+0Ch+numProperties], edx
- push esi
- push edi
- mov [esp+14h+var_4], edx
- jbe loc_4CB20D
- mov esi, [esp+14h+properties]
- mov ebp, [esp+14h+pThis]
- lea ecx, [ecx+0]
-
-loc_4CB090: ; CODE XREF: sub_4CB070+197j
- mov eax, [esp+14h+propIDs]
- mov eax, [eax+edx*4]
- add eax, 0FFFFFC00h
- cmp eax, 90h ; switch 145 cases
- ja loc_4CB131 ; default
- ; jumptable 004CB0AE cases 1-63,67-79,83-111,113-127,130-143
- movzx ecx, ds:byte_4CB248[eax]
- jmp ds:off_4CB218[ecx*4] ; switch jump
-
-loc_4CB0B5: ; DATA XREF: .text:off_4CB218o
- cmp word ptr [esi], 13h ; jumptable 004CB0AE case 80
- jnz short loc_4CB131 ; default
- ; jumptable 004CB0AE cases 1-63,67-79,83-111,113-127,130-143
- mov eax, [esi+8]
- lea ecx, [eax-5]
- cmp ecx, 10Ch
- ja short loc_4CB131 ; default
- ; jumptable 004CB0AE cases 1-63,67-79,83-111,113-127,130-143
- mov [ebp+32EF0h], eax
- jmp loc_4CB1F9
-; ---------------------------------------------------------------------------
-
-loc_4CB0D4: ; CODE XREF: sub_4CB070+3Ej
- ; DATA XREF: .text:off_4CB218o
- cmp word ptr [esi], 13h ; jumptable 004CB0AE case 82
- jnz short loc_4CB131 ; default
- ; jumptable 004CB0AE cases 1-63,67-79,83-111,113-127,130-143
- mov eax, [esi+8]
- mov [ebp+33B88h], eax
- jmp loc_4CB1F9
-; ---------------------------------------------------------------------------
-
-loc_4CB0E8: ; CODE XREF: sub_4CB070+3Ej
- ; DATA XREF: .text:off_4CB218o
- cmp word ptr [esi], 13h ; jumptable 004CB0AE case 112
- jnz short loc_4CB131 ; default
- ; jumptable 004CB0AE cases 1-63,67-79,83-111,113-127,130-143
- cmp dword ptr [esi+8], 0
- setz cl
- mov [ebp+32EECh], cl
- jmp loc_4CB1F9
-; ---------------------------------------------------------------------------
-
-loc_4CB100: ; CODE XREF: sub_4CB070+3Ej
- ; DATA XREF: .text:off_4CB218o
- cmp word ptr [esi], 8 ; jumptable 004CB0AE case 81
- jnz short loc_4CB131 ; default
- ; jumptable 004CB0AE cases 1-63,67-79,83-111,113-127,130-143
- mov eax, [esi+8]
- lea edi, [ebp+0C4h]
- lea ebx, [ebp+0CCh]
- call sub_4CAFC0
- test eax, eax
- jz short loc_4CB131 ; default
- ; jumptable 004CB0AE cases 1-63,67-79,83-111,113-127,130-143
- mov edx, [esp+14h+var_4]
- jmp loc_4CB1F9
-; ---------------------------------------------------------------------------
-
-loc_4CB127: ; CODE XREF: sub_4CB070+3Ej
- ; DATA XREF: .text:off_4CB218o
- cmp word ptr [esi], 0Bh ; jumptable 004CB0AE case 128
- jz loc_4CB1F9
-
-loc_4CB131: ; CODE XREF: sub_4CB070+31j
- ; sub_4CB070+3Ej ...
- pop edi ; default
- ; jumptable 004CB0AE cases 1-63,67-79,83-111,113-127,130-143
- pop esi
- pop ebp
- mov eax, 80070057h
- pop ebx
- pop ecx
- retn 10h
-; ---------------------------------------------------------------------------
-
-loc_4CB13E: ; CODE XREF: sub_4CB070+3Ej
- ; DATA XREF: .text:off_4CB218o
- cmp word ptr [esi], 13h ; jumptable 004CB0AE case 129
- jnz short loc_4CB131 ; default
- ; jumptable 004CB0AE cases 1-63,67-79,83-111,113-127,130-143
- jmp loc_4CB1F9
-; ---------------------------------------------------------------------------
-
-loc_4CB149: ; CODE XREF: sub_4CB070+3Ej
- ; DATA XREF: .text:off_4CB218o
- cmp word ptr [esi], 13h ; jumptable 004CB0AE case 0
- jnz short loc_4CB131 ; default
- ; jumptable 004CB0AE cases 1-63,67-79,83-111,113-127,130-143
- mov eax, [esi+8]
- lea ecx, [eax-1]
- cmp ecx, 3FFFFFFFh
- ja short loc_4CB131 ; default
- ; jumptable 004CB0AE cases 1-63,67-79,83-111,113-127,130-143
- mov [ebp+33B64h], eax
- xor ecx, ecx
-
-loc_4CB165: ; CODE XREF: sub_4CB070+106j
- mov edi, 1
- shl edi, cl
- cmp eax, edi
- jbe short loc_4CB178
- add ecx, 1
- cmp ecx, 1Eh
- jb short loc_4CB165
-
-loc_4CB178: ; CODE XREF: sub_4CB070+FEj
- lea eax, [ecx+ecx]
- mov [ebp+33B50h], eax
- jmp short loc_4CB1F9
-; ---------------------------------------------------------------------------
-
-loc_4CB183: ; CODE XREF: sub_4CB070+3Ej
- ; DATA XREF: .text:off_4CB218o
- cmp word ptr [esi], 13h ; jumptable 004CB0AE case 64
- jnz short loc_4CB131 ; default
- ; jumptable 004CB0AE cases 1-63,67-79,83-111,113-127,130-143
- mov ecx, [esi+8]
- cmp ecx, 4
- ja short loc_4CB131 ; default
- ; jumptable 004CB0AE cases 1-63,67-79,83-111,113-127,130-143
- mov eax, 1
- shl eax, cl
- mov [ebp+33B54h], ecx
- sub eax, 1
- mov [ebp+33B58h], eax
- jmp short loc_4CB1F9
-; ---------------------------------------------------------------------------
-
-loc_4CB1A9: ; CODE XREF: sub_4CB070+3Ej
- ; DATA XREF: .text:off_4CB218o
- cmp word ptr [esi], 13h ; jumptable 004CB0AE case 66
- jnz short loc_4CB131 ; default
- ; jumptable 004CB0AE cases 1-63,67-79,83-111,113-127,130-143
- mov eax, [esi+8]
- cmp eax, 4
- ja loc_4CB131 ; default
- ; jumptable 004CB0AE cases 1-63,67-79,83-111,113-127,130-143
- mov [ebp+33B5Ch], eax
- jmp short loc_4CB1F9
-; ---------------------------------------------------------------------------
-
-loc_4CB1C3: ; CODE XREF: sub_4CB070+3Ej
- ; DATA XREF: .text:off_4CB218o
- cmp word ptr [esi], 13h ; jumptable 004CB0AE case 65
- jnz loc_4CB131 ; default
- ; jumptable 004CB0AE cases 1-63,67-79,83-111,113-127,130-143
- mov eax, [esi+8]
- cmp eax, 8
- ja loc_4CB131 ; default
- ; jumptable 004CB0AE cases 1-63,67-79,83-111,113-127,130-143
- mov [ebp+33B60h], eax
- jmp short loc_4CB1F9
-; ---------------------------------------------------------------------------
-
-loc_4CB1E1: ; CODE XREF: sub_4CB070+3Ej
- ; DATA XREF: .text:off_4CB218o
- cmp word ptr [esi], 0Bh ; jumptable 004CB0AE case 144
- jnz loc_4CB131 ; default
- ; jumptable 004CB0AE cases 1-63,67-79,83-111,113-127,130-143
- cmp word ptr [esi+8], 0FFFFh
- setz cl
- mov [ebp+33B8Ch], cl
-
-loc_4CB1F9: ; CODE XREF: sub_4CB070+5Fj
- ; sub_4CB070+73j ...
- add edx, 1
- add esi, 10h
- cmp edx, [esp+14h+numProperties]
- mov [esp+14h+var_4], edx
- jb loc_4CB090
-
-loc_4CB20D: ; CODE XREF: sub_4CB070+Fj
- pop edi
- pop esi
- pop ebp
- xor eax, eax
- pop ebx
- pop ecx
- retn 10h
-
-off_4CB218 dd offset loc_4CB149, offset loc_4CB183, offset loc_4CB1C3
- dd offset loc_4CB1A9, offset loc_4CB0B5, offset loc_4CB100 ; jump table for switch statement
- dd offset loc_4CB0D4, offset loc_4CB0E8, offset loc_4CB127
- dd offset loc_4CB13E, offset loc_4CB1E1, offset loc_4CB131
-
-ICompressSetCoderProperties_SetCoderProperties endp
-
-; =============== S U B R O U T I N E =======================================
-
-sub_4CB2E0 proc near ; CODE XREF: CEncoder_GetOptimum+1199p
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- push ebx
- push ebp
- push esi
- mov esi, [esp+0Ch+arg_4]
- lea eax, [esi+esi*4]
- lea edx, [ecx+eax*8]
- mov [ecx+32F08h], esi
- mov eax, [edx+100h]
- mov ebx, [edx+104h]
- push edi
-
-loc_4CB300: ; CODE XREF: sub_4CB2E0+A6j
- lea edx, [esi+esi*4]
- cmp byte ptr [ecx+edx*8+0F1h], 0
- lea edi, [ecx+edx*8]
- jz short loc_4CB359
- lea edx, [eax+eax*4+1Eh]
- lea edx, [ecx+edx*8]
- mov dword ptr [edx+14h], 0FFFFFFFFh
- mov byte ptr [edx+1], 0
- lea edx, [eax+eax*4]
- lea edx, [ecx+edx*8]
- lea ebp, [eax-1]
- mov [edx+100h], ebp
- cmp byte ptr [edi+0F2h], 0
- jz short loc_4CB359
- mov byte ptr [edx+0C9h], 0
- mov ebp, [edi+0F4h]
- mov [edx+0D8h], ebp
- mov edi, [edi+0F8h]
- mov [edx+0DCh], edi
-
-loc_4CB359: ; CODE XREF: sub_4CB2E0+2Ej
- ; sub_4CB2E0+58j
- lea edx, [eax+eax*4]
- add edx, edx
- add edx, edx
- add edx, edx
- mov edi, eax
- test edi, edi
- mov eax, [edx+ecx+100h]
- mov ebp, ebx
- mov ebx, [edx+ecx+104h]
- mov [edx+ecx+100h], esi
- mov [edx+ecx+104h], ebp
- mov esi, edi
- jnz loc_4CB300
- mov eax, [ecx+104h]
- mov edx, [esp+10h+arg_0]
- pop edi
- pop esi
- mov [edx], eax
- mov eax, [ecx+100h]
- pop ebp
- mov [ecx+32F0Ch], eax
- pop ebx
- retn 8
-sub_4CB2E0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CB3B0 proc near ; CODE XREF: CEncoder_GetOptimumFast+2Dp
- ; CEncoder_GetOptimumFast+28Fp ...
-
-arg_0 = dword ptr 4
-
- push ebx
- push ebp
- push esi
- mov esi, ecx
- mov ecx, [esi+80h]
- mov edx, [esi+78h]
- lea eax, [esi+32660h]
- push eax
- push ecx
- xor ebx, ebx
- call edx
- mov ebp, [esp+14h+arg_0]
- add esp, 8
- test eax, eax
- mov [ebp+0], eax
- jbe short loc_4CB446
- mov ebx, [esi+eax*4+32658h]
- cmp ebx, [esi+32EF8h]
- jnz short loc_4CB446
- mov eax, [esi+80h]
- mov ecx, [esi+70h]
- push edi
- push eax
- call ecx
- mov edx, [esi+80h]
- mov edi, eax
- mov eax, [esi+74h]
- push edx
- add edi, 1
- call eax
- mov ecx, [ebp+0]
- mov ecx, [esi+ecx*4+3265Ch]
- add esp, 8
- sub eax, 1
- add ecx, 1
- cmp edi, 111h
- jbe short loc_4CB425
- mov edi, 111h
-
-loc_4CB425: ; CODE XREF: sub_4CB3B0+6Ej
- mov edx, eax
- sub edx, ecx
- cmp ebx, edi
- jnb short loc_4CB445
- mov ebp, edx
- lea ecx, [eax+ebx]
- sub ebp, eax
-
-loc_4CB434: ; CODE XREF: sub_4CB3B0+93j
- mov dl, [ecx]
- cmp dl, [ecx+ebp]
- jnz short loc_4CB445
- add ebx, 1
- add ecx, 1
- cmp ebx, edi
- jb short loc_4CB434
-
-loc_4CB445: ; CODE XREF: sub_4CB3B0+7Bj
- ; sub_4CB3B0+89j
- pop edi
-
-loc_4CB446: ; CODE XREF: sub_4CB3B0+26j
- ; sub_4CB3B0+35j
- add dword ptr [esi+32F04h], 1
- pop esi
- pop ebp
- mov eax, ebx
- pop ebx
- retn 4
-sub_4CB3B0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-CEncoder_GetOptimumFast proc near ; CODE XREF: CEncoder_CodeOneBlock+1F4p
-
-var_28 = dword ptr -28h
-var_24 = dword ptr -24h
-var_20 = dword ptr -20h
-var_1C = dword ptr -1Ch
-var_18 = dword ptr -18h
-var_14 = dword ptr -14h
-var_10 = dword ptr -10h
-arg_0 = dword ptr 4
-
- sub esp, 28h
- push ebx
- push esi
- push edi
- mov edi, ecx
- mov eax, [edi+80h]
- mov ecx, [edi+70h]
- push eax
- call ecx
- add esp, 4
- cmp byte ptr [edi+32F10h], 0
- mov esi, eax
- mov [esp+34h+var_24], esi
- jnz short loc_4CB498
- lea edx, [esp+34h+var_20]
- push edx
- mov ecx, edi
- call sub_4CB3B0
- mov ebx, [esp+34h+var_20]
- jmp short loc_4CB4AF
-; ---------------------------------------------------------------------------
-
-loc_4CB498: ; CODE XREF: CEncoder_GetOptimumFast+24j
- mov ebx, [edi+32F00h]
- mov eax, [edi+32EFCh]
- mov [esp+34h+var_20], ebx
- mov byte ptr [edi+32F10h], 0
-
-loc_4CB4AF: ; CODE XREF: CEncoder_GetOptimumFast+36j
- mov ecx, [edi+80h]
- mov edx, [edi+74h]
- push ecx
- mov [esp+38h+var_28], eax
- call edx
- add esp, 4
- sub eax, 1
- cmp esi, 111h
- jbe loc_4CB55E
- mov [esp+34h+var_24], 111h
-
-loc_4CB4D9: ; CODE XREF: CEncoder_GetOptimumFast+101j
- push ebp
- xor ebp, ebp
- lea ecx, [edi+14h]
- mov [esp+38h+var_18], ebp
- mov [esp+38h+var_14], ebp
- mov [esp+38h+var_1C], ecx
- jmp short loc_4CB4F0
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CB4F0: ; CODE XREF: CEncoder_GetOptimumFast+8Bj
- ; CEncoder_GetOptimumFast+132j
- mov edx, [esp+38h+var_1C]
- mov ecx, eax
- sub ecx, [edx]
- mov dl, [eax]
- sub ecx, 1
- cmp dl, [ecx]
- jnz short loc_4CB57F
- mov dl, [eax+1]
- cmp dl, [ecx+1]
- jnz short loc_4CB57F
- mov esi, 2
- cmp [esp+38h+var_24], esi
- jbe short loc_4CB537
- lea edx, [eax+2]
- sub ecx, eax
- lea esp, [esp+0]
-
-loc_4CB520: ; CODE XREF: CEncoder_GetOptimumFast+D1j
- mov bl, [edx]
- cmp bl, [ecx+edx]
- jnz short loc_4CB533
- add esi, 1
- add edx, 1
- cmp esi, [esp+38h+var_24]
- jb short loc_4CB520
-
-loc_4CB533: ; CODE XREF: CEncoder_GetOptimumFast+C5j
- mov ebx, [esp+38h+var_20]
-
-loc_4CB537: ; CODE XREF: CEncoder_GetOptimumFast+B2j
- cmp esi, [edi+32EF8h]
- jnb short loc_4CB5B9
- mov edx, [esp+38h+var_14]
- lea ecx, ds:0[ebp*4]
- mov [esp+ecx+38h+var_10], esi
- cmp esi, [esp+edx+38h+var_10]
- jbe short loc_4CB587
- mov [esp+38h+var_18], ebp
- mov [esp+38h+var_14], ecx
- jmp short loc_4CB587
-; ---------------------------------------------------------------------------
-
-loc_4CB55E: ; CODE XREF: CEncoder_GetOptimumFast+6Bj
- cmp esi, 2
- jnb loc_4CB4D9
- mov eax, [esp+34h+arg_0]
- pop edi
- pop esi
- mov dword ptr [eax], 0FFFFFFFFh
- mov eax, 1
- pop ebx
- add esp, 28h
- retn 4
-; ---------------------------------------------------------------------------
-
-loc_4CB57F: ; CODE XREF: CEncoder_GetOptimumFast+9Fj
- ; CEncoder_GetOptimumFast+A7j
- mov [esp+ebp*4+38h+var_10], 0
-
-loc_4CB587: ; CODE XREF: CEncoder_GetOptimumFast+F2j
- ; CEncoder_GetOptimumFast+FCj
- add [esp+38h+var_1C], 4
- add ebp, 1
- cmp ebp, 4
- jb loc_4CB4F0
- mov esi, [esp+38h+var_28]
- cmp esi, [edi+32EF8h]
- jb short loc_4CB5EC
- mov eax, [edi+ebx*4+3265Ch]
- mov ecx, [esp+38h+arg_0]
- add eax, 4
- mov [ecx], eax
- jmp loc_4CB69A
-; ---------------------------------------------------------------------------
-
-loc_4CB5B9: ; CODE XREF: CEncoder_GetOptimumFast+DDj
- mov eax, [esp+38h+arg_0]
- mov [eax], ebp
- lea eax, [esi-1]
- test eax, eax
- jz loc_4CB82E
- mov ecx, [edi+80h]
- mov edx, [edi+7Ch]
- add [edi+32F04h], eax
- push eax
- push ecx
- call edx
- add esp, 8
- pop ebp
- pop edi
- mov eax, esi
- pop esi
- pop ebx
- add esp, 28h
- retn 4
-; ---------------------------------------------------------------------------
-
-loc_4CB5EC: ; CODE XREF: CEncoder_GetOptimumFast+142j
- xor ebp, ebp
- cmp esi, 2
- mov [esp+38h+var_20], ebp
- jb short loc_4CB65A
- cmp ebx, 2
- mov ecx, [edi+ebx*4+3265Ch]
- mov [esp+38h+var_20], ecx
- jbe short loc_4CB63F
- lea eax, [edi+ebx*4+32654h]
- mov edi, edi
-
-loc_4CB610: ; CODE XREF: CEncoder_GetOptimumFast+1DDj
- mov edx, [eax-4]
- add edx, 1
- cmp esi, edx
- jnz short loc_4CB63F
- mov ecx, [esp+38h+var_20]
- shr ecx, 7
- cmp ecx, [eax]
- jbe short loc_4CB63F
- mov edx, [eax-4]
- mov ecx, [eax]
- sub eax, 8
- sub ebx, 2
- cmp ebx, 2
- mov [esp+38h+var_28], edx
- mov [esp+38h+var_20], ecx
- mov esi, edx
- ja short loc_4CB610
-
-loc_4CB63F: ; CODE XREF: CEncoder_GetOptimumFast+1A5j
- ; CEncoder_GetOptimumFast+1B8j ...
- cmp esi, 2
- jnz short loc_4CB656
- cmp [esp+38h+var_20], 80h
- jb short loc_4CB656
- mov [esp+38h+var_28], 1
-
-loc_4CB656: ; CODE XREF: CEncoder_GetOptimumFast+1E2j
- ; CEncoder_GetOptimumFast+1ECj
- mov ebp, [esp+38h+var_20]
-
-loc_4CB65A: ; CODE XREF: CEncoder_GetOptimumFast+195j
- mov edx, [esp+38h+var_18]
- mov esi, [esp+edx*4+38h+var_10]
- cmp esi, 2
- mov ebx, [esp+38h+var_28]
- jb short loc_4CB6C7
- lea eax, [esi+1]
- cmp eax, ebx
- jnb short loc_4CB690
- lea ecx, [esi+2]
- cmp ecx, ebx
- jb short loc_4CB681
- cmp ebp, 200h
- ja short loc_4CB690
-
-loc_4CB681: ; CODE XREF: CEncoder_GetOptimumFast+217j
- lea edx, [esi+3]
- cmp edx, ebx
- jb short loc_4CB6C7
- cmp ebp, 8000h
- jbe short loc_4CB6C7
-
-loc_4CB690: ; CODE XREF: CEncoder_GetOptimumFast+210j
- ; CEncoder_GetOptimumFast+21Fj
- mov eax, [esp+38h+arg_0]
- mov ecx, [esp+38h+var_18]
- mov [eax], ecx
-
-loc_4CB69A: ; CODE XREF: CEncoder_GetOptimumFast+154j
- lea eax, [esi-1]
- test eax, eax
- jz loc_4CB82E
- mov edx, [edi+80h]
- add [edi+32F04h], eax
- push eax
- mov eax, [edi+7Ch]
- push edx
- call eax
- add esp, 8
- pop ebp
- pop edi
- mov eax, esi
- pop esi
- pop ebx
- add esp, 28h
- retn 4
-; ---------------------------------------------------------------------------
-
-loc_4CB6C7: ; CODE XREF: CEncoder_GetOptimumFast+209j
- ; CEncoder_GetOptimumFast+226j ...
- cmp ebx, 2
- jb short loc_4CB73E
- cmp [esp+38h+var_24], 2
- jbe short loc_4CB73E
- mov ecx, [edi+80h]
- mov edx, [edi+70h]
- push ecx
- call edx
- add esp, 4
- lea esi, [edi+32F00h]
- push esi
- mov ecx, edi
- mov [esp+3Ch+var_24], eax
- call sub_4CB3B0
- cmp eax, 2
- mov [edi+32EFCh], eax
- jb short loc_4CB757
- cmp eax, ebx
- mov ecx, [esi]
- mov edx, [edi+ecx*4+3265Ch]
- jb short loc_4CB710
- cmp edx, ebp
- jb short loc_4CB737
-
-loc_4CB710: ; CODE XREF: CEncoder_GetOptimumFast+2AAj
- lea ecx, [ebx+1]
- cmp eax, ecx
- jnz short loc_4CB722
- mov esi, edx
- shr esi, 7
- cmp esi, ebp
- jbe short loc_4CB737
- cmp eax, ecx
-
-loc_4CB722: ; CODE XREF: CEncoder_GetOptimumFast+2B5j
- ja short loc_4CB737
- add eax, 1
- cmp eax, ebx
- jb short loc_4CB757
- cmp ebx, 3
- jb short loc_4CB757
- shr ebp, 7
- cmp ebp, edx
- jbe short loc_4CB757
-
-loc_4CB737: ; CODE XREF: CEncoder_GetOptimumFast+2AEj
- ; CEncoder_GetOptimumFast+2BEj ...
- mov byte ptr [edi+32F10h], 1
-
-loc_4CB73E: ; CODE XREF: CEncoder_GetOptimumFast+26Aj
- ; CEncoder_GetOptimumFast+271j
- mov edx, [esp+38h+arg_0]
- pop ebp
- pop edi
- pop esi
- mov dword ptr [edx], 0FFFFFFFFh
- mov eax, 1
- pop ebx
- add esp, 28h
- retn 4
-; ---------------------------------------------------------------------------
-
-loc_4CB757: ; CODE XREF: CEncoder_GetOptimumFast+29Dj
- ; CEncoder_GetOptimumFast+2C9j ...
- mov eax, [edi+80h]
- mov ecx, [edi+74h]
- push eax
- call ecx
- lea ecx, [edi+14h]
- add esp, 4
- sub eax, 1
- mov [esp+38h+var_18], 0
- mov ebx, ecx
-
-loc_4CB776: ; CODE XREF: CEncoder_GetOptimumFast+39Aj
- mov dl, [eax+1]
- mov ecx, eax
- sub ecx, [ebx]
- sub ecx, 1
- cmp dl, [ecx+1]
- jnz short loc_4CB7DD
- mov dl, [eax+2]
- cmp dl, [ecx+2]
- lea ebp, [eax+2]
- jnz short loc_4CB7DD
- mov esi, 2
- cmp [esp+38h+var_24], esi
- jbe short loc_4CB7B4
- mov edx, ebp
- mov ebp, ecx
- sub ebp, eax
-
-loc_4CB7A1: ; CODE XREF: CEncoder_GetOptimumFast+352j
- mov cl, [edx]
- cmp cl, [edx+ebp]
- jnz short loc_4CB7B4
- add esi, 1
- add edx, 1
- cmp esi, [esp+38h+var_24]
- jb short loc_4CB7A1
-
-loc_4CB7B4: ; CODE XREF: CEncoder_GetOptimumFast+339j
- ; CEncoder_GetOptimumFast+346j
- add esi, 1
- cmp esi, [esp+38h+var_28]
- jb short loc_4CB7E9
- mov eax, [esp+38h+arg_0]
- pop ebp
- mov byte ptr [edi+32F10h], 1
- pop edi
- pop esi
- mov dword ptr [eax], 0FFFFFFFFh
- mov eax, 1
- pop ebx
- add esp, 28h
- retn 4
-; ---------------------------------------------------------------------------
-
-loc_4CB7DD: ; CODE XREF: CEncoder_GetOptimumFast+323j
- ; CEncoder_GetOptimumFast+32Ej
- mov edx, [esp+38h+var_18]
- mov [esp+edx*4+38h+var_10], 0
-
-loc_4CB7E9: ; CODE XREF: CEncoder_GetOptimumFast+35Bj
- mov ecx, [esp+38h+var_18]
- add ecx, 1
- add ebx, 4
- cmp ecx, 4
- mov [esp+38h+var_18], ecx
- jb loc_4CB776
- mov esi, [esp+38h+var_28]
- mov ecx, [esp+38h+var_20]
- mov edx, [esp+38h+arg_0]
- add ecx, 4
- lea eax, [esi-2]
- test eax, eax
- mov [edx], ecx
- jz short loc_4CB82E
- add [edi+32F04h], eax
- mov ecx, [edi+7Ch]
- push eax
- mov eax, [edi+80h]
- push eax
- call ecx
- add esp, 8
-
-loc_4CB82E: ; CODE XREF: CEncoder_GetOptimumFast+164j
- ; CEncoder_GetOptimumFast+23Fj ...
- pop ebp
- pop edi
- mov eax, esi
- pop esi
- pop ebx
- add esp, 28h
- retn 4
-CEncoder_GetOptimumFast endp
-
-; =============== S U B R O U T I N E =======================================
-
-sub_4CB8A0 proc near ; CODE XREF: sub_4CD940+37p
-
-arg_0 = dword ptr 4
-
- push edi
- mov edi, [esp+4+arg_0]
- test edi, edi
- jz short loc_4CB8EB
- mov eax, dword_553598
- test eax, eax
- jnz short loc_4CB8DD
- push 0Ch ; Size
- call _operator_new ; operator new(uint)
- add esp, 4
- test eax, eax
- jz short loc_4CB8D6
- mov dword ptr [eax], 0
- mov dword ptr [eax+4], 0
- mov dword ptr [eax+8], 0
- jmp short loc_4CB8D8
-; ---------------------------------------------------------------------------
-
-loc_4CB8D6: ; CODE XREF: sub_4CB8A0+1Ej
- xor eax, eax
-
-loc_4CB8D8: ; CODE XREF: sub_4CB8A0+34j
- mov dword_553598, eax
-
-loc_4CB8DD: ; CODE XREF: sub_4CB8A0+10j
- mov eax, [eax]
- test eax, eax
- jz short loc_4CB8EB
- push edi
- call eax
- add esp, 4
- pop edi
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CB8EB: ; CODE XREF: sub_4CB8A0+7j
- ; sub_4CB8A0+41j
- xor eax, eax
- pop edi
- retn
-sub_4CB8A0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CB8F0 proc near ; CODE XREF: sub_4CBA60+85p
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-arg_8 = dword ptr 0Ch
-
- push esi
- mov esi, [esp+4+arg_0]
- push edi
- mov edi, [esi+44h]
- add edi, [esi+40h]
- add edi, [esp+8+arg_4]
- cmp dword ptr [esi+4Ch], 0
- jz short loc_4CB911
- mov [esi+3Ch], edi
- pop edi
- mov eax, 1
- pop esi
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CB911: ; CODE XREF: sub_4CB8F0+14j
- mov eax, [esi+30h]
- test eax, eax
- jz short loc_4CB91D
- cmp [esi+3Ch], edi
- jz short loc_4CB93E
-
-loc_4CB91D: ; CODE XREF: sub_4CB8F0+26j
- push ebx
- mov ebx, [esp+0Ch+arg_8]
- push eax
- mov eax, [ebx+4]
- call eax
- mov dword ptr [esi+30h], 0
- mov [esi+3Ch], edi
- mov ecx, [ebx]
- push edi
- call ecx
- add esp, 8
- mov [esi+30h], eax
- pop ebx
-
-loc_4CB93E: ; CODE XREF: sub_4CB8F0+2Bj
- xor eax, eax
- cmp [esi+30h], eax
- pop edi
- setnz al
- pop esi
- retn
-sub_4CB8F0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CB950: ; DATA XREF: sub_4CCAA0+1Co
- mov eax, [esp+4]
- mov eax, [eax]
- retn
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CB960: ; DATA XREF: sub_4CCAA0+Eo
- mov eax, [esp+4]
- mov ecx, [eax]
- mov edx, [esp+8]
- mov al, [edx+ecx]
- retn
-; ---------------------------------------------------------------------------
- align 10h
-loc_4CB970: ; DATA XREF: sub_4CCAA0+15o
- mov ecx, [esp+4]
-
-; =============== S U B R O U T I N E =======================================
-
-; Attributes: library function
-
-; public: int __thiscall CRect::Height(void)const
-?Height@CRect@@QBEHXZ proc near
- mov eax, [ecx+0Ch]
- sub eax, [ecx+4]
- retn
-?Height@CRect@@QBEHXZ endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CB980 proc near ; CODE XREF: sub_4CBC80+46p
- ; sub_4CBD50+61p
-
-arg_0 = dword ptr 4
-
- push esi
- mov esi, [esp+4+arg_0]
- cmp dword ptr [esi+38h], 0
- jnz short loc_4CB9F0
- cmp dword ptr [esi+68h], 0
- jnz short loc_4CB9F0
- mov eax, [esi]
- sub eax, [esi+4]
- mov ecx, [esi+30h]
- add eax, [esi+0Ch]
- sub ecx, eax
- add ecx, [esi+3Ch]
- jz short loc_4CB9F0
- push edi
-
-loc_4CB9A4: ; CODE XREF: sub_4CB980+63j
- mov edx, [esi+34h]
- lea edi, [esp+8+arg_0]
- push edi
- push ecx
- push eax
- mov eax, [edx]
- push edx
- call eax
- add esp, 10h
- test eax, eax
- mov [esi+68h], eax
- jnz short loc_4CB9EF
- mov eax, [esp+8+arg_0]
- test eax, eax
- jz short loc_4CB9E8
- add [esi+0Ch], eax
- mov eax, [esi+0Ch]
- sub eax, [esi+4]
- cmp eax, [esi+44h]
- ja short loc_4CB9EF
- mov eax, [esi]
- sub eax, [esi+4]
- mov ecx, [esi+30h]
- add eax, [esi+0Ch]
- sub ecx, eax
- add ecx, [esi+3Ch]
- jnz short loc_4CB9A4
- pop edi
- pop esi
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CB9E8: ; CODE XREF: sub_4CB980+43j
- mov dword ptr [esi+38h], 1
-
-loc_4CB9EF: ; CODE XREF: sub_4CB980+3Bj
- ; sub_4CB980+51j
- pop edi
-
-loc_4CB9F0: ; CODE XREF: sub_4CB980+9j
- ; sub_4CB980+Fj ...
- pop esi
- retn
-sub_4CB980 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CBA00 proc near ; CODE XREF: sub_4CBD50+58p
-
-arg_0 = dword ptr 4
-
- push ebx
- push ebp
- push esi
- push edi
- mov edi, [esp+10h+arg_0]
- mov esi, [edi+0Ch]
- mov eax, [edi+40h]
- sub esi, [edi+4]
- mov ebx, [edi]
- mov ebp, [edi+30h]
- add esi, eax
- sub ebx, eax
- mov eax, dword_553598
- test eax, eax
- jnz short loc_4CBA44
- push 0Ch ; Size
- call _operator_new ; operator new(uint)
- xor ecx, ecx
- add esp, 4
- cmp eax, ecx
- jz short loc_4CBA3D
- mov [eax], ecx
- mov [eax+4], ecx
- mov [eax+8], ecx
- jmp short loc_4CBA3F
-; ---------------------------------------------------------------------------
-
-loc_4CBA3D: ; CODE XREF: sub_4CBA00+31j
- xor eax, eax
-
-loc_4CBA3F: ; CODE XREF: sub_4CBA00+3Bj
- mov dword_553598, eax
-
-loc_4CBA44: ; CODE XREF: sub_4CBA00+21j
- mov eax, [eax+8]
- test eax, eax
- jz short loc_4CBA53
- push esi
- push ebx
- push ebp
- call eax
- add esp, 0Ch
-
-loc_4CBA53: ; CODE XREF: sub_4CBA00+49j
- mov eax, [edi+30h]
- add eax, [edi+40h]
- mov [edi], eax
- pop edi
- pop esi
- pop ebp
- pop ebx
- retn
-sub_4CBA00 endp
-
-; =============== S U B R O U T I N E =======================================
-
-sub_4CBA60 proc near ; CODE XREF: sub_4D0270+D2p
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-arg_8 = dword ptr 0Ch
-arg_C = dword ptr 10h
-arg_10 = dword ptr 14h
-arg_14 = dword ptr 18h
-
- push ebx
- push esi
- push edi
- mov edi, [esp+0Ch+arg_4]
- cmp edi, 0C0000000h
- jbe short loc_4CBAA2
- mov esi, [esp+0Ch+arg_0]
- mov eax, [esi+20h]
- mov edi, [esp+0Ch+arg_14]
- mov ecx, [edi+4]
- push eax
- call ecx
- xor ebx, ebx
- add esp, 4
- cmp [esi+4Ch], ebx
- mov [esi+20h], ebx
- jnz short loc_4CBA9C
- mov edx, [esi+30h]
- mov eax, [edi+4]
- push edx
- call eax
- add esp, 4
- mov [esi+30h], ebx
-
-loc_4CBA9C: ; CODE XREF: sub_4CBA60+2Bj
- pop edi
- pop esi
- xor eax, eax
- pop ebx
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CBAA2: ; CODE XREF: sub_4CBA60+Dj
- mov eax, edi
- shr eax, 1
- cmp edi, 80000000h
- jbe short loc_4CBAB3
- mov eax, edi
- shr eax, 2
-
-loc_4CBAB3: ; CODE XREF: sub_4CBA60+4Cj
- mov ecx, [esp+0Ch+arg_8]
- mov esi, [esp+0Ch+arg_0]
- mov ebx, [esp+0Ch+arg_C]
- lea edx, [edi+ecx+1]
- push ebp
- mov [esi+40h], edx
- mov edx, [esp+10h+arg_10]
- add ecx, ebx
- lea ebp, [ebx+edx]
- add ecx, edx
- mov [esi+44h], ebp
- mov ebp, [esp+10h+arg_14]
- shr ecx, 1
- push ebp
- lea eax, [ecx+eax+80000h]
- push eax
- push esi
- call sub_4CB8F0
- add esp, 0Ch
- test eax, eax
- jz loc_4CBBEA
- mov edx, [esi+48h]
- mov [esi+1Ch], ebx
- xor ebx, ebx
- cmp edx, 2
- lea ebp, [edi+1]
- mov [esi+5Ch], ebx
- jnz short loc_4CBB0F
- mov eax, 0FFFFh
- jmp short loc_4CBB49
-; ---------------------------------------------------------------------------
-
-loc_4CBB0F: ; CODE XREF: sub_4CBA60+A6j
- lea ecx, [edi-1]
- mov eax, ecx
- shr eax, 1
- or ecx, eax
- mov eax, ecx
- shr eax, 2
- or ecx, eax
- mov eax, ecx
- shr eax, 4
- or ecx, eax
- mov eax, ecx
- or eax, 1FFFE00h
- shr eax, 8
- or eax, ecx
- shr eax, 1
- cmp eax, 1000000h
- jbe short loc_4CBB49
- cmp edx, 3
- jnz short loc_4CBB47
- mov eax, 0FFFFFFh
- jmp short loc_4CBB49
-; ---------------------------------------------------------------------------
-
-loc_4CBB47: ; CODE XREF: sub_4CBA60+DEj
- shr eax, 1
-
-loc_4CBB49: ; CODE XREF: sub_4CBA60+ADj
- ; sub_4CBA60+D9j ...
- mov [esi+28h], eax
- add eax, 1
- cmp edx, 2
- jbe short loc_4CBB5B
- mov dword ptr [esi+5Ch], 400h
-
-loc_4CBB5B: ; CODE XREF: sub_4CBA60+F2j
- cmp edx, 3
- jbe short loc_4CBB67
- add dword ptr [esi+5Ch], 10000h
-
-loc_4CBB67: ; CODE XREF: sub_4CBA60+FEj
- cmp edx, 4
- jbe short loc_4CBB73
- add dword ptr [esi+5Ch], 100000h
-
-loc_4CBB73: ; CODE XREF: sub_4CBA60+10Aj
- mov ecx, [esi+60h]
- mov edx, [esi+5Ch]
- add ecx, [esi+64h]
- add eax, edx
- cmp [esi+50h], ebx
- mov [esi+58h], edi
- mov [esi+60h], eax
- mov [esi+18h], ebp
- lea edx, [ebp+ebp+0]
- jnz short loc_4CBB92
- mov edx, ebp
-
-loc_4CBB92: ; CODE XREF: sub_4CBA60+12Ej
- lea edi, [eax+edx]
- mov eax, [esi+20h]
- cmp eax, ebx
- mov [esi+64h], edx
- jz short loc_4CBBA3
- cmp ecx, edi
- jz short loc_4CBBE0
-
-loc_4CBBA3: ; CODE XREF: sub_4CBA60+13Dj
- mov ebp, [esp+10h+arg_14]
- push eax
- mov eax, [ebp+4]
- call eax
- lea eax, ds:0[edi*4]
- mov ecx, eax
- shr ecx, 2
- add esp, 4
- cmp ecx, edi
- mov [esi+20h], ebx
- jz short loc_4CBBC7
- xor eax, eax
- jmp short loc_4CBBD0
-; ---------------------------------------------------------------------------
-
-loc_4CBBC7: ; CODE XREF: sub_4CBA60+161j
- mov edx, [ebp+0]
- push eax
- call edx
- add esp, 4
-
-loc_4CBBD0: ; CODE XREF: sub_4CBA60+165j
- cmp eax, ebx
- mov [esi+20h], eax
- jz short loc_4CBBEC
- mov ecx, [esi+60h]
- lea edx, [eax+ecx*4]
- mov [esi+24h], edx
-
-loc_4CBBE0: ; CODE XREF: sub_4CBA60+141j
- pop ebp
- pop edi
- pop esi
- mov eax, 1
- pop ebx
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CBBEA: ; CODE XREF: sub_4CBA60+8Fj
- xor ebx, ebx
-
-loc_4CBBEC: ; CODE XREF: sub_4CBA60+175j
- mov eax, [esi+20h]
- mov ecx, [ebp+4]
- push eax
- call ecx
- add esp, 4
- cmp [esi+4Ch], ebx
- mov [esi+20h], ebx
- jnz short loc_4CBC0F
- mov edx, [esi+30h]
- mov eax, [ebp+4]
- push edx
- call eax
- add esp, 4
- mov [esi+30h], ebx
-
-loc_4CBC0F: ; CODE XREF: sub_4CBA60+19Ej
- pop ebp
- pop edi
- pop esi
- xor eax, eax
- pop ebx
- retn
-sub_4CBA60 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CBC20 proc near ; CODE XREF: sub_4CBD50+79p
-
-arg_0 = dword ptr 4
-
- mov eax, [esp+arg_0]
- mov edx, [eax+18h]
- sub edx, [eax+14h]
- push ebx
- mov ebx, [eax+4]
- or ecx, 0FFFFFFFFh
- sub ecx, ebx
- cmp edx, ecx
- push esi
- jnb short loc_4CBC3A
- mov ecx, edx
-
-loc_4CBC3A: ; CODE XREF: sub_4CBC20+16j
- mov esi, [eax+0Ch]
- sub esi, ebx
- push edi
- mov edi, [eax+44h]
- mov edx, esi
- cmp edx, edi
- ja short loc_4CBC54
- test edx, edx
- jbe short loc_4CBC56
- mov edx, 1
- jmp short loc_4CBC56
-; ---------------------------------------------------------------------------
-
-loc_4CBC54: ; CODE XREF: sub_4CBC20+27j
- sub edx, edi
-
-loc_4CBC56: ; CODE XREF: sub_4CBC20+2Bj
- ; sub_4CBC20+32j
- cmp edx, ecx
- pop edi
- jnb short loc_4CBC5D
- mov ecx, edx
-
-loc_4CBC5D: ; CODE XREF: sub_4CBC20+39j
- mov edx, [eax+1Ch]
- cmp esi, edx
- jbe short loc_4CBC66
- mov esi, edx
-
-loc_4CBC66: ; CODE XREF: sub_4CBC20+42j
- add ebx, ecx
- mov [eax+10h], esi
- pop esi
- mov [eax+8], ebx
- pop ebx
- retn
-sub_4CBC20 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CBC80 proc near ; DATA XREF: sub_4CCAA0+8o
-
-arg_0 = dword ptr 4
-
- push ebx
- push esi
- mov esi, [esp+8+arg_0]
- xor eax, eax
- cmp [esi+60h], eax
- jbe short loc_4CBCA2
- lea ecx, [ecx+0]
-
-loc_4CBC90: ; CODE XREF: sub_4CBC80+20j
- mov ecx, [esi+20h]
- mov dword ptr [ecx+eax*4], 0
- add eax, 1
- cmp eax, [esi+60h]
- jb short loc_4CBC90
-
-loc_4CBCA2: ; CODE XREF: sub_4CBC80+Bj
- mov eax, [esi+18h]
- mov edx, [esi+30h]
- push esi
- mov dword ptr [esi+14h], 0
- mov [esi], edx
- mov [esi+0Ch], eax
- mov [esi+4], eax
- mov dword ptr [esi+68h], 0
- mov dword ptr [esi+38h], 0
- call sub_4CB980
- mov eax, [esi+18h]
- mov ebx, [esi+4]
- sub eax, [esi+14h]
- or ecx, 0FFFFFFFFh
- sub ecx, ebx
- add esp, 4
- cmp eax, ecx
- jnb short loc_4CBCE2
- mov ecx, eax
-
-loc_4CBCE2: ; CODE XREF: sub_4CBC80+5Ej
- mov edx, [esi+0Ch]
- sub edx, ebx
- push edi
- mov edi, [esi+44h]
- mov eax, edx
- cmp eax, edi
- ja short loc_4CBCFC
- test eax, eax
- jbe short loc_4CBCFE
- mov eax, 1
- jmp short loc_4CBCFE
-; ---------------------------------------------------------------------------
-
-loc_4CBCFC: ; CODE XREF: sub_4CBC80+6Fj
- sub eax, edi
-
-loc_4CBCFE: ; CODE XREF: sub_4CBC80+73j
- ; sub_4CBC80+7Aj
- cmp eax, ecx
- pop edi
- jnb short loc_4CBD05
- mov ecx, eax
-
-loc_4CBD05: ; CODE XREF: sub_4CBC80+81j
- mov eax, edx
- mov edx, [esi+1Ch]
- cmp eax, edx
- jbe short loc_4CBD10
- mov eax, edx
-
-loc_4CBD10: ; CODE XREF: sub_4CBC80+8Cj
- add ebx, ecx
- mov [esi+8], ebx
- mov [esi+10h], eax
- pop esi
- pop ebx
- retn
-sub_4CBC80 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CBD20 proc near ; CODE XREF: sub_4CBD50+26p
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-arg_8 = dword ptr 0Ch
-
- push edi
- mov edi, [esp+4+arg_8]
- xor eax, eax
- test edi, edi
- jbe short loc_4CBD4C
- mov edx, [esp+4+arg_4]
- push esi
- mov esi, [esp+8+arg_0]
-
-loc_4CBD34: ; CODE XREF: sub_4CBD20+29j
- mov ecx, [edx+eax*4]
- cmp ecx, esi
- ja short loc_4CBD3F
- xor ecx, ecx
- jmp short loc_4CBD41
-; ---------------------------------------------------------------------------
-
-loc_4CBD3F: ; CODE XREF: sub_4CBD20+19j
- sub ecx, esi
-
-loc_4CBD41: ; CODE XREF: sub_4CBD20+1Dj
- mov [edx+eax*4], ecx
- add eax, 1
- cmp eax, edi
- jb short loc_4CBD34
- pop esi
-
-loc_4CBD4C: ; CODE XREF: sub_4CBD20+9j
- pop edi
- retn
-sub_4CBD20 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-; =============== S U B R O U T I N E =======================================
-
-sub_4CBD50 proc near ; CODE XREF: .text:004CC1A1p
- ; .text:004CC20Ap ...
-
-arg_0 = dword ptr 4
-
- push esi
- mov esi, [esp+4+arg_0]
- cmp dword ptr [esi+4], 0FFFFFFFFh
- jnz short loc_4CBD88
- mov eax, [esi+64h]
- add eax, [esi+60h]
- mov ecx, [esi+20h]
- push edi
- mov edi, 0FFFFFFFEh
- sub edi, [esi+58h]
- push eax
- push ecx
- and edi, 0FFFFFC00h
- push edi
- call sub_4CBD20
- sub [esi+8], edi
- sub [esi+4], edi
- add esp, 0Ch
- sub [esi+0Ch], edi
- pop edi
-
-loc_4CBD88: ; CODE XREF: sub_4CBD50+9j
- cmp dword ptr [esi+38h], 0
- jnz short loc_4CBDB9
- mov edx, [esi+0Ch]
- sub edx, [esi+4]
- mov eax, [esi+44h]
- cmp eax, edx
- jnz short loc_4CBDB9
- mov ecx, [esi+3Ch]
- add ecx, [esi+30h]
- sub ecx, [esi]
- cmp ecx, eax
- ja short loc_4CBDB0
- push esi
- call sub_4CBA00
- add esp, 4
-
-loc_4CBDB0: ; CODE XREF: sub_4CBD50+55j
- push esi
- call sub_4CB980
- add esp, 4
-
-loc_4CBDB9: ; CODE XREF: sub_4CBD50+3Cj
- ; sub_4CBD50+49j
- mov edx, [esi+14h]
- cmp edx, [esi+18h]
- jnz short loc_4CBDC8
- mov dword ptr [esi+14h], 0
-
-loc_4CBDC8: ; CODE XREF: sub_4CBD50+6Fj
- push esi
- call sub_4CBC20
- add esp, 4
- pop esi
- retn
-sub_4CBD50 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CBDE0 proc near ; CODE XREF: sub_4CC5C0+1B7p
-
-var_4 = dword ptr -4
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-arg_8 = dword ptr 0Ch
-arg_C = dword ptr 10h
-arg_10 = dword ptr 14h
-arg_14 = dword ptr 18h
-arg_18 = dword ptr 1Ch
-arg_1C = dword ptr 20h
-arg_20 = dword ptr 24h
-arg_24 = dword ptr 28h
-
- push ecx
- mov edx, [esp+4+arg_4]
- mov ecx, [esp+4+arg_10]
- mov eax, [esp+4+arg_14]
- push ebx
- mov [ecx+eax*4], edx
- mov ecx, [esp+8+arg_8]
- push ebp
- push esi
- sub ecx, edx
- cmp [esp+10h+arg_1C], 0
- push edi
- jz loc_4CBEAC
- mov ebp, [esp+14h+arg_C]
- mov ebx, [esp+14h+arg_24]
- jmp short loc_4CBE14
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CBE10: ; CODE XREF: sub_4CBDE0+C6j
- mov eax, [esp+14h+arg_14]
-
-loc_4CBE14: ; CODE XREF: sub_4CBDE0+2Dj
- mov esi, [esp+14h+arg_18]
- sub [esp+14h+arg_1C], 1
- cmp ecx, esi
- jnb loc_4CBEAC
- mov edx, ebp
- sub edx, ecx
- cmp eax, ecx
- sbb edi, edi
- and edi, esi
- sub edi, ecx
- add edi, eax
- mov eax, [esp+14h+arg_10]
- mov eax, [eax+edi*4]
- mov [esp+14h+arg_4], eax
- mov al, [edx+ebx]
- cmp al, [ebx+ebp]
- jnz short loc_4CBE99
- mov al, [edx]
- cmp al, [ebp+0]
- jnz short loc_4CBE99
- mov eax, [esp+14h+arg_0]
- mov esi, 1
- cmp eax, esi
- jz short loc_4CBE7A
- sub edx, ebp
- lea edi, [ebp+1]
- mov [esp+14h+var_4], edx
- jmp short loc_4CBE69
-; ---------------------------------------------------------------------------
-
-loc_4CBE65: ; CODE XREF: sub_4CBDE0+98j
- mov edx, [esp+14h+var_4]
-
-loc_4CBE69: ; CODE XREF: sub_4CBDE0+83j
- mov dl, [edx+edi]
- cmp dl, [edi]
- jnz short loc_4CBE7A
- add esi, 1
- add edi, 1
- cmp esi, eax
- jnz short loc_4CBE65
-
-loc_4CBE7A: ; CODE XREF: sub_4CBDE0+78j
- ; sub_4CBDE0+8Ej
- cmp ebx, esi
- jnb short loc_4CBE99
- mov edx, [esp+14h+arg_20]
- mov [edx], esi
- add edx, 4
- add ecx, 0FFFFFFFFh
- mov [edx], ecx
- add edx, 4
- cmp esi, eax
- mov ebx, esi
- mov [esp+14h+arg_20], edx
- jz short loc_4CBEB6
-
-loc_4CBE99: ; CODE XREF: sub_4CBDE0+64j
- ; sub_4CBDE0+6Bj ...
- mov ecx, [esp+14h+arg_8]
- sub ecx, [esp+14h+arg_4]
- cmp [esp+14h+arg_1C], 0
- jnz loc_4CBE10
-
-loc_4CBEAC: ; CODE XREF: sub_4CBDE0+1Fj
- ; sub_4CBDE0+3Fj
- mov eax, [esp+14h+arg_20]
- pop edi
- pop esi
- pop ebp
- pop ebx
- pop ecx
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CBEB6: ; CODE XREF: sub_4CBDE0+B7j
- pop edi
- pop esi
- pop ebp
- mov eax, edx
- pop ebx
- pop ecx
- retn
-sub_4CBDE0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CBEC0 proc near ; CODE XREF: .text:004CC1E7p
- ; sub_4CC220+14Ep ...
-
-var_10 = dword ptr -10h
-var_C = dword ptr -0Ch
-var_8 = dword ptr -8
-var_4 = dword ptr -4
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-arg_8 = dword ptr 0Ch
-arg_C = dword ptr 10h
-arg_10 = dword ptr 14h
-arg_14 = dword ptr 18h
-arg_18 = dword ptr 1Ch
-arg_1C = dword ptr 20h
-arg_20 = dword ptr 24h
-arg_24 = dword ptr 28h
-
- sub esp, 10h
- mov eax, [esp+10h+arg_10]
- mov edx, [esp+10h+arg_8]
- sub edx, [esp+10h+arg_4]
- push ebx
- push ebp
- push esi
- push edi
- mov edi, [esp+20h+arg_14]
- lea eax, [eax+edi*8]
- lea ecx, [eax+4]
- mov [esp+20h+var_C], ecx
- xor ecx, ecx
- xor ebx, ebx
- cmp [esp+20h+arg_1C], ecx
- mov ebp, eax
- mov [esp+20h+var_10], ebp
- mov [esp+20h+var_8], ecx
- mov [esp+20h+var_4], ebx
- jnz short loc_4CBF24
-
-loc_4CBEF9: ; CODE XREF: sub_4CBEC0+6Fj
- ; sub_4CBEC0+151j
- mov edx, [esp+20h+var_C]
- mov eax, [esp+20h+arg_20]
- pop edi
- pop esi
- mov dword ptr [ebp+0], 0
- pop ebp
- mov dword ptr [edx], 0
- pop ebx
- add esp, 10h
- retn
-; ---------------------------------------------------------------------------
- jmp short loc_4CBF20
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CBF20: ; CODE XREF: sub_4CBEC0+56j
- ; sub_4CBEC0+14Bj
- mov edi, [esp+20h+arg_14]
-
-loc_4CBF24: ; CODE XREF: sub_4CBEC0+37j
- mov eax, [esp+20h+arg_18]
- sub [esp+20h+arg_1C], 1
- cmp edx, eax
- jnb short loc_4CBEF9
- cmp edi, edx
- sbb esi, esi
- and esi, eax
- mov eax, [esp+20h+arg_10]
- sub esi, edx
- add esi, edi
- lea eax, [eax+esi*8]
- mov esi, [esp+20h+arg_C]
- sub esi, edx
- cmp ecx, ebx
- jb short loc_4CBF4E
- mov ecx, ebx
-
-loc_4CBF4E: ; CODE XREF: sub_4CBEC0+8Aj
- mov bl, [ecx+esi]
- mov edi, [esp+20h+arg_C]
- cmp bl, [ecx+edi]
- jnz short loc_4CBFB8
- add ecx, 1
- cmp ecx, [esp+20h+arg_0]
- jz short loc_4CBF93
- mov bl, [ecx+esi]
- cmp bl, [ecx+edi]
- jnz short loc_4CBF93
- add ecx, 1
- cmp ecx, [esp+20h+arg_0]
- jz short loc_4CBF93
- mov ebx, edi
- mov ebp, esi
- lea edi, [ecx+ebx]
- sub ebp, ebx
- lea ecx, [ecx+0]
-
-loc_4CBF80: ; CODE XREF: sub_4CBEC0+D1j
- mov bl, [edi+ebp]
- cmp bl, [edi]
- jnz short loc_4CBF93
- add ecx, 1
- add edi, 1
- cmp ecx, [esp+20h+arg_0]
- jnz short loc_4CBF80
-
-loc_4CBF93: ; CODE XREF: sub_4CBEC0+A1j
- ; sub_4CBEC0+A9j ...
- cmp [esp+20h+arg_24], ecx
- jnb short loc_4CBFB8
- mov edi, [esp+20h+arg_20]
- mov [edi], ecx
- add edi, 4
- add edx, 0FFFFFFFFh
- mov [edi], edx
- add edi, 4
- cmp ecx, [esp+20h+arg_0]
- mov [esp+20h+arg_24], ecx
- mov [esp+20h+arg_20], edi
- jz short loc_4CC016
-
-loc_4CBFB8: ; CODE XREF: sub_4CBEC0+98j
- ; sub_4CBEC0+D7j
- mov dl, [ecx+esi]
- mov esi, [esp+20h+arg_C]
- cmp dl, [ecx+esi]
- mov edx, [esp+20h+arg_4]
- jnb short loc_4CBFE4
- mov esi, [esp+20h+var_10]
- lea ebp, [eax+4]
- mov ebx, ecx
- mov ecx, [esp+20h+var_8]
- mov [esi], edx
- mov eax, [ebp+0]
- mov [esp+20h+var_10], ebp
- mov [esp+20h+var_4], ebx
- jmp short loc_4CBFFC
-; ---------------------------------------------------------------------------
-
-loc_4CBFE4: ; CODE XREF: sub_4CBEC0+106j
- mov esi, [esp+20h+var_C]
- mov ebp, [esp+20h+var_10]
- mov ebx, [esp+20h+var_4]
- mov [esi], edx
- mov [esp+20h+var_C], eax
- mov eax, [eax]
- mov [esp+20h+var_8], ecx
-
-loc_4CBFFC: ; CODE XREF: sub_4CBEC0+122j
- mov edx, [esp+20h+arg_8]
- sub edx, eax
- cmp [esp+20h+arg_1C], 0
- mov [esp+20h+arg_4], eax
- jnz loc_4CBF20
- jmp loc_4CBEF9
-; ---------------------------------------------------------------------------
-
-loc_4CC016: ; CODE XREF: sub_4CBEC0+F6j
- mov ecx, [eax]
- mov edx, [esp+20h+var_10]
- mov [edx], ecx
- mov eax, [eax+4]
- mov ecx, [esp+20h+var_C]
- mov [ecx], eax
- mov eax, edi
- pop edi
- pop esi
- pop ebp
- pop ebx
- add esp, 10h
- retn
-sub_4CBEC0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CC040 proc near ; CODE XREF: sub_4CC220+F8p
- ; sub_4CC3B0+173p ...
-
-var_10 = dword ptr -10h
-var_C = dword ptr -0Ch
-var_8 = dword ptr -8
-var_4 = dword ptr -4
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-arg_8 = dword ptr 0Ch
-arg_C = dword ptr 10h
-arg_10 = dword ptr 14h
-arg_14 = dword ptr 18h
-arg_18 = dword ptr 1Ch
-arg_1C = dword ptr 20h
-
- sub esp, 10h
- mov eax, [esp+10h+arg_10]
- mov edx, [esp+10h+arg_4]
- push ebx
- push ebp
- push esi
- mov esi, [esp+1Ch+arg_14]
- lea eax, [eax+esi*8]
- lea ecx, [eax+4]
- push edi
- mov edi, eax
- mov eax, [esp+20h+arg_8]
- xor ebx, ebx
- xor ebp, ebp
- sub eax, edx
- cmp [esp+20h+arg_1C], ebx
- mov [esp+20h+var_C], ecx
- mov [esp+20h+var_10], edi
- mov [esp+20h+var_8], ebx
- mov [esp+20h+var_4], ebp
- jz loc_4CC159
- nop
-
-loc_4CC080: ; CODE XREF: sub_4CC040+114j
- sub [esp+20h+arg_1C], 1
- cmp eax, [esp+20h+arg_18]
- jnb loc_4CC159
- cmp esi, eax
- sbb ecx, ecx
- and ecx, [esp+20h+arg_18]
- sub ecx, eax
- add ecx, esi
- mov esi, [esp+20h+arg_10]
- lea edi, [esi+ecx*8]
- mov ecx, [esp+20h+arg_C]
- sub ecx, eax
- cmp ebx, ebp
- mov eax, ebx
- jb short loc_4CC0B0
- mov eax, ebp
-
-loc_4CC0B0: ; CODE XREF: sub_4CC040+6Cj
- mov bl, [eax+ecx]
- mov esi, [esp+20h+arg_C]
- cmp bl, [eax+esi]
- jnz short loc_4CC102
- add eax, 1
- cmp eax, [esp+20h+arg_0]
- jz short loc_4CC0E3
- mov ebx, esi
- mov ebp, ecx
- lea esi, [eax+ebx]
- sub ebp, ebx
- mov edi, edi
-
-loc_4CC0D0: ; CODE XREF: sub_4CC040+A1j
- mov bl, [esi+ebp]
- cmp bl, [esi]
- jnz short loc_4CC0FC
- add eax, 1
- add esi, 1
- cmp eax, [esp+20h+arg_0]
- jnz short loc_4CC0D0
-
-loc_4CC0E3: ; CODE XREF: sub_4CC040+83j
- ; sub_4CC040+C0j
- mov edx, [edi]
- mov eax, [esp+20h+var_10]
- mov [eax], edx
- mov ecx, [edi+4]
- mov edx, [esp+20h+var_C]
- pop edi
- pop esi
- pop ebp
- mov [edx], ecx
- pop ebx
- add esp, 10h
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CC0FC: ; CODE XREF: sub_4CC040+95j
- cmp eax, [esp+20h+arg_0]
- jz short loc_4CC0E3
-
-loc_4CC102: ; CODE XREF: sub_4CC040+7Aj
- mov cl, [eax+ecx]
- mov esi, [esp+20h+arg_C]
- cmp cl, [eax+esi]
- jnb short loc_4CC129
- mov ecx, [esp+20h+var_10]
- mov ebx, [esp+20h+var_8]
- add edi, 4
- mov ebp, eax
- mov [ecx], edx
- mov edx, [edi]
- mov [esp+20h+var_10], edi
- mov [esp+20h+var_4], ebp
- jmp short loc_4CC143
-; ---------------------------------------------------------------------------
-
-loc_4CC129: ; CODE XREF: sub_4CC040+CCj
- mov ecx, [esp+20h+var_C]
- mov ebp, [esp+20h+var_4]
- mov [ecx], edx
- mov edx, [edi]
- mov ebx, eax
- mov [esp+20h+var_C], edi
- mov edi, [esp+20h+var_10]
- mov [esp+20h+var_8], ebx
-
-loc_4CC143: ; CODE XREF: sub_4CC040+E7j
- mov eax, [esp+20h+arg_8]
- sub eax, edx
- cmp [esp+20h+arg_1C], 0
- jz short loc_4CC159
- mov esi, [esp+20h+arg_14]
- jmp loc_4CC080
-; ---------------------------------------------------------------------------
-
-loc_4CC159: ; CODE XREF: sub_4CC040+39j
- ; sub_4CC040+49j ...
- mov eax, [esp+20h+var_C]
- mov dword ptr [edi], 0
- pop edi
- pop esi
- pop ebp
- mov dword ptr [eax], 0
- pop ebx
- add esp, 10h
- retn
-sub_4CC040 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CC180: ; DATA XREF: sub_4CCAA0+40o
- push esi
- mov esi, [esp+8]
- mov edx, [esi+10h]
- cmp edx, 2
- jnb short loc_4CC1AD
- add dword ptr [esi+4], 1
- mov eax, [esi+4]
- add dword ptr [esi+14h], 1
- add dword ptr [esi], 1
- cmp eax, [esi+8]
- jnz short loc_4CC1A9
- push esi
- call sub_4CBD50
- add esp, 4
-
-loc_4CC1A9: ; CODE XREF: .text:004CC19Ej
- xor eax, eax
- pop esi
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CC1AD: ; CODE XREF: .text:004CC18Bj
- mov eax, [esi]
- xor ecx, ecx
- mov ch, [eax+1]
- push ebx
- mov ebx, [esp+10h]
- push edi
- mov edi, [esi+4]
- push 1
- push ebx
- mov cl, [eax]
- mov eax, ecx
- mov ecx, [esi+20h]
- lea eax, [ecx+eax*4]
- mov ecx, [eax]
- mov [eax], edi
- mov eax, [esi+2Ch]
- push eax
- mov eax, [esi+18h]
- push eax
- mov eax, [esi+14h]
- push eax
- mov eax, [esi+24h]
- push eax
- mov eax, [esi]
- push eax
- mov eax, [esi+4]
- push eax
- push ecx
- push edx
- call sub_4CBEC0
- add dword ptr [esi+4], 1
- add dword ptr [esi+14h], 1
- add dword ptr [esi], 1
- mov edi, eax
- mov eax, [esi+4]
- sub edi, ebx
- add esp, 28h
- sar edi, 2
- cmp eax, [esi+8]
- jnz short loc_4CC212
- push esi
- call sub_4CBD50
- add esp, 4
-
-loc_4CC212: ; CODE XREF: .text:004CC207j
- mov eax, edi
- pop edi
- pop ebx
- pop esi
- retn
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CC220 proc near ; DATA XREF: sub_4CCAA0+54o
-
-var_8 = dword ptr -8
-var_4 = dword ptr -4
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- sub esp, 8
- push esi
- mov esi, [esp+0Ch+arg_0]
- mov eax, [esi+10h]
- cmp eax, 3
- mov [esp+0Ch+arg_0], eax
- jnb short loc_4CC259
- mov eax, 1
- add [esi+14h], eax
- add [esi], eax
- add [esi+4], eax
- mov eax, [esi+4]
- cmp eax, [esi+8]
- jnz short loc_4CC252
- push esi
- call sub_4CBD50
- add esp, 4
-
-loc_4CC252: ; CODE XREF: sub_4CC220+27j
- xor eax, eax
- pop esi
- add esp, 8
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CC259: ; CODE XREF: sub_4CC220+12j
- push ebx
- mov ebx, [esi+20h]
- push ebp
- xor edx, edx
- push edi
- mov edi, [esi]
- mov dh, [edi+2]
- movzx ecx, byte ptr [edi]
- movzx eax, byte ptr [edi+1]
- xor eax, dword_553198[ecx*4]
- xor edx, eax
- and edx, [esi+28h]
- mov ecx, eax
- mov ebp, [ebx+edx*4+1000h]
- mov eax, [esi+4]
- and ecx, 3FFh
- sub eax, [ebx+ecx*4]
- mov [esp+18h+var_8], ebp
- mov ebp, [esi+4]
- mov [ebx+edx*4+1000h], ebp
- mov ebx, [esi+20h]
- mov edx, [ebx+edx*4+1000h]
- mov [ebx+ecx*4], edx
- mov ebx, [esp+18h+arg_4]
- xor ebp, ebp
- cmp eax, [esi+18h]
- mov ecx, 2
- jnb loc_4CC348
- mov edx, edi
- sub edx, eax
- mov [esp+18h+var_4], edx
- mov dl, [edx]
- cmp dl, [edi]
- jnz short loc_4CC348
- mov edx, [esp+18h+arg_0]
- cmp edx, ecx
- jz short loc_4CC2EA
-
-loc_4CC2D3: ; CODE XREF: sub_4CC220+C4j
- mov ebx, [esp+18h+var_4]
- mov bl, [ebx+ecx]
- cmp bl, [ecx+edi]
- jnz short loc_4CC2E6
- add ecx, 1
- cmp ecx, edx
- jnz short loc_4CC2D3
-
-loc_4CC2E6: ; CODE XREF: sub_4CC220+BDj
- mov ebx, [esp+18h+arg_4]
-
-loc_4CC2EA: ; CODE XREF: sub_4CC220+B1j
- add eax, 0FFFFFFFFh
- cmp ecx, edx
- mov [ebx], ecx
- mov [ebx+4], eax
- mov ebp, 2
- jnz short loc_4CC34C
- mov eax, [esi+2Ch]
- mov ecx, [esi+18h]
- push eax
- mov eax, [esi+14h]
- push ecx
- mov ecx, [esi+24h]
- push eax
- mov eax, [esi]
- push ecx
- mov ecx, [esi+4]
- push eax
- mov eax, [esp+2Ch+var_8]
- push ecx
- push eax
- push edx
- call sub_4CC040
- mov eax, 1
- add [esi+14h], eax
- add [esi], eax
- add [esi+4], eax
- mov eax, [esi+4]
- add esp, 20h
- cmp eax, [esi+8]
- jnz short loc_4CC33E
- push esi
- call sub_4CBD50
- add esp, 4
-
-loc_4CC33E: ; CODE XREF: sub_4CC220+113j
- pop edi
- mov eax, ebp
- pop ebp
- pop ebx
- pop esi
- add esp, 8
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CC348: ; CODE XREF: sub_4CC220+97j
- ; sub_4CC220+A9j
- mov edx, [esp+18h+arg_0]
-
-loc_4CC34C: ; CODE XREF: sub_4CC220+D9j
- mov eax, [esi+2Ch]
- push ecx
- lea ecx, [ebx+ebp*4]
- push ecx
- mov ecx, [esi+18h]
- push eax
- mov eax, [esi+14h]
- push ecx
- mov ecx, [esi+24h]
- push eax
- mov eax, [esi]
- push ecx
- mov ecx, [esi+4]
- push eax
- mov eax, [esp+34h+var_8]
- push ecx
- push eax
- push edx
- call sub_4CBEC0
- mov edi, eax
- mov eax, 1
- add [esi+14h], eax
- add [esi], eax
- add [esi+4], eax
- mov eax, [esi+4]
- sub edi, ebx
- add esp, 28h
- sar edi, 2
- cmp eax, [esi+8]
- jnz short loc_4CC39B
- push esi
- call sub_4CBD50
- add esp, 4
-
-loc_4CC39B: ; CODE XREF: sub_4CC220+170j
- mov eax, edi
- pop edi
- pop ebp
- pop ebx
- pop esi
- add esp, 8
- retn
-sub_4CC220 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CC3B0 proc near ; DATA XREF: sub_4CCAA0:loc_4CCB03o
-
-var_10 = dword ptr -10h
-var_8 = dword ptr -8
-var_4 = dword ptr -4
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- sub esp, 10h
- push esi
- mov esi, [esp+14h+arg_0]
- mov eax, [esi+10h]
- cmp eax, 4
- mov [esp+14h+arg_0], eax
- jnb short loc_4CC3E9
- mov eax, 1
- add [esi+14h], eax
- add [esi], eax
- add [esi+4], eax
- mov eax, [esi+4]
- cmp eax, [esi+8]
- jnz short loc_4CC3E2
- push esi
- call sub_4CBD50
- add esp, 4
-
-loc_4CC3E2: ; CODE XREF: sub_4CC3B0+27j
- xor eax, eax
- pop esi
- add esp, 10h
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CC3E9: ; CODE XREF: sub_4CC3B0+12j
- push ebx
- push ebp
- push edi
- mov edi, [esi]
- movzx eax, byte ptr [edi]
- movzx edx, byte ptr [edi+1]
- xor edx, dword_553198[eax*4]
- movzx eax, byte ptr [edi+2]
- movzx ebp, byte ptr [edi+3]
- mov ecx, eax
- add eax, eax
- add eax, eax
- add eax, eax
- xor eax, dword_553198[ebp*4]
- mov ebp, [esi+4]
- shl eax, 5
- shl ecx, 8
- xor eax, edx
- and eax, [esi+28h]
- xor ecx, edx
- mov ebx, edx
- mov edx, [esi+20h]
- and ebx, 3FFh
- sub ebp, [edx+ebx*4]
- and ecx, 0FFFFh
- mov [esp+20h+var_4], ebp
- mov ebp, [esi+4]
- sub ebp, [edx+ecx*4+1000h]
- mov [esp+20h+var_10], ebp
- mov ebp, [edx+eax*4+41000h]
- mov [esp+20h+var_8], ebp
- mov ebp, [esi+4]
- mov [edx+eax*4+41000h], ebp
- mov edx, [esi+20h]
- mov eax, [edx+eax*4+41000h]
- mov [edx+ecx*4+1000h], eax
- mov eax, [esi+20h]
- mov ecx, [eax+ecx*4+1000h]
- mov [eax+ebx*4], ecx
- mov ecx, [esp+20h+var_4]
- mov ebx, [esp+20h+arg_4]
- xor ebp, ebp
- cmp ecx, [esi+18h]
- mov eax, 1
- jnb short loc_4CC4A9
- mov edx, edi
- sub edx, ecx
- mov dl, [edx]
- cmp dl, [edi]
- jnz short loc_4CC4A9
- mov eax, 2
- lea edx, [ecx-1]
- mov [ebx], eax
- mov [ebx+4], edx
- mov ebp, eax
-
-loc_4CC4A9: ; CODE XREF: sub_4CC3B0+DEj
- ; sub_4CC3B0+E8j
- mov edx, [esp+20h+var_10]
- cmp ecx, edx
- jz short loc_4CC4D5
- cmp edx, [esi+18h]
- jnb short loc_4CC4D5
- mov edx, edi
- sub edx, [esp+20h+var_10]
- mov dl, [edx]
- cmp dl, [edi]
- jnz short loc_4CC4D5
- mov ecx, [esp+20h+var_10]
- lea edx, [ecx-1]
- mov [ebx+ebp*4+4], edx
- mov eax, 3
- add ebp, 2
-
-loc_4CC4D5: ; CODE XREF: sub_4CC3B0+FFj
- ; sub_4CC3B0+104j ...
- test ebp, ebp
- mov edx, [esp+20h+arg_0]
- jz short loc_4CC553
- cmp eax, edx
- jz short loc_4CC4FE
- mov edx, eax
- sub edx, ecx
- add edx, edi
-
-loc_4CC4E7: ; CODE XREF: sub_4CC3B0+148j
- mov cl, [edx]
- cmp cl, [eax+edi]
- jnz short loc_4CC4FA
- add eax, 1
- add edx, 1
- cmp eax, [esp+20h+arg_0]
- jnz short loc_4CC4E7
-
-loc_4CC4FA: ; CODE XREF: sub_4CC3B0+13Cj
- mov edx, [esp+20h+arg_0]
-
-loc_4CC4FE: ; CODE XREF: sub_4CC3B0+12Fj
- cmp eax, edx
- mov [ebx+ebp*4-8], eax
- jnz short loc_4CC553
- mov eax, [esi+2Ch]
- mov ecx, [esi+18h]
- push eax
- mov eax, [esi+14h]
- push ecx
- mov ecx, [esi+24h]
- push eax
- mov eax, [esi]
- push ecx
- mov ecx, [esi+4]
- push eax
- mov eax, [esp+34h+var_8]
- push ecx
- push eax
- push edx
- call sub_4CC040
- mov eax, 1
- add [esi+14h], eax
- add [esi], eax
- add [esi+4], eax
- mov eax, [esi+4]
- add esp, 20h
- cmp eax, [esi+8]
- jnz short loc_4CC549
- push esi
- call sub_4CBD50
- add esp, 4
-
-loc_4CC549: ; CODE XREF: sub_4CC3B0+18Ej
- pop edi
- mov eax, ebp
- pop ebp
- pop ebx
- pop esi
- add esp, 10h
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CC553: ; CODE XREF: sub_4CC3B0+12Bj
- ; sub_4CC3B0+154j
- cmp eax, 3
- jnb short loc_4CC55D
- mov eax, 3
-
-loc_4CC55D: ; CODE XREF: sub_4CC3B0+1A6j
- push eax
- mov eax, [esi+2Ch]
- lea ecx, [ebx+ebp*4]
- push ecx
- mov ecx, [esi+18h]
- push eax
- mov eax, [esi+14h]
- push ecx
- mov ecx, [esi+24h]
- push eax
- mov eax, [esi]
- push ecx
- mov ecx, [esi+4]
- push eax
- mov eax, [esp+3Ch+var_8]
- push ecx
- push eax
- push edx
- call sub_4CBEC0
- mov edi, eax
- mov eax, 1
- add [esi+14h], eax
- add [esi], eax
- add [esi+4], eax
- mov eax, [esi+4]
- sub edi, ebx
- add esp, 28h
- sar edi, 2
- cmp eax, [esi+8]
- jnz short loc_4CC5AC
- push esi
- call sub_4CBD50
- add esp, 4
-
-loc_4CC5AC: ; CODE XREF: sub_4CC3B0+1F1j
- mov eax, edi
- pop edi
- pop ebp
- pop ebx
- pop esi
- add esp, 10h
- retn
-sub_4CC3B0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CC5C0 proc near ; DATA XREF: sub_4CCAA0+29o
-
-var_10 = dword ptr -10h
-var_8 = dword ptr -8
-var_4 = dword ptr -4
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- sub esp, 10h
- push esi
- mov esi, [esp+14h+arg_0]
- mov eax, [esi+10h]
- cmp eax, 4
- mov [esp+14h+arg_0], eax
- jnb short loc_4CC5F9
- mov eax, 1
- add [esi+14h], eax
- add [esi], eax
- add [esi+4], eax
- mov eax, [esi+4]
- cmp eax, [esi+8]
- jnz short loc_4CC5F2
- push esi
- call sub_4CBD50
- add esp, 4
-
-loc_4CC5F2: ; CODE XREF: sub_4CC5C0+27j
- xor eax, eax
- pop esi
- add esp, 10h
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CC5F9: ; CODE XREF: sub_4CC5C0+12j
- push ebx
- push ebp
- push edi
- mov edi, [esi]
- movzx eax, byte ptr [edi]
- movzx edx, byte ptr [edi+1]
- xor edx, dword_553198[eax*4]
- movzx eax, byte ptr [edi+2]
- movzx ebp, byte ptr [edi+3]
- mov ecx, eax
- add eax, eax
- add eax, eax
- add eax, eax
- xor eax, dword_553198[ebp*4]
- mov ebp, [esi+4]
- shl eax, 5
- shl ecx, 8
- xor eax, edx
- and eax, [esi+28h]
- xor ecx, edx
- mov ebx, edx
- mov edx, [esi+20h]
- and ebx, 3FFh
- sub ebp, [edx+ebx*4]
- and ecx, 0FFFFh
- mov [esp+20h+var_4], ebp
- mov ebp, [esi+4]
- sub ebp, [edx+ecx*4+1000h]
- mov [esp+20h+var_10], ebp
- mov ebp, [edx+eax*4+41000h]
- mov [esp+20h+var_8], ebp
- mov ebp, [esi+4]
- mov [edx+eax*4+41000h], ebp
- mov edx, [esi+20h]
- mov eax, [edx+eax*4+41000h]
- mov [edx+ecx*4+1000h], eax
- mov eax, [esi+20h]
- mov ecx, [eax+ecx*4+1000h]
- mov [eax+ebx*4], ecx
- mov ecx, [esp+20h+var_4]
- mov ebx, [esp+20h+arg_4]
- xor ebp, ebp
- cmp ecx, [esi+18h]
- mov eax, 1
- jnb short loc_4CC6B9
- mov edx, edi
- sub edx, ecx
- mov dl, [edx]
- cmp dl, [edi]
- jnz short loc_4CC6B9
- mov eax, 2
- lea edx, [ecx-1]
- mov [ebx], eax
- mov [ebx+4], edx
- mov ebp, eax
-
-loc_4CC6B9: ; CODE XREF: sub_4CC5C0+DEj
- ; sub_4CC5C0+E8j
- mov edx, [esp+20h+var_10]
- cmp ecx, edx
- jz short loc_4CC6E5
- cmp edx, [esi+18h]
- jnb short loc_4CC6E5
- mov edx, edi
- sub edx, [esp+20h+var_10]
- mov dl, [edx]
- cmp dl, [edi]
- jnz short loc_4CC6E5
- mov ecx, [esp+20h+var_10]
- lea edx, [ecx-1]
- mov [ebx+ebp*4+4], edx
- mov eax, 3
- add ebp, 2
-
-loc_4CC6E5: ; CODE XREF: sub_4CC5C0+FFj
- ; sub_4CC5C0+104j ...
- test ebp, ebp
- jz short loc_4CC747
- cmp eax, [esp+20h+arg_0]
- jz short loc_4CC708
- mov edx, eax
- sub edx, ecx
- add edx, edi
-
-loc_4CC6F5: ; CODE XREF: sub_4CC5C0+146j
- mov cl, [edx]
- cmp cl, [eax+edi]
- jnz short loc_4CC708
- add eax, 1
- add edx, 1
- cmp eax, [esp+20h+arg_0]
- jnz short loc_4CC6F5
-
-loc_4CC708: ; CODE XREF: sub_4CC5C0+12Dj
- ; sub_4CC5C0+13Aj
- cmp eax, [esp+20h+arg_0]
- mov [ebx+ebp*4-8], eax
- jnz short loc_4CC747
- mov edx, [esi+14h]
- mov eax, [esi+24h]
- mov ecx, [esp+20h+var_8]
- mov [eax+edx*4], ecx
- mov eax, 1
- add [esi+14h], eax
- add [esi], eax
- add [esi+4], eax
- mov eax, [esi+4]
- cmp eax, [esi+8]
- jnz short loc_4CC73D
- push esi
- call sub_4CBD50
- add esp, 4
-
-loc_4CC73D: ; CODE XREF: sub_4CC5C0+172j
- pop edi
- mov eax, ebp
- pop ebp
- pop ebx
- pop esi
- add esp, 10h
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CC747: ; CODE XREF: sub_4CC5C0+127j
- ; sub_4CC5C0+150j
- cmp eax, 3
- jnb short loc_4CC751
- mov eax, 3
-
-loc_4CC751: ; CODE XREF: sub_4CC5C0+18Aj
- mov ecx, [esi+18h]
- push eax
- mov eax, [esi+2Ch]
- lea edx, [ebx+ebp*4]
- push edx
- mov edx, [esi+14h]
- push eax
- mov eax, [esi+24h]
- push ecx
- mov ecx, [esi]
- push edx
- mov edx, [esi+4]
- push eax
- mov eax, [esp+38h+var_8]
- push ecx
- mov ecx, [esp+3Ch+arg_0]
- push edx
- push eax
- push ecx
- call sub_4CBDE0
- mov edi, eax
- mov eax, 1
- add [esi+14h], eax
- add [esi], eax
- add [esi+4], eax
- mov eax, [esi+4]
- sub edi, ebx
- add esp, 28h
- sar edi, 2
- cmp eax, [esi+8]
- jnz short loc_4CC7A4
- push esi
- call sub_4CBD50
- add esp, 4
-
-loc_4CC7A4: ; CODE XREF: sub_4CC5C0+1D9j
- mov eax, edi
- pop edi
- pop ebp
- pop ebx
- pop esi
- add esp, 10h
- retn
-sub_4CC5C0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CC7B0 proc near ; DATA XREF: sub_4CCAA0+47o
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- push ebx
- push ebp
- mov ebp, [esp+8+arg_4]
- push esi
- mov esi, [esp+0Ch+arg_0]
- push edi
- mov edi, 1
-
-loc_4CC7C1: ; CODE XREF: sub_4CC7B0+6Dj
- mov edx, [esi+10h]
- cmp edx, 2
- jb short loc_4CC802
- mov eax, [esi]
- mov ebx, [esi+4]
- xor ecx, ecx
- mov ch, [eax+1]
- mov cl, [eax]
- mov eax, ecx
- mov ecx, [esi+20h]
- lea eax, [ecx+eax*4]
- mov ecx, [eax]
- mov [eax], ebx
- mov eax, [esi+2Ch]
- push eax
- mov eax, [esi+18h]
- push eax
- mov eax, [esi+14h]
- push eax
- mov eax, [esi+24h]
- push eax
- mov eax, [esi]
- push eax
- mov eax, [esi+4]
- push eax
- push ecx
- push edx
- call sub_4CC040
- add esp, 20h
-
-loc_4CC802: ; CODE XREF: sub_4CC7B0+17j
- add [esi+4], edi
- mov eax, [esi+4]
- add [esi+14h], edi
- add [esi], edi
- cmp eax, [esi+8]
- jnz short loc_4CC81B
- push esi
- call sub_4CBD50
- add esp, 4
-
-loc_4CC81B: ; CODE XREF: sub_4CC7B0+60j
- sub ebp, edi
- jnz short loc_4CC7C1
- pop edi
- pop esi
- pop ebp
- pop ebx
- retn
-sub_4CC7B0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CC830 proc near ; DATA XREF: sub_4CCAA0+5Bo
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- push ebx
- push ebp
- push esi
- mov esi, [esp+0Ch+arg_0]
- push edi
- mov edi, 1
- lea ecx, [ecx+0]
-
-loc_4CC840: ; CODE XREF: sub_4CC830+9Fj
- mov ebp, [esi+10h]
- cmp ebp, 3
- jb short loc_4CC8B2
- mov ecx, [esi]
- movzx edx, byte ptr [ecx]
- movzx eax, byte ptr [ecx+1]
- xor eax, dword_553198[edx*4]
- mov ebx, [esi+4]
- xor edx, edx
- mov dh, [ecx+2]
- xor edx, eax
- and edx, [esi+28h]
- and eax, 3FFh
- mov ecx, edx
- mov edx, [esi+20h]
- mov edi, [edx+ecx*4+1000h]
- lea edx, [edx+ecx*4+1000h]
- mov [edx], ebx
- mov edx, [esi+20h]
- mov ecx, [edx+ecx*4+1000h]
- mov [edx+eax*4], ecx
- mov edx, [esi+2Ch]
- mov eax, [esi+18h]
- mov ecx, [esi+14h]
- push edx
- mov edx, [esi+24h]
- push eax
- mov eax, [esi]
- push ecx
- mov ecx, [esi+4]
- push edx
- push eax
- push ecx
- push edi
- push ebp
- call sub_4CC040
- add esp, 20h
- mov edi, 1
-
-loc_4CC8B2: ; CODE XREF: sub_4CC830+16j
- add [esi+4], edi
- mov eax, [esi+4]
- add [esi+14h], edi
- add [esi], edi
- cmp eax, [esi+8]
- jnz short loc_4CC8CB
- push esi
- call sub_4CBD50
- add esp, 4
-
-loc_4CC8CB: ; CODE XREF: sub_4CC830+90j
- sub [esp+10h+arg_4], edi
- jnz loc_4CC840
- pop edi
- pop esi
- pop ebp
- pop ebx
- retn
-sub_4CC830 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CC8E0 proc near ; DATA XREF: sub_4CCAA0+6Ao
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- push ebx
- push ebp
- push esi
- mov esi, [esp+0Ch+arg_0]
- push edi
- mov edi, 1
- lea ecx, [ecx+0]
-
-loc_4CC8F0: ; CODE XREF: sub_4CC8E0+D6j
- mov eax, [esi+10h]
- cmp eax, 4
- mov [esp+10h+arg_0], eax
- jb loc_4CC999
- mov eax, [esi]
- movzx edi, byte ptr [eax+2]
- movzx edx, byte ptr [eax]
- movzx ebx, byte ptr [eax+3]
- movzx ecx, byte ptr [eax+1]
- xor ecx, dword_553198[edx*4]
- mov ebp, [esi+4]
- lea eax, ds:0[edi*8]
- xor eax, dword_553198[ebx*4]
- mov edx, edi
- mov edi, [esi+20h]
- shl eax, 5
- xor eax, ecx
- and eax, [esi+28h]
- shl edx, 8
- mov ebx, [edi+eax*4+41000h]
- xor edx, ecx
- and edx, 0FFFFh
- mov [edi+edx*4+1000h], ebp
- mov edi, [esi+20h]
- mov edx, [edi+edx*4+1000h]
- and ecx, 3FFh
- mov [edi+ecx*4], edx
- mov ecx, [esi+20h]
- mov edx, [esi+4]
- mov [ecx+eax*4+41000h], edx
- mov eax, [esi+2Ch]
- mov ecx, [esi+18h]
- mov edx, [esi+14h]
- push eax
- mov eax, [esi+24h]
- push ecx
- mov ecx, [esi]
- push edx
- mov edx, [esi+4]
- push eax
- mov eax, [esp+20h+arg_0]
- push ecx
- push edx
- push ebx
- push eax
- call sub_4CC040
- add esp, 20h
- mov edi, 1
-
-loc_4CC999: ; CODE XREF: sub_4CC8E0+1Aj
- add [esi+4], edi
- mov eax, [esi+4]
- add [esi+14h], edi
- add [esi], edi
- cmp eax, [esi+8]
- jnz short loc_4CC9B2
- push esi
- call sub_4CBD50
- add esp, 4
-
-loc_4CC9B2: ; CODE XREF: sub_4CC8E0+C7j
- sub [esp+10h+arg_4], edi
- jnz loc_4CC8F0
- pop edi
- pop esi
- pop ebp
- pop ebx
- retn
-sub_4CC8E0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CC9D0 proc near ; DATA XREF: sub_4CCAA0+30o
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- push ebx
- push ebp
- push esi
- mov esi, [esp+0Ch+arg_0]
- push edi
- mov edi, 1
- lea ecx, [ecx+0]
-
-loc_4CC9E0: ; CODE XREF: sub_4CC9D0+BAj
- cmp dword ptr [esi+10h], 4
- jb loc_4CCA6D
- mov eax, [esi]
- movzx edi, byte ptr [eax+2]
- movzx edx, byte ptr [eax]
- movzx ebx, byte ptr [eax+3]
- movzx ecx, byte ptr [eax+1]
- xor ecx, dword_553198[edx*4]
- mov ebp, [esi+4]
- lea eax, ds:0[edi*8]
- xor eax, dword_553198[ebx*4]
- mov edx, edi
- mov edi, [esi+20h]
- shl eax, 5
- xor eax, ecx
- and eax, [esi+28h]
- mov ebx, [edi+eax*4+41000h]
- lea edi, [edi+eax*4+41000h]
- mov [edi], ebp
- mov edi, [esi+20h]
- mov eax, [edi+eax*4+41000h]
- shl edx, 8
- xor edx, ecx
- and edx, 0FFFFh
- mov [edi+edx*4+1000h], eax
- mov eax, [esi+20h]
- mov edx, [eax+edx*4+1000h]
- and ecx, 3FFh
- mov [eax+ecx*4], edx
- mov eax, [esi+14h]
- mov ecx, [esi+24h]
- mov [ecx+eax*4], ebx
- mov edi, 1
-
-loc_4CCA6D: ; CODE XREF: sub_4CC9D0+14j
- add [esi+4], edi
- mov eax, [esi+4]
- add [esi+14h], edi
- add [esi], edi
- cmp eax, [esi+8]
- jnz short loc_4CCA86
- push esi
- call sub_4CBD50
- add esp, 4
-
-loc_4CCA86: ; CODE XREF: sub_4CC9D0+ABj
- sub [esp+10h+arg_4], edi
- jnz loc_4CC9E0
- pop edi
- pop esi
- pop ebp
- pop ebx
- retn
-sub_4CC9D0 endp
-
-; =============== S U B R O U T I N E =======================================
-
-sub_4CCAA0 proc near ; CODE XREF: sub_4D0270+F3p
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- mov eax, [esp+arg_4]
- mov ecx, [esp+arg_0]
- mov dword ptr [eax], offset sub_4CBC80
- mov dword ptr [eax+4], offset loc_4CB960
- mov dword ptr [eax+8], offset loc_4CB970
- mov dword ptr [eax+0Ch], offset loc_4CB950
- cmp dword ptr [ecx+50h], 0
- jnz short loc_4CCAD8
- mov dword ptr [eax+10h], offset sub_4CC5C0
- mov dword ptr [eax+14h], offset sub_4CC9D0
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CCAD8: ; CODE XREF: sub_4CCAA0+27j
- mov ecx, [ecx+48h]
- cmp ecx, 2
- jnz short loc_4CCAEF
- mov dword ptr [eax+10h], offset loc_4CC180
- mov dword ptr [eax+14h], offset sub_4CC7B0
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CCAEF: ; CODE XREF: sub_4CCAA0+3Ej
- cmp ecx, 3
- jnz short loc_4CCB03
- mov dword ptr [eax+10h], offset sub_4CC220
- mov dword ptr [eax+14h], offset sub_4CC830
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CCB03: ; CODE XREF: sub_4CCAA0+52j
- mov dword ptr [eax+10h], offset sub_4CC3B0
- mov dword ptr [eax+14h], offset sub_4CC8E0
- retn
-sub_4CCAA0 endp
-
-; ---------------------------------------------------------------------------
-
-Interface1_AddRef proc near ; DATA XREF: .rdata:00517A94o
-;sub_4CCB80
-
-arg_0 = dword ptr 4
- mov eax, [esp+arg_0]
- add dword ptr [eax+4], 1
- mov eax, [eax+4]
- retn 4
-Interface1_AddRef endp
-
-; ---------------------------------------------------------------------------
-
-sub_4CCB20 proc near ; DATA XREF: .rdata:00517A9Co
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-arg_8 = dword ptr 0Ch
-arg_C = dword ptr 10h
-
- push esi
- mov esi, [esp+4+arg_0]
- mov ecx, [esi+10h]
- sub ecx, [esi+18h]
- mov eax, [esi+14h]
- sbb eax, [esi+1Ch]
- xor edx, edx
- cmp edx, eax
- push edi
- mov edi, [esp+8+arg_8]
- jb short loc_4CCB48
- ja short loc_4CCB42
- cmp edi, ecx
- jbe short loc_4CCB48
-
-loc_4CCB42: ; CODE XREF: sub_4CCB20+1Cj
- mov edi, [esi+10h]
- sub edi, [esi+18h]
-
-loc_4CCB48: ; CODE XREF: sub_4CCB20+1Aj
- ; sub_4CCB20+20j
- mov eax, [esp+8+arg_C]
- test eax, eax
- jz short loc_4CCB52
- mov [eax], edi
-
-loc_4CCB52: ; CODE XREF: sub_4CCB20+2Ej
- test edi, edi
- jz short loc_4CCB72
- mov eax, [esi+8]
- add eax, [esi+18h]
- mov ecx, [esp+8+arg_4]
- push edi ; size_t
- push eax ; void *
- push ecx ; void *
- call _memcpy ; Microsoft VisualC 2-8/net runtime
- add esp, 0Ch
- add [esi+18h], edi
- adc dword ptr [esi+1Ch], 0
-
-loc_4CCB72: ; CODE XREF: sub_4CCB20+34j
- pop edi
- xor eax, eax
- pop esi
- retn 10h
-sub_4CCB20 endp
-
-; ---------------------------------------------------------------------------
-
-sub_4CCB90 proc near ; DATA XREF: .rdata:00517AB0o
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-arg_8 = dword ptr 0Ch
-arg_C = dword ptr 10h
-
- push ebx
- mov ebx, [esp+4+arg_8]
- push esi
- mov esi, [esp+8+arg_0]
- mov ecx, [esi+10h]
- mov eax, [esi+14h]
- push edi
- xor edi, edi
- sub ecx, [esi+18h]
- sbb eax, [esi+1Ch]
- cmp edi, eax
- jb short loc_4CCBC2
- ja short loc_4CCBB3
- cmp ebx, ecx
- jbe short loc_4CCBC2
-
-loc_4CCBB3: ; CODE XREF: sub_4CCB90+1Dj
- pop edi
- mov byte ptr [esi+20h], 1
- pop esi
- mov eax, 80004005h
- pop ebx
- retn 10h
-
-loc_4CCBC2: ; CODE XREF: sub_4CCB90+1Bj
- ; sub_4CCB90+21j
- mov ecx, [esi+8]
- mov eax, [esp+0Ch+arg_4]
- add ecx, [esi+18h]
- push ebx ; size_t
- push eax ; void *
- push ecx ; void *
- call _memcpy ; Microsoft VisualC 2-8/net runtime
- mov eax, [esp+18h+arg_C]
- add esp, 0Ch
- add [esi+18h], ebx
- adc [esi+1Ch], edi
- test eax, eax
- jz short loc_4CCBE7
- mov [eax], ebx
-
-loc_4CCBE7: ; CODE XREF: sub_4CCB90+53j
- pop edi
- pop esi
- xor eax, eax
- pop ebx
- retn 10h
-sub_4CCB90 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; ---------------------------------------------------------------------------
-
-LzmaProps_Decode proc near ; CODE XREF: Decompress_lzma_internal+35p
-;sub_4CCBF0
-
-propsRes = dword ptr 4
-propsData = dword ptr 8
-propsSize = dword ptr 0Ch
-
- cmp [esp+propsSize], 5 ; LZMA_PROPS_SIZE
- jge short loc_4CCBFD
-
-loc_4CCBF7: ; CODE XREF: LzmaProps_Decode+16j
- mov eax, 1
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CCBFD: ; CODE XREF: LzmaProps_Decode+5j
- mov eax, [esp+propsData]
- mov cl, [eax]
- cmp cl, 0E1h ; 9 * 5 * 5
- jnb short loc_4CCBF7
- cmp cl, 2Dh
- push edi
- mov edi, [esp+4+propsRes]
- mov dword ptr [edi+8], 0
- jb short loc_4CCC40
- push esi
- movzx esi, cl
- mov eax, 6C16C16Dh
- mul esi
- mov eax, esi
- sub eax, edx
- shr eax, 1
- add eax, edx
- shr eax, 5
- movzx eax, al
- mov edx, eax
- pop esi
-
-loc_4CCC35: ; CODE XREF: LzmaProps_Decode+4Bj
- add cl, 0D3h
- sub eax, 1
- jnz short loc_4CCC35
- mov [edi+8], edx
-
-loc_4CCC40: ; CODE XREF: LzmaProps_Decode+27j
- cmp cl, 9
- mov dword ptr [edi+4], 0
- jb short loc_4CCC6B
- movzx edx, cl
- mov eax, 38E38E39h
- mul edx
- shr edx, 1
- movzx eax, dl
- mov edx, eax
- lea ecx, [ecx+0]
-
-loc_4CCC60: ; CODE XREF: LzmaProps_Decode+76j
- add cl, 0F7h
- sub eax, 1
- jnz short loc_4CCC60
- mov [edi+4], edx
-
-loc_4CCC6B: ; CODE XREF: LzmaProps_Decode+5Aj
- movzx eax, cl
- mov [edi], eax
- xor eax, eax
- pop edi
- retn
-LzmaProps_Decode endp
-
-sub_4CCC80 proc near ; CODE XREF: Decompress_lzma_internal+97p
-
-var_3C = dword ptr -3Ch
-var_38 = dword ptr -38h
-var_34 = dword ptr -34h
-var_30 = dword ptr -30h
-var_2C = dword ptr -2Ch
-var_28 = dword ptr -28h
-var_24 = dword ptr -24h
-var_20 = dword ptr -20h
-var_1C = dword ptr -1Ch
-var_18 = dword ptr -18h
-var_14 = dword ptr -14h
-var_10 = dword ptr -10h
-var_C = dword ptr -0Ch
-var_8 = dword ptr -8
-var_4 = dword ptr -4
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-arg_8 = dword ptr 0Ch
-arg_C = dword ptr 10h
-arg_10 = dword ptr 14h
-arg_14 = dword ptr 18h
-arg_18 = dword ptr 1Ch
-
- sub esp, 3Ch
- mov eax, [esp+3Ch+arg_0]
- mov ecx, [eax+8]
- push ebx
- push ebp
- mov ebp, 1
- mov edx, ebp
- shl edx, cl
- mov ecx, [eax+4]
- xor ebx, ebx
- push esi
- sub edx, ebp
- mov [esp+48h+var_C], edx
- mov edx, ebp
- shl edx, cl
- mov ecx, [esp+48h+arg_C]
- push edi
- mov edi, [eax+0Ch]
- sub edx, ebp
- mov [esp+4Ch+var_8], edx
- mov edx, [eax]
- mov [ecx], ebx
- mov ecx, [esp+4Ch+arg_18]
- mov [ecx], ebx
- mov ecx, [eax+4]
- add ecx, edx
- mov eax, 300h
- shl eax, cl
- mov [esp+4Ch+var_20], edi
- mov [esp+4Ch+var_2C], ebx
- mov byte ptr [esp+4Ch+arg_0], bl
- add eax, 736h
- mov [esp+4Ch+var_14], edx
- mov [esp+4Ch+var_34], ebx
- mov [esp+4Ch+var_38], ebp
- mov [esp+4Ch+var_24], ebp
- mov [esp+4Ch+var_28], ebp
- mov [esp+4Ch+var_18], ebp
- jz short loc_4CCD04
- mov ecx, eax
- shr ecx, 1
- mov eax, 4000400h
- rep stosd
- adc ecx, ecx
- rep stosw
-
-loc_4CCD04: ; CODE XREF: sub_4CCC80+72j
- mov edx, [esp+4Ch+arg_8]
- mov ecx, [esp+4Ch+arg_4]
- lea edi, [ecx+edx]
- xor esi, esi
- or eax, 0FFFFFFFFh
- mov [esp+4Ch+var_3C], edi
- xor edx, edx
- lea ebx, [ebx+0]
-
-loc_4CCD20: ; CODE XREF: sub_4CCC80+BCj
- cmp ecx, edi
- jz loc_4CCF0B
- movzx ebp, byte ptr [ecx]
- shl esi, 8
- or esi, ebp
- mov ebp, 1
- add edx, ebp
- add ecx, ebp
- cmp edx, 5
- jl short loc_4CCD20
- cmp [esp+4Ch+arg_14], ebx
- mov [esp+4Ch+arg_8], ecx
- jbe loc_4CCFCD
- lea esp, [esp+0]
-
-loc_4CCD50: ; CODE XREF: sub_4CCC80+32Dj
- mov edx, [esp+4Ch+var_34]
- mov ecx, [esp+4Ch+var_C]
- and ecx, [esp+4Ch+var_2C]
- mov edi, [esp+4Ch+var_20]
- mov ebx, edx
- shl ebx, 4
- add ebx, ecx
- cmp eax, 1000000h
- lea ebx, [edi+ebx*2]
- mov [esp+4Ch+var_1C], ecx
- mov [esp+4Ch+var_30], ebx
- jnb short loc_4CCD99
- mov ecx, [esp+4Ch+arg_8]
- cmp ecx, [esp+4Ch+var_3C]
- jz loc_4CD6E2
- movzx ebp, byte ptr [ecx]
- shl esi, 8
- shl eax, 8
- or esi, ebp
- add ecx, 1
- mov [esp+4Ch+arg_8], ecx
-
-loc_4CCD99: ; CODE XREF: sub_4CCC80+F7j
- movzx ebx, word ptr [ebx]
- movzx ebp, bx
- mov ecx, eax
- shr ecx, 0Bh
- imul ecx, ebp
- cmp esi, ecx
- jnb loc_4CCFF4
- mov edi, [esp+4Ch+var_30]
- mov eax, ecx
- mov ecx, 800h
- sub ecx, ebp
- mov ebp, [esp+4Ch+var_8]
- sar ecx, 5
- add ecx, ebx
- movzx ebx, byte ptr [esp+4Ch+arg_0]
- mov [edi], cx
- mov edi, [esp+4Ch+var_2C]
- mov ecx, 8
- sub cl, byte ptr [esp+4Ch+var_14]
- and ebp, edi
- shr ebx, cl
- mov ecx, [esp+4Ch+var_14]
- shl ebp, cl
- mov ecx, [esp+4Ch+var_20]
- mov edx, 1
- add ebx, ebp
- imul ebx, 600h
- cmp [esp+4Ch+var_34], 7
- lea ebp, [ebx+ecx+0E6Ch]
- mov [esp+4Ch+var_30], ebp
- jl loc_4CCEB0
- sub edi, [esp+4Ch+var_38]
- mov ecx, [esp+4Ch+arg_10]
- movzx ebx, byte ptr [edi+ecx]
- jmp short loc_4CCE20
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CCE20: ; CODE XREF: sub_4CCC80+197j
- ; sub_4CCC80+2C6j
- add ebx, ebx
- mov [esp+4Ch+var_10], ebx
- and ebx, 100h
- cmp eax, 1000000h
- lea ecx, [ebx+edx]
- lea ebp, [ebp+ecx*2+200h]
- mov [esp+4Ch+arg_0], ebp
- jnb short loc_4CCE61
- mov ecx, [esp+4Ch+arg_8]
- cmp ecx, [esp+4Ch+var_3C]
- jz loc_4CD6E2
- movzx edi, byte ptr [ecx]
- shl esi, 8
- shl eax, 8
- or esi, edi
- add ecx, 1
- mov [esp+4Ch+arg_8], ecx
-
-loc_4CCE61: ; CODE XREF: sub_4CCC80+1BFj
- movzx edi, word ptr [ebp+0]
- movzx ebp, di
- mov ecx, eax
- shr ecx, 0Bh
- imul ecx, ebp
- cmp esi, ecx
- jnb loc_4CCF15
- mov eax, ecx
- mov ecx, 800h
- sub ecx, ebp
- sar ecx, 5
- add ecx, edi
- mov edi, [esp+4Ch+arg_0]
- add edx, edx
- test ebx, ebx
- mov [edi], cx
- jz loc_4CCF36
-
-loc_4CCE97: ; CODE XREF: sub_4CCC80+2B0j
- cmp edx, 100h
- jge loc_4CCF70
- mov ebp, [esp+4Ch+var_30]
- jmp short loc_4CCEB0
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CCEB0: ; CODE XREF: sub_4CCC80+185j
- ; sub_4CCC80+227j ...
- cmp eax, 1000000h
- lea ecx, [edx+edx]
- mov [esp+4Ch+arg_0], ecx
- jnb short loc_4CCEDE
- mov edi, [esp+4Ch+arg_8]
- cmp edi, [esp+4Ch+var_3C]
- jz loc_4CD6E2
- movzx ebx, byte ptr [edi]
- shl esi, 8
- shl eax, 8
- or esi, ebx
- add edi, 1
- mov [esp+4Ch+arg_8], edi
-
-loc_4CCEDE: ; CODE XREF: sub_4CCC80+23Cj
- movzx edi, word ptr [ecx+ebp]
- movzx ebx, di
- mov ecx, eax
- shr ecx, 0Bh
- imul ecx, ebx
- cmp esi, ecx
- jnb short loc_4CCF4B
- mov eax, ecx
- mov ecx, 800h
- sub ecx, ebx
- sar ecx, 5
- add ecx, edi
- mov edi, [esp+4Ch+arg_0]
- mov [edi+ebp], cx
- add edx, edx
- jmp short loc_4CCF64
-; ---------------------------------------------------------------------------
-
-loc_4CCF0B: ; CODE XREF: sub_4CCC80+A2j
- pop edi
- pop esi
- mov eax, ebp
- pop ebp
- pop ebx
- add esp, 3Ch
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CCF15: ; CODE XREF: sub_4CCC80+1F2j
- sub eax, ecx
- sub esi, ecx
- mov cx, di
- shr cx, 5
- sub di, cx
- test ebx, ebx
- mov ecx, [esp+4Ch+arg_0]
- mov [ecx], di
- lea edx, [edx+edx+1]
- jz loc_4CCE97
-
-loc_4CCF36: ; CODE XREF: sub_4CCC80+211j
- cmp edx, 100h
- jge short loc_4CCF70
- mov ebp, [esp+4Ch+var_30]
- mov ebx, [esp+4Ch+var_10]
- jmp loc_4CCE20
-; ---------------------------------------------------------------------------
-
-loc_4CCF4B: ; CODE XREF: sub_4CCC80+26Fj
- mov dx, di
- shr dx, 5
- sub di, dx
- mov edx, [esp+4Ch+arg_0]
- sub eax, ecx
- sub esi, ecx
- mov [edx+ebp], di
- add edx, 1
-
-loc_4CCF64: ; CODE XREF: sub_4CCC80+289j
- cmp edx, 100h
- jl loc_4CCEB0
-
-loc_4CCF70: ; CODE XREF: sub_4CCC80+21Dj
- ; sub_4CCC80+2BCj
- mov ecx, [esp+4Ch+var_2C]
- mov edi, [esp+4Ch+arg_10]
- mov [ecx+edi], dl
- add ecx, 1
- mov [esp+4Ch+var_2C], ecx
- mov ecx, [esp+4Ch+var_34]
- cmp ecx, 4
- mov byte ptr [esp+4Ch+arg_0], dl
- jge short loc_4CCF99
- mov [esp+4Ch+var_34], 0
- jmp short loc_4CCFA5
-; ---------------------------------------------------------------------------
-
-loc_4CCF99: ; CODE XREF: sub_4CCC80+30Dj
- cmp ecx, 0Ah
- jge short loc_4CCFEF
- sub ecx, 3
-
-loc_4CCFA1: ; CODE XREF: sub_4CCC80+372j
- mov [esp+4Ch+var_34], ecx
-
-loc_4CCFA5: ; CODE XREF: sub_4CCC80+317j
- ; sub_4CCC80+530j ...
- mov ecx, [esp+4Ch+var_2C]
- cmp ecx, [esp+4Ch+arg_14]
- jb loc_4CCD50
-
-loc_4CCFB3: ; CODE XREF: sub_4CCC80+A13j
- ; sub_4CCC80+A5Aj
- cmp eax, 1000000h
- jnb short loc_4CCFCD
- mov edx, [esp+4Ch+arg_8]
- cmp edx, [esp+4Ch+var_3C]
- jz loc_4CD6E2
- add [esp+4Ch+arg_8], 1
-
-loc_4CCFCD: ; CODE XREF: sub_4CCC80+C6j
- ; sub_4CCC80+338j
- mov eax, [esp+4Ch+arg_8]
- sub eax, [esp+4Ch+arg_4]
- mov ecx, [esp+4Ch+arg_C]
- mov edx, [esp+4Ch+var_2C]
- pop edi
- mov [ecx], eax
- mov eax, [esp+48h+arg_18]
- pop esi
- pop ebp
- mov [eax], edx
- xor eax, eax
- pop ebx
- add esp, 3Ch
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CCFEF: ; CODE XREF: sub_4CCC80+31Cj
- sub ecx, 6
- jmp short loc_4CCFA1
-; ---------------------------------------------------------------------------
-
-loc_4CCFF4: ; CODE XREF: sub_4CCC80+129j
- sub eax, ecx
- sub esi, ecx
- mov cx, bx
- shr cx, 5
- sub bx, cx
- cmp eax, 1000000h
- mov ecx, [esp+4Ch+var_30]
- mov [ecx], bx
- jnb short loc_4CD030
- mov ecx, [esp+4Ch+arg_8]
- cmp ecx, [esp+4Ch+var_3C]
- jz loc_4CD6E2
- movzx ebx, byte ptr [ecx]
- shl esi, 8
- shl eax, 8
- or esi, ebx
- add ecx, 1
- mov [esp+4Ch+arg_8], ecx
-
-loc_4CD030: ; CODE XREF: sub_4CCC80+38Ej
- movzx ebx, word ptr [edi+edx*2+180h]
- movzx ebp, bx
- mov ecx, eax
- shr ecx, 0Bh
- imul ecx, ebp
- cmp esi, ecx
- jnb short loc_4CD096
- mov eax, ecx
- mov ecx, 800h
- sub ecx, ebp
- sar ecx, 5
- add ecx, ebx
- mov [edi+edx*2+180h], cx
- mov ecx, [esp+4Ch+var_28]
- mov ebp, [esp+4Ch+var_1C]
- mov [esp+4Ch+var_18], ecx
- mov ecx, [esp+4Ch+var_24]
- mov [esp+4Ch+var_28], ecx
- mov ecx, [esp+4Ch+var_38]
- mov [esp+4Ch+var_24], ecx
- xor ecx, ecx
- cmp edx, 7
- setl cl
- sub ecx, 1
- and ecx, 3
- mov [esp+4Ch+var_34], ecx
- lea ecx, [edi+664h]
- jmp loc_4CD30B
-; ---------------------------------------------------------------------------
-
-loc_4CD096: ; CODE XREF: sub_4CCC80+3C5j
- sub eax, ecx
- sub esi, ecx
- mov cx, bx
- shr cx, 5
- sub bx, cx
- cmp eax, 1000000h
- mov [edi+edx*2+180h], bx
- jnb short loc_4CD0D3
- mov ecx, [esp+4Ch+arg_8]
- cmp ecx, [esp+4Ch+var_3C]
- jz loc_4CD6E2
- movzx ebx, byte ptr [ecx]
- shl esi, 8
- shl eax, 8
- or esi, ebx
- add ecx, 1
- mov [esp+4Ch+arg_8], ecx
-
-loc_4CD0D3: ; CODE XREF: sub_4CCC80+431j
- movzx ebx, word ptr [edi+edx*2+198h]
- movzx ebp, bx
- mov ecx, eax
- shr ecx, 0Bh
- imul ecx, ebp
- cmp esi, ecx
- mov [esp+4Ch+arg_0], ebx
- jnb loc_4CD1D3
- mov ebx, 800h
- sub ebx, ebp
- mov ebp, [esp+4Ch+var_1C]
- sar ebx, 5
- add ebx, [esp+4Ch+arg_0]
- mov eax, ecx
- mov [edi+edx*2+198h], bx
- lea ebx, [edx+0Fh]
- shl ebx, 4
- add ebx, ebp
- cmp ecx, 1000000h
- lea ebx, [edi+ebx*2]
- mov [esp+4Ch+var_30], ebx
- jnb short loc_4CD147
- mov ebx, [esp+4Ch+arg_8]
- cmp ebx, [esp+4Ch+var_3C]
- jz loc_4CD6E2
- shl ecx, 8
- mov eax, ecx
- movzx ecx, byte ptr [ebx]
- shl esi, 8
- or esi, ecx
- add ebx, 1
- mov [esp+4Ch+arg_8], ebx
-
-loc_4CD147: ; CODE XREF: sub_4CCC80+4A3j
- mov ecx, [esp+4Ch+var_30]
- movzx ecx, word ptr [ecx]
- mov [esp+4Ch+arg_0], ecx
- movzx ebx, cx
- mov ecx, eax
- shr ecx, 0Bh
- imul ecx, ebx
- cmp esi, ecx
- jnb short loc_4CD1B5
- mov edi, [esp+4Ch+var_30]
- mov eax, ecx
- mov ecx, 800h
- sub ecx, ebx
- sar ecx, 5
- add ecx, [esp+4Ch+arg_0]
- mov [edi], cx
- mov edi, [esp+4Ch+var_2C]
- test edi, edi
- jz loc_4CD6E2
- xor ecx, ecx
- cmp edx, 7
- mov edx, [esp+4Ch+arg_10]
- setnl cl
- lea ecx, [ecx+ecx+9]
- mov [esp+4Ch+var_34], ecx
- mov ecx, edi
- sub ecx, [esp+4Ch+var_38]
- add edi, 1
- mov cl, [ecx+edx]
- mov [edi+edx-1], cl
- mov byte ptr [esp+4Ch+arg_0], cl
- mov [esp+4Ch+var_2C], edi
- jmp loc_4CCFA5
-; ---------------------------------------------------------------------------
-
-loc_4CD1B5: ; CODE XREF: sub_4CCC80+4DFj
- sub eax, ecx
- sub esi, ecx
- mov ecx, [esp+4Ch+arg_0]
- mov bx, cx
- shr bx, 5
- sub cx, bx
- mov ebx, [esp+4Ch+var_30]
- mov [ebx], cx
- jmp loc_4CD2F0
-; ---------------------------------------------------------------------------
-
-loc_4CD1D3: ; CODE XREF: sub_4CCC80+46Cj
- sub eax, ecx
- sub esi, ecx
- mov cx, bx
- shr cx, 5
- sub bx, cx
- cmp eax, 1000000h
- mov [edi+edx*2+198h], bx
- jnb short loc_4CD210
- mov ecx, [esp+4Ch+arg_8]
- cmp ecx, [esp+4Ch+var_3C]
- jz loc_4CD6E2
- movzx ebx, byte ptr [ecx]
- shl esi, 8
- shl eax, 8
- or esi, ebx
- add ecx, 1
- mov [esp+4Ch+arg_8], ecx
-
-loc_4CD210: ; CODE XREF: sub_4CCC80+56Ej
- movzx ebx, word ptr [edi+edx*2+1B0h]
- movzx ebp, bx
- mov ecx, eax
- shr ecx, 0Bh
- imul ecx, ebp
- cmp esi, ecx
- jnb short loc_4CD246
- mov eax, ecx
- mov ecx, 800h
- sub ecx, ebp
- sar ecx, 5
- add ecx, ebx
- mov [edi+edx*2+1B0h], cx
- mov ecx, [esp+4Ch+var_24]
- jmp loc_4CD2E0
-; ---------------------------------------------------------------------------
-
-loc_4CD246: ; CODE XREF: sub_4CCC80+5A5j
- sub eax, ecx
- sub esi, ecx
- mov cx, bx
- shr cx, 5
- sub bx, cx
- cmp eax, 1000000h
- mov [edi+edx*2+1B0h], bx
- jnb short loc_4CD283
- mov ecx, [esp+4Ch+arg_8]
- cmp ecx, [esp+4Ch+var_3C]
- jz loc_4CD6E2
- movzx ebx, byte ptr [ecx]
- shl esi, 8
- shl eax, 8
- or esi, ebx
- add ecx, 1
- mov [esp+4Ch+arg_8], ecx
-
-loc_4CD283: ; CODE XREF: sub_4CCC80+5E1j
- movzx ebx, word ptr [edi+edx*2+1C8h]
- movzx ebp, bx
- mov ecx, eax
- shr ecx, 0Bh
- imul ecx, ebp
- cmp esi, ecx
- jnb short loc_4CD2B6
- mov eax, ecx
- mov ecx, 800h
- sub ecx, ebp
- sar ecx, 5
- add ecx, ebx
- mov [edi+edx*2+1C8h], cx
- mov ecx, [esp+4Ch+var_28]
- jmp short loc_4CD2D8
-; ---------------------------------------------------------------------------
-
-loc_4CD2B6: ; CODE XREF: sub_4CCC80+618j
- sub eax, ecx
- sub esi, ecx
- mov cx, bx
- shr cx, 5
- sub bx, cx
- mov ecx, [esp+4Ch+var_18]
- mov [edi+edx*2+1C8h], bx
- mov ebx, [esp+4Ch+var_28]
- mov [esp+4Ch+var_18], ebx
-
-loc_4CD2D8: ; CODE XREF: sub_4CCC80+634j
- mov ebx, [esp+4Ch+var_24]
- mov [esp+4Ch+var_28], ebx
-
-loc_4CD2E0: ; CODE XREF: sub_4CCC80+5C1j
- mov ebx, [esp+4Ch+var_38]
- mov ebp, [esp+4Ch+var_1C]
- mov [esp+4Ch+var_24], ebx
- mov [esp+4Ch+var_38], ecx
-
-loc_4CD2F0: ; CODE XREF: sub_4CCC80+54Ej
- xor ecx, ecx
- cmp edx, 7
- setnl cl
- sub ecx, 1
- and ecx, 0FFFFFFFDh
- add ecx, 0Bh
- mov [esp+4Ch+var_34], ecx
- lea ecx, [edi+0A68h]
-
-loc_4CD30B: ; CODE XREF: sub_4CCC80+411j
- cmp eax, 1000000h
- jnb short loc_4CD332
- mov edx, [esp+4Ch+arg_8]
- cmp edx, [esp+4Ch+var_3C]
- jz loc_4CD6E2
- movzx edi, byte ptr [edx]
- shl esi, 8
- shl eax, 8
- or esi, edi
- add edx, 1
- mov [esp+4Ch+arg_8], edx
-
-loc_4CD332: ; CODE XREF: sub_4CCC80+690j
- movzx edi, word ptr [ecx]
- movzx ebx, di
- mov edx, eax
- shr edx, 0Bh
- imul edx, ebx
- cmp esi, edx
- jnb short loc_4CD36E
- mov eax, edx
- mov edx, 800h
- sub edx, ebx
- sar edx, 5
- add edx, edi
- mov [ecx], dx
- shl ebp, 4
- lea ecx, [ecx+ebp+4]
- mov [esp+4Ch+var_1C], 0
- mov edx, 3
- jmp loc_4CD409
-; ---------------------------------------------------------------------------
-
-loc_4CD36E: ; CODE XREF: sub_4CCC80+6C2j
- sub eax, edx
- sub esi, edx
- mov dx, di
- shr dx, 5
- sub di, dx
- cmp eax, 1000000h
- mov [ecx], di
- jnb short loc_4CD3A6
- mov edx, [esp+4Ch+arg_8]
- cmp edx, [esp+4Ch+var_3C]
- jz loc_4CD6E2
- movzx edi, byte ptr [edx]
- shl esi, 8
- shl eax, 8
- or esi, edi
- add edx, 1
- mov [esp+4Ch+arg_8], edx
-
-loc_4CD3A6: ; CODE XREF: sub_4CCC80+704j
- movzx edx, word ptr [ecx+2]
- movzx ebx, dx
- mov edi, eax
- shr edi, 0Bh
- imul edi, ebx
- cmp esi, edi
- jnb short loc_4CD3E4
- mov eax, edi
- mov edi, 800h
- sub edi, ebx
- sar edi, 5
- add edi, edx
- shl ebp, 4
- mov [ecx+2], di
- lea ecx, [ecx+ebp+104h]
- mov [esp+4Ch+var_1C], 8
- mov edx, 3
- jmp short loc_4CD409
-; ---------------------------------------------------------------------------
-
-loc_4CD3E4: ; CODE XREF: sub_4CCC80+737j
- sub eax, edi
- sub esi, edi
- mov di, dx
- shr di, 5
- sub dx, di
- mov [ecx+2], dx
- add ecx, 204h
- mov [esp+4Ch+var_1C], 10h
- mov edx, 8
-
-loc_4CD409: ; CODE XREF: sub_4CCC80+6E9j
- ; sub_4CCC80+762j
- mov [esp+4Ch+arg_0], edx
- mov [esp+4Ch+var_10], edx
- mov ebx, 1
- jmp short loc_4CD420
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CD420: ; CODE XREF: sub_4CCC80+796j
- ; sub_4CCC80+819j
- cmp eax, 1000000h
- mov edx, [esp+4Ch+arg_8]
- lea edi, [ebx+ebx]
- mov [esp+4Ch+var_30], edi
- jnb short loc_4CD44E
- cmp edx, [esp+4Ch+var_3C]
- jz loc_4CD6E2
- movzx ebp, byte ptr [edx]
- shl esi, 8
- shl eax, 8
- or esi, ebp
- add edx, 1
- mov [esp+4Ch+arg_8], edx
-
-loc_4CD44E: ; CODE XREF: sub_4CCC80+7B0j
- movzx edi, word ptr [edi+ecx]
- movzx ebp, di
- mov edx, eax
- shr edx, 0Bh
- imul edx, ebp
- cmp esi, edx
- jnb short loc_4CD47B
- mov eax, edx
- mov edx, 800h
- sub edx, ebp
- sar edx, 5
- add edx, edi
- mov edi, [esp+4Ch+var_30]
- mov [edi+ecx], dx
- add ebx, ebx
- jmp short loc_4CD494
-; ---------------------------------------------------------------------------
-
-loc_4CD47B: ; CODE XREF: sub_4CCC80+7DFj
- mov ebx, [esp+4Ch+var_30]
- sub eax, edx
- sub esi, edx
- mov dx, di
- shr dx, 5
- sub di, dx
- mov [ebx+ecx], di
- add ebx, 1
-
-loc_4CD494: ; CODE XREF: sub_4CCC80+7F9j
- sub [esp+4Ch+var_10], 1
- jnz short loc_4CD420
- mov ecx, [esp+4Ch+arg_0]
- mov edx, 1
- shl edx, cl
- mov ecx, [esp+4Ch+var_1C]
- sub ecx, edx
- add ebx, ecx
- cmp [esp+4Ch+var_34], 4
- mov [esp+4Ch+var_4], ebx
- jge loc_4CD69D
- add [esp+4Ch+var_34], 7
- cmp ebx, 4
- jl short loc_4CD4CC
- mov ebx, 3
-
-loc_4CD4CC: ; CODE XREF: sub_4CCC80+845j
- mov ecx, [esp+4Ch+var_20]
- shl ebx, 7
- lea ecx, [ebx+ecx+360h]
- mov [esp+4Ch+var_30], ecx
- mov [esp+4Ch+arg_0], 6
- mov edi, 1
- jmp short loc_4CD4F0
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CD4F0: ; CODE XREF: sub_4CCC80+86Bj
- ; sub_4CCC80+8E3j
- cmp eax, 1000000h
- mov edx, [esp+4Ch+arg_8]
- lea ebx, [edi+edi]
- jnb short loc_4CD51A
- cmp edx, [esp+4Ch+var_3C]
- jz loc_4CD6E2
- movzx ebp, byte ptr [edx]
- shl esi, 8
- shl eax, 8
- or esi, ebp
- add edx, 1
- mov [esp+4Ch+arg_8], edx
-
-loc_4CD51A: ; CODE XREF: sub_4CCC80+87Cj
- movzx edx, word ptr [ebx+ecx]
- movzx ebp, dx
- mov ecx, eax
- shr ecx, 0Bh
- imul ecx, ebp
- cmp esi, ecx
- jnb short loc_4CD545
- mov eax, ecx
- mov ecx, 800h
- sub ecx, ebp
- sar ecx, 5
- add ecx, edx
- mov [esp+4Ch+var_10], ecx
- mov edx, ecx
- add edi, edi
- jmp short loc_4CD556
-; ---------------------------------------------------------------------------
-
-loc_4CD545: ; CODE XREF: sub_4CCC80+8ABj
- sub eax, ecx
- sub esi, ecx
- mov cx, dx
- shr cx, 5
- sub dx, cx
- lea edi, [ebx+1]
-
-loc_4CD556: ; CODE XREF: sub_4CCC80+8C3j
- sub [esp+4Ch+arg_0], 1
- mov ecx, [esp+4Ch+var_30]
- mov [ebx+ecx], dx
- jnz short loc_4CD4F0
- sub edi, 40h
- cmp edi, 4
- jl loc_4CD68A
- mov ebx, 1
- mov ecx, edi
- mov edx, edi
- sar ecx, 1
- and edx, ebx
- sub ecx, ebx
- or edx, 2
- cmp edi, 0Eh
- mov [esp+4Ch+var_30], ecx
- jge short loc_4CD5A1
- shl edx, cl
- mov ecx, [esp+4Ch+var_20]
- mov [esp+4Ch+var_38], edx
- sub edx, edi
- lea ebp, [ecx+edx*2+55Eh]
- jmp short loc_4CD5F3
-; ---------------------------------------------------------------------------
-
-loc_4CD5A1: ; CODE XREF: sub_4CCC80+90Aj
- mov edi, [esp+4Ch+arg_8]
- sub ecx, 4
-
-loc_4CD5A8: ; CODE XREF: sub_4CCC80+958j
- cmp eax, 1000000h
- jnb short loc_4CD5CA
- cmp edi, [esp+4Ch+var_3C]
- jz loc_4CD6EF
- movzx ebp, byte ptr [edi]
- shl esi, 8
- shl eax, 8
- or esi, ebp
- add edi, ebx
- mov [esp+4Ch+arg_8], edi
-
-loc_4CD5CA: ; CODE XREF: sub_4CCC80+92Dj
- shr eax, 1
- add edx, edx
- cmp esi, eax
- jb short loc_4CD5D6
- sub esi, eax
- or edx, ebx
-
-loc_4CD5D6: ; CODE XREF: sub_4CCC80+950j
- sub ecx, ebx
- jnz short loc_4CD5A8
- mov ebp, [esp+4Ch+var_20]
- add ebp, 644h
- shl edx, 4
- mov [esp+4Ch+var_38], edx
- mov [esp+4Ch+var_30], 4
-
-loc_4CD5F3: ; CODE XREF: sub_4CCC80+91Fj
- mov [esp+4Ch+var_1C], ebx
- mov [esp+4Ch+arg_0], ebx
- jmp short loc_4CD600
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CD600: ; CODE XREF: sub_4CCC80+97Bj
- ; sub_4CCC80+A02j
- mov ebx, [esp+4Ch+arg_0]
- add ebx, ebx
- cmp eax, 1000000h
- jnb short loc_4CD62D
- mov ecx, [esp+4Ch+arg_8]
- cmp ecx, [esp+4Ch+var_3C]
- jz loc_4CD6E2
- movzx edx, byte ptr [ecx]
- shl esi, 8
- shl eax, 8
- or esi, edx
- add ecx, 1
- mov [esp+4Ch+arg_8], ecx
-
-loc_4CD62D: ; CODE XREF: sub_4CCC80+98Bj
- movzx edi, word ptr [ebx+ebp]
- movzx ecx, di
- mov edx, eax
- shr edx, 0Bh
- imul edx, ecx
- cmp esi, edx
- jnb short loc_4CD658
- mov eax, edx
- mov edx, 800h
- sub edx, ecx
- sar edx, 5
- add edx, edi
- shl [esp+4Ch+arg_0], 1
- mov [ebx+ebp], dx
- jmp short loc_4CD679
-; ---------------------------------------------------------------------------
-
-loc_4CD658: ; CODE XREF: sub_4CCC80+9BEj
- mov cx, di
- shr cx, 5
- sub di, cx
- sub eax, edx
- sub esi, edx
- mov edx, [esp+4Ch+var_1C]
- mov [ebx+ebp], di
- add ebx, 1
- or [esp+4Ch+var_38], edx
- mov [esp+4Ch+arg_0], ebx
-
-loc_4CD679: ; CODE XREF: sub_4CCC80+9D6j
- shl [esp+4Ch+var_1C], 1
- sub [esp+4Ch+var_30], 1
- jnz loc_4CD600
- jmp short loc_4CD68E
-; ---------------------------------------------------------------------------
-
-loc_4CD68A: ; CODE XREF: sub_4CCC80+8EBj
- mov [esp+4Ch+var_38], edi
-
-loc_4CD68E: ; CODE XREF: sub_4CCC80+A08j
- add [esp+4Ch+var_38], 1
- jz loc_4CCFB3
- mov ebx, [esp+4Ch+var_4]
-
-loc_4CD69D: ; CODE XREF: sub_4CCC80+837j
- mov ebp, [esp+4Ch+var_2C]
- mov ecx, [esp+4Ch+var_38]
- add ebx, 2
- cmp ecx, ebp
- ja short loc_4CD6E2
- mov edi, ebp
- sub edi, ecx
- add edi, [esp+4Ch+arg_10]
-
-loc_4CD6B4: ; CODE XREF: sub_4CCC80+A60j
- mov cl, [edi]
- mov edx, [esp+4Ch+arg_10]
- sub ebx, 1
- mov [edx+ebp], cl
- add ebp, 1
- add edi, 1
- test ebx, ebx
- mov byte ptr [esp+4Ch+arg_0], cl
- mov [esp+4Ch+var_2C], ebp
- jz loc_4CCFA5
- cmp ebp, [esp+4Ch+arg_14]
- jnb loc_4CCFB3
- jmp short loc_4CD6B4
-; ---------------------------------------------------------------------------
-
-loc_4CD6E2: ; CODE XREF: sub_4CCC80+101j
- ; sub_4CCC80+1C9j ...
- pop edi
- pop esi
- pop ebp
- mov eax, 1
- pop ebx
- add esp, 3Ch
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CD6EF: ; CODE XREF: sub_4CCC80+933j
- pop edi
- pop esi
- pop ebp
- mov eax, ebx
- pop ebx
- add esp, 3Ch
- retn
-sub_4CCC80 endp
-
-_starcraft_decompress_lzma PROC
-;sub_4CD700
-
-var_14 = byte ptr -14h
-var_10 = dword ptr -10h
-var_C = dword ptr -0Ch
-var_4 = dword ptr -4
-pbInBuffer = dword ptr 4
-cbInBuffer = dword ptr 8
-pbOutBuffer = dword ptr 0Ch
-cbOutBuffer = dword ptr 10h
-pcbOutBuffer = dword ptr 14h
-pfnAllocateMemory= dword ptr 18h
-pfnFreeMemory = dword ptr 1Ch
-
- sub esp, 14h
- push ebx
- mov ebx, [esp+18h+cbInBuffer]
- cmp ebx, 0Eh ; LZMA_PROPS_SIZE + 8
- jnb short loc_4CD714
- xor al, al
- pop ebx
- add esp, 14h
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CD714: ; CODE XREF: Decompress_lzma_internal+Bj
- push ebp
- mov ebp, [esp+1Ch+pcbOutBuffer]
- push edi
- mov edi, [esp+20h+pbInBuffer]
- mov dword ptr [ebp+0], 0
- cmp byte ptr [edi], 0
- jnz short loc_4CD741
- push 5
- lea eax, [edi+1]
- push eax
- lea ecx, [esp+28h+var_10]
- push ecx
- call LzmaProps_Decode
- add esp, 0Ch
- test eax, eax
- jz short loc_4CD74A
-
-loc_4CD741: ; CODE XREF: Decompress_lzma_internal+28j
- pop edi
- pop ebp
- xor al, al
- pop ebx
- add esp, 14h
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CD74A: ; CODE XREF: Decompress_lzma_internal+3Fj
- mov edx, [esp+20h+var_10]
- mov eax, [esp+20h+var_C]
- lea ecx, [eax+edx]
- mov edx, 300h
- shl edx, cl
- push esi
- lea eax, [edx+edx+0E6Ch]
- push eax
- call [esp+28h+pfnAllocateMemory]
- mov esi, eax
- add esp, 4
- test esi, esi
- mov [esp+24h+var_4], esi
- jz short loc_4CD7AA
- mov edx, [esp+24h+cbOutBuffer]
- mov eax, [esp+24h+pbOutBuffer]
- lea ecx, [esp+24h+cbInBuffer]
- push ecx ; cbInBuffer
- push edx ; cbOutBuffer
- push eax ; pbOutBuffer
- lea ecx, [esp+30h+var_14]
- push ecx ; &var_14
- add ebx, 0FFFFFFF2h
- push ebx ; cbInBuffer - LZMA86_HEADER_SIZE
- add edi, 0Eh
- lea edx, [esp+38h+var_10]
- push edi ; pbInBuffer + LZMA86_HEADER_SIZE
- push edx ; dest
- call sub_4CCC80
- push esi
- mov edi, eax
- call [esp+44h+pfnFreeMemory]
- add esp, 20h
- test edi, edi
- jz short loc_4CD7B4
-
-loc_4CD7AA: ; CODE XREF: Decompress_lzma_internal+74j
- pop esi
- pop edi
- pop ebp
- xor al, al
- pop ebx
- add esp, 14h
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CD7B4: ; CODE XREF: Decompress_lzma_internal+A8j
- mov eax, [esp+24h+cbInBuffer]
- pop esi
- pop edi
- mov [ebp+0], eax
- pop ebp
- mov al, 1
- pop ebx
- add esp, 14h
- retn
-_starcraft_decompress_lzma ENDP
-
-; =============== S U B R O U T I N E =======================================
-
-sub_4CD7D0 proc near ; CODE XREF: sub_4CDC00+74p
-
-arg_0 = dword ptr 4
-
- push esi
- mov esi, [esp+4+arg_0]
- or esi, 8
- xor eax, eax
- cmp esi, 1
- jz short loc_4CD806
- push edi
-
-loc_4CD7E0: ; CODE XREF: sub_4CD7D0+33j
- mov edx, esi
- shr esi, 1
- mov edi, [ecx+esi*4]
- and edx, 1
- sub edi, edx
- neg edx
- xor edi, edx
- shr edi, 2
- and edi, 1FFh
- add eax, dword_550998[edi*4]
- cmp esi, 1
- jnz short loc_4CD7E0
- pop edi
-
-loc_4CD806: ; CODE XREF: sub_4CD7D0+Dj
- pop esi
- retn 4
-sub_4CD7D0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CD810 proc near ; CODE XREF: CEncoder_FillAlignPrices+17p
-
-var_4 = dword ptr -4
-arg_0 = dword ptr 4
-
- push ecx
- push ebx
- push ebp
- push esi
- xor eax, eax
- push edi
- mov edi, [esp+14h+arg_0]
- mov [esp+14h+var_4], ecx
- lea esi, [eax+1]
- lea ebx, [eax+4]
-
-loc_4CD825: ; CODE XREF: sub_4CD810+42j
- mov ecx, [esp+14h+var_4]
- mov ecx, [ecx+esi*4]
- mov edx, edi
- and edx, 1
- sub ecx, edx
- mov ebp, edx
- neg ebp
- xor ecx, ebp
- shr ecx, 2
- and ecx, 1FFh
- add eax, dword_550998[ecx*4]
- add esi, esi
- shr edi, 1
- or esi, edx
- sub ebx, 1
- jnz short loc_4CD825
- pop edi
- pop esi
- pop ebp
- pop ebx
- pop ecx
- retn 4
-sub_4CD810 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CD860 proc near ; CODE XREF: CEncoder_FillDistancesPrices+6Bp
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-arg_8 = dword ptr 0Ch
-
- push edi
- mov edi, [esp+4+arg_4]
- xor eax, eax
- test edi, edi
- lea edx, [eax+1]
- jz short loc_4CD8A7
- push ebx
- push ebp
- push esi
- mov esi, [esp+10h+arg_8]
-
-loc_4CD875: ; CODE XREF: sub_4CD860+42j
- mov ebx, [esp+10h+arg_0]
- mov ebx, [ebx+edx*4]
- mov ecx, esi
- and ecx, 1
- sub ebx, ecx
- mov ebp, ecx
- neg ebp
- xor ebx, ebp
- shr ebx, 2
- and ebx, 1FFh
- add eax, dword_550998[ebx*4]
- add edx, edx
- shr esi, 1
- or edx, ecx
- sub edi, 1
- jnz short loc_4CD875
- pop esi
- pop ebp
- pop ebx
-
-loc_4CD8A7: ; CODE XREF: sub_4CD860+Cj
- pop edi
- retn
-sub_4CD860 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CD8B0 proc near ; CODE XREF: CEncoder_CodeOneBlock+7B8p
- mov eax, [ecx+24h]
- mov edx, [ecx+1Ch]
- push ebx
- push esi
- mov esi, [ecx+30h]
- xor ebx, ebx
- push edi
- mov edi, [ecx+34h]
- sub esi, eax
- sbb edi, ebx
- add esi, edx
- adc edi, ebx
- cmp eax, edx
- jbe short loc_4CD8D4
- mov eax, [ecx+28h]
- add esi, eax
- adc edi, ebx
-
-loc_4CD8D4: ; CODE XREF: sub_4CD8B0+1Bj
- mov eax, [ecx]
- xor edx, edx
- add eax, esi
- adc edx, edi
- pop edi
- add eax, 4
- pop esi
- adc edx, ebx
- pop ebx
- retn
-sub_4CD8B0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CD8F0 proc near ; CODE XREF: sub_4CD940+21p
- ; .text:loc_4CF730j ...
- mov eax, dword_553598
- test eax, eax
- push esi
- mov esi, ecx
- push edi
- mov edi, [esi]
- jnz short loc_4CD92A
- push 0Ch ; Size
- call _operator_new ; operator new(uint)
- add esp, 4
- test eax, eax
- jz short loc_4CD923
- mov dword ptr [eax], 0
- mov dword ptr [eax+4], 0
- mov dword ptr [eax+8], 0
- jmp short loc_4CD925
-; ---------------------------------------------------------------------------
-
-loc_4CD923: ; CODE XREF: sub_4CD8F0+1Bj
- xor eax, eax
-
-loc_4CD925: ; CODE XREF: sub_4CD8F0+31j
- mov dword_553598, eax
-
-loc_4CD92A: ; CODE XREF: sub_4CD8F0+Dj
- mov eax, [eax+4]
- test eax, eax
- jz short loc_4CD937
- push edi
- call eax
- add esp, 4
-
-loc_4CD937: ; CODE XREF: sub_4CD8F0+3Fj
- pop edi
- mov dword ptr [esi], 0
- pop esi
- retn
-sub_4CD8F0 endp
-
-; =============== S U B R O U T I N E =======================================
-
-sub_4CD940 proc near ; CODE XREF: sub_4D0270+74p
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- push ebx
- mov ebx, [esp+4+arg_4]
- push esi
- mov esi, ecx
- cmp dword ptr [esi], 0
- push edi
- mov edi, [esp+0Ch+arg_0]
- jz short loc_4CD95F
- mov eax, [esi+8]
- add eax, [esi+4]
- lea ecx, [edi+ebx]
- cmp ecx, eax
- jz short loc_4CD981
-
-loc_4CD95F: ; CODE XREF: sub_4CD940+10j
- mov ecx, esi
- call sub_4CD8F0
- lea ecx, [edi+ebx]
- mov edx, 1
- shl edx, cl
- imul edx, 0C00h
- push edx
- call sub_4CB8A0
- add esp, 4
- mov [esi], eax
-
-loc_4CD981: ; CODE XREF: sub_4CD940+1Dj
- mov ecx, edi
- mov eax, 1
- shl eax, cl
- mov [esi+8], edi
- pop edi
- mov [esi+4], ebx
- sub eax, 1
- mov [esi+0Ch], eax
- xor eax, eax
- cmp [esi], eax
- pop esi
- setnz al
- pop ebx
- retn 8
-sub_4CD940 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CD9B0 proc near ; CODE XREF: CEncoder_GetOptimum+436p
- ; CEncoder_GetOptimum+AE1p
-
-arg_0 = dword ptr 4
-arg_4 = byte ptr 8
-arg_8 = dword ptr 0Ch
-
- mov edx, [esp+arg_0]
- test edx, edx
- push esi
- jnz short loc_4CD9F2
- movzx eax, [esp+4+arg_4]
- mov edx, eax
- shl edx, 4
- add edx, [esp+4+arg_8]
- mov esi, 800h
- sub esi, [ecx+edx*4+284B0h]
- mov ecx, [ecx+eax*4+28420h]
- shr esi, 2
- mov eax, dword_550998[esi*4]
- shr ecx, 2
- add eax, dword_550998[ecx*4]
- pop esi
- retn 0Ch
-; ---------------------------------------------------------------------------
-
-loc_4CD9F2: ; CODE XREF: sub_4CD9B0+7j
- movzx esi, [esp+4+arg_4]
- mov eax, 800h
- sub eax, [ecx+esi*4+28420h]
- shr eax, 2
- cmp edx, 1
- mov eax, dword_550998[eax*4]
- jnz short loc_4CDA27
- mov ecx, [ecx+esi*4+28450h]
- shr ecx, 2
- add eax, dword_550998[ecx*4]
- pop esi
- retn 0Ch
-; ---------------------------------------------------------------------------
-
-loc_4CDA27: ; CODE XREF: sub_4CD9B0+60j
- push edi
- add edx, 0FFFFFFFEh
- mov edi, 800h
- sub edi, [ecx+esi*4+28450h]
- mov ecx, [ecx+esi*4+28480h]
- sub ecx, edx
- neg edx
- xor ecx, edx
- shr edi, 2
- mov edx, dword_550998[edi*4]
- shr ecx, 2
- and ecx, 1FFh
- add edx, dword_550998[ecx*4]
- pop edi
- add eax, edx
- pop esi
- retn 0Ch
-sub_4CD9B0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CDA70 proc near ; CODE XREF: CEncoder_CodeReal+10Cp
- ; CEncoder_CodeReal+134p ...
- push esi
- mov esi, [ecx]
- cmp dword ptr [esi+80h], 0
- jz short loc_4CDA8C
- cmp byte ptr [esi+33B95h], 0
- jz short loc_4CDA8C
- mov byte ptr [esi+33B95h], 0
-
-loc_4CDA8C: ; CODE XREF: sub_4CDA70+Aj
- ; sub_4CDA70+13j
- mov eax, [esi+33B8Ch]
- test eax, eax
- jz short loc_4CDAA8
- mov ecx, [eax]
- mov edx, [ecx+8]
- push eax
- call edx
- mov dword ptr [esi+33B8Ch], 0
-
-loc_4CDAA8: ; CODE XREF: sub_4CDA70+24j
- mov ecx, [esi+4]
- mov edx, [ecx+10h]
- lea eax, [esi+4]
- push eax
- call edx
- pop esi
- retn
-sub_4CDA70 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CDAC0 proc near ; CODE XREF: CEncoder_GetOptimum+2C4p
- ; CEncoder_GetOptimum+7ACp ...
-
-var_4 = dword ptr -4
-arg_0 = dword ptr 4
-arg_4 = byte ptr 8
-arg_8 = byte ptr 0Ch
-
- push ecx
- push ebx
- push ebp
- xor ebp, ebp
- cmp byte ptr [esp+0Ch+arg_0], 0
- push esi
- mov eax, ecx
- push edi
- mov [esp+14h+var_4], eax
- lea edi, [ebp+1]
- lea ebx, [ebp+8]
- jz short loc_4CDB3B
- movzx ecx, [esp+14h+arg_8]
- mov [esp+14h+arg_0], ecx
-
-loc_4CDAE3: ; CODE XREF: sub_4CDAC0+71j
- movzx esi, [esp+14h+arg_4]
- mov edx, [esp+14h+arg_0]
- sub ebx, 1
- movzx ecx, bl
- shr esi, cl
- shr edx, cl
- and esi, 1
- mov ecx, esi
- shl ecx, 8
- add ecx, edi
- mov eax, [eax+ecx*4+400h]
- and edx, 1
- sub eax, edx
- mov ecx, edx
- neg ecx
- xor eax, ecx
- shr eax, 2
- and eax, 1FFh
- add ebp, dword_550998[eax*4]
- add edi, edi
- or edi, edx
- cmp esi, edx
- jnz short loc_4CDB33
- test ebx, ebx
- jz short loc_4CDB75
- mov eax, [esp+14h+var_4]
- jmp short loc_4CDAE3
-; ---------------------------------------------------------------------------
-
-loc_4CDB33: ; CODE XREF: sub_4CDAC0+67j
- test ebx, ebx
- jz short loc_4CDB75
- mov eax, [esp+14h+var_4]
-
-loc_4CDB3B: ; CODE XREF: sub_4CDAC0+18j
- movzx edx, [esp+14h+arg_8]
- mov [esp+14h+arg_0], edx
-
-loc_4CDB44: ; CODE XREF: sub_4CDAC0+B3j
- mov edx, [esp+14h+arg_0]
- sub ebx, 1
- mov cl, bl
- shr edx, cl
- mov ecx, [eax+edi*4]
- add edi, edi
- and edx, 1
- sub ecx, edx
- mov esi, edx
- neg esi
- xor ecx, esi
- shr ecx, 2
- and ecx, 1FFh
- add ebp, dword_550998[ecx*4]
- or edi, edx
- test ebx, ebx
- jnz short loc_4CDB44
-
-loc_4CDB75: ; CODE XREF: sub_4CDAC0+6Bj
- ; sub_4CDAC0+75j
- pop edi
- pop esi
- mov eax, ebp
- pop ebp
- pop ebx
- pop ecx
- retn 0Ch
-sub_4CDAC0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CDB80 proc near ; CODE XREF: sub_4CDEA0+11Ep
- ; sub_4CDEA0+137p
-
-arg_0 = dword ptr 4
-
- push esi
- mov esi, [esp+4+arg_0]
- test esi, esi
- mov edx, 400h
- push edi
- mov [ecx], edx
- mov [ecx+4], edx
- jbe short loc_4CDBE6
- lea eax, [ecx+20Ch]
- lea ebx, [ebx+0]
-
-loc_4CDBA0: ; CODE XREF: sub_4CDB80+64j
- mov [eax-200h], edx
- mov [eax-1FCh], edx
- mov [eax-1F8h], edx
- mov [eax-1F4h], edx
- mov [eax-1F0h], edx
- mov [eax-1ECh], edx
- mov [eax-1E8h], edx
- mov [eax], edx
- mov [eax+4], edx
- mov [eax+8], edx
- mov [eax+0Ch], edx
- mov [eax+10h], edx
- mov [eax+14h], edx
- mov [eax+18h], edx
- add eax, 20h
- sub esi, 1
- jnz short loc_4CDBA0
-
-loc_4CDBE6: ; CODE XREF: sub_4CDB80+12j
- lea edi, [ecx+40Ch]
- mov ecx, 0FFh
- mov eax, edx
- rep stosd
- pop edi
- pop esi
- retn 4
-sub_4CDB80 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CDC00 proc near ; CODE XREF: sub_4CF740+22p
- ; sub_4CF780+2Bp
-
-var_C = dword ptr -0Ch
-var_8 = dword ptr -8
-var_4 = dword ptr -4
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-arg_8 = dword ptr 0Ch
-
- sub esp, 0Ch
- push ebx
- push ebp
- push esi
- push edi
- mov edi, ecx
- mov eax, [edi]
- mov ebx, [esp+1Ch+arg_0]
- mov ecx, eax
- shr ecx, 2
- mov edx, dword_550998[ecx*4]
- mov ecx, 800h
- sub ecx, eax
- shr ecx, 2
- mov eax, dword_550998[ecx*4]
- mov ecx, [edi+4]
- mov [esp+1Ch+var_C], edx
- mov edx, ecx
- shr edx, 2
- mov ebp, dword_550998[edx*4]
- mov edx, 800h
- sub edx, ecx
- shr edx, 2
- mov ecx, dword_550998[edx*4]
- add ebp, eax
- add ecx, eax
- mov [esp+1Ch+var_8], ebp
- mov [esp+1Ch+var_4], ecx
- xor esi, esi
- mov edi, edi
-
-loc_4CDC60: ; CODE XREF: sub_4CDC00+8Aj
- cmp esi, [esp+1Ch+arg_4]
- jnb loc_4CDD62
- mov eax, ebx
- shl eax, 5
- push esi
- lea ecx, [eax+edi+8]
- call sub_4CD7D0
- add eax, [esp+1Ch+var_C]
- mov ecx, [esp+1Ch+arg_8]
- mov [ecx+esi*4], eax
- add esi, 1
- cmp esi, 8
- jb short loc_4CDC60
- cmp esi, 10h
- jnb short loc_4CDD00
- lea ecx, [esi-8]
- mov [esp+1Ch+arg_0], ecx
- jmp short loc_4CDCA0
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CDCA0: ; CODE XREF: sub_4CDC00+98j
- ; sub_4CDC00+FEj
- cmp esi, [esp+1Ch+arg_4]
- jnb loc_4CDD62
- or ecx, 8
- xor edx, edx
- cmp ecx, 1
- jz short loc_4CDCE4
-
-loc_4CDCB4: ; CODE XREF: sub_4CDC00+DEj
- mov eax, ecx
- shr ecx, 1
- and eax, 1
- lea ebp, [ecx+ebx*8]
- mov ebp, [edi+ebp*4+208h]
- sub ebp, eax
- neg eax
- xor ebp, eax
- shr ebp, 2
- and ebp, 1FFh
- add edx, dword_550998[ebp*4]
- cmp ecx, 1
- jnz short loc_4CDCB4
- mov ebp, [esp+1Ch+var_8]
-
-loc_4CDCE4: ; CODE XREF: sub_4CDC00+B2j
- mov eax, [esp+1Ch+arg_8]
- mov ecx, [esp+1Ch+arg_0]
- add edx, ebp
- mov [eax+esi*4], edx
- add esi, 1
- add ecx, 1
- cmp esi, 10h
- mov [esp+1Ch+arg_0], ecx
- jb short loc_4CDCA0
-
-loc_4CDD00: ; CODE XREF: sub_4CDC00+8Fj
- cmp esi, [esp+1Ch+arg_4]
- jnb short loc_4CDD62
- lea ebx, [esi-10h]
- lea esp, [esp+0]
-
-loc_4CDD10: ; CODE XREF: sub_4CDC00+160j
- mov ecx, ebx
- or ecx, 100h
- xor edx, edx
- cmp ecx, 1
- jz short loc_4CDD49
- nop
-
-loc_4CDD20: ; CODE XREF: sub_4CDC00+147j
- mov eax, ecx
- shr ecx, 1
- mov ebp, [edi+ecx*4+408h]
- and eax, 1
- sub ebp, eax
- neg eax
- xor ebp, eax
- shr ebp, 2
- and ebp, 1FFh
- add edx, dword_550998[ebp*4]
- cmp ecx, 1
- jnz short loc_4CDD20
-
-loc_4CDD49: ; CODE XREF: sub_4CDC00+11Dj
- mov ecx, [esp+1Ch+var_4]
- mov eax, [esp+1Ch+arg_8]
- add edx, ecx
- mov [eax+esi*4], edx
- add esi, 1
- add ebx, 1
- cmp esi, [esp+1Ch+arg_4]
- jb short loc_4CDD10
-
-loc_4CDD62: ; CODE XREF: sub_4CDC00+64j
- ; sub_4CDC00+A4j ...
- pop edi
- pop esi
- pop ebp
- pop ebx
- add esp, 0Ch
- retn 0Ch
-sub_4CDC00 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-; int __cdecl sub_4CDD70(SIZE_T dwSize)
-sub_4CDD70 proc near ; DATA XREF: .data:off_546E20o
-
-dwSize = dword ptr 4
-
- mov eax, [esp+dwSize]
- test eax, eax
- jnz short loc_4CDD79
- retn
-; ---------------------------------------------------------------------------
-
-loc_4CDD79: ; CODE XREF: sub_4CDD70+6j
- push 4 ; flProtect
- push 1000h ; flAllocationType
- push eax ; dwSize
- push 0 ; lpAddress
- call ds:VirtualAlloc
- retn
-sub_4CDD70 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-
-; int __cdecl sub_4CDD90(void * lpAddress)
-sub_4CDD90 proc near ; CODE XREF: sub_4CF810+53p
- ; sub_4CF810+73p
- ; DATA XREF: ...
-
-lpAddress = dword ptr 4
-
- mov eax, [esp+lpAddress]
- test eax, eax
- jz short locret_4CDDA6
- push 8000h ; dwFreeType
- push 0 ; dwSize
- push eax ; lpAddress
- call ds:VirtualFree
-
-locret_4CDDA6: ; CODE XREF: sub_4CDD90+6j
- retn
-sub_4CDD90 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CDDB0 proc near ; DATA XREF: .rdata:00517AC8o
-
-var_10 = dword ptr -10h
-var_C = byte ptr -0Ch
-var_B = byte ptr -0Bh
-var_A = byte ptr -0Ah
-var_9 = byte ptr -9
-var_8 = byte ptr -8
-var_4 = dword ptr -4
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- sub esp, 10h
- mov eax, dword_544960
- xor eax, esp
- mov [esp+10h+var_4], eax
- mov ecx, [esp+10h+arg_0]
- mov al, [ecx+33B50h]
- mov dl, 5
- imul dl
- add al, [ecx+33B58h]
- mov dl, 9
- imul dl
- add al, [ecx+33B5Ch]
- push ebp
- mov ebp, [esp+14h+arg_4]
- mov [esp+14h+var_C], al
- mov eax, [ecx+33B60h]
- mov ecx, eax
- mov edx, eax
- push esi
- shr ecx, 8
- shr edx, 10h
- mov [esp+18h+var_B], al
- shr eax, 18h
- push edi
- mov [esp+1Ch+var_A], cl
- mov [esp+1Ch+var_9], dl
- mov [esp+1Ch+var_8], al
- mov esi, 5
- lea edi, [esp+1Ch+var_C]
-
-loc_4CDE13: ; CODE XREF: sub_4CDDB0+85j
- mov eax, [ebp+0]
- mov edx, [eax+0Ch]
- lea ecx, [esp+1Ch+var_10]
- push ecx
- push esi
- push edi
- push ebp
- call edx
- mov ecx, [esp+1Ch+var_10]
- add edi, ecx
- sub esi, ecx
- test eax, eax
- jnz short loc_4CDE37
- test ecx, ecx
- jz short loc_4CDE4B
- test esi, esi
- jnz short loc_4CDE13
-
-loc_4CDE37: ; CODE XREF: sub_4CDDB0+7Dj
- pop edi
- pop esi
- pop ebp
- mov ecx, [esp+10h+var_4]
- xor ecx, esp
- call sub_4A0686
- add esp, 10h
- retn 8
-; ---------------------------------------------------------------------------
-
-loc_4CDE4B: ; CODE XREF: sub_4CDDB0+81j
- mov ecx, [esp+1Ch+var_4]
- pop edi
- pop esi
- pop ebp
- xor ecx, esp
- mov eax, 80004005h
- call sub_4A0686
- add esp, 10h
- retn 8
-sub_4CDDB0 endp
-
- align 10h
-
-; =============== S U B R O U T I N E =======================================
-
-sub_4CDE70 proc near ; DATA XREF: .rdata:00517AF4o
-
-arg_0 = dword ptr 4
-
- push esi
- mov esi, [esp+4+arg_0]
- mov eax, [esi+50h]
- test eax, eax
- jz short loc_4CDE8B
- mov ecx, [eax]
- mov edx, [ecx+8]
- push eax
- call edx
- mov dword ptr [esi+50h], 0
-
-loc_4CDE8B: ; CODE XREF: sub_4CDE70+Aj
- xor eax, eax
- pop esi
- retn 4
-sub_4CDE70 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CDEA0 proc near ; CODE XREF: CEncoder_SetStreams+3Cp
-
-var_4 = dword ptr -4
-
- push ecx
- push ebx
- xor ebx, ebx
- push ebp
- push esi
- mov esi, ecx
- mov byte ptr [esi+10h], 0
- mov byte ptr [esi+11h], 0
- mov [esi+14h], ebx
- mov [esi+18h], ebx
- mov [esi+1Ch], ebx
- mov [esi+20h], ebx
- mov eax, [esi+50h]
- mov [esi+4Ch], ebx
- mov [esi+48h], eax
- mov [esi+44h], ebx
- mov [esi+58h], ebx
- mov [esi+5Ch], ebx
- mov [esi+64h], bl
- push edi
- mov [esi+30h], ebx
- mov [esi+34h], ebx
- mov dword ptr [esi+38h], 0FFFFFFFFh
- mov dword ptr [esi+28h], 1
- mov [esi+2Ch], bl
- lea ecx, [esi+28420h]
- lea edi, [esi+284B0h]
- mov [esp+14h+var_4], 0Ch
- mov ebp, 400h
-
-loc_4CDF02: ; CODE XREF: sub_4CDEA0+9Cj
- xor edx, edx
- mov eax, edi
- jmp short loc_4CDF10
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CDF10: ; CODE XREF: sub_4CDEA0+66j
- ; sub_4CDEA0+84j
- mov [eax-3C0h], ebp
- mov [eax], ebp
- add edx, 1
- add eax, 4
- cmp edx, [esi+33B60h]
- jbe short loc_4CDF10
- mov [ecx-30h], ebp
- mov [ecx], ebp
- mov [ecx+30h], ebp
- mov [ecx+60h], ebp
- add ecx, 4
- add edi, 40h
- sub [esp+14h+var_4], 1
- jnz short loc_4CDF02
- mov ecx, [esi+32658h]
- add ecx, [esi+32654h]
- mov eax, 1
- shl eax, cl
- cmp eax, ebx
- jbe short loc_4CDF7C
- xor edx, edx
- mov ebx, eax
- lea esp, [esp+0]
-
-loc_4CDF60: ; CODE XREF: sub_4CDEA0+DAj
- mov edi, [esi+32650h]
- add edi, edx
- mov ecx, 300h
- mov eax, ebp
- add edx, 0C00h
- sub ebx, 1
- rep stosd
- jnz short loc_4CDF60
-
-loc_4CDF7C: ; CODE XREF: sub_4CDEA0+B3j
- lea edx, [esi+287B4h]
- mov ebx, 4
-
-loc_4CDF87: ; CODE XREF: sub_4CDEA0+FBj
- mov edi, edx
- mov ecx, 3Fh
- mov eax, ebp
- add edx, 100h
- sub ebx, 1
- rep stosd
- jnz short loc_4CDF87
- lea edi, [esi+28BB0h]
- mov ecx, 72h
- rep stosd
- mov ecx, [esi+33B5Ch]
- mov edx, 1
- shl edx, cl
- lea ecx, [esi+28DB8h]
- push edx
- call sub_4CDB80
- mov ecx, [esi+33B5Ch]
- mov eax, 1
- shl eax, cl
- lea ecx, [esi+2DA04h]
- push eax
- call sub_4CDB80
- mov eax, ebp
- mov [esi+28D7Ch], eax
- mov [esi+28D80h], eax
- mov [esi+28D84h], eax
- mov [esi+28D88h], eax
- mov [esi+28D8Ch], eax
- mov [esi+28D90h], eax
- mov [esi+28D94h], eax
- mov [esi+28D98h], eax
- mov [esi+28D9Ch], eax
- mov [esi+28DA0h], eax
- mov [esi+28DA4h], eax
- mov [esi+28DA8h], eax
- mov [esi+28DACh], eax
- mov [esi+28DB0h], eax
- mov [esi+28DB4h], eax
- xor eax, eax
- pop edi
- mov [esi+32F10h], bl
- mov [esi+32F08h], eax
- mov [esi+32F0Ch], eax
- mov [esi+32F04h], eax
- pop esi
- pop ebp
- pop ebx
- pop ecx
- retn
-sub_4CDEA0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CF450 proc near ; CODE XREF: .text:004CF692p
- ; CEncoder_Flush+42p
-
-var_8 = dword ptr -8
-var_4 = dword ptr -4
-
- sub esp, 8
- push esi
- mov esi, ecx
- mov eax, [esi+0Ch]
- push edi
- mov edi, [esi+4]
- cmp eax, edi
- jb short loc_4CF464
- mov edi, [esi+10h]
-
-loc_4CF464: ; CODE XREF: sub_4CF450+Fj
- push ebp
- mov ebp, [esi+20h]
- xor edx, edx
- sub edi, eax
- cmp ebp, edx
- mov [esp+14h+var_4], edx
- jz short loc_4CF4BA
- push ebx
- mov ebx, [esi]
- add ebx, eax
- mov eax, dword_553598
- cmp eax, edx
- jnz short loc_4CF4A5
- push 0Ch ; Size
- call _operator_new ; operator new(uint)
- xor ecx, ecx
- add esp, 4
- cmp eax, ecx
- jz short loc_4CF49C
- mov [eax], ecx
- mov [eax+4], ecx
- mov [eax+8], ecx
- jmp short loc_4CF49E
-; ---------------------------------------------------------------------------
-
-loc_4CF49C: ; CODE XREF: sub_4CF450+40j
- xor eax, eax
-
-loc_4CF49E: ; CODE XREF: sub_4CF450+4Aj
- mov dword_553598, eax
- xor edx, edx
-
-loc_4CF4A5: ; CODE XREF: sub_4CF450+30j
- mov eax, [eax+8]
- cmp eax, edx
- jz short loc_4CF4B6
- push edi
- push ebx
- push ebp
- call eax
- add esp, 0Ch
- xor edx, edx
-
-loc_4CF4B6: ; CODE XREF: sub_4CF450+5Aj
- add [esi+20h], edi
- pop ebx
-
-loc_4CF4BA: ; CODE XREF: sub_4CF450+22j
- mov eax, [esi+14h]
- cmp eax, edx
- pop ebp
- jz short loc_4CF4E4
- mov [esp+10h+var_8], edx
- mov ecx, [eax]
- lea edx, [esp+10h+var_8]
- push edx
- mov edx, [esi]
- add edx, [esi+0Ch]
- push edi
- push edx
- push eax
- mov eax, [ecx+0Ch]
- call eax
- mov edi, [esp+10h+var_8]
- mov [esp+10h+var_4], eax
- xor edx, edx
-
-loc_4CF4E4: ; CODE XREF: sub_4CF450+70j
- add [esi+0Ch], edi
- mov ecx, [esi+0Ch]
- mov eax, [esi+10h]
- cmp ecx, eax
- jnz short loc_4CF4F4
- mov [esi+0Ch], edx
-
-loc_4CF4F4: ; CODE XREF: sub_4CF450+9Fj
- cmp [esi+4], eax
- jnz short loc_4CF500
- mov byte ptr [esi+24h], 1
- mov [esi+4], edx
-
-loc_4CF500: ; CODE XREF: sub_4CF450+A7j
- mov ecx, [esi+0Ch]
- cmp ecx, [esi+4]
- jbe short loc_4CF50A
- mov eax, ecx
-
-loc_4CF50A: ; CODE XREF: sub_4CF450+B6j
- add [esi+18h], edi
- mov [esi+8], eax
- mov eax, [esp+10h+var_4]
- adc [esi+1Ch], edx
- pop edi
- pop esi
- add esp, 8
- retn
-sub_4CF450 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-
-; ---------------------------------------------------------------------------
-
-; int __stdcall Interface1_QueryInterface(int, void *Buf1, int)
-Interface1_QueryInterface proc near ; DATA XREF: .rdata:off_517A90o
-; sub_4CF520
-
-arg_0 = dword ptr 4
-Buf1 = dword ptr 8
-arg_8 = dword ptr 0Ch
-
- mov eax, [esp+Buf1]
- push offset dword_512730 ; Buf2
- push eax ; Buf1
- call unknown_libname_324 ; MFC 3.1/4.0/4.2/8.0 32bit
- add esp, 8
- test eax, eax
- jz short loc_4CF54D
- mov eax, [esp+arg_0]
- mov ecx, [esp+arg_8]
- mov [ecx], eax
- mov edx, [eax]
- push eax
- mov eax, [edx+4]
- call eax
- xor eax, eax
- retn 0Ch
-loc_4CF54D: ; CODE XREF: Interface1_QueryInterface+14j
- mov eax, 80004002h
- retn 0Ch
-Interface1_QueryInterface endp
-
-; ---------------------------------------------------------------------------
-
-; int __stdcall Interface1_Release(void *pUnknown)
-Interface1_Release proc near ; DATA XREF: .rdata:00517A98o
-
-pUnknown = dword ptr 4
-
- mov ecx, [esp+pUnknown]
- add dword ptr [ecx+4], 0FFFFFFFFh
- mov eax, [ecx+4]
- jnz short locret_4CF585
- push ecx ; Memory
- mov dword ptr [ecx], offset off_517A90
- mov dword ptr [ecx+8], 0
- call j__free
- add esp, 4
- xor eax, eax
-
-locret_4CF585: ; CODE XREF: Interface1_Release+Bj
- retn 4
-Interface1_Release endp
-
-; ---------------------------------------------------------------------------
-
-sub_4CF590 proc near ; DATA XREF: .rdata:00517AB4o
-
-arg_0 = dword ptr 4
-arg_4 = byte ptr 8
-arg_8 = dword ptr 0Ch
-arg_C = dword ptr 10h
-
- mov eax, [esp+arg_0]
- mov edx, [eax+10h]
- sub edx, [eax+18h]
- mov ecx, [eax+14h]
- sbb ecx, [eax+1Ch]
- push ebx
- mov ebx, [esp+4+arg_8]
- push edi
- mov edi, [esp+8+arg_C]
- cmp edi, ecx
- jb short loc_4CF5C2
- ja short loc_4CF5B4
- cmp ebx, edx
- jbe short loc_4CF5C2
-
-loc_4CF5B4: ; CODE XREF: sub_4CF590+1Ej
- pop edi
- mov byte ptr [eax+20h], 1
- mov eax, 80004005h
- pop ebx
- retn 10h
-; ---------------------------------------------------------------------------
-
-loc_4CF5C2: ; CODE XREF: sub_4CF590+1Cj
- ; sub_4CF590+22j
- push esi
- xor esi, esi
- xor ecx, ecx
- test edi, edi
- jb short loc_4CF5FA
- ja short loc_4CF5D1
- test ebx, ebx
- jbe short loc_4CF5FA
-
-loc_4CF5D1: ; CODE XREF: sub_4CF590+3Bj
- mov dl, [esp+0Ch+arg_4]
- push ebp
-
-loc_4CF5D6: ; CODE XREF: sub_4CF590+5Fj
- ; sub_4CF590+67j
- mov ebp, [eax+18h]
- mov ebx, [eax+8]
- mov [ebx+ebp], dl
- add dword ptr [eax+18h], 1
- adc dword ptr [eax+1Ch], 0
- add esi, 1
- adc ecx, 0
- cmp ecx, edi
- jb short loc_4CF5D6
- ja short loc_4CF5F9
- cmp esi, [esp+10h+arg_8]
- jb short loc_4CF5D6
-
-loc_4CF5F9: ; CODE XREF: sub_4CF590+61j
- pop ebp
-
-loc_4CF5FA: ; CODE XREF: sub_4CF590+39j
- ; sub_4CF590+3Fj
- pop esi
- pop edi
- xor eax, eax
- pop ebx
- retn 10h
-sub_4CF590 endp
-
-; =============== S U B R O U T I N E =======================================
-
-; int __stdcall Interface2_Release(void *pUnknown)
-Interface2_Release proc near ; DATA XREF: .rdata:00517AACo
-; sub_4CF610
-
-pUnknown = dword ptr 4
-
- mov ecx, [esp+pUnknown]
- add dword ptr [ecx+4], 0FFFFFFFFh
- mov eax, [ecx+4]
- jnz short locret_4CF635
- push ecx ; Memory
- mov dword ptr [ecx], offset off_517AA4
- mov dword ptr [ecx+8], 0
- call j__free
- add esp, 4
- xor eax, eax
-
-locret_4CF635: ; CODE XREF: Interface2_Release+Bj
- retn 4
-Interface2_Release endp
-
-; =============== S U B R O U T I N E =======================================
-
-loc_4CF640: ; CODE XREF: sub_4CF6E0+39p
- ; sub_4CFAC0+57p ...
- push ecx
- push ebx
- push esi
- push edi
- mov edi, ecx
- mov esi, [edi+8]
- cmp esi, 0FF000000h
- jb short loc_4CF661
- mov edx, [edi+0Ch]
- mov eax, esi
- mov cl, 20h
- call __allshr ; Microsoft VisualC 2-8/net runtime
- test eax, eax
- jz short loc_4CF6B6
-
-loc_4CF661: ; CODE XREF: .text:004CF64Fj
- mov bl, [edi+4]
- lea esi, [edi+18h]
-
-loc_4CF667: ; CODE XREF: .text:004CF6A9j
- mov eax, [edi+8]
- mov edx, [edi+0Ch]
- mov cl, 20h
- call __allshr ; Microsoft VisualC 2-8/net runtime
- mov ecx, [esi+4]
- mov edx, [esi]
- add al, bl
- mov [ecx+edx], al
- add dword ptr [esi+4], 1
- mov eax, [esi+4]
- cmp eax, [esi+8]
- jnz short loc_4CF6A3
- cmp [esi+0Ch], eax
- jz short loc_4CF6A3
- nop
-
-loc_4CF690: ; CODE XREF: .text:004CF6A1j
- mov ecx, esi
- call sub_4CF450
- test eax, eax
- jnz short loc_4CF6CB
- mov eax, [esi+0Ch]
- cmp eax, [esi+4]
- jnz short loc_4CF690
-
-loc_4CF6A3: ; CODE XREF: .text:004CF688j
- ; .text:004CF68Dj
- or bl, 0FFh
- add dword ptr [edi], 0FFFFFFFFh
- jnz short loc_4CF667
- mov esi, [edi+8]
- mov edx, esi
- shr edx, 18h
- mov [edi+4], dl
-
-loc_4CF6B6: ; CODE XREF: .text:004CF65Fj
- add dword ptr [edi], 1
- shl esi, 8
- mov [edi+8], esi
- mov dword ptr [edi+0Ch], 0
- pop edi
- pop esi
- pop ebx
- pop ecx
- retn
-
-; ---------------------------------------------------------------------------
-
-loc_4CF6CB: ; CODE XREF: .text:004CF699j
- push offset dword_526DD0
- lea ecx, [esp+10h]
- push ecx
- mov [esp+14h], eax
- int 3
-; call __CxxThrowException@8 ; _CxxThrowException(x,x)
-; ---------------------------------------------------------------------------
-
- db 2 dup(0CCh)
-
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CF6E0 proc near ; CODE XREF: sub_4D0770+FBp
- ; CEncoder_CodeOneBlock+6C5p
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- push esi
- push edi
- mov edi, [esp+8+arg_4]
- add edi, 0FFFFFFFFh
- mov esi, ecx
- js short loc_4CF724
- push ebp
- mov ebp, [esp+0Ch+arg_0]
-
-loc_4CF6F2: ; CODE XREF: sub_4CF6E0+41j
- shr dword ptr [esi+10h], 1
- mov eax, [esi+10h]
- mov edx, ebp
- mov ecx, edi
- shr edx, cl
- test dl, 1
- jz short loc_4CF70A
- add [esi+8], eax
- adc dword ptr [esi+0Ch], 0
-
-loc_4CF70A: ; CODE XREF: sub_4CF6E0+21j
- cmp eax, 1000000h
- jnb short loc_4CF71E
- shl eax, 8
- mov ecx, esi
- mov [esi+10h], eax
- call loc_4CF640
-
-loc_4CF71E: ; CODE XREF: sub_4CF6E0+2Fj
- sub edi, 1
- jns short loc_4CF6F2
- pop ebp
-
-loc_4CF724: ; CODE XREF: sub_4CF6E0+Bj
- pop edi
- pop esi
- retn 8
-sub_4CF6E0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CF740 proc near ; CODE XREF: sub_4D0770+DFp
- ; CEncoder_CodeOneBlock+58Ap ...
-
-arg_0 = dword ptr 4
-
- push esi
- push edi
- mov edi, [esp+8+arg_0]
- mov eax, edi
- imul eax, 440h
- mov esi, ecx
- mov edx, [esi+4C08h]
- lea ecx, [eax+esi+808h]
- push ecx
- push edx
- push edi
- mov ecx, esi
- call sub_4CDC00
- mov eax, [esi+4C08h]
- mov [esi+edi*4+4C0Ch], eax
- pop edi
- pop esi
- retn 4
-sub_4CF740 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CF780 proc near ; CODE XREF: CEncoder_SetStreams+7Ep
- ; CEncoder_SetStreams+A6p
-
-arg_0 = dword ptr 4
-
- push esi
- push edi
- xor edi, edi
- cmp [esp+8+arg_0], edi
- mov esi, ecx
- jbe short loc_4CF7CC
- push ebx
- push ebp
- lea ebx, [esi+4C0Ch]
- lea ebp, [esi+808h]
- lea ebx, [ebx+0]
-
-loc_4CF7A0: ; CODE XREF: sub_4CF780+48j
- mov eax, [esi+4C08h]
- push ebp
- push eax
- push edi
- mov ecx, esi
- call sub_4CDC00
- mov ecx, [esi+4C08h]
- mov [ebx], ecx
- add edi, 1
- add ebx, 4
- add ebp, 440h
- cmp edi, [esp+10h+arg_0]
- jb short loc_4CF7A0
- pop ebp
- pop ebx
-
-loc_4CF7CC: ; CODE XREF: sub_4CF780+Aj
- pop edi
- pop esi
- retn 4
-sub_4CF780 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-CEncoder_GetOptimum proc near ; CODE XREF: CEncoder_CodeOneBlock+201p
-
-var_7D = byte ptr -7Dh
-var_7C = dword ptr -7Ch
-var_78 = dword ptr -78h
-var_74 = dword ptr -74h
-var_70 = dword ptr -70h
-var_6C = dword ptr -6Ch
-var_68 = dword ptr -68h
-var_64 = dword ptr -64h
-var_60 = dword ptr -60h
-var_5C = dword ptr -5Ch
-var_58 = dword ptr -58h
-var_54 = dword ptr -54h
-var_50 = dword ptr -50h
-var_4C = dword ptr -4Ch
-var_48 = dword ptr -48h
-var_44 = dword ptr -44h
-var_40 = dword ptr -40h
-var_3C = dword ptr -3Ch
-var_38 = dword ptr -38h
-var_34 = dword ptr -34h
-var_30 = dword ptr -30h
-var_2C = dword ptr -2Ch
-var_28 = dword ptr -28h
-var_24 = dword ptr -24h
-var_20 = dword ptr -20h
-var_1C = dword ptr -1Ch
-var_18 = dword ptr -18h
-var_14 = dword ptr -14h
-var_10 = dword ptr -10h
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- sub esp, 80h
- push ebp
- mov ebp, ecx
- mov edx, [ebp+32F0Ch]
- cmp [ebp+32F08h], edx
- push esi
- jz short loc_4CE0A5
- mov esi, [esp+88h+arg_4]
- lea eax, [edx+edx*4+1Eh]
- lea ecx, [ebp+eax*8+0]
- mov eax, [ecx+10h]
- sub eax, edx
- mov edx, [ecx+14h]
- mov [esi], edx
- mov ecx, [ecx+10h]
- pop esi
- mov [ebp+32F0Ch], ecx
- pop ebp
- add esp, 80h
- retn 8
-; ---------------------------------------------------------------------------
-
-loc_4CE0A5: ; CODE XREF: CEncoder_GetOptimum+16j
- mov edx, [ebp+80h]
- mov eax, [ebp+70h]
- push ebx
- xor esi, esi
- push edx
- mov [ebp+32F08h], esi
- mov [ebp+32F0Ch], esi
- call eax
- add esp, 4
- cmp byte ptr [ebp+32F10h], 0
- mov ebx, eax
- mov [esp+8Ch+var_60], eax
- jnz short loc_4CE0E4
- lea ecx, [esp+8Ch+var_70]
- push ecx
- mov ecx, ebp
- call sub_4CB3B0
- mov [esp+8Ch+var_68], eax
- jmp short loc_4CE0FF
-; ---------------------------------------------------------------------------
-
-loc_4CE0E4: ; CODE XREF: CEncoder_GetOptimum+70j
- mov edx, [ebp+32EFCh]
- mov eax, [ebp+32F00h]
- mov [esp+8Ch+var_68], edx
- mov [esp+8Ch+var_70], eax
- mov byte ptr [ebp+32F10h], 0
-
-loc_4CE0FF: ; CODE XREF: CEncoder_GetOptimum+82j
- mov ecx, [ebp+80h]
- mov edx, [ebp+74h]
- push edi
- push ecx
- call edx
- mov edi, eax
- add esp, 4
- sub edi, 1
- cmp ebx, 2
- jnb short loc_4CE138
- mov eax, [esp+90h+arg_4]
- pop edi
- pop ebx
- pop esi
- mov dword ptr [eax], 0FFFFFFFFh
- mov eax, 1
- pop ebp
- add esp, 80h
- retn 8
-; ---------------------------------------------------------------------------
-
-loc_4CE138: ; CODE XREF: CEncoder_GetOptimum+B7j
- cmp ebx, 111h
- jbe short loc_4CE149
- mov ebx, 111h
- mov [esp+90h+var_60], ebx
-
-loc_4CE149: ; CODE XREF: CEncoder_GetOptimum+DEj
- lea ecx, [ebp+14h]
- mov [esp+90h+var_50], esi
- mov [esp+90h+var_64], esi
- xor edx, edx
- mov [esp+90h+var_4C], esi
- mov [esp+90h+var_6C], ecx
- mov edi, edi
-
-loc_4CE160: ; CODE XREF: CEncoder_GetOptimum+180j
- mov eax, [esp+90h+var_6C]
- mov eax, [eax]
- mov ecx, edi
- sub ecx, eax
- mov [esp+edx+90h+var_20], eax
- mov al, [edi]
- sub ecx, 1
- cmp al, [ecx]
- jnz short loc_4CE1C9
- mov al, [edi+1]
- cmp al, [ecx+1]
- jnz short loc_4CE1C9
- mov eax, 2
- cmp ebx, eax
- jbe short loc_4CE1A7
- lea esi, [edi+2]
- sub ecx, edi
- lea ecx, [ecx+0]
-
-loc_4CE190: ; CODE XREF: CEncoder_GetOptimum+143j
- mov bl, [esi]
- cmp bl, [ecx+esi]
- mov ebx, [esp+90h+var_60]
- jnz short loc_4CE1A5
- add eax, 1
- add esi, 1
- cmp eax, ebx
- jb short loc_4CE190
-
-loc_4CE1A5: ; CODE XREF: CEncoder_GetOptimum+139j
- xor esi, esi
-
-loc_4CE1A7: ; CODE XREF: CEncoder_GetOptimum+126j
- mov ecx, [esp+90h+var_4C]
- mov [esp+edx+90h+var_10], eax
- cmp eax, [esp+ecx+90h+var_10]
- jbe short loc_4CE1D0
- mov eax, [esp+90h+var_64]
- mov [esp+90h+var_50], eax
- mov [esp+90h+var_4C], edx
- jmp short loc_4CE1D0
-; ---------------------------------------------------------------------------
-
-loc_4CE1C9: ; CODE XREF: CEncoder_GetOptimum+115j
- ; CEncoder_GetOptimum+11Dj
- mov [esp+edx+90h+var_10], esi
-
-loc_4CE1D0: ; CODE XREF: CEncoder_GetOptimum+159j
- ; CEncoder_GetOptimum+167j
- add [esp+90h+var_64], 1
- add [esp+90h+var_6C], 4
- add edx, 4
- cmp edx, 10h
- jb loc_4CE160
- mov ecx, [esp+90h+var_50]
- mov ebx, [esp+ecx*4+90h+var_10]
- mov eax, [ebp+32EF8h]
- cmp ebx, eax
- mov [esp+90h+var_40], ebx
- jb short loc_4CE234
- mov edx, [esp+90h+arg_4]
- lea eax, [ebx-1]
- cmp eax, esi
- mov [edx], ecx
- jz short loc_4CE225
- add [ebp+32F04h], eax
- mov ecx, [ebp+7Ch]
- push eax
- mov eax, [ebp+80h]
- push eax
- call ecx
- add esp, 8
-
-loc_4CE225: ; CODE XREF: CEncoder_GetOptimum+1ADj
- pop edi
- mov eax, ebx
- pop ebx
- pop esi
- pop ebp
- add esp, 80h
- retn 8
-; ---------------------------------------------------------------------------
-
-loc_4CE234: ; CODE XREF: CEncoder_GetOptimum+19Dj
- mov esi, [esp+90h+var_68]
- cmp esi, eax
- jb short loc_4CE27F
- mov edx, [esp+90h+var_70]
- mov eax, [ebp+edx*4+3265Ch]
- mov ecx, [esp+90h+arg_4]
- add eax, 4
- mov [ecx], eax
- lea eax, [esi-1]
- test eax, eax
- jz short loc_4CE270
- mov edx, [ebp+80h]
- add [ebp+32F04h], eax
- push eax
- mov eax, [ebp+7Ch]
- push edx
- call eax
- add esp, 8
-
-loc_4CE270: ; CODE XREF: CEncoder_GetOptimum+1F8j
- pop edi
- pop ebx
- mov eax, esi
- pop esi
- pop ebp
- add esp, 80h
- retn 8
-; ---------------------------------------------------------------------------
-
-loc_4CE27F: ; CODE XREF: CEncoder_GetOptimum+1DAj
- mov al, [edi]
- mov esi, [esp+90h+var_20]
- sub edi, esi
- cmp [esp+90h+var_68], 2
- mov cl, [edi-1]
- mov byte ptr [esp+90h+var_4C], al
- mov byte ptr [esp+90h+var_50], cl
- jnb short loc_4CE2C1
- cmp al, cl
- jz short loc_4CE2C1
- cmp ebx, 2
- jnb short loc_4CE2C1
- mov ecx, [esp+90h+arg_4]
- pop edi
- pop ebx
- pop esi
- mov dword ptr [ecx], 0FFFFFFFFh
- mov eax, 1
- pop ebp
- add esp, 80h
- retn 8
-; ---------------------------------------------------------------------------
-
-loc_4CE2C1: ; CODE XREF: CEncoder_GetOptimum+237j
- ; CEncoder_GetOptimum+23Bj ...
- mov edx, [esp+90h+var_4C]
- mov bl, [ebp+10h]
- mov edi, [ebp+33B60h]
- and edi, [esp+90h+arg_0]
- mov ecx, [esp+90h+var_50]
- push edx
- cmp bl, 7
- setnb dl
- push ecx
- mov [ebp+0F0h], bl
- mov eax, [ebp+32654h]
- mov ecx, 8
- sub cl, al
- push edx
- movzx edx, byte ptr [ebp+11h]
- shr edx, cl
- mov ecx, [ebp+3265Ch]
- and ecx, [esp+9Ch+arg_0]
- mov [esp+9Ch+var_3C], ecx
- mov ecx, eax
- mov eax, [esp+9Ch+var_3C]
- shl eax, cl
- add edx, eax
- imul edx, 0C00h
- add edx, [ebp+32650h]
- mov ecx, edx
- call sub_4CDAC0
- movzx ecx, bl
- shl ecx, 4
- add ecx, edi
- mov edx, [ebp+ecx*4+280F0h]
- shr edx, 2
- add eax, dword_550998[edx*4]
- mov ebx, 800h
- mov [ebp+124h], eax
- mov dword ptr [ebp+12Ch], 0FFFFFFFFh
- mov byte ptr [ebp+119h], 0
- mov cl, [ebp+10h]
- movzx eax, cl
- mov edx, eax
- shl edx, 4
- add edx, edi
- sub ebx, [ebp+edx*4+280F0h]
- mov edx, 800h
- sub edx, [ebp+eax*4+283F0h]
- mov al, byte ptr [esp+90h+var_4C]
- shr edx, 2
- mov edx, dword_550998[edx*4]
- shr ebx, 2
- mov ebx, dword_550998[ebx*4]
- add edx, ebx
- cmp byte ptr [esp+90h+var_50], al
- mov [esp+90h+var_44], ebx
- mov [esp+90h+var_3C], edx
- jnz short loc_4CE3F3
- movzx eax, cl
- mov ebx, [ebp+eax*4+28420h]
- mov ecx, eax
- shl ecx, 4
- add ecx, edi
- mov ecx, [ebp+ecx*4+284B0h]
- shr ecx, 2
- mov eax, dword_550998[ecx*4]
- shr ebx, 2
- add eax, dword_550998[ebx*4]
- add eax, edx
- cmp eax, [ebp+124h]
- jnb short loc_4CE3F3
- mov [ebp+124h], eax
- mov dword ptr [ebp+12Ch], 0
- mov byte ptr [ebp+119h], 0
-
-loc_4CE3F3: ; CODE XREF: CEncoder_GetOptimum+344j
- ; CEncoder_GetOptimum+37Aj
- mov eax, [esp+90h+var_68]
- mov ecx, [esp+90h+var_40]
- cmp eax, ecx
- jb short loc_4CE405
- mov [esp+90h+var_7C], eax
- jmp short loc_4CE40B
-; ---------------------------------------------------------------------------
-
-loc_4CE405: ; CODE XREF: CEncoder_GetOptimum+39Dj
- mov [esp+90h+var_7C], ecx
- mov eax, ecx
-
-loc_4CE40B: ; CODE XREF: CEncoder_GetOptimum+3A3j
- cmp eax, 2
- jnb short loc_4CE431
- mov edx, [ebp+12Ch]
- mov eax, [esp+90h+arg_4]
- pop edi
- pop ebx
- pop esi
- mov [eax], edx
- mov eax, 1
- pop ebp
- add esp, 80h
- retn 8
-; ---------------------------------------------------------------------------
-
-loc_4CE431: ; CODE XREF: CEncoder_GetOptimum+3AEj
- mov ecx, [esp+90h+var_1C]
- mov edx, [esp+90h+var_18]
- xor ebx, ebx
- mov [ebp+128h], ebx
- mov [ebp+10Ch], ecx
- mov ecx, [esp+90h+var_14]
- mov [ebp+110h], edx
- lea edx, [eax+eax*4]
- mov [ebp+114h], ecx
- mov [ebp+108h], esi
- lea ecx, [ebp+edx*8+0FCh]
- jmp short loc_4CE470
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CE470: ; CODE XREF: CEncoder_GetOptimum+407j
- ; CEncoder_GetOptimum+41Fj
- mov dword ptr [ecx], 0FFFFFFFh
- sub eax, 1
- sub ecx, 28h
- cmp eax, 2
- jnb short loc_4CE470
-
-loc_4CE481: ; CODE XREF: CEncoder_GetOptimum+48Ej
- mov esi, [esp+ebx*4+90h+var_10]
- cmp esi, 2
- jb short loc_4CE4E8
- movzx eax, byte ptr [ebp+10h]
- push edi
- push eax
- push ebx
- mov ecx, ebp
- call sub_4CD9B0
- add eax, [esp+90h+var_3C]
- mov ecx, edi
- imul ecx, 110h
- add ecx, esi
- mov [esp+90h+var_40], eax
- lea edx, [esi+esi*4]
- lea eax, [ebp+ecx*4+2E204h]
- lea ecx, [ebp+edx*8+0FCh]
- mov edi, edi
-
-loc_4CE4C0: ; CODE XREF: CEncoder_GetOptimum+486j
- mov edx, [eax]
- add edx, [esp+90h+var_40]
- cmp edx, [ecx]
- jnb short loc_4CE4DA
- mov [ecx], edx
- mov dword ptr [ecx+4], 0
- mov [ecx+8], ebx
- mov byte ptr [ecx-0Bh], 0
-
-loc_4CE4DA: ; CODE XREF: CEncoder_GetOptimum+468j
- sub esi, 1
- sub eax, 4
- sub ecx, 28h
- cmp esi, 2
- jnb short loc_4CE4C0
-
-loc_4CE4E8: ; CODE XREF: CEncoder_GetOptimum+42Bj
- add ebx, 1
- cmp ebx, 4
- jb short loc_4CE481
- movzx eax, byte ptr [ebp+10h]
- mov ecx, [ebp+eax*4+283F0h]
- shr ecx, 2
- mov eax, dword_550998[ecx*4]
- add eax, [esp+90h+var_44]
- mov [esp+90h+var_3C], eax
- mov eax, [esp+90h+var_10]
- cmp eax, 2
- lea ebx, [eax+1]
- jnb short loc_4CE521
- mov ebx, 2
-
-loc_4CE521: ; CODE XREF: CEncoder_GetOptimum+4BAj
- cmp ebx, [esp+90h+var_68]
- ja loc_4CE5BA
- xor eax, eax
- cmp ebx, [ebp+32660h]
- mov [esp+90h+var_60], eax
- jbe short loc_4CE550
- lea esp, [esp+0]
-
-loc_4CE540: ; CODE XREF: CEncoder_GetOptimum+4EAj
- add eax, 2
- cmp ebx, [ebp+eax*4+32660h]
- ja short loc_4CE540
- mov [esp+90h+var_60], eax
-
-loc_4CE550: ; CODE XREF: CEncoder_GetOptimum+4D7j
- lea edx, [ebx+ebx*4]
- lea esi, [ebp+edx*8+0FCh]
- lea ebx, [ebx+0]
-
-loc_4CE560: ; CODE XREF: CEncoder_GetOptimum+558j
- mov eax, [esp+90h+var_60]
- mov eax, [ebp+eax*4+32664h]
- push edi
- push ebx
- push eax
- mov ecx, ebp
- mov [esp+9Ch+var_40], eax
- call sub_4CAEC0
- add eax, [esp+90h+var_3C]
- cmp eax, [esi]
- jnb short loc_4CE598
- mov ecx, [esp+90h+var_40]
- add ecx, 4
- mov [esi], eax
- mov dword ptr [esi+4], 0
- mov [esi+8], ecx
- mov byte ptr [esi-0Bh], 0
-
-loc_4CE598: ; CODE XREF: CEncoder_GetOptimum+51Fj
- mov eax, [esp+90h+var_60]
- cmp ebx, [ebp+eax*4+32660h]
- jnz short loc_4CE5B2
- add eax, 2
- cmp eax, [esp+90h+var_70]
- mov [esp+90h+var_60], eax
- jz short loc_4CE5BA
-
-loc_4CE5B2: ; CODE XREF: CEncoder_GetOptimum+543j
- add ebx, 1
- add esi, 28h
- jmp short loc_4CE560
-; ---------------------------------------------------------------------------
-
-loc_4CE5BA: ; CODE XREF: CEncoder_GetOptimum+4C5j
- ; CEncoder_GetOptimum+550j
- mov eax, 1
- cmp [esp+90h+var_7C], eax
- mov [esp+90h+var_78], eax
- jz loc_4CF1D0
- mov esi, eax
- jmp short loc_4CE5D5
-; ---------------------------------------------------------------------------
-
-loc_4CE5D1: ; CODE XREF: CEncoder_GetOptimum+116Aj
- mov esi, [esp+90h+var_78]
-
-loc_4CE5D5: ; CODE XREF: CEncoder_GetOptimum+56Fj
- mov edx, [ebp+80h]
- mov eax, [ebp+70h]
- push edx
- call eax
- add esp, 4
- lea ecx, [esp+90h+var_4C]
- push ecx
- mov ecx, ebp
- mov [esp+94h+var_60], eax
- call sub_4CB3B0
- cmp eax, [ebp+32EF8h]
- mov [esp+90h+var_28], eax
- jnb loc_4CF1D7
- add [esp+90h+arg_0], 1
- lea edx, [esi+esi*4+1Eh]
- mov bl, [ebp+edx*8+1]
- test bl, bl
- lea eax, [ebp+edx*8+0]
- mov edx, [eax+10h]
- jz short loc_4CE673
- sub edx, 1
- cmp byte ptr [eax+2], 0
- jz short loc_4CE660
- mov ecx, [eax+4]
- add ecx, 6
- cmp dword ptr [eax+8], 4
- lea ecx, [ecx+ecx*4]
- mov cl, [ebp+ecx*8+0]
- movzx ecx, cl
- jnb short loc_4CE64F
- mov cl, ds:kRepNextStates[ecx]
- movzx ecx, cl
- mov cl, ds:kLiteralNextStates[ecx]
- jmp short loc_4CE67B
-; ---------------------------------------------------------------------------
-
-loc_4CE64F: ; CODE XREF: CEncoder_GetOptimum+5DCj
- mov cl, ds:kMatchNextStates[ecx]
- movzx ecx, cl
- mov cl, ds:kLiteralNextStates[ecx]
- jmp short loc_4CE67B
-; ---------------------------------------------------------------------------
-
-loc_4CE660: ; CODE XREF: CEncoder_GetOptimum+5C6j
- lea ecx, [edx+edx*4+1Eh]
- mov cl, [ebp+ecx*8+0]
- movzx ecx, cl
- mov cl, ds:kLiteralNextStates[ecx]
- jmp short loc_4CE67B
-; ---------------------------------------------------------------------------
-
-loc_4CE673: ; CODE XREF: CEncoder_GetOptimum+5BDj
- lea ecx, [edx+edx*4+1Eh]
- mov cl, [ebp+ecx*8+0]
-
-loc_4CE67B: ; CODE XREF: CEncoder_GetOptimum+5EDj
- ; CEncoder_GetOptimum+5FEj ...
- add esi, 0FFFFFFFFh
- cmp edx, esi
- jnz short loc_4CE6AC
- cmp dword ptr [eax+14h], 0
- jnz short loc_4CE69A
- movzx edx, cl
- mov bl, ds:kShortRepNextStates[edx]
- mov byte ptr [esp+90h+var_64], bl
- jmp loc_4CE754
-; ---------------------------------------------------------------------------
-
-loc_4CE69A: ; CODE XREF: CEncoder_GetOptimum+626j
- movzx ecx, cl
- mov bl, ds:kLiteralNextStates[ecx]
- mov byte ptr [esp+90h+var_64], bl
- jmp loc_4CE754
-; ---------------------------------------------------------------------------
-
-loc_4CE6AC: ; CODE XREF: CEncoder_GetOptimum+620j
- test bl, bl
- jz short loc_4CE6CB
- cmp byte ptr [eax+2], 0
- jz short loc_4CE6CB
- mov edi, [eax+8]
- mov edx, [eax+4]
- movzx ecx, cl
- mov bl, ds:kRepNextStates[ecx]
- mov [esp+90h+var_68], edi
- jmp short loc_4CE6EA
-; ---------------------------------------------------------------------------
-
-loc_4CE6CB: ; CODE XREF: CEncoder_GetOptimum+64Ej
- ; CEncoder_GetOptimum+654j
- mov esi, [eax+14h]
- cmp esi, 4
- mov [esp+90h+var_68], esi
- movzx ecx, cl
- mov edi, esi
- jnb short loc_4CE6E4
- mov bl, ds:kRepNextStates[ecx]
- jmp short loc_4CE6EA
-; ---------------------------------------------------------------------------
-
-loc_4CE6E4: ; CODE XREF: CEncoder_GetOptimum+67Aj
- mov bl, ds:kMatchNextStates[ecx]
-
-loc_4CE6EA: ; CODE XREF: CEncoder_GetOptimum+669j
- ; CEncoder_GetOptimum+682j
- cmp edi, 4
- lea edx, [edx+edx*4+1Eh]
- mov byte ptr [esp+90h+var_64], bl
- lea edx, [ebp+edx*8+0]
- jnb short loc_4CE738
- mov ecx, [edx+edi*4+18h]
- mov esi, 1
- cmp edi, esi
- mov [esp+90h+var_20], ecx
- jb short loc_4CE723
- mov ecx, edi
- lea esi, [edx+18h]
- lea edi, [esp+90h+var_1C]
- rep movsd
- mov esi, [esp+90h+var_68]
- add esi, 1
- cmp esi, 4
- jnb short loc_4CE754
-
-loc_4CE723: ; CODE XREF: CEncoder_GetOptimum+6AAj
- lea edx, [edx+esi*4+18h]
- mov ecx, 4
- lea edi, [esp+esi*4+90h+var_20]
- sub ecx, esi
- mov esi, edx
- rep movsd
- jmp short loc_4CE754
-; ---------------------------------------------------------------------------
-
-loc_4CE738: ; CODE XREF: CEncoder_GetOptimum+699j
- mov ecx, [edx+18h]
- mov [esp+90h+var_1C], ecx
- mov ecx, [edx+1Ch]
- mov edx, [edx+20h]
- add edi, 0FFFFFFFCh
- mov [esp+90h+var_20], edi
- mov [esp+90h+var_18], ecx
- mov [esp+90h+var_14], edx
-
-loc_4CE754: ; CODE XREF: CEncoder_GetOptimum+635j
- ; CEncoder_GetOptimum+647j ...
- mov ecx, [esp+90h+var_1C]
- mov edx, [esp+90h+var_18]
- mov edi, [esp+90h+var_20]
- mov [eax], bl
- mov [eax+1Ch], ecx
- mov ecx, [esp+90h+var_14]
- mov [eax+18h], edi
- mov [eax+20h], edx
- mov [eax+24h], ecx
- mov esi, [eax+0Ch]
- mov edx, [ebp+80h]
- mov eax, [ebp+74h]
- push edx
- mov [esp+94h+var_3C], esi
- call eax
- movzx ecx, byte ptr [eax-1]
- sub eax, 1
- mov edx, eax
- mov byte ptr [esp+94h+var_5C], cl
- sub edx, edi
- movzx ecx, byte ptr [edx-1]
- lea edi, [edx-1]
- mov edx, [ebp+32654h]
- mov byte ptr [esp+94h+var_58], cl
- mov ecx, [ebp+33B60h]
- and ecx, [esp+94h+arg_0]
- mov [esp+94h+var_40], edi
- movzx edi, bl
- mov [esp+94h+var_54], ecx
- mov [esp+94h+var_68], edi
- add esp, 4
- shl edi, 4
- add edi, ecx
- mov ecx, [esp+90h+var_5C]
- push ecx
- mov ecx, [esp+94h+var_58]
- push ecx
- cmp bl, 7
- mov ebx, [ebp+3265Ch]
- setnb cl
- and ebx, [esp+98h+arg_0]
- mov [esp+98h+var_74], eax
- movzx eax, byte ptr [eax-1]
- push ecx
- mov ecx, 8
- sub cl, dl
- shr eax, cl
- mov ecx, edx
- shl ebx, cl
- add eax, ebx
- imul eax, 0C00h
- add eax, [ebp+32650h]
- mov ecx, eax
- call sub_4CDAC0
- mov ecx, [ebp+edi*4+280F0h]
- shr ecx, 2
- add eax, dword_550998[ecx*4]
- mov ecx, [esp+90h+var_78]
- add eax, esi
- lea edx, [ecx+ecx*4+23h]
- cmp eax, [ebp+edx*8+0Ch]
- lea esi, [ebp+edx*8+0]
- mov [esp+90h+var_7D], 0
- jnb short loc_4CE851
- mov [esi+0Ch], eax
- mov [esi+10h], ecx
- mov dword ptr [esi+14h], 0FFFFFFFFh
- mov byte ptr [esi+1], 0
- mov [esp+90h+var_7D], 1
-
-loc_4CE851: ; CODE XREF: CEncoder_GetOptimum+7D9j
- mov ebx, [esp+90h+var_68]
- mov edx, 800h
- sub edx, [ebp+edi*4+280F0h]
- shr edx, 2
- mov ecx, dword_550998[edx*4]
- add ecx, [esp+90h+var_3C]
- mov edx, 800h
- sub edx, [ebp+ebx*4+283F0h]
- mov ebx, [esp+90h+var_78]
- shr edx, 2
- mov edx, dword_550998[edx*4]
- add edx, ecx
- mov [esp+90h+var_24], ecx
- mov cl, byte ptr [esp+90h+var_58]
- cmp cl, byte ptr [esp+90h+var_5C]
- mov [esp+90h+var_38], edx
- jnz short loc_4CE8EB
- cmp [esi+10h], ebx
- jnb short loc_4CE8A8
- cmp dword ptr [esi+14h], 0
- jz short loc_4CE8EB
-
-loc_4CE8A8: ; CODE XREF: CEncoder_GetOptimum+840j
- mov ecx, [esp+90h+var_68]
- mov ecx, [ebp+ecx*4+28420h]
- mov edi, [ebp+edi*4+284B0h]
- shr ecx, 2
- mov ecx, dword_550998[ecx*4]
- shr edi, 2
- add ecx, dword_550998[edi*4]
- add ecx, edx
- cmp ecx, [esi+0Ch]
- ja short loc_4CE8EB
- mov [esi+0Ch], ecx
- mov [esi+10h], ebx
- mov dword ptr [esi+14h], 0
- mov byte ptr [esi+1], 0
- mov [esp+90h+var_7D], 1
-
-loc_4CE8EB: ; CODE XREF: CEncoder_GetOptimum+83Bj
- ; CEncoder_GetOptimum+846j ...
- mov edx, [esp+90h+var_60]
- mov ecx, 0FFFh
- sub ecx, ebx
- cmp ecx, edx
- jnb short loc_4CE900
- mov edx, ecx
- mov [esp+90h+var_60], edx
-
-loc_4CE900: ; CODE XREF: CEncoder_GetOptimum+898j
- cmp edx, 2
- mov ebx, edx
- mov [esp+90h+var_6C], ebx
- jb loc_4CF1BB
- mov esi, [ebp+32EF8h]
- mov edi, [esp+90h+var_60]
- cmp edi, esi
- jbe short loc_4CE923
- mov ebx, esi
- mov [esp+90h+var_6C], esi
-
-loc_4CE923: ; CODE XREF: CEncoder_GetOptimum+8BBj
- cmp [esp+90h+var_7D], 0
- jnz loc_4CEA90
- mov dl, byte ptr [esp+90h+var_5C]
- cmp byte ptr [esp+90h+var_58], dl
- jz loc_4CEA90
- lea ecx, [esi+1]
- cmp edi, ecx
- jb short loc_4CE945
- mov edi, ecx
-
-loc_4CE945: ; CODE XREF: CEncoder_GetOptimum+8E1j
- mov esi, 1
- cmp edi, esi
- jbe short loc_4CE975
- mov ebx, [esp+90h+var_74]
- mov edx, [esp+90h+var_40]
- lea ecx, [ebx+1]
- sub edx, ebx
- jmp short loc_4CE960
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CE960: ; CODE XREF: CEncoder_GetOptimum+8FBj
- ; CEncoder_GetOptimum+90Fj
- mov bl, [ecx]
- cmp bl, [edx+ecx]
- jnz short loc_4CE971
- add esi, 1
- add ecx, 1
- cmp esi, edi
- jb short loc_4CE960
-
-loc_4CE971: ; CODE XREF: CEncoder_GetOptimum+905j
- mov ebx, [esp+90h+var_6C]
-
-loc_4CE975: ; CODE XREF: CEncoder_GetOptimum+8ECj
- add esi, 0FFFFFFFFh
- cmp esi, 2
- mov [esp+90h+var_50], esi
- jb loc_4CEA90
- mov ecx, [esp+90h+var_68]
- mov dl, ds:kLiteralNextStates[ecx]
- mov ecx, [esp+90h+arg_0]
- movzx ebx, dl
- add ecx, 1
- and ecx, [ebp+33B60h]
- mov edx, ebx
- shl edx, 4
- lea esi, [edx+ecx]
- mov edx, 800h
- sub edx, [ebp+ebx*4+283F0h]
- mov edi, 800h
- sub edi, [ebp+esi*4+280F0h]
- shr edx, 2
- mov edx, dword_550998[edx*4]
- shr edi, 2
- add edx, dword_550998[edi*4]
- mov edi, [esp+90h+var_78]
- add edx, eax
- mov eax, [esp+90h+var_50]
- lea edi, [eax+edi+1]
- mov eax, [esp+90h+var_7C]
- cmp eax, edi
- mov [esp+90h+var_40], esi
- jnb short loc_4CEA22
- mov esi, [esp+90h+var_7C]
- lea eax, [eax+eax*4]
- lea eax, [ebp+eax*8+0FCh]
- mov [esp+90h+var_3C], eax
- mov eax, edi
- sub eax, esi
- add esi, eax
- mov [esp+90h+var_7C], esi
- mov esi, [esp+90h+var_3C]
-
-loc_4CEA10: ; CODE XREF: CEncoder_GetOptimum+9BCj
- add esi, 28h
- sub eax, 1
- mov dword ptr [esi], 0FFFFFFFh
- jnz short loc_4CEA10
- mov esi, [esp+90h+var_40]
-
-loc_4CEA22: ; CODE XREF: CEncoder_GetOptimum+98Ej
- imul ecx, 110h
- add ecx, [esp+90h+var_50]
- mov eax, 800h
- sub eax, [ebp+esi*4+284B0h]
- mov esi, [ebp+ebx*4+28420h]
- mov ebx, [esp+90h+var_6C]
- shr eax, 2
- mov eax, dword_550998[eax*4]
- shr esi, 2
- add eax, dword_550998[esi*4]
- mov esi, [esp+90h+var_7C]
- add eax, [ebp+ecx*4+2E204h]
- lea ecx, [edi+edi*4+1Eh]
- add eax, edx
- cmp eax, [ebp+ecx*8+0Ch]
- lea ecx, [ebp+ecx*8+0]
- jnb short loc_4CEA94
- mov edx, [esp+90h+var_78]
- add edx, 1
- mov [ecx+0Ch], eax
- mov [ecx+10h], edx
- mov dword ptr [ecx+14h], 0
- mov byte ptr [ecx+1], 1
- mov byte ptr [ecx+2], 0
- jmp short loc_4CEA94
-; ---------------------------------------------------------------------------
-
-loc_4CEA90: ; CODE XREF: CEncoder_GetOptimum+8C8j
- ; CEncoder_GetOptimum+8D6j ...
- mov esi, [esp+90h+var_7C]
-
-loc_4CEA94: ; CODE XREF: CEncoder_GetOptimum+A10j
- ; CEncoder_GetOptimum+A2Ej
- mov [esp+90h+var_70], 0
- mov ecx, [esp+90h+var_70]
- mov [esp+90h+var_40], 2
- jmp short loc_4CEAB8
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CEAB0: ; CODE XREF: CEncoder_GetOptimum+D63j
- mov ebx, [esp+90h+var_6C]
- mov esi, [esp+90h+var_7C]
-
-loc_4CEAB8: ; CODE XREF: CEncoder_GetOptimum+A48j
- mov edx, [esp+90h+var_74]
- mov eax, edx
- sub eax, [esp+ecx*4+90h+var_20]
- mov cl, [edx]
- sub eax, 1
- cmp cl, [eax]
- mov [esp+90h+var_48], eax
- jnz loc_4CEDB5
- mov cl, [edx+1]
- cmp cl, [eax+1]
- jnz loc_4CEDB5
- mov edi, 2
- cmp ebx, edi
- jbe short loc_4CEB01
- lea ecx, [edx+2]
- sub eax, edx
- lea ecx, [ecx+0]
-
-loc_4CEAF0: ; CODE XREF: CEncoder_GetOptimum+A9Fj
- mov dl, [ecx]
- cmp dl, [eax+ecx]
- jnz short loc_4CEB01
- add edi, 1
- add ecx, 1
- cmp edi, ebx
- jb short loc_4CEAF0
-
-loc_4CEB01: ; CODE XREF: CEncoder_GetOptimum+A86j
- ; CEncoder_GetOptimum+A95j
- mov eax, [esp+90h+var_78]
- lea ebx, [edi+eax]
- cmp esi, ebx
- jnb short loc_4CEB2E
- mov eax, ebx
- lea ecx, [esi+esi*4]
- sub eax, esi
- add esi, eax
- lea ecx, [ebp+ecx*8+0FCh]
- mov [esp+90h+var_7C], esi
-
-loc_4CEB20: ; CODE XREF: CEncoder_GetOptimum+ACCj
- add ecx, 28h
- sub eax, 1
- mov dword ptr [ecx], 0FFFFFFFh
- jnz short loc_4CEB20
-
-loc_4CEB2E: ; CODE XREF: CEncoder_GetOptimum+AAAj
- mov edx, [esp+90h+var_54]
- mov eax, [esp+90h+var_64]
- mov ecx, [esp+90h+var_70]
- push edx
- push eax
- push ecx
- mov ecx, ebp
- mov esi, edi
- call sub_4CD9B0
- add eax, [esp+90h+var_38]
- mov ecx, [esp+90h+var_54]
- imul ecx, 110h
- lea edx, [edi+ecx]
- mov [esp+90h+var_34], ecx
- lea ecx, [ebp+edx*4+2E204h]
- mov [esp+90h+var_50], ecx
- lea edx, [ebx+ebx*4]
- mov ebx, [esp+90h+var_50]
- mov [esp+90h+var_2C], eax
- lea ecx, [ebp+edx*8+0FCh]
-
-loc_4CEB78: ; CODE XREF: CEncoder_GetOptimum+B40j
- mov edx, [ebx]
- add edx, eax
- cmp edx, [ecx]
- jnb short loc_4CEB94
- mov [ecx], edx
- mov edx, [esp+90h+var_78]
- mov [ecx+4], edx
- mov edx, [esp+90h+var_70]
- mov [ecx+8], edx
- mov byte ptr [ecx-0Bh], 0
-
-loc_4CEB94: ; CODE XREF: CEncoder_GetOptimum+B1Ej
- sub edi, 1
- sub ebx, 4
- sub ecx, 28h
- cmp edi, 2
- jnb short loc_4CEB78
- cmp [esp+90h+var_70], 0
- jnz short loc_4CEBB0
- lea eax, [esi+1]
- mov [esp+90h+var_40], eax
-
-loc_4CEBB0: ; CODE XREF: CEncoder_GetOptimum+B47j
- mov ecx, [ebp+32EF8h]
- mov edx, [esp+90h+var_60]
- lea eax, [esi+1]
- add ecx, eax
- cmp edx, ecx
- jnb short loc_4CEBC5
- mov ecx, edx
-
-loc_4CEBC5: ; CODE XREF: CEncoder_GetOptimum+B61j
- cmp eax, ecx
- jnb short loc_4CEBE7
- mov ebx, [esp+90h+var_74]
- mov edi, [esp+90h+var_48]
- lea edx, [eax+ebx]
- sub edi, ebx
-
-loc_4CEBD6: ; CODE XREF: CEncoder_GetOptimum+B85j
- mov bl, [edx]
- cmp bl, [edx+edi]
- jnz short loc_4CEBE7
- add eax, 1
- add edx, 1
- cmp eax, ecx
- jb short loc_4CEBD6
-
-loc_4CEBE7: ; CODE XREF: CEncoder_GetOptimum+B67j
- ; CEncoder_GetOptimum+B7Bj
- or ecx, 0FFFFFFFFh
- sub ecx, esi
- add eax, ecx
- cmp eax, 2
- mov [esp+90h+var_44], eax
- jb loc_4CEDB5
- mov edx, [esp+90h+var_68]
- mov cl, ds:kRepNextStates[edx]
- mov eax, [ebp+33B60h]
- mov edi, [esp+90h+arg_0]
- movzx ecx, cl
- mov ebx, eax
- lea edx, [esi+edi]
- and ebx, edx
- mov edx, ecx
- mov cl, ds:kLiteralNextStates[ecx]
- shl edx, 4
- add ebx, edx
- mov edx, [ebp+ebx*4+280F0h]
- movzx ebx, cl
- shr edx, 2
- mov edx, dword_550998[edx*4]
- mov [esp+90h+var_30], edx
- lea edi, [esi+edi+1]
- and edi, eax
- mov eax, [ebp+32654h]
- mov ecx, ebx
- shl ecx, 4
- add ecx, edi
- mov [esp+90h+var_50], ecx
- mov ecx, [esp+90h+var_74]
- movzx edx, byte ptr [esi+ecx]
- push edx
- mov edx, [esp+94h+var_48]
- movzx edx, byte ptr [esi+edx]
- push edx
- movzx edx, byte ptr [ecx+esi-1]
- mov ecx, 8
- sub cl, al
- shr edx, cl
- mov ecx, [esp+98h+arg_0]
- lea eax, [esi+ecx]
- mov ecx, [ebp+3265Ch]
- and ecx, eax
- mov eax, ecx
- mov ecx, [ebp+32654h]
- shl eax, cl
- push 1
- add edx, eax
- imul edx, 0C00h
- add edx, [ebp+32650h]
- mov ecx, edx
- call sub_4CDAC0
- mov ecx, [esp+90h+var_50]
- mov edx, 800h
- sub edx, [ebp+ecx*4+280F0h]
- mov ecx, [esp+90h+var_34]
- shr edx, 2
- add eax, dword_550998[edx*4]
- mov edx, 800h
- sub edx, [ebp+ebx*4+283F0h]
- shr edx, 2
- add eax, dword_550998[edx*4]
- lea edx, [esi+ecx]
- add eax, [ebp+edx*4+2E204h]
- mov ecx, [esp+90h+var_44]
- add eax, [esp+90h+var_30]
- mov edx, [esp+90h+var_78]
- add eax, [esp+90h+var_2C]
- add ecx, esi
- lea ecx, [ecx+edx+1]
- cmp [esp+90h+var_7C], ecx
- mov [esp+90h+var_30], ecx
- jnb short loc_4CED3E
- mov edx, [esp+90h+var_7C]
- lea edx, [edx+edx*4]
- lea edx, [ebp+edx*8+0FCh]
- mov [esp+90h+var_2C], edx
- mov edx, [esp+90h+var_7C]
- sub ecx, edx
- add edx, ecx
- mov [esp+90h+var_7C], edx
- mov edx, [esp+90h+var_2C]
- jmp short loc_4CED30
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CED30: ; CODE XREF: CEncoder_GetOptimum+CCBj
- ; CEncoder_GetOptimum+CDCj
- add edx, 28h
- sub ecx, 1
- mov dword ptr [edx], 0FFFFFFFh
- jnz short loc_4CED30
-
-loc_4CED3E: ; CODE XREF: CEncoder_GetOptimum+CA7j
- mov edx, [esp+90h+var_50]
- imul edi, 110h
- add edi, [esp+90h+var_44]
- mov ecx, 800h
- sub ecx, [ebp+edx*4+284B0h]
- mov edx, [ebp+ebx*4+28420h]
- shr ecx, 2
- mov ecx, dword_550998[ecx*4]
- shr edx, 2
- add ecx, dword_550998[edx*4]
- add ecx, [ebp+edi*4+2E204h]
- add ecx, eax
- mov eax, [esp+90h+var_30]
- lea eax, [eax+eax*4+1Eh]
- cmp ecx, [ebp+eax*8+0Ch]
- lea eax, [ebp+eax*8+0]
- jnb short loc_4CEDB5
- mov [eax+0Ch], ecx
- mov ecx, [esp+90h+var_78]
- lea edx, [esi+ecx+1]
- mov [eax+4], ecx
- mov ecx, [esp+90h+var_70]
- mov [eax+10h], edx
- mov dword ptr [eax+14h], 0
- mov byte ptr [eax+1], 1
- mov byte ptr [eax+2], 1
- mov [eax+8], ecx
-
-loc_4CEDB5: ; CODE XREF: CEncoder_GetOptimum+A6Dj
- ; CEncoder_GetOptimum+A79j ...
- mov ecx, [esp+90h+var_70]
- add ecx, 1
- cmp ecx, 4
- mov [esp+90h+var_70], ecx
- jb loc_4CEAB0
- mov edx, [esp+90h+var_28]
- mov ecx, [esp+90h+var_6C]
- cmp edx, ecx
- jbe short loc_4CEDFB
- xor eax, eax
- cmp ecx, [ebp+32660h]
- mov edx, ecx
- jbe short loc_4CEDED
-
-loc_4CEDE1: ; CODE XREF: CEncoder_GetOptimum+D8Bj
- add eax, 2
- cmp ecx, [ebp+eax*4+32660h]
- ja short loc_4CEDE1
-
-loc_4CEDED: ; CODE XREF: CEncoder_GetOptimum+D7Fj
- mov [ebp+eax*4+32660h], ecx
- add eax, 2
- mov [esp+90h+var_4C], eax
-
-loc_4CEDFB: ; CODE XREF: CEncoder_GetOptimum+D73j
- mov esi, [esp+90h+var_40]
- cmp edx, esi
- jb loc_4CF1BB
- mov eax, [esp+90h+var_68]
- mov ecx, [ebp+eax*4+283F0h]
- shr ecx, 2
- mov eax, dword_550998[ecx*4]
- add eax, [esp+90h+var_24]
- mov ecx, [esp+90h+var_7C]
- mov [esp+90h+var_40], eax
- mov eax, [esp+90h+var_78]
- add eax, edx
- cmp ecx, eax
- jnb short loc_4CEE52
- lea edx, [ecx+ecx*4]
- sub eax, ecx
- add ecx, eax
- lea edx, [ebp+edx*8+0FCh]
- mov [esp+90h+var_7C], ecx
-
-loc_4CEE44: ; CODE XREF: CEncoder_GetOptimum+DF0j
- add edx, 28h
- sub eax, 1
- mov dword ptr [edx], 0FFFFFFFh
- jnz short loc_4CEE44
-
-loc_4CEE52: ; CODE XREF: CEncoder_GetOptimum+DD0j
- xor eax, eax
- cmp esi, [ebp+32660h]
- mov [esp+90h+var_70], eax
- jbe short loc_4CEE70
-
-loc_4CEE60: ; CODE XREF: CEncoder_GetOptimum+E0Aj
- add eax, 2
- cmp esi, [ebp+eax*4+32660h]
- ja short loc_4CEE60
- mov [esp+90h+var_70], eax
-
-loc_4CEE70: ; CODE XREF: CEncoder_GetOptimum+DFEj
- lea ebx, ds:0[eax*4]
- mov edx, [ebx+ebp+32664h]
- mov ecx, 7FFFFh
- sub ecx, edx
- sar ecx, 1Fh
- and ecx, 0Ch
- add ecx, 6
- mov eax, edx
- shr eax, cl
- mov [esp+90h+var_6C], edx
- lea edi, [esi+1]
- movzx eax, byte ptr dword_551198[eax]
- lea ecx, [eax+ecx*2]
- mov eax, [esp+90h+var_54]
- imul eax, 110h
- add eax, esi
- lea eax, [ebp+eax*4+295B8h]
- mov [esp+90h+var_3C], ecx
- mov ecx, [esp+90h+var_78]
- mov [esp+90h+var_54], eax
- lea eax, [esi+ecx]
- lea eax, [eax+eax*4]
- lea ecx, [ebp+eax*8+0FCh]
- mov [esp+90h+var_50], ecx
-
-loc_4CEED3: ; CODE XREF: CEncoder_GetOptimum+1156j
- lea eax, [edi-3]
- cmp eax, 4
- jb short loc_4CEEE0
- mov eax, 3
-
-loc_4CEEE0: ; CODE XREF: CEncoder_GetOptimum+E79j
- cmp edx, 80h
- jnb short loc_4CEEF6
- shl eax, 7
- add eax, edx
- mov eax, [ebp+eax*4+33314h]
- jmp short loc_4CEF10
-; ---------------------------------------------------------------------------
-
-loc_4CEEF6: ; CODE XREF: CEncoder_GetOptimum+E86j
- shl eax, 6
- add eax, [esp+90h+var_3C]
- mov esi, edx
- mov eax, [ebp+eax*4+32F14h]
- and esi, 0Fh
- add eax, [ebp+esi*4+33B14h]
-
-loc_4CEF10: ; CODE XREF: CEncoder_GetOptimum+E94j
- add eax, [esp+90h+var_40]
- mov esi, [esp+90h+var_54]
- add eax, [esi]
- cmp eax, [ecx]
- mov [esp+90h+var_2C], eax
- jnb short loc_4CEF35
- mov [ecx], eax
- mov eax, [esp+90h+var_78]
- add edx, 4
- mov [ecx+4], eax
- mov [ecx+8], edx
- mov byte ptr [ecx-0Bh], 0
-
-loc_4CEF35: ; CODE XREF: CEncoder_GetOptimum+EC0j
- lea eax, [edi-1]
- cmp eax, [ebx+ebp+32660h]
- jnz loc_4CF1A1
- mov ebx, [esp+90h+var_74]
- mov eax, [ebp+32EF8h]
- mov esi, [esp+90h+var_60]
- mov edx, ebx
- sub edx, [esp+90h+var_6C]
- add eax, edi
- sub edx, 1
- cmp esi, eax
- mov ecx, edi
- jnb short loc_4CEF6C
- mov eax, esi
- mov [esp+90h+var_44], esi
- jmp short loc_4CEF70
-; ---------------------------------------------------------------------------
-
-loc_4CEF6C: ; CODE XREF: CEncoder_GetOptimum+F02j
- mov [esp+90h+var_44], eax
-
-loc_4CEF70: ; CODE XREF: CEncoder_GetOptimum+F0Aj
- cmp edi, eax
- jnb short loc_4CEF93
- lea esi, [edi+edx]
- sub ebx, edx
- lea esp, [esp+0]
-
-loc_4CEF80: ; CODE XREF: CEncoder_GetOptimum+F31j
- mov al, [ebx+esi]
- cmp al, [esi]
- jnz short loc_4CEF93
- add ecx, 1
- add esi, 1
- cmp ecx, [esp+90h+var_44]
- jb short loc_4CEF80
-
-loc_4CEF93: ; CODE XREF: CEncoder_GetOptimum+F12j
- ; CEncoder_GetOptimum+F25j
- or esi, 0FFFFFFFFh
- lea eax, [edi-1]
- sub esi, eax
- add ecx, esi
- cmp ecx, 2
- mov [esp+90h+var_48], ecx
- jb loc_4CF157
- mov ecx, [esp+90h+var_68]
- mov bl, ds:kMatchNextStates[ecx]
- mov ecx, [ebp+33B60h]
- mov eax, [esp+90h+arg_0]
- lea esi, [edi+eax-1]
- mov eax, ecx
- and eax, esi
- movzx esi, bl
- movzx edx, byte ptr [edi+edx-1]
- mov ebx, esi
- shl ebx, 4
- add ebx, eax
- mov ebx, [ebp+ebx*4+280F0h]
- shr ebx, 2
- mov ebx, dword_550998[ebx*4]
- mov [esp+90h+var_28], ebx
- mov bl, ds:kLiteralNextStates[esi]
- lea esi, [eax+1]
- mov eax, [ebp+32654h]
- and esi, ecx
- movzx ebx, bl
- mov ecx, ebx
- shl ecx, 4
- add ecx, esi
- mov [esp+90h+var_44], ecx
- mov ecx, [esp+90h+var_74]
- movzx ecx, byte ptr [ecx+edi-1]
- push ecx
- mov ecx, [esp+94h+var_74]
- push edx
- movzx edx, byte ptr [edi+ecx-2]
- mov ecx, 8
- sub cl, al
- shr edx, cl
- mov ecx, [esp+98h+arg_0]
- lea eax, [edi+ecx-1]
- mov ecx, [ebp+3265Ch]
- and ecx, eax
- mov eax, ecx
- mov ecx, [ebp+32654h]
- shl eax, cl
- push 1
- add edx, eax
- imul edx, 0C00h
- add edx, [ebp+32650h]
- mov ecx, edx
- call sub_4CDAC0
- mov edx, 800h
- sub edx, [ebp+ebx*4+283F0h]
- mov ecx, 800h
- shr edx, 2
- add eax, dword_550998[edx*4]
- mov edx, [esp+90h+var_44]
- sub ecx, [ebp+edx*4+280F0h]
- mov edx, [esp+90h+var_78]
- shr ecx, 2
- add eax, dword_550998[ecx*4]
- mov ecx, [esp+90h+var_48]
- add eax, [esp+90h+var_28]
- add ecx, edx
- add eax, [esp+90h+var_2C]
- add ecx, edi
- cmp [esp+90h+var_7C], ecx
- mov [esp+90h+var_28], ecx
- jnb short loc_4CF0DE
- mov edx, [esp+90h+var_7C]
- lea edx, [edx+edx*4]
- lea edx, [ebp+edx*8+0FCh]
- mov [esp+90h+var_24], edx
- mov edx, [esp+90h+var_7C]
- sub ecx, edx
- add edx, ecx
- mov [esp+90h+var_7C], edx
- mov edx, [esp+90h+var_24]
- lea ecx, [ecx+0]
-
-loc_4CF0D0: ; CODE XREF: CEncoder_GetOptimum+107Cj
- add edx, 28h
- sub ecx, 1
- mov dword ptr [edx], 0FFFFFFFh
- jnz short loc_4CF0D0
-
-loc_4CF0DE: ; CODE XREF: CEncoder_GetOptimum+1049j
- mov edx, [esp+90h+var_44]
- imul esi, 110h
- add esi, [esp+90h+var_48]
- mov ecx, 800h
- sub ecx, [ebp+edx*4+284B0h]
- mov edx, [ebp+ebx*4+28420h]
- shr ecx, 2
- mov ecx, dword_550998[ecx*4]
- shr edx, 2
- add ecx, dword_550998[edx*4]
- add ecx, [ebp+esi*4+2E204h]
- add ecx, eax
- mov eax, [esp+90h+var_28]
- lea eax, [eax+eax*4+1Eh]
- cmp ecx, [ebp+eax*8+0Ch]
- lea eax, [ebp+eax*8+0]
- jnb short loc_4CF157
- mov [eax+0Ch], ecx
- mov ecx, [esp+90h+var_78]
- lea edx, [ecx+edi]
- mov [eax+4], ecx
- mov ecx, [esp+90h+var_6C]
- add ecx, 4
- mov [eax+10h], edx
- mov dword ptr [eax+14h], 0
- mov byte ptr [eax+1], 1
- mov byte ptr [eax+2], 1
- mov [eax+8], ecx
-
-loc_4CF157: ; CODE XREF: CEncoder_GetOptimum+F44j
- ; CEncoder_GetOptimum+10CCj
- mov eax, [esp+90h+var_70]
- add eax, 2
- cmp eax, [esp+90h+var_4C]
- mov [esp+90h+var_70], eax
- jz short loc_4CF1BB
- lea ebx, ds:0[eax*4]
- mov eax, [ebx+ebp+32664h]
- cmp eax, 80h
- mov [esp+90h+var_6C], eax
- jb short loc_4CF1A1
- mov ecx, 7FFFFh
- sub ecx, eax
- sar ecx, 1Fh
- and ecx, 0Ch
- add ecx, 6
- shr eax, cl
- movzx edx, byte ptr dword_551198[eax]
- lea eax, [edx+ecx*2]
- mov [esp+90h+var_3C], eax
-
-loc_4CF1A1: ; CODE XREF: CEncoder_GetOptimum+EDFj
- ; CEncoder_GetOptimum+111Fj
- add [esp+90h+var_50], 28h
- add [esp+90h+var_54], 4
- mov ecx, [esp+90h+var_50]
- mov edx, [esp+90h+var_6C]
- add edi, 1
- jmp loc_4CEED3
-; ---------------------------------------------------------------------------
-
-loc_4CF1BB: ; CODE XREF: CEncoder_GetOptimum+8A9j
- ; CEncoder_GetOptimum+DA1j ...
- mov eax, [esp+90h+var_78]
- add eax, 1
- cmp eax, [esp+90h+var_7C]
- mov [esp+90h+var_78], eax
- jnz loc_4CE5D1
-
-loc_4CF1D0: ; CODE XREF: CEncoder_GetOptimum+567j
- mov ecx, [esp+90h+var_78]
- push ecx
- jmp short loc_4CF1EF
-; ---------------------------------------------------------------------------
-
-loc_4CF1D7: ; CODE XREF: CEncoder_GetOptimum+59Ej
- mov ecx, [esp+90h+var_4C]
- mov [ebp+32F00h], ecx
- mov [ebp+32EFCh], eax
- mov byte ptr [ebp+32F10h], 1
- push esi
-
-loc_4CF1EF: ; CODE XREF: CEncoder_GetOptimum+1175j
- mov edx, [esp+94h+arg_4]
- push edx
- mov ecx, ebp
- call sub_4CB2E0
- pop edi
- pop ebx
- pop esi
- pop ebp
- add esp, 80h
- retn 8
-CEncoder_GetOptimum endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CF210: ; DATA XREF: CEncoder_CodeOneBlock+44o
- mov edx, [esp+10h]
- mov eax, [esp+4]
- mov eax, [eax+4]
- mov ecx, [eax]
- push edx
- mov edx, [esp+10h]
- push edx
- mov edx, [esp+10h]
- push edx
- push eax
- mov eax, [ecx+0Ch]
- call eax
- retn
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-CEncoder_FillDistancesPrices proc near ; CODE XREF: CEncoder_SetStreams+4Fp
- ; CEncoder_CodeOneBlock+751p
-
-var_20C = dword ptr -20Ch
-var_208 = dword ptr -208h
-var_204 = dword ptr -204h
-var_200 = dword ptr -200h
-
- sub esp, 20Ch
- push ebx
- push ebp
- push esi
- push edi
- mov ebx, ecx
- mov esi, 4
-
-loc_4CF241: ; CODE XREF: CEncoder_FillDistancesPrices+80j
- cmp esi, 2000h
- jnb short loc_4CF252
- movzx edx, byte ptr dword_551198[esi]
- jmp short loc_4CF27A
-; ---------------------------------------------------------------------------
-
-loc_4CF252: ; CODE XREF: CEncoder_FillDistancesPrices+17j
- cmp esi, 2000000h
- jnb short loc_4CF26B
- mov eax, esi
- shr eax, 0Ch
- movzx edx, byte ptr dword_551198[eax]
- add edx, 18h
- jmp short loc_4CF27A
-; ---------------------------------------------------------------------------
-
-loc_4CF26B: ; CODE XREF: CEncoder_FillDistancesPrices+28j
- mov ecx, esi
- shr ecx, 18h
- movzx edx, byte ptr dword_551198[ecx]
- add edx, 30h
-
-loc_4CF27A: ; CODE XREF: CEncoder_FillDistancesPrices+20j
- ; CEncoder_FillDistancesPrices+39j
- mov ecx, edx
- mov eax, edx
- and eax, 1
- shr ecx, 1
- sub ecx, 1
- or eax, 2
- shl eax, cl
- mov edi, esi
- sub edi, eax
- push edi
- sub eax, edx
- push ecx
- lea edx, [ebx+eax*4+28BACh]
- push edx
- call sub_4CD860
- mov [esp+esi*4+228h+var_200], eax
- add esi, 1
- add esp, 0Ch
- cmp esi, 80h
- jb short loc_4CF241
- lea ebp, [esp+21Ch+var_200]
- sub ebp, ebx
- lea esi, [ebx+3331Ch]
- sub ebp, 33314h
- lea edx, [ebx+32F14h]
- mov [esp+21Ch+var_20C], esi
- mov [esp+21Ch+var_208], ebp
- mov [esp+21Ch+var_204], 4
- jmp short loc_4CF2E4
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CF2E0: ; CODE XREF: CEncoder_FillDistancesPrices+1BDj
- mov esi, [esp+21Ch+var_20C]
-
-loc_4CF2E4: ; CODE XREF: CEncoder_FillDistancesPrices+AAj
- xor edi, edi
- cmp [ebx+33B58h], edi
- jbe short loc_4CF33F
- mov edi, edi
-
-loc_4CF2F0: ; CODE XREF: CEncoder_FillDistancesPrices+109j
- mov ecx, edi
- or ecx, 40h
- xor esi, esi
- cmp ecx, 1
- jz short loc_4CF32D
- lea esp, [esp+0]
-
-loc_4CF300: ; CODE XREF: CEncoder_FillDistancesPrices+F7j
- mov eax, ecx
- shr ecx, 1
- mov ebp, [edx+ecx*4-0A764h]
- and eax, 1
- sub ebp, eax
- neg eax
- xor ebp, eax
- shr ebp, 2
- and ebp, 1FFh
- add esi, dword_550998[ebp*4]
- cmp ecx, 1
- jnz short loc_4CF300
- mov ebp, [esp+21Ch+var_208]
-
-loc_4CF32D: ; CODE XREF: CEncoder_FillDistancesPrices+CAj
- mov [edx+edi*4], esi
- add edi, 1
- cmp edi, [ebx+33B58h]
- jb short loc_4CF2F0
- mov esi, [esp+21Ch+var_20C]
-
-loc_4CF33F: ; CODE XREF: CEncoder_FillDistancesPrices+BCj
- mov eax, 0Eh
- cmp [ebx+33B58h], eax
- jbe short loc_4CF368
- lea esp, [esp+0]
-
-loc_4CF350: ; CODE XREF: CEncoder_FillDistancesPrices+136j
- mov ecx, eax
- shr ecx, 1
- sub ecx, 5
- shl ecx, 6
- add [edx+eax*4], ecx
- add eax, 1
- cmp eax, [ebx+33B58h]
- jb short loc_4CF350
-
-loc_4CF368: ; CODE XREF: CEncoder_FillDistancesPrices+11Aj
- mov eax, [edx]
- mov [esi-8], eax
- mov ecx, [edx+4]
- mov [esi-4], ecx
- mov eax, [edx+8]
- mov [esi], eax
- mov ecx, [edx+0Ch]
- mov [esi+4], ecx
- mov eax, 4
- add esi, 8
-
-loc_4CF386: ; CODE XREF: CEncoder_FillDistancesPrices+19Ej
- cmp eax, 2000h
- jnb short loc_4CF396
- movzx ecx, byte ptr dword_551198[eax]
- jmp short loc_4CF3BB
-; ---------------------------------------------------------------------------
-
-loc_4CF396: ; CODE XREF: CEncoder_FillDistancesPrices+15Bj
- cmp eax, 2000000h
- mov ecx, eax
- jnb short loc_4CF3AE
- shr ecx, 0Ch
- movzx ecx, byte ptr dword_551198[ecx]
- add ecx, 18h
- jmp short loc_4CF3BB
-; ---------------------------------------------------------------------------
-
-loc_4CF3AE: ; CODE XREF: CEncoder_FillDistancesPrices+16Dj
- shr ecx, 18h
- movzx ecx, byte ptr dword_551198[ecx]
- add ecx, 30h
-
-loc_4CF3BB: ; CODE XREF: CEncoder_FillDistancesPrices+164j
- ; CEncoder_FillDistancesPrices+17Cj
- mov ecx, [edx+ecx*4]
- add ecx, [esi+ebp]
- add eax, 1
- mov [esi], ecx
- add esi, 4
- cmp eax, 80h
- jb short loc_4CF386
- add [esp+21Ch+var_20C], 200h
- sub ebp, 200h
- add edx, 100h
- sub [esp+21Ch+var_204], 1
- mov [esp+21Ch+var_208], ebp
- jnz loc_4CF2E0
- pop edi
- pop esi
- pop ebp
- mov dword ptr [ebx+33B70h], 0
- pop ebx
- add esp, 20Ch
- retn
-CEncoder_FillDistancesPrices endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-CEncoder_FillAlignPrices proc near ; CODE XREF: CEncoder_SetStreams+56p
- ; CEncoder_CodeOneBlock+761p
- push ebx
- push ebp
- push esi
- mov ebp, ecx
- push edi
- xor esi, esi
- lea ebx, [ebp+28D78h]
- lea edi, [ebp+33B14h]
-
-loc_4CF424: ; CODE XREF: CEncoder_FillAlignPrices+27j
- push esi
- mov ecx, ebx
- call sub_4CD810
- mov [edi], eax
- add esi, 1
- add edi, 4
- cmp esi, 10h
- jb short loc_4CF424
- pop edi
- pop esi
- mov dword ptr [ebp+33B54h], 0
- pop ebp
- pop ebx
- retn
-CEncoder_FillAlignPrices endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CF810 proc near ; CODE XREF: sub_4D0250+3p
-
-var_10 = dword ptr -10h
-var_C = dword ptr -0Ch
-var_4 = dword ptr -4
-
- push 0FFFFFFFFh
- push offset loc_4DA0C9
- mov eax, dword ptr fs:[0]
- push eax
- push ecx
- push ebx
- push esi
- mov eax, dword_544960
- xor eax, esp
- push eax
- lea eax, [esp+1Ch+var_C]
- mov dword ptr fs:[0], eax
- mov esi, ecx
- mov [esp+1Ch+var_10], esi
- mov dword ptr [esi], offset NCompress_NLZMA_CEncoder_vftable
- mov dword ptr [esi+4], offset NCompress_NLZMA_CEncoder_vftable_ICompressSetOutStream
- mov dword ptr [esi+8], offset NCompress_NLZMA_CEncoder_vftable_ICompressSetCoderProperties
- mov dword ptr [esi+0Ch], offset NCompress_NLZMA_CEncoder_vftable_ICompressWriteCoderProperties
- mov eax, [esi+0A4h]
- push eax ; lpAddress
- mov [esp+20h+var_4], 1
- call off_546E24
- xor ebx, ebx
- add esp, 4
- cmp [esi+0D0h], ebx
- mov [esi+0A4h], ebx
- jnz short loc_4CF892
- mov ecx, [esi+0B4h]
- push ecx ; lpAddress
- call off_546E24
- add esp, 4
- mov [esi+0B4h], ebx
-
-loc_4CF892: ; CODE XREF: sub_4CF810+6Aj
- mov eax, [esi+33B8Ch]
- cmp eax, ebx
- jz short loc_4CF8A4
- mov edx, [eax]
- push eax
- mov eax, [edx+8]
- call eax
-
-loc_4CF8A4: ; CODE XREF: sub_4CF810+8Aj
- lea ecx, [esi+32650h]
- mov byte ptr [esp+1Ch+var_4], bl
- call sub_4CD8F0
- mov eax, [esi+40h]
- cmp eax, ebx
- mov [esp+1Ch+var_4], 0FFFFFFFFh
- jz short loc_4CF8CF
- push 8000h ; dwFreeType
- push ebx ; dwSize
- push eax ; lpAddress
- call ds:VirtualFree
-
-loc_4CF8CF: ; CODE XREF: sub_4CF810+B0j
- mov [esi+40h], ebx
- mov esi, [esi+54h]
- cmp esi, ebx
- jz short loc_4CF8E1
- mov ecx, [esi]
- mov edx, [ecx+8]
- push esi
- call edx
-
-loc_4CF8E1: ; CODE XREF: sub_4CF810+C7j
- mov ecx, [esp+1Ch+var_C]
- mov dword ptr fs:[0], ecx
- pop ecx
- pop esi
- pop ebx
- add esp, 10h
- retn
-sub_4CF810 endp
-
-; =============== S U B R O U T I N E =======================================
-
-; int __stdcall sub_4CF900(int, void *Buf1, int)
-sub_4CF900 proc near ; CODE XREF: sub_4CFA20+5j
- ; ICompressSetCoderProperties_QueryInterface+5j ...
-
-arg_0 = dword ptr 4
-Buf1 = dword ptr 8
-arg_8 = dword ptr 0Ch
-
- push esi
- mov esi, [esp+4+Buf1]
- push offset dword_512730 ; Buf2
- push esi ; Buf1
- call unknown_libname_324 ; MFC 3.1/4.0/4.2/8.0 32bit
- add esp, 8
- test eax, eax
- jz short loc_4CF94C
-
-loc_4CF917: ; CODE XREF: sub_4CF900+5Cj
- mov eax, [esp+4+arg_0]
- test eax, eax
- jz short loc_4CF936
- mov edx, [esp+4+arg_8]
- lea ecx, [eax+4]
- mov [edx], ecx
- mov ecx, [eax]
- mov edx, [ecx+4]
- push eax
- call edx
- xor eax, eax
- pop esi
- retn 0Ch
-; ---------------------------------------------------------------------------
-
-loc_4CF936: ; CODE XREF: sub_4CF900+1Dj
- ; sub_4CF900+76j ...
- mov edx, [esp+4+arg_8]
- xor ecx, ecx
- mov [edx], ecx
- mov ecx, [eax]
- mov edx, [ecx+4]
- push eax
- call edx
- xor eax, eax
- pop esi
- retn 0Ch
-; ---------------------------------------------------------------------------
-
-loc_4CF94C: ; CODE XREF: sub_4CF900+15j
- push offset dword_5535A0 ; Buf2
- push esi ; Buf1
- call unknown_libname_324 ; MFC 3.1/4.0/4.2/8.0 32bit
- add esp, 8
- test eax, eax
- jnz short loc_4CF917
- push offset dword_5535B0 ; Buf2
- push esi ; Buf1
- call unknown_libname_324 ; MFC 3.1/4.0/4.2/8.0 32bit
- add esp, 8
- test eax, eax
- jz short loc_4CF98F
- mov eax, [esp+4+arg_0]
- test eax, eax
- jz short loc_4CF936
- mov edx, [esp+4+arg_8]
- lea ecx, [eax+8]
- mov [edx], ecx
- mov ecx, [eax]
- mov edx, [ecx+4]
- push eax
- call edx
- xor eax, eax
- pop esi
- retn 0Ch
-; ---------------------------------------------------------------------------
-
-loc_4CF98F: ; CODE XREF: sub_4CF900+6Ej
- push offset dword_5535C0 ; Buf2
- push esi ; Buf1
- call unknown_libname_324 ; MFC 3.1/4.0/4.2/8.0 32bit
- add esp, 8
- test eax, eax
- jz short loc_4CF9C0
- mov eax, [esp+4+arg_0]
- test eax, eax
- jz short loc_4CF936
- mov edx, [esp+4+arg_8]
- lea ecx, [eax+0Ch]
- mov [edx], ecx
- mov ecx, [eax]
- mov edx, [ecx+4]
- push eax
- call edx
- xor eax, eax
- pop esi
- retn 0Ch
-; ---------------------------------------------------------------------------
-
-loc_4CF9C0: ; CODE XREF: sub_4CF900+9Fj
- mov eax, 80004002h
- pop esi
- retn 0Ch
-sub_4CF900 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CF9D0 proc near ; CODE XREF: ICompressSetCoderProperties_AddRef+5j
- ; sub_4CFA10+5j ...
-
-arg_0 = dword ptr 4
-
- mov eax, [esp+arg_0]
- add dword ptr [eax+24h], 1
- mov eax, [eax+24h]
- retn 4
-sub_4CF9D0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CF9E0 proc near ; CODE XREF: sub_4CFA40+5j
- ; ICompressSetCoderProperties_Release+5j ...
-
-arg_0 = dword ptr 4
-
- mov ecx, [esp+arg_0]
- add dword ptr [ecx+24h], 0FFFFFFFFh
- mov eax, [ecx+24h]
- jnz short locret_4CF9F8
- mov eax, [ecx]
- mov edx, [eax+10h]
- push 1
- call edx
- xor eax, eax
-
-locret_4CF9F8: ; CODE XREF: sub_4CF9E0+Bj
- retn 4
-sub_4CF9E0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-; =============== S U B R O U T I N E =======================================
-
-
-ICompressSetCoderProperties_AddRef proc near ; DATA XREF: .rdata:00517AD4o
-
-arg_0 = dword ptr 4
-
- sub [esp+arg_0], 8
- jmp sub_4CF9D0
-ICompressSetCoderProperties_AddRef endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CFA10 proc near ; DATA XREF: .rdata:00517AC0o
-
-arg_0 = dword ptr 4
-
- sub [esp+arg_0], 0Ch
- jmp sub_4CF9D0
-sub_4CFA10 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CFA20 proc near ; DATA XREF: .rdata:NCompress_NLZMA_CEncoder_vftable_ICompressSetOutStreamo
-
-arg_0 = dword ptr 4
-
- sub [esp+arg_0], 4
- jmp sub_4CF900
-sub_4CFA20 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-; =============== S U B R O U T I N E =======================================
-
-
-ICompressSetCoderProperties_QueryInterface proc near ; DATA XREF: .rdata:NCompress_NLZMA_CEncoder_vftable_ICompressSetCoderPropertieso
-
-arg_0 = dword ptr 4
-
- sub [esp+arg_0], 8
- jmp sub_4CF900
-ICompressSetCoderProperties_QueryInterface endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CFA40 proc near ; DATA XREF: .rdata:00517AECo
-
-arg_0 = dword ptr 4
-
- sub [esp+arg_0], 4
- jmp sub_4CF9E0
-sub_4CFA40 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CFA50 proc near ; DATA XREF: .rdata:NCompress_NLZMA_CEncoder_vftable_ICompressWriteCoderPropertieso
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-arg_8 = dword ptr 0Ch
-
- sub [esp+arg_0], 0Ch
- jmp sub_4CF900
-sub_4CFA50 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-; =============== S U B R O U T I N E =======================================
-
-
-ICompressSetCoderProperties_Release proc near ; DATA XREF: .rdata:00517AD8o
-
-arg_0 = dword ptr 4
-
- sub [esp+arg_0], 8
- jmp sub_4CF9E0
-ICompressSetCoderProperties_Release endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CFA70 proc near ; DATA XREF: .rdata:00517AC4o
-
-arg_0 = dword ptr 4
-
- sub [esp+arg_0], 0Ch
- jmp sub_4CF9E0
-sub_4CFA70 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CFA80 proc near ; DATA XREF: .rdata:00517AE8o
-
-arg_0 = dword ptr 4
-
- sub [esp+arg_0], 4
- jmp sub_4CF9D0
-sub_4CFA80 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CFA90 proc near ; DATA XREF: .rdata:00517AF0o
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- push esi
- mov esi, [esp+4+arg_4]
- test esi, esi
- push edi
- mov edi, [esp+8+arg_0]
- jz short loc_4CFAA6
- mov eax, [esi]
- mov ecx, [eax+4]
- push esi
- call ecx
-
-loc_4CFAA6: ; CODE XREF: sub_4CFA90+Cj
- mov eax, [edi+50h]
- test eax, eax
- jz short loc_4CFAB5
- mov edx, [eax]
- push eax
- mov eax, [edx+8]
- call eax
-
-loc_4CFAB5: ; CODE XREF: sub_4CFA90+1Bj
- mov [edi+50h], esi
- pop edi
- xor eax, eax
- pop esi
- retn 8
-sub_4CFA90 endp
-
-; =============== S U B R O U T I N E =======================================
-
-sub_4CFAC0 proc near ; CODE XREF: CEncoder_CodeOneBlock+42Ap
- ; CEncoder_CodeOneBlock+517p
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- mov eax, [esp+arg_0]
- push esi
- mov esi, [eax+10h]
- mov edx, esi
- shr edx, 0Bh
- imul edx, [ecx]
- cmp [esp+4+arg_4], 0
- jnz short loc_4CFAEC
- mov [eax+10h], edx
- mov edx, [ecx]
- mov esi, 800h
- sub esi, edx
- shr esi, 5
- add esi, edx
- mov [ecx], esi
- jmp short loc_4CFB03
-; ---------------------------------------------------------------------------
-
-loc_4CFAEC: ; CODE XREF: sub_4CFAC0+15j
- add [eax+8], edx
- adc dword ptr [eax+0Ch], 0
- sub esi, edx
- mov [eax+10h], esi
- mov edx, [ecx]
- mov esi, edx
- shr esi, 5
- sub edx, esi
- mov [ecx], edx
-
-loc_4CFB03: ; CODE XREF: sub_4CFAC0+2Aj
- mov ecx, [eax+10h]
- cmp ecx, 1000000h
- pop esi
- jnb short locret_4CFB1C
- shl ecx, 8
- mov [eax+10h], ecx
- mov ecx, eax
- call loc_4CF640
-
-locret_4CFB1C: ; CODE XREF: sub_4CFAC0+4Dj
- retn 8
-sub_4CFAC0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CFB20 proc near ; CODE XREF: sub_4D0020+52p
- ; sub_4D0020+E4p
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- push ebx
- push ebp
- push esi
- mov esi, [esp+0Ch+arg_0]
- push edi
- mov ebp, ecx
- mov ebx, 1
- mov edx, 3
-
-loc_4CFB34: ; CODE XREF: sub_4CFB20+8Cj
- mov edi, [esp+10h+arg_4]
- sub edx, 1
- mov ecx, edx
- shr edi, cl
- mov ecx, [esi+10h]
- mov eax, ecx
- shr eax, 0Bh
- imul eax, [ebp+ebx*4+0]
- and edi, 1
- test edi, edi
- mov [esp+10h+arg_0], edx
- jnz short loc_4CFB70
- mov [esi+10h], eax
- mov eax, [ebp+ebx*4+0]
- mov ecx, 800h
- sub ecx, eax
- shr ecx, 5
- add ecx, eax
- mov [ebp+ebx*4+0], ecx
- jmp short loc_4CFB8B
-; ---------------------------------------------------------------------------
-
-loc_4CFB70: ; CODE XREF: sub_4CFB20+35j
- add [esi+8], eax
- adc dword ptr [esi+0Ch], 0
- sub ecx, eax
- mov [esi+10h], ecx
- mov eax, [ebp+ebx*4+0]
- mov ecx, eax
- shr ecx, 5
- sub eax, ecx
- mov [ebp+ebx*4+0], eax
-
-loc_4CFB8B: ; CODE XREF: sub_4CFB20+4Ej
- mov eax, [esi+10h]
- cmp eax, 1000000h
- jnb short loc_4CFBA6
- shl eax, 8
- mov ecx, esi
- mov [esi+10h], eax
- call loc_4CF640
- mov edx, [esp+10h+arg_0]
-
-loc_4CFBA6: ; CODE XREF: sub_4CFB20+73j
- add ebx, ebx
- or ebx, edi
- test edx, edx
- jnz short loc_4CFB34
- pop edi
- pop esi
- pop ebp
- pop ebx
- retn 8
-sub_4CFB20 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CFBC0 proc near ; CODE XREF: sub_4D0020+136p
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- push ebx
- push ebp
- push esi
- mov esi, [esp+0Ch+arg_0]
- push edi
- mov ebp, ecx
- mov ebx, 1
- mov edx, 8
-
-loc_4CFBD4: ; CODE XREF: sub_4CFBC0+8Cj
- mov edi, [esp+10h+arg_4]
- sub edx, 1
- mov ecx, edx
- shr edi, cl
- mov ecx, [esi+10h]
- mov eax, ecx
- shr eax, 0Bh
- imul eax, [ebp+ebx*4+0]
- and edi, 1
- test edi, edi
- mov [esp+10h+arg_0], edx
- jnz short loc_4CFC10
- mov [esi+10h], eax
- mov eax, [ebp+ebx*4+0]
- mov ecx, 800h
- sub ecx, eax
- shr ecx, 5
- add ecx, eax
- mov [ebp+ebx*4+0], ecx
- jmp short loc_4CFC2B
-; ---------------------------------------------------------------------------
-
-loc_4CFC10: ; CODE XREF: sub_4CFBC0+35j
- add [esi+8], eax
- adc dword ptr [esi+0Ch], 0
- sub ecx, eax
- mov [esi+10h], ecx
- mov eax, [ebp+ebx*4+0]
- mov ecx, eax
- shr ecx, 5
- sub eax, ecx
- mov [ebp+ebx*4+0], eax
-
-loc_4CFC2B: ; CODE XREF: sub_4CFBC0+4Ej
- mov eax, [esi+10h]
- cmp eax, 1000000h
- jnb short loc_4CFC46
- shl eax, 8
- mov ecx, esi
- mov [esi+10h], eax
- call loc_4CF640
- mov edx, [esp+10h+arg_0]
-
-loc_4CFC46: ; CODE XREF: sub_4CFBC0+73j
- add ebx, ebx
- or ebx, edi
- test edx, edx
- jnz short loc_4CFBD4
- pop edi
- pop esi
- pop ebp
- pop ebx
- retn 8
-sub_4CFBC0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CFC60 proc near ; CODE XREF: sub_4D0770+EDp
- ; CEncoder_CodeOneBlock+67Cp
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- push ebx
- push ebp
- push esi
- mov esi, [esp+0Ch+arg_0]
- push edi
- mov ebp, ecx
- mov ebx, 1
- mov edx, 6
-
-loc_4CFC74: ; CODE XREF: sub_4CFC60+8Cj
- mov edi, [esp+10h+arg_4]
- sub edx, 1
- mov ecx, edx
- shr edi, cl
- mov ecx, [esi+10h]
- mov eax, ecx
- shr eax, 0Bh
- imul eax, [ebp+ebx*4+0]
- and edi, 1
- test edi, edi
- mov [esp+10h+arg_0], edx
- jnz short loc_4CFCB0
- mov [esi+10h], eax
- mov eax, [ebp+ebx*4+0]
- mov ecx, 800h
- sub ecx, eax
- shr ecx, 5
- add ecx, eax
- mov [ebp+ebx*4+0], ecx
- jmp short loc_4CFCCB
-; ---------------------------------------------------------------------------
-
-loc_4CFCB0: ; CODE XREF: sub_4CFC60+35j
- add [esi+8], eax
- adc dword ptr [esi+0Ch], 0
- sub ecx, eax
- mov [esi+10h], ecx
- mov eax, [ebp+ebx*4+0]
- mov ecx, eax
- shr ecx, 5
- sub eax, ecx
- mov [ebp+ebx*4+0], eax
-
-loc_4CFCCB: ; CODE XREF: sub_4CFC60+4Ej
- mov eax, [esi+10h]
- cmp eax, 1000000h
- jnb short loc_4CFCE6
- shl eax, 8
- mov ecx, esi
- mov [esi+10h], eax
- call loc_4CF640
- mov edx, [esp+10h+arg_0]
-
-loc_4CFCE6: ; CODE XREF: sub_4CFC60+73j
- add ebx, ebx
- or ebx, edi
- test edx, edx
- jnz short loc_4CFC74
- pop edi
- pop esi
- pop ebp
- pop ebx
- retn 8
-sub_4CFC60 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CFD00 proc near ; CODE XREF: sub_4D0770+109p
- ; CEncoder_CodeOneBlock+6D5p
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- push ebx
- push ebp
- push esi
- mov esi, [esp+0Ch+arg_0]
- push edi
- mov ebp, ecx
- mov edi, 1
- mov [esp+10h+arg_0], 4
-
-loc_4CFD17: ; CODE XREF: sub_4CFD00+87j
- mov ecx, [esi+10h]
- mov ebx, [esp+10h+arg_4]
- mov eax, ecx
- shr eax, 0Bh
- imul eax, [ebp+edi*4+0]
- and ebx, 1
- test ebx, ebx
- jnz short loc_4CFD48
- mov [esi+10h], eax
- mov eax, [ebp+edi*4+0]
- mov ecx, 800h
- sub ecx, eax
- shr ecx, 5
- add ecx, eax
- mov [ebp+edi*4+0], ecx
- jmp short loc_4CFD63
-; ---------------------------------------------------------------------------
-
-loc_4CFD48: ; CODE XREF: sub_4CFD00+2Dj
- add [esi+8], eax
- adc dword ptr [esi+0Ch], 0
- sub ecx, eax
- mov [esi+10h], ecx
- mov eax, [ebp+edi*4+0]
- mov edx, eax
- shr edx, 5
- sub eax, edx
- mov [ebp+edi*4+0], eax
-
-loc_4CFD63: ; CODE XREF: sub_4CFD00+46j
- mov eax, [esi+10h]
- cmp eax, 1000000h
- jnb short loc_4CFD7A
- shl eax, 8
- mov ecx, esi
- mov [esi+10h], eax
- call loc_4CF640
-
-loc_4CFD7A: ; CODE XREF: sub_4CFD00+6Bj
- shr [esp+10h+arg_4], 1
- add edi, edi
- or edi, ebx
- sub [esp+10h+arg_0], 1
- jnz short loc_4CFD17
- pop edi
- pop esi
- pop ebp
- pop ebx
- retn 8
-sub_4CFD00 endp
-
-
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CFD90 proc near ; CODE XREF: CEncoder_CodeOneBlock+6AFp
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-arg_8 = dword ptr 0Ch
-arg_C = dword ptr 10h
-
- mov eax, [esp+arg_8]
- test eax, eax
- push edi
- mov edi, 1
- jle loc_4CFE26
- push ebx
- push ebp
- mov ebp, [esp+0Ch+arg_0]
- push esi
- mov esi, [esp+10h+arg_4]
- mov [esp+10h+arg_8], eax
-
-loc_4CFDB1: ; CODE XREF: sub_4CFD90+91j
- mov ecx, [esi+10h]
- mov ebx, [esp+10h+arg_C]
- mov eax, ecx
- shr eax, 0Bh
- imul eax, [ebp+edi*4+0]
- and ebx, 1
- test ebx, ebx
- jnz short loc_4CFDE2
- mov [esi+10h], eax
- mov eax, [ebp+edi*4+0]
- mov ecx, 800h
- sub ecx, eax
- shr ecx, 5
- add ecx, eax
- mov [ebp+edi*4+0], ecx
- jmp short loc_4CFDFD
-; ---------------------------------------------------------------------------
-
-loc_4CFDE2: ; CODE XREF: sub_4CFD90+37j
- add [esi+8], eax
- adc dword ptr [esi+0Ch], 0
- sub ecx, eax
- mov [esi+10h], ecx
- mov eax, [ebp+edi*4+0]
- mov edx, eax
- shr edx, 5
- sub eax, edx
- mov [ebp+edi*4+0], eax
-
-loc_4CFDFD: ; CODE XREF: sub_4CFD90+50j
- mov eax, [esi+10h]
- cmp eax, 1000000h
- jnb short loc_4CFE14
- shl eax, 8
- mov ecx, esi
- mov [esi+10h], eax
- call loc_4CF640
-
-loc_4CFE14: ; CODE XREF: sub_4CFD90+75j
- shr [esp+10h+arg_C], 1
- add edi, edi
- or edi, ebx
- sub [esp+10h+arg_8], 1
- jnz short loc_4CFDB1
- pop esi
- pop ebp
- pop ebx
-
-loc_4CFE26: ; CODE XREF: sub_4CFD90+Cj
- pop edi
- retn
-sub_4CFD90 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-
-; =============== S U B R O U T I N E =======================================
-
-
-sub_4CFE30 proc near ; CODE XREF: CEncoder_CodeOneBlock+190p
- ; CEncoder_CodeOneBlock+2CCp
-
-arg_0 = dword ptr 4
-arg_4 = byte ptr 8
-
- push ebx
- push ebp
- push esi
- mov esi, [esp+0Ch+arg_0]
- push edi
- mov ebx, ecx
- mov ebp, 1
- mov edx, 8
-
-loc_4CFE44: ; CODE XREF: sub_4CFE30+88j
- movzx edi, [esp+10h+arg_4]
- sub edx, 1
- mov cl, dl
- shr edi, cl
- mov ecx, [esi+10h]
- mov eax, ecx
- shr eax, 0Bh
- imul eax, [ebx+ebp*4]
- and edi, 1
- test edi, edi
- mov [esp+10h+arg_0], edx
- jnz short loc_4CFE7E
- mov [esi+10h], eax
- mov eax, [ebx+ebp*4]
- mov ecx, 800h
- sub ecx, eax
- shr ecx, 5
- add ecx, eax
- mov [ebx+ebp*4], ecx
- jmp short loc_4CFE97
-; ---------------------------------------------------------------------------
-
-loc_4CFE7E: ; CODE XREF: sub_4CFE30+35j
- add [esi+8], eax
- adc dword ptr [esi+0Ch], 0
- sub ecx, eax
- mov [esi+10h], ecx
- mov eax, [ebx+ebp*4]
- mov ecx, eax
- shr ecx, 5
- sub eax, ecx
- mov [ebx+ebp*4], eax
-
-loc_4CFE97: ; CODE XREF: sub_4CFE30+4Cj
- mov eax, [esi+10h]
- cmp eax, 1000000h
- jnb short loc_4CFEB2
- shl eax, 8
- mov ecx, esi
- mov [esi+10h], eax
- call loc_4CF640
- mov edx, [esp+10h+arg_0]
-
-loc_4CFEB2: ; CODE XREF: sub_4CFE30+6Fj
- add ebp, ebp
- or ebp, edi
- test edx, edx
- jnz short loc_4CFE44
- pop edi
- pop esi
- pop ebp
- pop ebx
- retn 8
-sub_4CFE30 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4CFED0 proc near ; CODE XREF: CEncoder_CodeOneBlock+300p
-
-var_4 = dword ptr -4
-arg_0 = dword ptr 4
-arg_4 = byte ptr 8
-arg_8 = byte ptr 0Ch
-
- push ecx
- push ebx
- push ebp
- push esi
- mov esi, [esp+10h+arg_0]
- push edi
- mov [esp+14h+var_4], ecx
- mov ebx, 1
- mov edx, 8
- jmp short loc_4CFEF0
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4CFEF0: ; CODE XREF: sub_4CFED0+17j
- ; sub_4CFED0+ADj
- movzx ebp, [esp+14h+arg_4]
- movzx edi, [esp+14h+arg_8]
- sub edx, 1
- movzx ecx, dl
- shr ebp, cl
- shr edi, cl
- mov ecx, [esp+14h+var_4]
- mov [esp+14h+arg_0], edx
- mov edx, [esi+10h]
- and ebp, 1
- lea eax, [ebp+1]
- shl eax, 8
- add eax, ebx
- lea ecx, [ecx+eax*4]
- mov eax, edx
- shr eax, 0Bh
- imul eax, [ecx]
- and edi, 1
- test edi, edi
- jnz short loc_4CFF41
- mov [esi+10h], eax
- mov eax, [ecx]
- mov edx, 800h
- sub edx, eax
- shr edx, 5
- add edx, eax
- mov [ecx], edx
- jmp short loc_4CFF58
-; ---------------------------------------------------------------------------
-
-loc_4CFF41: ; CODE XREF: sub_4CFED0+5Aj
- add [esi+8], eax
- adc dword ptr [esi+0Ch], 0
- sub edx, eax
- mov [esi+10h], edx
- mov eax, [ecx]
- mov edx, eax
- shr edx, 5
- sub eax, edx
- mov [ecx], eax
-
-loc_4CFF58: ; CODE XREF: sub_4CFED0+6Fj
- mov eax, [esi+10h]
- cmp eax, 1000000h
- jnb short loc_4CFF6F
- shl eax, 8
- mov ecx, esi
- mov [esi+10h], eax
- call loc_4CF640
-
-loc_4CFF6F: ; CODE XREF: sub_4CFED0+90j
- mov edx, [esp+14h+arg_0]
- add ebx, ebx
- or ebx, edi
- cmp ebp, edi
- jnz short loc_4CFF8B
- test edx, edx
- jnz loc_4CFEF0
- pop edi
- pop esi
- pop ebp
- pop ebx
- pop ecx
- retn 0Ch
-; ---------------------------------------------------------------------------
-
-loc_4CFF8B: ; CODE XREF: sub_4CFED0+A9j
- test edx, edx
- jz loc_4D0012
-
-loc_4CFF93: ; CODE XREF: sub_4CFED0+140j
- movzx edi, [esp+14h+arg_8]
- mov ebp, [esp+14h+var_4]
- sub edx, 1
- mov cl, dl
- shr edi, cl
- mov ecx, [esi+10h]
- mov eax, ecx
- shr eax, 0Bh
- imul eax, [ebp+ebx*4+0]
- and edi, 1
- test edi, edi
- mov [esp+14h+arg_0], edx
- jnz short loc_4CFFD4
- mov [esi+10h], eax
- mov eax, [ebp+ebx*4+0]
- mov ecx, 800h
- sub ecx, eax
- shr ecx, 5
- add ecx, eax
- mov [ebp+ebx*4+0], ecx
- jmp short loc_4CFFEF
-; ---------------------------------------------------------------------------
-
-loc_4CFFD4: ; CODE XREF: sub_4CFED0+E9j
- add [esi+8], eax
- adc dword ptr [esi+0Ch], 0
- sub ecx, eax
- mov [esi+10h], ecx
- mov eax, [ebp+ebx*4+0]
- mov ecx, eax
- shr ecx, 5
- sub eax, ecx
- mov [ebp+ebx*4+0], eax
-
-loc_4CFFEF: ; CODE XREF: sub_4CFED0+102j
- mov eax, [esi+10h]
- cmp eax, 1000000h
- jnb short loc_4D000A
- shl eax, 8
- mov ecx, esi
- mov [esi+10h], eax
- call loc_4CF640
- mov edx, [esp+14h+arg_0]
-
-loc_4D000A: ; CODE XREF: sub_4CFED0+127j
- add ebx, ebx
- or ebx, edi
- test edx, edx
- jnz short loc_4CFF93
-
-loc_4D0012: ; CODE XREF: sub_4CFED0+BDj
- pop edi
- pop esi
- pop ebp
- pop ebx
- pop ecx
- retn 0Ch
-sub_4CFED0 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4D0020 proc near ; CODE XREF: sub_4D0770+C6p
- ; CEncoder_CodeOneBlock+56Dp ...
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-arg_8 = dword ptr 0Ch
-
- push ebp
- mov ebp, [esp+4+arg_4]
- cmp ebp, 8
- push esi
- mov esi, [esp+8+arg_0]
- push edi
- mov edi, ecx
- jnb short loc_4D007D
- mov eax, [esi+10h]
- shr eax, 0Bh
- imul eax, [edi]
- mov [esi+10h], eax
- mov eax, [edi]
- mov ecx, 800h
- sub ecx, eax
-
-loc_4D0047: ; DATA XREF: .rdata:0050C3BCo
- shr ecx, 5
- add ecx, eax
- mov [edi], ecx
- mov eax, [esi+10h]
- cmp eax, 1000000h
- jnb short loc_4D0065
- shl eax, 8
-
-loc_4D005B: ; DATA XREF: .rdata:005064B0o
- mov ecx, esi
- mov [esi+10h], eax
- call loc_4CF640
-
-loc_4D0065: ; CODE XREF: sub_4D0020+36j
- mov edx, [esp+0Ch+arg_8]
- push ebp
- shl edx, 5
- push esi
- lea ecx, [edx+edi+8]
- call sub_4CFB20
- pop edi
- pop esi
- pop ebp
- retn 0Ch
-; ---------------------------------------------------------------------------
-
-loc_4D007D: ; CODE XREF: sub_4D0020+10j
- mov ecx, [esi+10h]
- mov eax, ecx
- shr eax, 0Bh
- imul eax, [edi]
- add [esi+8], eax
- adc dword ptr [esi+0Ch], 0
- sub ecx, eax
- mov [esi+10h], ecx
- mov eax, [edi]
- mov ecx, eax
- shr ecx, 5
- sub eax, ecx
- mov [edi], eax
- mov eax, [esi+10h]
- cmp eax, 1000000h
- jnb short loc_4D00B6
- shl eax, 8
- mov ecx, esi
- mov [esi+10h], eax
- call loc_4CF640
-
-loc_4D00B6: ; CODE XREF: sub_4D0020+87j
- cmp ebp, 10h
- jnb short loc_4D010F
- mov edx, [esi+10h]
- shr edx, 0Bh
- imul edx, [edi+4]
- mov [esi+10h], edx
- mov eax, [edi+4]
- mov ecx, 800h
- sub ecx, eax
- shr ecx, 5
- add ecx, eax
- mov [edi+4], ecx
- mov eax, [esi+10h]
- cmp eax, 1000000h
- jnb short loc_4D00F1
- shl eax, 8
- mov ecx, esi
- mov [esi+10h], eax
- call loc_4CF640
-
-loc_4D00F1: ; CODE XREF: sub_4D0020+C2j
- mov edx, [esp+0Ch+arg_8]
- add ebp, 0FFFFFFF8h
- push ebp
- shl edx, 5
- push esi
- lea ecx, [edx+edi+208h]
- call sub_4CFB20
- pop edi
- pop esi
- pop ebp
- retn 0Ch
-; ---------------------------------------------------------------------------
-
-loc_4D010F: ; CODE XREF: sub_4D0020+99j
- mov ecx, [esi+10h]
- mov eax, ecx
- shr eax, 0Bh
- imul eax, [edi+4]
- add [esi+8], eax
- adc dword ptr [esi+0Ch], 0
- sub ecx, eax
- mov [esi+10h], ecx
- mov eax, [edi+4]
- mov ecx, eax
- shr ecx, 5
- sub eax, ecx
- mov [edi+4], eax
- mov eax, [esi+10h]
- cmp eax, 1000000h
- jnb short loc_4D014B
- shl eax, 8
- mov ecx, esi
- mov [esi+10h], eax
- call loc_4CF640
-
-loc_4D014B: ; CODE XREF: sub_4D0020+11Cj
- add ebp, 0FFFFFFF0h
- push ebp
- push esi
- lea ecx, [edi+408h]
- call sub_4CFBC0
- pop edi
- pop esi
- pop ebp
- retn 0Ch
-sub_4D0020 endp
-
-; =============== S U B R O U T I N E =======================================
-
-NCompress_NLZMA_CEncoder_CEncoder proc near ; CODE XREF: Compress_lzma_internal+149p
- mov eax, ecx
- mov dword ptr [eax+4], offset ICompressSetOutStream_vftable
- mov dword ptr [eax+8], offset ICompressSetCoderProperties_vftable
- mov dword ptr [eax+0Ch], offset ICompressWriteCoderProperties_vftable
- xor ecx, ecx
- mov [eax+24h], ecx
- mov dword ptr [eax], offset NCompress_NLZMA_CEncoder_vftable
- mov dword ptr [eax+4], offset NCompress_NLZMA_CEncoder_vftable_ICompressSetOutStream
- mov dword ptr [eax+8], offset NCompress_NLZMA_CEncoder_vftable_ICompressSetCoderProperties
- mov dword ptr [eax+0Ch], offset NCompress_NLZMA_CEncoder_vftable_ICompressWriteCoderProperties
- mov [eax+40h], ecx
- mov [eax+44h], ecx
- mov [eax+54h], ecx
- mov [eax+60h], ecx
- mov [eax+32650h], ecx
- mov dword ptr [eax+32EF8h], 20h
- mov dword ptr [eax+33B58h], 2Ch
- mov dword ptr [eax+33B5Ch], 2
- mov [eax+33B64h], ecx
- mov dword ptr [eax+33B6Ch], 00400000h
- mov edx, 3
- mov [eax+33B60h], edx
- mov [eax+33B68h], edx
- mov [eax+33B8Ch], ecx
- mov [eax+33B90h], ecx
- mov [eax+33B94h], cl
- mov [eax+0B4h], ecx
- mov [eax+0A4h], ecx
- mov dword ptr [eax+0B0h], 20h
- mov dword ptr [eax+0D4h], 1
- mov dword ptr [eax+0CCh], 4
- mov [eax+0D0h], ecx
- mov [eax+0D8h], ecx
- mov [eax+32EF4h], cl
- retn
-NCompress_NLZMA_CEncoder_CEncoder endp
-
-; =============== S U B R O U T I N E =======================================
-
-; int __thiscall sub_4D0250(void *Memory, char)
-sub_4D0250 proc near ; DATA XREF: .rdata:00517B0Co
-
-arg_0 = byte ptr 4
-
- push esi
- mov esi, ecx
- call sub_4CF810
- test [esp+4+arg_0], 1
- jz short loc_4D0268
- push esi ; Memory
- call j__free
- add esp, 4
-
-loc_4D0268: ; CODE XREF: sub_4D0250+Dj
- mov eax, esi
- pop esi
- retn 4
-sub_4D0250 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-sub_4D0270 proc near ; CODE XREF: CEncoder_SetStreams+14p
- push esi
- mov esi, ecx
- mov eax, [esi+40h]
- test eax, eax
- push edi
- mov edi, 100000h
- jz short loc_4D0297
- cmp [esi+50h], edi
- jz short loc_4D02C5
- test eax, eax
- jz short loc_4D0297
- push 8000h ; dwFreeType
- push 0 ; dwSize
- push eax ; lpAddress
- call ds:VirtualFree
-
-loc_4D0297: ; CODE XREF: sub_4D0270+Ej
- ; sub_4D0270+17j
- push 4 ; flProtect
- push 1000h ; flAllocationType
- push edi ; dwSize
- push 0 ; lpAddress
- mov dword ptr [esi+40h], 0
- mov [esi+50h], edi
- call ds:VirtualAlloc
- test eax, eax
- mov [esi+40h], eax
- setnz al
- test al, al
- jnz short loc_4D02C5
- pop edi
- mov eax, 8007000Eh
- pop esi
- retn
-; ---------------------------------------------------------------------------
-
-loc_4D02C5: ; CODE XREF: sub_4D0270+13j
- ; sub_4D0270+4Bj
- mov eax, [esi+33B68h]
- mov ecx, [esi+33B64h]
- cmp dword ptr [esi+0D4h], 0
- push ebx
- push eax
- push ecx
- lea ecx, [esi+32650h]
- setnz bl
- call sub_4CD940
- test al, al
- jz short loc_4D034F
- mov ecx, [esi+33B6Ch]
- mov edx, 1000000h
- cmp edx, ecx
- sbb eax, eax
- neg eax
- push ebp
- mov ebp, [esi+32EF8h]
- mov [esi+0D8h], eax
- mov eax, ebp
- shr eax, 1
- add eax, 10h
- test bl, bl
- jnz short loc_4D0318
- shr eax, 1
-
-loc_4D0318: ; CODE XREF: sub_4D0270+A4j
- mov edx, [esi+33B90h]
- test edx, edx
- jz short loc_4D0324
- mov eax, edx
-
-loc_4D0324: ; CODE XREF: sub_4D0270+B0j
- push offset off_546E20
- push 111h
- push ebp
- push 1000h
- push ecx
- lea edi, [esi+84h]
- push edi
- mov [esi+0B0h], eax
- call sub_4CBA60
- add esp, 18h
- test eax, eax
- pop ebp
- jnz short loc_4D0358
-
-loc_4D034F: ; CODE XREF: sub_4D0270+7Bj
- pop ebx
- pop edi
- mov eax, 8007000Eh
- pop esi
- retn
-; ---------------------------------------------------------------------------
-
-loc_4D0358: ; CODE XREF: sub_4D0270+DDj
- mov [esi+80h], edi
- add esi, 68h
- push esi
- push edi
- call sub_4CCAA0
- add esp, 8
- pop ebx
- pop edi
- xor eax, eax
- pop esi
- retn
-sub_4D0270 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-CEncoder_SetStreams proc near ; CODE XREF: CEncoder_CodeReal+4Ap
-
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-
- mov eax, [esp+arg_0]
- push esi
- mov esi, ecx
- mov [esi+33B84h], eax
- mov byte ptr [esi+33B80h], 0
- call sub_4D0270
- test eax, eax
- jnz loc_4D0441
- mov edx, [esp+4+arg_4]
- mov ecx, [esi+4]
- lea eax, [esi+4]
- push edx
- push eax
- mov eax, [ecx+0Ch]
- call eax
- test eax, eax
- jnz loc_4D0441
- mov ecx, esi
- call sub_4CDEA0
- test eax, eax
- jnz short loc_4D0441
- cmp [esi+32EF4h], al
- jnz short loc_4D03DB
- mov ecx, esi
- call CEncoder_FillDistancesPrices
- mov ecx, esi
- call CEncoder_FillAlignPrices
-
-loc_4D03DB: ; CODE XREF: CEncoder_SetStreams+4Bj
- mov ecx, [esi+32EF8h]
- sub ecx, 1
- mov [esi+2D9C0h], ecx
- mov ecx, [esi+33B5Ch]
- mov edx, 1
- shl edx, cl
- lea ecx, [esi+28DB8h]
- push edx
- call sub_4CF780
- mov ecx, [esi+33B5Ch]
- mov eax, [esi+32EF8h]
- mov edx, 1
- shl edx, cl
- sub eax, 1
- lea ecx, [esi+2DA04h]
- mov [esi+3260Ch], eax
- push edx
- call sub_4CF780
- mov dword ptr [esi+33B78h], 0
- mov dword ptr [esi+33B7Ch], 0
- xor eax, eax
-
-loc_4D0441: ; CODE XREF: CEncoder_SetStreams+1Bj
- ; CEncoder_SetStreams+34j ...
- pop esi
- retn 10h
-CEncoder_SetStreams endp
-
-;Compress_lzma_internal proc near ; CODE XREF: Compress_lzma+34p
-_starcraft_compress_lzma proc near ; CODE XREF: Compress_lzma+34p
-; sub_4D0450
-
-var_58 = dword ptr -58h
-var_54 = dword ptr -54h
-var_50 = dword ptr -50h
-var_4C = dword ptr -4Ch
-var_48 = dword ptr -48h
-var_44 = dword ptr -44h
-var_40 = dword ptr -40h
-var_3C = word ptr -3Ch
-var_34 = dword ptr -34h
-var_2C = word ptr -2Ch
-var_24 = dword ptr -24h
-var_1C = dword ptr -1Ch
-var_14 = dword ptr -14h
-var_C = dword ptr -0Ch
-var_4 = dword ptr -4
-pbInBuffer = dword ptr 4
-cbInBuffer = dword ptr 8
-pcbInBuffer = dword ptr 0Ch
-pbOutBuffer = dword ptr 10h
-cbOutBuffer = dword ptr 14h
-dummy = dword ptr 18h
-pcbOutBuffer = dword ptr 1Ch
-pfnAllocateMemory= dword ptr 20h
-pfnFreeMemory = dword ptr 24h
-pfnGiveData = dword ptr 28h
-
- push 0FFFFFFFFh
- push offset loc_4DA0FB
- mov eax, dword ptr fs:[0]
- push eax
- sub esp, 4Ch
- push ebx
- push ebp
- push esi
- push edi
- mov eax, dword_544960
- xor eax, esp
- push eax
- lea eax, [esp+6Ch+var_C]
- mov dword ptr fs:[0], eax
- mov eax, dword_553598
- xor ebx, ebx
- cmp eax, ebx
- jnz short loc_4D04A1
- push 0Ch ; Size
- call _operator_new ; operator new(uint)
- add esp, 4
- cmp eax, ebx
- jz short loc_4D049A
- mov [eax], ebx
- mov [eax+4], ebx
- mov [eax+8], ebx
- jmp short loc_4D049C
-; ---------------------------------------------------------------------------
-
-loc_4D049A: ; CODE XREF: Compress_lzma_internal+3Ej
- xor eax, eax
-
-loc_4D049C: ; CODE XREF: Compress_lzma_internal+48j
- mov dword ptr dword_553598, eax
-
-loc_4D04A1: ; CODE XREF: Compress_lzma_internal+30j
- cmp [eax], ebx
- jnz short loc_4D04B3
- mov ecx, [esp+6Ch+pfnAllocateMemory]
- mov [eax], ecx
- mov eax, dword_553598
-
-loc_4D04B3: ; CODE XREF: Compress_lzma_internal+53j
- cmp eax, ebx
- jnz short loc_4D04D6
- push 0Ch ; Size
- call _operator_new ; operator new(uint)
- add esp, 4
- cmp eax, ebx
- jz short loc_4D04CF
- mov [eax], ebx
- mov [eax+4], ebx
- mov [eax+8], ebx
- jmp short loc_4D04D1
-; ---------------------------------------------------------------------------
-
-loc_4D04CF: ; CODE XREF: Compress_lzma_internal+73j
- xor eax, eax
-
-loc_4D04D1: ; CODE XREF: Compress_lzma_internal+7Dj
- mov dword_553598, eax
-
-loc_4D04D6: ; CODE XREF: Compress_lzma_internal+65j
- cmp [eax+4], ebx
- jnz short loc_4D04EA
- mov edx, [esp+6Ch+pfnFreeMemory]
- mov [eax+4], edx
- mov eax, dword_553598
-
-loc_4D04EA: ; CODE XREF: Compress_lzma_internal+89j
- cmp [eax+8], ebx
- jnz short loc_4D04F9
- mov ecx, [esp+6Ch+pfnGiveData]
- mov [eax+8], ecx
-
-loc_4D04F9: ; CODE XREF: Compress_lzma_internal+9Dj
- mov edx, [esp+6Ch+pcbOutBuffer]
- mov ebp, [esp+6Ch+pcbInBuffer]
- cmp ebp, ebx
- mov esi, [esp+6Ch+cbInBuffer]
- mov [edx], ebx
- mov edx, 1
- mov eax, esi
- mov ecx, ebp
- ja short loc_4D0520
- cmp esi, ebx
- jbe short loc_4D053A
- jmp short loc_4D0520
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4D0520: ; CODE XREF: Compress_lzma_internal+C5j
- ; Compress_lzma_internal+CBj ...
- shrd eax, ecx, 1
- add edx, edx
- shr ecx, 1
- cmp edx, 2000000h
- ja short loc_4D053A
- cmp ecx, ebx
- ja short loc_4D0520
- jb short loc_4D053A
- cmp eax, ebx
- ja short loc_4D0520
-
-loc_4D053A: ; CODE XREF: Compress_lzma_internal+C9j
- ; Compress_lzma_internal+DEj ...
- mov eax, 13h
- push 33B98h ; Size
- mov [esp+70h+var_48], 470h
- mov [esp+70h+var_44], 400h
- mov [esp+70h+var_40], 450h
- mov [esp+70h+var_3C], ax
- mov [esp+70h+var_2C], ax
- mov word ptr [esp+70h+var_1C], ax
- mov [esp+70h+var_34], 2
- mov [esp+70h+var_24], edx
- mov [esp+70h+var_14], 40h
- mov [esp+70h+var_58], ebx
- call _operator_new ; operator new(uint)
- add esp, 4
- mov [esp+6Ch+var_4C], eax
- cmp eax, ebx
- mov [esp+6Ch+var_4], ebx
- jz short loc_4D05A4
- mov ecx, eax
- call NCompress_NLZMA_CEncoder_CEncoder
- mov [esp+6Ch+var_54], eax
- jmp short loc_4D05AA
-; ---------------------------------------------------------------------------
-
-loc_4D05A4: ; CODE XREF: Compress_lzma_internal+145j
- mov [esp+6Ch+var_54], ebx
- mov eax, ebx
-
-loc_4D05AA: ; CODE XREF: Compress_lzma_internal+152j
- or edi, 0FFFFFFFFh
- cmp eax, ebx
- mov [esp+6Ch+var_4], edi
- jz short loc_4D05D1
- mov ecx, [eax+8]
- push 3
- lea edx, [esp+70h+var_3C]
- push edx
- add eax, 8
- lea edx, [esp+74h+var_48]
- push edx
- push eax
- mov eax, [ecx+0Ch]
- call eax ; ICompressSetCodeProperties::SetCoderProperties
- test eax, eax
- jz short loc_4D05D5
-
-loc_4D05D1: ; CODE XREF: Compress_lzma_internal+163j
- mov [esp+6Ch+var_58], edi
-
-loc_4D05D5: ; CODE XREF: Compress_lzma_internal+17Fj
- push 28h ; Size
- call _operator_new ; operator new(uint)
- add esp, 4
- cmp eax, ebx
- jz short loc_4D060E
- mov ecx, [esp+6Ch+pbInBuffer]
- mov [eax+4], ebx
- add dword ptr [eax+4], 1
- mov dword ptr [eax], offset off_517A90
- mov [eax+8], ecx
- mov [eax+10h], esi
- mov [eax+14h], ebp
- mov [eax+18h], ebx
- mov [eax+1Ch], ebx
- mov [eax+20h], bl
- mov edi, eax ; EDI = pInStreamMemory
- mov [esp+6Ch+var_50], eax
- jmp short loc_4D0614
-; ---------------------------------------------------------------------------
-
-loc_4D060E: ; CODE XREF: Compress_lzma_internal+191j
- xor edi, edi
- mov [esp+6Ch+var_50], edi
-
-loc_4D0614: ; CODE XREF: Compress_lzma_internal+1BCj
- push 28h ; Size
- call _operator_new ; operator new(uint)
- add esp, 4
- cmp eax, ebx
- jz short loc_4D0657
- mov edx, [esp+6Ch+pbOutBuffer]
- mov ecx, [esp+6Ch+cbOutBuffer]
- mov [eax+4], ebx
- add dword ptr [eax+4], 1
- mov [eax+8], edx
- mov edx, [esp+6Ch+dummy]
- mov dword ptr [eax], offset off_517AA4
- mov [eax+10h], ecx
- mov [eax+14h], edx
- mov [eax+18h], ebx
- mov [eax+1Ch], ebx
- mov [eax+20h], bl
- mov esi, eax ; ESI = pOutStreamMemory
- jmp short loc_4D0659
-; ---------------------------------------------------------------------------
-
-loc_4D0657: ; CODE XREF: Compress_lzma_internal+1D0j
- xor esi, esi
-
-loc_4D0659: ; CODE XREF: Compress_lzma_internal+205j
- cmp edi, ebx
- jz short loc_4D0661
- cmp esi, ebx
- jnz short loc_4D0669
-
-loc_4D0661: ; CODE XREF: Compress_lzma_internal+20Bj
- mov [esp+6Ch+var_58], 0FFFFFFFFh
-
-loc_4D0669: ; CODE XREF: Compress_lzma_internal+20Fj
- mov eax, [esi] ; EAX = pOutStreamMemory->vftable
- mov ecx, [eax+10h] ; ECX =
- push ebx
- mov edi, 1
- push edi
- push ebx
- push esi
- call ecx
- test eax, eax
- jz short loc_4D0681
- mov [esp+6Ch+var_58], edi
-
-loc_4D0681: ; CODE XREF: Compress_lzma_internal+22Bj
- mov eax, [esp+6Ch+var_54]
- mov edx, [eax+0Ch]
- add eax, 0Ch
- push esi
- push eax
- mov eax, [edx+0Ch]
- call eax
- test eax, eax
- jz short loc_4D069A
- mov [esp+6Ch+var_58], edi
-
-loc_4D069A: ; CODE XREF: Compress_lzma_internal+244j
- xor edi, edi
- jmp short loc_4D06A4
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4D06A0: ; CODE XREF: Compress_lzma_internal+27Fj
- mov ebp, [esp+6Ch+pcbInBuffer]
-
-loc_4D06A4: ; CODE XREF: Compress_lzma_internal+24Cj
- mov eax, [esp+6Ch+cbInBuffer]
- push ebx
- push 1
- mov edx, ebp
- mov ecx, edi
- call __allshr ; Microsoft VisualC 2-8/net runtime
- push eax
- mov eax, [esi]
- mov ecx, [eax+10h]
- push esi
- call ecx
- test eax, eax
- jz short loc_4D06C9
- mov [esp+6Ch+var_58], 1
-
-loc_4D06C9: ; CODE XREF: Compress_lzma_internal+26Fj
- add edi, 8
- cmp edi, 40h
- jl short loc_4D06A0
- mov ebp, [esp+6Ch+var_54]
- xor edi, edi
- cmp [esp+6Ch+var_58], ebx
- jnz short loc_4D0723
- mov eax, [esp+6Ch+var_50]
- mov edx, [ebp+0]
- mov ecx, [edx+0Ch]
- push ebx
- push ebx
- push ebx
- push esi
- push eax
- push ebp
- call ecx
- mov ecx, [esi+18h]
- mov edi, eax
- mov eax, [esi+1Ch]
- cmp eax, ebx
- ja short loc_4D0700
- cmp ecx, 0FFFFFFFFh
- jbe short loc_4D0709
-
-loc_4D0700: ; CODE XREF: Compress_lzma_internal+2A9j
- or ecx, 0FFFFFFFFh
- mov [esp+6Ch+pcbInBuffer], ebx
- jmp short loc_4D070D
-; ---------------------------------------------------------------------------
-
-loc_4D0709: ; CODE XREF: Compress_lzma_internal+2AEj
- mov [esp+6Ch+pcbInBuffer], eax
-
-loc_4D070D: ; CODE XREF: Compress_lzma_internal+2B7j
- mov edx, [esp+6Ch+pcbOutBuffer]
- mov [edx], ecx
- cmp [esi+20h], bl
- jz short loc_4D0723
- mov [esp+6Ch+var_58], 1
-
-loc_4D0723: ; CODE XREF: Compress_lzma_internal+28Bj
- ; Compress_lzma_internal+2C9j
- mov eax, [esp+6Ch+var_50]
- cmp eax, ebx
- jz short loc_4D0733
- mov ecx, [eax]
- mov edx, [ecx+8]
- push eax
- call edx
-
-loc_4D0733: ; CODE XREF: Compress_lzma_internal+2D9j
- mov eax, [esi]
- mov ecx, [eax+8]
- push esi
- call ecx
- mov edx, [ebp+0]
- mov eax, [edx+10h]
- push 1
- mov ecx, ebp
- call eax
- mov eax, [esp+6Ch+var_58]
- cmp eax, ebx
- jnz short loc_4D0755
- neg edi
- sbb edi, edi
- mov eax, edi
-
-loc_4D0755: ; CODE XREF: Compress_lzma_internal+2FDj
- mov ecx, [esp+6Ch+var_C]
- mov dword ptr fs:[0], ecx
- pop ecx
- pop edi
- pop esi
- pop ebp
- pop ebx
- add esp, 58h
- retn
-_starcraft_compress_lzma endp
-;Compress_lzma_internal endp
-
-; =============== S U B R O U T I N E =======================================
-
-Compress_lzma proc near ; DATA XREF: .rdata:00509684o
-
-pbOutBuffer = dword ptr 4
-pcbOutBuffer = dword ptr 8
-pbInBuffer = dword ptr 0Ch
-cbInBuffer = dword ptr 10h
-
- push esi
- push edi
-; call sub_47F198
- mov esi, [esp+8+pcbOutBuffer] ; ESI = pcbOutBuffer
- mov edi, [esp+8+cbInBuffer] ; EDI = cbInBuffer
-; push offset GiveDataToCompress
-; push offset FreeMemory_47F3AB
-; push offset AllocateMemory_47F396
- push esi ; pcbOutBuffer
- push 0
- mov [eax+493E0h], eax
- push dword ptr [esi] ; cbOutBuffer
- push [esp+20h+pbOutBuffer] ; pbOutBuffer
- push 0
- push edi ; cbInBuffer
- push [esp+2Ch+pbInBuffer] ; pbInBuffer
-; call Compress_lzma_internal
- add esp, 28h
- sub eax, 0
- jz short loc_47F401
- mov [esi], edi
- dec eax
-
-loc_47F401: ; CODE XREF: Compress_lzma+3Fj
- pop edi
- pop esi
- retn
-Compress_lzma endp
-
-; =============== S U B R O U T I N E =======================================
-
-sub_4D0770 proc near ; CODE XREF: CEncoder_Flush+1Ap
-
-arg_0 = dword ptr 4
-
- push edi
- mov edi, ecx
- cmp byte ptr [edi+33B94h], 0
- jz loc_4D0881
- movzx eax, byte ptr [edi+10h]
- mov ecx, [edi+38h]
- shl eax, 4
- push ebx
- mov ebx, [esp+8+arg_0]
- add eax, ebx
- lea edx, [edi+eax*4+280F0h]
- push ebp
- push esi
- lea esi, [edi+28h]
- mov eax, ecx
- shr eax, 0Bh
- imul eax, [edx]
- add [esi+8], eax
- adc dword ptr [esi+0Ch], 0
- sub ecx, eax
- mov [esi+10h], ecx
- mov eax, [edx]
- mov ecx, eax
- shr ecx, 5
- sub eax, ecx
- mov [edx], eax
- mov eax, [esi+10h]
- cmp eax, 1000000h
- jnb short loc_4D07D3
- shl eax, 8
- mov ecx, esi
- mov [esi+10h], eax
- call loc_4CF640
-
-loc_4D07D3: ; CODE XREF: sub_4D0770+54j
- movzx edx, byte ptr [edi+10h]
- mov ecx, [esi+10h]
- lea eax, [edi+edx*4+283F0h]
- shr ecx, 0Bh
- imul ecx, [eax]
- mov [esi+10h], ecx
- mov ecx, [eax]
- mov edx, 800h
- sub edx, ecx
- shr edx, 5
- add edx, ecx
- mov [eax], edx
- mov eax, [esi+10h]
- cmp eax, 1000000h
- jnb short loc_4D0811
- shl eax, 8
- mov ecx, esi
- mov [esi+10h], eax
- call loc_4CF640
-
-loc_4D0811: ; CODE XREF: sub_4D0770+92j
- movzx eax, byte ptr [edi+10h]
- mov cl, ds:kMatchNextStates[eax]
- push ebx
- mov [edi+10h], cl
- cmp byte ptr [edi+32EF4h], 0
- push 0
- lea ebp, [edi+28DB8h]
- push esi
- mov ecx, ebp
- setz byte ptr [esp+1Ch+arg_0]
- call sub_4D0020
- cmp byte ptr [esp+10h+arg_0], 0
- jz short loc_4D0854
- add dword ptr [ebp+ebx*4+4C0Ch], 0FFFFFFFFh
- jnz short loc_4D0854
- push ebx
- mov ecx, ebp
- call sub_4CF740
-
-loc_4D0854: ; CODE XREF: sub_4D0770+D0j
- ; sub_4D0770+DAj
- push 3Fh
- push esi
- lea ecx, [edi+287B0h]
- call sub_4CFC60
- push 1Ah
- push 3FFFFFFh
- mov ecx, esi
- call sub_4CF6E0
- push 0Fh
- push esi
- lea ecx, [edi+28D78h]
- call sub_4CFD00
- pop esi
- pop ebp
- pop ebx
-
-loc_4D0881: ; CODE XREF: sub_4D0770+Aj
- pop edi
- retn 4
-sub_4D0770 endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-CEncoder_Flush proc near ; CODE XREF: CEncoder_CodeOneBlock+BAp
- ; CEncoder_CodeOneBlock+1D0p ...
-
-arg_0 = dword ptr 4
-
- push esi
- mov esi, ecx
- mov eax, [esi+0ECh]
- test eax, eax
- jnz short loc_4D08E5
- mov eax, [esi+33B60h]
- and eax, [esp+4+arg_0]
- push ebx
- push edi
- push eax
- call sub_4D0770
- lea ebx, [esi+28h]
- mov edi, 5
-
-loc_4D08B7: ; CODE XREF: CEncoder_Flush+31j
- mov ecx, ebx
- call loc_4CF640
- sub edi, 1
- jnz short loc_4D08B7
- mov ecx, [esi+4Ch]
- add esi, 40h
- cmp ecx, [esi+4]
- pop edi
- pop ebx
- jz short loc_4D08E3
-
-loc_4D08D0: ; CODE XREF: CEncoder_Flush+51j
- mov ecx, esi
- call sub_4CF450
- test eax, eax
- jnz short loc_4D08E5
- mov edx, [esi+0Ch]
- cmp edx, [esi+4]
- jnz short loc_4D08D0
-
-loc_4D08E3: ; CODE XREF: CEncoder_Flush+3Ej
- xor eax, eax
-
-loc_4D08E5: ; CODE XREF: CEncoder_Flush+Bj
- ; CEncoder_Flush+49j
- pop esi
- retn 4
-CEncoder_Flush endp
-
-; ---------------------------------------------------------------------------
- align 10h
-; =============== S U B R O U T I N E =======================================
-
-CEncoder_CodeOneBlock proc near ; CODE XREF: CEncoder_CodeReal+B1p
- ; CEncoder_CodeReal+F5p
-
-var_20 = byte ptr -20h
-var_1C = dword ptr -1Ch
-var_18 = dword ptr -18h
-var_14 = dword ptr -14h
-var_10 = dword ptr -10h
-var_C = dword ptr -0Ch
-var_8 = dword ptr -8
-var_4 = dword ptr -4
-arg_0 = dword ptr 4
-arg_4 = dword ptr 8
-arg_8 = dword ptr 0Ch
-
- sub esp, 20h
- push ebp
- push esi
- mov esi, ecx
- push edi
- mov edi, [esi+33B84h]
- xor ebp, ebp
- cmp edi, ebp
- jz short loc_4D0952
- mov eax, [edi]
- mov ecx, [eax+4]
- push edi
- call ecx
- mov eax, [esi+33B8Ch]
- cmp eax, ebp
- jz short loc_4D091E
- mov edx, [eax]
- push eax
- mov eax, [edx+8]
- call eax
-
-loc_4D091E: ; CODE XREF: CEncoder_CodeOneBlock+24j
- mov [esi+33B8Ch], edi
- mov ecx, [esi+80h]
- mov edx, [esi+68h]
- lea eax, [esi+33B88h]
- push ecx
- mov dword ptr [eax], offset loc_4CF210
- mov [esi+0B8h], eax
- call edx
- add esp, 4
- mov byte ptr [esi+33B95h], 1
- mov [esi+33B84h], ebp
-
-loc_4D0952: ; CODE XREF: CEncoder_CodeOneBlock+12j
- mov eax, [esp+2Ch+arg_8]
- mov dword ptr [eax], 1
- cmp byte ptr [esi+33B80h], 0
- jz short loc_4D0974
- mov eax, [esi+0ECh]
- pop edi
- pop esi
- pop ebp
- add esp, 20h
- retn 0Ch
-; ---------------------------------------------------------------------------
-
-loc_4D0974: ; CODE XREF: CEncoder_CodeOneBlock+73j
- mov ecx, [esi+33B78h]
- or ecx, [esi+33B7Ch]
- push ebx
- mov byte ptr [esi+33B80h], 1
- jnz loc_4D0A9C
- mov edx, [esi+80h]
- mov eax, [esi+70h]
- push edx
- call eax
- add esp, 4
- test eax, eax
- jnz short loc_4D09B9
- mov ecx, [esi+33B78h]
- push ecx
- mov ecx, esi
- call CEncoder_Flush
- pop ebx
- pop edi
- pop esi
- pop ebp
- add esp, 20h
- retn 0Ch
-; ---------------------------------------------------------------------------
-
-loc_4D09B9: ; CODE XREF: CEncoder_CodeOneBlock+AFj
- lea edx, [esp+30h+var_4]
- push edx
- mov ecx, esi
- call sub_4CB3B0
- movzx ecx, byte ptr [esi+10h]
- mov eax, [esi+33B60h]
- and eax, [esi+33B78h]
- mov edx, [esi+38h]
- lea edi, [esi+28h]
- shl ecx, 4
- add eax, ecx
- shr edx, 0Bh
- imul edx, [esi+eax*4+280F0h]
- lea eax, [esi+eax*4+280F0h]
- mov [edi+10h], edx
- mov ecx, [eax]
- mov edx, 800h
- sub edx, ecx
- shr edx, 5
- add edx, ecx
- mov [eax], edx
- mov eax, [edi+10h]
- cmp eax, 1000000h
- jnb short loc_4D0A1C
- shl eax, 8
- mov ecx, edi
- mov [edi+10h], eax
- call loc_4CF640
-
-loc_4D0A1C: ; CODE XREF: CEncoder_CodeOneBlock+11Dj
- movzx eax, byte ptr [esi+10h]
- mov cl, ds:kLiteralNextStates[eax]
- mov [esi+10h], cl
- mov edx, [esi+32F04h]
- mov eax, [esi+80h]
- mov ecx, [esi+6Ch]
- neg edx
- push edx
- push eax
- call ecx
- mov bl, al
- mov eax, [esi+32654h]
- add esp, 8
- mov byte ptr [esp+30h+var_10], bl
- mov edx, [esp+30h+var_10]
- push edx
- movzx edx, byte ptr [esi+11h]
- push edi
- mov edi, [esi+3265Ch]
- and edi, [esi+33B78h]
- mov ecx, 8
- sub cl, al
- shr edx, cl
- mov ecx, eax
- shl edi, cl
- add edx, edi
- imul edx, 0C00h
- add edx, [esi+32650h]
- mov ecx, edx
- call sub_4CFE30
- add dword ptr [esi+32F04h], 0FFFFFFFFh
- add dword ptr [esi+33B78h], 1
- mov [esi+11h], bl
- adc [esi+33B7Ch], ebp
-
-loc_4D0A9C: ; CODE XREF: CEncoder_CodeOneBlock+98j
- mov edi, [esi+33B78h]
- mov eax, [esi+80h]
- mov ecx, [esi+70h]
- push eax
- mov [esp+34h+var_14], edi
- mov [esp+34h+var_4], edi
- call ecx
- add esp, 4
- test eax, eax
- jnz short loc_4D0AD4
- push edi
- mov ecx, esi
- call CEncoder_Flush
- pop ebx
- pop edi
- pop esi
- pop ebp
- add esp, 20h
- retn 0Ch
-; ---------------------------------------------------------------------------
- align 10h
-
-loc_4D0AD0: ; CODE XREF: CEncoder_CodeOneBlock+735j
- ; CEncoder_CodeOneBlock+78Bj
- mov edi, [esp+30h+var_14]
-
-loc_4D0AD4: ; CODE XREF: CEncoder_CodeOneBlock+1CBj
- cmp byte ptr [esi+32EF4h], 0
- mov ecx, esi
- jz short loc_4D0AEB
- lea edx, [esp+30h+var_1C]
- push edx
- call CEncoder_GetOptimumFast
- jmp short loc_4D0AF6
-; ---------------------------------------------------------------------------
-
-loc_4D0AEB: ; CODE XREF: CEncoder_CodeOneBlock+1EDj
- lea eax, [esp+30h+var_1C]
- push eax
- push edi
- call CEncoder_GetOptimum
-
-loc_4D0AF6: ; CODE XREF: CEncoder_CodeOneBlock+1F9j
- mov ebx, [esi+33B60h]
- and ebx, edi
- cmp eax, 1
- mov [esp+30h+var_18], eax
- jnz loc_4D0C0E
- cmp [esp+30h+var_1C], 0FFFFFFFFh
- jnz loc_4D0C0E
- movzx ecx, byte ptr [esi+10h]
- mov edx, [esi+38h]
- lea ebp, [esi+28h]
- shl ecx, 4
- shr edx, 0Bh
- add ecx, ebx
- imul edx, [esi+ecx*4+280F0h]
- lea eax, [esi+ecx*4+280F0h]
- mov [ebp+10h], edx
- mov ecx, [eax]
- mov edx, 800h
- sub edx, ecx
- shr edx, 5
- add edx, ecx
- mov [eax], edx
- mov eax, [ebp+10h]
- cmp eax, 1000000h
- jnb short loc_4D0B61
- shl eax, 8
- mov ecx, ebp
- mov [ebp+10h], eax
- call loc_4CF640
-
-loc_4D0B61: ; CODE XREF: CEncoder_CodeOneBlock+262j
- mov eax, [esi+32F04h]
- mov ecx, [esi+80h]
- mov edx, [esi+6Ch]
- neg eax
- push eax
- push ecx
- call edx
- movzx edi, byte ptr [esi+11h]
- mov edx, [esi+3265Ch]
- and edx, [esp+38h+var_14]
- mov bl, al
- mov eax, [esi+32654h]
- mov ecx, 8
- sub cl, al
- shr edi, cl
- mov ecx, eax
- shl edx, cl
- add esp, 8
- mov byte ptr [esp+30h+var_10], bl
- add edi, edx
- imul edi, 0C00h
- add edi, [esi+32650h]
- cmp byte ptr [esi+10h], 7
- jnb short loc_4D0BC3
- mov eax, [esp+30h+var_10]
- push eax
- push ebp
- mov ecx, edi
- call sub_4CFE30
- jmp short loc_4D0BF5
-; ---------------------------------------------------------------------------
-
-loc_4D0BC3: ; CODE XREF: CEncoder_CodeOneBlock+2C2j
- mov edx, [esi+80h]
- mov eax, [esi+6Ch]
- or ecx, 0FFFFFFFFh
- sub ecx, [esi+14h]
- sub ecx, [esi+32F04h]
- push ecx
- push edx
- call eax
- mov ecx, [esp+38h+var_10]
- add esp, 8
- mov byte ptr [esp+30h+var_C], al
- mov edx, [esp+30h+var_C]
- push ecx
- push edx
- push ebp
- mov ecx, edi
- call sub_4CFED0
-
-loc_4D0BF5: ; CODE XREF: CEncoder_CodeOneBlock+2D1j
- movzx eax, byte ptr [esi+10h]
- mov cl, ds:kLiteralNextStates[eax]
- mov ebp, [esp+30h+var_18]
- mov [esi+10h], cl
- mov [esi+11h], bl
- jmp loc_4D1013
-; ---------------------------------------------------------------------------
-
-loc_4D0C0E: ; CODE XREF: CEncoder_CodeOneBlock+215j
- ; CEncoder_CodeOneBlock+220j
- movzx edx, byte ptr [esi+10h]
- mov ecx, [esi+38h]
- lea edi, [esi+28h]
- shl edx, 4
- mov eax, ecx
- shr eax, 0Bh
- add edx, ebx
- imul eax, [esi+edx*4+280F0h]
- add [edi+8], eax
- lea edx, [esi+edx*4+280F0h]
- mov ebp, 0
- adc [edi+0Ch], ebp
- sub ecx, eax
- mov [edi+10h], ecx
- mov eax, [edx]
- mov ecx, eax
- shr ecx, 5
- sub eax, ecx
- mov [edx], eax
- mov eax, [edi+10h]
- cmp eax, 1000000h
- jnb short loc_4D0C63
- shl eax, 8
- mov ecx, edi
- mov [edi+10h], eax
- call loc_4CF640
-
-loc_4D0C63: ; CODE XREF: CEncoder_CodeOneBlock+364j
- cmp [esp+30h+var_1C], 4
- movzx edx, byte ptr [esi+10h]
- mov ecx, [edi+10h]
- jnb loc_4D0E91
- mov eax, ecx
- shr eax, 0Bh
- imul eax, [esi+edx*4+283F0h]
- add [edi+8], eax
- lea edx, [esi+edx*4+283F0h]
- adc [edi+0Ch], ebp
- sub ecx, eax
- mov [edi+10h], ecx
- mov eax, [edx]
- mov ecx, eax
- shr ecx, 5
- sub eax, ecx
- mov [edx], eax
- mov eax, [edi+10h]
- cmp eax, 1000000h
- jnb short loc_4D0CB6
- shl eax, 8
- mov ecx, edi
- mov [edi+10h], eax
- call loc_4CF640
-
-loc_4D0CB6: ; CODE XREF: CEncoder_CodeOneBlock+3B7j
- mov eax, [esp+30h+var_1C]
- cmp eax, ebp
- mov ecx, [edi+10h]
- jnz short loc_4D0D24
- movzx edx, byte ptr [esi+10h]
- lea eax, [esi+edx*4+28420h]
- shr ecx, 0Bh
- imul ecx, [eax]
- mov [edi+10h], ecx
- mov ecx, [eax]
- mov edx, 800h
- sub edx, ecx
- shr edx, 5
- add edx, ecx
- mov [eax], edx
- mov eax, [edi+10h]
- cmp eax, 1000000h
- jnb short loc_4D0CFC
- shl eax, 8
- mov ecx, edi
- mov [edi+10h], eax
- call loc_4CF640
-
-loc_4D0CFC: ; CODE XREF: CEncoder_CodeOneBlock+3FDj
- mov ebp, [esp+30h+var_18]
- movzx ecx, byte ptr [esi+10h]
- xor eax, eax
- cmp ebp, 1
- setnz al
- shl ecx, 4
- add ecx, ebx
- lea ecx, [esi+ecx*4+284B0h]
- push eax
- push edi
- call sub_4CFAC0
- jmp loc_4D0E2E
-; ---------------------------------------------------------------------------
-
-loc_4D0D24: ; CODE XREF: CEncoder_CodeOneBlock+3CFj
- mov edx, [esi+eax*4+14h]
- movzx eax, byte ptr [esi+10h]
- mov [esp+30h+var_8], edx
- lea edx, [esi+eax*4+28420h]
- mov eax, ecx
- shr eax, 0Bh
- imul eax, [edx]
- add [edi+8], eax
- adc [edi+0Ch], ebp
- sub ecx, eax
- mov [edi+10h], ecx
- mov eax, [edx]
- mov ecx, eax
- shr ecx, 5
- sub eax, ecx
- mov [edx], eax
- mov eax, [edi+10h]
- cmp eax, 1000000h
- jnb short loc_4D0D6C
- shl eax, 8
- mov ecx, edi
- mov [edi+10h], eax
- call loc_4CF640
-
-loc_4D0D6C: ; CODE XREF: CEncoder_CodeOneBlock+46Dj
- cmp [esp+30h+var_1C], 1
- mov ecx, [edi+10h]
- jnz short loc_4D0DB3
- movzx edx, byte ptr [esi+10h]
- lea eax, [esi+edx*4+28450h]
- shr ecx, 0Bh
- imul ecx, [eax]
- mov [edi+10h], ecx
- mov ecx, [eax]
- mov edx, 800h
- sub edx, ecx
- shr edx, 5
- add edx, ecx
- mov [eax], edx
- mov eax, [edi+10h]
- cmp eax, 1000000h
- jnb short loc_4D0E1D
- shl eax, 8
- mov ecx, edi
- mov [edi+10h], eax
- call loc_4CF640
- jmp short loc_4D0E1D
-; ---------------------------------------------------------------------------
-
-loc_4D0DB3: ; CODE XREF: CEncoder_CodeOneBlock+484j
- movzx eax, byte ptr [esi+10h]
- lea edx, [esi+eax*4+28450h]
- mov eax, ecx
- shr eax, 0Bh
- imul eax, [edx]
- add [edi+8], eax
- adc [edi+0Ch], ebp
- sub ecx, eax
- mov [edi+10h], ecx
- mov eax, [edx]
- mov ecx, eax
- shr ecx, 5
- sub eax, ecx
- mov [edx], eax
- mov eax, [edi+10h]
- cmp eax, 1000000h
- jnb short loc_4D0DF3
- shl eax, 8
- mov ecx, edi
- mov [edi+10h], eax
- call loc_4CF640
-
-loc_4D0DF3: ; CODE XREF: CEncoder_CodeOneBlock+4F4j
- mov ebp, [esp+30h+var_1C]
- movzx eax, byte ptr [esi+10h]
- lea edx, [ebp-2]
- push edx
- push edi
- lea ecx, [esi+eax*4+28480h]
- call sub_4CFAC0
- cmp ebp, 3
- jnz short loc_4D0E17
- mov ecx, [esi+1Ch]
- mov [esi+20h], ecx
-
-loc_4D0E17: ; CODE XREF: CEncoder_CodeOneBlock+51Fj
- mov edx, [esi+18h]
- mov [esi+1Ch], edx
-
-loc_4D0E1D: ; CODE XREF: CEncoder_CodeOneBlock+4B2j
- ; CEncoder_CodeOneBlock+4C1j
- mov eax, [esi+14h]
- mov ecx, [esp+30h+var_8]
- mov ebp, [esp+30h+var_18]
- mov [esi+18h], eax
- mov [esi+14h], ecx
-
-loc_4D0E2E: ; CODE XREF: CEncoder_CodeOneBlock+42Fj
- cmp ebp, 1
- jnz short loc_4D0E45
- movzx edx, byte ptr [esi+10h]
- mov al, ds:kShortRepNextStates[edx]
- mov [esi+10h], al
- jmp loc_4D0FF5
-; ---------------------------------------------------------------------------
-
-loc_4D0E45: ; CODE XREF: CEncoder_CodeOneBlock+541j
- cmp byte ptr [esi+32EF4h], 0
- push ebx
- lea edx, [ebp-2]
- push edx
- lea ecx, [esi+2DA04h]
- push edi
- setz [esp+3Ch+var_20]
- call sub_4D0020
- cmp [esp+30h+var_20], 0
- jz short loc_4D0E7F
- add dword ptr [esi+ebx*4+32610h], 0FFFFFFFFh
- lea ecx, [esi+2DA04h]
- jnz short loc_4D0E7F
- push ebx
- call sub_4CF740
-
-loc_4D0E7F: ; CODE XREF: CEncoder_CodeOneBlock+577j
- ; CEncoder_CodeOneBlock+587j
- movzx eax, byte ptr [esi+10h]
- mov cl, ds:kRepNextStates[eax]
- mov [esi+10h], cl
- jmp loc_4D0FF5
-; ---------------------------------------------------------------------------
-
-loc_4D0E91: ; CODE XREF: CEncoder_CodeOneBlock+37Fj
- lea eax, [esi+edx*4+283F0h]
- shr ecx, 0Bh
- imul ecx, [eax]
- mov [edi+10h], ecx
- mov ecx, [eax]
- mov edx, 800h
- sub edx, ecx
- shr edx, 5
- add edx, ecx
- mov [eax], edx
- mov eax, [edi+10h]
- cmp eax, 1000000h
- jnb short loc_4D0EC8
- shl eax, 8
- mov ecx, edi
- mov [edi+10h], eax
- call loc_4CF640
-
-loc_4D0EC8: ; CODE XREF: CEncoder_CodeOneBlock+5C9j
- movzx eax, byte ptr [esi+10h]
- mov cl, ds:kMatchNextStates[eax]
- mov eax, [esp+30h+var_18]
- mov [esi+10h], cl
- cmp byte ptr [esi+32EF4h], 0
- push ebx
- setz [esp+34h+var_20]
- add eax, 0FFFFFFFEh
- push eax
- lea ebp, [esi+28DB8h]
- push edi
- mov ecx, ebp
- call sub_4D0020
- cmp [esp+30h+var_20], 0
- jz short loc_4D0F11
- add dword ptr [ebp+ebx*4+4C0Ch], 0FFFFFFFFh
- jnz short loc_4D0F11
- push ebx
- mov ecx, ebp
- call sub_4CF740
-
-loc_4D0F11: ; CODE XREF: CEncoder_CodeOneBlock+60Dj
- ; CEncoder_CodeOneBlock+617j
- mov eax, [esp+30h+var_1C]
- sub eax, 4
- cmp eax, 2000h
- mov [esp+30h+var_1C], eax
- jnb short loc_4D0F2C
- movzx ebp, byte ptr dword_551198[eax]
- jmp short loc_4D0F4F
-; ---------------------------------------------------------------------------
-
-loc_4D0F2C: ; CODE XREF: CEncoder_CodeOneBlock+631j
- cmp eax, 2000000h
- jnb short loc_4D0F42
- shr eax, 0Ch
- movzx ebp, byte ptr dword_551198[eax]
- add ebp, 18h
- jmp short loc_4D0F4F
-; ---------------------------------------------------------------------------
-
-loc_4D0F42: ; CODE XREF: CEncoder_CodeOneBlock+641j
- shr eax, 18h
- movzx ebp, byte ptr dword_551198[eax]
- add ebp, 30h
-
-loc_4D0F4F: ; CODE XREF: CEncoder_CodeOneBlock+63Aj
- ; CEncoder_CodeOneBlock+650j
- mov eax, [esp+30h+var_18]
- add eax, 0FFFFFFFEh
- cmp eax, 4
- jb short loc_4D0F60
- mov eax, 3
-
-loc_4D0F60: ; CODE XREF: CEncoder_CodeOneBlock+669j
- push ebp
- shl eax, 8
- push edi
- lea ecx, [eax+esi+287B0h]
- call sub_4CFC60
- cmp ebp, 4
- jb short loc_4D0FD1
- mov ebx, [esp+30h+var_1C]
- mov ecx, ebp
- mov eax, ebp
- and eax, 1
- shr ecx, 1
- sub ecx, 1
- or eax, 2
- shl eax, cl
- sub ebx, eax
- cmp ebp, 0Eh
- jnb short loc_4D0FA9
- push ebx
- push ecx
- sub eax, ebp
- lea edx, [esi+eax*4+28BACh]
- push edi
- push edx
- call sub_4CFD90
- add esp, 10h
- jmp short loc_4D0FD1
-; ---------------------------------------------------------------------------
-
-loc_4D0FA9: ; CODE XREF: CEncoder_CodeOneBlock+6A0j
- add ecx, 0FFFFFFFCh
- push ecx
- mov eax, ebx
- shr eax, 4
- push eax
- mov ecx, edi
- call sub_4CF6E0
- and ebx, 0Fh
- push ebx
- push edi
- lea ecx, [esi+28D78h]
- call sub_4CFD00
- add dword ptr [esi+33B54h], 1
-
-loc_4D0FD1: ; CODE XREF: CEncoder_CodeOneBlock+684j
- ; CEncoder_CodeOneBlock+6B7j
- mov ecx, [esi+1Ch]
- mov edx, [esi+18h]
- mov eax, [esi+14h]
- add dword ptr [esi+33B70h], 1
- mov ebp, [esp+30h+var_18]
- mov [esi+20h], ecx
- mov ecx, [esp+30h+var_1C]
- mov [esi+1Ch], edx
- mov [esi+18h], eax
- mov [esi+14h], ecx
-
-loc_4D0FF5: ; CODE XREF: CEncoder_CodeOneBlock+550j
- ; CEncoder_CodeOneBlock+59Cj
- mov eax, [esi+80h]
- mov ecx, [esi+6Ch]
- mov edx, ebp
- sub edx, [esi+32F04h]
- sub edx, 1
- push edx
- push eax
- call ecx
- add esp, 8
- mov [esi+11h], al
-
-loc_4D1013: ; CODE XREF: CEncoder_CodeOneBlock+319j
- sub [esi+32F04h], ebp
- mov eax, [esi+32F04h]
- add [esp+30h+var_14], ebp
- test eax, eax
- jnz loc_4D0AD0
- cmp [esi+32EF4h], al
- jnz short loc_4D1056
- cmp dword ptr [esi+33B70h], 80h
- jb short loc_4D1046
- mov ecx, esi
- call CEncoder_FillDistancesPrices
-
-loc_4D1046: ; CODE XREF: CEncoder_CodeOneBlock+74Dj
- cmp dword ptr [esi+33B54h], 10h
- jb short loc_4D1056
- mov ecx, esi
- call CEncoder_FillAlignPrices
-
-loc_4D1056: ; CODE XREF: CEncoder_CodeOneBlock+741j
- ; CEncoder_CodeOneBlock+75Dj
- mov edx, [esi+80h]
- mov eax, [esi+70h]
- push edx
- call eax
- add esp, 4
- test eax, eax
- mov eax, [esp+30h+var_14]
- jz short loc_4D10D7
- mov ecx, [esp+30h+var_4]
- mov edx, eax
- sub edx, ecx
- cmp edx, 4000h
- jb loc_4D0AD0
- sub eax, ecx
- add [esi+33B78h], eax
- mov ecx, [esi+33B78h]
- mov eax, [esp+30h+arg_0]
- adc dword ptr [esi+33B7Ch], 0
- mov [eax], ecx
- mov edx, [esi+33B7Ch]
- lea ecx, [esi+28h]
- mov [eax+4], edx
- call sub_4CD8B0
- mov ecx, [esp+30h+arg_4]
- mov [ecx], eax
- mov eax, [esp+30h+arg_8]
- mov [ecx+4], edx
- pop ebx
- mov byte ptr [esi+33B80h], 0
- pop edi
- mov dword ptr [eax], 0
- mov eax, [esi+0ECh]
- pop esi
- pop ebp
- add esp, 20h
- retn 0Ch
-; ---------------------------------------------------------------------------
-
-loc_4D10D7: ; CODE XREF: CEncoder_CodeOneBlock+77Bj
- push eax
- mov ecx, esi
- call CEncoder_Flush
- pop ebx
- pop edi
- pop esi
- pop ebp
- add esp, 20h
- retn 0Ch
-CEncoder_CodeOneBlock endp
-
-; ---------------------------------------------------------------------------
- align 10h
-CEncoder_CodeReal proc near ; CODE XREF: CEncoder_Code+49p
-
-var_20 = dword ptr -20h
-processedOutSize= byte ptr -1Ch
-processedInSize = byte ptr -14h
-var_C = dword ptr -0Ch
-var_4 = dword ptr -4
-inStream = dword ptr 4
-outStream = dword ptr 8
-inSize = dword ptr 0Ch
-outSize = dword ptr 10h
-progress = dword ptr 14h
-
- push 0FFFFFFFFh
- push offset loc_4DA128
- mov eax, dword ptr fs:[0]
- push eax
- sub esp, 14h
- push ebp
- push esi
- push edi
- mov eax, dword_544960
- xor eax, esp
- push eax
- lea eax, [esp+30h+var_C]
- mov dword ptr fs:[0], eax
- mov esi, ecx
- mov [esp+30h+var_20], esi
- mov eax, [esp+30h+outSize]
- mov ecx, [esp+30h+inSize]
- mov edx, [esp+30h+outStream]
- push eax
- mov eax, [esp+34h+inStream]
- push ecx
- push edx
- push eax
- mov ecx, esi
- mov [esp+40h+var_4], 0
- call CEncoder_SetStreams
- mov edi, eax
- test edi, edi
- jz short loc_4D1190
- cmp dword ptr [esi+80h], 0
- mov [esp+30h+var_4], 0FFFFFFFFh
- jz short loc_4D1166
- cmp byte ptr [esi+33B95h], 0
- jz short loc_4D1166
- mov byte ptr [esi+33B95h], 0
-
-loc_4D1166: ; CODE XREF: CEncoder_CodeReal+64j
- ; CEncoder_CodeReal+6Dj
- mov eax, [esi+33B8Ch]
- test eax, eax
- jz short loc_4D1182
- mov ecx, [eax]
- mov edx, [ecx+8]
- push eax
- call edx
- mov dword ptr [esi+33B8Ch], 0
-
-loc_4D1182: ; CODE XREF: CEncoder_CodeReal+7Ej
- mov ecx, [esi+4]
- mov edx, [ecx+10h]
- lea eax, [esi+4]
- push eax
- call edx
- jmp short loc_4D1201
-; ---------------------------------------------------------------------------
-
-loc_4D1190: ; CODE XREF: CEncoder_CodeReal+53j
- lea eax, [esp+30h+outSize]
- push eax
- lea ecx, [esp+34h+processedOutSize]
- push ecx
- lea edx, [esp+38h+processedInSize]
- push edx
- mov ecx, esi
- call CEncoder_CodeOneBlock
- mov edi, eax
- test edi, edi
- jnz short loc_4D11F0
- mov ebp, [esp+30h+progress]
-
-loc_4D11B0: ; CODE XREF: CEncoder_CodeReal+FEj
- cmp [esp+30h+outSize], 0
- jnz short loc_4D1218
- test ebp, ebp
- jz short loc_4D11D4
- mov eax, [ebp+0]
- mov eax, [eax+0Ch]
- lea ecx, [esp+30h+processedOutSize]
- push ecx
- lea edx, [esp+34h+processedInSize]
- push edx
- push ebp
- call eax ; SetRatioInfo
- mov edi, eax
- test edi, edi
- jnz short loc_4D11F0
-
-loc_4D11D4: ; CODE XREF: CEncoder_CodeReal+C9j
- lea ecx, [esp+30h+outSize]
- push ecx
- lea edx, [esp+34h+processedOutSize]
- push edx
- lea eax, [esp+38h+processedInSize]
- push eax
- mov ecx, esi
- call CEncoder_CodeOneBlock
- mov edi, eax
- test edi, edi
- jz short loc_4D11B0
-
-loc_4D11F0: ; CODE XREF: CEncoder_CodeReal+BAj
- ; CEncoder_CodeReal+E2j
- lea ecx, [esp+30h+var_20]
- mov [esp+30h+var_4], 0FFFFFFFFh
- call sub_4CDA70
-
-loc_4D1201: ; CODE XREF: CEncoder_CodeReal+9Ej
- mov eax, edi
- mov ecx, [esp+30h+var_C]
- mov dword ptr fs:[0], ecx
- pop ecx
- pop edi
- pop esi
- pop ebp
- add esp, 20h
- retn 14h
-; ---------------------------------------------------------------------------
-
-loc_4D1218: ; CODE XREF: CEncoder_CodeReal+C5j
- lea ecx, [esp+30h+var_20]
- mov [esp+30h+var_4], 0FFFFFFFFh
- call sub_4CDA70
- xor eax, eax
- mov ecx, [esp+30h+var_C]
- mov dword ptr fs:[0], ecx
- pop ecx
- pop edi
- pop esi
- pop ebp
- add esp, 20h
- retn 14h
-CEncoder_CodeReal endp
-
-; =============== S U B R O U T I N E =======================================
-; Attributes: bp-based frame
-
-CEncoder_Code proc near ; DATA XREF: .rdata:00517B08o
-; sub_4D1240
-
-var_10 = dword ptr -10h
-var_C = dword ptr -0Ch
-var_4 = dword ptr -4
-pThis = dword ptr 8
-pInStream = dword ptr 0Ch
-pOutStream = dword ptr 10h
-pInSize = dword ptr 14h
-pOutSize = dword ptr 18h
-progress = dword ptr 1Ch
-
- push ebp
- mov ebp, esp
- push 0FFFFFFFFh
- push offset loc_4DA150
- mov eax, dword ptr fs:[0]
- push eax
- sub esp, 8
- push ebx
- push esi
- push edi
- mov eax, dword_544960
- xor eax, ebp
- push eax
- lea eax, [ebp+var_C]
- mov dword ptr fs:[0], eax
- mov [ebp+var_10], esp
- mov eax, [ebp+progress]
- mov ecx, [ebp+pOutSize]
- mov edx, [ebp+pInSize]
- push eax
- mov eax, [ebp+pOutStream]
- push ecx
- mov ecx, [ebp+pInStream]
- push edx
- push eax
- push ecx
- mov ecx, [ebp+pThis]
- mov [ebp+var_4], 0
- call CEncoder_CodeReal
- mov ecx, [ebp+var_C]
- mov dword ptr fs:[0], ecx
- pop ecx
- pop edi
- pop esi
- pop ebx
- mov esp, ebp
- pop ebp
- retn 18h
-CEncoder_Code endp
-
-; ---------------------------------------------------------------------------
-
-loc_4DA0FB: ; DATA XREF: Compress_lzma_internal+2o
- mov edx, [esp+8]
- lea eax, [edx-5Ch]
- mov ecx, [edx-60h]
- xor ecx, eax
- call sub_4A0686
- mov eax, 0 ; offset dword_526E44
- int 3;
-; jmp ___CxxFrameHandler3
-
-loc_4DA0C9: ; DATA XREF: sub_4CF810+2o
- mov edx, [esp+8]
- lea eax, [edx-0Ch]
- mov ecx, [edx-10h]
- xor ecx, eax
- call sub_4A0686
- mov eax, 0 ; offset dword_526E18
- int 3;
-; jmp ___CxxFrameHandler3
-
-loc_4DA128: ; DATA XREF: CEncoder_CodeReal+2o
- mov edx, [esp+8]
- lea eax, [edx-20h]
- mov ecx, [edx-24h]
- xor ecx, eax
- call sub_4A0686
- mov eax, 0 ; offset unk_526E70
- int 3;
-; jmp ___CxxFrameHandler3
-
-loc_4DA150: ; DATA XREF: CEncoder_Code+5o
- mov edx, [esp+8]
- lea eax, [edx+0Ch]
- mov ecx, [edx-18h]
- xor ecx, eax
- call sub_4A0686
- mov eax, 0 ; offset unk_526ED8
- int 3;
-; jmp ___CxxFrameHandler3
-
-END