From 9facabe8a1bbec7b465ce96aebf9b34a829d2771 Mon Sep 17 00:00:00 2001 From: p989 Date: Sat, 27 Jun 2009 18:41:37 +0000 Subject: [PATCH] win32: 7z, rar, bz2 support, dialog for selecting a file from an archive with multiple files, lua console dialog --- desmume/src/windows/7z/7zip.lib | Bin 0 -> 6277950 bytes desmume/src/windows/7z/7zip.vcproj | 4058 +++++++++++++++++ desmume/src/windows/7z/C/7zCrc.c | 35 + desmume/src/windows/7z/C/7zCrc.h | 24 + desmume/src/windows/7z/C/Aes.c | 262 ++ desmume/src/windows/7z/C/Aes.h | 48 + desmume/src/windows/7z/C/Alloc.c | 127 + desmume/src/windows/7z/C/Alloc.h | 32 + desmume/src/windows/7z/C/Bra.c | 133 + desmume/src/windows/7z/C/Bra.h | 60 + desmume/src/windows/7z/C/Bra86.c | 85 + desmume/src/windows/7z/C/BraIA64.c | 67 + desmume/src/windows/7z/C/BwtSort.c | 516 +++ desmume/src/windows/7z/C/BwtSort.h | 24 + desmume/src/windows/7z/C/CpuArch.h | 69 + desmume/src/windows/7z/C/HuffEnc.c | 148 + desmume/src/windows/7z/C/HuffEnc.h | 21 + desmume/src/windows/7z/C/LzFind.c | 751 +++ desmume/src/windows/7z/C/LzFind.h | 107 + desmume/src/windows/7z/C/LzFindMt.c | 793 ++++ desmume/src/windows/7z/C/LzFindMt.h | 97 + desmume/src/windows/7z/C/LzHash.h | 54 + desmume/src/windows/7z/C/LzmaDec.c | 1007 ++++ desmume/src/windows/7z/C/LzmaDec.h | 223 + desmume/src/windows/7z/C/LzmaEnc.c | 2275 +++++++++ desmume/src/windows/7z/C/LzmaEnc.h | 72 + desmume/src/windows/7z/C/RotateDefs.h | 22 + desmume/src/windows/7z/C/Sha256.c | 204 + desmume/src/windows/7z/C/Sha256.h | 22 + desmume/src/windows/7z/C/Sort.c | 95 + desmume/src/windows/7z/C/Sort.h | 14 + desmume/src/windows/7z/C/Threads.c | 109 + desmume/src/windows/7z/C/Threads.h | 68 + desmume/src/windows/7z/C/Types.h | 208 + .../CPP/7zip/Archive/7z/7zCompressionMode.cpp | 3 + .../CPP/7zip/Archive/7z/7zCompressionMode.h | 50 + .../7z/CPP/7zip/Archive/7z/7zDecode.cpp | 332 ++ .../windows/7z/CPP/7zip/Archive/7z/7zDecode.h | 68 + .../7z/CPP/7zip/Archive/7z/7zExtract.cpp | 273 ++ .../CPP/7zip/Archive/7z/7zFolderInStream.cpp | 130 + .../7z/CPP/7zip/Archive/7z/7zFolderInStream.h | 66 + .../CPP/7zip/Archive/7z/7zFolderOutStream.cpp | 164 + .../CPP/7zip/Archive/7z/7zFolderOutStream.h | 60 + .../7z/CPP/7zip/Archive/7z/7zHandler.cpp | 503 ++ .../7z/CPP/7zip/Archive/7z/7zHandler.h | 121 + .../7z/CPP/7zip/Archive/7z/7zHeader.cpp | 27 + .../windows/7z/CPP/7zip/Archive/7z/7zHeader.h | 97 + .../windows/7z/CPP/7zip/Archive/7z/7zIn.cpp | 1260 +++++ .../src/windows/7z/CPP/7zip/Archive/7z/7zIn.h | 245 + .../windows/7z/CPP/7zip/Archive/7z/7zItem.h | 258 ++ .../7z/CPP/7zip/Archive/7z/7zProperties.cpp | 163 + .../7z/CPP/7zip/Archive/7z/7zProperties.h | 22 + .../7z/CPP/7zip/Archive/7z/7zRegister.cpp | 18 + .../7z/CPP/7zip/Archive/7z/7zSpecStream.cpp | 24 + .../7z/CPP/7zip/Archive/7z/7zSpecStream.h | 35 + .../windows/7z/CPP/7zip/Archive/7z/StdAfx.h | 9 + .../7z/CPP/7zip/Archive/ArchiveExports.cpp | 130 + .../CPP/7zip/Archive/BZip2/BZip2Handler.cpp | 216 + .../7z/CPP/7zip/Archive/BZip2/BZip2Handler.h | 70 + .../7z/CPP/7zip/Archive/BZip2/BZip2Item.h | 20 + .../7z/CPP/7zip/Archive/BZip2/StdAfx.h | 8 + .../7z/CPP/7zip/Archive/BZip2/bz2Register.cpp | 18 + .../CPP/7zip/Archive/Common/CoderMixer2.cpp | 121 + .../7z/CPP/7zip/Archive/Common/CoderMixer2.h | 174 + .../CPP/7zip/Archive/Common/CoderMixer2MT.cpp | 230 + .../CPP/7zip/Archive/Common/CoderMixer2MT.h | 80 + .../7zip/Archive/Common/DummyOutStream.cpp | 22 + .../CPP/7zip/Archive/Common/DummyOutStream.h | 24 + .../CPP/7zip/Archive/Common/FindSignature.cpp | 62 + .../CPP/7zip/Archive/Common/FindSignature.h | 12 + .../7zip/Archive/Common/InStreamWithCRC.cpp | 40 + .../CPP/7zip/Archive/Common/InStreamWithCRC.h | 69 + .../CPP/7zip/Archive/Common/ItemNameUtils.cpp | 59 + .../CPP/7zip/Archive/Common/ItemNameUtils.h | 24 + .../CPP/7zip/Archive/Common/MultiStream.cpp | 201 + .../7z/CPP/7zip/Archive/Common/MultiStream.h | 76 + .../7zip/Archive/Common/OutStreamWithCRC.cpp | 24 + .../7zip/Archive/Common/OutStreamWithCRC.h | 38 + .../7zip/Archive/Common/ParseProperties.cpp | 177 + .../CPP/7zip/Archive/Common/ParseProperties.h | 18 + .../7z/CPP/7zip/Archive/Common/StdAfx.h | 9 + .../7z/CPP/7zip/Archive/DllExports2.cpp | 82 + .../7z/CPP/7zip/Archive/GZip/GZipHandler.cpp | 284 ++ .../7z/CPP/7zip/Archive/GZip/GZipHandler.h | 65 + .../7z/CPP/7zip/Archive/GZip/GZipHeader.cpp | 20 + .../7z/CPP/7zip/Archive/GZip/GZipHeader.h | 85 + .../7z/CPP/7zip/Archive/GZip/GZipIn.cpp | 119 + .../windows/7z/CPP/7zip/Archive/GZip/GZipIn.h | 30 + .../7z/CPP/7zip/Archive/GZip/GZipItem.h | 59 + .../7z/CPP/7zip/Archive/GZip/GZipRegister.cpp | 18 + .../7z/CPP/7zip/Archive/GZip/GZipUpdate.h | 39 + .../windows/7z/CPP/7zip/Archive/GZip/StdAfx.h | 8 + .../windows/7z/CPP/7zip/Archive/IArchive.h | 237 + .../7z/CPP/7zip/Archive/Lzh/LzhCRC.cpp | 43 + .../windows/7z/CPP/7zip/Archive/Lzh/LzhCRC.h | 27 + .../7z/CPP/7zip/Archive/Lzh/LzhHandler.cpp | 387 ++ .../7z/CPP/7zip/Archive/Lzh/LzhHandler.h | 30 + .../7z/CPP/7zip/Archive/Lzh/LzhHeader.h | 19 + .../windows/7z/CPP/7zip/Archive/Lzh/LzhIn.cpp | 172 + .../windows/7z/CPP/7zip/Archive/Lzh/LzhIn.h | 29 + .../windows/7z/CPP/7zip/Archive/Lzh/LzhItem.h | 172 + .../7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp | 27 + .../7zip/Archive/Lzh/LzhOutStreamWithCRC.h | 38 + .../7z/CPP/7zip/Archive/Lzh/LzhRegister.cpp | 13 + .../windows/7z/CPP/7zip/Archive/Lzh/StdAfx.h | 8 + .../CPP/7zip/Archive/Lzma/LzmaArcRegister.cpp | 14 + .../7zip/Archive/Lzma/LzmaFiltersDecode.cpp | 86 + .../CPP/7zip/Archive/Lzma/LzmaFiltersDecode.h | 26 + .../7z/CPP/7zip/Archive/Lzma/LzmaHandler.cpp | 243 + .../7z/CPP/7zip/Archive/Lzma/LzmaHandler.h | 69 + .../7z/CPP/7zip/Archive/Lzma/LzmaIn.cpp | 56 + .../windows/7z/CPP/7zip/Archive/Lzma/LzmaIn.h | 16 + .../7z/CPP/7zip/Archive/Lzma/LzmaItem.h | 27 + .../windows/7z/CPP/7zip/Archive/Lzma/StdAfx.h | 8 + .../7z/CPP/7zip/Archive/Rar/RarHandler.cpp | 835 ++++ .../7z/CPP/7zip/Archive/Rar/RarHandler.h | 60 + .../7z/CPP/7zip/Archive/Rar/RarHeader.cpp | 19 + .../7z/CPP/7zip/Archive/Rar/RarHeader.h | 224 + .../windows/7z/CPP/7zip/Archive/Rar/RarIn.cpp | 513 +++ .../windows/7z/CPP/7zip/Archive/Rar/RarIn.h | 126 + .../7z/CPP/7zip/Archive/Rar/RarItem.cpp | 55 + .../windows/7z/CPP/7zip/Archive/Rar/RarItem.h | 79 + .../7z/CPP/7zip/Archive/Rar/RarRegister.cpp | 13 + .../7zip/Archive/Rar/RarVolumeInStream.cpp | 84 + .../CPP/7zip/Archive/Rar/RarVolumeInStream.h | 49 + .../windows/7z/CPP/7zip/Archive/Rar/StdAfx.h | 8 + .../CPP/7zip/Archive/Split/SplitHandler.cpp | 357 ++ .../7z/CPP/7zip/Archive/Split/SplitHandler.h | 37 + .../CPP/7zip/Archive/Split/SplitRegister.cpp | 20 + .../7z/CPP/7zip/Archive/Split/StdAfx.h | 8 + .../src/windows/7z/CPP/7zip/Archive/StdAfx.h | 9 + .../windows/7z/CPP/7zip/Archive/Tar/StdAfx.h | 9 + .../7z/CPP/7zip/Archive/Tar/TarHandler.cpp | 229 + .../7z/CPP/7zip/Archive/Tar/TarHandler.h | 37 + .../7z/CPP/7zip/Archive/Tar/TarHeader.cpp | 25 + .../7z/CPP/7zip/Archive/Tar/TarHeader.h | 108 + .../windows/7z/CPP/7zip/Archive/Tar/TarIn.cpp | 176 + .../windows/7z/CPP/7zip/Archive/Tar/TarIn.h | 18 + .../windows/7z/CPP/7zip/Archive/Tar/TarItem.h | 71 + .../7z/CPP/7zip/Archive/Tar/TarRegister.cpp | 18 + .../windows/7z/CPP/7zip/Archive/Zip/StdAfx.h | 8 + .../CPP/7zip/Archive/Zip/ZipCompressionMode.h | 39 + .../7z/CPP/7zip/Archive/Zip/ZipHandler.cpp | 831 ++++ .../7z/CPP/7zip/Archive/Zip/ZipHandler.h | 100 + .../7z/CPP/7zip/Archive/Zip/ZipHeader.cpp | 35 + .../7z/CPP/7zip/Archive/Zip/ZipHeader.h | 265 ++ .../windows/7z/CPP/7zip/Archive/Zip/ZipIn.cpp | 868 ++++ .../windows/7z/CPP/7zip/Archive/Zip/ZipIn.h | 116 + .../7z/CPP/7zip/Archive/Zip/ZipItem.cpp | 147 + .../windows/7z/CPP/7zip/Archive/Zip/ZipItem.h | 268 ++ .../7z/CPP/7zip/Archive/Zip/ZipItemEx.h | 34 + .../7z/CPP/7zip/Archive/Zip/ZipRegister.cpp | 21 + .../7z/CPP/7zip/Common/CreateCoder.cpp | 292 ++ .../windows/7z/CPP/7zip/Common/CreateCoder.h | 98 + .../windows/7z/CPP/7zip/Common/DeclareArcs.h | 28 + .../7z/CPP/7zip/Common/DeclareCodecs.h | 31 + .../7z/CPP/7zip/Common/FilterCoder.cpp | 262 ++ .../windows/7z/CPP/7zip/Common/FilterCoder.h | 143 + .../windows/7z/CPP/7zip/Common/InBuffer.cpp | 83 + .../src/windows/7z/CPP/7zip/Common/InBuffer.h | 81 + .../7z/CPP/7zip/Common/InOutTempBuffer.cpp | 122 + .../7z/CPP/7zip/Common/InOutTempBuffer.h | 55 + .../7z/CPP/7zip/Common/LimitedStreams.cpp | 45 + .../7z/CPP/7zip/Common/LimitedStreams.h | 54 + .../7z/CPP/7zip/Common/LockedStream.cpp | 23 + .../windows/7z/CPP/7zip/Common/LockedStream.h | 38 + .../windows/7z/CPP/7zip/Common/MemBlocks.cpp | 183 + .../windows/7z/CPP/7zip/Common/MemBlocks.h | 77 + .../windows/7z/CPP/7zip/Common/MethodId.cpp | 27 + .../src/windows/7z/CPP/7zip/Common/MethodId.h | 10 + .../7z/CPP/7zip/Common/MethodProps.cpp | 99 + .../windows/7z/CPP/7zip/Common/MethodProps.h | 41 + .../7z/CPP/7zip/Common/OffsetStream.cpp | 35 + .../windows/7z/CPP/7zip/Common/OffsetStream.h | 25 + .../windows/7z/CPP/7zip/Common/OutBuffer.cpp | 119 + .../windows/7z/CPP/7zip/Common/OutBuffer.h | 64 + .../7z/CPP/7zip/Common/OutMemStream.cpp | 142 + .../windows/7z/CPP/7zip/Common/OutMemStream.h | 96 + .../windows/7z/CPP/7zip/Common/ProgressMt.cpp | 53 + .../windows/7z/CPP/7zip/Common/ProgressMt.h | 46 + .../7z/CPP/7zip/Common/ProgressUtils.cpp | 42 + .../7z/CPP/7zip/Common/ProgressUtils.h | 34 + .../windows/7z/CPP/7zip/Common/RegisterArc.h | 33 + .../7z/CPP/7zip/Common/RegisterCodec.h | 30 + .../src/windows/7z/CPP/7zip/Common/StdAfx.h | 9 + .../7z/CPP/7zip/Common/StreamBinder.cpp | 150 + .../windows/7z/CPP/7zip/Common/StreamBinder.h | 32 + .../7z/CPP/7zip/Common/StreamObjects.cpp | 68 + .../7z/CPP/7zip/Common/StreamObjects.h | 117 + .../7z/CPP/7zip/Common/StreamUtils.cpp | 56 + .../windows/7z/CPP/7zip/Common/StreamUtils.h | 13 + .../windows/7z/CPP/7zip/Common/VirtThread.cpp | 45 + .../windows/7z/CPP/7zip/Common/VirtThread.h | 23 + .../windows/7z/CPP/7zip/Compress/BZip2Const.h | 54 + .../windows/7z/CPP/7zip/Compress/BZip2Crc.cpp | 26 + .../windows/7z/CPP/7zip/Compress/BZip2Crc.h | 31 + .../7z/CPP/7zip/Compress/BZip2Decoder.cpp | 791 ++++ .../7z/CPP/7zip/Compress/BZip2Decoder.h | 159 + .../7z/CPP/7zip/Compress/BZip2Register.cpp | 20 + .../7z/CPP/7zip/Compress/Bcj2Coder.cpp | 393 ++ .../windows/7z/CPP/7zip/Compress/Bcj2Coder.h | 125 + .../7z/CPP/7zip/Compress/Bcj2Register.cpp | 19 + .../windows/7z/CPP/7zip/Compress/BcjCoder.cpp | 15 + .../windows/7z/CPP/7zip/Compress/BcjCoder.h | 22 + .../7z/CPP/7zip/Compress/BcjRegister.cpp | 19 + .../7z/CPP/7zip/Compress/BitlDecoder.cpp | 24 + .../7z/CPP/7zip/Compress/BitlDecoder.h | 125 + .../7z/CPP/7zip/Compress/BitmDecoder.h | 66 + .../7z/CPP/7zip/Compress/BranchCoder.cpp | 19 + .../7z/CPP/7zip/Compress/BranchCoder.h | 44 + .../7z/CPP/7zip/Compress/BranchMisc.cpp | 40 + .../windows/7z/CPP/7zip/Compress/BranchMisc.h | 14 + .../7z/CPP/7zip/Compress/BranchRegister.cpp | 30 + .../windows/7z/CPP/7zip/Compress/ByteSwap.cpp | 38 + .../windows/7z/CPP/7zip/Compress/ByteSwap.h | 30 + .../7z/CPP/7zip/Compress/ByteSwapRegister.cpp | 18 + .../windows/7z/CPP/7zip/Compress/Codec.def | 4 + .../7z/CPP/7zip/Compress/CodecExports.cpp | 157 + .../7z/CPP/7zip/Compress/CopyCoder.cpp | 62 + .../windows/7z/CPP/7zip/Compress/CopyCoder.h | 32 + .../7z/CPP/7zip/Compress/CopyRegister.cpp | 14 + .../CPP/7zip/Compress/Deflate64Register.cpp | 20 + .../7z/CPP/7zip/Compress/DeflateConst.h | 134 + .../7z/CPP/7zip/Compress/DeflateDecoder.cpp | 345 ++ .../7z/CPP/7zip/Compress/DeflateDecoder.h | 136 + .../CPP/7zip/Compress/DeflateNsisRegister.cpp | 14 + .../7z/CPP/7zip/Compress/DeflateRegister.cpp | 21 + .../7z/CPP/7zip/Compress/HuffmanDecoder.h | 89 + .../7z/CPP/7zip/Compress/ImplodeDecoder.cpp | 219 + .../7z/CPP/7zip/Compress/ImplodeDecoder.h | 57 + .../7zip/Compress/ImplodeHuffmanDecoder.cpp | 89 + .../CPP/7zip/Compress/ImplodeHuffmanDecoder.h | 34 + .../7z/CPP/7zip/Compress/LzOutWindow.cpp | 14 + .../7z/CPP/7zip/Compress/LzOutWindow.h | 66 + .../7z/CPP/7zip/Compress/LzhDecoder.cpp | 220 + .../windows/7z/CPP/7zip/Compress/LzhDecoder.h | 106 + .../7z/CPP/7zip/Compress/LzmaDecoder.cpp | 190 + .../7z/CPP/7zip/Compress/LzmaDecoder.h | 73 + .../7z/CPP/7zip/Compress/LzmaRegister.cpp | 20 + .../src/windows/7z/CPP/7zip/Compress/Mtf8.h | 196 + .../7z/CPP/7zip/Compress/PpmdContext.h | 489 ++ .../windows/7z/CPP/7zip/Compress/PpmdDecode.h | 154 + .../7z/CPP/7zip/Compress/PpmdDecoder.cpp | 182 + .../7z/CPP/7zip/Compress/PpmdDecoder.h | 86 + .../7z/CPP/7zip/Compress/PpmdRegister.cpp | 20 + .../7z/CPP/7zip/Compress/PpmdSubAlloc.h | 295 ++ .../windows/7z/CPP/7zip/Compress/PpmdType.h | 20 + .../windows/7z/CPP/7zip/Compress/RangeCoder.h | 204 + .../7z/CPP/7zip/Compress/RangeCoderBit.h | 113 + .../7z/CPP/7zip/Compress/Rar1Decoder.cpp | 478 ++ .../7z/CPP/7zip/Compress/Rar1Decoder.h | 88 + .../7z/CPP/7zip/Compress/Rar2Decoder.cpp | 389 ++ .../7z/CPP/7zip/Compress/Rar2Decoder.h | 174 + .../7z/CPP/7zip/Compress/Rar3Decoder.cpp | 834 ++++ .../7z/CPP/7zip/Compress/Rar3Decoder.h | 301 ++ .../windows/7z/CPP/7zip/Compress/Rar3Vm.cpp | 1094 +++++ .../src/windows/7z/CPP/7zip/Compress/Rar3Vm.h | 179 + .../CPP/7zip/Compress/RarCodecsRegister.cpp | 26 + .../7z/CPP/7zip/Compress/ShrinkDecoder.cpp | 148 + .../7z/CPP/7zip/Compress/ShrinkDecoder.h | 38 + .../src/windows/7z/CPP/7zip/Compress/StdAfx.h | 8 + .../7z/CPP/7zip/Compress/ZlibDecoder.cpp | 94 + .../7z/CPP/7zip/Compress/ZlibDecoder.h | 46 + .../src/windows/7z/CPP/7zip/Crypto/7zAes.cpp | 245 + .../src/windows/7z/CPP/7zip/Crypto/7zAes.h | 117 + .../7z/CPP/7zip/Crypto/7zAesRegister.cpp | 18 + .../windows/7z/CPP/7zip/Crypto/HmacSha1.cpp | 109 + .../src/windows/7z/CPP/7zip/Crypto/HmacSha1.h | 39 + .../src/windows/7z/CPP/7zip/Crypto/MyAes.cpp | 57 + .../src/windows/7z/CPP/7zip/Crypto/MyAes.h | 48 + .../7z/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp | 83 + .../7z/CPP/7zip/Crypto/Pbkdf2HmacSha1.h | 21 + .../windows/7z/CPP/7zip/Crypto/RandGen.cpp | 107 + .../src/windows/7z/CPP/7zip/Crypto/RandGen.h | 21 + .../7z/CPP/7zip/Crypto/Rar20Crypto.cpp | 136 + .../windows/7z/CPP/7zip/Crypto/Rar20Crypto.h | 50 + .../src/windows/7z/CPP/7zip/Crypto/RarAes.cpp | 139 + .../src/windows/7z/CPP/7zip/Crypto/RarAes.h | 62 + .../src/windows/7z/CPP/7zip/Crypto/Sha1.cpp | 213 + desmume/src/windows/7z/CPP/7zip/Crypto/Sha1.h | 68 + .../src/windows/7z/CPP/7zip/Crypto/StdAfx.h | 8 + .../src/windows/7z/CPP/7zip/Crypto/WzAes.cpp | 209 + .../src/windows/7z/CPP/7zip/Crypto/WzAes.h | 119 + .../windows/7z/CPP/7zip/Crypto/ZipCrypto.cpp | 131 + .../windows/7z/CPP/7zip/Crypto/ZipCrypto.h | 71 + .../windows/7z/CPP/7zip/Crypto/ZipStrong.cpp | 180 + .../windows/7z/CPP/7zip/Crypto/ZipStrong.h | 53 + desmume/src/windows/7z/CPP/7zip/ICoder.h | 186 + desmume/src/windows/7z/CPP/7zip/IDecl.h | 15 + desmume/src/windows/7z/CPP/7zip/IPassword.h | 24 + desmume/src/windows/7z/CPP/7zip/IProgress.h | 33 + desmume/src/windows/7z/CPP/7zip/IStream.h | 58 + desmume/src/windows/7z/CPP/7zip/PropID.h | 69 + desmume/src/windows/7z/CPP/Common/Buffer.h | 77 + desmume/src/windows/7z/CPP/Common/CRC.cpp | 10 + desmume/src/windows/7z/CPP/Common/ComTry.h | 17 + desmume/src/windows/7z/CPP/Common/Defs.h | 20 + .../src/windows/7z/CPP/Common/DynamicBuffer.h | 47 + .../7z/CPP/Common/InitializeStaticLib.h | 29 + .../src/windows/7z/CPP/Common/IntToString.cpp | 63 + .../src/windows/7z/CPP/Common/IntToString.h | 15 + desmume/src/windows/7z/CPP/Common/MyCom.h | 225 + .../src/windows/7z/CPP/Common/MyException.h | 14 + .../src/windows/7z/CPP/Common/MyInitGuid.h | 15 + desmume/src/windows/7z/CPP/Common/MyMap.cpp | 140 + desmume/src/windows/7z/CPP/Common/MyMap.h | 28 + .../src/windows/7z/CPP/Common/MyString.cpp | 198 + desmume/src/windows/7z/CPP/Common/MyString.h | 631 +++ desmume/src/windows/7z/CPP/Common/MyUnknown.h | 24 + .../src/windows/7z/CPP/Common/MyVector.cpp | 90 + desmume/src/windows/7z/CPP/Common/MyVector.h | 256 ++ desmume/src/windows/7z/CPP/Common/MyWindows.h | 214 + desmume/src/windows/7z/CPP/Common/MyXml.cpp | 209 + desmume/src/windows/7z/CPP/Common/MyXml.h | 40 + .../src/windows/7z/CPP/Common/NewHandler.cpp | 116 + .../src/windows/7z/CPP/Common/NewHandler.h | 16 + .../windows/7z/CPP/Common/StringConvert.cpp | 102 + .../src/windows/7z/CPP/Common/StringConvert.h | 73 + .../src/windows/7z/CPP/Common/StringToInt.cpp | 90 + .../src/windows/7z/CPP/Common/StringToInt.h | 18 + desmume/src/windows/7z/CPP/Common/Types.h | 14 + .../src/windows/7z/CPP/Common/UTFConvert.cpp | 145 + .../src/windows/7z/CPP/Common/UTFConvert.h | 11 + .../src/windows/7z/CPP/Common/Wildcard.cpp | 458 ++ desmume/src/windows/7z/CPP/Common/Wildcard.h | 80 + desmume/src/windows/7z/CPP/Windows/Defs.h | 23 + .../src/windows/7z/CPP/Windows/FileDir.cpp | 841 ++++ desmume/src/windows/7z/CPP/Windows/FileDir.h | 178 + .../src/windows/7z/CPP/Windows/FileFind.cpp | 402 ++ desmume/src/windows/7z/CPP/Windows/FileFind.h | 153 + desmume/src/windows/7z/CPP/Windows/FileIO.cpp | 317 ++ desmume/src/windows/7z/CPP/Windows/FileIO.h | 99 + desmume/src/windows/7z/CPP/Windows/FileName.h | 25 + desmume/src/windows/7z/CPP/Windows/Handle.h | 37 + .../windows/7z/CPP/Windows/PropVariant.cpp | 312 ++ .../src/windows/7z/CPP/Windows/PropVariant.h | 57 + desmume/src/windows/7z/CPP/Windows/StdAfx.h | 9 + .../windows/7z/CPP/Windows/Synchronization.h | 168 + desmume/src/windows/7z/CPP/Windows/Thread.h | 38 + desmume/src/windows/7z/CPP/Windows/Time.cpp | 86 + desmume/src/windows/7z/CPP/Windows/Time.h | 21 + desmume/src/windows/7z/DOC/License.txt | 57 + desmume/src/windows/7z/DOC/gpl.txt | 339 ++ desmume/src/windows/7z/DOC/readme.txt | 48 + desmume/src/windows/7z/DOC/unRarLicense.txt | 41 + desmume/src/windows/7zip.cpp | 367 ++ desmume/src/windows/7zip.h | 41 + desmume/src/windows/7zipstreams.h | 315 ++ desmume/src/windows/DeSmuME_2005.vcproj | 30 +- desmume/src/windows/DeSmuME_2008.vcproj | 32 +- desmume/src/windows/OpenArchive.cpp | 674 +++ desmume/src/windows/OpenArchive.h | 43 + desmume/src/windows/luaconsole.cpp | 721 +++ desmume/src/windows/main.cpp | 136 +- desmume/src/windows/ram_search.cpp | 2 +- desmume/src/windows/ramwatch.cpp | 4 +- desmume/src/windows/resource.h | 10 + desmume/src/windows/resources.rc | Bin 676534 -> 678860 bytes 358 files changed, 50854 insertions(+), 19 deletions(-) create mode 100644 desmume/src/windows/7z/7zip.lib create mode 100644 desmume/src/windows/7z/7zip.vcproj create mode 100644 desmume/src/windows/7z/C/7zCrc.c create mode 100644 desmume/src/windows/7z/C/7zCrc.h create mode 100644 desmume/src/windows/7z/C/Aes.c create mode 100644 desmume/src/windows/7z/C/Aes.h create mode 100644 desmume/src/windows/7z/C/Alloc.c create mode 100644 desmume/src/windows/7z/C/Alloc.h create mode 100644 desmume/src/windows/7z/C/Bra.c create mode 100644 desmume/src/windows/7z/C/Bra.h create mode 100644 desmume/src/windows/7z/C/Bra86.c create mode 100644 desmume/src/windows/7z/C/BraIA64.c create mode 100644 desmume/src/windows/7z/C/BwtSort.c create mode 100644 desmume/src/windows/7z/C/BwtSort.h create mode 100644 desmume/src/windows/7z/C/CpuArch.h create mode 100644 desmume/src/windows/7z/C/HuffEnc.c create mode 100644 desmume/src/windows/7z/C/HuffEnc.h create mode 100644 desmume/src/windows/7z/C/LzFind.c create mode 100644 desmume/src/windows/7z/C/LzFind.h create mode 100644 desmume/src/windows/7z/C/LzFindMt.c create mode 100644 desmume/src/windows/7z/C/LzFindMt.h create mode 100644 desmume/src/windows/7z/C/LzHash.h create mode 100644 desmume/src/windows/7z/C/LzmaDec.c create mode 100644 desmume/src/windows/7z/C/LzmaDec.h create mode 100644 desmume/src/windows/7z/C/LzmaEnc.c create mode 100644 desmume/src/windows/7z/C/LzmaEnc.h create mode 100644 desmume/src/windows/7z/C/RotateDefs.h create mode 100644 desmume/src/windows/7z/C/Sha256.c create mode 100644 desmume/src/windows/7z/C/Sha256.h create mode 100644 desmume/src/windows/7z/C/Sort.c create mode 100644 desmume/src/windows/7z/C/Sort.h create mode 100644 desmume/src/windows/7z/C/Threads.c create mode 100644 desmume/src/windows/7z/C/Threads.h create mode 100644 desmume/src/windows/7z/C/Types.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zCompressionMode.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zCompressionMode.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zDecode.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zDecode.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zExtract.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zFolderInStream.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zFolderInStream.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zFolderOutStream.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zFolderOutStream.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zHandler.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zHandler.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zHeader.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zHeader.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zIn.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zIn.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zItem.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zProperties.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zProperties.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zRegister.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zSpecStream.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/7zSpecStream.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/7z/StdAfx.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/ArchiveExports.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/BZip2/BZip2Handler.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/BZip2/BZip2Handler.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/BZip2/BZip2Item.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/BZip2/StdAfx.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/BZip2/bz2Register.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Common/CoderMixer2.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Common/CoderMixer2.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Common/CoderMixer2MT.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Common/CoderMixer2MT.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Common/DummyOutStream.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Common/DummyOutStream.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Common/FindSignature.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Common/FindSignature.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Common/InStreamWithCRC.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Common/InStreamWithCRC.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Common/ItemNameUtils.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Common/ItemNameUtils.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Common/MultiStream.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Common/MultiStream.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Common/OutStreamWithCRC.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Common/ParseProperties.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Common/ParseProperties.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Common/StdAfx.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/DllExports2.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipHandler.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipHandler.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipHeader.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipHeader.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipIn.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipIn.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipItem.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipRegister.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipUpdate.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/GZip/StdAfx.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/IArchive.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhCRC.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhCRC.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhHandler.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhHandler.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhHeader.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhIn.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhIn.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhItem.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhRegister.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzh/StdAfx.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaArcRegister.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaHandler.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaHandler.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaIn.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaIn.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaItem.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Lzma/StdAfx.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarHandler.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarHandler.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarHeader.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarHeader.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarIn.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarIn.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarItem.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarItem.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarRegister.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarVolumeInStream.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarVolumeInStream.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Rar/StdAfx.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Split/SplitHandler.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Split/SplitHandler.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Split/SplitRegister.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Split/StdAfx.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/StdAfx.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Tar/StdAfx.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarHandler.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarHandler.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarHeader.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarHeader.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarIn.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarIn.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarItem.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarRegister.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Zip/StdAfx.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipCompressionMode.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipHandler.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipHandler.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipHeader.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipHeader.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipIn.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipIn.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipItem.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipItem.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipItemEx.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipRegister.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/CreateCoder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/CreateCoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/DeclareArcs.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/DeclareCodecs.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/FilterCoder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/FilterCoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/InBuffer.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/InBuffer.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/InOutTempBuffer.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/InOutTempBuffer.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/LimitedStreams.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/LimitedStreams.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/LockedStream.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/LockedStream.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/MemBlocks.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/MemBlocks.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/MethodId.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/MethodId.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/MethodProps.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/MethodProps.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/OffsetStream.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/OffsetStream.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/OutBuffer.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/OutBuffer.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/OutMemStream.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/OutMemStream.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/ProgressMt.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/ProgressMt.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/ProgressUtils.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/ProgressUtils.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/RegisterArc.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/RegisterCodec.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/StdAfx.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/StreamBinder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/StreamBinder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/StreamObjects.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/StreamObjects.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/StreamUtils.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/StreamUtils.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/VirtThread.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Common/VirtThread.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/BZip2Const.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/BZip2Crc.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/BZip2Crc.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/BZip2Decoder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/BZip2Decoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/BZip2Register.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/Bcj2Coder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/Bcj2Coder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/Bcj2Register.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/BcjCoder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/BcjCoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/BcjRegister.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/BitlDecoder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/BitlDecoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/BitmDecoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/BranchCoder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/BranchCoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/BranchMisc.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/BranchMisc.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/BranchRegister.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/ByteSwap.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/ByteSwap.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/ByteSwapRegister.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/Codec.def create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/CodecExports.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/CopyCoder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/CopyCoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/CopyRegister.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/Deflate64Register.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/DeflateConst.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/DeflateDecoder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/DeflateDecoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/DeflateNsisRegister.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/DeflateRegister.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/HuffmanDecoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/ImplodeDecoder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/ImplodeDecoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/ImplodeHuffmanDecoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/LzOutWindow.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/LzOutWindow.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/LzhDecoder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/LzhDecoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/LzmaDecoder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/LzmaDecoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/LzmaRegister.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/Mtf8.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/PpmdContext.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/PpmdDecode.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/PpmdDecoder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/PpmdDecoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/PpmdRegister.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/PpmdSubAlloc.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/PpmdType.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/RangeCoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/RangeCoderBit.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/Rar1Decoder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/Rar1Decoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/Rar2Decoder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/Rar2Decoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/Rar3Decoder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/Rar3Decoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/Rar3Vm.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/Rar3Vm.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/RarCodecsRegister.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/ShrinkDecoder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/ShrinkDecoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/StdAfx.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/ZlibDecoder.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Compress/ZlibDecoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/7zAes.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/7zAes.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/7zAesRegister.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/HmacSha1.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/HmacSha1.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/MyAes.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/MyAes.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/Pbkdf2HmacSha1.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/RandGen.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/RandGen.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/Rar20Crypto.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/Rar20Crypto.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/RarAes.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/RarAes.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/Sha1.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/Sha1.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/StdAfx.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/WzAes.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/WzAes.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/ZipCrypto.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/ZipCrypto.h create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/ZipStrong.cpp create mode 100644 desmume/src/windows/7z/CPP/7zip/Crypto/ZipStrong.h create mode 100644 desmume/src/windows/7z/CPP/7zip/ICoder.h create mode 100644 desmume/src/windows/7z/CPP/7zip/IDecl.h create mode 100644 desmume/src/windows/7z/CPP/7zip/IPassword.h create mode 100644 desmume/src/windows/7z/CPP/7zip/IProgress.h create mode 100644 desmume/src/windows/7z/CPP/7zip/IStream.h create mode 100644 desmume/src/windows/7z/CPP/7zip/PropID.h create mode 100644 desmume/src/windows/7z/CPP/Common/Buffer.h create mode 100644 desmume/src/windows/7z/CPP/Common/CRC.cpp create mode 100644 desmume/src/windows/7z/CPP/Common/ComTry.h create mode 100644 desmume/src/windows/7z/CPP/Common/Defs.h create mode 100644 desmume/src/windows/7z/CPP/Common/DynamicBuffer.h create mode 100644 desmume/src/windows/7z/CPP/Common/InitializeStaticLib.h create mode 100644 desmume/src/windows/7z/CPP/Common/IntToString.cpp create mode 100644 desmume/src/windows/7z/CPP/Common/IntToString.h create mode 100644 desmume/src/windows/7z/CPP/Common/MyCom.h create mode 100644 desmume/src/windows/7z/CPP/Common/MyException.h create mode 100644 desmume/src/windows/7z/CPP/Common/MyInitGuid.h create mode 100644 desmume/src/windows/7z/CPP/Common/MyMap.cpp create mode 100644 desmume/src/windows/7z/CPP/Common/MyMap.h create mode 100644 desmume/src/windows/7z/CPP/Common/MyString.cpp create mode 100644 desmume/src/windows/7z/CPP/Common/MyString.h create mode 100644 desmume/src/windows/7z/CPP/Common/MyUnknown.h create mode 100644 desmume/src/windows/7z/CPP/Common/MyVector.cpp create mode 100644 desmume/src/windows/7z/CPP/Common/MyVector.h create mode 100644 desmume/src/windows/7z/CPP/Common/MyWindows.h create mode 100644 desmume/src/windows/7z/CPP/Common/MyXml.cpp create mode 100644 desmume/src/windows/7z/CPP/Common/MyXml.h create mode 100644 desmume/src/windows/7z/CPP/Common/NewHandler.cpp create mode 100644 desmume/src/windows/7z/CPP/Common/NewHandler.h create mode 100644 desmume/src/windows/7z/CPP/Common/StringConvert.cpp create mode 100644 desmume/src/windows/7z/CPP/Common/StringConvert.h create mode 100644 desmume/src/windows/7z/CPP/Common/StringToInt.cpp create mode 100644 desmume/src/windows/7z/CPP/Common/StringToInt.h create mode 100644 desmume/src/windows/7z/CPP/Common/Types.h create mode 100644 desmume/src/windows/7z/CPP/Common/UTFConvert.cpp create mode 100644 desmume/src/windows/7z/CPP/Common/UTFConvert.h create mode 100644 desmume/src/windows/7z/CPP/Common/Wildcard.cpp create mode 100644 desmume/src/windows/7z/CPP/Common/Wildcard.h create mode 100644 desmume/src/windows/7z/CPP/Windows/Defs.h create mode 100644 desmume/src/windows/7z/CPP/Windows/FileDir.cpp create mode 100644 desmume/src/windows/7z/CPP/Windows/FileDir.h create mode 100644 desmume/src/windows/7z/CPP/Windows/FileFind.cpp create mode 100644 desmume/src/windows/7z/CPP/Windows/FileFind.h create mode 100644 desmume/src/windows/7z/CPP/Windows/FileIO.cpp create mode 100644 desmume/src/windows/7z/CPP/Windows/FileIO.h create mode 100644 desmume/src/windows/7z/CPP/Windows/FileName.h create mode 100644 desmume/src/windows/7z/CPP/Windows/Handle.h create mode 100644 desmume/src/windows/7z/CPP/Windows/PropVariant.cpp create mode 100644 desmume/src/windows/7z/CPP/Windows/PropVariant.h create mode 100644 desmume/src/windows/7z/CPP/Windows/StdAfx.h create mode 100644 desmume/src/windows/7z/CPP/Windows/Synchronization.h create mode 100644 desmume/src/windows/7z/CPP/Windows/Thread.h create mode 100644 desmume/src/windows/7z/CPP/Windows/Time.cpp create mode 100644 desmume/src/windows/7z/CPP/Windows/Time.h create mode 100644 desmume/src/windows/7z/DOC/License.txt create mode 100644 desmume/src/windows/7z/DOC/gpl.txt create mode 100644 desmume/src/windows/7z/DOC/readme.txt create mode 100644 desmume/src/windows/7z/DOC/unRarLicense.txt create mode 100644 desmume/src/windows/7zip.cpp create mode 100644 desmume/src/windows/7zip.h create mode 100644 desmume/src/windows/7zipstreams.h create mode 100644 desmume/src/windows/OpenArchive.cpp create mode 100644 desmume/src/windows/OpenArchive.h create mode 100644 desmume/src/windows/luaconsole.cpp diff --git a/desmume/src/windows/7z/7zip.lib b/desmume/src/windows/7z/7zip.lib new file mode 100644 index 0000000000000000000000000000000000000000..a11edfdc9560482ebc3606d9868f1eddbdb3defc GIT binary patch literal 6277950 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�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

u) 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

7v=dbj_ELIV$quWajBQ{RGh zUb1|Zmdv*9F1ZRqAgyrbEcpn4{KNs}QXdoOMgq>5T5w&#_H_Wh*?)sBB;V}M1lg3|Nu$&}PRY=9(GHq#l+AHvoFTGs1|+BF5Y=-&!4q zID+Hxh>H!@@>Uj^_6xRTHZbgi8^xTbj65<~r zrvCpxd?sSHACK7>TqO>cT98u1BdL&la8L2RjS48X1f*j>Ku>F7KTd!+TRyFUCQu7We^{rRMqoXJur{mrV4kJlBQhOsQJMt6o z5$Nc5l+uAT16_qdbzC(J@Hhb*t#k{vg|2RD%J9Udt

6YrW>_y3l3|p01mM9>r4f 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≻<{j4d=0%Gc*`+9w;@nRgdupoRT_erGz2ke2uY(M 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ɐ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≀N)XZRxxh|c% zs;r_;yv!jtN2Y}zUWJ_{cFE&C(agQ|xo_Cftc=MUD6{?HqRFz)NV`s9`T=n{&3?O% zi?iRfNMiy{@o7xNLvZ;-+O#F$?4sO|6WbH)t{H+obk_^14fYSju3iRPk1)MJsp!QY*TPfDX>b=GZ zX&GZvJpq@NK5|s*n6xn?#{_WnrKP5h8a2w}8J&J&`iUawGW#A zF`p?KjrAp_`s{RLa2~@Cb~?l7vz~xLexCD?j)PrB;iBW24?ZKc!+I76@jR2nr)YRj z=SeI)&3bAEaqr^d2}Xm|ximbB!k37ASWaIf9rHIEG!=@D@jA)l=^nM9S*T8|2`7)I z=d>#tc!hJ4_a;KF16_?el_s3L%RsjgH0kP$nQ-ZgMZHe|O%Bdup$jK(5W-f1=4wS3 zPF@NEHi6~|bqY&3c}bA>1!>f2B;n-k0*MN#1QBxD|9$@+2ksoa7Y&Ujdq}iVn$jOkWNP;$_ez zO_TD%<(K)(Ry2~*S>8_wECAif`H|%fLGam%CXzfK(svu^KAIj`UIK#q@rWIZb1J`B z$Qum0;WH#5Pu+1Uze9mZ}c z3zt5glK&KFmYf<{9=}t44QSpdi7fAN(ESZG*Dj7M?_DJ5MbO+@9$6mKcMoW0E{!aY zC*ik(=DlTI%li;C7c7q~Zx-Zj1x;La*YXYl&DPq;@@VS!fabWm$nx0UGC;E&Cjruh z)4xFoyHU{yLi{A>bFkM=4aG|7#T<(-4z$)I^! z(S?(@69F%S=AM<2<+ULAe?U`mhNO!muM#wQ&0Who3p76}x=8YRo{6vBo)uXh^V|Py z!?*$$T_kxofoAn;Nf)j@DDOVd3_n-WMUpofH2v2^mWQTmZCh{9E0mR&~zv|3@fBO%eOyCHw@P<&?K+rojmnSjCU>H_9T7)t|5ws z_rmo^4LbFgI5A$a(K+RVdcP2KCF`W9aQ#dof^SzelG3?cUPIu+pj&soqzYGWEayi+ zlYD`sivn;;AImu%H0Q6EbdkzAwhi+VTy)X6ggl3Go(r1u6dlYa>J9S>+qj+Oca@@n zS2(BivHb1_-NP43nsDVe2*E#sCdDu5z~-1=_WQ?xCVhjX3s-)`mxHEK(S?(DH|QEb zb7Z@e$8t9HRHDQ``{{|G$yIdW(_EdIOz_@)dHFu6&=$DJ?OBW7*9It z{T-lrB$!UkLj&>bC+kYwUEk@=Jug zD;14Qp|d?;`@J1>GcT7^X8GCVB_OyKG^-U|xc0Uabn8L0?25?po<#8Zpvk#1K<8Ay z9G@-*&A6*2ovgRebr9OqDn%nHo%73i$_1di{u)UY&Ym8M;159agQ8=7IHiyB4!+hf zj=E0D3zxpp2rdGRU(tmtKlVpgf@b&ik>#Z!c;F3^M*lmdZvy1ygKqtel8SofWS<*> z{|9L1-X!T_0G#Aq19_K$=J<`0E)KwyXB(GX1DYolo!MVHw98LG^Mj%bZkLAXXm^Kg zLR`4$Oge}Dw;nV%DY|g&i1Ho)&2x4-oBcZ$bbkSj>lVhU*7d^J@i@>745kZd=hUmg zpgBp=v77_zj=^^POwe4V=z2t;y9+eWb%X9Np!u#FbnaWx58|Thfh%14#(`$8oz7N% z?2k?d&H0MXCFONE^@EpyW@9j2Ncpke?*h%eUC=S!t)O{J(S^$g^ezw!u>|Z(P zl5WGF#W}T)0mxtz=-O|Wgi=pK?G^EV0?jjuj^*Mc?|tB30nJ^%i!84U!S91+(jAh{ zY;WZii<_2uXG<(>0U}xong@R`G2!e%Zv^+gQ*%k^l)jw^It+9_C|c&rv5t)_WvfQ2E*HU*A9CIRq{`Q=WspDg{luqBHf>rhj80V-slpqUgfqcO(Kn z0?mN?M6_YoE#5{%CxgcGprqq?!Kr@tfvy8ITQ*0QN45JGXfAz3(wX_S=^szv-U^zg zt&!!if4f7`NJ{7Qv449PbjgoNs-XJNjFg3Z)PUv?4m{wJa5?4oCD8o|H2!UZENuD3 zL6M#S&5maz9p}wX@^+#iwmge9yB8!K+m)%$7JWGy_`_br90?blS$+=sQURJv6&;c* z?Xyi^*p6-o&4QOGO@52ODSaM9bR}pWeofN#1#n8=K;RqxY#0~eqGLM}@@(l_1^nHh z@xD$f`F#S>f7tqkK?rLE&6SD{)yRBw*q^H%1^msR*=DD+<@X5Cy$G7!ijL*tl;2N* z|Cw}ezylY~9(WPf>rKNLii<9sJOc@z1e!^2NxDe(Zv|-1QgqC(Q~F?9jCG(%dt1sg z(M8k%+Qp|E0Q;Iyp^K6k7XBQTFhUd)7E64zKPC-s?)|@HulmL@6W8Q3faio9A?A+`* zv#{}XMoCU?;jG+joGpzYoOC@aGrOo{MnV1pQX)8e)`G&K8N8XBJtnnePT`bUnK`)= zQ&**qPD@1^CVPfY&hZS-o!Y>^GSBeoNY#R-hQ{*JC96g(Lujo%iMsF+RvtcVUWR8l z#GQf+PpS6|FG99Xsqzf3sjaGATI(5JQD0wMkL{MV^^N1|>QM(Ml)UNVigV`A&Y4y+ zy|g}ctn?S>;lzQa@(KhWwZGL+DOry?5Z=Ls;J{;iw1n{M50p-@ofe{&%=lXJ>|Gu z%coBdpf&yRK$lk51OgZ@<);|@ghK#7K;gl_7-fL?I)oN=iYve&0#X#qO4stK6{U58 zrGbfRz$xZfHI@;II(ZB$T@~ONsCW{MTMTY`h46~wnlN7HAPE~~h{rk9!mmpMWydJ<(FZi9 zV+B54Ks1g9V%V#W?c1)g=A$U$OdMEWWBkac8DTjtK=vP&!Va%3C z#EZsE|ZJ>Q58L>%6O~xJ&agJ-& z?4nty;Mk-Q5~Wgs@55jtOl*?JFbtl~jBh^0CN<(lY`Mo5yJC}?a3^=*i`%2s?WmEc zvDlhv5dXc|HC?peY zeX~GR+F4d6$9EV-^v5xJB&ixXQ^}fOD#l58{280HwJ^9)R2#Q2q@6e{ee9T%jG>@@ zs5{gn74f~@Ax;M|({Wd~h)*0X({X!usME%tWE>08D`2fd>pl3O0<^4eaP7qmgp-g& z*VLtHuikg)J8=^?-9Gi$n2WK}kS6fAto!K7?6>fpFP9GCavu)X+TmcS<*{`}11 z-XDE*^>?K=-SFr7wfL;Dz^}`U8+&`=dj?ZKW``iEh;7gUqpVj>OjypbmpdS|a1^)D# z?tJXq%Bs&7Cr#a3HDkc#n5+wYrBSr)_3EBKe>dRC4M*MdNe33MfT!z=Sze;+%TLnU zcRs&%Tz2jXPydEPv9Ogb@H21PxUy)<4Wo0ueB$|6?%y;6n{@>Kr>v7NZDMvkm1+7N}zWkykpA6`~t@FKyj@-1pE$@e&W84n-{&@nRrvLq5W1E#@7(HgDWKVc?5>E za==@r4)!UoIKMqDk1NJ(W+@IW^DGe)#cFfj*-*Z`p;%@>P7zA=6rp%APNKq>N*W@^!*7{5k`(KZ z1B-nrX5{4+OAvWg_|&hI)7*x@GcMv2*B&XGlP( zMp#8TYlK-r@PsK_F{?6_Y%%P$PMxzzL0<`)sxAalGb(E$DxsOY3jH>RgG^N*b!8FK zW2S$ZJP|r_7R+dsGX9E+FRO1v#ZxK0MX8<<^`*1%aiX$io{1iBMP;3b$VK9&LEen? z4E0RhA6m#+ELqdA9ztRJ%e_jZV&t!39&=#K!RcmBWLkcmxQtQ1Dm9utkeoEU5ph5z ztMd07v0D-}3JX&QQq?*^zYV)3K_?!d?#TqH;tk0ARmzxtfVq>pmzMe~3paI?N_`+Z z2QE{k=~tC*nraW0^cJQ@FYT5VJXHO4W@bh--sws;_2FgJc6eUaTw0U8ILKS+jteec!7IE z`P{~*@bwnBy~^h{dd6VmiohMDd~V}t__&fEXB?}1ZX*-EM1jjyKDTjvFZl`WIAetJ zxsB`L;|HYUjGL9uZM*~@Km8nMyrz6^LoT0q#DX+tAU&d@d&cyNb;lo^m^>iGGbDA4 zukf_GmW>@d5vOo2xE^p(aM5r*;TXU%JI2ih$H;t$fz*kwVKehg@BmyMT&cKxxK6{> zf~x};nOlBy0ZbNCfxL>8aHP%W)T|<=idDcOXAvU_$Q5(cvu8|9uU@gS2OZ>g$Hm3R z_wIf0!3hb8LC%PdP4xI$I>3SAieV(eaaUywo>guacTckzzQyGgxAKpPu)3#EUMx1! zeu;|Q3AER+uWdnqZ zEPMrOkA;Kr^2G|)OtQjXkD6lPu{wJh^OY~o;JPGnZexpyd)&nNlg7`CuJ5@U2;;&Y zS#3#AGcSBdm@IN`FQq;tv^bU$oi3#+_{Z8xN%OGi?!}6Ta^|YTxN%(573*DH7tTEp zU@07yj897hWL$M97OL1tg&&2Ip%+`rTBvek09jI)z_&0>aCa~lugU*f1%5;xcXrGIj?Ki?ZW&%bZz_cO-t zs848F?KK)F`R68%f1zPa)DQlG*g5_xZ}QL`<6mBR0?8UNPGWBdoVCy$NV5%p}_ zAbNdrY$u|d96e?H zP$riE4$G%fjnUclLaCjia`Oa(jz@G!tr z)%|IJLvUXKh?;F#3V1wVGvH7_tOgmw0M`MI0Nembc`Q%LV*!C5T1~yBFV3Jjq|a^e zZ6=B1ei@1LyZkewXJ1(Cja{FT*qIsa&x~F;J~Otd=Ps}qPen6%HYLkph;qoJa4dK_ zDjAJB?+Mw_(dqDE!Xxk4@0^WmyiG|clf1OkpM+Bq^@Ya}710r)9%4gOBwneA2a*>H zUHA${5eykQY0|m=)SX`k1CjvqV3|d~Mk(QSQj|xG-uTs7^kvHPp#``92r}DXt zWvfsJryDaxIk!F&|1`TjL}6*oUfgLH)H4HVx3}j5H``W_nuppura((_SQ>VEB!DLc zeBnQ&fK4%G0gr-cOQ(gmqe0^d(1~4EiO4N}$enc1a8YO|TxEmllQx(>x3L5N68Dnw zxs93rnFIWpDQ%gawwWoj{eSV#jGyDL^d#K-)?ELJ*o1q(j(Xd_B6^;`+3VjvG&8xa zIXU6py=|G`NkmAacR<3uF;TDiT?zMY2gsb?9{p6pla1b#ZTq5*&+(>2eYZZx+c)aF zsPFvGU7PXL(5GCPL;TMT-LCw@+M`GNn+K@7R7=Q6gedeFpr2O$3GLAt%IgFAS@`{D zdk0W%4w_uw_UI8Rcq)Q>DSy7dSCo#v@WMBapE*C_$*0;fy=}cZGmE~7B($(~-$4l%e2m*p?>hWrq|v%>Z^DK*;4PWDsLgfi zg-HZed8Y~nf5zP8N7l0_PO2~yQ9_bO^N2b3`e-`>p@ zz7F`Zgzp*nGKFskd_LjhZbkMyF~)1~og{p3!Z%U)-i2?1@VyV;c;VX#AN#BrgH``6 zuG?^F_Yp#gXO+^?*09GX?qFPZ+QKUlaHt5C?R%pw{C5b)LrQSUHwLe92#;4I2gc)f z2$!=tIkH%T5-PIUI;NSte7KUfzqW4NxE!%ME{q*>sU0n6!1cx!fWRFla6R>{H@_e~ z)rLqLV@Hg#BSzX0>2^da3fvmY7~B0Q+xyjgo4i z?!f+w(Gy2ivvJQ+RV5%tRSkd~4e>!DM_1;OOZPK#rdJ0}cZ`43MLyqXE+Z2Lq-94h3WjBMp|8-?&?2^`;QqR(xV z!j~y<70Tx}>f!SV+)Cwh8?EpmN07&dx%9b>E8wGzi!-iKKDTi@e6)6P#+}ONHXeqL zb}!D@s(fzaS@>uHeIP*_m1$jU{-D zXk1_7T8?Xs%~+9#G`!-p4Z-#YwNVBmFTHW6>m`FI@LNY;th78_a$-xL98}TgHs;Rr zems%c7BwwkN#;F$Dkf);u>1V6Nb5 zeP%$(qNh2eL$g8CKH2m!_v}{6acNhiJqogHr00Ny~19 zCEbdv&{oonlk#b5rbg-(vSklYFGsyNl(MO;5#JSW2pRv%_#jR=&OvnaSReNMqN z&@A@E#d4y<1h9qang=)lZ~uP%mX7OTckJ`4(Ek0c> z3@(RsrO1h@lj@5q7uyAp1dKrK^9rVo1xw{gRtbAf6&wpuHUau%6QEB{#w2bh?j^4E zY;U})A$H3=qgTsQ@rFOg8{0C*@E3Wb6RzC0{=$){nv4zvIF;%UNTFkO(XmwNNK3W+ zBd&S2Qq??z8OBm%m@GM~gVd_FE&GxW)t zq0cR1khpIY9Ty_kbu`BMWBoH@3p-zTw7`ta>g*NpdjwY4DnRobj4(HbLdu!np?BOD zIBwkP$OPTc@}7uHY5Bp%*d(nqF|gt+db^4xpa!m*ARi zs|L!Xi~+dzqZ*V|2`O$SMLNCsV=Hc5?cs`>>9H3#N2IK##kl114t;WYhd#F$9ZB5# zicadX#8Ht=iD(!!6k;PnF3w$6L>2$7GploQoXJ6767o9cSTHuc$ zY>BPFDU&i-;GQn@-rRqBl6cCKU0ZG2FdHD~Mok~nc#8TQ$W+t>Rjbv!5AYWQ+`lO+u&uzSpe~Eir`S6(8 z#IeVabpNY{=2ApkVAFf6q1m6R=)R?~mAI~ZQ=>zRJd&|lfjmfKL!Z=X`rO8Q_?Ni9 zDW6;H~7o$>u?5O;31KhXyu?T!dYzy5xoBr*JZe-+R9S%5LymZ48QLh z<^yX7*zg~Iw4(L)5R6n*_jrgJyl`kDcl3$ZA_4;x4+6AfT6}2F_?bgNbV$NJtOQP~ zFMU#d>2n+G9VPBv<-?TIQf}t}dtl{uIXI_9D7XH|r*e_X4TC;;KK}j{oqiOSF&RfU zsT20)$j&~#a4I+S4Wiu6MgnEI(I?A|K3Q%O$8wW6e`f5^%*44*dVm?4cI~`vpGReM z4t;LmJ5iYfO8U-B2@ERAL80AI+M^)*xJ3A=f4y*_^9^zgKS+d1y52#ddhjhZl={04 z*DPB-FiyrX2-m>w)kBxhrDco|XjXe`4gBwYL>ZaQ<;#<%0z-h(TGnXOMnulfFXq@n)xxouU5 z@`ScpU&iZCvI)-i=RB0Wl{RqbD{t(KdabR7cRoX`BT?C!*a#&43FpoHwd%deg=|}xB`aaHr#2)lRqgW zS|O;w@#_8{z~#2^Z$YRRJ=_Ri>JZ*T%*HXpLiiWBtn$gP=b|*;>?Ew=BRO&u>Msra zzi_wE)X z3g?s8*67_vG=TeL{NkT^{XMP}+;QYWM+3--(BXhw(mE1w7T_SjQvr_xTmt9?tN|Ph zxCZc8KpLDOfENND2e<)n7$ECn1mNv}Cjj0Lm#Dq80hkKNy5v3U^#WXSO_x5orb{2T z0)a~6?o&RuvF6iD5C-Gozgx62EFpfM@j8q}w~Y#D^Klj8D#A4%M&^+g$ZWqJf3z{j z2^+&bg0L|uurVpyV^D>#G0#P}exF+ZKI}(ITmQCszKjldSSTbB4HV+6ts+sge_Ee2(;d^p@lb%Jj9rMEGs&i#$-U= z(=;Au3qK#GD^5`-A^Zr3@F-;(`yf2UA-sn$Y&Z}Z;e3!_jsIE5x0*)wd8gP+Bh$<@ zrUO1uNP6MAG>v#g(9tq7e(e&q$MC>M%XmLxIAF`zh|21oW#n>eoubCOUKOhXV?~-D z?U;9(N|;44;~?H@Dp_YVm8Ss?0xSnS3a}c`3&_L_23!kxEZ}-Tn#y)Sn#zj-j|aRQ zkS22@AWi0jfHav;0@7se0Hn!$9grsTAAmHO9|O{4CLxV9nNt91GN%F3WX=Gj$?SuC zWC9)nm<8woq{%#5-JbxMihI^^79dUL23*o)(kD$OeQx7%NR_w_<)g`D-Yny>0~(9L zlI2^*V^=_=IUeHy+pv|1u$75{@mTBkDfMr0FqRxN7`p_cu>smd+D2o17V0n>OSW0b z`5~jRy+}@&(bxv>4G5HG@{OT?=HO3kLK*sJ8pKQ&5XnQov>3$sFgx?Z7(@}~Xb|Va zAkyH?4`UD+PJ-fGC3?hvkrdTcx6ZQ*k{hOrFwcH_=&&zRu)jCV_ndGod-As zkOL;#uQtG8fR_N$Zrut(8odE&H8={Q)ffSo377^*tH54@R^udfe=;Dg2J2E=4K^)lHRzL8gFb0BB#u@? z;{Nki<2A$`YBgHF?<+?;!AnmZ?Sxx<;uz|HY{pAqJaC)Qy035jd;4KAB9AlpF%)Zy zwp$D*i(nmRaPz;F-)b?~w{6E|57!ohYIPTfxi zq{U!eYKw6_(kd+mebQpkCoP7=(PBs(9tXCb6k9)XUi<3U_HwV`PZ&QVy8a;ltGmEr z?CE)-E3+*D??AQ2>`U1E+O`j3<6daP-AS$6B#J*hhl-JUt>%%QG4P^0`rIwsBqLAripz`A|OYoOdn_1Y>69j$tMi-$tMi- zxkWKaTr>(y;{4lqGLJDd*6)jcW7pOJ^kb{pV2sI)H+EqF#Hhc;<;A7lAmw2goh)iu z6)Z{)I#0GOu#l$*E>`g2-788woRQm-?Ij5j%IU|8mWMKZu;{^raY|9sR4vXzvrHVI z;HG1mXjEC8I)B4aj7%p7_)IGs1dH`{T=JnAee$6hee$81#BsncaoiE&atW)3$AJ_+fprAZ9$S(=yN%CnWG=HX7cBf3|b(`#2&a2>tt!nCMmxWfDj@mdv? z>0wDS&00~>;977irbL{vo``#+hU0e&k~f zKSaIb-_e#R>Sbu-V?W8YlULvPJgV_AU+XV@>klef)ViZ{A?nP(_Q4i#mn`DVboe&n z3RK`)+-Y}?@-XvsY!1BvdC#hEz(uFS`L3LNK||V~6*4#|yr)|4?2oWghj86*Q$e1@ z)nro;rip1d6IW?5{-o<(zbyAA&Tg(=Tw66Eys`6~6rxP5SLr+ev~iX$n-6((7GO1C5nvtQY(SP1@0kJ4>*b4<^vM@3>2n*WAw?2bu6)?YxL=C776q`s zin-<&F*Q9P-E2X+=~(V`cHLYl(Pp?^H+9)-eui6hv)qB-s+)g8_)42@wgAU^WgRcu z58X@`v&`R8IV}^=2+B!g*MdvC7I^*>x>*Ie)J^Inb&+<1y2*0Vy7>_NQa9<7x=EkZ zO^Ks!O5FbGCZEIazix`>>i;KovvPlQ69-G`x6OVV!)bYX{{M+?ZZ&n2KB=4ZN!^q< z>ZZi)pKfw+vA??6`b+Bn%?`bBKNM3up!_XursdgX1iciK=N44HcK^)|odYCkH0hIy zNuN|qiKAjl-2N%%UdY*h#Z39XshCasp_t-H({HJmmWNRPzbNL@ree}36_Y-xm=Z_D zl(^G7mm$n3-^BmInR5lqc&4yD#~WXME0K5yq0t+=9XnchC#E_6mGQjCe7T7Zs(uzK3RNu8%JTrf<>**Bt9Jl-z&Ic#HkK13tt-kU&0lb_IPop-Kp>->Ki}~ zEr(#*!nq!&C5vz!A9%^Rq@-dQ-b*gW*Fn6KCZ(C@DEWLdGjo0OPr*#vd?C7|q^XAI zX)bBPHzz6@9qGNPDxM1g?MIC;Z9{NjDqw7$jz8(lNVykZpDQjVG1iR4YI08gQ5WNq zcA@kRfu9o^%TZ3;fse_DaDn~c94>k!Qv5S5b*M!AP?FN29K}>)2X1?br7Ml zKa_b5=NJ}^i+PF>8uX^{G421t#rK8z7VkH>dSWSt?-)#u$E!67=G#n@IZX@mI@3S~ zSsc}p%FQSl^`Vw9dKs?Q38}VgaGhkEu}~&uaD~!Yoz(jTVK#L$Zt3)bl}(GZ`USKo zWLGiMU{|A|N{#-CF!@#iee$gW`rP6yZi!=)mbj0UFHTqpiSuvEc)l&RZEAGe)a16Q z9`i*pFKD&XiPZP90S}ka>wKdDwG`DG1;!txN!T@{AO5T9We)^Zy+P>*r$*XO(Y}KV$h?FiB zz;16XHST0@?FzuO*cAYaM8evBj4)|!S@zP}(&sj~EJU*xXH+Ynw6^4s)|NiEIAUG$ z{u}p_m#>>iI*;;6Yb$ZIwvty^+vM(8+bYPmTiefo`!&{T-fom#+~fttx%e zs?z5+UckS^vD1<`T2+Z-QA?bBZ-1tLJ$Gp@f4;c=5?b(CQL>B0!ZJIQvACSu{2+wT zMN6Q%s(``04){5?LM0Ck?h&}g7T`}h>%wpN&xPP@FgYUch9$O~4yIr0_aH8D#0*lv zQ6LMOOzDFdYk*hOH5o{a{PYL->Woumv4!xZ3*lmTnZByPWc?i4tY;(0fOvC!^mHm32B=th%nfqE~p6Qc$rjMsx zY!{gkgAg}RfzzzC)-e1aK@|A24@b^GP>!v2kcZmFOi$!90_n`}(}=Sza8wB1iLS#T zAr0cb8+AGwvaG`rR%$OZgY?M^(&yH(hCpudk$F8<_?SxRqde)ONt3=1b|6T{7A7ry zvhZoT5tB0K1ZT|W6Jgv@#O5j;i-(S)c(76+M4&mhkZC;J41`BGJp=Hmdjgr70q_N< zhG9_cOONj}**#M(s`%QmCFB@&vRdNbMXm>R6pt zHRRT|fI!568Jd~q?x~?n9o0~#?zfolG(eiqrU}eHlg|0hXW@E`U)N!XmYI$G%UY&S z)-ruK3CjOvdqM0j#BbmTil;ey=Z2m@$C1Mz<(N#Xvk&WfTLa;jHkQpscADz}?IRG% zWZ!x)uA?m@kg%Wc!W2-BI_e|!D>72ZG~dLv>{HMk=~PiHt3X7b9J0~pHfGPk`)y}? zll@0fN50}L75T5i7Za^4^(1&m(p_&r+fD8@_m%WnI zoOXoU_Xsh~Oygs?rdc#c_r~U@?zFz>;p+725M#-P7;s#;<6%jvkLKyoOn4KnI_!y2 z!xD~HsnOaoJ$rFclh0PjR}6W;*QA1*j~!0gpbp0gpa;{+`4Y;a=kYmuGdCA%Qb& z7LYS4HvhwLb#q*~zq33`!{?HKuIk9MJRb@PKQtlfuns5+cs7u7mPem78T7f0zkpEU zP-(&^PvnreeJ0Lgaks~KfcC$#Xg2`FVs#y&lJR{+`v#&M5-8`iB*`MAih|ud5J-`S zSm9;_Otw`6Wl{!VH><(%SZJm}I=uvEDSb=38KcPn87GUIyfAUXrJ%T(p2Gp-0FMAn z0z49sdOjcYvKr`<)j*$|?@8QFMJEo#OXOCtz(z3G_ISB{@l|XHC&Y`Np?c@W)SGatVQT#JatUl(M>7pBpYGOLa0S*Qn510lx0gyBk z0a=ZUL^WQcd~)|Gac(jEr!USJfPaY-=E@tq2;~K@;h&rzjLj$3d1;EtusZt~Mpv7r zv5#SHMS%TyNy?l8R%szqffRn`rP8tfW-X|=p}BC^2LeMC?qZ#)RHb% z`9hY;XV2XPMngWCOtd_ijNd+46hp>e+ZM&jBk2^TZBb&|qU5$k-nK=l?FGKJV($Pk zmRf()7$o2S93EFDnvW|N>gSbwQWS$e-7sFp6(dSPPVA_{D?}*!<{IIf3t#w=a3ex> zM*^>~vBzP&gJF%pm)pX>L%^X%ylA{%B8=mMvDPJZ>-u}D9 zAYfYd;-Voze<0i}Xy$3~%~l$^40Y8@eEx^E8)q<#KDTi-d^}YpPP}YDpWFBeIC7vz z!9RU&gRj9zUK%mU%aOXI<5*qNiS_tI(NW8%pWpaT-s|}ElS^^-_4p>pv98C1#L;aO zbX0rJJ7UBLx8GlXOu$E3lb%W?SJb83CmEfKCz=)FK`s# z7d~p_MZ%X1-=)F_kLbh*b(#2hqnymo0Ne%VhryaYOVJW|gjCWWZOVtoV9GST4}R_J ziw+uZrSD2Ud6-`(`B#|fx!Oz*=|z25Ki}o^5p4u2fp<(f9n0{#Ab#V<;9C%MH+p8x z>YUVO3+rmGKW%(^)4pBvycxsXVsizY*yAn314}Grb zsD#a#@YcKF?+1Sm_ZWa|!>g_-I27FUiXG36FNy&MS8k(L^{ zkT(`5!x<{4tY-kG*@oF#W*NfHt0JXvc@4QMno6st%*o3M8Ky~rB=g`(KnFh%1=7c; z=cj|yOhjLaNQbpV;_PEI#@m6*I!4=1^36Qd!~=~tdHAKyK)dfpBx0x zCl5T8xc3#ETkZits9*~WoV~zk$3$42wP4vd*5evtD>%(VXeqdf6GO@?AeqD3M6r(tjdKo`sBhIee&C3 z61N5X5;qs$o{4`Hx0v(oBEYEiL~J081?@D~mB=&pc}Djeikg_MtIllJ_)RMco@v%xtQtZ_cY}tf*g7S{C|Z98)8m2O#8ZYyGJ&wvx)q za%4YF9Ix!beQi_YjK!x{lr@UeW``*;bC4_!p|dRaW-DSG+A%L2LNhlIgBDE78=4w7g; zxKs0R?TmR>&KzYrtea()KrXd4lSC?hr~j`w=;WhLQ@6MGSf!$aMmTr%eemPnDJ|JDYf8$ za@S$zjy{55~kE~iz+t;S~pFNL=o)3l`MMtkA;s- zhkd^nmv#%_;jlwHDvWir>e&bgJAF$FKe$zUS0hf}x@1?=w+oR5`y0qi_YhoEqi!xl zm`~}2qFOT@3n9{_0@ycNS=J+DJEsyqE2?<{d@OmnWr{wx!O_qTfn#H%PcGGwBaX}3 zg4Zn`zDnLf2$8%YQ?IZaPo1V-FF}rV>ZQk~-JR|*t#Z2avhew5j%m*va{$YUBaq3B zxB{)W9CzAb$xJw^BOO(aoeb}}GOX97tl_;ysH8iP66Qa^vUHyiQ{si#I5<%gTmTG z0U6JqfUeBtxI(iXGri~gi-|n%rZxN`n7(ja+Do~dD%r9Ks=t(+v&ToXu`4UizW=2 zI%QqQxx4n%x9&@78f=#oCG&7d>xaE$*Y5Pr|x#Z(q-8@t2-0;kKI6Nw53|r$pWS}8cS!qG|Dr0T zgtc$~(%CtA&34wpny2}ocf24!`>%VZ;XR5Wh3(T%GimPvZTklAEYQwuZ(ol_YX)7+ zpewvwyqJYTc3XlP8T15;c`IXSZ}blN`u6)={taF}W5pxgg&8jiIcuJwI*TXtFQYhP z#Om%w_>#qHo%F53Jv+H%@pM<>e!{)<^+N>Li_o#~@p)phL6wrB?2o1IbJI5glb@>u z-7@$t5WZIUSfR-VzaVz0@VyA%Yr=;#hCE$<8=*|RcC>9C+z`d}zz1#NBT;txh|hiq zzuy+#h;ST%jSx9AyUQUwT1`_tpt;>4TzBxCalVQx-!|hEX$JlY@Sfa#+gMb(xJrF4 z%9>+KzlySDU-}c&@DNxzo2BH@#~=OJ*|`nN3sn^>E2{GO*MP!~OWFtg6eOjl;tUIR zC$P${Dy%tqS%$c@V}58?X_JZ-zTA+XomvVw75GZP(*bdbukTd>uE%{1;2!{M0cip1 z0G|e20Z3iM$g+iHh-8S9i_zJ)?8H5^vBizJngIs`o(afJLl^>xgQze&X_<)o)qq)m zE%>qdtO4X>(^fz}%UcI{3g88R=Kvy2Ef)i}0dn!l4|p@+MS!;fUJS^g!zF<13!tMd z-vV9%7=v=S5-0f2HvsZ0dm8~80XG5i>v^{TQrB(+d<^h*KzEjN1Cx@#m+~S21(UP3&D7M>%Xl*#$v(!iIR7+$DIp zyim-L!O9D>4yQ)po|VcC^GA#h55zOPzxFax5c!ud>#k95%3AX zjes41w*vkNkY&Jo=HPu)hC1H+=1#~`kx169$rw@^8t`@fr&o3z(k+h_y?#Y?i1y6 ziNz7=*0(@nD1}oVNu;{(cxlCv0y03d0?} z4daV7dq^PnVeDA*PxOe!8(-jy+^@9t6Gja5U^UwF$3)@u^hAtL%~6$qUu$P-LhB3Q zhv-ERjm`nGV(~Zhg*Wynp;51``A~@6V+!?8KubWG|G1{J6O*Qd^VkEmU+pq}>fH9P zBe&4(;LF??Z11Mt%Um~k{8#ehm;QEs{PN`1e?<8ozfycE6Uo~B6Ij;#*b~$Vt>{7w z|2onReY$lg$kvgJBWt%B^l>!bx-TW6m3dcbZvj`g(vIj7HeX8W_Ts~O;K6s|nod?r z{aM-ahFPkwX}>^ZXV;PPT>2eR?=f`G+%-Sa;3u@+3;~F`hBfk|rA9tmvxnKxHS)12 zy3c}Y1ZD+=_cISw=8S~JrOE~|pkQXV$&%?5g)k3#(sm;YO;qUGj>dt<72~5FP!S{H z;+uXJyBE>Rv_8WXPPu{6^kW950tO=%+20hxcO0%{@%5v4_+r>?8yf{~6aM3H#fZ}h zpA@*4@Xx*?Mr=#iC~#~P80iC7i|jrvaO>fd^8NtdMuFpEo0J!Yj3x?>VerXNez-S5 z;FiNTL~zhba5d>RT-x1%Q0k?&AT(or)crw#{1CP^d`GXq=1ORdak(u#2E=-EB~y2) zL%7~t$(*-4gh#9OtuGOdo+V@>0MpDgZUW3NfJZt9GpaV@>dlq;XNrX+=0`i0Tfo`+ zN4>eS5ft29nZ$uE^sWi_SSnbI$1_$`mH3{BTsHj*Bpe=U$29N7%@ADq3jYzzC(Y}} zfF8hq0uBY-4VVGA2e1h6Q$Y5%UjSADehrA8m?zwe4VI|WmS=GPZ$P&9eSoou;|IVL zz)rwHjMF7gY{sg;I2jSmNqn3GYyT}v5e}Y~GXM_)q@9lgd_}kA(T*ijxf3@vwwW$Y-749tu z8@*a~vmLZg_X&bs6bf_lu|KA59mm8tClX%;Y3D%M-`C#|4Kph~dxS?QMTHPogfAaq zZY}r{Hn(%5&`fpGBp$I9&VpbO)_&@k_GxNE{EOS8Jcvf%(KpU-d4g;P?A}xWqv;I) z%OVVMc;cRGI#n$kV2P*obz}UMV$hz7LAyxc8OJDUWN2V}zIQ&wK+!veh%G2XWB2{| z4++ZX*nKVV|BtyZfsd-X{(r-S5GN55jEaalU_=y%31JDFOdw%j!VVG%Aqfx-TNV}< z91Ngw2<}U(MR2K0)!MpLt3S)8;J#O__AhO<#X>7u7pk`Tf4}G6`{vDiGfC9`>hFH$ zzH{EW=bU@*x%-{_-m|6acA0de7ajUFW;#D; zl^^j%LTO0hFl=#knTE@-X;YhDi5%YeMg3%)@$5$9VB06F)207FG^>?iF8vE|QftyX zT~PEz&VM}rG(nj54hQz*KA;+&J)6z#Er}o;M#inVP_X?+gsG$++j>@=r)R!)K-N`?2ZrkNYtQ zKjI3%4&lc^8_4nyCORoBKppP^ah#&#>>iud)uF`y#uOA3jW5PiZqqAQ)>kg8t17D= zr@xXH3dPd#c)NO60|G{tPUy!_b0n^~X8B@1{5NjdqUE7b=p5{qIa1_0ocDvJ3V#|Y zo81hXxljGEoH(ia9EP3Lw!z+HLd|H)pUtFT@RykI2OUKfj{oo3AxRMLbmu# zSo~YBUy#8G00*PBqp(M{Ouqlfe-zR+iHv-OE;Tax0i!XM(4~T@Uuwn+NWrNH;QWH$ zlYB$p*DotBD?eXkyMW9n&O`rLj;d2*7KWmg2N$WJ)_h)!>16brr7Wyo?ojfcW>r+f z&!inPsW5SJk;pNbZpIk>Uoa;%SD}oIW7!DNq1i(r_Ou}T+GX-!N?u!Ah0mR;3m{aQ+fKLI= z1bh~77U1syF{ul)ADRbv0PtMEZvYnnc7Vak0FMD&2*}Svl>>6$4snLLW4#El7;p*T zO28_>>j4@6&j70dIrCTwxD#+W;B$a00AB%I33wPV2as)|29TBGAkxr5&hD~jPqo6J z5esnIX8m1goi!G)UI0dkRO=Ou1*|k^Q?gt+DcM0NVZ}F8V|ZG}rp>TvO_Q82-`Nux zzr%CEfoM&(uV(vGQ=Fs9R)G7wi}mW8+|IWK!BRJOei=Wp5E@(Q0ZHnezm-5w*?Zc!44Y0`m6M&nG)q*!Gl6;C4vo%S%gdR$ly$m2ny>D7SjlhCU` zQ`il_{w?{XT{*a+SF+v1z`AHp;s@xrdh5ZB*1uJUk%w;5Q5?L~;Ko(g7WmE1p~5wI zwJ>naEEw~@F>t8?;$>K2wCm3h=9R0aZSb?~0m9ePYLEkj3=Ss$5Jm2dBgVnuZPY|g zkUB*zku`C0Zk}~Tlu%k)URGDWBx?k9{@2Zt)$jjMT5>U-*|Q56YViM|wB^VNFpl0l z8&bEVN`0D>9cRoJh|SpP9pgE8yT*9d9+I46d^gZy#&~{7o}+7@c^CuG1XJY|Y<=a< z-hZD1DdSk555qID6E$%aI(gRd)qt$x7XmH>Tmx9E?=J&fi~H*VF96)8>CEH5&{L>K z5!lP9M-hkx?pxlpdAI90gMJnmM28`k6*G{p9ofmP@0wlgK~WNfc>JsqBZ4}EBMXW zP)I^EysTIjsMnIk=f(ef2PpalPWbxjj+!Mm4SSN*(}f&UxCqOXS12BjBt`#2bB;47 zOYE_`hbTIW@-$x8IN{DW)N!|XzN)23VyP0Tg%SI5QBOfeoJ*XmCVV(L!~V*GyzucmAmozff`ol@Uf z?=9FCZFeD@NGOqt5*~< zC_>71CRvsh1TDcSS}qG1Y#ifHM*{Fey;1Hb*vq3;`GAkIDluhMVgYNv4o$T_(3typ zDfy!Hkg*uYooJ_1f5s_0(MoJi#oy<6skYCzJzvTkcb6QG)tEY7N?Jh5c!+iEu|02^ zUsw9(-m#B-ao?8N*Z=xj&N-G2DH(J@|A7N=y#T(X235PPwz6bZ`QV)F6%`Aue|-8$ zs2uP1$*!t6dD;d%)xuU2T2xt9mz{&P0lE*NWLMPSO!=xx5Trc(zFeX)F1w;~Vg2H) z=_DdyI2HaRDlIobqAt6pqO7h=-LrN2ee8be&iZ}rGfIwkroxb?o#m8bh~Jmbq`{qi z%gb*nj8`rg>4ZnH{Q#0fB`wro1G^g0uBcRfyh-PB1@*>V17u!p;1kXR_Su6_Nait2+ z8@QUd0yc(!BE$texnPa=`>w&2xoCgey(_(%S#$h84%kL>nvG>r3@**i#UM?wgyOVV zNAUT5-Ek#L-s;L*y>WFCo^D_;abc1Q8Xb@A&~>zeuCm|?!0*ezl`Kv3AD-sb%uv6a z$Ta%WZOxd6iAxvFrAsT9)>fJt_Hou9_OpK93|tYh^{*}$V*`TBPRn!j_WQVjWJ>us8{>Wh-EkhxT|o8wSe|sx zKl#xrZ<W~ZG` z!M)$dS%cAhvaR_At@&h6nu8)`+Qfu*@2>W0?k+qWcZ}wst=UwUpht5Lk!sl*rwUJ+ zLvs&X^H^OGdw4WwiB!whI8Aui7n(F@*_u~t%~>AJJw=M+2n4OCbH`zF=(h9e!t)uf zrq=bevHP^(ZWAcR;whKSL+M_j}>B&VOk-8XC_*rR36;*mQ_Z6Ny5TVi6 z$HsoHHTUso&K9YmkfP=fQ_i{9tNAS9VXtR2XWQ6kT64BXGy6`z?`^21=2I7sz0IpR zS9qLh#w+PTqs!Mwjz=^5V80I=-J*HKS$*To3eYKl$EmrWt@$FYxt~XKf03G|HNWxn z=;yp?9^ld3-`2cSYwqvSETfI@Y{){n^+3B_WnRsLL^FE;V}pS<)?Tl$2YNJf)Kaqx zAXff|x1gIrQN{FHgM}x_p*i2yJWy-S_h=p>Qk=a&(0cfSa|*qhhYAmST9f7>Hnv!6 z9^%nFOr-etEHzIE9@^{GjNudc+V9Xj%+`FP);!FknHKi@!njiN8;kgiu-h6VgvY7* zY+G|z-I1N`(Hs(~Fs{^m%jAjUyqXJy$Ei7FYu>6ghdi1`ij=X&PwqeCuU^fgJeo(^ zntQN&gB$75i~@r-jOJ|{@5Vlb+Zsi}<4kj*t@%!^xzM9|v`C%HEBxmxUi!$Zd5rMP z@TqfRxWS&dsU^L*L=Z|4DU#Vv)*7LV#ntcYi7UI7^6r=Sj!F&JQe%-G)iGCSiX|ze zf{Sd5N)cw1pm2^8m3q+TVeE8!Vkp^bxBycL8i!E7k3BFs5B=fGyQ1lNA5t`t@BpH2 z1O#YGcC9E9(s*3`KF+x49_inK(+xQ1Om712{XR2KSbWMM*v?&E6NQIuSyw1L!Dy_S zrDLBU)^KW`BvM>2&=q}l^xIy|s2qs>6d0O+7sAgRgrizrQ2`RV#bZb;Crq}q$okn58S!uG_U44!gC+5@N~0n&9z$d zY>(!-;A?HJb&l}t;T4{4uB|zuHP7{Eo(Dd)o53{4-_0lyo(Fk_r<-SMepqXsr!+hE zh@{^7GQn+Z7~RZ%2~zBX$Yb`1vTAT6AKLMYlDTU$N;PXK@+eJR(|~Fh8~XxKu?E4FdM@s8+DIc~S$(w>d19r?Kv6a{DUC`MYAN!> zN-Y#AuDK|+;Fxcoh)T`VQsjx1DvyyGv+5m8B}}XrYANzS%CXZ`AyQn)GG9ZVKeRC_ zb-k7%Pi$P3B4wrL=M`Sz=@#3y?Jcc&vC{0QnN{FZb&RQ0E?GlvYO-dMCpKT_fs&|Zp1}<*IPyTs zVfphx@%y-fpfyhX^w7m7=jaEu6nSFfsun3@`Ph1Rv6doFtkhDG!oUf-aR$3XOOYp5 zY8fclSrWRt9zL(7$O9=y=`0s1rjRcFsJ8+ke&2n(k_m3PT{>TD&C5OIz7l+D7lIb+ zUcTTNl^^F`0lNy!V0ne7TWM=PrlX+*wH=0Oinor{g4OSPidXoTKfCf$RZh;h>V$`@ zEmK=+ZEUL6TphyW!2v1m9)ueu|)_iePvz|3wB2qnZWe?G5$jfV^QWtBfOCW{aOGj@L7OD8-;6sq2F7lXG z2^4NUe4;+;b1g+4)xJ+hLu5{L?2b7$Dm3);(VU!PN7FnTQk;(o4Bd19q510~w~jcEGnwP;*3v=n(_r7n+=8nW^mG&mF2 zIxR(>SgFPssli7wbe#v;x=BlsCsyi;7^(6fXJEs_#I;vTktbFv5+n8bwsv<#rS@wn z@<7T_UYl(xT7L3~Gn%4O|JG9EiH!?Pu%Rih*m**i&Ip7fPps4yQ2ai&I>x1($yc_P zB2TQ;m7qk+D|Y@W&p)lN7Hh8-!;f(ro(G>+Lum(P_S3G=tIlTvLdv@;Tuc;>yKZ>_!ly z|0<4rr$+~G>^BL|eq2qyZnUw}wdNZ=`TCJap(~f#^2qX0VXx*N3(v#6!qff8)?BPL z|Hz~HX7KrCa{&gi;%mM|c$_ntn{CZkYt1)%H2*}TxOQV%yf^69Q@m;3Dm-HmwJD3A z*qWcvntu}2tVg0-Maqmsd-hisMWx=?Qnx}%+2L4Je2xx^;#{q76Ftt+A*!bcQXCzG z2N1jHpwMlDkNt;kJ1M@wxFRFg%YT2QSz*qWa+~n<2ZJg1?KXC|*1R2Qj;&F*i_~vX z@z}qdaPiT=7>85y9m2!MF^uNhZR`!L`F4-yJ4FiJqLfa_n#bpOHUCt2o^+)7PFr)k zV-W~1MU{yySK~%_gOq!+s`}U(U>&d(IGh1^+YyMeOv#zW6 zi{?{tWh>}EsOdLRspR88g1aA5h#F3gz6i#eKzG09u|zW|uX`wmJ(SbA*cE5=6oSI~ ztm1OEf(Jm2og+n4_`H@99?>_Q27*%*=XmjRQ2oA#apeqT(Vx%G^V;x1;R(VNx|!ld zH>RB4)0%%SIaLRZ)hltRnL4qbb%MMg1X9LgZ-8j^fu6P{5=8-h( z()k6bYM+hvziwK`@zM1B7E*M-khq){`z5G;-x^$L(Ft2_oe-6pi$zZssKNt?&xL@( z)*Gc%V7WOqhH?NDI>qChlRN}!biZ!*{U6q-)TM3da6;);4cb6mEqES5(Z-iQv zDJm!!D^ZQe8E1d9&X|zV<1siKw5`WehAlk(0Lw|_C=5O)VL!kYH<@_8G5QYn+kAj9lZ!`6duUBbVZry;F>=y>Ku5vI|A3Oh)^$u?UbD2Un%!Y*<)AwQ zl;5nf>iX9C(T=4mPFlXIvUqt+fhDNBb5z66QdNBV+NBGZSBGY`k}hYubwx;=?Q!U& zTGPiC{k@aWLh=3A($GSC_;015h353%NX8uWx@mUBSzO$ z#!fU;D=IB5t*tDtuc@kATUx$+`T13q(CBztGmbVel#W`nW^_&2(#o-A%POiXYx1m+ zQxB&jT3e{U=v!33th@>@5y-+Al{gP|e8FUV7BjBK@8&t0VQvsR0g~Yu(Rr!yZ06yL z8Z9=6qoCVFu^g&cDwo7$Iv$HExoEDvJnn4Aa>#%jJ0WX*7FVREW4WGbrM6cqy^@)` zVLoTx5+PHv=nQB?=^%H|z>y&oQ0cV(i2`!se32RZl#m%zw{}HkDeF!sWYpxj)d=Ub ze(}k<1)&i+1)-vXP^;ng3{@$VRM|9@o@sf}d8~=nX30m*Sb@1L9w)12jkF_-KmQEb z#&no00jtS-)P$`t#+Wn#ubm}RlnMAuM%%;|$KEZd%}G!XbJ|=Fz5U4u)g~q_ZFxzd zXQ6t=-u9U&dmC9fwVp(2p=y;Cvq}`YtP-(!bxs@-Oi0uOCMKmVt(Q=*BnI?}W|p4l zb8FtduvHoMjA)pNRSz85TE&;{plup-?}F8T%(&EQD&6BwTLfY||9U; zO*6Ve^%RV0l!^7~=GYoTv>~>Yb5zLPx#i}$`_2~Ha_Kb99!Jk0t;e;SVt2H&TmiNf zVs~Fm*5gqf`HdIcKd}|sQei`mFIh2hvEM~$p{Lw?!bf zwYM&zw)NOyC(bi=s>Y4wmIOO@^-krMxl1Q=I3aiREzE6^fZ?T2(PKhQ{H-wRR^>DC zg4VQ3vZ)h^`2k)n<{5~7u%yV$pL?tBE!FWfr)S$JW`SY$h}4+x*>x?Q?Aoq!P3U7c zxe%ylC9;WWw$fr{)GQ{Zx%^<3bG5=BG959E`-e-&5A$9hl*14FTA?2}0l7c41zZCd zD_{%#@Bh+Euh=O>Hz9tgG}P6sl@|u;eU2Y08PXtX*Dn2`UbV%IFi)rS->(yT{So(F zKzh#2orCD0=6L^)3Ller_JegNX18kdJTEl20RO*mu4{I&TF$M^C(YkyiQ_O+&%jx^ z{c{Hfqb|2!|A9IAx%vI`qcmc-6icc+#AP|^6pyYbp={6S9V zeANl>bK&2^@rW1~NRRnDpJ97&n&xO6c6hb7;^hC|AuD~P^FRSZ`s1JafAO@G!-cGz z9nL@B8N{Ppxo0_;fCkfx7dVd*F!XKsA>iwr!#njSe<&UCIu0R{-Wk3SJhL<(vl~wz z4<#%B&qQV%j)w-~>AME>b>KxO_! zz;p9}mi6(l+KZY;amLT@Hwb(id~XbFS)U)l$%Bk01>@!S4g?(qzWX&V<>J||3+T_c zK_4F=`xE#+#?cPCMD}B~>pmFe22a{z7gQNWK_%gIwANMnx`dwDbTkAeESL&R|kN2^@Uwf$0DOi!FcK8%P&p` z-=NWoCy_p!r?M{AJVt9gefiLL6Zl>k)3QG1_c)%%a=3Wkpn@ zlN4Vfeccg!j^HpYstx` zY93LDOT7Hje$RvN<++M0Q9Gv{jy(r+1b8}##npEo=vm--Mf1@v@ydhk^6%jJq7{96 zz=vm$tv&E`iS%(E_DAp>)O?B3_aOK_2hW`))aKCVc#MnmO!(d4c}w%DdVu;YeCpvP z!*>)a!%3_VaCUh(4yclT5_~RrCTl*X5A9=zTOaG`9PliO<@3bL{MLZyLd|E#>q=iY z@LdU>pS6MSH{f~K&F9L;@zD1%c#`J>fomxr>EH>*@_F(>yPgT2v)p{H`poqT? zu?zG2Pw=!`00hpCH%|E;w*dV(Je|$wvLEZ!=mq46x_I_u`<=A_ddd`^Z9kVj&Le{0 zIZN~Tcpqoovmf-q;5lI-5V%D8PDI!s%_EGs#M8%l#5C|NDpy>I`YX;$?gP)$nvZr# zr0*T@{H;RiQ}w{RF6)TkQ!4Rl0C>7Y`Qmv{{9Gf z(v~Zl%@=2$b2fO+(|oK~GS6|fOX^z(o@?BEu72Zm@ck4#FKRwyKjFCW7I^*=%jfAg zSnodpPhbTQINCX0`Zz9(2G2sxmna|PTLqqL+Q9cy@a$>>-*3V5X&d;GS7PoCPiLpk zWk05GAb6%}zLxA)0-owvK9Bua?yJCaVJm!$cO!VVYd$-Daq7V%;Ca@~=ju<{{rq0@ z02LRneQ+ILP=gn~)GD4t{R`<4@LZ+&XqR~U-UI!|;91263YSP9yV1MBlUgrq(e~ze zoiIZtBBDI-T(U~>CF)-|4}M4UD9-rl+mFCMgYTKuiYrn20th|=o_1>#U!weSd`kn* zW17#8d%J&8qH?9a--2gt0<1&Yt^uUz)yL$x7yG8LO8h=kk@XO%&RP)*OIZplS z`V)*b@N`Iq8joD{kL~Cj@O0ctE;Vk&%Wn`7jR((pw<*430PObbXdj$U_PQNkjDn}L z?dM7#n|B#_-qCzqm&$nQ8fUtLe#RY$8=j8!S=MhZz8;{@0M9BnpDVv7gD(u8t(uQ^ ziI?9)p#PG5cLIT9KJ5GoMP0H0o&?W+&6h|Y6aE=^KKrSXYYz}lAN#+acVTV^PsjYm zOW%E<4*}1gHJ_b6$D@Rl55XthO)Tp8zYG52IjgW}bivGtGbWB3IiyE@eN{zvb=ATi ziO5Ni{{)^NrpmT_8M7Z6)98MGzW!gTWLjBGu0HUTy?o($)(~r0hA+r>$aR8-lc%NF za8gxy&GOpii|T^CrkxR-g3oO%t-638m*64VDjb@({@8AKhE=}0!u_&-tGwEpIHW{A zzE`$1h{y9PYfGZ)W>wYJmsJO+*VR{4Ee{UP&MBESs$^l+vXb)Z?8-HjR{7EjtM8P4 z!M;-#@=^s~2fsGhcg&1n-*N7ojVdk<_AQ(}ZgL*D3nv#Ajhs0KNGT|VQ)W*mI%?XC z(&nh3?t;t@3(Bg26<#uKS$TDRMJ0lJeA{BEQldS+i)>k4_0mPV}=v1)6|t?Uxi3Vb%AYDI}T@*Pw2%U7(h_z{Ujg<*eXLfX|; zXkf=#9Wr+0^Uuxm@szC`jFabfj|KhGQCw`1KCN;EpVF%)2p0gb}ea18_pHnij6-lRJ+|m_z6G=)&5P9NL&3KVSN(L7XGsi8f%j;*Q z;g*9p?gsXkz*BV~ZjVRc?UNA0^tH8hl}qhY4Jg@^jC&Yh4(LaN(h;=B8DyOXN|!Mv zop>I2Se!4co{jGorDRMkL`uA$UzM{w+z#$Vn8VeL(PR{JW8o z@lb4(b|~JmpOW!3^*RnDMq@n&p`W=zQA#NpUy_JI)&ri^9klex*x@vt!jK_6y`DQ{ zh&ir-Pmrc$j6|u~C!2ZPr$!PmAGxr}GPvn4%ZgPmbPB~iV=mF3!RYynaWu|hcFCP> zosQ_kXeDt{Cd(#?_k5qj>YbzMzD_4SJGJEK4?ei@i?Xe^yjrsXi&Np>SdcpS&h&RCKX~8p z#y5^yff?g%LLWM5`;P}zE&FucqV|0|Z#(BKEZ&8F=io=~|JV3A-5#2Hb>QoJ9>+{E zfCQ!c#@u$}{|v4^;m^-KwK?^a2hVvGlWd`XkvA!ISANE?JDh&U(c>N;_?3L7l;28v zZ||26y-;=Lg==5ich{j`VkUl>@SnH!o+m!9s{Z@JjIoESr*yd%iw>c0+8I3i_|<=Z z^Oxsk+>`d&sEt@WfKJCxkEZ*!4=c*P{T~;+aQ1+oAJ^l8n=9WQ) zpZw3WFa2Ws6l|;s{hMVg>$}bPYR)$cuAA`muqoKQt($s)gj;R5^d0bL`!SedL)iT0nFKLl~ z>GEYI;9ZC(zAI~5;;kxYYiN<9wyvhKY-s`(q>XVcU0c8G{AJ5mF9X~8LrO54S&WA< zgNtOMxYV9^)>fQfTcR?crU+$bicqo;--5z}b+s+W!$;eLkz_v20 zvMbp_bY&)W@l^_c6?m#!QOKH6wXDTTXeY1Id;l>V8bZFr$)p%Tr- zdWg!tt@Ij6MgQ+6tfJ0W!c5Ee(x!xQ>hXJIM5pE3T0v#RL>5%<1I)r!0-bvC(3eTJ2~gY!|Ab=-M9BYVz4?f>{%#CTEu~oL;u7vSM20 zVl3H7FBUqP5LR4&vbYAj&g4~*-YRO=TS3s}zp%M{vk z8VgwO16z)HT&ndajp6&e*o|8uv`mdL_fdywmuvuX(~i?3=AP-K?k?~_?Xl?fI3q(F z(=JRmH-Wpt_khoWk0(bm%Zl+Zj_z^1FHU@56Nk)Mec*?|PlPYlo^$Y)ehS8*gPHO6LgixpVkM`;KONvr=Y9j`aTLl%e}-I)&F|S#={Kv(kq? zSDWwuDl$1`W~4eRv-iHCFRnTZzryEBnUD57xU%|+RzxnDv zKezNj-~3%ER%t(cJUPW0x-PxGU0!n}`HIZ^$mFEUGgF!o-RPt-L-E1o4*G-36#T6b zT#vM!1|KcC4Y)Jz8jY}g=~#03S*+izM_b_OoZ;p()$CBIoz59YR zh9A{_uE*VQSIuCW$aW?ChmM-z*x^C*F)tDHG#yrV<$?fgI)94Rj$`nZdFGAnwgNky zWy{JdG0LT8Faso3S1v>2MfZh&>)_du7-wvCJP3O<@mSOnrWJ!jm<;P4_X_}f;l2{^ z48X;JX9BJT>D z-bWC1$4>Sl_@S;!LY8TbQK9g^FpZ$tOy}^<4k^> z-ANt{%W!lrQUL}4vV&ze!!)v+q2Wv4Y5O&Xj(8`!lBC8In3!q) z96k%)IJQ7KlOOl!gx=qpqLeOF_@>C8P;eu^F!V-PDw||0Z9!o#8k$J1+2UsjRgxD3o055 zmNXVrHx{gDELhW6P!~66U80c*#+=cyYOoD8z!$r6W@Ol*{VUpr;#7q~wabLO#=O_G zg&cE4V8i+%+V|Q;J{IvA$273W*_MZCBHCA&=&6A08&KtCNX9TGZL23B(~JQ|ss@H^ zZ9!tng2V#SO)J_y+$&n7Fe~MZ^6K(j>2B21P!_M>rMDm{9u%pv;J0m+W+M@TC z_7)vGkrdnY));as&TaDBL7m_-xsmCGuz$AAz*QwCriy@A!1@4JMLVD|R_y%sm*cK}+^@p`jqC4# z{>Jrp%XOPvZ;|Uwa=i}Mz3Z>Sl?$A`>vsV21tD?ulMKK5F<#d{EZ5C)y-%(W;u^QH zR6~=~xl8V11dex=oRMJ{@huulA-?L^QZs=zSHU@EA9EauWc(}@l(Z}j8HDqLVZup( zEERl4R%Q=42OXY^`$pqr$AD zUvsKFtBC`P^>`4MNY45{Tllv#_0z_jh8;-_ANlGJHT>1L_K%Ueth6Oo6265viv@2r z>`B`@x(h}2j?N4TNM9fzEi52qn}DPp1j+kx<%D+#;5hhb6D-7?arGLZQRtinNrNmA zYIORk!jULA_KJ7Iy9?UrtU*|FTbpQ24PT1uDQFcF6p3>cbZ0#%)`M%*lCm27HHbeM z^;8rzo+emcTwR74D(eKBsk1^bo$d-T4+YDp&IL>doDX;`U@0J`ib6-zwHDyM0B|87 z^H~na3NaR5%}$7^*$J_L#iRO)mZq_QHGSr+$Vamu=fL$9&T=Kn%cbcPbm}! z*Jr|e2vnu2@v0<>6ej_J46cw+`Wqihg67DpU%u9Kfp6r_KO$O2xc-mM$WtWR6fibT z^)=p%cC2^z?e=JQB^6!Qn>Fb}NE!Kac^vLEcl2nsYq^8ZiNSZ2K4STX?HC?|MiJKOAQ7EPJ&z-ls3Yt|by2!?^w6X2L z#v+Pn8@q!sYR89?osMmYGhZY}CTe%P!Z~|a(^WNR`l&0t3gLd~#?&(JjyU1%EY?Of zE7%q%Tm^Ypi}AB_uo}oaHPA z#B$L>naB#^Jis9Cmja#xIqY+Wfpfzm90ptocmrS!AoEiTNb5|7?;x*AAch@YO$%5d za4A}$#sXHuMOkUS+LXs;TOGo?(%6@$g!8S)jI5+i*YCXiiVYCX+kpU<>gVuT@W%Dh zh$@rVUY5P+1Mst5!=;hIoXtvQVw7uXZW;e*MB;S@HFnZ{D5sgSH%3AV0*>p91wO}K z5}0sym$i5YxAdiIabFCQaZE2ujN@COCcXtr6MY+y^mnx7-vjJ~``-bc3ivJ{^GQ0R z;sRa`tHji>N-Q8TDB5S555uZ&fb7dC+8el6v;!JTwGP=d?#Cs=z8#Hy_p%9E^KCPmvL+SL#yFZ8Kf9;n zn#1WBZZ^YM3|GNVauox0Qb!l~Z&3{TG>^yJNl>F)5Vf40k;~ks*b|wX>2aIeEU~%4 zq(*;YYV;?D|B-N2H1;xz#@3=}tjmhVDI!eXNRvyIPC}KAJTu?1f8jJZ*H?5VS2QRa z8t>VC9|KS440js*R|s3=GB|Zo2Mr!H+x7~ z$n6U3Zw;2ydq|Pp3}iYNBt<)>+g&iozjP=I5vB@;m?{`z0r^uz(fsJ@6^&0lDOxw1 z_8;hE?nQ))UB))Gjh)P?-@@4Odzluj4gK1gdhf7yylzJI@IfO5$h5i*Y&x372vZ#m zG1bu!3s|q=s%XE}SU|cLMPnOKeE-#s=4wPc*;N$Ij^^7GMcaECm&Hxlo1O+~;u0kY zZ(K{AO*NQQohGL0G_ip74z7y!dyNI;P@|$9v1tuEQ$E6t^bTCaM5nJ=Bx}dX0G+cB zG574WuYn)yvZawBJkBwBNq9OF-3QLL;oNTG*@~&R$3mYT9=X_KvN$zShnwWowVG49 zZOOE7Vuv4csvHI+=^s|&R#jhOs`?TOSR5S{ja|5+IqkLv)bD1uYa!|0-E!LP__o;% zlRot#&~Iltv%8fy8WU-JIEyC>)y%FfcEi{pc3X`+D7z6;b|a?jrf9UAqD6M{7^~Gg zB@#+{{lMc;V)e%E{AoPv{rUmN5a+CZ-N8lYtbXnE{U?A|!@GANC_|o;;ZJIt8O;}C z+F-@5(F$nqKp>)J^-EE`Yn2gIQ_ca|IHrl!k8>H5zrHXd(|Hyk(+Yku>&3v8S&1pL z5>sYXG@4b>&~rANol?_(cGJ3)riv^p(rM_Fq?)55FCPGlb+G*vzJkV1_^-1e`ADZn zU)lMGl+@=Mad&n~?VF|Zck`d8Q{bbOxPoHZapTeH+%r0}<7{}GGrFTd%rgNRGTiJY zvGmr#yBh)HB-?QKE^RA4`vXCq;xjEu^{brkIr@)iN0E=XjAQ&PDb~0?ns_=&hH2^r zm=1`&pfJ;SCSV%irSKi(LsM$}v?PrMtn;ux0avk|*W#(O1m^82ZYs=5 ztGJy+Oabe%QuY>RNlzsO8CjLado-5jjbC7Lm>e0KGOPJj{J)h}(Reh4=FV@}lg?92 z@=@euIY6`-cgb>OJpwFR$fgQ{C{s^n$~YEMFKjSyrq4o}4}YfBK0}AcyiYjZH(PR? zyz0G{eAQ@mWnJ74xMZ=JFrF*m-G5V_3mS|rJGPHvjjEmFl*2k3m%?{uB*n0^WuYvF zWE_C?xSz+0;5hTZ3D9`W9376`Jt5P=QxN#sBM9s$72q<^I>;X|O~6vE5U#`mvW3c= zrOKF0OzjR+B31riAr=q|C|PbFDA}%vO7Wenv4F*Aq7{w*G%MN2q{9t6(_}Emjzmh+ z$Rm;QpXKe7dh-~x$$2KEPp$MaWo~~Z?lR>~K^(!8_5?(c&@qgS zgn3GqV^AE^k|pi;0Lul#8Uw#Lru_VS@$Eowr8N+~=f>3}G9m@#{wEb2857How)5fSS=u zo}Wa#D$m4Jo{8~L*j_+=v|$gBWGN(0yRt~v?kIz3=pH3kgI?$=P|9$WWTuB>X|0|8 zY^xjr!zm!_l**HYa^HqB<%@frqa_Pci*;aY|gJ4Xh!l+MSY-tJu z;&J3-n^7GQ+YA>8%4Ns-P@jZ6k86~T=AomiSK*@}q{@biO5 zXrWrI8Vv^J>}nMEpFc-6iyPjCYPSM$xvSlu5x1&##8kB-mbls-Lg@Feb{~rtR?klb z!$n+7wTqk4xW(zLhHUxCTAc<*gv7qPZPievj@3}5?msaNuZ6adt0pl2Ogg9Ge@irC ze7^xhTIRo?UzIX3Rm#KyT*Wm_PB{SF!XHz+I{@;pljy)v$RO>QOs8WX%5jl~WrI4} z83gWi6>SSD$OZ@0RRwiv2S5&0bWtJ$eogy~;c1X0ENf1*r z31VWF$msvxH0&BAW{S%&&S_X1N8E2aEpwQJbNIGR%R(>^eyAeKVc{O8F;hTP#w4bU zNh~0bQz_d2(|qb53`JwxRD6!QxHmZna^$7??0KOU^#iIhaUe|Xzs0Yg@%9j$_461i zb2xYXT#K;Lu4150>L6@mG4NEdr#o)7LP9?~n|yfV7$?n5**==s4d!NgP6A8?JQ*+p z@DxB6!_nYZ#Xw9I12J_lT+#MxK6QxE=ac4-9edjOQuwHKvv6k|TPU5$39V=DIVHXd zew@pCMn+QFw$`mb-tIA=#3h$FEjrQGz1yNpkK3Zy)eci{e?X2K0|1#`KC3{B9wQc= zqcPQalBSMb5KEPLj-ufih4fjG6-nyPk>_6j`|JqL8mYfWUS9ua&Us${yZ^1ozD9Mx zx>TJ9VDZM9z5*2E25H1;dX5{s=W64uIN_$CIwK5~L!49Ixp99rLfwD6Fiyq+vskCJ zt?1+tHU4Yjp5=3Ds@%6II|#7&LP}7sOcRTbd1kuk2BVmm&LM!O0S*Ps1sn!Qp5cHj zMxFyuoBG7mrarNNm5HmO@v3OD4$q2Rhi5^H6&XD-mO7Et_^Wd!!|B}Pr71SUS-zNI!CN?{Qdss->3B-PJudLRC!(gam+$UY#x$nGl+?_MO*bCJ zz;sUlWWNTpg_#G;dZc(x0>A3Fh^c;ySipK0T#EL-#sbzsoA$9y<3BQrkHd+QofXNA zjQ-y!M#Nw-dxY_d(X_r#5PmPb`#>N~L|K~P;u2hxi*q0_<~bvtNQ)tOnwq0Dp^|&E zjt7t0RGQN2f;vG2OzUBIrZ*Fw4zm*}wjLm=Vk4%Cjab0?Be)ce>j_0;MNzabY#I+x zD;lee;&W~CPM@_M?3VgZE#2{-8qUy5e)HaKoS&l3vS~`={Pf28nT_+a8t3OUO%64d zWOb2I?((gighrmhA8qOOA8qr@KW+SvBN=NXwV#?Sl~=9(*z@E_DF0CGE7&Yxi6_f- z2u+7Kj*a^aY$b4rA-zIF6aFjYuFutEU78eq4zK ztYNq+*^tHp@>h@ItF!rJ2RU74s%i)Mv&i_vasRLT728!OWIRTmL(xRn=zF0Kwv=fvFv8 z^PL^Tht+@V_tIl(wrG1ESCu_Z0!&7!v>-;6FuN~>!a^Iq0iTT4s9vn5_EpE*shT8M zCPIsCrHqcw*d!!(>Z0<){esy1Fx2pmRIGB1w{3-pq;w5`$idG+PHl6s1(;07^0%g+ z>X_en`lm}SnSMMQ<pO<{q5bMlY&ekAuqz4AoirRtsy&pqBk#41cyMvo{K&4|ogVdddbD5fXX<-&db9v& zjSu*7z}o?D2Rs1W-|5lu{@y!x9yz69pU)x8bZ|$h(2v|dqh zG1d;;w}bDd={vR2c4_1AAtSZtMocXmi3O~OA)#oGX^b0ActG&iRHffqfknmuK9&M_ zJVurDCY%8X@T3LLkmup;7kFv~WE>B0QDc?VKk-<*kQF97Yvu|hAX)b5SUQ=Ujmw*a zlC5dL6pi)NUE^8mbS!l`77P?v*RQPAFbvnB#U$A zk&b)26)_Ium={i8nI8@tbYpZy;6STd2{F}5hy`TwsAwHKT!A~|u)`^i)sc=>j)M&EJHVU$CujK45~}#V%kD4ZWE|K8w~k+Rx;E_oaslF6*_)mFI>Zp?(0$Ov49GMchKH>sZ2)p~o7L-T5Y_H3F}1r(OzrL} z8h3UTt!Zlh^a$SH6d9G)dsND-NR8gE5A56@z>fWIIIr9J_cUzRcfw-zaLw^!dLNDy zK9STr>50b~Tkn@&-#_$l?MJ>Lk>?KJ-qO^_Gp`@;Cp}R*e;)o#q19pwbpu(otJKh0 zXe=n+)6aK>^EvVpb)h0rGG8N$k!LtwV=q$FQy^GuxS5}EDt$G)yN_U+D7z5;>$VlT z`YRUiX7CJZv{Tf%N(ej_bJFFt_)LVJY0LU#K~&CSnpo&Z!Ozfi^N-B{%L+69 z`G9=^Q9)$ue<)x-+@rS%j|Ie*U3e_*N_iX4d)S;}7fUO(8dqf_L?hP~}~9y|)~nYaY6mnc%4>v!|+ zjHkj7ojtulj7F<9u3OVMzfRfiHNKx{*SR#_uDQD-qgV9a8*13^kCbd$AW=p>7QTiZ z?IK6kH~WyZ`pkxZ1?oFBJWA8~Aepyg-rU{mzh=Ku;~Nv%vIF#SL*J=cJmz3U_1>v;z7)+~<0djl98x}!TQ+S*ogCY6q`B_Y=FMCA4v@%Zp*3&V!n?-J zoA{xWM#b2$w_Rk`ipG)~79j0Rxz29m=oKoPj(kfjy0%D;QC-jmbT2a#SQdPy{1eNX zkZk<~SN0ak)}6Q>BiMbob{6b$TsgB%meXfQ8nE`T!ll46tr5W3>XNNOU~B`Kvi4A+ z>_}B?zXX;de2?3F$?a5MlWd&?OvyF?QxeF%%&YDIG>+d9Al*0)a_w>7CYzuQbR*{%cprfvPD`e@8K z(px&SD-9Q_lymi#T&Us|D$VRI)n{k$K^Wa(ehP`ZVRz%0Cia)?|8CLr@#ycE&MAPL zFrY7#H-=%WSe|=AzbY?8+6uTB;iyUBrGRq)HvyglcqL#7;C8@s0q+4U1^gLc8Q}i_ zE(ClUuoCcVz(s&ZAq{9W;m&~P0rJmQ=nnHQ6xcmH2(SilEFczJ;WdD(0B-|idhP(k zyfFL=K+LVfy8y9t4ZjSC&LNDqP*`F7-UB56{{y@f@Xvq^fPVqp0Qf23M!&kh0A33?7VtX2DS+1l&H}_A3*otd zKLV@({4wBSK(xXz>j=}A2D{vhIMusKh^cp#5DQo{a8Vadm-wbuSN`GN`hmQ zea09ZBSrL{fDxv%3Z>x7Qjs-$0aoH7TBf5ro03+>u5mNa6}Sr#2e)ocFvcBIJ8hCL~}i@>fr|M9?72afJQcl780 zH0^F+m%?YtJ4n)iC0qXw*Hpni#5Ew;AzYP~si;w7ahEBt1yZsL&^Sa)ti};pUY~+#O;Qb?RrhdF4_UgwKc*?i?D> z{E?&d3;^4iG_Qng8;6F8%a<*ls73~7YFZo_x?p6$i?f>R5wUrJZ}c5$AaZ!v0gD^Q zba8kX0ROP2-)321#)vLm9$dZ`@HE`t4@kbB1C9Xv1z;iIF9D|kJ_I-$@L|Amz()Wp z0kPB$qpRlobi)mRPXJyHh#?|;1>kQ0w*l@1ybthcK*(Cp0PX_Z2lz7Jvw*(^d=BvU zfY?M1{}J#7zz+al1pEvTykYiJuK;!cd>xQm1aAOxczF{r1PEQ>m4NR8HUPc{cm*Kp zYxn`c{eVva{sC|wAmR$Y0f@N5ZvlP?$l>KLfcpUt0Db`Y5#Zkd{|a~*@F3t3K-Bs0 zKLP&+=xc|!Jp(2IehhdDAj&4(8xZ9Y9su|cKn^d+Q@9ZDOF-72BY0_Hb4Z)7hRiyczA++;tz`JRo|9Zu#iwo$8j6O`N^> zTf?)>kt0t)y*2m&zEHB$h8uwQ{(9&?J8gUbn74B@>!4G=78OJPRd-BjqsXeEYyP>I zdGDTXdgLQtzJFr#m+vouE-o7O`bFxz_K}w&ZwtEfPwi88>*+C80Vh1L0i0vi`{3*~ z6g#lpkxd*L8;+!NB)Eb2MI8q}z*l0{CpT_o>Xl&{HgVKUSFgwO?=>UMQ=~RSd83$* zqbrBry~2GJ=)NssTr;*X0g(+)Z6;WjiIA6z7^VV?Nh^8({)=m z2O$(_s`B}FH=c<{`PYB79cosEnzl+v^K=YYAlL(zjwX(RkVAg;z6ex9uJJlaR%s&^ z9k^At&IHyGUTu1zq=Dt&nkLxUxT=1;2v|U9<8f8}b`!8m;WMrKaOLzr)8Ya`$?gWG z_+GL@(H?ZK&Q^9B?lP_CfsGX`3D?iz?|?UsUqW^|=OO@tR%chZ`{jBaUE%JR>!rmB zH$6S`@iilHILbSFdJL@Cg^%s&ndbJO^Mh(_?CJSpJ+*P-*)>ULgtl|71EPODInv4a z(Sums;W@dc`vyG*)6~vqg}Vaclv21CU=rX!KrHg4Cr<{PjC=H&VNBL7OxD9I08;_k zx{n5A`Sb_83vdA7-GG?Phta$9Xl!^dAmRAl#Apd!Q>3~cp z%YpH;Jnsar>M@C_9+Q}QDWIYi;$G3F&zijiLU>)n0RczYXrU(Z3K#z=>;K3uq3OCC z_=d^GEqt|ZBoJzv>uc<~VMl!-+AZia*=!->Y__ecsPZ+QxnW1$o^#oD!OgY{AZ-_L z{ycf^8yK1^8>nh%#lXhG$DcIaj1Z?|Q(}{5jYf{SMu~B3N=HekT5sPN6AIHKJVj5F zpvwLff?;EL2k8tfi`~a?6QE%y&a@os=`ilxZ---=nMSOe+WH>_-t;oMx@>VRo>c$# zZHbek1@Oi(el{ged}nClU{odMcPJodc-R#Qb5d9UI0SGcAoGiA6uuO23?SBv7S^+2 z=3^WnOYUA6T~$S5swxswRZ-Dc6%{S^03?=wv$sQsJ^`6&PC(|pJGdmPPp1uMpvvQv zdCt(UJ8j^83r3+OEak?DS^W=C4)rteSVyZv_#;1qmxU0VZnpDK^Zpd+fYnZ~#!X=` zN2VlES)+_@)AWmHIz77Sa)cG@Tdd5ort0m$rgiyEQ}iQ5FYoOT1e-*Pcb@c#yo8gN z-Q+f3PF~h`ZJfWLaehVP{3VU^s~hL9Xq;~^LI%qQ-$f^0k}`N}7+O|k=&8ZpO&q#Y zKx%lgS#fpRjM`Bkiuj@lPOIHrXO#UL1rOW!_ zPK8`@)r%<9uvt!?@kDvWioUkoj>_h5GvPmaXMkjP=1Kl04M_VUhCFl3tJ zuUz!ub=12uu_#in_ehqV!p*o#mJ=e6BAQHj^+^qAnes}IM}&3@?jIKHZeVL9^dVe3 z3T+3lONGYi{3yXb!IeW!rhEaFwLMdg^s@`jl>HAy+k|^gZZqYoXs_X3@qGY{`y`px zsi@ExK7b9fu|i-E32nMfW537gMg_cas}P!o8%~Sp*hlsRg$PBretrhu1kvc!=g{azXVo5eWRqKf17YkaLP z|JF>`Br=jljf{T4XpHTpiN6?y$Lokj<(fSkl%2sj<^B0wzltcwAc0j>jF0T>2kOI{DivFcL5ZGc!5%Yu9Z;2zwg4Tkpt zUIxex_Hw{?0j~gL8X|yfQ%!)FLRxr-c9<>yDnL&At_8$Y%)%5dJRI;wK#p<9PZ;AO zTX2}$K|cYU1Gp7%A>ekvYQWn8@&0G)4nX9|`Y9md=6-jWd4CWPveqvF!NWE$3wiWS z;m2_QE5IiJfrs}3{u=PNfKLLx4Y(Wd4}g0B{|?CXrog`Y0J{P{3z!YabdLah4sage zT0quCEM{bE|2bqk$bo&th_O8kn-B{~KZw+U))`k~0qX@^DUoWuqOpL*g^7~oG*-#( z0H*l%Xe?kgO>({$>TqQIAlkMcug4uy%`*I82icL^2v@Y9__XvbW-C zME@-Bu2N^IH{&ju4x88PHuiz244j0~4)|@<#N%+^DQbzViIa2l@c)eCHFf1>b>&O4MzCZ5ubU;S-~XYs zCEE}^c3ouBMc$v;1_^KEFh;^8Ja44G{ge@UX6sN z%2OtaZxLwhZ&I!EG=>9mz;+3ZgCH@SJw*$}@C82Ze-H~;R{~@Im1a!CNR~&z zP=LTHK%>c$*=A8gg%d}ixpFE^_IN&y!hYt07bvRQGQ?D zQRd@6Nzu2!Z$R{!atz~lg2fwWPL|l!<_%FURPeJmbGpU}cfJ{(lf3z^eM{=3juYWK z+WooJQh&anw!EymtR`4diMM}NEn5tvwyvhW9Os(7hnkrW<$`EpuF17N|IIe@4sxxI z#}iY>gW#N#?$h8a_`xyGRd;6Ae1FIF3;^M1{=rt(~$uD>?Q0N%PDEk&_mX)D5wYJ+|jf^Xp3A+&lJ>FYeni`}$vB%Q?r=Ati$@=s$1(t{1?U)SzmY z)mE0QDj%Gay`o~F^^Z?K36xdqkA{lYVLQLcRC%gNJEYJ`)LCu5Y8(x2Oz(p!+K${UMI z2Ze(1^R13|%J%po-rlp{7JyRLE#>l7X9nBQlHh5iTMovW!tbE9^=*AL3j?~YBb}h9Pa2AD}a%K zn&}!eh3z#qF3vXmzH4x0Ti2cW z)d!!qy7E?UT&cp-4Gbo(fQ|hHVRQkHX0|uKkFs>nKl#xruVzjg{64PmjOH{OOJ;)L z(ma|wg6j9FT87QK^@s330&VInWp2&+eRuE*PlpMyLgdh*qPVTW8tV6%mB^QuEgqrl z;?#`h2%a>DHPUU(({-BDJ!xjm@%uP$B+HcW6|=pXQKi7+v~y=$GsiEw&K}K~p!$8) z5(>?K$wH>d>`XJ)naCH&#s---#x*-#rbjdTKEJOXSF&7g{bG?1wdO33 z=AI(O{uYAP)4Ag?g<}StZRd31`3zUnc6!>_dab#qXa+aj^!XCg7SlE{=YF zpEIsrc3dxN&Asfnj$>017j%svXM(DFbq42ucnb>LoiFx9eqRz2WAcSJ{*xVUg4TSd zCl`GX>i3G&w*KpFN62xhl-$zSQ+o3;vc~>+&6_8>b5gtHnuxmYvl3go`Bm|Q= z=rNj0X4QvqnhVJie)N1qVFQD zSy7zjHB|JN^15<+RgpLE!-U6KUPJA?Z_}EGM)NK)s>2q3smeZ39=LPQXcqdALV222@D3+_Qy*XAiINba?rYLag6u%_BUT3&5e~^GtL6`TR)Xd5~9l zx&m9XUsvb?rMV`$a2f?Zzb_M4lZxoB%}J1ACqN#|%tb1z1~;;=ucTBzK$^h@=(q}n z=3Ju{f#UaZCcs>DJ^kAKQK`vViabhFm8O8;ihVRFs>M;y#T`yV)=lgeX({r=rg@A= zalK%8qu8}tiafDWV?~NH97-)X=9?#?Quk^p^2ADwi;)_$>K#;Y6YFzYiad~t7KQw~ z;`ebT$$Slc{?Nv#)CXE>ypnR1#RO2I*4S#@`$AOepIVAMu_>G=QY>@ErJPA&fK?cd zJc@Rrrl_&N*-j^cr?r~N)uihEOwF8R*S4No^CT;1rx5ILQ{WTT%wkBfW|Aj1U&XeR z$&JYa{_@pvktf#jQ$>p7HLY>tr-v?%N^RFtf|eprtkiUoieC@^ zp{2+ZD>Xx;;@88jR0c;LNICWaW`fe%*fdLcoPFI)yL85D%`;W$I5f`|Db8|fvF_yy zo?+avGsZc>v!7RZy4kkog$y(^JCszl-QctTIlB4n%~r#=h?aNaU(%o&{Y;Pj{CS~r^Oz=;2d<2Zi~%F zh*~9?xX!iXIzekb*OQAYHDny=1z=xVR#1;WF5g3(-RW8<{uQjg{`k>ZSt?%jK@ z{@km1AwvAVVbE*}u*}wcf!18+(OfQ4M)RW3yxYB+D}<+yLvy*U`Da>lxkq!QNY&xW z;dFk_Po7qGajs<+3C~r~%vlUwrLFl*t+_I)SMJcpo>-}sF;f4Zy?23+syO?{&t{jfZX%mt)F`McMnxkS2qF-a%?*e` z2ni6>NVp`CKnO9}aIvV13z+4&h>CbEYQ?v;)p{-94HJ-?SHM=Omx|U}6t&(3Y|a1s zotd+Ha&|Wa+qb@-&;K{c>@(+?XPz_j%*->-nKLtI=z&z#n}F8Rj^?lY&Su9{G`J!; zoN;F=9wv-(<*QVr>6ogiL#l7@P55;rRfS4L8l*DS7kiDo7wfBd#95(8s;g8g(saC6 zvq)vsS4RtEl}bgLj;ZE}RMbYimvlzCeydWEremu4z(l0c(Xwh)sYuf?6{-iR(gYq$ zw8jkhBPpbNPo*LaQkllMg}~Tt)IxNRPOklhOl8(2S0Se3jN-zuCh0?E54R9Hp(AH7 zLMo%|v7bQ}37U8COFFt=h>-V!3%o-l0vIc27%t#U?Ml7kJLAc|(Rsc`(2RlD4UK(u z_#OjPp05_1L8x7+FbqqX-P!?Tme{qRvD=hDwY)#~f&IxeW{LR)&0hQ(<+?T;x?gd= zHmY2UMJg&;WLx{g+F{=2HGawYAM;9nAIj)xMRC4Sq~h*T4h0|W z+qpTK^GZRJjtVk3-xv-(s5svk#TkYj^2}XKY;>1@+yK)L#qQ9*ZWc6CO?kd4%z3xs zd{Y!>49wts7k}ZO`sg%IH0M=<=3d;;$n!1XP`l!MOBCl@MJg`EJr1GU%90^eYo1pN zn#t%UY^QX$hB^03H838uQqk&EFSrd6b{ncq^smKR{+<;{^&6GyHspsT!aN*zJmux3ajnsYqu@HFC}{MihC}Or1}$5 zWdJK^0C8UK@p2tx1hW^I(H&^2(gmqXWwvd8iHOJ>-pvpHtx;+{(toT{kp^wdWD%_q zsrum820#0jMhIE99_0B1px{W;aeTiA7`yFcfrlM+)4e81!@S9DAu%>(dw&&Xg0_c&5i%2Qj$RM!tMho_k?2Aad+2%Pg0 zPJ!@1ZN!MI{Ei1QkIyaiPQFwdA&y^L=)>aJqI$U^O`HW^7>=u(J7e}hb8K#Ip@_|& z+psW?v0n41rbOz>;-VsK85uFMuDNMud980|{>*C9g;%`^s>!@Z2^PYM+nYXjC}RuB z0r}?A-9}@3L+ld}OHAi~4;aYZDo9uq{*aqdR(@dzdoQr^thuqesgvcvNFXw2Dx&&$ zRLuKdBuh*71$d>?CB}`7+|GL#(vsYwEEa~GyFgBP#{T$O{M|xgL3m!FsICzMMr5Fw zU<*)*uhAQO2a%{7)pEp|CvO+i2!W2sibsv6VeCbcw}`t{Nz`uKoJR4H4Y~8IS`*32 zZ^UY?Y8KC^`$?ug;uW776In%TXP)vUy@>|RNX4O6ROt@SZgR(x7uAR5BCA(jcDzrg ziLl#s(zLqf!;qb`(Q*6VZ|Ii8?!a9nGe;F;^rMB z`0=Ckwe>Y~V}6w$6tWDyY18YfW0OFGipCYYTG;xa!#XNH(S4BrXsmHR<_e2t#T}!l zB0}pJC8gF;L>(z)wN%gSQ0Q1B)>22)Sc~0}!e|s$rLIbT_)Z`Rv%=dE#UK#TJtHd5 zw?+-l^Fq{>rGw%{WX1S2DW(sQ=6v76hU!YT0yXO7Up^n z8y_B(Btwy_Fiz&DG&?eO8Mh6S3_+u8!1#qV)pcT+Gj?po*8E;$@H2}n4yjT0hzJiu z*g>RmXv0N1Og@c*c8M&8yyM)SY_p;a6xF=C+zz9)o2C69o|EVj9LT$>Qw43u8w(!l zOLtviBb2$Y@bG!HE+mlJzk@>SikSpe)&(O?sX}8gjdzrFv%n>9 zZW*VU2;I>&4oVey#qcpx4l_{Hhs~vRxamrQj(Yg;DTD&-k{rUNU=sA>PClSx^x*h> zRo^`vL8RAql``LJ)r14Gt%^2IjmkVJ@)&&1S9~nbMKYNXNXG}JuoOC?jiSfGn#vn1 zdQf~Rbfv+1O&@t-<~km#-^r5&P5#`xiIt-!78USFfRfzFuwN^SiV7+_?Y*`VH1)OlP&a;SGlGcRP9-mxU%(ej)YCOJJ?D&q)qKGs6m@(V=tyd>Q$9cEY0`e&&t%KXV2!9sBc2z%qcb0d}HS|Cf%5pi+p; zJ^WmG@HH-+&UtG!sq=GXLv)Cyg>!zc!znob6{VE^`)xu!f5hB9uWW8kGejoKOgrXf z{HRW?A6U1-pc#?vy(AaYq_lO7hxg7)D-2TgFx&~HVY{9?V9=m}o`@STaM0kaAp?dC z8WO=VG$1Q$@ZiB7&!7QA@JlzhRyRd9TB>eW*6`cKDs7ba)3@tY~;mN4cN^&Mhb$nLBaJgfT^V z!}>JiyN>W`q}rzDX?315UvpLMT+h({SrwD=E2h`hSInsEU%jAO zn=z+K>o;zor{B2g{HcZa!7udm8#TexugF@m{E`w+zk>3j;%rbC6c-fcO&oyL4j1%)N0h55M?3K3N}c|vJ!{)EbL#bYiZC8G07FDaQYju(^i zhh$YwEE!drTTpmG)`G0_2V@}+BR%~_7I^v~lPsv8^UHa1o_%x&}y!*MZl z8X%OSvBN3~CYKdlTsd}HW7bd^t|-D>eREYcqWc_aHPp(aeSS*XX}-ESH8U#AEG~}U z3Xtihit^g}s=4!!hn7F1p+V!R2=OW- zd~AZ~SN+g~Ptdxjw&L}@N1KgD*1Xy)#0xC+rY0OBBctphO5*Vbxe1GEWJJ0tf(d#8 ze_cKlg`bDQ%pNhcN;#TAv3 zq`FZM@u8}AS{+`LHEM&jE+*nzrP%|u zGjX{BIZ(O7R4{WF4Lmn<52XCL z_|b

$UX%I!UY&l!8)o#)rqe|1eww|+hEz4TlRHpoDV?SY|xc=%rzP44}~_?uim zJjgFLjS~1#zq;+Yp>-#G^y0=Fl1_Q_(p^|^E%4uEk4@S%B=za;XRbZE=&8Ynwk;#V>C&z z-B>dHxkp>?nes||%9`$($6YB7$=4o2oHlz{g*f~Pin2y1$~j@Z+f+5XsbapVi%c`R zNCm&_TUA}te`Zt@M$?uJe+E*vm|2iZ>(!gQQ)f;VMNo!^J=(qfWS7%_G6t6-iStC}KX z)x5BVtAOBQ*MX8~!;H>kges{+&VTC7XEge7a~3RPLYAk0*4fRLG^B41Rz(gQ7GHZ>KL^bMOXmUL z2~;|6)KeZy#}lZ&0(!Kh5Wmb5SIs5D4;L7*8Qsr(!pid#p9;u2!iq`pO?1?uIR6`~ z2>rB!X_v|mQ8FYyM9Gl+5T(RXzf0Uxh>3g{o$Vn}+?}yqJA#RIMaMi+)?7wCLvtgW z5l2Ivj&MzH5#)~=j;2;Ete*zu=`oFG9-L0=IWzv)cV_f?UtzW)5I%CxW5VJ9`P+HEp-Ctx}E;eDFwP^x{Z9V%cqckYk80auCuf5&?|I;H)0%m{YlJfQ{<% zZfBN9bH?rm(Covn!8vje(nY}1@gOAT8z&R<2f0wCFg@@=FyOP)3$lR2If>_y#p*Ao$AU@Pyf%4~cE= zc?WoNwaWM`IvSXml^ATEfH>T&#NhMK8=8$rVmT}EOED|q+bs_vrhH?~O5DxfX?8JY zB^IH_z5==;7>RVOLN8|}Ogr$2_rPDNXn0L0p5{%vk%&7L{wB~pu4vgDV$CA-M#QtA z*^|XoviXH)B_vAx_Q$VlfC+(MEPmW8Gz4@@21;5s=UDts0)CyMk(9Cdai8w%p!<7v z=lm$*69yTaB#f264-qv0bjO}2Y2xLNL&YdXBPnC&k6m^G=!Vl4fQ!eEin(6V2txeC z%indNt2tj%#pB2P-L7alKQy;JbpgJ9X~>lgnwe??*`;g2i@_xk}Mv-(-B<+ntDZtWHIySLBs;k z+@9AtzuAa>5j5xJOS*(O{MLeB5okUu=$zjth(4tdvf&5}7cYOeBjOm){BD$_i&x%D zk)d}LjiiiS-l?EFA0zB-V>;)z0ns}^vv{nei&x&g$ltA?X&%=(zbg>^YtZy4k#zCO z%YFFips5?*IX^b1HK2J%(Z%COefkk-4wZJ!ZziJ8DZ@hsJYBrEP{ zHz4{~py@wJ(#7NV4fy4OX7J?B`SnHgOhqFpW7jYH?@G`;c}eH|dLsHG&>T>7NEWky zdZrttF;hF|NBLc&Xe4F)`p`i)f10F< zC%+RA{h*@hjNdni+yuIH(>v#PGNSh>n$Gy~p)_#@US(8u&d-DB5=GM)KMnjEK-W;+ zIX{j^zfv@v@nd^_6m)mjbk2|c<5fk|89(Zmy`cMs3Jxw_eK-(z29=D-#p)k>5q~!5 zT(y!g9zPa!xT2AivD?dVAsbMpDM+$NsS!bX(_k&hI_Q z`2c9%yi(F70>sK6Kg@DWqo$okg9k2N{x}gn5j4*?N9bblI9w+>|^GS{i6&tBNmb>KEK_FyHe2zLj1(a-`%)T{#AHE@C!*5ue{q4ow^9;xWm(- zSTXs10e+u>=G|)q876yTKW{mKKkZtS8J;d)dEY_Yd7w%4lPZ3BpFmu`A1Cm`)5Xgl z?LXIIoSt``q>EQxH=_3{8c7+uyv+DNK=+S8=ls?q`qU+Ou7#)LePh)}UnnBiQtXBe z3Nr0jfbjFG+C9#gUht0Puu#3(*_G}Yl1)5STo#|9drssVs6b-M1OUUYQN(pht!B>IqDign0a=}Y7Z3$>r z-5@x{?UytUw}R$`kfdWdV)5g1*=e8|x1w`?9H$p68c7+OAIF(HLHGL`B~`q3Pk!Gh zn$GyKyhpFZ`RX@y&hI2d&rmd-@f!qw{0i8UH%qE`?Vj!GBSq60KL_~PZb6$_C8^?- zm;5ePG>79?1G-ta9-iN$il#Guv~ykp-CtLC&X26lx=qtI!qXvH%=W_PyzQWwdWRs3 z+x|WR-OZp`aF?Wu$B!NMI?!CVM$#Px5boy^C4M<~`VMH`{gp(rU&U(APSEwcAG-3_ zk}h6-WF+7;9?;zLprnhJzh^=BAZV%|l63LfOCzFh1Iu59+x!6 zZ>;*r0>4S1TgHJ2E?#}`vF&BhobjX}i<`d|@XG?thCfKUc=eHo=ubd%&brR|4FSKw zpsDA;1Q(CrRM6c^nx_Pr7O#F6AR-MkH#{Thjs}R;p7HTNt;e(YLd0{O^IHpkt)QuD zm2^pQ__2HM2F=ViNr!F_v;FPCeOH2J=4MG3ue={1`cBX+dZBZE1<2o8(CpjVIll_r z_rz`Z%I$VZ$95H~z3c(MouK*6OOlTEM=bfh5B!BMW88m5(y?8|;+F#bQVp8sos#Yt zfG|Ic9g)2Y_B}iul1Y9s?1(zhe5mNChol`LzIHN!Y3aQ1gLX3%aeQxp7Zm?{tM*D7 z=2ZQ^ReS$$)t=82bMd5k$=#8z`1?P;YR}yAk8IW69ngR$sug%xwKsO!f^m&l0%fcR z#4%lRbzZwRHg|I6IJ~P@tMats0p^Q==8Np`#fe(+pzun*WNl(`5!RR%U0N8%ouL(1 zVhL*DsXifvF#5#cRmkvQh-{SI;Xy0bGiYm|{y99lEn^wsO|X0;3PaO+Hc zq5zX2Wz|njW7H3Nc!Db zMK7K61s?VUzM=ZKN0KiY^X&gTHLAXK*D08EnrT7$zB>7_ zvJ~6W`t;C)+TEUO&dB^e@au2(VnK$WuUb*_QTp+1?SFpql>4>?i+;odr@%+AOg;%2 zO0m^cZ2aZQwR?YAt?zg*FR*qPCQ_JDxS1k8Z`eKmnDn>uS1AU#8nQurO&sam zC+!$tarB2D-uB(JHFxi7Tp~XehkQk?SjI$`rVYY_fI92AuRZ@MB zc0OfU*FT$=Idft1+-Bc&9EFC}(y^EChSx7w8=qB;Ln!tifLboYZh&gzisLR3H&V^W zCEKwxVen>#YwN@L{b>uSk7PADi&6DcSCcEzsfEjNE28$WCIA2X3UjtuV`sqOq}ibb z8dVp&RfU^20x{a@Vb-;WQ>&cC;9%}+k!~R~)n)P-bL+YIuFLdI&C_u<)!Z3K@b9m- zk7~3P2JfgCV<$!}%EzVt|FwnsM{uLaD*pl4J|~v>|D@Cdu{G|eq?Vf#2C6Lvk=*=y z{EQt7M_3e@nE``kQ6ic7x7bA$&ES6|?IDtvpPE_;dWf}b9r$6(M}v6>2{(<%T_nI$ zm>ss14B?g%PsSJ#(|^YFvT5_Gt4gb{z{W`8O9Y-oh%1?fLlB$7dr1D?)^{~r;MS6>2;Wf)qHWkVKu zGVRImf5s$;a*+v~VZ+LChHJIh;A-7!W!wm_2p|-0wR#yW)K;rxEh&`*9{A~+vGK}_ zE5jM(f&8%jR=RYFs{u2Pt17sct111Bqtny3u49PFuGvv~^LPX;Bs*p?5 z3o;z~gbZhJymON7OL3HkCZsrmS32~AnFoT45}kUHLoaYTD}xDBHaRusnzFBgH(Y-e zVCB+dt|~_7UM@cHPJO}SW$fw zHWcUjFqzRa#fT*|G7+hlDM+sB#ck9JvYv-6p~!wxDpNGWH;9Tt;4649yy2J^579Pk1_Wym3X*FN8nOB6{*L|e*x9FPS#cnw%YR&^2PTU)_3uJbVLiW)#KZB8=p|L43F(k#rkldUpaWCUq;@D}Iwl>=#q)Z{P zIMOmIBc8O_pf0pX%Sc0QSl?NL8YkO?RUsmoaxvOe57nmZ$Wa3tq^VnajAVe!gH=+6 zN>Y6hCmR$)Qc?`b1|@OZaV>F_RHq^`8b>@4wSZNjMMOp#HmEL$=qI(QSd!{WgTfTK z&{F-7Hz_8Dq?j0z4NBtJpd{|!?su_N)6rm0M={OqtR>~u&Hj&cINYZzBEqW(A)r$5l~!F$*&6x)EO1{Ajn!advA2a9!@&j8sPo}oI1*)n zS*w|i4d#i0ChK$H=`Mz#3C95T1RM+K0mQvT8y$|YG&UHL#s)(!@sdj74&YkiXl$r< zDkVNi&kD-Ah-c9m#CExQ6@?#ww+f#;nYK54V_e}&yY9$^Zy41b z#r+lT<%KsK^FU#nA9%(?sEjWKWO>Q}na>G;%q!mC38CjAEQQXH6gopL?L+)Z+&&eO z4?H1<*WPNUiATP)nls=H*FyyuM`yL`t^#g|r2!jh_*$qbt_&v*%sVozaI_kLDZJu| zs-;qP9(cp?-d2q;S;+?Di_!=TNsYjeOPqfsajm$PIB0`p_qqb7cp`MKo8WR}?!;4J zh7$q{IhMKC`CMm}yVou1;mA4UJ41i=vELwRad3!!AoD4j%E4zJqap!a4@YSDypUr< z<{M;lmflgrR4NTKWm9sv2C9(Ia4arevIL?AV9yI$TFw;;Z;nq9vBK`x3Sz_?3X8qq zL3nE~;5~VdE8%@{Yp|@L4$Dlqv?i(|4Sgpo$D)FaiWDkn9=cmZ2hFX+k{hTY;#eSN zq`rE-z?lrLsX!Z!B&>0&%n1s48ETwC$i`0@T@J`zH3hIg;8Z{ir8sv+^P@*$;z9E> zE#&TJnX3VLd#E_HnA=rIK9UmW(zp?Tp(KqJ%F!%`Tl zam*}87h_a0=50nBG=RJ>D~2K%uJBC|Ec1d&^Rtc213U(BJ|G`Dk$*q)3AG|B01G3O zI%7zxGlpE+9{ft&J1XSTPyu>kxxOePIcJ-1($dyWt72(;vpcv^^wbM0AGL9i360AT zwH6fhg{PG6l>=KD5ok>gF5{lhph3#a%4#e?s2n~r8CQiX!_8I!LweQHQHz?%Qs9fgn8db^H0`|bQAOE!J7XuCeybh4oSrBj-Aj;~$08j_?0xku_IH)ZH zp z-&tCTXeYX86MB!(a9eQM1f*#D*uLR+zy0lRzkk2&6Z`Dl6ZCC?7m_nKJZm23lYZ;U1@CMov0tcLpU*`r6BsU$cP1$6H6VlTemLzEf{K{;YZBU^kVY?9L5+_44l%(}W%aXXjrzz5^E}Mu({1kOq z<^lWA?A zLq(@NjZ-?cnqUeH|FjzSx}G(`k_2#TetZLNt=Vw5z*fguxK;CAFvZgK21m~K?j?|x zw%-+6n*peWiqx!|dwoS#LTCbf@5@4t+wEJQ5zL3CHJKimH9;vYDKUOiHu z?9^vEbZMj2o#J4oW;%m)InEm0n^0p*kfm|2U!+(LzZSOJ^JHk>S~GMA^X_|4iOx5W zxmr38{ZC}F#F6u+dkL#eWl=K2%LK>+?-D8!9elBXurpYZ<#ez2r6er=(GU7-hKJT% z3pQ>0yXWhhzu(igx4ZodyeZl_S=Gs8PWV__qw_PXTe%M z%aOCym&Jg6tp1nGJ(*vJ9P{+YSk16m^(XK64Q>TK>ghJPL?Gl%?3?se4^q7aQ{-KO zOT=ZQU`zWWgOyV*hqg%B%s&4u{91U!iB)sP1t3Q|_7T#$;K!iPa3nC?sogkIF_x`X z(=M{aS0dgxE0Aq}bc}eL(hjwZ&0{k`LX@I{2ybutz=+6aw7;q}!qktR<9|yb=@Cm>>0iOf}FYOP2 zz-f;FZUI~mxEJslK1@Lr~^)*1&!!AJ9_jLH~!qj6ZNxZaU$ffbF634Al5;sw= z%fO4fFZ~;T3mUDtpBxa|_wh=<;rEb=wseQ@I9-@`7zCX`iJWpdY&?BSNM2#^<*@4O z9~i3nzAD#+jc9*XjQkUIcS-OD5iHkVm5jHcMll`UR2#i~>Hia|d zAL&Nv$t$P}wu-2Dqj%BPVGE)&r#GHE*?VADMfD!$$qA1Z)X98_SYSU9!*EmSw8rSk zKvuPM9so=4F$_&SGMJ{QXlEMoKv0C)Thb6V%K1845#{nnz*N9D0Mh~A1Z1z-1K1Z3 z>e`(35zXSdPkm;@g+zYq_@O?nop0tSk zzXxPIdY-tZoOsP5UjZ*ia)#tc&X7y%i)>3Adzr*R4Lc@bHoCExQ6`RmvcXc`|JkeEcc5NE3>hY%p%7X&$h!G#_KK zfz2m8Yb2Cy12BeT9@u<12r(aY`%z7Vp8|65`V8<`z|R5C1Vs1rpAGm0U@joaCz=hK zroRZ+Ujvo{egjCJq-V9)!OJN+hU7CXLvo5v;#eILrwdaoN7Saz6=?k?C=iD6?G4aA~Bu0CDp%f+=Tt zX)9_gU#=*PsxKoA>dP5bUxv9oHA02=e6n_q0-T`m2Ov!b4+8c8JOp?=;E#ap79 zbVho{cUM<-;HNSY&K#epQEr;n2j0s7oDu&iJF+tIzC`GDc(0`e%><5ltcG6@w*_IR z8a}!y#*C;2l!BDfc>pXO-gx(KM^P}H$h8A09cLJo8sHFO)&b0yRR`E?(%?z}WGk}+ zvXwaiPX?3LD81OFWGg<57Ud%5^c~4Pzw}aeTa`Gx#&TaaDlOIlP23;&aH<)G}$T zSzG1}z_BF<;TOhjnPoE@YwKtKZ?#OeRpyzx7c<}CA&afG1>SHXuL*Ju+aiT@qjfQe z$t(YHfT@5d0>WhXdjL-Xq>*o zbG(d|BiSvWv#u5)Px3e&KK^@FKJ>+|Yu;Nr4{mGGLe@19u~m?;L$VAufXowh5Or^c z!uNr+89WV;dCgGLUyQJ{BN&o)1Vi%us>ETG)Fe(%%^B}#?DjDb+VX_FVCrVd>U#Lt zwn0x4nw-@(s6*UPi)J^{q$2K-vEjtw&9uXYiLX@iBPiCl3t{50P4F-nSdQcOMyL=a zM<;gsK?*+@V>*N919k@-0?2j>D@Z&53{%(3fRkfBLvqY#$R!>fB<@jMOPp@Y%yr&j z&rLaIeA;GKItO8+au7t-cXU=!u`656C?gHCw=t%uxbCfS?hNcTt*#RLKo2jn=b}aC zF=dVSoC5Z)2dzvgYbVyCd!n~TlS1#-t6LijLBmm1aW;Hnzcu~4+kTr<4f=_jOY*quQ;HBUgl7eGMzM+!1cW^CnVZpKZKTUAAA?5f^1b5ew2o9T#<)>b| z&>>B-Gi|M=8sDf4Akf++YvAIK#beXWRSEq!$DKumy`Vn)g&r z*~}zs;L|idy>--pRlpdIwvE}b1+&4>vn3RnBN1l2VZlI!YolVs8y3u$h`SbkjHM!Z zPx8MA{>~$*NO4ewRYOq2OXmUL2xY26Hgqxmuw@&L_vbaD!tZR6Pe1eI$Ny1)ivc;_ zUI*v_Tms1aE(J^m{3X16y~dDyy~dDBh)v=g5TL~U+uBtJ>&X@|Qq$2fJNF)m7=MD& zjU`eKZ>}8kLXon`7+QCm64m{{$v(i4>;nwBI5VnA+)fozt98=0;9A?7n_#aArf$u( z$6IZD0?FW5b97eyOMP^aMQlbI+K#`EEjD>DJD0Y)SGCmykDFp|3lHoCpf?4IuANc{1TS3J)3knJ1J-JmvNVWd7hq zkA4_oX=ySfElq}8+Ftxh+=nWJX4#+Zr}aEk8LfZ6Ix2_ zVM%8oh2cC#KtU-ym74z!|1pGC(8kHLNSWxR>EP2vCw7PX;L@ z^5SQnJb=`ZeE^REJPnZfJROiq>2Y}3av72>mm!zdieHI)L4{nJdws6My}l@+ZEs3a zq@|kW*8{X>XYK8=l%$d7Xe3tkxq=%8DT=D~6d9(KF^B_N<#a=ik;Q6>_-jPno^;v|aTp5yb zWk_xYlDNINmbg%ELd>3PNDzd=SzDeTSgQ^+(opAY>9Qo})>oJLy4H1Hh=|Y7fgaq; zaJ;{@wZZZcQfWh+lnO&qDh$b9J%|5@KWN7QjsyoSy^S{wRQR2|S_ zH7AuWX#6ZgjjGbE2+QG%Avt_8rI$!j(9hS`w#TMnVDO zJtAAcx9}P8hT}*>XS5Ehu2_w@5=)~r(x3|+p}4xfcc}|f6HiJWV`xEjnCC8AI z97D3fNgNxT#Qi5Fw+dXX^HD!la{tMe*Ol%%TS@ONltD_5At^nEzRhYM>t1@#M1D}E0_%E9O&K0+TZ3$S|ySP0?rCRhd ztkpEcquLa(4 z?;$qXxB#T`W;)W+ziEkI4q2Ml|NbdPym|fa>oMYu^}pvKt{L|*-+w#!n_uXy#ML;9 z>SLan$F~9h+y&KFTHWNss`#1uvZkz+%_XQs=@xAEIi70mIJQ3U4^( zhl9qkKs>3C_2|6JV*?-`&aVVK9k3B_7$9E6`Ki{y)lVe_If%7;croXH4%hPmcK|K` z{43y9fb27i0BO}+3zz}87|;uN9U!}J0B|DU62N-^mjXTwxD2or@OnVXtp$)Gcn@B_ z>|;p2>|@BKk(;(dM=r$yp$sBgnIr?hq0ewX) ze)(2<1$%!`bnU=ZPR)0=T($=VB<6cJvd`<+I&Ff^ejq3ifoq*w^IxT|&__F#?r1(H zyR|YXdb;GrHBQC?z^I6zP(S;SL2U!hV{stQobf~n01{??i*Rt+R)j+LK#Ne_Q z0mrv2dlf*WL)Nof_4bw}i7%j5y@3PvMPFaQ(moHb={xn;uI`0(%Ylz=Evp1cvtyM0 zTAo+XEZR5A8(PiBg;`puU^lZBsY1&f5Zx@N+;tFmA-!_zvNb4vcNV5U2rh?Dlb~_=gn! z358z=h&VqVxYq!-0p17rN5EeJ{uA(iK(?l}fJXy90O$ey4d6L|zXd!O@OOYi0DliS z8t@T7*5RXolsEIiUd{5!$$Ez5WIaQ2H-W@)H-W^7Zo74{=*WxPq{T2^v{Q~a$040; zYYv3i!ZP3uN8M(2R^y*5DMwrMw~^)~#C1h~=hszFYaBbRDSAU<HlFS8Uo*Dru#gE~o;l+?Nycm)@OC_!q*Ah2gUrgoYUY{~)BkK}7 zE*v#EZ@8D-3liPyEGx&>Ge>s&ey7}}U_XFur&#l|st4cM%f#7l4}I(*!DNK{p3O8( zVAiDF;$ENbUhhqq{dQ8$X7~C6%r@NJmU$q%6`K_9Zmqm5lr|pLMsg^v#Jx^TQrLI8 z*FSj^R~m(u2!N?u_xd+p{{++HUoG7&rpL3U*k9ztMbLH0CZ`r!d^Z&@teI`J#k46z z8uh&d2*d40fOuqCIMz2c1#yI%RoEPF=#NtocZntbuS}@8^+BjSW;|;{YMlE3FSfKN z=85-y75@D$Xq-9IW>@39bgTina-f*w5P3jiI(aLGJn)t#WnQ&hP+L=jl}B=xqpk=; z`iyCH#)diZcr=+@lw%&LeJGbP3Kv2<14_G5wYysZX%nmld zJhS;Zyj*F_kX&iZkW1tEAaT?Z5?983l)~ID4=qSQgR~2y+Pz*YQESIg`+BNg>eTnR z*V||HC~4n~7JFfEBMs{1qinnxK6HOJWnI zcx8()%&~G3tCmT+J<#T9JJ>xFZ)KRU?Gu-K9Sjz5T}`DET=ppLux%MzKDoHpxm#8Z zpdJd3@+OY#p$h|*K}MYX@1eWNuoQ%8!vj< z+8&A#Z!{my#X%=yS!+tFA`^gl;{CS3r;igT{+O3SbU4AB=aCN^CKp6-Qf}d#>2vF% zrsblW?6KgjUdkP>hREZ95+^0AYH8gdg%EF;yzH~_xt@d7pBVc~_Kv*mUtyDUX zCSM$%3fKeJ=(S==?rDHSaD6)9g@9)OUJQ69U?pH*z$(DA0A~XZ0E87R4tays%X44+ z*8}zk^G13seS`tnix1RA$0CC!TRMm!)h8Ivh19qkbRMD?i zdCwM<5&tNWbR(3^4&YLbXbi~_jUhRrNn9(gB`$z1*WH?&8_Korey$wFde!ATLJubx zt{60iJ$49w>D=o|Y_`?BLMTCB!BE==PWy{N5d_lS_CZSI((7p3n{ICl3I>4#Z_hhw zgUze?d04_sKK+G?d+#IPC9TazZNSGzM2uuRK2%&M;@s<6zu(iV_4KdW4_w>Lpt%N# zZiY|OXqHV9AyzNVmI8RgJ)r{03YsgG1`kuyb&Mw`ISjF3mRmZv!IK?-XV)qn?~hb> z#G z4Nic}Gq2t7OW^6y+5LoI=Z6l)2U%o?V@D?)8kOGzcr4)AfX4$~0eAvn9pH(8jew-* z&3gml@l(8azCqz{1cVvre^gyFqd&sS34Mm-gg!$qEe&m1;?h-!@1tR@ID*ctUWX0i z3}wVh&VV-@GfT%fI#zN5Ag{lK|0TTjbs*D_h8bE_fgkDO_gwXrhRC`#s0 z_^Yl=JA&Ez1eGcdbT>c6cvL0`m_JsSxpz~eGQU{Hu6j2^vUf8iU+7ERhlZ!qr&J9FwCX-l1h5N8+Z>%Dcq{5ttMVtsm zSOJZ}DjlI7B2 zjQHcAnAkMfbXLIMpmjr65w5bbdge@QY^bYl%oxFSj9z0Eqqmp?x;NZ@yxxhqqb@4R zooM=;jq%kGueT#U{J{`Jpf)9dT<2GnhDR^d=2eO zI$JnP!-k1GMp`gJ#^GLue3&LhrIaC;HY{}yrp2f&-4RJ-j42+Fjk6g{qM0$xH)H0{ zB$kYU|A+E205(@xE)dkv|3i7pLM6&!Bs{Kga)oMz%Rym#$_1f(t;>dxf!>6Ve<&>9 zO48O?m@i0qa0nNJvGou|LgL5~qk(oFIAWx_q7e&C(CLy=KSe`2=Q6(I<<&l1^%GaL zQO6+x9h+|Wkv`mv5yAGo5}sp~(Z^e$64~aL1C9s00k9fS2c)sdYs86b_6uIKtejfy zE~eF~W0JI~z%k?!XVfw_NsLAexwJ9(m2{jem2@=-QST&)2`7eJ+I;>B+%HtfrPc6&QM;m ze$j{7+l9@v0mTv16?m`}8%8jgW0>bw5vV>4NERA8MlZOiM z6aAhy@6hj=yAJ(6-1CMojdIKvdmfXYqi{E(Cou@T*qw0`AoG1QAbZ%Ekehr2VMrP& z49U0X68DaxgO#TaaKxn5t!*tW1!w|GcKA|tSFmL`!g{GAxYCP2X!P)H{xJy9ZS$9e zLwrv85v?s!Jr{wZA8r`CdddWc_|mK@ zYq*LcSr8`*Mkz;>!B4JttEzz=EVe(c0qhI>eSpP)zXBw$`vH>yITJ0bjv-lf49TTs z61P{;sbjlvT2~L9CQ=YN1*PxX} zz2_%S^57_R+9>=;CqIoC_j`lf&4l@89F1-@;N{)O#Dng^nZc96RT=Ocsc4(iC8ny8 zD*EA^dAb)O!#^6JbbMZ-cn1P0pMMyV&p!;gc$9&NO%fkslellfxC1KmUl#dF+}5h7 z%p!LkM&yQiy6{LO-mPSu@y2%qNM|%K zgNE^js^ZwO3VxDBIq{xMOS>z54t}Jo#PZ*Q%Chp@lHt+ANc7U+3!{1ic}mCLkc39x z3Y~%8Fd%$!jOH6COg3w^Fi%7C_=?B1jzPv`3~v z%ecc@W~As>kqRh~xfH*>OkoBoK(m^ORRPBPPzv}ucLd1 ziL)n5RH8^^=oQn4G^kfn6w8QSu?o~E7vvHa=($Ruxj;&_!jNp|47qq-k0x=is*pNQ zR?zJWx-4VUM%36c zj#}ZyJWPd$bizW$GlpojBY~7cW=IN|Ar}uv(j@K`6_P@hI0{+P{g;JI19hTBRhWf* zMBCJkw0)a4SH+Tjtkyjm`85mvdL{Ua!-8i>3Z5Z3=Ou9;BCW)6sFb*WhH+v-TdsX8 z*AI4i;hQtK;vw)bEqp@<$;Z<`8kgIMBk)pj_FWCWE`#-4i8zEPyKSNVn~iv47s$? z_?5UZD&*1@f9ga9i4z+S>bLQws(XDNb^tXd=r`VrEA9i@idOO&RtP-8H@NnF{%13K zvrVn=}zUW@^9OCso`jQL}DA5Lwg|&^9?rd$v`i+9m zi~9@oT&GxmfF`Jr+iLh4J+Rrq{E3{d*xw7Zp!X)=)lbq++5C+Rg^>N6 zx7EhY2U!`|lJsY5912%Y=+$#o{v`-hWT}XW(-O1e{hr{P5dhS}3(QqFjmg(4n>DY7GbOA(*e8Up|PqYiO1-RQ1 zKOBr4iW?_acE*UetA6f6{HrnI6V%Kudp_T?SeIKe&&=byfbXD-DHq-I)dmu|Z9lv( zN*=4oLL1JoXEe+H{U*jUaTa(q&8}@g zyh$?*fFems{pSzu?N1`h6NRRzh62M{PT)SG@@QxhNgV%dZ~v0l#_kjjKVFp8a4i29 z@TUVYNa6pWG{7@}*}$U{`l+*90WSyK3^)@Inp7+pdkJtQu3rXR4frY`c!;ABp9S27 z>y3cB0owro2)GyU&wzged>fGU^9Eot^6)NTPr$zb(i(mbuoocG_)i6VACP7EDoU?o+&kxBa~AWVO89@*6=NkL2{bk{%Kpv-p zhhCl#M57&-2+Po+@5~f+6D)TuA8qp=Jh`cR!j6{Fw*8K+UfTkkq3pFig(jha;qLF> zsOu9J$%;UjJe!H_`pb7L>HN{gu!;MK~1fvz#qWr-aT4iM(y; z^;u!gc4jHC$sQ^=3;P$!6ZU86yV^c*WbVq@)N3~reP;hGFNdV|KZTNaczO}uy3ykj!S^_)AUgg282gD<@cgh?V~jtO1>;qH&!cEtztPW;hJEf+_78eU@vPa z)LO>c^ij_In&2sd1s6lggIEvbi1zPZS_1iedS?uA(UiVz2e<5vGR@P1wyXM8l2w|R^@7HmZK0Y!emll>y$Ss{vId)t@;TY?v%t4sDB{=HV z$X%d(+4CGO!xn)UcKJ%E8CjiCBQC#DmpD0@ER2Jd>*b)#A$cn5&2TIyhh!S-6BPb? z3^^?O0YH}H2f*_H{{@%>h!;-&JV2WbJ0t+H9>QM%=m4w&Oa!b4><-ufh&M?7`G6R1 z{fhwczDX=&NdauZHIG}n6Yw~|`vEZwi&dL=YbDlpp9uIq@EB(O9|O(=#PF!q0v-aK z1xR!2WI)hr9zYxlrosEO0W$zc0GeL z{zZWKfDZ$rxA`9d90j-m5RX3oR=|q@Uje)ra1S6Jg#3E}#{&Khuo&>~fa3u71Hw%4 zC!pPy0-gw12Iv9AdOd$8AWQ`R1%NOR{G$Oc0lWwh=8V4=2@@5MYxE9a7ZnQ1??aV_%*Kp`|-@4iU(yoIT zQ=~zJF=Ypy(b75Tzy}{tcgMq2=D{ec8rww)%S&v-N`9C(tcFMGr|1|4Dlkl6awvEL za`$6R@Dc|z^@`7>zty(iIqZ@j=6`@wDbtZ zZP&rfgEclRjg~gd`UK=GCD*&_;I0EX+kGdMjGw56HnSDS?BYNQWoceSv%(!-wLC@f zFF@0)ENz!tz40XaUr4)_S*tAOCGy#}}&a3|m!fV%*{1_aKZ1o@EO z4ajTOF|VmFp;uAwdsIm3OX6JGBK$IxBxctnj!$jk(Wk@dH)?W7OoiIF8xK*(<*Z-< z=Jg1!5KkCF#ZB3)dZB-#cs6Q2Np4>fPfE5~+TyJ*pw=d_1#`pUl+7a%poUIEgR$;p zDj=0|jYdF0_Bjj-qQ4<|heL%)!g%w$p{s$j+GFHN9#_J5rB4)BFYv`X7J~g=IuC%Q zUzpnUR7oU$d4INRcHapKkGl0UPj3Qd0PX>#o%CnGJixtx`GC++{)+(dI4{1(^cO&u zgYm5QE5KL2@?c2LyfY+c-X-osMJHcP7h@qnN@yh40_YNvXRVm~5ow*xCQl0C4ER?{@FQJ}IW4t5+wy`*PHGv+2u;-kE0on^TB*;s97ika z_i;O3_g2^8w|X>khbSZg^T-ZM&gT#TH%yb22ZPqnx52{!S%wP$St;!3vQik5mBNsV zGe{yfNo*#Sxcy-q=5<7@JUm6Fbt0XlL#Op$fIGT|O$)eL zqo;^lVe(DYaDR1e)G#a9t8fI&>q>Zz*n{BdGF1hm!u{;E7;(h%De!`|q-o~@vZAjH zS2RPiq8XAe7bT7rC2`-VP?Ff$A#ur|mUJ9lBu>5y8=29uZ)PAhrdGHunKJkm-dv5R zG8)d1533Oz#WmqcjD$1C8&@~`jkAGmJhu2lIK1kO z71&e8q3;?Cc&vSr`C^rk8LCLQTQ&Li2;~r;2)hlC`Mw>HRW%O`s zVPFlv^K}#F8~s<=7FAA}*G+U`ZqF;lJvcB&I_MH$40ovt7@}j%Vj@!GHQ^XbJh#vp zHB0H77Be2|5e^Mmobku7!C$7Q%;c)B>jAB1CiBF5m&5-BR-JM&G`HM5Cl3Z35Y-&y zU6|SfZy8Q$W-?RaC8IPN*%GG08;<#~4z0}?8X1rJ6P4JstJwh<>kA;VCTSd1reY#q?h^2z3DABiUZ@8Kc<-w4c%uUk^@qS~x{!069 z_qs}3&gQEtqgo1iCi07f{A{l#A{i(iMOTF zrk=C|-ULVBheg*+R_%flt7r&v79p@LajQI9$Gxr`?^chpzg3j8=h~h)-NM%&sO})J zzm>D+n$Oj(N;3E8d5$vNYp3yH34@`S-EgmSF2{ym7hY_L=kS)*;wU}58kYIY++4!M zC}Q{JD`?fX+>k{pKKvve6nle5Zxh@gLh%92afjsg;lMu<1N(69hS)LO{C9Qd<)D&n znwAfHN<_!4B@5-IB8JY~dfBRZ%_u%P&>8X6QN}cH0`Qkw;vd4OZA|mh5Sbh!-k9d4 zd4%aP;SByvZ=UA;3$CmSj+tlXk&{tJx{X-wA&%CEDZH(49{jQ=b#)UlH96e@Xk(6| zwenIssILEHx$db-%=pL}jXjErfaSwuiI{?TS>a&}`dQ{7fb5OXI(`~Zw1CG0(gLPV zz7TLWAbO^lzV!lLhwEHGY9eSJv4#VWLw=0h7+*C1U4Wwip8y;UxCIa+qyJ4nEbbPM z<)r@z*LWoIe+PImU>fo`1~3C~EZ`tO6iU2#9S6wzVLECDXc1@`mXaa)n9L9!jqodR zY)cZyiC&4D6~@sjkT{GZiViwS;h=>S?%ptNZ5S6`dlEhaz`cG*=0@(g4`G&TywPpd zJQkMKW4;YB>EX2@@@>o})#X|b;q{N{gPrbmlM}ffV^uc$t?vt5+k!UxetvZCAGYSb zoTk(77K>T*W9(bNJ*7lX&|hlbnX?67q)EqmkaTxQhjiTQ#@TYVUz>vUwC;6tZGlY= z`ztxyuK`DBwPP~3mq62uXF{+{>-0!ssq_4!Y&bCNUgWBVN)KWIo#QcL(1U7a z2ectRm7^a6J*scZ+)^?TH{ES0UuWhDAv-Ki3G8#=gPvIFvaaXyHB??aw+rV0-93<^ zX#N}XSz{X#PFabCW0o6bpxmFsV>1qFtm8<$7I?$0K`a+i7`no2kAbDO!V=HbBZjV` z)pdg^yG$F7|GVub8UoU_!*@abM(_k9Ry`{h$jKpa=1HIH0r6KgS~ zNuw7ztuOq;D>4S*$ex_l?32Ei%alE&xcHutOH7uhhwUWyy3MqdDyIatw==-HqgGDi zes^)OL>kX95amtN{0MO>EMj}Gt_;T~Upj{b!m?&R@q8s`#>_{Q{726xF->V2{f~KJ{@9mj zuiQWc++wsv$}0d!+h7UcsenrX&j4Hom<0%%&_5Uuq?TD#UJ4*b9EpY9T<%hu7=_H{#~72 zw}-6ZPBq^d`ijwjnJXsaS6{|`Y`vCM;5U1B&dx^Xd`Hg5^Ahxr^<~`ZhD9(bfdlRC zB`a{}z=0o|GeX54(F5G;#CaMeq2h+%8bP`y%c%~q%h~TM=0^_G_4d%nbdrc9OIsJ6 zv$WmUt)=^@{k`=`WArJbL&c+894EHpomQ?RC)e4my47d4=B@i(+e8-dLZ!WuLwe>G z+cM@ku$sBW;E9!xoA9|rgxR*z#KiZ9BGiIkmOo8<3?a9`p*cq_yZ8V&I%Hfpj&bHb zL3^0ah&T6%1mNEiv5|P%)5fjyI2SPb1bk&CfhDkMF_1 zSb`tv;`SLF_re|aWewFcqUI&ot|N|Pn`s`|n6+Xf6=!-Fr)+y5r8(6&WgF|Q=Rn4C z`r^8LknwmuvBfZAYj2O-fS<1wGg`+1KCAHAXxEe_ZEkpBa}NcitvwQuwl?dVw)S{H zFChC7ZYTOrA)p`EqX2IJ91V!RC2VB$C1E4q1_<@yzXK2=6RRP?%fA8FOiwv89rHw+ zdmCUG;5&d504ZyNgNe~#05T0!Lv8k_J-<5&t%o=uj~Ue z4TsGfJw=>0gV(kxJiG!+>@dq+R*rWTJnAADM(3D}bMQ1S=n)>IPfFHHlS3nu$MdDe zD_Aj{vK988Ewqu{LXgekZ~$ZS)nIol@scU`EPdO(bP4Xs*YAOi?5pU|EkJu_wMs-ZM~!B9*{r-@G{9|T2Y{9KDG!|~ai{Uu!? zs4Kc53?O`|CH@dPsZGR4x{?_2hUORm9;aF2hq!p7Wd86tD(%#m@v;YhiTFyyTXhBV z%sld`FLD}3{3F1WuD~bux;+U7#A(?E>VBY6A+P3d8{ zq`M2Gye^lQ+TH4UtGb>5-NE=F5EGs8PGyw34o}g4g-GfQ!%@B~alwo~q>#`}V(#El zz>|QZt<8M-0M7!v9B??`6u{Adm4MV|Re*B=YXHgf3P6r)wSW%*qGkJk2UrLADj;p` zHvy4GyuxSt?{UraryyUv-|2u&fUJLBvo7vHSn4l^r2b;a#h3UZHc5L)g5I;;aKtekXg-oIMCH;>Ifhh5{cWo zlSFUEK|jejB}f`G`WkAY@ui{SFM@?13SEO`P%}aA(uI=B+#Kv4Djp(Yq7VInhL*<& zrHP8hF+yoEiR3Xtib#@fK*^EXdN5InmIypnZUC}1_Yfg81ErqkBP7+%?Fc;}VxJ3# zHY4;afuo}N79M>m?A}Mn18;Or>(N3lTjE=wRLn;UVerF18r}fW;bc z7l;bp_pz?K;*E>Cy6d`l@_(MH>YkoHCJ=U4-}m#Y&(u_P)l*MZf2-=-)m7bH=<*y& zSUw3fR?9M%nqm5aqjipm(a^#_6q zss#vq2&W>n9VqqdF34~d6tNh(71c-nM2;BMQ3W1}uK5S1|C>ddX2MFu@cDNJZ zLUD=Zi#yXv0l0U;g@O~`7KWk{-xlVC!ygcS9^8B2UayYtQ^#yajOSV3fc7Ro zp~L&+uxFJoMmry>PL}0j<&z&95ueL>w}a2+aK_@- z^0}P5L|H~a@OKMeI(&Ha4CO0;Z-DTXz()aCKbJ$1$i9d~N_*fID&6}GfdekG%HMa6`aOqQ44TxF)BhfL?_pS2hMJnpd!;VJrrWha;_UlUx~C(y}xO!+qYH5wiwG zKwmMLNpD1@|ZIqXUE}A(nUVyxwWP!)S;djn2w&%rbsn=6r z%B!o97cW*cU2V+K2=#i76tQ@WtKzTdrIe!iEHDrTCeg$kZ7{R5(?r{tIsEl{c)_Ic z6z=-m&K!#vujeED>+*>)e3vpAOpJ}0io@%nx}q7|^wwYO%#8JVI7ZN!dlai$^`_eHP#8&In>;snNAW_+kkrQm%gO)nd>XhTMspL??lhKyF`1f&cvbG*Uq z^$23LMW3Z@^cJZiOQVm#n9JPTU`|%dy=}~tLq~Ex)W(eWF%d?yP%$Ukn5iSYo}&Z` zGmq(O#@eOPPhduXL+9&j__($})7Qq#_U82r60w-m+jzm>?97J=Op=MYzrlRHV(xEa zK3t??3!(YLAMd%+&dfgT^}LIJz08LjzNZxP;Wp+0B9*RJwiQ1*)XvNv>h){_ht52} z@V&2?2iTYgid0AApO7`bKfKn?Oj$u6nwSR~%-n~bW}slEk1u~nsQ$GqJ+Jk#lYz2m1Ov?R4J20US_R+j7YTw|Ah4Y z`M0PF`pmi)O##fiOlNV7!Ms&5A7f)4CQ>cMKN4z#({F*-%FKINucySsJj`JJOfe6$ zF&`&VVJ=TFztVgApX|&WIEG&@jx(5h@j?o7oQ;{I60c_&{+aprLpEGtXC5gqT;P7$dn zf12AjOn$|F797KPJ!burVlZz|%qceJ(IOSKJ&L5gxacA%b!(lb2@Ec@2H$AIcZXsg zEtmn(_=1x(R{5kOIHdWP_jv|t-kR4Kfq5POdR?R&zE2c$y6r5W=)uesJd3-2`{dDf z=5YeE7yml*Si=_^g2FlIUD z8q9xD%(*t^sUj8oGR+xX+tG2Y{c9Rx!nNpBgZWV25Wq~eF;7RR*P}PnD^{f}vNPuk z%r5+^0%Gk%_Z2GU={DvWB2@tYG;^}L+-YZK`}cY#c|y!H4Cb>H^9&nvfk@S#v@p(h z3bPR7^?ZeYy`%+(?*+wNU}G*6se0m{#`#WRHe$RUvj!+Mn7elq39$y{L;aZhV39}_ zxy*9}#$4tigSkL47ulGL_k($^z?l1BvBA7aF&EpIOGK*oJiHHt8THj!_8OcgF!5-N zx|~Z4-)oAw#Kt^dq&gYQOx5r46o)a=0)gR(QfHoT_`K1Ggqd$+UWibyhk66#T2j@r zPwZtrUSQ09aG}9GS}`xQF=Kuo%&+2~CUeE1EA7lDBF5{vTAdehCm75pD&`Yx%%vjL zPW-b^SFdmX!p?k>z$J5Z4(ntu``zmjQJj9k-_{o z#k@!`1E}@p&Al)_OAB9&P_O4+{PQdx^FM=b#9Ymz({h0^kLMQ~d5uuai$z}MzOzK6 z;(avDgttev+Rvf_G2t3}iNU-~F)y((SBg{*;-9kI+%F9U^uT8>b3kB*K}BLvBTS{i ze4}En6wLDT^kO46uI|WQqa79_-qt{fPs|Eoy%HhkAYO)uZ?)s7NrdRBj))bTQkzm; zjS$@^-IBCQ1XSVQ>k;>o@LgQoYeuMqcdJxYM((3~=q#*3nyFzS$*VZ`C8?Jp*6U#| zYzQ;Yy>4cRxg4pI5GpWm@%WQ<~o5f&u`Qk%so}-s1?irYPouMvE@}Sc=R#bj!VzFU&_ba<{Jbi5ryeSGMIWJ zuagvWy^R^l1@ei^j7kND^3j=3F_84Byj= zxyi=dB2uyM(42Qeb)KCW7boN%Wh!%v!90`=9;U^{jLQR3>C8(9eU9{Ohh{mmXN5Db zG??=h^GX}@>iu9oRbV(a*5$m~U_MzfueLG&Mx?p~|468fK7J?$an>@g5tz#X(B=Fa z!*{)6{*8_KG?D5Pq#|?d=zGwWt<0wj43(r(tJ-M>^UsR;G{Fp@R+s>712Qs;@ria4 zLbl;ZhM4=;83^@yILu`a_vKH+O^G%4R)OJ@z`DfFFmkU4GtC)B?pGq@eG$Uk&3Uaw zDDKul?}2ZNXTt=0US|r-Bf#h~Tx=B|9?)e>g9W)%Dt0Z!mj$i-dS4(uWe6%e+CPf(V2( zp7`d>(RSvu1*X8nyun}|t(Z61m^X@4gYi#u(o>VS%RJ1|;8oV^NddE7ryC9ClN9qt z8*@;k;&=}UwdUB0_w8lgBrsf*bFE^YGwniL z^sQySP+)FGus%q+z+hgem@lv~UnEjpihp!E?Jr~a1euljVu5)Zx$7mp$nf2ym@l$1 zQ-gUuA1LOxs&_wTZyU_l>&ZoiI`bul?+e9ziH-R(k*XBsVJ{doXysjY=F0_!pCwY4 z9qhZI=P@7=kuaADX5mvIni2A-E##Z95Oe>!0u)})`}k)I@42ZEB}d`Hbi$Pa6A!(r zP77NL>*Yx}6p=7jh}=1X9gCx#B1G4#nZP`uFd%_hiIDq@5T+W9qiaNnp6YI3*ec2F zl{!I<@r>V=PH@XG#0&Dq%x01L#YP$m19wX0S<3EAcU8UP{@@C znI0DM20~~gM(K?bhVV?h9zVTdCZQjm-^#D6ZpMC@*yL3!%Ujg|x4a>sWiDu}ZVqIx zZpQXp#ttuj|D3G6g?V^hCR4olzo5E#SB_9myo6D4TpfwHN%yb&!mjG2v9mr)4V5lDSf#u>&u(MPa* zoygP~q~|$zSz~qG@(zGP{5(-NoT)98SIYjVf5=~Ss63X54~Gd!jrJQ`H~IZpS$QIs z-NpRilo^9wRW_3p@=L^~2j+^)>y`%i=zXJkM?T0@)~b;ptTZYPJ1WV?>-UEbXXw1c zAA5j_DJ-LiiP*^YD`%d#1c#F|+%7fsc^iMByJ& z=$fjd&aZB4_JfdmM2uH-3TQOzPNV3MGbj#)3m@``7<3E83uUVBKOBKk>|Kg3#oRMf zEFVmAEC9ANov-8ksiQ@?f0+$Z%gWSK$G=GSczpR6EavRZ z`sLLD1pVSW=b}_Ot5!{IEUyhrmwWi8X?}A_c{iZSi{TziT-8!nQ4O8`3+-x)GBh`? zUcw=8bNP~*z%N$}(WRPJ*Zx8!NMd!g)UB+ptNcX;k(pUmoZ_;_sDC_kW!bpq)eV6% zwi&;FY_^|4GKHa)OUKGPG>Rtga(O9HJ3aX` zlZ& zy}kuuA5B{T9S^02G)!9}bug&pt=>EiC$n%34ZjWK5JQZ9W%Rr;ba`6V%~v81Q_Nxl zL0O@}n=bj1)RrtsW79{E9j_&Ywqs$)xKu6E^a=S0dGXAX!af|2^l78VYMJUYz#XK` zG<_MhBWPH);5OT+7l-kYsFBQ69V13cyg77$ib1{NHd?Hn(4K-rB{qKb{kcemHiT}e z4%VkkE^dKcZXtNr=s0v{a(V9Rn@_qZIyc%hQ=vTa@ZhOBWSSmn2&}(Gud_H*9cBz> zV75!l@DYxAg_;O(F~oJzsE~C2+`uU#bT$OOB?qU3$zWCO&L^gHhi^WA%dz zA1341;y;d@~Z2d1}L(BgWDKOTJY?J==RK%5^o zS6}pE01WfRIgZNBo0>JRprjx_J7Y*oOLb*(P4$u?Zoymv`x>?gD=f*HCt<<8(>7XP zi&Gbf(t=abe-~g}TE8;6e#y!BT-~GukB>`0JiUR%(S|##x}veZslKY&H>~(r-|U9w z>e}j4tLv8fs7tDA@GAWWT_z`J6)P*P@8D?_HCjPNsn9j$wZ5qUH$<6D}VE6b}^B`-s4y|swC@DW$(9=9OPHxhIw;Do0&`bL)Ev`(n;jjXG$ zsb5;}8yRS9tZ!@#G}JdXXEZdT4j`2LSsA6d3+Lv}ESpu{m@+~7OY`e0YFa7-h#qpF z)le;y4(UwV^5&Y_s)|xG#Z32BfI>Hw%7)lfx?*f{O4ffQlEe?-Thhx+6 zg^B2dAye_P{H)c;JbP|QF+TbboscYp=G85)t6y1{k4+!?A@rtM0M1?A)EuZaZnUsv zb9BNpj4-aXp*XU?9~Os?#YZQkOw%)T-9a9o1dC3%Hy67TIgAysz8jtJ4S7u(0_XG% z>?&wFDmy$f^X`s+-}`*^alcvp>dsp~{{t35vqX49pzqy1jxTuRmWQU*ZGB}Bp2j&@ zgujy-JoWw|cW%5V_M_oVZ}OuNTrj1%A2!}IeQD}Tn-6;{cJd9soj$bdd3e_2V-dbS zD|W(f<4M;)S(Hr_LF)(uyVtFHUU=~ah}?0x+Sqwr+02>4LT?b^({8-%(Frw&ee&#Mn_>rTKH(L7K1_svn>H)^Ah~ zp7{@r{a(JB9Pc^#+S?xfS9Q&oOA@AkRWrN)Mfm)oz~8w3qf2t${CY^Q*xw(U|J;bL zo;lZEzoKN?)#Gx%e)O3a@3~<%K0$<~dzyuC<30D~rCsoB;ZLV*jk&USRKI4Z z{xd}QsDi(LbMA?mmsNDR^Qr+u9=u)Ct{36w6)kym^VaJYy|6F-+HS-9o+3ZoCSGJ( zo>7WkzZA1UzAB+mYYqL}RJpvVlyeRBD`i(I*Sk{bQd~PK169e(Y)u_qptPdCwzj^m zw03o1RYd>_zP`={D0&jmVhmYYb83A{v&=7L&34DVNe2 zr_mz&7GRx|){^q30OmuQBIm;y6Gup?9#i99S1aVjuPJo#TVbfoQV7nyvUI_*#vuPC zEmc*4#>geDT@BGVKvV@aR5**=kf&->4h%+3R#yga*YX4|%4a96y zV4Lb|sw*|q_XNkAk}`jS2p*xrq1RgJ#q&e0d}arOOz~+8jDUrUV+`aL${1X-N|g`0 zl^S7B8ewGqb$(TWBl2)#9*griBCm(?fo|4rJoR|gCVl2{IL|HoO&hQA+!EtxyqXWf zrx`5%`Nt6RIGtm6r>A)`5Uyq;P1j2~wOCfjTVJ=S%2BCfMyJTz81diXUC+1)DQN=9 zyPiUE*E1M{k3X}xFiv+pxoos%<8aqA9?t`|Sa5!ayBNt zwH&Fz7EijKO9OVbxRx54@!k+QnvjPx}z4c!T!((B(q=Y>w%&@~? zzq8<+r|N}?#Mc7MVH_pExbanjU?wnkPm#Dt zd=CM0QkKNI@sZ{{U|vu-H$Fa{{T48BIg$AWBRWfAB+|J)_-@G(;Hq*X^Kq8!a$s&z zI3#myf4tG!49u3i$b1|#{SBCUEc1a>NiUOpZt~-oL#u$9RW5O{aGct65gO*hz{FNY=KDSP zCIhoOAaRt76CWpTva9f>?Xt*xmxJ$lU@A|J%*SoO9|NX$ZDhW`1D6X-T7$$T!f`6! z^ffWK79k0yO*t=3jctrw!u)iR%B2XhAsA$5?kc{plqQjyN4N>M+SKw`=<|a^M5=*8?5Giso z;aXl-5zzU1t60s$a?IjaaxtN06k%3%oea~-_j!08Sl6gsQePvBb0#i0QLVgAFP{$f z`o`7b+uNoy%;s~03>2rX(@T-$h%jADhlEZ`gzKm46XAFTW_~$dX%SI6zZ8@V#}ZDH zA@cqrO(+5Lm1V`(ZYlPr<@>*)a{#MEu8Tj1VIk%=3?T8$cea@04XypeBkDi z`cHFN`q7^Tnj#jI=3r27TKUlJ-dlM<;CUAe|71E-$q>-G~ow zW7W};Qk{=UAgN@ab-%zkmk|K}Wq-ip3@}>x29^_c7-KoE5^^vc@3F7SaqJoI z={a=#<=My0TKUgqyT0#wRn>Et9T(woM?N#BwC6`3UG{DHwO7B=xDJ!YBHX^(_>>5@ zuQqa$Gu~rgZ5)Y$#(V6mjYT5dzS_vo7dfq_-Y&xJtC0M7e!OQv@n8OY-@t3{9lNvF zh(qsr0ki!BAS0SFaN|8|GAk$Fb)0wc#1DrrKjz54qOg@B+`dY=L4^NUcS_5ElJ6J( zxcK6kPfePQLF$7d+`c-=7n0*WmFHG{(!bxfeSf-d&<#5_=KqWv1B?mdJ@(b#5eTQ5 zCgOMQnc4G(tG5Q{pV;Hk%$aTV*t|=G+gC?#5aG_Npxg-SKewW&*0?%aNYhtU)f$y` zr8Be)RzcMhaiQ%0TT7UoTR;shH+ObDaKDy7^=0T~l>sStj=8LLb3m)m22%$sqR#87 zMl(RPEZY)XMfAcsQ_6L1V7Pi}ExVbJ>%G-=`?uU1X&t|VMPGe+S(bm99BM{B1&4Lw z&Q^QpmVpmo$r#JYOXLc2DjpN#n(~1xI5YJsu^63hN-QW%3)NhkmW$OYtFV>p@m#s~ zB^3yoA zi>UL-L*+>wGq!UDQZUjfoHlgCAcal$*X3Xe=63-aDazf?lG@~pKpPKBv zc+ynWgo5{!MVS6-uoW^s0NP`owX7iyMLqs9)YuFmt36_U6 z^fU>GyBqft${2(8j0`@KES}jLp!JT|MxyygoE ztuJh-G2?#1Fc&Hxn>-C`i0zrRNokx5OJk1jB4TA1Av=vZUOyU&@JbP@hhR04#2V{X zc9u)vPPViFmWgFJ5B6hI3ozY-<36vxVYQfuvDLmLM_SDXYk91R+XJx(EwGhp@(2&+ z%YEJ$Sc6F`)00jwBS<&8tnh&x?MW4QC|U{23JJHe1t6|95$<7d2gAkcnb;}qNVr@O z#)Bea(;y$*EF1$Pc7!|%ZUK&y;Bw(<6kIIc@X4xHERtaI1G}NCrHrVl=LM$S{5fO@?9X#5qxO z&%yS=XAg*%JDZ*u+S(M4wV`;HMwW{Z-QXmJq2OuQ$hyMiG2LFUG^7*9sEyH2`=dM% zGt2!i*d$op#3_${P82Tgf(4esy90KqMR-g@3|qn@nD0=g!znB4RE+i5))#f=kf0wz zc9usB|A-)Qdt?aP7fL5y^Wd`__!+txlV(Dg#7W&upVZCt#b}@7pT1b_E9HyP9QNev z;kGB=yaBpkc$l7+<{W^A zqXCeeo%}{vbNoLMZ{Ah!V#Hr)-h$5b`WUC_{Bly$ug`M&3o+?w{z%Y&>AgTU@x5rv zvn)-V=Sx}L1bc_k#KU&zbDWjsm8CKu8nP}bFo>%=UHv+rk?^+jMty16H_o*8VAv-! z$cz^(bLC{f|42gkaK^8#M5)mDhK$6wp?_^93~fqy9okOwvg#(hcOo|>v~32<%YOJ~ zu-v+pg8=UPS}nJ3^kQJ!#H=r)r7v6+B2ktv?Ie2&r?h18$4&1kKd^y}d!DYW8j+cm| zVdaj5)I)MdLi%DfK2*clSgpVE#b^uQleiO=FGg%eOx+Z#wIGbX80}2>I7E!q&Qd<` zp(kT#Lq6q;(Qbi{x-M3`UHM|P2jIhy2Vs9yK3qR>;ge`iC5H(P1c&FbuaEhILng ztY&)kV^%be{roc-AN&|jpe!Tsj{yaI9CpykT?!`%UkUyx6uC>`WZ|pCKLsjxDWtfm z@TEz1`QV0#&A`6}YJbVg?>Avt=e+&tx_)bOuV8d=PBgak-XS;^8Fz=~OA?1iW@Ekg zpybU)j%;vUf}z?!AJ(e&$%&d4m$H~?@JM5PY-5tc%HkB>ed7~WO;YXaY3Rz#=+g&^ zhk#U#U)UY>(U-oRGKY#j;+0`}{HS!+J5>S=2Fs#bQ5JG2NS_=E(ig*ysL8N*l`lq& zV`SJjM%e#U+!r9*Ld#XwEbgN^5I35S{Qlno$$MaAd814RBJzCTrO4@%BBw8gI!}{f ze^EYY40M(=D>p)6nf(NVG8S z3%wYsG-7v9d#lxxhFa~R;8U&kP+U@2tQJ@~SudV%koUY+S+Xn(EzK9*QZ!!{Q4YT8 zlY?*iVzk%sFT>c7WtdrR^AOrOxpA~RGlJauF*9i*$<6pm#D3hcm_(;f9)t}6gy8l^ zZvBDy2H~OU9=#z4jVU(K;3uZ+R&x)V_m=7VtQ?FRC?MrXkzTrBMe_5Y7 z1462`5(wQ4(LKtg>f|_u72gdODk#h_zPoCz#BoB*Y#6Uk;;{X$hb^|$1M_6s!LUc{ zUp;g%%;gt(ltg{Eaop zebmPK+_YC8#;_jva!=DPiJ-2<+sMnEj{+!+T z*Dz2T(Dq~x@1Ch3IsL-4t-*_vu19#>13lu`KhxYhSh8thd%>oK8`p{R!pyn9ZEv5( zKb^P;bCxHqeUie%qy=U!LkEa6AN~NyV%U&2xEV*f;j0uRVXLKKE9?Q6$K7H1)Pgy_ z?hs!5B{~N2{M^1ZzKfcwWcV|%)_8q#@*2cFXoeq7cPe4t&hV^h5H=b(Qw~@n-2G5xSVfe>m3KT7s@sfE?=d> zaJcmdxKrQ`f}06918x@F$#ApbPJ>HLF+&~Chns?9)+OV6fVT{`n;4+c7b|A%=!?nMch`kxquur4?X;XNitA(zADDCA1GBj8>S_rEa;;WBF$ z_%q>hl#vgYqY#c>dCYqmjzU)yBrUf%Y8bnLSmaWo~m>5Z~Q+Yc8x zn8)aqOr{LRQ(=Zm5JyWF8pPY5h6K zlqS+0e_?%NZFvpe*|6R5L)R#yPw|=V_(QWI<8>5V=FeK;Iih6N4>WDAq=Xu;aCVh8iRA~wcRc& z!GnRKF)OMr>X^4H7r@T2C<>+_W+3d5`zK1=w2QY;Y?1_pGP)#9H|tygVZnIAQP)x{ z-g%MI6}J^=;D%wDC|-&)NrjGt7+KCya9LJ%2#S@r5^^$yJ~^2}pPWpQVQ(uOmeX^S zqC6ha>LEi;gizd}n@>GA1lk@-kPTBxm(n~RHs2!6UQ7rR3p;TCq&W*49`W9*C z&C*SnRE_3_%JNtnDmq*%g2fFJZ`8)%nC0b-6D7JDR!WpUDN*`jw3k(EteD`FVU%bv ze(wBWLsaljvdupG+LxH6ieCE(S2HFyB{jtbU)=Utx3~u$IqY>X?CJeD+B_nLHAV;b zO`DkhaMSnRw}Lx2#*2Cx-u&>7a!%u=*S_>NKb+h4bDzfUWsBN&?mH267F>7l*+^Zs zhzES^BfJ9FAw)N)DNmGgS%I9_;xVhfNrmh2eCnjDh?O&4r#QqPqGk^;2db4j#Ov2> zHju|)TPzKPWnvjlh5hsZuFH6nB_l(w8_RdqCb=s+-xOP8V!cY^gJYRE-~<6>&<70` zkAurOdUeas2Gt6y8E!+~g4RGherJQ)o6F41KKC(ogd}N8f7;Q01B*QoskYNYbFgfBp z(1yA8XED(1RNHJtxoPyaXKkA+WV8`)ZJWC6_4JH4x6Mk2^yaqtIO11W+GZ=lSg)+( z-3QP%<(Tn5**HzZ$q0?p+BRAK|3=%a0WaGo+a%i}^#xS|A z*q>L(wXjnxT8NzF;9bW9xKt<;_N2U6t5?@4>$pkRh?=otZ+cvwEB5h}tdD~aM~~-Ks2x_WAk!yTkm-vNs|hmf1%->zK2p9|ZMP97gq#>Iz2IH_LM*TydWWHvz|kR5e@;zpMuOWHrzy9}t&eyKpSS@PK$cZ@xmeUcog-PJ zOS}cce8HEd+pDtR(~EHDGy(+S)li8L-HcNn{gkENmU^9&ljx?xnB(=aY;VNiR2<@? zMHs8;0$A%r1oPw#emd-+{kwG*uT1glBi3tx%n3xsHNaF=ZuibWv$yzRb;B~T`gqPP z7tI7z6U&(amv=c6;ikf!1ech}aH+y>gq8C>^vU@i`s6c{GORziWms_S>s|0v#n#j0 zYiOt;HVxj%I8RPc$~56MAde~GCtz1wI)a`i4sq|7;!hg$%Cz-~X!}f1HN-LvK=W;jZh;Wb*e_p_g)8EB_Hlrm00`8!PLkdkcq4j z`ecpJCu>B8u|{NAaP9LBedKK5J69te^^s3HRU@XGj)Sd`kN2xWY+CDJYUCcHM(C3@ zLZ7S=8O9osVPcRqAbcb{0B9{ZH8(som!Zz%+f+uGjP;tYUu<-U^(NwWL@cm$EOPQ1 zn*w{&{#B!RH^VaQwO?6ueH&6_d_TZt+{+;ul#?)_yA5_A^B93;rAj092!WLs6PBMB z6OJLKz~#AQ!tDWlUC|JJI`GGe61TGbCDc$uZD$w^UV z!#;XIRV`mw(!VN{k#Tx>fNfM^s(a+cNmSFjY^>`c2&Q3O^H{HCqwcM`lVxYso5vT^ zQN=tT&Z2gQI|D9k!~<(5=IvxE0*_sJnjao_i=N4PZ29|9StZi z2ge*s!(g7wV=U~g2h=e3V_eB)0JZ>A@7Kqb&B)KZz{N`U!Rm(Pq6)=Nl#k)4U{R^t z;Fp6&`sARIz8LX(jSOS8$*{K1lWstymi8nbFZIox7yMH&CndN%eSUjWio74#`Pvt4 zTMt=)^_MUDw0%5iV=10qt-;f)T}9_!|3%BRVAtU3>gHkRYkvng_~OQ{+y36C?bAU5 z)3&eA#)nf-U2&Vrka5|fleWOoPQ+`ezO?5he6MX^x0dC5x~b=5!|{HWt6$rvcvLpJaZGz% z^!dSA+QeC0$9_R1-_w=r*t0aph3wbx#(n?w`M?hNfe`GHn{z`FsZV%tdT9FbRp7l){P}DxNR7#*ADFq@v zG41)ZtqPDNUY)@h7HdrV#C)4A1@7w+Ve(OEQHScheWZvkW8@wVT(l=A0L*! z7vU=tVei2wS=a^t1$#5BZup7YB>ey`yDvuBqJzf4ea;fU4+`yY)qUd;|BNMma#!At zM=Pku$z6B}*T98}X$`{l!95r5V7TYQ#c8x&4;S~X zt()Nvh5IVpVQ_cBg}hqFAaC9|@tN2WaA(6E374O{hMI0|hMNNS61e2K4sJSJ))AMI zpMndO+e*2!9IVBsVdc{*^vS1H=!+3McFC|cz{{|3wHC}unTt*|V&44rQ&ON+dMq$2 ztVb!P;d_EFto;;%)n5C%cRM>QI%0p(f7b77DGKk>!56&SH+I$G`Uf-iB~TS?+`>AE z+tdqXanW?RGjH3MaK`)W(P>}oSjz;+c^}kj;`)7Y=l%}m3D2-?tFxY~c2C`WUTwjc05!FUubXU}zKmyQ^aH<5ZDk#U<<KAh38(dY z2;&rO_zQE|b4Qpp5>KrikNy|0-Ik7yF64+Xn__|}qDTPS6)!XCs)_1Gs+>#VLsNko z`il|9N3f-8S`FV~5qmy-0pYs=KAD2dRyD*gW1|U+T;T{cV@IHW4OS{k}Y-;Iclv_7E52_`~@ktdp3EjIF{JcvkfXlm-BDj9IO>nc|ZiI_r ztN8W^GHksb$5Y|n1a}(T-@--PX}t|Dhq@2Joe6gvT&yUxeh3${fvsP`oeeh+WtaoE z5bj*KR8J*v=fIr@mup!I;8w$32)7mP@o*`B=1+C>9IRAF^htF@UyNAvkzt#Fmtku^ z=LbG-Ks*Op>yn~ygt69V!Mv2Lj7-OwHZCkr@thFZ&9W8$Chx@>x54HZ>l4(^7 z-R00C4!Q_H(aqNG6KNhjJDzH2AF>pqtAfp^g+deI^ZMSEYZ|zSkS=@O=DAUuqBNDYd1h4*VPqz_W&ck365qc*IJxde-?;LGP;!ELjR3wG;Br9Y)?;D20c4a$L z8fTf|+YXO!Q-Easr3J1g<3d`5p z&GGFx1APdD%eU5KiGLpP`VfeBH*Bxw^o-YsK+I>ML%dn{+ysnO_pr=Ndj{MC9|Gls zbdR}UXnVQ=Z3n}jAAj1n?*m=Whyf4phQ87X;0n2d2tydLSjs32Nn5Fp7sJKSf*(6+ zWnBi~o(;De?zwPLZ(>-p9PX7ku7!IwT;eywZGgK2?kRAehYOw5`Z8Q7y4JVgV#w6W zKDH9B2W40V_ei*_;SPcO8@S1EPlG!FZYzEh;jV?74VU@wRiQSxd89$OY@-CE1qp6vfbf9jr^ zq+#tRMWeBMwBU2Q!Jw_%+S2Q!6SwpV!JwGN0}+okI2{p(I}0-;Z7XkkU=uO;NiR}V zC+nQN=Fd^7q2=_Iz2J*-ZBMWwVPe{=ZKo~l$@|K<>z;TTw=_zOqn<> zDsIE`II+ea?Bf&T;@Wr*g8QR%EpGi)1g=T)Yt4DVsnNry#y{jk$naiQZ2OFFx^Bap zu2cKtUMs%O`~h=N*d*kc3)*49_+W7lL?q3@cLsucG5T815r9?A#!Hq`Y-N7QKJu|TY1HBCwAgnQFB1#e0hBm3C zJrjJ*i+4o(AeIk+_gEP=3UH za}NXVSxfvtUi;L*759MJPD^~Li04p8492t@9OL6f{MYyo;LNSlXDl;;<1m;JH}TUTnfw zNOm(WXchdDlRkAUUZ&lv6PC-pA;b*u2nd#@WSaa~54^kpu2R8_qMSLf9sz%i3U9{+ zgQCGjPFy(7gUcHnwBlCQH#&A}8r%!vPEg@~xEJAgK3w#SRuod;m%zOg$2D*-gS!gu z<#5-+y#g-s(s1z<1MyqnzK`SE;eHPH4!Hk>dl%fEDBIm|$HTn`F5gD^1KcXO&~B}@ zaPNb=0q%ovc`LUC?(g9K5$+Rk(Q8^?f%_=jcj0b_yBF@0aDRmR6xbifXi~cqK@B!y938;$BgfR^LYbSUWnKZ1TWhF%S>~Y3bCI>cf@!-gYoZyOTwKKD|dObZ%%&`VDdWSHvHfGA)>p?FR*v=#EMTBV1jZ{u*muq`Ld0j?aMUD1 z^i&rE6EHCFXh+Dz^y=+LZTcFA5U=M5{=;5e+-pXtgvlyZ97-s?4;nmrojw;9l5E;0 zmX{8%hnkSBWahco%?vSrf>cQe6&Scs{*V!mLLomPWO`W0237GAW8OkG0k}~6*?#B8 zjk1;zto4?n#I`+pSgHzPEH`*AZ!V`7hJDuS8G?TZUR!=qBXX2&7oUn!sfa-;)5f&u z-bjVw3e)rLFZ|MHZik5o@_IPVpxJThS@%n3b8BH6@p`yaEQS_1N;FzarOG`KbrG%s zIIil5xu3u!nwa|<%$F73ALwE^KpMjX_(8*GxB=A!N1-s`y0L&6mx&U z42brV3ejwN@rnygf`9kCL@N!;>u@8l!<5JlH}YDd3(=O>0Ff7KndZs#Z*fxA^EwhS zUe7QTMnA6shVL@PJix|0P^99h7(eZuCuTe7u|WcJGcwef2O7SY74tyBTvi*XZ3;94 zPh+ijAHuvIJ+B?l4q9tJi@^e8&dX=ybtr`me+j-s|Bths<|%d7|9Te6+xD1f6*V~$YWJObLav?pSb^aPQ!n!{!`FouH<)2I=Hn3R_3*BX z%n4t{w%VD83(PJP^Kl0AXvKV-jd_Gf1v1Dp4 z|GKGm=2150WP^DkFXJ%DHs%zB$}17$mk#YY2qU=}YtB0j~&JX)lp z_MkcMhUz>!Gq1g}ZRpIS4dz{{%%g40=^|BR<}m_e*1hQla~BRzVA5^OV-YH~I%UxF z=6x9ETct5hV92buy0M0DoMIj;m;ux(RETEFYrNng8>qAkQtrLLo)_#FU{nF3=j^Av;mLB%}9#_SiV*oJ8WTOV3$XU;;5*F$F21vS6H zJV_1n{Wj)oktzrONT^*mZ_`(HX2yCwr6%TVgSkmDXA5QkwL4UZX3Goe4?JuS%dQx&o%OTS~2I^n4wCLifi+%_5p>Lt+g{x6BusutGD^7hHtN8o@!&B zE>dxMjZ!^4YT;vc=6r$ShQB)Vbi+4_>K|shjd=z_y`IYzbI*&fxy8;rQ(#I=%rgw; z3dKCb##|s$apr8ULo`Q=VayOEj&TRamHt~IW|khTE9+c#>~mi zE1O9QV;>5?d5=huMOk5fz8{dOH7!lc7F0Jc%UKqvSndzKWhGDx$)YwYuyZWTBSU6N z__K)}erz2l=r78epE^1%-A@8O-P&QI|I!!Q%gQRa4{OpdSqOXt{Z~gS~V3riv^~a*HzX88q+ktxxDN~s?`2;QSPdi zx{B($s`_8Fk)b5bjjP2Bax-^E{-p~ex?R)i+F!IBSmP@zYpLV@l)nO@WM-BXr?`Cf z+&>V`lW+mhcuHrvl2nZoJo=S-qj0sNUs#z)5e^Blf1?uUU|7V5sEG{&d0 z&57j4o|%unfy8{%CCx8B2%=wigwAi|$DzY6T3LCxCNa+V0P=p&EiB4%IiD~hQ(1VL zkrLT1tR0<`ez6Vzx}mx3Nh#S`e*ES7{e|kSHS^{pC{bBqQMS04c1)7}pCBnJ>X^m& zDwX+ETxwM`9R1r%9pba|9V5Gz!sy@OAaX_n*x*8>vMKtflW8Luw3|;^$^Z$KP7&Ug%Hi|7cT|d-N6?ktnoE&El8@Z(R}v#D`Ka7}rQ!MT zW{eL=beQ13bVHUY`>bg@MX4{!3d4s6)*IFEOS*ZC!jn>?jc^?#hZ`}YQpco^@r6w4 z==8BE<5S0{j|+v-mzt6?cI;TVspChdj%Uc?m;z6MXWYGcGX_laXs=*8fhM`KF;LOG zA|Q{%$H293I8SOeG4Wx`L5y04iHD;xGuoalft)?{Yw_91OPaV&X&5fUSWT;zvemq7 z#(3hsR$MyX7hkm4JmJLfBuv8e#4J}TXQ*H}jpL6;zRiJE%_2npacQRl81Z%o{79xb z@qL5vbAUTN4;~nUuhFz(h;YvLZ3gBMg`@cV@hSdfflF${p)iT~e+QT^6%I2y5*JQ~ z=^9MlVJ>V4=fhxFKJaa|@^Kk-1Td4rakhL90d6WVGdsXh&hvmdMd6I{S>zW5+e7g|-C@|M>HV;P1*h!_%J`H9a*F^ zN!N*wDPcM|{TvmpV5xUp%5KfN4^= zNcC|VFy$p3^IZhYO$z76_c>_p1m=o)k@+as=YV-x;oSJP0{0FuSMq5$7`OhGgt#rh zysL0-{g?Io6)>+aAe%cMm(%_MOwWY^rn!}m?XMp&`xMS-FAn-S^>{oQ3`-M9Kc5Ip zy}}v#&!V4)fTInV-zpr-=cb?U2Ilc_oJ~Ko{XGNBs|si2Yq@?n_B z%<}aGX1v0=$&c5|Y+$NR6m+iofY-~*fw^Dd-1xXS_&6|qPKwOe6VZ7JBazPim+iS2 zxG9S|=4()xj`&UkuDUET-%vzf1A#!7 zcL^{PDg?~6K6rUq4$S=uhh&a?eBy-}}HMER%ePxbRWm=O~OsI-l<@L{0;4XthMS@lih?uP_qn%=a!L ztAWcqIWk{gM6XnsNPKKB?ZDlzJTf2G?Op@seT8$YU)IMSU|y<;%-0Xmo?1K@4@<*( zb83I=Z)1TOQb&~g_<;JV1elW)&aHgZ&r5-s%?<$LRv$+oZY?lZE1Vl&6e4Z`=Jp0b z7vgi!_wNF;Tj69obsmp*Jq63burzF^V%%=g_oES>49sGMWBJ_l{mH~oCetM)>@jA>P%fuga8BpZ1LtuL zaF?!-d~WTEd^;6JBAw+zzBhn-e`RF8u88ilN@tR;Q~B604+HKeg>@@mEO4V%?;l?V za05@3ST{bZiy~kiRyenQz8UBHCtxI4)V;itEu@0SoC3OFtstK44~@DRFLm z%Mh^un8({9^RYg@2BvgfWWFNsRRQzB`pA52p1Xl5J1a6Dulv=&e77MoA8)sZpN+TI zU}@aW_hLk>0Ve(&iF2zD>hWw~PEt5GK0YS76qx#;h0j5c-vG>=3di;=^s{ALoQUw} zfO${h3_WDg=k@Wbjz`Uk#Zsnss{ZwHDA^x1o zM}7JYaTiFGTYDkjXoZnTcfL&EW?mSXkL~X?U@liU)~{3fenj|&awTi1ZJJWxs{LY??zxAQ#hl1 z4(;z%U`Add&%>?#U5|p70kiK?iHp?!YA?ecF0eF_+TRvnK2kWh^0B?_RTx2tKd1Vo zemUfFj3=&;s7UQEQ(-#dD*&$K%8vQYQkahTE&}eVt0MF9zU&2H_9z_X;&i^>AbcM% z|GZlA$#!6$7bRc9H5hZi(nR9R0cPB_5*LYY9xzP`=f?LHXf^<|^18@;e?jymz%*Vj zaoylJo$qvHw1t?PBra0>s{`f&g^Sew9s=fLh2wdM>x`v;oQ&}AfT_4y=Iho!UPk-7 z1em}r9hdJlV7^tjNaY)NE56(UOXF6)@rYZbFan4_C;2Tz`7QxZ0>x=Bd*&WxG#gHapUuW z?{r|Uy;I`c&bJ=XF9VZ#m&A32<5a$_;QI|Q6E{m7^^()|cM`%M1?D@2Gx#j`QN)e8 z2kS1dG;9Y>?e9&5Uja=0ABb|Vj|Mc5)xdmqpTxPHFUPw_+>fy$ERCD|T5-M`fa&(2 z#JTYuf#?aqlqejMIm(aCZV@nDw@5zbYsgOqiGSvk1kAAt=f=nCPXp$?4){g@_mjei z4DjbvzXizX*oW}7nLkRD+xey=`c`26tZ;7SYe2-uz|4CjGG9KTHvsdp!nyIijfi)E z`NLz8`DP&cBVdvrmpHfjT?4)XV0Lbe%vXZw?|~`YCUJ(osthb?S(-FghGJd-d@F#t z@d+8y9gb1ImU)IBff=;j!e{9pthZ^vG%1{${%Zwp12Em5lzgl=r~2KA@=XB7^R&dd zT|bUNbUiSaD4cP=4&{3kn9mf>t$e=$-%r4-+9C6GD_;}{ZU^SBXF4w5fM;>f1xpjD zd?y2QslvIH?-+304$R962QfLykK_AyfcfM(=IXAWhaj&1^O%={rE%lqcr6#0f)^yt zt-lRK^y$D{t#CXKr~2KE@Xf$n{-Wgb!ZF&P3=;q3djOc%70!)s7jV0Q+4+)4CiJ8e z-y}qT0?d$?CC-iScR1g%!2IB#Fb1DP|Cj{KGKHgDoUU)I)-}N7zeP6r+PKsC z^7ZyBfEoFY#6>FKRlq!^aFNRQ2{66?Ecx8ZcO2w$3@}CSN?bG?r}9;T;Cf)9-jleV zaE$h1(tpDdeiktID4d}WEb`-Z=0jlm?ScnJwr9*|TgIo;5I1HQWC%-x;yRWu9T8{k z!Usd%C(6D5lJ9e1(moI{SH2YRO$Mg+Ly2>1&%AzI2h2Yej_2Vdzg^%<_y}$5B{qu-=^bSiaf7objoExz7L1Li9ZfBazO0=Y#KO;LiOlGT+IF-U`fdf0H=3 z^W6-->A>vW6PfP;L?8D#)*E4Iy1_b~uMdJa<_qY9zYAEzdH(x=c}w9U^^bkP4F5{< zQO-{NHxc2Pz|1w_oXWQgxTU~M`x+h?xAsE$tp?^p6V8e6NyzWee_&4gpMoyp`A+)= zU$ldziFCdf0`r){xt;G&aJ&l4cM6AMIM&CH2>1RA_vo-RYzKxu5Fzp}2?R%ei+iMh z%i|b0PUjm1g5Lsj+xHR|N&ofx0oPwxnn>rn1ekLb&h30J0mqHNjN=KxbcJ;)-y{$; z0dx1y0v548j@$=Xz|ur2-!fn>Ryeov4FbpSfZ3sNZuLPqzXHs^G$P#FUpeB2dOY}E zsl@T$>3ly&#D&0|&hP)jxV7gi5w{tb8Brme6W=aGuK}jCtHin0?=j$e7MQOTE|UEE zck^huurzM+V|!i*%o!$}Q~7xPxCodX9Js-_o$n;XeFw}K^`#r;>%@06X!3#iA|^5) z_5Gk&k2VgL#*L5nA2Wej$$=`2TluJ8ZUd$dzq+MxPUYi#dmb=9@r%_kZuM~#;+DsG zv~yu;BGtzOzu6}WqWN$V&1*bbcP_gzE>fXO;c;@s+&{q1gG-cYzm<@*VkV-J^n zk;*q2m`4@Pt$bTS^LJqG=EN9Gr1Bkkq({qvrHNF&<-lB~aBk&eJNP{?pPFz^^7|dK z`vI7n2FZNg`WuJ!ZvbVUaY;oQo17f9{`ru5jz z<>U4Da$sH`-f{V|p)3Pbm@tv#*AC1>3g=cn7V8CIz8xv~+{Q1tAUFY^{Jl1%SUt$gt~!OMWTmAfy%41slOe@UqLAI73xO_sRBfOD!}UOx_-f_!0V z*e?a2WgU@n{aRs&qY?Vlf@6F8mlMvS|0;p|0k|@LJr_pmQ~UkkT*N&DOb@@r@!#ou zn-S3$m~*luF0B71t*&4mG)KTb0?b<`oD<*Mz;(~|Xz#<)7<>-r+b2h21Q375b;gqK zVZfy;tec+v23{zr3GLT21i^L%s7XaBnFr+m+M#-iPo#z+9In z^Y!95)Lz2*9tGxEg>&P366ya6%#Bkmd^yD>Negr4AzB#DKWqhNr^1PLub~}CeO01h znjfBb6($rGpY8McM&;&B&6-zGQjnjWF{GuXx-z+@ddU#C;3%Z#y;u&;aJc44Sa9#O zjkOu2<4#Q@tl<4@$rr|4#@`=M;q>}>Waqt zruwR8->~9ieX|>yt81%It*%?@%c-wzsK!SLw70uVPS7e=R%(`iNZgWdzb-iywa!Tp^oYE!Lb)^+G$$?b?t)jM48##NlZ{+MH z{Hum-hF$F&IjzJuGT)L}X--j*Z)EO*{K7P#a|?6xvgb{Mrwk#vvlq;z7qwG1H!o*i zF*HzTCR0a?|hF&{B>zR;( zV`-L_<&-xC=3>*3>gH;^eb-m(me4bv`von}s#~42th}*_fB2%P49_&eMQ}eAT&gY4 zt!~T>)SyQ-2O3kcsffgn3Xd3#J(7DQ{Arq={c`r)9Q0hW;VpjT+auw+0dCPr)p(7$ zy1b_P)IejBz?!J?Yia^Z%WHH-_R&IoZ$zAfHZGhu5;i=O{#taxYbb9{Hsn+ssHktO zoR1e3>l^Vk=;(yE5i<{OVnd1G!%5KzUz8fh3Uwqx`{U-NP}foTnsyGvUEf%UcSfPv zq7&Y)1^w(LCxccdnv^3cndPLF6%b8X^Az6{2sJw4X$x0=bD$O%%jksdHDGZ_hbL#F z6JEAu;ar|6+A%=C5fRNCr=S@D$1Ke8@WM7!Wv726o<(9 zorpP;VG7#@=fJLqj!^Mg0_{oO;u%DR4D`@y$={Db&9H}Gq_K5+5ick0gBJR)b@ zp6WMxh_6p0JUipMzt8`8!HXyStM1un6{o9UTZ9wAvPh`f)lH(ACU<~ZAsTmNRAr#5 z$pN7X+fdO#7W{AwR3sRZN>Y5ujpcI#<&71~e3N}if$9by0~d*dCV7zV8}6HYAXxA$ zStWSVeIv(FGA|BAw+^&9#%~qWX!FW2iLg2gNtq#&>YC)*DjiWUZe|=YrC(AP7pgQOTTZif_pDYbN+0eNzC7WStimlyrno$*KoI1nKwVc%P z>U=`Am1;0*i*bL+o7-5eQu$)E_uzXLHdgHGLSKybGyY!?VO?-*N?(k29DL7+uw>VUdjB!;t3{_r4S!;z=ZR=B5yrK;Tv*-c17Mbm zrauNc7={QeT@EQ|%<(c-6JwE^5jWeiZ6P_CmJ>`nFl<%EHm=RcCi74*PEVfAKY6w3`#LB-Tm0v$U3Lp1P0?P@B3t?wigv&I<91i`dO zD10&6>qZ!7)`;WGYPji-Ln*tV!pCamkehRgcEif!Y+hHf-2&H5L%8J3tob&H`2E1h zFR_G>Y!WnN8v+}O;hweTLmXk_9W~r>*-kiGz@3; zH^5G|RKK1E-ClbkV)cvq8ld%#2hzdlHE!xjPW^=WS*sTPTJ)1-#L23qPgX5`G1_MQ z%dq>D585jD^==$!-{vModz!nejU}Iq3O>CE9fkRfflUae!>sy>54X|ia-hs8 z3m#K^>=rcU_%7;*GCdo1o<*kQBnRv5m54H3+*DCsQ{L#S4AcagIh|Jt1=iTYoAjZ! z-lZ2oDjsSrQ}3dz*}#s0mAZyLscYzq(b}`Rbh_2}EoZ0~g=e|D7Jt&rS}pJ5@nOJ1 zd`pP)7e)2eb(mJMos6CYCxbp1gOfQ0q`lEb-CE6fBw>v}s|w@OWUI-*k!&^e$yP(3 zY&9~Btwx4bwe2l!?vDRa&EB-F+qaO>Q7nfd!fdRasS1%}wYUT`Mo+^ceh?B%zLGGR0((~aAKbtlUR6{G>B)GlcLbbGV7MaH^50BYEGGV2- z=#%22FGl;FijCz~TLKq@{T=5AKZ|>?MGL;OAnw75RqMZPuB>YN`M8$D+h=tNz9u># zwtGCO3L8UC#I~rTx1P8i@tG~%5YqhRo}{XY|85@CIvIq}{C^F;BvJ%ltP1WGzN(2k zT6VTQ)rDEaJ@}h0ZQHvbkCv;`wjw?F;w}au+|8a7xBEbm3!5mmyNQOct5%HvJQ2q0 zfb>Pd$8LTztZp{x9_6w&4}qUpHi2_gxbAQ%Ln;w@bv#RtQ0`j9do`9pcJ*~CTz44X zMRZ81_fOR$l*@Qb@Q5R-kyWtP*2FTij6v8xhgwr!-Lmq!ia_P8@}}h+@7P*XxPqph z=!Kx(S}hWY!441mXmyxjG&)?7AF)TY%$baG75XT;|sR zw-7F61&&tAoV;hl#oU_MWS+-8aEyG=%HLK#xv3h%Vzlv)Jbkg+B;~^(*Hg3`LE7;` z6R@0#S`_}-ijrV;V;xUeb;3FTty>rBX}J3MPt(P~VZJjX<8;Sq(2g&M3z{tA$l4PKELTm zF!c?A#&TR0eQHkGS5aTr)a*OX*7!rE&<7-Y!ewI{xw9Nr;e4rtGaGSIIP^*3&=$7Zx6i_Hdmn^tXf9->hrn~haa&4|ph2ue>wt=?e^%EMCB>iv+4LyJi< z6^waOC=`y~115O1Rvc>Bby!?s(0@cD$1*H!>x8T*T;v=@LX}}QR*|egWR687dYWj&{nU|2@|*Uzx!7c4y=7y* zR*~S@3n7w4h?63rPl|*-DH0h*k;pJ?^BaZTl)DR!{6v&^Y@-sf&MG+`F*JHpu*zs1 z;;b^#)9`+~%XFp|#!2^b1KHY!^2We{wVNL5UiZ(afhOZ3>r)xgVHvFQTB77tfjB8I z`lP(*lPXz;QUAy=CwZNW*v`r89Hh**w5iU>tFWG{vj;0Rd)IT4+cG7$YLs2djXo(i z`eKBRmSHdBScZKDpSU89f$JwC;1Sr=j~-Q{!@4Y~%&sDSSV~#t(9u zuK044S&uxW0O*qfpikT^2fNBaPTP}F&bQ3nfJ}!?#A>bXW4GccC>K^YNy@`G8cM|r zm&fpGK3E!ay!n=yP7Y z$s+YftSpi~6&0Ks9W3mDx$@|ZiEDAtKHamiFj}9Ex)}J7p2;P-GDDQhra@!vQ3GYL zYmZuoc{VBzW>MEo4{99 zobTi3k`Tg8WW6jZ>Q%1@f*J@a5R?Q$2#65YpdyPB1YAG}iY><2Kx@3l+Sa<&wpy{G z)rwWCwb}+z5pCVNsIBc6t8KAp)w*G;@_U~5ojGUjIX4SNKL7uG?%el1@65bs)_2}n z59C{QdR?lp+Dr+iD>!l9qp|Rz1@o~^5r?-MVS~(Hj3;Y2Y^7mjXqfq30hxSOg8gA> zTz6gj(6&lpN#nYAF;8sgH^7E95WbV|U_0Mdi9aQ}D z7WcRpUuj8$aR?ym8cn&EL%ri`*u$h?t)XH@LpK^02@Ri_rB}jE42ez~hK2pxHnY@@ zCr>{kQtc7mm?W}`)&4hN*W%((w(&OO5*DB1O;-I7ZYn;BsrV$ON{Z5+$FtJ*c~))z zaCnp9aFD6{`ZUuEhsOH%)ige!6$SHYkdapt@)63O>qJSX-P%yx_2ElH9a-A@ucDx;Wn-D{Cvy; zLtGpVUYlVPGO@r;B`C=Cc(R6SFHNoj5g{y8K2w^UW9ZiXIS{)T-_#Cjvbc9LQk_-k zlq~M5U#N)sHr&G^ig98b&V_xmt%|}ALoHgl=q!8_FH%(~a@8aOD59LI($}df=hs~1 zGm&~B6=S6dOu#r%`WL`1hNanrioiTV0oQj0L~{|Te;?pcc)lNSIN;9#O93AQtO9%p z@N~dm0xki>m|iAt9|dHT?}6|u=J2V74_=ZA8e0?CJWxN5~kElh4X6$KS9R8j0C1*OONqQ6P)Sc*q$7!THt zIP5$_Y({A!3%o6WjN@Z~3BV@+_Xm6u@G!t_fWrWv0VI##0FD9tEg;kNEFk0e0Ib#u zVp=PR#XX+$QW{TGDb1?d*@v*q2DBQgV{ou zQa%GkC^fFTJK(<#&T~S!MV{o*2lj|F@TVqoGkFU;y+@C>>f4DC(P-n~`Gb~2z};wX zw#FX>(uF~dXYI6x@uDmvpP`2M6Vz13^)5g(BkyiN#`~v$g@C_?)to1$IZrI^?KZ9j z-lqop;_L8r;4n3mi#D~4-J|E?Pfd2!qrj?p*6hwYAKnALT@zN$mcwy$D2HsA?r=NhJU_JEsQ|g@ zA5)0bCEvHdM?n`-bw)R;Wbs|h4VFgA1n!C4Ale&{aX`J1I`cGe%^hNzJH+C$_^!0g zcvf0^%be~H4qwtZtYJ&1hR0-y{GIuJ9+ktNHJp=jjhjb|S1;EQxVq;GmA%nA*pg5l zTAr-)R|mDs<{>{i-Et->Yw}N`?ND~Fs*&tx;y5Yfxj z6U7Kr+9f2ew8w)0*&d&R)%HkC+as~K_o{I%@OBssqfu;a3|1SufW8W2u$raBG)sx;im1{aGX78jk(ZK*ok1#x&7NUh;o_QbhFuEB@a{evhVb=B zhS~FG{2DyZo3$bUnQv^nns5G25|GpVec4puhC@IUqRQ*BBq%| zO#2C?J&tFkwJ{z44|x1y)A6?=Z{kVw@?*hJ1-!%Yn!F5O z_JQ^OEm++v`;K7N%}mw186qE64Mbq+f@*$US^}`51nz;M7~D2KU_7!%l9m$*TuK+ziRp%fyIwkHI=6d7vD-^`n|^5RQ@)J#kTTP zf;48KmwuLye2G3zL5Rlv=yK}(hR1tsWjZ=Z?m;E+VuC?#c>jRS<31;^88*S4QDz83 ziSr?B3f7v_fl$q`hC*Nv8Ykn!4(Qvk4uUd7feaFe#l6$vN5d{KSlqi3nEJcgVCXSUd6$ios!M*;xZUZ=9~3{e zlLU4u+99*@tbk3(2rCys6C%cVXH}jo3grmRwu-|#f5%+cLl#j3&mMU)8QR2oVj)kW zyA0Tkuus6g2>T)IQD}B2!159kUbK7(Y#R3GuusAM3HG0`pTi!2wlNs?cv#+v=ataMsw_GN~4 zW#uC#D<3sk`74u^yr)aEl9*;CG0jS)F)NkEtjxZJoI=?(VU2A)9K+j1Z5Zl;ckgW; zR;*faesrBMh(ZzquN^{;aR>`J%x8#dOCh0oLrn9An2r{d_7uV^ji<*Z6{gEC`_vz- zrh@1oc%}(wPy?K+LOq5J!@9rM88mLuS?9E(<+hMNQkjxYR2heG25m7Jbg-X6#59A5 zX$C2c8KktC=~v`<-S~X2qx5J>3@&-TE`P|D#`08;^v(@$*OknvZW`0Xckjw+n&hR& z7p6ya!7lus>2A8PV$Z$gH*CvocssV{FW}Q3JQEA%&z_!sM!JPFPRGL6N#HR8HX&mS z#m>a@V4+dAQ`y)EYt1Jr#E&1q=AAdk>*fp@5nj*+IiNGmcAP@7>$>gIhpqYNNv-eIpopN!U;Wipn2* zT(B0N?Qub=LX{v`!+5d^v8_>Mpm`Eih;iQrcrf5ofJK1Y0hyGi0hz960GUfv#&wfB zG2P@&Ebd`PoVXTv=Ne3Afs31$=QQRuR^&ETbpD8#4x5z5>{Hsz^gJwpR;NEH{%BhlGTJtg4Fn*cV9BWB+WZPkYp%w$ zrZ(1e_w?_&KiFwWW6VzHHLrQ6@uJ-HHeIhe2Ej5*WIZ_D z2`}C;V<%)It&H(vDZ8y~2TGaw^cvt$z`p?w2YelnQGWw)GT`3<84KRhr|VP1bbX4L z9wkv4kCG@2>r=87$&3&yq!hMQNL5Hr%+;L;>3->MX8Ai(57N_e7c@>arx*{#`!j38 zVoY`Z7JzWt??v}6sqp`?L^O4_d2 z1RJU0??14mu+}h6EM@9U?AK`iiPB>lcLH)Q;7vfL_g{dOfV%)$y2DX&x^sz`?pz`k z7wt}I%r~X!Hna45C7;)pr1OfmZ`1O{X^(Vu?hLcE)@tcagzU{-pl4JM#ryZJbeUI7 z6(S@kXzQPFmc{$3L+Guh3x9YgVW0^3%@^nVLJP;gi@U$2aWZ9)xYd9)vv^dl2#){u{fb z%R^w`4cU^jyV_QYid^n=nUyNUc9ya|cp^bIx0IRcP>vuiSBG=pO2gu(VR5n{+Ujt& zP&3_aM@&D9vbejA{Tpx(Z$sca`HrQq|7~w|7!qBSZC8D`0535IURfO~VXa|2!eShX zPCe6=GR1rZ;2b;;1grtXrL&?ep_7(kr-;^uPE3oPm=?RzSnNuhNp-vs!aO}cKm82K zzB+wL?xd1W>V~(m1tnj$pnM`*P~4(V&-R)M%c9bLc5ZBr$OGu;xsvG2DzFhrvF0L! zFxfP$0&dU0TFHJDaeIEY9Of{M4NraA?o{mpdboltsz1gS!0 zl3y=_LQM5-VsWn$|4N%;Fp(TGw5!nlOHGMU7~18gcMthw!=Abn9)~YVNkfZop+YP!>n=)r z3*nRoB*RRHPt8wGsjL2TH?o8yf~a9}&Jur=H`Rh!Us)HioC`5a{d{c4O4ex^tnDkj zGlZOr=QOOwmfEYvR@xq(?3{fmaBDQy{qd-=-p4Chobu0;t5srx9fcQb)ja`NGi*m! zvTg#8N$wg{>nm9;7KB;On&z@%hi!pEk<5fwayc)!^*eg|FVjxYk_g~R{?0cgO z+=}c`Wq_E9TVip!d`oGsBJE1s=h@iUo@|uM`1f-2&gJ_y8#npcNKCVlm}aBWn2k!? z=h^s;eU*(|$8J?IZC`C{NuRpg&qiXJjl?t?mBwsTTH9yIK7-$VeU|Kdc*oLEKf!4y zPN7i=`*}-ck!?ba8;?79w9MICCF&RFL_UJm6>(y^B2FwgTh{VodH_T-@%1az

-HyD(;1nrO^v}qeDR-~3Xdsy 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�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 z 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
  • dLyNFC6Y;CC^36@0kQ-vo;Q^k}C% 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 A7l8)fZLu4ru`fh7K+iNeW{)H4H|iA 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�lhUj1qYz~DLtFgdNzsjduwumxhQW~99F;F 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%0A`R&;+*(xMDTcE{vH*cALEw{{T%g5M~4%? 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 z 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%0AW z9kGy8hR+FYl*YWxP>0`6zk*NBu?A3oJN?USco0+3V>{J%8uhi6{tof?+)8Cx=y2QV z#i}?tLJ*U7N=(|R&|cQA{|&|2Wtt4sIBCV1T^SbXYjHk=_&?0zyu>R`Vp5#Mq&S7f z;uM;Z4*zFWYd0W0_I^MAtm}7&9JTv7@$!x1>|fZ*$Eb2#r!kT7NK-RaYIoImP}+qK zK3Nq^Rs|MpXQ!Cnl~;mdOn)~Kv>+n;@l*dMf?iy;QPtd-c^{7q7EGmCe$3R*vb&AZ zi#Gi3Z5V`)04&oqY&A%5TrSkzB$g)=Tv0q4un5qcO<(R6EHNoqVzQ51XfMLQ(6}>Z zraOm2vpY37@X7k=?$c882RrtxkJjN>N!T5q?+$-J)8WgVou3@O>0ni`y8OM?|C-NL zZH`IKix%!h1WqZr=4^6J z5xJ)LfZKE+;NzUC{ABU2WYeyI;vU=y+xko4pSfTlu8Ru;od>LY2BPr5$}<&624Y6| zn?l)ijT?7J6CMLmf@S^r!_(a`5L%NnE{nTipi|*S_V$Or(PE&l!`Z!wXVC4|jnBA@QvFwszaYYnd4%p3eZmVx64=G`Bwq<=qCF^wn)7Kc+w z9EMDVx>roa^pmMLbdaf77G$cKfMhD>%`jDq$5h0GsfdLf>ivbbRAc|2sZel-VybV$ zk3EL_nd;U$co37`EA^nY?-O(Rbo7R~Zo)VJCz$JMkGY5ma}f(UO<*aZ@pPHc+^yx? zng_Vsvfc;6iHqN`FF{NW8`_(&EwH1l*#X1Q51ajiP52{b%2iXAtr(j&2xRO`KhXjdcmY9g8#N9WD_31Lb}g^rS{TpVMJG}7n?{_v5~QOYzP*bcHh1t*=ogQ1RyQwJ z#rQXP97W&S@Y`J|7e+H&(=bRTh;myd^K>F0(}oGWD%*BdwiH!~i9|(AP9O{ICG8q= zmLFUS+-bO-e`}}DR`vTbjdIBsI9mUcRB=c2+&>lx2FJcg?f2aAD)prMQl=sj)eF;e{jAIX0@RV!n5SW3lPu zCdB4^5@|BmLnB#SyC%sj=OL6W4^s9W4?Z&~%<9<~NqxeV3D6IC< zeIB0=t75nbSS|$%=W~k2hJYWQL28s4a>N%-U{mPM&>z3cEXo{|1(2({QWj6H6M^f^ z3S&kGA+pP0?||I_dkg~K3i~+hd$4(!tegOQ1MHVzzXAIY>{GBW!0v<1L7O=Sb_nb_ zu;XAahy6V4H(`GS>rO8&?V8=Od;Kx)#0Yokjvf)ui?wYHmTzl)t8Lf8?hY$Nky;ug zMHzOz_^*Bwq8n4j?{0jv8Q%eG-z~{F8TMq@raJr)W6Ka#E1RH`9y6v2jBL*NR;`4R zT3(9D81_sOQl0iPM6P+cNNXZn@U3M!hKbfaFfpAF0;aJG7RBpLj>n;^MipTKFNYQ? z0MUJ8OR>BhS_R1F@)g#rdSIQHbmhe4kqe;(!6-uWYUVgyGi_S~y{w$m@i7{cbGvdV zL(}-(%`aBY7Fc_soN=;pSO9&m9Pj3_zSYhNzS>#Y5|;{2RS(C47_2c&V;8Kya%xcc ztelB}lv^eNMgS)RGA~mASvhxjl|xJ_hnQ53&{#P_b0-#gUCF%&ol-V1PGd}uYM@_! zVL5Y^#=gVC_$B=AY!j1XHv;dSH=ZAn2Yxc&gYiOp;>ul!QFFdoNR0#z`Pxe)6_JuV zc~TDlRp&*guj(@VrYgfZpb!%|keH|^h4!*`MgKjqsGCQVSRdmC6$d-)g+GD)z@hb4QFB^8@6g!lHke0*i};OQeAmFy7Q#%JBDj6OFU8k)?#f^< ze%mg(+jY_1?-d;}DLP`pUP9|ac%gkT>~%HbvsV=lkG&>V9!BwGlutI+xi+EwsK~8Os}dArPBMswey-xMbYxa{@~ljIZUeL%t%;MeM(?@q zkgspB(WXD7Gor*Mj8JoeLv(yhpUs(H*Co$su*gEhWVj_3QhVICD%z6>PfQjMwkaAH z4~RjPiV;Y{1~g`dl={xAeJ^XM=TSzwvqlCM@NJFlobsf%{svHti5f&h*3%&1tO>$m zO*cU5QR?Yf5UJwz8*vx@=a7FJtX+@%CgVN@w)dUyAs^TH!0M6dv+Hq-uE(9I3ppxA zOpb~X3-MthXP2Vw)0kW+^0=bC4;rx$-+6E(Y*b@h2rhDKgFGi_-fnxs_jcQx`r#YC z-BzpKZX1Hwy024CXK73?#5&2tZ`K;?i{(z^cQc)mMXR1xWYSsoUZ$trV;d*O;7)B3n@&mUB`FoI({1UBy~(o>X=xFk5DYi3-$$M17{s}YF= zp&X?nCMF#*F}apXX#3$`XyxOA%>(bv+3rrvAGm8%&W@by7hNBN0DdFApcK3**ojub znlMc4jlC&Y+rp6IPW1<;UG}O9w$_(mriBH|UfD3zX(%vy zIUSG;FcgsP!vRry&KZD|0nP+u9!Tdz<~OQv6eppmfi$Uz9(mo~+zzy1fI*_1I~4v1$;Hz-L$;QcUmv+8Kp5NJ*Npn*masX1L~U zngJ53)Qf%(bRWo)g&7Eol1VdkAK)Ym-#f~8 z5RK}REy1Om-ZA5$Tg3rv7RE4r7VPQls|Pr-VD>qwxu>Tp8rQsd>9RGA z&@(r!JY+9t4Ng4d&Q?Q{y2m1;I+zx_IvR3BvxB=;)gF{3fMkY0qe!JkBPKl>v5?r+rV$N!W){=*EiNnqYZNVD%Wca8r2j zxMWRmBOZbMVL}Jogh1G?)c!nnloi~xbz}YjZajHrU-`dUe}bLD7th@mlr=W>0IY~M zoL`7&!*UVPhU}BxyKe!-m^L6RY*l%HWIkq?G~~}&t8wEF4nU^qD$Tpaa{nVd9;sua zuhm)HgSvO;I^eP_?q&(^O}PCEcABMbVw#!8t6+EZs%ue7PEV*(4M4Jh7+?wo=)dWM zz)1V$>yh&EwNFGo#=jrA<%)^8T7NYXm^YY(Mwx7l_bUQQ+9LTn{ZRtui`^9S)TD*+)XBv@WA0$vM9 zfBeqdsAPH2m6+^DAQn>ZIJ~21=O9hQLh9Q7e<&Kq9AY8o7GM(gR*jh%Sb42^IeF%6 zw`5cC$nltPf&T|BxcC)(+Cj4^^qLGdR2dwSeDO~Z7v4YItNbZ(eq(VkXF+h-do8a( zdI9e<^}^RffH4JO=WJlo62<_NmM{rex{%)viZKluG5qb9HQB+iENP58r4wl#>>+t+ zqL_4d`NdJ5bwZQw&a_MCz6;R4&d8)`5!?=kzcU|4mGAMJG!}!G*@ScLIbbgs+^DXX z$|uxc=7apqiNrijhn$ii3TZ|?qzMToaWa1Y5s;D~hETQh{x5(R;P+m@@tR%@_zHfr zTwVoauHHwz%Z__uB0UicIr;eVzZ9)dV3u-t(oVSB$3qL%v` zkdEGOci`G=_U#T8h=xno*@sHb0sI{mIn}?lp%w0<{aX~WZ*7>c&bp*m?{2uzAGG`3 z4c!EfmZYXWvc{JEd)Jp7LY1E z7E#H@0Inv55NWQOczsS)xY-!MjR1(hTSK=1EE6iHOY;=wZr!QEsEuOBC=$KB4I5Ps z^5;k&PSh4P+d#8>BZfg5RS)*vN+4pgJq(4%NwYkN)(d&_F2w7vHMZSY#kyt~gdXA>r4J*WyPx&Kh;#4XXcH{-^-}xZs%mSd&!>aOTY0CtQ71hgxG3N6NXj%k?sXM=)@W+WU-?#crTdj z2*l`TGO3+1jX zu6xi(E9Pm7aB}!AK5GH7-L1%X^AEU{2Lc0MIp&$_@@s-g98PHcIpz4aM}ylbNr>FS z)fkamN`a-zEn7e_=5ipZo={ryAkfHDw2LkGk!Z#Pm5XRj7Fq7A;BGdOGv4`G+@-)M zKXCU=`u7>$j8ClIufWQ& zjPq>362KC`ivULeGJmCjY(%5MN+Mqq6Zx80$hibx5*kzy3WL^$3l{nAo8{{R@$oY| z4z3wmzZa1>E+&Bi94G4NT2oZM6FY);*7BUuOy$`2X#TzdrF(F?#XE?aTo6pI4_v&E z`>!aS%tn6{<_37@LVP={_OGQk-FALPn^_u?k7(F*Stk6Aqd05}Ei$Kzj=Y)5J7PhrO`|f5c=zc?X4G@6MJYMyfk}r<%;! z(iX&zt7t3C!>C5SU1z=w$TZ!C@?^@JG#xYW1j_*JSe+=10J3!t0p!4c3SblvHZcki zGH-%&mD2&o0uBXa_Rat#Kb;B4JP!lpcP_y9MBXJP@-8tsVJbB8u+R>1X<{`3X4grb zh)?;AEhu~&j_a&xIm0mP%;q)hAH<{|m9)h^Pb-DPlD+lWi@x4>eq1&7zacFVogf00 zKO~my9M<%2>LRXGMa+(Yn2ZR-WKBb8`?YJPFfz$2(>V$Qi#aPXRHkGD{W%3#rBjqY z_F}aPGw%AP5dTTjSY1k!Wr^{zmZ>%ILKXpI>&3!CoMUO=n@Rjh1o#svo0 zkd(n%OpKTa(!tK+5k#xSh|G%}j?!A6$KYuNqBGq_#KZ!q@@?@Rcu+O(1*i?tJ`)q| zGcj2V5E>T)gx1?>s@yi%=b7qdiZuo!$+9sYeUT$w#`(Z5h7CjQZ#L_*q*%pKSYznN zKRmOF{d3ma;C_*R;+ZyQy)c^ABlO7pb>q|?{ptS5GG?)Tk5JERA3!>Su zhKcGpoWdNxXz}G4T{|Mv#&qpg%Teoy5#tF^rNe4ETXi9|c!fkv3W=E9FDA675Qork zX1%m)`M_i@ZU?{}0ekrooJCjL%jy)*vpn90t)!DS9BciCWrt6wvO~*qI6?6ny8G{U zZG)q&-eH`K<9OINeIsU;XE7k5Wua!2D^o7Ul&kOV7LOSt#uFgZ&}EhDf9i6*8i|t; zk(i8##NZtp!+AI3c;CX)70Xs2inOOQ6#vHXePc{HGf!oj_;-{u(YJJY zgXh$QmFjk(cRYLfKU9Nk_XX-Z^j~Cfx_IkXl#} z+H2aC-C(-e*Hzxl{QgV{cZN@sfSgA*ImQ8OImWVm4oJZdPQr zrM}KMB+=wzN%V&-|MK*lf2HP3d{{X5gOY#0j2LVDBI_aK-)`zb3%^tSG4(?D?J+h; zzA_;H0C2U{;{3Ajd3|nihY)=IP0sYZNP{;IgwzZEwikXfnxEbJdXjs;ikg=7A=bIb zy~IN5hUVK9Z4;6}Eabcoj3FQnpeYjzIeem7!YdK66H&gx)c!4mWcmZYJL3Vq^Lu^L`seBr-2C>5qxY z>Y&hGLc~J*(2H{Phg+1s#&h^Z`7k5}7WGd7S^bY_$>CnFD2Yi?5|g47+Dq^+w0=$> z+7Xd`fsKFqa6z97vX^rQUlAJKiy$q=^fYz&kyk*(q=1OY^H4(Dg@}aKZ(jQKq;gu=`h{E(XZXFPw;rTNP?5$TE7RJ`4tNeo$BW6w(9HiaIhCNOc*LKPF!L_I$5}#EyA?yR7>f_#Pv8ttGS;0=~*c> zsr~eJD`1*Rta&UJT+{-_?@^#4HxZN0msp6}L`P^43=|e}e(BMk_h|hT06Gwn{XT(T z0C=Ofqg(1u++IomzT0q>mMim|dQU>YpS^-3CIv@K^oK&D{!nPM>z8Ajz+U`z)V6?l z5wBKq2PX^N>49Wzz?~SxescE!HU@b6QfA{R==|i^&Dc56S(CFcITeQ=1E?&sJ>VQ* z=^IWO7{4}?G-O+$A@fqbz~AVZ)Itz|`b|jpBlIsSXU35T;}0Lub2{pMZ-TW2H-3}f zp!)31zSmo}*8$j}i80DaU$vRDj<4Wb-s=GHZ8rc_7FGk;?nndJr|R(*gd!%#9f^gU zA{3L*iZzC15S$h9Kj_ZV*{RaE{WyTXBjDlb$-aruaci{o>&YJOcC-~mWa=_F-e#r- zTx(SB#$PWw9N#_1S=GTk>B;u1;+=!s5tC*@O!Q#k(y}Kdq_8w^ z`UiW$cU1_gA>LP*@z>q(B&8CYKzT~}?S4o)m=>Xl*cqVGLq_Q9kR)m4kR)m4N<1&G z$GMbu-RfXx{+Z>wxFYZF#aWb*GiP^}vC%p1Z_P#Z)!3z$+wpiD9f><&dCtLS5JR|a zN1$zAPRkz_TwFK9{e|js7S6|#ejS1igH7#L-on_lS)ie5Z|n|Op3E2I30x2)#<=@$ zr-yXp?J@GZoBe4xoT~ORF$Uw_<=aCP0iB&0O}e|Nli1y0jVoiBiD_mUsVRD*@9m?q z5m&)w9@CX?B1$I$%N+zh{?D9kn;iskc;*fQ4#_d#G<<*0H?-iFXH1;|O&pl_0*52csJFOva4TxJe^Jb!8F@TA9rcCD^P4lre*!g#EDo)?GZj&(Kf)9m~`_D zk>|Vy8ZjJu1_MgidX0sgc3|RfqsIER>EJkg$UkxF>vV{Tm+8>)3hTEPhZ}5rdi!Bp z-#MdC+Sjd!zvnFnz0=}604_jQGBzC)qnKnOK}-gEVxq+n+RF$hG#00mb<)KS(QoWY z*QeoVKf!3i909k-`d*Gz%_~>*bgh7qJgqj9DQBv5SaRmibgMbpD<5J~KE!0cAhf5D zexZHHld8igq+U*{GRi1J81HFPb(&X5#H5gjNg)Z1g(S2?zj(ntP9OGTvR^}bnyfCL zLL@$|wyl1af|rJ}X`vnol8qU}WJ3Tk{R#$7gjWTb%)R`BNow|Y zL@4XgN3J?mP!3G)qYw;Lm9YtCIA}C_t`tISEAritev{qbLhF?TE2u~7|G9=cUGNf+x!!ARv_g~gS8Rjj42Qlew zJBwzII`Dor>kNH2%kVc|84{B+Bqr@T*RSQw&X6BPB;7aP({=vHwlsG0Jw?dfHeVK@ zz39w1kwPa5dz!BZGu5GoUu3%BTFO$Ro=quBS%eoNbHawiqzH+HoIhySJaze%&<;K9 zP>%huS(EbQ@*Y_87k!t5`pKP{LqE%QpjWoUq-=>P_Eg8G^ltYm5Ha_aLCCER$gxHD zc=sr+?kM>2fF;Qs^Nc`O%U|7T0cb@7*oO(d=*bA2zGJX~@o6(vL-h^dHWzblM&oxk zgAi%slxw=XnPO2r!5xM6PECH3Tz(Pk>(%%pCflCOUhdQcPiqqaWS{EWscBxy*n>~4 z_NyIYIt&5R)CCEZl5!adFn@96$_k8G>YbHW0GZ!c0c!yF0kS41q9EjAIAWqHB^GkR z7{`T1ovF~!N}#x|*R_b-BA_^(8f0}<^JHB4)-}cETqf$#t%tHZIDLkA#|b&U^n_Za zmPq<0_8AwTIK%3Vg$otNnt2;@mzVMXa zWKCDV-pnEs)7@b=GjGd$tjSlwKv}`Qqi%!s?ok(CxU^--lE!9#EmJ{c4AXNP62$ye zYT{X_MW*p=K<*xZ!Yy$M;0VBBfFl88fZ&P*^KmX9YkevTN@|^$)H<<{!)qFZ#`+hU z=^OcSlc`?TBLe6HC{$6b1P7+nkd>eqLuDup{nOaB7Z!4wyQw|4L)MOc{}AJ3&X0xd z>w{XERb)~I^`NezL%gS@CP1U`ZDUj(Q38xcagZ|v>BXwwC5X(oxyD{o<#)Saks0*mV%Tf3x4IMw7F{4QQR5Jk z7ovpru=d9n*~V3NbhQLZchB8EyS{VX!H$EiBi$>DOLup?v;JszT%@flFnUz{xbbaW z!SY|XzU5A=aRcwVv)&CXTrhWg$L`iQaAoXO&n{&e`0^32_~F?r3u$`5%y2g$j)EU_)mhxhLl9hGPlmPQ_X`%c!QH+#kZEEX z$X&}1UAZ`xQnz9i&Q8r-cC{>Q`9CO0K}=2rHvLkmQu|V=Qn^&h_jZa|CRoK7v|;+X zVDn%bU}-2=FwG@^{3HboYK_hVWI0jLU>Ah@GSuo;86fjVca{_Bt$a-DRpx|_tE8=PHVy1Vq9(t~(w_PqhPQY0UYJ}$p==D(kP zb$ngt@S}M($-aTObFL6e2x6pE?PF_7)x2<| z1y0S4t6Q4*v|H*4%Vk=|X7|U=+Zd*?3zlUw8I}f9hXm6-29SydOkC7DF1R~EKm1KG zoxc|Vegcqr1lKDLzZw-H>$$}ATZ6#lAxok0_A_FS$xdX&l*p1A25B$z;l{$&`|CJ z7M@`Zx5C=DgYcV-;SAVNN)MT#dGsz0>i*uK6mv#^vU06^gY1Ee-|m8C-ps&tv#x>b zkSLk#5R=IcF%cz%#(+X=do74kOv-!)+`+J)1*`(x3|I^JIY8#;^MFiGI|^7vC}J`~5eqprh*4;hH74q>&h-Jk zMW=0jz7zilcKx{1^4(b*-cQa34{S%lJDU(gN@8gM#h9o;G-N$~;TpEwc369hAHT_OoC4dsYocYFja8Kh?HLxWm2D^@KLLD$q zY{_gVUj$_9z6FqJ#Y9NeQ4*e{g%gt&PE0QB5E?J+5E}Z}D~r6F#145yJ3IeJV8gsV z$hyS09Ta0ABBdEt92*wWp(>7|q~EYhHG}d1I8a~XH*`09Ga1imen;SRH-j=O_G_^A zU2aSh!=4S>yNd12CGD)ybV+lBEoqL(xV}`)4ef55>0_nizt?SlLs#l&QE<}mh)KgE zhBp@AeY2v4G!}A>2lhEdJ5ggI8cJA-h7vY?bJT{{y6|OO9$kMspu<;I+oQh(*6?-y zRy+3E4nzt*`zbUJcUp1VyTI1~FMVCzjSJDP2(}nDf;Y^g=5`mix@6$i&NzmNd!jEQ zqP>i*^zqRvi`Nf#t0SF(U9MA(tECItj%CF0Xk=43cSj&Mr+s%p#{iH9K3P7kxb>F| zQi34$Wu1XdCdePaEmjad;K3jzt-o~FR(4{1QeT`6OrFvze|!B9C4+iykUEPoHbr&> za-5ub(c)o$Z~3F7@GQ3;DSX0>1tf{hncrKezgOJ)93$M>u5wB7S#sKytc=crodY`$ z_7d0z*rl*du&ZF>uGRjE0&WwqMZjGG?h$aW zfcpeIAmCvET>>5zuuH&G0-gbQ5S-*Nh=ZDq!B)c7;CAuJNbuO?ttz{vdq5lxTY{=D zgX1VT4lR9W^xEJKDUbo{7rEHZIsD$zJ)`G`*PM(w0E%m@DkGGACFFvdWZ9;JmC?$I z^7-NBKhR&%nv>vZsCcT3mcV0KvTOr9mB3R`^B=0p*9Kd^i7llyF23tlV@{0^*LHNR zKh3=^LcRMSH{W$DJDf+r_Re#E?yPK|HNI_U@W_(#S<%|o-!gigLj77W5@pvRCf&1s z7D4#Z-48Mvvpuz>c$O^vf{R*(Wuu| zbJev|a#zx&pxut>bJY#AzXH>S)$_3zgC2Hp>4LuH@d)^lP50bmIaaw2hwneCupPj} z^==OvjL(Tb-W@8~gC0iic^kF?))*dgVM2}J@Nfyxu83{|I?7x3jdx*-=@imrHxP@#G6|d$6J~kV_IEg-6Sx5{Dg&5@xt;% ze7MgLEsV(4f32|zRLiqof!qV1dwyzYXHIDiH(4q z+kO}DLcpH@#sGg0SONGk#8nA+Cg23X>41nU!M)0p0Z#*?P6J#7SPRJeRc8XO0h|Sx z07P~ZUj@WeB5@~RJ>Ygg`o~@S)b%BBS2^_?i2(8eO;utf;H7{uz{P-7fGDWMW&pT2k&l}L6ggUf-3lzvNoXwOYz6iuMSDzRa<}=H z6^)8XVj+iHU;jhVF4h=!xdCI$dCpTB3ppX=LcVd7#zM}Gz{KAz8Vfm{o#ca8@J*m( z0*$iH6^bDw*!igv{B$=B$KQ;XvIik(95xKSue{a}=DnEe-G;E54aucmsB7nINM)|l zYo=d_jd%~jS&3omzaq2ZnQNED7cb?Tz*nqXlX;SXe5wr+#h&DD#OTxM!|`vhG3|+f-)EaY z0uXIn83^LwM7Sd8USuZ13wBfooQola7J`NIA>;&WXCw=hZ@A<@ce<=GxW^FFFlWYzc4=>AbG&bRS}Me>9bW@e%kp`N4x*EcHyV`+i)v?Ml*FugX5 z+zu9C9_|2Sv)KYT0q{;h=Ia}PjQDOOL0E*Cun4h`Qwzor8rR2!hAI!%K@0B2f>3rQ z)(0F&uZ7^4diR3Pg&xOTr&K2w1>Kpr#%|O5RG;m@Zla69ErsBg{JI&*ql8}0~z-JFU#0bx(G z!gn1>g4E+jfkpTe#)KF5LPaAxp?EXciD_mUsbu>;DqEYLdys7GB%d+id%;e}YIaf^ zRG_+(lPbt?E+Ziuku{8AI>|<4o2Vv!3v5F4Za}90+kh;M@1ej&Gfqr2ga0S4gM;`Gl|ze zE-NxKX6tTDJ$aMrl^_ObeGmi~ts`piXbE6UdiFjm30E4!1a_a*A=jd04y8VwzZSpN9Qjf0#@@gIJVFR~40wwsc45+7JAlTVfAu z*}6Hymydv@*v-jPor*8XlymgQ379W3CCg$m2`~_2Rp0hKK#IQi0@CgKfVF@>1Y8Pu zA0Ru<`vF-l4*)WI_n~H`&m$&%9SDA8J) zxFyN(xLDhc0p&Ye-&9TmN*`a6%wLzhIy}>trn)r1ba&xqHkzNp+N)m76a8<7-NNoojNLQqiwr2%EozVpJTtay6q>*a zrZ=0BcC#t9n@y=S8{fN_X7lJjs;$kVxA{KA^s{jc24wBgfN>Md6LjVY%0fp19tW5Y z7yU?Q)ID zO~?}87SJTVbhU8XYmqdaaAmYiD}-NwsxOS;p|W%J(B%>L*Qynj9xUHk(D8Ldrhc|} z#Rrvkz48V8hCX;GQtu>Np(t#PmMkTo1Boe*_3mB;fA(>Bsqd^fqqdH!Mg)q{pK^0A zintZgwnxKlTXWi;aiC?4KwOHVb=Gw3j-N2>qR5FA(em+ug6n^dNScG?p@QqT1A~-R z=>|LTmf?(t7}>D@oY5IRXGSe{Cg4Q*{*HGFI{qTwiU%G*ii$eA3feb;(snS?ysfkT z_vjRMubG_~JM?_4U>z*qw))5zf3&<^zAb)X=h&g{KT03p@CE`noefcE)2)=(Wo=*pY_x0B&(wA z9FBF-SBf#?6zT&gMrU6YyQ9vsp`BL`eJ}{Z-|s{vL{Z#bJqkPD zulVz65381~Xu$pas^eOA*@{J?L-ZDPEj8k}aT6xh;*q9_D`Ywwi`9-_cv0+=P|h5| zK89xDLQAjs!F(br@1IRVUhP+Jm{Imvufpv+J@wMwL%7+Jqc$4O znT*#Oyr#2IUC9~7=)rqXLNv4RTZDXyQ|Lib24zY9rWWZfO+6hwHp_P?AVwPpT0kX6 z4FiN0&p8Y5GC;gysb0Pu0r)BW9tp@k1Hwz)_3D^#Z>1g6cz&b##5L^WK z13;|gCmsfz0=NxuDj<0VV~ZM*9!2964Iz6A(GU^~sg}J{(SC>Y5|bT143VeaHzXEv zzK7T(><={-a#o;3#UIz&#NT?4_9>4>y`cEJ)uVMz+4~AUNKr1>IsO@U(o-2KKz!Gs z{?5L`|0y{1=QuqxDaYx5t}smJ-Q4<}RbW4!`I$_BlWIq~`aUi>6Qmwj8syd%c212< zU!JoZJ$L=V-PkKS44rvlty!1{;iGN=E>eP{o9jRDmb{>}3y&%Vl{m-ZNX@Vs_(^S6 zX=u7cdxq7N#ocIy*sU(f;%+)vcA2lk+WU6-O%5ej!1k`2nYOBNMTQ_~l8jhjK8UV_ zE!$`=c}$MK$4K<5rSmu2DUESAGr-ibIyK#|6<_Kv^UJPa5MZUIL-S~AINLgXz%-NZC&2!wSHml%2|d=IC| zV&`c25aOXp`(fz~FyBd^B4I{kH5Kz@?zKqL!i7s#Hea!*NeyZo(l}u;hUq6CGta{{ zaT)lMd4dWmK@khXh|+$7dlbJu56_~$A|~o9Vj&J{&I^i$;Y?v6B?kUR(J(YQ#6oIE zwS?u6Bw_j9q5Fb+QIQr|v3I!qv6fsc+!w_wXV-5Ab53wqr*kHsF)ZCZ>=&Z}*PgEU z^JL-Ai}db~$69tGhDgg+{njBm&%Mm%Q=9+`Q=aKzY@|Y44lJEf9|gsjl|aZ=rne%a zvg1VFlwD}KbCA8G@#$V! zhQ=`MWMY1QvL2NndhJ5H_Pq`K$i6H@O7Di6O$P@ zv5+$fUwTQ=AR{R(&)w(dvHtIgnCTcirwk?r3VvZk8$F~6cpSTmAjqO19;$k?V0WFwp!Pjas8_@J6Ky#;Im#h6b4 zL3SPCN$INDRglI~Z`QbRM^VBrU1i8zWx4+mRhOsR6T`6m`QxX%tf$IaVr3S0!*g%K z?G;%205j9fG_HevuvZ+;uDWK?>ZO&-F2h7aI%&xRqJZhClOAdF_{a<%H=T4GQDK(D zH)U62XNxRi{izPxUHNWh=Gi0FMX!CEyUiUjd#8_-nusfG+^X0Dl9>u$UJmSZ2Qk}?^|!`^kLNe52;Pv#`22Ry>_P(%eg zcCQU?cn?#%>((5x7in?oW<#7lQtv)Sa~i5!!%Pi3_N+Od`xG~O@jUJBb$_G6;$Bkh zTIX}Q^L7OuKuVmPs^A&Wue9uj@}|%Wfjw{TuDmDW^V$xCTEZQ>TeyH*GNW#${_MVU z-L>BMv;aHd0~nvMM{U@X7@vv@uKyxphMsC`!S$WM20o8xQq$r`+$~$$t_?aZOWdEU zl+DzzW6%1C`*%4?BQ9RPzf&xcl4)idDXjmb z*Zov2&dE(&v1Fx^Bu#b^icg;juewwyq$?C>9 zYF7HKv!V7jXZBXB9b7CD_GYA3%&1sxx-)ivOeniE~NC>pd!3WI_T*k2V58X<*+sJn6YE7~-T;ZAE{65sP03pwdJ{^_%C z$Jf=CZwMn=z5ix14lT;mu~5N>2f$TzKb=#D?!a%oRd#BaKg7j-njX>r%C=|p()mWU zyZ}84w`@A^A!YvSGC4gP3oGwG3&!b(VDo`3MzEAhBMOQ!lqdX5&35d6$@2}kpX*n% z`n0$gj_79Fr@Yx&?hj^ZXL}BceV+XYJfc5=OORjoA04n&R{z1W8Vb7zb_Lp(d20A2Prr>imsbc_`*N8ku@LTXahwB+wpL>y=U!m% zD%yP-3n}H&KNXGnBPN?^7;~OFY)&lX+yL&DZ*10>?}E)K``fmLDFgDM&$g{Y1?~B* zPhmbz6>4F_=(^;to3J{cB3lJn?El8+bGd=iN#806f-*>rGQHg@$SjIz%c792f-I<9 zCxUnmDlEMLx4l+lEz-@?t@stJq7^}=Sf#gZV7kzR-A1+Mr`FoIyWD?b?h(c6*U+|i zKhjd&aj>NVZMbRl^x*p6U}fE?cd%Txd+n9Y!43bWsI~So6VJ?`Tfv=cP06y&2P=Zr z<=lT>%xG?7cuEv32R06?h7X+h{wS}0t zzq>Xxa3`Lkd}WU5Q`)Y9AXLH};9$Y3;QCX|$Mw#rXcMFv7B&)4RlX|N`a2{jTDp7m zOvWBA_{rm9u(mjxE3pzNk zjGh-ATF^n^3v%;h*jm_GD6=^%bif*x9cT@(qhQCv#z3zG%hFw`<8YXwtQIF4CSyhN z=NLa$$zZ}nm%cuFSrB1RRrezVvb@S2pU;g)fm_`CFM&Z@Q8O(UB(9p}#K)RKn~lv) zJcrr}**AyhO{dqozd$xxrI_`JL!7M%Z#Y;T+&878Yt2NINh@+UYg4hA7Kk{!v3M}Z zF~(ASmzg_E3%d3BY8H?z-jq`v9Ju!k1aJA7TE|7QE6V3es&ANtYC+b@kgWziU`~$K zAm4H2b)8qCr5`DT>tO) zv85RsM)70d)+7+!YE@-R4M$&@h88(`L9k`MDHm{_Q5}@;TmLabRwr}SGyyXI>zpRQ zqs}V)o#ejFMeMY^BikrB&MEdH4fD*nE()|++rmoUnFs0EzhunH77@Mzn276;1of04 z?qM!45$hlGX#0VQ2pvB`G3eS-}uBLwW{56 zsjOA6=F}lp(ZkaAoN?oMRrs_^m*c5=*>Z*#(M5Ey7Q$n(apUOM|KfdYVpb~F$Fq4} zI5idvn}2gG@_gRs%KwP6S*9 zI0^7hz>5IC2{;9iix1NPe+D=m@KwMWfPV#~|F-~V0sa#ZTPqVsAPv}VlsFBLzt04m z3m5~O4_F1b0FcV~O8~Lj>MR0W3V12tm4FR^R{=Hx-Uzq^@Ge05<7R}VfS8^;%K@3! z%K?i4R|1{~cqJg8L%}A6#8kl5fVF^eK%_RMQ{50Tbz>R?AfJwj#Ko{_nfHwfPYx+h&#`|SJ zY~xbLyEX$phTqsUk@y$jR{)Pgy<#?#I1vyBuM*P$ZvvbRh%q$rN&Wj0z%SxA+xOQ1 z$*}>9`mzaxS>$Bb7hiK1M9$)By`A+FXr=oV$=ZiSHhb;po_um(+x>bIMb`iQirBq%B!Dh_D%k z)$El5i<}XY>E00hJ_;YqbxsGCeY(eK9&*yHLC%$?kp&^sJQhx_(qt7VEPZmy^nK-tbr{>!d}xdQ&!`x#>^ zVeW&&d0sb-b!VTn0ZmF}lVWPQqW5EDU%;6)tf`IwCD9Qaw|q zoLCb>&^gJwX`IGMy`S#|1W6foe?(&Hm;8}5bDbbP&5Sjh|1m07`u~I%KVwpPoN|?Z zxfa!$kumyW=4hC)SXy|eBK;>k^yc#quvTWfBg#j%oY=NEfa@gCAlnWER=-BY4>Vgh zZd>4P+g@;gPQm>nhwW$?QgHt`pv^hJj{`mc_yFJ`-~$WppEPjT)~yFV-nJ{p7nnuC zW>E=iOoKr*WV4{5U!s)y{6^gAD$Rz<-Vs*6YT{fBw@)?Er!o^)Pq?yWQB!r@#LA5J zAQ94A1hxP>^-e^A9PKn;*0QXDi&#Q9MhGL(Dv`Lq!D|fG7=E_~78T&_6}!!G68P!d z4tN^i9e^C{`J3tEZ&u<&1dt7nOE0(LDaR*gDeRZNAxF|K^nWbuK~?on=)ZILNRCBbT?>>8G~!{W;8Cz=nqUl(;ryH z>^1*L$|JM`-4_?fKq)R_Qe4DB&cg^Lv@VS)4i2=93mkOE1zPf^D>laY8t`mDi2~*D zn7z@T2p5{}imVlG_SsYuhC@-WifjfRf?Tw^&#cKZW8;s&8pCgQ$6*u}q{xU#kr9(3 z6IvI-3ylj_?z^2o=6+A3o35@jcj}k!!D7I|%JoBxlk8!GA{wgs>KZryu7Pt)CX}zN zZ2d2)p|?}ux)@eg=|uZ_CVq?dm8DB&-2!V27n=Qs%*yeLevu?+vfmLn4`3dl>xo^T z5z37>9-uUL)KToHF%BBieW31%_>HP8?gR8}>P@)a1beA9PBP6*Bigjn-o1uRZzit9 zQQ%8a?-SOI8B?{asY!HMGvkYz852xg6R;kWzca9bLfgR!!F`v&acKF%%4@GQsZdKU zj4PS1E<~-L*EaUcPRqcGeb1*wk}TeU2okN)V;mg#;P>n2#h9}4z?Ykktl&Hz#liE8 zI6J7)TvTwwEPU0ZS#>;59SuLy7I-Wv)fR+yu18w~OxnjS9`+Lt8-(Iok6)>N>rwnN zCLgY5R3(kA=SVcEwQ4NjCjc)1WG}D~aEAVkZo?Ue-L$ijjLcc)!~nrwB^UKwjxel49A5`JWbc@*RXwWOCI_)Y)`JNF)0F6@0m#l8ZXX=WN%z~(N&A2I2y*3AQmz2>t0sB|q<9h%E{B(X{-!&3q)+1$@| zs;v9Kc8d`s*^c=%Y!~;~j+n3=u@KKJIzqctV{%7}(6}8}{FxVlvcJX1E{5CnKJ3>6 z+1Gy38s8~>vR*mPU76}a>`p_(h594GgEvMHDdBb2;E$N@-v7%^&zNaSFU_bTu&l}6JO)VVmHv%k+HM1Hv22Xa>sUty z(Kc1(lpBf3%~Zrf4%eiG7SmYoH^rBBC94A1nTqzfv#OBg!a15SkKzPO&{A(d?w}si zY?Cx1Y0+b|s!|MD5Ay zE9+5KUx|g()sn8FU4`JpWJQ1>WIQD%N8%)G2|gfUDcXrYigw};`_*4zLa-Yams(_9 zTO|Wf&a^MJ_$)rupGz&6c)8SKv%-42FCo2wuu2Z6fqY4Qb1*{7ri2)h!q-5M3%#T2)Lw&Ml#Iw=jgfp+b2_vWZ^{DZz#q?9~(>0k4^TavD}23l*Yn3mBvCWgd4r_f{CKBE{KJk7lAQEp7WB%WHXV3 zWydXH*8vlM6h4Xh&U^H|vD}IX`qNmLcxfzOQP_WPWBG>qW_n|}HcMkke~Gg%qsd*U zjA?$B@3FDeRg8y%s&>&bdv{NI8>;h1c*r)?yGZruvmNPO(?i3$B{c&`Z&YCr-K{Wv8}9!zx2AWXf@WBZI}$VsjU!;c(}+J}Yz`DP zuemjSJzrwS^=k6FC-ECYG{x_`5p(83PsDr;km(o&CcuAB*xsx~qVJ(L~oU#M^P{s*x2u&K#G1AZCv zK9C|5#M_3iI*%m#v0@NEpsfjvkbpyAgy z2FM|TzXDze`kR22fPVv=3;1`yMSyPu;u{V&#wVHq-v#_U;6DNH1w{Kvyrbz%<$Y*l zvN@ftO*W?!lZ&Z;tY}>3B!-i@eY*+{O zprW0nv5>O`n8bIN#<&svHQ!|JWp~m`85?EM@>OSPPv(A#==(ElGLtfFKBBNgE*XsJ zX33yXcY5|(!GCqPR>1W^(fL*Y6Kxo)a~N!@^V))6#;BP$evt8KY!&4aA$#ujssSg5 zG$y>gYQU9Cnsj&RDx;vEuUu{SLPdQOfA4~|Pd_ou?AR}Ztw=TS^i>0Uz!qI|Usk6^ zBI;hR8<+-IgESdqv>F%>dbKz;5B{FO5YK!)sfYUQ;2>F?A|_f5V)9&p(5TB0nmrS$ zzny83VZKlg^KUMX>?IYurl2dp?N+>pxqK%s%)~f4-QA@eaq^nCOcZel7J@u8J9aZp z0C(2pBryQvxq{TNo6@#DrFi~md_j~6LxJH85%_NcFsgyW>Olz^WZ4Gah9xf;lK?^v zpc@T&@>C43EJyOh^RSnBoo@PB2kcpkWjQLTwcXbF2Q@>g88;qhDZBCTNnEOFdUt%t z8uC8qkLf|}4&=`kOB0}-3fly`pw~RFa|NzPQZwdC(h3owr@?z!4`~!pYg6oRwo+2p zzYI5J=}nP;L&yk&Ym*>EO@kd#$6~f?KHi0Tm-!O;L*`4wLe8D=_@ttJOJkyhV2C`W zJtiji7D`y|W0SCt0uz6`GzP`Qg#EROW#?`eMc!NPr2QFvKcdwABL{go8o@n0zkoxo zGXz-r(Fh(jV!paFbR)kqC(`#nqp;q!NLg+Auv+8`Dka^u$Tqn4w?*EAoKN>R6rYHi zt&!LwCzO3?h8FdcP+j+}?O72}hnOW=-O6rPX-?ndodE4rShljAjrb!bePqeL<`Oxq zM)nXsqQ@B1$lRK=MwYQJG{H1=)5?B@x|CMNI+s>PETonSpI5XmAUH93N{%7&_=JK( z3=4F?By7FLLe4GP6$^Quzy7td7xAtBv@)h&TG?+EhV6*0czI`#`=(ma?W_-CQFlh? zRK2!X9Zpt-ah2S{D{Tn5qW*4@*d8-LEGi!t6l8!Xm%c!t6uXo9OF2<*-45T#}`vvNBV zB>&2-%wYe30+kDqiOJe6FGgP&etx zV&6W+5Xaz)B7U3!OvH~lz@*N3FeY96s078BJAl~Y$7x#pAf59dzdP@(I}Q}qJZtww z*k%5n>kyq`U8*9xl~25?wtajOTgdv>N%rq^y7T-x@@R|YEVt8OsQ|q`#lh*FXSe*^ zP4~%y7E=PiX*W;T9}ApZ?b|?Rx=(U-N=C6o6sEDe&hsyd^C^Urhw_|DG!{~a7++O1 zh~*BkklGN<5b%dCffz&?U=sFQ8Vm8pJLQ_kJMXl=jLvhvJL$Dvizsj4Tm9)gnSSX! z|Ee%`C2qbuKgdnpXkY`ki~Lmj4z9jD);)+l*KYXxGxR+*RpozgecjzjMccN367y2q zo>>anrZZ!TL5o$2?8^z*Xi*4LF%`|t`vR$1AOJm$Q%`|t`ve%@(hsN)2HZjAi zngHAGW)m~p?0>-8o0ynprjb+F>kfyXdBOOi_{!#CnPU6g3?-ibPc!_ z^B(eXEvzxBJW()%K&aHjdmU`V1^#_Nruzqg6mGHZnTP=12UrUDBS7Zqen3tE-a@U( z6qA@tF^LI}3ynN3v~+>C?X^p8M-&(YFqfQX-HaC3W5RvWc6d?u%3`irj8P$~1oYC^ zU0x_Vs{B{hg|b@hVQy4SHbLp!#Cy6hQT=VfrwftGeMjo2!AoDqNCA-vE8k7HDyu0< zm39n=Tax!g6QHUu)#06S{zwfdqCkf7xM|b-xX~GdRe4Qd^#<>;K1d4%_ix)cD|$R0 zgBUhF*!EIE`L=@V=OYHRi>@^vcL#TpX&hYtwW)Z_#(8CzR97Xh3YPD0ejTz%aod4l z!Dr8*?>)$38JE$g@lHDKFB^_~VHp@3`i?Jz z61^-r-$_mg#4j}0;CAdTxc)b|eX2Q+*OFa_=a=v!If1f`$|v0)qWiJh{X6)vFUZ9t zL=rG;g7&X4<>s1STr^j3eH(-2%Vl!~*SFwTc}spg*744op`w0*N?<}h$_be- zD&NsOz}?|aDXg7duRe?&Ss1ntx^;zShgKkYZDFznuV~_uGhUh<7*-Q>uPrQpv*7w7 zL|*zhVm^)=v~hiQ(WdZ6H-<+aj0MM)KP~0Qq$UbFUdP>B?u2j-Rw)ou5w7FH^=U(~ zND<{}jiU0(=%|8Ey-QEvkG36Q_vtB8;hKf0!(c6SyuN0c$u9zqVvawDU|vDCGY(TA z&(pb?&iQiDal!Qsbl1xk>dIowEk`B8>e^za42Pv8MUORq5n@iH{I{!*P$?PqTO=*o z*)r5{bK844Ez{_w^dK%qKF6&q=A&2Zk8!6&cpcd2(ecw_ZCiuo+gji9K8X8_ar@l{ ze5CE#lAQQFsqC)S|Eey3ueodAt6nzutciKK*vnkpgA2`&3#6Xx@>O1MrgI?*o#C6) zQop^q3zAhlC0WhC7{BM0KBa5934K0QZ#n3bav@L}DeGhps|NN6Y*>w-vT8zw78QkI zwclOFi<|MAk>;|$QsZKnXIk~7oR{G7SJ>gzF%sXGJnU%?dmETYcSoaBkga}0fR(GT zcL0;`-VIE?`v@?J?{^;dZ(t%14oBuB&7S}!Ayxtt*H3${eAioIdDL?~08A7K9EIM7 zZGbgq0EnDc(v5~nt&v))q~hUE2<>;DfmNVmwN!Z$++VibKL__P{vqi~>O^l2wVF>9 z^hur7jq$0C>*AsUA?CKH{?l4KX383m0m2fk#PS# z^8Vx5K*ZQGq;DlBBQ)${Z7CP?wApGfO`f`%i$RvDTcs!y ze;Sf&)5;Z>;ROFj;Nf17PN9c}lmu}va%>FCma9XQ2)1bY>Kt5kgx}bjkZ1tJjmhdr z5$^d`M~c<~a_)pSnYacJ*OjPMp=$wm;P-mKrvNtq{sj<QaE zK&UAa&46D6#I;Y(ZGi27KLfKZZJI1SqSN@{yvV{&MdA>_~|u@Fl@ zhee(h7UJt1&cBpDmL)Mca`kUTdl58ZA>QHb98|P7G=@X#z$lkOwnq67!wpFUbu7P5RZ-fd%lbT=iVe;VEcYS~B}N zLd9ebQD7LvUA;0kF2E?ql*rgYS)HMOgz-gV-(V2jLI)+h!G9f#BV!t;_4p2AZXtK zJQnb~faKp0N?I=PASOpKh{@##LUX`TLQ9`vbblvT`rcQj2a;W%H-{gixL`0si@qoZ zjMtvodtcKzAPQf`EC)g!F-1!b@NW*k8*a7Uc#^(cbs_h6Tlac)tLsVI6Pq^HTVwKJ z$Lfv7k0H(LEUsiehr-swUX1}vo3!NjcrLKFJ~I}o$Wvk{EpVLXgOlViO9_;Xfio27 z%m;fdc44M=qZRG*8WRONLx=*MSjf2=(Mnj1h6=-_ z48X)+m&SU%fA$!wGo<4BIDDu-`xBTA=>m^enBCy~dR=eT7_;_#%uORQ-|MUn*LF?~ zQ%Q>i$t1gT+EARG;;RM4`qhH^vCzSfC1C(XeaEe?O;*)znl@|W)LEE5cC&yyL?tRU zw>SqOS$bjhHrE}hC!Ph`Mujy3;-p$%v7ZjmP_2c1AnwMGSb!p#O1<_yFQy+v14yMOgcZNtPou>6HGK zq}skIlrdvaL|BoKS%ZgUG-M72VoXE!uQ>b8@fksxSEc&bC>TL8Do@%dIYrtiF|<9n zeq7Nwha(nJv$Tk!Z3B&1NL@Q{vZC?8Ix#ux%b4@j+b_gI&NtyI-+%Lufb3x82=ZKodWiHF4tpHj5!Uy>w zy&!WN@?}4|mH_Qk*e2LmYWm#sFf2{Do7I?}+pllKlv#~o`}J01{)Ti!V2w!-u?FJp zdLSN#x|T*xo{&aPEacpdKxZr3of-={oLn+Qo_h3&7!JIECSf@wOIRvG#UF=c@t3g} zleP6?gvq*JWF)@TpT!vFM8@J$g{8N`4X@pb@208M+oSh_)bMrufl9q}&&=g{GPWA! z<$jFRk@DxDQiqz=d!udRJZMkbqg@D9%U#^X$y?PA342fUQAQ_M_RQ9>{O<*yegWit zd0N#@_2dKW#vTmf57gSTVCTTjgW!D$WC3<+q%VbSf?b7oB;ueqXnHF?nxL0kqwNIk z(TxD`unvIK%>r%|a0|f=Q5FI8_cs90Y`itP1ps-d#mz!H+M^HSmlilcgYyF*NWRoV zZEoe}_wi1JqTpqPf{sxr7pRaUh?HLO>)O5rfBB!d>s?ASIiPhAOU z=sjLqMXM|nzK1s}?LEA3%MMr962vL0nv0?Qjx@J3BVL?%#jc?JXt1_=NrVMc{#-%F zeSk=A47L)MuVhSy9~S&r02VIG0WFcdpL))(2uHw&J;6f6`zS>P*PlWSy?WE{1Zw9&ANUN<@Y^NQ@djFgdxJEb zB$vjVxm>^8@aSDYal;EnWoMjfekTBvdEmLgeuwObaX#1RdMR~^cKAwQa&q80V4^3u z9+=iK1Cu%AuYo~3h9>?GV5chVB>bJFu+jL-PAJS5OrYR2~%sP&mTZPrPHzv z*wrdke1=25_9tMXi>5YQG}WU~nL?u#`>d>#_>t)mw;Snxevk3awi}qbf+B3 z6y4~Tu6;wbI&7dG2RQWO8MT>@XV@FXQod1Yc?aeVIDvG6%oD)o7h_ z;c5vT=q-J_t+5|dZ=^!253;HRFqFntjhUNHwsQV81tg7?> z`;r(i0TMJQR@8`5QHEJU7?y-2kjM%fG#Ww@AR3aGfnXg$K!KO2t-J1RD^*;r0~JTb zS$DNn>#kBq-BPvk|9+oy?z!`Q6GY4ZcRtDcJoh=z^F4dqbI!e&*O?Fu*76?Ru&aRU zT|s$XA{lfJXfMzT(B7boM=IzF&@@oqC-(up5)?}}?UR6oZ#v2cF(|Lc^&X(unXvG5 zOFPdA?G1{Z0&5>oto&R1f^uzsKhT#zGeBS0{%?Wqk89Y7d;loz4+lL6^a#*{LGdvV zJ}J{a2Xqi9K2Bi`2E7Cn&&{;o2|5&X6KEFbqoCQK&w}QFzNP)&1I@#APvp-qP}Z}2 zUL$?^$Vc_e564cmD?u*V;tXVz$o9}&GWSlb(IUexiE#LuH_(p|*<{TnTmJ<2OOgFc zbNJ8%LlxP2&EZ>x;8eJuX)f97j$vwy=%r{b+1d+SfynmJ9CkUtDZJM-hn|SeB!ik?Ovm*{tsSSqMpJ_o|4J zWJ$L~WVp|WeiohFPc8A`>w~S$-8uOwIPrL#SIEaXhCHkQ4#d%x6OY=Kxr(7<(v^v+ zZwB%O?_t5Dbm}yF6XnALIGvt7RZodOOot9XDL8og%xUGb?NbPo?Sm^Ps-Tu!^#O6^ zc-cTJDygO*o=b+Ony|3BPLs48367s)O~>YnDr|N5AW_PO%UH^SleSawpN^>p-uNT7 z7lE4~+@*%Q(s0)rj{T<6<1BuvSn%eoT(~>HO%aYI^%eeUX*{qy+eV0*lp0Hq z%guDQKM%yIO(``|U#Gl{KM%wu=&2amgS9rqzZ)iJbi3kzg>VkOdTuLCq?~+l)6c)2 zz&JCGXXF2oE)O>9$!Ph=nT$3tHco|SU-q(k_OW?T?{k$o{^u(36{_COJPc1>j__UQ z`L1()*D=4Y>>I8)iXr#IKDx~O41RQ(sd^8?ko{q0_eYmGzIr~o%)zi9gzmwRAIf3_ z?fgSo8PE#*P*x`7jDq(QR5-Ac(uXz5{h=%w4`o1H3Lo3CtT`Yuh4osv9vwf+{}xcp z<*f~%+>*Twl*b6}0-X$cH)uKNeW1sH;>b;VCFsMTyj`N*8KAdeiTV2$G58$77+;US6DyJ85LbBi<@whZ|DQvJR!k!7_B1PCI;a>Sl5O`ZyLpTRSt;>L+ z=8cN1S7Zap%1ri0SWRIkWZ&U~=HqsnAD$izF-qkcXtoXLk|bjMTI6NpVK)6-MUL%-2AWt1l7`4r5h5#;Ob~T_C3Y z5mTH^u@D<7;3zbLKN*5uCAjJON#Y@IXeyCpel^o4D|Xj!6KXzw@b$tC-adIo1MpFzaZr$&$L zF;$(>=DEv6q^BR{(Xl<06nK0qLVsG9_E@tt@i-L$T#tIVwbztL1fHcQ^|v=Gornx;WDcu@dJ+f z`Q_85cC5=}eMDBA2a+raMuztr^>FH{Mo6I6KYz}Q)(pWev$0jiVD>O-Y`Oa4Efq)1 z;R;m0Q*-soBWxx{6SqVsZb>YOpcMOH0Vy)B6srCDOr8ke{sp57vl!gTFER~1X4^%A zw4fLZu=d2_&q!T20Bb>r>$^xXblAdF9YW1ISqqXRQV`700(FuTf<;=OmIwjEZc@wC zQkdP8pgdT6sP$QwKy8M?nr%@l=>^Pn(wMP^$%xs}C_u&JHD`e$%iR=Rhp+jfL-DL; zErR5sG`;kh8lCFOh39|9B>$8tV~K9r59#C_=6LkHNmvrHm*j?nQwwJtUDTr1YH(^% z>tS$b!YoO?qQ!9|-HIYdjuY-_aLl_T`7+*17{<~q+~DaoecnbbOr(s>QSCVKWoPO@ zY1HUlV|;H1cOX!btlbf2orJ-!1TGTp0dVOO#jVuXaDp_xED)xAb zzg|$xGQP!zn{Bw`4acuVsyXa!;8eH|8{ZcV_nzVYW4L6*@^Z%3+83OP3%>@XxDvy` zAg};94Zf^%Y4D@-F906l^KVV{E&z`9`QHwI_X6Mr$jg(QDW2z>c3j3NY^YHmed9M4 zYHRdFGw#{eBP%Bq7V@7ffS&a}|B@h<`IfuG4q4{=nZwV_$=&Hu$j-LfcXBR_*y%CI z-{~=a_gH{7y*3 zJ1V-oMiM@f$Z`n>SlgxBj10M4oL`CAY+p!yi}U$;0mBju%M;3 z6=#msSJ8e|rq=9TVvh4qc$f0|4Q#%rjjQYSat9XCQ~He7LM+n9_|7-iA~>aWeLfqb ze@dTMkfh+(v*okkAHnNutn9fz3(l{&J)-4|!SuS5@S-e!=9^#QC6FC2dl`lSZ(zQ; zwjcI{>_*6#8QiH*pKfYwkrk6g0D8U_9_k~ySQAOeHLirf_5E+gz6QppjKk}v+gjBWM#|t)9YAGeb8SmoeQRZ#yb5c$JNh?x0g3?*V!`=&qo* zfF^_T1`?YB@&)l;pg-WcHz*hUQ$dG;{sQzgP<$@59glKY2Z3G%4F%MN69lRq^8y)15 z<=aR{iR^pmkyGFBJz8W;J2~}ovkH-QL%hl1eKz2Z5g8v%A%}yBh|RGgS+eGmt<~VFM7BPb!LDEn$^!d2Z2y{N7o}OYe9f|t(ky!x z&9eW|EW0PovJcR#vrp8)rmLj}7waNDI!-?iDABd&;5T%O2;CBHxp>f#orwDGx!M>S zh--C2#wArH`z1JKQ3g&~%rL%OT2(iF$AR0%D|t0~KUBYTs~y+s5c!4R)Rxnw;2Mza zN!C^1)Rq&slvvqgIe-PWr6{9A{S}A$DGv2d9O{=i1SJmTF0O}<+V+$;O1zj0tb9rG zYAROEBr6{>R@Wq}030iGl2r?!ZYk#R9mq%q3w7eEsUO9jLYbX z0{mjx1?!`?bD?_{Hr>?uHh^Z1`g7|(^u($WjZsDQE8O6><&|AwAEkYyw?gYP3t!hz zyKt^3Ekbna@!y1~w6a`4Yjl+EQZd`8$R-d3^#}-1$=(4%huB}M$c>7u2Z8?v5J{z4 z#l{s^!DyX;uPV1yBc+uc%CB6nv2kg*ep*LSd3nbKq$;I}V}N~5E1)Tjud z2DvjB<(l;Y{JB6}ADx)lgaxa?YZ9LWTMrR0u?+b{;e9F-!d; zS60u6{OI-DMt6B-=!}fR-Uu6Ur zwLb+i_KSPSml;o6qO|NiUYrixntH}^rs3pFzTIcjaS4dwyA-Un39)eX5s1JdTI3_3 zAA>U9pJ@7TQq+%UK~Q+`Nkoz9Q=98D--LLo7OFK_EPLbS3jHE&t2%C<164cEP~iBk zNaAB?5~$vfu}ZSwSNy7n)w-Ww3EhKRY1OtRhpgBr{ZVF8fS86;C~MOE6|eW zAr@>=?6l-0E8@%guQLv{ZHDB+s2@%p$V`Jkuk6proP#=6@n~Y2ygSv36lcyk1dFC^ zuW?3Y-A%wXcVwQU$a#ufM6xoI-9EN)){(Sko(#2ivg-95@L$cViJ41Lv^qZBp=Y{= zyp)Gf{qs{-eusYEUYOUlfIUaF1h0AM0f5Zh$Jzglm2A_tcf&!W5e~j}bNAJEZNPw>%C5T0C`1`*Fey3 zy$Qlh2FsYyMT_cnJg1h+VPwWt?F!+srz|@u6EpL4I@HDp-hQ!dNr`-(unEna_|eg; z*Cr;f9>3qpO?c-uvJx-PZcZH4l$d(vYQD8$U^M+uw!1Y=*o(n?GS*3>YrY?E%g(YB zyld-0IG`~&kWzGJlkp~w<=^9N*(zElZoaK!@DUSU$Pep ztU`|WwvXnvQb-pR$PuTLEk{ox$9KRPnj$LKoQ$$S)z z79AQTEB+m6`zxyWQVoNh7#rgV9*ANKQGUp)c3cB#B?ucqWTQw1ebe^$57TsLQ|%M% zA#}cH1{np0}AP0I_<;FvpZINiYsn27Tce#{qXMD9n+Wc;4?m%tWL;( zc>U~-=#^09uv9$FmYxIi$Nc77PDDqY`+V-U5oi+44JY;j?Z0G!-F{HeO+8r3E3W<) zrQBm}&)(xu#48_9UG-}SR&0)}c-|UC(-%+79))+qG(Yv>A$(^_X=3izgPs`Ciao6} z7ecc+8SSlq>X}Cq23*2(Ys!1H-^-bYb>gn=_hy6Xwj?7uvmds{1{JfBVpFVt>Z(Iw zFbYFQ>Z%Ny+TFV9)Nz)&AKJFv^jGynRm69EAD3CqK(zIKqdr~o3ls~>1NB+ekHP}H zAm&T@O3#I#m+zw^vo<}s za5XkX5sQJFp@e2zAU*t}1^Zen(5G6h`*+;VIkKmxUkj7f={-39<0UiWP{%VzeUo}R z4?(gPq7}2n=p8~;`L#^--B2pm0yX$_s1aSuwqq>D@GzRu2BJMCo+nh_HMzkB-1V4b?_WrI$p(VAEt_e`vPW3^5u5k*rm(MdQ(O3 zTchWkfake)wUO5fPHp7jEeLX~BHel!oC=Mb_3C6hPE+cwx&y%}S%u+N8}1Hp>RkR` z!7(S(EuJV;+;@hN~y z55TEd^+Ku@hfnxwt_hqiY$=&bz^UgD?f|zD zR@i6+w^q2p&{3g{2lu_inRigi;z@8y?;CI`Uv|Y@?<>*ct-gw12{;wMIp9=^PBXr| z{a3!17~dzrDU_FuEVT#1Ma*yr(s22Pn{2pUFdNfl4o-!32!o3S_t#BWJJ4?8az^xYUQ*dVr_a(S9gxd

    _ML3@?$+hz``;y&J0cqpc2~zYkmZiZa-D~^_?;QQAa|HgBRAV8$nk4<&QudL zhr3pGxFX2)3v&E|Kqy)MokqTnjDy%+6gK z46u1v;wY#$qH$GU`xQ2{*70q2YM1U(c=-1cTXis1(Bvl`bQs*@%!k)T?`9@Mm8KBZ5F#;KG2 zKVG%M+qM7awrasPCrTovPnH{|w+p7JsY#xrdISoA=cu^f$xV@f2ealWcrXvl$OuNHX7U598k`Yj{*g{RRLNJ zdJJd_=seI1K<9&A0g5fV_D!IRLEi&y0R0-Y5tQ%kXa*es+5$QW6kB`k?Vw9Q*MKeu z<@2(qgT4T|0`whF%-`ET0L5{;_Af!#fTm!Qgg3Ia_W_N9P6Wjkp}ak=1C(3+zXrt- zck5hGJ}-41Xg{R!e9-+tF95|Br*#o1wid06L1%zo0(z{zUI2P2uHOK~E>C+R+Qk*1 z+{U{S^bpXiK!<}~4LS?-TF_R|>p;)d*B9#RdqJ;<`~%P%KzG3mdp+nrpnm|(0=)&4 zN9{I%jsv|NbROs(pbJ3n1U&`xZqQYr_kdmjdM_wHONhIi_WMEa1KkB>{vc=;=tH0r zKpzI>!TCo(xxx2m&?eB$pe>+}fpSj#I4Eb%Pk`PA`V=VkRjp@1dx7E}syzerdC-GE zUjRK=%LnW0EYO!AKMC}&pc}RPe$c<;`ccqVLH`2!3FsG~pMq}H@@=56;kqyGH(m!F z2>K7uUxK1c+Gm5l4cY|y4(O%&`dZL`;`(~f&p@96{Q~qY&@VwFxL0Am?+VI%&jj5H zdJrguj@YxzWdT@H#HfcANys2lCApu2!B1;x{C?I(lo3c3yy zb*BAd&=k;{Kzo9&2gOm+_M1WRz3ldfLDBcNKMlGY=wCs12Ym-L9rS(BJwQJJ-4nDw z#z8z;*3R+p7oa^6omP~U+WzKhfZF~hr#`lPqR3u@9y#?`#!`{-u?%v_*5%-qiHzI- z@z{Q{<5ra>;T4fp@bhvg=7MS+?eRUz;L3tK^a;KY53XvcxYrJnDj9-lgJE7tNvE z!11m(#kyK^$<{64*osrE+clSLZ34$T;S}o;%_UpUf#bbyiuID_lC5XaT2%hMs5w4& z$&q*q>JL~Bv5K9vLDNe$eM+lv=AcEZwTPp<7CoY=t?k~QxP~y-#dg!kD8o9)C1r|!p;;C%))F>N;+Ms8XQ5*E_ z!WBS|4Nq;*vstPQdNx|MLC+?gWX*#f8@$?}XLq1B=-EZ64SIGUYJ;BLOK^ie3!TDM zK;awcS7r{zm2bPg7^0eMsDXW;8MweBuFqgkZSV&o8<(->Oioy$lQY+xJsQl~SwmM} z$W`;T;|^PWCRfc@K5uV(PR@$XDu|9NjyB{)kIj#sIvR`1=^c~vu-lb)4`=^aDjz7g zSYXBzz^h7#{B+8bsjK+3TJ+@{J>;pc)8O^FqCnjU>=$V$p zK`%tVjrNZ2g#h|bi*Ekrm5Yz-hQk6yX;W1g5yJGI4R5uN#&ADICUs2tVb$X&54|mE zZE??uqxWn}%Ae75QtK~9N7}l#pWJg&Vr%M(Esu z3;`!+L}z6pp@UaEn1LOUHLDAd&Nb(7j~~*!=rbvgrLN@D^hm*(EvT+5wrxv2^Efa- zO9Oml`poj^SY$2sJswP5#b-aT!rq^i0Hv6L|4eN7ao#5%xm7XijVNWR2eJ^c^i`W$ zcgJQ!=2Yd&XI1XABk)-CO?k5T*O z=+kRfJOxfrun99z*DvgB^yAZT{mXfxp+B|^SYOpvy?mx`H0o^u{)-XwQjAngK|WJ} zhqj^3$g2&86YeD52J#HG-n0UwLnE&eH}Quc?+LbL>UyU+SHcQRWoeK=Wg1vLSh#=)oh*U=j5=d z7VV}oLFKf5N}S0`TxFW$xY9K%HZeyhPh1my1dRQPea0gCX_un^C}I*_mnpr3>tQO0 z*q7+{-YbJQ+w_EGB}0zCb;V)Tug*@4E_U7h09kk zD82o`aj;Lf^1!KZOTejcCxBDo^5mr&^}qxc#ZQHhnNL5u7lAlRFNz<4>!W@C7hvh7 zpI#Ktg#S@K|CivuC*lN1Sro^s#_{oIv*ZzY#;6#Ffq6PQ=f|&$dtNsfvM#>kLEsgl z|ARoX{}+L9fq|P91t_4&zO(hL3#>CUK)b$JXR=q;>sXg;#}Qk(G}HpF*L{ld!u}M% z2E0>@t=zj1m!0Kbtjo^!e;gn?JI8N@=cs%**lO@evPN{WaK=TOM-Z#Pq77G}-h>Am zL<2tbpw=gO5?+>)K7f~Rsf+K?c?IG&k44e6B02E>6n#pu64SO|L2Yx69Ls0G)W$n> z#x*xC)|)^$b)M4adwBI(AnLLtMRP`_x(&8epsf~2gm}&AvTJRNr`O+uh;Bx)I?dh< zrQ*KkX0iMFW8XFFjP1|WDK1WNp~rTtKb-50gy1zTUxb@n1ZUNOjsyK2DBli(joS8; zL7PEO1H}SN`{|%lgzl=B4i;O*6**Mlwwy%F?0P^SMn(BFfu2VD>PGUy*b zUjxO6BQFQq0J;^|xM6PJBSE&5W%27yT<7BYPoSeg@m>P?Gy*oX+vnpNgJ}DOpbvv$ z;mdji6bnDrpFy#pgEKw&^aAK+(04%}1N{p0anK}`-xHuIpihJHg+4EVvOoAMC>JX( z!T6vSD>zQ$1{X4N$=0jjcte|Fy`i~ei<8JJM8=6EIrR~@D@DfXBssi)0x2aj-anza zWUCdN3S+6}lC9r@yGryf*PMD^1aF_!`y$BUrNr>PMr03Z4mZc(t`*sfnoG9c26vsv z_*x`#$<~+Pt``~epBxrbkOL}yiJHR#hLNQkS%#5i8d;W+)48;>);yh5usw+pZoAW;~KE$_~bZLiYR5cgOWy{JZ_nfxr7( zmdC>1^YtI!nE`unjXgWUH+YYXcWOWl_uY~ClYGNH<9-PKxoF}H_mNKCZD+?wMtdgB zb`DRDqy3wxD9lptYlMb-4@p#4wN@|69K+KEHuR59EKX|jg9SIvGT&n5)>scjL2r$j zJ(U8;Y{z`yu*Jn1wgEc4nY5jG^FHVZ(0_qW0^I`2{Ngpc!wskz-BE(72Blc@G?#3> z368!g*1MWZwhlljtZ6CM!J12!6F972DOMq5{UWE`TLrUT!~(!Ypw+yGh&B_CrV(|LNGg(IJYnW%|;{*hD(;ubMZL zpw_SM5pFbm?iG$r=x*U?G1BVW_n?c8ZLNH1bLpL5uRm+{`S+a5BXNsIRt!HWZ`k4Z zJqiC6&9(KlxK*fFQavJTXcKlizxe#Kg6hV_O+)Ky_MNuUVz-oF6)dQ&Y8{%D#W*U- z(3eeN-5J+kgBH3g;ZfH&I{I-Re(^%7C34nYsy)exh$#FK-==>5m^7SqGhTB+*9R#c=G< z>2?Vqv-?ko(4Tp8)i37YX4;R;nvoFs62CTbcf*xJO4nT>H`n0aO-Yy!2@y63X8>Rv z=@#Ihsih85Dpr}zxZt?TREV6{bc_$(az#W3R!&f8D74DJFH@1T_l=)BR+m9SM;(Q9 zuUxAiZ|D-+2>UAHTyFjTDcc6!p|+xq*NW{bA;P?&m2!5RKhW3I@mlqUBq7pY1(X{nQIqOx9R_+>=3UNZju5r&ibH{QOlDn=l z9}*(Z;@2*B98^$n@|G8}sg@rZqZzF1R&Zg*ubv4av;Rqmyog^LuaDvQ*$28l0b~xI z36XvA%RHHU$oflz$gDXDkvI8^f4bcbGS`5VgmI?(R7)%gi<19(B<>vR3ty*{Z@%u4 z1B0P+WJ`#A%3u7`^);dYLKkjd3CoSlKDaYvwta89_B6yythHVK_l-SKxSXmS)5r1RQ<8@c^`w!J0`k)0?7M8 znh;_Aq{@E^d!td3bJzI{Tqi`*B2LZR&me!Rk@pj1DDtUl?O3DSWx7A)36Zn$%a-=| zsBWJH!x|tuOI=~@Z^GhU1Ks`-mK*s1NE0ILlVNCmk@w!RAabVYu#QCQ7M;8Ji+{R72Dz{9 zTn7b^hd?hO!rWl)zP0cEKd9Kd>)}w*VF}tj=@5gQqmhRIIe{m}a-k;2k%^onC)K=? zp-VYfs!u)~1~1fb{4&Rs(-qsArID$lWLQ(tE`v4Pg_8xjQxCmkC6CI`QO9e=S(Y00 z7<%3vpS)p*BZv{I;9ws{MS8e3O4aXxvbcY9!heO&Ka=z%e<2>9T*K6eA0pt-~ zK;|l)cf=oIkoo2Ux)A~7QIIA?IFqDX)2sbPRXXnaJQ_Y~EU zT_oHXK}H+I`ZM!}65R%|M$N?nTjH)ig^(sh*jgF-YrU?m4~9Ngbn0E97n;y{IEAjz z4xLrPA|8>Y2Vhjt$J-Kj=tYnwL~g<_o6dmeUY!{Xy;yV#&mYkQe zVE?Kl?wl`!G$FD-ei{13^S^2jhJK{z)VM+~GoinsLof4$PCOzzq3>oS?$9R)va~61 zm-UaF9Bii(MaMk~PcWe;>n1({p{wz3q?W+Q*K#Kbj?%(mkmVmCSeB)`1SgBmwfx0D z-6Rv%Q5t!Yq|}{?DbQ21xCpqpOJNTOAg4yd&ClvEtmDsaSh%9~7A#>IQ8^9dB4O#ENx` zR^Bo9F>OU1uN9g%V#u7Jm2!4iuW2jlc&%nZ66^l-Q*A{Zh184LCN4uuc+At5)J3*} zwZl|WcbU$H$eEcpzP9zxO50sq=7^5FOlO-iEz)7lR%Pm1lbI`4EIGRH``n}8lMwj` zzjkezYq+B{^4tJ2=gFPjL05>*r!M594RVV{K01JWj0gGQb`BKGJ9lmzD>|>akg=nV zE4p@r=H*NYzl_e zBs%W;(`dqaL?bs!SZ?GKx`5mqKt91B^Kn|b69ULBkS0Xpx6@Y9VFubgK#M`MwH3^0ubGYb)xgwEmzaPHW0wMvBX@>LQ$H+PR{n?s|9%Lab2xW$J1>r-_x_c5a_rd2|rDU355eu#rzQT#ZIP zEr7hd3&^Jjke3_eGc@w@0P+g4+8e(S{D;@@m7>Ej&W`g6!`-NnS14px4PT|K_=|t# z?D67tSh0pv$6FK5fF#yqN)i4rWkMQ>IZJR#cU#tA=-om5#0zUc=849TtRLTRIH)sz&YzAfGK(c0D}n-%n%m z?r)Xnh|atCwUN&@+#uckpRJHx_3+nX#cCR?hh?y0J*1AeyikE+*27vI7Ik3ds)y%_ z)&BTJ@~xY53O73Cbh@^pjyJ6H#45a}y-HhA$7^-IScTWajoOMjUaJelD!d-PtgWb{ zYS(vKVo9z-Z0*BniepcEE0P(z9$pANXWsIkeh=wZ>F#MS5}i!o*kyX5;l}8&E|k#S zefY&YMUSVQqghO!%GbE z3XOb80QoYp;@D01_XobaK8Sodd=et=S=?m?`3jAESpXT!J+Rt~uyC6%IOEPB@|Ezx z$~F>Z&ws8k$d75{D+0(@iIv@M!tYbA79DqPTxF0y*T`1|kgw?i^0lJ#8h-5(yvA?` z^nn=engH^3kS0V1i7%cbA?=(I$w8v9kN9@O!HpMdwZY z+Htmi9XR(`LosN=QzgII<4QG4tLPdMs$t!{=S*1c7hwxW)T^>i(9 z`lwcyq%QIWl4++8MsV()0zD@|_y_)&TPDV#ONHmf8RO5f7>qy8G2TMCSvo17h87kYCcsw+E2XaUeJL#V>O# z{4~NJMTc>=`-M9V@~0a4&H(bC#40}WU83`;3;9n5xzFwp!~H3Md^e=dN?`bI={=&e ziNE-#yW1e=YUH~E$oE38v)sS{4;{|uZRC3m@-&TnZvgqeE+F48I_y_%XygY1$PbED{NC>&(P6E#d%p(__ZN-)ph9-_eh-UPPyXUxxgUevJM<9uHr;x0NS?a*b)%*QftOnpWg8%h@w+>cy9T(O>ZABe#SdT&ytM@C_ zR@CuYZ5FHW-mgYmQO9fbm{^6+(Au>XbyS~rot8Mg-(xOGU1TKGlqO8XxqH9IA?d95 zdqQ;Fz2D=eOh43NJszknPl{Fi-tQ^Varb^t8syZz@PvCZfc!M1ovl#)MReTAPaEW1 zjr?=~`56!Lxo_{bhsry5zxu4`xX;o&V~}TS@Fet_hJVUC6H*oF|}mg(z)b2NS#)~yRK zn;Q)4AEI-IE3DT|SRZNR*8{0|qYKDyiq1wC@*4(u_dVeW_eKEuEl8a+lehfxH>Dqcf`uhtba#0ArbyEm3rbiIsA@6uGPrz1d!hoa&T4}oeW6_p6~KV+-ILSY9~ZS<2MoiXO9}3R5@Ry2p_fh{6olLEB^GUZONPj+mC_2T+XS;6v z%W!FI&~X29@>vNi_W21B4C>-i4_vxFi2SkWxRF0H$m2EgM*-wd#EPYYC|RejTY-Mk zALoCI4i)S;e`2`PH1a0_WSQ|sexZ^7n({EZ7C-W5g3SKJM*h@rH*4fi1IV9?Rs1-A zAv$lmkUuxbuW01Y1IR2?wdTN>mK>D5G#KZvM8_THFAef8OfKA)0pzbCb#Wc zp3hZnSxMY={#*DYL|Eq;`Ywn3b6qg>??k7-75cX(^c6bvZ#|(CkH}8woRTStJM`}b znek=l`~C&r-VW5U|B6nzEA;P8=o@tC-y{sW}yX%zNvV^%%} zL&n2B|Jf!wc@Wz*{0GCmu0#I;p(l9m-wBftVed(|U-#QFRQi!4qT@dQW68-8T4e0a zU$}@Lna?X=Ee>9+;ZOXt?zkXwg6K5i*RCzy405$b?gr#;JijV+L-3&Qaqb%?aU_4Weeu;?6Pdd?iF`pv{^Y>HpcW!O(k& z&a?QnL+@!qFYFI9xSkP~1w+rn74e9yLO&c=NR*biL+>rfbKu9cPdV}}R0`&=yS!3G zXQC_g-X`?5I`rNVhAzl@PLd{8tbauASeZ7(vAS7XrNK(ofp;O{NTMX}nL{7Jv0KVV zZ+&xvgOk3GvJxFwW2}ILPD$J;-A!-ih}$R?KhZZ0=4S7Ik3dT4CUq>k=Z&RWR1-i{HXr&bE3{ zTT#aw)}CU;8bB-WZu?i-iaK5^-m|DVwjF{K)@~e_;HcxZ+Doihz_jx2wjZXgsN=Qz zg~!VKY}ZU}MIBhVa$|3?LKaB6Mm_n_DitaOR-?9}jyEj!Y0i3!_e|hQZABfg)jnb+ zZItlh?0h+2TTw^JuGbRF${>zwmy@3rNQk7s9*lMV=ey`QyIb6TqT}u%_citKR*k%G z#E+aIR>uRCwfCiQy{l9hZsh$HGJfs4nqiP%(8w79@HBrU`414l7f_Qs+(q z1b2|K0%x~wr=3>8itUs--f}-!tT^wnOWWbj*I`iyR<4>kP^?D43XHYaC%d2OSUsVw zsN)Um5V5k`={w!eKFhI+WB>?`I$o`o8Xx)J5?6T&+nzI(MBPY{H_?jn{oWNol+5&k)gJ>Dy&G*p%s> z`_m5J-i%~0?XK1|RIHAMAFWOtdDG)T;~u{poL&QzmFU14AN7HRPD$J;%@G`XRUmxjEmw3n z^4fWrV^VsaM$Us-{r+Gc9xgf`z`{n(Gsyqc$aw+eVPe$}R$#3B z(=W{pA`cfG&PZ+KVFr05vmb6)#2@E;5AqX(_QRy78#LWDYJ}*x=luBwd6q`b4YFPW9cVyK=aA0t-b{ZFa3qK-F)1!5K6|18y3 z)bUysidA_3bECGR4oej)LRw;38CufsK=Hs2&x-JEJxbG-y4%iJ2`hdtQ6xHd;n!{n zV@;V((P52^FmyrIy+pBCu^1BZ&snZxb-K1Hh83a*w;2-l5=!FkB}xRx-Agz)Nx1E$ zmFN)08V3oTlDJdKXWX6ri|}4zyy&<`&v7QDXKLhe5tC903EwB~0&-aZxzr%Pppi=h z$VZBmo$KNK&jitV7jfA|$LC0cyq{i>J2HSgu?umYBs%UsbD}|BtdS=MkSB{({2Dby zblf#+vO&I2BTsgab&V<)D|d}@tiI4z<*>p^g{yCwDpuir%cy~>c2Y;Rkw!>Zqco1| z8P#cmv3A*^jhsMNnHdl zgV&nM(mQLKBVna#uka^C=8Ddj(CM!A=9oHmj}B{2B!j7N&6SBTY-uwoAEw)(xd73Ut8j}aY?;5KrFK^`&)W^fe|f1HmMtN7z`rRccF z_UzR0)`Tjt3a{bM=&+~*E7!O@U#x}z5sY=h8NDZ~ z{K18_Ra;TV8&m!fW^m+KM`=hF_&6P7Qy? zC8>)fAoG-_ilw)PFOaZ~g%=oWSh9Xym2$4D$UN z`J@2y$zm111WyqicL|7prmbW9dBl+@QK3@^aCc=R$5b$oNc_xb}!2`E;@B2Vd6bstJ7`4}RPM!<-41;`?Mm{5eyjra0S!zt) zcGHxyU~a4tomZe^m*8rH{Dwwe9Y9_yR+X?~KCj!5c|s65DmokRyDN0))*58_=9EY> zfPh_?+&o-yWFxZd!sK!n#*w(kf^~wN27fTxF&>qbGs?0{m4G@J<6Lv~4zc3sLMvw- zyRx!qMxi#Nj@RlevEuknt4ZVUy+EZD7uH~IyTVZiR<3!=*)%U#*C?) zmQ`AiPb=zpN8xkCs+OK`AHVeBP0GqWg8W)^HsaSVuX9YUj@0ovCz9bq{*7223RE!G z-m|am8ALu;bo#rHe`ApAH1cl($mfYw6Hr+KZ?0H{{Sk8RIG-;%tc`Y@&ojtTjeK4J z`2w-Z1Qr-;?875Fg2)$&PO%I50)u?NM!rCh0bzZrC6<-p%b$w`hg~7#{>rAeZVrZZ zvFOahuU(%nGGXnJLwua*i4d9l%dF4DBeL3GW_>=$NZfOh-wN{I&>8lI{}lz7tW{}t z=iw!ygU@@(`@W!N{nmtDs6+p4#H35lzAhE3vC!tcq~fKu4>?wiu-XICOJSu($y*>{ zopmJt*2s?JFsw=LZ*<)4>oN&zH2io6u<6OI5htuVSg}_Y9ZQJ0(CcvB-^9x=HAYq~4NY7#h>@+l9MVtV37zDji15^dxw z4RQ(#74FK2ANgvrnhQT7R~-8Kj3DwgqQm-NBVTQhOEvP<0c6g%6C!JXN~_e`mzsmf z*NM)v__gPV*BazsYvgMM88tJH>jlIkveeAO*(?@$Bw4sBG7@*`TrXi=3_sSHd-J+Q zgYmgRbPA9ac6_ck@%dQC=lTfqko)h9&qeqrvg-L6AFqV*Il}0;<8z~g#cXHWX@7O` zYr**ZPIT}IKht(@H1QeCW(jv=#FVLSJHHpJ1K`K{yx%VtzUf%CYOCMFiur)IcWQ}c z5r-~en7WryI_{QolOS_$OikX)ILNcLmFN)0S`P`Gl5jV$x@nmbNm%aOSTD%zjloz+ zmt2nFj-0#g{6Ta!;n%(kT5ocr+i(TEK4Nl139OsNinBrH#tS{~|15}ni|E{iU%Q9A z*&vV9$TtfzM|_qk+ai&ja(5)|ba57u5NU)qL;rOvp9F-+ldfAu=S%$Bp>HsupP@tF z5MjC)Iy1Ea|3p@yQ^k?EL%&UsPlrF-;IeLq-5Cu1cF{>kf!d+pW4jmtD zRd1UmvV@*PmF4(X5_jl#2r}pSyTkwfi@*Oc82X)}!*~1JE$$8z`X2c(gS#W5Lm$re z#k&n6OX$PdWqKv-e;FsGl&qLG!vog4QE4!+=EahtmQ;&X2Zmd?GRvk8gnBWU;>r^$`SHS#?Xe{OJ&r=Fc; zt;;xe@8=w=hLI}m8)2n#~?Lr z-{jBd8u|W+KY!SRsdJ3XpQHL^&2p@E|D|dPn_#8#XB;GSn}NKWvBi8vH#xBvHG>PqK?<pI z+J_hL7iV_@R!@r+OBjrHc5X~4Py*_B!}^O@*}3688&;*QsH2eDwFEs3aa?P{&j?P9 z3dY(nr|wtE#@%u`=fr#C@oU$^XH4zAMI%2G@gqMcR(86=pAvmubY4T~Hu7_VTyVq@ z>h>8v&jpZQ5G#&vOx+2|Nx0=D=Z^D>qQm=KdxiW36X*L2pbYmygmI?(p+JcIc=P8a z!LfU+vwF_JU7J6wzlx4K6)%~vdKN0=mm&e&unFlmZJP%lMVY`G_NN=h*9l+ya008_yoq z|CL~l{X=v(pRv>Rx(WT=LYTq59`UE^4Y4`_ek_60zq@2<5cy5f*@R!aM!jK>_a6&0 zxHlqxh(fI)W_UQ1IK|WR^zZF1!N315m3XJuu%kDfd80U9Irw4zb zL-&qBK3yZf6YV()HW{}i1H{Mz~ao1FJlDKCD z{}LScU7Le5L0gFqLczQk5;`Su*VPXN$4=?c?$)?qN0}!g6Qpf6PZS^s%5}<)Fi&aXM#GTSl1jn6H2Pa!wiH_h@K|-e_?v(ypaN?)* zQ_*3cY^U_!CZ)g8$p4P`Q~H@$xl`&`J*BNagOy5YzY>*FC2^@apm?V|fCVvu!h`9`elJX~Kq?%eoRbll_De@wbgE`>7Oe4*&ch!B$DM}`&J(a={SX~c zoO?b}h?cnXaGT(?!<#A1TYkWS!IUyn6C!uHQo7Bgbd5&d7V)PvB3AB{I#z$yR*`OY zN_U^2QmQ2Gly(ywcS;?cqhZCAiVi5&F(IK-5_d`y1ScDQNQiaGb3=X?OlhL%aNfci zMVHXcZabf7=?z$jylIZZ8)G368+r=RFn`lc6vaT)N#mdgZ z(G}Albgb&NRdq3B3N&V__dN!)q3tKf`=9~kSY zNh3nqMY8CuM;_Wax2s9%R~mWOKpv)uRW~$>eSo}p>M`xXo~@_oOoR^Ce&|vRavrC# zBJt;8FR{vkALH}>Ll^GtShZ=ZUXq8hPLhkXAq2)pualr_TbtmKp!>`6O0YaoBcaoZ z?lB;s z7O5u3ZqvxAfwJf$R_s@qW8t%}-9(3Tc)LFLG02~3$QxbO`_7$8c{8(yl6ec9A+;op1 zdx#GE`CbHp>uXXvRU`Keq;yZQ8Ubx0-!u1}0glyDSg{80X;OMCBuuFz`Ikm^BnM1W ztCvdR&W(N&7F#8Am8+LdShHZoIwCrtsLPPhDTzBb_;EeFdkuap_h)+_@^LUX_+2S{ zQO;HFdzsvLKqK!J$PIq4HX(8lP#HsxdX81E=@7x~ZE|BVB&=0R;!bIQ!Ev`82WK;^ zn1`Z6Kx@DZAzI>2={|zPZxgY%`S$sNNDuxzGlzXeCk@5dSHW2On3SHXk@pFtbU(4; zl%+fVpZ@TJO^(%nVYN4;`f+f5}7ky}9r|Lv(bya?sIQzi~_0pzuCa;@CRF z0}|>~x^)O_p<8gQ&|g~?#SRWqrh~K^O^Z zZ$9##dC6Q=wKpHd{2O!(NhD>~5;F2BmMGL6Jt=MNT~o=74a<=BOv*9U9DK+)mbmyZxMtihX_a1)T} z4wgFat_g>T)w%FvO&E4*T9sqrmbw(gz2N?;2Nm_ujw4f?~ z+_m>m9TQqXE zvT~h}%n>V&C8*rixarG=I98*N!&(8Pq63O|ia?S9>PX&)gwBzSI$q5cltibUotBj= zVHJ?|xN~4JW=vMmq-8T3j&Eo@v7u~nQ$YbfI9@R4C~HhvLtSe@(e&CA+G-nG>#FLf zw6#ueZLY0a46Phdn^Rs`QdR&}V2s6wo2S)QH#XPI!nc?kn-z}otsEZWJ#1_N3@fMQ z#qrA;Q#dQc8=F$F9NxODskXANVL@X-fen@$qAkkPa$@>q7Z!}kDl8}|EQqBtKEz{Y zVM%%69G$+B_zK1Nu61i|7(7tsl$J6Jr`MensxftJNvV`ZOUdG<)@5NJP^p|uoiUZ2 z#Wc5IZXrr-jucvUc&w%H$7GMmEb^4+%%Y;kn%ZVn1zO6O?UO|^scva4io2iyiHT`D zwyvS3ysECb>o#Rw1sr}-f&EGQ__3&*;6N7POXJN2MKjA9T8HHo*DlbNcCrTyEnyDx zRV#;9akoNYbM>OSCAG!)Jm-8ghl03hWer+gWo5j8eYhn{V<4**Th=gkS!-=hh)(%f z-CP5OTRGXunqbkFI-WBYH8-AEvb4IkskN@L!57BdGUkSy3}?eNDU78L)uN?KeUSN- z;*fZk5oX9i?=Gnq1kj&L!(*q1noGGoA4j~KNP z`NGm0f*hsC_}bQ@s-~*yIt+4NTl89D$?Ti7tf+Bud24gQ%(9S~3HyIm{PMzB z-i!fb+%+5%;V!5nA+bU=vG)w97~t$iipdP(warUvr!>@-H@4KtI1@5cDbs`Vn8Gluu_c9L z%Vc5|?vF-VsQrD_0rjh?xwfT6<~Eq;x=M)^&=YIUDB_eMy<--l+cT^b=^v{Y=@+9M z9k190X>C*@+ORBIiLD}2_VBE z62~fLId#D%toY)X#VXY}CNT=TQ;XPjpfl4z)reydzs7XUFsvfQv1I*VxAIyWovZpoHlYzbJhgVP!@Y zY5bF8G=Aleraf8ZE4yFJW9u3g^8Tuza<-GJ({SGmnVwyQ>dg@lt;kWuHBy%~sQIz( z!{ts*rXR6%)DZ5N$+%q<2Q<`x^R`$aa2hnT%n1Qk*#(kOf$D{ut~j*|zIOd#c%D(o z_zsR=|* zEi=SX;8^62KI^L|ySbb~4Yl?mfqVR8_A6f8prNm|VRgqJv^V4A{=yTqL@iD&691U> z$m1JUlSCm_T@ue2waMidyFNKefpm+PyHF}i{8{5y39D72!+J#~bj(m1937?>s;(wD zov~303&A-xbjtkWaG$T&mGt6S$Wo6~?83s>3W7M@dvoOLFF6%f0q0l{?A!gm4K zv+fuZSFb#dZEUPp-EZZ%y88OcaaHw!HF>O9t3Jy!Y;xe0uFD01<*CAk8uY`y0^*ur z3<#+ko+yWPzG&cj51|p!i&?a`8diN}Wg=uK(Om_*hR#%^Dw+I=9V)9|X^iBlju)%T z21gcTV;4(2AXonvw!Oi*RlNQzhD|2>r|`}whDGcSCbmJWJ|>n07l%U^FHHef4i8r_ zQ?>Zsn5)HF|5OvQ+;Dq6TZ`xEOxL=oWmdrzxJ1p!?75?}R&GbZsBk-|32XAzRrU2U zOrkBHr1AOYSI*4?o1GfPd4uMeO~szF z`S0AiY-Y-Ld&07f^bEbrf!UeAJz?qM*?tqJ-fXumXa8MJlxtEsMs5mzj3qaN${K2F zm!iinQu}qXFBRMXF2mjhx-~V=<(=X71Q(-I+kTW_H@E#5fsXG-LHN4DAAzCPi@ThS zdgU(Gc&A43s_Nr;chPlF-pRyn-ex<;cN=DRL6|DUTe9M`UsafpE+urL*-3vA!^Z9x zxIW}ddM6g)JxL6s*xg7BgP46tT>W?*NIb)k-Xn&3XI)1Z%tCsA*j8O`{&69?()Qy5 zbfMvQX5VS6j}H*qAN?XETT50yt`S7b{%nD5!Hhf9LO4;u*3t@=e9J$K1rec9Hw;|3^V|Qd{Gt zLPvuKjsm@EJUhE94(nLs*~RKx={a9=?h#b)+cd4A9m9(OMZdjpJ{h)Jp_YoHdb46tJ*azv|5HK z#;S^L-FVf{trw@t1=ZqLvw(hR)pBcfUY%lS>r=U5eTdIOAJLVAL*C-|6`1L!R3GD7 ztnET5DC*7!bAJ^vA$Hy|`V!?H4b1vz*P@9U85qm_5tD)1E0j@dTytYXYhX6+RkRzU zCwJKp!ke^5EvBv7KJye`>?yu~YcAe`n%QrWeGXp$G3E-MN*h|m!}~UWypZ&8MRbC3 z;^oh7cXZe*h1}Sfy_PZTVw}2!fV_J#;_q2b4coB^YK8B{Ffb3;cJ0Pwg-`wL5dt@A zGaGQ^5QjN=_&&6(P>*F%n}?F+pfTPkohPRiu_Rzt`mxj$%UYjZEb3(43Zn}L3gkSV zu!z4PYaioQ9avYb*nYGHr?nv`>X0pJG0c6sH}-Na0gJdhgE+TU^W1FgOpxaj0t>j? zV;#1kwO#fhyIb33?^{aV9$Vin)^?hD=BwLfi+xdk%n}drNUe%>PTXDr?NqPaeW<@6 zC%3?^iQE?HERcXPdK6Dj!a3280xB0EPsi&+)|q*f4y9)fBr$5- zGG*R)@_MZ&Y(+++j)G)<8N5Be=-XS(LnM8=Yx; z3Z;{{U?l@jQO0@1-Clo-tz=f-I#=PETWl?RwJo-WUT5n}!C7JJR5RCp^48=oQ-$3zNEH6Y!pmV}rasiB$kI3&$T>K6VaHOY#gxL0L=532jyN<7eU&8iJhK zR@=M`4}#Vu18U2{5JeAM|O`b(j za~gFbg)0sE{$5YUw4uPDto;YuOo;x zr8A3DSfUBv3N0%e&){KF8uIY0vn0heE6*yCT5>W6gabES!K3nCi$EXMc?h0P zs&jR3FV&g8O1>wFoNcK*Qiq_skVc z`+pm{uZsN71NT&{|8eMgEjq9h6!SI|dlY(H3EPN;S@e>MB5 z@qHEPXMp!qm7g3xd~e;mIxG(WhO8L}dXTW#`FkV`oZOxFh7j0({qaa$C=g%Zoh46i z(e6N$c&iiZoTP8E6&6ao38Tu+I2v7UW3eLWG~<{WT`ImfanvOcM}w(wPxF4pY>HFd zaU$52B#e1HJIMU`|>?!{0J?dusf0P-aXvh zbiCo-T^yRijXT5kW%y4SZ9sd<*_|69U+=h6Bjf7?c6MAmy~fUsjM^KQW%n*@jCZM@ z`DqS4Y)^lcmy?^vRd8k{4k4)>IiAs|<&h?w7>s`iKK3KKr``m z3VW>a^nX8hxY;p!m7hD@5j!Wje41Ld&HrgG58pY#4%<1w9=>ye<;ziaLfP)5h8tsg z@^iP_ozz`qSp`MS)kRhH)!g`2-G4#sgAl$$izI)DoF_`_KPoymGGs{BJ@G%x`|?dZ$MIQjGrUJ=!r(h#twk zw&3A{7)x)=tQ`c+%!$zwcN909)9aA_Y)5fpjJ!Jv8)IbMQP>zG=Z?b07#VjIHpa-e zqp&eXwjG6yF>>uF?9bI6exBwKaud6Q8Gv~DJLDZl40O0V3Mscz_VKIuFRt4DK6S@& z!xnqlTmJ;eF{Us-0dh!P+Hus7>hzO<25Qt#fa}&vZ~Pb;-O!q5yn}X${xqOv z;k#(owfr)g+a;%YK9okUyYS7km!Q{ykNnZ`6KDli+Ss8rRjpMbQ9qPFu61m2ft9t% z{c$$Rcg6oR(0fJeG71@K<@4MhXro>tJl=-RKWPBRPoov2A>3B%IA<=a79oE48N7b@ z1mJ%7r;CO65&RB;PG5cx56J|n9fKT|gzSQ9iJ z?U3FA_s7<#S%CkUT8Gzk%s-UXVZ|lm3TIB7F|lmy$N_C_bu~ll>*f!LC1!y5jG%no zaF7-0GyC@OYZi~J7=BXTu*30t68z?){Nt>V*62Qw4CWL+c)9Pi9)?b; zt8Q*=Xu-;8B_2br^R(A;qB`gyy?Rks%Go0Zb$U7s!y!3d?8uY_146Z6>?Kp zwK#(Zu39P_xLI{AIGmj^y|t~Tt}$c8(5#ACMHTbw8Y-&mht@8wwW=4_SVN}dWDJ=y zpFef@Z^i$zj3MJ^WDF_u1y)g1UY;?ecy`(3Txb_hE-o26b3B+zNQ$S-o=z5}Q#rk) zXy!D0|7=QSaY^~KlA^*HCGaYlGhM*3zuu*;$CgxQrp=iZh0kl(z7vI%CKr#A4bbc+T|V z36+zonzKeIz5*YQs&A{Qh4+B%ErvQ}I^f6HR<+hIUQk`(hL{k$79i3s6|?cIY~zV7 z6-$N<%_{s!EazA)&DGXW)(TYgx~2+!kIM#NDt>iSlhsr+-(PP{3t3V)q4p-e*%jJ2>ZqPJ9`Fb&%Do&pZ77q&WNgawA7#S9#<}N7vc|0DX6(((#k3j%#ez zU+l8>g8cL%d=wqPd>f@|ngX2z=s^nPgG8lqx+>PJ?f`7gwaurn4&&$`%j z)Js&)+T!%AOH6yLKxAub7lc6TR5VpDvVJUfb#p7Q8Sl&)Ss6o{tES_tiPeiTj>yQY zt!v7l@L0KMQ5Sg`gEHi^%**j9RF3s2)+)^`QAVDgd?Zf%7-uE3LFXMga_MsKfsu zrXhBvHH;h?+D7_YyQKju#AP6iURF|{!3btIt94Obi`7kLQ=dZ_-_AA8P6u+vqz{p9 zr^4=_jO(7D`0llQz_z=5hMaknBA==zmu$VLeN(JgG?#3tjO-*EIiYepW+R=QjZyFm ztyE7o+BQk>yWI3m{%o9Av#g;CRXM}eJ7p|rY|c11ycaw8U@LZZGD?zv%)Sg>X=lfU z(N5Pg)GNuZ-Egh4i=4_Xa>>?H_*JrJHK*s3`bt%~kyhWn2VHb*YvoIuOYi)8{aLfm zzvtY&pyBT|n$_28D$FSJ#pj(Hz$##Bk%lXOZG zBH8%$I`>4G4I&}JDLQlBaqh`Et5HJ4_Wy2as;hpoOzEi8&2mrG>5~v)Rb)KwTlYG; zT!!Wjom1$92q)^~=n@T=sRWSlJId}!J7ba%VJQ*0{K4DS29fET5aE>FMou!^R7mNP zfQ+v%yQc4K7zq)g2HkQkq7LHYn#?neNCkd_mJe$y(XrD$gF@Dhgh&BdkNW^uUHBqo zSl{7$sRGYot2e$?mV~ztp8-DSOZ_hC=FSR@0Uod`v?{|9ymJcPpB|p4ZaC$)v-{KR z-0b{pxuNC#>4_2EpJpzKSeNKJ=&t(AQC9r*Bgwg3$o*;YzLxbm^!A^t^jN)kf8}lh z^eM&vFaIC0uf7vD%bZWF7;|IM>emu7F2I!pX)eD5n zc&~;|M<;sh)h~q3?OM;okN4y7vmJ|bv(~X?Vfn{y_DSenQlYd={`v4wyw=mu`B3XI z+%UX1A>Rg_H;w@Vr}9~^7bubZvTOM-bP|tM!dT_Y`1OX)KeV2SpRasJLoclox8?Y! z<2`n)@_idRUu!*+f4=hF3--zLEb9RL)5R;_A@eNj2>jD&y+HZ0>l!}~9WDOpOt`-K z*B^d0^Ds{0pDv!>dGjo51ODlZo-ZAkp;(X1v#eL~PZuv8@6EHUukcS7D;>=LZSzoW zRn&6n`RdDl@aqkoAzF{|3#%`$L0$-*eddFKi&bBkf1|XHDB>p!kF%^|==HBwTBg4E z;z#*p=uFpokr;TKkQ@V@LuwRW0*G1vQX=^!-gxLt)OxY-UWDE(=p0(BjAP+(URMg8 zxmqt){-q(H#n3rrfx_DbBrJYsLw*Z%ez{QTv3-Q)-_rlb-j{$!QDtpcAcWY7B+;m- zs8OS$q5?s7At3}3BoKB`1d${Xfv_YIP{GE4(za1tW?aUZaUXPC7-baqut-qRabHHq zVU%%TK*bGpM&*Csb8b~vS66oe$oKvK^ZfVe+vn7|=bpNC?z#J|Tafn_c!pLfUp#qi zz!!n%O2ZfLdD##z2haSA63b&%^#FL{8`SYA5>_cJ`o=`U{!0*8XH^Q^@3sMia?bD`mjr$5S@1D-Ln6U*cCU1fNb z(?5OpAnLf6B!Uhai5>k&Wl*3%;^>${Vj- zW+3_376Q1``YXM(4|@U;eeyng#+@YEPS zN6()A?y-n}6?j${zC`)^D0tRJ^ZDlQCh)v%_?-Lt+t#H@8O0=IsNnZ zdjy^czN16Rl_-D93{P|N&I8|=s}sv({$2&1y9{5v{M`b+2f?$P^N?^(`h4 zTL7ouWJd(#IJx_B7XheW`<9A~8VL)JO+`63OccdC!9H+nbatUizrNKEJXhDfCMp`&UE2H}=m)$|!Y-})*OJck=T=e|Dm)oI`<@$z}< z7xoX%Gdz0d`1W!U_{RQDxg7oZ$XjN3nv?e{@Gbs*VtKO={1|wSyF>Zn*$ekjbqCL1 z?^M2c=^KLJ^t^bHoZ^i(B3@5!}=8D5t;v zK15(K_;T-8t~LOE_4A>ik2O5X=`WAt-x=TwK9E@600cj3coNAwAM(Bd-{=Pu%R3&y zR~nu~@|eE+!T0P#iRGPu;4chMB6;5LZEeF@O6Ro<#CEKA#A_`MQ zJTDtQMDr~lG=aClv+z$UFJAl60l~ik&l83(p1elztpU&CM-$8Iis0Xa=XJvu&z{$V z@1Nkg|FOjKx+Ay=JUiml;6w0Cd`85@txty`_*(FMX!zpE8;yWZ!PEP> z=H<-*&r^mko;)mpTI<2nsWGv<=?I<#o)-;YJb7gZcoRIwuSEp7c=oawVPnAaj^T?Z z?-m4X2G4vNHe5V;^APp`c#eHR*sOT+*uI?#o~Jh`Up#s2AADwbl+)jyxeoCk@C7y| zmbVz7}F=Vimk^u_D{y$zm!M)Sq=|Ck?NfagcU7cYGsz<0ze zXw%{8ob-9hFZqTT9%00vUwy^;uM&J$zp7mE?1l7az_Z5i#mkQ^;CmT7kNidD#cMy# zMer-&>G+!RQNCaL8gZj@z;nbK%9jS&@FsZvZulHMd+Oaz zi2oCKPJR;zoTFz?e>@vuXMtygm(OD_y}(xip5Gb1ME0@*JgcMmeC=f|c>ZGeoagYQ zk9P1Gcn)|A2%PgA9(&0`*iqm)-NomZA6vmU06eF>O=+(B%A@C0giQobx#4r}>q%cW z_~wJ>8ZVzme@B4t4)8o>_!8-FJ$T-V=8MrE?d>D*e9{b`=np&xyn_gE&U1M5$N7z; zz*B7am>==n3d!7f*ky5%%n6%c}bax$OJ;+w+a!`P}fuv*$+K zDCcAJu|83GiR^h88m~F_NPp7D{;mSgjfO8?{?h*b1fCZRpYyyP`|AO|_ra6N1_F-h zi`O4I0z9Wg^ZD9eH}Dh~zIf@Q{Y?hXrH0Q*pU3{r1>bex`L~PDFF#fx;Xi}t(SIWX zT)h0Cye;7Azg^gb&rcrf(>dTd`7`B9WPdk<=PARN40e&{Q=fheo_3$Bym-%hG=h%< zPri%KFMZ#GZ!~y@exdSI&#~o={h^D%^J^EMpFFB}6?ksnnOGjv_Y`>EGkkmwKY8DP zz5_g)zieLK&*16smGZ@t$LH+~o{nE9mUjYz2Z3k0;fp7a&wDv|E@VRC;^~jiyA(Wk z8@_n*n7${#^T@Z97GK_6guMcu{=0-tHmLjQkM?&dc=9M1?m&2_y>!h-uz&hz@O*Cg zQgAKuJoeWY^izJom;s)ScIr1Dfhhs&TEjy=I=}R7LHdgSgYo%~$`h}=-3-1-;Q96^ z<#W+&<&kKIa%mmlvV_(t%|un+-`dhtu&TM+O$c-C^_1djax zKmA`Mg6|*T8Pitzv_8N%)Kg#8!9do5r)NO1 za4~qYbCfS$JJSvFt^m*DhR?}2Px@Hje*~Vuu_}-Cm7g6HgMPH(0V>Wfefbbm3BLRI zE+||)JGc=6?}2A}N98L8ub;g2FwB{!CRtt1RK5c6`Pso7(4X#+WOeGPd`>y{$=`2-wlVnYWrz4-AyzvNL44(J-37%u~l`oz>&w#v9;CbHg#d}`L`x|(! zACOoc^J5)&{$cpy^&{9X`4&8XD^z*$@`L&IU+_G}h7&Gc`Y7*p@H|-*;d9EH#MHmv z0K5yHxr3B171w_Gy9^0m3!Wh*$``L5XFvNJ@C+Z~k>|1Jq2T*Hc(xlpmKQ&Jz5`-T zIy=c~8mjU#Ro&zR$M9yoIWYByg}eQA3XONKIWUByfTP+6+B0uukzTh^Q(v0&X*e=pyK@GF@1BuS2`te z`q=Nk-0-M0|McxZ;BDZ$@`A+aV>`16JpHFe?(3I6_Uq<==d23l)AANu5A}k)H^Gx$ zseJM3p}ycN2G0`1=adhRy|A5m5Iip#KH8OE`q(af1fC5S>V2JdM%&BL2o{%*|1E|` zDaf~dIj3hB?$oLIb9$y!m*b$FeLkq?NC7DA?Al+fCm zKD(;CY)b7kyi27d932EwNzK5jxei-fp~-1KhZwe06BC~R=J`Sg8}b1{E~u@YTXlgW zG9bjl(N%cY(!NcaGDgwTg;p9xJ5Xq&X3eN7m&1ve>I|V3RZpF}V0LXqxs_>dez4FB zM;1ECIYcNWH3ikRRSxk`A(mFuPMcNkq~}N>4&Y&ZIMqc}ag@-?X4T-}qFL2W{9GXq zudJ-8sCCkGq7b2C5mAFvJ5)v|l`(CBsEIkkCpb;0dWceugmf?=$w3bPm<3~MD&`KX zsI02S6Ed_XK@6-WBq)ZPxrkhD@JaIBWI-(J~3i!K5UZ z=j5U1loq&&$t0GQl@1i^Tq|NFz!yNE{nV^u$Sw!-;k0&Pe~c8L535^8gS{&QjjW>iwR5LT zt#!mPLC2xvs~`B5{LKdGbR`+(m&}|k_oa>swPq+OM-82tbvNe53P&xdsjZkrhdIU2&E)7t38!%e__0@>p4oQRVDqbBfvHy`XTK= z$(6cdh~VjGdPnRT&@<2qQRl#Bpkid3rwm5Ek7*qRj$1{9B)D%~bxqZUs9JKEas4E? z#z%mDZ^}9YvCo@{1h_x8(l_qi`dOzVLIoqZtt%$N0Gz8=Hl+&pKMwqDV)&gzR#n5a zP6W?Sw7V#o4$tJt;OgG3A1bZXthZzME}m6Yo^wh+>llP?@Oe@@EpnT``7n6C_$(PV zGbYIwpxo$94jLPqANEIm2qh}WhsK)FKaJ2h)=vx?VTQmxNxp4)s`xSyEK zf#c&Rvn$T-O3hmAlTN2}^HU09;%Po|%+uJ12zG?98-0X%9=d406zcnYI8okE0=i1V z-}enSvZT&WAhxHS4lw^<-|=53jeUW=%t#Hq4v@iDMHBhnM#5UC8!r z?3B4xQ>tsxM5Si68^;?;$D*cmR(XXKtHm)lGA#Y1X3dYpv5tj|Qe1lrmWmuyH)Do8 z*Nw3fnUa2DEt7rX+uy%H-KC-=ah-9uD`P~(zjr@5Xz^Och$?~J7%WNsB%ufR*aSl* zf7kgWv{?JoQanbVAC-G1W8FvQ)ZO2}FKew6=$T2gD-L}meZtUZ?t5}@ zb>r*DEW)BH!ZVY8ee8xa5AXW>gGLwr;hE|;|NKw9z$o<7HXVD-p(~#3I5}m<%#U|H z^(bTseR0a;Hy!)e>Z@0FD(tbn>g{yPdRXWKdjI~5vHu+R>N($5zx3T-dt#RNHKEt# zHN3Dr>h5y_xS1TlwHw zp|=j0jaifXgx;t0&f9uaRe!apvdw7+-EqztSiBbcy}kbY&`(3gcX({X^@0E1|70pQ zHngJrGlqWg&9&$DzjZkWVdpG|ptN6mfM{YpB3VD{9RQ=gaN8j+}CwG0__ojn0j;|bmMqTLtcwqe2A9mfg z6K3&8qog1YfkLn z?&F)V0X>=N`ti$AgYTa-wfyI$_q{*inQJi%G*sxZXL>dWJ@#zSl|qj_8}uciuUNNo z;tl_N>A|sI-+64S&OLVHY*3+hyZf2DKl|Ot&Na{fYvjtzwpcwn9y5ZONx!|};lKRw z^#kRf-E!sp2R~Ze9~FksNBr)Ni$@Q>y~n^WpMCMwKi!F0={ca&T_fSEit?_1Y1mJ5 z8Uwc-lzdn%ri~sGdhFSw-wOSiVXHbld|9VMzRG^+-4QpRREEtiDZKyXi*r6+wRqOK zc{z8!vGl7z4{YKPdik}LpSC}2&F=SC9dl<>s02p;HSYa2SCzbn3-aVqbCl@J1r>J3 z3I}ugG0FkCQ_NwfCRPURgCm9z@cQ-MYIX*OQDs5rX z2F&L0Cyu@BC4Prd~q)hi~T?g>U5X_ zw(0RtcC9I&UNdnXYIys!EJdJGxRR&4KTLp#6*Piw| z$rs`{bN{nw_u}AO$#CW|j!1986N*Vd`Lp@GDzw`(k&P{mXTDeEdl)d2Zs!n_bFubc z63MQbJ*B2*-mJNP36Foa@WiRJ>zGY(Bpbs5z(*1i^Ppc}JIg7kA^;tXGQPHLDGyoUk;h> zmJ^9A5?u#S^UP^IgxcIG>O|_E2nF*{5p(*~3r0=3xT1Vy#f3QJpY$@JlL=vEQ*iip z4I@Y@|0iw~dBm>x2EpDaNVVHjBS*x!HP*s&yCadibl;b>bd5>OzR5F>;z}Mq2(dS+ zQd_cJrV-&Wz`N;d9wV7V~q=;^NX(OgQ$K>+f$}?(o+yDQp8oNZL{D1h~ zPPw;E$Cv;^O-xjFHCVtJ18f1tHfh!bg9WT9ZShS7p;Z`++x4)~1D^5e4ut10g6>3k z&TP|lfXwP7W2PhKkd}LvxdxggI24xi(pZV1gdIiEwx8TX;sZ z-BAW%7~LEs7^7F=CFDw@Mn3l-;Tq{hF211zghBY?lTL| zMRJ^(`xWHoz}t@Z^JeYgCTmYdm}V_8{Yn6_fVC3;N?T>HfHgM!TpUbq8}qf{{j@4TQHHx3kbOjE+Tyy5Kc4jvA+Phqp3U)af$# zF&>>#CS`DI(CZ0xdVbB+DKnD=M& z8e}oThIwib%A^dM$FKa0)IL@no-&5}P)}pvwe}#UwFj|)6<*T>i28$%@hyBVuZ%mu zMhx`!JL*6m;CV#Gp=t3kI}O60I;?#~*0<5;a9_5d>NpjWTvZ2TdTS5fcPDO4^I(aj z`;DnRrU2L4gP7JH!~)i8{44Dlg9WT@z(kC;Gk%IOQ`uw`=dDg}0M+|xBs&h_T|+e< z{-f8goE2oQGNXP?5ZVH*U5VR7X^pl}39rf^rph4pi#+&k5Okr(BHRx?=xi{ki}Psq z(s}%cw>es%fKzb07zIqn{Z#?PQ~|^yU5|!g*^|TynD=wwv!&Osm~9UOLAPC&jTlIK zU{8U(N$_cgZUZey4AtiMa=@V;wNWNz5N={&Rp(vd^lSw{(VBq|iN)wf??n-I7yc#4 zbnAu%iWYA>-Zvi!U>b4_aWV=Nug?c$0Y}jZ(xzs^YyCn@>lb1HYcu|pw#8sj^ElJR zgPym7YBdb&XkcFh%M2`6xM+U(FNzH}F`l~v@nVP@{fIkbiIW?y<-T{#WZLH(cy}fr z;?UT$*U%FjjKe#nVZF&<{T+;DTSM8NE5)Wm=3Oql?IKUE6zZOiywv?dc<&hAjzf5HeBDQFfQhGhh%nBs0BSv&*EY4I%?8N( zHlj^sd(JKk9bk|Uh;qBndxT$a!Lid3LXuJ!XpK#D<-9hLUkxc5d^O70Wob4 zhy|=I_$QVonNKWY6yaCJAi}Rk8sBAL$ObdcG8c@Ax>7Jcx;M)>KjU`ZEX#5S0@wOa zmB=y}gfI0p!<5M^Biyqr!v?zgON!HU#DPokp+Txz{VOzSOT z0k#U3(l#2*)iu5mq-=|s;jQ4?faZ2o5*>MITub0bc$8$vA;hZ!wo9y}Mf;{D8d#2f zCqUlYtE5b$q#F>XN+PC8BBn}G8kM9pd{Nd4OoAZq3CANC4RhkG8@jzjq47>$Sj=s}-s zP>vbs>9*zOOaDJ0)}5~wAM`GGeNbZhpu_^!MZ2c~TIF~0zih-VxnpGE)1aU~D5*pM?(Q zS2V^W6lKkE)GT%;LzdPVZ0h=1ZR`Rtd2+=xv!5onfB!Cpp0S_j`=#cCrvu&b>#Dh{ zqOuO(tgonTv5Z_k3+u3(;m3P&n$OS?elYx=j8hkRlP{+2)$c00I zv!~-7zcTm#0N>W?i+|=wnw4*`fXtUaAhaOXZSMs8u**w?}FzB)9>IrKu{O>>)^wf z8x0p<#wQ5{@*3Bs`Zi?;;VyJ`26zkntqAiLcsmaJA%7aj*y6n7M6;{9ckjU!wRl_P zf{MArD@(9ySd*Y)qo544%J?8e%eTI{?8x-h;i;2Yv?HGM51s_B6$vq|NQmKM>-bmNW`n^*uvpb3#Wt=|DV#2zQkm7~ zddij^CmmsXs8lnCV24U~a_*^u+ea(dCCGnqmuaPvX}Wf2Yq3!#2IfYY#8jEY0#fpn zwiDM%qcZEiPnny#dYsiZxHj8@xn?#b=ZDjmG6x%ym*U?F1uDb&saQzQMsRv%D5(i$ z0Yj5UL^u)%^_+s2d2EbPzlG0*x7`4P*y;5e`dbM1t^(R|IR5!_%M3j_FBZsqD)HMl zrYXkUGws|!AZl>DH%k`UMFXl#?mkBIla|Hm^Ef;ycT<)OMDv)I#b-MfBy6r6yT{Nw|u5}dAAN>S`dh7-VqB}*~n_8aWYM5eFGVfH`XNAH+EiE-`K;qKWG~@WQg-B zeHN&FtPH!+6COJbd-Qi!3yFW8+68q=F*K7vwJ?fyXghKcHwhY+u6p< z?n^gAd;-Qy6t#XZ0Ejvu$dM_pnJ!*4LpH*z!icHDi0N9T(pDKh)Er4V*EvCSbq47E zJx<=y?YvrBf@mrG=Ax&8amQ+|H|*s}ShziraBoA?%yx6vGO1 z3RdoO%!{QtQ)gAz)aIO$z|L&lY>(DW%%T<3;Z@G(MmcXFOqD}Sl|w8b2Bx%4xK>(T zW3PhbjGG#LRmA*vJFki^Mqr_*>9OM=m#v?gQ&CAx(ahPk3-&@IF)HDGy(;OKq$TTJ zgsDo1sY;0HI-b&=!L`!%c00{=kTB7s4b-3Fm|-^*n+qsSUx4+z!P>jGV=~Tq9$#(U z1H-u<_iz=e7%ee92VgY$2OlfS`lol>X_O%)NiNPq&YcrRD zT9QCZH#V;&RM&-5W>1+~)gsIBsN^f$KSxrge|{Q44_s>Ge}F|bLQFM6EWi~6OKFV; z)A=xGqh3>fCM7q)qlr5df7{^wH`%b);dWFRYZwaP=;?a+NgkCk4tY3OST+=Y>Y~TV zjuq*uaDu=Vl)#up;TYp$nwWb@@a#R%on%z`DR5OKF;yk8fJKv1+It4Gn;%>nhl=0m z?mvR1;y+g~{KdF*P`-fI0T44h#o^&Lz5cmTn#eE7&zJDSqByBtI!a^zFCv3f>w6(F zi*f|RpFB9BJzC4>g>jmo_PEjng$raeXG8L`wYoda+s8c6MC2{#yank7(7cn*b{uN( zh89|dUFV#8UJH!idI&Z33wxGKTP?iyEdBfUOq16t3XN4zV`>$|)GCOnRVa;Cp|t(3 zvg`JT%3S4UUsN{GsH}~nGGeMSVyZHwQDsVt+B}Rpi3P`1Cmo20dsipj3PF_#>ZDF* zgF#(XVT&|*_I3=+-bcNP?NnMeLkr9@X1~TB)lED(S*?(ms+5=x*_E~#&!RN*R1V<5 z{HnvF1#7-;;)%&xHytXNEy}NMntXP%l@lj~Je3pA71lK6K)42iB+jpL(iE|B(iAx* zZR1{6PQQjI@2J9EId$Iy^Vp*b>P!g!1uLjrXiZInn3@K$fWy-w%^s3x4+cp zDnP$PC3Ui+He#waVyZT!QEf`|R#ISeS5iD+VDBoa#SrA(O6l%6eKH0N>Z0o)v%ug( zY(Zrdv%auLmC@;VTD3T0sybpiwpH3jq*-Zp@@?1+oT{q8wuiM3(^3o%B{`jDyL(g&qS^v6wFP1UYZGG$?KOjO{9#&ls>0iww1?#g66YOb z)Pw3>if0`5f@wq#mEcdE-*Gf(#QhGbX?_;ye#lKUU}YM-+j9>xT_K#hY}7+c)k92+ ziqcqAlon1}+E|+!P7RMpE!+Ku@7OiNJfRJ|UGAF@;BD3HIGo9Qq&X!m+IKCrvwF$& zEz_8SxlX@nS*FRWG<%fKW2)7rh^f+u>6lh&jfk%_4$hRu_D*ToA|FnHF5B6<)D82x zlZtkSuBzj3+bBnsV*bIRjpDAdJ;u$TcBzG#W8W*`y;Dq-Ng1pnnpOEoyh_7UsJy1A zw}1p^W2?&)sbo82Z6(KU9cMbcYPP2ic#5`er6HzUX@~`^R}o8TZx~Eh6qUBap^Xh= zQF&bWho!q$p z%*DCG+e)am0$h8fbBDJQ2|6ipAHux#D(}gAbcFwNb7jGd8j4Vt1C(pFuB=Hn z!_IlABxhq%zE>8i198kKUgx;3BSX^hhDyM6GUIq7d&rk#SwZUMSip3^;{dY(j|b!= zOD-U2I48^s!t)i*AfFR@6#j{btb0F+>E2Ib0XaBHX{~Urv~~tdvkr1-9UU6aSXVx- zyP~{>Sl*=WN=Drko#_LS2;12+N$yNzBgbnlNpKq+ojcsU_wWgX`Hku*gQczTeEg|% z)nsOwYPjnJM7)F03`0z=+i8jv$b$2ow!zNzOPyS|AH^x2Um;yNnl|~TF1)1^ktDOG zK*3r%iD~I17O-|BmeN||T4`LRQd$Rx_6xKo58zhbcOL9Yhpow=^YN#y8C`M_Cer-+ zWk-y*ZOOjc_G@EetG`683=ad>R)(0iGQ6>#FV|EzX=P!EO5=V^FmOKy9?rx3DB2IUd zLQIuHEV7gJfA`(h8}J<7w~vknjcqMU)7^GmiHg8~%0}mz_wiLU*Myl?->i;*fY%aB zOiL`W|66p&36H5BTXXAf@E(lZ_fdbYv3x{-M~UstM=FV_{)qkGqCXDP#wF0-Ph-HK zF533YP<yvsi^v z&01V8s$w6Dm{x7XbkSL9n@p%Z`o^VkOC5dPC|D}!x$x++`Z#9IGU4N_MOZMK&2QGC ztYCb8zA(gJ;JG$RiZEX4lAp91uDuo5lo+zL%;`%g^mftb!*D2+20O55+MdhwT4m8*5%dsPiI zebL`Jsv@SUBBrWR8dasVG2t1xsTdIy^{Gy+otXDx_=TrhA@IA8GnTIz_uczx8%J!# zrB%N^xqeZq75;wF$=KmBD0$Ig4fn7_S>bk-;p~FSQ1;;bK7*1k+Zj&LZA6F=9+n*H z#}_)Xhli?DCr>&LGj16DSoa_?+1Lu>ed&D(Rzilx7)cI{!>fL)(f;|PSaMa}ha6IbT zyL6~)8ML}$p0hC_GV+{lA`>u8o#E5q%i-x(z!0Ef>wdrk05L9*ePNFQo`UODfL#F} z2h0b=AT3x1xEkcrAy&jPW4#aUvd^)y((8Wo-Z zyZZXnImzR~m*r*->+|!X&h`JzUvxlt-L0ptef|6G8F`KM|4q&KU1M?m=Jfi;0H=MzPWc~KbqT8h9H#A&PiGdwZUs7#u@}qXNUh4;Q@2S zPJ4lbMu(?JKC7JGKH+XlxeDQfJhdv*#5B-InzfX{b7##PT2Xyr?X;LdmCI0IcpgKs zhp@G{NwrMdNeep-m$qX%XdMCgiH6u{sdcOYWE$53a$e#EKu$ny06Y$`39t*`%YZ!r zHv#qqd-C3o84g8(k)`HLdn9%=8DR+9q-9&j%IQVu~(86B-#g%Y3U2dOnev$(B_Mn*2%;I zEQ}JGCIw4rcrX33+;scp^zg;$n6=5|2IElj&!M3|Cr_TVHeK>`6+}czML9&-?gWF_ z7Q|A)x`4VzB-!d1b>I6|3z;UlHtKv}0PO3v`DuYTd|3S`yE}1kgyggSdmN8a1q#>VWs^4DYTEFzgEQuAC-h z8V)fQ^_*y8JSfDpIv^I1SALYX(u8twI5y*nu9cxK^=n$yuWePibXVOM{);1rB97a+ zb;NWX$wcDk4J~LOr+gfK7*X%Y#s9ZMDdlVq8Y(1!*f77$l@_%unE=a z!B)-OsiIX@vF_5!dsC+r(+QpqZB&qu3nP3cjAnyO8+vt8TGxqgX=TLJ%82Ra8>MYF zq0lYn!}}C;Sa^JRL{6}8rd4}HxFnr#C5;VtTNCOU9=IksG$46p(xkQM{K~sEh-x+E z%Y$`wzqd4y0mcn5ko6IrJ0CdrZ#P%b;UZHuXx+-tCTb_^waDa!=gkA}yKM4) z6W>XSsb2MN5awjfUm!K^VlyjTCil`3zQN(Vub{KIv}D^co%zTZG7mMx>Bt+RFrOf8 zup010z*&GN1J(dCf9C+AHn!#h@;OOQ2i)l7DKX7cVgV}^|4K_Y81i()_`JrYZ!F3V zmrQIZ&$a4%CCy9AuV0hgXYFNQcWqp^(trQ{@wk!OxigJT-eP!frr2?gL)Z~xo!H(? zF*E3qLrF?%^y_U2Djf)8hwpGmjhgtCil@xEl{R=(cw5kHBm5kS1Bts_Yrq^pJeM?eyr!aGffBW!LQE?rV&+8%p=~sLrtmDz0d-+^IK(YW!M>?hZR%=Z z7CP>D1+p#^2$OtS4X|NsBMfLNU z*^j3C#;EfR5LKPTRGq|h+mg~g1i#Y4iOQb(I40*uOC(7m-Ntr;sXgSJhSu4h!MMo zx0SPI;5!T@@)jBCd<^#PaYQ9#D_xY%c7g4H?f49ht)kmnR9-=b<5odF+c=X4?>c!v zO!I&k#(?-&8fy`yMeTWEQ{+GG%5JXP(SVU2$s{Ts6&v3Ejh=R89P;ofuP?-(y2$B> z=m|To*vC}YHhZMH_MWiE^7|nkL=BFZJ}fbIB6#X=r%-X{P;s}W{GLojQ+`K^UB_w6 z1HtA0tR2YXa^7dX5@Fs|F~;GuG9xaHZ)DEn@=Zjn@J3y?Kn30t2GFIzYZQ(Sh^Y>U z**Y*MA4hFo4i&c#6?X^~=QQQB8iQt}D9d{ms+rS3jlXfQD?;7QtD~zC=v|Fq9O|eG z{JVS5pnIG67U;?Qin{3OQ%6t4R8Pck^u&(TKE)jtb_|!HPn2cV9uv+_4`*)-58RlH zQD}MyeWr%w+_DgAs;x*oCI?ed(RTv21MwpRQg>C=9ig;2R%3M35Nb`Q#M}?O#PhNx zQHtphL+BGX2W{SrQrm`7GA~(o(mB zUrQ@7%>iQiHnP%o8a|v89^Tj?LWRL4+R)3d;xU)4uS% z-RDQR&YvipF{`E`ztFtU?>T#7Ou^tGP?zMfFk3ci zDBeqqi>b9;1SiJxAvVKa4h7yWlIGl@!+KzF<2plQ>Xh24({lT_ApJP^!k*r6&K=;M zihd>qQF~U(>|_B3;c1obzTpd)lj1YuyyhTmoZ&&v*1QN<3ivYM6u_4NsTW?;TE7%I z6M@kR(ya3hrW^ejnr1bEMl4|MGNEbKe;hu(*+3gflQ*`B1uXU+zZM!RUSjw%GX7QG zEQ1BCB@S(wL*qEDVL*C#$c~tEFb>2`ABN9HxyE8YqNK>yz=wpEkAJtbm)~q?hasBu z>v+wRGH8x;qzoy|wjcI-K zeiV~~3fMDe?eyky^gi;>G<1gNGf1-w_^zoUlb~|lra??ce#GFX1N*fiPh><(? zIOgqYqRCrLgC#jlgOL=}-o5f_QwL#^sRolwV^!-J;Wsm$XoXW7?8%kJx-UZWlEY29 z_Ha6)Md!#8N-}Pwf%Y>~R$6F???3n14p{t3ubq=+@Jog$`d4a5R+Uc1uzLZH%6%48y4w-YxFl3Z#U zB&HA^oUH4V;lsl1%u;5I9fXG`PYw+;2mT+6yGC0=IViUC=CrqL@+s&f4S?>lNm>B| z;oRZ&xQ;n}J-j!kc~6#IR^FfeA~`Lpfi&N;Yp*wbfLlf7a=ygSKc*}ZgXugwX?nm1u{4WYCzYm)B;han{9M~7oRasV z$zQB0g~uh2w2yF1l)Hmb_a>Vi&wHM`)D@o!3Bq})>fE_!uSO%;F>8>_eS3|OxqBtN zckeSb$$Kz&zi%#g?Tr};_dY|Ar||k^=~rMoAKrF$jf8(d3!p6YehTS0UWHq|AHr9@F6e(^7LdbuaB< z4sN0|@-fvo)8Vbgk4JX$xzK}?Y(4>SEUr%ktN=U-km>FS$ZS8v$#!Cz?ZhqeL6SJ)qcbu|cQ+I+krdB(L!da-K4PV=U|g z;M8W4WO#F_V3F|uwiQJP6{vj9h!?hehPRPBkWc2!85|YfN(NKfN4N@MUSndKnZ`x% zKMcm7I=}v1DSei8y8KN{}RCx1f5>03r zHmNLx8U4@#GvXeVA7qb;yFLkzvHa{PJO-Ztkw!*LiIre{Q<{fRIy_vO3*jsNg-0n^ugz)ni8O|MF$K~-&iD_mUIfc^VW@>Lu$<_6s zDN&oYV>)O`P?^)c>O?h^YxF zjV7ctv&k^L*9UI=9=ANlGaPNCv0 z8M`OYqAi+>afi4oe$H5pYPB8HN42vl$~8pv$Ad(l1Z29O0;D=~MV;dfrqf%b>FLkJ z(&QL!rPc3{Z7!J83jYwEmzwuM2zy}guG%QfUzH_?FHa8*&CSG=W47t7HzXe|?S44D zDLlF9-uh zgVRGDc7|r`MDuVShJE$x(^2bRjC4ouuek>l+bsveXS9n7i|QffIu-B=Pk0H42O4e` zm!MC0x*7RVhpgG$@))K!d{HMh2+T*mxNo$WGh#L5B2cEGh&$38-^8*b@r%wh2j!rP8%D~6|i zu}IQQ1q$zrGP8BB{kX#sg>jua)vkzKwrf~jX)O$J}Kxes$X*EDh-%?fD4#ZQMOQ@jTz^VEiAQ3EN`q9hBMfB8aYhF%X%=m;+d zS1JU7;_O+*d~;2piDs$RMB~gjEVZO^F?ejaOY5)t?3}bH`P8+cq_vTi;DN6A9SlzO z(7Ah|OfXt{aqe)t_M-9K1MfXamogcbyF!}=<4;}8M=5*v9*ylhvRqqGU0yhA?p!oe zI8!&qvZxq!wq?0K=4ekOvGnWlPwmW-@C&#%PS!<1h&?crY4jRiwlTb7C|u_biRs)S zFx5LhAtxbu=-+wb`_zj z_nvmXAliu7j_1JJj_LN6#}%eLjucbt3l8Renw4*`fP61%jL;fDBNmXd$Qb&CBVqxI z%Rw5q#$W;K4q(c6kHN6e-@=2^5y5*<`b6BweNZ~m6XnjAaF+OL!9-iQOmPnBYw3~d ze9ROv;PV8Fx{bMD37zWjRYvjow`cK;YIhj|y@zAlacJ0~VkdUIb5a-i2ehD4T?XN< zzLB>)Fdg3WQIQAI@2thMYsZL~R=vdZ9Y>{YLVTq;&j92S(Hb*lnPBcP8>i_klu+s* z7{zByM-Pq7FUrrCNYS<-IR!f9)JMg(u8h6}gI||MZ_fPJn`8PG+Y-vOxeyb;J7WGX zsB?s*meCHFTE@{1#^?SPejvQm8 ze{=ITw2vF+J%)sPQu9|q)!K(4rhOP<=NRaA*SVn*naPt@PiiKu8EH8 zeyOg>ZFs0+cWNZFz?z zW^n4Qf)jN~ZV?k>mxOt)T@qpeS(5vW(5^-(v4Hg>FvdW0g*t^;z^VYIajOg#ux>G- zSlMv+_MuDid)&y~C9x~pmUc9lc=McTgD#ETK0}i zN5l>q?LlH^Nsaz7ZLGgpndd5ro$eq}@1*6uP?0vu#I({Ormv4EZ8PF2ZNICs*Zx(d ztMKf-DxWc`d=`+|{~RD&pa&dP5>r(YQ&lRBs#IDt^JzJjhg^!i<(}LMt{$mk*cv2J=GoF@c z(cMk=?Amitvh90VYlO@m+@20aG}-KmYO>jP+Df?-)^T1YepiVD6Swnrl@=n<`>|X* z4vWHp5!>>1m2Bm(r)1+Tu$MM5_QHI55vox;Af|ReY`=Gv-jF=qTyO-kFFgB%YeFjX@^= z63+KHoMJaE?=r>IIeXG&dR0t~T_)zecA1C;xXs;qU1--B3`GF77Gvlv4zYkW6EuxG z$6z{(qkNpjQNDfXGQEu(?Ms)5kD*|yJ!J^pA1>2Kt63QB7M--o5J3kh$ZHcn>w3+`RO0<)duY}AT z-P2}XQ_W^xQ!N|ExSaqmErkcCHe{dN=QXUNtqE^k`q`p0MvZOg#%Uib{5Sh7qrvIn z^v;n3k2WONZ%?Y*#*;TDojYcP*)A~oytS$Fmb!KuMnVEjG%|O24}}`X7J!Z_r=!6V z=i{NG<6Da2>~QZnMk9Q}?Q@LyBJb&*@OMQJv(U0~;5!k4v*l~JHWe%|>>PVPO2#yk zpEEDt?0JD1hy#*qW6wv9G*3B@%RK_F0ufs!*^7T%4zw5lfU>13hPNHl%4>F6*(T9# zKf}RI~l5=ERvLu~kT8ou?jWR(FIS0{_XLn`JYT zPf-Ij`rAXg)zI`VsxKx-wmu)%ch zi7_y`fG}bK>q1}}mv2mIT+TfyALpKwZy!2RDPoSSX&!>lb|(5;I`_oK(2i7F!LSIh z6@n6+jx!REmMx#Kjvkf`WHjTr7C^^Zl#aD3#LG3FT88zcyTjeH{oHvs!((2QNf}4N zUl*C-PTW^_rnu2j*vI*Q&%&zAfX@^YnU53^)7gJwa>#0U5EcORZ5B~!+|?BH!p*us z1~Ansb2Pqw?N-CBKev8a4C&nAZv8Gt*m)lPQYK}b3_mfVU+=Kk(dgbQG*z1y&yoUb z`Ya?sS5t_oK8dyD&{|IS?r*zf)m-J#o7*mnTUzazsr0?qAritS+BHAO>Ww-qaBPy8 z>X2AVbjWet{?;K!TGJEgu(HKEv}f`5S&Oc*m(KA~k82%05>q`AbINw&LJcD~1(^Na z_(k~ygwnZ-DvKenSydhjPv;JI7v<{^=KTmMWm3j*@R<>HdW*6>J+b%tGbPzO=SB79 zAOTvGiK+UCwZshBD(-JH{4LUWQ35mkA)>d$O^n?!*?TP_C7$lKnQ5jTzlJVUkHl1u z#9H3bZ5Ym;$?hGE&f(2($}WaRRdgmGAAA3`vxetqUT+Ei!! zx%PL17R&|B-IZfE!M#E3bA+Gi?!HF#g#EXMj?k@O zecaJvdcBFF=61yqYpzoO_AGLjeThu%anQFEevrpDsjH6gQ{b!PH_zIz$egtt-m`}@ zkLN?Odk#c5Ih=w#Z!5z$=DzlXi3NB7n01=a<{3;sUVggJI7%QEus#EJhS2zY!~#|s zsy9kbvql>%U|j=D@3GuquFYblJL}hEZ$o_UAFE%}QBgT#;QR29Z(`0EpvkH6WdP%* z$!zI)R^lpKz6tZNU{re^5|RRA^Y)`b5Qo%=W4{`#aUJ=1Up}I?$5cQH?x%`Mv2uWQ z6I%U__IS;ys(5VpPkdUw3*9N)?YZz}&syQjJLffqYI8I5cIADL_eTBhRyfq9J$wfc zb3zkybAfll8yMM_4a7V3nc+F<^-Vv&{>9*iZXY#t=nsZY;oae*TdxaGNAZvA#Jd;m@$Q9PnD4=}*bZ-%$R}eMM#sX;!p&>?mGEo|?eG&1 zpmFIH7kM7^gqI^c&CH7cm8nB_e1^A`9*^GVR-gEG^+KcD0`L8(GSkd7(omO0DtvE4 z={X)Q>a49nbu(tjd0SPN=$s1EXgkVQmjl2`z6B?3@qG-QXLCHF)KKaXAZ!Jp4g`D! z+Z^qs$8Xth2-hO4%Cd*J`M9zjpRp0PPaStN#Ir3c$m`*N1%PFM96yc#q%JUL7G&eo z3wEkAFT`}_g;+q&2v^z)n6A>IW{pRU8H@F1Z0_sG<1+cq5iI<9bQrAA{7mOKr_k)& zP+7L?+$&ab*3-0#(DGGe+|CQPNU!IKr$)S~aYuB1|UT7I!>IPem z{O9t2IbH*|&Rv%UA$msEQNX%@mV%erzTu3it>@K% z-rX-uGt>BMz>Y00=y*fNQ}kn&5%jjabq+jBcs9gGHK9y-Kc^rO(}F~74|;LeGB?>j zV`WGavKp?XeX#qcC)6}tOIzc0TN8eVxlYmRVe=W-#$1&1LJtUQ7*@uM)+VGcFIt(4 zed#Qg;St@PMNW}+hR>FRskj)FEi>$jU5IPNY8`AbFdda%3ryqw2AGcaS2(mkJJ@;$ zvyC?w6x+QIB$8*^O1Zn7Kf+4-xx0VST~3cVcve(Q-*ccler)%#B{Fh*VfSppPH2my z^!!Dn^!P=jbpJ)9ocW7L>Gq3A$@@j5bp1u7booW3==&}=ql|dpO=Y?12)_~jusx_i z7x~tp?h=>^iRxIoy|1%)Yg1OHg;JUJ1;+YChaZsPU4k8f|4PA5z`s`8%xITJU$94+bS2#i^&$ICIJQ)D5UnV(|iBb26*A`7B4p%gi6gJzW?i@7vE?UB(W zQ{*fenr;eTjTXaBi9Kbqe#g)_=S*Vk*oZ@A>wc^Z6+KfKDt#_ogzva~y`kvGr26l3 zGOpqRRL0}WA==uV`zwNrS~rxw7plYW!%*Gktt5r&9t_p34Are_Dq77aZ7NzpGK93w z`=Fu33KymJ89y3lk>-yN_q_!N0}NZb>$0ryaGZ?%r?Q696(VH&zYFtrZGVf0efOzb znbB|!B!r7rh5POdPu!WzqxKp~w}guD+Zrm`AyGz+0||H04odyPtybMhq-~N=NM@jR zWx``Njf`-vPp)71p;a5WC`KoGicj%jI6?S?~QFJeMY%U zSAao#KVyOEJQ-NG&kC2O*00GFu8hZD8)?VbJ{C#{=a0rsRK)fo5|+IM{f3vnhW`;G zx1S=U4~6uek`9Bs@Zw^ULPPogTH5Qiff0_Fa8ag%Lp0K&{XW0bLDLhT4ywIpW}L4} zF)qnQ1hz_PEikzaO}|DAu|2Rq!l%f2adU+>0oQW`n*mIZPpJo{gN{D|I~ipwTSnj- z%3T7p5F^`ah3BpoECU$Nk;>-jRA#~)XUNDQL)rXbiyZ5bEvLntf%uqQ1Z}3o<<@>y zD%lp_JJis6V6VVuTi4-#y71irtV*zd0jm(~YhdMq?FM$ENI3%OxBxU1Utlu?>kDkQ zVEMo*1se$LBEk5M@`Zv81vX8vGGJ2#vwNZgA>DR$2px|LJ8O94>Z!P*t`C7f-xI#- zfaoJvd7pFLeMDDJ6(@n4{vl7^#m8F~Bszcf?6QI}wNoxE8#%meY{AHqf?=cc^YhQa zOk?~G=r3`D-0u7T7H97NTXft1x5(T7x9BPp&pS~9yyyDUPEUnBvS+hu91wBwkKm0p z4H-1k)NPk(BQg|Ym+ux-!iR!-pq0+)3fp-uGa?p=(|Yr|V#lV-M5pR;y|MS-bKA!* zm*{(S>FGHtxVz{2OwV;U&vl;Xx@+u#!C9E*V`Xq0JP)=m!C}ZCQCXAlryup;xGq@qSYq=O12Eo+OR&a9}NHmiKtl$jOi z@|Y7Fkngr*es9F}u^@1si4NHwqzxbwgQo$a#t*XpeGcGxfRg}c15O5HXKV`KEr3%2 zx!zk2cpqQ|;1edi5pWu=Uj)1e@J+z!fNWmTjs$lB&IIIqST*4BNXsn1lL2wBU>@Kc z!2W<(90`sA#BxM%3LxeWf|mha4EQU+d4Tr;&If!FZ~@>Zz)JwP17h3|{0?v-U>iLD z<$yd)co87&p4ZHp38>B6%9q;M8lra&8nFOhQ<7eL8o$OTSU}pb^MsF+a>N4iwbV&M zs|Sr(!1@^2WTEkRcVYpn2zO=QKg}vJ7(NdPj44R7UNcz0IvCfQmctAdu(|+a%baGN zX|RBN0fTLHnl%vr!~!ykVJnv=omOHx@|Y?#-kn&$dIJA!`O>VX4Td+Mfw5govo;wF z-^>8U))3QM2E+DOU~CQ3tQ`gmSlYnLp}7O|Hib7xK>hmSwYpaHNARXd#dbLaXUneG6g(ID zbqG<_^0B^!r`l~-1f&?=eq>HHw=>sY0{$L;i07jOj6Pn~y7XIAya=oj&W z1bJOY&ob2{KS0C#`8ebd8>%0n^+S-Y_J-IxuxicB>YFw5wP?UDsH?23m@Cz*?1=5@ z63Fzie&sVUo9J#r{lYZ=8t_EGn*o`A)S*)EEP~c_dpR-PUQSGR?<;K!_>~s@6@vO5 z9k3Q-^0BM|%ZBST-@Yrvzf`G!5ddZOiaC zBK(~Y!%bl7Tf_e<{+F zSL+`O+TBodwtResIh8G^$Q>i);2MPLxCORg-6(OHXUg}ogZ&kl#$W<8#!g_%B?j9{ zjgf{sDId-NHhjkdYY;x1;VI{AW?TJ$X{st6K3XPAVmZ9+u0Uu<`vTCtRpTIB&-R3$ zfmxVCQNgnEIvAcO!?@$mMED^nMGR+2ei`9o+`YNz(TtYQL9^!agGOWdc{9({`-GDI z1!Hl-k1`IJf-g=?9+#hAf^kgLAjvZwkIv#gh|cY{KZWP*PvKqnr|>SCr@uwMdTVFf zj%W|@YiHkVkzs_}hR`WCju>m_jZ!;95Y?f?oix0Q?5<0YLVC9|UC2@gYE*sw?rSH^xs#_!5-mwle3VfNrgmwY`*|(bs4;zT;V}TUq*iU2i7tcW>7Q?9^-QGi`>GmEfH%0o7RDFt6cee-@ z-5`%}rfb);InLJR`0Dqu_a+w~1;V$uFKQir6)-2%FSIBbp9R{=n#vWy+3l{t&BjfRP!T$zggTfp5s+8U4%1Nr3=%FEv)?JcN zTD`Vb1;Dgjr~-Bfax>dn;$Tz(TZn=1wqsw6<&a@?Y#~lT3jiSW>kPERpG6CBgsTPM zcyVz27NEFde%F@O`9-MnOWlHE>-;?uhRFc7P?y2?_4GCQ%%{L#4S#psz9woj-caf< zYRGmGyfa9wzc#z-uN=@?xjyCj6|T$RZO41FrsA-|&WEQ_Gf>tufb3^J4|pEnvw$@J z=Kz-(I@8>UYZk5FBKLJ%OFPhUEwO+cdU~hO?gt;SfPCYDG16p&ODtdwK}s|(*U>aC zN8rjAG#FN_igwm-PRdxqyVh6i{5f2jEVaTqtp;}beJdy%ysyA#TPNaQ3;L>98O+d|NZXTPT`XA;q=8g7_EM5()^>t zBhnkPuLuVg_eyH}WlCL2{eonx_Q2x$eCgG2=SvqpzZC7j%hS9Nf z(D9nqwH)4iP=OtXIr;23{HgPfWXy-P@O8qPqUx!07tFR#0JbBwtxTuLANpc}?5+BXUGXJj8UwLoC3U5}IbcWiX#luPxpYM4(gAMt^^et71)9 zOo6KmEv<#wRE8QZ2H+A+U1qp6J-nRJ!`WAJ{b%vd$r$iuTy;5AwD@O^=`-rv1Fzrk zQ~l3JWL$M2@QlYFr?}m@eB_EKoausr=SNg9rmhy6BL$R(= zjV#;Ni0g(iTSty)ScY`#czsD@#*)Vvt!PKMbStF(hD^U=(nhvfhFj`=Iij$sD;?@3 zF6w&@wH(yoCCA{Q&jA)5kZK-PB@L3$qY>Jdp+nN6p06WlBf=YnRaVtRNg6YqVfN#o zwTlwV*OQGh(yy-n0m}FrDOiW>wv5Y(b!IF#C>2V^3FEs%=cOm4a&i6m0`O)Gdw)0VPT`(1B-gD#ml0`vTfCfa8^=sYb#^v6^I5&i&PSq zxWa=ouWlbDF5~f+M>N!}atlk5i}09LQ7fTQvBD-1E8OvPr&zdXMVSgXFMZpmNWocB z!xbVS{gIHQj4N2yywWlrZ(F~)e_2D_?QV%i>!r7k*mg4_A-a`u<*&Ta^LF7>_dYvo z4zK^Y&Bezzj7{qET1|(j8$?}f9|tWolrA4}b$Vy_%?^-@@R;RMk3DGnUGnJ==HC)G zd%&A6W^W7Y<4xOkW1OtF3bLZa>#u zKx_MjZ(-pK&&TTc&ArlZtUC=`yBn@$PZS@s$O$jIgQ4lyhx0qMel>j4Mtr1UcX-Lh zWPq}f+mkQC)Ob`vvPZfu6-COl$oj1dXC_`3&Xk4+nX{L!UAv@Kt+77bwq3i_cJ107 z&@PY$&@R2*fo$JCLGewI7dEw1xdgP2g%$?(55evL_IF^})}z35ITzg)GiC8Eu;~(d z5cJebFfIU4``OlT{B!y~TTXdX>{5qzD==N`eZs-k17kCiZM_LhCI1818}Qi{m%o(O z9(6<#JdQZVzjl9zIkYLjborW#B|6P=6Rbvy>zWp(Qe!LzruVoO zn8skY=SBDwi(876ZzHe`LVL}jy$x)g(EjGoJ_p9mUAFaK{Hr`RRhj~}WV)<>3NQ`L zb3zLp>|9`)=hGb8Rlqdgwg5AW^uWsHZmrtbi}XhUdk(Y|t1qz4g5?AINU(vxm|E<% z0rsI_LxH_3SQ)Ut3N{+p`+|)J#w85Qj|1Z~r $dq=QxU~dUF4cME4%>c$07W;F6 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

    BZ-R@A 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 z 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
    MCJb$S6`c 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%0Dw*{!cMob}N3@t(Q6J@>^W#&rj>J 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≻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ⅈyUC65L+=796hu1n0y)+4vE9gN)dO^x4O7 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

    `euUJzen0^ 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/desmume/src/windows/7z/C/7zCrc.c b/desmume/src/windows/7z/C/7zCrc.c new file mode 100644 index 000000000..92c47de0d --- /dev/null +++ b/desmume/src/windows/7z/C/7zCrc.c @@ -0,0 +1,35 @@ +/* 7zCrc.c -- CRC32 calculation +2008-08-05 +Igor Pavlov +Public domain */ + +#include "7zCrc.h" + +#define kCrcPoly 0xEDB88320 +UInt32 g_CrcTable[256]; + +void MY_FAST_CALL CrcGenerateTable(void) +{ + UInt32 i; + for (i = 0; i < 256; i++) + { + UInt32 r = i; + int j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); + g_CrcTable[i] = r; + } +} + +UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) +{ + const Byte *p = (const Byte *)data; + for (; size > 0 ; size--, p++) + v = CRC_UPDATE_BYTE(v, *p); + return v; +} + +UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) +{ + return CrcUpdate(CRC_INIT_VAL, data, size) ^ 0xFFFFFFFF; +} diff --git a/desmume/src/windows/7z/C/7zCrc.h b/desmume/src/windows/7z/C/7zCrc.h new file mode 100644 index 000000000..ae230991e --- /dev/null +++ b/desmume/src/windows/7z/C/7zCrc.h @@ -0,0 +1,24 @@ +/* 7zCrc.h -- CRC32 calculation +2008-03-13 +Igor Pavlov +Public domain */ + +#ifndef __7Z_CRC_H +#define __7Z_CRC_H + +#include + +#include "Types.h" + +extern UInt32 g_CrcTable[]; + +void MY_FAST_CALL CrcGenerateTable(void); + +#define CRC_INIT_VAL 0xFFFFFFFF +#define CRC_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFF) +#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size); +UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size); + +#endif diff --git a/desmume/src/windows/7z/C/Aes.c b/desmume/src/windows/7z/C/Aes.c new file mode 100644 index 000000000..8c185f20b --- /dev/null +++ b/desmume/src/windows/7z/C/Aes.c @@ -0,0 +1,262 @@ +/* Aes.c -- AES encryption / decryption +2008-08-05 +Igor Pavlov +Public domain */ + +#include "Aes.h" +#include "CpuArch.h" + +static UInt32 T[256 * 4]; +static Byte Sbox[256] = { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; + +static UInt32 D[256 * 4]; +static Byte InvS[256]; + +static Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; + +#define xtime(x) ((((x) << 1) ^ (((x) & 0x80) != 0 ? 0x1B : 0)) & 0xFF) + +#define Ui32(a0, a1, a2, a3) ((UInt32)(a0) | ((UInt32)(a1) << 8) | ((UInt32)(a2) << 16) | ((UInt32)(a3) << 24)) + +#define gb0(x) ( (x) & 0xFF) +#define gb1(x) (((x) >> ( 8)) & 0xFF) +#define gb2(x) (((x) >> (16)) & 0xFF) +#define gb3(x) (((x) >> (24)) & 0xFF) + +void AesGenTables(void) +{ + unsigned i; + for (i = 0; i < 256; i++) + InvS[Sbox[i]] = (Byte)i; + for (i = 0; i < 256; i++) + { + { + UInt32 a1 = Sbox[i]; + UInt32 a2 = xtime(a1); + UInt32 a3 = xtime(a1) ^ a1; + T[ i] = Ui32(a2, a1, a1, a3); + T[0x100 + i] = Ui32(a3, a2, a1, a1); + T[0x200 + i] = Ui32(a1, a3, a2, a1); + T[0x300 + i] = Ui32(a1, a1, a3, a2); + } + { + UInt32 a1 = InvS[i]; + UInt32 a2 = xtime(a1); + UInt32 a4 = xtime(a2); + UInt32 a8 = xtime(a4); + UInt32 a9 = a8 ^ a1; + UInt32 aB = a8 ^ a2 ^ a1; + UInt32 aD = a8 ^ a4 ^ a1; + UInt32 aE = a8 ^ a4 ^ a2; + D[ i] = Ui32(aE, a9, aD, aB); + D[0x100 + i] = Ui32(aB, aE, a9, aD); + D[0x200 + i] = Ui32(aD, aB, aE, a9); + D[0x300 + i] = Ui32(a9, aD, aB, aE); + } + } +} + +#define HT(i, x, s) (T + (x << 8))[gb ## x(s[(i + x) & 3])] +#define HT4(m, i, s, p) m[i] = \ + HT(i, 0, s) ^ \ + HT(i, 1, s) ^ \ + HT(i, 2, s) ^ \ + HT(i, 3, s) ^ w[p + i] +/* such order (2031) in HT16 is for VC6/K8 speed optimization) */ +#define HT16(m, s, p) \ + HT4(m, 2, s, p); \ + HT4(m, 0, s, p); \ + HT4(m, 3, s, p); \ + HT4(m, 1, s, p); \ + +#define FT(i, x) Sbox[gb ## x(m[(i + x) & 3])] +#define FT4(i) dest[i] = Ui32(FT(i, 0), FT(i, 1), FT(i, 2), FT(i, 3)) ^ w[i]; + +#define HD(i, x, s) (D + (x << 8))[gb ## x(s[(i - x) & 3])] +#define HD4(m, i, s, p) m[i] = \ + HD(i, 0, s) ^ \ + HD(i, 1, s) ^ \ + HD(i, 2, s) ^ \ + HD(i, 3, s) ^ w[p + i]; +/* such order (0231) in HD16 is for VC6/K8 speed optimization) */ +#define HD16(m, s, p) \ + HD4(m, 0, s, p); \ + HD4(m, 2, s, p); \ + HD4(m, 3, s, p); \ + HD4(m, 1, s, p); \ + +#define FD(i, x) InvS[gb ## x(m[(i - x) & 3])] +#define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i]; + +void Aes_SetKeyEncode(CAes *p, const Byte *key, unsigned keySize) +{ + unsigned i, wSize; + UInt32 *w; + keySize /= 4; + p->numRounds2 = keySize / 2 + 3; + + wSize = (p->numRounds2 * 2 + 1) * 4; + w = p->rkey; + + for (i = 0; i < keySize; i++, key += 4) + w[i] = Ui32(key[0], key[1], key[2], key[3]); + + for (; i < wSize; i++) + { + UInt32 t = w[i - 1]; + unsigned rem = i % keySize; + if (rem == 0) + t = Ui32(Sbox[gb1(t)] ^ Rcon[i / keySize], Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]); + else if (keySize > 6 && rem == 4) + t = Ui32(Sbox[gb0(t)], Sbox[gb1(t)], Sbox[gb2(t)], Sbox[gb3(t)]); + w[i] = w[i - keySize] ^ t; + } +} + +void Aes_SetKeyDecode(CAes *p, const Byte *key, unsigned keySize) +{ + unsigned i, num; + UInt32 *w; + Aes_SetKeyEncode(p, key, keySize); + num = p->numRounds2 * 8 - 4; + w = p->rkey + 4; + for (i = 0; i < num; i++) + { + UInt32 r = w[i]; + w[i] = + D[ Sbox[gb0(r)]] ^ + D[0x100 + Sbox[gb1(r)]] ^ + D[0x200 + Sbox[gb2(r)]] ^ + D[0x300 + Sbox[gb3(r)]]; + } +} + +static void AesEncode32(UInt32 *dest, const UInt32 *src, const UInt32 *w, unsigned numRounds2) +{ + UInt32 s[4]; + UInt32 m[4]; + s[0] = src[0] ^ w[0]; + s[1] = src[1] ^ w[1]; + s[2] = src[2] ^ w[2]; + s[3] = src[3] ^ w[3]; + w += 4; + for (;;) + { + HT16(m, s, 0); + if (--numRounds2 == 0) + break; + HT16(s, m, 4); + w += 8; + } + w += 4; + FT4(0); FT4(1); FT4(2); FT4(3); +} + +static void AesDecode32(UInt32 *dest, const UInt32 *src, const UInt32 *w, unsigned numRounds2) +{ + UInt32 s[4]; + UInt32 m[4]; + w += numRounds2 * 8; + s[0] = src[0] ^ w[0]; + s[1] = src[1] ^ w[1]; + s[2] = src[2] ^ w[2]; + s[3] = src[3] ^ w[3]; + for (;;) + { + w -= 8; + HD16(m, s, 4); + if (--numRounds2 == 0) + break; + HD16(s, m, 0); + } + FD4(0); FD4(1); FD4(2); FD4(3); +} + +void Aes_Encode32(const CAes *p, UInt32 *dest, const UInt32 *src) +{ + AesEncode32(dest, src, p->rkey, p->numRounds2); +} + +void Aes_Decode32(const CAes *p, UInt32 *dest, const UInt32 *src) +{ + AesDecode32(dest, src, p->rkey, p->numRounds2); +} + +void AesCbc_Init(CAesCbc *p, const Byte *iv) +{ + unsigned i; + for (i = 0; i < 4; i++) + p->prev[i] = GetUi32(iv + i * 4); +} + +SizeT AesCbc_Encode(CAesCbc *p, Byte *data, SizeT size) +{ + SizeT i; + if (size == 0) + return 0; + if (size < AES_BLOCK_SIZE) + return AES_BLOCK_SIZE; + size -= AES_BLOCK_SIZE; + for (i = 0; i <= size; i += AES_BLOCK_SIZE, data += AES_BLOCK_SIZE) + { + p->prev[0] ^= GetUi32(data); + p->prev[1] ^= GetUi32(data + 4); + p->prev[2] ^= GetUi32(data + 8); + p->prev[3] ^= GetUi32(data + 12); + + AesEncode32(p->prev, p->prev, p->aes.rkey, p->aes.numRounds2); + + SetUi32(data, p->prev[0]); + SetUi32(data + 4, p->prev[1]); + SetUi32(data + 8, p->prev[2]); + SetUi32(data + 12, p->prev[3]); + } + return i; +} + +SizeT AesCbc_Decode(CAesCbc *p, Byte *data, SizeT size) +{ + SizeT i; + UInt32 in[4], out[4]; + if (size == 0) + return 0; + if (size < AES_BLOCK_SIZE) + return AES_BLOCK_SIZE; + size -= AES_BLOCK_SIZE; + for (i = 0; i <= size; i += AES_BLOCK_SIZE, data += AES_BLOCK_SIZE) + { + in[0] = GetUi32(data); + in[1] = GetUi32(data + 4); + in[2] = GetUi32(data + 8); + in[3] = GetUi32(data + 12); + + AesDecode32(out, in, p->aes.rkey, p->aes.numRounds2); + + SetUi32(data, p->prev[0] ^ out[0]); + SetUi32(data + 4, p->prev[1] ^ out[1]); + SetUi32(data + 8, p->prev[2] ^ out[2]); + SetUi32(data + 12, p->prev[3] ^ out[3]); + + p->prev[0] = in[0]; + p->prev[1] = in[1]; + p->prev[2] = in[2]; + p->prev[3] = in[3]; + } + return i; +} diff --git a/desmume/src/windows/7z/C/Aes.h b/desmume/src/windows/7z/C/Aes.h new file mode 100644 index 000000000..98ef0c6ea --- /dev/null +++ b/desmume/src/windows/7z/C/Aes.h @@ -0,0 +1,48 @@ +/* Aes.h -- AES encryption / decryption +2008-08-05 +Igor Pavlov +Public domain */ + +#ifndef __AES_H +#define __AES_H + +#include "Types.h" + +#define AES_BLOCK_SIZE 16 + +typedef struct +{ + unsigned numRounds2; /* = numRounds / 2 */ + UInt32 rkey[(14 + 1) * 4]; +} CAes; + +/* Call AesGenTables one time before other AES functions */ +void AesGenTables(void); + +/* keySize = 16 or 24 or 32 (bytes) */ +void Aes_SetKeyEncode(CAes *p, const Byte *key, unsigned keySize); +void Aes_SetKeyDecode(CAes *p, const Byte *key, unsigned keySize); + +/* Aes_Encode32 and Aes_Decode32 functions work with little-endian words. + src and dest are pointers to 4 UInt32 words. + arc and dest can point to same block */ +void Aes_Encode32(const CAes *p, UInt32 *dest, const UInt32 *src); +void Aes_Decode32(const CAes *p, UInt32 *dest, const UInt32 *src); + +typedef struct +{ + UInt32 prev[4]; + CAes aes; +} CAesCbc; + +void AesCbc_Init(CAesCbc *p, const Byte *iv); /* iv size is AES_BLOCK_SIZE */ + +/* AesCbc_Encode and AesCbc_Decode: + if (res <= size): Filter have converted res bytes + if (res > size): Filter have not converted anything. And it needs at + least res = AES_BLOCK_SIZE bytes to convert one block */ + +SizeT AesCbc_Encode(CAesCbc *p, Byte *data, SizeT size); +SizeT AesCbc_Decode(CAesCbc *p, Byte *data, SizeT size); + +#endif diff --git a/desmume/src/windows/7z/C/Alloc.c b/desmume/src/windows/7z/C/Alloc.c new file mode 100644 index 000000000..bb24a772b --- /dev/null +++ b/desmume/src/windows/7z/C/Alloc.c @@ -0,0 +1,127 @@ +/* Alloc.c -- Memory allocation functions +2008-09-24 +Igor Pavlov +Public domain */ + +#ifdef _WIN32 +#include +#endif +#include + +#include "Alloc.h" + +/* #define _SZ_ALLOC_DEBUG */ + +/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ +#ifdef _SZ_ALLOC_DEBUG +#include +int g_allocCount = 0; +int g_allocCountMid = 0; +int g_allocCountBig = 0; +#endif + +void *MyAlloc(size_t size) +{ + if (size == 0) + return 0; + #ifdef _SZ_ALLOC_DEBUG + { + void *p = malloc(size); + fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p); + return p; + } + #else + return malloc(size); + #endif +} + +void MyFree(void *address) +{ + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address); + #endif + free(address); +} + +#ifdef _WIN32 + +void *MidAlloc(size_t size) +{ + if (size == 0) + return 0; + #ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++); + #endif + return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); +} + +void MidFree(void *address) +{ + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid); + #endif + if (address == 0) + return; + VirtualFree(address, 0, MEM_RELEASE); +} + +#ifndef MEM_LARGE_PAGES +#undef _7ZIP_LARGE_PAGES +#endif + +#ifdef _7ZIP_LARGE_PAGES +SIZE_T g_LargePageSize = 0; +typedef SIZE_T (WINAPI *GetLargePageMinimumP)(); +#endif + +void SetLargePageSize() +{ + #ifdef _7ZIP_LARGE_PAGES + SIZE_T size = 0; + GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP) + GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum"); + if (largePageMinimum == 0) + return; + size = largePageMinimum(); + if (size == 0 || (size & (size - 1)) != 0) + return; + g_LargePageSize = size; + #endif +} + + +void *BigAlloc(size_t size) +{ + if (size == 0) + return 0; + #ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++); + #endif + + #ifdef _7ZIP_LARGE_PAGES + if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18)) + { + void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)), + MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); + if (res != 0) + return res; + } + #endif + return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); +} + +void BigFree(void *address) +{ + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig); + #endif + + if (address == 0) + return; + VirtualFree(address, 0, MEM_RELEASE); +} + +#endif diff --git a/desmume/src/windows/7z/C/Alloc.h b/desmume/src/windows/7z/C/Alloc.h new file mode 100644 index 000000000..a396c6b9e --- /dev/null +++ b/desmume/src/windows/7z/C/Alloc.h @@ -0,0 +1,32 @@ +/* Alloc.h -- Memory allocation functions +2008-03-13 +Igor Pavlov +Public domain */ + +#ifndef __COMMON_ALLOC_H +#define __COMMON_ALLOC_H + +#include + +void *MyAlloc(size_t size); +void MyFree(void *address); + +#ifdef _WIN32 + +void SetLargePageSize(); + +void *MidAlloc(size_t size); +void MidFree(void *address); +void *BigAlloc(size_t size); +void BigFree(void *address); + +#else + +#define MidAlloc(size) MyAlloc(size) +#define MidFree(address) MyFree(address) +#define BigAlloc(size) MyAlloc(size) +#define BigFree(address) MyFree(address) + +#endif + +#endif diff --git a/desmume/src/windows/7z/C/Bra.c b/desmume/src/windows/7z/C/Bra.c new file mode 100644 index 000000000..3b75f0ccb --- /dev/null +++ b/desmume/src/windows/7z/C/Bra.c @@ -0,0 +1,133 @@ +/* Bra.c -- Converters for RISC code +2008-10-04 : Igor Pavlov : Public domain */ + +#include "Bra.h" + +SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + SizeT i; + if (size < 4) + return 0; + size -= 4; + ip += 8; + for (i = 0; i <= size; i += 4) + { + if (data[i + 3] == 0xEB) + { + UInt32 dest; + UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]); + src <<= 2; + if (encoding) + dest = ip + (UInt32)i + src; + else + dest = src - (ip + (UInt32)i); + dest >>= 2; + data[i + 2] = (Byte)(dest >> 16); + data[i + 1] = (Byte)(dest >> 8); + data[i + 0] = (Byte)dest; + } + } + return i; +} + +SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + SizeT i; + if (size < 4) + return 0; + size -= 4; + ip += 4; + for (i = 0; i <= size; i += 2) + { + if ((data[i + 1] & 0xF8) == 0xF0 && + (data[i + 3] & 0xF8) == 0xF8) + { + UInt32 dest; + UInt32 src = + (((UInt32)data[i + 1] & 0x7) << 19) | + ((UInt32)data[i + 0] << 11) | + (((UInt32)data[i + 3] & 0x7) << 8) | + (data[i + 2]); + + src <<= 1; + if (encoding) + dest = ip + (UInt32)i + src; + else + dest = src - (ip + (UInt32)i); + dest >>= 1; + + data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7)); + data[i + 0] = (Byte)(dest >> 11); + data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7)); + data[i + 2] = (Byte)dest; + i += 2; + } + } + return i; +} + +SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + SizeT i; + if (size < 4) + return 0; + size -= 4; + for (i = 0; i <= size; i += 4) + { + if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1) + { + UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) | + ((UInt32)data[i + 1] << 16) | + ((UInt32)data[i + 2] << 8) | + ((UInt32)data[i + 3] & (~3)); + + UInt32 dest; + if (encoding) + dest = ip + (UInt32)i + src; + else + dest = src - (ip + (UInt32)i); + data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3)); + data[i + 1] = (Byte)(dest >> 16); + data[i + 2] = (Byte)(dest >> 8); + data[i + 3] &= 0x3; + data[i + 3] |= dest; + } + } + return i; +} + +SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + UInt32 i; + if (size < 4) + return 0; + size -= 4; + for (i = 0; i <= size; i += 4) + { + if (data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00 || + data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0) + { + UInt32 src = + ((UInt32)data[i + 0] << 24) | + ((UInt32)data[i + 1] << 16) | + ((UInt32)data[i + 2] << 8) | + ((UInt32)data[i + 3]); + UInt32 dest; + + src <<= 2; + if (encoding) + dest = ip + i + src; + else + dest = src - (ip + i); + dest >>= 2; + + dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000; + + data[i + 0] = (Byte)(dest >> 24); + data[i + 1] = (Byte)(dest >> 16); + data[i + 2] = (Byte)(dest >> 8); + data[i + 3] = (Byte)dest; + } + } + return i; +} diff --git a/desmume/src/windows/7z/C/Bra.h b/desmume/src/windows/7z/C/Bra.h new file mode 100644 index 000000000..b9018eb99 --- /dev/null +++ b/desmume/src/windows/7z/C/Bra.h @@ -0,0 +1,60 @@ +/* Bra.h -- Branch converters for executables +2008-10-04 : Igor Pavlov : Public domain */ + +#ifndef __BRA_H +#define __BRA_H + +#include "Types.h" + +/* +These functions convert relative addresses to absolute addresses +in CALL instructions to increase the compression ratio. + + In: + data - data buffer + size - size of data + ip - current virtual Instruction Pinter (IP) value + state - state variable for x86 converter + encoding - 0 (for decoding), 1 (for encoding) + + Out: + state - state variable for x86 converter + + Returns: + The number of processed bytes. If you call these functions with multiple calls, + you must start next call with first byte after block of processed bytes. + + Type Endian Alignment LookAhead + + x86 little 1 4 + ARMT little 2 2 + ARM little 4 0 + PPC big 4 0 + SPARC big 4 0 + IA64 little 16 0 + + size must be >= Alignment + LookAhead, if it's not last block. + If (size < Alignment + LookAhead), converter returns 0. + + Example: + + UInt32 ip = 0; + for () + { + ; size must be >= Alignment + LookAhead, if it's not last block + SizeT processed = Convert(data, size, ip, 1); + data += processed; + size -= processed; + ip += processed; + } +*/ + +#define x86_Convert_Init(state) { state = 0; } +SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); +SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); + +#endif diff --git a/desmume/src/windows/7z/C/Bra86.c b/desmume/src/windows/7z/C/Bra86.c new file mode 100644 index 000000000..c3eda016e --- /dev/null +++ b/desmume/src/windows/7z/C/Bra86.c @@ -0,0 +1,85 @@ +/* Bra86.c -- Converter for x86 code (BCJ) +2008-10-04 : Igor Pavlov : Public domain */ + +#include "Bra.h" + +#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) + +const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; +const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; + +SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) +{ + SizeT bufferPos = 0, prevPosT; + UInt32 prevMask = *state & 0x7; + if (size < 5) + return 0; + ip += 5; + prevPosT = (SizeT)0 - 1; + + for (;;) + { + Byte *p = data + bufferPos; + Byte *limit = data + size - 4; + for (; p < limit; p++) + if ((*p & 0xFE) == 0xE8) + break; + bufferPos = (SizeT)(p - data); + if (p >= limit) + break; + prevPosT = bufferPos - prevPosT; + if (prevPosT > 3) + prevMask = 0; + else + { + prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7; + if (prevMask != 0) + { + Byte b = p[4 - kMaskToBitNumber[prevMask]]; + if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b)) + { + prevPosT = bufferPos; + prevMask = ((prevMask << 1) & 0x7) | 1; + bufferPos++; + continue; + } + } + } + prevPosT = bufferPos; + + if (Test86MSByte(p[4])) + { + UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); + UInt32 dest; + for (;;) + { + Byte b; + int index; + if (encoding) + dest = (ip + (UInt32)bufferPos) + src; + else + dest = src - (ip + (UInt32)bufferPos); + if (prevMask == 0) + break; + index = kMaskToBitNumber[prevMask] * 8; + b = (Byte)((dest >> (24 - index)) & 0xFF); + if (!Test86MSByte(b)) + break; + src = dest ^ ((1 << (32 - index)) - 1); + } + p[4] = (Byte)((~(((dest >> 24) & 1) - 1)) & 0xFF); + p[3] = (Byte)((dest >> 16) & 0xFF); + p[2] = (Byte)((dest >> 8) & 0xFF); + p[1] = (Byte)(dest & 0xFF); + bufferPos += 5; + } + else + { + prevMask = ((prevMask << 1) & 0x7) | 1; + bufferPos++; + } + } + prevPosT = bufferPos - prevPosT; + *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7)); + return bufferPos; +} diff --git a/desmume/src/windows/7z/C/BraIA64.c b/desmume/src/windows/7z/C/BraIA64.c new file mode 100644 index 000000000..f359f16a3 --- /dev/null +++ b/desmume/src/windows/7z/C/BraIA64.c @@ -0,0 +1,67 @@ +/* BraIA64.c -- Converter for IA-64 code +2008-10-04 : Igor Pavlov : Public domain */ + +#include "Bra.h" + +static const Byte kBranchTable[32] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 4, 6, 6, 0, 0, 7, 7, + 4, 4, 0, 0, 4, 4, 0, 0 +}; + +SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + SizeT i; + if (size < 16) + return 0; + size -= 16; + for (i = 0; i <= size; i += 16) + { + UInt32 instrTemplate = data[i] & 0x1F; + UInt32 mask = kBranchTable[instrTemplate]; + UInt32 bitPos = 5; + int slot; + for (slot = 0; slot < 3; slot++, bitPos += 41) + { + UInt32 bytePos, bitRes; + UInt64 instruction, instNorm; + int j; + if (((mask >> slot) & 1) == 0) + continue; + bytePos = (bitPos >> 3); + bitRes = bitPos & 0x7; + instruction = 0; + for (j = 0; j < 6; j++) + instruction += (UInt64)data[i + j + bytePos] << (8 * j); + + instNorm = instruction >> bitRes; + if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0) + { + UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF); + UInt32 dest; + src |= ((UInt32)(instNorm >> 36) & 1) << 20; + + src <<= 4; + + if (encoding) + dest = ip + (UInt32)i + src; + else + dest = src - (ip + (UInt32)i); + + dest >>= 4; + + instNorm &= ~((UInt64)(0x8FFFFF) << 13); + instNorm |= ((UInt64)(dest & 0xFFFFF) << 13); + instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20)); + + instruction &= (1 << bitRes) - 1; + instruction |= (instNorm << bitRes); + for (j = 0; j < 6; j++) + data[i + j + bytePos] = (Byte)(instruction >> (8 * j)); + } + } + } + return i; +} diff --git a/desmume/src/windows/7z/C/BwtSort.c b/desmume/src/windows/7z/C/BwtSort.c new file mode 100644 index 000000000..d6b545e83 --- /dev/null +++ b/desmume/src/windows/7z/C/BwtSort.c @@ -0,0 +1,516 @@ +/* BwtSort.c -- BWT block sorting +2008-08-17 +Igor Pavlov +Public domain */ + +#include "BwtSort.h" +#include "Sort.h" + +/* #define BLOCK_SORT_USE_HEAP_SORT */ + +#define NO_INLINE MY_FAST_CALL + +/* Don't change it !!! */ +#define kNumHashBytes 2 +#define kNumHashValues (1 << (kNumHashBytes * 8)) + +/* kNumRefBitsMax must be < (kNumHashBytes * 8) = 16 */ +#define kNumRefBitsMax 12 + +#define BS_TEMP_SIZE kNumHashValues + +#ifdef BLOCK_SORT_EXTERNAL_FLAGS + +/* 32 Flags in UInt32 word */ +#define kNumFlagsBits 5 +#define kNumFlagsInWord (1 << kNumFlagsBits) +#define kFlagsMask (kNumFlagsInWord - 1) +#define kAllFlags 0xFFFFFFFF + +#else + +#define kNumBitsMax 20 +#define kIndexMask ((1 << kNumBitsMax) - 1) +#define kNumExtraBits (32 - kNumBitsMax) +#define kNumExtra0Bits (kNumExtraBits - 2) +#define kNumExtra0Mask ((1 << kNumExtra0Bits) - 1) + +#define SetFinishedGroupSize(p, size) \ + { *(p) |= ((((size) - 1) & kNumExtra0Mask) << kNumBitsMax); \ + if ((size) > (1 << kNumExtra0Bits)) { \ + *(p) |= 0x40000000; *((p) + 1) |= ((((size) - 1)>> kNumExtra0Bits) << kNumBitsMax); } } \ + +static void SetGroupSize(UInt32 *p, UInt32 size) +{ + if (--size == 0) + return; + *p |= 0x80000000 | ((size & kNumExtra0Mask) << kNumBitsMax); + if (size >= (1 << kNumExtra0Bits)) + { + *p |= 0x40000000; + p[1] |= ((size >> kNumExtra0Bits) << kNumBitsMax); + } +} + +#endif + +/* +SortGroup - is recursive Range-Sort function with HeapSort optimization for small blocks + "range" is not real range. It's only for optimization. +returns: 1 - if there are groups, 0 - no more groups +*/ + +UInt32 NO_INLINE SortGroup(UInt32 BlockSize, UInt32 NumSortedBytes, UInt32 groupOffset, UInt32 groupSize, int NumRefBits, UInt32 *Indices + #ifndef BLOCK_SORT_USE_HEAP_SORT + , UInt32 left, UInt32 range + #endif + ) +{ + UInt32 *ind2 = Indices + groupOffset; + UInt32 *Groups; + if (groupSize <= 1) + { + /* + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetFinishedGroupSize(ind2, 1); + #endif + */ + return 0; + } + Groups = Indices + BlockSize + BS_TEMP_SIZE; + if (groupSize <= ((UInt32)1 << NumRefBits) + #ifndef BLOCK_SORT_USE_HEAP_SORT + && groupSize <= range + #endif + ) + { + UInt32 *temp = Indices + BlockSize; + UInt32 j; + UInt32 mask, thereAreGroups, group, cg; + { + UInt32 gPrev; + UInt32 gRes = 0; + { + UInt32 sp = ind2[0] + NumSortedBytes; + if (sp >= BlockSize) sp -= BlockSize; + gPrev = Groups[sp]; + temp[0] = (gPrev << NumRefBits); + } + + for (j = 1; j < groupSize; j++) + { + UInt32 sp = ind2[j] + NumSortedBytes; + UInt32 g; + if (sp >= BlockSize) sp -= BlockSize; + g = Groups[sp]; + temp[j] = (g << NumRefBits) | j; + gRes |= (gPrev ^ g); + } + if (gRes == 0) + { + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(ind2, groupSize); + #endif + return 1; + } + } + + HeapSort(temp, groupSize); + mask = ((1 << NumRefBits) - 1); + thereAreGroups = 0; + + group = groupOffset; + cg = (temp[0] >> NumRefBits); + temp[0] = ind2[temp[0] & mask]; + + { + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 *Flags = Groups + BlockSize; + #else + UInt32 prevGroupStart = 0; + #endif + + for (j = 1; j < groupSize; j++) + { + UInt32 val = temp[j]; + UInt32 cgCur = (val >> NumRefBits); + + if (cgCur != cg) + { + cg = cgCur; + group = groupOffset + j; + + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + { + UInt32 t = group - 1; + Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + } + #else + SetGroupSize(temp + prevGroupStart, j - prevGroupStart); + prevGroupStart = j; + #endif + } + else + thereAreGroups = 1; + { + UInt32 ind = ind2[val & mask]; + temp[j] = ind; + Groups[ind] = group; + } + } + + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(temp + prevGroupStart, j - prevGroupStart); + #endif + } + + for (j = 0; j < groupSize; j++) + ind2[j] = temp[j]; + return thereAreGroups; + } + + /* Check that all strings are in one group (cannot sort) */ + { + UInt32 group, j; + UInt32 sp = ind2[0] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + group = Groups[sp]; + for (j = 1; j < groupSize; j++) + { + sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + if (Groups[sp] != group) + break; + } + if (j == groupSize) + { + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(ind2, groupSize); + #endif + return 1; + } + } + + #ifndef BLOCK_SORT_USE_HEAP_SORT + { + /* ---------- Range Sort ---------- */ + UInt32 i; + UInt32 mid; + for (;;) + { + UInt32 j; + if (range <= 1) + { + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(ind2, groupSize); + #endif + return 1; + } + mid = left + ((range + 1) >> 1); + j = groupSize; + i = 0; + do + { + UInt32 sp = ind2[i] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + if (Groups[sp] >= mid) + { + for (j--; j > i; j--) + { + sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + if (Groups[sp] < mid) + { + UInt32 temp = ind2[i]; ind2[i] = ind2[j]; ind2[j] = temp; + break; + } + } + if (i >= j) + break; + } + } + while (++i < j); + if (i == 0) + { + range = range - (mid - left); + left = mid; + } + else if (i == groupSize) + range = (mid - left); + else + break; + } + + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + { + UInt32 t = (groupOffset + i - 1); + UInt32 *Flags = Groups + BlockSize; + Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + } + #endif + + { + UInt32 j; + for (j = i; j < groupSize; j++) + Groups[ind2[j]] = groupOffset + i; + } + + { + UInt32 res = SortGroup(BlockSize, NumSortedBytes, groupOffset, i, NumRefBits, Indices, left, mid - left); + return res | SortGroup(BlockSize, NumSortedBytes, groupOffset + i, groupSize - i, NumRefBits, Indices, mid, range - (mid - left)); + } + + } + + #else + + /* ---------- Heap Sort ---------- */ + + { + UInt32 j; + for (j = 0; j < groupSize; j++) + { + UInt32 sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + ind2[j] = sp; + } + + HeapSortRef(ind2, Groups, groupSize); + + /* Write Flags */ + { + UInt32 sp = ind2[0]; + UInt32 group = Groups[sp]; + + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 *Flags = Groups + BlockSize; + #else + UInt32 prevGroupStart = 0; + #endif + + for (j = 1; j < groupSize; j++) + { + sp = ind2[j]; + if (Groups[sp] != group) + { + group = Groups[sp]; + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + { + UInt32 t = groupOffset + j - 1; + Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + } + #else + SetGroupSize(ind2 + prevGroupStart, j - prevGroupStart); + prevGroupStart = j; + #endif + } + } + + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(ind2 + prevGroupStart, j - prevGroupStart); + #endif + } + { + /* Write new Groups values and Check that there are groups */ + UInt32 thereAreGroups = 0; + for (j = 0; j < groupSize; j++) + { + UInt32 group = groupOffset + j; + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 subGroupSize = ((ind2[j] & ~0xC0000000) >> kNumBitsMax); + if ((ind2[j] & 0x40000000) != 0) + subGroupSize += ((ind2[j + 1] >> kNumBitsMax) << kNumExtra0Bits); + subGroupSize++; + for (;;) + { + UInt32 original = ind2[j]; + UInt32 sp = original & kIndexMask; + if (sp < NumSortedBytes) sp += BlockSize; sp -= NumSortedBytes; + ind2[j] = sp | (original & ~kIndexMask); + Groups[sp] = group; + if (--subGroupSize == 0) + break; + j++; + thereAreGroups = 1; + } + #else + UInt32 *Flags = Groups + BlockSize; + for (;;) + { + UInt32 sp = ind2[j]; if (sp < NumSortedBytes) sp += BlockSize; sp -= NumSortedBytes; + ind2[j] = sp; + Groups[sp] = group; + if ((Flags[(groupOffset + j) >> kNumFlagsBits] & (1 << ((groupOffset + j) & kFlagsMask))) == 0) + break; + j++; + thereAreGroups = 1; + } + #endif + } + return thereAreGroups; + } + } + #endif +} + +/* conditions: blockSize > 0 */ +UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize) +{ + UInt32 *counters = Indices + blockSize; + UInt32 i; + UInt32 *Groups; + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 *Flags; + #endif + + /* Radix-Sort for 2 bytes */ + for (i = 0; i < kNumHashValues; i++) + counters[i] = 0; + for (i = 0; i < blockSize - 1; i++) + counters[((UInt32)data[i] << 8) | data[i + 1]]++; + counters[((UInt32)data[i] << 8) | data[0]]++; + + Groups = counters + BS_TEMP_SIZE; + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + Flags = Groups + blockSize; + { + UInt32 numWords = (blockSize + kFlagsMask) >> kNumFlagsBits; + for (i = 0; i < numWords; i++) + Flags[i] = kAllFlags; + } + #endif + + { + UInt32 sum = 0; + for (i = 0; i < kNumHashValues; i++) + { + UInt32 groupSize = counters[i]; + if (groupSize > 0) + { + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 t = sum + groupSize - 1; + Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + #endif + sum += groupSize; + } + counters[i] = sum - groupSize; + } + + for (i = 0; i < blockSize - 1; i++) + Groups[i] = counters[((UInt32)data[i] << 8) | data[i + 1]]; + Groups[i] = counters[((UInt32)data[i] << 8) | data[0]]; + + for (i = 0; i < blockSize - 1; i++) + Indices[counters[((UInt32)data[i] << 8) | data[i + 1]]++] = i; + Indices[counters[((UInt32)data[i] << 8) | data[0]]++] = i; + + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + { + UInt32 prev = 0; + for (i = 0; i < kNumHashValues; i++) + { + UInt32 prevGroupSize = counters[i] - prev; + if (prevGroupSize == 0) + continue; + SetGroupSize(Indices + prev, prevGroupSize); + prev = counters[i]; + } + } + #endif + } + + { + int NumRefBits; + UInt32 NumSortedBytes; + for (NumRefBits = 0; ((blockSize - 1) >> NumRefBits) != 0; NumRefBits++); + NumRefBits = 32 - NumRefBits; + if (NumRefBits > kNumRefBitsMax) + NumRefBits = kNumRefBitsMax; + + for (NumSortedBytes = kNumHashBytes; ; NumSortedBytes <<= 1) + { + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 finishedGroupSize = 0; + #endif + UInt32 newLimit = 0; + for (i = 0; i < blockSize;) + { + UInt32 groupSize; + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + + if ((Flags[i >> kNumFlagsBits] & (1 << (i & kFlagsMask))) == 0) + { + i++; + continue; + } + for (groupSize = 1; + (Flags[(i + groupSize) >> kNumFlagsBits] & (1 << ((i + groupSize) & kFlagsMask))) != 0; + groupSize++); + + groupSize++; + + #else + + groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax); + { + Bool finishedGroup = ((Indices[i] & 0x80000000) == 0); + if ((Indices[i] & 0x40000000) != 0) + { + groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits); + Indices[i + 1] &= kIndexMask; + } + Indices[i] &= kIndexMask; + groupSize++; + if (finishedGroup || groupSize == 1) + { + Indices[i - finishedGroupSize] &= kIndexMask; + if (finishedGroupSize > 1) + Indices[i - finishedGroupSize + 1] &= kIndexMask; + { + UInt32 newGroupSize = groupSize + finishedGroupSize; + SetFinishedGroupSize(Indices + i - finishedGroupSize, newGroupSize); + finishedGroupSize = newGroupSize; + } + i += groupSize; + continue; + } + finishedGroupSize = 0; + } + + #endif + + if (NumSortedBytes >= blockSize) + { + UInt32 j; + for (j = 0; j < groupSize; j++) + { + UInt32 t = (i + j); + /* Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); */ + Groups[Indices[t]] = t; + } + } + else + if (SortGroup(blockSize, NumSortedBytes, i, groupSize, NumRefBits, Indices + #ifndef BLOCK_SORT_USE_HEAP_SORT + , 0, blockSize + #endif + ) != 0) + newLimit = i + groupSize; + i += groupSize; + } + if (newLimit == 0) + break; + } + } + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + for (i = 0; i < blockSize;) + { + UInt32 groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax); + if ((Indices[i] & 0x40000000) != 0) + { + groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits); + Indices[i + 1] &= kIndexMask; + } + Indices[i] &= kIndexMask; + groupSize++; + i += groupSize; + } + #endif + return Groups[0]; +} + diff --git a/desmume/src/windows/7z/C/BwtSort.h b/desmume/src/windows/7z/C/BwtSort.h new file mode 100644 index 000000000..84c50339c --- /dev/null +++ b/desmume/src/windows/7z/C/BwtSort.h @@ -0,0 +1,24 @@ +/* BwtSort.h -- BWT block sorting +2008-03-26 +Igor Pavlov +Public domain */ + +#ifndef __BWTSORT_H +#define __BWTSORT_H + +#include "Types.h" + +/* use BLOCK_SORT_EXTERNAL_FLAGS if blockSize can be > 1M */ +/* #define BLOCK_SORT_EXTERNAL_FLAGS */ + +#ifdef BLOCK_SORT_EXTERNAL_FLAGS +#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) ((((blockSize) + 31) >> 5)) +#else +#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) 0 +#endif + +#define BLOCK_SORT_BUF_SIZE(blockSize) ((blockSize) * 2 + BLOCK_SORT_EXTERNAL_SIZE(blockSize) + (1 << 16)) + +UInt32 BlockSort(UInt32 *indices, const Byte *data, UInt32 blockSize); + +#endif diff --git a/desmume/src/windows/7z/C/CpuArch.h b/desmume/src/windows/7z/C/CpuArch.h new file mode 100644 index 000000000..006361f2f --- /dev/null +++ b/desmume/src/windows/7z/C/CpuArch.h @@ -0,0 +1,69 @@ +/* CpuArch.h +2008-08-05 +Igor Pavlov +Public domain */ + +#ifndef __CPUARCH_H +#define __CPUARCH_H + +/* +LITTLE_ENDIAN_UNALIGN means: + 1) CPU is LITTLE_ENDIAN + 2) it's allowed to make unaligned memory accesses +if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know +about these properties of platform. +*/ + +#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__) +#define LITTLE_ENDIAN_UNALIGN +#endif + +#ifdef LITTLE_ENDIAN_UNALIGN + +#define GetUi16(p) (*(const UInt16 *)(p)) +#define GetUi32(p) (*(const UInt32 *)(p)) +#define GetUi64(p) (*(const UInt64 *)(p)) +#define SetUi32(p, d) *(UInt32 *)(p) = (d); + +#else + +#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8)) + +#define GetUi32(p) ( \ + ((const Byte *)(p))[0] | \ + ((UInt32)((const Byte *)(p))[1] << 8) | \ + ((UInt32)((const Byte *)(p))[2] << 16) | \ + ((UInt32)((const Byte *)(p))[3] << 24)) + +#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) + +#define SetUi32(p, d) { UInt32 _x_ = (d); \ + ((Byte *)(p))[0] = (Byte)_x_; \ + ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \ + ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \ + ((Byte *)(p))[3] = (Byte)(_x_ >> 24); } + +#endif + +#if defined(LITTLE_ENDIAN_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300) + +#pragma intrinsic(_byteswap_ulong) +#pragma intrinsic(_byteswap_uint64) +#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) +#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) + +#else + +#define GetBe32(p) ( \ + ((UInt32)((const Byte *)(p))[0] << 24) | \ + ((UInt32)((const Byte *)(p))[1] << 16) | \ + ((UInt32)((const Byte *)(p))[2] << 8) | \ + ((const Byte *)(p))[3] ) + +#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) + +#endif + +#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]) + +#endif diff --git a/desmume/src/windows/7z/C/HuffEnc.c b/desmume/src/windows/7z/C/HuffEnc.c new file mode 100644 index 000000000..2d31ad596 --- /dev/null +++ b/desmume/src/windows/7z/C/HuffEnc.c @@ -0,0 +1,148 @@ +/* HuffEnc.c -- functions for Huffman encoding +2008-08-05 +Igor Pavlov +Public domain */ + +#include "HuffEnc.h" +#include "Sort.h" + +#define kMaxLen 16 +#define NUM_BITS 10 +#define MASK ((1 << NUM_BITS) - 1) + +#define NUM_COUNTERS 64 + +#define HUFFMAN_SPEED_OPT + +void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymbols, UInt32 maxLen) +{ + UInt32 num = 0; + /* if (maxLen > 10) maxLen = 10; */ + { + UInt32 i; + + #ifdef HUFFMAN_SPEED_OPT + + UInt32 counters[NUM_COUNTERS]; + for (i = 0; i < NUM_COUNTERS; i++) + counters[i] = 0; + for (i = 0; i < numSymbols; i++) + { + UInt32 freq = freqs[i]; + counters[(freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1]++; + } + + for (i = 1; i < NUM_COUNTERS; i++) + { + UInt32 temp = counters[i]; + counters[i] = num; + num += temp; + } + + for (i = 0; i < numSymbols; i++) + { + UInt32 freq = freqs[i]; + if (freq == 0) + lens[i] = 0; + else + p[counters[((freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1)]++] = i | (freq << NUM_BITS); + } + counters[0] = 0; + HeapSort(p + counters[NUM_COUNTERS - 2], counters[NUM_COUNTERS - 1] - counters[NUM_COUNTERS - 2]); + + #else + + for (i = 0; i < numSymbols; i++) + { + UInt32 freq = freqs[i]; + if (freq == 0) + lens[i] = 0; + else + p[num++] = i | (freq << NUM_BITS); + } + HeapSort(p, num); + + #endif + } + + if (num < 2) + { + int minCode = 0; + int maxCode = 1; + if (num == 1) + { + maxCode = (int)(p[0] & MASK); + if (maxCode == 0) + maxCode++; + } + p[minCode] = 0; + p[maxCode] = 1; + lens[minCode] = lens[maxCode] = 1; + return; + } + + { + UInt32 b, e, i; + + i = b = e = 0; + do + { + UInt32 n, m, freq; + n = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++; + freq = (p[n] & ~MASK); + p[n] = (p[n] & MASK) | (e << NUM_BITS); + m = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++; + freq += (p[m] & ~MASK); + p[m] = (p[m] & MASK) | (e << NUM_BITS); + p[e] = (p[e] & MASK) | freq; + e++; + } + while (num - e > 1); + + { + UInt32 lenCounters[kMaxLen + 1]; + for (i = 0; i <= kMaxLen; i++) + lenCounters[i] = 0; + + p[--e] &= MASK; + lenCounters[1] = 2; + while (e > 0) + { + UInt32 len = (p[p[--e] >> NUM_BITS] >> NUM_BITS) + 1; + p[e] = (p[e] & MASK) | (len << NUM_BITS); + if (len >= maxLen) + for (len = maxLen - 1; lenCounters[len] == 0; len--); + lenCounters[len]--; + lenCounters[len + 1] += 2; + } + + { + UInt32 len; + i = 0; + for (len = maxLen; len != 0; len--) + { + UInt32 num; + for (num = lenCounters[len]; num != 0; num--) + lens[p[i++] & MASK] = (Byte)len; + } + } + + { + UInt32 nextCodes[kMaxLen + 1]; + { + UInt32 code = 0; + UInt32 len; + for (len = 1; len <= kMaxLen; len++) + nextCodes[len] = code = (code + lenCounters[len - 1]) << 1; + } + /* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */ + + { + UInt32 i; + for (i = 0; i < numSymbols; i++) + p[i] = nextCodes[lens[i]]++; + } + } + } + } +} diff --git a/desmume/src/windows/7z/C/HuffEnc.h b/desmume/src/windows/7z/C/HuffEnc.h new file mode 100644 index 000000000..c0617b33e --- /dev/null +++ b/desmume/src/windows/7z/C/HuffEnc.h @@ -0,0 +1,21 @@ +/* HuffEnc.h -- functions for Huffman encoding +2008-03-26 +Igor Pavlov +Public domain */ + +#ifndef __HUFFENC_H +#define __HUFFENC_H + +#include "Types.h" + +/* +Conditions: + num <= 1024 = 2 ^ NUM_BITS + Sum(freqs) < 4M = 2 ^ (32 - NUM_BITS) + maxLen <= 16 = kMaxLen + Num_Items(p) >= HUFFMAN_TEMP_SIZE(num) +*/ + +void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 num, UInt32 maxLen); + +#endif diff --git a/desmume/src/windows/7z/C/LzFind.c b/desmume/src/windows/7z/C/LzFind.c new file mode 100644 index 000000000..e0ebe6235 --- /dev/null +++ b/desmume/src/windows/7z/C/LzFind.c @@ -0,0 +1,751 @@ +/* LzFind.c -- Match finder for LZ algorithms +2008-10-04 : Igor Pavlov : Public domain */ + +#include + +#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; + 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->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->skipModeBits = 0; */ + p->directInput = 0; + 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 /* >> p->skipModeBits */) + 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 >>= p->skipModeBits; */ + 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/desmume/src/windows/7z/C/LzFind.h b/desmume/src/windows/7z/C/LzFind.h new file mode 100644 index 000000000..423d67e0c --- /dev/null +++ b/desmume/src/windows/7z/C/LzFind.h @@ -0,0 +1,107 @@ +/* LzFind.h -- Match finder for LZ algorithms +2008-10-04 : Igor Pavlov : Public domain */ + +#ifndef __LZFIND_H +#define __LZFIND_H + +#include "Types.h" + +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; + int btMode; + /* int skipModeBits; */ + 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); + +#endif diff --git a/desmume/src/windows/7z/C/LzFindMt.c b/desmume/src/windows/7z/C/LzFindMt.c new file mode 100644 index 000000000..0ef134735 --- /dev/null +++ b/desmume/src/windows/7z/C/LzFindMt.c @@ -0,0 +1,793 @@ +/* LzFindMt.c -- multithreaded Match finder for LZ algorithms +2008-10-04 : 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 do { GET_NEXT_BLOCK_IF_REQUIRED +#define SKIP_HEADER(n) SKIP_HEADER2 if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash; +#define SKIP_FOOTER } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0); + +void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num) +{ + SKIP_HEADER2 { p->btNumAvailBytes--; + SKIP_FOOTER +} + +void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num) +{ + SKIP_HEADER(2) + UInt32 hash2Value; + MT_HASH2_CALC + hash[hash2Value] = p->lzPos; + SKIP_FOOTER +} + +void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num) +{ + SKIP_HEADER(3) + UInt32 hash2Value, hash3Value; + MT_HASH3_CALC + hash[kFix3HashSize + hash3Value] = + hash[ hash2Value] = + p->lzPos; + SKIP_FOOTER +} + +/* +void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num) +{ + SKIP_HEADER(4) + UInt32 hash2Value, hash3Value, hash4Value; + MT_HASH4_CALC + hash[kFix4HashSize + hash4Value] = + hash[kFix3HashSize + hash3Value] = + hash[ hash2Value] = + p->lzPos; + SKIP_FOOTER +} +*/ + +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/desmume/src/windows/7z/C/LzFindMt.h b/desmume/src/windows/7z/C/LzFindMt.h new file mode 100644 index 000000000..b7ead2d47 --- /dev/null +++ b/desmume/src/windows/7z/C/LzFindMt.h @@ -0,0 +1,97 @@ +/* LzFindMt.h -- multithreaded Match finder for LZ algorithms +2008-10-04 : Igor Pavlov : Public domain */ + +#ifndef __LZFINDMT_H +#define __LZFINDMT_H + +#include "Threads.h" +#include "LzFind.h" + +#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); + +#endif diff --git a/desmume/src/windows/7z/C/LzHash.h b/desmume/src/windows/7z/C/LzHash.h new file mode 100644 index 000000000..c92341750 --- /dev/null +++ b/desmume/src/windows/7z/C/LzHash.h @@ -0,0 +1,54 @@ +/* LzHash.h -- HASH functions for LZ algorithms +2008-10-04 : Igor Pavlov : Public domain */ + +#ifndef __LZHASH_H +#define __LZHASH_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/desmume/src/windows/7z/C/LzmaDec.c b/desmume/src/windows/7z/C/LzmaDec.c new file mode 100644 index 000000000..e40e4286e --- /dev/null +++ b/desmume/src/windows/7z/C/LzmaDec.c @@ -0,0 +1,1007 @@ +/* LzmaDec.c -- LZMA Decoder +2008-11-06 : Igor Pavlov : Public domain */ + +#include "LzmaDec.h" + +#include + +#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 + +static const Byte kLiteralNextStates[kNumStates * 2] = +{ + 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5, + 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10 +}; + +#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) + { + 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; + 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 & 0xFF); + processedPos++; + + state = kLiteralNextStates[state]; + /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */ + 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; + /* state = kLiteralNextStates[state]; */ + } + + 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/desmume/src/windows/7z/C/LzmaDec.h b/desmume/src/windows/7z/C/LzmaDec.h new file mode 100644 index 000000000..ad7d7057a --- /dev/null +++ b/desmume/src/windows/7z/C/LzmaDec.h @@ -0,0 +1,223 @@ +/* LzmaDec.h -- LZMA Decoder +2008-10-04 : Igor Pavlov : Public domain */ + +#ifndef __LZMADEC_H +#define __LZMADEC_H + +#include "Types.h" + +/* #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); + +#endif diff --git a/desmume/src/windows/7z/C/LzmaEnc.c b/desmume/src/windows/7z/C/LzmaEnc.c new file mode 100644 index 000000000..a5a82da91 --- /dev/null +++ b/desmume/src/windows/7z/C/LzmaEnc.c @@ -0,0 +1,2275 @@ +/* LzmaEnc.c -- LZMA Encoder +2008-10-04 : Igor Pavlov : Public domain */ + +#include + +/* #define SHOW_STAT */ +/* #define SHOW_STAT2 */ + +#if defined(SHOW_STAT) || defined(SHOW_STAT2) +#include +#endif + +#include "LzmaEnc.h" + +#include "LzFind.h" +#ifdef COMPRESS_MF_MT +#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 = ((p->btMode && p->algo) ? 2 : 1); +} + +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 _COptimal +{ + 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 / 2)) + +#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 _CRangeEnc +{ + UInt32 range; + Byte cache; + UInt64 low; + UInt64 cacheSize; + Byte *buf; + Byte *bufLim; + Byte *bufBase; + ISeqOutStream *outStream; + UInt64 processed; + SRes res; +} CRangeEnc; + +typedef struct _CSeqInStreamBuf +{ + ISeqInStream funcTable; + const Byte *data; + SizeT rem; +} CSeqInStreamBuf; + +static SRes MyRead(void *pp, void *data, size_t *size) +{ + size_t curSize = *size; + CSeqInStreamBuf *p = (CSeqInStreamBuf *)pp; + if (p->rem < curSize) + curSize = p->rem; + memcpy(data, p->data, curSize); + p->rem -= curSize; + p->data += curSize; + *size = curSize; + return SZ_OK; +} + +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 _CLzmaEnc +{ + IMatchFinder matchFinder; + void *matchFinderObj; + + #ifdef COMPRESS_MF_MT + Bool mtMode; + CMatchFinderMt matchFinderMt; + #endif + + CMatchFinder matchFinderBase; + + #ifdef COMPRESS_MF_MT + 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; + + ISeqInStream *inStream; + CSeqInStreamBuf seqBufInStream; + + 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; + + #ifdef COMPRESS_MF_MT + /* + 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); + #ifdef COMPRESS_MF_MT + 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) +{ + #ifdef COMPRESS_MF_MT + 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->inStream != 0) + { + p->matchFinderBase.stream = p->inStream; + p->matchFinder.Init(p->matchFinderObj); + p->inStream = 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); + #ifdef COMPRESS_MF_MT + 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; + + #ifdef COMPRESS_MF_MT + 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, ISeqInStream *inStream, ISeqOutStream *outStream, + ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + p->inStream = inStream; + 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->inStream = inStream; + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); +} + +static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) +{ + p->seqBufInStream.funcTable.Read = MyRead; + p->seqBufInStream.data = src; + p->seqBufInStream.rem = 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->inStream = &p->seqBufInStream.funcTable; + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); +} + +void LzmaEnc_Finish(CLzmaEncHandle pp) +{ + #ifdef COMPRESS_MF_MT + CLzmaEnc *p = (CLzmaEnc *)pp; + if (p->mtMode) + MatchFinderMt_ReleaseStream(&p->matchFinderMt); + #else + pp = pp; + #endif +} + +typedef struct _CSeqOutStreamBuf +{ + 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; +} + +SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, + ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + SRes res = SZ_OK; + + #ifdef COMPRESS_MF_MT + Byte allocaDummy[0x300]; + int i = 0; + for (i = 0; i < 16; i++) + allocaDummy[i] = (Byte)i; + #endif + + RINOK(LzmaEnc_Prepare(pp, inStream, outStream, alloc, allocBig)); + + 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(pp); + return res; +} + +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; + res = LzmaEnc_Encode(pp, &outStream.funcTable, &p->seqBufInStream.funcTable, + progress, alloc, allocBig); + + *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/desmume/src/windows/7z/C/LzmaEnc.h b/desmume/src/windows/7z/C/LzmaEnc.h new file mode 100644 index 000000000..e3d84fa35 --- /dev/null +++ b/desmume/src/windows/7z/C/LzmaEnc.h @@ -0,0 +1,72 @@ +/* LzmaEnc.h -- LZMA Encoder +2008-10-04 : Igor Pavlov : Public domain */ + +#ifndef __LZMAENC_H +#define __LZMAENC_H + +#include "Types.h" + +#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); + +#endif diff --git a/desmume/src/windows/7z/C/RotateDefs.h b/desmume/src/windows/7z/C/RotateDefs.h new file mode 100644 index 000000000..189350d7b --- /dev/null +++ b/desmume/src/windows/7z/C/RotateDefs.h @@ -0,0 +1,22 @@ +/* RotateDefs.h -- Rotate functions +2008-08-05 +Igor Pavlov +Public domain */ + +#ifndef __ROTATEDEFS_H +#define __ROTATEDEFS_H + +#ifdef _MSC_VER + +#include +#define rotlFixed(x, n) _rotl((x), (n)) +#define rotrFixed(x, n) _rotr((x), (n)) + +#else + +#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) +#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) + +#endif + +#endif diff --git a/desmume/src/windows/7z/C/Sha256.c b/desmume/src/windows/7z/C/Sha256.c new file mode 100644 index 000000000..657c2ab92 --- /dev/null +++ b/desmume/src/windows/7z/C/Sha256.c @@ -0,0 +1,204 @@ +/* Crypto/Sha256.c -- SHA-256 Hash function +2008-11-06 : Igor Pavlov : Public domain +This code is based on public domain code from Wei Dai's Crypto++ library. */ + +#include "Sha256.h" +#include "RotateDefs.h" + +/* define it for speed optimization */ +/* #define _SHA256_UNROLL */ +/* #define _SHA256_UNROLL2 */ + +void Sha256_Init(CSha256 *p) +{ + p->state[0] = 0x6a09e667; + p->state[1] = 0xbb67ae85; + p->state[2] = 0x3c6ef372; + p->state[3] = 0xa54ff53a; + p->state[4] = 0x510e527f; + p->state[5] = 0x9b05688c; + p->state[6] = 0x1f83d9ab; + p->state[7] = 0x5be0cd19; + p->count = 0; +} + +#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22)) +#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25)) +#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3)) +#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10)) + +#define blk0(i) (W[i] = data[i]) +#define blk2(i) (W[i&15] += s1(W[(i-2)&15]) + W[(i-7)&15] + s0(W[(i-15)&15])) + +#define Ch(x,y,z) (z^(x&(y^z))) +#define Maj(x,y,z) ((x&y)|(z&(x|y))) + +#define a(i) T[(0-(i))&7] +#define b(i) T[(1-(i))&7] +#define c(i) T[(2-(i))&7] +#define d(i) T[(3-(i))&7] +#define e(i) T[(4-(i))&7] +#define f(i) T[(5-(i))&7] +#define g(i) T[(6-(i))&7] +#define h(i) T[(7-(i))&7] + + +#ifdef _SHA256_UNROLL2 + +#define R(a,b,c,d,e,f,g,h, i) h += S1(e) + Ch(e,f,g) + K[i+j] + (j?blk2(i):blk0(i));\ + d += h; h += S0(a) + Maj(a, b, c) + +#define RX_8(i) \ + R(a,b,c,d,e,f,g,h, i); \ + R(h,a,b,c,d,e,f,g, i+1); \ + R(g,h,a,b,c,d,e,f, i+2); \ + R(f,g,h,a,b,c,d,e, i+3); \ + R(e,f,g,h,a,b,c,d, i+4); \ + R(d,e,f,g,h,a,b,c, i+5); \ + R(c,d,e,f,g,h,a,b, i+6); \ + R(b,c,d,e,f,g,h,a, i+7) + +#else + +#define R(i) h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[i+j] + (j?blk2(i):blk0(i));\ + d(i) += h(i); h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) + +#ifdef _SHA256_UNROLL + +#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7); + +#endif + +#endif + +const UInt32 K[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +static void Sha256_Transform(UInt32 *state, const UInt32 *data) +{ + UInt32 W[16]; + unsigned j; + #ifdef _SHA256_UNROLL2 + UInt32 a,b,c,d,e,f,g,h; + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + #else + UInt32 T[8]; + for (j = 0; j < 8; j++) + T[j] = state[j]; + #endif + + for (j = 0; j < 64; j += 16) + { + #if defined(_SHA256_UNROLL) || defined(_SHA256_UNROLL2) + RX_8(0); RX_8(8); + #else + unsigned i; + for (i = 0; i < 16; i++) { R(i); } + #endif + } + + #ifdef _SHA256_UNROLL2 + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + #else + for (j = 0; j < 8; j++) + state[j] += T[j]; + #endif + + /* Wipe variables */ + /* memset(W, 0, sizeof(W)); */ + /* memset(T, 0, sizeof(T)); */ +} + +#undef S0 +#undef S1 +#undef s0 +#undef s1 + +static void Sha256_WriteByteBlock(CSha256 *p) +{ + UInt32 data32[16]; + unsigned i; + for (i = 0; i < 16; i++) + data32[i] = + ((UInt32)(p->buffer[i * 4 ]) << 24) + + ((UInt32)(p->buffer[i * 4 + 1]) << 16) + + ((UInt32)(p->buffer[i * 4 + 2]) << 8) + + ((UInt32)(p->buffer[i * 4 + 3])); + Sha256_Transform(p->state, data32); +} + +void Sha256_Update(CSha256 *p, const Byte *data, size_t size) +{ + UInt32 curBufferPos = (UInt32)p->count & 0x3F; + while (size > 0) + { + p->buffer[curBufferPos++] = *data++; + p->count++; + size--; + if (curBufferPos == 64) + { + curBufferPos = 0; + Sha256_WriteByteBlock(p); + } + } +} + +void Sha256_Final(CSha256 *p, Byte *digest) +{ + UInt64 lenInBits = (p->count << 3); + UInt32 curBufferPos = (UInt32)p->count & 0x3F; + unsigned i; + p->buffer[curBufferPos++] = 0x80; + while (curBufferPos != (64 - 8)) + { + curBufferPos &= 0x3F; + if (curBufferPos == 0) + Sha256_WriteByteBlock(p); + p->buffer[curBufferPos++] = 0; + } + for (i = 0; i < 8; i++) + { + p->buffer[curBufferPos++] = (Byte)(lenInBits >> 56); + lenInBits <<= 8; + } + Sha256_WriteByteBlock(p); + + for (i = 0; i < 8; i++) + { + *digest++ = (Byte)((p->state[i] >> 24) & 0xFF); + *digest++ = (Byte)((p->state[i] >> 16) & 0xFF); + *digest++ = (Byte)((p->state[i] >> 8) & 0xFF); + *digest++ = (Byte)((p->state[i]) & 0xFF); + } + Sha256_Init(p); +} diff --git a/desmume/src/windows/7z/C/Sha256.h b/desmume/src/windows/7z/C/Sha256.h new file mode 100644 index 000000000..8703b4a63 --- /dev/null +++ b/desmume/src/windows/7z/C/Sha256.h @@ -0,0 +1,22 @@ +/* Crypto/Sha256.h -- SHA-256 Hash function +2008-10-04 : Igor Pavlov : Public domain */ + +#ifndef __CRYPTO_SHA256_H +#define __CRYPTO_SHA256_H + +#include "Types.h" + +#define SHA256_DIGEST_SIZE 32 + +typedef struct +{ + UInt32 state[8]; + UInt64 count; + Byte buffer[64]; +} CSha256; + +void Sha256_Init(CSha256 *p); +void Sha256_Update(CSha256 *p, const Byte *data, size_t size); +void Sha256_Final(CSha256 *p, Byte *digest); + +#endif diff --git a/desmume/src/windows/7z/C/Sort.c b/desmume/src/windows/7z/C/Sort.c new file mode 100644 index 000000000..bb20dc348 --- /dev/null +++ b/desmume/src/windows/7z/C/Sort.c @@ -0,0 +1,95 @@ +/* Sort.c -- Sort functions +2008-08-17 +Igor Pavlov +Public domain */ + +#include "Sort.h" + +#define HeapSortDown(p, k, size, temp) \ + { for (;;) { \ + UInt32 s = (k << 1); \ + if (s > size) break; \ + if (s < size && p[s + 1] > p[s]) s++; \ + if (temp >= p[s]) break; \ + p[k] = p[s]; k = s; \ + } p[k] = temp; } + +void HeapSort(UInt32 *p, UInt32 size) +{ + if (size <= 1) + return; + p--; + { + UInt32 i = size / 2; + do + { + UInt32 temp = p[i]; + UInt32 k = i; + HeapSortDown(p, k, size, temp) + } + while (--i != 0); + } + /* + do + { + UInt32 k = 1; + UInt32 temp = p[size]; + p[size--] = p[1]; + HeapSortDown(p, k, size, temp) + } + while (size > 1); + */ + while (size > 3) + { + UInt32 temp = p[size]; + UInt32 k = (p[3] > p[2]) ? 3 : 2; + p[size--] = p[1]; + p[1] = p[k]; + HeapSortDown(p, k, size, temp) + } + { + UInt32 temp = p[size]; + p[size] = p[1]; + if (size > 2 && p[2] < temp) + { + p[1] = p[2]; + p[2] = temp; + } + else + p[1] = temp; + } +} + +/* +#define HeapSortRefDown(p, vals, n, size, temp) \ + { UInt32 k = n; UInt32 val = vals[temp]; for (;;) { \ + UInt32 s = (k << 1); \ + if (s > size) break; \ + if (s < size && vals[p[s + 1]] > vals[p[s]]) s++; \ + if (val >= vals[p[s]]) break; \ + p[k] = p[s]; k = s; \ + } p[k] = temp; } + +void HeapSortRef(UInt32 *p, UInt32 *vals, UInt32 size) +{ + if (size <= 1) + return; + p--; + { + UInt32 i = size / 2; + do + { + UInt32 temp = p[i]; + HeapSortRefDown(p, vals, i, size, temp); + } + while (--i != 0); + } + do + { + UInt32 temp = p[size]; + p[size--] = p[1]; + HeapSortRefDown(p, vals, 1, size, temp); + } + while (size > 1); +} +*/ \ No newline at end of file diff --git a/desmume/src/windows/7z/C/Sort.h b/desmume/src/windows/7z/C/Sort.h new file mode 100644 index 000000000..cff6c4c32 --- /dev/null +++ b/desmume/src/windows/7z/C/Sort.h @@ -0,0 +1,14 @@ +/* Sort.h -- Sort functions +2008-03-19 +Igor Pavlov +Public domain */ + +#ifndef __7Z_SORT_H +#define __7Z_SORT_H + +#include "Types.h" + +void HeapSort(UInt32 *p, UInt32 size); +/* void HeapSortRef(UInt32 *p, UInt32 *vals, UInt32 size); */ + +#endif diff --git a/desmume/src/windows/7z/C/Threads.c b/desmume/src/windows/7z/C/Threads.c new file mode 100644 index 000000000..c7d8b0a8a --- /dev/null +++ b/desmume/src/windows/7z/C/Threads.c @@ -0,0 +1,109 @@ +/* Threads.c -- multithreading library +2008-08-05 +Igor Pavlov +Public domain */ + +#include "Threads.h" +#include + +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(); } + +static WRes MyCloseHandle(HANDLE *h) +{ + if (*h != NULL) + if (!CloseHandle(*h)) + return GetError(); + *h = NULL; + return 0; +} + +WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter) +{ + unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */ + thread->handle = + /* CreateThread(0, 0, startAddress, parameter, 0, &threadId); */ + (HANDLE)_beginthreadex(NULL, 0, startAddress, parameter, 0, &threadId); + /* maybe we must use errno here, but probably GetLastError() is also OK. */ + return HandleToWRes(thread->handle); +} + +WRes WaitObject(HANDLE h) +{ + return (WRes)WaitForSingleObject(h, INFINITE); +} + +WRes Thread_Wait(CThread *thread) +{ + if (thread->handle == NULL) + return 1; + return WaitObject(thread->handle); +} + +WRes Thread_Close(CThread *thread) +{ + return MyCloseHandle(&thread->handle); +} + +WRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled) +{ + p->handle = CreateEvent(NULL, manualReset, (initialSignaled ? TRUE : FALSE), NULL); + return HandleToWRes(p->handle); +} + +WRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled) + { return Event_Create(p, TRUE, initialSignaled); } +WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) + { return ManualResetEvent_Create(p, 0); } + +WRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled) + { return Event_Create(p, FALSE, initialSignaled); } +WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) + { return AutoResetEvent_Create(p, 0); } + +WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(p->handle)); } +WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(p->handle)); } +WRes Event_Wait(CEvent *p) { return WaitObject(p->handle); } +WRes Event_Close(CEvent *p) { return MyCloseHandle(&p->handle); } + + +WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount) +{ + p->handle = CreateSemaphore(NULL, (LONG)initiallyCount, (LONG)maxCount, NULL); + return HandleToWRes(p->handle); +} + +WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount) +{ + return BOOLToWRes(ReleaseSemaphore(p->handle, releaseCount, previousCount)); +} +WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount) +{ + return Semaphore_Release(p, (LONG)releaseCount, NULL); +} +WRes Semaphore_Release1(CSemaphore *p) +{ + return Semaphore_ReleaseN(p, 1); +} + +WRes Semaphore_Wait(CSemaphore *p) { return WaitObject(p->handle); } +WRes Semaphore_Close(CSemaphore *p) { return MyCloseHandle(&p->handle); } + +WRes CriticalSection_Init(CCriticalSection *p) +{ + /* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */ + __try + { + InitializeCriticalSection(p); + /* InitializeCriticalSectionAndSpinCount(p, 0); */ + } + __except (EXCEPTION_EXECUTE_HANDLER) { return 1; } + return 0; +} + diff --git a/desmume/src/windows/7z/C/Threads.h b/desmume/src/windows/7z/C/Threads.h new file mode 100644 index 000000000..3d9072946 --- /dev/null +++ b/desmume/src/windows/7z/C/Threads.h @@ -0,0 +1,68 @@ +/* Threads.h -- multithreading library +2008-11-22 : Igor Pavlov : Public domain */ + +#ifndef __7Z_THRESDS_H +#define __7Z_THRESDS_H + +#include "Types.h" + +typedef struct _CThread +{ + HANDLE handle; +} CThread; + +#define Thread_Construct(thread) (thread)->handle = NULL +#define Thread_WasCreated(thread) ((thread)->handle != NULL) + +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 + +WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter); +WRes Thread_Wait(CThread *thread); +WRes Thread_Close(CThread *thread); + +typedef struct _CEvent +{ + HANDLE handle; +} CEvent; + +typedef CEvent CAutoResetEvent; +typedef CEvent CManualResetEvent; + +#define Event_Construct(event) (event)->handle = NULL +#define Event_IsCreated(event) ((event)->handle != NULL) + +WRes ManualResetEvent_Create(CManualResetEvent *event, int initialSignaled); +WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *event); +WRes AutoResetEvent_Create(CAutoResetEvent *event, int initialSignaled); +WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *event); +WRes Event_Set(CEvent *event); +WRes Event_Reset(CEvent *event); +WRes Event_Wait(CEvent *event); +WRes Event_Close(CEvent *event); + + +typedef struct _CSemaphore +{ + HANDLE handle; +} CSemaphore; + +#define Semaphore_Construct(p) (p)->handle = NULL + +WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount); +WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num); +WRes Semaphore_Release1(CSemaphore *p); +WRes Semaphore_Wait(CSemaphore *p); +WRes Semaphore_Close(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) + +#endif + diff --git a/desmume/src/windows/7z/C/Types.h b/desmume/src/windows/7z/C/Types.h new file mode 100644 index 000000000..2638196aa --- /dev/null +++ b/desmume/src/windows/7z/C/Types.h @@ -0,0 +1,208 @@ +/* Types.h -- Basic types +2008-11-23 : Igor Pavlov : Public domain */ + +#ifndef __7Z_TYPES_H +#define __7Z_TYPES_H + +#include + +#ifdef _WIN32 +#include +#endif + +#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 _MSC_VER + +#if _MSC_VER >= 1300 +#define MY_NO_INLINE __declspec(noinline) +#else +#define MY_NO_INLINE +#endif + +#define MY_CDECL __cdecl +#define MY_STD_CALL __stdcall +#define MY_FAST_CALL MY_NO_INLINE __fastcall + +#else + +#define MY_CDECL +#define MY_STD_CALL +#define MY_FAST_CALL + +#endif + + +/* The following interfaces use first parameter as pointer to structure */ + +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, 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) + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zCompressionMode.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zCompressionMode.cpp new file mode 100644 index 000000000..232c63820 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zCompressionMode.cpp @@ -0,0 +1,3 @@ +// CompressionMethod.cpp + +#include "StdAfx.h" diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zCompressionMode.h b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zCompressionMode.h new file mode 100644 index 000000000..5e986355b --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zCompressionMode.h @@ -0,0 +1,50 @@ +// 7zCompressionMode.h + +#ifndef __7Z_COMPRESSION_MODE_H +#define __7Z_COMPRESSION_MODE_H + +#include "../../../Common/MyString.h" + +#include "../../../Windows/PropVariant.h" + +#include "../../Common/MethodProps.h" + +namespace NArchive { +namespace N7z { + +struct CMethodFull: public CMethod +{ + UInt32 NumInStreams; + UInt32 NumOutStreams; + bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); } +}; + +struct CBind +{ + UInt32 InCoder; + UInt32 InStream; + UInt32 OutCoder; + UInt32 OutStream; +}; + +struct CCompressionMethodMode +{ + CObjectVector Methods; + CRecordVector Binds; + #ifdef COMPRESS_MT + UInt32 NumThreads; + #endif + bool PasswordIsDefined; + UString Password; + + bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); } + CCompressionMethodMode(): PasswordIsDefined(false) + #ifdef COMPRESS_MT + , NumThreads(1) + #endif + {} +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zDecode.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zDecode.cpp new file mode 100644 index 000000000..02744c96a --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zDecode.cpp @@ -0,0 +1,332 @@ +// 7zDecode.cpp + +#include "StdAfx.h" + +#include "../../Common/LimitedStreams.h" +#include "../../Common/LockedStream.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamObjects.h" + +#include "7zDecode.h" + +namespace NArchive { +namespace N7z { + +static void ConvertFolderItemInfoToBindInfo(const CFolder &folder, + CBindInfoEx &bindInfo) +{ + bindInfo.Clear(); + int i; + for (i = 0; i < folder.BindPairs.Size(); i++) + { + NCoderMixer::CBindPair bindPair; + bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex; + bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex; + bindInfo.BindPairs.Add(bindPair); + } + UInt32 outStreamIndex = 0; + for (i = 0; i < folder.Coders.Size(); i++) + { + NCoderMixer::CCoderStreamsInfo coderStreamsInfo; + const CCoderInfo &coderInfo = folder.Coders[i]; + coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams; + coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams; + bindInfo.Coders.Add(coderStreamsInfo); + bindInfo.CoderMethodIDs.Add(coderInfo.MethodID); + for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++) + if (folder.FindBindPairForOutStream(outStreamIndex) < 0) + bindInfo.OutStreams.Add(outStreamIndex); + } + for (i = 0; i < folder.PackStreams.Size(); i++) + bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]); +} + +static bool AreCodersEqual(const NCoderMixer::CCoderStreamsInfo &a1, + const NCoderMixer::CCoderStreamsInfo &a2) +{ + return (a1.NumInStreams == a2.NumInStreams) && + (a1.NumOutStreams == a2.NumOutStreams); +} + +static bool AreBindPairsEqual(const NCoderMixer::CBindPair &a1, const NCoderMixer::CBindPair &a2) +{ + return (a1.InIndex == a2.InIndex) && + (a1.OutIndex == a2.OutIndex); +} + +static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2) +{ + if (a1.Coders.Size() != a2.Coders.Size()) + return false; + int i; + for (i = 0; i < a1.Coders.Size(); i++) + if (!AreCodersEqual(a1.Coders[i], a2.Coders[i])) + return false; + if (a1.BindPairs.Size() != a2.BindPairs.Size()) + return false; + for (i = 0; i < a1.BindPairs.Size(); i++) + if (!AreBindPairsEqual(a1.BindPairs[i], a2.BindPairs[i])) + return false; + for (i = 0; i < a1.CoderMethodIDs.Size(); i++) + if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i]) + return false; + if (a1.InStreams.Size() != a2.InStreams.Size()) + return false; + if (a1.OutStreams.Size() != a2.OutStreams.Size()) + return false; + return true; +} + +CDecoder::CDecoder(bool multiThread) +{ + #ifndef _ST_MODE + multiThread = true; + #endif + _multiThread = multiThread; + _bindInfoExPrevIsDefined = false; +} + +HRESULT CDecoder::Decode( + DECL_EXTERNAL_CODECS_LOC_VARS + IInStream *inStream, + UInt64 startPos, + const UInt64 *packSizes, + const CFolder &folderInfo, + ISequentialOutStream *outStream, + ICompressProgressInfo *compressProgress + #ifndef _NO_CRYPTO + , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined + #endif + #ifdef COMPRESS_MT + , bool mtMode, UInt32 numThreads + #endif + ) +{ + if (!folderInfo.CheckStructure()) + return E_NOTIMPL; + #ifndef _NO_CRYPTO + passwordIsDefined = false; + #endif + CObjectVector< CMyComPtr > inStreams; + + CLockedInStream lockedInStream; + lockedInStream.Init(inStream); + + for (int j = 0; j < folderInfo.PackStreams.Size(); j++) + { + CLockedSequentialInStreamImp *lockedStreamImpSpec = new + CLockedSequentialInStreamImp; + CMyComPtr lockedStreamImp = lockedStreamImpSpec; + lockedStreamImpSpec->Init(&lockedInStream, startPos); + startPos += packSizes[j]; + + CLimitedSequentialInStream *streamSpec = new + CLimitedSequentialInStream; + CMyComPtr inStream = streamSpec; + streamSpec->SetStream(lockedStreamImp); + streamSpec->Init(packSizes[j]); + inStreams.Add(inStream); + } + + int numCoders = folderInfo.Coders.Size(); + + CBindInfoEx bindInfo; + ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo); + bool createNewCoders; + if (!_bindInfoExPrevIsDefined) + createNewCoders = true; + else + createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev); + if (createNewCoders) + { + int i; + _decoders.Clear(); + // _decoders2.Clear(); + + _mixerCoder.Release(); + + if (_multiThread) + { + _mixerCoderMTSpec = new NCoderMixer::CCoderMixer2MT; + _mixerCoder = _mixerCoderMTSpec; + _mixerCoderCommon = _mixerCoderMTSpec; + } + else + { + #ifdef _ST_MODE + _mixerCoderSTSpec = new NCoderMixer::CCoderMixer2ST; + _mixerCoder = _mixerCoderSTSpec; + _mixerCoderCommon = _mixerCoderSTSpec; + #endif + } + RINOK(_mixerCoderCommon->SetBindInfo(bindInfo)); + + for (i = 0; i < numCoders; i++) + { + const CCoderInfo &coderInfo = folderInfo.Coders[i]; + + + CMyComPtr decoder; + CMyComPtr decoder2; + RINOK(CreateCoder( + EXTERNAL_CODECS_LOC_VARS + coderInfo.MethodID, decoder, decoder2, false)); + CMyComPtr decoderUnknown; + if (coderInfo.IsSimpleCoder()) + { + if (decoder == 0) + return E_NOTIMPL; + + decoderUnknown = (IUnknown *)decoder; + + if (_multiThread) + _mixerCoderMTSpec->AddCoder(decoder); + #ifdef _ST_MODE + else + _mixerCoderSTSpec->AddCoder(decoder, false); + #endif + } + else + { + if (decoder2 == 0) + return E_NOTIMPL; + decoderUnknown = (IUnknown *)decoder2; + if (_multiThread) + _mixerCoderMTSpec->AddCoder2(decoder2); + #ifdef _ST_MODE + else + _mixerCoderSTSpec->AddCoder2(decoder2, false); + #endif + } + _decoders.Add(decoderUnknown); + #ifdef EXTERNAL_CODECS + CMyComPtr setCompressCodecsInfo; + decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); + if (setCompressCodecsInfo) + { + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo)); + } + #endif + } + _bindInfoExPrev = bindInfo; + _bindInfoExPrevIsDefined = true; + } + int i; + _mixerCoderCommon->ReInit(); + + UInt32 packStreamIndex = 0, unpackStreamIndex = 0; + UInt32 coderIndex = 0; + // UInt32 coder2Index = 0; + + for (i = 0; i < numCoders; i++) + { + const CCoderInfo &coderInfo = folderInfo.Coders[i]; + CMyComPtr &decoder = _decoders[coderIndex]; + + { + CMyComPtr setDecoderProperties; + decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties); + if (setDecoderProperties) + { + const CByteBuffer &props = coderInfo.Props; + size_t size = props.GetCapacity(); + if (size > 0xFFFFFFFF) + return E_NOTIMPL; + if (size > 0) + { + RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size)); + } + } + } + + #ifdef COMPRESS_MT + if (mtMode) + { + CMyComPtr setCoderMt; + decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); + if (setCoderMt) + { + RINOK(setCoderMt->SetNumberOfThreads(numThreads)); + } + } + #endif + + #ifndef _NO_CRYPTO + { + CMyComPtr cryptoSetPassword; + decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword); + if (cryptoSetPassword) + { + if (getTextPassword == 0) + return E_FAIL; + CMyComBSTR passwordBSTR; + RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR)); + CByteBuffer buffer; + passwordIsDefined = true; + const UString password(passwordBSTR); + const UInt32 sizeInBytes = password.Length() * 2; + buffer.SetCapacity(sizeInBytes); + for (int i = 0; i < password.Length(); i++) + { + wchar_t c = password[i]; + ((Byte *)buffer)[i * 2] = (Byte)c; + ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); + } + RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes)); + } + } + #endif + + coderIndex++; + + UInt32 numInStreams = (UInt32)coderInfo.NumInStreams; + UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams; + CRecordVector packSizesPointers; + CRecordVector unpackSizesPointers; + packSizesPointers.Reserve(numInStreams); + unpackSizesPointers.Reserve(numOutStreams); + UInt32 j; + for (j = 0; j < numOutStreams; j++, unpackStreamIndex++) + unpackSizesPointers.Add(&folderInfo.UnpackSizes[unpackStreamIndex]); + + for (j = 0; j < numInStreams; j++, packStreamIndex++) + { + int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex); + if (bindPairIndex >= 0) + packSizesPointers.Add( + &folderInfo.UnpackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]); + else + { + int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex); + if (index < 0) + return E_FAIL; + packSizesPointers.Add(&packSizes[index]); + } + } + + _mixerCoderCommon->SetCoderInfo(i, + &packSizesPointers.Front(), + &unpackSizesPointers.Front()); + } + UInt32 mainCoder, temp; + bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp); + + if (_multiThread) + _mixerCoderMTSpec->SetProgressCoderIndex(mainCoder); + /* + else + _mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);; + */ + + if (numCoders == 0) + return 0; + CRecordVector inStreamPointers; + inStreamPointers.Reserve(inStreams.Size()); + for (i = 0; i < inStreams.Size(); i++) + inStreamPointers.Add(inStreams[i]); + ISequentialOutStream *outStreamPointer = outStream; + return _mixerCoder->Code(&inStreamPointers.Front(), NULL, + inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress); +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zDecode.h b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zDecode.h new file mode 100644 index 000000000..aa3904a7c --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zDecode.h @@ -0,0 +1,68 @@ +// 7zDecode.h + +#ifndef __7Z_DECODE_H +#define __7Z_DECODE_H + +#include "../../IStream.h" +#include "../../IPassword.h" + +#include "../Common/CoderMixer2.h" +#include "../Common/CoderMixer2MT.h" +#ifdef _ST_MODE +#include "../Common/CoderMixer2ST.h" +#endif + +#include "../../Common/CreateCoder.h" + +#include "7zItem.h" + +namespace NArchive { +namespace N7z { + +struct CBindInfoEx: public NCoderMixer::CBindInfo +{ + CRecordVector CoderMethodIDs; + void Clear() + { + CBindInfo::Clear(); + CoderMethodIDs.Clear(); + } +}; + +class CDecoder +{ + bool _bindInfoExPrevIsDefined; + CBindInfoEx _bindInfoExPrev; + + bool _multiThread; + #ifdef _ST_MODE + NCoderMixer::CCoderMixer2ST *_mixerCoderSTSpec; + #endif + NCoderMixer::CCoderMixer2MT *_mixerCoderMTSpec; + NCoderMixer::CCoderMixer2 *_mixerCoderCommon; + + CMyComPtr _mixerCoder; + CObjectVector > _decoders; + // CObjectVector > _decoders2; +public: + CDecoder(bool multiThread); + HRESULT Decode( + DECL_EXTERNAL_CODECS_LOC_VARS + IInStream *inStream, + UInt64 startPos, + const UInt64 *packSizes, + const CFolder &folder, + ISequentialOutStream *outStream, + ICompressProgressInfo *compressProgress + #ifndef _NO_CRYPTO + , ICryptoGetTextPassword *getTextPasswordSpec, bool &passwordIsDefined + #endif + #ifdef COMPRESS_MT + , bool mtMode, UInt32 numThreads + #endif + ); +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zExtract.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zExtract.cpp new file mode 100644 index 000000000..dbc1aa522 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zExtract.cpp @@ -0,0 +1,273 @@ +// 7zExtract.cpp + +#include "StdAfx.h" + +#include "7zHandler.h" +#include "7zFolderOutStream.h" +#include "7zDecode.h" +// #include "7z1Decode.h" + +#include "../../../Common/ComTry.h" +#include "../../Common/StreamObjects.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/LimitedStreams.h" + +namespace NArchive { +namespace N7z { + +struct CExtractFolderInfo +{ + #ifdef _7Z_VOL + int VolumeIndex; + #endif + CNum FileIndex; + CNum FolderIndex; + CBoolVector ExtractStatuses; + UInt64 UnpackSize; + CExtractFolderInfo( + #ifdef _7Z_VOL + int volumeIndex, + #endif + CNum fileIndex, CNum folderIndex): + #ifdef _7Z_VOL + VolumeIndex(volumeIndex), + #endif + FileIndex(fileIndex), + FolderIndex(folderIndex), + UnpackSize(0) + { + if (fileIndex != kNumNoIndex) + { + ExtractStatuses.Reserve(1); + ExtractStatuses.Add(true); + } + }; +}; + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec) +{ + COM_TRY_BEGIN + bool testMode = (testModeSpec != 0); + CMyComPtr extractCallback = extractCallbackSpec; + UInt64 importantTotalUnpacked = 0; + + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = + #ifdef _7Z_VOL + _refs.Size(); + #else + _db.Files.Size(); + #endif + + if(numItems == 0) + return S_OK; + + /* + if(_volumes.Size() != 1) + return E_FAIL; + const CVolume &volume = _volumes.Front(); + const CArchiveDatabaseEx &_db = volume.Database; + IInStream *_inStream = volume.Stream; + */ + + CObjectVector extractFolderInfoVector; + for(UInt32 ii = 0; ii < numItems; ii++) + { + // UInt32 fileIndex = allFilesMode ? indexIndex : indices[indexIndex]; + UInt32 ref2Index = allFilesMode ? ii : indices[ii]; + // const CRef2 &ref2 = _refs[ref2Index]; + + // for(UInt32 ri = 0; ri < ref2.Refs.Size(); ri++) + { + #ifdef _7Z_VOL + // const CRef &ref = ref2.Refs[ri]; + const CRef &ref = _refs[ref2Index]; + + int volumeIndex = ref.VolumeIndex; + const CVolume &volume = _volumes[volumeIndex]; + const CArchiveDatabaseEx &db = volume.Database; + UInt32 fileIndex = ref.ItemIndex; + #else + const CArchiveDatabaseEx &db = _db; + UInt32 fileIndex = ref2Index; + #endif + + CNum folderIndex = db.FileIndexToFolderIndexMap[fileIndex]; + if (folderIndex == kNumNoIndex) + { + extractFolderInfoVector.Add(CExtractFolderInfo( + #ifdef _7Z_VOL + volumeIndex, + #endif + fileIndex, kNumNoIndex)); + continue; + } + if (extractFolderInfoVector.IsEmpty() || + folderIndex != extractFolderInfoVector.Back().FolderIndex + #ifdef _7Z_VOL + || volumeIndex != extractFolderInfoVector.Back().VolumeIndex + #endif + ) + { + extractFolderInfoVector.Add(CExtractFolderInfo( + #ifdef _7Z_VOL + volumeIndex, + #endif + kNumNoIndex, folderIndex)); + const CFolder &folderInfo = db.Folders[folderIndex]; + UInt64 unpackSize = folderInfo.GetUnpackSize(); + importantTotalUnpacked += unpackSize; + extractFolderInfoVector.Back().UnpackSize = unpackSize; + } + + CExtractFolderInfo &efi = extractFolderInfoVector.Back(); + + // const CFolderInfo &folderInfo = m_dam_Folders[folderIndex]; + CNum startIndex = db.FolderStartFileIndex[folderIndex]; + for (CNum index = efi.ExtractStatuses.Size(); + index <= fileIndex - startIndex; index++) + { + // UInt64 unpackSize = _db.Files[startIndex + index].UnpackSize; + // Count partial_folder_size + // efi.UnpackSize += unpackSize; + // importantTotalUnpacked += unpackSize; + efi.ExtractStatuses.Add(index == fileIndex - startIndex); + } + } + } + + extractCallback->SetTotal(importantTotalUnpacked); + + CDecoder decoder( + #ifdef _ST_MODE + false + #else + true + #endif + ); + // CDecoder1 decoder; + + UInt64 currentTotalPacked = 0; + UInt64 currentTotalUnpacked = 0; + UInt64 totalFolderUnpacked; + UInt64 totalFolderPacked; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + for(int i = 0; i < extractFolderInfoVector.Size(); i++, + currentTotalUnpacked += totalFolderUnpacked, + currentTotalPacked += totalFolderPacked) + { + lps->OutSize = currentTotalUnpacked; + lps->InSize = currentTotalPacked; + RINOK(lps->SetCur()); + + const CExtractFolderInfo &efi = extractFolderInfoVector[i]; + totalFolderUnpacked = efi.UnpackSize; + + totalFolderPacked = 0; + + CFolderOutStream *folderOutStream = new CFolderOutStream; + CMyComPtr outStream(folderOutStream); + + #ifdef _7Z_VOL + const CVolume &volume = _volumes[efi.VolumeIndex]; + const CArchiveDatabaseEx &db = volume.Database; + #else + const CArchiveDatabaseEx &db = _db; + #endif + + CNum startIndex; + if (efi.FileIndex != kNumNoIndex) + startIndex = efi.FileIndex; + else + startIndex = db.FolderStartFileIndex[efi.FolderIndex]; + + + HRESULT result = folderOutStream->Init(&db, + #ifdef _7Z_VOL + volume.StartRef2Index, + #else + 0, + #endif + startIndex, + &efi.ExtractStatuses, extractCallback, testMode, _crcSize != 0); + + RINOK(result); + + if (efi.FileIndex != kNumNoIndex) + continue; + + CNum folderIndex = efi.FolderIndex; + const CFolder &folderInfo = db.Folders[folderIndex]; + + totalFolderPacked = _db.GetFolderFullPackSize(folderIndex); + + CNum packStreamIndex = db.FolderStartPackStreamIndex[folderIndex]; + UInt64 folderStartPackPos = db.GetFolderStreamPos(folderIndex, 0); + + #ifndef _NO_CRYPTO + CMyComPtr getTextPassword; + if (extractCallback) + extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); + #endif + + try + { + #ifndef _NO_CRYPTO + bool passwordIsDefined; + #endif + + HRESULT result = decoder.Decode( + EXTERNAL_CODECS_VARS + #ifdef _7Z_VOL + volume.Stream, + #else + _inStream, + #endif + folderStartPackPos, + &db.PackSizes[packStreamIndex], + folderInfo, + outStream, + progress + #ifndef _NO_CRYPTO + , getTextPassword, passwordIsDefined + #endif + #ifdef COMPRESS_MT + , true, _numThreads + #endif + ); + + if (result == S_FALSE) + { + RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + if (result == E_NOTIMPL) + { + RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + continue; + } + if (result != S_OK) + return result; + if (folderOutStream->WasWritingFinished() != S_OK) + { + RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + } + catch(...) + { + RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + } + return S_OK; + COM_TRY_END +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zFolderInStream.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zFolderInStream.cpp new file mode 100644 index 000000000..3b11f1686 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zFolderInStream.cpp @@ -0,0 +1,130 @@ +// 7zFolderInStream.cpp + +#include "StdAfx.h" + +#include "7zFolderInStream.h" + +namespace NArchive { +namespace N7z { + +CFolderInStream::CFolderInStream() +{ + _inStreamWithHashSpec = new CSequentialInStreamWithCRC; + _inStreamWithHash = _inStreamWithHashSpec; +} + +void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback, + const UInt32 *fileIndices, UInt32 numFiles) +{ + _updateCallback = updateCallback; + _numFiles = numFiles; + _fileIndex = 0; + _fileIndices = fileIndices; + Processed.Clear(); + CRCs.Clear(); + Sizes.Clear(); + _fileIsOpen = false; + _currentSizeIsDefined = false; +} + +HRESULT CFolderInStream::OpenStream() +{ + _filePos = 0; + while (_fileIndex < _numFiles) + { + _currentSizeIsDefined = false; + CMyComPtr stream; + HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream); + if (result != S_OK && result != S_FALSE) + return result; + _fileIndex++; + _inStreamWithHashSpec->SetStream(stream); + _inStreamWithHashSpec->Init(); + if (!stream) + { + RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); + Sizes.Add(0); + Processed.Add(result == S_OK); + AddDigest(); + continue; + } + CMyComPtr streamGetSize; + if (stream.QueryInterface(IID_IStreamGetSize, &streamGetSize) == S_OK) + { + if(streamGetSize) + { + _currentSizeIsDefined = true; + RINOK(streamGetSize->GetSize(&_currentSize)); + } + } + + _fileIsOpen = true; + return S_OK; + } + return S_OK; +} + +void CFolderInStream::AddDigest() +{ + CRCs.Add(_inStreamWithHashSpec->GetCRC()); +} + +HRESULT CFolderInStream::CloseStream() +{ + RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); + _inStreamWithHashSpec->ReleaseStream(); + _fileIsOpen = false; + Processed.Add(true); + Sizes.Add(_filePos); + AddDigest(); + return S_OK; +} + +STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize = 0; + while ((_fileIndex < _numFiles || _fileIsOpen) && size > 0) + { + if (_fileIsOpen) + { + UInt32 localProcessedSize; + RINOK(_inStreamWithHash->Read( + ((Byte *)data) + realProcessedSize, size, &localProcessedSize)); + if (localProcessedSize == 0) + { + RINOK(CloseStream()); + continue; + } + realProcessedSize += localProcessedSize; + _filePos += localProcessedSize; + size -= localProcessedSize; + break; + } + else + { + RINOK(OpenStream()); + } + } + if (processedSize != 0) + *processedSize = realProcessedSize; + return S_OK; +} + +STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value) +{ + *value = 0; + int subStreamIndex = (int)subStream; + if (subStreamIndex < 0 || subStream > Sizes.Size()) + return E_FAIL; + if (subStreamIndex < Sizes.Size()) + { + *value= Sizes[subStreamIndex]; + return S_OK; + } + if (!_currentSizeIsDefined) + return S_FALSE; + *value = _currentSize; + return S_OK; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zFolderInStream.h b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zFolderInStream.h new file mode 100644 index 000000000..b4df6d62a --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zFolderInStream.h @@ -0,0 +1,66 @@ +// 7z/FolderInStream.h + +#ifndef __7Z_FOLDERINSTREAM_H +#define __7Z_FOLDERINSTREAM_H + +#include "7zItem.h" +#include "7zHeader.h" + +#include "../IArchive.h" +#include "../Common/InStreamWithCRC.h" +#include "../../IStream.h" +#include "../../ICoder.h" + +namespace NArchive { +namespace N7z { + +class CFolderInStream: + public ISequentialInStream, + public ICompressGetSubStreamSize, + public CMyUnknownImp +{ +public: + + MY_UNKNOWN_IMP1(ICompressGetSubStreamSize) + + CFolderInStream(); + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + + STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value); +private: + CSequentialInStreamWithCRC *_inStreamWithHashSpec; + CMyComPtr _inStreamWithHash; + CMyComPtr _updateCallback; + + bool _currentSizeIsDefined; + UInt64 _currentSize; + + bool _fileIsOpen; + UInt64 _filePos; + + const UInt32 *_fileIndices; + UInt32 _numFiles; + UInt32 _fileIndex; + + HRESULT OpenStream(); + HRESULT CloseStream(); + void AddDigest(); +public: + void Init(IArchiveUpdateCallback *updateCallback, + const UInt32 *fileIndices, UInt32 numFiles); + CRecordVector Processed; + CRecordVector CRCs; + CRecordVector Sizes; + UInt64 GetFullSize() const + { + UInt64 size = 0; + for (int i = 0; i < Sizes.Size(); i++) + size += Sizes[i]; + return size; + } +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zFolderOutStream.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zFolderOutStream.cpp new file mode 100644 index 000000000..d3a79ee13 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zFolderOutStream.cpp @@ -0,0 +1,164 @@ +// 7zFolderOutStream.cpp + +#include "StdAfx.h" + +#include "7zFolderOutStream.h" + +namespace NArchive { +namespace N7z { + +CFolderOutStream::CFolderOutStream() +{ + _outStreamWithHashSpec = new COutStreamWithCRC; + _outStreamWithHash = _outStreamWithHashSpec; +} + +HRESULT CFolderOutStream::Init( + const CArchiveDatabaseEx *archiveDatabase, + UInt32 ref2Offset, + UInt32 startIndex, + const CBoolVector *extractStatuses, + IArchiveExtractCallback *extractCallback, + bool testMode, + bool checkCrc) +{ + _archiveDatabase = archiveDatabase; + _ref2Offset = ref2Offset; + _startIndex = startIndex; + + _extractStatuses = extractStatuses; + _extractCallback = extractCallback; + _testMode = testMode; + + _checkCrc = checkCrc; + + _currentIndex = 0; + _fileIsOpen = false; + return WriteEmptyFiles(); +} + +HRESULT CFolderOutStream::OpenFile() +{ + Int32 askMode; + if((*_extractStatuses)[_currentIndex]) + askMode = _testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + else + askMode = NArchive::NExtract::NAskMode::kSkip; + CMyComPtr realOutStream; + + UInt32 index = _startIndex + _currentIndex; + RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode)); + + _outStreamWithHashSpec->SetStream(realOutStream); + _outStreamWithHashSpec->Init(_checkCrc); + if (askMode == NArchive::NExtract::NAskMode::kExtract && + (!realOutStream)) + { + const CFileItem &fi = _archiveDatabase->Files[index]; + if (!_archiveDatabase->IsItemAnti(index) && !fi.IsDir) + askMode = NArchive::NExtract::NAskMode::kSkip; + } + return _extractCallback->PrepareOperation(askMode); +} + +HRESULT CFolderOutStream::WriteEmptyFiles() +{ + for(;_currentIndex < _extractStatuses->Size(); _currentIndex++) + { + UInt32 index = _startIndex + _currentIndex; + const CFileItem &fi = _archiveDatabase->Files[index]; + if (!_archiveDatabase->IsItemAnti(index) && !fi.IsDir && fi.Size != 0) + return S_OK; + RINOK(OpenFile()); + RINOK(_extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + _outStreamWithHashSpec->ReleaseStream(); + } + return S_OK; +} + +STDMETHODIMP CFolderOutStream::Write(const void *data, + UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize = 0; + while(_currentIndex < _extractStatuses->Size()) + { + if (_fileIsOpen) + { + UInt32 index = _startIndex + _currentIndex; + const CFileItem &fi = _archiveDatabase->Files[index]; + UInt64 fileSize = fi.Size; + + UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos, + UInt64(size - realProcessedSize)); + + UInt32 processedSizeLocal; + RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize, + numBytesToWrite, &processedSizeLocal)); + + _filePos += processedSizeLocal; + realProcessedSize += processedSizeLocal; + if (_filePos == fileSize) + { + bool digestsAreEqual; + if (fi.CrcDefined && _checkCrc) + digestsAreEqual = fi.Crc == _outStreamWithHashSpec->GetCRC(); + else + digestsAreEqual = true; + + RINOK(_extractCallback->SetOperationResult( + digestsAreEqual ? + NArchive::NExtract::NOperationResult::kOK : + NArchive::NExtract::NOperationResult::kCRCError)); + _outStreamWithHashSpec->ReleaseStream(); + _fileIsOpen = false; + _currentIndex++; + } + if (realProcessedSize == size) + { + if (processedSize != NULL) + *processedSize = realProcessedSize; + return WriteEmptyFiles(); + } + } + else + { + RINOK(OpenFile()); + _fileIsOpen = true; + _filePos = 0; + } + } + if (processedSize != NULL) + *processedSize = size; + return S_OK; +} + +HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult) +{ + while(_currentIndex < _extractStatuses->Size()) + { + if (_fileIsOpen) + { + RINOK(_extractCallback->SetOperationResult(resultEOperationResult)); + _outStreamWithHashSpec->ReleaseStream(); + _fileIsOpen = false; + _currentIndex++; + } + else + { + RINOK(OpenFile()); + _fileIsOpen = true; + } + } + return S_OK; +} + +HRESULT CFolderOutStream::WasWritingFinished() +{ + if (_currentIndex == _extractStatuses->Size()) + return S_OK; + return E_FAIL; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zFolderOutStream.h b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zFolderOutStream.h new file mode 100644 index 000000000..d88cde985 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zFolderOutStream.h @@ -0,0 +1,60 @@ +// 7zFolderOutStream.h + +#ifndef __7Z_FOLDEROUTSTREAM_H +#define __7Z_FOLDEROUTSTREAM_H + +#include "7zIn.h" + +#include "../../IStream.h" +#include "../IArchive.h" +#include "../Common/OutStreamWithCRC.h" + +namespace NArchive { +namespace N7z { + +class CFolderOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + CFolderOutStream(); + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +private: + + COutStreamWithCRC *_outStreamWithHashSpec; + CMyComPtr _outStreamWithHash; + const CArchiveDatabaseEx *_archiveDatabase; + const CBoolVector *_extractStatuses; + UInt32 _startIndex; + UInt32 _ref2Offset; + int _currentIndex; + // UInt64 _currentDataPos; + CMyComPtr _extractCallback; + bool _testMode; + + bool _fileIsOpen; + + bool _checkCrc; + UInt64 _filePos; + + HRESULT OpenFile(); + HRESULT WriteEmptyFiles(); +public: + HRESULT Init( + const CArchiveDatabaseEx *archiveDatabase, + UInt32 ref2Offset, + UInt32 startIndex, + const CBoolVector *extractStatuses, + IArchiveExtractCallback *extractCallback, + bool testMode, + bool checkCrc); + HRESULT FlushCorrupted(Int32 resultEOperationResult); + HRESULT WasWritingFinished(); +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zHandler.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zHandler.cpp new file mode 100644 index 000000000..c76a106f8 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zHandler.cpp @@ -0,0 +1,503 @@ +// 7zHandler.cpp + +#include "StdAfx.h" + +extern "C" +{ + #include "../../../../C/CpuArch.h" +} + +#include "../../../Common/ComTry.h" +#include "../../../Common/IntToString.h" + +#ifdef COMPRESS_MT +#include "../../../Windows/System.h" +#endif + +#include "../Common/ItemNameUtils.h" + +#include "7zHandler.h" +#include "7zProperties.h" + +#ifdef __7Z_SET_PROPERTIES +#ifdef EXTRACT_ONLY +#include "../Common/ParseProperties.h" +#endif +#endif + +using namespace NWindows; + +extern UString ConvertMethodIdToString(UInt64 id); + +namespace NArchive { +namespace N7z { + +CHandler::CHandler() +{ + _crcSize = 4; + + #ifndef _NO_CRYPTO + _passwordIsDefined = false; + #endif + + #ifdef EXTRACT_ONLY + #ifdef COMPRESS_MT + _numThreads = NSystem::GetNumberOfProcessors(); + #endif + #else + Init(); + #endif +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _db.Files.Size(); + return S_OK; +} + +#ifdef _SFX + +IMP_IInArchive_ArcProps_NO + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +{ + return E_NOTIMPL; +} + + +#else + +STATPROPSTG kArcProps[] = +{ + { NULL, kpidMethod, VT_BSTR}, + { NULL, kpidSolid, VT_BOOL}, + { NULL, kpidNumBlocks, VT_UI4}, + { NULL, kpidPhySize, VT_UI8}, + { NULL, kpidHeadersSize, VT_UI8}, + { NULL, kpidOffset, VT_UI8} +}; + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch(propID) + { + case kpidMethod: + { + UString resString; + CRecordVector ids; + int i; + for (i = 0; i < _db.Folders.Size(); i++) + { + const CFolder &f = _db.Folders[i]; + for (int j = f.Coders.Size() - 1; j >= 0; j--) + ids.AddToUniqueSorted(f.Coders[j].MethodID); + } + + for (i = 0; i < ids.Size(); i++) + { + UInt64 id = ids[i]; + UString methodName; + /* bool methodIsKnown = */ FindMethod(EXTERNAL_CODECS_VARS id, methodName); + if (methodName.IsEmpty()) + methodName = ConvertMethodIdToString(id); + if (!resString.IsEmpty()) + resString += L' '; + resString += methodName; + } + prop = resString; + break; + } + case kpidSolid: prop = _db.IsSolid(); break; + case kpidNumBlocks: prop = (UInt32)_db.Folders.Size(); break; + case kpidHeadersSize: prop = _db.HeadersSize; break; + case kpidPhySize: prop = _db.PhySize; break; + case kpidOffset: if (_db.ArchiveInfo.StartPosition != 0) prop = _db.ArchiveInfo.StartPosition; break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +IMP_IInArchive_ArcProps + +#endif + +static void SetPropFromUInt64Def(CUInt64DefVector &v, int index, NCOM::CPropVariant &prop) +{ + UInt64 value; + if (v.GetItem(index, value)) + { + FILETIME ft; + ft.dwLowDateTime = (DWORD)value; + ft.dwHighDateTime = (DWORD)(value >> 32); + prop = ft; + } +} + +#ifndef _SFX + +static UString ConvertUInt32ToString(UInt32 value) +{ + wchar_t buffer[32]; + ConvertUInt64ToString(value, buffer); + return buffer; +} + +static UString GetStringForSizeValue(UInt32 value) +{ + for (int i = 31; i >= 0; i--) + if ((UInt32(1) << i) == value) + return ConvertUInt32ToString(i); + UString result; + if (value % (1 << 20) == 0) + { + result += ConvertUInt32ToString(value >> 20); + result += L"m"; + } + else if (value % (1 << 10) == 0) + { + result += ConvertUInt32ToString(value >> 10); + result += L"k"; + } + else + { + result += ConvertUInt32ToString(value); + result += L"b"; + } + return result; +} + +static const UInt64 k_Copy = 0x0; +static const UInt64 k_LZMA = 0x030101; +static const UInt64 k_PPMD = 0x030401; + +static wchar_t GetHex(Byte value) +{ + return (wchar_t)((value < 10) ? (L'0' + value) : (L'A' + (value - 10))); +} +static inline UString GetHex2(Byte value) +{ + UString result; + result += GetHex((Byte)(value >> 4)); + result += GetHex((Byte)(value & 0xF)); + return result; +} + +#endif + +static const UInt64 k_AES = 0x06F10701; + +bool CHandler::IsEncrypted(UInt32 index2) const +{ + CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; + if (folderIndex != kNumNoIndex) + { + const CFolder &folderInfo = _db.Folders[folderIndex]; + for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--) + if (folderInfo.Coders[i].MethodID == k_AES) + return true; + } + return false; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + /* + const CRef2 &ref2 = _refs[index]; + if (ref2.Refs.IsEmpty()) + return E_FAIL; + const CRef &ref = ref2.Refs.Front(); + */ + + const CFileItem &item = _db.Files[index]; + UInt32 index2 = index; + + switch(propID) + { + case kpidPath: + if (!item.Name.IsEmpty()) + prop = NItemName::GetOSName(item.Name); + break; + case kpidIsDir: prop = item.IsDir; break; + case kpidSize: + { + prop = item.Size; + // prop = ref2.Size; + break; + } + case kpidPackSize: + { + // prop = ref2.PackSize; + { + CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; + if (folderIndex != kNumNoIndex) + { + if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2) + prop = _db.GetFolderFullPackSize(folderIndex); + /* + else + prop = (UInt64)0; + */ + } + else + prop = (UInt64)0; + } + break; + } + case kpidPosition: { UInt64 v; if (_db.StartPos.GetItem(index2, v)) prop = v; break; } + case kpidCTime: SetPropFromUInt64Def(_db.CTime, index2, prop); break; + case kpidATime: SetPropFromUInt64Def(_db.ATime, index2, prop); break; + case kpidMTime: SetPropFromUInt64Def(_db.MTime, index2, prop); break; + case kpidAttrib: if (item.AttribDefined) prop = item.Attrib; break; + case kpidCRC: if (item.CrcDefined) prop = item.Crc; break; + case kpidEncrypted: prop = IsEncrypted(index2); break; + case kpidIsAnti: prop = _db.IsItemAnti(index2); break; + #ifndef _SFX + case kpidMethod: + { + CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; + if (folderIndex != kNumNoIndex) + { + const CFolder &folderInfo = _db.Folders[folderIndex]; + UString methodsString; + for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--) + { + const CCoderInfo &coderInfo = folderInfo.Coders[i]; + if (!methodsString.IsEmpty()) + methodsString += L' '; + + { + UString methodName; + bool methodIsKnown = FindMethod( + EXTERNAL_CODECS_VARS + coderInfo.MethodID, methodName); + + if (methodIsKnown) + { + methodsString += methodName; + if (coderInfo.MethodID == k_LZMA) + { + if (coderInfo.Props.GetCapacity() >= 5) + { + methodsString += L":"; + UInt32 dicSize = GetUi32((const Byte *)coderInfo.Props + 1); + methodsString += GetStringForSizeValue(dicSize); + } + } + else if (coderInfo.MethodID == k_PPMD) + { + if (coderInfo.Props.GetCapacity() >= 5) + { + Byte order = *(const Byte *)coderInfo.Props; + methodsString += L":o"; + methodsString += ConvertUInt32ToString(order); + methodsString += L":mem"; + UInt32 dicSize = GetUi32((const Byte *)coderInfo.Props + 1); + methodsString += GetStringForSizeValue(dicSize); + } + } + else if (coderInfo.MethodID == k_AES) + { + if (coderInfo.Props.GetCapacity() >= 1) + { + methodsString += L":"; + const Byte *data = (const Byte *)coderInfo.Props; + Byte firstByte = *data++; + UInt32 numCyclesPower = firstByte & 0x3F; + methodsString += ConvertUInt32ToString(numCyclesPower); + /* + if ((firstByte & 0xC0) != 0) + { + methodsString += L":"; + return S_OK; + UInt32 saltSize = (firstByte >> 7) & 1; + UInt32 ivSize = (firstByte >> 6) & 1; + if (coderInfo.Props.GetCapacity() >= 2) + { + Byte secondByte = *data++; + saltSize += (secondByte >> 4); + ivSize += (secondByte & 0x0F); + } + } + */ + } + } + else + { + if (coderInfo.Props.GetCapacity() > 0) + { + methodsString += L":["; + for (size_t bi = 0; bi < coderInfo.Props.GetCapacity(); bi++) + { + if (bi > 5 && bi + 1 < coderInfo.Props.GetCapacity()) + { + methodsString += L".."; + break; + } + else + methodsString += GetHex2(coderInfo.Props[bi]); + } + methodsString += L"]"; + } + } + } + else + { + methodsString += ConvertMethodIdToString(coderInfo.MethodID); + } + } + } + prop = methodsString; + } + } + break; + case kpidBlock: + { + CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; + if (folderIndex != kNumNoIndex) + prop = (UInt32)folderIndex; + } + break; + case kpidPackedSize0: + case kpidPackedSize1: + case kpidPackedSize2: + case kpidPackedSize3: + case kpidPackedSize4: + { + CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; + if (folderIndex != kNumNoIndex) + { + const CFolder &folderInfo = _db.Folders[folderIndex]; + if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2 && + folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0)) + { + prop = _db.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0); + } + else + prop = (UInt64)0; + } + else + prop = (UInt64)0; + } + break; + #endif + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + Close(); + #ifndef _SFX + _fileInfoPopIDs.Clear(); + #endif + try + { + CMyComPtr openArchiveCallbackTemp = openArchiveCallback; + + #ifndef _NO_CRYPTO + CMyComPtr getTextPassword; + if (openArchiveCallback) + { + openArchiveCallbackTemp.QueryInterface( + IID_ICryptoGetTextPassword, &getTextPassword); + } + #endif + CInArchive archive; + RINOK(archive.Open(stream, maxCheckStartPosition)); + #ifndef _NO_CRYPTO + _passwordIsDefined = false; + UString password; + #endif + HRESULT result = archive.ReadDatabase( + EXTERNAL_CODECS_VARS + _db + #ifndef _NO_CRYPTO + , getTextPassword, _passwordIsDefined + #endif + ); + RINOK(result); + _db.Fill(); + _inStream = stream; + } + catch(...) + { + Close(); + return S_FALSE; + } + // _inStream = stream; + #ifndef _SFX + FillPopIDs(); + #endif + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + COM_TRY_BEGIN + _inStream.Release(); + _db.Clear(); + return S_OK; + COM_TRY_END +} + +#ifdef __7Z_SET_PROPERTIES +#ifdef EXTRACT_ONLY + +STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) +{ + COM_TRY_BEGIN + #ifdef COMPRESS_MT + const UInt32 numProcessors = NSystem::GetNumberOfProcessors(); + _numThreads = numProcessors; + #endif + + for (int i = 0; i < numProperties; i++) + { + UString name = names[i]; + name.MakeUpper(); + if (name.IsEmpty()) + return E_INVALIDARG; + const PROPVARIANT &value = values[i]; + UInt32 number; + int index = ParseStringToUInt32(name, number); + if (index == 0) + { + if(name.Left(2).CompareNoCase(L"MT") == 0) + { + #ifdef COMPRESS_MT + RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads)); + #endif + continue; + } + else + return E_INVALIDARG; + } + } + return S_OK; + COM_TRY_END +} + +#endif +#endif + +IMPL_ISetCompressCodecsInfo + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zHandler.h b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zHandler.h new file mode 100644 index 000000000..c04a0f931 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zHandler.h @@ -0,0 +1,121 @@ +// 7z/Handler.h + +#ifndef __7Z_HANDLER_H +#define __7Z_HANDLER_H + +#include "../../ICoder.h" +#include "../IArchive.h" +#include "7zIn.h" + +#include "7zCompressionMode.h" + +#include "../../Common/CreateCoder.h" + +#ifndef EXTRACT_ONLY +#include "../Common/HandlerOut.h" +#endif + +namespace NArchive { +namespace N7z { + +#ifndef __7Z_SET_PROPERTIES + +#ifdef EXTRACT_ONLY +#ifdef COMPRESS_MT +#define __7Z_SET_PROPERTIES +#endif +#else +#define __7Z_SET_PROPERTIES +#endif + +#endif + + +class CHandler: + #ifndef EXTRACT_ONLY + public NArchive::COutHandler, + #endif + public IInArchive, + #ifdef __7Z_SET_PROPERTIES + public ISetProperties, + #endif + #ifndef EXTRACT_ONLY + public IOutArchive, + #endif + PUBLIC_ISetCompressCodecsInfo + public CMyUnknownImp +{ +public: + MY_QUERYINTERFACE_BEGIN2(IInArchive) + #ifdef __7Z_SET_PROPERTIES + MY_QUERYINTERFACE_ENTRY(ISetProperties) + #endif + #ifndef EXTRACT_ONLY + MY_QUERYINTERFACE_ENTRY(IOutArchive) + #endif + QUERY_ENTRY_ISetCompressCodecsInfo + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + INTERFACE_IInArchive(;) + + #ifdef __7Z_SET_PROPERTIES + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties); + #endif + + #ifndef EXTRACT_ONLY + INTERFACE_IOutArchive(;) + #endif + + DECL_ISetCompressCodecsInfo + + CHandler(); + +private: + CMyComPtr _inStream; + NArchive::N7z::CArchiveDatabaseEx _db; + #ifndef _NO_CRYPTO + bool _passwordIsDefined; + #endif + + #ifdef EXTRACT_ONLY + + #ifdef COMPRESS_MT + UInt32 _numThreads; + #endif + + UInt32 _crcSize; + + #else + + CRecordVector _binds; + + HRESULT SetPassword(CCompressionMethodMode &methodMode, IArchiveUpdateCallback *updateCallback); + + HRESULT SetCompressionMethod(CCompressionMethodMode &method, + CObjectVector &methodsInfo + #ifdef COMPRESS_MT + , UInt32 numThreads + #endif + ); + + HRESULT SetCompressionMethod( + CCompressionMethodMode &method, + CCompressionMethodMode &headerMethod); + + #endif + + bool IsEncrypted(UInt32 index2) const; + #ifndef _SFX + + CRecordVector _fileInfoPopIDs; + void FillPopIDs(); + + #endif + + DECL_EXTERNAL_CODECS_VARS +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zHeader.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zHeader.cpp new file mode 100644 index 000000000..c010f3671 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zHeader.cpp @@ -0,0 +1,27 @@ +// 7z/Header.cpp + +#include "StdAfx.h" +#include "7zHeader.h" + +namespace NArchive { +namespace N7z { + +Byte kSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C}; +#ifdef _7Z_VOL +Byte kFinishSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C + 1}; +#endif + +class SignatureInitializer +{ +public: + SignatureInitializer() + { + kSignature[0]--; + #ifdef _7Z_VOL + kFinishSignature[0]--; + #endif + }; +} g_SignatureInitializer; + +}} + diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zHeader.h b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zHeader.h new file mode 100644 index 000000000..57f455b81 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zHeader.h @@ -0,0 +1,97 @@ +// 7z/7zHeader.h + +#ifndef __7Z_HEADER_H +#define __7Z_HEADER_H + +#include "../../../Common/Types.h" + +namespace NArchive { +namespace N7z { + +const int kSignatureSize = 6; +extern Byte kSignature[kSignatureSize]; + +// #define _7Z_VOL +// 7z-MultiVolume is not finished yet. +// It can work already, but I still do not like some +// things of that new multivolume format. +// So please keep it commented. + +#ifdef _7Z_VOL +extern Byte kFinishSignature[kSignatureSize]; +#endif + +struct CArchiveVersion +{ + Byte Major; + Byte Minor; +}; + +const Byte kMajorVersion = 0; + +struct CStartHeader +{ + UInt64 NextHeaderOffset; + UInt64 NextHeaderSize; + UInt32 NextHeaderCRC; +}; + +const UInt32 kStartHeaderSize = 20; + +#ifdef _7Z_VOL +struct CFinishHeader: public CStartHeader +{ + UInt64 ArchiveStartOffset; // data offset from end if that struct + UInt64 AdditionalStartBlockSize; // start signature & start header size +}; + +const UInt32 kFinishHeaderSize = kStartHeaderSize + 16; +#endif + +namespace NID +{ + enum EEnum + { + kEnd, + + kHeader, + + kArchiveProperties, + + kAdditionalStreamsInfo, + kMainStreamsInfo, + kFilesInfo, + + kPackInfo, + kUnpackInfo, + kSubStreamsInfo, + + kSize, + kCRC, + + kFolder, + + kCodersUnpackSize, + kNumUnpackStream, + + kEmptyStream, + kEmptyFile, + kAnti, + + kName, + kCTime, + kATime, + kMTime, + kWinAttributes, + kComment, + + kEncodedHeader, + + kStartPos, + kDummy + }; +} + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zIn.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zIn.cpp new file mode 100644 index 000000000..a9fecf8e1 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zIn.cpp @@ -0,0 +1,1260 @@ +// 7zIn.cpp + +#include "StdAfx.h" + +extern "C" +{ + #include "../../../../C/7zCrc.h" + #include "../../../../C/CpuArch.h" +} + +#include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" + +#include "7zDecode.h" +#include "7zIn.h" + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + +// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader +#ifndef _SFX +#define FORMAT_7Z_RECOVERY +#endif + +namespace NArchive { +namespace N7z { + +static void BoolVector_Fill_False(CBoolVector &v, int size) +{ + v.Clear(); + v.Reserve(size); + for (int i = 0; i < size; i++) + v.Add(false); +} + +static bool BoolVector_GetAndSet(CBoolVector &v, UInt32 index) +{ + if (index >= (UInt32)v.Size()) + return true; + bool res = v[index]; + v[index] = true; + return res; +} + +bool CFolder::CheckStructure() const +{ + const int kNumCodersMax = sizeof(UInt32) * 8; // don't change it + const int kMaskSize = sizeof(UInt32) * 8; // it must be >= kNumCodersMax + const int kNumBindsMax = 32; + + if (Coders.Size() > kNumCodersMax || BindPairs.Size() > kNumBindsMax) + return false; + + { + CBoolVector v; + BoolVector_Fill_False(v, BindPairs.Size() + PackStreams.Size()); + + int i; + for (i = 0; i < BindPairs.Size(); i++) + if (BoolVector_GetAndSet(v, BindPairs[i].InIndex)) + return false; + for (i = 0; i < PackStreams.Size(); i++) + if (BoolVector_GetAndSet(v, PackStreams[i])) + return false; + + BoolVector_Fill_False(v, UnpackSizes.Size()); + for (i = 0; i < BindPairs.Size(); i++) + if (BoolVector_GetAndSet(v, BindPairs[i].OutIndex)) + return false; + } + + UInt32 mask[kMaskSize]; + int i; + for (i = 0; i < kMaskSize; i++) + mask[i] = 0; + + { + CIntVector inStreamToCoder, outStreamToCoder; + for (i = 0; i < Coders.Size(); i++) + { + CNum j; + const CCoderInfo &coder = Coders[i]; + for (j = 0; j < coder.NumInStreams; j++) + inStreamToCoder.Add(i); + for (j = 0; j < coder.NumOutStreams; j++) + outStreamToCoder.Add(i); + } + + for (i = 0; i < BindPairs.Size(); i++) + { + const CBindPair &bp = BindPairs[i]; + mask[inStreamToCoder[bp.InIndex]] |= (1 << outStreamToCoder[bp.OutIndex]); + } + } + + for (i = 0; i < kMaskSize; i++) + for (int j = 0; j < kMaskSize; j++) + if (((1 << j) & mask[i]) != 0) + mask[i] |= mask[j]; + + for (i = 0; i < kMaskSize; i++) + if (((1 << i) & mask[i]) != 0) + return false; + + return true; +} + +class CInArchiveException {}; + +static void ThrowException() { throw CInArchiveException(); } +static inline void ThrowEndOfData() { ThrowException(); } +static inline void ThrowUnsupported() { ThrowException(); } +static inline void ThrowIncorrect() { ThrowException(); } +static inline void ThrowUnsupportedVersion() { ThrowException(); } + +/* +class CInArchiveException +{ +public: + enum CCauseType + { + kUnsupportedVersion = 0, + kUnsupported, + kIncorrect, + kEndOfData, + } Cause; + CInArchiveException(CCauseType cause): Cause(cause) {}; +}; + +static void ThrowException(CInArchiveException::CCauseType c) { throw CInArchiveException(c); } +static void ThrowEndOfData() { ThrowException(CInArchiveException::kEndOfData); } +static void ThrowUnsupported() { ThrowException(CInArchiveException::kUnsupported); } +static void ThrowIncorrect() { ThrowException(CInArchiveException::kIncorrect); } +static void ThrowUnsupportedVersion() { ThrowException(CInArchiveException::kUnsupportedVersion); } +*/ + +class CStreamSwitch +{ + CInArchive *_archive; + bool _needRemove; +public: + CStreamSwitch(): _needRemove(false) {} + ~CStreamSwitch() { Remove(); } + void Remove(); + void Set(CInArchive *archive, const Byte *data, size_t size); + void Set(CInArchive *archive, const CByteBuffer &byteBuffer); + void Set(CInArchive *archive, const CObjectVector *dataVector); +}; + +void CStreamSwitch::Remove() +{ + if (_needRemove) + { + _archive->DeleteByteStream(); + _needRemove = false; + } +} + +void CStreamSwitch::Set(CInArchive *archive, const Byte *data, size_t size) +{ + Remove(); + _archive = archive; + _archive->AddByteStream(data, size); + _needRemove = true; +} + +void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer) +{ + Set(archive, byteBuffer, byteBuffer.GetCapacity()); +} + +void CStreamSwitch::Set(CInArchive *archive, const CObjectVector *dataVector) +{ + Remove(); + Byte external = archive->ReadByte(); + if (external != 0) + { + int dataIndex = (int)archive->ReadNum(); + if (dataIndex < 0 || dataIndex >= dataVector->Size()) + ThrowIncorrect(); + Set(archive, (*dataVector)[dataIndex]); + } +} + +Byte CInByte2::ReadByte() +{ + if (_pos >= _size) + ThrowEndOfData(); + return _buffer[_pos++]; +} + +void CInByte2::ReadBytes(Byte *data, size_t size) +{ + if (size > _size - _pos) + ThrowEndOfData(); + for (size_t i = 0; i < size; i++) + data[i] = _buffer[_pos++]; +} + +void CInByte2::SkeepData(UInt64 size) +{ + if (size > _size - _pos) + ThrowEndOfData(); + _pos += (size_t)size; +} + +void CInByte2::SkeepData() +{ + SkeepData(ReadNumber()); +} + +UInt64 CInByte2::ReadNumber() +{ + if (_pos >= _size) + ThrowEndOfData(); + Byte firstByte = _buffer[_pos++]; + Byte mask = 0x80; + UInt64 value = 0; + for (int i = 0; i < 8; i++) + { + if ((firstByte & mask) == 0) + { + UInt64 highPart = firstByte & (mask - 1); + value += (highPart << (i * 8)); + return value; + } + if (_pos >= _size) + ThrowEndOfData(); + value |= ((UInt64)_buffer[_pos++] << (8 * i)); + mask >>= 1; + } + return value; +} + +CNum CInByte2::ReadNum() +{ + UInt64 value = ReadNumber(); + if (value > kNumMax) + ThrowUnsupported(); + return (CNum)value; +} + +UInt32 CInByte2::ReadUInt32() +{ + if (_pos + 4 > _size) + ThrowEndOfData(); + UInt32 res = Get32(_buffer + _pos); + _pos += 4; + return res; +} + +UInt64 CInByte2::ReadUInt64() +{ + if (_pos + 8 > _size) + ThrowEndOfData(); + UInt64 res = Get64(_buffer + _pos); + _pos += 8; + return res; +} + +void CInByte2::ReadString(UString &s) +{ + const Byte *buf = _buffer + _pos; + size_t rem = (_size - _pos) / 2 * 2; + { + size_t i; + for (i = 0; i < rem; i += 2) + if (buf[i] == 0 && buf[i + 1] == 0) + break; + if (i == rem) + ThrowEndOfData(); + rem = i; + } + int len = (int)(rem / 2); + if (len < 0 || (size_t)len * 2 != rem) + ThrowUnsupported(); + wchar_t *p = s.GetBuffer(len); + int i; + for (i = 0; i < len; i++, buf += 2) + p[i] = (wchar_t)Get16(buf); + s.ReleaseBuffer(len); + _pos += rem + 2; +} + +static inline bool TestSignatureCandidate(const Byte *p) +{ + for (int i = 0; i < kSignatureSize; i++) + if (p[i] != kSignature[i]) + return false; + return (p[0x1A] == 0 && p[0x1B] == 0); +} + +HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit) +{ + RINOK(ReadStream_FALSE(stream, _header, kHeaderSize)); + + if (TestSignatureCandidate(_header)) + return S_OK; + + CByteBuffer byteBuffer; + const UInt32 kBufferSize = (1 << 16); + byteBuffer.SetCapacity(kBufferSize); + Byte *buffer = byteBuffer; + UInt32 numPrevBytes = kHeaderSize - 1; + memcpy(buffer, _header + 1, numPrevBytes); + UInt64 curTestPos = _arhiveBeginStreamPosition + 1; + for (;;) + { + if (searchHeaderSizeLimit != NULL) + if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit) + break; + do + { + UInt32 numReadBytes = kBufferSize - numPrevBytes; + UInt32 processedSize; + RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize)); + numPrevBytes += processedSize; + if (processedSize == 0) + return S_FALSE; + } + while (numPrevBytes < kHeaderSize); + UInt32 numTests = numPrevBytes - kHeaderSize + 1; + for (UInt32 pos = 0; pos < numTests; pos++) + { + for (; buffer[pos] != '7' && pos < numTests; pos++); + if (pos == numTests) + break; + if (TestSignatureCandidate(buffer + pos)) + { + memcpy(_header, buffer + pos, kHeaderSize); + curTestPos += pos; + _arhiveBeginStreamPosition = curTestPos; + return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL); + } + } + curTestPos += numTests; + numPrevBytes -= numTests; + memmove(buffer, buffer + numTests, numPrevBytes); + } + return S_FALSE; +} + +// S_FALSE means that file is not archive +HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) +{ + HeadersSize = 0; + Close(); + RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition)) + RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit)); + _stream = stream; + return S_OK; +} + +void CInArchive::Close() +{ + _stream.Release(); +} + +void CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */) +{ + for (;;) + { + if (ReadID() == NID::kEnd) + break; + SkeepData(); + } +} + +void CInArchive::GetNextFolderItem(CFolder &folder) +{ + CNum numCoders = ReadNum(); + + folder.Coders.Clear(); + folder.Coders.Reserve((int)numCoders); + CNum numInStreams = 0; + CNum numOutStreams = 0; + CNum i; + for (i = 0; i < numCoders; i++) + { + folder.Coders.Add(CCoderInfo()); + CCoderInfo &coder = folder.Coders.Back(); + + { + Byte mainByte = ReadByte(); + int idSize = (mainByte & 0xF); + Byte longID[15]; + ReadBytes(longID, idSize); + if (idSize > 8) + ThrowUnsupported(); + UInt64 id = 0; + for (int j = 0; j < idSize; j++) + id |= (UInt64)longID[idSize - 1 - j] << (8 * j); + coder.MethodID = id; + + if ((mainByte & 0x10) != 0) + { + coder.NumInStreams = ReadNum(); + coder.NumOutStreams = ReadNum(); + } + else + { + coder.NumInStreams = 1; + coder.NumOutStreams = 1; + } + if ((mainByte & 0x20) != 0) + { + CNum propsSize = ReadNum(); + coder.Props.SetCapacity((size_t)propsSize); + ReadBytes((Byte *)coder.Props, (size_t)propsSize); + } + if ((mainByte & 0x80) != 0) + ThrowUnsupported(); + } + numInStreams += coder.NumInStreams; + numOutStreams += coder.NumOutStreams; + } + + CNum numBindPairs = numOutStreams - 1; + folder.BindPairs.Clear(); + folder.BindPairs.Reserve(numBindPairs); + for (i = 0; i < numBindPairs; i++) + { + CBindPair bp; + bp.InIndex = ReadNum(); + bp.OutIndex = ReadNum(); + folder.BindPairs.Add(bp); + } + + if (numInStreams < numBindPairs) + ThrowUnsupported(); + CNum numPackStreams = numInStreams - numBindPairs; + folder.PackStreams.Reserve(numPackStreams); + if (numPackStreams == 1) + { + for (i = 0; i < numInStreams; i++) + if (folder.FindBindPairForInStream(i) < 0) + { + folder.PackStreams.Add(i); + break; + } + if (folder.PackStreams.Size() != 1) + ThrowUnsupported(); + } + else + for (i = 0; i < numPackStreams; i++) + folder.PackStreams.Add(ReadNum()); +} + +void CInArchive::WaitAttribute(UInt64 attribute) +{ + for (;;) + { + UInt64 type = ReadID(); + if (type == attribute) + return; + if (type == NID::kEnd) + ThrowIncorrect(); + SkeepData(); + } +} + +void CInArchive::ReadHashDigests(int numItems, + CBoolVector &digestsDefined, + CRecordVector &digests) +{ + ReadBoolVector2(numItems, digestsDefined); + digests.Clear(); + digests.Reserve(numItems); + for (int i = 0; i < numItems; i++) + { + UInt32 crc = 0; + if (digestsDefined[i]) + crc = ReadUInt32(); + digests.Add(crc); + } +} + +void CInArchive::ReadPackInfo( + UInt64 &dataOffset, + CRecordVector &packSizes, + CBoolVector &packCRCsDefined, + CRecordVector &packCRCs) +{ + dataOffset = ReadNumber(); + CNum numPackStreams = ReadNum(); + + WaitAttribute(NID::kSize); + packSizes.Clear(); + packSizes.Reserve(numPackStreams); + for (CNum i = 0; i < numPackStreams; i++) + packSizes.Add(ReadNumber()); + + UInt64 type; + for (;;) + { + type = ReadID(); + if (type == NID::kEnd) + break; + if (type == NID::kCRC) + { + ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs); + continue; + } + SkeepData(); + } + if (packCRCsDefined.IsEmpty()) + { + BoolVector_Fill_False(packCRCsDefined, numPackStreams); + packCRCs.Reserve(numPackStreams); + packCRCs.Clear(); + for (CNum i = 0; i < numPackStreams; i++) + packCRCs.Add(0); + } +} + +void CInArchive::ReadUnpackInfo( + const CObjectVector *dataVector, + CObjectVector &folders) +{ + WaitAttribute(NID::kFolder); + CNum numFolders = ReadNum(); + + { + CStreamSwitch streamSwitch; + streamSwitch.Set(this, dataVector); + folders.Clear(); + folders.Reserve(numFolders); + for (CNum i = 0; i < numFolders; i++) + { + folders.Add(CFolder()); + GetNextFolderItem(folders.Back()); + } + } + + WaitAttribute(NID::kCodersUnpackSize); + + CNum i; + for (i = 0; i < numFolders; i++) + { + CFolder &folder = folders[i]; + CNum numOutStreams = folder.GetNumOutStreams(); + folder.UnpackSizes.Reserve(numOutStreams); + for (CNum j = 0; j < numOutStreams; j++) + folder.UnpackSizes.Add(ReadNumber()); + } + + for (;;) + { + UInt64 type = ReadID(); + if (type == NID::kEnd) + return; + if (type == NID::kCRC) + { + CBoolVector crcsDefined; + CRecordVector crcs; + ReadHashDigests(numFolders, crcsDefined, crcs); + for (i = 0; i < numFolders; i++) + { + CFolder &folder = folders[i]; + folder.UnpackCRCDefined = crcsDefined[i]; + folder.UnpackCRC = crcs[i]; + } + continue; + } + SkeepData(); + } +} + +void CInArchive::ReadSubStreamsInfo( + const CObjectVector &folders, + CRecordVector &numUnpackStreamsInFolders, + CRecordVector &unpackSizes, + CBoolVector &digestsDefined, + CRecordVector &digests) +{ + numUnpackStreamsInFolders.Clear(); + numUnpackStreamsInFolders.Reserve(folders.Size()); + UInt64 type; + for (;;) + { + type = ReadID(); + if (type == NID::kNumUnpackStream) + { + for (int i = 0; i < folders.Size(); i++) + numUnpackStreamsInFolders.Add(ReadNum()); + continue; + } + if (type == NID::kCRC || type == NID::kSize) + break; + if (type == NID::kEnd) + break; + SkeepData(); + } + + if (numUnpackStreamsInFolders.IsEmpty()) + for (int i = 0; i < folders.Size(); i++) + numUnpackStreamsInFolders.Add(1); + + int i; + for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) + { + // v3.13 incorrectly worked with empty folders + // v4.07: we check that folder is empty + CNum numSubstreams = numUnpackStreamsInFolders[i]; + if (numSubstreams == 0) + continue; + UInt64 sum = 0; + for (CNum j = 1; j < numSubstreams; j++) + if (type == NID::kSize) + { + UInt64 size = ReadNumber(); + unpackSizes.Add(size); + sum += size; + } + unpackSizes.Add(folders[i].GetUnpackSize() - sum); + } + if (type == NID::kSize) + type = ReadID(); + + int numDigests = 0; + int numDigestsTotal = 0; + for (i = 0; i < folders.Size(); i++) + { + CNum numSubstreams = numUnpackStreamsInFolders[i]; + if (numSubstreams != 1 || !folders[i].UnpackCRCDefined) + numDigests += numSubstreams; + numDigestsTotal += numSubstreams; + } + + for (;;) + { + if (type == NID::kCRC) + { + CBoolVector digestsDefined2; + CRecordVector digests2; + ReadHashDigests(numDigests, digestsDefined2, digests2); + int digestIndex = 0; + for (i = 0; i < folders.Size(); i++) + { + CNum numSubstreams = numUnpackStreamsInFolders[i]; + const CFolder &folder = folders[i]; + if (numSubstreams == 1 && folder.UnpackCRCDefined) + { + digestsDefined.Add(true); + digests.Add(folder.UnpackCRC); + } + else + for (CNum j = 0; j < numSubstreams; j++, digestIndex++) + { + digestsDefined.Add(digestsDefined2[digestIndex]); + digests.Add(digests2[digestIndex]); + } + } + } + else if (type == NID::kEnd) + { + if (digestsDefined.IsEmpty()) + { + BoolVector_Fill_False(digestsDefined, numDigestsTotal); + digests.Clear(); + for (int i = 0; i < numDigestsTotal; i++) + digests.Add(0); + } + return; + } + else + SkeepData(); + type = ReadID(); + } +} + +void CInArchive::ReadStreamsInfo( + const CObjectVector *dataVector, + UInt64 &dataOffset, + CRecordVector &packSizes, + CBoolVector &packCRCsDefined, + CRecordVector &packCRCs, + CObjectVector &folders, + CRecordVector &numUnpackStreamsInFolders, + CRecordVector &unpackSizes, + CBoolVector &digestsDefined, + CRecordVector &digests) +{ + for (;;) + { + UInt64 type = ReadID(); + if (type > ((UInt32)1 << 30)) + ThrowIncorrect(); + switch((UInt32)type) + { + case NID::kEnd: + return; + case NID::kPackInfo: + { + ReadPackInfo(dataOffset, packSizes, packCRCsDefined, packCRCs); + break; + } + case NID::kUnpackInfo: + { + ReadUnpackInfo(dataVector, folders); + break; + } + case NID::kSubStreamsInfo: + { + ReadSubStreamsInfo(folders, numUnpackStreamsInFolders, + unpackSizes, digestsDefined, digests); + break; + } + default: + ThrowIncorrect(); + } + } +} + +void CInArchive::ReadBoolVector(int numItems, CBoolVector &v) +{ + v.Clear(); + v.Reserve(numItems); + Byte b = 0; + Byte mask = 0; + for (int i = 0; i < numItems; i++) + { + if (mask == 0) + { + b = ReadByte(); + mask = 0x80; + } + v.Add((b & mask) != 0); + mask >>= 1; + } +} + +void CInArchive::ReadBoolVector2(int numItems, CBoolVector &v) +{ + Byte allAreDefined = ReadByte(); + if (allAreDefined == 0) + { + ReadBoolVector(numItems, v); + return; + } + v.Clear(); + v.Reserve(numItems); + for (int i = 0; i < numItems; i++) + v.Add(true); +} + +void CInArchive::ReadUInt64DefVector(const CObjectVector &dataVector, + CUInt64DefVector &v, int numFiles) +{ + ReadBoolVector2(numFiles, v.Defined); + + CStreamSwitch streamSwitch; + streamSwitch.Set(this, &dataVector); + v.Values.Reserve(numFiles); + + for (int i = 0; i < numFiles; i++) + { + UInt64 t = 0; + if (v.Defined[i]) + t = ReadUInt64(); + v.Values.Add(t); + } +} + +HRESULT CInArchive::ReadAndDecodePackedStreams( + DECL_EXTERNAL_CODECS_LOC_VARS + UInt64 baseOffset, + UInt64 &dataOffset, CObjectVector &dataVector + #ifndef _NO_CRYPTO + , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined + #endif + ) +{ + CRecordVector packSizes; + CBoolVector packCRCsDefined; + CRecordVector packCRCs; + CObjectVector folders; + + CRecordVector numUnpackStreamsInFolders; + CRecordVector unpackSizes; + CBoolVector digestsDefined; + CRecordVector digests; + + ReadStreamsInfo(NULL, + dataOffset, + packSizes, + packCRCsDefined, + packCRCs, + folders, + numUnpackStreamsInFolders, + unpackSizes, + digestsDefined, + digests); + + // db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader; + + CNum packIndex = 0; + CDecoder decoder( + #ifdef _ST_MODE + false + #else + true + #endif + ); + UInt64 dataStartPos = baseOffset + dataOffset; + for (int i = 0; i < folders.Size(); i++) + { + const CFolder &folder = folders[i]; + dataVector.Add(CByteBuffer()); + CByteBuffer &data = dataVector.Back(); + UInt64 unpackSize64 = folder.GetUnpackSize(); + size_t unpackSize = (size_t)unpackSize64; + if (unpackSize != unpackSize64) + ThrowUnsupported(); + data.SetCapacity(unpackSize); + + CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2; + CMyComPtr outStream = outStreamSpec; + outStreamSpec->Init(data, unpackSize); + + HRESULT result = decoder.Decode( + EXTERNAL_CODECS_LOC_VARS + _stream, dataStartPos, + &packSizes[packIndex], folder, outStream, NULL + #ifndef _NO_CRYPTO + , getTextPassword, passwordIsDefined + #endif + #ifdef COMPRESS_MT + , false, 1 + #endif + ); + RINOK(result); + + if (folder.UnpackCRCDefined) + if (CrcCalc(data, unpackSize) != folder.UnpackCRC) + ThrowIncorrect(); + for (int j = 0; j < folder.PackStreams.Size(); j++) + { + UInt64 packSize = packSizes[packIndex++]; + dataStartPos += packSize; + HeadersSize += packSize; + } + } + return S_OK; +} + +HRESULT CInArchive::ReadHeader( + DECL_EXTERNAL_CODECS_LOC_VARS + CArchiveDatabaseEx &db + #ifndef _NO_CRYPTO + , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined + #endif + ) +{ + UInt64 type = ReadID(); + + if (type == NID::kArchiveProperties) + { + ReadArchiveProperties(db.ArchiveInfo); + type = ReadID(); + } + + CObjectVector dataVector; + + if (type == NID::kAdditionalStreamsInfo) + { + HRESULT result = ReadAndDecodePackedStreams( + EXTERNAL_CODECS_LOC_VARS + db.ArchiveInfo.StartPositionAfterHeader, + db.ArchiveInfo.DataStartPosition2, + dataVector + #ifndef _NO_CRYPTO + , getTextPassword, passwordIsDefined + #endif + ); + RINOK(result); + db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader; + type = ReadID(); + } + + CRecordVector unpackSizes; + CBoolVector digestsDefined; + CRecordVector digests; + + if (type == NID::kMainStreamsInfo) + { + ReadStreamsInfo(&dataVector, + db.ArchiveInfo.DataStartPosition, + db.PackSizes, + db.PackCRCsDefined, + db.PackCRCs, + db.Folders, + db.NumUnpackStreamsVector, + unpackSizes, + digestsDefined, + digests); + db.ArchiveInfo.DataStartPosition += db.ArchiveInfo.StartPositionAfterHeader; + type = ReadID(); + } + else + { + for (int i = 0; i < db.Folders.Size(); i++) + { + db.NumUnpackStreamsVector.Add(1); + CFolder &folder = db.Folders[i]; + unpackSizes.Add(folder.GetUnpackSize()); + digestsDefined.Add(folder.UnpackCRCDefined); + digests.Add(folder.UnpackCRC); + } + } + + db.Files.Clear(); + + if (type == NID::kEnd) + return S_OK; + if (type != NID::kFilesInfo) + ThrowIncorrect(); + + CNum numFiles = ReadNum(); + db.Files.Reserve(numFiles); + CNum i; + for (i = 0; i < numFiles; i++) + db.Files.Add(CFileItem()); + + db.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize); + if (!db.PackSizes.IsEmpty()) + db.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo); + if (numFiles > 0 && !digests.IsEmpty()) + db.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC); + + CBoolVector emptyStreamVector; + BoolVector_Fill_False(emptyStreamVector, (int)numFiles); + CBoolVector emptyFileVector; + CBoolVector antiFileVector; + CNum numEmptyStreams = 0; + + for (;;) + { + UInt64 type = ReadID(); + if (type == NID::kEnd) + break; + UInt64 size = ReadNumber(); + size_t ppp = _inByteBack->_pos; + bool addPropIdToList = true; + bool isKnownType = true; + if (type > ((UInt32)1 << 30)) + isKnownType = false; + else switch((UInt32)type) + { + case NID::kName: + { + CStreamSwitch streamSwitch; + streamSwitch.Set(this, &dataVector); + for (int i = 0; i < db.Files.Size(); i++) + _inByteBack->ReadString(db.Files[i].Name); + break; + } + case NID::kWinAttributes: + { + CBoolVector boolVector; + ReadBoolVector2(db.Files.Size(), boolVector); + CStreamSwitch streamSwitch; + streamSwitch.Set(this, &dataVector); + for (i = 0; i < numFiles; i++) + { + CFileItem &file = db.Files[i]; + file.AttribDefined = boolVector[i]; + if (file.AttribDefined) + file.Attrib = ReadUInt32(); + } + break; + } + case NID::kEmptyStream: + { + ReadBoolVector(numFiles, emptyStreamVector); + for (i = 0; i < (CNum)emptyStreamVector.Size(); i++) + if (emptyStreamVector[i]) + numEmptyStreams++; + + BoolVector_Fill_False(emptyFileVector, numEmptyStreams); + BoolVector_Fill_False(antiFileVector, numEmptyStreams); + + break; + } + case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break; + case NID::kAnti: ReadBoolVector(numEmptyStreams, antiFileVector); break; + case NID::kStartPos: ReadUInt64DefVector(dataVector, db.StartPos, (int)numFiles); break; + case NID::kCTime: ReadUInt64DefVector(dataVector, db.CTime, (int)numFiles); break; + case NID::kATime: ReadUInt64DefVector(dataVector, db.ATime, (int)numFiles); break; + case NID::kMTime: ReadUInt64DefVector(dataVector, db.MTime, (int)numFiles); break; + case NID::kDummy: + { + for (UInt64 j = 0; j < size; j++) + if (ReadByte() != 0) + ThrowIncorrect(); + addPropIdToList = false; + break; + } + default: + addPropIdToList = isKnownType = false; + } + if (isKnownType) + { + if(addPropIdToList) + db.ArchiveInfo.FileInfoPopIDs.Add(type); + } + else + SkeepData(size); + bool checkRecordsSize = (db.ArchiveInfo.Version.Major > 0 || + db.ArchiveInfo.Version.Minor > 2); + if (checkRecordsSize && _inByteBack->_pos - ppp != size) + ThrowIncorrect(); + } + + CNum emptyFileIndex = 0; + CNum sizeIndex = 0; + + CNum numAntiItems = 0; + for (i = 0; i < numEmptyStreams; i++) + if (antiFileVector[i]) + numAntiItems++; + + for (i = 0; i < numFiles; i++) + { + CFileItem &file = db.Files[i]; + bool isAnti; + file.HasStream = !emptyStreamVector[i]; + if (file.HasStream) + { + file.IsDir = false; + isAnti = false; + file.Size = unpackSizes[sizeIndex]; + file.Crc = digests[sizeIndex]; + file.CrcDefined = digestsDefined[sizeIndex]; + sizeIndex++; + } + else + { + file.IsDir = !emptyFileVector[emptyFileIndex]; + isAnti = antiFileVector[emptyFileIndex]; + emptyFileIndex++; + file.Size = 0; + file.CrcDefined = false; + } + if (numAntiItems != 0) + db.IsAnti.Add(isAnti); + } + return S_OK; +} + + +void CArchiveDatabaseEx::FillFolderStartPackStream() +{ + FolderStartPackStreamIndex.Clear(); + FolderStartPackStreamIndex.Reserve(Folders.Size()); + CNum startPos = 0; + for (int i = 0; i < Folders.Size(); i++) + { + FolderStartPackStreamIndex.Add(startPos); + startPos += (CNum)Folders[i].PackStreams.Size(); + } +} + +void CArchiveDatabaseEx::FillStartPos() +{ + PackStreamStartPositions.Clear(); + PackStreamStartPositions.Reserve(PackSizes.Size()); + UInt64 startPos = 0; + for (int i = 0; i < PackSizes.Size(); i++) + { + PackStreamStartPositions.Add(startPos); + startPos += PackSizes[i]; + } +} + +void CArchiveDatabaseEx::FillFolderStartFileIndex() +{ + FolderStartFileIndex.Clear(); + FolderStartFileIndex.Reserve(Folders.Size()); + FileIndexToFolderIndexMap.Clear(); + FileIndexToFolderIndexMap.Reserve(Files.Size()); + + int folderIndex = 0; + CNum indexInFolder = 0; + for (int i = 0; i < Files.Size(); i++) + { + const CFileItem &file = Files[i]; + bool emptyStream = !file.HasStream; + if (emptyStream && indexInFolder == 0) + { + FileIndexToFolderIndexMap.Add(kNumNoIndex); + continue; + } + if (indexInFolder == 0) + { + // v3.13 incorrectly worked with empty folders + // v4.07: Loop for skipping empty folders + for (;;) + { + if (folderIndex >= Folders.Size()) + ThrowIncorrect(); + FolderStartFileIndex.Add(i); // check it + if (NumUnpackStreamsVector[folderIndex] != 0) + break; + folderIndex++; + } + } + FileIndexToFolderIndexMap.Add(folderIndex); + if (emptyStream) + continue; + indexInFolder++; + if (indexInFolder >= NumUnpackStreamsVector[folderIndex]) + { + folderIndex++; + indexInFolder = 0; + } + } +} + +HRESULT CInArchive::ReadDatabase2( + DECL_EXTERNAL_CODECS_LOC_VARS + CArchiveDatabaseEx &db + #ifndef _NO_CRYPTO + , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined + #endif + ) +{ + db.Clear(); + db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition; + + db.ArchiveInfo.Version.Major = _header[6]; + db.ArchiveInfo.Version.Minor = _header[7]; + + if (db.ArchiveInfo.Version.Major != kMajorVersion) + ThrowUnsupportedVersion(); + + UInt32 crcFromArchive = Get32(_header + 8); + UInt64 nextHeaderOffset = Get64(_header + 0xC); + UInt64 nextHeaderSize = Get64(_header + 0x14); + UInt32 nextHeaderCRC = Get32(_header + 0x1C); + UInt32 crc = CrcCalc(_header + 0xC, 20); + + #ifdef FORMAT_7Z_RECOVERY + if (crcFromArchive == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0) + { + UInt64 cur, cur2; + RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &cur)); + const int kCheckSize = 500; + Byte buf[kCheckSize]; + RINOK(_stream->Seek(0, STREAM_SEEK_END, &cur2)); + int checkSize = kCheckSize; + if (cur2 - cur < kCheckSize) + checkSize = (int)(cur2 - cur); + RINOK(_stream->Seek(-checkSize, STREAM_SEEK_END, &cur2)); + + RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize)); + + int i; + for (i = (int)checkSize - 2; i >= 0; i--) + if (buf[i] == 0x17 && buf[i + 1] == 0x6 || buf[i] == 0x01 && buf[i + 1] == 0x04) + break; + if (i < 0) + return S_FALSE; + nextHeaderSize = checkSize - i; + nextHeaderOffset = cur2 - cur + i; + nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize); + RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL)); + } + #endif + + #ifdef FORMAT_7Z_RECOVERY + crcFromArchive = crc; + #endif + + db.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize; + + if (crc != crcFromArchive) + ThrowIncorrect(); + + if (nextHeaderSize == 0) + return S_OK; + + if (nextHeaderSize > (UInt64)0xFFFFFFFF) + return S_FALSE; + + RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL)); + + CByteBuffer buffer2; + buffer2.SetCapacity((size_t)nextHeaderSize); + + RINOK(ReadStream_FALSE(_stream, buffer2, (size_t)nextHeaderSize)); + HeadersSize += kHeaderSize + nextHeaderSize; + db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize; + + if (CrcCalc(buffer2, (UInt32)nextHeaderSize) != nextHeaderCRC) + ThrowIncorrect(); + + CStreamSwitch streamSwitch; + streamSwitch.Set(this, buffer2); + + CObjectVector dataVector; + + UInt64 type = ReadID(); + if (type != NID::kHeader) + { + if (type != NID::kEncodedHeader) + ThrowIncorrect(); + HRESULT result = ReadAndDecodePackedStreams( + EXTERNAL_CODECS_LOC_VARS + db.ArchiveInfo.StartPositionAfterHeader, + db.ArchiveInfo.DataStartPosition2, + dataVector + #ifndef _NO_CRYPTO + , getTextPassword, passwordIsDefined + #endif + ); + RINOK(result); + if (dataVector.Size() == 0) + return S_OK; + if (dataVector.Size() > 1) + ThrowIncorrect(); + streamSwitch.Remove(); + streamSwitch.Set(this, dataVector.Front()); + if (ReadID() != NID::kHeader) + ThrowIncorrect(); + } + + db.HeadersSize = HeadersSize; + + return ReadHeader( + EXTERNAL_CODECS_LOC_VARS + db + #ifndef _NO_CRYPTO + , getTextPassword, passwordIsDefined + #endif + ); +} + +HRESULT CInArchive::ReadDatabase( + DECL_EXTERNAL_CODECS_LOC_VARS + CArchiveDatabaseEx &db + #ifndef _NO_CRYPTO + , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined + #endif + ) +{ + try + { + return ReadDatabase2( + EXTERNAL_CODECS_LOC_VARS db + #ifndef _NO_CRYPTO + , getTextPassword, passwordIsDefined + #endif + ); + } + catch(CInArchiveException &) { return S_FALSE; } +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zIn.h b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zIn.h new file mode 100644 index 000000000..bfec78564 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zIn.h @@ -0,0 +1,245 @@ +// 7zIn.h + +#ifndef __7Z_IN_H +#define __7Z_IN_H + +#include "../../../Common/MyCom.h" + +#include "../../IPassword.h" +#include "../../IStream.h" + +#include "../../Common/CreateCoder.h" +#include "../../Common/InBuffer.h" + +#include "7zItem.h" + +namespace NArchive { +namespace N7z { + +struct CInArchiveInfo +{ + CArchiveVersion Version; + UInt64 StartPosition; + UInt64 StartPositionAfterHeader; + UInt64 DataStartPosition; + UInt64 DataStartPosition2; + CRecordVector FileInfoPopIDs; + void Clear() + { + FileInfoPopIDs.Clear(); + } +}; + +struct CArchiveDatabaseEx: public CArchiveDatabase +{ + CInArchiveInfo ArchiveInfo; + CRecordVector PackStreamStartPositions; + CRecordVector FolderStartPackStreamIndex; + CRecordVector FolderStartFileIndex; + CRecordVector FileIndexToFolderIndexMap; + + UInt64 HeadersSize; + UInt64 PhySize; + + void Clear() + { + CArchiveDatabase::Clear(); + ArchiveInfo.Clear(); + PackStreamStartPositions.Clear(); + FolderStartPackStreamIndex.Clear(); + FolderStartFileIndex.Clear(); + FileIndexToFolderIndexMap.Clear(); + + HeadersSize = 0; + PhySize = 0; + } + + void FillFolderStartPackStream(); + void FillStartPos(); + void FillFolderStartFileIndex(); + + void Fill() + { + FillFolderStartPackStream(); + FillStartPos(); + FillFolderStartFileIndex(); + } + + UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const + { + return ArchiveInfo.DataStartPosition + + PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + indexInFolder]; + } + + UInt64 GetFolderFullPackSize(int folderIndex) const + { + CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex]; + const CFolder &folder = Folders[folderIndex]; + UInt64 size = 0; + for (int i = 0; i < folder.PackStreams.Size(); i++) + size += PackSizes[packStreamIndex + i]; + return size; + } + + UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const + { + return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; + } + + UInt64 GetFilePackSize(CNum fileIndex) const + { + CNum folderIndex = FileIndexToFolderIndexMap[fileIndex]; + if (folderIndex != kNumNoIndex) + if (FolderStartFileIndex[folderIndex] == fileIndex) + return GetFolderFullPackSize(folderIndex); + return 0; + } +}; + +class CInByte2 +{ + const Byte *_buffer; + size_t _size; +public: + size_t _pos; + void Init(const Byte *buffer, size_t size) + { + _buffer = buffer; + _size = size; + _pos = 0; + } + Byte ReadByte(); + void ReadBytes(Byte *data, size_t size); + void SkeepData(UInt64 size); + void SkeepData(); + UInt64 ReadNumber(); + CNum ReadNum(); + UInt32 ReadUInt32(); + UInt64 ReadUInt64(); + void ReadString(UString &s); +}; + +class CStreamSwitch; + +const UInt32 kHeaderSize = 32; + +class CInArchive +{ + friend class CStreamSwitch; + + CMyComPtr _stream; + + CObjectVector _inByteVector; + CInByte2 *_inByteBack; + + UInt64 _arhiveBeginStreamPosition; + + Byte _header[kHeaderSize]; + + UInt64 HeadersSize; + + void AddByteStream(const Byte *buffer, size_t size) + { + _inByteVector.Add(CInByte2()); + _inByteBack = &_inByteVector.Back(); + _inByteBack->Init(buffer, size); + } + + void DeleteByteStream() + { + _inByteVector.DeleteBack(); + if (!_inByteVector.IsEmpty()) + _inByteBack = &_inByteVector.Back(); + } + +private: + HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); + + void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); } + Byte ReadByte() { return _inByteBack->ReadByte(); } + UInt64 ReadNumber() { return _inByteBack->ReadNumber(); } + CNum ReadNum() { return _inByteBack->ReadNum(); } + UInt64 ReadID() { return _inByteBack->ReadNumber(); } + UInt32 ReadUInt32() { return _inByteBack->ReadUInt32(); } + UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); } + void SkeepData(UInt64 size) { _inByteBack->SkeepData(size); } + void SkeepData() { _inByteBack->SkeepData(); } + void WaitAttribute(UInt64 attribute); + + void ReadArchiveProperties(CInArchiveInfo &archiveInfo); + void GetNextFolderItem(CFolder &itemInfo); + void ReadHashDigests(int numItems, + CBoolVector &digestsDefined, CRecordVector &digests); + + void ReadPackInfo( + UInt64 &dataOffset, + CRecordVector &packSizes, + CBoolVector &packCRCsDefined, + CRecordVector &packCRCs); + + void ReadUnpackInfo( + const CObjectVector *dataVector, + CObjectVector &folders); + + void ReadSubStreamsInfo( + const CObjectVector &folders, + CRecordVector &numUnpackStreamsInFolders, + CRecordVector &unpackSizes, + CBoolVector &digestsDefined, + CRecordVector &digests); + + void ReadStreamsInfo( + const CObjectVector *dataVector, + UInt64 &dataOffset, + CRecordVector &packSizes, + CBoolVector &packCRCsDefined, + CRecordVector &packCRCs, + CObjectVector &folders, + CRecordVector &numUnpackStreamsInFolders, + CRecordVector &unpackSizes, + CBoolVector &digestsDefined, + CRecordVector &digests); + + + void ReadBoolVector(int numItems, CBoolVector &v); + void ReadBoolVector2(int numItems, CBoolVector &v); + void ReadUInt64DefVector(const CObjectVector &dataVector, + CUInt64DefVector &v, int numFiles); + HRESULT ReadAndDecodePackedStreams( + DECL_EXTERNAL_CODECS_LOC_VARS + UInt64 baseOffset, UInt64 &dataOffset, + CObjectVector &dataVector + #ifndef _NO_CRYPTO + , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined + #endif + ); + HRESULT ReadHeader( + DECL_EXTERNAL_CODECS_LOC_VARS + CArchiveDatabaseEx &db + #ifndef _NO_CRYPTO + ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined + #endif + ); + HRESULT ReadDatabase2( + DECL_EXTERNAL_CODECS_LOC_VARS + CArchiveDatabaseEx &db + #ifndef _NO_CRYPTO + ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined + #endif + ); +public: + HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive + void Close(); + + HRESULT ReadDatabase( + DECL_EXTERNAL_CODECS_LOC_VARS + CArchiveDatabaseEx &db + #ifndef _NO_CRYPTO + ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined + #endif + ); +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zItem.h b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zItem.h new file mode 100644 index 000000000..6cc9ccc55 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zItem.h @@ -0,0 +1,258 @@ +// 7zItem.h + +#ifndef __7Z_ITEM_H +#define __7Z_ITEM_H + +#include "../../../Common/Buffer.h" +#include "../../../Common/MyString.h" + +#include "../../Common/MethodId.h" + +#include "7zHeader.h" + +namespace NArchive { +namespace N7z { + +typedef UInt32 CNum; +const CNum kNumMax = 0x7FFFFFFF; +const CNum kNumNoIndex = 0xFFFFFFFF; + +struct CCoderInfo +{ + CMethodId MethodID; + CByteBuffer Props; + CNum NumInStreams; + CNum NumOutStreams; + bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); } +}; + +struct CBindPair +{ + CNum InIndex; + CNum OutIndex; +}; + +struct CFolder +{ + CObjectVector Coders; + CRecordVector BindPairs; + CRecordVector PackStreams; + CRecordVector UnpackSizes; + UInt32 UnpackCRC; + bool UnpackCRCDefined; + + CFolder(): UnpackCRCDefined(false) {} + + UInt64 GetUnpackSize() const // test it + { + if (UnpackSizes.IsEmpty()) + return 0; + for (int i = UnpackSizes.Size() - 1; i >= 0; i--) + if (FindBindPairForOutStream(i) < 0) + return UnpackSizes[i]; + throw 1; + } + + CNum GetNumOutStreams() const + { + CNum result = 0; + for (int i = 0; i < Coders.Size(); i++) + result += Coders[i].NumOutStreams; + return result; + } + + int FindBindPairForInStream(CNum inStreamIndex) const + { + for(int i = 0; i < BindPairs.Size(); i++) + if (BindPairs[i].InIndex == inStreamIndex) + return i; + return -1; + } + int FindBindPairForOutStream(CNum outStreamIndex) const + { + for(int i = 0; i < BindPairs.Size(); i++) + if (BindPairs[i].OutIndex == outStreamIndex) + return i; + return -1; + } + int FindPackStreamArrayIndex(CNum inStreamIndex) const + { + for(int i = 0; i < PackStreams.Size(); i++) + if (PackStreams[i] == inStreamIndex) + return i; + return -1; + } + + bool CheckStructure() const; +}; + +struct CUInt64DefVector +{ + CRecordVector Values; + CRecordVector Defined; + + void Clear() + { + Values.Clear(); + Defined.Clear(); + } + + void ReserveDown() + { + Values.ReserveDown(); + Values.ReserveDown(); + } + + bool GetItem(int index, UInt64 &value) const + { + if (index < Defined.Size() && Defined[index]) + { + value = Values[index]; + return true; + } + value = 0; + return false; + } + + void SetItem(int index, bool defined, UInt64 value) + { + while (index >= Defined.Size()) + Defined.Add(false); + Defined[index] = defined; + if (!defined) + return; + while (index >= Values.Size()) + Values.Add(0); + Values[index] = value; + } + + bool CheckSize(int size) const { return Defined.Size() == size || Defined.Size() == 0; } +}; + +struct CFileItem +{ + UInt64 Size; + UInt32 Attrib; + UInt32 Crc; + UString Name; + + bool HasStream; // Test it !!! it means that there is + // stream in some folder. It can be empty stream + bool IsDir; + bool CrcDefined; + bool AttribDefined; + + CFileItem(): + HasStream(true), + IsDir(false), + CrcDefined(false), + AttribDefined(false) + {} + void SetAttrib(UInt32 attrib) + { + AttribDefined = true; + Attrib = attrib; + } +}; + +struct CFileItem2 +{ + UInt64 CTime; + UInt64 ATime; + UInt64 MTime; + UInt64 StartPos; + bool CTimeDefined; + bool ATimeDefined; + bool MTimeDefined; + bool StartPosDefined; + bool IsAnti; +}; + +struct CArchiveDatabase +{ + CRecordVector PackSizes; + CRecordVector PackCRCsDefined; + CRecordVector PackCRCs; + CObjectVector Folders; + CRecordVector NumUnpackStreamsVector; + CObjectVector Files; + + CUInt64DefVector CTime; + CUInt64DefVector ATime; + CUInt64DefVector MTime; + CUInt64DefVector StartPos; + CRecordVector IsAnti; + + void Clear() + { + PackSizes.Clear(); + PackCRCsDefined.Clear(); + PackCRCs.Clear(); + Folders.Clear(); + NumUnpackStreamsVector.Clear(); + Files.Clear(); + CTime.Clear(); + ATime.Clear(); + MTime.Clear(); + StartPos.Clear(); + IsAnti.Clear(); + } + + void ReserveDown() + { + PackSizes.ReserveDown(); + PackCRCsDefined.ReserveDown(); + PackCRCs.ReserveDown(); + Folders.ReserveDown(); + NumUnpackStreamsVector.ReserveDown(); + Files.ReserveDown(); + CTime.ReserveDown(); + ATime.ReserveDown(); + MTime.ReserveDown(); + StartPos.ReserveDown(); + IsAnti.ReserveDown(); + } + + bool IsEmpty() const + { + return (PackSizes.IsEmpty() && + PackCRCsDefined.IsEmpty() && + PackCRCs.IsEmpty() && + Folders.IsEmpty() && + NumUnpackStreamsVector.IsEmpty() && + Files.IsEmpty()); + } + + bool CheckNumFiles() const + { + int size = Files.Size(); + return ( + CTime.CheckSize(size) && + ATime.CheckSize(size) && + MTime.CheckSize(size) && + StartPos.CheckSize(size) && + (size == IsAnti.Size() || IsAnti.Size() == 0)); + } + + bool IsSolid() const + { + for (int i = 0; i < NumUnpackStreamsVector.Size(); i++) + if (NumUnpackStreamsVector[i] > 1) + return true; + return false; + } + bool IsItemAnti(int index) const { return (index < IsAnti.Size() && IsAnti[index]); } + void SetItemAnti(int index, bool isAnti) + { + while (index >= IsAnti.Size()) + IsAnti.Add(false); + IsAnti[index] = isAnti; + } + + void GetFile(int index, CFileItem &file, CFileItem2 &file2) const; + void AddFile(const CFileItem &file, const CFileItem2 &file2); +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zProperties.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zProperties.cpp new file mode 100644 index 000000000..f5ac3b9bf --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zProperties.cpp @@ -0,0 +1,163 @@ +// 7zProperties.cpp + +#include "StdAfx.h" + +#include "7zProperties.h" +#include "7zHeader.h" +#include "7zHandler.h" + +// #define _MULTI_PACK + +namespace NArchive { +namespace N7z { + +struct CPropMap +{ + UInt64 FilePropID; + STATPROPSTG StatPROPSTG; +}; + +CPropMap kPropMap[] = +{ + { NID::kName, NULL, kpidPath, VT_BSTR}, + { NID::kSize, NULL, kpidSize, VT_UI8}, + { NID::kPackInfo, NULL, kpidPackSize, VT_UI8}, + + #ifdef _MULTI_PACK + { 100, L"Pack0", kpidPackedSize0, VT_UI8}, + { 101, L"Pack1", kpidPackedSize1, VT_UI8}, + { 102, L"Pack2", kpidPackedSize2, VT_UI8}, + { 103, L"Pack3", kpidPackedSize3, VT_UI8}, + { 104, L"Pack4", kpidPackedSize4, VT_UI8}, + #endif + + { NID::kCTime, NULL, kpidCTime, VT_FILETIME}, + { NID::kMTime, NULL, kpidMTime, VT_FILETIME}, + { NID::kATime, NULL, kpidATime, VT_FILETIME}, + { NID::kWinAttributes, NULL, kpidAttrib, VT_UI4}, + { NID::kStartPos, NULL, kpidPosition, VT_UI4}, + + { NID::kCRC, NULL, kpidCRC, VT_UI4}, + + { NID::kAnti, NULL, kpidIsAnti, VT_BOOL}, + + #ifndef _SFX + { 97, NULL, kpidEncrypted, VT_BOOL}, + { 98, NULL, kpidMethod, VT_BSTR}, + { 99, NULL, kpidBlock, VT_UI4} + #endif +}; + +static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]); + +static int FindPropInMap(UInt64 filePropID) +{ + for (int i = 0; i < kPropMapSize; i++) + if (kPropMap[i].FilePropID == filePropID) + return i; + return -1; +} + +static void CopyOneItem(CRecordVector &src, + CRecordVector &dest, UInt32 item) +{ + for (int i = 0; i < src.Size(); i++) + if (src[i] == item) + { + dest.Add(item); + src.Delete(i); + return; + } +} + +static void RemoveOneItem(CRecordVector &src, UInt32 item) +{ + for (int i = 0; i < src.Size(); i++) + if (src[i] == item) + { + src.Delete(i); + return; + } +} + +static void InsertToHead(CRecordVector &dest, UInt32 item) +{ + for (int i = 0; i < dest.Size(); i++) + if (dest[i] == item) + { + dest.Delete(i); + break; + } + dest.Insert(0, item); +} + +void CHandler::FillPopIDs() +{ + _fileInfoPopIDs.Clear(); + + #ifdef _7Z_VOL + if(_volumes.Size() < 1) + return; + const CVolume &volume = _volumes.Front(); + const CArchiveDatabaseEx &_db = volume.Database; + #endif + + CRecordVector fileInfoPopIDs = _db.ArchiveInfo.FileInfoPopIDs; + + RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream); + RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile); + + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kName); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCTime); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kMTime); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kATime); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment); + _fileInfoPopIDs += fileInfoPopIDs; + + #ifndef _SFX + _fileInfoPopIDs.Add(97); + _fileInfoPopIDs.Add(98); + _fileInfoPopIDs.Add(99); + #endif + #ifdef _MULTI_PACK + _fileInfoPopIDs.Add(100); + _fileInfoPopIDs.Add(101); + _fileInfoPopIDs.Add(102); + _fileInfoPopIDs.Add(103); + _fileInfoPopIDs.Add(104); + #endif + + #ifndef _SFX + InsertToHead(_fileInfoPopIDs, NID::kMTime); + InsertToHead(_fileInfoPopIDs, NID::kPackInfo); + InsertToHead(_fileInfoPopIDs, NID::kSize); + InsertToHead(_fileInfoPopIDs, NID::kName); + #endif +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = _fileInfoPopIDs.Size(); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if ((int)index >= _fileInfoPopIDs.Size()) + return E_INVALIDARG; + int indexInMap = FindPropInMap(_fileInfoPopIDs[index]); + if (indexInMap == -1) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kPropMap[indexInMap].StatPROPSTG; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zProperties.h b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zProperties.h new file mode 100644 index 000000000..7b78130ef --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zProperties.h @@ -0,0 +1,22 @@ +// 7zProperties.h + +#ifndef __7Z_PROPERTIES_H +#define __7Z_PROPERTIES_H + +#include "../../PropID.h" + +namespace NArchive { +namespace N7z { + +enum +{ + kpidPackedSize0 = kpidUserDefined, + kpidPackedSize1, + kpidPackedSize2, + kpidPackedSize3, + kpidPackedSize4 +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zRegister.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zRegister.cpp new file mode 100644 index 000000000..4450498f0 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zRegister.cpp @@ -0,0 +1,18 @@ +// 7zRegister.cpp + +#include "StdAfx.h" + +#include "../../Common/RegisterArc.h" + +#include "7zHandler.h" +static IInArchive *CreateArc() { return new NArchive::N7z::CHandler; } +#ifndef EXTRACT_ONLY +static IOutArchive *CreateArcOut() { return new NArchive::N7z::CHandler; } +#else +#define CreateArcOut 0 +#endif + +static CArcInfo g_ArcInfo = + { L"7z", L"7z", 0, 7, {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}, 6, false, CreateArc, CreateArcOut }; + +REGISTER_ARC(7z) diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zSpecStream.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zSpecStream.cpp new file mode 100644 index 000000000..58f2ec459 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zSpecStream.cpp @@ -0,0 +1,24 @@ +// 7zSpecStream.cpp + +#include "StdAfx.h" + +#include "7zSpecStream.h" + +STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result = _stream->Read(data, size, &realProcessedSize); + _size += realProcessedSize; + if (processedSize != 0) + *processedSize = realProcessedSize; + return result; +} + +STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize( + UInt64 subStream, UInt64 *value) +{ + if (_getSubStreamSize == NULL) + return E_NOTIMPL; + return _getSubStreamSize->GetSubStreamSize(subStream, value); +} + diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zSpecStream.h b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zSpecStream.h new file mode 100644 index 000000000..0058ac27c --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/7zSpecStream.h @@ -0,0 +1,35 @@ +// 7zSpecStream.h + +#ifndef __7Z_SPEC_STREAM_H +#define __7Z_SPEC_STREAM_H + +#include "../../IStream.h" +#include "../../ICoder.h" +#include "../../../Common/MyCom.h" + +class CSequentialInStreamSizeCount2: + public ISequentialInStream, + public ICompressGetSubStreamSize, + public CMyUnknownImp +{ + CMyComPtr _stream; + CMyComPtr _getSubStreamSize; + UInt64 _size; +public: + void Init(ISequentialInStream *stream) + { + _stream = stream; + _getSubStreamSize = 0; + _stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize); + _size = 0; + } + UInt64 GetSize() const { return _size; } + + MY_UNKNOWN_IMP1(ICompressGetSubStreamSize) + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + + STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value); +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/7z/StdAfx.h b/desmume/src/windows/7z/CPP/7zip/Archive/7z/StdAfx.h new file mode 100644 index 000000000..a4e617312 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/7z/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/ArchiveExports.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/ArchiveExports.cpp new file mode 100644 index 000000000..054f1b081 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/ArchiveExports.cpp @@ -0,0 +1,130 @@ +// ArchiveExports.cpp + +#include "StdAfx.h" + +#include "../../Common/ComTry.h" +#include "../../Common/Types.h" +#include "../../Windows/PropVariant.h" +#include "../Common/RegisterArc.h" + +#include "IArchive.h" +#include "../ICoder.h" +#include "../IPassword.h" + +static const unsigned int kNumArcsMax = 32; +static unsigned int g_NumArcs = 0; +static const CArcInfo *g_Arcs[kNumArcsMax]; +void RegisterArc(const CArcInfo *arcInfo) +{ + if (g_NumArcs < kNumArcsMax) + g_Arcs[g_NumArcs++] = arcInfo; +} + +DEFINE_GUID(CLSID_CArchiveHandler, +0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00); + +#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5]) + +static inline HRESULT SetPropString(const char *s, unsigned int size, PROPVARIANT *value) +{ + if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0) + value->vt = VT_BSTR; + return S_OK; +} + +static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value) +{ + return SetPropString((const char *)&guid, sizeof(GUID), value); +} + +int FindFormatCalssId(const GUID *clsID) +{ + GUID cls = *clsID; + CLS_ARC_ID_ITEM(cls) = 0; + if (cls != CLSID_CArchiveHandler) + return -1; + Byte id = CLS_ARC_ID_ITEM(*clsID); + for (unsigned i = 0; i < g_NumArcs; i++) + if (g_Arcs[i]->ClassId == id) + return (int)i; + return -1; +} + +STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject) +{ + COM_TRY_BEGIN + { + int needIn = (*iid == IID_IInArchive); + int needOut = (*iid == IID_IOutArchive); + if (!needIn && !needOut) + return E_NOINTERFACE; + int formatIndex = FindFormatCalssId(clsid); + if (formatIndex < 0) + return CLASS_E_CLASSNOTAVAILABLE; + + const CArcInfo &arc = *g_Arcs[formatIndex]; + if (needIn) + { + *outObject = arc.CreateInArchive(); + ((IInArchive *)*outObject)->AddRef(); + } + else + { + if (!arc.CreateOutArchive) + return CLASS_E_CLASSNOTAVAILABLE; + *outObject = arc.CreateOutArchive(); + ((IOutArchive *)*outObject)->AddRef(); + } + } + COM_TRY_END + return S_OK; +} + +STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value) +{ + if (formatIndex >= g_NumArcs) + return E_INVALIDARG; + const CArcInfo &arc = *g_Arcs[formatIndex]; + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case NArchive::kName: + prop = arc.Name; + break; + case NArchive::kClassID: + { + GUID clsId = CLSID_CArchiveHandler; + CLS_ARC_ID_ITEM(clsId) = arc.ClassId; + return SetPropGUID(clsId, value); + } + case NArchive::kExtension: + if (arc.Ext != 0) + prop = arc.Ext; + break; + case NArchive::kAddExtension: + if (arc.AddExt != 0) + prop = arc.AddExt; + break; + case NArchive::kUpdate: + prop = (bool)(arc.CreateOutArchive != 0); + break; + case NArchive::kKeepName: + prop = arc.KeepName; + break; + case NArchive::kStartSignature: + return SetPropString((const char *)arc.Signature, arc.SignatureSize, value); + } + prop.Detach(value); + return S_OK; +} + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + return GetHandlerProperty2(0, propID, value); +} + +STDAPI GetNumberOfFormats(UINT32 *numFormats) +{ + *numFormats = g_NumArcs; + return S_OK; +} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/BZip2/BZip2Handler.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/BZip2/BZip2Handler.cpp new file mode 100644 index 000000000..a797b6ddd --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/BZip2/BZip2Handler.cpp @@ -0,0 +1,216 @@ +// BZip2Handler.cpp + +#include "StdAfx.h" + +#include "Common/ComTry.h" + +#include "Windows/PropVariant.h" + +#include "../../Common/CreateCoder.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamUtils.h" + +#include "../Common/DummyOutStream.h" + +#include "BZip2Handler.h" + +using namespace NWindows; + +namespace NArchive { +namespace NBZip2 { + +static const CMethodId kMethodId_BZip2 = 0x040202; + +STATPROPSTG kProps[] = +{ + { NULL, kpidPackSize, VT_UI8} +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = 1; + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidPackSize: prop = _item.PackSize; break; + } + prop.Detach(value); + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */) +{ + COM_TRY_BEGIN + try + { + RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition)); + const int kSignatureSize = 3; + Byte buffer[kSignatureSize]; + RINOK(ReadStream_FALSE(stream, buffer, kSignatureSize)); + if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h') + return S_FALSE; + + UInt64 endPosition; + RINOK(stream->Seek(0, STREAM_SEEK_END, &endPosition)); + _item.PackSize = endPosition - _streamStartPosition; + + _stream = stream; + } + catch(...) + { + return S_FALSE; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _stream.Release(); + return S_OK; +} + + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool allFilesMode = (numItems == UInt32(-1)); + if (!allFilesMode) + { + if (numItems == 0) + return S_OK; + if (numItems != 1) + return E_INVALIDARG; + if (indices[0] != 0) + return E_INVALIDARG; + } + + bool testMode = (testModeSpec != 0); + + extractCallback->SetTotal(_item.PackSize); + + UInt64 currentTotalPacked = 0; + + RINOK(extractCallback->SetCompleted(¤tTotalPacked)); + + CMyComPtr realOutStream; + Int32 askMode; + askMode = testMode ? NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); + + if(!testMode && !realOutStream) + return S_OK; + + + extractCallback->PrepareOperation(askMode); + + CMyComPtr decoder; + HRESULT loadResult = CreateCoder( + EXTERNAL_CODECS_VARS + kMethodId_BZip2, decoder, false); + if (loadResult != S_OK || !decoder) + { + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod)); + return S_OK; + } + + #ifdef COMPRESS_MT + { + CMyComPtr setCoderMt; + decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); + if (setCoderMt) + { + RINOK(setCoderMt->SetNumberOfThreads(_numThreads)); + } + } + #endif + + CDummyOutStream *outStreamSpec = new CDummyOutStream; + CMyComPtr outStream(outStreamSpec); + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(); + + realOutStream.Release(); + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, true); + + RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL)); + + HRESULT result = S_OK; + + bool firstItem = true; + for (;;) + { + lps->InSize = currentTotalPacked; + lps->OutSize = outStreamSpec->GetSize(); + + RINOK(lps->SetCur()); + + const int kSignatureSize = 3; + Byte buffer[kSignatureSize]; + size_t processedSize = kSignatureSize; + RINOK(ReadStream(_stream, buffer, &processedSize)); + if (processedSize != kSignatureSize) + { + if (firstItem) + return E_FAIL; + break; + } + if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h') + { + if (firstItem) + return E_FAIL; + break; + } + firstItem = false; + + UInt64 dataStartPos; + RINOK(_stream->Seek((UInt64)(Int64)(-3), STREAM_SEEK_CUR, &dataStartPos)); + + result = decoder->Code(_stream, outStream, NULL, NULL, progress); + + if (result != S_OK) + break; + + CMyComPtr getInStreamProcessedSize; + decoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, &getInStreamProcessedSize); + if (!getInStreamProcessedSize) + break; + UInt64 packSize; + RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&packSize)); + UInt64 pos; + RINOK(_stream->Seek(dataStartPos + packSize, STREAM_SEEK_SET, &pos)); + currentTotalPacked = pos - _streamStartPosition; + } + outStream.Release(); + + Int32 retResult; + if (result == S_OK) + retResult = NExtract::NOperationResult::kOK; + else if (result == S_FALSE) + retResult = NExtract::NOperationResult::kDataError; + else + return result; + return extractCallback->SetOperationResult(retResult); + + COM_TRY_END +} + +IMPL_ISetCompressCodecsInfo + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/BZip2/BZip2Handler.h b/desmume/src/windows/7z/CPP/7zip/Archive/BZip2/BZip2Handler.h new file mode 100644 index 000000000..5d9fb1430 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/BZip2/BZip2Handler.h @@ -0,0 +1,70 @@ +// BZip2/Handler.h + +#ifndef __BZIP2_HANDLER_H +#define __BZIP2_HANDLER_H + +#include "Common/MyCom.h" +#include "../IArchive.h" +#include "../../Common/CreateCoder.h" +#include "BZip2Item.h" + +#ifdef COMPRESS_MT +#include "../../../Windows/System.h" +#endif + +namespace NArchive { +namespace NBZip2 { + +class CHandler: + public IInArchive, + public IOutArchive, + public ISetProperties, + PUBLIC_ISetCompressCodecsInfo + public CMyUnknownImp +{ + CMyComPtr _stream; + NArchive::NBZip2::CItem _item; + UInt64 _streamStartPosition; + + UInt32 _level; + UInt32 _dicSize; + UInt32 _numPasses; + #ifdef COMPRESS_MT + UInt32 _numThreads; + #endif + + DECL_EXTERNAL_CODECS_VARS + + void InitMethodProperties() + { + _level = 5; + _dicSize = + _numPasses = 0xFFFFFFFF; + #ifdef COMPRESS_MT + _numThreads = NWindows::NSystem::GetNumberOfProcessors();; + #endif + } + +public: + MY_QUERYINTERFACE_BEGIN2(IInArchive) + MY_QUERYINTERFACE_ENTRY(IOutArchive) + MY_QUERYINTERFACE_ENTRY(ISetProperties) + QUERY_ENTRY_ISetCompressCodecsInfo + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + INTERFACE_IInArchive(;) +#ifndef EXTRACT_ONLY + INTERFACE_IOutArchive(;) + + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties); +#endif + + DECL_ISetCompressCodecsInfo + + CHandler() { InitMethodProperties(); } +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/BZip2/BZip2Item.h b/desmume/src/windows/7z/CPP/7zip/Archive/BZip2/BZip2Item.h new file mode 100644 index 000000000..f3fce499a --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/BZip2/BZip2Item.h @@ -0,0 +1,20 @@ +// Archive/BZip2Item.h + +#ifndef __ARCHIVE_BZIP2_ITEM_H +#define __ARCHIVE_BZIP2_ITEM_H + +namespace NArchive { +namespace NBZip2 { + +struct CItem +{ + UInt64 PackSize; + UInt64 UnPackSize; +}; + +}} + +#endif + + + diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/BZip2/StdAfx.h b/desmume/src/windows/7z/CPP/7zip/Archive/BZip2/StdAfx.h new file mode 100644 index 000000000..83fdd22d5 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/BZip2/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/BZip2/bz2Register.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/BZip2/bz2Register.cpp new file mode 100644 index 000000000..f4a706ed1 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/BZip2/bz2Register.cpp @@ -0,0 +1,18 @@ +// BZip2Register.cpp + +#include "StdAfx.h" + +#include "../../Common/RegisterArc.h" + +#include "BZip2Handler.h" +static IInArchive *CreateArc() { return new NArchive::NBZip2::CHandler; } +#ifndef EXTRACT_ONLY +static IOutArchive *CreateArcOut() { return new NArchive::NBZip2::CHandler; } +#else +#define CreateArcOut 0 +#endif + +static CArcInfo g_ArcInfo = + { L"BZip2", L"bz2 bzip2 tbz2 tbz", L"* * .tar .tar", 2, { 'B', 'Z', 'h' }, 3, true, CreateArc, CreateArcOut }; + +REGISTER_ARC(BZip2) diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Common/CoderMixer2.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Common/CoderMixer2.cpp new file mode 100644 index 000000000..c4333f234 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Common/CoderMixer2.cpp @@ -0,0 +1,121 @@ +// CoderMixer2.cpp + +#include "StdAfx.h" + +#include "CoderMixer2.h" + +namespace NCoderMixer { + +CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo): + _srcBindInfo(srcBindInfo) +{ + srcBindInfo.GetNumStreams(NumSrcInStreams, _numSrcOutStreams); + + UInt32 j; + for (j = 0; j < NumSrcInStreams; j++) + { + _srcInToDestOutMap.Add(0); + DestOutToSrcInMap.Add(0); + } + for (j = 0; j < _numSrcOutStreams; j++) + { + _srcOutToDestInMap.Add(0); + _destInToSrcOutMap.Add(0); + } + + UInt32 destInOffset = 0; + UInt32 destOutOffset = 0; + UInt32 srcInOffset = NumSrcInStreams; + UInt32 srcOutOffset = _numSrcOutStreams; + + for (int i = srcBindInfo.Coders.Size() - 1; i >= 0; i--) + { + const CCoderStreamsInfo &srcCoderInfo = srcBindInfo.Coders[i]; + + srcInOffset -= srcCoderInfo.NumInStreams; + srcOutOffset -= srcCoderInfo.NumOutStreams; + + UInt32 j; + for (j = 0; j < srcCoderInfo.NumInStreams; j++, destOutOffset++) + { + UInt32 index = srcInOffset + j; + _srcInToDestOutMap[index] = destOutOffset; + DestOutToSrcInMap[destOutOffset] = index; + } + for (j = 0; j < srcCoderInfo.NumOutStreams; j++, destInOffset++) + { + UInt32 index = srcOutOffset + j; + _srcOutToDestInMap[index] = destInOffset; + _destInToSrcOutMap[destInOffset] = index; + } + } +} + +void CBindReverseConverter::CreateReverseBindInfo(CBindInfo &destBindInfo) +{ + destBindInfo.Coders.Clear(); + destBindInfo.BindPairs.Clear(); + destBindInfo.InStreams.Clear(); + destBindInfo.OutStreams.Clear(); + + int i; + for (i = _srcBindInfo.Coders.Size() - 1; i >= 0; i--) + { + const CCoderStreamsInfo &srcCoderInfo = _srcBindInfo.Coders[i]; + CCoderStreamsInfo destCoderInfo; + destCoderInfo.NumInStreams = srcCoderInfo.NumOutStreams; + destCoderInfo.NumOutStreams = srcCoderInfo.NumInStreams; + destBindInfo.Coders.Add(destCoderInfo); + } + for (i = _srcBindInfo.BindPairs.Size() - 1; i >= 0; i--) + { + const CBindPair &srcBindPair = _srcBindInfo.BindPairs[i]; + CBindPair destBindPair; + destBindPair.InIndex = _srcOutToDestInMap[srcBindPair.OutIndex]; + destBindPair.OutIndex = _srcInToDestOutMap[srcBindPair.InIndex]; + destBindInfo.BindPairs.Add(destBindPair); + } + for (i = 0; i < _srcBindInfo.InStreams.Size(); i++) + destBindInfo.OutStreams.Add(_srcInToDestOutMap[_srcBindInfo.InStreams[i]]); + for (i = 0; i < _srcBindInfo.OutStreams.Size(); i++) + destBindInfo.InStreams.Add(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]); +} + +CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams): + NumInStreams(numInStreams), + NumOutStreams(numOutStreams) +{ + InSizes.Reserve(NumInStreams); + InSizePointers.Reserve(NumInStreams); + OutSizePointers.Reserve(NumOutStreams); + OutSizePointers.Reserve(NumOutStreams); +} + +static void SetSizes(const UInt64 **srcSizes, CRecordVector &sizes, + CRecordVector &sizePointers, UInt32 numItems) +{ + sizes.Clear(); + sizePointers.Clear(); + for(UInt32 i = 0; i < numItems; i++) + { + if (srcSizes == 0 || srcSizes[i] == NULL) + { + sizes.Add(0); + sizePointers.Add(NULL); + } + else + { + sizes.Add(*srcSizes[i]); + sizePointers.Add(&sizes.Back()); + } + } +} + +void CCoderInfo2::SetCoderInfo(const UInt64 **inSizes, + const UInt64 **outSizes) +{ + SetSizes(inSizes, InSizes, InSizePointers, NumInStreams); + SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams); +} + +} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Common/CoderMixer2.h b/desmume/src/windows/7z/CPP/7zip/Archive/Common/CoderMixer2.h new file mode 100644 index 000000000..b1893b217 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Common/CoderMixer2.h @@ -0,0 +1,174 @@ +// CoderMixer2.h + +#ifndef __CODER_MIXER2_H +#define __CODER_MIXER2_H + +#include "../../../Common/MyVector.h" +#include "../../../Common/Types.h" +#include "../../../Common/MyCom.h" +#include "../../ICoder.h" + +namespace NCoderMixer { + +struct CBindPair +{ + UInt32 InIndex; + UInt32 OutIndex; +}; + +struct CCoderStreamsInfo +{ + UInt32 NumInStreams; + UInt32 NumOutStreams; +}; + +struct CBindInfo +{ + CRecordVector Coders; + CRecordVector BindPairs; + CRecordVector InStreams; + CRecordVector OutStreams; + + void Clear() + { + Coders.Clear(); + BindPairs.Clear(); + InStreams.Clear(); + OutStreams.Clear(); + } + + /* + UInt32 GetCoderStartOutStream(UInt32 coderIndex) const + { + UInt32 numOutStreams = 0; + for (UInt32 i = 0; i < coderIndex; i++) + numOutStreams += Coders[i].NumOutStreams; + return numOutStreams; + } + */ + + + void GetNumStreams(UInt32 &numInStreams, UInt32 &numOutStreams) const + { + numInStreams = 0; + numOutStreams = 0; + for (int i = 0; i < Coders.Size(); i++) + { + const CCoderStreamsInfo &coderStreamsInfo = Coders[i]; + numInStreams += coderStreamsInfo.NumInStreams; + numOutStreams += coderStreamsInfo.NumOutStreams; + } + } + + int FindBinderForInStream(UInt32 inStream) const + { + for (int i = 0; i < BindPairs.Size(); i++) + if (BindPairs[i].InIndex == inStream) + return i; + return -1; + } + int FindBinderForOutStream(UInt32 outStream) const + { + for (int i = 0; i < BindPairs.Size(); i++) + if (BindPairs[i].OutIndex == outStream) + return i; + return -1; + } + + UInt32 GetCoderInStreamIndex(UInt32 coderIndex) const + { + UInt32 streamIndex = 0; + for (UInt32 i = 0; i < coderIndex; i++) + streamIndex += Coders[i].NumInStreams; + return streamIndex; + } + + UInt32 GetCoderOutStreamIndex(UInt32 coderIndex) const + { + UInt32 streamIndex = 0; + for (UInt32 i = 0; i < coderIndex; i++) + streamIndex += Coders[i].NumOutStreams; + return streamIndex; + } + + + void FindInStream(UInt32 streamIndex, UInt32 &coderIndex, + UInt32 &coderStreamIndex) const + { + for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++) + { + UInt32 curSize = Coders[coderIndex].NumInStreams; + if (streamIndex < curSize) + { + coderStreamIndex = streamIndex; + return; + } + streamIndex -= curSize; + } + throw 1; + } + void FindOutStream(UInt32 streamIndex, UInt32 &coderIndex, + UInt32 &coderStreamIndex) const + { + for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++) + { + UInt32 curSize = Coders[coderIndex].NumOutStreams; + if (streamIndex < curSize) + { + coderStreamIndex = streamIndex; + return; + } + streamIndex -= curSize; + } + throw 1; + } +}; + +class CBindReverseConverter +{ + UInt32 _numSrcOutStreams; + NCoderMixer::CBindInfo _srcBindInfo; + CRecordVector _srcInToDestOutMap; + CRecordVector _srcOutToDestInMap; + CRecordVector _destInToSrcOutMap; +public: + UInt32 NumSrcInStreams; + CRecordVector DestOutToSrcInMap; + + CBindReverseConverter(const NCoderMixer::CBindInfo &srcBindInfo); + void CreateReverseBindInfo(NCoderMixer::CBindInfo &destBindInfo); +}; + +struct CCoderInfo2 +{ + CMyComPtr Coder; + CMyComPtr Coder2; + UInt32 NumInStreams; + UInt32 NumOutStreams; + + CRecordVector InSizes; + CRecordVector OutSizes; + CRecordVector InSizePointers; + CRecordVector OutSizePointers; + + CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams); + void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes); + + HRESULT QueryInterface(REFGUID iid, void** pp) const + { + IUnknown *p = Coder ? (IUnknown *)Coder : (IUnknown *)Coder2; + return p->QueryInterface(iid, pp); + } +}; + +class CCoderMixer2 +{ +public: + virtual HRESULT SetBindInfo(const CBindInfo &bindInfo) = 0; + virtual void ReInit() = 0; + virtual void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) = 0; +}; + +} +#endif + diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Common/CoderMixer2MT.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Common/CoderMixer2MT.cpp new file mode 100644 index 000000000..f3bea728d --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Common/CoderMixer2MT.cpp @@ -0,0 +1,230 @@ +// CoderMixer2MT.cpp + +#include "StdAfx.h" + +#include "CoderMixer2MT.h" + +namespace NCoderMixer { + +CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams): + CCoderInfo2(numInStreams, numOutStreams) +{ + InStreams.Reserve(NumInStreams); + InStreamPointers.Reserve(NumInStreams); + OutStreams.Reserve(NumOutStreams); + OutStreamPointers.Reserve(NumOutStreams); +} + +void CCoder2::Execute() { Code(NULL); } + +void CCoder2::Code(ICompressProgressInfo *progress) +{ + InStreamPointers.Clear(); + OutStreamPointers.Clear(); + UInt32 i; + for (i = 0; i < NumInStreams; i++) + { + if (InSizePointers[i] != NULL) + InSizePointers[i] = &InSizes[i]; + InStreamPointers.Add((ISequentialInStream *)InStreams[i]); + } + for (i = 0; i < NumOutStreams; i++) + { + if (OutSizePointers[i] != NULL) + OutSizePointers[i] = &OutSizes[i]; + OutStreamPointers.Add((ISequentialOutStream *)OutStreams[i]); + } + if (Coder) + Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0], + InSizePointers[0], OutSizePointers[0], progress); + else + Result = Coder2->Code(&InStreamPointers.Front(), &InSizePointers.Front(), NumInStreams, + &OutStreamPointers.Front(), &OutSizePointers.Front(), NumOutStreams, progress); + { + int i; + for (i = 0; i < InStreams.Size(); i++) + InStreams[i].Release(); + for (i = 0; i < OutStreams.Size(); i++) + OutStreams[i].Release(); + } +} + +static void SetSizes(const UInt64 **srcSizes, CRecordVector &sizes, + CRecordVector &sizePointers, UInt32 numItems) +{ + sizes.Clear(); + sizePointers.Clear(); + for(UInt32 i = 0; i < numItems; i++) + { + if (srcSizes == 0 || srcSizes[i] == NULL) + { + sizes.Add(0); + sizePointers.Add(NULL); + } + else + { + sizes.Add(*srcSizes[i]); + sizePointers.Add(&sizes.Back()); + } + } +} + + +void CCoder2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes) +{ + SetSizes(inSizes, InSizes, InSizePointers, NumInStreams); + SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams); +} + +////////////////////////////////////// +// CCoderMixer2MT + +HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo) +{ + _bindInfo = bindInfo; + _streamBinders.Clear(); + for(int i = 0; i < _bindInfo.BindPairs.Size(); i++) + { + _streamBinders.Add(CStreamBinder()); + RINOK(_streamBinders.Back().CreateEvents()); + } + return S_OK; +} + +void CCoderMixer2MT::AddCoderCommon() +{ + const CCoderStreamsInfo &c = _bindInfo.Coders[_coders.Size()]; + CCoder2 threadCoderInfo(c.NumInStreams, c.NumOutStreams); + _coders.Add(threadCoderInfo); +} + +void CCoderMixer2MT::AddCoder(ICompressCoder *coder) +{ + AddCoderCommon(); + _coders.Back().Coder = coder; +} + +void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder) +{ + AddCoderCommon(); + _coders.Back().Coder2 = coder; +} + + +void CCoderMixer2MT::ReInit() +{ + for(int i = 0; i < _streamBinders.Size(); i++) + _streamBinders[i].ReInit(); +} + + +HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams) +{ + /* + if (_coders.Size() != _bindInfo.Coders.Size()) + throw 0; + */ + int i; + for(i = 0; i < _coders.Size(); i++) + { + CCoder2 &coderInfo = _coders[i]; + const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i]; + coderInfo.InStreams.Clear(); + UInt32 j; + for(j = 0; j < coderStreamsInfo.NumInStreams; j++) + coderInfo.InStreams.Add(NULL); + coderInfo.OutStreams.Clear(); + for(j = 0; j < coderStreamsInfo.NumOutStreams; j++) + coderInfo.OutStreams.Add(NULL); + } + + for(i = 0; i < _bindInfo.BindPairs.Size(); i++) + { + const CBindPair &bindPair = _bindInfo.BindPairs[i]; + UInt32 inCoderIndex, inCoderStreamIndex; + UInt32 outCoderIndex, outCoderStreamIndex; + _bindInfo.FindInStream(bindPair.InIndex, inCoderIndex, inCoderStreamIndex); + _bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex); + + _streamBinders[i].CreateStreams( + &_coders[inCoderIndex].InStreams[inCoderStreamIndex], + &_coders[outCoderIndex].OutStreams[outCoderStreamIndex]); + } + + for(i = 0; i < _bindInfo.InStreams.Size(); i++) + { + UInt32 inCoderIndex, inCoderStreamIndex; + _bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex); + _coders[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i]; + } + + for(i = 0; i < _bindInfo.OutStreams.Size(); i++) + { + UInt32 outCoderIndex, outCoderStreamIndex; + _bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex); + _coders[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i]; + } + return S_OK; +} + +HRESULT CCoderMixer2MT::ReturnIfError(HRESULT code) +{ + for (int i = 0; i < _coders.Size(); i++) + if (_coders[i].Result == code) + return code; + return S_OK; +} + +STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams, + const UInt64 ** /* inSizes */, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 ** /* outSizes */, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + if (numInStreams != (UInt32)_bindInfo.InStreams.Size() || + numOutStreams != (UInt32)_bindInfo.OutStreams.Size()) + return E_INVALIDARG; + + Init(inStreams, outStreams); + + int i; + for (i = 0; i < _coders.Size(); i++) + if (i != _progressCoderIndex) + { + RINOK(_coders[i].Create()); + } + + for (i = 0; i < _coders.Size(); i++) + if (i != _progressCoderIndex) + _coders[i].Start(); + + _coders[_progressCoderIndex].Code(progress); + + for (i = 0; i < _coders.Size(); i++) + if (i != _progressCoderIndex) + _coders[i].WaitFinish(); + + RINOK(ReturnIfError(E_ABORT)); + RINOK(ReturnIfError(E_OUTOFMEMORY)); + + for (i = 0; i < _coders.Size(); i++) + { + HRESULT result = _coders[i].Result; + if (result != S_OK && result != E_FAIL && result != S_FALSE) + return result; + } + + RINOK(ReturnIfError(S_FALSE)); + + for (i = 0; i < _coders.Size(); i++) + { + HRESULT result = _coders[i].Result; + if (result != S_OK) + return result; + } + return S_OK; +} + +} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Common/CoderMixer2MT.h b/desmume/src/windows/7z/CPP/7zip/Archive/Common/CoderMixer2MT.h new file mode 100644 index 000000000..acecc390f --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Common/CoderMixer2MT.h @@ -0,0 +1,80 @@ +// CoderMixer2MT.h + +#ifndef __CODER_MIXER2_MT_H +#define __CODER_MIXER2_MT_H + +#include "CoderMixer2.h" +#include "../../../Common/MyCom.h" +#include "../../Common/StreamBinder.h" +#include "../../Common/VirtThread.h" + +namespace NCoderMixer { + +struct CCoder2: public CCoderInfo2, public CVirtThread +{ + HRESULT Result; + CObjectVector< CMyComPtr > InStreams; + CObjectVector< CMyComPtr > OutStreams; + CRecordVector InStreamPointers; + CRecordVector OutStreamPointers; + + CCoder2(UInt32 numInStreams, UInt32 numOutStreams); + void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes); + virtual void Execute(); + void Code(ICompressProgressInfo *progress); +}; + + +/* + SetBindInfo() + for each coder + AddCoder[2]() + SetProgressIndex(UInt32 coderIndex); + + for each file + { + ReInit() + for each coder + SetCoderInfo + Code + } +*/ + +class CCoderMixer2MT: + public ICompressCoder2, + public CCoderMixer2, + public CMyUnknownImp +{ + CBindInfo _bindInfo; + CObjectVector _streamBinders; + int _progressCoderIndex; + + void AddCoderCommon(); + HRESULT Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams); + HRESULT ReturnIfError(HRESULT code); +public: + CObjectVector _coders; + MY_UNKNOWN_IMP + + STDMETHOD(Code)(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress); + + HRESULT SetBindInfo(const CBindInfo &bindInfo); + void AddCoder(ICompressCoder *coder); + void AddCoder2(ICompressCoder2 *coder); + void SetProgressCoderIndex(int coderIndex) { _progressCoderIndex = coderIndex; } + + void ReInit(); + void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) + { _coders[coderIndex].SetCoderInfo(inSizes, outSizes); } + UInt64 GetWriteProcessedSize(UInt32 binderIndex) const + { return _streamBinders[binderIndex].ProcessedSize; } +}; + +} +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Common/DummyOutStream.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Common/DummyOutStream.cpp new file mode 100644 index 000000000..237e01e59 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Common/DummyOutStream.cpp @@ -0,0 +1,22 @@ +// DummyOutStream.cpp + +#include "StdAfx.h" + +#include "DummyOutStream.h" + +STDMETHODIMP CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result; + if(!_stream) + { + realProcessedSize = size; + result = S_OK; + } + else + result = _stream->Write(data, size, &realProcessedSize); + _size += realProcessedSize; + if(processedSize != NULL) + *processedSize = realProcessedSize; + return result; +} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Common/DummyOutStream.h b/desmume/src/windows/7z/CPP/7zip/Archive/Common/DummyOutStream.h new file mode 100644 index 000000000..c993bb3dd --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Common/DummyOutStream.h @@ -0,0 +1,24 @@ +// DummyOutStream.h + +#ifndef __DUMMYOUTSTREAM_H +#define __DUMMYOUTSTREAM_H + +#include "../../IStream.h" +#include "Common/MyCom.h" + +class CDummyOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ + CMyComPtr _stream; + UInt64 _size; +public: + void SetStream(ISequentialOutStream *outStream) { _stream = outStream; } + void ReleaseStream() { _stream.Release(); } + void Init() { _size = 0; } + MY_UNKNOWN_IMP + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + UInt64 GetSize() const { return _size; } +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Common/FindSignature.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Common/FindSignature.cpp new file mode 100644 index 000000000..ad04bfcb7 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Common/FindSignature.cpp @@ -0,0 +1,62 @@ +// FindSignature.cpp + +#include "StdAfx.h" + +#include "Common/Buffer.h" + +#include "FindSignature.h" + +#include "../../Common/StreamUtils.h" + +HRESULT FindSignatureInStream(ISequentialInStream *stream, + const Byte *signature, unsigned signatureSize, + const UInt64 *limit, UInt64 &resPos) +{ + resPos = 0; + CByteBuffer byteBuffer2; + byteBuffer2.SetCapacity(signatureSize); + RINOK(ReadStream_FALSE(stream, byteBuffer2, signatureSize)); + + if (memcmp(byteBuffer2, signature, signatureSize) == 0) + return S_OK; + + const UInt32 kBufferSize = (1 << 16); + CByteBuffer byteBuffer; + byteBuffer.SetCapacity(kBufferSize); + Byte *buffer = byteBuffer; + UInt32 numPrevBytes = signatureSize - 1; + memcpy(buffer, (const Byte *)byteBuffer2 + 1, numPrevBytes); + resPos = 1; + for (;;) + { + if (limit != NULL) + if (resPos > *limit) + return S_FALSE; + do + { + UInt32 numReadBytes = kBufferSize - numPrevBytes; + UInt32 processedSize; + RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize)); + numPrevBytes += processedSize; + if (processedSize == 0) + return S_FALSE; + } + while (numPrevBytes < signatureSize); + UInt32 numTests = numPrevBytes - signatureSize + 1; + for (UInt32 pos = 0; pos < numTests; pos++) + { + Byte b = signature[0]; + for (; buffer[pos] != b && pos < numTests; pos++); + if (pos == numTests) + break; + if (memcmp(buffer + pos, signature, signatureSize) == 0) + { + resPos += pos; + return S_OK; + } + } + resPos += numTests; + numPrevBytes -= numTests; + memmove(buffer, buffer + numTests, numPrevBytes); + } +} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Common/FindSignature.h b/desmume/src/windows/7z/CPP/7zip/Archive/Common/FindSignature.h new file mode 100644 index 000000000..f801d9860 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Common/FindSignature.h @@ -0,0 +1,12 @@ +// FindSignature.h + +#ifndef __FINDSIGNATURE_H +#define __FINDSIGNATURE_H + +#include "../../IStream.h" + +HRESULT FindSignatureInStream(ISequentialInStream *stream, + const Byte *signature, unsigned signatureSize, + const UInt64 *limit, UInt64 &resPos); + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Common/InStreamWithCRC.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Common/InStreamWithCRC.cpp new file mode 100644 index 000000000..4b87a43c0 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Common/InStreamWithCRC.cpp @@ -0,0 +1,40 @@ +// InStreamWithCRC.cpp + +#include "StdAfx.h" + +#include "InStreamWithCRC.h" + +STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result = _stream->Read(data, size, &realProcessedSize); + _size += realProcessedSize; + if (size > 0 && realProcessedSize == 0) + _wasFinished = true; + _crc = CrcUpdate(_crc, data, realProcessedSize); + if(processedSize != NULL) + *processedSize = realProcessedSize; + return result; +} + +STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result = _stream->Read(data, size, &realProcessedSize); + if (size > 0 && realProcessedSize == 0) + _wasFinished = true; + _size += realProcessedSize; + _crc = CrcUpdate(_crc, data, realProcessedSize); + if(processedSize != NULL) + *processedSize = realProcessedSize; + return result; +} + +STDMETHODIMP CInStreamWithCRC::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +{ + if (seekOrigin != STREAM_SEEK_SET || offset != 0) + return E_FAIL; + _size = 0; + _crc = CRC_INIT_VAL; + return _stream->Seek(offset, seekOrigin, newPosition); +} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Common/InStreamWithCRC.h b/desmume/src/windows/7z/CPP/7zip/Archive/Common/InStreamWithCRC.h new file mode 100644 index 000000000..d73f658e3 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Common/InStreamWithCRC.h @@ -0,0 +1,69 @@ +// InStreamWithCRC.h + +#ifndef __INSTREAMWITHCRC_H +#define __INSTREAMWITHCRC_H + +#include "../../../Common/MyCom.h" +#include "../../IStream.h" + +extern "C" +{ +#include "../../../../C/7zCrc.h" +} + +class CSequentialInStreamWithCRC: + public ISequentialInStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +private: + CMyComPtr _stream; + UInt64 _size; + UInt32 _crc; + bool _wasFinished; +public: + void SetStream(ISequentialInStream *stream) { _stream = stream; } + void Init() + { + _size = 0; + _wasFinished = false; + _crc = CRC_INIT_VAL; + } + void ReleaseStream() { _stream.Release(); } + UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); } + UInt64 GetSize() const { return _size; } + bool WasFinished() const { return _wasFinished; } +}; + +class CInStreamWithCRC: + public IInStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1(IInStream) + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); +private: + CMyComPtr _stream; + UInt64 _size; + UInt32 _crc; + bool _wasFinished; +public: + void SetStream(IInStream *stream) { _stream = stream; } + void Init() + { + _size = 0; + _wasFinished = false; + _crc = CRC_INIT_VAL; + } + void ReleaseStream() { _stream.Release(); } + UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); } + UInt64 GetSize() const { return _size; } + bool WasFinished() const { return _wasFinished; } +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Common/ItemNameUtils.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Common/ItemNameUtils.cpp new file mode 100644 index 000000000..b4fee7c06 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Common/ItemNameUtils.cpp @@ -0,0 +1,59 @@ +// Archive/Common/ItemNameUtils.cpp + +#include "StdAfx.h" + +#include "ItemNameUtils.h" + +namespace NArchive { +namespace NItemName { + +static const wchar_t kOSDirDelimiter = WCHAR_PATH_SEPARATOR; +static const wchar_t kDirDelimiter = L'/'; + +UString MakeLegalName(const UString &name) +{ + UString zipName = name; + zipName.Replace(kOSDirDelimiter, kDirDelimiter); + return zipName; +} + +UString GetOSName(const UString &name) +{ + UString newName = name; + newName.Replace(kDirDelimiter, kOSDirDelimiter); + return newName; +} + +UString GetOSName2(const UString &name) +{ + if (name.IsEmpty()) + return UString(); + UString newName = GetOSName(name); + if (newName[newName.Length() - 1] == kOSDirDelimiter) + newName.Delete(newName.Length() - 1); + return newName; +} + +bool HasTailSlash(const AString &name, UINT codePage) +{ + if (name.IsEmpty()) + return false; + LPCSTR prev = + #ifdef _WIN32 + CharPrevExA((WORD)codePage, name, &name[name.Length()], 0); + #else + (LPCSTR)(name) + (name.Length() - 1); + #endif + return (*prev == '/'); +} + +#ifndef _WIN32 +UString WinNameToOSName(const UString &name) +{ + UString newName = name; + newName.Replace(L'\\', kOSDirDelimiter); + return newName; +} +#endif + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Common/ItemNameUtils.h b/desmume/src/windows/7z/CPP/7zip/Archive/Common/ItemNameUtils.h new file mode 100644 index 000000000..8b91d1c68 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Common/ItemNameUtils.h @@ -0,0 +1,24 @@ +// Archive/Common/ItemNameUtils.h + +#ifndef __ARCHIVE_ITEMNAMEUTILS_H +#define __ARCHIVE_ITEMNAMEUTILS_H + +#include "../../../Common/MyString.h" + +namespace NArchive { +namespace NItemName { + + UString MakeLegalName(const UString &name); + UString GetOSName(const UString &name); + UString GetOSName2(const UString &name); + bool HasTailSlash(const AString &name, UINT codePage); + + #ifdef _WIN32 + inline UString WinNameToOSName(const UString &name) { return name; } + #else + UString WinNameToOSName(const UString &name); + #endif + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Common/MultiStream.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Common/MultiStream.cpp new file mode 100644 index 000000000..33bb91ed8 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Common/MultiStream.cpp @@ -0,0 +1,201 @@ +// MultiStream.cpp + +#include "StdAfx.h" + +#include "MultiStream.h" + +STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + if(processedSize != NULL) + *processedSize = 0; + while(_streamIndex < Streams.Size() && size > 0) + { + CSubStreamInfo &s = Streams[_streamIndex]; + if (_pos == s.Size) + { + _streamIndex++; + _pos = 0; + continue; + } + RINOK(s.Stream->Seek(s.Pos + _pos, STREAM_SEEK_SET, 0)); + UInt32 sizeToRead = UInt32(MyMin((UInt64)size, s.Size - _pos)); + UInt32 realProcessed; + HRESULT result = s.Stream->Read(data, sizeToRead, &realProcessed); + data = (void *)((Byte *)data + realProcessed); + size -= realProcessed; + if(processedSize != NULL) + *processedSize += realProcessed; + _pos += realProcessed; + _seekPos += realProcessed; + RINOK(result); + break; + } + return S_OK; +} + +STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, + UInt64 *newPosition) +{ + UInt64 newPos; + switch(seekOrigin) + { + case STREAM_SEEK_SET: + newPos = offset; + break; + case STREAM_SEEK_CUR: + newPos = _seekPos + offset; + break; + case STREAM_SEEK_END: + newPos = _totalLength + offset; + break; + default: + return STG_E_INVALIDFUNCTION; + } + _seekPos = 0; + for (_streamIndex = 0; _streamIndex < Streams.Size(); _streamIndex++) + { + UInt64 size = Streams[_streamIndex].Size; + if (newPos < _seekPos + size) + { + _pos = newPos - _seekPos; + _seekPos += _pos; + if (newPosition != 0) + *newPosition = newPos; + return S_OK; + } + _seekPos += size; + } + if (newPos == _seekPos) + { + if (newPosition != 0) + *newPosition = newPos; + return S_OK; + } + return E_FAIL; +} + + +/* +class COutVolumeStream: + public ISequentialOutStream, + public CMyUnknownImp +{ + int _volIndex; + UInt64 _volSize; + UInt64 _curPos; + CMyComPtr _volumeStream; + COutArchive _archive; + CCRC _crc; + +public: + MY_UNKNOWN_IMP + + CFileItem _file; + CUpdateOptions _options; + CMyComPtr VolumeCallback; + void Init(IArchiveUpdateCallback2 *volumeCallback, + const UString &name) + { + _file.Name = name; + _file.IsStartPosDefined = true; + _file.StartPos = 0; + + VolumeCallback = volumeCallback; + _volIndex = 0; + _volSize = 0; + } + + HRESULT Flush(); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +HRESULT COutVolumeStream::Flush() +{ + if (_volumeStream) + { + _file.UnPackSize = _curPos; + _file.FileCRC = _crc.GetDigest(); + RINOK(WriteVolumeHeader(_archive, _file, _options)); + _archive.Close(); + _volumeStream.Release(); + _file.StartPos += _file.UnPackSize; + } + return S_OK; +} +*/ + +/* +STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if(processedSize != NULL) + *processedSize = 0; + while(size > 0) + { + if (_streamIndex >= Streams.Size()) + { + CSubStreamInfo subStream; + RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size)); + RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream)); + subStream.Pos = 0; + Streams.Add(subStream); + continue; + } + CSubStreamInfo &subStream = Streams[_streamIndex]; + if (_offsetPos >= subStream.Size) + { + _offsetPos -= subStream.Size; + _streamIndex++; + continue; + } + if (_offsetPos != subStream.Pos) + { + CMyComPtr outStream; + RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream)); + RINOK(outStream->Seek(_offsetPos, STREAM_SEEK_SET, NULL)); + subStream.Pos = _offsetPos; + } + + UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos); + UInt32 realProcessed; + RINOK(subStream.Stream->Write(data, curSize, &realProcessed)); + data = (void *)((Byte *)data + realProcessed); + size -= realProcessed; + subStream.Pos += realProcessed; + _offsetPos += realProcessed; + _absPos += realProcessed; + if (_absPos > _length) + _length = _absPos; + if(processedSize != NULL) + *processedSize += realProcessed; + if (subStream.Pos == subStream.Size) + { + _streamIndex++; + _offsetPos = 0; + } + if (realProcessed != curSize && realProcessed == 0) + return E_FAIL; + } + return S_OK; +} + +STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +{ + if(seekOrigin >= 3) + return STG_E_INVALIDFUNCTION; + switch(seekOrigin) + { + case STREAM_SEEK_SET: + _absPos = offset; + break; + case STREAM_SEEK_CUR: + _absPos += offset; + break; + case STREAM_SEEK_END: + _absPos = _length + offset; + break; + } + _offsetPos = _absPos; + _streamIndex = 0; + return S_OK; +} +*/ diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Common/MultiStream.h b/desmume/src/windows/7z/CPP/7zip/Archive/Common/MultiStream.h new file mode 100644 index 000000000..133a06f9f --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Common/MultiStream.h @@ -0,0 +1,76 @@ +// MultiStream.h + +#ifndef __MULTISTREAM_H +#define __MULTISTREAM_H + +#include "../../../Common/MyCom.h" +#include "../../../Common/MyVector.h" +#include "../../Archive/IArchive.h" + +class CMultiStream: + public IInStream, + public CMyUnknownImp +{ + int _streamIndex; + UInt64 _pos; + UInt64 _seekPos; + UInt64 _totalLength; +public: + struct CSubStreamInfo + { + CMyComPtr Stream; + UInt64 Pos; + UInt64 Size; + }; + CObjectVector Streams; + void Init() + { + _streamIndex = 0; + _pos = 0; + _seekPos = 0; + _totalLength = 0; + for (int i = 0; i < Streams.Size(); i++) + _totalLength += Streams[i].Size; + } + + MY_UNKNOWN_IMP1(IInStream) + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); +}; + +/* +class COutMultiStream: + public IOutStream, + public CMyUnknownImp +{ + int _streamIndex; // required stream + UInt64 _offsetPos; // offset from start of _streamIndex index + UInt64 _absPos; + UInt64 _length; + + struct CSubStreamInfo + { + CMyComPtr Stream; + UInt64 Size; + UInt64 Pos; + }; + CObjectVector Streams; +public: + CMyComPtr VolumeCallback; + void Init() + { + _streamIndex = 0; + _offsetPos = 0; + _absPos = 0; + _length = 0; + } + + MY_UNKNOWN_IMP1(IOutStream) + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); +}; +*/ + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp new file mode 100644 index 000000000..37b157d1e --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp @@ -0,0 +1,24 @@ +// OutStreamWithCRC.cpp + +#include "StdAfx.h" + +#include "OutStreamWithCRC.h" + +STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result; + if(!_stream) + { + realProcessedSize = size; + result = S_OK; + } + else + result = _stream->Write(data, size, &realProcessedSize); + if (_calculate) + _crc = CrcUpdate(_crc, data, realProcessedSize); + _size += realProcessedSize; + if(processedSize != NULL) + *processedSize = realProcessedSize; + return result; +} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Common/OutStreamWithCRC.h b/desmume/src/windows/7z/CPP/7zip/Archive/Common/OutStreamWithCRC.h new file mode 100644 index 000000000..44e5eb24b --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Common/OutStreamWithCRC.h @@ -0,0 +1,38 @@ +// OutStreamWithCRC.h + +#ifndef __OUT_STREAM_WITH_CRC_H +#define __OUT_STREAM_WITH_CRC_H + +#include "../../../Common/MyCom.h" +#include "../../IStream.h" + +extern "C" +{ +#include "../../../../C/7zCrc.h" +} + +class COutStreamWithCRC: + public ISequentialOutStream, + public CMyUnknownImp +{ + CMyComPtr _stream; + UInt64 _size; + UInt32 _crc; + bool _calculate; +public: + MY_UNKNOWN_IMP + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void ReleaseStream() { _stream.Release(); } + void Init(bool calculate = true) + { + _size = 0; + _calculate = calculate; + _crc = CRC_INIT_VAL; + } + void InitCRC() { _crc = CRC_INIT_VAL; } + UInt64 GetSize() const { return _size; } + UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); } +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Common/ParseProperties.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Common/ParseProperties.cpp new file mode 100644 index 000000000..5550a23bc --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Common/ParseProperties.cpp @@ -0,0 +1,177 @@ +// ParseProperties.cpp + +#include "StdAfx.h" + +#include "ParseProperties.h" + +#include "Common/StringToInt.h" +#include "Common/MyCom.h" + +HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue) +{ + if (prop.vt == VT_UI4) + { + if (!name.IsEmpty()) + return E_INVALIDARG; + resValue = prop.ulVal; + } + else if (prop.vt == VT_EMPTY) + { + if(!name.IsEmpty()) + { + const wchar_t *start = name; + const wchar_t *end; + UInt64 v = ConvertStringToUInt64(start, &end); + if (end - start != name.Length()) + return E_INVALIDARG; + resValue = (UInt32)v; + } + } + else + return E_INVALIDARG; + return S_OK; +} + +static const int kLogarithmicSizeLimit = 32; +static const wchar_t kByteSymbol = L'B'; +static const wchar_t kKiloByteSymbol = L'K'; +static const wchar_t kMegaByteSymbol = L'M'; + +HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize) +{ + UString srcString = srcStringSpec; + srcString.MakeUpper(); + + const wchar_t *start = srcString; + const wchar_t *end; + UInt64 number = ConvertStringToUInt64(start, &end); + int numDigits = (int)(end - start); + if (numDigits == 0 || srcString.Length() > numDigits + 1) + return E_INVALIDARG; + if (srcString.Length() == numDigits) + { + if (number >= kLogarithmicSizeLimit) + return E_INVALIDARG; + dicSize = (UInt32)1 << (int)number; + return S_OK; + } + switch (srcString[numDigits]) + { + case kByteSymbol: + if (number >= ((UInt64)1 << kLogarithmicSizeLimit)) + return E_INVALIDARG; + dicSize = (UInt32)number; + break; + case kKiloByteSymbol: + if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10))) + return E_INVALIDARG; + dicSize = (UInt32)(number << 10); + break; + case kMegaByteSymbol: + if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20))) + return E_INVALIDARG; + dicSize = (UInt32)(number << 20); + break; + default: + return E_INVALIDARG; + } + return S_OK; +} + +HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue) +{ + if (name.IsEmpty()) + { + if (prop.vt == VT_UI4) + { + UInt32 logDicSize = prop.ulVal; + if (logDicSize >= 32) + return E_INVALIDARG; + resValue = (UInt32)1 << logDicSize; + return S_OK; + } + if (prop.vt == VT_BSTR) + return ParsePropDictionaryValue(prop.bstrVal, resValue); + return E_INVALIDARG; + } + return ParsePropDictionaryValue(name, resValue); +} + +bool StringToBool(const UString &s, bool &res) +{ + if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0 || s.Compare(L"+") == 0) + { + res = true; + return true; + } + if (s.CompareNoCase(L"OFF") == 0 || s.Compare(L"-") == 0) + { + res = false; + return true; + } + return false; +} + +HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value) +{ + switch(value.vt) + { + case VT_EMPTY: + dest = true; + return S_OK; + case VT_BOOL: + dest = (value.boolVal != VARIANT_FALSE); + return S_OK; + /* + case VT_UI4: + dest = (value.ulVal != 0); + break; + */ + case VT_BSTR: + return StringToBool(value.bstrVal, dest) ? S_OK : E_INVALIDARG; + } + return E_INVALIDARG; +} + +int ParseStringToUInt32(const UString &srcString, UInt32 &number) +{ + const wchar_t *start = srcString; + const wchar_t *end; + UInt64 number64 = ConvertStringToUInt64(start, &end); + if (number64 > 0xFFFFFFFF) + { + number = 0; + return 0; + } + number = (UInt32)number64; + return (int)(end - start); +} + +HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads) +{ + if (name.IsEmpty()) + { + switch(prop.vt) + { + case VT_UI4: + numThreads = prop.ulVal; + break; + default: + { + bool val; + RINOK(SetBoolProperty(val, prop)); + numThreads = (val ? defaultNumThreads : 1); + break; + } + } + } + else + { + UInt32 number; + int index = ParseStringToUInt32(name, number); + if (index != name.Length()) + return E_INVALIDARG; + numThreads = number; + } + return S_OK; +} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Common/ParseProperties.h b/desmume/src/windows/7z/CPP/7zip/Archive/Common/ParseProperties.h new file mode 100644 index 000000000..c64fc1ea1 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Common/ParseProperties.h @@ -0,0 +1,18 @@ +// ParseProperties.h + +#ifndef __PARSEPROPERTIES_H +#define __PARSEPROPERTIES_H + +#include "Common/MyString.h" +#include "Common/Types.h" + +HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue); +HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize); +HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue); + +bool StringToBool(const UString &s, bool &res); +HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value); +int ParseStringToUInt32(const UString &srcString, UInt32 &number); +HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads); + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Common/StdAfx.h b/desmume/src/windows/7z/CPP/7zip/Archive/Common/StdAfx.h new file mode 100644 index 000000000..a4e617312 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Common/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/DllExports2.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/DllExports2.cpp new file mode 100644 index 000000000..74d2a440f --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/DllExports2.cpp @@ -0,0 +1,82 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "../../Common/MyInitGuid.h" +#include "../../Common/ComTry.h" +#include "../../Common/Types.h" +#include "../../Windows/PropVariant.h" +#if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES) +extern "C" +{ +#include "../../../C/Alloc.h" +} +#endif + +#include "IArchive.h" +#include "../ICoder.h" +#include "../IPassword.h" + +HINSTANCE g_hInstance; +#ifndef _UNICODE +#ifdef _WIN32 +bool g_IsNT = false; +static bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#endif +#endif + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + g_hInstance = hInstance; + #ifndef _UNICODE + #ifdef _WIN32 + g_IsNT = IsItWindowsNT(); + #endif + #endif + } + return TRUE; +} + +DEFINE_GUID(CLSID_CArchiveHandler, +0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00); + +static const UInt16 kDecodeId = 0x2790; + +DEFINE_GUID(CLSID_CCodec, +0x23170F69, 0x40C1, kDecodeId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + +STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject); +STDAPI CreateArchiver(const GUID *classID, const GUID *iid, void **outObject); + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + // COM_TRY_BEGIN + *outObject = 0; + if (*iid == IID_ICompressCoder || *iid == IID_ICompressCoder2 || *iid == IID_ICompressFilter) + { + return CreateCoder(clsid, iid, outObject); + } + else + { + return CreateArchiver(clsid, iid, outObject); + } + // COM_TRY_END +} + +STDAPI SetLargePageMode() +{ + #if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES) + SetLargePageSize(); + #endif + return S_OK; +} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipHandler.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipHandler.cpp new file mode 100644 index 000000000..01a5c9f99 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipHandler.cpp @@ -0,0 +1,284 @@ +// GZipHandler.cpp + +#include "StdAfx.h" + +#include "GZipHandler.h" + +#include "Common/Defs.h" +#include "Common/StringConvert.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "Windows/Time.h" + +#include "../../ICoder.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/CreateCoder.h" +#include "../Common/OutStreamWithCRC.h" + +using namespace NWindows; + +namespace NArchive { +namespace NGZip { + +static const CMethodId kMethodId_Deflate = 0x040108; + +const wchar_t *kHostOS[] = +{ + L"FAT", + L"AMIGA", + L"VMS", + L"Unix", + L"VM_CMS", + L"Atari", // what if it's a minix filesystem? [cjh] + L"HPFS", // filesystem used by OS/2 (and NT 3.x) + L"Mac", + L"Z_System", + L"CPM", + L"TOPS20", // pkzip 2.50 NTFS + L"NTFS", // filesystem used by Windows NT + L"QDOS ", // SMS/QDOS + L"Acorn", // Archimedes Acorn RISC OS + L"VFAT", // filesystem used by Windows 95, NT + L"MVS", + L"BeOS", // hybrid POSIX/database filesystem + // BeBOX or PowerMac + L"Tandem", + L"THEOS" +}; + +static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]); + +static const wchar_t *kUnknownOS = L"Unknown"; + +/* +enum // PropID +{ + kpidExtraIsPresent = kpidUserDefined, + kpidExtraFlags, + kpidIsText +}; +*/ + +STATPROPSTG kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME}, + // { NULL, kpidMethod, VT_UI1}, + { NULL, kpidHostOS, VT_BSTR}, + { NULL, kpidCRC, VT_UI4} + // { L"Extra", kpidExtraIsPresent, VT_BOOL} + // { L"Extra flags", kpidExtraFlags, VT_UI1}, + // { L"Is Text", kpidIsText, VT_BOOL}, +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = 1; + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidPath: + if (m_Item.NameIsPresent()) + prop = MultiByteToUnicodeString(m_Item.Name, CP_ACP); + break; + case kpidMTime: + { + FILETIME utcTime; + if (m_Item.Time != 0) + { + NTime::UnixTimeToFileTime((UInt32)m_Item.Time, utcTime); + prop = utcTime; + } + else + { + // utcTime.dwLowDateTime = utcTime.dwHighDateTime = 0; + // prop = utcTime; + } + break; + } + case kpidSize: prop = UInt64(m_Item.UnPackSize32); break; + case kpidPackSize: prop = m_PackSize; break; + case kpidCommented: prop = m_Item.CommentIsPresent(); break; + case kpidHostOS: + prop = (m_Item.HostOS < kNumHostOSes) ? + kHostOS[m_Item.HostOS] : kUnknownOS; + break; + case kpidMethod: prop = m_Item.CompressionMethod; break; + case kpidCRC: prop = m_Item.FileCRC; break; + /* + case kpidExtraFlags: prop = m_Item.ExtraFlags; break; + case kpidIsText: prop = m_Item.IsText(); break; + case kpidExtraIsPresent: prop = m_Item.ExtraFieldIsPresent(); break; + */ + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */) +{ + COM_TRY_BEGIN + try + { + CInArchive archive; + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition)); + RINOK(archive.ReadHeader(inStream, m_Item)); + m_DataOffset = archive.GetOffset(); + UInt64 newPosition; + RINOK(inStream->Seek(-8, STREAM_SEEK_END, &newPosition)); + m_PackSize = newPosition - (m_StreamStartPosition + m_DataOffset); + if (archive.ReadPostHeader(inStream, m_Item) != S_OK) + return S_FALSE; + m_Stream = inStream; + } + catch(...) + { + return S_FALSE; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + m_Stream.Release(); + return S_OK; +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool allFilesMode = (numItems == UInt32(-1)); + if (!allFilesMode) + { + if (numItems == 0) + return S_OK; + if (numItems != 1) + return E_INVALIDARG; + if (indices[0] != 0) + return E_INVALIDARG; + } + + bool testMode = (_aTestMode != 0); + + extractCallback->SetTotal(m_PackSize); + + UInt64 currentTotalPacked = 0; + + RINOK(extractCallback->SetCompleted(¤tTotalPacked)); + CMyComPtr realOutStream; + Int32 askMode; + askMode = testMode ? NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); + + if(!testMode && !realOutStream) + return S_OK; + + extractCallback->PrepareOperation(askMode); + + COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; + CMyComPtr outStream(outStreamSpec); + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(); + realOutStream.Release(); + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, true); + + CMyComPtr deflateDecoder; + bool firstItem = true; + RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL)); + Int32 opRes; + for (;;) + { + lps->InSize = currentTotalPacked; + lps->OutSize = outStreamSpec->GetSize(); + + CInArchive archive; + CItem item; + HRESULT result = archive.ReadHeader(m_Stream, item); + if (result != S_OK) + { + if (firstItem) + return E_FAIL; + opRes = NArchive::NExtract::NOperationResult::kOK; + break; + } + firstItem = false; + + UInt64 dataStartPos; + RINOK(m_Stream->Seek(0, STREAM_SEEK_CUR, &dataStartPos)); + + outStreamSpec->InitCRC(); + + if (item.CompressionMethod != NFileHeader::NCompressionMethod::kDeflate) + { + opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + break; + } + + if (!deflateDecoder) + { + RINOK(CreateCoder( + EXTERNAL_CODECS_VARS + kMethodId_Deflate, deflateDecoder, false)); + if (!deflateDecoder) + { + opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + break; + } + } + result = deflateDecoder->Code(m_Stream, outStream, NULL, NULL, progress); + if (result != S_OK) + { + if (result != S_FALSE) + return result; + opRes = NArchive::NExtract::NOperationResult::kDataError; + break; + } + + CMyComPtr getInStreamProcessedSize; + RINOK(deflateDecoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, + &getInStreamProcessedSize)); + UInt64 packSize; + RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&packSize)); + UInt64 pos; + RINOK(m_Stream->Seek(dataStartPos + packSize, STREAM_SEEK_SET, &pos)); + + currentTotalPacked = pos - m_StreamStartPosition; + + CItem postItem; + if (archive.ReadPostHeader(m_Stream, postItem) != S_OK) + return E_FAIL; + if((outStreamSpec->GetCRC() != postItem.FileCRC)) + { + opRes = NArchive::NExtract::NOperationResult::kCRCError; + break; + } + } + outStream.Release(); + return extractCallback->SetOperationResult(opRes); + COM_TRY_END +} + +IMPL_ISetCompressCodecsInfo + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipHandler.h b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipHandler.h new file mode 100644 index 000000000..31f5a430f --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipHandler.h @@ -0,0 +1,65 @@ +// GZip/Handler.h + +#ifndef __GZIP_HANDLER_H +#define __GZIP_HANDLER_H + +#include "Common/MyCom.h" + +#include "../IArchive.h" + +#include "../../Common/CreateCoder.h" + +#include "GZipIn.h" +#include "GZipUpdate.h" + +namespace NArchive { +namespace NGZip { + +class CHandler: + public IInArchive, + public IOutArchive, + public ISetProperties, + PUBLIC_ISetCompressCodecsInfo + public CMyUnknownImp +{ +public: + MY_QUERYINTERFACE_BEGIN2(IInArchive) + MY_QUERYINTERFACE_ENTRY(IOutArchive) + MY_QUERYINTERFACE_ENTRY(ISetProperties) + QUERY_ENTRY_ISetCompressCodecsInfo + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + INTERFACE_IInArchive(;) +#ifndef EXTRACT_ONLY + INTERFACE_IOutArchive(;) + + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties); +#endif + + DECL_ISetCompressCodecsInfo + + CHandler() { InitMethodProperties(); } + +private: + NArchive::NGZip::CItem m_Item; + UInt64 m_StreamStartPosition; + UInt64 m_DataOffset; + UInt64 m_PackSize; + CMyComPtr m_Stream; + CCompressionMethodMode m_Method; + UInt32 m_Level; + + DECL_EXTERNAL_CODECS_VARS + + void InitMethodProperties() + { + m_Method.NumMatchFinderCyclesDefined = false; + m_Level = m_Method.NumPasses = m_Method.NumFastBytes = + m_Method.NumMatchFinderCycles = m_Method.Algo = 0xFFFFFFFF; + } +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipHeader.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipHeader.cpp new file mode 100644 index 000000000..508d6bd5b --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipHeader.cpp @@ -0,0 +1,20 @@ +// Archive/GZip/Header.h + +#include "StdAfx.h" + +#include "GZipHeader.h" + +namespace NArchive { +namespace NGZip { + +extern UInt16 kSignature = 0x8B1F + 1; + +class CMarkersInitializer +{ +public: + CMarkersInitializer() + { kSignature--; } +} g_MarkerInitializer; + +}} + diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipHeader.h b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipHeader.h new file mode 100644 index 000000000..3e76ad6d2 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipHeader.h @@ -0,0 +1,85 @@ +// Archive/GZip/Header.h + +#ifndef __ARCHIVE_GZIP_HEADER_H +#define __ARCHIVE_GZIP_HEADER_H + +#include "Common/Types.h" + +namespace NArchive { +namespace NGZip { + +extern UInt16 kSignature; +static const UInt32 kSignatureSize = 2; + +namespace NFileHeader +{ + /* + struct CBlock + { + UInt16 Id; + Byte CompressionMethod; + Byte Flags; + UInt32 Time; + Byte ExtraFlags; + Byte HostOS; + }; + */ + + namespace NFlags + { + const int kDataIsText = 1 << 0; + const int kHeaderCRCIsPresent = 1 << 1; + const int kExtraIsPresent = 1 << 2; + const int kNameIsPresent = 1 << 3; + const int kComentIsPresent = 1 << 4; + } + + namespace NExtraFlags + { + enum EEnum + { + kMaximum = 2, + kFastest = 4 + }; + } + + namespace NCompressionMethod + { + const Byte kDeflate = 8; + } + + namespace NHostOS + { + enum EEnum + { + kFAT = 0, // filesystem used by MS-DOS, OS/2, Win32 + // pkzip 2.50 (FAT / VFAT / FAT32 file systems) + kAMIGA = 1, + kVMS = 2, // VAX/VMS + kUnix = 3, + kVM_CMS = 4, + kAtari = 5, // what if it's a minix filesystem? [cjh] + kHPFS = 6, // filesystem used by OS/2 (and NT 3.x) + kMac = 7, + kZ_System = 8, + kCPM = 9, + kTOPS20 = 10, // pkzip 2.50 NTFS + kNTFS = 11, // filesystem used by Windows NT + kQDOS = 12, // SMS/QDOS + kAcorn = 13, // Archimedes Acorn RISC OS + kVFAT = 14, // filesystem used by Windows 95, NT + kMVS = 15, + kBeOS = 16, // hybrid POSIX/database filesystem + // BeBOX or PowerMac + kTandem = 17, + kTHEOS = 18, + + kUnknown = 255 + }; + const int kNumHostSystems = 19; + } +} + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipIn.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipIn.cpp new file mode 100644 index 000000000..b29f10e08 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipIn.cpp @@ -0,0 +1,119 @@ +// Archive/GZipIn.cpp + +#include "StdAfx.h" + +#include "GZipIn.h" + +#include "Common/Defs.h" +#include "Common/MyCom.h" +#include "Windows/Defs.h" + +#include "../../Common/StreamUtils.h" + +extern "C" +{ + #include "../../../../C/7zCrc.h" +} + +namespace NArchive { +namespace NGZip { + +HRESULT CInArchive::ReadBytes(ISequentialInStream *inStream, void *data, UInt32 size) +{ + RINOK(ReadStream_FALSE(inStream, data, size)); + m_Position += size; + return S_OK; +} + +HRESULT CInArchive::ReadByte(ISequentialInStream *inStream, Byte &value, UInt32 &crc) +{ + RINOK(ReadBytes(inStream, &value, 1)); + crc = CRC_UPDATE_BYTE(crc, value); + return S_OK; +} + +HRESULT CInArchive::ReadUInt16(ISequentialInStream *inStream, UInt16 &value, UInt32 &crc) +{ + value = 0; + for (int i = 0; i < 2; i++) + { + Byte b; + RINOK(ReadByte(inStream, b, crc)); + value |= (UInt16(b) << (8 * i)); + } + return S_OK; +} + +HRESULT CInArchive::ReadUInt32(ISequentialInStream *inStream, UInt32 &value, UInt32 &crc) +{ + value = 0; + for (int i = 0; i < 4; i++) + { + Byte b; + RINOK(ReadByte(inStream, b, crc)); + value |= (UInt32(b) << (8 * i)); + } + return S_OK; +} + +HRESULT CInArchive::ReadZeroTerminatedString(ISequentialInStream *inStream, AString &resString, UInt32 &crc) +{ + resString.Empty(); + for (;;) + { + Byte c; + RINOK(ReadByte(inStream, c, crc)); + if (c == 0) + return S_OK; + resString += char(c); + } +} + +HRESULT CInArchive::ReadHeader(ISequentialInStream *inStream, CItem &item) +{ + item.Clear(); + m_Position = 0; + + UInt16 signature; + UInt32 crc = CRC_INIT_VAL;; + RINOK(ReadUInt16(inStream, signature, crc)); + if (signature != kSignature) + return S_FALSE; + + RINOK(ReadByte(inStream, item.CompressionMethod, crc)); + RINOK(ReadByte(inStream, item.Flags, crc)); + RINOK(ReadUInt32(inStream, item.Time, crc)); + RINOK(ReadByte(inStream, item.ExtraFlags, crc)); + RINOK(ReadByte(inStream, item.HostOS, crc)); + + if (item.ExtraFieldIsPresent()) + { + UInt16 extraSize; + RINOK(ReadUInt16(inStream, extraSize, crc)); + item.Extra.SetCapacity(extraSize); + RINOK(ReadBytes(inStream, item.Extra, extraSize)); + crc = CrcUpdate(crc, item.Extra, extraSize); + } + if (item.NameIsPresent()) + RINOK(ReadZeroTerminatedString(inStream, item.Name, crc)); + if (item.CommentIsPresent()) + RINOK(ReadZeroTerminatedString(inStream, item.Comment, crc)); + if (item.HeaderCRCIsPresent()) + { + UInt16 headerCRC; + UInt32 dummy = 0; + RINOK(ReadUInt16(inStream, headerCRC, dummy)); + if ((UInt16)CRC_GET_DIGEST(crc) != headerCRC) + return S_FALSE; + } + return S_OK; +} + +HRESULT CInArchive::ReadPostHeader(ISequentialInStream *inStream, CItem &item) +{ + UInt32 dummy = 0; + RINOK(ReadUInt32(inStream, item.FileCRC, dummy)); + return ReadUInt32(inStream, item.UnPackSize32, dummy); +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipIn.h b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipIn.h new file mode 100644 index 000000000..1204d667c --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipIn.h @@ -0,0 +1,30 @@ +// Archive/GZipIn.h + +#ifndef __ARCHIVE_GZIP_IN_H +#define __ARCHIVE_GZIP_IN_H + +#include "GZipHeader.h" +#include "GZipItem.h" +#include "../../IStream.h" + +namespace NArchive { +namespace NGZip { + +class CInArchive +{ + UInt64 m_Position; + + HRESULT ReadBytes(ISequentialInStream *inStream, void *data, UInt32 size); + HRESULT ReadZeroTerminatedString(ISequentialInStream *inStream, AString &resString, UInt32 &crc); + HRESULT ReadByte(ISequentialInStream *inStream, Byte &value, UInt32 &crc); + HRESULT ReadUInt16(ISequentialInStream *inStream, UInt16 &value, UInt32 &crc); + HRESULT ReadUInt32(ISequentialInStream *inStream, UInt32 &value, UInt32 &crc); +public: + HRESULT ReadHeader(ISequentialInStream *inStream, CItem &item); + HRESULT ReadPostHeader(ISequentialInStream *inStream, CItem &item); + UInt64 GetOffset() const { return m_Position; } +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipItem.h b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipItem.h new file mode 100644 index 000000000..50eaef8a8 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipItem.h @@ -0,0 +1,59 @@ +// Archive/GZipItem.h + +#ifndef __ARCHIVE_GZIP_ITEM_H +#define __ARCHIVE_GZIP_ITEM_H + +#include "Common/Types.h" +#include "Common/MyString.h" +#include "Common/Buffer.h" + +namespace NArchive { +namespace NGZip { + +class CItem +{ +private: + bool TestFlag(Byte flag) const { return ((Flags & flag) != 0); } +public: + Byte CompressionMethod; + Byte Flags; + UInt32 Time; + Byte ExtraFlags; + Byte HostOS; + UInt32 FileCRC; + UInt32 UnPackSize32; + + AString Name; + AString Comment; + CByteBuffer Extra; + + bool IsText() const + { return TestFlag(NFileHeader::NFlags::kDataIsText); } + bool HeaderCRCIsPresent() const + { return TestFlag(NFileHeader::NFlags::kHeaderCRCIsPresent); } + bool ExtraFieldIsPresent() const + { return TestFlag(NFileHeader::NFlags::kExtraIsPresent); } + bool NameIsPresent() const + { return TestFlag(NFileHeader::NFlags::kNameIsPresent); } + bool CommentIsPresent() const + { return TestFlag(NFileHeader::NFlags::kComentIsPresent); } + + void SetNameIsPresentFlag(bool nameIsPresent) + { + if (nameIsPresent) + Flags |= NFileHeader::NFlags::kNameIsPresent; + else + Flags &= (~NFileHeader::NFlags::kNameIsPresent); + } + + void Clear() + { + Name.Empty(); + Comment.Empty();; + Extra.SetCapacity(0); + } +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipRegister.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipRegister.cpp new file mode 100644 index 000000000..0c1065088 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipRegister.cpp @@ -0,0 +1,18 @@ +// GZipRegister.cpp + +#include "StdAfx.h" + +#include "../../Common/RegisterArc.h" + +#include "GZipHandler.h" +static IInArchive *CreateArc() { return new NArchive::NGZip::CHandler; } +#ifndef EXTRACT_ONLY +static IOutArchive *CreateArcOut() { return new NArchive::NGZip::CHandler; } +#else +#define CreateArcOut 0 +#endif + +static CArcInfo g_ArcInfo = + { L"GZip", L"gz gzip tgz tpz", L"* * .tar .tar", 0xEF, { 0x1F, 0x8B, 8 }, 3, true, CreateArc, CreateArcOut }; + +REGISTER_ARC(GZip) diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipUpdate.h b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipUpdate.h new file mode 100644 index 000000000..59115ba2d --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/GZipUpdate.h @@ -0,0 +1,39 @@ +// GZip/Update.h + +#ifndef __GZIP_UPDATE_H +#define __GZIP_UPDATE_H + +#include "../IArchive.h" + +#include "../../Common/CreateCoder.h" + +#ifndef EXTRACT_ONLY +#include "GZipOut.h" +#endif +#include "GZipItem.h" + +namespace NArchive { +namespace NGZip { + +struct CCompressionMethodMode +{ + UInt32 NumPasses; + UInt32 NumFastBytes; + UInt32 Algo; + bool NumMatchFinderCyclesDefined; + UInt32 NumMatchFinderCycles; +}; + +HRESULT UpdateArchive( + DECL_EXTERNAL_CODECS_LOC_VARS + IInStream *inStream, + UInt64 unpackSize, + ISequentialOutStream *outStream, + const CItem &newItem, + const CCompressionMethodMode &compressionMethod, + int indexInClient, + IArchiveUpdateCallback *updateCallback); + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/GZip/StdAfx.h b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/StdAfx.h new file mode 100644 index 000000000..83fdd22d5 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/GZip/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/IArchive.h b/desmume/src/windows/7z/CPP/7zip/Archive/IArchive.h new file mode 100644 index 000000000..2ab476324 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/IArchive.h @@ -0,0 +1,237 @@ +// IArchive.h + +#ifndef __IARCHIVE_H +#define __IARCHIVE_H + +#include "../IStream.h" +#include "../IProgress.h" +#include "../PropID.h" + +#define ARCHIVE_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 6, x) +#define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x) + +namespace NFileTimeType +{ + enum EEnum + { + kWindows, + kUnix, + kDOS + }; +} + +namespace NArchive +{ + enum + { + kName = 0, + kClassID, + kExtension, + kAddExtension, + kUpdate, + kKeepName, + kStartSignature, + kFinishSignature, + kAssociate + }; + + namespace NExtract + { + namespace NAskMode + { + enum + { + kExtract = 0, + kTest, + kSkip + }; + } + namespace NOperationResult + { + enum + { + kOK = 0, + kUnSupportedMethod, + kDataError, + kCRCError + }; + } + } + namespace NUpdate + { + namespace NOperationResult + { + enum + { + kOK = 0, + kError + }; + } + } +} + +#define INTERFACE_IArchiveOpenCallback(x) \ + STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) x; \ + STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) x; \ + +ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10) +{ + INTERFACE_IArchiveOpenCallback(PURE); +}; + + +#define INTERFACE_IArchiveExtractCallback(x) \ + INTERFACE_IProgress(x) \ + /* GetStream OUT: S_OK - OK, S_FALSE - skeep this file */ \ + STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) x; \ + STDMETHOD(PrepareOperation)(Int32 askExtractMode) x; \ + STDMETHOD(SetOperationResult)(Int32 resultEOperationResult) x; \ + +ARCHIVE_INTERFACE_SUB(IArchiveExtractCallback, IProgress, 0x20) +{ + INTERFACE_IArchiveExtractCallback(PURE) +}; + + +#define INTERFACE_IArchiveOpenVolumeCallback(x) \ + STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) x; \ + STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) x; \ + +ARCHIVE_INTERFACE(IArchiveOpenVolumeCallback, 0x30) +{ + INTERFACE_IArchiveOpenVolumeCallback(PURE); +}; + + +ARCHIVE_INTERFACE(IInArchiveGetStream, 0x40) +{ + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE; +}; + + +ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50) +{ + STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE; +}; + + +/* +IInArchive::Extract: + indices must be sorted + numItems = 0xFFFFFFFF means "all files" + testMode != 0 means "test files without writing to outStream" +*/ + +#define INTERFACE_IInArchive(x) \ + STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) x; \ + STDMETHOD(Close)() x; \ + STDMETHOD(GetNumberOfItems)(UInt32 *numItems) x; \ + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \ + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) x; \ + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) x; \ + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \ + STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \ + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) x; \ + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; + +ARCHIVE_INTERFACE(IInArchive, 0x60) +{ + INTERFACE_IInArchive(PURE) + virtual ~IInArchive() {} +}; + + +#define INTERFACE_IArchiveUpdateCallback(x) \ + INTERFACE_IProgress(x); \ + STDMETHOD(GetUpdateItemInfo)(UInt32 index, \ + Int32 *newData, /*1 - new data, 0 - old data */ \ + Int32 *newProperties, /* 1 - new properties, 0 - old properties */ \ + UInt32 *indexInArchive /* -1 if there is no in archive, or if doesn't matter */ \ + ) x; \ + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \ + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) x; \ + STDMETHOD(SetOperationResult)(Int32 operationResult) x; \ + +ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback, IProgress, 0x80) +{ + INTERFACE_IArchiveUpdateCallback(PURE); +}; + +#define INTERFACE_IArchiveUpdateCallback2(x) \ + INTERFACE_IArchiveUpdateCallback(x) \ + STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) x; \ + STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) x; \ + +ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82) +{ + INTERFACE_IArchiveUpdateCallback2(PURE); +}; + + +#ifndef EXTRACT_ONLY +#define INTERFACE_IOutArchive(x) \ + STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) x; \ + STDMETHOD(GetFileTimeType)(UInt32 *type) x; +#else +#define INTERFACE_IOutArchive(x) +#endif + +ARCHIVE_INTERFACE(IOutArchive, 0xA0) +{ +#ifndef EXTRACT_ONLY + INTERFACE_IOutArchive(PURE) +#endif +}; + + +ARCHIVE_INTERFACE(ISetProperties, 0x03) +{ +#ifndef EXTRACT_ONLY + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) PURE; +#endif +}; + + +#define IMP_IInArchive_GetProp(k) \ + (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \ + { if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \ + const STATPROPSTG &srcItem = k[index]; \ + *propID = srcItem.propid; *varType = srcItem.vt; *name = 0; return S_OK; } \ + +#define IMP_IInArchive_GetProp_WITH_NAME(k) \ + (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \ + { if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \ + const STATPROPSTG &srcItem = k[index]; \ + *propID = srcItem.propid; *varType = srcItem.vt; \ + if (srcItem.lpwstrName == 0) *name = 0; else *name = ::SysAllocString(srcItem.lpwstrName); return S_OK; } \ + +#define IMP_IInArchive_Props \ + STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \ + { *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \ + STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp(kProps) + +#define IMP_IInArchive_Props_WITH_NAME \ + STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \ + { *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \ + STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kProps) + + +#define IMP_IInArchive_ArcProps \ + STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \ + { *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \ + STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp(kArcProps) + +#define IMP_IInArchive_ArcProps_WITH_NAME \ + STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \ + { *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \ + STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kArcProps) + +#define IMP_IInArchive_ArcProps_NO \ + STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \ + { *numProperties = 0; return S_OK; } \ + STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *) \ + { return E_NOTIMPL; } \ + STDMETHODIMP CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value) \ + { value->vt = VT_EMPTY; return S_OK; } + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhCRC.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhCRC.cpp new file mode 100644 index 000000000..0afeb7102 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhCRC.cpp @@ -0,0 +1,43 @@ +// LzhCRC.cpp + +#include "StdAfx.h" + +#include "LzhCRC.h" + +namespace NArchive { +namespace NLzh { + +static const UInt16 kCRCPoly = 0xA001; + +UInt16 CCRC::Table[256]; + +void CCRC::InitTable() +{ + for (UInt32 i = 0; i < 256; i++) + { + UInt32 r = i; + for (int j = 0; j < 8; j++) + if (r & 1) + r = (r >> 1) ^ kCRCPoly; + else + r >>= 1; + CCRC::Table[i] = (UInt16)r; + } +} + +class CCRCTableInit +{ +public: + CCRCTableInit() { CCRC::InitTable(); } +} g_CRCTableInit; + +void CCRC::Update(const void *data, size_t size) +{ + UInt16 v = _value; + const Byte *p = (const Byte *)data; + for (; size > 0; size--, p++) + v = (UInt16)(Table[((Byte)(v)) ^ *p] ^ (v >> 8)); + _value = v; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhCRC.h b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhCRC.h new file mode 100644 index 000000000..aaa647baf --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhCRC.h @@ -0,0 +1,27 @@ +// LzhCRC.h + +#ifndef __LZH_CRC_H +#define __LZH_CRC_H + +#include +#include "Common/Types.h" + +namespace NArchive { +namespace NLzh { + +class CCRC +{ + UInt16 _value; +public: + static UInt16 Table[256]; + static void InitTable(); + + CCRC(): _value(0){}; + void Init() { _value = 0; } + void Update(const void *data, size_t size); + UInt16 GetDigest() const { return _value; } +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhHandler.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhHandler.cpp new file mode 100644 index 000000000..b15ffd1bc --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhHandler.cpp @@ -0,0 +1,387 @@ +// LzhHandler.cpp + +#include "StdAfx.h" + +#include "Common/ComTry.h" +#include "Common/Defs.h" +#include "Common/StringConvert.h" + +#include "Windows/PropVariant.h" +#include "Windows/Time.h" + +#include "LzhHandler.h" +#include "LzhOutStreamWithCRC.h" + +#include "../../ICoder.h" + +#include "../../Common/LimitedStreams.h" +#include "../../Common/ProgressUtils.h" + +#include "../../Compress/CopyCoder.h" +#include "../../Compress/LzhDecoder.h" + +#include "../Common/ItemNameUtils.h" + +using namespace NWindows; +using namespace NTime; + +namespace NArchive { +namespace NLzh{ + +struct COsPair +{ + Byte Id; + const wchar_t *Name; +}; + +COsPair g_OsPairs[] = +{ + { 'M', L"MS-DOS" }, + { '2', L"OS/2" }, + { '9', L"OS9" }, + { 'K', L"OS/68K" }, + { '3', L"OS/386" }, + { 'H', L"HUMAN" }, + { 'U', L"UNIX" }, + { 'C', L"CP/M" }, + { 'F', L"FLEX" }, + { 'm', L"Mac" }, + { 'R', L"Runser" }, + { 'T', L"TownsOS" }, + { 'X', L"XOSK" }, + { 'w', L"Windows95" }, + { 'W', L"WindowsNT" }, + { 0, L"MS-DOS" }, + { 'J', L"Java VM" } +}; + +const wchar_t *kUnknownOS = L"Unknown"; + +const int kNumHostOSes = sizeof(g_OsPairs) / sizeof(g_OsPairs[0]); + +static const wchar_t *GetOS(Byte osId) +{ + for (int i = 0; i < kNumHostOSes; i++) + if (g_OsPairs[i].Id == osId) + return g_OsPairs[i].Name; + return kUnknownOS; +}; + +STATPROPSTG kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsDir, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME}, + { NULL, kpidAttrib, VT_UI4}, + + // { NULL, kpidCommented, VT_BOOL}, + + { NULL, kpidCRC, VT_UI4}, + + { NULL, kpidMethod, VT_UI1}, + { NULL, kpidHostOS, VT_BSTR} + +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO + +CHandler::CHandler() {} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _items.Size(); + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + const CItemEx &item = _items[index]; + switch(propID) + { + case kpidPath: + { + UString s = NItemName::WinNameToOSName(MultiByteToUnicodeString(item.GetName(), CP_OEMCP)); + if (!s.IsEmpty()) + { + if (s[s.Length() - 1] == WCHAR_PATH_SEPARATOR) + s.Delete(s.Length() - 1); + prop = s; + } + break; + } + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: prop = item.Size; break; + case kpidPackSize: prop = item.PackSize; break; + case kpidCRC: prop = (UInt32)item.CRC; break; + case kpidHostOS: prop = GetOS(item.OsId); break; + case kpidMTime: + { + FILETIME utcFileTime; + UInt32 unixTime; + if (item.GetUnixTime(unixTime)) + NTime::UnixTimeToFileTime(unixTime, utcFileTime); + else + { + FILETIME localFileTime; + if (DosTimeToFileTime(item.ModifiedTime, localFileTime)) + { + if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + } + else + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + } + prop = utcFileTime; + break; + } + /* + case kpidAttrib: prop = (UInt32)item.Attributes; break; + case kpidCommented: prop = item.IsCommented(); break; + */ + case kpidMethod: + { + wchar_t method2[kMethodIdSize + 1]; + method2[kMethodIdSize] = 0; + for (int i = 0; i < kMethodIdSize; i++) + method2[i] = item.Method[i]; + prop = method2; + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +/* +class CProgressImp: public CProgressVirt +{ +public: + CMyComPtr Callback; + STDMETHOD(SetCompleted)(const UInt64 *numFiles); +}; + +STDMETHODIMP CProgressImp::SetCompleted(const UInt64 *numFiles) +{ + if (Callback) + return Callback->SetCompleted(numFiles, NULL); + return S_OK; +} +*/ + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback *callback) +{ + COM_TRY_BEGIN + try + { + _items.Clear(); + CInArchive archive; + + UInt64 endPos = 0; + bool needSetTotal = true; + + if (callback != NULL) + { + RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); + RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); + } + + RINOK(archive.Open(stream)); + for (;;) + { + CItemEx item; + bool filled; + HRESULT result = archive.GetNextItem(filled, item); + if (result == S_FALSE) + return S_FALSE; + if (result != S_OK) + return S_FALSE; + if (!filled) + break; + _items.Add(item); + archive.Skeep(item.PackSize); + if (callback != NULL) + { + if (needSetTotal) + { + RINOK(callback->SetTotal(NULL, &endPos)); + needSetTotal = false; + } + if (_items.Size() % 100 == 0) + { + UInt64 numFiles = _items.Size(); + UInt64 numBytes = item.DataPosition; + RINOK(callback->SetCompleted(&numFiles, &numBytes)); + } + } + } + if (_items.IsEmpty()) + return S_FALSE; + + _stream = stream; + } + catch(...) + { + return S_FALSE; + } + COM_TRY_END + return S_OK; +} + +STDMETHODIMP CHandler::Close() +{ + _items.Clear(); + _stream.Release(); + return S_OK; +} + + + +////////////////////////////////////// +// CHandler::DecompressItems + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool testMode = (testModeSpec != 0); + UInt64 totalUnPacked = 0, totalPacked = 0; + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = _items.Size(); + if(numItems == 0) + return S_OK; + UInt32 i; + for(i = 0; i < numItems; i++) + { + const CItemEx &item = _items[allFilesMode ? i : indices[i]]; + totalUnPacked += item.Size; + totalPacked += item.PackSize; + } + extractCallback->SetTotal(totalUnPacked); + + UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0; + UInt64 currentItemUnPacked, currentItemPacked; + + NCompress::NLzh::NDecoder::CCoder *lzhDecoderSpec = 0; + CMyComPtr lzhDecoder; + CMyComPtr lzh1Decoder; + CMyComPtr arj2Decoder; + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr copyCoder = copyCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStream(streamSpec); + streamSpec->SetStream(_stream); + + for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked, + currentTotalPacked += currentItemPacked) + { + currentItemUnPacked = 0; + currentItemPacked = 0; + + lps->InSize = currentTotalPacked; + lps->OutSize = currentTotalUnPacked; + RINOK(lps->SetCur()); + + CMyComPtr realOutStream; + Int32 askMode; + askMode = testMode ? NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + Int32 index = allFilesMode ? i : indices[i]; + const CItemEx &item = _items[index]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + + if (item.IsDir()) + { + // if (!testMode) + { + RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + } + continue; + } + + if (!testMode && (!realOutStream)) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)); + currentItemUnPacked = item.Size; + currentItemPacked = item.PackSize; + + { + COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; + CMyComPtr outStream(outStreamSpec); + outStreamSpec->Init(realOutStream); + realOutStream.Release(); + + UInt64 pos; + _stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos); + + streamSpec->Init(item.PackSize); + + HRESULT result = S_OK; + Int32 opRes = NExtract::NOperationResult::kOK; + + if (item.IsCopyMethod()) + { + result = copyCoder->Code(inStream, outStream, NULL, NULL, progress); + if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize) + result = S_FALSE; + } + else if (item.IsLh4GroupMethod()) + { + if (!lzhDecoder) + { + lzhDecoderSpec = new NCompress::NLzh::NDecoder::CCoder; + lzhDecoder = lzhDecoderSpec; + } + lzhDecoderSpec->SetDictionary(item.GetNumDictBits()); + result = lzhDecoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress); + } + /* + else if (item.IsLh1GroupMethod()) + { + if (!lzh1Decoder) + { + lzh1DecoderSpec = new NCompress::NLzh1::NDecoder::CCoder; + lzh1Decoder = lzh1DecoderSpec; + } + lzh1DecoderSpec->SetDictionary(item.GetNumDictBits()); + result = lzh1Decoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress); + } + */ + else + opRes = NExtract::NOperationResult::kUnSupportedMethod; + + if (opRes == NExtract::NOperationResult::kOK) + { + if (result == S_FALSE) + opRes = NExtract::NOperationResult::kDataError; + else + { + RINOK(result); + if (outStreamSpec->GetCRC() != item.CRC) + opRes = NExtract::NOperationResult::kCRCError; + } + } + outStream.Release(); + RINOK(extractCallback->SetOperationResult(opRes)); + } + } + return S_OK; + COM_TRY_END +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhHandler.h b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhHandler.h new file mode 100644 index 000000000..6d31df534 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhHandler.h @@ -0,0 +1,30 @@ +// LzhHandler.h + +#ifndef __LZH_HANDLER_H +#define __LZH_HANDLER_H + +#include "Common/MyCom.h" +#include "../IArchive.h" +#include "LzhIn.h" + +namespace NArchive { +namespace NLzh { + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1(IInArchive) + + INTERFACE_IInArchive(;) + + CHandler(); +private: + CObjectVector _items; + CMyComPtr _stream; +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhHeader.h b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhHeader.h new file mode 100644 index 000000000..1c758a14b --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhHeader.h @@ -0,0 +1,19 @@ +// Archive/Lzh/Header.h + +#ifndef __ARCHIVE_LZH_HEADER_H +#define __ARCHIVE_LZH_HEADER_H + +#include "Common/Types.h" + +namespace NArchive { +namespace NLzh { + +const int kMethodIdSize = 5; + +const Byte kExtIdFileName = 0x01; +const Byte kExtIdDirName = 0x02; +const Byte kExtIdUnixTime = 0x54; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhIn.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhIn.cpp new file mode 100644 index 000000000..56b62a943 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhIn.cpp @@ -0,0 +1,172 @@ +// Archive/LzhIn.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/Buffer.h" + +#include "../../Common/StreamUtils.h" + +#include "LzhIn.h" + +namespace NArchive { +namespace NLzh { + +HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize) +{ + size_t realProcessedSize = size; + RINOK(ReadStream(m_Stream, data, &realProcessedSize)); + processedSize = (UInt32)realProcessedSize; + m_Position += processedSize; + return S_OK; +} + +HRESULT CInArchive::CheckReadBytes(void *data, UInt32 size) +{ + UInt32 processedSize; + RINOK(ReadBytes(data, size, processedSize)); + return (processedSize == size) ? S_OK: S_FALSE; +} + +HRESULT CInArchive::Open(IInStream *inStream) +{ + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position)); + m_Stream = inStream; + return S_OK; +} + +static const Byte *ReadUInt32(const Byte *p, UInt32 &v) +{ + v = 0; + for (int i = 0; i < 4; i++) + v |= ((UInt32)(*p++) << (i * 8)); + return p; +} + +static const Byte *ReadUInt16(const Byte *p, UInt16 &v) +{ + v = 0; + for (int i = 0; i < 2; i++) + v |= ((UInt16)(*p++) << (i * 8)); + return p; +} + +static const Byte *ReadString(const Byte *p, size_t size, AString &s) +{ + s.Empty(); + for (size_t i = 0; i < size; i++) + { + char c = p[i]; + if (c == 0) + break; + s += c; + } + return p + size; +} + +static Byte CalcSum(const Byte *data, size_t size) +{ + Byte sum = 0; + for (size_t i = 0; i < size; i++) + sum = (Byte)(sum + data[i]); + return sum; +} + +HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) +{ + filled = false; + + UInt32 processedSize; + Byte startHeader[2]; + RINOK(ReadBytes(startHeader, 2, processedSize)) + if (processedSize == 0) + return S_OK; + if (processedSize == 1) + return (startHeader[0] == 0) ? S_OK: S_FALSE; + if (startHeader[0] == 0 && startHeader[1] == 0) + return S_OK; + + Byte header[256]; + const UInt32 kBasicPartSize = 22; + RINOK(ReadBytes(header, kBasicPartSize, processedSize)); + if (processedSize != kBasicPartSize) + return (startHeader[0] == 0) ? S_OK: S_FALSE; + + const Byte *p = header; + memmove(item.Method, p, kMethodIdSize); + if (!item.IsValidMethod()) + return S_OK; + p += kMethodIdSize; + p = ReadUInt32(p, item.PackSize); + p = ReadUInt32(p, item.Size); + p = ReadUInt32(p, item.ModifiedTime); + item.Attributes = *p++; + item.Level = *p++; + if (item.Level > 2) + return S_FALSE; + UInt32 headerSize; + if (item.Level < 2) + { + headerSize = startHeader[0]; + if (headerSize < kBasicPartSize) + return S_FALSE; + UInt32 remain = headerSize - kBasicPartSize; + RINOK(CheckReadBytes(header + kBasicPartSize, remain)); + if (startHeader[1] != CalcSum(header, headerSize)) + return S_FALSE; + size_t nameLength = *p++; + if ((p - header) + nameLength + 2 > headerSize) + return S_FALSE; + p = ReadString(p, nameLength, item.Name); + } + else + headerSize = startHeader[0] | ((UInt32)startHeader[1] << 8); + p = ReadUInt16(p, item.CRC); + if (item.Level != 0) + { + if (item.Level == 2) + { + RINOK(CheckReadBytes(header + kBasicPartSize, 2)); + } + if ((size_t)(p - header) + 3 > headerSize) + return S_FALSE; + item.OsId = *p++; + UInt16 nextSize; + p = ReadUInt16(p, nextSize); + while (nextSize != 0) + { + if (nextSize < 3) + return S_FALSE; + if (item.Level == 1) + { + if (item.PackSize < nextSize) + return S_FALSE; + item.PackSize -= nextSize; + } + CExtension ext; + RINOK(CheckReadBytes(&ext.Type, 1)) + nextSize -= 3; + ext.Data.SetCapacity(nextSize); + RINOK(CheckReadBytes((Byte *)ext.Data, nextSize)) + item.Extensions.Add(ext); + Byte hdr2[2]; + RINOK(CheckReadBytes(hdr2, 2)); + ReadUInt16(hdr2, nextSize); + } + } + item.DataPosition = m_Position; + filled = true; + return S_OK; +} + +HRESULT CInArchive::Skeep(UInt64 numBytes) +{ + UInt64 newPostion; + RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion)); + m_Position += numBytes; + if (m_Position != newPostion) + return E_FAIL; + return S_OK; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhIn.h b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhIn.h new file mode 100644 index 000000000..a8c639801 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhIn.h @@ -0,0 +1,29 @@ +// Archive/LzhIn.h + +#ifndef __ARCHIVE_LZHIN_H +#define __ARCHIVE_LZHIN_H + +#include "Common/MyCom.h" +#include "../../IStream.h" + +#include "LzhItem.h" + +namespace NArchive { +namespace NLzh { + +class CInArchive +{ + CMyComPtr m_Stream; + UInt64 m_Position; + + HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize); + HRESULT CheckReadBytes(void *data, UInt32 size); +public: + HRESULT Open(IInStream *inStream); + HRESULT GetNextItem(bool &filled, CItemEx &itemInfo); + HRESULT Skeep(UInt64 numBytes); +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhItem.h b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhItem.h new file mode 100644 index 000000000..ca85a5153 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhItem.h @@ -0,0 +1,172 @@ +// Archive/LzhItem.h + +#ifndef __ARCHIVE_LZH_ITEM_H +#define __ARCHIVE_LZH_ITEM_H + +#include "Common/Types.h" +#include "Common/MyString.h" +#include "Common/Buffer.h" +#include "LzhHeader.h" + +namespace NArchive { +namespace NLzh { + +struct CExtension +{ + Byte Type; + CByteBuffer Data; + AString GetString() const + { + AString s; + for (size_t i = 0; i < Data.GetCapacity(); i++) + { + char c = (char)Data[i]; + if (c == 0) + break; + s += c; + } + return s; + } +}; + +struct CItem +{ +public: + AString Name; + Byte Method[kMethodIdSize]; + UInt32 PackSize; + UInt32 Size; + UInt32 ModifiedTime; + Byte Attributes; + Byte Level; + UInt16 CRC; + Byte OsId; + CObjectVector Extensions; + + bool IsValidMethod() const { return (Method[0] == '-' && Method[1] == 'l' && Method[4] == '-'); } + bool IsLhMethod() const {return (IsValidMethod() && Method[2] == 'h'); } + bool IsDir() const {return (IsLhMethod() && Method[3] == 'd'); } + + bool IsCopyMethod() const + { + return (IsLhMethod() && Method[3] == '0') || + (IsValidMethod() && Method[2] == 'z' && Method[3] == '4'); + } + + bool IsLh1GroupMethod() const + { + if (!IsLhMethod()) + return false; + switch(Method[3]) + { + case '1': + return true; + } + return false; + } + + bool IsLh4GroupMethod() const + { + if (!IsLhMethod()) + return false; + switch(Method[3]) + { + case '4': + case '5': + case '6': + case '7': + return true; + } + return false; + } + + int GetNumDictBits() const + { + if (!IsLhMethod()) + return 0; + switch(Method[3]) + { + case '1': + return 12; + case '2': + return 13; + case '3': + return 13; + case '4': + return 12; + case '5': + return 13; + case '6': + return 15; + case '7': + return 16; + } + return 0; + } + + int FindExt(Byte type) const + { + for (int i = 0; i < Extensions.Size(); i++) + if (Extensions[i].Type == type) + return i; + return -1; + } + bool GetUnixTime(UInt32 &value) const + { + int index = FindExt(kExtIdUnixTime); + if (index < 0) + { + if (Level == 2) + { + value = ModifiedTime; + return true; + } + return false; + } + const Byte *data = (const Byte *)(Extensions[index].Data); + value = data[0] | + ((UInt32)data[1] << 8) | + ((UInt32)data[2] << 16) | + ((UInt32)data[3] << 24); + return true; + } + + AString GetDirName() const + { + int index = FindExt(kExtIdDirName); + if (index < 0) + return AString(); + return Extensions[index].GetString(); + } + + AString GetFileName() const + { + int index = FindExt(kExtIdFileName); + if (index < 0) + return Name; + return Extensions[index].GetString(); + } + + AString GetName() const + { + AString dirName = GetDirName(); + dirName.Replace((char)(unsigned char)0xFF, '\\'); + if (!dirName.IsEmpty()) + { + char c = dirName[dirName.Length() - 1]; + if (c != '\\') + dirName += '\\'; + } + return dirName + GetFileName(); + } +}; + +class CItemEx: public CItem +{ +public: + UInt64 DataPosition; +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp new file mode 100644 index 000000000..3cd632aa7 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp @@ -0,0 +1,27 @@ +// LzhOutStreamWithCRC.cpp + +#include "StdAfx.h" + +#include "LzhOutStreamWithCRC.h" + +namespace NArchive { +namespace NLzh { + +STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result; + if(!_stream) + { + realProcessedSize = size; + result = S_OK; + } + else + result = _stream->Write(data, size, &realProcessedSize); + _crc.Update(data, realProcessedSize); + if(processedSize != NULL) + *processedSize = realProcessedSize; + return result; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.h b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.h new file mode 100644 index 000000000..eee15d0e2 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.h @@ -0,0 +1,38 @@ +// LzhOutStreamWithCRC.h + +#ifndef __LZHOUTSTREAMWITHCRC_H +#define __LZHOUTSTREAMWITHCRC_H + +#include "LzhCRC.h" +#include "../../../Common/MyCom.h" +#include "../../IStream.h" + +namespace NArchive { +namespace NLzh { + +class COutStreamWithCRC: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +private: + CCRC _crc; + CMyComPtr _stream; +public: + void Init(ISequentialOutStream *stream) + { + _stream = stream; + _crc.Init(); + } + void ReleaseStream() { _stream.Release(); } + UInt32 GetCRC() const { return _crc.GetDigest(); } + void InitCRC() { _crc.Init(); } + +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhRegister.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhRegister.cpp new file mode 100644 index 000000000..b83d2ee6c --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/LzhRegister.cpp @@ -0,0 +1,13 @@ +// LzhRegister.cpp + +#include "StdAfx.h" + +#include "../../Common/RegisterArc.h" + +#include "LzhHandler.h" +static IInArchive *CreateArc() { return new NArchive::NLzh::CHandler; } + +static CArcInfo g_ArcInfo = + { L"Lzh", L"lzh lha", 0, 6, { '-', 'l' }, 2, false, CreateArc, 0 }; + +REGISTER_ARC(Lzh) diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/StdAfx.h b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/StdAfx.h new file mode 100644 index 000000000..83fdd22d5 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzh/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaArcRegister.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaArcRegister.cpp new file mode 100644 index 000000000..867bc78ff --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaArcRegister.cpp @@ -0,0 +1,14 @@ +// LzmaArcRegister.cpp + +#include "StdAfx.h" + +#include "../../Common/RegisterArc.h" + +#include "LzmaHandler.h" + +static IInArchive *CreateArc() { return new NArchive::NLzma::CHandler; } + +static CArcInfo g_ArcInfo = + { L"Lzma", L"lzma lzma86", 0, 0xA, {0 }, 0, true, CreateArc, NULL }; + +REGISTER_ARC(Lzma) diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.cpp new file mode 100644 index 000000000..2ab3dbf4b --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.cpp @@ -0,0 +1,86 @@ +// LzmaFiltersDecode.cpp + +#include "StdAfx.h" + +#include "LzmaFiltersDecode.h" + +namespace NArchive { +namespace NLzma { + +static const UInt64 k_LZMA = 0x030101; +static const UInt64 k_BCJ = 0x03030103; + +HRESULT CDecoder::Code( + DECL_EXTERNAL_CODECS_LOC_VARS + const CHeader &block, + ISequentialInStream *inStream, ISequentialOutStream *outStream, + UInt64 *inProcessedSize, ICompressProgressInfo *progress) +{ + *inProcessedSize = (UInt64)(Int64)-1; + + if (block.FilterMethod > 1) + return E_NOTIMPL; + + if (!_lzmaDecoder) + { + RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS k_LZMA, _lzmaDecoder, false)); + if (_lzmaDecoder == 0) + return E_NOTIMPL; + } + + { + CMyComPtr setDecoderProperties; + _lzmaDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties); + if (!setDecoderProperties) + return E_NOTIMPL; + RINOK(setDecoderProperties->SetDecoderProperties2(block.LzmaProps, 5)); + } + + bool filteredMode = (block.FilterMethod == 1); + + CMyComPtr setOutStream; + + if (filteredMode) + { + if (!_bcjStream) + { + CMyComPtr coder; + RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS k_BCJ, coder, false)); + if (!coder) + return E_NOTIMPL; + coder.QueryInterface(IID_ISequentialOutStream, &_bcjStream); + if (!_bcjStream) + return E_NOTIMPL; + } + + _bcjStream.QueryInterface(IID_ICompressSetOutStream, &setOutStream); + if (!setOutStream) + return E_NOTIMPL; + RINOK(setOutStream->SetOutStream(outStream)); + outStream = _bcjStream; + } + + const UInt64 *unpackSize = block.HasUnpackSize() ? &block.UnpackSize : NULL; + RINOK(_lzmaDecoder->Code(inStream, outStream, NULL, unpackSize, progress)); + + if (filteredMode) + { + CMyComPtr flush; + _bcjStream.QueryInterface(IID_IOutStreamFlush, &flush); + if (flush) + { + RINOK(flush->Flush()); + } + RINOK(setOutStream->ReleaseOutStream()); + } + + CMyComPtr getInStreamProcessedSize; + _lzmaDecoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, &getInStreamProcessedSize); + if (getInStreamProcessedSize) + { + RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(inProcessedSize)); + } + return S_OK; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.h b/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.h new file mode 100644 index 000000000..b966b422a --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaFiltersDecode.h @@ -0,0 +1,26 @@ +// LzmaFiltersDecode.h + +#ifndef __LZMA_FILTERS_DECODE_H +#define __LZMA_FILTERS_DECODE_H + +#include "../../Common/CreateCoder.h" + +#include "LzmaItem.h" + +namespace NArchive { +namespace NLzma { + +class CDecoder +{ + CMyComPtr _lzmaDecoder; + CMyComPtr _bcjStream; +public: + HRESULT Code(DECL_EXTERNAL_CODECS_LOC_VARS + const CHeader &block, + ISequentialInStream *inStream, ISequentialOutStream *outStream, + UInt64 *inProcessedSize, ICompressProgressInfo *progress); +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaHandler.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaHandler.cpp new file mode 100644 index 000000000..249fd90fa --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaHandler.cpp @@ -0,0 +1,243 @@ +// LzmaHandler.cpp + +#include "StdAfx.h" + +#include "LzmaHandler.h" + +#include "Common/Defs.h" +#include "Common/StringConvert.h" +#include "Common/ComTry.h" +#include "Common/IntToString.h" + +#include "Windows/PropVariant.h" + +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamUtils.h" +#include "../Common/DummyOutStream.h" + +#include "LzmaFiltersDecode.h" + +namespace NArchive { +namespace NLzma { + +STATPROPSTG kProps[] = +{ + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMethod, VT_UI1} +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = 1; + return S_OK; +} + +static void ConvertUInt32ToString(UInt32 value, wchar_t *s) +{ + ConvertUInt64ToString(value, s + MyStringLen(s)); +} + +static void DictSizeToString(UInt32 value, wchar_t *s) +{ + for (int i = 0; i <= 31; i++) + if ((UInt32(1) << i) == value) + { + ConvertUInt32ToString(i, s); + return; + } + wchar_t c = L'b'; + if ((value & ((1 << 20) - 1)) == 0) + { + value >>= 20; + c = L'm'; + } + else if ((value & ((1 << 10) - 1)) == 0) + { + value >>= 10; + c = L'k'; + } + ConvertUInt32ToString(value, s); + int p = MyStringLen(s); + s[p++] = c; + s[p++] = L'\0'; +} + +static void MyStrCat(wchar_t *d, const wchar_t *s) +{ + MyStringCopy(d + MyStringLen(d), s); +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + if (index != 0) + return E_INVALIDARG; + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case kpidSize: + if (m_StreamInfo.HasUnpackSize()) + propVariant = (UInt64)m_StreamInfo.UnpackSize; + break; + case kpidPackSize: + propVariant = (UInt64)m_PackSize; + break; + case kpidMethod: + { + wchar_t s[64]; + s[0] = '\0'; + if (m_StreamInfo.IsThereFilter) + { + const wchar_t *f; + if (m_StreamInfo.FilterMethod == 0) + f = L"Copy"; + else if (m_StreamInfo.FilterMethod == 1) + f = L"BCJ"; + else + f = L"Unknown"; + MyStrCat(s, f); + MyStrCat(s, L" "); + } + MyStrCat(s, L"LZMA:"); + DictSizeToString(m_StreamInfo.GetDicSize(), s); + propVariant = s; + break; + } + } + propVariant.Detach(value); + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */) +{ + { + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition)); + + HRESULT res = ReadStreamHeader(inStream, m_StreamInfo); + if (res != S_OK) + return S_FALSE; + + Byte b; + RINOK(ReadStream_FALSE(inStream, &b, 1)); + if (b != 0) + return S_FALSE; + + UInt64 endPos; + RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos)); + m_PackSize = endPos - m_StreamStartPosition - m_StreamInfo.GetHeaderSize(); + + m_Stream = inStream; + } + return S_OK; +} + +STDMETHODIMP CHandler::Close() +{ + m_Stream.Release(); + return S_OK; +} + + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool allFilesMode = (numItems == UInt32(-1)); + if (!allFilesMode) + { + if (numItems == 0) + return S_OK; + if (numItems != 1) + return E_INVALIDARG; + if (indices[0] != 0) + return E_INVALIDARG; + } + + bool testMode = (_aTestMode != 0); + + RINOK(extractCallback->SetTotal(m_PackSize)); + + UInt64 currentTotalPacked = 0; + + CDummyOutStream *outStreamSpec = new CDummyOutStream; + CMyComPtr outStream(outStreamSpec); + + { + CMyComPtr realOutStream; + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); + + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(); + if(!testMode && !realOutStream) + return S_OK; + extractCallback->PrepareOperation(askMode); + } + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, true); + + CDecoder decoder; + RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL)); + UInt64 streamPos = m_StreamStartPosition; + Int32 opRes = NArchive::NExtract::NOperationResult::kOK; + bool firstItem = true; + for (;;) + { + CHeader st; + HRESULT result = ReadStreamHeader(m_Stream, st); + if (result != S_OK) + { + if (firstItem) + return E_FAIL; + break; + } + firstItem = false; + + lps->OutSize = outStreamSpec->GetSize(); + lps->InSize = currentTotalPacked; + RINOK(lps->SetCur()); + + streamPos += st.GetHeaderSize(); + UInt64 packProcessed; + + { + result = decoder.Code( + EXTERNAL_CODECS_VARS + st, m_Stream, outStream, &packProcessed, progress); + if (result == E_NOTIMPL) + { + opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + break; + } + if (result == S_FALSE) + { + opRes = NArchive::NExtract::NOperationResult::kDataError; + break; + } + RINOK(result); + } + + if (packProcessed == (UInt64)(Int64)-1) + break; + RINOK(m_Stream->Seek(streamPos + packProcessed, STREAM_SEEK_SET, NULL)); + currentTotalPacked += packProcessed; + streamPos += packProcessed; + } + outStream.Release(); + return extractCallback->SetOperationResult(opRes); + COM_TRY_END +} + +IMPL_ISetCompressCodecsInfo + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaHandler.h b/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaHandler.h new file mode 100644 index 000000000..bbf11a46b --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaHandler.h @@ -0,0 +1,69 @@ +// Lzma/Handler.h + +#ifndef __GZIP_HANDLER_H +#define __GZIP_HANDLER_H + +#include "Common/MyCom.h" + +#include "../IArchive.h" +#include "../../Common/CreateCoder.h" + +#include "LzmaIn.h" + +namespace NArchive { +namespace NLzma { + +// const UInt64 k_LZMA = 0x030101; + +class CHandler: + public IInArchive, + PUBLIC_ISetCompressCodecsInfo + public CMyUnknownImp +{ +public: + MY_QUERYINTERFACE_BEGIN + MY_QUERYINTERFACE_ENTRY(IInArchive) + QUERY_ENTRY_ISetCompressCodecsInfo + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + STDMETHOD(Open)(IInStream *inStream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); + STDMETHOD(Close)(); + + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + UString GetMethodString(); +public: + CHandler() { } + +private: + CHeader m_StreamInfo; + UInt64 m_StreamStartPosition; + UInt64 m_PackSize; + + CMyComPtr m_Stream; + + DECL_EXTERNAL_CODECS_VARS + + DECL_ISetCompressCodecsInfo + +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaIn.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaIn.cpp new file mode 100644 index 000000000..7d2475c75 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaIn.cpp @@ -0,0 +1,56 @@ +// Archive/LzmaIn.cpp + +#include "StdAfx.h" + +#include "LzmaIn.h" + +#include "../../Common/StreamUtils.h" + +namespace NArchive { +namespace NLzma { + +static bool CheckDictSize(const Byte *p) +{ + UInt32 dicSize = GetUi32(p); + int i; + for (i = 1; i <= 30; i++) + if (dicSize == ((UInt32)2 << i) || dicSize == ((UInt32)3 << i)) + return true; + return false; +} + +HRESULT ReadStreamHeader(ISequentialInStream *inStream, CHeader &block) +{ + Byte sig[5 + 9]; + RINOK(ReadStream_FALSE(inStream, sig, 5 + 8)); + + const Byte kMaxProp0Val = 5 * 5 * 9 - 1; + if (sig[0] > kMaxProp0Val) + return S_FALSE; + + for (int i = 0; i < 5; i++) + block.LzmaProps[i] = sig[i]; + + block.IsThereFilter = false; + block.FilterMethod = 0; + + if (!CheckDictSize(sig + 1)) + { + if (sig[0] > 1 || sig[1] > kMaxProp0Val) + return S_FALSE; + block.IsThereFilter = true; + block.FilterMethod = sig[0]; + for (int i = 0; i < 5; i++) + block.LzmaProps[i] = sig[i + 1]; + if (!CheckDictSize(block.LzmaProps + 1)) + return S_FALSE; + RINOK(ReadStream_FALSE(inStream, sig + 5 + 8, 1)); + } + UInt32 unpOffset = 5 + (block.IsThereFilter ? 1 : 0); + block.UnpackSize = GetUi64(sig + unpOffset); + if (block.HasUnpackSize() && block.UnpackSize >= ((UInt64)1 << 56)) + return S_FALSE; + return S_OK; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaIn.h b/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaIn.h new file mode 100644 index 000000000..6f5c24c0e --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaIn.h @@ -0,0 +1,16 @@ +// Archive/LzmaIn.h + +#ifndef __ARCHIVE_LZMA_IN_H +#define __ARCHIVE_LZMA_IN_H + +#include "LzmaItem.h" +#include "../../IStream.h" + +namespace NArchive { +namespace NLzma { + +HRESULT ReadStreamHeader(ISequentialInStream *inStream, CHeader &st); + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaItem.h b/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaItem.h new file mode 100644 index 000000000..1bfadf727 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/LzmaItem.h @@ -0,0 +1,27 @@ +// Archive/LzmaItem.h + +#ifndef __ARCHIVE_LZMA_ITEM_H +#define __ARCHIVE_LZMA_ITEM_H + +#include "Common/Types.h" + +#include "../../../../C/CpuArch.h" + +namespace NArchive { +namespace NLzma { + +struct CHeader +{ + UInt64 UnpackSize; + bool IsThereFilter; + Byte FilterMethod; + Byte LzmaProps[5]; + + UInt32 GetDicSize() const { return GetUi32(LzmaProps + 1); } + bool HasUnpackSize() const { return (UnpackSize != (UInt64)(Int64)-1); } + unsigned GetHeaderSize() const { return 5 + 8 + (IsThereFilter ? 1 : 0); } +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/StdAfx.h b/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/StdAfx.h new file mode 100644 index 000000000..83fdd22d5 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Lzma/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarHandler.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarHandler.cpp new file mode 100644 index 000000000..3bd17b6db --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarHandler.cpp @@ -0,0 +1,835 @@ +// RarHandler.cpp + +#include "StdAfx.h" + +#include "Common/ComTry.h" +#include "Common/IntToString.h" +#include "Common/StringConvert.h" + +#include "Windows/PropVariant.h" +#include "Windows/Time.h" + +#include "../../IPassword.h" + +#include "../../Common/CreateCoder.h" +#include "../../Common/FilterCoder.h" +#include "../../Common/MethodId.h" +#include "../../Common/ProgressUtils.h" + +#include "../../Compress/CopyCoder.h" + +#include "../../Crypto/Rar20Crypto.h" +#include "../../Crypto/RarAes.h" + +#include "../Common/ItemNameUtils.h" +#include "../Common/OutStreamWithCRC.h" + +#include "RarHandler.h" + +using namespace NWindows; +using namespace NTime; + +namespace NArchive { +namespace NRar { + +static const wchar_t *kHostOS[] = +{ + L"MS DOS", + L"OS/2", + L"Win32", + L"Unix", + L"Mac OS", + L"BeOS" +}; + +static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]); + +static const wchar_t *kUnknownOS = L"Unknown"; + +STATPROPSTG kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsDir, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME}, + { NULL, kpidCTime, VT_FILETIME}, + { NULL, kpidATime, VT_FILETIME}, + { NULL, kpidAttrib, VT_UI4}, + + { NULL, kpidEncrypted, VT_BOOL}, + { NULL, kpidSolid, VT_BOOL}, + { NULL, kpidCommented, VT_BOOL}, + { NULL, kpidSplitBefore, VT_BOOL}, + { NULL, kpidSplitAfter, VT_BOOL}, + { NULL, kpidCRC, VT_UI4}, + { NULL, kpidHostOS, VT_BSTR}, + { NULL, kpidMethod, VT_BSTR}, + { NULL, kpidUnpackVer, VT_UI1} +}; + +STATPROPSTG kArcProps[] = +{ + { NULL, kpidSolid, VT_BOOL}, + { NULL, kpidNumBlocks, VT_UI4}, + // { NULL, kpidEncrypted, VT_BOOL}, + { NULL, kpidIsVolume, VT_BOOL}, + { NULL, kpidNumVolumes, VT_UI4}, + { NULL, kpidPhySize, VT_UI8} + // { NULL, kpidCommented, VT_BOOL} +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +UInt64 CHandler::GetPackSize(int refIndex) const +{ + const CRefItem &refItem = _refItems[refIndex]; + UInt64 totalPackSize = 0; + for (int i = 0; i < refItem.NumItems; i++) + totalPackSize += _items[refItem.ItemIndex + i].PackSize; + return totalPackSize; +} + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + // COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidSolid: prop = _archiveInfo.IsSolid(); break; + // case kpidEncrypted: prop = _archiveInfo.IsEncrypted(); break; // it's for encrypted names. + case kpidIsVolume: prop = _archiveInfo.IsVolume(); break; + case kpidNumVolumes: prop = (UInt32)_archives.Size(); break; + case kpidOffset: if (_archiveInfo.StartPosition != 0) prop = _archiveInfo.StartPosition; break; + // case kpidCommented: prop = _archiveInfo.IsCommented(); break; + case kpidNumBlocks: + { + UInt32 numBlocks = 0; + for (int i = 0; i < _refItems.Size(); i++) + if (!IsSolid(i)) + numBlocks++; + prop = (UInt32)numBlocks; + break; + } + } + prop.Detach(value); + return S_OK; + // COM_TRY_END +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _refItems.Size(); + return S_OK; +} + +static bool RarTimeToFileTime(const CRarTime &rarTime, FILETIME &result) +{ + if (!DosTimeToFileTime(rarTime.DosTime, result)) + return false; + UInt64 value = (((UInt64)result.dwHighDateTime) << 32) + result.dwLowDateTime; + value += (UInt64)rarTime.LowSecond * 10000000; + value += ((UInt64)rarTime.SubTime[2] << 16) + + ((UInt64)rarTime.SubTime[1] << 8) + + ((UInt64)rarTime.SubTime[0]); + result.dwLowDateTime = (DWORD)value; + result.dwHighDateTime = DWORD(value >> 32); + return true; +} + +static void RarTimeToProp(const CRarTime &rarTime, NWindows::NCOM::CPropVariant &prop) +{ + FILETIME localFileTime, utcFileTime; + if (RarTimeToFileTime(rarTime, localFileTime)) + { + if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + } + else + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + prop = utcFileTime; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + const CRefItem &refItem = _refItems[index]; + const CItemEx &item = _items[refItem.ItemIndex]; + switch(propID) + { + case kpidPath: + { + UString u; + if (item.HasUnicodeName() && !item.UnicodeName.IsEmpty()) + u = item.UnicodeName; + else + u = MultiByteToUnicodeString(item.Name, CP_OEMCP); + prop = (const wchar_t *)NItemName::WinNameToOSName(u); + break; + } + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: prop = item.Size; break; + case kpidPackSize: prop = GetPackSize(index); break; + case kpidMTime: RarTimeToProp(item.MTime, prop); break; + case kpidCTime: if (item.CTimeDefined) RarTimeToProp(item.CTime, prop); break; + case kpidATime: if (item.ATimeDefined) RarTimeToProp(item.ATime, prop); break; + case kpidAttrib: prop = item.GetWinAttributes(); break; + case kpidEncrypted: prop = item.IsEncrypted(); break; + case kpidSolid: prop = IsSolid(index); break; + case kpidCommented: prop = item.IsCommented(); break; + case kpidSplitBefore: prop = item.IsSplitBefore(); break; + case kpidSplitAfter: prop = _items[refItem.ItemIndex + refItem.NumItems - 1].IsSplitAfter(); break; + case kpidCRC: + { + const CItemEx &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1]; + prop = ((lastItem.IsSplitAfter()) ? item.FileCRC : lastItem.FileCRC); + break; + } + case kpidUnpackVer: prop = item.UnPackVersion; break; + case kpidMethod: + { + UString method; + if (item.Method >= Byte('0') && item.Method <= Byte('5')) + { + method = L"m"; + wchar_t temp[32]; + ConvertUInt64ToString(item.Method - Byte('0'), temp); + method += temp; + if (!item.IsDir()) + { + method += L":"; + ConvertUInt64ToString(16 + item.GetDictSize(), temp); + method += temp; + } + } + else + { + wchar_t temp[32]; + ConvertUInt64ToString(item.Method, temp); + method += temp; + } + prop = method; + break; + } + case kpidHostOS: prop = (item.HostOS < kNumHostOSes) ? (kHostOS[item.HostOS]) : kUnknownOS; break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +class CVolumeName +{ + bool _first; + bool _newStyle; + UString _unchangedPart; + UString _changedPart; + UString _afterPart; +public: + CVolumeName(): _newStyle(true) {}; + + bool InitName(const UString &name, bool newStyle) + { + _first = true; + _newStyle = newStyle; + int dotPos = name.ReverseFind('.'); + UString basePart = name; + if (dotPos >= 0) + { + UString ext = name.Mid(dotPos + 1); + if (ext.CompareNoCase(L"rar") == 0) + { + _afterPart = name.Mid(dotPos); + basePart = name.Left(dotPos); + } + else if (ext.CompareNoCase(L"exe") == 0) + { + _afterPart = L".rar"; + basePart = name.Left(dotPos); + } + else if (!_newStyle) + { + if (ext.CompareNoCase(L"000") == 0 || ext.CompareNoCase(L"001") == 0) + { + _afterPart.Empty(); + _first = false; + _changedPart = ext; + _unchangedPart = name.Left(dotPos + 1); + return true; + } + } + } + + if (!_newStyle) + { + _afterPart.Empty(); + _unchangedPart = basePart + UString(L"."); + _changedPart = L"r00"; + return true; + } + + int numLetters = 1; + if (basePart.Right(numLetters) == L"1" || basePart.Right(numLetters) == L"0") + { + while (numLetters < basePart.Length()) + { + if (basePart[basePart.Length() - numLetters - 1] != '0') + break; + numLetters++; + } + } + else + return false; + _unchangedPart = basePart.Left(basePart.Length() - numLetters); + _changedPart = basePart.Right(numLetters); + return true; + } + + UString GetNextName() + { + UString newName; + if (_newStyle || !_first) + { + int i; + int numLetters = _changedPart.Length(); + for (i = numLetters - 1; i >= 0; i--) + { + wchar_t c = _changedPart[i]; + if (c == L'9') + { + c = L'0'; + newName = c + newName; + if (i == 0) + newName = UString(L'1') + newName; + continue; + } + c++; + newName = UString(c) + newName; + i--; + for (; i >= 0; i--) + newName = _changedPart[i] + newName; + break; + } + _changedPart = newName; + } + _first = false; + return _unchangedPart + _changedPart + _afterPart; + } +}; + +HRESULT CHandler::Open2(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback) +{ + { + CMyComPtr openVolumeCallback; + CMyComPtr getTextPassword; + CMyComPtr openArchiveCallbackWrap = openArchiveCallback; + + CVolumeName seqName; + + UInt64 totalBytes = 0; + UInt64 curBytes = 0; + + if (openArchiveCallback != NULL) + { + openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback); + openArchiveCallbackWrap.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); + } + + for (;;) + { + CMyComPtr inStream; + if (!_archives.IsEmpty()) + { + if (!openVolumeCallback) + break; + + if(_archives.Size() == 1) + { + if (!_archiveInfo.IsVolume()) + break; + UString baseName; + { + NCOM::CPropVariant prop; + RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); + if (prop.vt != VT_BSTR) + break; + baseName = prop.bstrVal; + } + seqName.InitName(baseName, _archiveInfo.HaveNewVolumeName()); + } + + UString fullName = seqName.GetNextName(); + HRESULT result = openVolumeCallback->GetStream(fullName, &inStream); + if (result == S_FALSE) + break; + if (result != S_OK) + return result; + if (!stream) + break; + } + else + inStream = stream; + + UInt64 endPos = 0; + if (openArchiveCallback != NULL) + { + RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); + RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); + totalBytes += endPos; + RINOK(openArchiveCallback->SetTotal(NULL, &totalBytes)); + } + + NArchive::NRar::CInArchive archive; + RINOK(archive.Open(inStream, maxCheckStartPosition)); + + if (_archives.IsEmpty()) + archive.GetArchiveInfo(_archiveInfo); + + CItemEx item; + for (;;) + { + HRESULT result = archive.GetNextItem(item, getTextPassword); + if (result == S_FALSE) + break; + RINOK(result); + if (item.IgnoreItem()) + continue; + + bool needAdd = true; + if (item.IsSplitBefore()) + { + if (!_refItems.IsEmpty()) + { + CRefItem &refItem = _refItems.Back(); + refItem.NumItems++; + needAdd = false; + } + } + if (needAdd) + { + CRefItem refItem; + refItem.ItemIndex = _items.Size(); + refItem.NumItems = 1; + refItem.VolumeIndex = _archives.Size(); + _refItems.Add(refItem); + } + _items.Add(item); + if (openArchiveCallback != NULL && _items.Size() % 100 == 0) + { + UInt64 numFiles = _items.Size(); + UInt64 numBytes = curBytes + item.Position; + RINOK(openArchiveCallback->SetCompleted(&numFiles, &numBytes)); + } + } + curBytes += endPos; + _archives.Add(archive); + } + } + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + Close(); + try + { + HRESULT res = Open2(stream, maxCheckStartPosition, openArchiveCallback); + if (res != S_OK) + Close(); + return res; + } + catch(const CInArchiveException &) { Close(); return S_FALSE; } + catch(...) { Close(); throw; } + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + COM_TRY_BEGIN + _refItems.Clear(); + _items.Clear(); + _archives.Clear(); + return S_OK; + COM_TRY_END +} + +struct CMethodItem +{ + Byte RarUnPackVersion; + CMyComPtr Coder; +}; + + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *_anExtractCallback) +{ + COM_TRY_BEGIN + CMyComPtr getTextPassword; + bool testMode = (_aTestMode != 0); + CMyComPtr extractCallback = _anExtractCallback; + UInt64 censoredTotalUnPacked = 0, + // censoredTotalPacked = 0, + importantTotalUnPacked = 0; + // importantTotalPacked = 0; + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = _refItems.Size(); + if(numItems == 0) + return S_OK; + int lastIndex = 0; + CRecordVector importantIndexes; + CRecordVector extractStatuses; + + for(UInt32 t = 0; t < numItems; t++) + { + int index = allFilesMode ? t : indices[t]; + const CRefItem &refItem = _refItems[index]; + const CItemEx &item = _items[refItem.ItemIndex]; + censoredTotalUnPacked += item.Size; + // censoredTotalPacked += item.PackSize; + int j; + for(j = lastIndex; j <= index; j++) + // if(!_items[_refItems[j].ItemIndex].IsSolid()) + if(!IsSolid(j)) + lastIndex = j; + for(j = lastIndex; j <= index; j++) + { + const CRefItem &refItem = _refItems[j]; + const CItemEx &item = _items[refItem.ItemIndex]; + + // const CItemEx &item = _items[j]; + + importantTotalUnPacked += item.Size; + // importantTotalPacked += item.PackSize; + importantIndexes.Add(j); + extractStatuses.Add(j == index); + } + lastIndex = index + 1; + } + + extractCallback->SetTotal(importantTotalUnPacked); + UInt64 currentImportantTotalUnPacked = 0; + UInt64 currentImportantTotalPacked = 0; + UInt64 currentUnPackSize, currentPackSize; + + CObjectVector methodItems; + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; + CMyComPtr copyCoder = copyCoderSpec; + + CFilterCoder *filterStreamSpec = new CFilterCoder; + CMyComPtr filterStream = filterStreamSpec; + + NCrypto::NRar20::CDecoder *rar20CryptoDecoderSpec = NULL; + CMyComPtr rar20CryptoDecoder; + NCrypto::NRar29::CDecoder *rar29CryptoDecoderSpec = NULL; + CMyComPtr rar29CryptoDecoder; + + CFolderInStream *folderInStreamSpec = NULL; + CMyComPtr folderInStream; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + bool solidStart = true; + for(int i = 0; i < importantIndexes.Size(); i++, + currentImportantTotalUnPacked += currentUnPackSize, + currentImportantTotalPacked += currentPackSize) + { + lps->InSize = currentImportantTotalPacked; + lps->OutSize = currentImportantTotalUnPacked; + RINOK(lps->SetCur()); + CMyComPtr realOutStream; + + Int32 askMode; + if(extractStatuses[i]) + askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + else + askMode = NArchive::NExtract::NAskMode::kSkip; + + UInt32 index = importantIndexes[i]; + + const CRefItem &refItem = _refItems[index]; + const CItemEx &item = _items[refItem.ItemIndex]; + + currentUnPackSize = item.Size; + + currentPackSize = GetPackSize(index); + + if(item.IgnoreItem()) + continue; + + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + + if (!IsSolid(index)) + solidStart = true; + if(item.IsDir()) + { + RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; + } + + bool mustBeProcessedAnywhere = false; + if(i < importantIndexes.Size() - 1) + { + // const CRefItem &nextRefItem = _refItems[importantIndexes[i + 1]]; + // const CItemEx &nextItemInfo = _items[nextRefItem.ItemIndex]; + // mustBeProcessedAnywhere = nextItemInfo.IsSolid(); + mustBeProcessedAnywhere = IsSolid(importantIndexes[i + 1]); + } + + if (!mustBeProcessedAnywhere && !testMode && !realOutStream) + continue; + + if (!realOutStream && !testMode) + askMode = NArchive::NExtract::NAskMode::kSkip; + + RINOK(extractCallback->PrepareOperation(askMode)); + + COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; + CMyComPtr outStream(outStreamSpec); + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(); + realOutStream.Release(); + + /* + for (int partIndex = 0; partIndex < 1; partIndex++) + { + CMyComPtr inStream; + + // item redefinition + const CItemEx &item = _items[refItem.ItemIndex + partIndex]; + + NArchive::NRar::CInArchive &archive = _archives[refItem.VolumeIndex + partIndex]; + + inStream.Attach(archive.CreateLimitedStream(item.GetDataPosition(), + item.PackSize)); + */ + if (!folderInStream) + { + folderInStreamSpec = new CFolderInStream; + folderInStream = folderInStreamSpec; + } + + folderInStreamSpec->Init(&_archives, &_items, refItem); + + UInt64 packSize = currentPackSize; + + // packedPos += item.PackSize; + // unpackedPos += 0; + + CMyComPtr inStream; + if (item.IsEncrypted()) + { + CMyComPtr cryptoSetPassword; + if (item.UnPackVersion >= 29) + { + if (!rar29CryptoDecoder) + { + rar29CryptoDecoderSpec = new NCrypto::NRar29::CDecoder; + rar29CryptoDecoder = rar29CryptoDecoderSpec; + // RINOK(rar29CryptoDecoder.CoCreateInstance(CLSID_CCryptoRar29Decoder)); + } + rar29CryptoDecoderSpec->SetRar350Mode(item.UnPackVersion < 36); + CMyComPtr cryptoProperties; + RINOK(rar29CryptoDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, + &cryptoProperties)); + RINOK(cryptoProperties->SetDecoderProperties2(item.Salt, item.HasSalt() ? sizeof(item.Salt) : 0)); + filterStreamSpec->Filter = rar29CryptoDecoder; + } + else if (item.UnPackVersion >= 20) + { + if (!rar20CryptoDecoder) + { + rar20CryptoDecoderSpec = new NCrypto::NRar20::CDecoder; + rar20CryptoDecoder = rar20CryptoDecoderSpec; + // RINOK(rar20CryptoDecoder.CoCreateInstance(CLSID_CCryptoRar20Decoder)); + } + filterStreamSpec->Filter = rar20CryptoDecoder; + } + else + { + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + continue; + } + RINOK(filterStreamSpec->Filter.QueryInterface(IID_ICryptoSetPassword, + &cryptoSetPassword)); + + if (!getTextPassword) + extractCallback.QueryInterface(IID_ICryptoGetTextPassword, + &getTextPassword); + if (getTextPassword) + { + CMyComBSTR password; + RINOK(getTextPassword->CryptoGetTextPassword(&password)); + if (item.UnPackVersion >= 29) + { + CByteBuffer buffer; + UString unicodePassword(password); + const UInt32 sizeInBytes = unicodePassword.Length() * 2; + buffer.SetCapacity(sizeInBytes); + for (int i = 0; i < unicodePassword.Length(); i++) + { + wchar_t c = unicodePassword[i]; + ((Byte *)buffer)[i * 2] = (Byte)c; + ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); + } + RINOK(cryptoSetPassword->CryptoSetPassword( + (const Byte *)buffer, sizeInBytes)); + } + else + { + AString oemPassword = UnicodeStringToMultiByte( + (const wchar_t *)password, CP_OEMCP); + RINOK(cryptoSetPassword->CryptoSetPassword( + (const Byte *)(const char *)oemPassword, oemPassword.Length())); + } + } + else + { + RINOK(cryptoSetPassword->CryptoSetPassword(0, 0)); + } + filterStreamSpec->SetInStream(folderInStream); + inStream = filterStream; + } + else + { + inStream = folderInStream; + } + CMyComPtr commonCoder; + switch(item.Method) + { + case '0': + { + commonCoder = copyCoder; + break; + } + case '1': + case '2': + case '3': + case '4': + case '5': + { + /* + if (item.UnPackVersion >= 29) + { + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + continue; + } + */ + int m; + for (m = 0; m < methodItems.Size(); m++) + if (methodItems[m].RarUnPackVersion == item.UnPackVersion) + break; + if (m == methodItems.Size()) + { + CMethodItem mi; + mi.RarUnPackVersion = item.UnPackVersion; + + mi.Coder.Release(); + if (item.UnPackVersion <= 30) + { + UInt32 methodID = 0x040300; + if (item.UnPackVersion < 20) + methodID += 1; + else if (item.UnPackVersion < 29) + methodID += 2; + else + methodID += 3; + RINOK(CreateCoder(EXTERNAL_CODECS_VARS methodID, mi.Coder, false)); + } + + if (mi.Coder == 0) + { + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + continue; + } + + m = methodItems.Add(mi); + } + CMyComPtr decoder = methodItems[m].Coder; + + CMyComPtr compressSetDecoderProperties; + RINOK(decoder.QueryInterface(IID_ICompressSetDecoderProperties2, + &compressSetDecoderProperties)); + + Byte isSolid = (Byte)((IsSolid(index) || item.IsSplitBefore()) ? 1: 0); + if (solidStart) + { + isSolid = false; + solidStart = false; + } + + + RINOK(compressSetDecoderProperties->SetDecoderProperties2(&isSolid, 1)); + + commonCoder = decoder; + break; + } + default: + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + continue; + } + HRESULT result = commonCoder->Code(inStream, outStream, &packSize, &item.Size, progress); + if (item.IsEncrypted()) + filterStreamSpec->ReleaseInStream(); + if (result == S_FALSE) + { + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + if (result != S_OK) + return result; + + /* + if (refItem.NumItems == 1 && + !item.IsSplitBefore() && !item.IsSplitAfter()) + */ + { + const CItemEx &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1]; + bool crcOK = outStreamSpec->GetCRC() == lastItem.FileCRC; + outStream.Release(); + RINOK(extractCallback->SetOperationResult(crcOK ? NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kCRCError)); + } + /* + else + { + bool crcOK = true; + for (int partIndex = 0; partIndex < refItem.NumItems; partIndex++) + { + const CItemEx &item = _items[refItem.ItemIndex + partIndex]; + if (item.FileCRC != folderInStreamSpec->CRCs[partIndex]) + { + crcOK = false; + break; + } + } + RINOK(extractCallback->SetOperationResult(crcOK ? NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kCRCError)); + } + */ + } + return S_OK; + COM_TRY_END +} + +IMPL_ISetCompressCodecsInfo + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarHandler.h b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarHandler.h new file mode 100644 index 000000000..dff8ed322 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarHandler.h @@ -0,0 +1,60 @@ +// Rar/Handler.h + +#ifndef __RAR_HANDLER_H +#define __RAR_HANDLER_H + +#include "../IArchive.h" +#include "RarIn.h" +#include "RarVolumeInStream.h" + +#include "../../Common/CreateCoder.h" + +namespace NArchive { +namespace NRar { + +class CHandler: + public IInArchive, + PUBLIC_ISetCompressCodecsInfo + public CMyUnknownImp +{ +public: + MY_QUERYINTERFACE_BEGIN2(IInArchive) + QUERY_ENTRY_ISetCompressCodecsInfo + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + INTERFACE_IInArchive(;) + + DECL_ISetCompressCodecsInfo + +private: + CRecordVector _refItems; + CObjectVector _items; + CObjectVector _archives; + NArchive::NRar::CInArchiveInfo _archiveInfo; + + DECL_EXTERNAL_CODECS_VARS + + UInt64 GetPackSize(int refIndex) const; + // NArchive::NRar::CInArchive _archive; + + bool IsSolid(int refIndex) + { + const CItemEx &item = _items[_refItems[refIndex].ItemIndex]; + if (item.UnPackVersion < 20) + { + if (_archiveInfo.IsSolid()) + return (refIndex > 0); + return false; + } + return item.IsSolid(); + } + + HRESULT Open2(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarHeader.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarHeader.cpp new file mode 100644 index 000000000..90dc8366f --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarHeader.cpp @@ -0,0 +1,19 @@ +// Archive/Rar/Headers.cpp + +#include "StdAfx.h" + +#include "RarHeader.h" + +namespace NArchive{ +namespace NRar{ +namespace NHeader{ + +Byte kMarker[kMarkerSize] = {0x52 + 1, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00}; + +class CMarkerInitializer +{ +public: + CMarkerInitializer() { kMarker[0]--; }; +} g_MarkerInitializer; + +}}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarHeader.h b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarHeader.h new file mode 100644 index 000000000..e5a3e1deb --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarHeader.h @@ -0,0 +1,224 @@ +// Archive/RarHeader.h + +#ifndef __ARCHIVE_RAR_HEADER_H +#define __ARCHIVE_RAR_HEADER_H + +#include "Common/Types.h" + +namespace NArchive{ +namespace NRar{ +namespace NHeader{ + +const int kMarkerSize = 7; +extern Byte kMarker[kMarkerSize]; + +const int kArchiveSolid = 0x1; + +namespace NBlockType +{ + enum EBlockType + { + kMarker = 0x72, + kArchiveHeader = 0x73, + kFileHeader = 0x74, + kCommentHeader = 0x75, + kOldAuthenticity = 0x76, + kSubBlock = 0x77, + kRecoveryRecord = 0x78, + kAuthenticity = 0x79, + + kEndOfArchive = 0x7B // Is not safe + }; +} + +namespace NArchive +{ + const UInt16 kVolume = 1; + const UInt16 kComment = 2; + const UInt16 kLock = 4; + const UInt16 kSolid = 8; + const UInt16 kNewVolName = 0x10; // ('volname.partN.rar') + const UInt16 kAuthenticity = 0x20; + const UInt16 kRecovery = 0x40; + const UInt16 kBlockEncryption = 0x80; + const UInt16 kFirstVolume = 0x100; // (set only by RAR 3.0 and later) + const UInt16 kEncryptVer = 0x200; // RAR 3.6 there is EncryptVer Byte in End of MainHeader + + const int kHeaderSizeMin = 7; + + struct CBlock + { + UInt16 CRC; + Byte Type; + UInt16 Flags; + UInt16 Size; + UInt16 Reserved1; + UInt32 Reserved2; + // UInt16 GetRealCRC() const; + }; + + const int kArchiveHeaderSize = 13; + + const int kBlockHeadersAreEncrypted = 0x80; + + struct CHeader360: public CBlock + { + Byte EncryptVersion; + bool IsEncrypted() const { return (Flags & NHeader::NArchive::kBlockEncryption) != 0; } + bool IsThereEncryptVer() const { return (Flags & NHeader::NArchive::kEncryptVer) != 0; } + bool IsEncryptOld() const { return (!IsThereEncryptVer() || EncryptVersion < 36); } + UInt32 GetBaseSize() const { return kArchiveHeaderSize + (IsEncryptOld() ? 0 : 1); } + }; +} + +namespace NFile +{ + const int kSplitBefore = 1 << 0; + const int kSplitAfter = 1 << 1; + const int kEncrypted = 1 << 2; + const int kComment = 1 << 3; + const int kSolid = 1 << 4; + + const int kDictBitStart = 5; + const int kNumDictBits = 3; + const int kDictMask = (1 << kNumDictBits) - 1; + const int kDictDirectoryValue = 0x7; + + const int kSize64Bits = 1 << 8; + const int kUnicodeName = 1 << 9; + const int kSalt = 1 << 10; + const int kOldVersion = 1 << 11; + const int kExtTime = 1 << 12; + // const int kExtFlags = 1 << 13; + // const int kSkipIfUnknown = 1 << 14; + + const int kLongBlock = 1 << 15; + + /* + struct CBlock + { + // UInt16 HeadCRC; + // Byte Type; + // UInt16 Flags; + // UInt16 HeadSize; + UInt32 PackSize; + UInt32 UnPackSize; + Byte HostOS; + UInt32 FileCRC; + UInt32 Time; + Byte UnPackVersion; + Byte Method; + UInt16 NameSize; + UInt32 Attributes; + }; + */ + + /* + struct CBlock32 + { + UInt16 HeadCRC; + Byte Type; + UInt16 Flags; + UInt16 HeadSize; + UInt32 PackSize; + UInt32 UnPackSize; + Byte HostOS; + UInt32 FileCRC; + UInt32 Time; + Byte UnPackVersion; + Byte Method; + UInt16 NameSize; + UInt32 Attributes; + UInt16 GetRealCRC(const void *aName, UInt32 aNameSize, + bool anExtraDataDefined = false, Byte *anExtraData = 0) const; + }; + struct CBlock64 + { + UInt16 HeadCRC; + Byte Type; + UInt16 Flags; + UInt16 HeadSize; + UInt32 PackSizeLow; + UInt32 UnPackSizeLow; + Byte HostOS; + UInt32 FileCRC; + UInt32 Time; + Byte UnPackVersion; + Byte Method; + UInt16 NameSize; + UInt32 Attributes; + UInt32 PackSizeHigh; + UInt32 UnPackSizeHigh; + UInt16 GetRealCRC(const void *aName, UInt32 aNameSize) const; + }; + */ + + const int kLabelFileAttribute = 0x08; + const int kWinFileDirectoryAttributeMask = 0x10; + + enum CHostOS + { + kHostMSDOS = 0, + kHostOS2 = 1, + kHostWin32 = 2, + kHostUnix = 3, + kHostMacOS = 4, + kHostBeOS = 5 + }; +} + +namespace NBlock +{ + const UInt16 kLongBlock = 1 << 15; + struct CBlock + { + UInt16 CRC; + Byte Type; + UInt16 Flags; + UInt16 HeadSize; + // UInt32 DataSize; + }; +} + +/* +struct CSubBlock +{ + UInt16 HeadCRC; + Byte HeadType; + UInt16 Flags; + UInt16 HeadSize; + UInt32 DataSize; + UInt16 SubType; + Byte Level; // Reserved : Must be 0 +}; + +struct CCommentBlock +{ + UInt16 HeadCRC; + Byte HeadType; + UInt16 Flags; + UInt16 HeadSize; + UInt16 UnpSize; + Byte UnpVer; + Byte Method; + UInt16 CommCRC; +}; + + +struct CProtectHeader +{ + UInt16 HeadCRC; + Byte HeadType; + UInt16 Flags; + UInt16 HeadSize; + UInt32 DataSize; + Byte Version; + UInt16 RecSectors; + UInt32 TotalBlocks; + Byte Mark[8]; +}; +*/ + +}}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarIn.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarIn.cpp new file mode 100644 index 000000000..f434bce63 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarIn.cpp @@ -0,0 +1,513 @@ +// Archive/RarIn.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/UTFConvert.h" + +#include "RarIn.h" +#include "../../Common/LimitedStreams.h" +#include "../../Common/StreamUtils.h" + +#include "../Common/FindSignature.h" + +extern "C" +{ + #include "../../../../C/7zCrc.h" +} + +namespace NArchive { +namespace NRar { + +void CInArchive::ThrowExceptionWithCode( + CInArchiveException::CCauseType cause) +{ + throw CInArchiveException(cause); +} + +HRESULT CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit) +{ + try + { + Close(); + HRESULT res = Open2(inStream, searchHeaderSizeLimit); + if (res == S_OK) + return res; + Close(); + return res; + } + catch(...) { Close(); throw; } +} + +void CInArchive::Close() +{ + m_Stream.Release(); +} + + +static inline bool TestMarkerCandidate(const void *aTestBytes) +{ + for (UInt32 i = 0; i < NHeader::kMarkerSize; i++) + if (((const Byte *)aTestBytes)[i] != NHeader::kMarker[i]) + return false; + return true; +} + +HRESULT CInArchive::FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit) +{ + RINOK(FindSignatureInStream(stream, + NHeader::kMarker, NHeader::kMarkerSize, + searchHeaderSizeLimit, m_ArchiveStartPosition)); + m_Stream = stream; + m_Position = m_ArchiveStartPosition + NHeader::kMarkerSize; + return m_Stream->Seek(m_Position, STREAM_SEEK_SET, NULL); +} + +void CInArchive::ThrowUnexpectedEndOfArchiveException() +{ + ThrowExceptionWithCode(CInArchiveException::kUnexpectedEndOfArchive); +} + +bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size) +{ + if (m_CryptoMode) + { + const Byte *bufData = (const Byte *)m_DecryptedData; + UInt32 bufSize = m_DecryptedDataSize; + UInt32 i; + for (i = 0; i < size && m_CryptoPos < bufSize; i++) + ((Byte *)data)[i] = bufData[m_CryptoPos++]; + return (i == size); + } + return (ReadStream_FALSE(m_Stream, data, size) == S_OK); +} + +void CInArchive::ReadBytesAndTestResult(void *data, UInt32 size) +{ + if(!ReadBytesAndTestSize(data,size)) + ThrowUnexpectedEndOfArchiveException(); +} + +HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize) +{ + size_t realProcessedSize = size; + HRESULT result = ReadStream(m_Stream, data, &realProcessedSize); + if (processedSize != NULL) + *processedSize = (UInt32)realProcessedSize; + AddToSeekValue(realProcessedSize); + return result; +} + +static UInt32 CrcUpdateUInt16(UInt32 crc, UInt16 v) +{ + crc = CRC_UPDATE_BYTE(crc, (Byte)(v & 0xFF)); + crc = CRC_UPDATE_BYTE(crc, (Byte)((v >> 8) & 0xFF)); + return crc; +} + +static UInt32 CrcUpdateUInt32(UInt32 crc, UInt32 v) +{ + crc = CRC_UPDATE_BYTE(crc, (Byte)(v & 0xFF)); + crc = CRC_UPDATE_BYTE(crc, (Byte)((v >> 8) & 0xFF)); + crc = CRC_UPDATE_BYTE(crc, (Byte)((v >> 16) & 0xFF)); + crc = CRC_UPDATE_BYTE(crc, (Byte)((v >> 24) & 0xFF)); + return crc; +} + + +HRESULT CInArchive::Open2(IInStream *stream, const UInt64 *searchHeaderSizeLimit) +{ + m_CryptoMode = false; + RINOK(stream->Seek(0, STREAM_SEEK_SET, &m_StreamStartPosition)); + m_Position = m_StreamStartPosition; + + RINOK(FindAndReadMarker(stream, searchHeaderSizeLimit)); + + Byte buf[NHeader::NArchive::kArchiveHeaderSize]; + UInt32 processedSize; + ReadBytes(buf, sizeof(buf), &processedSize); + if (processedSize != sizeof(buf)) + return S_FALSE; + m_CurData = buf; + m_CurPos = 0; + m_PosLimit = sizeof(buf); + + m_ArchiveHeader.CRC = ReadUInt16(); + m_ArchiveHeader.Type = ReadByte(); + m_ArchiveHeader.Flags = ReadUInt16(); + m_ArchiveHeader.Size = ReadUInt16(); + m_ArchiveHeader.Reserved1 = ReadUInt16(); + m_ArchiveHeader.Reserved2 = ReadUInt32(); + m_ArchiveHeader.EncryptVersion = 0; + + UInt32 crc = CRC_INIT_VAL; + crc = CRC_UPDATE_BYTE(crc, m_ArchiveHeader.Type); + crc = CrcUpdateUInt16(crc, m_ArchiveHeader.Flags); + crc = CrcUpdateUInt16(crc, m_ArchiveHeader.Size); + crc = CrcUpdateUInt16(crc, m_ArchiveHeader.Reserved1); + crc = CrcUpdateUInt32(crc, m_ArchiveHeader.Reserved2); + + if (m_ArchiveHeader.IsThereEncryptVer() && m_ArchiveHeader.Size > NHeader::NArchive::kArchiveHeaderSize) + { + ReadBytes(&m_ArchiveHeader.EncryptVersion, 1, &processedSize); + if (processedSize != 1) + return S_FALSE; + crc = CRC_UPDATE_BYTE(crc, m_ArchiveHeader.EncryptVersion); + } + + if(m_ArchiveHeader.CRC != (CRC_GET_DIGEST(crc) & 0xFFFF)) + ThrowExceptionWithCode(CInArchiveException::kArchiveHeaderCRCError); + if (m_ArchiveHeader.Type != NHeader::NBlockType::kArchiveHeader) + return S_FALSE; + m_ArchiveCommentPosition = m_Position; + m_SeekOnArchiveComment = true; + return S_OK; +} + +void CInArchive::SkipArchiveComment() +{ + if (!m_SeekOnArchiveComment) + return; + AddToSeekValue(m_ArchiveHeader.Size - m_ArchiveHeader.GetBaseSize()); + m_SeekOnArchiveComment = false; +} + +void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const +{ + archiveInfo.StartPosition = m_ArchiveStartPosition; + archiveInfo.Flags = m_ArchiveHeader.Flags; + archiveInfo.CommentPosition = m_ArchiveCommentPosition; + archiveInfo.CommentSize = (UInt16)(m_ArchiveHeader.Size - NHeader::NArchive::kArchiveHeaderSize); +} + +static void DecodeUnicodeFileName(const char *name, const Byte *encName, + int encSize, wchar_t *unicodeName, int maxDecSize) +{ + int encPos = 0; + int decPos = 0; + int flagBits = 0; + Byte flags = 0; + Byte highByte = encName[encPos++]; + while (encPos < encSize && decPos < maxDecSize) + { + if (flagBits == 0) + { + flags = encName[encPos++]; + flagBits = 8; + } + switch(flags >> 6) + { + case 0: + unicodeName[decPos++] = encName[encPos++]; + break; + case 1: + unicodeName[decPos++] = (wchar_t)(encName[encPos++] + (highByte << 8)); + break; + case 2: + unicodeName[decPos++] = (wchar_t)(encName[encPos] + (encName[encPos + 1] << 8)); + encPos += 2; + break; + case 3: + { + int length = encName[encPos++]; + if (length & 0x80) + { + Byte correction = encName[encPos++]; + for (length = (length & 0x7f) + 2; + length > 0 && decPos < maxDecSize; length--, decPos++) + unicodeName[decPos] = (wchar_t)(((name[decPos] + correction) & 0xff) + (highByte << 8)); + } + else + for (length += 2; length > 0 && decPos < maxDecSize; length--, decPos++) + unicodeName[decPos] = name[decPos]; + } + break; + } + flags <<= 2; + flagBits -= 2; + } + unicodeName[decPos < maxDecSize ? decPos : maxDecSize - 1] = 0; +} + +void CInArchive::ReadName(CItemEx &item, int nameSize) +{ + item.UnicodeName.Empty(); + if (nameSize > 0) + { + m_NameBuffer.EnsureCapacity(nameSize + 1); + char *buffer = (char *)m_NameBuffer; + + for (int i = 0; i < nameSize; i++) + buffer[i] = ReadByte(); + + int mainLen; + for (mainLen = 0; mainLen < nameSize; mainLen++) + if (buffer[mainLen] == '\0') + break; + buffer[mainLen] = '\0'; + item.Name = buffer; + + if(item.HasUnicodeName()) + { + if(mainLen < nameSize) + { + int unicodeNameSizeMax = MyMin(nameSize, (0x400)); + _unicodeNameBuffer.EnsureCapacity(unicodeNameSizeMax + 1); + DecodeUnicodeFileName(buffer, (const Byte *)buffer + mainLen + 1, + nameSize - (mainLen + 1), _unicodeNameBuffer, unicodeNameSizeMax); + item.UnicodeName = _unicodeNameBuffer; + } + else if (!ConvertUTF8ToUnicode(item.Name, item.UnicodeName)) + item.UnicodeName.Empty(); + } + } + else + item.Name.Empty(); +} + +Byte CInArchive::ReadByte() +{ + if (m_CurPos >= m_PosLimit) + throw CInArchiveException(CInArchiveException::kIncorrectArchive); + return m_CurData[m_CurPos++]; +} + +UInt16 CInArchive::ReadUInt16() +{ + UInt16 value = 0; + for (int i = 0; i < 2; i++) + { + Byte b = ReadByte(); + value |= (UInt16(b) << (8 * i)); + } + return value; +} + +UInt32 CInArchive::ReadUInt32() +{ + UInt32 value = 0; + for (int i = 0; i < 4; i++) + { + Byte b = ReadByte(); + value |= (UInt32(b) << (8 * i)); + } + return value; +} + +void CInArchive::ReadTime(Byte mask, CRarTime &rarTime) +{ + rarTime.LowSecond = (Byte)(((mask & 4) != 0) ? 1 : 0); + int numDigits = (mask & 3); + rarTime.SubTime[0] = rarTime.SubTime[1] = rarTime.SubTime[2] = 0; + for (int i = 0; i < numDigits; i++) + rarTime.SubTime[3 - numDigits + i] = ReadByte(); +} + +void CInArchive::ReadHeaderReal(CItemEx &item) +{ + item.Flags = m_BlockHeader.Flags; + item.PackSize = ReadUInt32(); + item.Size = ReadUInt32(); + item.HostOS = ReadByte(); + item.FileCRC = ReadUInt32(); + item.MTime.DosTime = ReadUInt32(); + item.UnPackVersion = ReadByte(); + item.Method = ReadByte(); + int nameSize = ReadUInt16(); + item.Attrib = ReadUInt32(); + + item.MTime.LowSecond = 0; + item.MTime.SubTime[0] = + item.MTime.SubTime[1] = + item.MTime.SubTime[2] = 0; + + if((item.Flags & NHeader::NFile::kSize64Bits) != 0) + { + item.PackSize |= ((UInt64)ReadUInt32() << 32); + item.Size |= ((UInt64)ReadUInt32() << 32); + } + + ReadName(item, nameSize); + + if (item.HasSalt()) + for (int i = 0; i < sizeof(item.Salt); i++) + item.Salt[i] = ReadByte(); + + // some rar archives have HasExtTime flag without field. + if (m_CurPos < m_PosLimit && item.HasExtTime()) + { + Byte accessMask = (Byte)(ReadByte() >> 4); + Byte b = ReadByte(); + Byte modifMask = (Byte)(b >> 4); + Byte createMask = (Byte)(b & 0xF); + if ((modifMask & 8) != 0) + ReadTime(modifMask, item.MTime); + item.CTimeDefined = ((createMask & 8) != 0); + if (item.CTimeDefined) + { + item.CTime.DosTime = ReadUInt32(); + ReadTime(createMask, item.CTime); + } + item.ATimeDefined = ((accessMask & 8) != 0); + if (item.ATimeDefined) + { + item.ATime.DosTime = ReadUInt32(); + ReadTime(accessMask, item.ATime); + } + } + + UInt16 fileHeaderWithNameSize = (UInt16)m_CurPos; + + item.Position = m_Position; + item.MainPartSize = fileHeaderWithNameSize; + item.CommentSize = (UInt16)(m_BlockHeader.HeadSize - fileHeaderWithNameSize); + + if (m_CryptoMode) + item.AlignSize = (UInt16)((16 - ((m_BlockHeader.HeadSize) & 0xF)) & 0xF); + else + item.AlignSize = 0; + AddToSeekValue(m_BlockHeader.HeadSize); +} + +void CInArchive::AddToSeekValue(UInt64 addValue) +{ + m_Position += addValue; +} + +HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword) +{ + if (m_SeekOnArchiveComment) + SkipArchiveComment(); + for (;;) + { + if(!SeekInArchive(m_Position)) + return S_FALSE; + if (!m_CryptoMode && (m_ArchiveHeader.Flags & + NHeader::NArchive::kBlockHeadersAreEncrypted) != 0) + { + m_CryptoMode = false; + if (getTextPassword == 0) + return S_FALSE; + if(!SeekInArchive(m_Position)) + return S_FALSE; + if (!m_RarAES) + { + m_RarAESSpec = new NCrypto::NRar29::CDecoder; + m_RarAES = m_RarAESSpec; + } + m_RarAESSpec->SetRar350Mode(m_ArchiveHeader.IsEncryptOld()); + + // Salt + const UInt32 kSaltSize = 8; + Byte salt[kSaltSize]; + if(!ReadBytesAndTestSize(salt, kSaltSize)) + return S_FALSE; + m_Position += kSaltSize; + RINOK(m_RarAESSpec->SetDecoderProperties2(salt, kSaltSize)) + // Password + CMyComBSTR password; + RINOK(getTextPassword->CryptoGetTextPassword(&password)) + UString unicodePassword(password); + + CByteBuffer buffer; + const UInt32 sizeInBytes = unicodePassword.Length() * 2; + buffer.SetCapacity(sizeInBytes); + for (int i = 0; i < unicodePassword.Length(); i++) + { + wchar_t c = unicodePassword[i]; + ((Byte *)buffer)[i * 2] = (Byte)c; + ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); + } + + RINOK(m_RarAESSpec->CryptoSetPassword((const Byte *)buffer, sizeInBytes)); + + const UInt32 kDecryptedBufferSize = (1 << 12); + if (m_DecryptedData.GetCapacity() == 0) + { + m_DecryptedData.SetCapacity(kDecryptedBufferSize); + } + RINOK(m_RarAES->Init()); + size_t decryptedDataSizeT = kDecryptedBufferSize; + RINOK(ReadStream(m_Stream, (Byte *)m_DecryptedData, &decryptedDataSizeT)); + m_DecryptedDataSize = (UInt32)decryptedDataSizeT; + m_DecryptedDataSize = m_RarAES->Filter((Byte *)m_DecryptedData, m_DecryptedDataSize); + + m_CryptoMode = true; + m_CryptoPos = 0; + } + + m_FileHeaderData.EnsureCapacity(7); + if(!ReadBytesAndTestSize((Byte *)m_FileHeaderData, 7)) + return S_FALSE; + + m_CurData = (Byte *)m_FileHeaderData; + m_CurPos = 0; + m_PosLimit = 7; + m_BlockHeader.CRC = ReadUInt16(); + m_BlockHeader.Type = ReadByte(); + m_BlockHeader.Flags = ReadUInt16(); + m_BlockHeader.HeadSize = ReadUInt16(); + + if (m_BlockHeader.HeadSize < 7) + ThrowExceptionWithCode(CInArchiveException::kIncorrectArchive); + + if (m_BlockHeader.Type == NHeader::NBlockType::kEndOfArchive) + return S_FALSE; + + if (m_BlockHeader.Type == NHeader::NBlockType::kFileHeader) + { + m_FileHeaderData.EnsureCapacity(m_BlockHeader.HeadSize); + m_CurData = (Byte *)m_FileHeaderData; + m_PosLimit = m_BlockHeader.HeadSize; + ReadBytesAndTestResult(m_CurData + m_CurPos, m_BlockHeader.HeadSize - 7); + ReadHeaderReal(item); + if ((CrcCalc(m_CurData + 2, + m_BlockHeader.HeadSize - item.CommentSize - 2) & 0xFFFF) != m_BlockHeader.CRC) + ThrowExceptionWithCode(CInArchiveException::kFileHeaderCRCError); + + FinishCryptoBlock(); + m_CryptoMode = false; + SeekInArchive(m_Position); // Move Position to compressed Data; + AddToSeekValue(item.PackSize); // m_Position points to next header; + return S_OK; + } + if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 12)) + return E_FAIL; // it's for bad passwords + if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0) + { + m_FileHeaderData.EnsureCapacity(7 + 4); + m_CurData = (Byte *)m_FileHeaderData; + ReadBytesAndTestResult(m_CurData + m_CurPos, 4); // test it + m_PosLimit = 7 + 4; + UInt32 dataSize = ReadUInt32(); + AddToSeekValue(dataSize); + if (m_CryptoMode && dataSize > (1 << 27)) + return E_FAIL; // it's for bad passwords + m_CryptoPos = m_BlockHeader.HeadSize; + } + else + m_CryptoPos = 0; + AddToSeekValue(m_BlockHeader.HeadSize); + FinishCryptoBlock(); + m_CryptoMode = false; + } +} + +bool CInArchive::SeekInArchive(UInt64 position) +{ + UInt64 newPosition; + m_Stream->Seek(position, STREAM_SEEK_SET, &newPosition); + return newPosition == position; +} + +ISequentialInStream* CInArchive::CreateLimitedStream(UInt64 position, UInt64 size) +{ + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStream(streamSpec); + SeekInArchive(position); + streamSpec->SetStream(m_Stream); + streamSpec->Init(size); + return inStream.Detach(); +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarIn.h b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarIn.h new file mode 100644 index 000000000..500f1134e --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarIn.h @@ -0,0 +1,126 @@ +// RarIn.h + +#ifndef __ARCHIVE_RAR_IN_H +#define __ARCHIVE_RAR_IN_H + +#include "Common/DynamicBuffer.h" +#include "Common/MyCom.h" + +#include "../../ICoder.h" +#include "../../IStream.h" + +#include "../../Common/StreamObjects.h" + +#include "../../Crypto/RarAes.h" + +#include "RarHeader.h" +#include "RarItem.h" + +namespace NArchive { +namespace NRar { + +class CInArchiveException +{ +public: + enum CCauseType + { + kUnexpectedEndOfArchive = 0, + kArchiveHeaderCRCError, + kFileHeaderCRCError, + kIncorrectArchive + } + Cause; + CInArchiveException(CCauseType cause) : Cause(cause) {} +}; + +class CInArchiveInfo +{ +public: + UInt64 StartPosition; + UInt16 Flags; + UInt64 CommentPosition; + UInt16 CommentSize; + bool IsSolid() const { return (Flags & NHeader::NArchive::kSolid) != 0; } + bool IsCommented() const { return (Flags & NHeader::NArchive::kComment) != 0; } + bool IsVolume() const { return (Flags & NHeader::NArchive::kVolume) != 0; } + bool HaveNewVolumeName() const { return (Flags & NHeader::NArchive::kNewVolName) != 0; } + bool IsEncrypted() const { return (Flags & NHeader::NArchive::kBlockEncryption) != 0; } +}; + +class CInArchive +{ + CMyComPtr m_Stream; + + UInt64 m_StreamStartPosition; + UInt64 m_Position; + UInt64 m_ArchiveStartPosition; + + NHeader::NArchive::CHeader360 m_ArchiveHeader; + CDynamicBuffer m_NameBuffer; + CDynamicBuffer _unicodeNameBuffer; + bool m_SeekOnArchiveComment; + UInt64 m_ArchiveCommentPosition; + + void ReadName(CItemEx &item, int nameSize); + void ReadHeaderReal(CItemEx &item); + + HRESULT ReadBytes(void *data, UInt32 size, UInt32 *aProcessedSize); + bool ReadBytesAndTestSize(void *data, UInt32 size); + void ReadBytesAndTestResult(void *data, UInt32 size); + + HRESULT FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit); + HRESULT Open2(IInStream *stream, const UInt64 *searchHeaderSizeLimit); + + void ThrowExceptionWithCode(CInArchiveException::CCauseType cause); + void ThrowUnexpectedEndOfArchiveException(); + + void AddToSeekValue(UInt64 addValue); + +protected: + + CDynamicBuffer m_FileHeaderData; + + NHeader::NBlock::CBlock m_BlockHeader; + + NCrypto::NRar29::CDecoder *m_RarAESSpec; + CMyComPtr m_RarAES; + + Byte *m_CurData; // it must point to start of Rar::Block + UInt32 m_CurPos; + UInt32 m_PosLimit; + Byte ReadByte(); + UInt16 ReadUInt16(); + UInt32 ReadUInt32(); + void ReadTime(Byte mask, CRarTime &rarTime); + + CBuffer m_DecryptedData; + UInt32 m_DecryptedDataSize; + + bool m_CryptoMode; + UInt32 m_CryptoPos; + void FinishCryptoBlock() + { + if (m_CryptoMode) + while ((m_CryptoPos & 0xF) != 0) + { + m_CryptoPos++; + m_Position++; + } + } + +public: + HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit); + void Close(); + HRESULT GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword); + + void SkipArchiveComment(); + + void GetArchiveInfo(CInArchiveInfo &archiveInfo) const; + + bool SeekInArchive(UInt64 position); + ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarItem.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarItem.cpp new file mode 100644 index 000000000..b0963778b --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarItem.cpp @@ -0,0 +1,55 @@ +// RarItem.cpp + +#include "StdAfx.h" + +#include "RarItem.h" + +namespace NArchive{ +namespace NRar{ + +bool CItem::IgnoreItem() const +{ + switch(HostOS) + { + case NHeader::NFile::kHostMSDOS: + case NHeader::NFile::kHostOS2: + case NHeader::NFile::kHostWin32: + return ((Attrib & NHeader::NFile::kLabelFileAttribute) != 0); + } + return false; +} + +bool CItem::IsDir() const +{ + if (GetDictSize() == NHeader::NFile::kDictDirectoryValue) + return true; + switch(HostOS) + { + case NHeader::NFile::kHostMSDOS: + case NHeader::NFile::kHostOS2: + case NHeader::NFile::kHostWin32: + if ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0) + return true; + } + return false; +} + +UInt32 CItem::GetWinAttributes() const +{ + UInt32 winAttributes; + switch(HostOS) + { + case NHeader::NFile::kHostMSDOS: + case NHeader::NFile::kHostOS2: + case NHeader::NFile::kHostWin32: + winAttributes = Attrib; + break; + default: + winAttributes = 0; // must be converted from unix value; + } + if (IsDir()) + winAttributes |= NHeader::NFile::kWinFileDirectoryAttributeMask; + return winAttributes; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarItem.h b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarItem.h new file mode 100644 index 000000000..515ecd4be --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarItem.h @@ -0,0 +1,79 @@ +// RarItem.h + +#ifndef __ARCHIVE_RAR_ITEM_H +#define __ARCHIVE_RAR_ITEM_H + +#include "Common/Types.h" +#include "Common/MyString.h" + +#include "RarHeader.h" + +namespace NArchive{ +namespace NRar{ + +struct CRarTime +{ + UInt32 DosTime; + Byte LowSecond; + Byte SubTime[3]; +}; + +struct CItem +{ + UInt64 Size; + UInt64 PackSize; + + CRarTime CTime; + CRarTime ATime; + CRarTime MTime; + + UInt32 FileCRC; + UInt32 Attrib; + + UInt16 Flags; + Byte HostOS; + Byte UnPackVersion; + Byte Method; + + bool CTimeDefined; + bool ATimeDefined; + + AString Name; + UString UnicodeName; + + Byte Salt[8]; + + bool IsEncrypted() const { return (Flags & NHeader::NFile::kEncrypted) != 0; } + bool IsSolid() const { return (Flags & NHeader::NFile::kSolid) != 0; } + bool IsCommented() const { return (Flags & NHeader::NFile::kComment) != 0; } + bool IsSplitBefore() const { return (Flags & NHeader::NFile::kSplitBefore) != 0; } + bool IsSplitAfter() const { return (Flags & NHeader::NFile::kSplitAfter) != 0; } + bool HasSalt() const { return (Flags & NHeader::NFile::kSalt) != 0; } + bool HasExtTime() const { return (Flags & NHeader::NFile::kExtTime) != 0; } + bool HasUnicodeName()const { return (Flags & NHeader::NFile::kUnicodeName) != 0; } + bool IsOldVersion() const { return (Flags & NHeader::NFile::kOldVersion) != 0; } + + UInt32 GetDictSize() const { return (Flags >> NHeader::NFile::kDictBitStart) & NHeader::NFile::kDictMask; } + bool IsDir() const; + bool IgnoreItem() const; + UInt32 GetWinAttributes() const; + + CItem(): CTimeDefined(false), ATimeDefined(false) {} +}; + +class CItemEx: public CItem +{ +public: + UInt64 Position; + UInt16 MainPartSize; + UInt16 CommentSize; + UInt16 AlignSize; + UInt64 GetFullSize() const { return MainPartSize + CommentSize + AlignSize + PackSize; }; + // DWORD GetHeaderWithCommentSize() const { return MainPartSize + CommentSize; }; + UInt64 GetCommentPosition() const { return Position + MainPartSize; }; + UInt64 GetDataPosition() const { return GetCommentPosition() + CommentSize + AlignSize; }; +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarRegister.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarRegister.cpp new file mode 100644 index 000000000..f7897a607 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarRegister.cpp @@ -0,0 +1,13 @@ +// RarRegister.cpp + +#include "StdAfx.h" + +#include "../../Common/RegisterArc.h" + +#include "RarHandler.h" +static IInArchive *CreateArc() { return new NArchive::NRar::CHandler; } + +static CArcInfo g_ArcInfo = + { L"Rar", L"rar r00", 0, 3, {0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00}, 7, false, CreateArc, 0, }; + +REGISTER_ARC(Rar) diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarVolumeInStream.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarVolumeInStream.cpp new file mode 100644 index 000000000..8b62d9fd9 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarVolumeInStream.cpp @@ -0,0 +1,84 @@ +// RarVolumeInStream.cpp + +#include "StdAfx.h" + +#include "RarVolumeInStream.h" + +#include "Windows/Defs.h" +#include "Common/Defs.h" + +extern "C" +{ + #include "../../../../C/7zCrc.h" +} + +namespace NArchive { +namespace NRar { + +void CFolderInStream::Init( + CObjectVector *archives, + const CObjectVector *items, + const CRefItem &refItem) +{ + _archives = archives; + _items = items; + _refItem = refItem; + _curIndex = 0; + CRCs.Clear(); + _fileIsOpen = false; +} + +HRESULT CFolderInStream::OpenStream() +{ + while (_curIndex < _refItem.NumItems) + { + const CItemEx &item = (*_items)[_refItem.ItemIndex + _curIndex]; + _stream.Attach((*_archives)[_refItem.VolumeIndex + _curIndex]. + CreateLimitedStream(item.GetDataPosition(), item.PackSize)); + _curIndex++; + _fileIsOpen = true; + _crc = CRC_INIT_VAL; + return S_OK; + } + return S_OK; +} + +HRESULT CFolderInStream::CloseStream() +{ + CRCs.Add(CRC_GET_DIGEST(_crc)); + _stream.Release(); + _fileIsOpen = false; + return S_OK; +} + +STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize = 0; + while ((_curIndex < _refItem.NumItems || _fileIsOpen) && size > 0) + { + if (_fileIsOpen) + { + UInt32 localProcessedSize; + RINOK(_stream->Read( + ((Byte *)data) + realProcessedSize, size, &localProcessedSize)); + _crc = CrcUpdate(_crc, ((Byte *)data) + realProcessedSize, localProcessedSize); + if (localProcessedSize == 0) + { + RINOK(CloseStream()); + continue; + } + realProcessedSize += localProcessedSize; + size -= localProcessedSize; + break; + } + else + { + RINOK(OpenStream()); + } + } + if (processedSize != 0) + *processedSize = realProcessedSize; + return S_OK; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarVolumeInStream.h b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarVolumeInStream.h new file mode 100644 index 000000000..d175a2c0c --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/RarVolumeInStream.h @@ -0,0 +1,49 @@ +// RarVolumeInStream.h + +#ifndef __RAR_VOLUME_IN_STREAM_H +#define __RAR_VOLUME_IN_STREAM_H + +#include "../../IStream.h" +#include "RarIn.h" + +namespace NArchive { +namespace NRar { + +struct CRefItem +{ + int VolumeIndex; + int ItemIndex; + int NumItems; +}; + +class CFolderInStream: + public ISequentialInStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + +private: + CObjectVector *_archives; + const CObjectVector *_items; + CRefItem _refItem; + int _curIndex; + UInt32 _crc; + bool _fileIsOpen; + CMyComPtr _stream; + + HRESULT OpenStream(); + HRESULT CloseStream(); +public: + void Init(CObjectVector *archives, + const CObjectVector *items, + const CRefItem &refItem); + + CRecordVector CRCs; +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Rar/StdAfx.h b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/StdAfx.h new file mode 100644 index 000000000..83fdd22d5 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Rar/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Split/SplitHandler.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Split/SplitHandler.cpp new file mode 100644 index 000000000..36be6cc3b --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Split/SplitHandler.cpp @@ -0,0 +1,357 @@ +// SplitHandler.cpp + +#include "StdAfx.h" + +#include "Common/ComTry.h" +#include "Common/Defs.h" +#include "Common/NewHandler.h" +#include "Common/StringConvert.h" + +#include "Windows/PropVariant.h" +#include "Windows/Time.h" + +#include "../../Common/ProgressUtils.h" + +#include "../../Compress/CopyCoder.h" + +#include "../Common/ItemNameUtils.h" +#include "../Common/MultiStream.h" + +#include "SplitHandler.h" + +using namespace NWindows; +using namespace NTime; + +namespace NArchive { +namespace NSplit { + +STATPROPSTG kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO + +class CSeqName +{ +public: + UString _unchangedPart; + UString _changedPart; + bool _splitStyle; + UString GetNextName() + { + UString newName; + if (_splitStyle) + { + int i; + int numLetters = _changedPart.Length(); + for (i = numLetters - 1; i >= 0; i--) + { + wchar_t c = _changedPart[i]; + if (c == 'z') + { + c = 'a'; + newName = c + newName; + continue; + } + else if (c == 'Z') + { + c = 'A'; + newName = c + newName; + continue; + } + c++; + if ((c == 'z' || c == 'Z') && i == 0) + { + _unchangedPart += c; + wchar_t newChar = (c == 'z') ? L'a' : L'A'; + newName.Empty(); + numLetters++; + for (int k = 0; k < numLetters; k++) + newName += newChar; + break; + } + newName = c + newName; + i--; + for (; i >= 0; i--) + newName = _changedPart[i] + newName; + break; + } + } + else + { + int i; + int numLetters = _changedPart.Length(); + for (i = numLetters - 1; i >= 0; i--) + { + wchar_t c = _changedPart[i]; + if (c == L'9') + { + c = L'0'; + newName = c + newName; + if (i == 0) + newName = UString(L'1') + newName; + continue; + } + c++; + newName = c + newName; + i--; + for (; i >= 0; i--) + newName = _changedPart[i] + newName; + break; + } + } + _changedPart = newName; + return _unchangedPart + _changedPart; + } +}; + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + Close(); + if (openArchiveCallback == 0) + return S_FALSE; + // try + { + CMyComPtr openVolumeCallback; + CMyComPtr openArchiveCallbackWrap = openArchiveCallback; + if (openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, + &openVolumeCallback) != S_OK) + return S_FALSE; + + { + NCOM::CPropVariant prop; + RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); + if (prop.vt != VT_BSTR) + return S_FALSE; + _name = prop.bstrVal; + } + + int dotPos = _name.ReverseFind('.'); + UString prefix, ext; + if (dotPos >= 0) + { + prefix = _name.Left(dotPos + 1); + ext = _name.Mid(dotPos + 1); + } + else + ext = _name; + UString extBig = ext; + extBig.MakeUpper(); + + CSeqName seqName; + + int numLetters = 2; + bool splitStyle = false; + if (extBig.Right(2) == L"AA") + { + splitStyle = true; + while (numLetters < extBig.Length()) + { + if (extBig[extBig.Length() - numLetters - 1] != 'A') + break; + numLetters++; + } + } + else if (ext.Right(2) == L"01") + { + while (numLetters < extBig.Length()) + { + if (extBig[extBig.Length() - numLetters - 1] != '0') + break; + numLetters++; + } + if (numLetters != ext.Length()) + return S_FALSE; + } + else + return S_FALSE; + + _streams.Add(stream); + + seqName._unchangedPart = prefix + ext.Left(extBig.Length() - numLetters); + seqName._changedPart = ext.Right(numLetters); + seqName._splitStyle = splitStyle; + + if (prefix.Length() < 1) + _subName = L"file"; + else + _subName = prefix.Left(prefix.Length() - 1); + + _totalSize = 0; + UInt64 size; + { + NCOM::CPropVariant prop; + RINOK(openVolumeCallback->GetProperty(kpidSize, &prop)); + if (prop.vt != VT_UI8) + return E_INVALIDARG; + size = prop.uhVal.QuadPart; + } + _totalSize += size; + _sizes.Add(size); + + if (openArchiveCallback != NULL) + { + UInt64 numFiles = _streams.Size(); + RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + } + + for (;;) + { + UString fullName = seqName.GetNextName(); + CMyComPtr nextStream; + HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream); + if (result == S_FALSE) + break; + if (result != S_OK) + return result; + if (!stream) + break; + { + NCOM::CPropVariant prop; + RINOK(openVolumeCallback->GetProperty(kpidSize, &prop)); + if (prop.vt != VT_UI8) + return E_INVALIDARG; + size = prop.uhVal.QuadPart; + } + _totalSize += size; + _sizes.Add(size); + _streams.Add(nextStream); + if (openArchiveCallback != NULL) + { + UInt64 numFiles = _streams.Size(); + RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + } + } + } + /* + catch(...) + { + return S_FALSE; + } + */ + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _sizes.Clear(); + _streams.Clear(); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _streams.IsEmpty() ? 0 : 1; + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidPath: + prop = _subName; + break; + case kpidSize: + case kpidPackSize: + prop = _totalSize; + break; + } + prop.Detach(value); + return S_OK; +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *_anExtractCallback) +{ + COM_TRY_BEGIN + + if (numItems != UInt32(-1)) + { + if (numItems != 1) + return E_INVALIDARG; + if (indices[0] != 0) + return E_INVALIDARG; + } + bool testMode = (_aTestMode != 0); + CMyComPtr extractCallback = _anExtractCallback; + extractCallback->SetTotal(_totalSize); + + /* + CMyComPtr volumeExtractCallback; + if (extractCallback.QueryInterface(&volumeExtractCallback) != S_OK) + return E_FAIL; + */ + + UInt64 currentTotalSize = 0; + UInt64 currentItemSize; + + RINOK(extractCallback->SetCompleted(¤tTotalSize)); + CMyComPtr realOutStream; + Int32 askMode; + askMode = testMode ? NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + Int32 index = 0; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + + RINOK(extractCallback->PrepareOperation(askMode)); + if (testMode) + { + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + return S_OK; + } + + if (!testMode && (!realOutStream)) + return S_OK; + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; + CMyComPtr copyCoder = copyCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + for (int i = 0; i < _streams.Size(); i++, currentTotalSize += currentItemSize) + { + lps->InSize = lps->OutSize = currentTotalSize; + RINOK(lps->SetCur()); + IInStream *inStream = _streams[i]; + RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); + currentItemSize = copyCoderSpec->TotalSize; + } + realOutStream.Release(); + return extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK); + COM_TRY_END +} + +STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +{ + if (index != 0) + return E_INVALIDARG; + *stream = 0; + CMultiStream *streamSpec = new CMultiStream; + CMyComPtr streamTemp = streamSpec; + for (int i = 0; i < _streams.Size(); i++) + { + CMultiStream::CSubStreamInfo subStreamInfo; + subStreamInfo.Stream = _streams[i]; + subStreamInfo.Pos = 0; + subStreamInfo.Size = _sizes[i]; + streamSpec->Streams.Add(subStreamInfo); + } + streamSpec->Init(); + *stream = streamTemp.Detach(); + return S_OK; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Split/SplitHandler.h b/desmume/src/windows/7z/CPP/7zip/Archive/Split/SplitHandler.h new file mode 100644 index 000000000..c323490ae --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Split/SplitHandler.h @@ -0,0 +1,37 @@ +// Split/Handler.h + +#ifndef __SPLIT_HANDLER_H +#define __SPLIT_HANDLER_H + +#include "Common/MyCom.h" +#include "Common/MyString.h" +#include "../IArchive.h" + +namespace NArchive { +namespace NSplit { + +class CHandler: + public IInArchive, + public IInArchiveGetStream, + // public IOutArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) + + INTERFACE_IInArchive(;) + + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); + +private: + UString _subName; + UString _name; + CObjectVector > _streams; + CRecordVector _sizes; + + UInt64 _totalSize; +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Split/SplitRegister.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Split/SplitRegister.cpp new file mode 100644 index 000000000..691a3829c --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Split/SplitRegister.cpp @@ -0,0 +1,20 @@ +// SplitRegister.cpp + +#include "StdAfx.h" + +#include "../../Common/RegisterArc.h" + +#include "SplitHandler.h" +static IInArchive *CreateArc() { return new NArchive::NSplit::CHandler; } +/* +#ifndef EXTRACT_ONLY +static IOutArchive *CreateArcOut() { return new NArchive::NSplit::CHandler; } +#else +#define CreateArcOut 0 +#endif +*/ + +static CArcInfo g_ArcInfo = +{ L"Split", L"001", 0, 0xEA, { 0 }, 0, false, CreateArc, 0 }; + +REGISTER_ARC(Split) diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Split/StdAfx.h b/desmume/src/windows/7z/CPP/7zip/Archive/Split/StdAfx.h new file mode 100644 index 000000000..83fdd22d5 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Split/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/StdAfx.h b/desmume/src/windows/7z/CPP/7zip/Archive/StdAfx.h new file mode 100644 index 000000000..f56e92fd8 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../Common/MyWindows.h" +#include "../../Common/NewHandler.h" + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Tar/StdAfx.h b/desmume/src/windows/7z/CPP/7zip/Archive/Tar/StdAfx.h new file mode 100644 index 000000000..a4e617312 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Tar/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarHandler.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarHandler.cpp new file mode 100644 index 000000000..b1e34fff7 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarHandler.cpp @@ -0,0 +1,229 @@ +// TarHandler.cpp + +#include "StdAfx.h" + +#include "Common/ComTry.h" +#include "Common/Defs.h" +#include "Common/NewHandler.h" +#include "Common/StringConvert.h" + +#include "Windows/PropVariant.h" +#include "Windows/Time.h" + +#include "../../Common/LimitedStreams.h" +#include "../../Common/ProgressUtils.h" + +#include "../../Compress/CopyCoder.h" + +#include "../Common/DummyOutStream.h" +#include "../Common/ItemNameUtils.h" + +#include "TarHandler.h" +#include "TarIn.h" + +using namespace NWindows; + +namespace NArchive { +namespace NTar { + +STATPROPSTG kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsDir, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME}, + { NULL, kpidUser, VT_BSTR}, + { NULL, kpidGroup, VT_BSTR} +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO + +HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) +{ + UInt64 endPos = 0; + if (callback != NULL) + { + RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); + RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); + } + + UInt64 pos = 0; + for (;;) + { + CItemEx item; + bool filled; + item.HeaderPosition = pos; + RINOK(ReadItem(stream, filled, item)); + if (!filled) + break; + _items.Add(item); + + RINOK(stream->Seek(item.GetPackSize(), STREAM_SEEK_CUR, &pos)); + if (pos >= endPos) + return S_FALSE; + if (callback != NULL) + { + if (_items.Size() == 1) + { + RINOK(callback->SetTotal(NULL, &endPos)); + } + if (_items.Size() % 100 == 0) + { + UInt64 numFiles = _items.Size(); + RINOK(callback->SetCompleted(&numFiles, &pos)); + } + } + } + + if (_items.Size() == 0) + { + CMyComPtr openVolumeCallback; + if (!callback) + return S_FALSE; + callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); + if (!openVolumeCallback) + return S_FALSE; + NCOM::CPropVariant prop; + if (openVolumeCallback->GetProperty(kpidName, &prop) != S_OK) + return S_FALSE; + if (prop.vt != VT_BSTR) + return S_FALSE; + UString baseName = prop.bstrVal; + baseName = baseName.Right(4); + if (baseName.CompareNoCase(L".tar") != 0) + return S_FALSE; + } + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + { + Close(); + RINOK(Open2(stream, openArchiveCallback)); + _inStream = stream; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _items.Clear(); + _inStream.Release(); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _items.Size(); + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + const CItemEx &item = _items[index]; + + switch(propID) + { + case kpidPath: prop = NItemName::GetOSName2(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break; + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: prop = item.Size; break; + case kpidPackSize: prop = item.GetPackSize(); break; + case kpidMTime: + if (item.MTime != 0) + { + FILETIME ft; + NTime::UnixTimeToFileTime(item.MTime, ft); + prop = ft; + } + break; + case kpidUser: prop = MultiByteToUnicodeString(item.UserName, CP_OEMCP); break; + case kpidGroup: prop = MultiByteToUnicodeString(item.GroupName, CP_OEMCP); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool testMode = (_aTestMode != 0); + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = _items.Size(); + if (numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + totalSize += _items[allFilesMode ? i : indices[i]].Size; + extractCallback->SetTotal(totalSize); + + UInt64 totalPackSize, curPackSize, curSize; + totalSize = totalPackSize = 0; + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr copyCoder = copyCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStream(streamSpec); + streamSpec->SetStream(_inStream); + + CDummyOutStream *outStreamSpec = new CDummyOutStream; + CMyComPtr outStream(outStreamSpec); + + for (i = 0; i < numItems; i++, totalSize += curSize, totalPackSize += curPackSize) + { + lps->InSize = totalPackSize; + lps->OutSize = totalSize; + RINOK(lps->SetCur()); + CMyComPtr realOutStream; + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + Int32 index = allFilesMode ? i : indices[i]; + const CItemEx &item = _items[index]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + curSize = item.Size; + curPackSize = item.GetPackSize(); + if (item.IsDir()) + { + RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; + } + if (!testMode && (!realOutStream)) + continue; + RINOK(extractCallback->PrepareOperation(askMode)); + + outStreamSpec->SetStream(realOutStream); + realOutStream.Release(); + outStreamSpec->Init(); + + RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL)); + streamSpec->Init(item.Size); + RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); + outStreamSpec->ReleaseStream(); + RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == item.Size ? + NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kDataError)); + } + return S_OK; + COM_TRY_END +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarHandler.h b/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarHandler.h new file mode 100644 index 000000000..38792b25a --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarHandler.h @@ -0,0 +1,37 @@ +// Tar/Handler.h + +#ifndef __TAR_HANDLER_H +#define __TAR_HANDLER_H + +#include "Common/MyCom.h" +#include "../IArchive.h" + +#include "TarItem.h" + +namespace NArchive { +namespace NTar { + +class CHandler: + public IInArchive, + public IOutArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP2( + IInArchive, + IOutArchive + ) + + INTERFACE_IInArchive(;) + INTERFACE_IOutArchive(;) + + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback); + +private: + CObjectVector _items; + CMyComPtr _inStream; +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarHeader.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarHeader.cpp new file mode 100644 index 000000000..9304388bc --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarHeader.cpp @@ -0,0 +1,25 @@ +// Archive/Tar/Header.h + +#include "StdAfx.h" + +#include "TarHeader.h" + +namespace NArchive { +namespace NTar { +namespace NFileHeader { + + // The checksum field is filled with this while the checksum is computed. + const char *kCheckSumBlanks = " "; // 8 blanks, no null + + const char *kLongLink = "././@LongLink"; + const char *kLongLink2 = "@LongLink"; + + // The magic field is filled with this if uname and gname are valid. + namespace NMagic + { + const char *kUsTar = "ustar"; // 5 chars + const char *kGNUTar = "GNUtar "; // 7 chars and a null + const char *kEmpty = "\0\0\0\0\0\0\0\0"; // 7 chars and a null + } + +}}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarHeader.h b/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarHeader.h new file mode 100644 index 000000000..dece1f7f4 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarHeader.h @@ -0,0 +1,108 @@ +// Archive/Tar/Header.h + +#ifndef __ARCHIVE_TAR_HEADER_H +#define __ARCHIVE_TAR_HEADER_H + +#include "Common/Types.h" + +namespace NArchive { +namespace NTar { + +namespace NFileHeader +{ + const int kRecordSize = 512; + const int kNameSize = 100; + const int kUserNameSize = 32; + const int kGroupNameSize = 32; + const int kPrefixSize = 155; + + /* + struct CHeader + { + char Name[kNameSize]; + char Mode[8]; + char UID[8]; + char GID[8]; + char Size[12]; + char ModificationTime[12]; + char CheckSum[8]; + char LinkFlag; + char LinkName[kNameSize]; + char Magic[8]; + char UserName[kUserNameSize]; + char GroupName[kGroupNameSize]; + char DeviceMajor[8]; + char DeviceMinor[8]; + char Prefix[155]; + }; + union CRecord + { + CHeader Header; + Byte Padding[kRecordSize]; + }; + */ + + namespace NMode + { + const int kSetUID = 04000; // Set UID on execution + const int kSetGID = 02000; // Set GID on execution + const int kSaveText = 01000; // Save text (sticky bit) + } + + namespace NFilePermissions + { + const int kUserRead = 00400; // read by owner + const int kUserWrite = 00200; // write by owner + const int kUserExecute = 00100; // execute/search by owner + const int kGroupRead = 00040; // read by group + const int kGroupWrite = 00020; // write by group + const int kGroupExecute = 00010; // execute/search by group + const int kOtherRead = 00004; // read by other + const int kOtherWrite = 00002; // write by other + const int kOtherExecute = 00001; // execute/search by other + } + + + // The linkflag defines the type of file + namespace NLinkFlag + { + const char kOldNormal = '\0'; // Normal disk file, Unix compatible + const char kNormal = '0'; // Normal disk file + const char kLink = '1'; // Link to previously dumped file + const char kSymbolicLink = '2'; // Symbolic link + const char kCharacter = '3'; // Character special file + const char kBlock = '4'; // Block special file + const char kDirectory = '5'; // Directory + const char kFIFO = '6'; // FIFO special file + const char kContiguous = '7'; // Contiguous file + + const char kDumpDir = 'D'; /* GNUTYPE_DUMPDIR. + data: list of files created by the --incremental (-G) option + Each file name is preceded by either + - 'Y' (file should be in this archive) + - 'N' (file is a directory, or is not stored in the archive.) + Each file name is terminated by a null + an additional null after + the last file name. */ + + } + // Further link types may be defined later. + + // The checksum field is filled with this while the checksum is computed. + extern const char *kCheckSumBlanks;// = " "; // 8 blanks, no null + + extern const char *kLongLink; // = "././@LongLink"; + extern const char *kLongLink2; // = "@LongLink"; + + // The magic field is filled with this if uname and gname are valid. + namespace NMagic + { + extern const char *kUsTar; // = "ustar"; // 5 chars + extern const char *kGNUTar; // = "GNUtar "; // 7 chars and a null + extern const char *kEmpty; // = "GNUtar "; // 7 chars and a null + } + +} + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarIn.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarIn.cpp new file mode 100644 index 000000000..85702eb2b --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarIn.cpp @@ -0,0 +1,176 @@ +// Archive/TarIn.cpp + +#include "StdAfx.h" + +#include "TarIn.h" +#include "TarHeader.h" + +#include "Common/StringToInt.h" +#include "Windows/Defs.h" + +#include "../../Common/StreamUtils.h" + +namespace NArchive { +namespace NTar { + +static void MyStrNCpy(char *dest, const char *src, int size) +{ + for (int i = 0; i < size; i++) + { + char c = src[i]; + dest[i] = c; + if (c == 0) + break; + } +} + +static bool OctalToNumber(const char *srcString, int size, UInt64 &res) +{ + char sz[32]; + MyStrNCpy(sz, srcString, size); + sz[size] = 0; + const char *end; + int i; + for (i = 0; sz[i] == ' '; i++); + res = ConvertOctStringToUInt64(sz + i, &end); + return (*end == ' ' || *end == 0); +} + +static bool OctalToNumber32(const char *srcString, int size, UInt32 &res) +{ + UInt64 res64; + if (!OctalToNumber(srcString, size, res64)) + return false; + res = (UInt32)res64; + return (res64 <= 0xFFFFFFFF); +} + +#define RIF(x) { if (!(x)) return S_FALSE; } + +static bool IsRecordLast(const char *buf) +{ + for (int i = 0; i < NFileHeader::kRecordSize; i++) + if (buf[i] != 0) + return false; + return true; +} + +static void ReadString(const char *s, int size, AString &result) +{ + char temp[NFileHeader::kRecordSize + 1]; + MyStrNCpy(temp, s, size); + temp[size] = '\0'; + result = temp; +} + +static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemEx &item, size_t &processedSize) +{ + item.LongLinkSize = 0; + char buf[NFileHeader::kRecordSize]; + char *p = buf; + + filled = false; + + processedSize = NFileHeader::kRecordSize; + RINOK(ReadStream(stream, buf, &processedSize)); + if (processedSize == 0 || (processedSize == NFileHeader::kRecordSize && IsRecordLast(buf))) + return S_OK; + if (processedSize < NFileHeader::kRecordSize) + return S_FALSE; + + ReadString(p, NFileHeader::kNameSize, item.Name); p += NFileHeader::kNameSize; + + RIF(OctalToNumber32(p, 8, item.Mode)); p += 8; + + if (!OctalToNumber32(p, 8, item.UID)) item.UID = 0; p += 8; + if (!OctalToNumber32(p, 8, item.GID)) item.GID = 0; p += 8; + + RIF(OctalToNumber(p, 12, item.Size)); p += 12; + RIF(OctalToNumber32(p, 12, item.MTime)); p += 12; + + UInt32 checkSum; + RIF(OctalToNumber32(p, 8, checkSum)); + memcpy(p, NFileHeader::kCheckSumBlanks, 8); p += 8; + + item.LinkFlag = *p++; + + ReadString(p, NFileHeader::kNameSize, item.LinkName); p += NFileHeader::kNameSize; + + memcpy(item.Magic, p, 8); p += 8; + + ReadString(p, NFileHeader::kUserNameSize, item.UserName); p += NFileHeader::kUserNameSize; + ReadString(p, NFileHeader::kUserNameSize, item.GroupName); p += NFileHeader::kUserNameSize; + + item.DeviceMajorDefined = (p[0] != 0); RIF(OctalToNumber32(p, 8, item.DeviceMajor)); p += 8; + item.DeviceMinorDefined = (p[0] != 0); RIF(OctalToNumber32(p, 8, item.DeviceMinor)); p += 8; + + AString prefix; + ReadString(p, NFileHeader::kPrefixSize, prefix); + p += NFileHeader::kPrefixSize; + if (!prefix.IsEmpty() && item.IsMagic() && + (item.LinkFlag != 'L' /* || prefix != "00000000000" */ )) + item.Name = prefix + AString('/') + item.Name; + + if (item.LinkFlag == NFileHeader::NLinkFlag::kLink) + item.Size = 0; + + UInt32 checkSumReal = 0; + for (int i = 0; i < NFileHeader::kRecordSize; i++) + checkSumReal += (Byte)buf[i]; + + if (checkSumReal != checkSum) + return S_FALSE; + + filled = true; + return S_OK; +} + +HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item) +{ + size_t processedSize; + RINOK(GetNextItemReal(stream, filled, item, processedSize)); + if (!filled) + return S_OK; + // GNUtar extension + if (item.LinkFlag == 'L') + { + if (item.Name.Compare(NFileHeader::kLongLink) != 0) + if (item.Name.Compare(NFileHeader::kLongLink2) != 0) + return S_FALSE; + + AString fullName; + if (item.Size > (1 << 15)) + return S_FALSE; + int packSize = (int)item.GetPackSize(); + char *buffer = fullName.GetBuffer(packSize + 1); + + RINOK(ReadStream_FALSE(stream, buffer, packSize)); + processedSize += packSize; + buffer[item.Size] = '\0'; + fullName.ReleaseBuffer(); + + UInt64 headerPosition = item.HeaderPosition; + { + size_t processedSize2; + RINOK(GetNextItemReal(stream, filled, item, processedSize2)); + } + item.LongLinkSize = (unsigned)processedSize; + item.Name = fullName; + item.HeaderPosition = headerPosition; + } + else if (item.LinkFlag == 'g' || item.LinkFlag == 'x' || item.LinkFlag == 'X') + { + // pax Extended Header + return S_OK; + } + else if (item.LinkFlag == NFileHeader::NLinkFlag::kDumpDir) + { + // GNU Extensions to the Archive Format + return S_OK; + } + else if (item.LinkFlag > '7' || (item.LinkFlag < '0' && item.LinkFlag != 0)) + return S_FALSE; + return S_OK; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarIn.h b/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarIn.h new file mode 100644 index 000000000..546ad1966 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarIn.h @@ -0,0 +1,18 @@ +// Archive/TarIn.h + +#ifndef __ARCHIVE_TAR_IN_H +#define __ARCHIVE_TAR_IN_H + +#include "Common/MyCom.h" +#include "../../IStream.h" + +#include "TarItem.h" + +namespace NArchive { +namespace NTar { + +HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &itemInfo); + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarItem.h b/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarItem.h new file mode 100644 index 000000000..54beefcc4 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarItem.h @@ -0,0 +1,71 @@ +// Archive/Tar/Item.h + +#ifndef __ARCHIVE_TAR_ITEM_H +#define __ARCHIVE_TAR_ITEM_H + +#include "Common/Types.h" +#include "Common/MyString.h" + +#include "../Common/ItemNameUtils.h" +#include "TarHeader.h" + +namespace NArchive { +namespace NTar { + +struct CItem +{ + AString Name; + UInt64 Size; + + UInt32 Mode; + UInt32 UID; + UInt32 GID; + UInt32 MTime; + UInt32 DeviceMajor; + UInt32 DeviceMinor; + + AString LinkName; + AString UserName; + AString GroupName; + + char Magic[8]; + char LinkFlag; + bool DeviceMajorDefined; + bool DeviceMinorDefined; + + bool IsDir() const + { + switch(LinkFlag) + { + case NFileHeader::NLinkFlag::kDirectory: + case NFileHeader::NLinkFlag::kDumpDir: + return true; + case NFileHeader::NLinkFlag::kOldNormal: + case NFileHeader::NLinkFlag::kNormal: + return NItemName::HasTailSlash(Name, CP_OEMCP); + } + return false; + } + + bool IsMagic() const + { + for (int i = 0; i < 5; i++) + if (Magic[i] != NFileHeader::NMagic::kUsTar[i]) + return false; + return true; + } + + UInt64 GetPackSize() const { return (Size + 0x1FF) & (~((UInt64)0x1FF)); } +}; + +struct CItemEx: public CItem +{ + UInt64 HeaderPosition; + unsigned LongLinkSize; + UInt64 GetDataPosition() const { return HeaderPosition + LongLinkSize + NFileHeader::kRecordSize; } + UInt64 GetFullSize() const { return LongLinkSize + NFileHeader::kRecordSize + Size; } +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarRegister.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarRegister.cpp new file mode 100644 index 000000000..17eccb7b3 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Tar/TarRegister.cpp @@ -0,0 +1,18 @@ +// TarRegister.cpp + +#include "StdAfx.h" + +#include "../../Common/RegisterArc.h" + +#include "TarHandler.h" +static IInArchive *CreateArc() { return new NArchive::NTar::CHandler; } +#ifndef EXTRACT_ONLY +static IOutArchive *CreateArcOut() { return new NArchive::NTar::CHandler; } +#else +#define CreateArcOut 0 +#endif + +static CArcInfo g_ArcInfo = +{ L"Tar", L"tar", 0, 0xEE, { 'u', 's', 't', 'a', 'r' }, 5, false, CreateArc, CreateArcOut }; + +REGISTER_ARC(Tar) diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Zip/StdAfx.h b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/StdAfx.h new file mode 100644 index 000000000..83fdd22d5 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipCompressionMode.h b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipCompressionMode.h new file mode 100644 index 000000000..f3c105e81 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipCompressionMode.h @@ -0,0 +1,39 @@ +// CompressionMode.h + +#ifndef __ZIP_COMPRESSIONMETHOD_H +#define __ZIP_COMPRESSIONMETHOD_H + +#include "../../../Common/MyString.h" + +namespace NArchive { +namespace NZip { + +struct CCompressionMethodMode +{ + CRecordVector MethodSequence; + UString MatchFinder; + UInt32 Algo; + UInt32 NumPasses; + UInt32 NumFastBytes; + bool NumMatchFinderCyclesDefined; + UInt32 NumMatchFinderCycles; + UInt32 DicSize; + #ifdef COMPRESS_MT + UInt32 NumThreads; + #endif + bool PasswordIsDefined; + AString Password; + bool IsAesMode; + Byte AesKeyMode; + + CCompressionMethodMode(): + NumMatchFinderCyclesDefined(false), + PasswordIsDefined(false), + IsAesMode(false), + AesKeyMode(3) + {} +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipHandler.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipHandler.cpp new file mode 100644 index 000000000..43f1cf996 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipHandler.cpp @@ -0,0 +1,831 @@ +// ZipHandler.cpp + +#include "StdAfx.h" + +#include "Common/ComTry.h" +#include "Common/Defs.h" +#include "Common/IntToString.h" +#include "Common/StringConvert.h" + +#include "Windows/PropVariant.h" +#include "Windows/Time.h" + +#include "../../IPassword.h" + +#include "../../Common/CreateCoder.h" +#include "../../Common/FilterCoder.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" + +#include "../../Compress/CopyCoder.h" +#include "../../Compress/LzmaDecoder.h" +#include "../../Compress/ImplodeDecoder.h" +#include "../../Compress/ShrinkDecoder.h" + +#include "../../Crypto/WzAes.h" +#include "../../Crypto/ZipCrypto.h" +#include "../../Crypto/ZipStrong.h" + +#include "../Common/ItemNameUtils.h" +#include "../Common/OutStreamWithCRC.h" + +#include "ZipHandler.h" + +using namespace NWindows; + +namespace NArchive { +namespace NZip { + +// static const CMethodId kMethodId_Store = 0; +static const CMethodId kMethodId_ZipBase = 0x040100; +static const CMethodId kMethodId_BZip2 = 0x040202; + +const wchar_t *kHostOS[] = +{ + L"FAT", + L"AMIGA", + L"VMS", + L"Unix", + L"VM/CMS", + L"Atari", + L"HPFS", + L"Macintosh", + L"Z-System", + L"CP/M", + L"TOPS-20", + L"NTFS", + L"SMS/QDOS", + L"Acorn", + L"VFAT", + L"MVS", + L"BeOS", + L"Tandem", + L"OS/400", + L"OS/X" +}; + + +static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]); + +static const wchar_t *kUnknownOS = L"Unknown"; + +STATPROPSTG kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsDir, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME}, + { NULL, kpidCTime, VT_FILETIME}, + { NULL, kpidATime, VT_FILETIME}, + + { NULL, kpidAttrib, VT_UI4}, + + { NULL, kpidEncrypted, VT_BOOL}, + { NULL, kpidComment, VT_BSTR}, + + { NULL, kpidCRC, VT_UI4}, + + { NULL, kpidMethod, VT_BSTR}, + { NULL, kpidHostOS, VT_BSTR} + + // { NULL, kpidUnpackVer, VT_UI1}, +}; + +const wchar_t *kMethods[] = +{ + L"Store", + L"Shrink", + L"Reduced1", + L"Reduced2", + L"Reduced2", + L"Reduced3", + L"Implode", + L"Tokenizing", + L"Deflate", + L"Deflate64", + L"PKImploding" +}; + +const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]); +const wchar_t *kBZip2Method = L"BZip2"; +const wchar_t *kLZMAMethod = L"LZMA"; +const wchar_t *kJpegMethod = L"Jpeg"; +const wchar_t *kWavPackMethod = L"WavPack"; +const wchar_t *kPPMdMethod = L"PPMd"; +const wchar_t *kAESMethod = L"AES"; +const wchar_t *kZipCryptoMethod = L"ZipCrypto"; +const wchar_t *kStrongCryptoMethod = L"StrongCrypto"; + +struct CStrongCryptoPair +{ + UInt16 Id; + const wchar_t *Name; +}; + +CStrongCryptoPair g_StrongCryptoPairs[] = +{ + { NStrongCryptoFlags::kDES, L"DES" }, + { NStrongCryptoFlags::kRC2old, L"RC2a" }, + { NStrongCryptoFlags::k3DES168, L"3DES-168" }, + { NStrongCryptoFlags::k3DES112, L"3DES-112" }, + { NStrongCryptoFlags::kAES128, L"pkAES-128" }, + { NStrongCryptoFlags::kAES192, L"pkAES-192" }, + { NStrongCryptoFlags::kAES256, L"pkAES-256" }, + { NStrongCryptoFlags::kRC2, L"RC2" }, + { NStrongCryptoFlags::kBlowfish, L"Blowfish" }, + { NStrongCryptoFlags::kTwofish, L"Twofish" }, + { NStrongCryptoFlags::kRC4, L"RC4" } +}; + +STATPROPSTG kArcProps[] = +{ + { NULL, kpidBit64, VT_BOOL}, + { NULL, kpidComment, VT_BSTR} +}; + +CHandler::CHandler() +{ + InitMethodProperties(); +} + +static AString BytesToString(const CByteBuffer &data) +{ + AString s; + int size = (int)data.GetCapacity(); + if (size > 0) + { + char *p = s.GetBuffer(size + 1); + memcpy(p, (const Byte *)data, size); + p[size] = '\0'; + s.ReleaseBuffer(); + } + return s; +} + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidBit64: if (m_Archive.IsZip64) prop = m_Archive.IsZip64; break; + case kpidComment: + prop = MultiByteToUnicodeString(BytesToString(m_Archive.m_ArchiveInfo.Comment), CP_ACP); + break; + } + prop.Detach(value); + COM_TRY_END + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = m_Items.Size(); + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + const CItemEx &item = m_Items[index]; + switch(propID) + { + case kpidPath: prop = NItemName::GetOSName2(item.GetUnicodeString(item.Name)); break; + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: prop = item.UnPackSize; break; + case kpidPackSize: prop = item.PackSize; break; + case kpidTimeType: + { + FILETIME utcFileTime; + if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kTagTime, utcFileTime)) + prop = (UInt32)NFileTimeType::kWindows; + break; + } + case kpidCTime: + { + FILETIME ft; + if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, ft)) + prop = ft; + break; + } + case kpidATime: + { + FILETIME ft; + if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, ft)) + prop = ft; + break; + } + case kpidMTime: + { + FILETIME utcFileTime; + if (!item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utcFileTime)) + { + FILETIME localFileTime; + if (NTime::DosTimeToFileTime(item.Time, localFileTime)) + { + if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + } + else + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + } + prop = utcFileTime; + break; + } + case kpidAttrib: prop = item.GetWinAttributes(); break; + case kpidEncrypted: prop = item.IsEncrypted(); break; + case kpidComment: prop = item.GetUnicodeString(BytesToString(item.Comment)); break; + case kpidCRC: if (item.IsThereCrc()) prop = item.FileCRC; break; + case kpidMethod: + { + UInt16 methodId = item.CompressionMethod; + UString method; + if (item.IsEncrypted()) + { + if (methodId == NFileHeader::NCompressionMethod::kWzAES) + { + method = kAESMethod; + CWzAesExtraField aesField; + if (item.CentralExtra.GetWzAesField(aesField)) + { + method += L"-"; + wchar_t s[32]; + ConvertUInt64ToString((aesField.Strength + 1) * 64 , s); + method += s; + method += L" "; + methodId = aesField.Method; + } + } + else + { + if (item.IsStrongEncrypted()) + { + CStrongCryptoField f; + bool finded = false; + if (item.CentralExtra.GetStrongCryptoField(f)) + { + for (int i = 0; i < sizeof(g_StrongCryptoPairs) / sizeof(g_StrongCryptoPairs[0]); i++) + { + const CStrongCryptoPair &pair = g_StrongCryptoPairs[i]; + if (f.AlgId == pair.Id) + { + method += pair.Name; + finded = true; + break; + } + } + } + if (!finded) + method += kStrongCryptoMethod; + } + else + method += kZipCryptoMethod; + method += L" "; + } + } + if (methodId < kNumMethods) + method += kMethods[methodId]; + else switch (methodId) + { + case NFileHeader::NCompressionMethod::kLZMA: + method += kLZMAMethod; + if (item.IsLzmaEOS()) + method += L":EOS"; + break; + case NFileHeader::NCompressionMethod::kBZip2: method += kBZip2Method; break; + case NFileHeader::NCompressionMethod::kJpeg: method += kJpegMethod; break; + case NFileHeader::NCompressionMethod::kWavPack: method += kWavPackMethod; break; + case NFileHeader::NCompressionMethod::kPPMd: method += kPPMdMethod; break; + default: + { + wchar_t s[32]; + ConvertUInt64ToString(methodId, s); + method += s; + } + } + prop = method; + break; + } + case kpidHostOS: + prop = (item.MadeByVersion.HostOS < kNumHostOSes) ? + (kHostOS[item.MadeByVersion.HostOS]) : kUnknownOS; + break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +class CProgressImp: public CProgressVirt +{ + CMyComPtr _callback; +public: + STDMETHOD(SetTotal)(UInt64 numFiles); + STDMETHOD(SetCompleted)(UInt64 numFiles); + CProgressImp(IArchiveOpenCallback *callback): _callback(callback) {} +}; + +STDMETHODIMP CProgressImp::SetTotal(UInt64 numFiles) +{ + if (_callback) + return _callback->SetTotal(&numFiles, NULL); + return S_OK; +} + +STDMETHODIMP CProgressImp::SetCompleted(UInt64 numFiles) +{ + if (_callback) + return _callback->SetCompleted(&numFiles, NULL); + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback) +{ + COM_TRY_BEGIN + try + { + Close(); + RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(m_Archive.Open(inStream, maxCheckStartPosition)); + CProgressImp progressImp(callback); + return m_Archive.ReadHeaders(m_Items, &progressImp); + } + catch(const CInArchiveException &) { Close(); return S_FALSE; } + catch(...) { Close(); throw; } + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + m_Items.Clear(); + m_Archive.Close(); + return S_OK; +} + +////////////////////////////////////// +// CHandler::DecompressItems + +class CLzmaDecoder: + public ICompressCoder, + public CMyUnknownImp +{ + NCompress::NLzma::CDecoder *DecoderSpec; + CMyComPtr Decoder; +public: + CLzmaDecoder(); + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + + MY_UNKNOWN_IMP +}; + +CLzmaDecoder::CLzmaDecoder() +{ + DecoderSpec = new NCompress::NLzma::CDecoder; + Decoder = DecoderSpec; +} + +HRESULT CLzmaDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + Byte buf[9]; + RINOK(ReadStream_FALSE(inStream, buf, 9)); + if (buf[2] != 5 || buf[3] != 0) + return E_NOTIMPL; + RINOK(DecoderSpec->SetDecoderProperties2(buf + 4, 5)); + return Decoder->Code(inStream, outStream, NULL, outSize, progress); +} + +struct CMethodItem +{ + UInt16 ZipMethod; + CMyComPtr Coder; +}; + +class CZipDecoder +{ + NCrypto::NZip::CDecoder *_zipCryptoDecoderSpec; + NCrypto::NZipStrong::CDecoder *_pkAesDecoderSpec; + NCrypto::NWzAes::CDecoder *_wzAesDecoderSpec; + + CMyComPtr _zipCryptoDecoder; + CMyComPtr _pkAesDecoder; + CMyComPtr _wzAesDecoder; + + CFilterCoder *filterStreamSpec; + CMyComPtr filterStream; + CMyComPtr getTextPassword; + CObjectVector methodItems; + +public: + CZipDecoder(): + _zipCryptoDecoderSpec(0), + _pkAesDecoderSpec(0), + _wzAesDecoderSpec(0), + filterStreamSpec(0) {} + + HRESULT Decode( + DECL_EXTERNAL_CODECS_LOC_VARS + CInArchive &archive, const CItemEx &item, + ISequentialOutStream *realOutStream, + IArchiveExtractCallback *extractCallback, + ICompressProgressInfo *compressProgress, + UInt32 numThreads, Int32 &res); +}; + +HRESULT CZipDecoder::Decode( + DECL_EXTERNAL_CODECS_LOC_VARS + CInArchive &archive, const CItemEx &item, + ISequentialOutStream *realOutStream, + IArchiveExtractCallback *extractCallback, + ICompressProgressInfo *compressProgress, + UInt32 numThreads, Int32 &res) +{ + res = NArchive::NExtract::NOperationResult::kDataError; + CInStreamReleaser inStreamReleaser; + + bool needCRC = true; + bool wzAesMode = false; + bool pkAesMode = false; + UInt16 methodId = item.CompressionMethod; + if (item.IsEncrypted()) + { + if (item.IsStrongEncrypted()) + { + CStrongCryptoField f; + if (item.CentralExtra.GetStrongCryptoField(f)) + { + pkAesMode = true; + } + if (!pkAesMode) + { + res = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + return S_OK; + } + } + if (methodId == NFileHeader::NCompressionMethod::kWzAES) + { + CWzAesExtraField aesField; + if (item.CentralExtra.GetWzAesField(aesField)) + { + wzAesMode = true; + needCRC = aesField.NeedCrc(); + } + } + } + + COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; + CMyComPtr outStream = outStreamSpec; + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(needCRC); + + UInt64 authenticationPos; + + CMyComPtr inStream; + { + UInt64 packSize = item.PackSize; + if (wzAesMode) + { + if (packSize < NCrypto::NWzAes::kMacSize) + return S_OK; + packSize -= NCrypto::NWzAes::kMacSize; + } + UInt64 dataPos = item.GetDataPosition(); + inStream.Attach(archive.CreateLimitedStream(dataPos, packSize)); + authenticationPos = dataPos + packSize; + } + + CMyComPtr cryptoFilter; + if (item.IsEncrypted()) + { + if (wzAesMode) + { + CWzAesExtraField aesField; + if (!item.CentralExtra.GetWzAesField(aesField)) + return S_OK; + methodId = aesField.Method; + if (!_wzAesDecoder) + { + _wzAesDecoderSpec = new NCrypto::NWzAes::CDecoder; + _wzAesDecoder = _wzAesDecoderSpec; + } + cryptoFilter = _wzAesDecoder; + Byte properties = aesField.Strength; + RINOK(_wzAesDecoderSpec->SetDecoderProperties2(&properties, 1)); + } + else if (pkAesMode) + { + if (!_pkAesDecoder) + { + _pkAesDecoderSpec = new NCrypto::NZipStrong::CDecoder; + _pkAesDecoder = _pkAesDecoderSpec; + } + cryptoFilter = _pkAesDecoder; + } + else + { + if (!_zipCryptoDecoder) + { + _zipCryptoDecoderSpec = new NCrypto::NZip::CDecoder; + _zipCryptoDecoder = _zipCryptoDecoderSpec; + } + cryptoFilter = _zipCryptoDecoder; + } + CMyComPtr cryptoSetPassword; + RINOK(cryptoFilter.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword)); + + if (!getTextPassword) + extractCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword); + + if (getTextPassword) + { + CMyComBSTR password; + RINOK(getTextPassword->CryptoGetTextPassword(&password)); + AString charPassword; + if (wzAesMode || pkAesMode) + { + charPassword = UnicodeStringToMultiByte((const wchar_t *)password, CP_ACP); + /* + for (int i = 0;; i++) + { + wchar_t c = password[i]; + if (c == 0) + break; + if (c >= 0x80) + { + res = NArchive::NExtract::NOperationResult::kDataError; + return S_OK; + } + charPassword += (char)c; + } + */ + } + else + { + // we use OEM. WinZip/Windows probably use ANSI for some files + charPassword = UnicodeStringToMultiByte((const wchar_t *)password, CP_OEMCP); + } + HRESULT result = cryptoSetPassword->CryptoSetPassword( + (const Byte *)(const char *)charPassword, charPassword.Length()); + if (result != S_OK) + return S_OK; + } + else + { + RINOK(cryptoSetPassword->CryptoSetPassword(0, 0)); + } + } + + int m; + for (m = 0; m < methodItems.Size(); m++) + if (methodItems[m].ZipMethod == methodId) + break; + + if (m == methodItems.Size()) + { + CMethodItem mi; + mi.ZipMethod = methodId; + if (methodId == NFileHeader::NCompressionMethod::kStored) + mi.Coder = new NCompress::CCopyCoder; + else if (methodId == NFileHeader::NCompressionMethod::kShrunk) + mi.Coder = new NCompress::NShrink::CDecoder; + else if (methodId == NFileHeader::NCompressionMethod::kImploded) + mi.Coder = new NCompress::NImplode::NDecoder::CCoder; + else if (methodId == NFileHeader::NCompressionMethod::kLZMA) + mi.Coder = new CLzmaDecoder; + else + { + CMethodId szMethodID; + if (methodId == NFileHeader::NCompressionMethod::kBZip2) + szMethodID = kMethodId_BZip2; + else + { + if (methodId > 0xFF) + { + res = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + return S_OK; + } + szMethodID = kMethodId_ZipBase + (Byte)methodId; + } + + RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS szMethodID, mi.Coder, false)); + + if (mi.Coder == 0) + { + res = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + return S_OK; + } + } + m = methodItems.Add(mi); + } + ICompressCoder *coder = methodItems[m].Coder; + + { + CMyComPtr setDecoderProperties; + coder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties); + if (setDecoderProperties) + { + Byte properties = (Byte)item.Flags; + RINOK(setDecoderProperties->SetDecoderProperties2(&properties, 1)); + } + } + + #ifdef COMPRESS_MT + { + CMyComPtr setCoderMt; + coder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt); + if (setCoderMt) + { + RINOK(setCoderMt->SetNumberOfThreads(numThreads)); + } + } + #endif + + { + HRESULT result = S_OK; + CMyComPtr inStreamNew; + if (item.IsEncrypted()) + { + if (!filterStream) + { + filterStreamSpec = new CFilterCoder; + filterStream = filterStreamSpec; + } + filterStreamSpec->Filter = cryptoFilter; + if (wzAesMode) + { + result = _wzAesDecoderSpec->ReadHeader(inStream); + } + else if (pkAesMode) + { + result =_pkAesDecoderSpec->ReadHeader(inStream, item.FileCRC, item.UnPackSize); + if (result == S_OK) + { + bool passwOK; + result = _pkAesDecoderSpec->CheckPassword(passwOK); + if (result == S_OK && !passwOK) + result = S_FALSE; + } + } + else + { + result = _zipCryptoDecoderSpec->ReadHeader(inStream); + } + + if (result == S_OK) + { + RINOK(filterStreamSpec->SetInStream(inStream)); + inStreamReleaser.FilterCoder = filterStreamSpec; + inStreamNew = filterStream; + if (wzAesMode) + { + if (!_wzAesDecoderSpec->CheckPasswordVerifyCode()) + result = S_FALSE; + } + } + } + else + inStreamNew = inStream; + if (result == S_OK) + result = coder->Code(inStreamNew, outStream, NULL, &item.UnPackSize, compressProgress); + if (result == S_FALSE) + return S_OK; + if (result == E_NOTIMPL) + { + res = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + return S_OK; + } + + RINOK(result); + } + bool crcOK = true; + bool authOk = true; + if (needCRC) + crcOK = (outStreamSpec->GetCRC() == item.FileCRC); + if (wzAesMode) + { + inStream.Attach(archive.CreateLimitedStream(authenticationPos, NCrypto::NWzAes::kMacSize)); + if (_wzAesDecoderSpec->CheckMac(inStream, authOk) != S_OK) + authOk = false; + } + + res = ((crcOK && authOk) ? + NArchive::NExtract::NOperationResult::kOK : + NArchive::NExtract::NOperationResult::kCRCError); + return S_OK; +} + + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + CZipDecoder myDecoder; + bool testMode = (_aTestMode != 0); + UInt64 totalUnPacked = 0, totalPacked = 0; + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = m_Items.Size(); + if(numItems == 0) + return S_OK; + UInt32 i; + for(i = 0; i < numItems; i++) + { + const CItemEx &item = m_Items[allFilesMode ? i : indices[i]]; + totalUnPacked += item.UnPackSize; + totalPacked += item.PackSize; + } + RINOK(extractCallback->SetTotal(totalUnPacked)); + + UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0; + UInt64 currentItemUnPacked, currentItemPacked; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + for (i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked, + currentTotalPacked += currentItemPacked) + { + currentItemUnPacked = 0; + currentItemPacked = 0; + + lps->InSize = currentTotalPacked; + lps->OutSize = currentTotalUnPacked; + RINOK(lps->SetCur()); + + CMyComPtr realOutStream; + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + Int32 index = allFilesMode ? i : indices[i]; + + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + + CItemEx item = m_Items[index]; + if (!item.FromLocal) + { + HRESULT res = m_Archive.ReadLocalItemAfterCdItem(item); + if (res == S_FALSE) + { + if (item.IsDir() || realOutStream || testMode) + { + RINOK(extractCallback->PrepareOperation(askMode)); + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + } + continue; + } + RINOK(res); + } + + if (item.IsDir() || item.IgnoreItem()) + { + // if (!testMode) + { + RINOK(extractCallback->PrepareOperation(askMode)); + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + } + continue; + } + + currentItemUnPacked = item.UnPackSize; + currentItemPacked = item.PackSize; + + if (!testMode && (!realOutStream)) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)); + +#ifndef COMPRESS_MT +#define _numThreads 1 +#endif + + Int32 res; + RINOK(myDecoder.Decode( + EXTERNAL_CODECS_VARS + m_Archive, item, realOutStream, extractCallback, + progress, + _numThreads, + res)); + realOutStream.Release(); + + RINOK(extractCallback->SetOperationResult(res)) + } + return S_OK; + COM_TRY_END +} + +#ifndef EXTRACT_ONLY +IMPL_ISetCompressCodecsInfo +#endif + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipHandler.h b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipHandler.h new file mode 100644 index 000000000..fc0cfa250 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipHandler.h @@ -0,0 +1,100 @@ +// Zip/Handler.h + +#ifndef __ZIP_HANDLER_H +#define __ZIP_HANDLER_H + +#include "../../../Common/DynamicBuffer.h" +#include "../../ICoder.h" +#include "../IArchive.h" + +#include "../../Common/CreateCoder.h" + +#include "ZipIn.h" +#include "ZipCompressionMode.h" + +#ifdef COMPRESS_MT +#include "../../../Windows/System.h" +#endif + +namespace NArchive { +namespace NZip { + +class CHandler: + public IInArchive, +#ifndef EXTRACT_ONLY + public IOutArchive, + public ISetProperties, + PUBLIC_ISetCompressCodecsInfo +#endif + public CMyUnknownImp +{ +public: + MY_QUERYINTERFACE_BEGIN2(IInArchive) +#ifndef EXTRACT_ONLY + MY_QUERYINTERFACE_ENTRY(IOutArchive) + MY_QUERYINTERFACE_ENTRY(ISetProperties) + QUERY_ENTRY_ISetCompressCodecsInfo +#endif + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + INTERFACE_IInArchive(;) +#ifndef EXTRACT_ONLY + INTERFACE_IOutArchive(;) + + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties); + + DECL_ISetCompressCodecsInfo +#endif + + CHandler(); +private: + CObjectVector m_Items; + CInArchive m_Archive; + + int m_Level; + int m_MainMethod; + UInt32 m_DicSize; + UInt32 m_Algo; + UInt32 m_NumPasses; + UInt32 m_NumFastBytes; + UInt32 m_NumMatchFinderCycles; + bool m_NumMatchFinderCyclesDefined; + + bool m_IsAesMode; + Byte m_AesKeyMode; + + bool m_WriteNtfsTimeExtra; + bool m_ForseLocal; + bool m_ForseUtf8; + + #ifdef COMPRESS_MT + UInt32 _numThreads; + #endif + + DECL_EXTERNAL_CODECS_VARS + + void InitMethodProperties() + { + m_Level = -1; + m_MainMethod = -1; + m_Algo = + m_DicSize = + m_NumPasses = + m_NumFastBytes = + m_NumMatchFinderCycles = 0xFFFFFFFF; + m_NumMatchFinderCyclesDefined = false; + m_IsAesMode = false; + m_AesKeyMode = 3; // aes-256 + m_WriteNtfsTimeExtra = false; + m_ForseLocal = false; + m_ForseUtf8 = false; + #ifdef COMPRESS_MT + _numThreads = NWindows::NSystem::GetNumberOfProcessors();; + #endif + } +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipHeader.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipHeader.cpp new file mode 100644 index 000000000..331aed2be --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipHeader.cpp @@ -0,0 +1,35 @@ +// Archive/Zip/Header.h + +#include "StdAfx.h" + +#include "ZipHeader.h" + +namespace NArchive { +namespace NZip { + +namespace NSignature +{ + UInt32 kLocalFileHeader = 0x04034B50 + 1; + UInt32 kDataDescriptor = 0x08074B50 + 1; + UInt32 kCentralFileHeader = 0x02014B50 + 1; + UInt32 kEndOfCentralDir = 0x06054B50 + 1; + UInt32 kZip64EndOfCentralDir = 0x06064B50 + 1; + UInt32 kZip64EndOfCentralDirLocator = 0x07064B50 + 1; + + class CMarkersInitializer + { + public: + CMarkersInitializer() + { + kLocalFileHeader--; + kDataDescriptor--; + kCentralFileHeader--; + kEndOfCentralDir--; + kZip64EndOfCentralDir--; + kZip64EndOfCentralDirLocator--; + } + } g_MarkerInitializer; +} + +}} + diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipHeader.h b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipHeader.h new file mode 100644 index 000000000..b595e65e8 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipHeader.h @@ -0,0 +1,265 @@ +// Archive/Zip/Header.h + +#ifndef __ARCHIVE_ZIP_HEADER_H +#define __ARCHIVE_ZIP_HEADER_H + +#include "../../../Common/Types.h" + +namespace NArchive { +namespace NZip { + +namespace NSignature +{ + extern UInt32 kLocalFileHeader; + extern UInt32 kDataDescriptor; + extern UInt32 kCentralFileHeader; + extern UInt32 kEndOfCentralDir; + extern UInt32 kZip64EndOfCentralDir; + extern UInt32 kZip64EndOfCentralDirLocator; + + static const UInt32 kMarkerSize = 4; +} + +const UInt32 kEcdSize = 22; +const UInt32 kZip64EcdSize = 44; +const UInt32 kZip64EcdLocatorSize = 20; +/* +struct CEndOfCentralDirectoryRecord +{ + UInt16 ThisDiskNumber; + UInt16 StartCentralDirectoryDiskNumber; + UInt16 NumEntriesInCentaralDirectoryOnThisDisk; + UInt16 NumEntriesInCentaralDirectory; + UInt32 CentralDirectorySize; + UInt32 CentralDirectoryStartOffset; + UInt16 CommentSize; +}; + +struct CEndOfCentralDirectoryRecordFull +{ + UInt32 Signature; + CEndOfCentralDirectoryRecord Header; +}; +*/ + +namespace NFileHeader +{ + /* + struct CVersion + { + Byte Version; + Byte HostOS; + }; + */ + + namespace NCompressionMethod + { + enum EType + { + kStored = 0, + kShrunk = 1, + kReduced1 = 2, + kReduced2 = 3, + kReduced3 = 4, + kReduced4 = 5, + kImploded = 6, + kReservedTokenizing = 7, // reserved for tokenizing + kDeflated = 8, + kDeflated64 = 9, + kPKImploding = 10, + + kBZip2 = 12, + kLZMA = 14, + kTerse = 18, + kLz77 = 19, + kJpeg = 0x60, + kWavPack = 0x61, + kPPMd = 0x62, + kWzAES = 0x63 + }; + const int kNumCompressionMethods = 11; + const Byte kMadeByProgramVersion = 20; + + const Byte kDeflateExtractVersion = 20; + const Byte kStoreExtractVersion = 10; + + const Byte kSupportedVersion = 20; + } + + namespace NExtraID + { + enum + { + kZip64 = 0x01, + kNTFS = 0x0A, + kStrongEncrypt = 0x17, + kWzAES = 0x9901 + }; + } + + namespace NNtfsExtra + { + const UInt16 kTagTime = 1; + enum + { + kMTime = 0, + kATime = 1, + kCTime = 2 + }; + } + + const UInt32 kLocalBlockSize = 26; + /* + struct CLocalBlock + { + CVersion ExtractVersion; + + UInt16 Flags; + UInt16 CompressionMethod; + UInt32 Time; + UInt32 FileCRC; + UInt32 PackSize; + UInt32 UnPackSize; + UInt16 NameSize; + UInt16 ExtraSize; + }; + */ + + const UInt32 kDataDescriptorSize = 16; + // const UInt32 kDataDescriptor64Size = 16 + 8; + /* + struct CDataDescriptor + { + UInt32 Signature; + UInt32 FileCRC; + UInt32 PackSize; + UInt32 UnPackSize; + }; + + struct CLocalBlockFull + { + UInt32 Signature; + CLocalBlock Header; + }; + */ + + const UInt32 kCentralBlockSize = 42; + /* + struct CBlock + { + CVersion MadeByVersion; + CVersion ExtractVersion; + UInt16 Flags; + UInt16 CompressionMethod; + UInt32 Time; + UInt32 FileCRC; + UInt32 PackSize; + UInt32 UnPackSize; + UInt16 NameSize; + UInt16 ExtraSize; + UInt16 CommentSize; + UInt16 DiskNumberStart; + UInt16 InternalAttributes; + UInt32 ExternalAttributes; + UInt32 LocalHeaderOffset; + }; + + struct CBlockFull + { + UInt32 Signature; + CBlock Header; + }; + */ + + namespace NFlags + { + const int kEncrypted = 1 << 0; + const int kLzmaEOS = 1 << 1; + const int kDescriptorUsedMask = 1 << 3; + const int kStrongEncrypted = 1 << 6; + const int kUtf8 = 1 << 11; + + const int kImplodeDictionarySizeMask = 1 << 1; + const int kImplodeLiteralsOnMask = 1 << 2; + + const int kDeflateTypeBitStart = 1; + const int kNumDeflateTypeBits = 2; + const int kNumDeflateTypes = (1 << kNumDeflateTypeBits); + const int kDeflateTypeMask = (1 << kNumDeflateTypeBits) - 1; + } + + namespace NHostOS + { + enum EEnum + { + kFAT = 0, + kAMIGA = 1, + kVMS = 2, // VAX/VMS + kUnix = 3, + kVM_CMS = 4, + kAtari = 5, // what if it's a minix filesystem? [cjh] + kHPFS = 6, // filesystem used by OS/2 (and NT 3.x) + kMac = 7, + kZ_System = 8, + kCPM = 9, + kTOPS20 = 10, // pkzip 2.50 NTFS + kNTFS = 11, // filesystem used by Windows NT + kQDOS = 12, // SMS/QDOS + kAcorn = 13, // Archimedes Acorn RISC OS + kVFAT = 14, // filesystem used by Windows 95, NT + kMVS = 15, + kBeOS = 16, // hybrid POSIX/database filesystem + kTandem = 17, + kOS400 = 18, + kOSX = 19 + }; + } + namespace NUnixAttribute + { + const UInt32 kIFMT = 0170000; /* Unix file type mask */ + + const UInt32 kIFDIR = 0040000; /* Unix directory */ + const UInt32 kIFREG = 0100000; /* Unix regular file */ + const UInt32 kIFSOCK = 0140000; /* Unix socket (BSD, not SysV or Amiga) */ + const UInt32 kIFLNK = 0120000; /* Unix symbolic link (not SysV, Amiga) */ + const UInt32 kIFBLK = 0060000; /* Unix block special (not Amiga) */ + const UInt32 kIFCHR = 0020000; /* Unix character special (not Amiga) */ + const UInt32 kIFIFO = 0010000; /* Unix fifo (BCC, not MSC or Amiga) */ + + const UInt32 kISUID = 04000; /* Unix set user id on execution */ + const UInt32 kISGID = 02000; /* Unix set group id on execution */ + const UInt32 kISVTX = 01000; /* Unix directory permissions control */ + const UInt32 kENFMT = kISGID; /* Unix record locking enforcement flag */ + const UInt32 kIRWXU = 00700; /* Unix read, write, execute: owner */ + const UInt32 kIRUSR = 00400; /* Unix read permission: owner */ + const UInt32 kIWUSR = 00200; /* Unix write permission: owner */ + const UInt32 kIXUSR = 00100; /* Unix execute permission: owner */ + const UInt32 kIRWXG = 00070; /* Unix read, write, execute: group */ + const UInt32 kIRGRP = 00040; /* Unix read permission: group */ + const UInt32 kIWGRP = 00020; /* Unix write permission: group */ + const UInt32 kIXGRP = 00010; /* Unix execute permission: group */ + const UInt32 kIRWXO = 00007; /* Unix read, write, execute: other */ + const UInt32 kIROTH = 00004; /* Unix read permission: other */ + const UInt32 kIWOTH = 00002; /* Unix write permission: other */ + const UInt32 kIXOTH = 00001; /* Unix execute permission: other */ + } + + namespace NAmigaAttribute + { + const UInt32 kIFMT = 06000; /* Amiga file type mask */ + const UInt32 kIFDIR = 04000; /* Amiga directory */ + const UInt32 kIFREG = 02000; /* Amiga regular file */ + const UInt32 kIHIDDEN = 00200; /* to be supported in AmigaDOS 3.x */ + const UInt32 kISCRIPT = 00100; /* executable script (text command file) */ + const UInt32 kIPURE = 00040; /* allow loading into resident memory */ + const UInt32 kIARCHIVE = 00020; /* not modified since bit was last set */ + const UInt32 kIREAD = 00010; /* can be opened for reading */ + const UInt32 kIWRITE = 00004; /* can be opened for writing */ + const UInt32 kIEXECUTE = 00002; /* executable image, a loadable runfile */ + const UInt32 kIDELETE = 00001; /* can be deleted */ + } +} + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipIn.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipIn.cpp new file mode 100644 index 000000000..7c43bd911 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipIn.cpp @@ -0,0 +1,868 @@ +// Archive/ZipIn.cpp + +#include "StdAfx.h" + +#include "ZipIn.h" +#include "Windows/Defs.h" +#include "Common/StringConvert.h" +#include "Common/DynamicBuffer.h" +#include "../../Common/LimitedStreams.h" +#include "../../Common/StreamUtils.h" + +extern "C" +{ + #include "../../../../C/CpuArch.h" +} + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + +namespace NArchive { +namespace NZip { + +// static const char kEndOfString = '\0'; + +HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) +{ + Close(); + RINOK(stream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition)); + m_Position = m_StreamStartPosition; + RINOK(FindAndReadMarker(stream, searchHeaderSizeLimit)); + RINOK(stream->Seek(m_Position, STREAM_SEEK_SET, NULL)); + m_Stream = stream; + return S_OK; +} + +void CInArchive::Close() +{ + m_Stream.Release(); +} + +HRESULT CInArchive::Seek(UInt64 offset) +{ + return m_Stream->Seek(offset, STREAM_SEEK_SET, NULL); +} + +////////////////////////////////////// +// Markers + +static inline bool TestMarkerCandidate(const Byte *p, UInt32 &value) +{ + value = Get32(p); + return + (value == NSignature::kLocalFileHeader) || + (value == NSignature::kEndOfCentralDir); +} + +static const UInt32 kNumMarkerAddtionalBytes = 2; +static inline bool TestMarkerCandidate2(const Byte *p, UInt32 &value) +{ + value = Get32(p); + if (value == NSignature::kEndOfCentralDir) + return (Get16(p + 4) == 0); + return (value == NSignature::kLocalFileHeader && p[4] < 128); +} + +HRESULT CInArchive::FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit) +{ + m_ArchiveInfo.Clear(); + m_Position = m_StreamStartPosition; + + Byte marker[NSignature::kMarkerSize]; + RINOK(ReadStream_FALSE(stream, marker, NSignature::kMarkerSize)); + m_Position += NSignature::kMarkerSize; + if (TestMarkerCandidate(marker, m_Signature)) + return S_OK; + + CByteDynamicBuffer dynamicBuffer; + const UInt32 kSearchMarkerBufferSize = 0x10000; + dynamicBuffer.EnsureCapacity(kSearchMarkerBufferSize); + Byte *buffer = dynamicBuffer; + UInt32 numBytesPrev = NSignature::kMarkerSize - 1; + memcpy(buffer, marker + 1, numBytesPrev); + UInt64 curTestPos = m_StreamStartPosition + 1; + for (;;) + { + if (searchHeaderSizeLimit != NULL) + if (curTestPos - m_StreamStartPosition > *searchHeaderSizeLimit) + break; + size_t numReadBytes = kSearchMarkerBufferSize - numBytesPrev; + RINOK(ReadStream(stream, buffer + numBytesPrev, &numReadBytes)); + m_Position += numReadBytes; + UInt32 numBytesInBuffer = numBytesPrev + (UInt32)numReadBytes; + const UInt32 kMarker2Size = NSignature::kMarkerSize + kNumMarkerAddtionalBytes; + if (numBytesInBuffer < kMarker2Size) + break; + UInt32 numTests = numBytesInBuffer - kMarker2Size + 1; + for (UInt32 pos = 0; pos < numTests; pos++) + { + if (buffer[pos] != 0x50) + continue; + if (TestMarkerCandidate2(buffer + pos, m_Signature)) + { + curTestPos += pos; + m_ArchiveInfo.StartPosition = curTestPos; + m_Position = curTestPos + NSignature::kMarkerSize; + return S_OK; + } + } + curTestPos += numTests; + numBytesPrev = numBytesInBuffer - numTests; + memmove(buffer, buffer + numTests, numBytesPrev); + } + return S_FALSE; +} + +HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize) +{ + size_t realProcessedSize = size; + HRESULT result = ReadStream(m_Stream, data, &realProcessedSize); + if (processedSize != NULL) + *processedSize = (UInt32)realProcessedSize; + m_Position += realProcessedSize; + return result; +} + +void CInArchive::IncreaseRealPosition(UInt64 addValue) +{ + if (m_Stream->Seek(addValue, STREAM_SEEK_CUR, &m_Position) != S_OK) + throw CInArchiveException(CInArchiveException::kSeekStreamError); +} + +bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size) +{ + UInt32 realProcessedSize; + if (ReadBytes(data, size, &realProcessedSize) != S_OK) + throw CInArchiveException(CInArchiveException::kReadStreamError); + return (realProcessedSize == size); +} + +void CInArchive::SafeReadBytes(void *data, UInt32 size) +{ + if (!ReadBytesAndTestSize(data, size)) + throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); +} + +void CInArchive::ReadBuffer(CByteBuffer &buffer, UInt32 size) +{ + buffer.SetCapacity(size); + if (size > 0) + SafeReadBytes(buffer, size); +} + +Byte CInArchive::ReadByte() +{ + Byte b; + SafeReadBytes(&b, 1); + return b; +} + +UInt16 CInArchive::ReadUInt16() +{ + UInt16 value = 0; + for (int i = 0; i < 2; i++) + value |= (((UInt16)ReadByte()) << (8 * i)); + return value; +} + +UInt32 CInArchive::ReadUInt32() +{ + UInt32 value = 0; + for (int i = 0; i < 4; i++) + value |= (((UInt32)ReadByte()) << (8 * i)); + return value; +} + +UInt64 CInArchive::ReadUInt64() +{ + UInt64 value = 0; + for (int i = 0; i < 8; i++) + value |= (((UInt64)ReadByte()) << (8 * i)); + return value; +} + +bool CInArchive::ReadUInt32(UInt32 &value) +{ + value = 0; + for (int i = 0; i < 4; i++) + { + Byte b; + if (!ReadBytesAndTestSize(&b, 1)) + return false; + value |= (UInt32(b) << (8 * i)); + } + return true; +} + + +AString CInArchive::ReadFileName(UInt32 nameSize) +{ + if (nameSize == 0) + return AString(); + char *p = m_NameBuffer.GetBuffer(nameSize); + SafeReadBytes(p, nameSize); + p[nameSize] = 0; + m_NameBuffer.ReleaseBuffer(); + return m_NameBuffer; +} + +void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const +{ + archiveInfo = m_ArchiveInfo; +} + +/* +void CInArchive::ThrowIncorrectArchiveException() +{ + throw CInArchiveException(CInArchiveException::kIncorrectArchive); +} +*/ + +static UInt32 GetUInt32(const Byte *data) +{ + return + ((UInt32)(Byte)data[0]) | + (((UInt32)(Byte)data[1]) << 8) | + (((UInt32)(Byte)data[2]) << 16) | + (((UInt32)(Byte)data[3]) << 24); +} + +/* +static UInt16 GetUInt16(const Byte *data) +{ + return + ((UInt16)(Byte)data[0]) | + (((UInt16)(Byte)data[1]) << 8); +} +*/ + +static UInt64 GetUInt64(const Byte *data) +{ + return GetUInt32(data) | ((UInt64)GetUInt32(data + 4) << 32); +} + + + +void CInArchive::ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock, + UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber) +{ + extraBlock.Clear(); + UInt32 remain = extraSize; + while(remain >= 4) + { + CExtraSubBlock subBlock; + subBlock.ID = ReadUInt16(); + UInt32 dataSize = ReadUInt16(); + remain -= 4; + if (dataSize > remain) // it's bug + dataSize = remain; + if (subBlock.ID == NFileHeader::NExtraID::kZip64) + { + if (unpackSize == 0xFFFFFFFF) + { + if (dataSize < 8) + break; + unpackSize = ReadUInt64(); + remain -= 8; + dataSize -= 8; + } + if (packSize == 0xFFFFFFFF) + { + if (dataSize < 8) + break; + packSize = ReadUInt64(); + remain -= 8; + dataSize -= 8; + } + if (localHeaderOffset == 0xFFFFFFFF) + { + if (dataSize < 8) + break; + localHeaderOffset = ReadUInt64(); + remain -= 8; + dataSize -= 8; + } + if (diskStartNumber == 0xFFFF) + { + if (dataSize < 4) + break; + diskStartNumber = ReadUInt32(); + remain -= 4; + dataSize -= 4; + } + for (UInt32 i = 0; i < dataSize; i++) + ReadByte(); + } + else + { + ReadBuffer(subBlock.Data, dataSize); + extraBlock.SubBlocks.Add(subBlock); + } + remain -= dataSize; + } + IncreaseRealPosition(remain); +} + +HRESULT CInArchive::ReadLocalItem(CItemEx &item) +{ + item.ExtractVersion.Version = ReadByte(); + item.ExtractVersion.HostOS = ReadByte(); + item.Flags = ReadUInt16(); + item.CompressionMethod = ReadUInt16(); + item.Time = ReadUInt32(); + item.FileCRC = ReadUInt32(); + item.PackSize = ReadUInt32(); + item.UnPackSize = ReadUInt32(); + UInt32 fileNameSize = ReadUInt16(); + item.LocalExtraSize = ReadUInt16(); + item.Name = ReadFileName(fileNameSize); + item.FileHeaderWithNameSize = 4 + NFileHeader::kLocalBlockSize + fileNameSize; + if (item.LocalExtraSize > 0) + { + UInt64 localHeaderOffset = 0; + UInt32 diskStartNumber = 0; + ReadExtra(item.LocalExtraSize, item.LocalExtra, item.UnPackSize, item.PackSize, + localHeaderOffset, diskStartNumber); + } + /* + if (item.IsDir()) + item.UnPackSize = 0; // check It + */ + return S_OK; +} + +HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item) +{ + if (item.FromLocal) + return S_OK; + try + { + RINOK(Seek(m_ArchiveInfo.Base + item.LocalHeaderPosition)); + CItemEx localItem; + if (ReadUInt32() != NSignature::kLocalFileHeader) + return S_FALSE; + RINOK(ReadLocalItem(localItem)); + if (item.Flags != localItem.Flags) + { + if ( + (item.CompressionMethod != NFileHeader::NCompressionMethod::kDeflated || + (item.Flags & 0x7FF9) != (localItem.Flags & 0x7FF9)) && + (item.CompressionMethod != NFileHeader::NCompressionMethod::kStored || + (item.Flags & 0x7FFF) != (localItem.Flags & 0x7FFF)) && + (item.CompressionMethod != NFileHeader::NCompressionMethod::kImploded || + (item.Flags & 0x7FFF) != (localItem.Flags & 0x7FFF)) + ) + return S_FALSE; + } + + if (item.CompressionMethod != localItem.CompressionMethod || + // item.Time != localItem.Time || + (!localItem.HasDescriptor() && + ( + item.FileCRC != localItem.FileCRC || + item.PackSize != localItem.PackSize || + item.UnPackSize != localItem.UnPackSize + ) + ) || + item.Name.Length() != localItem.Name.Length() + ) + return S_FALSE; + item.FileHeaderWithNameSize = localItem.FileHeaderWithNameSize; + item.LocalExtraSize = localItem.LocalExtraSize; + item.LocalExtra = localItem.LocalExtra; + item.FromLocal = true; + } + catch(...) { return S_FALSE; } + return S_OK; +} + +HRESULT CInArchive::ReadLocalItemDescriptor(CItemEx &item) +{ + if (item.HasDescriptor()) + { + const int kBufferSize = (1 << 12); + Byte buffer[kBufferSize]; + + UInt32 numBytesInBuffer = 0; + UInt32 packedSize = 0; + + bool descriptorWasFound = false; + for (;;) + { + UInt32 processedSize; + RINOK(ReadBytes(buffer + numBytesInBuffer, kBufferSize - numBytesInBuffer, &processedSize)); + numBytesInBuffer += processedSize; + if (numBytesInBuffer < NFileHeader::kDataDescriptorSize) + return S_FALSE; + UInt32 i; + for (i = 0; i <= numBytesInBuffer - NFileHeader::kDataDescriptorSize; i++) + { + // descriptorSignature field is Info-ZIP's extension + // to Zip specification. + UInt32 descriptorSignature = GetUInt32(buffer + i); + + // !!!! It must be fixed for Zip64 archives + UInt32 descriptorPackSize = GetUInt32(buffer + i + 8); + if (descriptorSignature== NSignature::kDataDescriptor && descriptorPackSize == packedSize + i) + { + descriptorWasFound = true; + item.FileCRC = GetUInt32(buffer + i + 4); + item.PackSize = descriptorPackSize; + item.UnPackSize = GetUInt32(buffer + i + 12); + IncreaseRealPosition(Int64(Int32(0 - (numBytesInBuffer - i - NFileHeader::kDataDescriptorSize)))); + break; + } + } + if (descriptorWasFound) + break; + packedSize += i; + int j; + for (j = 0; i < numBytesInBuffer; i++, j++) + buffer[j] = buffer[i]; + numBytesInBuffer = j; + } + } + else + IncreaseRealPosition(item.PackSize); + return S_OK; +} + +HRESULT CInArchive::ReadLocalItemAfterCdItemFull(CItemEx &item) +{ + if (item.FromLocal) + return S_OK; + try + { + RINOK(ReadLocalItemAfterCdItem(item)); + if (item.HasDescriptor()) + { + RINOK(Seek(m_ArchiveInfo.Base + item.GetDataPosition() + item.PackSize)); + if (ReadUInt32() != NSignature::kDataDescriptor) + return S_FALSE; + UInt32 crc = ReadUInt32(); + UInt64 packSize, unpackSize; + + /* + if (IsZip64) + { + packSize = ReadUInt64(); + unpackSize = ReadUInt64(); + } + else + */ + { + packSize = ReadUInt32(); + unpackSize = ReadUInt32(); + } + + if (crc != item.FileCRC || item.PackSize != packSize || item.UnPackSize != unpackSize) + return S_FALSE; + } + } + catch(...) { return S_FALSE; } + return S_OK; +} + +HRESULT CInArchive::ReadCdItem(CItemEx &item) +{ + item.FromCentral = true; + const int kBufSize = 42; + Byte p[kBufSize]; + SafeReadBytes(p, kBufSize); + item.MadeByVersion.Version = p[0]; + item.MadeByVersion.HostOS = p[1]; + item.ExtractVersion.Version = p[2]; + item.ExtractVersion.HostOS = p[3]; + item.Flags = Get16(p + 4); + item.CompressionMethod = Get16(p + 6); + item.Time = Get32(p + 8); + item.FileCRC = Get32(p + 12); + item.PackSize = Get32(p + 16); + item.UnPackSize = Get32(p + 20); + UInt16 headerNameSize = Get16(p + 24); + UInt16 headerExtraSize = Get16(p + 26); + UInt16 headerCommentSize = Get16(p + 28); + UInt32 headerDiskNumberStart = Get16(p + 30); + item.InternalAttributes = Get16(p + 32); + item.ExternalAttributes = Get32(p + 34); + item.LocalHeaderPosition = Get32(p + 38); + item.Name = ReadFileName(headerNameSize); + + if (headerExtraSize > 0) + { + ReadExtra(headerExtraSize, item.CentralExtra, item.UnPackSize, item.PackSize, + item.LocalHeaderPosition, headerDiskNumberStart); + } + + if (headerDiskNumberStart != 0) + throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported); + + // May be these strings must be deleted + /* + if (item.IsDir()) + item.UnPackSize = 0; + */ + + ReadBuffer(item.Comment, headerCommentSize); + return S_OK; +} + +HRESULT CInArchive::TryEcd64(UInt64 offset, CCdInfo &cdInfo) +{ + RINOK(Seek(offset)); + const UInt32 kEcd64Size = 56; + Byte buf[kEcd64Size]; + if (!ReadBytesAndTestSize(buf, kEcd64Size)) + return S_FALSE; + if (GetUInt32(buf) != NSignature::kZip64EndOfCentralDir) + return S_FALSE; + // cdInfo.NumEntries = GetUInt64(buf + 24); + cdInfo.Size = GetUInt64(buf + 40); + cdInfo.Offset = GetUInt64(buf + 48); + return S_OK; +} + +HRESULT CInArchive::FindCd(CCdInfo &cdInfo) +{ + UInt64 endPosition; + RINOK(m_Stream->Seek(0, STREAM_SEEK_END, &endPosition)); + const UInt32 kBufSizeMax = (1 << 16) + kEcdSize + kZip64EcdLocatorSize; + Byte buf[kBufSizeMax]; + UInt32 bufSize = (endPosition < kBufSizeMax) ? (UInt32)endPosition : kBufSizeMax; + if (bufSize < kEcdSize) + return S_FALSE; + UInt64 startPosition = endPosition - bufSize; + RINOK(m_Stream->Seek(startPosition, STREAM_SEEK_SET, &m_Position)); + if (m_Position != startPosition) + return S_FALSE; + if (!ReadBytesAndTestSize(buf, bufSize)) + return S_FALSE; + for (int i = (int)(bufSize - kEcdSize); i >= 0; i--) + { + if (GetUInt32(buf + i) == NSignature::kEndOfCentralDir) + { + if (i >= kZip64EcdLocatorSize) + { + const Byte *locator = buf + i - kZip64EcdLocatorSize; + if (GetUInt32(locator) == NSignature::kZip64EndOfCentralDirLocator) + { + UInt64 ecd64Offset = GetUInt64(locator + 8); + if (TryEcd64(ecd64Offset, cdInfo) == S_OK) + return S_OK; + if (TryEcd64(m_ArchiveInfo.StartPosition + ecd64Offset, cdInfo) == S_OK) + { + m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition; + return S_OK; + } + } + } + if (GetUInt32(buf + i + 4) == 0) + { + // cdInfo.NumEntries = GetUInt16(buf + i + 10); + cdInfo.Size = GetUInt32(buf + i + 12); + cdInfo.Offset = GetUInt32(buf + i + 16); + UInt64 curPos = endPosition - bufSize + i; + UInt64 cdEnd = cdInfo.Size + cdInfo.Offset; + if (curPos > cdEnd) + m_ArchiveInfo.Base = curPos - cdEnd; + return S_OK; + } + } + } + return S_FALSE; +} + +HRESULT CInArchive::TryReadCd(CObjectVector &items, UInt64 cdOffset, UInt64 cdSize, CProgressVirt *progress) +{ + items.Clear(); + RINOK(m_Stream->Seek(cdOffset, STREAM_SEEK_SET, &m_Position)); + if (m_Position != cdOffset) + return S_FALSE; + while(m_Position - cdOffset < cdSize) + { + if (ReadUInt32() != NSignature::kCentralFileHeader) + return S_FALSE; + CItemEx cdItem; + RINOK(ReadCdItem(cdItem)); + items.Add(cdItem); + if (progress && items.Size() % 1000 == 0) + RINOK(progress->SetCompleted(items.Size())); + } + return (m_Position - cdOffset == cdSize) ? S_OK : S_FALSE; +} + +HRESULT CInArchive::ReadCd(CObjectVector &items, UInt64 &cdOffset, UInt64 &cdSize, CProgressVirt *progress) +{ + m_ArchiveInfo.Base = 0; + CCdInfo cdInfo; + RINOK(FindCd(cdInfo)); + HRESULT res = S_FALSE; + cdSize = cdInfo.Size; + cdOffset = cdInfo.Offset; + res = TryReadCd(items, m_ArchiveInfo.Base + cdOffset, cdSize, progress); + if (res == S_FALSE && m_ArchiveInfo.Base == 0) + { + res = TryReadCd(items, cdInfo.Offset + m_ArchiveInfo.StartPosition, cdSize, progress); + if (res == S_OK) + m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition; + } + if (!ReadUInt32(m_Signature)) + return S_FALSE; + return res; +} + +HRESULT CInArchive::ReadLocalsAndCd(CObjectVector &items, CProgressVirt *progress, UInt64 &cdOffset) +{ + items.Clear(); + while (m_Signature == NSignature::kLocalFileHeader) + { + // FSeek points to next byte after signature + // NFileHeader::CLocalBlock localHeader; + CItemEx item; + item.LocalHeaderPosition = m_Position - m_StreamStartPosition - 4; // points to signature; + RINOK(ReadLocalItem(item)); + item.FromLocal = true; + ReadLocalItemDescriptor(item); + items.Add(item); + if (progress && items.Size() % 100 == 0) + RINOK(progress->SetCompleted(items.Size())); + if (!ReadUInt32(m_Signature)) + break; + } + cdOffset = m_Position - 4; + for (int i = 0; i < items.Size(); i++) + { + if (progress && i % 1000 == 0) + RINOK(progress->SetCompleted(items.Size())); + if (m_Signature != NSignature::kCentralFileHeader) + return S_FALSE; + + CItemEx cdItem; + RINOK(ReadCdItem(cdItem)); + + if (i == 0) + { + if (cdItem.LocalHeaderPosition == 0) + m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition; + } + + int index; + int left = 0, right = items.Size(); + for (;;) + { + if (left >= right) + return S_FALSE; + index = (left + right) / 2; + UInt64 position = items[index].LocalHeaderPosition - m_ArchiveInfo.Base; + if (cdItem.LocalHeaderPosition == position) + break; + if (cdItem.LocalHeaderPosition < position) + right = index; + else + left = index + 1; + } + CItemEx &item = items[index]; + item.LocalHeaderPosition = cdItem.LocalHeaderPosition; + item.MadeByVersion = cdItem.MadeByVersion; + item.CentralExtra = cdItem.CentralExtra; + + if ( + // item.ExtractVersion != cdItem.ExtractVersion || + item.Flags != cdItem.Flags || + item.CompressionMethod != cdItem.CompressionMethod || + // item.Time != cdItem.Time || + item.FileCRC != cdItem.FileCRC) + return S_FALSE; + + if (item.Name.Length() != cdItem.Name.Length() || + item.PackSize != cdItem.PackSize || + item.UnPackSize != cdItem.UnPackSize + ) + return S_FALSE; + item.Name = cdItem.Name; + item.InternalAttributes = cdItem.InternalAttributes; + item.ExternalAttributes = cdItem.ExternalAttributes; + item.Comment = cdItem.Comment; + item.FromCentral = cdItem.FromCentral; + if (!ReadUInt32(m_Signature)) + return S_FALSE; + } + return S_OK; +} + +struct CEcd +{ + UInt16 thisDiskNumber; + UInt16 startCDDiskNumber; + UInt16 numEntriesInCDOnThisDisk; + UInt16 numEntriesInCD; + UInt32 cdSize; + UInt32 cdStartOffset; + UInt16 commentSize; + void Parse(const Byte *p); +}; + +void CEcd::Parse(const Byte *p) +{ + thisDiskNumber = Get16(p); + startCDDiskNumber = Get16(p + 2); + numEntriesInCDOnThisDisk = Get16(p + 4); + numEntriesInCD = Get16(p + 6); + cdSize = Get32(p + 8); + cdStartOffset = Get32(p + 12); + commentSize = Get16(p + 16); +} + +struct CEcd64 +{ + UInt16 versionMade; + UInt16 versionNeedExtract; + UInt32 thisDiskNumber; + UInt32 startCDDiskNumber; + UInt64 numEntriesInCDOnThisDisk; + UInt64 numEntriesInCD; + UInt64 cdSize; + UInt64 cdStartOffset; + void Parse(const Byte *p); + CEcd64() { memset(this, 0, sizeof(*this)); } +}; + +void CEcd64::Parse(const Byte *p) +{ + versionMade = Get16(p); + versionNeedExtract = Get16(p + 2); + thisDiskNumber = Get32(p + 4); + startCDDiskNumber = Get32(p + 8); + numEntriesInCDOnThisDisk = Get64(p + 12); + numEntriesInCD = Get64(p + 20); + cdSize = Get64(p + 28); + cdStartOffset = Get64(p + 36); +} + +#define COPY_ECD_ITEM_16(n) if (!isZip64 || ecd. n != 0xFFFF) ecd64. n = ecd. n; +#define COPY_ECD_ITEM_32(n) if (!isZip64 || ecd. n != 0xFFFFFFFF) ecd64. n = ecd. n; + +HRESULT CInArchive::ReadHeaders(CObjectVector &items, CProgressVirt *progress) +{ + // m_Signature must be kLocalFileHeaderSignature or + // kEndOfCentralDirSignature + // m_Position points to next byte after signature + + IsZip64 = false; + items.Clear(); + + UInt64 cdSize, cdStartOffset; + HRESULT res = ReadCd(items, cdStartOffset, cdSize, progress); + if (res != S_FALSE && res != S_OK) + return res; + + /* + if (res != S_OK) + return res; + res = S_FALSE; + */ + + if (res == S_FALSE) + { + m_ArchiveInfo.Base = 0; + RINOK(m_Stream->Seek(m_ArchiveInfo.StartPosition, STREAM_SEEK_SET, &m_Position)); + if (m_Position != m_ArchiveInfo.StartPosition) + return S_FALSE; + if (!ReadUInt32(m_Signature)) + return S_FALSE; + RINOK(ReadLocalsAndCd(items, progress, cdStartOffset)); + cdSize = (m_Position - 4) - cdStartOffset; + cdStartOffset -= m_ArchiveInfo.Base; + } + + CEcd64 ecd64; + bool isZip64 = false; + UInt64 zip64EcdStartOffset = m_Position - 4 - m_ArchiveInfo.Base; + if (m_Signature == NSignature::kZip64EndOfCentralDir) + { + IsZip64 = isZip64 = true; + UInt64 recordSize = ReadUInt64(); + + const int kBufSize = kZip64EcdSize; + Byte buf[kBufSize]; + SafeReadBytes(buf, kBufSize); + ecd64.Parse(buf); + + IncreaseRealPosition(recordSize - kZip64EcdSize); + if (!ReadUInt32(m_Signature)) + return S_FALSE; + if (ecd64.thisDiskNumber != 0 || ecd64.startCDDiskNumber != 0) + throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported); + if (ecd64.numEntriesInCDOnThisDisk != items.Size() || + ecd64.numEntriesInCD != items.Size() || + ecd64.cdSize != cdSize || + (ecd64.cdStartOffset != cdStartOffset && + (!items.IsEmpty()))) + return S_FALSE; + } + if (m_Signature == NSignature::kZip64EndOfCentralDirLocator) + { + /* UInt32 startEndCDDiskNumber = */ ReadUInt32(); + UInt64 endCDStartOffset = ReadUInt64(); + /* UInt32 numberOfDisks = */ ReadUInt32(); + if (zip64EcdStartOffset != endCDStartOffset) + return S_FALSE; + if (!ReadUInt32(m_Signature)) + return S_FALSE; + } + if (m_Signature != NSignature::kEndOfCentralDir) + return S_FALSE; + + const int kBufSize = kEcdSize - 4; + Byte buf[kBufSize]; + SafeReadBytes(buf, kBufSize); + CEcd ecd; + ecd.Parse(buf); + + COPY_ECD_ITEM_16(thisDiskNumber); + COPY_ECD_ITEM_16(startCDDiskNumber); + COPY_ECD_ITEM_16(numEntriesInCDOnThisDisk); + COPY_ECD_ITEM_16(numEntriesInCD); + COPY_ECD_ITEM_32(cdSize); + COPY_ECD_ITEM_32(cdStartOffset); + + ReadBuffer(m_ArchiveInfo.Comment, ecd.commentSize); + + if (ecd64.thisDiskNumber != 0 || ecd64.startCDDiskNumber != 0) + throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported); + if ((UInt16)ecd64.numEntriesInCDOnThisDisk != ((UInt16)items.Size()) || + (UInt16)ecd64.numEntriesInCD != ((UInt16)items.Size()) || + (UInt32)ecd64.cdSize != (UInt32)cdSize || + ((UInt32)(ecd64.cdStartOffset) != (UInt32)cdStartOffset && + (!items.IsEmpty()))) + return S_FALSE; + + return S_OK; +} + +ISequentialInStream* CInArchive::CreateLimitedStream(UInt64 position, UInt64 size) +{ + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr stream(streamSpec); + SeekInArchive(m_ArchiveInfo.Base + position); + streamSpec->SetStream(m_Stream); + streamSpec->Init(size); + return stream.Detach(); +} + +IInStream* CInArchive::CreateStream() +{ + CMyComPtr stream = m_Stream; + return stream.Detach(); +} + +bool CInArchive::SeekInArchive(UInt64 position) +{ + UInt64 newPosition; + if (m_Stream->Seek(position, STREAM_SEEK_SET, &newPosition) != S_OK) + return false; + return (newPosition == position); +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipIn.h b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipIn.h new file mode 100644 index 000000000..dd8114c3d --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipIn.h @@ -0,0 +1,116 @@ +// Archive/ZipIn.h + +#ifndef __ZIP_IN_H +#define __ZIP_IN_H + +#include "../../../Common/MyCom.h" +#include "../../IStream.h" + +#include "ZipHeader.h" +#include "ZipItemEx.h" + +namespace NArchive { +namespace NZip { + +class CInArchiveException +{ +public: + enum ECauseType + { + kUnexpectedEndOfArchive = 0, + kArchiceHeaderCRCError, + kFileHeaderCRCError, + kIncorrectArchive, + kDataDescroptorsAreNotSupported, + kMultiVolumeArchiveAreNotSupported, + kReadStreamError, + kSeekStreamError + } + Cause; + CInArchiveException(ECauseType cause): Cause(cause) {} +}; + +class CInArchiveInfo +{ +public: + UInt64 Base; + UInt64 StartPosition; + CByteBuffer Comment; + CInArchiveInfo(): Base(0), StartPosition(0) {} + void Clear() + { + Base = 0; + StartPosition = 0; + Comment.SetCapacity(0); + } +}; + +class CProgressVirt +{ +public: + STDMETHOD(SetTotal)(UInt64 numFiles) PURE; + STDMETHOD(SetCompleted)(UInt64 numFiles) PURE; +}; + +struct CCdInfo +{ + // UInt64 NumEntries; + UInt64 Size; + UInt64 Offset; +}; + +class CInArchive +{ + CMyComPtr m_Stream; + UInt32 m_Signature; + UInt64 m_StreamStartPosition; + UInt64 m_Position; + AString m_NameBuffer; + + HRESULT Seek(UInt64 offset); + + HRESULT FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit); + bool ReadUInt32(UInt32 &signature); + AString ReadFileName(UInt32 nameSize); + + HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize); + bool ReadBytesAndTestSize(void *data, UInt32 size); + void SafeReadBytes(void *data, UInt32 size); + void ReadBuffer(CByteBuffer &buffer, UInt32 size); + Byte ReadByte(); + UInt16 ReadUInt16(); + UInt32 ReadUInt32(); + UInt64 ReadUInt64(); + + void IncreaseRealPosition(UInt64 addValue); + + void ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock, + UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber); + HRESULT ReadLocalItem(CItemEx &item); + HRESULT ReadLocalItemDescriptor(CItemEx &item); + HRESULT ReadCdItem(CItemEx &item); + HRESULT TryEcd64(UInt64 offset, CCdInfo &cdInfo); + HRESULT FindCd(CCdInfo &cdInfo); + HRESULT TryReadCd(CObjectVector &items, UInt64 cdOffset, UInt64 cdSize, CProgressVirt *progress); + HRESULT ReadCd(CObjectVector &items, UInt64 &cdOffset, UInt64 &cdSize, CProgressVirt *progress); + HRESULT ReadLocalsAndCd(CObjectVector &items, CProgressVirt *progress, UInt64 &cdOffset); +public: + CInArchiveInfo m_ArchiveInfo; + bool IsZip64; + + HRESULT ReadHeaders(CObjectVector &items, CProgressVirt *progress); + HRESULT ReadLocalItemAfterCdItem(CItemEx &item); + HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item); + HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); + void Close(); + void GetArchiveInfo(CInArchiveInfo &archiveInfo) const; + bool SeekInArchive(UInt64 position); + ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); + IInStream* CreateStream(); + + bool IsOpen() const { return m_Stream != NULL; } +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipItem.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipItem.cpp new file mode 100644 index 000000000..6756e4b44 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipItem.cpp @@ -0,0 +1,147 @@ +// Archive/ZipItem.cpp + +#include "StdAfx.h" + +#include "ZipHeader.h" +#include "ZipItem.h" +#include "../Common/ItemNameUtils.h" +#include "../../../../C/CpuArch.h" + +namespace NArchive { +namespace NZip { + +bool operator==(const CVersion &v1, const CVersion &v2) +{ + return (v1.Version == v2.Version) && (v1.HostOS == v2.HostOS); +} + +bool operator!=(const CVersion &v1, const CVersion &v2) +{ + return !(v1 == v2); +} + +bool CExtraSubBlock::ExtractNtfsTime(int index, FILETIME &ft) const +{ + ft.dwHighDateTime = ft.dwLowDateTime = 0; + UInt32 size = (UInt32)Data.GetCapacity(); + if (ID != NFileHeader::NExtraID::kNTFS || size < 32) + return false; + const Byte *p = (const Byte *)Data; + p += 4; // for reserved + size -= 4; + while (size > 4) + { + UInt16 tag = GetUi16(p); + UInt32 attrSize = GetUi16(p + 2); + p += 4; + size -= 4; + if (attrSize > size) + attrSize = size; + + if (tag == NFileHeader::NNtfsExtra::kTagTime && attrSize >= 24) + { + p += 8 * index; + ft.dwLowDateTime = GetUi32(p); + ft.dwHighDateTime = GetUi32(p + 4); + return true; + } + p += attrSize; + size -= attrSize; + } + return false; +} + +bool CLocalItem::IsDir() const +{ + return NItemName::HasTailSlash(Name, GetCodePage()); +} + +bool CItem::IsDir() const +{ + if (NItemName::HasTailSlash(Name, GetCodePage())) + return true; + if (!FromCentral) + return false; + WORD highAttributes = WORD((ExternalAttributes >> 16 ) & 0xFFFF); + switch(MadeByVersion.HostOS) + { + case NFileHeader::NHostOS::kAMIGA: + switch (highAttributes & NFileHeader::NAmigaAttribute::kIFMT) + { + case NFileHeader::NAmigaAttribute::kIFDIR: return true; + case NFileHeader::NAmigaAttribute::kIFREG: return false; + default: return false; // change it throw kUnknownAttributes; + } + case NFileHeader::NHostOS::kFAT: + case NFileHeader::NHostOS::kNTFS: + case NFileHeader::NHostOS::kHPFS: + case NFileHeader::NHostOS::kVFAT: + return ((ExternalAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0); + case NFileHeader::NHostOS::kAtari: + case NFileHeader::NHostOS::kMac: + case NFileHeader::NHostOS::kVMS: + case NFileHeader::NHostOS::kVM_CMS: + case NFileHeader::NHostOS::kAcorn: + case NFileHeader::NHostOS::kMVS: + return false; // change it throw kUnknownAttributes; + default: + /* + switch (highAttributes & NFileHeader::NUnixAttribute::kIFMT) + { + case NFileHeader::NUnixAttribute::kIFDIR: + return true; + default: + return false; + } + */ + return false; + } +} + +UInt32 CLocalItem::GetWinAttributes() const +{ + DWORD winAttributes = 0; + if (IsDir()) + winAttributes |= FILE_ATTRIBUTE_DIRECTORY; + return winAttributes; +} + +UInt32 CItem::GetWinAttributes() const +{ + DWORD winAttributes = 0; + switch(MadeByVersion.HostOS) + { + case NFileHeader::NHostOS::kFAT: + case NFileHeader::NHostOS::kNTFS: + if (FromCentral) + winAttributes = ExternalAttributes; + break; + default: + winAttributes = 0; // must be converted from unix value; + } + if (IsDir()) // test it; + winAttributes |= FILE_ATTRIBUTE_DIRECTORY; + return winAttributes; +} + +void CLocalItem::SetFlagBits(int startBitNumber, int numBits, int value) +{ + UInt16 mask = (UInt16)(((1 << numBits) - 1) << startBitNumber); + Flags &= ~mask; + Flags |= value << startBitNumber; +} + +void CLocalItem::SetBitMask(int bitMask, bool enable) +{ + if(enable) + Flags |= bitMask; + else + Flags &= ~bitMask; +} + +void CLocalItem::SetEncrypted(bool encrypted) + { SetBitMask(NFileHeader::NFlags::kEncrypted, encrypted); } +void CLocalItem::SetUtf8(bool isUtf8) + { SetBitMask(NFileHeader::NFlags::kUtf8, isUtf8); } + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipItem.h b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipItem.h new file mode 100644 index 000000000..e7e0c47bf --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipItem.h @@ -0,0 +1,268 @@ +// Archive/ZipItem.h + +#ifndef __ARCHIVE_ZIP_ITEM_H +#define __ARCHIVE_ZIP_ITEM_H + +#include "../../../Common/Types.h" +#include "../../../Common/MyString.h" +#include "../../../Common/Buffer.h" +#include "../../../Common/UTFConvert.h" +#include "../../../Common/StringConvert.h" + +#include "ZipHeader.h" + +namespace NArchive { +namespace NZip { + +struct CVersion +{ + Byte Version; + Byte HostOS; +}; + +bool operator==(const CVersion &v1, const CVersion &v2); +bool operator!=(const CVersion &v1, const CVersion &v2); + +struct CExtraSubBlock +{ + UInt16 ID; + CByteBuffer Data; + bool ExtractNtfsTime(int index, FILETIME &ft) const; +}; + +struct CWzAesExtraField +{ + UInt16 VendorVersion; // 0x0001 - AE-1, 0x0002 - AE-2, + // UInt16 VendorId; // "AE" + Byte Strength; // 1 - 128-bit , 2 - 192-bit , 3 - 256-bit + UInt16 Method; + + CWzAesExtraField(): VendorVersion(2), Strength(3), Method(0) {} + + bool NeedCrc() const { return (VendorVersion == 1); } + + bool ParseFromSubBlock(const CExtraSubBlock &sb) + { + if (sb.ID != NFileHeader::NExtraID::kWzAES) + return false; + if (sb.Data.GetCapacity() < 7) + return false; + const Byte *p = (const Byte *)sb.Data; + VendorVersion = (((UInt16)p[1]) << 8) | p[0]; + if (p[2] != 'A' || p[3] != 'E') + return false; + Strength = p[4]; + Method = (((UInt16)p[6]) << 16) | p[5]; + return true; + } + void SetSubBlock(CExtraSubBlock &sb) const + { + sb.Data.SetCapacity(7); + sb.ID = NFileHeader::NExtraID::kWzAES; + Byte *p = (Byte *)sb.Data; + p[0] = (Byte)VendorVersion; + p[1] = (Byte)(VendorVersion >> 8); + p[2] = 'A'; + p[3] = 'E'; + p[4] = Strength; + p[5] = (Byte)Method; + p[6] = (Byte)(Method >> 8); + } +}; + +namespace NStrongCryptoFlags +{ + const UInt16 kDES = 0x6601; + const UInt16 kRC2old = 0x6602; + const UInt16 k3DES168 = 0x6603; + const UInt16 k3DES112 = 0x6609; + const UInt16 kAES128 = 0x660E; + const UInt16 kAES192 = 0x660F; + const UInt16 kAES256 = 0x6610; + const UInt16 kRC2 = 0x6702; + const UInt16 kBlowfish = 0x6720; + const UInt16 kTwofish = 0x6721; + const UInt16 kRC4 = 0x6801; +} + +struct CStrongCryptoField +{ + UInt16 Format; + UInt16 AlgId; + UInt16 BitLen; + UInt16 Flags; + + bool ParseFromSubBlock(const CExtraSubBlock &sb) + { + if (sb.ID != NFileHeader::NExtraID::kStrongEncrypt) + return false; + const Byte *p = (const Byte *)sb.Data; + if (sb.Data.GetCapacity() < 8) + return false; + Format = (((UInt16)p[1]) << 8) | p[0]; + AlgId = (((UInt16)p[3]) << 8) | p[2]; + BitLen = (((UInt16)p[5]) << 8) | p[4]; + Flags = (((UInt16)p[7]) << 8) | p[6]; + return (Format == 2); + } +}; + +struct CExtraBlock +{ + CObjectVector SubBlocks; + void Clear() { SubBlocks.Clear(); } + size_t GetSize() const + { + size_t res = 0; + for (int i = 0; i < SubBlocks.Size(); i++) + res += SubBlocks[i].Data.GetCapacity() + 2 + 2; + return res; + } + bool GetWzAesField(CWzAesExtraField &aesField) const + { + for (int i = 0; i < SubBlocks.Size(); i++) + if (aesField.ParseFromSubBlock(SubBlocks[i])) + return true; + return false; + } + + bool GetStrongCryptoField(CStrongCryptoField &f) const + { + for (int i = 0; i < SubBlocks.Size(); i++) + if (f.ParseFromSubBlock(SubBlocks[i])) + return true; + return false; + } + + bool HasWzAesField() const + { + CWzAesExtraField aesField; + return GetWzAesField(aesField); + } + + bool GetNtfsTime(int index, FILETIME &ft) const + { + for (int i = 0; i < SubBlocks.Size(); i++) + { + const CExtraSubBlock &sb = SubBlocks[i]; + if (sb.ID == NFileHeader::NExtraID::kNTFS) + return sb.ExtractNtfsTime(index, ft); + } + return false; + } + + /* + bool HasStrongCryptoField() const + { + CStrongCryptoField f; + return GetStrongCryptoField(f); + } + */ + + void RemoveUnknownSubBlocks() + { + for (int i = SubBlocks.Size() - 1; i >= 0; i--) + if (SubBlocks[i].ID != NFileHeader::NExtraID::kWzAES) + SubBlocks.Delete(i); + } +}; + + +class CLocalItem +{ +public: + CVersion ExtractVersion; + UInt16 Flags; + UInt16 CompressionMethod; + UInt32 Time; + UInt32 FileCRC; + UInt64 PackSize; + UInt64 UnPackSize; + + AString Name; + + CExtraBlock LocalExtra; + + bool IsUtf8() const { return (Flags & NFileHeader::NFlags::kUtf8) != 0; } + + bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kEncrypted) != 0; } + bool IsStrongEncrypted() const { return IsEncrypted() && (Flags & NFileHeader::NFlags::kStrongEncrypted) != 0; }; + + bool IsLzmaEOS() const { return (Flags & NFileHeader::NFlags::kLzmaEOS) != 0; } + + bool IsDir() const; + bool IgnoreItem() const { return false; } + UInt32 GetWinAttributes() const; + + bool HasDescriptor() const { return (Flags & NFileHeader::NFlags::kDescriptorUsedMask) != 0; } + + UString GetUnicodeString(const AString &s) const + { + UString res; + if (IsUtf8()) + if (!ConvertUTF8ToUnicode(s, res)) + res.Empty(); + if (res.IsEmpty()) + res = MultiByteToUnicodeString(s, GetCodePage()); + return res; + } + +private: + void SetFlagBits(int startBitNumber, int numBits, int value); + void SetBitMask(int bitMask, bool enable); +public: + void ClearFlags() { Flags = 0; } + void SetEncrypted(bool encrypted); + void SetUtf8(bool isUtf8); + + WORD GetCodePage() const { return CP_OEMCP; } +}; + +class CItem: public CLocalItem +{ +public: + CVersion MadeByVersion; + UInt16 InternalAttributes; + UInt32 ExternalAttributes; + + UInt64 LocalHeaderPosition; + + FILETIME NtfsMTime; + FILETIME NtfsATime; + FILETIME NtfsCTime; + + CExtraBlock CentralExtra; + CByteBuffer Comment; + + bool FromLocal; + bool FromCentral; + bool NtfsTimeIsDefined; + + bool IsDir() const; + UInt32 GetWinAttributes() const; + + bool IsThereCrc() const + { + if (CompressionMethod == NFileHeader::NCompressionMethod::kWzAES) + { + CWzAesExtraField aesField; + if (CentralExtra.GetWzAesField(aesField)) + return aesField.NeedCrc(); + } + return (FileCRC != 0 || !IsDir()); + } + + WORD GetCodePage() const + { + return (WORD)((MadeByVersion.HostOS == NFileHeader::NHostOS::kFAT + || MadeByVersion.HostOS == NFileHeader::NHostOS::kNTFS + ) ? CP_OEMCP : CP_ACP); + } + CItem() : FromLocal(false), FromCentral(false), NtfsTimeIsDefined(false) {} +}; + +}} + +#endif + + diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipItemEx.h b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipItemEx.h new file mode 100644 index 000000000..0d74edd80 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipItemEx.h @@ -0,0 +1,34 @@ +// Archive/ZipItemEx.h + +#ifndef __ARCHIVE_ZIP_ITEMEX_H +#define __ARCHIVE_ZIP_ITEMEX_H + +#include "ZipHeader.h" +#include "ZipItem.h" + +namespace NArchive { +namespace NZip { + +class CItemEx: public CItem +{ +public: + UInt32 FileHeaderWithNameSize; + UInt16 LocalExtraSize; + + UInt64 GetLocalFullSize() const + { return FileHeaderWithNameSize + LocalExtraSize + PackSize + + (HasDescriptor() ? NFileHeader::kDataDescriptorSize : 0); }; + /* + UInt64 GetLocalFullSize(bool isZip64) const + { return FileHeaderWithNameSize + LocalExtraSize + PackSize + + (HasDescriptor() ? (isZip64 ? NFileHeader::kDataDescriptor64Size : NFileHeader::kDataDescriptorSize) : 0); }; + */ + UInt64 GetLocalExtraPosition() const + { return LocalHeaderPosition + FileHeaderWithNameSize; }; + UInt64 GetDataPosition() const + { return GetLocalExtraPosition() + LocalExtraSize; }; +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipRegister.cpp b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipRegister.cpp new file mode 100644 index 000000000..0e90e4ec3 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Archive/Zip/ZipRegister.cpp @@ -0,0 +1,21 @@ +// ZipRegister.cpp + +#include "StdAfx.h" + +#include "../../Common/RegisterArc.h" + +#include "ZipHandler.h" +static IInArchive *CreateArc() { return new NArchive::NZip::CHandler; } +#ifndef EXTRACT_ONLY +static IOutArchive *CreateArcOut() { return new NArchive::NZip::CHandler; } +#else +#define CreateArcOut 0 +#endif + +static CArcInfo g_ArcInfo = { L"Zip", L"zip jar xpi zsg", 0, 1, { 0x50, 0x4B, 0x03, 0x04 }, 4, false, CreateArc, CreateArcOut }; +static CArcInfo g_ArcInfo2 = { L"Zip", L"zip jar xpi zsg", 0, 1, { 0x50, 0x4B, 0x01, 0x02 }, 4, false, CreateArc, CreateArcOut }; +static CArcInfo g_ArcInfo3 = { L"Zip", L"zip jar xpi zsg", 0, 1, { 0x50, 0x4B, 0x05, 0x06 }, 4, false, CreateArc, CreateArcOut }; + +REGISTER_ARC(Zip) +REGISTER_ARCN(Zip,2) +REGISTER_ARCN(Zip,3) diff --git a/desmume/src/windows/7z/CPP/7zip/Common/CreateCoder.cpp b/desmume/src/windows/7z/CPP/7zip/Common/CreateCoder.cpp new file mode 100644 index 000000000..10c9f9600 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/CreateCoder.cpp @@ -0,0 +1,292 @@ +// CreateCoder.cpp + +#include "StdAfx.h" + +#include "CreateCoder.h" + +#include "../../Windows/PropVariant.h" +#include "../../Windows/Defs.h" +#include "FilterCoder.h" +#include "RegisterCodec.h" + +static const unsigned int kNumCodecsMax = 64; +unsigned int g_NumCodecs = 0; +const CCodecInfo *g_Codecs[kNumCodecsMax]; +void RegisterCodec(const CCodecInfo *codecInfo) +{ + if (g_NumCodecs < kNumCodecsMax) + g_Codecs[g_NumCodecs++] = codecInfo; +} + +#ifdef EXTERNAL_CODECS +static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, UInt32 &res) +{ + NWindows::NCOM::CPropVariant prop; + RINOK(codecsInfo->GetProperty(index, propID, &prop)); + if (prop.vt == VT_EMPTY) + res = 1; + else if (prop.vt == VT_UI4) + res = prop.ulVal; + else + return E_INVALIDARG; + return S_OK; +} + +static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, bool &res) +{ + NWindows::NCOM::CPropVariant prop; + RINOK(codecsInfo->GetProperty(index, propID, &prop)); + if (prop.vt == VT_EMPTY) + res = true; + else if (prop.vt == VT_BOOL) + res = VARIANT_BOOLToBool(prop.boolVal); + else + return E_INVALIDARG; + return S_OK; +} + +HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector &externalCodecs) +{ + UInt32 num; + RINOK(codecsInfo->GetNumberOfMethods(&num)); + for (UInt32 i = 0; i < num; i++) + { + CCodecInfoEx info; + NWindows::NCOM::CPropVariant prop; + RINOK(codecsInfo->GetProperty(i, NMethodPropID::kID, &prop)); + // if (prop.vt != VT_BSTR) + // info.Id.IDSize = (Byte)SysStringByteLen(prop.bstrVal); + // memmove(info.Id.ID, prop.bstrVal, info.Id.IDSize); + if (prop.vt != VT_UI8) + { + continue; // old Interface + // return E_INVALIDARG; + } + info.Id = prop.uhVal.QuadPart; + prop.Clear(); + + RINOK(codecsInfo->GetProperty(i, NMethodPropID::kName, &prop)); + if (prop.vt == VT_BSTR) + info.Name = prop.bstrVal; + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG;; + + RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kInStreams, info.NumInStreams)); + RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kOutStreams, info.NumOutStreams)); + RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned)); + RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned)); + + externalCodecs.Add(info); + } + return S_OK; +} + +#endif + +bool FindMethod( + #ifdef EXTERNAL_CODECS + ICompressCodecsInfo * /* codecsInfo */, const CObjectVector *externalCodecs, + #endif + const UString &name, + CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams) +{ + UInt32 i; + for (i = 0; i < g_NumCodecs; i++) + { + const CCodecInfo &codec = *g_Codecs[i]; + if (name.CompareNoCase(codec.Name) == 0) + { + methodId = codec.Id; + numInStreams = codec.NumInStreams; + numOutStreams = 1; + return true; + } + } + #ifdef EXTERNAL_CODECS + if (externalCodecs) + for (i = 0; i < (UInt32)externalCodecs->Size(); i++) + { + const CCodecInfoEx &codec = (*externalCodecs)[i]; + if (codec.Name.CompareNoCase(name) == 0) + { + methodId = codec.Id; + numInStreams = codec.NumInStreams; + numOutStreams = codec.NumOutStreams; + return true; + } + } + #endif + return false; +} + +bool FindMethod( + #ifdef EXTERNAL_CODECS + ICompressCodecsInfo * /* codecsInfo */, const CObjectVector *externalCodecs, + #endif + CMethodId methodId, UString &name) +{ + UInt32 i; + for (i = 0; i < g_NumCodecs; i++) + { + const CCodecInfo &codec = *g_Codecs[i]; + if (methodId == codec.Id) + { + name = codec.Name; + return true; + } + } + #ifdef EXTERNAL_CODECS + if (externalCodecs) + for (i = 0; i < (UInt32)externalCodecs->Size(); i++) + { + const CCodecInfoEx &codec = (*externalCodecs)[i]; + if (methodId == codec.Id) + { + name = codec.Name; + return true; + } + } + #endif + return false; +} + +HRESULT CreateCoder( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, + CMyComPtr &filter, + CMyComPtr &coder, + CMyComPtr &coder2, + bool encode, bool onlyCoder) +{ + bool created = false; + UInt32 i; + for (i = 0; i < g_NumCodecs; i++) + { + const CCodecInfo &codec = *g_Codecs[i]; + if (codec.Id == methodId) + { + if (encode) + { + if (codec.CreateEncoder) + { + void *p = codec.CreateEncoder(); + if (codec.IsFilter) filter = (ICompressFilter *)p; + else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p; + else coder2 = (ICompressCoder2 *)p; + created = (p != 0); + break; + } + } + else + if (codec.CreateDecoder) + { + void *p = codec.CreateDecoder(); + if (codec.IsFilter) filter = (ICompressFilter *)p; + else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p; + else coder2 = (ICompressCoder2 *)p; + created = (p != 0); + break; + } + } + } + + #ifdef EXTERNAL_CODECS + if (!created && externalCodecs) + for (i = 0; i < (UInt32)externalCodecs->Size(); i++) + { + const CCodecInfoEx &codec = (*externalCodecs)[i]; + if (codec.Id == methodId) + { + if (encode) + { + if (codec.EncoderIsAssigned) + { + if (codec.IsSimpleCodec()) + { + HRESULT result = codecsInfo->CreateEncoder(i, &IID_ICompressCoder, (void **)&coder); + if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE) + return result; + if (!coder) + { + RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter)); + } + } + else + { + RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressCoder2, (void **)&coder2)); + } + break; + } + } + else + if (codec.DecoderIsAssigned) + { + if (codec.IsSimpleCodec()) + { + HRESULT result = codecsInfo->CreateDecoder(i, &IID_ICompressCoder, (void **)&coder); + if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE) + return result; + if (!coder) + { + RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter)); + } + } + else + { + RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressCoder2, (void **)&coder2)); + } + break; + } + } + } + #endif + + if (onlyCoder && filter) + { + CFilterCoder *coderSpec = new CFilterCoder; + coder = coderSpec; + coderSpec->Filter = filter; + } + return S_OK; +} + +HRESULT CreateCoder( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, + CMyComPtr &coder, + CMyComPtr &coder2, + bool encode) +{ + CMyComPtr filter; + return CreateCoder( + EXTERNAL_CODECS_LOC_VARS + methodId, + filter, coder, coder2, encode, true); +} + +HRESULT CreateCoder( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, + CMyComPtr &coder, bool encode) +{ + CMyComPtr filter; + CMyComPtr coder2; + return CreateCoder( + EXTERNAL_CODECS_LOC_VARS + methodId, + coder, coder2, encode); +} + +HRESULT CreateFilter( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, + CMyComPtr &filter, + bool encode) +{ + CMyComPtr coder; + CMyComPtr coder2; + return CreateCoder( + EXTERNAL_CODECS_LOC_VARS + methodId, + filter, coder, coder2, encode, false); +} diff --git a/desmume/src/windows/7z/CPP/7zip/Common/CreateCoder.h b/desmume/src/windows/7z/CPP/7zip/Common/CreateCoder.h new file mode 100644 index 000000000..2f83f5ec5 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/CreateCoder.h @@ -0,0 +1,98 @@ +// CreateCoder.h + +#ifndef __CREATECODER_H +#define __CREATECODER_H + +#include "../../Common/MyCom.h" +#include "../../Common/MyString.h" +#include "../ICoder.h" + +#include "MethodId.h" + +#ifdef EXTERNAL_CODECS + +struct CCodecInfoEx +{ + UString Name; + CMethodId Id; + UInt32 NumInStreams; + UInt32 NumOutStreams; + bool EncoderIsAssigned; + bool DecoderIsAssigned; + bool IsSimpleCodec() const { return NumOutStreams == 1 && NumInStreams == 1; } + CCodecInfoEx(): EncoderIsAssigned(false), DecoderIsAssigned(false) {} +}; + +HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector &externalCodecs); + +#define PUBLIC_ISetCompressCodecsInfo public ISetCompressCodecsInfo, +#define QUERY_ENTRY_ISetCompressCodecsInfo MY_QUERYINTERFACE_ENTRY(ISetCompressCodecsInfo) +#define DECL_ISetCompressCodecsInfo STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo); +#define IMPL_ISetCompressCodecsInfo2(x) \ +STDMETHODIMP x::SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo) { \ + COM_TRY_BEGIN _codecsInfo = compressCodecsInfo; return LoadExternalCodecs(_codecsInfo, _externalCodecs); COM_TRY_END } +#define IMPL_ISetCompressCodecsInfo IMPL_ISetCompressCodecsInfo2(CHandler) + +#define EXTERNAL_CODECS_VARS2 _codecsInfo, &_externalCodecs + +#define DECL_EXTERNAL_CODECS_VARS CMyComPtr _codecsInfo; CObjectVector _externalCodecs; +#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2, + +#define DECL_EXTERNAL_CODECS_LOC_VARS2 ICompressCodecsInfo *codecsInfo, const CObjectVector *externalCodecs +#define EXTERNAL_CODECS_LOC_VARS2 codecsInfo, externalCodecs + +#define DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS2, +#define EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS2, + +#else + +#define PUBLIC_ISetCompressCodecsInfo +#define QUERY_ENTRY_ISetCompressCodecsInfo +#define DECL_ISetCompressCodecsInfo +#define IMPL_ISetCompressCodecsInfo +#define EXTERNAL_CODECS_VARS2 +#define DECL_EXTERNAL_CODECS_VARS +#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2 +#define DECL_EXTERNAL_CODECS_LOC_VARS2 +#define EXTERNAL_CODECS_LOC_VARS2 +#define DECL_EXTERNAL_CODECS_LOC_VARS +#define EXTERNAL_CODECS_LOC_VARS + +#endif + +bool FindMethod( + DECL_EXTERNAL_CODECS_LOC_VARS + const UString &name, CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams); + +bool FindMethod( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, UString &name); + + +HRESULT CreateCoder( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, + CMyComPtr &filter, + CMyComPtr &coder, + CMyComPtr &coder2, + bool encode, bool onlyCoder); + +HRESULT CreateCoder( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, + CMyComPtr &coder, + CMyComPtr &coder2, + bool encode); + +HRESULT CreateCoder( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, + CMyComPtr &coder, bool encode); + +HRESULT CreateFilter( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, + CMyComPtr &filter, + bool encode); + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/DeclareArcs.h b/desmume/src/windows/7z/CPP/7zip/Common/DeclareArcs.h new file mode 100644 index 000000000..22443a779 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/DeclareArcs.h @@ -0,0 +1,28 @@ +// DeclareArcs.h + +#ifndef __DECLAREARCS_H +#define __DECLAREARCS_H + +#define DECLARE_ARC(x) struct CRegister##x { CRegister##x(); }; \ + FORCE_REF(CRegister##x, g_RegisterArc##x) + +#define DECLARE_ARCN(x,n) struct CRegister##x##n { CRegister##x##n(); }; \ + FORCE_REF(CRegister##x##n, g_RegisterArc##n##x) + +#ifndef FORCE_REF + #define FORCE_REF(...) +#endif + +DECLARE_ARC(7z) +DECLARE_ARC(BZip2) +DECLARE_ARC(GZip) +DECLARE_ARC(Lzh) +DECLARE_ARC(Lzma) +DECLARE_ARC(Rar) +DECLARE_ARC(Split) +DECLARE_ARC(Tar) +DECLARE_ARC(Zip) +DECLARE_ARCN(Zip,2) +DECLARE_ARCN(Zip,3) + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/DeclareCodecs.h b/desmume/src/windows/7z/CPP/7zip/Common/DeclareCodecs.h new file mode 100644 index 000000000..6b933cac6 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/DeclareCodecs.h @@ -0,0 +1,31 @@ +// DeclareCodecs.h + +#ifndef __DECLARECODECS_H +#define __DECLARECODECS_H + +#define DECLARE_CODEC(x) struct CRegisterCodec##x { CRegisterCodec##x(); }; \ + FORCE_REF(CRegisterCodec##x, g_RegisterCodec##x) + +#define DECLARE_CODECS(x) struct CRegisterCodecs##x { CRegisterCodecs##x(); }; \ + FORCE_REF(CRegisterCodecs##x, g_RegisterCodecs##x) + +#ifndef FORCE_REF + #define FORCE_REF(...) +#endif + +DECLARE_CODEC(7zAES) +DECLARE_CODEC(BCJ2) +DECLARE_CODEC(BCJ) +DECLARE_CODEC(BZip2) +DECLARE_CODEC(Copy) +DECLARE_CODEC(Deflate64) +DECLARE_CODEC(DeflateNsis) +DECLARE_CODEC(Deflate) +DECLARE_CODEC(LZMA) +DECLARE_CODEC(PPMD) + +DECLARE_CODECS(Branch) +DECLARE_CODECS(ByteSwap) +DECLARE_CODECS(Rar) + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/FilterCoder.cpp b/desmume/src/windows/7z/CPP/7zip/Common/FilterCoder.cpp new file mode 100644 index 000000000..1985d383a --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/FilterCoder.cpp @@ -0,0 +1,262 @@ +// FilterCoder.cpp + +#include "StdAfx.h" + +#include "FilterCoder.h" +extern "C" +{ +#include "../../../C/Alloc.h" +} +#include "../../Common/Defs.h" +#include "StreamUtils.h" + +static const UInt32 kBufferSize = 1 << 17; + +CFilterCoder::CFilterCoder() +{ + _buffer = (Byte *)::MidAlloc(kBufferSize); +} + +CFilterCoder::~CFilterCoder() +{ + ::MidFree(_buffer); +} + +HRESULT CFilterCoder::WriteWithLimit(ISequentialOutStream *outStream, UInt32 size) +{ + if (_outSizeIsDefined) + { + UInt64 remSize = _outSize - _nowPos64; + if (size > remSize) + size = (UInt32)remSize; + } + RINOK(WriteStream(outStream, _buffer, size)); + _nowPos64 += size; + return S_OK; +} + + +STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + RINOK(Init()); + UInt32 bufferPos = 0; + _outSizeIsDefined = (outSize != 0); + if (_outSizeIsDefined) + _outSize = *outSize; + + while(NeedMore()) + { + size_t processedSize = kBufferSize - bufferPos; + + // Change it: It can be optimized using ReadPart + RINOK(ReadStream(inStream, _buffer + bufferPos, &processedSize)); + + UInt32 endPos = bufferPos + (UInt32)processedSize; + + bufferPos = Filter->Filter(_buffer, endPos); + if (bufferPos > endPos) + { + for (; endPos< bufferPos; endPos++) + _buffer[endPos] = 0; + bufferPos = Filter->Filter(_buffer, endPos); + } + + if (bufferPos == 0) + { + if (endPos > 0) + return WriteWithLimit(outStream, endPos); + return S_OK; + } + RINOK(WriteWithLimit(outStream, bufferPos)); + if (progress != NULL) + { + RINOK(progress->SetRatioInfo(&_nowPos64, &_nowPos64)); + } + UInt32 i = 0; + while(bufferPos < endPos) + _buffer[i++] = _buffer[bufferPos++]; + bufferPos = i; + } + return S_OK; +} + +// #ifdef _ST_MODE +STDMETHODIMP CFilterCoder::SetOutStream(ISequentialOutStream *outStream) +{ + _bufferPos = 0; + _outStream = outStream; + return Init(); +} + +STDMETHODIMP CFilterCoder::ReleaseOutStream() +{ + _outStream.Release(); + return S_OK; +}; + + +STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 processedSizeTotal = 0; + while(size > 0) + { + UInt32 sizeMax = kBufferSize - _bufferPos; + UInt32 sizeTemp = size; + if (sizeTemp > sizeMax) + sizeTemp = sizeMax; + memmove(_buffer + _bufferPos, data, sizeTemp); + size -= sizeTemp; + processedSizeTotal += sizeTemp; + data = (const Byte *)data + sizeTemp; + UInt32 endPos = _bufferPos + sizeTemp; + _bufferPos = Filter->Filter(_buffer, endPos); + if (_bufferPos == 0) + { + _bufferPos = endPos; + break; + } + if (_bufferPos > endPos) + { + if (size != 0) + return E_FAIL; + break; + } + RINOK(WriteWithLimit(_outStream, _bufferPos)); + UInt32 i = 0; + while(_bufferPos < endPos) + _buffer[i++] = _buffer[_bufferPos++]; + _bufferPos = i; + } + if (processedSize != NULL) + *processedSize = processedSizeTotal; + return S_OK; +} + +STDMETHODIMP CFilterCoder::Flush() +{ + if (_bufferPos != 0) + { + UInt32 endPos = Filter->Filter(_buffer, _bufferPos); + if (endPos > _bufferPos) + { + for (; _bufferPos < endPos; _bufferPos++) + _buffer[_bufferPos] = 0; + if (Filter->Filter(_buffer, endPos) != endPos) + return E_FAIL; + } + RINOK(WriteStream(_outStream, _buffer, _bufferPos)); + _bufferPos = 0; + } + CMyComPtr flush; + _outStream.QueryInterface(IID_IOutStreamFlush, &flush); + if (flush) + return flush->Flush(); + return S_OK; +} + + +STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream) +{ + _convertedPosBegin = _convertedPosEnd = _bufferPos = 0; + _inStream = inStream; + return Init(); +} + +STDMETHODIMP CFilterCoder::ReleaseInStream() +{ + _inStream.Release(); + return S_OK; +}; + +STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 processedSizeTotal = 0; + while(size > 0) + { + if (_convertedPosBegin != _convertedPosEnd) + { + UInt32 sizeTemp = MyMin(size, _convertedPosEnd - _convertedPosBegin); + memmove(data, _buffer + _convertedPosBegin, sizeTemp); + _convertedPosBegin += sizeTemp; + data = (void *)((Byte *)data + sizeTemp); + size -= sizeTemp; + processedSizeTotal += sizeTemp; + break; + } + int i; + for (i = 0; _convertedPosEnd + i < _bufferPos; i++) + _buffer[i] = _buffer[i + _convertedPosEnd]; + _bufferPos = i; + _convertedPosBegin = _convertedPosEnd = 0; + size_t processedSizeTemp = kBufferSize - _bufferPos; + RINOK(ReadStream(_inStream, _buffer + _bufferPos, &processedSizeTemp)); + _bufferPos = _bufferPos + (UInt32)processedSizeTemp; + _convertedPosEnd = Filter->Filter(_buffer, _bufferPos); + if (_convertedPosEnd == 0) + { + if (_bufferPos == 0) + break; + else + { + _convertedPosEnd = _bufferPos; // check it + continue; + } + } + if (_convertedPosEnd > _bufferPos) + { + for (; _bufferPos < _convertedPosEnd; _bufferPos++) + _buffer[_bufferPos] = 0; + _convertedPosEnd = Filter->Filter(_buffer, _bufferPos); + } + } + if (processedSize != NULL) + *processedSize = processedSizeTotal; + return S_OK; +} + +// #endif // _ST_MODE + +#ifndef _NO_CRYPTO +STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size) +{ + return _setPassword->CryptoSetPassword(data, size); +} +#endif + +#ifndef EXTRACT_ONLY +STDMETHODIMP CFilterCoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties) +{ + return _SetCoderProperties->SetCoderProperties(propIDs, properties, numProperties); +} + +STDMETHODIMP CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream) +{ + return _writeCoderProperties->WriteCoderProperties(outStream); +} + +/* +STDMETHODIMP CFilterCoder::ResetSalt() +{ + return _CryptoResetSalt->ResetSalt(); +} +*/ + +STDMETHODIMP CFilterCoder::ResetInitVector() +{ + return _CryptoResetInitVector->ResetInitVector(); +} +#endif + +STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + return _setDecoderProperties->SetDecoderProperties2(data, size); +} + + + +void foo() +{ +} diff --git a/desmume/src/windows/7z/CPP/7zip/Common/FilterCoder.h b/desmume/src/windows/7z/CPP/7zip/Common/FilterCoder.h new file mode 100644 index 000000000..496eb5e04 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/FilterCoder.h @@ -0,0 +1,143 @@ +// FilterCoder.h + +#ifndef __FILTERCODER_H +#define __FILTERCODER_H + +#include "../../Common/MyCom.h" +#include "../ICoder.h" +#include "../IPassword.h" + +#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) if (iid == IID_ ## i) \ +{ if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \ +*outObject = (void *)(i *)this; AddRef(); return S_OK; } + +class CFilterCoder: + public ICompressCoder, + // #ifdef _ST_MODE + public ICompressSetInStream, + public ISequentialInStream, + public ICompressSetOutStream, + public ISequentialOutStream, + public IOutStreamFlush, + // #endif + + #ifndef _NO_CRYPTO + public ICryptoSetPassword, + #endif + #ifndef EXTRACT_ONLY + public ICompressSetCoderProperties, + public ICompressWriteCoderProperties, + // public ICryptoResetSalt, + public ICryptoResetInitVector, + #endif + public ICompressSetDecoderProperties2, + public CMyUnknownImp +{ +protected: + Byte *_buffer; + // #ifdef _ST_MODE + CMyComPtr _inStream; + CMyComPtr _outStream; + UInt32 _bufferPos; + UInt32 _convertedPosBegin; + UInt32 _convertedPosEnd; + // #endif + bool _outSizeIsDefined; + UInt64 _outSize; + UInt64 _nowPos64; + + HRESULT Init() + { + _nowPos64 = 0; + _outSizeIsDefined = false; + return Filter->Init(); + } + + CMyComPtr _setPassword; + #ifndef EXTRACT_ONLY + CMyComPtr _SetCoderProperties; + CMyComPtr _writeCoderProperties; + // CMyComPtr _CryptoResetSalt; + CMyComPtr _CryptoResetInitVector; + #endif + CMyComPtr _setDecoderProperties; +public: + CMyComPtr Filter; + + CFilterCoder(); + ~CFilterCoder(); + HRESULT WriteWithLimit(ISequentialOutStream *outStream, UInt32 size); + bool NeedMore() const + { return (!_outSizeIsDefined || (_nowPos64 < _outSize)); } + +public: + MY_QUERYINTERFACE_BEGIN + MY_QUERYINTERFACE_ENTRY(ICompressCoder) + // #ifdef _ST_MODE + MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) + MY_QUERYINTERFACE_ENTRY(ISequentialInStream) + + MY_QUERYINTERFACE_ENTRY(ICompressSetOutStream) + MY_QUERYINTERFACE_ENTRY(ISequentialOutStream) + MY_QUERYINTERFACE_ENTRY(IOutStreamFlush) + // #endif + + #ifndef _NO_CRYPTO + MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _setPassword) + #endif + + #ifndef EXTRACT_ONLY + MY_QUERYINTERFACE_ENTRY_AG(ICompressSetCoderProperties, Filter, _SetCoderProperties) + MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _writeCoderProperties) + // MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetSalt, Filter, _CryptoResetSalt) + MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetInitVector, Filter, _CryptoResetInitVector) + #endif + + MY_QUERYINTERFACE_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _setDecoderProperties) + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + // #ifdef _ST_MODE + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); \ + STDMETHOD(SetOutStream)(ISequentialOutStream *outStream); + STDMETHOD(ReleaseOutStream)(); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Flush)(); + // #endif + + #ifndef _NO_CRYPTO + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); + #endif + #ifndef EXTRACT_ONLY + STDMETHOD(SetCoderProperties)(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties); + STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); + // STDMETHOD(ResetSalt)(); + STDMETHOD(ResetInitVector)(); + #endif + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); +}; + +// #ifdef _ST_MODE +class CInStreamReleaser +{ +public: + CFilterCoder *FilterCoder; + CInStreamReleaser(): FilterCoder(0) {} + ~CInStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseInStream(); } +}; + +class COutStreamReleaser +{ +public: + CFilterCoder *FilterCoder; + COutStreamReleaser(): FilterCoder(0) {} + ~COutStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); } +}; +// #endif + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/InBuffer.cpp b/desmume/src/windows/7z/CPP/7zip/Common/InBuffer.cpp new file mode 100644 index 000000000..7e061156a --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/InBuffer.cpp @@ -0,0 +1,83 @@ +// InBuffer.cpp + +#include "StdAfx.h" + +#include "InBuffer.h" + +extern "C" +{ + #include "../../../C/Alloc.h" +} + +CInBuffer::CInBuffer(): + _buffer(0), + _bufferLimit(0), + _bufferBase(0), + _stream(0), + _bufferSize(0) +{} + +bool CInBuffer::Create(UInt32 bufferSize) +{ + const UInt32 kMinBlockSize = 1; + if (bufferSize < kMinBlockSize) + bufferSize = kMinBlockSize; + if (_bufferBase != 0 && _bufferSize == bufferSize) + return true; + Free(); + _bufferSize = bufferSize; + _bufferBase = (Byte *)::MidAlloc(bufferSize); + return (_bufferBase != 0); +} + +void CInBuffer::Free() +{ + ::MidFree(_bufferBase); + _bufferBase = 0; +} + +void CInBuffer::SetStream(ISequentialInStream *stream) +{ + _stream = stream; +} + +void CInBuffer::Init() +{ + _processedSize = 0; + _buffer = _bufferBase; + _bufferLimit = _buffer; + _wasFinished = false; + #ifdef _NO_EXCEPTIONS + ErrorCode = S_OK; + #endif +} + +bool CInBuffer::ReadBlock() +{ + #ifdef _NO_EXCEPTIONS + if (ErrorCode != S_OK) + return false; + #endif + if (_wasFinished) + return false; + _processedSize += (_buffer - _bufferBase); + UInt32 numProcessedBytes; + HRESULT result = _stream->Read(_bufferBase, _bufferSize, &numProcessedBytes); + #ifdef _NO_EXCEPTIONS + ErrorCode = result; + #else + if (result != S_OK) + throw CInBufferException(result); + #endif + _buffer = _bufferBase; + _bufferLimit = _buffer + numProcessedBytes; + _wasFinished = (numProcessedBytes == 0); + return (!_wasFinished); +} + +Byte CInBuffer::ReadBlock2() +{ + if(!ReadBlock()) + return 0xFF; + return *_buffer++; +} diff --git a/desmume/src/windows/7z/CPP/7zip/Common/InBuffer.h b/desmume/src/windows/7z/CPP/7zip/Common/InBuffer.h new file mode 100644 index 000000000..cdd50f1b2 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/InBuffer.h @@ -0,0 +1,81 @@ +// InBuffer.h + +#ifndef __INBUFFER_H +#define __INBUFFER_H + +#include "../IStream.h" +#include "../../Common/MyCom.h" +#include "../../Common/MyException.h" + +#ifndef _NO_EXCEPTIONS +struct CInBufferException: public CSystemException +{ + CInBufferException(HRESULT errorCode): CSystemException(errorCode) {} +}; +#endif + +class CInBuffer +{ + Byte *_buffer; + Byte *_bufferLimit; + Byte *_bufferBase; + CMyComPtr _stream; + UInt64 _processedSize; + UInt32 _bufferSize; + bool _wasFinished; + + bool ReadBlock(); + Byte ReadBlock2(); + +public: + #ifdef _NO_EXCEPTIONS + HRESULT ErrorCode; + #endif + + CInBuffer(); + ~CInBuffer() { Free(); } + + bool Create(UInt32 bufferSize); + void Free(); + + void SetStream(ISequentialInStream *stream); + void Init(); + void ReleaseStream() { _stream.Release(); } + + bool ReadByte(Byte &b) + { + if (_buffer >= _bufferLimit) + if (!ReadBlock()) + return false; + b = *_buffer++; + return true; + } + Byte ReadByte() + { + if (_buffer >= _bufferLimit) + return ReadBlock2(); + return *_buffer++; + } + UInt32 ReadBytes(Byte *buf, UInt32 size) + { + if ((UInt32)(_bufferLimit - _buffer) >= size) + { + for (UInt32 i = 0; i < size; i++) + buf[i] = _buffer[i]; + _buffer += size; + return size; + } + for (UInt32 i = 0; i < size; i++) + { + if (_buffer >= _bufferLimit) + if (!ReadBlock()) + return i; + buf[i] = *_buffer++; + } + return size; + } + UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); } + bool WasFinished() const { return _wasFinished; } +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/InOutTempBuffer.cpp b/desmume/src/windows/7z/CPP/7zip/Common/InOutTempBuffer.cpp new file mode 100644 index 000000000..79c04c109 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/InOutTempBuffer.cpp @@ -0,0 +1,122 @@ +// InOutTempBuffer.cpp + +#include "StdAfx.h" + +#include "InOutTempBuffer.h" +#include "../../Common/Defs.h" +// #include "Windows/Defs.h" + +#include "StreamUtils.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDirectory; + +static UInt32 kTmpBufferMemorySize = (1 << 20); + +static LPCTSTR kTempFilePrefixString = TEXT("iot"); + +CInOutTempBuffer::CInOutTempBuffer(): + _buffer(NULL) +{ +} + +void CInOutTempBuffer::Create() +{ + _buffer = new Byte[kTmpBufferMemorySize]; +} + +CInOutTempBuffer::~CInOutTempBuffer() +{ + delete []_buffer; +} +void CInOutTempBuffer::InitWriting() +{ + _bufferPosition = 0; + _tmpFileCreated = false; + _fileSize = 0; +} + +bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size) +{ + if (size == 0) + return true; + if(!_tmpFileCreated) + { + CSysString tempDirPath; + if(!MyGetTempPath(tempDirPath)) + return false; + if (_tempFile.Create(tempDirPath, kTempFilePrefixString, _tmpFileName) == 0) + return false; + // _outFile.SetOpenCreationDispositionCreateAlways(); + if(!_outFile.Create(_tmpFileName, true)) + return false; + _tmpFileCreated = true; + } + UInt32 processedSize; + if(!_outFile.Write(data, size, processedSize)) + return false; + _fileSize += processedSize; + return (processedSize == size); +} + +bool CInOutTempBuffer::FlushWrite() +{ + return _outFile.Close(); +} + +bool CInOutTempBuffer::Write(const void *data, UInt32 size) +{ + if(_bufferPosition < kTmpBufferMemorySize) + { + UInt32 curSize = MyMin(kTmpBufferMemorySize - _bufferPosition, size); + memmove(_buffer + _bufferPosition, (const Byte *)data, curSize); + _bufferPosition += curSize; + size -= curSize; + data = ((const Byte *)data) + curSize; + _fileSize += curSize; + } + return WriteToFile(data, size); +} + +bool CInOutTempBuffer::InitReading() +{ + _currentPositionInBuffer = 0; + if(_tmpFileCreated) + return _inFile.Open(_tmpFileName); + return true; +} + +HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream) +{ + if (_currentPositionInBuffer < _bufferPosition) + { + UInt32 sizeToWrite = _bufferPosition - _currentPositionInBuffer; + RINOK(WriteStream(stream, _buffer + _currentPositionInBuffer, sizeToWrite)); + _currentPositionInBuffer += sizeToWrite; + } + if (!_tmpFileCreated) + return true; + for (;;) + { + UInt32 localProcessedSize; + if (!_inFile.ReadPart(_buffer, kTmpBufferMemorySize, localProcessedSize)) + return E_FAIL; + if (localProcessedSize == 0) + return S_OK; + RINOK(WriteStream(stream, _buffer, localProcessedSize)); + } +} + +STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if (!_buffer->Write(data, size)) + { + if (processedSize != NULL) + *processedSize = 0; + return E_FAIL; + } + if (processedSize != NULL) + *processedSize = size; + return S_OK; +} diff --git a/desmume/src/windows/7z/CPP/7zip/Common/InOutTempBuffer.h b/desmume/src/windows/7z/CPP/7zip/Common/InOutTempBuffer.h new file mode 100644 index 000000000..1ccf1153f --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/InOutTempBuffer.h @@ -0,0 +1,55 @@ +// Util/InOutTempBuffer.h + +#ifndef __IN_OUT_TEMP_BUFFER_H +#define __IN_OUT_TEMP_BUFFER_H + +#include "../../Windows/FileIO.h" +#include "../../Windows/FileDir.h" +#include "../../Common/MyCom.h" + +#include "../IStream.h" + +class CInOutTempBuffer +{ + NWindows::NFile::NDirectory::CTempFile _tempFile; + NWindows::NFile::NIO::COutFile _outFile; + NWindows::NFile::NIO::CInFile _inFile; + Byte *_buffer; + UInt32 _bufferPosition; + UInt32 _currentPositionInBuffer; + CSysString _tmpFileName; + bool _tmpFileCreated; + + UInt64 _fileSize; + + bool WriteToFile(const void *data, UInt32 size); +public: + CInOutTempBuffer(); + ~CInOutTempBuffer(); + void Create(); + + void InitWriting(); + bool Write(const void *data, UInt32 size); + UInt64 GetDataSize() const { return _fileSize; } + bool FlushWrite(); + bool InitReading(); + HRESULT WriteToStream(ISequentialOutStream *stream); +}; + +class CSequentialOutTempBufferImp: + public ISequentialOutStream, + public CMyUnknownImp +{ + CInOutTempBuffer *_buffer; +public: + // CSequentialOutStreamImp(): _size(0) {} + // UInt32 _size; + void Init(CInOutTempBuffer *buffer) { _buffer = buffer; } + // UInt32 GetSize() const { return _size; } + + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/LimitedStreams.cpp b/desmume/src/windows/7z/CPP/7zip/Common/LimitedStreams.cpp new file mode 100644 index 000000000..0a1bfa38e --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/LimitedStreams.cpp @@ -0,0 +1,45 @@ +// LimitedStreams.cpp + +#include "StdAfx.h" + +#include "LimitedStreams.h" +#include "../../Common/Defs.h" + +STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize = 0; + UInt32 sizeToRead = (UInt32)MyMin((_size - _pos), (UInt64)size); + HRESULT result = S_OK; + if (sizeToRead > 0) + { + result = _stream->Read(data, sizeToRead, &realProcessedSize); + _pos += realProcessedSize; + if (realProcessedSize == 0) + _wasFinished = true; + } + if(processedSize != NULL) + *processedSize = realProcessedSize; + return result; +} + +STDMETHODIMP CLimitedSequentialOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + HRESULT result = S_OK; + if (processedSize != NULL) + *processedSize = 0; + if (size > _size) + { + size = (UInt32)_size; + if (size == 0) + { + _overflow = true; + return E_FAIL; + } + } + if (_stream) + result = _stream->Write(data, size, &size); + _size -= size; + if (processedSize != NULL) + *processedSize = size; + return result; +} diff --git a/desmume/src/windows/7z/CPP/7zip/Common/LimitedStreams.h b/desmume/src/windows/7z/CPP/7zip/Common/LimitedStreams.h new file mode 100644 index 000000000..7e0e1c126 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/LimitedStreams.h @@ -0,0 +1,54 @@ +// LimitedStreams.h + +#ifndef __LIMITEDSTREAMS_H +#define __LIMITEDSTREAMS_H + +#include "../../Common/MyCom.h" +#include "../IStream.h" + +class CLimitedSequentialInStream: + public ISequentialInStream, + public CMyUnknownImp +{ + CMyComPtr _stream; + UInt64 _size; + UInt64 _pos; + bool _wasFinished; +public: + void SetStream(ISequentialInStream *stream) { _stream = stream; } + void Init(UInt64 streamSize) + { + _size = streamSize; + _pos = 0; + _wasFinished = false; + } + + MY_UNKNOWN_IMP + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + UInt64 GetSize() const { return _pos; } + bool WasFinished() const { return _wasFinished; } +}; + +class CLimitedSequentialOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ + CMyComPtr _stream; + UInt64 _size; + bool _overflow; +public: + MY_UNKNOWN_IMP + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void ReleaseStream() { _stream.Release(); } + void Init(UInt64 size) + { + _size = size; + _overflow = false; + } + bool IsFinishedOK() const { return (_size == 0 && !_overflow); } + UInt64 GetRem() const { return _size; } +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/LockedStream.cpp b/desmume/src/windows/7z/CPP/7zip/Common/LockedStream.cpp new file mode 100644 index 000000000..d1bbf6dba --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/LockedStream.cpp @@ -0,0 +1,23 @@ +// LockedStream.cpp + +#include "StdAfx.h" + +#include "LockedStream.h" + +HRESULT CLockedInStream::Read(UInt64 startPos, void *data, UInt32 size, + UInt32 *processedSize) +{ + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + RINOK(_stream->Seek(startPos, STREAM_SEEK_SET, NULL)); + return _stream->Read(data, size, processedSize); +} + +STDMETHODIMP CLockedSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize = 0; + HRESULT result = _lockedInStream->Read(_pos, data, size, &realProcessedSize); + _pos += realProcessedSize; + if (processedSize != NULL) + *processedSize = realProcessedSize; + return result; +} diff --git a/desmume/src/windows/7z/CPP/7zip/Common/LockedStream.h b/desmume/src/windows/7z/CPP/7zip/Common/LockedStream.h new file mode 100644 index 000000000..e12e22a4a --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/LockedStream.h @@ -0,0 +1,38 @@ +// LockedStream.h + +#ifndef __LOCKEDSTREAM_H +#define __LOCKEDSTREAM_H + +#include "../../Windows/Synchronization.h" +#include "../../Common/MyCom.h" +#include "../IStream.h" + +class CLockedInStream +{ + CMyComPtr _stream; + NWindows::NSynchronization::CCriticalSection _criticalSection; +public: + void Init(IInStream *stream) + { _stream = stream; } + HRESULT Read(UInt64 startPos, void *data, UInt32 size, UInt32 *processedSize); +}; + +class CLockedSequentialInStreamImp: + public ISequentialInStream, + public CMyUnknownImp +{ + CLockedInStream *_lockedInStream; + UInt64 _pos; +public: + void Init(CLockedInStream *lockedInStream, UInt64 startPos) + { + _lockedInStream = lockedInStream; + _pos = startPos; + } + + MY_UNKNOWN_IMP + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/MemBlocks.cpp b/desmume/src/windows/7z/CPP/7zip/Common/MemBlocks.cpp new file mode 100644 index 000000000..923c2e775 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/MemBlocks.cpp @@ -0,0 +1,183 @@ +// MemBlocks.cpp + +#include "StdAfx.h" + +#include "Common/MyCom.h" + +#include "StreamUtils.h" +#include "MemBlocks.h" + +bool CMemBlockManager::AllocateSpace(size_t numBlocks) +{ + FreeSpace(); + if (_blockSize < sizeof(void *) || numBlocks < 1) + return false; + size_t totalSize = numBlocks * _blockSize; + if (totalSize / _blockSize != numBlocks) + return false; + _data = ::MidAlloc(totalSize); + if (_data == 0) + return false; + Byte *p = (Byte *)_data; + for (size_t i = 0; i + 1 < numBlocks; i++, p += _blockSize) + *(Byte **)p = (p + _blockSize); + *(Byte **)p = 0; + _headFree = _data; + return true; +} + +void CMemBlockManager::FreeSpace() +{ + ::MidFree(_data); + _data = 0; + _headFree= 0; +} + +void *CMemBlockManager::AllocateBlock() +{ + if (_headFree == 0) + return 0; + void *p = _headFree; + _headFree = *(void **)_headFree; + return p; +} + +void CMemBlockManager::FreeBlock(void *p) +{ + if (p == 0) + return; + *(void **)p = _headFree; + _headFree = p; +} + + +HRes CMemBlockManagerMt::AllocateSpace(size_t numBlocks, size_t numNoLockBlocks) +{ + if (numNoLockBlocks > numBlocks) + return E_INVALIDARG; + if (!CMemBlockManager::AllocateSpace(numBlocks)) + return E_OUTOFMEMORY; + size_t numLockBlocks = numBlocks - numNoLockBlocks; + Semaphore.Close(); + return Semaphore.Create((LONG)numLockBlocks, (LONG)numLockBlocks); +} + +HRes CMemBlockManagerMt::AllocateSpaceAlways(size_t desiredNumberOfBlocks, size_t numNoLockBlocks) +{ + if (numNoLockBlocks > desiredNumberOfBlocks) + return E_INVALIDARG; + for (;;) + { + if (AllocateSpace(desiredNumberOfBlocks, numNoLockBlocks) == 0) + return 0; + if (desiredNumberOfBlocks == numNoLockBlocks) + return E_OUTOFMEMORY; + desiredNumberOfBlocks = numNoLockBlocks + ((desiredNumberOfBlocks - numNoLockBlocks) >> 1); + } +} + +void CMemBlockManagerMt::FreeSpace() +{ + Semaphore.Close(); + CMemBlockManager::FreeSpace(); +} + +void *CMemBlockManagerMt::AllocateBlock() +{ + // Semaphore.Lock(); + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + return CMemBlockManager::AllocateBlock(); +} + +void CMemBlockManagerMt::FreeBlock(void *p, bool lockMode) +{ + if (p == 0) + return; + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + CMemBlockManager::FreeBlock(p); + } + if (lockMode) + Semaphore.Release(); +} + +void CMemBlocks::Free(CMemBlockManagerMt *manager) +{ + while(Blocks.Size() > 0) + { + manager->FreeBlock(Blocks.Back()); + Blocks.DeleteBack(); + } + TotalSize = 0; +} + +void CMemBlocks::FreeOpt(CMemBlockManagerMt *manager) +{ + Free(manager); + Blocks.ClearAndFree(); +} + +HRESULT CMemBlocks::WriteToStream(size_t blockSize, ISequentialOutStream *outStream) const +{ + UInt64 totalSize = TotalSize; + for (int blockIndex = 0; totalSize > 0; blockIndex++) + { + UInt32 curSize = (UInt32)blockSize; + if (totalSize < curSize) + curSize = (UInt32)totalSize; + if (blockIndex >= Blocks.Size()) + return E_FAIL; + RINOK(WriteStream(outStream, Blocks[blockIndex], curSize)); + totalSize -= curSize; + } + return S_OK; +} + + +void CMemLockBlocks::FreeBlock(int index, CMemBlockManagerMt *memManager) +{ + memManager->FreeBlock(Blocks[index], LockMode); + Blocks[index] = 0; +} + +void CMemLockBlocks::Free(CMemBlockManagerMt *memManager) +{ + while (Blocks.Size() > 0) + { + FreeBlock(Blocks.Size() - 1, memManager); + Blocks.DeleteBack(); + } + TotalSize = 0; +} + +HRes CMemLockBlocks::SwitchToNoLockMode(CMemBlockManagerMt *memManager) +{ + if (LockMode) + { + if (Blocks.Size() > 0) + { + RINOK(memManager->ReleaseLockedBlocks(Blocks.Size())); + } + LockMode = false; + } + return 0; +} + +void CMemLockBlocks::Detach(CMemLockBlocks &blocks, CMemBlockManagerMt *memManager) +{ + blocks.Free(memManager); + blocks.LockMode = LockMode; + UInt64 totalSize = 0; + size_t blockSize = memManager->GetBlockSize(); + for (int i = 0; i < Blocks.Size(); i++) + { + if (totalSize < TotalSize) + blocks.Blocks.Add(Blocks[i]); + else + FreeBlock(i, memManager); + Blocks[i] = 0; + totalSize += blockSize; + } + blocks.TotalSize = TotalSize; + Free(memManager); +} diff --git a/desmume/src/windows/7z/CPP/7zip/Common/MemBlocks.h b/desmume/src/windows/7z/CPP/7zip/Common/MemBlocks.h new file mode 100644 index 000000000..4b20a1c4a --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/MemBlocks.h @@ -0,0 +1,77 @@ +// MemBlocks.h + +#ifndef __MEMBLOCKS_H +#define __MEMBLOCKS_H + +extern "C" +{ +#include "../../../C/Alloc.h" +} + +#include "Common/Types.h" +#include "Common/MyVector.h" + +#include "Windows/Synchronization.h" + +#include "../IStream.h" + +class CMemBlockManager +{ + void *_data; + size_t _blockSize; + void *_headFree; +public: + CMemBlockManager(size_t blockSize = (1 << 20)): _data(0), _blockSize(blockSize), _headFree(0) {} + ~CMemBlockManager() { FreeSpace(); } + + bool AllocateSpace(size_t numBlocks); + void FreeSpace(); + size_t GetBlockSize() const { return _blockSize; } + void *AllocateBlock(); + void FreeBlock(void *p); +}; + + +class CMemBlockManagerMt: public CMemBlockManager +{ + NWindows::NSynchronization::CCriticalSection _criticalSection; +public: + NWindows::NSynchronization::CSemaphore Semaphore; + + CMemBlockManagerMt(size_t blockSize = (1 << 20)): CMemBlockManager(blockSize) {} + ~CMemBlockManagerMt() { FreeSpace(); } + + HRes AllocateSpace(size_t numBlocks, size_t numNoLockBlocks = 0); + HRes AllocateSpaceAlways(size_t desiredNumberOfBlocks, size_t numNoLockBlocks = 0); + void FreeSpace(); + void *AllocateBlock(); + void FreeBlock(void *p, bool lockMode = true); + HRes ReleaseLockedBlocks(int number) { return Semaphore.Release(number); } +}; + + +class CMemBlocks +{ + void Free(CMemBlockManagerMt *manager); +public: + CRecordVector Blocks; + UInt64 TotalSize; + + CMemBlocks(): TotalSize(0) {} + + void FreeOpt(CMemBlockManagerMt *manager); + HRESULT WriteToStream(size_t blockSize, ISequentialOutStream *outStream) const; +}; + +struct CMemLockBlocks: public CMemBlocks +{ + bool LockMode; + + CMemLockBlocks(): LockMode(true) {}; + void Free(CMemBlockManagerMt *memManager); + void FreeBlock(int index, CMemBlockManagerMt *memManager); + HRes SwitchToNoLockMode(CMemBlockManagerMt *memManager); + void Detach(CMemLockBlocks &blocks, CMemBlockManagerMt *memManager); +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/MethodId.cpp b/desmume/src/windows/7z/CPP/7zip/Common/MethodId.cpp new file mode 100644 index 000000000..705cc4d9b --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/MethodId.cpp @@ -0,0 +1,27 @@ +// MethodId.cpp + +#include "StdAfx.h" + +#include "MethodId.h" +#include "../../Common/MyString.h" + +static inline wchar_t GetHex(Byte value) +{ + return (wchar_t)((value < 10) ? ('0' + value) : ('A' + (value - 10))); +} + +UString ConvertMethodIdToString(UInt64 id) +{ + wchar_t s[32]; + int len = 32; + s[--len] = 0; + do + { + s[--len] = GetHex((Byte)id & 0xF); + id >>= 4; + s[--len] = GetHex((Byte)id & 0xF); + id >>= 4; + } + while (id != 0); + return s + len; +} diff --git a/desmume/src/windows/7z/CPP/7zip/Common/MethodId.h b/desmume/src/windows/7z/CPP/7zip/Common/MethodId.h new file mode 100644 index 000000000..955172354 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/MethodId.h @@ -0,0 +1,10 @@ +// MethodId.h + +#ifndef __7Z_METHOD_ID_H +#define __7Z_METHOD_ID_H + +#include "../../Common/Types.h" + +typedef UInt64 CMethodId; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/MethodProps.cpp b/desmume/src/windows/7z/CPP/7zip/Common/MethodProps.cpp new file mode 100644 index 000000000..d917a2c23 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/MethodProps.cpp @@ -0,0 +1,99 @@ +// MethodProps.cpp + +#include "StdAfx.h" + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "MethodProps.h" + +static UInt64 k_LZMA = 0x030101; +// static UInt64 k_LZMA2 = 0x030102; + +HRESULT SetMethodProperties(const CMethod &method, const UInt64 *inSizeForReduce, IUnknown *coder) +{ + bool tryReduce = false; + UInt32 reducedDictionarySize = 1 << 10; + if (inSizeForReduce != 0 && (method.Id == k_LZMA /* || methodFull.MethodID == k_LZMA2 */)) + { + for (;;) + { + const UInt32 step = (reducedDictionarySize >> 1); + if (reducedDictionarySize >= *inSizeForReduce) + { + tryReduce = true; + break; + } + reducedDictionarySize += step; + if (reducedDictionarySize >= *inSizeForReduce) + { + tryReduce = true; + break; + } + if (reducedDictionarySize >= ((UInt32)3 << 30)) + break; + reducedDictionarySize += step; + } + } + + { + int numProps = method.Props.Size(); + CMyComPtr setCoderProperties; + coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties); + if (setCoderProperties == NULL) + { + if (numProps != 0) + return E_INVALIDARG; + } + else + { + CRecordVector propIDs; + NWindows::NCOM::CPropVariant *values = new NWindows::NCOM::CPropVariant[numProps]; + HRESULT res = S_OK; + try + { + for (int i = 0; i < numProps; i++) + { + const CProp &prop = method.Props[i]; + propIDs.Add(prop.Id); + NWindows::NCOM::CPropVariant &value = values[i]; + value = prop.Value; + // if (tryReduce && prop.Id == NCoderPropID::kDictionarySize && value.vt == VT_UI4 && reducedDictionarySize < value.ulVal) + if (tryReduce) + if (prop.Id == NCoderPropID::kDictionarySize) + if (value.vt == VT_UI4) + if (reducedDictionarySize < value.ulVal) + value.ulVal = reducedDictionarySize; + } + CMyComPtr setCoderProperties; + coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties); + res = setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProps); + } + catch(...) + { + delete []values; + throw; + } + delete []values; + RINOK(res); + } + } + + /* + CMyComPtr writeCoderProperties; + coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties); + if (writeCoderProperties != NULL) + { + CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp; + CMyComPtr outStream(outStreamSpec); + outStreamSpec->Init(); + RINOK(writeCoderProperties->WriteCoderProperties(outStream)); + size_t size = outStreamSpec->GetSize(); + filterProps.SetCapacity(size); + memmove(filterProps, outStreamSpec->GetBuffer(), size); + } + */ + return S_OK; +} + diff --git a/desmume/src/windows/7z/CPP/7zip/Common/MethodProps.h b/desmume/src/windows/7z/CPP/7zip/Common/MethodProps.h new file mode 100644 index 000000000..e27f09574 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/MethodProps.h @@ -0,0 +1,41 @@ +// MethodProps.h + +#ifndef __7Z_METHOD_PROPS_H +#define __7Z_METHOD_PROPS_H + +#include "../../Common/MyVector.h" + +#include "../../Windows/PropVariant.h" + +#include "MethodId.h" + +struct CProp +{ + PROPID Id; + NWindows::NCOM::CPropVariant Value; +}; + +struct CMethod +{ + CMethodId Id; + CObjectVector Props; +}; + +struct CMethodsMode +{ + CObjectVector Methods; + #ifdef COMPRESS_MT + UInt32 NumThreads; + #endif + + CMethodsMode() + #ifdef COMPRESS_MT + : NumThreads(1) + #endif + {} + bool IsEmpty() const { return Methods.IsEmpty() ; } +}; + +HRESULT SetMethodProperties(const CMethod &method, const UInt64 *inSizeForReduce, IUnknown *coder); + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/OffsetStream.cpp b/desmume/src/windows/7z/CPP/7zip/Common/OffsetStream.cpp new file mode 100644 index 000000000..d37657949 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/OffsetStream.cpp @@ -0,0 +1,35 @@ +// OffsetStream.cpp + +#include "StdAfx.h" + +#include "Common/Defs.h" +#include "OffsetStream.h" + +HRESULT COffsetOutStream::Init(IOutStream *stream, UInt64 offset) +{ + _offset = offset; + _stream = stream; + return _stream->Seek(offset, STREAM_SEEK_SET, NULL); +} + +STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + return _stream->Write(data, size, processedSize); +} + +STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin, + UInt64 *newPosition) +{ + UInt64 absoluteNewPosition; + if (seekOrigin == STREAM_SEEK_SET) + offset += _offset; + HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition); + if (newPosition != NULL) + *newPosition = absoluteNewPosition - _offset; + return result; +} + +STDMETHODIMP COffsetOutStream::SetSize(Int64 newSize) +{ + return _stream->SetSize(_offset + newSize); +} diff --git a/desmume/src/windows/7z/CPP/7zip/Common/OffsetStream.h b/desmume/src/windows/7z/CPP/7zip/Common/OffsetStream.h new file mode 100644 index 000000000..15846b24a --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/OffsetStream.h @@ -0,0 +1,25 @@ +// OffsetStream.h + +#ifndef __OFFSETSTREAM_H +#define __OFFSETSTREAM_H + +#include "Common/MyCom.h" +#include "../IStream.h" + +class COffsetOutStream: + public IOutStream, + public CMyUnknownImp +{ + UInt64 _offset; + CMyComPtr _stream; +public: + HRESULT Init(IOutStream *stream, UInt64 offset); + + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); + STDMETHOD(SetSize)(Int64 newSize); +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/OutBuffer.cpp b/desmume/src/windows/7z/CPP/7zip/Common/OutBuffer.cpp new file mode 100644 index 000000000..238320fe4 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/OutBuffer.cpp @@ -0,0 +1,119 @@ +// OutByte.cpp + +#include "StdAfx.h" + +#include "OutBuffer.h" + +extern "C" +{ + #include "../../../C/Alloc.h" +} + +bool COutBuffer::Create(UInt32 bufferSize) +{ + const UInt32 kMinBlockSize = 1; + if (bufferSize < kMinBlockSize) + bufferSize = kMinBlockSize; + if (_buffer != 0 && _bufferSize == bufferSize) + return true; + Free(); + _bufferSize = bufferSize; + _buffer = (Byte *)::MidAlloc(bufferSize); + return (_buffer != 0); +} + +void COutBuffer::Free() +{ + ::MidFree(_buffer); + _buffer = 0; +} + +void COutBuffer::SetStream(ISequentialOutStream *stream) +{ + _stream = stream; +} + +void COutBuffer::Init() +{ + _streamPos = 0; + _limitPos = _bufferSize; + _pos = 0; + _processedSize = 0; + _overDict = false; + #ifdef _NO_EXCEPTIONS + ErrorCode = S_OK; + #endif +} + +UInt64 COutBuffer::GetProcessedSize() const +{ + UInt64 res = _processedSize + _pos - _streamPos; + if (_streamPos > _pos) + res += _bufferSize; + return res; +} + + +HRESULT COutBuffer::FlushPart() +{ + // _streamPos < _bufferSize + UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos); + HRESULT result = S_OK; + #ifdef _NO_EXCEPTIONS + result = ErrorCode; + #endif + if (_buffer2 != 0) + { + memmove(_buffer2, _buffer + _streamPos, size); + _buffer2 += size; + } + + if (_stream != 0 + #ifdef _NO_EXCEPTIONS + && (ErrorCode == S_OK) + #endif + ) + { + UInt32 processedSize = 0; + result = _stream->Write(_buffer + _streamPos, size, &processedSize); + size = processedSize; + } + _streamPos += size; + if (_streamPos == _bufferSize) + _streamPos = 0; + if (_pos == _bufferSize) + { + _overDict = true; + _pos = 0; + } + _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize; + _processedSize += size; + return result; +} + +HRESULT COutBuffer::Flush() +{ + #ifdef _NO_EXCEPTIONS + if (ErrorCode != S_OK) + return ErrorCode; + #endif + + while(_streamPos != _pos) + { + HRESULT result = FlushPart(); + if (result != S_OK) + return result; + } + return S_OK; +} + +void COutBuffer::FlushWithCheck() +{ + HRESULT result = Flush(); + #ifdef _NO_EXCEPTIONS + ErrorCode = result; + #else + if (result != S_OK) + throw COutBufferException(result); + #endif +} diff --git a/desmume/src/windows/7z/CPP/7zip/Common/OutBuffer.h b/desmume/src/windows/7z/CPP/7zip/Common/OutBuffer.h new file mode 100644 index 000000000..e2e76ad58 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/OutBuffer.h @@ -0,0 +1,64 @@ +// OutBuffer.h + +#ifndef __OUTBUFFER_H +#define __OUTBUFFER_H + +#include "../IStream.h" +#include "../../Common/MyCom.h" +#include "../../Common/MyException.h" + +#ifndef _NO_EXCEPTIONS +struct COutBufferException: public CSystemException +{ + COutBufferException(HRESULT errorCode): CSystemException(errorCode) {} +}; +#endif + +class COutBuffer +{ +protected: + Byte *_buffer; + UInt32 _pos; + UInt32 _limitPos; + UInt32 _streamPos; + UInt32 _bufferSize; + CMyComPtr _stream; + UInt64 _processedSize; + Byte *_buffer2; + bool _overDict; + + HRESULT FlushPart(); +public: + #ifdef _NO_EXCEPTIONS + HRESULT ErrorCode; + #endif + + COutBuffer(): _buffer(0), _pos(0), _stream(0), _buffer2(0) {} + ~COutBuffer() { Free(); } + + bool Create(UInt32 bufferSize); + void Free(); + + void SetMemStream(Byte *buffer) { _buffer2 = buffer; } + void SetStream(ISequentialOutStream *stream); + void Init(); + HRESULT Flush(); + void FlushWithCheck(); + void ReleaseStream() { _stream.Release(); } + + void WriteByte(Byte b) + { + _buffer[_pos++] = b; + if(_pos == _limitPos) + FlushWithCheck(); + } + void WriteBytes(const void *data, size_t size) + { + for (size_t i = 0; i < size; i++) + WriteByte(((const Byte *)data)[i]); + } + + UInt64 GetProcessedSize() const; +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/OutMemStream.cpp b/desmume/src/windows/7z/CPP/7zip/Common/OutMemStream.cpp new file mode 100644 index 000000000..f0208eaaf --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/OutMemStream.cpp @@ -0,0 +1,142 @@ +// OutMemStream.cpp + +#include "StdAfx.h" + +#include "OutMemStream.h" + +void COutMemStream::Free() +{ + Blocks.Free(_memManager); + Blocks.LockMode = true; +} + +void COutMemStream::Init() +{ + WriteToRealStreamEvent.Reset(); + _unlockEventWasSent = false; + _realStreamMode = false; + Free(); + _curBlockPos = 0; + _curBlockIndex = 0; +} + +void COutMemStream::DetachData(CMemLockBlocks &blocks) +{ + Blocks.Detach(blocks, _memManager); + Free(); +} + + +HRESULT COutMemStream::WriteToRealStream() +{ + RINOK(Blocks.WriteToStream(_memManager->GetBlockSize(), OutSeqStream)); + Blocks.Free(_memManager); + return S_OK; +} + +STDMETHODIMP COutMemStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if (_realStreamMode) + return OutSeqStream->Write(data, size, processedSize); + if (processedSize != 0) + *processedSize = 0; + while(size != 0) + { + if ((int)_curBlockIndex < Blocks.Blocks.Size()) + { + Byte *p = (Byte *)Blocks.Blocks[(int)_curBlockIndex] + _curBlockPos; + size_t curSize = _memManager->GetBlockSize() - _curBlockPos; + if (size < curSize) + curSize = size; + memmove(p, data, curSize); + if (processedSize != 0) + *processedSize += (UInt32)curSize; + data = (const void *)((const Byte *)data + curSize); + size -= (UInt32)curSize; + _curBlockPos += curSize; + + UInt64 pos64 = GetPos(); + if (pos64 > Blocks.TotalSize) + Blocks.TotalSize = pos64; + if (_curBlockPos == _memManager->GetBlockSize()) + { + _curBlockIndex++; + _curBlockPos = 0; + } + continue; + } + HANDLE events[3] = { StopWritingEvent, WriteToRealStreamEvent, /* NoLockEvent, */ _memManager->Semaphore }; + DWORD waitResult = ::WaitForMultipleObjects((Blocks.LockMode ? 3 : 2), events, FALSE, INFINITE); + switch (waitResult) + { + case (WAIT_OBJECT_0 + 0): + return StopWriteResult; + case (WAIT_OBJECT_0 + 1): + { + _realStreamMode = true; + RINOK(WriteToRealStream()); + UInt32 processedSize2; + HRESULT res = OutSeqStream->Write(data, size, &processedSize2); + if (processedSize != 0) + *processedSize += processedSize2; + return res; + } + /* + case (WAIT_OBJECT_0 + 2): + { + // it has bug: no write. + if (!Blocks.SwitchToNoLockMode(_memManager)) + return E_FAIL; + break; + } + */ + case (WAIT_OBJECT_0 + 2): + break; + default: + return E_FAIL; + } + Blocks.Blocks.Add(_memManager->AllocateBlock()); + if (Blocks.Blocks.Back() == 0) + return E_FAIL; + } + return S_OK; +} + +STDMETHODIMP COutMemStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +{ + if (_realStreamMode) + { + if (!OutStream) + return E_FAIL; + return OutStream->Seek(offset, seekOrigin, newPosition); + } + if (seekOrigin == STREAM_SEEK_CUR) + { + if (offset != 0) + return E_NOTIMPL; + } + else if (seekOrigin == STREAM_SEEK_SET) + { + if (offset != 0) + return E_NOTIMPL; + _curBlockIndex = 0; + _curBlockPos = 0; + } + else + return E_NOTIMPL; + if (newPosition != 0) + *newPosition = GetPos(); + return S_OK; +} + +STDMETHODIMP COutMemStream::SetSize(Int64 newSize) +{ + if (_realStreamMode) + { + if (!OutStream) + return E_FAIL; + return OutStream->SetSize(newSize); + } + Blocks.TotalSize = newSize; + return S_OK; +} diff --git a/desmume/src/windows/7z/CPP/7zip/Common/OutMemStream.h b/desmume/src/windows/7z/CPP/7zip/Common/OutMemStream.h new file mode 100644 index 000000000..9a8cac431 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/OutMemStream.h @@ -0,0 +1,96 @@ +// OutMemStream.h + +#ifndef __OUTMEMSTREAM_H +#define __OUTMEMSTREAM_H + +#include "Common/MyCom.h" +#include "MemBlocks.h" + +class COutMemStream: + public IOutStream, + public CMyUnknownImp +{ + CMemBlockManagerMt *_memManager; + size_t _curBlockIndex; + size_t _curBlockPos; + bool _realStreamMode; + + bool _unlockEventWasSent; + NWindows::NSynchronization::CAutoResetEvent StopWritingEvent; + NWindows::NSynchronization::CAutoResetEvent WriteToRealStreamEvent; + // NWindows::NSynchronization::CAutoResetEvent NoLockEvent; + + HRESULT StopWriteResult; + CMemLockBlocks Blocks; + + UInt64 GetPos() const { return (UInt64)_curBlockIndex * _memManager->GetBlockSize() + _curBlockPos; } + + CMyComPtr OutSeqStream; + CMyComPtr OutStream; + +public: + + HRes CreateEvents() + { + RINOK(StopWritingEvent.CreateIfNotCreated()); + return WriteToRealStreamEvent.CreateIfNotCreated(); + } + + void SetOutStream(IOutStream *outStream) + { + OutStream = outStream; + OutSeqStream = outStream; + } + + void SetSeqOutStream(ISequentialOutStream *outStream) + { + OutStream = NULL; + OutSeqStream = outStream; + } + + void ReleaseOutStream() + { + OutStream.Release(); + OutSeqStream.Release(); + } + + COutMemStream(CMemBlockManagerMt *memManager): _memManager(memManager) { } + + ~COutMemStream() { Free(); } + void Free(); + + void Init(); + HRESULT WriteToRealStream(); + + void DetachData(CMemLockBlocks &blocks); + + bool WasUnlockEventSent() const { return _unlockEventWasSent; } + + void SetRealStreamMode() + { + _unlockEventWasSent = true; + WriteToRealStreamEvent.Set(); + } + + /* + void SetNoLockMode() + { + _unlockEventWasSent = true; + NoLockEvent.Set(); + } + */ + + void StopWriting(HRESULT res) + { + StopWriteResult = res; + StopWritingEvent.Set(); + } + + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); + STDMETHOD(SetSize)(Int64 newSize); +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/ProgressMt.cpp b/desmume/src/windows/7z/CPP/7zip/Common/ProgressMt.cpp new file mode 100644 index 000000000..e1e7f38e0 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/ProgressMt.cpp @@ -0,0 +1,53 @@ +// ProgressMt.h + +#include "StdAfx.h" + +#include "ProgressMt.h" + +void CMtCompressProgressMixer::Init(int numItems, ICompressProgressInfo *progress) +{ + NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); + InSizes.Clear(); + OutSizes.Clear(); + for (int i = 0; i < numItems; i++) + { + InSizes.Add(0); + OutSizes.Add(0); + } + TotalInSize = 0; + TotalOutSize = 0; + _progress = progress; +} + +void CMtCompressProgressMixer::Reinit(int index) +{ + NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); + InSizes[index] = 0; + OutSizes[index] = 0; +} + +HRESULT CMtCompressProgressMixer::SetRatioInfo(int index, const UInt64 *inSize, const UInt64 *outSize) +{ + NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); + if (inSize != 0) + { + UInt64 diff = *inSize - InSizes[index]; + InSizes[index] = *inSize; + TotalInSize += diff; + } + if (outSize != 0) + { + UInt64 diff = *outSize - OutSizes[index]; + OutSizes[index] = *outSize; + TotalOutSize += diff; + } + if (_progress) + return _progress->SetRatioInfo(&TotalInSize, &TotalOutSize); + return S_OK; +} + + +STDMETHODIMP CMtCompressProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +{ + return _progress->SetRatioInfo(_index, inSize, outSize); +} diff --git a/desmume/src/windows/7z/CPP/7zip/Common/ProgressMt.h b/desmume/src/windows/7z/CPP/7zip/Common/ProgressMt.h new file mode 100644 index 000000000..4eeb02aa0 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/ProgressMt.h @@ -0,0 +1,46 @@ +// ProgressMt.h + +#ifndef __PROGRESSMT_H +#define __PROGRESSMT_H + +#include "../../Common/MyCom.h" +#include "../../Common/MyVector.h" +#include "../../Windows/Synchronization.h" + +#include "../ICoder.h" +#include "../IProgress.h" + +class CMtCompressProgressMixer +{ + CMyComPtr _progress; + CRecordVector InSizes; + CRecordVector OutSizes; + UInt64 TotalInSize; + UInt64 TotalOutSize; +public: + NWindows::NSynchronization::CCriticalSection CriticalSection; + void Init(int numItems, ICompressProgressInfo *progress); + void Reinit(int index); + HRESULT SetRatioInfo(int index, const UInt64 *inSize, const UInt64 *outSize); +}; + +class CMtCompressProgress: + public ICompressProgressInfo, + public CMyUnknownImp +{ + CMtCompressProgressMixer *_progress; + int _index; +public: + void Init(CMtCompressProgressMixer *progress, int index) + { + _progress = progress; + _index = index; + } + void Reinit() { _progress->Reinit(_index); } + + MY_UNKNOWN_IMP + + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/ProgressUtils.cpp b/desmume/src/windows/7z/CPP/7zip/Common/ProgressUtils.cpp new file mode 100644 index 000000000..84a3eaf65 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/ProgressUtils.cpp @@ -0,0 +1,42 @@ +// ProgressUtils.h + +#include "StdAfx.h" + +#include "ProgressUtils.h" + +CLocalProgress::CLocalProgress() +{ + ProgressOffset = InSize = OutSize = 0; + SendRatio = SendProgress = true; +} + +void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain) +{ + _ratioProgress.Release(); + _progress = progress; + _progress.QueryInterface(IID_ICompressProgressInfo, &_ratioProgress); + _inSizeIsMain = inSizeIsMain; +} + +STDMETHODIMP CLocalProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +{ + UInt64 inSizeNew = InSize, outSizeNew = OutSize; + if (inSize) + inSizeNew += (*inSize); + if (outSize) + outSizeNew += (*outSize); + if (SendRatio && _ratioProgress) + { + RINOK(_ratioProgress->SetRatioInfo(&inSizeNew, &outSizeNew)); + } + inSizeNew += ProgressOffset; + outSizeNew += ProgressOffset; + if (SendProgress) + return _progress->SetCompleted(_inSizeIsMain ? &inSizeNew : &outSizeNew); + return S_OK; +} + +HRESULT CLocalProgress::SetCur() +{ + return SetRatioInfo(NULL, NULL); +} diff --git a/desmume/src/windows/7z/CPP/7zip/Common/ProgressUtils.h b/desmume/src/windows/7z/CPP/7zip/Common/ProgressUtils.h new file mode 100644 index 000000000..c6204844a --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/ProgressUtils.h @@ -0,0 +1,34 @@ +// ProgressUtils.h + +#ifndef __PROGRESSUTILS_H +#define __PROGRESSUTILS_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" +#include "../IProgress.h" + +class CLocalProgress: + public ICompressProgressInfo, + public CMyUnknownImp +{ + CMyComPtr _progress; + CMyComPtr _ratioProgress; + bool _inSizeIsMain; +public: + UInt64 ProgressOffset; + UInt64 InSize; + UInt64 OutSize; + bool SendRatio; + bool SendProgress; + + CLocalProgress(); + void Init(IProgress *progress, bool inSizeIsMain); + HRESULT SetCur(); + + MY_UNKNOWN_IMP + + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/RegisterArc.h b/desmume/src/windows/7z/CPP/7zip/Common/RegisterArc.h new file mode 100644 index 000000000..e377c4095 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/RegisterArc.h @@ -0,0 +1,33 @@ +// RegisterArc.h + +#ifndef __REGISTERARC_H +#define __REGISTERARC_H + +#include "../Archive/IArchive.h" +#include "DeclareArcs.h" + +typedef IInArchive * (*CreateInArchiveP)(); +typedef IOutArchive * (*CreateOutArchiveP)(); + +struct CArcInfo +{ + const wchar_t *Name; + const wchar_t *Ext; + const wchar_t *AddExt; + Byte ClassId; + Byte Signature[16]; + int SignatureSize; + bool KeepName; + CreateInArchiveP CreateInArchive; + CreateOutArchiveP CreateOutArchive; +}; + +void RegisterArc(const CArcInfo *arcInfo); + +#define REGISTER_ARC(x) CRegister##x::CRegister##x() { RegisterArc(&g_ArcInfo); } \ + CRegister##x g_RegisterArc##x; + +#define REGISTER_ARCN(x,n) CRegister##x##n::CRegister##x##n() { RegisterArc(&g_ArcInfo##n); } \ + CRegister##x##n g_RegisterArc##n##x; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/RegisterCodec.h b/desmume/src/windows/7z/CPP/7zip/Common/RegisterCodec.h new file mode 100644 index 000000000..f51e6317e --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/RegisterCodec.h @@ -0,0 +1,30 @@ +// RegisterCodec.h + +#ifndef __REGISTERCODEC_H +#define __REGISTERCODEC_H + +#include "../Common/MethodId.h" +#include "DeclareCodecs.h" + +typedef void * (*CreateCodecP)(); +struct CCodecInfo +{ + CreateCodecP CreateDecoder; + CreateCodecP CreateEncoder; + CMethodId Id; + const wchar_t *Name; + UInt32 NumInStreams; + bool IsFilter; +}; + +void RegisterCodec(const CCodecInfo *codecInfo); + +#define REGISTER_CODEC(x) CRegisterCodec##x::CRegisterCodec##x() { RegisterCodec(&g_CodecInfo); } \ + CRegisterCodec##x g_RegisterCodec##x; + +#define REGISTER_CODECS(x) CRegisterCodecs##x::CRegisterCodecs##x() { \ + for(int i=0;iCloseRead(); } + void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; } +}; + +STDMETHODIMP CSequentialInStreamForBinder::Read(void *data, UInt32 size, UInt32 *processedSize) + { return m_StreamBinder->Read(data, size, processedSize); } + +class CSequentialOutStreamForBinder: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + +private: + CStreamBinder *m_StreamBinder; +public: + ~CSequentialOutStreamForBinder() { m_StreamBinder->CloseWrite(); } + void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; } +}; + +STDMETHODIMP CSequentialOutStreamForBinder::Write(const void *data, UInt32 size, UInt32 *processedSize) + { return m_StreamBinder->Write(data, size, processedSize); } + + +////////////////////////// +// CStreamBinder +// (_thereAreBytesToReadEvent && _bufferSize == 0) means that stream is finished. + +HRes CStreamBinder::CreateEvents() +{ + RINOK(_allBytesAreWritenEvent.Create(true)); + RINOK(_thereAreBytesToReadEvent.Create()); + return _readStreamIsClosedEvent.Create(); +} + +void CStreamBinder::ReInit() +{ + _thereAreBytesToReadEvent.Reset(); + _readStreamIsClosedEvent.Reset(); + ProcessedSize = 0; +} + + + +void CStreamBinder::CreateStreams(ISequentialInStream **inStream, + ISequentialOutStream **outStream) +{ + CSequentialInStreamForBinder *inStreamSpec = new + CSequentialInStreamForBinder; + CMyComPtr inStreamLoc(inStreamSpec); + inStreamSpec->SetBinder(this); + *inStream = inStreamLoc.Detach(); + + CSequentialOutStreamForBinder *outStreamSpec = new + CSequentialOutStreamForBinder; + CMyComPtr outStreamLoc(outStreamSpec); + outStreamSpec->SetBinder(this); + *outStream = outStreamLoc.Detach(); + + _buffer = NULL; + _bufferSize= 0; + ProcessedSize = 0; +} + +HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 sizeToRead = size; + if (size > 0) + { + RINOK(_thereAreBytesToReadEvent.Lock()); + sizeToRead = MyMin(_bufferSize, size); + if (_bufferSize > 0) + { + memcpy(data, _buffer, sizeToRead); + _buffer = ((const Byte *)_buffer) + sizeToRead; + _bufferSize -= sizeToRead; + if (_bufferSize == 0) + { + _thereAreBytesToReadEvent.Reset(); + _allBytesAreWritenEvent.Set(); + } + } + } + if (processedSize != NULL) + *processedSize = sizeToRead; + ProcessedSize += sizeToRead; + return S_OK; +} + +void CStreamBinder::CloseRead() +{ + _readStreamIsClosedEvent.Set(); +} + +HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if (size > 0) + { + _buffer = data; + _bufferSize = size; + _allBytesAreWritenEvent.Reset(); + _thereAreBytesToReadEvent.Set(); + + HANDLE events[2]; + events[0] = _allBytesAreWritenEvent; + events[1] = _readStreamIsClosedEvent; + DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); + if (waitResult != WAIT_OBJECT_0 + 0) + { + // ReadingWasClosed = true; + return S_FALSE; + } + // if(!_allBytesAreWritenEvent.Lock()) + // return E_FAIL; + } + if (processedSize != NULL) + *processedSize = size; + return S_OK; +} + +void CStreamBinder::CloseWrite() +{ + // _bufferSize must be = 0 + _thereAreBytesToReadEvent.Set(); +} diff --git a/desmume/src/windows/7z/CPP/7zip/Common/StreamBinder.h b/desmume/src/windows/7z/CPP/7zip/Common/StreamBinder.h new file mode 100644 index 000000000..b5d6c0d1c --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/StreamBinder.h @@ -0,0 +1,32 @@ +// StreamBinder.h + +#ifndef __STREAMBINDER_H +#define __STREAMBINDER_H + +#include "../IStream.h" +#include "../../Windows/Synchronization.h" + +class CStreamBinder +{ + NWindows::NSynchronization::CManualResetEvent _allBytesAreWritenEvent; + NWindows::NSynchronization::CManualResetEvent _thereAreBytesToReadEvent; + NWindows::NSynchronization::CManualResetEvent _readStreamIsClosedEvent; + UInt32 _bufferSize; + const void *_buffer; +public: + // bool ReadingWasClosed; + UInt64 ProcessedSize; + CStreamBinder() {} + HRes CreateEvents(); + + void CreateStreams(ISequentialInStream **inStream, + ISequentialOutStream **outStream); + HRESULT Read(void *data, UInt32 size, UInt32 *processedSize); + void CloseRead(); + + HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize); + void CloseWrite(); + void ReInit(); +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/StreamObjects.cpp b/desmume/src/windows/7z/CPP/7zip/Common/StreamObjects.cpp new file mode 100644 index 000000000..f42b56bfa --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/StreamObjects.cpp @@ -0,0 +1,68 @@ +// StreamObjects.cpp + +#include "StdAfx.h" + +#include "StreamObjects.h" +#include "../../Common/Defs.h" + + +STDMETHODIMP CSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + size_t rem = _size - _pos; + if (size < rem) + rem = (size_t)size; + memcpy(data, _dataPointer + _pos, rem); + _pos += rem; + if (processedSize != NULL) + *processedSize = (UInt32)rem; + return S_OK; +} + + +void CWriteBuffer::Write(const void *data, size_t size) +{ + size_t newCapacity = _size + size; + _buffer.EnsureCapacity(newCapacity); + memcpy(_buffer + _size, data, size); + _size += size; +} + +STDMETHODIMP CSequentialOutStreamImp::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + _writeBuffer.Write(data, (size_t)size); + if(processedSize != NULL) + *processedSize = size; + return S_OK; +} + +STDMETHODIMP CSequentialOutStreamImp2::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + size_t rem = _size - _pos; + if (size < rem) + rem = (size_t)size; + memcpy(_buffer + _pos, data, rem); + _pos += rem; + if (processedSize != NULL) + *processedSize = (UInt32)rem; + return (rem == size ? S_OK : E_FAIL); +} + +STDMETHODIMP CSequentialInStreamSizeCount::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result = _stream->Read(data, size, &realProcessedSize); + _size += realProcessedSize; + if (processedSize != 0) + *processedSize = realProcessedSize; + return result; +} + +STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result = _stream->Write(data, size, &realProcessedSize); + _size += realProcessedSize; + if (processedSize != 0) + *processedSize = realProcessedSize; + return result; +} diff --git a/desmume/src/windows/7z/CPP/7zip/Common/StreamObjects.h b/desmume/src/windows/7z/CPP/7zip/Common/StreamObjects.h new file mode 100644 index 000000000..7f19fd479 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/StreamObjects.h @@ -0,0 +1,117 @@ +// StreamObjects.h + +#ifndef __STREAMOBJECTS_H +#define __STREAMOBJECTS_H + +#include "../../Common/DynamicBuffer.h" +#include "../../Common/MyCom.h" +#include "../IStream.h" + +class CSequentialInStreamImp: + public ISequentialInStream, + public CMyUnknownImp +{ + const Byte *_dataPointer; + size_t _size; + size_t _pos; + +public: + void Init(const Byte *dataPointer, size_t size) + { + _dataPointer = dataPointer; + _size = size; + _pos = 0; + } + + MY_UNKNOWN_IMP + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +}; + + +class CWriteBuffer +{ + CByteDynamicBuffer _buffer; + size_t _size; +public: + CWriteBuffer(): _size(0) {} + void Init() { _size = 0; } + void Write(const void *data, size_t size); + size_t GetSize() const { return _size; } + const CByteDynamicBuffer& GetBuffer() const { return _buffer; } +}; + +class CSequentialOutStreamImp: + public ISequentialOutStream, + public CMyUnknownImp +{ + CWriteBuffer _writeBuffer; +public: + void Init() { _writeBuffer.Init(); } + size_t GetSize() const { return _writeBuffer.GetSize(); } + const CByteDynamicBuffer& GetBuffer() const { return _writeBuffer.GetBuffer(); } + + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +class CSequentialOutStreamImp2: + public ISequentialOutStream, + public CMyUnknownImp +{ + Byte *_buffer; + size_t _size; + size_t _pos; +public: + + void Init(Byte *buffer, size_t size) + { + _buffer = buffer; + _pos = 0; + _size = size; + } + + size_t GetPos() const { return _pos; } + + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +class CSequentialInStreamSizeCount: + public ISequentialInStream, + public CMyUnknownImp +{ + CMyComPtr _stream; + UInt64 _size; +public: + void Init(ISequentialInStream *stream) + { + _stream = stream; + _size = 0; + } + UInt64 GetSize() const { return _size; } + + MY_UNKNOWN_IMP + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +}; + +class CSequentialOutStreamSizeCount: + public ISequentialOutStream, + public CMyUnknownImp +{ + CMyComPtr _stream; + UInt64 _size; +public: + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void Init() { _size = 0; } + UInt64 GetSize() const { return _size; } + + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/StreamUtils.cpp b/desmume/src/windows/7z/CPP/7zip/Common/StreamUtils.cpp new file mode 100644 index 000000000..57ff4ee38 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/StreamUtils.cpp @@ -0,0 +1,56 @@ +// StreamUtils.cpp + +#include "StdAfx.h" + +#include "StreamUtils.h" + +static const UInt32 kBlockSize = ((UInt32)1 << 31); + +HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSize) +{ + size_t size = *processedSize; + *processedSize = 0; + while (size != 0) + { + UInt32 curSize = (size < kBlockSize) ? (UInt32)size : kBlockSize; + UInt32 processedSizeLoc; + HRESULT res = stream->Read(data, curSize, &processedSizeLoc); + *processedSize += processedSizeLoc; + data = (void *)((Byte *)data + processedSizeLoc); + size -= processedSizeLoc; + RINOK(res); + if (processedSizeLoc == 0) + return S_OK; + } + return S_OK; +} + +HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size) +{ + size_t processedSize = size; + RINOK(ReadStream(stream, data, &processedSize)); + return (size == processedSize) ? S_OK : S_FALSE; +} + +HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size) +{ + size_t processedSize = size; + RINOK(ReadStream(stream, data, &processedSize)); + return (size == processedSize) ? S_OK : E_FAIL; +} + +HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size) +{ + while (size != 0) + { + UInt32 curSize = (size < kBlockSize) ? (UInt32)size : kBlockSize; + UInt32 processedSizeLoc; + HRESULT res = stream->Write(data, curSize, &processedSizeLoc); + data = (const void *)((const Byte *)data + processedSizeLoc); + size -= processedSizeLoc; + RINOK(res); + if (processedSizeLoc == 0) + return E_FAIL; + } + return S_OK; +} diff --git a/desmume/src/windows/7z/CPP/7zip/Common/StreamUtils.h b/desmume/src/windows/7z/CPP/7zip/Common/StreamUtils.h new file mode 100644 index 000000000..30535ab1b --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/StreamUtils.h @@ -0,0 +1,13 @@ +// StreamUtils.h + +#ifndef __STREAMUTILS_H +#define __STREAMUTILS_H + +#include "../IStream.h" + +HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *size); +HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size); +HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size); +HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size); + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Common/VirtThread.cpp b/desmume/src/windows/7z/CPP/7zip/Common/VirtThread.cpp new file mode 100644 index 000000000..75dc24c35 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/VirtThread.cpp @@ -0,0 +1,45 @@ +// VirtThread.cpp + +#include "StdAfx.h" + +#include "VirtThread.h" + +static THREAD_FUNC_DECL CoderThread(void *p) +{ + for (;;) + { + CVirtThread *t = (CVirtThread *)p; + t->StartEvent.Lock(); + if (t->ExitEvent) + return 0; + t->Execute(); + t->FinishedEvent.Set(); + } +} + +WRes CVirtThread::Create() +{ + RINOK(StartEvent.CreateIfNotCreated()); + RINOK(FinishedEvent.CreateIfNotCreated()); + StartEvent.Reset(); + FinishedEvent.Reset(); + ExitEvent = false; + if (Thread.IsCreated()) + return S_OK; + return Thread.Create(CoderThread, this); +} + +void CVirtThread::Start() +{ + ExitEvent = false; + StartEvent.Set(); +} + +CVirtThread::~CVirtThread() +{ + ExitEvent = true; + if (StartEvent.IsCreated()) + StartEvent.Set(); + Thread.Wait(); +} + diff --git a/desmume/src/windows/7z/CPP/7zip/Common/VirtThread.h b/desmume/src/windows/7z/CPP/7zip/Common/VirtThread.h new file mode 100644 index 000000000..bfc10dc4a --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Common/VirtThread.h @@ -0,0 +1,23 @@ +// VirtThread.h + +#ifndef __VIRTTHREAD_H +#define __VIRTTHREAD_H + +#include "../../Windows/Synchronization.h" +#include "../../Windows/Thread.h" + +struct CVirtThread +{ + NWindows::NSynchronization::CAutoResetEvent StartEvent; + NWindows::NSynchronization::CAutoResetEvent FinishedEvent; + NWindows::CThread Thread; + bool ExitEvent; + + ~CVirtThread(); + WRes Create(); + void Start(); + void WaitFinish() { FinishedEvent.Lock(); } + virtual void Execute() = 0; +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/BZip2Const.h b/desmume/src/windows/7z/CPP/7zip/Compress/BZip2Const.h new file mode 100644 index 000000000..fe0c53ff2 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/BZip2Const.h @@ -0,0 +1,54 @@ +// Compress/BZip2Const.h + +#ifndef __COMPRESS_BZIP2_CONST_H +#define __COMPRESS_BZIP2_CONST_H + +namespace NCompress { +namespace NBZip2 { + +const Byte kArSig0 = 'B'; +const Byte kArSig1 = 'Z'; +const Byte kArSig2 = 'h'; +const Byte kArSig3 = '0'; + +const Byte kFinSig0 = 0x17; +const Byte kFinSig1 = 0x72; +const Byte kFinSig2 = 0x45; +const Byte kFinSig3 = 0x38; +const Byte kFinSig4 = 0x50; +const Byte kFinSig5 = 0x90; + +const Byte kBlockSig0 = 0x31; +const Byte kBlockSig1 = 0x41; +const Byte kBlockSig2 = 0x59; +const Byte kBlockSig3 = 0x26; +const Byte kBlockSig4 = 0x53; +const Byte kBlockSig5 = 0x59; + +const int kNumOrigBits = 24; + +const int kNumTablesBits = 3; +const int kNumTablesMin = 2; +const int kNumTablesMax = 6; + +const int kNumLevelsBits = 5; + +const int kMaxHuffmanLen = 20; // Check it + +const int kMaxAlphaSize = 258; + +const int kGroupSize = 50; + +const int kBlockSizeMultMin = 1; +const int kBlockSizeMultMax = 9; +const UInt32 kBlockSizeStep = 100000; +const UInt32 kBlockSizeMax = kBlockSizeMultMax * kBlockSizeStep; + +const int kNumSelectorsBits = 15; +const UInt32 kNumSelectorsMax = (2 + (kBlockSizeMax / kGroupSize)); + +const int kRleModeRepSize = 4; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/BZip2Crc.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/BZip2Crc.cpp new file mode 100644 index 000000000..2a8277ca4 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/BZip2Crc.cpp @@ -0,0 +1,26 @@ +// BZip2Crc.cpp + +#include "StdAfx.h" + +#include "BZip2Crc.h" + +UInt32 CBZip2Crc::Table[256]; + +static const UInt32 kBZip2CrcPoly = 0x04c11db7; /* AUTODIN II, Ethernet, & FDDI */ + +void CBZip2Crc::InitTable() +{ + for (UInt32 i = 0; i < 256; i++) + { + UInt32 r = (i << 24); + for (int j = 8; j > 0; j--) + r = (r & 0x80000000) ? ((r << 1) ^ kBZip2CrcPoly) : (r << 1); + Table[i] = r; + } +} + +class CBZip2CrcTableInit +{ +public: + CBZip2CrcTableInit() { CBZip2Crc::InitTable(); } +} g_BZip2CrcTableInit; diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/BZip2Crc.h b/desmume/src/windows/7z/CPP/7zip/Compress/BZip2Crc.h new file mode 100644 index 000000000..ad1322fdd --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/BZip2Crc.h @@ -0,0 +1,31 @@ +// BZip2Crc.h + +#ifndef __BZIP2_CRC_H +#define __BZIP2_CRC_H + +#include "Common/Types.h" + +class CBZip2Crc +{ + UInt32 _value; + static UInt32 Table[256]; +public: + static void InitTable(); + CBZip2Crc(): _value(0xFFFFFFFF) {}; + void Init() { _value = 0xFFFFFFFF; } + void UpdateByte(Byte b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); } + void UpdateByte(unsigned int b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); } + UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; } +}; + +class CBZip2CombinedCrc +{ + UInt32 _value; +public: + CBZip2CombinedCrc(): _value(0){}; + void Init() { _value = 0; } + void Update(UInt32 v) { _value = ((_value << 1) | (_value >> 31)) ^ v; } + UInt32 GetDigest() const { return _value ; } +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/BZip2Decoder.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/BZip2Decoder.cpp new file mode 100644 index 000000000..b291be6f1 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/BZip2Decoder.cpp @@ -0,0 +1,791 @@ +// BZip2Decoder.cpp + +#include "StdAfx.h" + +extern "C" +{ +#include "../../../C/Alloc.h" +} + +#include "../../Common/Defs.h" + +#include "BZip2Crc.h" +#include "BZip2Decoder.h" +#include "Mtf8.h" + +namespace NCompress { +namespace NBZip2 { + +#define NO_INLINE MY_FAST_CALL + +const UInt32 kNumThreadsMax = 4; + +static const UInt32 kBufferSize = (1 << 17); + +static Int16 kRandNums[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 +}; + +bool CState::Alloc() +{ + if (Counters == 0) + Counters = (UInt32 *)BigAlloc((256 + kBlockSizeMax) * sizeof(UInt32)); + return (Counters != 0); +} + +void CState::Free() +{ + ::BigFree(Counters); + Counters = 0; +} + +UInt32 CDecoder::ReadBits(int numBits) { return m_InStream.ReadBits(numBits); } +Byte CDecoder::ReadByte() {return (Byte)ReadBits(8); } +bool CDecoder::ReadBit() { return ReadBits(1) != 0; } + +UInt32 CDecoder::ReadCrc() +{ + UInt32 crc = 0; + for (int i = 0; i < 4; i++) + { + crc <<= 8; + crc |= ReadByte(); + } + return crc; +} + +UInt32 NO_INLINE ReadBits(NBitm::CDecoder *m_InStream, int num) +{ + return m_InStream->ReadBits(num); +} + +UInt32 NO_INLINE ReadBit(NBitm::CDecoder *m_InStream) +{ + return m_InStream->ReadBits(1); +} + +static HRESULT NO_INLINE ReadBlock(NBitm::CDecoder *m_InStream, + UInt32 *CharCounters, UInt32 blockSizeMax, Byte *m_Selectors, CHuffmanDecoder *m_HuffmanDecoders, + UInt32 *blockSizeRes, UInt32 *origPtrRes, bool *randRes) +{ + *randRes = ReadBit(m_InStream) ? true : false; + *origPtrRes = ReadBits(m_InStream, kNumOrigBits); + + // in original code it compares OrigPtr to (UInt32)(10 + blockSizeMax)) : why ? + if (*origPtrRes >= blockSizeMax) + return S_FALSE; + + CMtf8Decoder mtf; + mtf.StartInit(); + + int numInUse = 0; + { + Byte inUse16[16]; + int i; + for (i = 0; i < 16; i++) + inUse16[i] = (Byte)ReadBit(m_InStream); + for (i = 0; i < 256; i++) + if (inUse16[i >> 4]) + { + if (ReadBit(m_InStream)) + mtf.Add(numInUse++, (Byte)i); + } + if (numInUse == 0) + return S_FALSE; + // mtf.Init(numInUse); + } + int alphaSize = numInUse + 2; + + int numTables = ReadBits(m_InStream, kNumTablesBits); + if (numTables < kNumTablesMin || numTables > kNumTablesMax) + return S_FALSE; + + UInt32 numSelectors = ReadBits(m_InStream, kNumSelectorsBits); + if (numSelectors < 1 || numSelectors > kNumSelectorsMax) + return S_FALSE; + + { + Byte mtfPos[kNumTablesMax]; + int t = 0; + do + mtfPos[t] = (Byte)t; + while(++t < numTables); + UInt32 i = 0; + do + { + int j = 0; + while (ReadBit(m_InStream)) + if (++j >= numTables) + return S_FALSE; + Byte tmp = mtfPos[j]; + for (;j > 0; j--) + mtfPos[j] = mtfPos[j - 1]; + m_Selectors[i] = mtfPos[0] = tmp; + } + while(++i < numSelectors); + } + + int t = 0; + do + { + Byte lens[kMaxAlphaSize]; + int len = (int)ReadBits(m_InStream, kNumLevelsBits); + int i; + for (i = 0; i < alphaSize; i++) + { + for (;;) + { + if (len < 1 || len > kMaxHuffmanLen) + return S_FALSE; + if (!ReadBit(m_InStream)) + break; + len += 1 - (int)(ReadBit(m_InStream) << 1); + } + lens[i] = (Byte)len; + } + for (; i < kMaxAlphaSize; i++) + lens[i] = 0; + if(!m_HuffmanDecoders[t].SetCodeLengths(lens)) + return S_FALSE; + } + while(++t < numTables); + + { + for (int i = 0; i < 256; i++) + CharCounters[i] = 0; + } + + UInt32 blockSize = 0; + { + UInt32 groupIndex = 0; + UInt32 groupSize = 0; + CHuffmanDecoder *huffmanDecoder = 0; + int runPower = 0; + UInt32 runCounter = 0; + + for (;;) + { + if (groupSize == 0) + { + if (groupIndex >= numSelectors) + return S_FALSE; + groupSize = kGroupSize; + huffmanDecoder = &m_HuffmanDecoders[m_Selectors[groupIndex++]]; + } + groupSize--; + + UInt32 nextSym = huffmanDecoder->DecodeSymbol(m_InStream); + + if (nextSym < 2) + { + runCounter += ((UInt32)(nextSym + 1) << runPower++); + if (blockSizeMax - blockSize < runCounter) + return S_FALSE; + continue; + } + if (runCounter != 0) + { + UInt32 b = (UInt32)mtf.GetHead(); + CharCounters[b] += runCounter; + do + CharCounters[256 + blockSize++] = b; + while(--runCounter != 0); + runPower = 0; + } + if (nextSym <= (UInt32)numInUse) + { + UInt32 b = (UInt32)mtf.GetAndMove((int)nextSym - 1); + if (blockSize >= blockSizeMax) + return S_FALSE; + CharCounters[b]++; + CharCounters[256 + blockSize++] = b; + } + else if (nextSym == (UInt32)numInUse + 1) + break; + else + return S_FALSE; + } + } + *blockSizeRes = blockSize; + return (*origPtrRes < blockSize) ? S_OK : S_FALSE; +} + +void NO_INLINE DecodeBlock1(UInt32 *charCounters, UInt32 blockSize) +{ + { + UInt32 sum = 0; + for (UInt32 i = 0; i < 256; i++) + { + sum += charCounters[i]; + charCounters[i] = sum - charCounters[i]; + } + } + + UInt32 *tt = charCounters + 256; + // Compute the T^(-1) vector + UInt32 i = 0; + do + tt[charCounters[tt[i] & 0xFF]++] |= (i << 8); + while(++i < blockSize); +} + +static UInt32 NO_INLINE DecodeBlock2(const UInt32 *tt, UInt32 blockSize, UInt32 OrigPtr, COutBuffer &m_OutStream) +{ + CBZip2Crc crc; + + // it's for speed optimization: prefetch & prevByte_init; + UInt32 tPos = tt[tt[OrigPtr] >> 8]; + unsigned int prevByte = (unsigned int)(tPos & 0xFF); + + int numReps = 0; + + do + { + unsigned int b = (unsigned int)(tPos & 0xFF); + tPos = tt[tPos >> 8]; + + if (numReps == kRleModeRepSize) + { + for (; b > 0; b--) + { + crc.UpdateByte(prevByte); + m_OutStream.WriteByte((Byte)prevByte); + } + numReps = 0; + continue; + } + if (b != prevByte) + numReps = 0; + numReps++; + prevByte = b; + crc.UpdateByte(b); + m_OutStream.WriteByte((Byte)b); + + /* + prevByte = b; + crc.UpdateByte(b); + m_OutStream.WriteByte((Byte)b); + for (; --blockSize != 0;) + { + b = (unsigned int)(tPos & 0xFF); + tPos = tt[tPos >> 8]; + crc.UpdateByte(b); + m_OutStream.WriteByte((Byte)b); + if (b != prevByte) + { + prevByte = b; + continue; + } + if (--blockSize == 0) + break; + + b = (unsigned int)(tPos & 0xFF); + tPos = tt[tPos >> 8]; + crc.UpdateByte(b); + m_OutStream.WriteByte((Byte)b); + if (b != prevByte) + { + prevByte = b; + continue; + } + if (--blockSize == 0) + break; + + b = (unsigned int)(tPos & 0xFF); + tPos = tt[tPos >> 8]; + crc.UpdateByte(b); + m_OutStream.WriteByte((Byte)b); + if (b != prevByte) + { + prevByte = b; + continue; + } + --blockSize; + break; + } + if (blockSize == 0) + break; + + b = (unsigned int)(tPos & 0xFF); + tPos = tt[tPos >> 8]; + + for (; b > 0; b--) + { + crc.UpdateByte(prevByte); + m_OutStream.WriteByte((Byte)prevByte); + } + */ + } + while(--blockSize != 0); + return crc.GetDigest(); +} + +static UInt32 NO_INLINE DecodeBlock2Rand(const UInt32 *tt, UInt32 blockSize, UInt32 OrigPtr, COutBuffer &m_OutStream) +{ + CBZip2Crc crc; + + UInt32 randIndex = 1; + UInt32 randToGo = kRandNums[0] - 2; + + int numReps = 0; + + // it's for speed optimization: prefetch & prevByte_init; + UInt32 tPos = tt[tt[OrigPtr] >> 8]; + unsigned int prevByte = (unsigned int)(tPos & 0xFF); + + do + { + unsigned int b = (unsigned int)(tPos & 0xFF); + tPos = tt[tPos >> 8]; + + { + if (randToGo == 0) + { + b ^= 1; + randToGo = kRandNums[randIndex++]; + randIndex &= 0x1FF; + } + randToGo--; + } + + if (numReps == kRleModeRepSize) + { + for (; b > 0; b--) + { + crc.UpdateByte(prevByte); + m_OutStream.WriteByte((Byte)prevByte); + } + numReps = 0; + continue; + } + if (b != prevByte) + numReps = 0; + numReps++; + prevByte = b; + crc.UpdateByte(b); + m_OutStream.WriteByte((Byte)b); + } + while(--blockSize != 0); + return crc.GetDigest(); +} + +#ifdef COMPRESS_BZIP2_MT + +CDecoder::CDecoder(): + m_States(0) +{ + m_NumThreadsPrev = 0; + NumThreads = 1; +} + +CDecoder::~CDecoder() +{ + Free(); +} + +#define RINOK_THREAD(x) { WRes __result_ = (x); if(__result_ != 0) return __result_; } + +HRESULT CDecoder::Create() +{ + RINOK_THREAD(CanProcessEvent.CreateIfNotCreated()); + RINOK_THREAD(CanStartWaitingEvent.CreateIfNotCreated()); + if (m_States != 0 && m_NumThreadsPrev == NumThreads) + return S_OK; + Free(); + MtMode = (NumThreads > 1); + m_NumThreadsPrev = NumThreads; + try + { + m_States = new CState[NumThreads]; + if (m_States == 0) + return E_OUTOFMEMORY; + } + catch(...) { return E_OUTOFMEMORY; } + for (UInt32 t = 0; t < NumThreads; t++) + { + CState &ti = m_States[t]; + ti.Decoder = this; + if (MtMode) + { + HRESULT res = ti.Create(); + if (res != S_OK) + { + NumThreads = t; + Free(); + return res; + } + } + } + return S_OK; +} + +void CDecoder::Free() +{ + if (!m_States) + return; + CloseThreads = true; + CanProcessEvent.Set(); + for (UInt32 t = 0; t < NumThreads; t++) + { + CState &s = m_States[t]; + if (MtMode) + s.Thread.Wait(); + s.Free(); + } + delete []m_States; + m_States = 0; +} +#endif + +HRESULT CDecoder::ReadSignatures(bool &wasFinished, UInt32 &crc) +{ + wasFinished = false; + Byte s[6]; + for (int i = 0; i < 6; i++) + s[i] = ReadByte(); + crc = ReadCrc(); + if (s[0] == kFinSig0) + { + if (s[1] != kFinSig1 || + s[2] != kFinSig2 || + s[3] != kFinSig3 || + s[4] != kFinSig4 || + s[5] != kFinSig5) + return S_FALSE; + + wasFinished = true; + return (crc == CombinedCrc.GetDigest()) ? S_OK : S_FALSE; + } + if (s[0] != kBlockSig0 || + s[1] != kBlockSig1 || + s[2] != kBlockSig2 || + s[3] != kBlockSig3 || + s[4] != kBlockSig4 || + s[5] != kBlockSig5) + return S_FALSE; + CombinedCrc.Update(crc); + return S_OK; +} + +HRESULT CDecoder::DecodeFile(bool &isBZ, ICompressProgressInfo *progress) +{ + #ifdef COMPRESS_BZIP2_MT + Progress = progress; + RINOK(Create()); + for (UInt32 t = 0; t < NumThreads; t++) + { + CState &s = m_States[t]; + if (!s.Alloc()) + return E_OUTOFMEMORY; + if (MtMode) + { + RINOK(s.StreamWasFinishedEvent.Reset()); + RINOK(s.WaitingWasStartedEvent.Reset()); + RINOK(s.CanWriteEvent.Reset()); + } + } + #else + if (!m_States[0].Alloc()) + return E_OUTOFMEMORY; + #endif + + isBZ = false; + Byte s[6]; + int i; + for (i = 0; i < 4; i++) + s[i] = ReadByte(); + if (s[0] != kArSig0 || + s[1] != kArSig1 || + s[2] != kArSig2 || + s[3] <= kArSig3 || + s[3] > kArSig3 + kBlockSizeMultMax) + return S_OK; + isBZ = true; + UInt32 dicSize = (UInt32)(s[3] - kArSig3) * kBlockSizeStep; + + CombinedCrc.Init(); + #ifdef COMPRESS_BZIP2_MT + if (MtMode) + { + NextBlockIndex = 0; + StreamWasFinished1 = StreamWasFinished2 = false; + CloseThreads = false; + CanStartWaitingEvent.Reset(); + m_States[0].CanWriteEvent.Set(); + BlockSizeMax = dicSize; + Result1 = Result2 = S_OK; + CanProcessEvent.Set(); + UInt32 t; + for (t = 0; t < NumThreads; t++) + m_States[t].StreamWasFinishedEvent.Lock(); + CanProcessEvent.Reset(); + CanStartWaitingEvent.Set(); + for (t = 0; t < NumThreads; t++) + m_States[t].WaitingWasStartedEvent.Lock(); + CanStartWaitingEvent.Reset(); + RINOK(Result2); + RINOK(Result1); + } + else + #endif + { + CState &state = m_States[0]; + for (;;) + { + if (progress) + { + UInt64 packSize = m_InStream.GetProcessedSize(); + UInt64 unpackSize = m_OutStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &unpackSize)); + } + bool wasFinished; + UInt32 crc; + RINOK(ReadSignatures(wasFinished, crc)); + if (wasFinished) + return S_OK; + + UInt32 blockSize, origPtr; + bool randMode; + RINOK(ReadBlock(&m_InStream, state.Counters, dicSize, + m_Selectors, m_HuffmanDecoders, + &blockSize, &origPtr, &randMode)); + DecodeBlock1(state.Counters, blockSize); + if ((randMode ? + DecodeBlock2Rand(state.Counters + 256, blockSize, origPtr, m_OutStream) : + DecodeBlock2(state.Counters + 256, blockSize, origPtr, m_OutStream)) != crc) + return S_FALSE; + } + } + return S_OK; +} + +HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) +{ + if (!m_InStream.Create(kBufferSize)) + return E_OUTOFMEMORY; + if (!m_OutStream.Create(kBufferSize)) + return E_OUTOFMEMORY; + + m_InStream.SetStream(inStream); + m_InStream.Init(); + + m_OutStream.SetStream(outStream); + m_OutStream.Init(); + + CDecoderFlusher flusher(this); + + bool isBZ; + RINOK(DecodeFile(isBZ, progress)); + return isBZ ? S_OK: S_FALSE; +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return E_FAIL; } +} + +STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) +{ + if (value == NULL) + return E_INVALIDARG; + *value = m_InStream.GetProcessedSize(); + return S_OK; +} + +#ifdef COMPRESS_BZIP2_MT + +static THREAD_FUNC_DECL MFThread(void *p) { ((CState *)p)->ThreadFunc(); return 0; } + +HRESULT CState::Create() +{ + RINOK_THREAD(StreamWasFinishedEvent.CreateIfNotCreated()); + RINOK_THREAD(WaitingWasStartedEvent.CreateIfNotCreated()); + RINOK_THREAD(CanWriteEvent.CreateIfNotCreated()); + RINOK_THREAD(Thread.Create(MFThread, this)); + return S_OK; +} + +void CState::FinishStream() +{ + Decoder->StreamWasFinished1 = true; + StreamWasFinishedEvent.Set(); + Decoder->CS.Leave(); + Decoder->CanStartWaitingEvent.Lock(); + WaitingWasStartedEvent.Set(); +} + +void CState::ThreadFunc() +{ + for (;;) + { + Decoder->CanProcessEvent.Lock(); + Decoder->CS.Enter(); + if (Decoder->CloseThreads) + { + Decoder->CS.Leave(); + return; + } + if (Decoder->StreamWasFinished1) + { + FinishStream(); + continue; + } + HRESULT res = S_OK; + + UInt32 blockIndex = Decoder->NextBlockIndex; + UInt32 nextBlockIndex = blockIndex + 1; + if (nextBlockIndex == Decoder->NumThreads) + nextBlockIndex = 0; + Decoder->NextBlockIndex = nextBlockIndex; + UInt32 crc; + UInt64 packSize; + UInt32 blockSize = 0, origPtr = 0; + bool randMode = false; + + try + { + bool wasFinished; + res = Decoder->ReadSignatures(wasFinished, crc); + if (res != S_OK) + { + Decoder->Result1 = res; + FinishStream(); + continue; + } + if (wasFinished) + { + Decoder->Result1 = res; + FinishStream(); + continue; + } + + res = ReadBlock(&Decoder->m_InStream, Counters, Decoder->BlockSizeMax, + Decoder->m_Selectors, Decoder->m_HuffmanDecoders, + &blockSize, &origPtr, &randMode); + if (res != S_OK) + { + Decoder->Result1 = res; + FinishStream(); + continue; + } + packSize = Decoder->m_InStream.GetProcessedSize(); + } + catch(const CInBufferException &e) { res = e.ErrorCode; if (res != S_OK) res = E_FAIL; } + catch(...) { res = E_FAIL; } + if (res != S_OK) + { + Decoder->Result1 = res; + FinishStream(); + continue; + } + + Decoder->CS.Leave(); + + DecodeBlock1(Counters, blockSize); + + bool needFinish = true; + try + { + Decoder->m_States[blockIndex].CanWriteEvent.Lock(); + needFinish = Decoder->StreamWasFinished2; + if (!needFinish) + { + if ((randMode ? + DecodeBlock2Rand(Counters + 256, blockSize, origPtr, Decoder->m_OutStream) : + DecodeBlock2(Counters + 256, blockSize, origPtr, Decoder->m_OutStream)) == crc) + { + if (Decoder->Progress) + { + UInt64 unpackSize = Decoder->m_OutStream.GetProcessedSize(); + res = Decoder->Progress->SetRatioInfo(&packSize, &unpackSize); + } + } + else + res = S_FALSE; + } + } + catch(const COutBufferException &e) { res = e.ErrorCode; if (res != S_OK) res = E_FAIL; } + catch(...) { res = E_FAIL; } + if (res != S_OK) + { + Decoder->Result2 = res; + Decoder->StreamWasFinished2 = true; + } + Decoder->m_States[nextBlockIndex].CanWriteEvent.Set(); + if (res != S_OK || needFinish) + { + StreamWasFinishedEvent.Set(); + Decoder->CanStartWaitingEvent.Lock(); + WaitingWasStartedEvent.Set(); + } + } +} + +STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads) +{ + NumThreads = numThreads; + if (NumThreads < 1) + NumThreads = 1; + if (NumThreads > kNumThreadsMax) + NumThreads = kNumThreadsMax; + return S_OK; +} +#endif + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/BZip2Decoder.h b/desmume/src/windows/7z/CPP/7zip/Compress/BZip2Decoder.h new file mode 100644 index 000000000..394860071 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/BZip2Decoder.h @@ -0,0 +1,159 @@ +// Compress/BZip2Decoder.h + +#ifndef __COMPRESS_BZIP2_DECODER_H +#define __COMPRESS_BZIP2_DECODER_H + +#include "../../Common/MyCom.h" + +#ifdef COMPRESS_BZIP2_MT +#include "../../Windows/Synchronization.h" +#include "../../Windows/Thread.h" +#endif + +#include "../ICoder.h" + +#include "../Common/InBuffer.h" +#include "../Common/OutBuffer.h" + +#include "BitmDecoder.h" +#include "BZip2Const.h" +#include "BZip2Crc.h" +#include "HuffmanDecoder.h" + +namespace NCompress { +namespace NBZip2 { + +typedef NCompress::NHuffman::CDecoder CHuffmanDecoder; + +class CDecoder; + +struct CState +{ + UInt32 *Counters; + + #ifdef COMPRESS_BZIP2_MT + + CDecoder *Decoder; + NWindows::CThread Thread; + bool m_OptimizeNumTables; + + NWindows::NSynchronization::CAutoResetEvent StreamWasFinishedEvent; + NWindows::NSynchronization::CAutoResetEvent WaitingWasStartedEvent; + + // it's not member of this thread. We just need one event per thread + NWindows::NSynchronization::CAutoResetEvent CanWriteEvent; + + Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size. + + HRESULT Create(); + void FinishStream(); + void ThreadFunc(); + + #endif + + CState(): Counters(0) {} + ~CState() { Free(); } + bool Alloc(); + void Free(); +}; + +class CDecoder : + public ICompressCoder, + #ifdef COMPRESS_BZIP2_MT + public ICompressSetCoderMt, + #endif + public ICompressGetInStreamProcessedSize, + public CMyUnknownImp +{ +public: + COutBuffer m_OutStream; + Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size. + NBitm::CDecoder m_InStream; + Byte m_Selectors[kNumSelectorsMax]; + CHuffmanDecoder m_HuffmanDecoders[kNumTablesMax]; +private: + + UInt32 m_NumThreadsPrev; + + UInt32 ReadBits(int numBits); + Byte ReadByte(); + bool ReadBit(); + UInt32 ReadCrc(); + HRESULT PrepareBlock(CState &state); + HRESULT DecodeFile(bool &isBZ, ICompressProgressInfo *progress); + HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + class CDecoderFlusher + { + CDecoder *_decoder; + public: + bool NeedFlush; + CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {} + ~CDecoderFlusher() + { + if (NeedFlush) + _decoder->Flush(); + _decoder->ReleaseStreams(); + } + }; + +public: + CBZip2CombinedCrc CombinedCrc; + + #ifdef COMPRESS_BZIP2_MT + ICompressProgressInfo *Progress; + CState *m_States; + + NWindows::NSynchronization::CManualResetEvent CanProcessEvent; + NWindows::NSynchronization::CCriticalSection CS; + UInt32 NumThreads; + bool MtMode; + UInt32 NextBlockIndex; + bool CloseThreads; + bool StreamWasFinished1; + bool StreamWasFinished2; + NWindows::NSynchronization::CManualResetEvent CanStartWaitingEvent; + + HRESULT Result1; + HRESULT Result2; + + UInt32 BlockSizeMax; + CDecoder(); + ~CDecoder(); + HRESULT Create(); + void Free(); + + #else + CState m_States[1]; + #endif + + HRESULT ReadSignatures(bool &wasFinished, UInt32 &crc); + + + HRESULT Flush() { return m_OutStream.Flush(); } + void ReleaseStreams() + { + m_InStream.ReleaseStream(); + m_OutStream.ReleaseStream(); + } + + #ifdef COMPRESS_BZIP2_MT + MY_UNKNOWN_IMP2(ICompressSetCoderMt, ICompressGetInStreamProcessedSize) + #else + MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize) + #endif + + + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); + + #ifdef COMPRESS_BZIP2_MT + STDMETHOD(SetNumberOfThreads)(UInt32 numThreads); + #endif +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/BZip2Register.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/BZip2Register.cpp new file mode 100644 index 000000000..f10e594c6 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/BZip2Register.cpp @@ -0,0 +1,20 @@ +// BZip2Register.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "BZip2Decoder.h" + +static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::NBZip2::CDecoder); } +#if !defined(EXTRACT_ONLY) && !defined(BZIP2_EXTRACT_ONLY) +#include "BZip2Encoder.h" +static void *CreateCodecOut() { return (void *)(ICompressCoder *)(new NCompress::NBZip2::CEncoder); } +#else +#define CreateCodecOut 0 +#endif + +static CCodecInfo g_CodecInfo = + { CreateCodec, CreateCodecOut, 0x040202, L"BZip2", 1, false }; + +REGISTER_CODEC(BZip2) diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/Bcj2Coder.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/Bcj2Coder.cpp new file mode 100644 index 000000000..e52095a77 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/Bcj2Coder.cpp @@ -0,0 +1,393 @@ +// Bcj2Coder.cpp + +#include "StdAfx.h" + +extern "C" +{ +#include "../../../C/Alloc.h" +} + +#include "Bcj2Coder.h" + +namespace NCompress { +namespace NBcj2 { + +inline bool IsJcc(Byte b0, Byte b1) { return (b0 == 0x0F && (b1 & 0xF0) == 0x80); } +inline bool IsJ(Byte b0, Byte b1) { return ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)); } +inline unsigned GetIndex(Byte b0, Byte b1) { return ((b1 == 0xE8) ? b0 : ((b1 == 0xE9) ? 256 : 257)); } + +#ifndef EXTRACT_ONLY + +static const int kBufferSize = 1 << 17; + +static bool inline Test86MSByte(Byte b) +{ + return (b == 0 || b == 0xFF); +} + +bool CEncoder::Create() +{ + if (!_mainStream.Create(1 << 16)) + return false; + if (!_callStream.Create(1 << 20)) + return false; + if (!_jumpStream.Create(1 << 20)) + return false; + if (!_rangeEncoder.Create(1 << 20)) + return false; + if (_buffer == 0) + { + _buffer = (Byte *)MidAlloc(kBufferSize); + if (_buffer == 0) + return false; + } + return true; +} + +CEncoder::~CEncoder() +{ + ::MidFree(_buffer); +} + +HRESULT CEncoder::Flush() +{ + RINOK(_mainStream.Flush()); + RINOK(_callStream.Flush()); + RINOK(_jumpStream.Flush()); + _rangeEncoder.FlushData(); + return _rangeEncoder.FlushStream(); +} + +const UInt32 kDefaultLimit = (1 << 24); + +HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 ** /* outSizes */, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + if (numInStreams != 1 || numOutStreams != 4) + return E_INVALIDARG; + + if (!Create()) + return E_OUTOFMEMORY; + + bool sizeIsDefined = false; + UInt64 inSize = 0; + if (inSizes != NULL) + if (inSizes[0] != NULL) + { + inSize = *inSizes[0]; + if (inSize <= kDefaultLimit) + sizeIsDefined = true; + } + + ISequentialInStream *inStream = inStreams[0]; + + _mainStream.SetStream(outStreams[0]); + _mainStream.Init(); + _callStream.SetStream(outStreams[1]); + _callStream.Init(); + _jumpStream.SetStream(outStreams[2]); + _jumpStream.Init(); + _rangeEncoder.SetStream(outStreams[3]); + _rangeEncoder.Init(); + for (int i = 0; i < 256 + 2; i++) + _statusEncoder[i].Init(); + CCoderReleaser releaser(this); + + CMyComPtr getSubStreamSize; + { + inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize); + } + + UInt32 nowPos = 0; + UInt64 nowPos64 = 0; + UInt32 bufferPos = 0; + + Byte prevByte = 0; + + UInt64 subStreamIndex = 0; + UInt64 subStreamStartPos = 0; + UInt64 subStreamEndPos = 0; + + for (;;) + { + UInt32 processedSize = 0; + for (;;) + { + UInt32 size = kBufferSize - (bufferPos + processedSize); + UInt32 processedSizeLoc; + if (size == 0) + break; + RINOK(inStream->Read(_buffer + bufferPos + processedSize, size, &processedSizeLoc)); + if (processedSizeLoc == 0) + break; + processedSize += processedSizeLoc; + } + UInt32 endPos = bufferPos + processedSize; + + if (endPos < 5) + { + // change it + for (bufferPos = 0; bufferPos < endPos; bufferPos++) + { + Byte b = _buffer[bufferPos]; + _mainStream.WriteByte(b); + UInt32 index; + if (b == 0xE8) + index = prevByte; + else if (b == 0xE9) + index = 256; + else if (IsJcc(prevByte, b)) + index = 257; + else + { + prevByte = b; + continue; + } + _statusEncoder[index].Encode(&_rangeEncoder, 0); + prevByte = b; + } + return Flush(); + } + + bufferPos = 0; + + UInt32 limit = endPos - 5; + while(bufferPos <= limit) + { + Byte b = _buffer[bufferPos]; + _mainStream.WriteByte(b); + if (!IsJ(prevByte, b)) + { + bufferPos++; + prevByte = b; + continue; + } + Byte nextByte = _buffer[bufferPos + 4]; + UInt32 src = + (UInt32(nextByte) << 24) | + (UInt32(_buffer[bufferPos + 3]) << 16) | + (UInt32(_buffer[bufferPos + 2]) << 8) | + (_buffer[bufferPos + 1]); + UInt32 dest = (nowPos + bufferPos + 5) + src; + // if (Test86MSByte(nextByte)) + bool convert; + if (getSubStreamSize != NULL) + { + UInt64 currentPos = (nowPos64 + bufferPos); + while (subStreamEndPos < currentPos) + { + UInt64 subStreamSize; + HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize); + if (result == S_OK) + { + subStreamStartPos = subStreamEndPos; + subStreamEndPos += subStreamSize; + subStreamIndex++; + } + else if (result == S_FALSE || result == E_NOTIMPL) + { + getSubStreamSize.Release(); + subStreamStartPos = 0; + subStreamEndPos = subStreamStartPos - 1; + } + else + return result; + } + if (getSubStreamSize == NULL) + { + if (sizeIsDefined) + convert = (dest < inSize); + else + convert = Test86MSByte(nextByte); + } + else if (subStreamEndPos - subStreamStartPos > kDefaultLimit) + convert = Test86MSByte(nextByte); + else + { + UInt64 dest64 = (currentPos + 5) + Int64(Int32(src)); + convert = (dest64 >= subStreamStartPos && dest64 < subStreamEndPos); + } + } + else if (sizeIsDefined) + convert = (dest < inSize); + else + convert = Test86MSByte(nextByte); + unsigned index = GetIndex(prevByte, b); + if (convert) + { + _statusEncoder[index].Encode(&_rangeEncoder, 1); + bufferPos += 5; + COutBuffer &s = (b == 0xE8) ? _callStream : _jumpStream; + for (int i = 24; i >= 0; i -= 8) + s.WriteByte((Byte)(dest >> i)); + prevByte = nextByte; + } + else + { + _statusEncoder[index].Encode(&_rangeEncoder, 0); + bufferPos++; + prevByte = b; + } + } + nowPos += bufferPos; + nowPos64 += bufferPos; + + if (progress != NULL) + { + /* + const UInt64 compressedSize = + _mainStream.GetProcessedSize() + + _callStream.GetProcessedSize() + + _jumpStream.GetProcessedSize() + + _rangeEncoder.GetProcessedSize(); + */ + RINOK(progress->SetRatioInfo(&nowPos64, NULL)); + } + + UInt32 i = 0; + while(bufferPos < endPos) + _buffer[i++] = _buffer[bufferPos++]; + bufferPos = i; + } +} + +STDMETHODIMP CEncoder::Code(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + try + { + return CodeReal(inStreams, inSizes, numInStreams, + outStreams, outSizes,numOutStreams, progress); + } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +#endif + +HRESULT CDecoder::CodeReal(ISequentialInStream **inStreams, + const UInt64 ** /* inSizes */, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 ** /* outSizes */, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + if (numInStreams != 4 || numOutStreams != 1) + return E_INVALIDARG; + + if (!_mainInStream.Create(1 << 16)) + return E_OUTOFMEMORY; + if (!_callStream.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_jumpStream.Create(1 << 16)) + return E_OUTOFMEMORY; + if (!_rangeDecoder.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_outStream.Create(1 << 16)) + return E_OUTOFMEMORY; + + _mainInStream.SetStream(inStreams[0]); + _callStream.SetStream(inStreams[1]); + _jumpStream.SetStream(inStreams[2]); + _rangeDecoder.SetStream(inStreams[3]); + _outStream.SetStream(outStreams[0]); + + _mainInStream.Init(); + _callStream.Init(); + _jumpStream.Init(); + _rangeDecoder.Init(); + _outStream.Init(); + + for (int i = 0; i < 256 + 2; i++) + _statusDecoder[i].Init(); + + CCoderReleaser releaser(this); + + Byte prevByte = 0; + UInt32 processedBytes = 0; + for (;;) + { + if (processedBytes >= (1 << 20) && progress != NULL) + { + /* + const UInt64 compressedSize = + _mainInStream.GetProcessedSize() + + _callStream.GetProcessedSize() + + _jumpStream.GetProcessedSize() + + _rangeDecoder.GetProcessedSize(); + */ + const UInt64 nowPos64 = _outStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(NULL, &nowPos64)); + processedBytes = 0; + } + UInt32 i; + Byte b = 0; + const UInt32 kBurstSize = (1 << 18); + for (i = 0; i < kBurstSize; i++) + { + if (!_mainInStream.ReadByte(b)) + return Flush(); + _outStream.WriteByte(b); + if (IsJ(prevByte, b)) + break; + prevByte = b; + } + processedBytes += i; + if (i == kBurstSize) + continue; + unsigned index = GetIndex(prevByte, b); + if (_statusDecoder[index].Decode(&_rangeDecoder) == 1) + { + UInt32 src = 0; + CInBuffer &s = (b == 0xE8) ? _callStream : _jumpStream; + for (int i = 0; i < 4; i++) + { + Byte b0; + if(!s.ReadByte(b0)) + return S_FALSE; + src <<= 8; + src |= ((UInt32)b0); + } + UInt32 dest = src - (UInt32(_outStream.GetProcessedSize()) + 4) ; + _outStream.WriteByte((Byte)(dest)); + _outStream.WriteByte((Byte)(dest >> 8)); + _outStream.WriteByte((Byte)(dest >> 16)); + _outStream.WriteByte((Byte)(dest >> 24)); + prevByte = (Byte)(dest >> 24); + processedBytes += 4; + } + else + prevByte = b; + } +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + try + { + return CodeReal(inStreams, inSizes, numInStreams, + outStreams, outSizes,numOutStreams, progress); + } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/Bcj2Coder.h b/desmume/src/windows/7z/CPP/7zip/Compress/Bcj2Coder.h new file mode 100644 index 000000000..fcbc2a411 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/Bcj2Coder.h @@ -0,0 +1,125 @@ +// Bcj2Coder.h + +#ifndef __COMPRESS_BCJ2_CODER_H +#define __COMPRESS_BCJ2_CODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "RangeCoderBit.h" + +namespace NCompress { +namespace NBcj2 { + +const int kNumMoveBits = 5; + +#ifndef EXTRACT_ONLY + +class CEncoder: + public ICompressCoder2, + public CMyUnknownImp +{ + Byte *_buffer; +public: + CEncoder(): _buffer(0) {}; + ~CEncoder(); + bool Create(); + + COutBuffer _mainStream; + COutBuffer _callStream; + COutBuffer _jumpStream; + NCompress::NRangeCoder::CEncoder _rangeEncoder; + NCompress::NRangeCoder::CBitEncoder _statusEncoder[256 + 2]; + + HRESULT Flush(); + void ReleaseStreams() + { + _mainStream.ReleaseStream(); + _callStream.ReleaseStream(); + _jumpStream.ReleaseStream(); + _rangeEncoder.ReleaseStream(); + } + + class CCoderReleaser + { + CEncoder *_coder; + public: + CCoderReleaser(CEncoder *coder): _coder(coder) {} + ~CCoderReleaser() { _coder->ReleaseStreams(); } + }; + +public: + + MY_UNKNOWN_IMP + + HRESULT CodeReal(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress); + STDMETHOD(Code)(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress); +}; + +#endif + +class CDecoder: + public ICompressCoder2, + public CMyUnknownImp +{ +public: + CInBuffer _mainInStream; + CInBuffer _callStream; + CInBuffer _jumpStream; + NCompress::NRangeCoder::CDecoder _rangeDecoder; + NCompress::NRangeCoder::CBitDecoder _statusDecoder[256 + 2]; + + COutBuffer _outStream; + + void ReleaseStreams() + { + _mainInStream.ReleaseStream(); + _callStream.ReleaseStream(); + _jumpStream.ReleaseStream(); + _rangeDecoder.ReleaseStream(); + _outStream.ReleaseStream(); + } + + HRESULT Flush() { return _outStream.Flush(); } + class CCoderReleaser + { + CDecoder *_coder; + public: + CCoderReleaser(CDecoder *coder): _coder(coder) {} + ~CCoderReleaser() { _coder->ReleaseStreams(); } + }; + +public: + MY_UNKNOWN_IMP + HRESULT CodeReal(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress); + STDMETHOD(Code)(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress); +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/Bcj2Register.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/Bcj2Register.cpp new file mode 100644 index 000000000..b063f3f69 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/Bcj2Register.cpp @@ -0,0 +1,19 @@ +// Bcj2Register.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "Bcj2Coder.h" + +static void *CreateCodec() { return (void *)(ICompressCoder2 *)(new NCompress::NBcj2::CDecoder()); } +#ifndef EXTRACT_ONLY +static void *CreateCodecOut() { return (void *)(ICompressCoder2 *)(new NCompress::NBcj2::CEncoder()); } +#else +#define CreateCodecOut 0 +#endif + +static CCodecInfo g_CodecInfo = + { CreateCodec, CreateCodecOut, 0x0303011B, L"BCJ2", 4, false }; + +REGISTER_CODEC(BCJ2) diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/BcjCoder.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/BcjCoder.cpp new file mode 100644 index 000000000..108c573d5 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/BcjCoder.cpp @@ -0,0 +1,15 @@ +// BcjCoder.cpp + +#include "StdAfx.h" + +#include "BcjCoder.h" + +UInt32 CBCJ_x86_Encoder::SubFilter(Byte *data, UInt32 size) +{ + return (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, 1); +} + +UInt32 CBCJ_x86_Decoder::SubFilter(Byte *data, UInt32 size) +{ + return (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, 0); +} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/BcjCoder.h b/desmume/src/windows/7z/CPP/7zip/Compress/BcjCoder.h new file mode 100644 index 000000000..3389b2092 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/BcjCoder.h @@ -0,0 +1,22 @@ +// BcjCoder.h + +#ifndef __COMPRESS_BCJ_CODER_H +#define __COMPRESS_BCJ_CODER_H + +extern "C" +{ +#include "../../../C/Bra.h" +} + +#include "BranchCoder.h" + +struct CBranch86 +{ + UInt32 _prevMask; + void x86Init() { x86_Convert_Init(_prevMask); } +}; + +MyClassB(BCJ_x86, 0x01, 3, CBranch86 , + virtual void SubInit() { x86Init(); }) + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/BcjRegister.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/BcjRegister.cpp new file mode 100644 index 000000000..09e53c655 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/BcjRegister.cpp @@ -0,0 +1,19 @@ +// BcjRegister.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "BcjCoder.h" + +static void *CreateCodec() { return (void *)(ICompressFilter *)(new CBCJ_x86_Decoder()); } +#ifndef EXTRACT_ONLY +static void *CreateCodecOut() { return (void *)(ICompressFilter *)(new CBCJ_x86_Encoder()); } +#else +#define CreateCodecOut 0 +#endif + +static CCodecInfo g_CodecInfo = + { CreateCodec, CreateCodecOut, 0x03030103, L"BCJ", 1, true }; + +REGISTER_CODEC(BCJ) diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/BitlDecoder.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/BitlDecoder.cpp new file mode 100644 index 000000000..6022e8bf5 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/BitlDecoder.cpp @@ -0,0 +1,24 @@ +// BitlDecoder.cpp + +#include "StdAfx.h" + +#include "BitlDecoder.h" + +namespace NBitl { + +Byte kInvertTable[256]; + +struct CInverterTableInitializer +{ + CInverterTableInitializer() + { + for (int i = 0; i < 256; i++) + { + int x = ((i & 0x55) << 1) | ((i & 0xAA) >> 1); + x = ((x & 0x33) << 2) | ((x & 0xCC) >> 2); + kInvertTable[i] = (Byte)(((x & 0x0F) << 4) | ((x & 0xF0) >> 4)); + } + } +} g_InverterTableInitializer; + +} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/BitlDecoder.h b/desmume/src/windows/7z/CPP/7zip/Compress/BitlDecoder.h new file mode 100644 index 000000000..f2e115d48 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/BitlDecoder.h @@ -0,0 +1,125 @@ +// BitlDecoder.h -- the Least Significant Bit of byte is First + +#ifndef __BITL_DECODER_H +#define __BITL_DECODER_H + +#include "../IStream.h" + +namespace NBitl { + +const int kNumBigValueBits = 8 * 4; + +const int kNumValueBytes = 3; +const int kNumValueBits = 8 * kNumValueBytes; + +const UInt32 kMask = (1 << kNumValueBits) - 1; + +extern Byte kInvertTable[256]; + +template +class CBaseDecoder +{ +protected: + int m_BitPos; + UInt32 m_Value; + TInByte m_Stream; +public: + UInt32 NumExtraBytes; + bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } + void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream); } + void ReleaseStream() { m_Stream.ReleaseStream(); } + void Init() + { + m_Stream.Init(); + m_BitPos = kNumBigValueBits; + m_Value = 0; + NumExtraBytes = 0; + } + UInt64 GetProcessedSize() const + { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; } + UInt64 GetProcessedBitsSize() const + { return (m_Stream.GetProcessedSize() << 3) - (kNumBigValueBits - m_BitPos); } + int GetBitPosition() const { return (m_BitPos & 7); } + + void Normalize() + { + for (;m_BitPos >= 8; m_BitPos -= 8) + { + Byte b = 0; + if (!m_Stream.ReadByte(b)) + { + b = 0xFF; // check it + NumExtraBytes++; + } + m_Value = (b << (kNumBigValueBits - m_BitPos)) | m_Value; + } + } + + UInt32 ReadBits(int numBits) + { + Normalize(); + UInt32 res = m_Value & ((1 << numBits) - 1); + m_BitPos += numBits; + m_Value >>= numBits; + return res; + } + + bool ExtraBitsWereRead() const + { + if (NumExtraBytes == 0) + return false; + return ((UInt32)(kNumBigValueBits - m_BitPos) < (NumExtraBytes << 3)); + } +}; + +template +class CDecoder: public CBaseDecoder +{ + UInt32 m_NormalValue; + +public: + void Init() + { + CBaseDecoder::Init(); + m_NormalValue = 0; + } + + void Normalize() + { + for (; this->m_BitPos >= 8; this->m_BitPos -= 8) + { + Byte b = 0; + if (!this->m_Stream.ReadByte(b)) + { + b = 0xFF; // check it + this->NumExtraBytes++; + } + m_NormalValue = (b << (kNumBigValueBits - this->m_BitPos)) | m_NormalValue; + this->m_Value = (this->m_Value << 8) | kInvertTable[b]; + } + } + + UInt32 GetValue(int numBits) + { + Normalize(); + return ((this->m_Value >> (8 - this->m_BitPos)) & kMask) >> (kNumValueBits - numBits); + } + + void MovePos(int numBits) + { + this->m_BitPos += numBits; + m_NormalValue >>= numBits; + } + + UInt32 ReadBits(int numBits) + { + Normalize(); + UInt32 res = m_NormalValue & ( (1 << numBits) - 1); + MovePos(numBits); + return res; + } +}; + +} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/BitmDecoder.h b/desmume/src/windows/7z/CPP/7zip/Compress/BitmDecoder.h new file mode 100644 index 000000000..f58ec29e5 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/BitmDecoder.h @@ -0,0 +1,66 @@ +// BitmDecoder.h -- the Most Significant Bit of byte is First + +#ifndef __BITM_DECODER_H +#define __BITM_DECODER_H + +#include "../IStream.h" + +namespace NBitm { + +const int kNumBigValueBits = 8 * 4; +const int kNumValueBytes = 3; +const int kNumValueBits = 8 * kNumValueBytes; + +const UInt32 kMask = (1 << kNumValueBits) - 1; + +template +class CDecoder +{ + UInt32 m_BitPos; + UInt32 m_Value; +public: + TInByte m_Stream; + bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } + void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);} + void ReleaseStream() { m_Stream.ReleaseStream();} + + void Init() + { + m_Stream.Init(); + m_BitPos = kNumBigValueBits; + Normalize(); + } + + UInt64 GetProcessedSize() const + { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; } + UInt32 GetBitPosition() const { return (m_BitPos & 7); } + + void Normalize() + { + for (;m_BitPos >= 8; m_BitPos -= 8) + m_Value = (m_Value << 8) | m_Stream.ReadByte(); + } + + UInt32 GetValue(UInt32 numBits) const + { + // return (m_Value << m_BitPos) >> (kNumBigValueBits - numBits); + return ((m_Value >> (8 - m_BitPos)) & kMask) >> (kNumValueBits - numBits); + } + + void MovePos(UInt32 numBits) + { + m_BitPos += numBits; + Normalize(); + } + + UInt32 ReadBits(UInt32 numBits) + { + UInt32 res = GetValue(numBits); + MovePos(numBits); + return res; + } +}; + +} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/BranchCoder.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/BranchCoder.cpp new file mode 100644 index 000000000..6cacc66ac --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/BranchCoder.cpp @@ -0,0 +1,19 @@ +// BranchCoder.cpp + +#include "StdAfx.h" + +#include "BranchCoder.h" + +STDMETHODIMP CBranchConverter::Init() +{ + _bufferPos = 0; + SubInit(); + return S_OK; +} + +STDMETHODIMP_(UInt32) CBranchConverter::Filter(Byte *data, UInt32 size) +{ + UInt32 processedSize = SubFilter(data, size); + _bufferPos += processedSize; + return processedSize; +} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/BranchCoder.h b/desmume/src/windows/7z/CPP/7zip/Compress/BranchCoder.h new file mode 100644 index 000000000..473286af3 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/BranchCoder.h @@ -0,0 +1,44 @@ +// BranchCoder.h + +#ifndef __COMPRESS_BRANCH_CODER_H +#define __COMPRESS_BRANCH_CODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +class CBranchConverter: + public ICompressFilter, + public CMyUnknownImp +{ +protected: + UInt32 _bufferPos; + virtual void SubInit() {} + virtual UInt32 SubFilter(Byte *data, UInt32 size) = 0; +public: + MY_UNKNOWN_IMP; + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); +}; + +#define MyClassEncoderA(Name) class C ## Name: public CBranchConverter \ + { public: UInt32 SubFilter(Byte *data, UInt32 size); }; + +#define MyClassDecoderA(Name) class C ## Name: public CBranchConverter \ + { public: UInt32 SubFilter(Byte *data, UInt32 size); }; + +#define MyClassEncoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \ + { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT}; + +#define MyClassDecoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \ + { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT}; + +#define MyClassA(Name, id, subId) \ +MyClassEncoderA(Name ## _Encoder) \ +MyClassDecoderA(Name ## _Decoder) + +#define MyClassB(Name, id, subId, ADD_ITEMS, ADD_INIT) \ +MyClassEncoderB(Name ## _Encoder, ADD_ITEMS, ADD_INIT) \ +MyClassDecoderB(Name ## _Decoder, ADD_ITEMS, ADD_INIT) + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/BranchMisc.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/BranchMisc.cpp new file mode 100644 index 000000000..238dbe311 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/BranchMisc.cpp @@ -0,0 +1,40 @@ +// BranchMisc.cpp + +#include "StdAfx.h" + +extern "C" +{ +#include "../../../C/Bra.h" +} + +#include "BranchMisc.h" + +UInt32 CBC_ARM_Encoder::SubFilter(Byte *data, UInt32 size) + { return (UInt32)::ARM_Convert(data, size, _bufferPos, 1); } + +UInt32 CBC_ARM_Decoder::SubFilter(Byte *data, UInt32 size) + { return (UInt32)::ARM_Convert(data, size, _bufferPos, 0); } + +UInt32 CBC_ARMT_Encoder::SubFilter(Byte *data, UInt32 size) + { return (UInt32)::ARMT_Convert(data, size, _bufferPos, 1); } + +UInt32 CBC_ARMT_Decoder::SubFilter(Byte *data, UInt32 size) + { return (UInt32)::ARMT_Convert(data, size, _bufferPos, 0); } + +UInt32 CBC_PPC_Encoder::SubFilter(Byte *data, UInt32 size) + { return (UInt32)::PPC_Convert(data, size, _bufferPos, 1); } + +UInt32 CBC_PPC_Decoder::SubFilter(Byte *data, UInt32 size) + { return (UInt32)::PPC_Convert(data, size, _bufferPos, 0); } + +UInt32 CBC_SPARC_Encoder::SubFilter(Byte *data, UInt32 size) + { return (UInt32)::SPARC_Convert(data, size, _bufferPos, 1); } + +UInt32 CBC_SPARC_Decoder::SubFilter(Byte *data, UInt32 size) + { return (UInt32)::SPARC_Convert(data, size, _bufferPos, 0); } + +UInt32 CBC_IA64_Encoder::SubFilter(Byte *data, UInt32 size) + { return (UInt32)::IA64_Convert(data, size, _bufferPos, 1); } + +UInt32 CBC_IA64_Decoder::SubFilter(Byte *data, UInt32 size) + { return (UInt32)::IA64_Convert(data, size, _bufferPos, 0); } diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/BranchMisc.h b/desmume/src/windows/7z/CPP/7zip/Compress/BranchMisc.h new file mode 100644 index 000000000..053e923a9 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/BranchMisc.h @@ -0,0 +1,14 @@ +// BranchMisc.h + +#ifndef __COMPRESS_BRANCH_MISC_H +#define __COMPRESS_BRANCH_MISC_H + +#include "BranchCoder.h" + +MyClassA(BC_ARM, 0x05, 1) +MyClassA(BC_ARMT, 0x07, 1) +MyClassA(BC_PPC, 0x02, 5) +MyClassA(BC_SPARC, 0x08, 5) +MyClassA(BC_IA64, 0x04, 1) + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/BranchRegister.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/BranchRegister.cpp new file mode 100644 index 000000000..bc55dd668 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/BranchRegister.cpp @@ -0,0 +1,30 @@ +// BranchRegister.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "BranchMisc.h" + +#define CREATE_CODEC(x) \ + static void *CreateCodec ## x() { return (void *)(ICompressFilter *)(new C ## x ## _Decoder); } \ + static void *CreateCodec ## x ## Out() { return (void *)(ICompressFilter *)(new C ## x ## _Encoder); } + +CREATE_CODEC(BC_PPC) +CREATE_CODEC(BC_IA64) +CREATE_CODEC(BC_ARM) +CREATE_CODEC(BC_ARMT) +CREATE_CODEC(BC_SPARC) + +#define METHOD_ITEM(x, id1, id2, name) { CreateCodec ## x, CreateCodec ## x ## Out, 0x03030000 + (id1 * 256) + id2, name, 1, true } + +static CCodecInfo g_CodecsInfo[] = +{ + METHOD_ITEM(BC_PPC, 0x02, 0x05, L"PPC"), + METHOD_ITEM(BC_IA64, 0x04, 1, L"IA64"), + METHOD_ITEM(BC_ARM, 0x05, 1, L"ARM"), + METHOD_ITEM(BC_ARMT, 0x07, 1, L"ARMT"), + METHOD_ITEM(BC_SPARC, 0x08, 0x05, L"SPARC") +}; + +REGISTER_CODECS(Branch) diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/ByteSwap.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/ByteSwap.cpp new file mode 100644 index 000000000..f21a7acfe --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/ByteSwap.cpp @@ -0,0 +1,38 @@ +// ByteSwap.cpp + +#include "StdAfx.h" + +#include "ByteSwap.h" + +STDMETHODIMP CByteSwap2::Init() { return S_OK; } + +STDMETHODIMP_(UInt32) CByteSwap2::Filter(Byte *data, UInt32 size) +{ + const UInt32 kStep = 2; + UInt32 i; + for (i = 0; i + kStep <= size; i += kStep) + { + Byte b = data[i]; + data[i] = data[i + 1]; + data[i + 1] = b; + } + return i; +} + +STDMETHODIMP CByteSwap4::Init() { return S_OK; } + +STDMETHODIMP_(UInt32) CByteSwap4::Filter(Byte *data, UInt32 size) +{ + const UInt32 kStep = 4; + UInt32 i; + for (i = 0; i + kStep <= size; i += kStep) + { + Byte b0 = data[i]; + Byte b1 = data[i + 1]; + data[i] = data[i + 3]; + data[i + 1] = data[i + 2]; + data[i + 2] = b1; + data[i + 3] = b0; + } + return i; +} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/ByteSwap.h b/desmume/src/windows/7z/CPP/7zip/Compress/ByteSwap.h new file mode 100644 index 000000000..ecf983db4 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/ByteSwap.h @@ -0,0 +1,30 @@ +// ByteSwap.h + +#ifndef __COMPRESS_BYTE_SWAP_H +#define __COMPRESS_BYTE_SWAP_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +class CByteSwap2: + public ICompressFilter, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); +}; + +class CByteSwap4: + public ICompressFilter, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/ByteSwapRegister.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/ByteSwapRegister.cpp new file mode 100644 index 000000000..c3413f67b --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/ByteSwapRegister.cpp @@ -0,0 +1,18 @@ +// ByteSwapRegister.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "ByteSwap.h" + +static void *CreateCodec2() { return (void *)(ICompressFilter *)(new CByteSwap2); } +static void *CreateCodec4() { return (void *)(ICompressFilter *)(new CByteSwap4); } + +static CCodecInfo g_CodecsInfo[] = +{ + { CreateCodec2, CreateCodec4, 0x020302, L"Swap2", 1, true }, + { CreateCodec4, CreateCodec4, 0x020304, L"Swap4", 1, true } +}; + +REGISTER_CODECS(ByteSwap) diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/Codec.def b/desmume/src/windows/7z/CPP/7zip/Compress/Codec.def new file mode 100644 index 000000000..aab87ef8e --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/Codec.def @@ -0,0 +1,4 @@ +EXPORTS + CreateObject PRIVATE + GetNumberOfMethods PRIVATE + GetMethodProperty PRIVATE diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/CodecExports.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/CodecExports.cpp new file mode 100644 index 000000000..0cf84e73f --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/CodecExports.cpp @@ -0,0 +1,157 @@ +// CodecExports.cpp + +#include "StdAfx.h" + +#include "../../Common/ComTry.h" +#include "../../Windows/PropVariant.h" +#include "../Common/RegisterCodec.h" +#include "../ICoder.h" + +extern unsigned int g_NumCodecs; +extern const CCodecInfo *g_Codecs[]; + +static const UInt16 kDecodeId = 0x2790; + +DEFINE_GUID(CLSID_CCodec, +0x23170F69, 0x40C1, kDecodeId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + +static inline HRESULT SetPropString(const char *s, unsigned int size, PROPVARIANT *value) +{ + if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0) + value->vt = VT_BSTR; + return S_OK; +} + +static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value) +{ + return SetPropString((const char *)&guid, sizeof(GUID), value); +} + +static HRESULT SetClassID(CMethodId id, bool encode, PROPVARIANT *value) +{ + GUID clsId = CLSID_CCodec; + for (int i = 0; i < sizeof(id); i++, id >>= 8) + clsId.Data4[i] = (Byte)(id & 0xFF); + if (encode) + clsId.Data3++; + return SetPropGUID(clsId, value); +} + +static HRESULT FindCodecClassId(const GUID *clsID, UInt32 isCoder2, bool isFilter, bool &encode, int &index) +{ + index = -1; + if (clsID->Data1 != CLSID_CCodec.Data1 || + clsID->Data2 != CLSID_CCodec.Data2 || + (clsID->Data3 & ~1) != kDecodeId) + return S_OK; + encode = (clsID->Data3 != kDecodeId); + UInt64 id = 0; + for (int j = 0; j < 8; j++) + id |= ((UInt64)clsID->Data4[j]) << (8 * j); + for (unsigned i = 0; i < g_NumCodecs; i++) + { + const CCodecInfo &codec = *g_Codecs[i]; + if (id != codec.Id || encode && !codec.CreateEncoder || !encode && !codec.CreateDecoder) + continue; + if (!isFilter && codec.IsFilter || isFilter && !codec.IsFilter || + codec.NumInStreams != 1 && !isCoder2 || codec.NumInStreams == 1 && isCoder2) + return E_NOINTERFACE; + index = i; + return S_OK; + } + return S_OK; +} + +STDAPI CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + bool isCoder = (*iid == IID_ICompressCoder) != 0; + bool isCoder2 = (*iid == IID_ICompressCoder2) != 0; + bool isFilter = (*iid == IID_ICompressFilter) != 0; + const CCodecInfo &codec = *g_Codecs[index]; + if (!isFilter && codec.IsFilter || isFilter && !codec.IsFilter || + codec.NumInStreams != 1 && !isCoder2 || codec.NumInStreams == 1 && isCoder2) + return E_NOINTERFACE; + if (encode) + { + if (!codec.CreateEncoder) + return CLASS_E_CLASSNOTAVAILABLE; + *outObject = codec.CreateEncoder(); + } + else + { + if (!codec.CreateDecoder) + return CLASS_E_CLASSNOTAVAILABLE; + *outObject = codec.CreateDecoder(); + } + if (isCoder) + ((ICompressCoder *)*outObject)->AddRef(); + else if (isCoder2) + ((ICompressCoder2 *)*outObject)->AddRef(); + else + ((ICompressFilter *)*outObject)->AddRef(); + return S_OK; + COM_TRY_END +} + +STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject) +{ + *outObject = 0; + bool isCoder = (*iid == IID_ICompressCoder) != 0; + bool isCoder2 = (*iid == IID_ICompressCoder2) != 0; + bool isFilter = (*iid == IID_ICompressFilter) != 0; + if (!isCoder && !isCoder2 && !isFilter) + return E_NOINTERFACE; + bool encode; + int codecIndex; + HRESULT res = FindCodecClassId(clsid, isCoder2, isFilter, encode, codecIndex); + if (res != S_OK) + return res; + if (codecIndex < 0) + return CLASS_E_CLASSNOTAVAILABLE; + return CreateCoder2(encode, codecIndex, iid, outObject); +} + +STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value) +{ + ::VariantClear((VARIANTARG *)value); + const CCodecInfo &codec = *g_Codecs[codecIndex]; + switch(propID) + { + case NMethodPropID::kID: + { + value->uhVal.QuadPart = (UInt64)codec.Id; + value->vt = VT_UI8; + break; + } + case NMethodPropID::kName: + if ((value->bstrVal = ::SysAllocString(codec.Name)) != 0) + value->vt = VT_BSTR; + break; + case NMethodPropID::kDecoder: + if (codec.CreateDecoder) + return SetClassID(codec.Id, false, value); + break; + case NMethodPropID::kEncoder: + if (codec.CreateEncoder) + return SetClassID(codec.Id, true, value); + break; + case NMethodPropID::kInStreams: + { + if (codec.NumInStreams != 1) + { + value->vt = VT_UI4; + value->ulVal = (ULONG)codec.NumInStreams; + } + break; + } + } + return S_OK; +} + +STDAPI GetNumberOfMethods(UINT32 *numCodecs) +{ + *numCodecs = g_NumCodecs; + return S_OK; +} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/CopyCoder.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/CopyCoder.cpp new file mode 100644 index 000000000..4c2f5e0fc --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/CopyCoder.cpp @@ -0,0 +1,62 @@ +// Compress/CopyCoder.cpp + +#include "StdAfx.h" + +extern "C" +{ +#include "../../../C/Alloc.h" +} + +#include "../Common/StreamUtils.h" + +#include "CopyCoder.h" + +namespace NCompress { + +static const UInt32 kBufferSize = 1 << 17; + +CCopyCoder::~CCopyCoder() +{ + ::MidFree(_buffer); +} + +STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + if (_buffer == 0) + { + _buffer = (Byte *)::MidAlloc(kBufferSize); + if (_buffer == 0) + return E_OUTOFMEMORY; + } + + TotalSize = 0; + for (;;) + { + UInt32 realProcessedSize; + UInt32 size = kBufferSize; + if (outSize != 0) + if (size > *outSize - TotalSize) + size = (UInt32)(*outSize - TotalSize); + RINOK(inStream->Read(_buffer, size, &realProcessedSize)); + if (realProcessedSize == 0) + break; + RINOK(WriteStream(outStream, _buffer, realProcessedSize)); + TotalSize += realProcessedSize; + if (progress != NULL) + { + RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize)); + } + } + return S_OK; +} + +STDMETHODIMP CCopyCoder::GetInStreamProcessedSize(UInt64 *value) +{ + *value = TotalSize; + return S_OK; +} + +} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/CopyCoder.h b/desmume/src/windows/7z/CPP/7zip/Compress/CopyCoder.h new file mode 100644 index 000000000..7c9d3d355 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/CopyCoder.h @@ -0,0 +1,32 @@ +// Compress/CopyCoder.h + +#ifndef __COMPRESS_COPY_CODER_H +#define __COMPRESS_COPY_CODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +namespace NCompress { + +class CCopyCoder: + public ICompressCoder, + public ICompressGetInStreamProcessedSize, + public CMyUnknownImp +{ + Byte *_buffer; +public: + UInt64 TotalSize; + CCopyCoder(): TotalSize(0) , _buffer(0) {}; + ~CCopyCoder(); + + MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize) + + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); +}; + +} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/CopyRegister.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/CopyRegister.cpp new file mode 100644 index 000000000..3ef245978 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/CopyRegister.cpp @@ -0,0 +1,14 @@ +// CopyRegister.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "CopyCoder.h" + +static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::CCopyCoder); } + +static CCodecInfo g_CodecInfo = +{ CreateCodec, CreateCodec, 0x00, L"Copy", 1, false }; + +REGISTER_CODEC(Copy) diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/Deflate64Register.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/Deflate64Register.cpp new file mode 100644 index 000000000..6d6a904d1 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/Deflate64Register.cpp @@ -0,0 +1,20 @@ +// Deflate64Register.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "DeflateDecoder.h" + +static void *CreateCodecDeflate64() { return (void *)(ICompressCoder *)(new NCompress::NDeflate::NDecoder::CCOMCoder64); } +#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY) +#include "DeflateEncoder.h" +static void *CreateCodecOutDeflate64() { return (void *)(ICompressCoder *)(new NCompress::NDeflate::NEncoder::CCOMCoder64); } +#else +#define CreateCodecOutDeflate64 0 +#endif + +static CCodecInfo g_CodecInfo = + { CreateCodecDeflate64, CreateCodecOutDeflate64, 0x040109, L"Deflate64", 1, false }; + +REGISTER_CODEC(Deflate64) diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/DeflateConst.h b/desmume/src/windows/7z/CPP/7zip/Compress/DeflateConst.h new file mode 100644 index 000000000..b5c28d79e --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/DeflateConst.h @@ -0,0 +1,134 @@ +// DeflateConst.h + +#ifndef __DEFLATE_CONST_H +#define __DEFLATE_CONST_H + +namespace NCompress { +namespace NDeflate { + +const int kNumHuffmanBits = 15; + +const UInt32 kHistorySize32 = (1 << 15); +const UInt32 kHistorySize64 = (1 << 16); + +const UInt32 kDistTableSize32 = 30; +const UInt32 kDistTableSize64 = 32; + +const UInt32 kNumLenSymbols32 = 256; +const UInt32 kNumLenSymbols64 = 255; // don't change it. It must be <= 255. +const UInt32 kNumLenSymbolsMax = kNumLenSymbols32; + +const UInt32 kNumLenSlots = 29; + +const UInt32 kFixedDistTableSize = 32; +const UInt32 kFixedLenTableSize = 31; + +const UInt32 kSymbolEndOfBlock = 0x100; +const UInt32 kSymbolMatch = kSymbolEndOfBlock + 1; + +const UInt32 kMainTableSize = kSymbolMatch + kNumLenSlots; +const UInt32 kFixedMainTableSize = kSymbolMatch + kFixedLenTableSize; + +const UInt32 kLevelTableSize = 19; + +const UInt32 kTableDirectLevels = 16; +const UInt32 kTableLevelRepNumber = kTableDirectLevels; +const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1; +const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1; + +const UInt32 kLevelMask = 0xF; + +const Byte kLenStart32[kFixedLenTableSize] = + {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, 255, 0, 0}; +const Byte kLenStart64[kFixedLenTableSize] = + {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, 0, 0}; + +const Byte kLenDirectBits32[kFixedLenTableSize] = + {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, 0, 0}; +const Byte kLenDirectBits64[kFixedLenTableSize] = + {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, 16, 0, 0}; + +const UInt32 kDistStart[kDistTableSize64] = + {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,32768,49152}; +const Byte kDistDirectBits[kDistTableSize64] = + {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,14,14}; + +const Byte kLevelDirectBits[3] = {2, 3, 7}; + +const Byte kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +const UInt32 kMatchMinLen = 3; +const UInt32 kMatchMaxLen32 = kNumLenSymbols32 + kMatchMinLen - 1; //256 + 2 +const UInt32 kMatchMaxLen64 = kNumLenSymbols64 + kMatchMinLen - 1; //255 + 2 +const UInt32 kMatchMaxLen = kMatchMaxLen32; + +const int kFinalBlockFieldSize = 1; + +namespace NFinalBlockField +{ + enum + { + kNotFinalBlock = 0, + kFinalBlock = 1 + }; +} + +const int kBlockTypeFieldSize = 2; + +namespace NBlockType +{ + enum + { + kStored = 0, + kFixedHuffman = 1, + kDynamicHuffman = 2 + }; +} + +const int kNumLenCodesFieldSize = 5; +const int kNumDistCodesFieldSize = 5; +const int kNumLevelCodesFieldSize = 4; + +const UInt32 kNumLitLenCodesMin = 257; +const UInt32 kNumDistCodesMin = 1; +const UInt32 kNumLevelCodesMin = 4; + +const int kLevelFieldSize = 3; + +const int kStoredBlockLengthFieldSize = 16; + +struct CLevels +{ + Byte litLenLevels[kFixedMainTableSize]; + Byte distLevels[kFixedDistTableSize]; + + void SubClear() + { + UInt32 i; + for(i = kNumLitLenCodesMin; i < kFixedMainTableSize; i++) + litLenLevels[i] = 0; + for(i = 0; i < kFixedDistTableSize; i++) + distLevels[i] = 0; + } + + void SetFixedLevels() + { + int i; + + for (i = 0; i < 144; i++) + litLenLevels[i] = 8; + for (; i < 256; i++) + litLenLevels[i] = 9; + for (; i < 280; i++) + litLenLevels[i] = 7; + for (; i < 288; i++) + litLenLevels[i] = 8; + for (i = 0; i < kFixedDistTableSize; i++) // test it: InfoZip only uses kDistTableSize + distLevels[i] = 5; + } +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/DeflateDecoder.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/DeflateDecoder.cpp new file mode 100644 index 000000000..31a61371b --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/DeflateDecoder.cpp @@ -0,0 +1,345 @@ +// DeflateDecoder.cpp + +#include "StdAfx.h" + +#include "DeflateDecoder.h" + +namespace NCompress { +namespace NDeflate { +namespace NDecoder { + +static const int kLenIdFinished = -1; +static const int kLenIdNeedInit = -2; + +CCoder::CCoder(bool deflate64Mode, bool deflateNSIS): + _deflate64Mode(deflate64Mode), + _deflateNSIS(deflateNSIS), + _keepHistory(false), + ZlibMode(false) {} + +UInt32 CCoder::ReadBits(int numBits) +{ + return m_InBitStream.ReadBits(numBits); +} + +bool CCoder::DeCodeLevelTable(Byte *values, int numSymbols) +{ + int i = 0; + do + { + UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); + if (number < kTableDirectLevels) + values[i++] = (Byte)number; + else if (number < kLevelTableSize) + { + if (number == kTableLevelRepNumber) + { + if (i == 0) + return false; + int num = ReadBits(2) + 3; + for (; num > 0 && i < numSymbols; num--, i++) + values[i] = values[i - 1]; + } + else + { + int num; + if (number == kTableLevel0Number) + num = ReadBits(3) + 3; + else + num = ReadBits(7) + 11; + for (;num > 0 && i < numSymbols; num--) + values[i++] = 0; + } + } + else + return false; + } + while(i < numSymbols); + return true; +} + +#define RIF(x) { if (!(x)) return false; } + +bool CCoder::ReadTables(void) +{ + m_FinalBlock = (ReadBits(kFinalBlockFieldSize) == NFinalBlockField::kFinalBlock); + UInt32 blockType = ReadBits(kBlockTypeFieldSize); + if (blockType > NBlockType::kDynamicHuffman) + return false; + + if (blockType == NBlockType::kStored) + { + m_StoredMode = true; + UInt32 currentBitPosition = m_InBitStream.GetBitPosition(); + int numBitsForAlign = (int)(currentBitPosition > 0 ? (8 - currentBitPosition): 0); + ReadBits(numBitsForAlign); + m_StoredBlockSize = ReadBits(kStoredBlockLengthFieldSize); + if (_deflateNSIS) + return true; + return (m_StoredBlockSize == (UInt16)~ReadBits(kStoredBlockLengthFieldSize)); + } + + m_StoredMode = false; + + CLevels levels; + if (blockType == NBlockType::kFixedHuffman) + { + levels.SetFixedLevels(); + _numDistLevels = _deflate64Mode ? kDistTableSize64 : kDistTableSize32; + } + else + { + int numLitLenLevels = ReadBits(kNumLenCodesFieldSize) + kNumLitLenCodesMin; + _numDistLevels = ReadBits(kNumDistCodesFieldSize) + kNumDistCodesMin; + int numLevelCodes = ReadBits(kNumLevelCodesFieldSize) + kNumLevelCodesMin; + + if (!_deflate64Mode) + if (_numDistLevels > kDistTableSize32) + return false; + + Byte levelLevels[kLevelTableSize]; + for (int i = 0; i < kLevelTableSize; i++) + { + int position = kCodeLengthAlphabetOrder[i]; + if(i < numLevelCodes) + levelLevels[position] = (Byte)ReadBits(kLevelFieldSize); + else + levelLevels[position] = 0; + } + + RIF(m_LevelDecoder.SetCodeLengths(levelLevels)); + + Byte tmpLevels[kFixedMainTableSize + kFixedDistTableSize]; + if (!DeCodeLevelTable(tmpLevels, numLitLenLevels + _numDistLevels)) + return false; + + levels.SubClear(); + memcpy(levels.litLenLevels, tmpLevels, numLitLenLevels); + memcpy(levels.distLevels, tmpLevels + numLitLenLevels, _numDistLevels); + } + RIF(m_MainDecoder.SetCodeLengths(levels.litLenLevels)); + return m_DistDecoder.SetCodeLengths(levels.distLevels); +} + +HRESULT CCoder::CodeSpec(UInt32 curSize) +{ + if (_remainLen == kLenIdFinished) + return S_OK; + if (_remainLen == kLenIdNeedInit) + { + if (!_keepHistory) + if (!m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 17)) + return E_OUTOFMEMORY; + m_OutWindowStream.Init(_keepHistory); + m_InBitStream.Init(); + m_FinalBlock = false; + _remainLen = 0; + _needReadTable = true; + } + + if (curSize == 0) + return S_OK; + + while(_remainLen > 0 && curSize > 0) + { + _remainLen--; + Byte b = m_OutWindowStream.GetByte(_rep0); + m_OutWindowStream.PutByte(b); + curSize--; + } + + while(curSize > 0) + { + if (_needReadTable) + { + if (m_FinalBlock) + { + _remainLen = kLenIdFinished; + break; + } + if (!ReadTables()) + return S_FALSE; + _needReadTable = false; + } + + if(m_StoredMode) + { + for (; m_StoredBlockSize > 0 && curSize > 0; m_StoredBlockSize--, curSize--) + m_OutWindowStream.PutByte((Byte)m_InBitStream.ReadBits(8)); + _needReadTable = (m_StoredBlockSize == 0); + continue; + } + while(curSize > 0) + { + if (m_InBitStream.NumExtraBytes > 4) + return S_FALSE; + + UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); + if (number < 0x100) + { + m_OutWindowStream.PutByte((Byte)number); + curSize--; + continue; + } + else if (number == kSymbolEndOfBlock) + { + _needReadTable = true; + break; + } + else if (number < kMainTableSize) + { + number -= kSymbolMatch; + UInt32 len; + { + int numBits; + if (_deflate64Mode) + { + len = kLenStart64[number]; + numBits = kLenDirectBits64[number]; + } + else + { + len = kLenStart32[number]; + numBits = kLenDirectBits32[number]; + } + len += kMatchMinLen + m_InBitStream.ReadBits(numBits); + } + UInt32 locLen = len; + if (locLen > curSize) + locLen = (UInt32)curSize; + number = m_DistDecoder.DecodeSymbol(&m_InBitStream); + if (number >= _numDistLevels) + return S_FALSE; + UInt32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]); + if (!m_OutWindowStream.CopyBlock(distance, locLen)) + return S_FALSE; + curSize -= locLen; + len -= locLen; + if (len != 0) + { + _remainLen = (Int32)len; + _rep0 = distance; + break; + } + } + else + return S_FALSE; + } + } + return S_OK; +} + +HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + SetInStream(inStream); + m_OutWindowStream.SetStream(outStream); + SetOutStreamSize(outSize); + CCoderReleaser flusher(this); + + const UInt64 start = m_OutWindowStream.GetProcessedSize(); + for (;;) + { + UInt32 curSize = 1 << 18; + if (outSize != 0) + { + const UInt64 rem = *outSize - (m_OutWindowStream.GetProcessedSize() - start); + if (curSize > rem) + curSize = (UInt32)rem; + } + if (curSize == 0) + break; + RINOK(CodeSpec(curSize)); + if (_remainLen == kLenIdFinished) + break; + if (progress != NULL) + { + const UInt64 inSize = m_InBitStream.GetProcessedSize(); + const UInt64 nowPos64 = m_OutWindowStream.GetProcessedSize() - start; + RINOK(progress->SetRatioInfo(&inSize, &nowPos64)); + } + } + if (_remainLen == kLenIdFinished && ZlibMode) + { + UInt32 currentBitPosition = m_InBitStream.GetBitPosition(); + int numBitsForAlign = (int)(currentBitPosition > 0 ? (8 - currentBitPosition): 0); + ReadBits(numBitsForAlign); + for (int i = 0; i < 4; i++) + ZlibFooter[i] = (Byte)m_InBitStream.ReadBits(8); + } + flusher.NeedFlush = false; + return Flush(); +} + + +#ifdef _NO_EXCEPTIONS + +#define DEFLATE_TRY_BEGIN +#define DEFLATE_TRY_END + +#else + +#define DEFLATE_TRY_BEGIN try { +#define DEFLATE_TRY_END } \ + catch(const CInBufferException &e) { return e.ErrorCode; } \ + catch(const CLzOutWindowException &e) { return e.ErrorCode; } \ + catch(...) { return S_FALSE; } + +#endif + +HRESULT CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + DEFLATE_TRY_BEGIN + return CodeReal(inStream, outStream, inSize, outSize, progress); + DEFLATE_TRY_END +} + +STDMETHODIMP CCoder::GetInStreamProcessedSize(UInt64 *value) +{ + if (value == NULL) + return E_INVALIDARG; + *value = m_InBitStream.GetProcessedSize(); + return S_OK; +} + +STDMETHODIMP CCoder::SetInStream(ISequentialInStream *inStream) +{ + m_InBitStream.SetStream(inStream); + return S_OK; +} + +STDMETHODIMP CCoder::ReleaseInStream() +{ + m_InBitStream.ReleaseStream(); + return S_OK; +} + +STDMETHODIMP CCoder::SetOutStreamSize(const UInt64 * /* outSize */) +{ + _remainLen = kLenIdNeedInit; + m_OutWindowStream.Init(_keepHistory); + return S_OK; +} + +#ifndef NO_READ_FROM_CODER + +STDMETHODIMP CCoder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + DEFLATE_TRY_BEGIN + if (processedSize) + *processedSize = 0; + const UInt64 startPos = m_OutWindowStream.GetProcessedSize(); + m_OutWindowStream.SetMemStream((Byte *)data); + RINOK(CodeSpec(size)); + if (processedSize) + *processedSize = (UInt32)(m_OutWindowStream.GetProcessedSize() - startPos); + return Flush(); + DEFLATE_TRY_END +} + +#endif + +}}} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/DeflateDecoder.h b/desmume/src/windows/7z/CPP/7zip/Compress/DeflateDecoder.h new file mode 100644 index 000000000..3a81e1657 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/DeflateDecoder.h @@ -0,0 +1,136 @@ +// DeflateDecoder.h + +#ifndef __DEFLATE_DECODER_H +#define __DEFLATE_DECODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "../Common/InBuffer.h" + +#include "BitlDecoder.h" +#include "DeflateConst.h" +#include "HuffmanDecoder.h" +#include "LzOutWindow.h" + +namespace NCompress { +namespace NDeflate { +namespace NDecoder { + +class CCoder: + public ICompressCoder, + public ICompressGetInStreamProcessedSize, + #ifndef NO_READ_FROM_CODER + public ICompressSetInStream, + public ICompressSetOutStreamSize, + public ISequentialInStream, + #endif + public CMyUnknownImp +{ + CLzOutWindow m_OutWindowStream; + NBitl::CDecoder m_InBitStream; + NCompress::NHuffman::CDecoder m_MainDecoder; + NCompress::NHuffman::CDecoder m_DistDecoder; + NCompress::NHuffman::CDecoder m_LevelDecoder; + + UInt32 m_StoredBlockSize; + + bool m_FinalBlock; + bool m_StoredMode; + UInt32 _numDistLevels; + + + bool _deflateNSIS; + bool _deflate64Mode; + bool _keepHistory; + Int32 _remainLen; + UInt32 _rep0; + bool _needReadTable; + + UInt32 ReadBits(int numBits); + + bool DeCodeLevelTable(Byte *values, int numSymbols); + bool ReadTables(); + + void ReleaseStreams() + { + m_OutWindowStream.ReleaseStream(); + ReleaseInStream(); + } + + HRESULT Flush() { return m_OutWindowStream.Flush(); } + class CCoderReleaser + { + CCoder *m_Coder; + public: + bool NeedFlush; + CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {} + ~CCoderReleaser() + { + if (NeedFlush) + m_Coder->Flush(); + m_Coder->ReleaseStreams(); + } + }; + friend class CCoderReleaser; + + HRESULT CodeSpec(UInt32 curSize); +public: + bool ZlibMode; + Byte ZlibFooter[4]; + + CCoder(bool deflate64Mode, bool deflateNSIS = false); + void SetKeepHistory(bool keepHistory) { _keepHistory = keepHistory; } + + HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + + #ifndef NO_READ_FROM_CODER + MY_UNKNOWN_IMP4( + ICompressGetInStreamProcessedSize, + ICompressSetInStream, + ICompressSetOutStreamSize, + ISequentialInStream + ) + #else + MY_UNKNOWN_IMP1( + ICompressGetInStreamProcessedSize) + #endif + + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); + + #ifndef NO_READ_FROM_CODER + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + #endif + + // IGetInStreamProcessedSize + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); +}; + +class CCOMCoder : public CCoder +{ +public: + CCOMCoder(): CCoder(false) {} +}; + +class CNsisCOMCoder : public CCoder +{ +public: + CNsisCOMCoder(): CCoder(false, true) {} +}; + +class CCOMCoder64 : public CCoder +{ +public: + CCOMCoder64(): CCoder(true) {} +}; + +}}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/DeflateNsisRegister.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/DeflateNsisRegister.cpp new file mode 100644 index 000000000..dbb128368 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/DeflateNsisRegister.cpp @@ -0,0 +1,14 @@ +// DeflateNsisRegister.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "DeflateDecoder.h" + +static void *CreateCodecDeflateNsis() { return (void *)(ICompressCoder *)(new NCompress::NDeflate::NDecoder::CNsisCOMCoder); } + +static CCodecInfo g_CodecInfo = + { CreateCodecDeflateNsis, 0, 0x040901, L"DeflateNSIS", 1, false }; + +REGISTER_CODEC(DeflateNsis) diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/DeflateRegister.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/DeflateRegister.cpp new file mode 100644 index 000000000..d8a9c8dc8 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/DeflateRegister.cpp @@ -0,0 +1,21 @@ +// DeflateRegister.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "DeflateDecoder.h" + +static void *CreateCodecDeflate() { return (void *)(ICompressCoder *)(new NCompress::NDeflate::NDecoder::CCOMCoder); } + +#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY) +#include "DeflateEncoder.h" +static void *CreateCodecOutDeflate() { return (void *)(ICompressCoder *)(new NCompress::NDeflate::NEncoder::CCOMCoder); } +#else +#define CreateCodecOutDeflate 0 +#endif + +static CCodecInfo g_CodecInfo = + { CreateCodecDeflate, CreateCodecOutDeflate, 0x040108, L"Deflate", 1, false }; + +REGISTER_CODEC(Deflate) diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/HuffmanDecoder.h b/desmume/src/windows/7z/CPP/7zip/Compress/HuffmanDecoder.h new file mode 100644 index 000000000..f71a58282 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/HuffmanDecoder.h @@ -0,0 +1,89 @@ +// Compress/HuffmanDecoder.h + +#ifndef __COMPRESS_HUFFMAN_DECODER_H +#define __COMPRESS_HUFFMAN_DECODER_H + +#include "../../Common/Types.h" + +namespace NCompress { +namespace NHuffman { + +const int kNumTableBits = 9; + +template +class CDecoder +{ + UInt32 m_Limits[kNumBitsMax + 1]; // m_Limits[i] = value limit for symbols with length = i + UInt32 m_Positions[kNumBitsMax + 1]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i + UInt32 m_Symbols[m_NumSymbols]; + Byte m_Lengths[1 << kNumTableBits]; // Table oh length for short codes. + +public: + + bool SetCodeLengths(const Byte *codeLengths) + { + int lenCounts[kNumBitsMax + 1]; + UInt32 tmpPositions[kNumBitsMax + 1]; + int i; + for(i = 1; i <= kNumBitsMax; i++) + lenCounts[i] = 0; + UInt32 symbol; + for (symbol = 0; symbol < m_NumSymbols; symbol++) + { + int len = codeLengths[symbol]; + if (len > kNumBitsMax) + return false; + lenCounts[len]++; + m_Symbols[symbol] = 0xFFFFFFFF; + } + lenCounts[0] = 0; + m_Positions[0] = m_Limits[0] = 0; + UInt32 startPos = 0; + UInt32 index = 0; + const UInt32 kMaxValue = (1 << kNumBitsMax); + for (i = 1; i <= kNumBitsMax; i++) + { + startPos += lenCounts[i] << (kNumBitsMax - i); + if (startPos > kMaxValue) + return false; + m_Limits[i] = (i == kNumBitsMax) ? kMaxValue : startPos; + m_Positions[i] = m_Positions[i - 1] + lenCounts[i - 1]; + tmpPositions[i] = m_Positions[i]; + if(i <= kNumTableBits) + { + UInt32 limit = (m_Limits[i] >> (kNumBitsMax - kNumTableBits)); + for (; index < limit; index++) + m_Lengths[index] = (Byte)i; + } + } + for (symbol = 0; symbol < m_NumSymbols; symbol++) + { + int len = codeLengths[symbol]; + if (len != 0) + m_Symbols[tmpPositions[len]++] = symbol; + } + return true; + } + + template + UInt32 DecodeSymbol(TBitDecoder *bitStream) + { + int numBits; + UInt32 value = bitStream->GetValue(kNumBitsMax); + if (value < m_Limits[kNumTableBits]) + numBits = m_Lengths[value >> (kNumBitsMax - kNumTableBits)]; + else + for (numBits = kNumTableBits + 1; value >= m_Limits[numBits]; numBits++); + bitStream->MovePos(numBits); + UInt32 index = m_Positions[numBits] + + ((value - m_Limits[numBits - 1]) >> (kNumBitsMax - numBits)); + if (index >= m_NumSymbols) + // throw CDecoderException(); // test it + return 0xFFFFFFFF; + return m_Symbols[index]; + } +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/ImplodeDecoder.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/ImplodeDecoder.cpp new file mode 100644 index 000000000..6c5e36284 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/ImplodeDecoder.cpp @@ -0,0 +1,219 @@ +// Implode/Decoder.cpp + +#include "StdAfx.h" + +#include "ImplodeDecoder.h" +#include "Common/Defs.h" + +namespace NCompress { +namespace NImplode { +namespace NDecoder { + +class CException +{ +public: + enum ECauseType + { + kData + } m_Cause; + CException(ECauseType cause): m_Cause(cause) {} +}; + +static const int kNumDistanceLowDirectBitsForBigDict = 7; +static const int kNumDistanceLowDirectBitsForSmallDict = 6; + +static const int kNumBitsInByte = 8; + +// static const int kLevelStructuresNumberFieldSize = kNumBitsInByte; +static const int kLevelStructuresNumberAdditionalValue = 1; + +static const int kNumLevelStructureLevelBits = 4; +static const int kLevelStructureLevelAdditionalValue = 1; + +static const int kNumLevelStructureRepNumberBits = 4; +static const int kLevelStructureRepNumberAdditionalValue = 1; + + +static const int kLiteralTableSize = (1 << kNumBitsInByte); +static const int kDistanceTableSize = 64; +static const int kLengthTableSize = 64; + +static const UInt32 kHistorySize = + (1 << MyMax(kNumDistanceLowDirectBitsForBigDict, + kNumDistanceLowDirectBitsForSmallDict)) * + kDistanceTableSize; // = 8 KB; + +static const int kNumAdditionalLengthBits = 8; + +static const UInt32 kMatchMinLenWhenLiteralsOn = 3; +static const UInt32 kMatchMinLenWhenLiteralsOff = 2; + +static const UInt32 kMatchMinLenMax = MyMax(kMatchMinLenWhenLiteralsOn, + kMatchMinLenWhenLiteralsOff); // 3 + +// static const UInt32 kMatchMaxLenMax = kMatchMinLenMax + (kLengthTableSize - 1) + (1 << kNumAdditionalLengthBits) - 1; // or 2 + +enum +{ + kMatchId = 0, + kLiteralId = 1 +}; + + +CCoder::CCoder(): + m_LiteralDecoder(kLiteralTableSize), + m_LengthDecoder(kLengthTableSize), + m_DistanceDecoder(kDistanceTableSize) +{ +} + +void CCoder::ReleaseStreams() +{ + m_OutWindowStream.ReleaseStream(); + m_InBitStream.ReleaseStream(); +} + +bool CCoder::ReadLevelItems(NImplode::NHuffman::CDecoder &decoder, + Byte *levels, int numLevelItems) +{ + int numCodedStructures = m_InBitStream.ReadBits(kNumBitsInByte) + + kLevelStructuresNumberAdditionalValue; + int currentIndex = 0; + for(int i = 0; i < numCodedStructures; i++) + { + int level = m_InBitStream.ReadBits(kNumLevelStructureLevelBits) + + kLevelStructureLevelAdditionalValue; + int rep = m_InBitStream.ReadBits(kNumLevelStructureRepNumberBits) + + kLevelStructureRepNumberAdditionalValue; + if (currentIndex + rep > numLevelItems) + throw CException(CException::kData); + for(int j = 0; j < rep; j++) + levels[currentIndex++] = (Byte)level; + } + if (currentIndex != numLevelItems) + return false; + return decoder.SetCodeLengths(levels); +} + + +bool CCoder::ReadTables(void) +{ + if (m_LiteralsOn) + { + Byte literalLevels[kLiteralTableSize]; + if (!ReadLevelItems(m_LiteralDecoder, literalLevels, kLiteralTableSize)) + return false; + } + + Byte lengthLevels[kLengthTableSize]; + if (!ReadLevelItems(m_LengthDecoder, lengthLevels, kLengthTableSize)) + return false; + + Byte distanceLevels[kDistanceTableSize]; + return ReadLevelItems(m_DistanceDecoder, distanceLevels, kDistanceTableSize); +} + +class CCoderReleaser +{ + CCoder *m_Coder; +public: + CCoderReleaser(CCoder *coder): m_Coder(coder) {} + ~CCoderReleaser() { m_Coder->ReleaseStreams(); } +}; + +HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (outSize == NULL) + return E_INVALIDARG; + UInt64 pos = 0, unPackSize = *outSize; + + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(false); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + CCoderReleaser coderReleaser(this); + + if (!ReadTables()) + return S_FALSE; + + while(pos < unPackSize) + { + if (progress != NULL && pos % (1 << 16) == 0) + { + UInt64 packSize = m_InBitStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &pos)); + } + if(m_InBitStream.ReadBits(1) == kMatchId) // match + { + UInt32 lowDistBits = m_InBitStream.ReadBits(m_NumDistanceLowDirectBits); + UInt32 distance = m_DistanceDecoder.DecodeSymbol(&m_InBitStream); + if (distance >= kDistanceTableSize) + return S_FALSE; + distance = (distance << m_NumDistanceLowDirectBits) + lowDistBits; + UInt32 lengthSymbol = m_LengthDecoder.DecodeSymbol(&m_InBitStream); + if (lengthSymbol >= kLengthTableSize) + return S_FALSE; + UInt32 length = lengthSymbol + m_MinMatchLength; + if (lengthSymbol == kLengthTableSize - 1) // special symbol = 63 + length += m_InBitStream.ReadBits(kNumAdditionalLengthBits); + while(distance >= pos && length > 0) + { + m_OutWindowStream.PutByte(0); + pos++; + length--; + } + if (length > 0) + m_OutWindowStream.CopyBlock(distance, length); + pos += length; + } + else + { + Byte b; + if (m_LiteralsOn) + { + UInt32 temp = m_LiteralDecoder.DecodeSymbol(&m_InBitStream); + if (temp >= kLiteralTableSize) + return S_FALSE; + b = (Byte)temp; + } + else + b = (Byte)m_InBitStream.ReadBits(kNumBitsInByte); + m_OutWindowStream.PutByte(b); + pos++; + } + } + if (pos > unPackSize) + return S_FALSE; + return m_OutWindowStream.Flush(); +} + +STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CLzOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +STDMETHODIMP CCoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + if (size < 1) + return E_INVALIDARG; + Byte flag = data[0]; + m_BigDictionaryOn = ((flag & 2) != 0); + m_NumDistanceLowDirectBits = m_BigDictionaryOn ? + kNumDistanceLowDirectBitsForBigDict: + kNumDistanceLowDirectBitsForSmallDict; + m_LiteralsOn = ((flag & 4) != 0); + m_MinMatchLength = m_LiteralsOn ? + kMatchMinLenWhenLiteralsOn : + kMatchMinLenWhenLiteralsOff; + return S_OK; +} + +}}} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/ImplodeDecoder.h b/desmume/src/windows/7z/CPP/7zip/Compress/ImplodeDecoder.h new file mode 100644 index 000000000..2b45f05da --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/ImplodeDecoder.h @@ -0,0 +1,57 @@ +// ImplodeDecoder.h + +#ifndef __COMPRESS_IMPLODE_DECODER_H +#define __COMPRESS_IMPLODE_DECODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "ImplodeHuffmanDecoder.h" +#include "LzOutWindow.h" + +namespace NCompress { +namespace NImplode { +namespace NDecoder { + +class CCoder: + public ICompressCoder, + public ICompressSetDecoderProperties2, + public CMyUnknownImp +{ + CLzOutWindow m_OutWindowStream; + NBitl::CDecoder m_InBitStream; + + NImplode::NHuffman::CDecoder m_LiteralDecoder; + NImplode::NHuffman::CDecoder m_LengthDecoder; + NImplode::NHuffman::CDecoder m_DistanceDecoder; + + bool m_BigDictionaryOn; + bool m_LiteralsOn; + + int m_NumDistanceLowDirectBits; + UInt32 m_MinMatchLength; + + bool ReadLevelItems(NImplode::NHuffman::CDecoder &table, Byte *levels, int numLevelItems); + bool ReadTables(); + void DeCodeLevelTable(Byte *newLevels, int numLevels); +public: + CCoder(); + + MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) + + void ReleaseStreams(); + HRESULT Flush() { return m_OutWindowStream.Flush(); } + + HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); +}; + +}}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp new file mode 100644 index 000000000..c7a163433 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp @@ -0,0 +1,89 @@ +// ImplodeHuffmanDecoder.cpp + +#include "StdAfx.h" + +#include "ImplodeHuffmanDecoder.h" + +namespace NCompress { +namespace NImplode { +namespace NHuffman { + +CDecoder::CDecoder(UInt32 numSymbols): + m_NumSymbols(numSymbols) +{ + m_Symbols = new UInt32[m_NumSymbols]; +} + +CDecoder::~CDecoder() +{ + delete []m_Symbols; +} + +bool CDecoder::SetCodeLengths(const Byte *codeLengths) +{ + // int lenCounts[kNumBitsInLongestCode + 1], tmpPositions[kNumBitsInLongestCode + 1]; + int lenCounts[kNumBitsInLongestCode + 2], tmpPositions[kNumBitsInLongestCode + 1]; + int i; + for(i = 0; i <= kNumBitsInLongestCode; i++) + lenCounts[i] = 0; + UInt32 symbolIndex; + for (symbolIndex = 0; symbolIndex < m_NumSymbols; symbolIndex++) + lenCounts[codeLengths[symbolIndex]]++; + // lenCounts[0] = 0; + + // tmpPositions[0] = m_Positions[0] = m_Limitits[0] = 0; + m_Limitits[kNumBitsInLongestCode + 1] = 0; + m_Positions[kNumBitsInLongestCode + 1] = 0; + lenCounts[kNumBitsInLongestCode + 1] = 0; + + + UInt32 startPos = 0; + static const UInt32 kMaxValue = (1 << kNumBitsInLongestCode); + + for (i = kNumBitsInLongestCode; i > 0; i--) + { + startPos += lenCounts[i] << (kNumBitsInLongestCode - i); + if (startPos > kMaxValue) + return false; + m_Limitits[i] = startPos; + m_Positions[i] = m_Positions[i + 1] + lenCounts[i + 1]; + tmpPositions[i] = m_Positions[i] + lenCounts[i]; + + } + + // if _ZIP_MODE do not throw exception for trees containing only one node + // #ifndef _ZIP_MODE + if (startPos != kMaxValue) + return false; + // #endif + + for (symbolIndex = 0; symbolIndex < m_NumSymbols; symbolIndex++) + if (codeLengths[symbolIndex] != 0) + m_Symbols[--tmpPositions[codeLengths[symbolIndex]]] = symbolIndex; + return true; +} + +UInt32 CDecoder::DecodeSymbol(CInBit *inStream) +{ + UInt32 numBits = 0; + UInt32 value = inStream->GetValue(kNumBitsInLongestCode); + int i; + for(i = kNumBitsInLongestCode; i > 0; i--) + { + if (value < m_Limitits[i]) + { + numBits = i; + break; + } + } + if (i == 0) + return 0xFFFFFFFF; + inStream->MovePos(numBits); + UInt32 index = m_Positions[numBits] + + ((value - m_Limitits[numBits + 1]) >> (kNumBitsInLongestCode - numBits)); + if (index >= m_NumSymbols) + return 0xFFFFFFFF; + return m_Symbols[index]; +} + +}}} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/ImplodeHuffmanDecoder.h b/desmume/src/windows/7z/CPP/7zip/Compress/ImplodeHuffmanDecoder.h new file mode 100644 index 000000000..8936c09e6 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/ImplodeHuffmanDecoder.h @@ -0,0 +1,34 @@ +// ImplodeHuffmanDecoder.h + +#ifndef __IMPLODE_HUFFMAN_DECODER_H +#define __IMPLODE_HUFFMAN_DECODER_H + +#include "../Common/InBuffer.h" + +#include "BitlDecoder.h" + +namespace NCompress { +namespace NImplode { +namespace NHuffman { + +const int kNumBitsInLongestCode = 16; + +typedef NBitl::CDecoder CInBit; + +class CDecoder +{ + UInt32 m_Limitits[kNumBitsInLongestCode + 2]; // m_Limitits[i] = value limit for symbols with length = i + UInt32 m_Positions[kNumBitsInLongestCode + 2]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i + UInt32 m_NumSymbols; // number of symbols in m_Symbols + UInt32 *m_Symbols; // symbols: at first with len=1 then 2, ... 15. +public: + CDecoder(UInt32 numSymbols); + ~CDecoder(); + + bool SetCodeLengths(const Byte *codeLengths); + UInt32 DecodeSymbol(CInBit *inStream); +}; + +}}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/LzOutWindow.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/LzOutWindow.cpp new file mode 100644 index 000000000..b04789471 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/LzOutWindow.cpp @@ -0,0 +1,14 @@ +// LzOutWindow.cpp + +#include "StdAfx.h" + +#include "LzOutWindow.h" + +void CLzOutWindow::Init(bool solid) +{ + if (!solid) + COutBuffer::Init(); + #ifdef _NO_EXCEPTIONS + ErrorCode = S_OK; + #endif +} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/LzOutWindow.h b/desmume/src/windows/7z/CPP/7zip/Compress/LzOutWindow.h new file mode 100644 index 000000000..bbec7ad5b --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/LzOutWindow.h @@ -0,0 +1,66 @@ +// LzOutWindow.h + +#ifndef __LZ_OUT_WINDOW_H +#define __LZ_OUT_WINDOW_H + +#include "../IStream.h" + +#include "../Common/OutBuffer.h" + +#ifndef _NO_EXCEPTIONS +typedef COutBufferException CLzOutWindowException; +#endif + +class CLzOutWindow: public COutBuffer +{ +public: + void Init(bool solid = false); + + // distance >= 0, len > 0, + bool CopyBlock(UInt32 distance, UInt32 len) + { + UInt32 pos = _pos - distance - 1; + if (distance >= _pos) + { + if (!_overDict || distance >= _bufferSize) + return false; + pos += _bufferSize; + } + if (_limitPos - _pos > len && _bufferSize - pos > len) + { + const Byte *src = _buffer + pos; + Byte *dest = _buffer + _pos; + _pos += len; + do + *dest++ = *src++; + while(--len != 0); + } + else do + { + if (pos == _bufferSize) + pos = 0; + _buffer[_pos++] = _buffer[pos++]; + if (_pos == _limitPos) + FlushWithCheck(); + } + while(--len != 0); + return true; + } + + void PutByte(Byte b) + { + _buffer[_pos++] = b; + if (_pos == _limitPos) + FlushWithCheck(); + } + + Byte GetByte(UInt32 distance) const + { + UInt32 pos = _pos - distance - 1; + if (pos >= _bufferSize) + pos += _bufferSize; + return _buffer[pos]; + } +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/LzhDecoder.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/LzhDecoder.cpp new file mode 100644 index 000000000..e1591f46f --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/LzhDecoder.cpp @@ -0,0 +1,220 @@ +// LzhDecoder.cpp + +#include "StdAfx.h" + +#include "LzhDecoder.h" + +#include "Windows/Defs.h" + +namespace NCompress{ +namespace NLzh { +namespace NDecoder { + +static const UInt32 kHistorySize = (1 << 16); + +static const int kBlockSizeBits = 16; +static const int kNumCBits = 9; +static const int kNumLevelBits = 5; // smallest integer such that (1 << kNumLevelBits) > kNumLevelSymbols/ + +UInt32 CCoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); } + +HRESULT CCoder::ReadLevelTable() +{ + int n = ReadBits(kNumLevelBits); + if (n == 0) + { + m_LevelHuffman.Symbol = ReadBits(kNumLevelBits); + if (m_LevelHuffman.Symbol >= kNumLevelSymbols) + return S_FALSE; + } + else + { + if (n > kNumLevelSymbols) + return S_FALSE; + m_LevelHuffman.Symbol = -1; + Byte lens[kNumLevelSymbols]; + int i = 0; + while (i < n) + { + int c = m_InBitStream.ReadBits(3); + if (c == 7) + while (ReadBits(1)) + if (c++ > kMaxHuffmanLen) + return S_FALSE; + lens[i++] = (Byte)c; + if (i == kNumSpecLevelSymbols) + { + c = ReadBits(2); + while (--c >= 0) + lens[i++] = 0; + } + } + while (i < kNumLevelSymbols) + lens[i++] = 0; + m_LevelHuffman.SetCodeLengths(lens); + } + return S_OK; +} + +HRESULT CCoder::ReadPTable(int numBits) +{ + int n = ReadBits(numBits); + if (n == 0) + { + m_PHuffmanDecoder.Symbol = ReadBits(numBits); + if (m_PHuffmanDecoder.Symbol >= kNumDistanceSymbols) + return S_FALSE; + } + else + { + if (n > kNumDistanceSymbols) + return S_FALSE; + m_PHuffmanDecoder.Symbol = -1; + Byte lens[kNumDistanceSymbols]; + int i = 0; + while (i < n) + { + int c = m_InBitStream.ReadBits(3); + if (c == 7) + while (ReadBits(1)) + { + if (c > kMaxHuffmanLen) + return S_FALSE; + c++; + } + lens[i++] = (Byte)c; + } + while (i < kNumDistanceSymbols) + lens[i++] = 0; + m_PHuffmanDecoder.SetCodeLengths(lens); + } + return S_OK; +} + +HRESULT CCoder::ReadCTable() +{ + int n = ReadBits(kNumCBits); + if (n == 0) + { + m_CHuffmanDecoder.Symbol = ReadBits(kNumCBits); + if (m_CHuffmanDecoder.Symbol >= kNumCSymbols) + return S_FALSE; + } + else + { + if (n > kNumCSymbols) + return S_FALSE; + m_CHuffmanDecoder.Symbol = -1; + Byte lens[kNumCSymbols]; + int i = 0; + while (i < n) + { + int c = m_LevelHuffman.Decode(&m_InBitStream); + if (c < kNumSpecLevelSymbols) + { + if (c == 0) + c = 1; + else if (c == 1) + c = ReadBits(4) + 3; + else + c = ReadBits(kNumCBits) + 20; + while (--c >= 0) + { + if (i > kNumCSymbols) + return S_FALSE; + lens[i++] = 0; + } + } + else + lens[i++] = (Byte)(c - 2); + } + while (i < kNumCSymbols) + lens[i++] = 0; + m_CHuffmanDecoder.SetCodeLengths(lens); + } + return S_OK; +} + +STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + if (outSize == NULL) + return E_INVALIDARG; + + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + + UInt64 pos = 0; + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(false); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + + CCoderReleaser coderReleaser(this); + + int pbit; + if (m_NumDictBits <= 13) + pbit = 4; + else + pbit = 5; + + UInt32 blockSize = 0; + + while(pos < *outSize) + { + // for (i = 0; i < dictSize; i++) dtext[i] = 0x20; + + if (blockSize == 0) + { + if (progress != NULL) + { + UInt64 packSize = m_InBitStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &pos)); + } + blockSize = ReadBits(kBlockSizeBits); + ReadLevelTable(); + ReadCTable(); + RINOK(ReadPTable(pbit)); + } + blockSize--; + UInt32 c = m_CHuffmanDecoder.Decode(&m_InBitStream); + if (c < 256) + { + m_OutWindowStream.PutByte((Byte)c); + pos++; + } + else if (c >= kNumCSymbols) + return S_FALSE; + else + { + // offset = (interface->method == LARC_METHOD_NUM) ? 0x100 - 2 : 0x100 - 3; + UInt32 len = c - 256 + kMinMatch; + UInt32 distance = m_PHuffmanDecoder.Decode(&m_InBitStream); + if (distance != 0) + distance = (1 << (distance - 1)) + ReadBits(distance - 1); + if (distance >= pos) + return S_FALSE; + if (pos + len > *outSize) + len = (UInt32)(*outSize - pos); + pos += len; + m_OutWindowStream.CopyBlock(distance, len); + } + } + coderReleaser.NeedFlush = false; + return m_OutWindowStream.Flush(); +} + +STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress);} + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const CLzOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +}}} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/LzhDecoder.h b/desmume/src/windows/7z/CPP/7zip/Compress/LzhDecoder.h new file mode 100644 index 000000000..3048797fb --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/LzhDecoder.h @@ -0,0 +1,106 @@ +// LzhDecoder.h + +#ifndef __COMPRESS_LZH_DECODER_H +#define __COMPRESS_LZH_DECODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "../Common/InBuffer.h" + +#include "BitmDecoder.h" +#include "HuffmanDecoder.h" +#include "LzOutWindow.h" + +namespace NCompress { +namespace NLzh { +namespace NDecoder { + +const int kMaxHuffmanLen = 16; // Check it + +const int kNumSpecLevelSymbols = 3; +const int kNumLevelSymbols = kNumSpecLevelSymbols + kMaxHuffmanLen; + +const int kDictBitsMax = 16; +const int kNumDistanceSymbols = kDictBitsMax + 1; + +const int kMaxMatch = 256; +const int kMinMatch = 3; +const int kNumCSymbols = 256 + kMaxMatch + 2 - kMinMatch; + +template +class CHuffmanDecoder:public NCompress::NHuffman::CDecoder +{ +public: + int Symbol; + template + UInt32 Decode(TBitDecoder *bitStream) + { + if (Symbol >= 0) + return (UInt32)Symbol; + return DecodeSymbol(bitStream); + } +}; + +class CCoder : + public ICompressCoder, + public CMyUnknownImp +{ + CLzOutWindow m_OutWindowStream; + NBitm::CDecoder m_InBitStream; + + int m_NumDictBits; + + CHuffmanDecoder m_LevelHuffman; + CHuffmanDecoder m_PHuffmanDecoder; + CHuffmanDecoder m_CHuffmanDecoder; + + void ReleaseStreams() + { + m_OutWindowStream.ReleaseStream(); + m_InBitStream.ReleaseStream(); + } + + class CCoderReleaser + { + CCoder *m_Coder; + public: + bool NeedFlush; + CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {} + ~CCoderReleaser() + { + if (NeedFlush) + m_Coder->m_OutWindowStream.Flush(); + m_Coder->ReleaseStreams(); + } + }; + friend class CCoderReleaser; + + void MakeTable(int nchar, Byte *bitlen, int tablebits, + UInt32 *table, int tablesize); + + UInt32 ReadBits(int numBits); + HRESULT ReadLevelTable(); + HRESULT ReadPTable(int numBits); + HRESULT ReadCTable(); + +public: + + MY_UNKNOWN_IMP + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + void SetDictionary(int numDictBits) { m_NumDictBits = numDictBits; } + CCoder(): m_NumDictBits(0) {} +}; + +}}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/LzmaDecoder.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/LzmaDecoder.cpp new file mode 100644 index 000000000..61a8cc009 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/LzmaDecoder.cpp @@ -0,0 +1,190 @@ +// LzmaDecoder.cpp + +#include "StdAfx.h" + +extern "C" +{ +#include "../../../C/Alloc.h" +} + +#include "../Common/StreamUtils.h" + +#include "LzmaDecoder.h" + +static HRESULT SResToHRESULT(SRes res) +{ + switch(res) + { + case SZ_OK: return S_OK; + case SZ_ERROR_MEM: return E_OUTOFMEMORY; + case SZ_ERROR_PARAM: return E_INVALIDARG; + case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL; + // case SZ_ERROR_PROGRESS: return E_ABORT; + case SZ_ERROR_DATA: return S_FALSE; + } + return E_FAIL; +} + +namespace NCompress { +namespace NLzma { + +static const UInt32 kInBufSize = 1 << 20; + +CDecoder::CDecoder(): _inBuf(0), _outSizeDefined(false), FinishStream(false) +{ + LzmaDec_Construct(&_state); +} + +static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } +static void SzFree(void *p, void *address) { p = p; MyFree(address); } +static ISzAlloc g_Alloc = { SzAlloc, SzFree }; + +CDecoder::~CDecoder() +{ + LzmaDec_Free(&_state, &g_Alloc); + MyFree(_inBuf); +} + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size) +{ + RINOK(SResToHRESULT(LzmaDec_Allocate(&_state, prop, size, &g_Alloc))); + + if (_inBuf == 0) + { + _inBuf = (Byte *)MyAlloc(kInBufSize); + if (_inBuf == 0) + return E_OUTOFMEMORY; + } + + return S_OK; +} + +STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) { *value = _inSizeProcessed; return S_OK; } +STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; } +STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; } + +STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) +{ + _outSizeDefined = (outSize != NULL); + if (_outSizeDefined) + _outSize = *outSize; + + LzmaDec_Init(&_state); + + _inPos = _inSize = 0; + _inSizeProcessed = _outSizeProcessed = 0; + return S_OK; +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + if (_inBuf == 0) + return S_FALSE; + SetOutStreamSize(outSize); + + for (;;) + { + if (_inPos == _inSize) + { + _inPos = _inSize = 0; + RINOK(inStream->Read(_inBuf, kInBufSize, &_inSize)); + } + + SizeT dicPos = _state.dicPos; + SizeT curSize = _state.dicBufSize - dicPos; + const UInt32 kStepSize = ((UInt32)1 << 22); + if (curSize > kStepSize) + curSize = (SizeT)kStepSize; + + ELzmaFinishMode finishMode = LZMA_FINISH_ANY; + if (_outSizeDefined) + { + const UInt64 rem = _outSize - _outSizeProcessed; + if (rem < curSize) + { + curSize = (SizeT)rem; + if (FinishStream) + finishMode = LZMA_FINISH_END; + } + } + + SizeT inSizeProcessed = _inSize - _inPos; + ELzmaStatus status; + SRes res = LzmaDec_DecodeToDic(&_state, dicPos + curSize, _inBuf + _inPos, &inSizeProcessed, finishMode, &status); + + _inPos += (UInt32)inSizeProcessed; + _inSizeProcessed += inSizeProcessed; + SizeT outSizeProcessed = _state.dicPos - dicPos; + _outSizeProcessed += outSizeProcessed; + + bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0); + bool stopDecoding = (_outSizeDefined && _outSizeProcessed >= _outSize); + + if (res != 0 || _state.dicPos == _state.dicBufSize || finished || stopDecoding) + { + HRESULT res2 = WriteStream(outStream, _state.dic, _state.dicPos); + if (res != 0) + return S_FALSE; + RINOK(res2); + if (stopDecoding) + return S_OK; + if (finished) + return (status == LZMA_STATUS_FINISHED_WITH_MARK ? S_OK : S_FALSE); + } + if (_state.dicPos == _state.dicBufSize) + _state.dicPos = 0; + + if (progress != NULL) + { + RINOK(progress->SetRatioInfo(&_inSizeProcessed, &_outSizeProcessed)); + } + } +} + +#ifndef NO_READ_FROM_CODER + +STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize) + *processedSize = 0; + do + { + if (_inPos == _inSize) + { + _inPos = _inSize = 0; + RINOK(_inStream->Read(_inBuf, kInBufSize, &_inSize)); + } + { + SizeT inProcessed = _inSize - _inPos; + + if (_outSizeDefined) + { + const UInt64 rem = _outSize - _outSizeProcessed; + if (rem < size) + size = (UInt32)rem; + } + + SizeT outProcessed = size; + ELzmaStatus status; + SRes res = LzmaDec_DecodeToBuf(&_state, (Byte *)data, &outProcessed, + _inBuf + _inPos, &inProcessed, LZMA_FINISH_ANY, &status); + _inPos += (UInt32)inProcessed; + _inSizeProcessed += inProcessed; + _outSizeProcessed += outProcessed; + size -= (UInt32)outProcessed; + data = (Byte *)data + outProcessed; + if (processedSize) + *processedSize += (UInt32)outProcessed; + RINOK(SResToHRESULT(res)); + if (inProcessed == 0 && outProcessed == 0) + return S_OK; + } + } + while (size != 0); + return S_OK; +} + +#endif + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/LzmaDecoder.h b/desmume/src/windows/7z/CPP/7zip/Compress/LzmaDecoder.h new file mode 100644 index 000000000..16b4791b0 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/LzmaDecoder.h @@ -0,0 +1,73 @@ +// LzmaDecoder.h + +#ifndef __LZMA_DECODER_H +#define __LZMA_DECODER_H + +extern "C" +{ +#include "../../../C/LzmaDec.h" +} + +#include "../../Common/MyCom.h" +#include "../ICoder.h" + +namespace NCompress { +namespace NLzma { + +class CDecoder: + public ICompressCoder, + public ICompressSetDecoderProperties2, + public ICompressGetInStreamProcessedSize, + #ifndef NO_READ_FROM_CODER + public ICompressSetInStream, + public ICompressSetOutStreamSize, + public ISequentialInStream, + #endif + public CMyUnknownImp +{ + CMyComPtr _inStream; + Byte *_inBuf; + UInt32 _inPos; + UInt32 _inSize; + CLzmaDec _state; + bool _outSizeDefined; + UInt64 _outSize; + UInt64 _inSizeProcessed; + UInt64 _outSizeProcessed; +public: + + #ifndef NO_READ_FROM_CODER + MY_UNKNOWN_IMP5( + ICompressSetDecoderProperties2, + ICompressGetInStreamProcessedSize, + ICompressSetInStream, + ICompressSetOutStreamSize, + ISequentialInStream) + #else + MY_UNKNOWN_IMP2( + ICompressSetDecoderProperties2, + ICompressGetInStreamProcessedSize) + #endif + + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); + + #ifndef NO_READ_FROM_CODER + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + #endif + + bool FinishStream; + + CDecoder(); + virtual ~CDecoder(); + +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/LzmaRegister.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/LzmaRegister.cpp new file mode 100644 index 000000000..9c67eaf94 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/LzmaRegister.cpp @@ -0,0 +1,20 @@ +// LzmaRegister.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "LzmaDecoder.h" + +static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::NLzma::CDecoder); } +#ifndef EXTRACT_ONLY +#include "LzmaEncoder.h" +static void *CreateCodecOut() { return (void *)(ICompressCoder *)(new NCompress::NLzma::CEncoder); } +#else +#define CreateCodecOut 0 +#endif + +static CCodecInfo g_CodecInfo = + { CreateCodec, CreateCodecOut, 0x030101, L"LZMA", 1, false }; + +REGISTER_CODEC(LZMA) diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/Mtf8.h b/desmume/src/windows/7z/CPP/7zip/Compress/Mtf8.h new file mode 100644 index 000000000..e5e0046de --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/Mtf8.h @@ -0,0 +1,196 @@ +// Mtf8.h + +#ifndef __COMPRESS_MTF8_H +#define __COMPRESS_MTF8_H + +#include "../../Common/Types.h" + +namespace NCompress { + +struct CMtf8Encoder +{ + Byte Buf[256]; + + int FindAndMove(Byte v) + { + int pos; + for (pos = 0; Buf[pos] != v; pos++); + int resPos = pos; + for (; pos >= 8; pos -= 8) + { + Buf[pos] = Buf[pos - 1]; + Buf[pos - 1] = Buf[pos - 2]; + Buf[pos - 2] = Buf[pos - 3]; + Buf[pos - 3] = Buf[pos - 4]; + Buf[pos - 4] = Buf[pos - 5]; + Buf[pos - 5] = Buf[pos - 6]; + Buf[pos - 6] = Buf[pos - 7]; + Buf[pos - 7] = Buf[pos - 8]; + } + for (; pos > 0; pos--) + Buf[pos] = Buf[pos - 1]; + Buf[0] = v; + return resPos; + } +}; + +/* +struct CMtf8Decoder +{ + Byte Buf[256]; + + void Init(int) {}; + Byte GetHead() const { return Buf[0]; } + Byte GetAndMove(int pos) + { + Byte res = Buf[pos]; + for (; pos >= 8; pos -= 8) + { + Buf[pos] = Buf[pos - 1]; + Buf[pos - 1] = Buf[pos - 2]; + Buf[pos - 2] = Buf[pos - 3]; + Buf[pos - 3] = Buf[pos - 4]; + Buf[pos - 4] = Buf[pos - 5]; + Buf[pos - 5] = Buf[pos - 6]; + Buf[pos - 6] = Buf[pos - 7]; + Buf[pos - 7] = Buf[pos - 8]; + } + for (; pos > 0; pos--) + Buf[pos] = Buf[pos - 1]; + Buf[0] = res; + return res; + } +}; +*/ + +#ifdef _WIN64 +#define MODE_64BIT +#endif + +#ifdef MODE_64BIT +typedef UInt64 CMtfVar; +#define MTF_MOVS 3 +#else +typedef UInt32 CMtfVar; +#define MTF_MOVS 2 +#endif + +#define MTF_MASK ((1 << MTF_MOVS) - 1) + + +struct CMtf8Decoder +{ + CMtfVar Buf[256 >> MTF_MOVS]; + + void StartInit() { memset(Buf, 0, sizeof(Buf)); } + void Add(unsigned int pos, Byte val) { Buf[pos >> MTF_MOVS] |= ((CMtfVar)val << ((pos & MTF_MASK) << 3)); } + Byte GetHead() const { return (Byte)Buf[0]; } + Byte GetAndMove(unsigned int pos) + { + UInt32 lim = ((UInt32)pos >> MTF_MOVS); + pos = (pos & MTF_MASK) << 3; + CMtfVar prev = (Buf[lim] >> pos) & 0xFF; + + UInt32 i = 0; + if ((lim & 1) != 0) + { + CMtfVar next = Buf[0]; + Buf[0] = (next << 8) | prev; + prev = (next >> (MTF_MASK << 3)); + i = 1; + lim -= 1; + } + for (; i < lim; i += 2) + { + CMtfVar next = Buf[i]; + Buf[i] = (next << 8) | prev; + prev = (next >> (MTF_MASK << 3)); + next = Buf[i + 1]; + Buf[i + 1] = (next << 8) | prev; + prev = (next >> (MTF_MASK << 3)); + } + CMtfVar next = Buf[i]; + CMtfVar mask = (((CMtfVar)0x100 << pos) - 1); + Buf[i] = (next & ~mask) | (((next << 8) | prev) & mask); + return (Byte)Buf[0]; + } +}; + +/* +const int kSmallSize = 64; +class CMtf8Decoder +{ + Byte SmallBuffer[kSmallSize]; + int SmallSize; + Byte Counts[16]; + int Size; +public: + Byte Buf[256]; + + Byte GetHead() const + { + if (SmallSize > 0) + return SmallBuffer[kSmallSize - SmallSize]; + return Buf[0]; + } + + void Init(int size) + { + Size = size; + SmallSize = 0; + for (int i = 0; i < 16; i++) + { + Counts[i] = ((size >= 16) ? 16 : size); + size -= Counts[i]; + } + } + + Byte GetAndMove(int pos) + { + if (pos < SmallSize) + { + Byte *p = SmallBuffer + kSmallSize - SmallSize; + Byte res = p[pos]; + for (; pos > 0; pos--) + p[pos] = p[pos - 1]; + SmallBuffer[kSmallSize - SmallSize] = res; + return res; + } + if (SmallSize == kSmallSize) + { + int i = Size - 1; + int g = 16; + do + { + g--; + int offset = (g << 4); + for (int t = Counts[g] - 1; t >= 0; t--, i--) + Buf[i] = Buf[offset + t]; + } + while(g != 0); + + for (i = kSmallSize - 1; i >= 0; i--) + Buf[i] = SmallBuffer[i]; + Init(Size); + } + pos -= SmallSize; + int g; + for (g = 0; pos >= Counts[g]; g++) + pos -= Counts[g]; + int offset = (g << 4); + Byte res = Buf[offset + pos]; + for (pos; pos < 16 - 1; pos++) + Buf[offset + pos] = Buf[offset + pos + 1]; + + SmallSize++; + SmallBuffer[kSmallSize - SmallSize] = res; + + Counts[g]--; + return res; + } +}; +*/ + +} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/PpmdContext.h b/desmume/src/windows/7z/CPP/7zip/Compress/PpmdContext.h new file mode 100644 index 000000000..11502a951 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/PpmdContext.h @@ -0,0 +1,489 @@ +// PpmdContext.h +// This code is based on Dmitry Shkarin's PPMdH code + +#ifndef __COMPRESS_PPMD_CONTEXT_H +#define __COMPRESS_PPMD_CONTEXT_H + +#include "../../Common/Types.h" + +#include "PpmdSubAlloc.h" +#include "RangeCoder.h" + +namespace NCompress { +namespace NPpmd { + +const int INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS, + INTERVAL=1 << INT_BITS, BIN_SCALE=1 << TOT_BITS, MAX_FREQ=124; + +struct SEE2_CONTEXT +{ + // SEE-contexts for PPM-contexts with masked symbols + UInt16 Summ; + Byte Shift, Count; + void init(int InitVal) { Summ = (UInt16)(InitVal << (Shift=PERIOD_BITS-4)); Count=4; } + unsigned int getMean() + { + unsigned int RetVal=(Summ >> Shift); + Summ = (UInt16)(Summ - RetVal); + return RetVal+(RetVal == 0); + } + void update() + { + if (Shift < PERIOD_BITS && --Count == 0) + { + Summ <<= 1; + Count = (Byte)(3 << Shift++); + } + } +}; + +struct PPM_CONTEXT +{ + UInt16 NumStats; // sizeof(UInt16) > sizeof(Byte) + UInt16 SummFreq; + + struct STATE + { + Byte Symbol, Freq; + UInt16 SuccessorLow; + UInt16 SuccessorHigh; + + UInt32 GetSuccessor() const { return SuccessorLow | ((UInt32)SuccessorHigh << 16); } + void SetSuccessor(UInt32 v) + { + SuccessorLow = (UInt16)(v & 0xFFFF); + SuccessorHigh = (UInt16)((v >> 16) & 0xFFFF); + } + }; + + UInt32 Stats; + UInt32 Suffix; + + PPM_CONTEXT* createChild(CSubAllocator &subAllocator, STATE* pStats, STATE& FirstState) + { + PPM_CONTEXT* pc = (PPM_CONTEXT*) subAllocator.AllocContext(); + if (pc) + { + pc->NumStats = 1; + pc->oneState() = FirstState; + pc->Suffix = subAllocator.GetOffset(this); + pStats->SetSuccessor(subAllocator.GetOffsetNoCheck(pc)); + } + return pc; + } + + STATE& oneState() const { return (STATE&) SummFreq; } +}; + +///////////////////////////////// + +const UInt16 InitBinEsc[] = + {0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; + +struct CInfo +{ + CSubAllocator SubAllocator; + SEE2_CONTEXT SEE2Cont[25][16], DummySEE2Cont; + PPM_CONTEXT * MinContext, * MaxContext; + + PPM_CONTEXT::STATE* FoundState; // found next state transition + int NumMasked, InitEsc, OrderFall, RunLength, InitRL, MaxOrder; + Byte CharMask[256], NS2Indx[256], NS2BSIndx[256], HB2Flag[256]; + Byte EscCount, PrintCount, PrevSuccess, HiBitsFlag; + UInt16 BinSumm[128][64]; // binary SEE-contexts + + UInt16 &GetBinSumm(const PPM_CONTEXT::STATE &rs, int numStates) + { + HiBitsFlag = HB2Flag[FoundState->Symbol]; + return BinSumm[rs.Freq - 1][ + PrevSuccess + NS2BSIndx[numStates - 1] + + HiBitsFlag + 2 * HB2Flag[rs.Symbol] + + ((RunLength >> 26) & 0x20)]; + } + + PPM_CONTEXT *GetContext(UInt32 offset) const { return (PPM_CONTEXT *)SubAllocator.GetPtr(offset); } + PPM_CONTEXT *GetContextNoCheck(UInt32 offset) const { return (PPM_CONTEXT *)SubAllocator.GetPtrNoCheck(offset); } + PPM_CONTEXT::STATE *GetState(UInt32 offset) const { return (PPM_CONTEXT::STATE *)SubAllocator.GetPtr(offset); } + PPM_CONTEXT::STATE *GetStateNoCheck(UInt32 offset) const { return (PPM_CONTEXT::STATE *)SubAllocator.GetPtr(offset); } + + void RestartModelRare() + { + int i, k, m; + memset(CharMask,0,sizeof(CharMask)); + SubAllocator.InitSubAllocator(); + InitRL = -((MaxOrder < 12) ? MaxOrder : 12) - 1; + MinContext = MaxContext = (PPM_CONTEXT*) SubAllocator.AllocContext(); + MinContext->Suffix = 0; + OrderFall = MaxOrder; + MinContext->SummFreq = (UInt16)((MinContext->NumStats = 256) + 1); + FoundState = (PPM_CONTEXT::STATE*)SubAllocator.AllocUnits(256 / 2); + MinContext->Stats = SubAllocator.GetOffsetNoCheck(FoundState); + PrevSuccess = 0; + for (RunLength = InitRL, i = 0; i < 256; i++) + { + PPM_CONTEXT::STATE &state = FoundState[i]; + state.Symbol = (Byte)i; + state.Freq = 1; + state.SetSuccessor(0); + } + for (i = 0; i < 128; i++) + for (k = 0; k < 8; k++) + for ( m=0; m < 64; m += 8) + BinSumm[i][k + m] = (UInt16)(BIN_SCALE - InitBinEsc[k] / (i + 2)); + for (i = 0; i < 25; i++) + for (k = 0; k < 16; k++) + SEE2Cont[i][k].init(5*i+10); + } + + void StartModelRare(int maxOrder) + { + int i, k, m ,Step; + EscCount=PrintCount=1; + if (maxOrder < 2) + { + memset(CharMask,0,sizeof(CharMask)); + OrderFall = MaxOrder; + MinContext = MaxContext; + while (MinContext->Suffix != 0) + { + MinContext = GetContextNoCheck(MinContext->Suffix); + OrderFall--; + } + FoundState = GetState(MinContext->Stats); + MinContext = MaxContext; + } + else + { + MaxOrder = maxOrder; + RestartModelRare(); + NS2BSIndx[0] = 2 * 0; + NS2BSIndx[1] = 2 * 1; + memset(NS2BSIndx + 2, 2 * 2, 9); + memset(NS2BSIndx + 11, 2 * 3, 256 - 11); + for (i = 0; i < 3; i++) + NS2Indx[i] = (Byte)i; + for (m = i, k = Step = 1; i < 256; i++) + { + NS2Indx[i] = (Byte)m; + if ( !--k ) + { + k = ++Step; + m++; + } + } + memset(HB2Flag, 0, 0x40); + memset(HB2Flag + 0x40, 0x08, 0x100 - 0x40); + DummySEE2Cont.Shift = PERIOD_BITS; + } + } + + PPM_CONTEXT* CreateSuccessors(bool skip, PPM_CONTEXT::STATE* p1) + { + // static UpState declaration bypasses IntelC bug + // static PPM_CONTEXT::STATE UpState; + PPM_CONTEXT::STATE UpState; + + PPM_CONTEXT *pc = MinContext; + PPM_CONTEXT *UpBranch = GetContext(FoundState->GetSuccessor()); + PPM_CONTEXT::STATE * p, * ps[MAX_O], ** pps = ps; + if ( !skip ) + { + *pps++ = FoundState; + if ( !pc->Suffix ) + goto NO_LOOP; + } + if ( p1 ) + { + p = p1; + pc = GetContext(pc->Suffix); + goto LOOP_ENTRY; + } + do + { + pc = GetContext(pc->Suffix); + if (pc->NumStats != 1) + { + if ((p = GetStateNoCheck(pc->Stats))->Symbol != FoundState->Symbol) + do { p++; } while (p->Symbol != FoundState->Symbol); + } + else + p = &(pc->oneState()); +LOOP_ENTRY: + if (GetContext(p->GetSuccessor()) != UpBranch) + { + pc = GetContext(p->GetSuccessor()); + break; + } + *pps++ = p; + } + while ( pc->Suffix ); +NO_LOOP: + if (pps == ps) + return pc; + UpState.Symbol = *(Byte*) UpBranch; + UpState.SetSuccessor(SubAllocator.GetOffset(UpBranch) + 1); + if (pc->NumStats != 1) + { + if ((p = GetStateNoCheck(pc->Stats))->Symbol != UpState.Symbol) + do { p++; } while (p->Symbol != UpState.Symbol); + unsigned int cf = p->Freq-1; + unsigned int s0 = pc->SummFreq - pc->NumStats - cf; + UpState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : + ((2 * cf + 3 * s0 - 1) / (2 * s0)))); + } + else + UpState.Freq = pc->oneState().Freq; + do + { + pc = pc->createChild(SubAllocator, *--pps, UpState); + if ( !pc ) + return NULL; + } + while (pps != ps); + return pc; + } + + void UpdateModel() + { + PPM_CONTEXT::STATE fs = *FoundState, * p = NULL; + PPM_CONTEXT* pc, * Successor; + unsigned int ns1, ns, cf, sf, s0; + if (fs.Freq < MAX_FREQ / 4 && MinContext->Suffix != 0) + { + pc = GetContextNoCheck(MinContext->Suffix); + + if (pc->NumStats != 1) + { + if ((p = GetStateNoCheck(pc->Stats))->Symbol != fs.Symbol) + { + do { p++; } while (p->Symbol != fs.Symbol); + if (p[0].Freq >= p[-1].Freq) + { + _PPMD_SWAP(p[0],p[-1]); + p--; + } + } + if (p->Freq < MAX_FREQ-9) + { + p->Freq += 2; + pc->SummFreq += 2; + } + } + else + { + p = &(pc->oneState()); + p->Freq = (Byte)(p->Freq + ((p->Freq < 32) ? 1 : 0)); + } + } + if ( !OrderFall ) + { + MinContext = MaxContext = CreateSuccessors(true, p); + FoundState->SetSuccessor(SubAllocator.GetOffset(MinContext)); + if (MinContext == 0) + goto RESTART_MODEL; + return; + } + *SubAllocator.pText++ = fs.Symbol; + Successor = (PPM_CONTEXT*) SubAllocator.pText; + if (SubAllocator.pText >= SubAllocator.UnitsStart) + goto RESTART_MODEL; + if (fs.GetSuccessor() != 0) + { + if ((Byte *)GetContext(fs.GetSuccessor()) <= SubAllocator.pText) + { + PPM_CONTEXT* cs = CreateSuccessors(false, p); + fs.SetSuccessor(SubAllocator.GetOffset(cs)); + if (cs == NULL) + goto RESTART_MODEL; + } + if ( !--OrderFall ) + { + Successor = GetContext(fs.GetSuccessor()); + SubAllocator.pText -= (MaxContext != MinContext); + } + } + else + { + FoundState->SetSuccessor(SubAllocator.GetOffsetNoCheck(Successor)); + fs.SetSuccessor(SubAllocator.GetOffsetNoCheck(MinContext)); + } + s0 = MinContext->SummFreq - (ns = MinContext->NumStats) - (fs.Freq - 1); + for (pc = MaxContext; pc != MinContext; pc = GetContext(pc->Suffix)) + { + if ((ns1 = pc->NumStats) != 1) + { + if ((ns1 & 1) == 0) + { + void *ppp = SubAllocator.ExpandUnits(GetState(pc->Stats), ns1 >> 1); + pc->Stats = SubAllocator.GetOffset(ppp); + if (!ppp) + goto RESTART_MODEL; + } + pc->SummFreq = (UInt16)(pc->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & + (pc->SummFreq <= 8 * ns1))); + } + else + { + p = (PPM_CONTEXT::STATE*) SubAllocator.AllocUnits(1); + if ( !p ) + goto RESTART_MODEL; + *p = pc->oneState(); + pc->Stats = SubAllocator.GetOffsetNoCheck(p); + if (p->Freq < MAX_FREQ / 4 - 1) + p->Freq <<= 1; + else + p->Freq = MAX_FREQ - 4; + pc->SummFreq = (UInt16)(p->Freq + InitEsc + (ns > 3)); + } + cf = 2 * fs.Freq * (pc->SummFreq+6); + sf = s0 + pc->SummFreq; + if (cf < 6 * sf) + { + cf = 1 + (cf > sf)+(cf >= 4 * sf); + pc->SummFreq += 3; + } + else + { + cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf); + pc->SummFreq = (UInt16)(pc->SummFreq + cf); + } + p = GetState(pc->Stats) + ns1; + p->SetSuccessor(SubAllocator.GetOffset(Successor)); + p->Symbol = fs.Symbol; + p->Freq = (Byte)cf; + pc->NumStats = (UInt16)++ns1; + } + MaxContext = MinContext = GetContext(fs.GetSuccessor()); + return; +RESTART_MODEL: + RestartModelRare(); + EscCount = 0; + PrintCount = 0xFF; + } + + void ClearMask() + { + EscCount = 1; + memset(CharMask, 0, sizeof(CharMask)); + // if (++PrintCount == 0) + // PrintInfo(DecodedFile,EncodedFile); + } + + void update1(PPM_CONTEXT::STATE* p) + { + (FoundState = p)->Freq += 4; + MinContext->SummFreq += 4; + if (p[0].Freq > p[-1].Freq) + { + _PPMD_SWAP(p[0],p[-1]); + FoundState = --p; + if (p->Freq > MAX_FREQ) + rescale(); + } + } + + + void update2(PPM_CONTEXT::STATE* p) + { + (FoundState = p)->Freq += 4; + MinContext->SummFreq += 4; + if (p->Freq > MAX_FREQ) + rescale(); + EscCount++; + RunLength = InitRL; + } + + SEE2_CONTEXT* makeEscFreq2(int Diff, UInt32 &scale) + { + SEE2_CONTEXT* psee2c; + if (MinContext->NumStats != 256) + { + psee2c = SEE2Cont[NS2Indx[Diff-1]] + + (Diff < (GetContext(MinContext->Suffix))->NumStats - MinContext->NumStats) + + 2 * (MinContext->SummFreq < 11 * MinContext->NumStats) + + 4 * (NumMasked > Diff) + + HiBitsFlag; + scale = psee2c->getMean(); + } + else + { + psee2c = &DummySEE2Cont; + scale = 1; + } + return psee2c; + } + + + + void rescale() + { + int OldNS = MinContext->NumStats, i = MinContext->NumStats - 1, Adder, EscFreq; + PPM_CONTEXT::STATE* p1, * p; + PPM_CONTEXT::STATE *stats = GetStateNoCheck(MinContext->Stats); + for (p = FoundState; p != stats; p--) + _PPMD_SWAP(p[0], p[-1]); + stats->Freq += 4; + MinContext->SummFreq += 4; + EscFreq = MinContext->SummFreq - p->Freq; + Adder = (OrderFall != 0); + p->Freq = (Byte)((p->Freq + Adder) >> 1); + MinContext->SummFreq = p->Freq; + do + { + EscFreq -= (++p)->Freq; + p->Freq = (Byte)((p->Freq + Adder) >> 1); + MinContext->SummFreq = (UInt16)(MinContext->SummFreq + p->Freq); + if (p[0].Freq > p[-1].Freq) + { + PPM_CONTEXT::STATE tmp = *(p1 = p); + do + { + p1[0] = p1[-1]; + } + while (--p1 != stats && tmp.Freq > p1[-1].Freq); + *p1 = tmp; + } + } + while ( --i ); + if (p->Freq == 0) + { + do { i++; } while ((--p)->Freq == 0); + EscFreq += i; + MinContext->NumStats = (UInt16)(MinContext->NumStats - i); + if (MinContext->NumStats == 1) + { + PPM_CONTEXT::STATE tmp = *stats; + do { tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1)); EscFreq >>= 1; } while (EscFreq > 1); + SubAllocator.FreeUnits(stats, (OldNS+1) >> 1); + *(FoundState = &MinContext->oneState()) = tmp; return; + } + } + EscFreq -= (EscFreq >> 1); + MinContext->SummFreq = (UInt16)(MinContext->SummFreq + EscFreq); + int n0 = (OldNS+1) >> 1, n1 = (MinContext->NumStats + 1) >> 1; + if (n0 != n1) + MinContext->Stats = SubAllocator.GetOffset(SubAllocator.ShrinkUnits(stats, n0, n1)); + FoundState = GetState(MinContext->Stats); + } + + void NextContext() + { + PPM_CONTEXT *c = GetContext(FoundState->GetSuccessor()); + if (!OrderFall && (Byte *)c > SubAllocator.pText) + MinContext = MaxContext = c; + else + { + UpdateModel(); + if (EscCount == 0) + ClearMask(); + } + } +}; + +// Tabulated escapes for exponential symbol distribution +const Byte ExpEscape[16]={ 25,14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; +#define GET_MEAN(SUMM,SHIFT,ROUND) ((SUMM+(1 << (SHIFT-ROUND))) >> (SHIFT)) + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/PpmdDecode.h b/desmume/src/windows/7z/CPP/7zip/Compress/PpmdDecode.h new file mode 100644 index 000000000..3ad037da6 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/PpmdDecode.h @@ -0,0 +1,154 @@ +// PpmdDecode.h +// This code is based on Dmitry Shkarin's PPMdH code + +#ifndef __COMPRESS_PPMD_DECODE_H +#define __COMPRESS_PPMD_DECODE_H + +#include "PpmdContext.h" + +namespace NCompress { +namespace NPpmd { + +class CRangeDecoderVirt +{ +public: + virtual UInt32 GetThreshold(UInt32 total) = 0; + virtual void Decode(UInt32 start, UInt32 size) = 0; + virtual UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) = 0; +}; + +typedef NRangeCoder::CDecoder CRangeDecoderMy; + +class CRangeDecoder:public CRangeDecoderVirt, public CRangeDecoderMy +{ + UInt32 GetThreshold(UInt32 total) { return CRangeDecoderMy::GetThreshold(total); } + void Decode(UInt32 start, UInt32 size) { CRangeDecoderMy::Decode(start, size); } + UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) { return CRangeDecoderMy::DecodeBit(size0, numTotalBits); } +}; + +struct CDecodeInfo: public CInfo +{ + void DecodeBinSymbol(CRangeDecoderVirt *rangeDecoder) + { + PPM_CONTEXT::STATE& rs = MinContext->oneState(); + UInt16& bs = GetBinSumm(rs, GetContextNoCheck(MinContext->Suffix)->NumStats); + if (rangeDecoder->DecodeBit(bs, TOT_BITS) == 0) + { + FoundState = &rs; + rs.Freq = (Byte)(rs.Freq + (rs.Freq < 128 ? 1: 0)); + bs = (UInt16)(bs + INTERVAL - GET_MEAN(bs, PERIOD_BITS, 2)); + PrevSuccess = 1; + RunLength++; + } + else + { + bs = (UInt16)(bs - GET_MEAN(bs, PERIOD_BITS, 2)); + InitEsc = ExpEscape[bs >> 10]; + NumMasked = 1; + CharMask[rs.Symbol] = EscCount; + PrevSuccess = 0; + FoundState = NULL; + } + } + + void DecodeSymbol1(CRangeDecoderVirt *rangeDecoder) + { + PPM_CONTEXT::STATE* p = GetStateNoCheck(MinContext->Stats); + int i, count, hiCnt; + if ((count = rangeDecoder->GetThreshold(MinContext->SummFreq)) < (hiCnt = p->Freq)) + { + PrevSuccess = (2 * hiCnt > MinContext->SummFreq); + RunLength += PrevSuccess; + rangeDecoder->Decode(0, p->Freq); // MinContext->SummFreq); + (FoundState = p)->Freq = (Byte)(hiCnt += 4); + MinContext->SummFreq += 4; + if (hiCnt > MAX_FREQ) + rescale(); + return; + } + PrevSuccess = 0; + i = MinContext->NumStats - 1; + while ((hiCnt += (++p)->Freq) <= count) + if (--i == 0) + { + HiBitsFlag = HB2Flag[FoundState->Symbol]; + rangeDecoder->Decode(hiCnt, MinContext->SummFreq - hiCnt); // , MinContext->SummFreq); + CharMask[p->Symbol] = EscCount; + i = (NumMasked = MinContext->NumStats)-1; + FoundState = NULL; + do { CharMask[(--p)->Symbol] = EscCount; } while ( --i ); + return; + } + rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , MinContext->SummFreq); + update1(p); + } + + + void DecodeSymbol2(CRangeDecoderVirt *rangeDecoder) + { + int count, hiCnt, i = MinContext->NumStats - NumMasked; + UInt32 freqSum; + SEE2_CONTEXT* psee2c = makeEscFreq2(i, freqSum); + PPM_CONTEXT::STATE* ps[256], ** pps = ps, * p = GetStateNoCheck(MinContext->Stats)-1; + hiCnt = 0; + do + { + do { p++; } while (CharMask[p->Symbol] == EscCount); + hiCnt += p->Freq; + *pps++ = p; + } + while ( --i ); + + freqSum += hiCnt; + count = rangeDecoder->GetThreshold(freqSum); + + p = *(pps = ps); + if (count < hiCnt) + { + hiCnt = 0; + while ((hiCnt += p->Freq) <= count) + p=*++pps; + rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , freqSum); + + psee2c->update(); + update2(p); + } + else + { + rangeDecoder->Decode(hiCnt, freqSum - hiCnt); // , freqSum); + + i = MinContext->NumStats - NumMasked; + pps--; + do { CharMask[(*++pps)->Symbol] = EscCount; } while ( --i ); + psee2c->Summ = (UInt16)(psee2c->Summ + freqSum); + NumMasked = MinContext->NumStats; + } + } + + int DecodeSymbol(CRangeDecoderVirt *rangeDecoder) + { + if (MinContext->NumStats != 1) + DecodeSymbol1(rangeDecoder); + else + DecodeBinSymbol(rangeDecoder); + while ( !FoundState ) + { + do + { + OrderFall++; + MinContext = GetContext(MinContext->Suffix); + if (MinContext == 0) + return -1; + } + while (MinContext->NumStats == NumMasked); + DecodeSymbol2(rangeDecoder); + } + Byte symbol = FoundState->Symbol; + NextContext(); + return symbol; + } +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/PpmdDecoder.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/PpmdDecoder.cpp new file mode 100644 index 000000000..9049a472b --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/PpmdDecoder.cpp @@ -0,0 +1,182 @@ +// PpmdDecoder.cpp + +#include "StdAfx.h" + +#include "Common/Defs.h" +#include "Windows/Defs.h" + +#include "PpmdDecoder.h" + +namespace NCompress { +namespace NPpmd { + +const int kLenIdFinished = -1; +const int kLenIdNeedInit = -2; + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size) +{ + if (size < 5) + return E_INVALIDARG; + _order = properties[0]; + _usedMemorySize = 0; + for (int i = 0; i < 4; i++) + _usedMemorySize += ((UInt32)(properties[1 + i])) << (i * 8); + + if (_usedMemorySize > kMaxMemBlockSize) + return E_NOTIMPL; + + if (!_rangeDecoder.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_info.SubAllocator.StartSubAllocator(_usedMemorySize)) + return E_OUTOFMEMORY; + + return S_OK; +} + +class CDecoderFlusher +{ + CDecoder *_coder; +public: + bool NeedFlush; + CDecoderFlusher(CDecoder *coder): _coder(coder), NeedFlush(true) {} + ~CDecoderFlusher() + { + if (NeedFlush) + _coder->Flush(); + _coder->ReleaseStreams(); + } +}; + +HRESULT CDecoder::CodeSpec(UInt32 size, Byte *memStream) +{ + if (_outSizeDefined) + { + const UInt64 rem = _outSize - _processedSize; + if (size > rem) + size = (UInt32)rem; + } + const UInt32 startSize = size; + + if (_remainLen == kLenIdFinished) + return S_OK; + if (_remainLen == kLenIdNeedInit) + { + _rangeDecoder.Init(); + _remainLen = 0; + _info.MaxOrder = 0; + _info.StartModelRare(_order); + } + while (size != 0) + { + int symbol = _info.DecodeSymbol(&_rangeDecoder); + if (symbol < 0) + { + _remainLen = kLenIdFinished; + break; + } + if (memStream != 0) + *memStream++ = (Byte)symbol; + else + _outStream.WriteByte((Byte)symbol); + size--; + } + _processedSize += startSize - size; + return S_OK; +} + +STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + if (!_outStream.Create(1 << 20)) + return E_OUTOFMEMORY; + + SetInStream(inStream); + _outStream.SetStream(outStream); + SetOutStreamSize(outSize); + CDecoderFlusher flusher(this); + + for (;;) + { + _processedSize = _outStream.GetProcessedSize(); + UInt32 curSize = (1 << 18); + RINOK(CodeSpec(curSize, NULL)); + if (_remainLen == kLenIdFinished) + break; + if (progress != NULL) + { + UInt64 inSize = _rangeDecoder.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&inSize, &_processedSize)); + } + if (_outSizeDefined) + if (_outStream.GetProcessedSize() >= _outSize) + break; + } + flusher.NeedFlush = false; + return Flush(); +} + +#ifdef _NO_EXCEPTIONS + +#define PPMD_TRY_BEGIN +#define PPMD_TRY_END + +#else + +#define PPMD_TRY_BEGIN try { +#define PPMD_TRY_END } \ + catch(const CInBufferException &e) { return e.ErrorCode; } \ + catch(const COutBufferException &e) { return e.ErrorCode; } \ + catch(...) { return S_FALSE; } + +#endif + + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + PPMD_TRY_BEGIN + return CodeReal(inStream, outStream, inSize, outSize, progress); + PPMD_TRY_END +} + +STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) +{ + _rangeDecoder.SetStream(inStream); + return S_OK; +} + +STDMETHODIMP CDecoder::ReleaseInStream() +{ + _rangeDecoder.ReleaseStream(); + return S_OK; +} + +STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) +{ + _outSizeDefined = (outSize != NULL); + if (_outSizeDefined) + _outSize = *outSize; + _processedSize = 0; + _remainLen = kLenIdNeedInit; + _outStream.Init(); + return S_OK; +} + +#ifndef NO_READ_FROM_CODER + +STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + PPMD_TRY_BEGIN + if (processedSize) + *processedSize = 0; + const UInt64 startPos = _processedSize; + RINOK(CodeSpec(size, (Byte *)data)); + if (processedSize) + *processedSize = (UInt32)(_processedSize - startPos); + return Flush(); + PPMD_TRY_END +} + +#endif + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/PpmdDecoder.h b/desmume/src/windows/7z/CPP/7zip/Compress/PpmdDecoder.h new file mode 100644 index 000000000..e14d37303 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/PpmdDecoder.h @@ -0,0 +1,86 @@ +// PpmdDecoder.h + +#ifndef __COMPRESS_PPMD_DECODER_H +#define __COMPRESS_PPMD_DECODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "../Common/OutBuffer.h" + +#include "PpmdDecode.h" +#include "RangeCoder.h" + +namespace NCompress { +namespace NPpmd { + +class CDecoder : + public ICompressCoder, + public ICompressSetDecoderProperties2, + #ifndef NO_READ_FROM_CODER + public ICompressSetInStream, + public ICompressSetOutStreamSize, + public ISequentialInStream, + #endif + public CMyUnknownImp +{ + CRangeDecoder _rangeDecoder; + + COutBuffer _outStream; + + CDecodeInfo _info; + + Byte _order; + UInt32 _usedMemorySize; + + int _remainLen; + UInt64 _outSize; + bool _outSizeDefined; + UInt64 _processedSize; + + HRESULT CodeSpec(UInt32 num, Byte *memStream); + +public: + + #ifndef NO_READ_FROM_CODER + MY_UNKNOWN_IMP4( + ICompressSetDecoderProperties2, + ICompressSetInStream, + ICompressSetOutStreamSize, + ISequentialInStream) + #else + MY_UNKNOWN_IMP1( + ICompressSetDecoderProperties2) + #endif + + void ReleaseStreams() + { + ReleaseInStream(); + _outStream.ReleaseStream(); + } + + HRESULT Flush() { return _outStream.Flush(); } + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); + + #ifndef NO_READ_FROM_CODER + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + #endif + + CDecoder(): _outSizeDefined(false) {} +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/PpmdRegister.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/PpmdRegister.cpp new file mode 100644 index 000000000..eed3d7b16 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/PpmdRegister.cpp @@ -0,0 +1,20 @@ +// PpmdRegister.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "PpmdDecoder.h" + +static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::NPpmd::CDecoder); } +#ifndef EXTRACT_ONLY +#include "PpmdEncoder.h" +static void *CreateCodecOut() { return (void *)(ICompressCoder *)(new NCompress::NPpmd::CEncoder); } +#else +#define CreateCodecOut 0 +#endif + +static CCodecInfo g_CodecInfo = + { CreateCodec, CreateCodecOut, 0x030401, L"PPMD", 1, false }; + +REGISTER_CODEC(PPMD) diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/PpmdSubAlloc.h b/desmume/src/windows/7z/CPP/7zip/Compress/PpmdSubAlloc.h new file mode 100644 index 000000000..fdea6d5df --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/PpmdSubAlloc.h @@ -0,0 +1,295 @@ +// PpmdSubAlloc.h +// This code is based on Dmitry Shkarin's PPMdH code + +#ifndef __COMPRESS_PPMD_SUB_ALLOC_H +#define __COMPRESS_PPMD_SUB_ALLOC_H + +extern "C" +{ +#include "../../../C/Alloc.h" +} + +#include "PpmdType.h" + +const UINT N1=4, N2=4, N3=4, N4=(128+3-1*N1-2*N2-3*N3)/4; +const UINT UNIT_SIZE=12, N_INDEXES=N1+N2+N3+N4; + +// Extra 1 * UNIT_SIZE for NULL support +// Extra 2 * UNIT_SIZE for s0 in GlueFreeBlocks() +const UInt32 kExtraSize = (UNIT_SIZE * 3); +const UInt32 kMaxMemBlockSize = 0xFFFFFFFF - kExtraSize; + +struct MEM_BLK +{ + UInt16 Stamp, NU; + UInt32 Next, Prev; + void InsertAt(Byte *Base, UInt32 p) + { + Prev = p; + MEM_BLK *pp = (MEM_BLK *)(Base + p); + Next = pp->Next; + pp->Next = ((MEM_BLK *)(Base + Next))->Prev = (UInt32)((Byte *)this - Base); + } + void Remove(Byte *Base) + { + ((MEM_BLK *)(Base + Prev))->Next = Next; + ((MEM_BLK *)(Base + Next))->Prev = Prev; + } +}; + + +class CSubAllocator +{ + UInt32 SubAllocatorSize; + Byte Indx2Units[N_INDEXES], Units2Indx[128], GlueCount; + UInt32 FreeList[N_INDEXES]; + + Byte *Base; + Byte *HeapStart, *LoUnit, *HiUnit; +public: + Byte *pText, *UnitsStart; + CSubAllocator(): + SubAllocatorSize(0), + GlueCount(0), + LoUnit(0), + HiUnit(0), + pText(0), + UnitsStart(0) + { + memset(Indx2Units, 0, sizeof(Indx2Units)); + memset(FreeList, 0, sizeof(FreeList)); + } + ~CSubAllocator() + { + StopSubAllocator(); + }; + + void *GetPtr(UInt32 offset) const { return (offset == 0) ? 0 : (void *)(Base + offset); } + void *GetPtrNoCheck(UInt32 offset) const { return (void *)(Base + offset); } + UInt32 GetOffset(void *ptr) const { return (ptr == 0) ? 0 : (UInt32)((Byte *)ptr - Base); } + UInt32 GetOffsetNoCheck(void *ptr) const { return (UInt32)((Byte *)ptr - Base); } + MEM_BLK *GetBlk(UInt32 offset) const { return (MEM_BLK *)(Base + offset); } + UInt32 *GetNode(UInt32 offset) const { return (UInt32 *)(Base + offset); } + + void InsertNode(void* p, int indx) + { + *(UInt32 *)p = FreeList[indx]; + FreeList[indx] = GetOffsetNoCheck(p); + } + + void* RemoveNode(int indx) + { + UInt32 offset = FreeList[indx]; + UInt32 *p = GetNode(offset); + FreeList[indx] = *p; + return (void *)p; + } + + UINT U2B(int NU) const { return (UINT)(NU) * UNIT_SIZE; } + + void SplitBlock(void* pv, int oldIndx, int newIndx) + { + int i, UDiff = Indx2Units[oldIndx] - Indx2Units[newIndx]; + Byte* p = ((Byte*)pv) + U2B(Indx2Units[newIndx]); + if (Indx2Units[i = Units2Indx[UDiff-1]] != UDiff) + { + InsertNode(p, --i); + p += U2B(i = Indx2Units[i]); + UDiff -= i; + } + InsertNode(p, Units2Indx[UDiff - 1]); + } + + UInt32 GetUsedMemory() const + { + UInt32 RetVal = SubAllocatorSize - (UInt32)(HiUnit - LoUnit) - (UInt32)(UnitsStart - pText); + for (UInt32 i = 0; i < N_INDEXES; i++) + for (UInt32 pn = FreeList[i]; pn != 0; RetVal -= (UInt32)Indx2Units[i] * UNIT_SIZE) + pn = *GetNode(pn); + return (RetVal >> 2); + } + + UInt32 GetSubAllocatorSize() const { return SubAllocatorSize; } + + void StopSubAllocator() + { + if (SubAllocatorSize != 0) + { + BigFree(Base); + SubAllocatorSize = 0; + Base = 0; + } + } + + bool StartSubAllocator(UInt32 size) + { + if (SubAllocatorSize == size) + return true; + StopSubAllocator(); + if (size == 0) + Base = 0; + else + { + if ((Base = (Byte *)::BigAlloc(size + kExtraSize)) == 0) + return false; + HeapStart = Base + UNIT_SIZE; // we need such code to support NULL; + } + SubAllocatorSize = size; + return true; + } + + void InitSubAllocator() + { + int i, k; + memset(FreeList, 0, sizeof(FreeList)); + HiUnit = (pText = HeapStart) + SubAllocatorSize; + UINT Diff = UNIT_SIZE * (SubAllocatorSize / 8 / UNIT_SIZE * 7); + LoUnit = UnitsStart = HiUnit - Diff; + for (i = 0, k=1; i < N1 ; i++, k += 1) Indx2Units[i] = (Byte)k; + for (k++; i < N1 + N2 ;i++, k += 2) Indx2Units[i] = (Byte)k; + for (k++; i < N1 + N2 + N3 ;i++,k += 3) Indx2Units[i] = (Byte)k; + for (k++; i < N1 + N2 + N3 + N4; i++, k += 4) Indx2Units[i] = (Byte)k; + GlueCount = 0; + for (k = i = 0; k < 128; k++) + { + i += (Indx2Units[i] < k+1); + Units2Indx[k] = (Byte)i; + } + } + + void GlueFreeBlocks() + { + UInt32 s0 = (UInt32)(HeapStart + SubAllocatorSize - Base); + + // We need add exta MEM_BLK with Stamp=0 + GetBlk(s0)->Stamp = 0; + s0 += UNIT_SIZE; + MEM_BLK *ps0 = GetBlk(s0); + + UInt32 p; + int i; + if (LoUnit != HiUnit) + *LoUnit=0; + ps0->Next = ps0->Prev = s0; + + for (i = 0; i < N_INDEXES; i++) + while (FreeList[i] != 0) + { + MEM_BLK *pp = (MEM_BLK *)RemoveNode(i); + pp->InsertAt(Base, s0); + pp->Stamp = 0xFFFF; + pp->NU = Indx2Units[i]; + } + for (p = ps0->Next; p != s0; p = GetBlk(p)->Next) + { + for (;;) + { + MEM_BLK *pp = GetBlk(p); + MEM_BLK *pp1 = GetBlk(p + pp->NU * UNIT_SIZE); + if (pp1->Stamp != 0xFFFF || int(pp->NU) + pp1->NU >= 0x10000) + break; + pp1->Remove(Base); + pp->NU = (UInt16)(pp->NU + pp1->NU); + } + } + while ((p = ps0->Next) != s0) + { + MEM_BLK *pp = GetBlk(p); + pp->Remove(Base); + int sz; + for (sz = pp->NU; sz > 128; sz -= 128, p += 128 * UNIT_SIZE) + InsertNode(Base + p, N_INDEXES - 1); + if (Indx2Units[i = Units2Indx[sz-1]] != sz) + { + int k = sz - Indx2Units[--i]; + InsertNode(Base + p + (sz - k) * UNIT_SIZE, k - 1); + } + InsertNode(Base + p, i); + } + } + void* AllocUnitsRare(int indx) + { + if ( !GlueCount ) + { + GlueCount = 255; + GlueFreeBlocks(); + if (FreeList[indx] != 0) + return RemoveNode(indx); + } + int i = indx; + do + { + if (++i == N_INDEXES) + { + GlueCount--; + i = U2B(Indx2Units[indx]); + return (UnitsStart - pText > i) ? (UnitsStart -= i) : (NULL); + } + } while (FreeList[i] == 0); + void* RetVal = RemoveNode(i); + SplitBlock(RetVal, i, indx); + return RetVal; + } + + void* AllocUnits(int NU) + { + int indx = Units2Indx[NU - 1]; + if (FreeList[indx] != 0) + return RemoveNode(indx); + void* RetVal = LoUnit; + LoUnit += U2B(Indx2Units[indx]); + if (LoUnit <= HiUnit) + return RetVal; + LoUnit -= U2B(Indx2Units[indx]); + return AllocUnitsRare(indx); + } + + void* AllocContext() + { + if (HiUnit != LoUnit) + return (HiUnit -= UNIT_SIZE); + if (FreeList[0] != 0) + return RemoveNode(0); + return AllocUnitsRare(0); + } + + void* ExpandUnits(void* oldPtr, int oldNU) + { + int i0=Units2Indx[oldNU - 1], i1=Units2Indx[oldNU - 1 + 1]; + if (i0 == i1) + return oldPtr; + void* ptr = AllocUnits(oldNU + 1); + if (ptr) + { + memcpy(ptr, oldPtr, U2B(oldNU)); + InsertNode(oldPtr, i0); + } + return ptr; + } + + void* ShrinkUnits(void* oldPtr, int oldNU, int newNU) + { + int i0 = Units2Indx[oldNU - 1], i1 = Units2Indx[newNU - 1]; + if (i0 == i1) + return oldPtr; + if (FreeList[i1] != 0) + { + void* ptr = RemoveNode(i1); + memcpy(ptr, oldPtr, U2B(newNU)); + InsertNode(oldPtr,i0); + return ptr; + } + else + { + SplitBlock(oldPtr, i0, i1); + return oldPtr; + } + } + + void FreeUnits(void* ptr, int oldNU) + { + InsertNode(ptr, Units2Indx[oldNU - 1]); + } +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/PpmdType.h b/desmume/src/windows/7z/CPP/7zip/Compress/PpmdType.h new file mode 100644 index 000000000..313c5f28e --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/PpmdType.h @@ -0,0 +1,20 @@ +/**************************************************************************** + * This file is part of PPMd project * + * Written and distributed to public domain by Dmitry Shkarin 1997, * + * 1999-2001 * + * Contents: compilation parameters and miscelaneous definitions * + * Comments: system & compiler dependent file + + * modified by Igor Pavlov (2004-08-29). + ****************************************************************************/ + +#ifndef __COMPRESS_PPMD_TYPE_H +#define __COMPRESS_PPMD_TYPE_H + +const int kMaxOrderCompress = 32; +const int MAX_O = 255; /* maximum allowed model order */ + +template +inline void _PPMD_SWAP(T& t1,T& t2) { T tmp = t1; t1 = t2; t2 = tmp; } + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/RangeCoder.h b/desmume/src/windows/7z/CPP/7zip/Compress/RangeCoder.h new file mode 100644 index 000000000..8040bcd06 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/RangeCoder.h @@ -0,0 +1,204 @@ +// Compress/RangeCoder.h + +#ifndef __COMPRESS_RANGE_CODER_H +#define __COMPRESS_RANGE_CODER_H + +#include "../Common/InBuffer.h" +#include "../Common/OutBuffer.h" + +namespace NCompress { +namespace NRangeCoder { + +const int kNumTopBits = 24; +const UInt32 kTopValue = (1 << kNumTopBits); + +class CEncoder +{ + UInt32 _cacheSize; + Byte _cache; +public: + UInt64 Low; + UInt32 Range; + COutBuffer Stream; + bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); } + + void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); } + void Init() + { + Stream.Init(); + Low = 0; + Range = 0xFFFFFFFF; + _cacheSize = 1; + _cache = 0; + } + + void FlushData() + { + // Low += 1; + for(int i = 0; i < 5; i++) + ShiftLow(); + } + + HRESULT FlushStream() { return Stream.Flush(); } + + void ReleaseStream() { Stream.ReleaseStream(); } + + void Encode(UInt32 start, UInt32 size, UInt32 total) + { + Low += start * (Range /= total); + Range *= size; + while (Range < kTopValue) + { + Range <<= 8; + ShiftLow(); + } + } + + void ShiftLow() + { + if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0) + { + Byte temp = _cache; + do + { + Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32))); + temp = 0xFF; + } + while(--_cacheSize != 0); + _cache = (Byte)((UInt32)Low >> 24); + } + _cacheSize++; + Low = (UInt32)Low << 8; + } + + void EncodeDirectBits(UInt32 value, int numBits) + { + for (numBits--; numBits >= 0; numBits--) + { + Range >>= 1; + Low += Range & (0 - ((value >> numBits) & 1)); + if (Range < kTopValue) + { + Range <<= 8; + ShiftLow(); + } + } + } + + void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol) + { + UInt32 newBound = (Range >> numTotalBits) * size0; + if (symbol == 0) + Range = newBound; + else + { + Low += newBound; + Range -= newBound; + } + while (Range < kTopValue) + { + Range <<= 8; + ShiftLow(); + } + } + + UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; } +}; + +class CDecoder +{ +public: + CInBuffer Stream; + UInt32 Range; + UInt32 Code; + bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); } + + void Normalize() + { + while (Range < kTopValue) + { + Code = (Code << 8) | Stream.ReadByte(); + Range <<= 8; + } + } + + void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); } + void Init() + { + Stream.Init(); + Code = 0; + Range = 0xFFFFFFFF; + for(int i = 0; i < 5; i++) + Code = (Code << 8) | Stream.ReadByte(); + } + + void ReleaseStream() { Stream.ReleaseStream(); } + + UInt32 GetThreshold(UInt32 total) + { + return (Code) / ( Range /= total); + } + + void Decode(UInt32 start, UInt32 size) + { + Code -= start * Range; + Range *= size; + Normalize(); + } + + UInt32 DecodeDirectBits(int numTotalBits) + { + UInt32 range = Range; + UInt32 code = Code; + UInt32 result = 0; + for (int i = numTotalBits; i != 0; i--) + { + range >>= 1; + /* + result <<= 1; + if (code >= range) + { + code -= range; + result |= 1; + } + */ + UInt32 t = (code - range) >> 31; + code -= range & (t - 1); + result = (result << 1) | (1 - t); + + if (range < kTopValue) + { + code = (code << 8) | Stream.ReadByte(); + range <<= 8; + } + } + Range = range; + Code = code; + return result; + } + + UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) + { + UInt32 newBound = (Range >> numTotalBits) * size0; + UInt32 symbol; + if (Code < newBound) + { + symbol = 0; + Range = newBound; + } + else + { + symbol = 1; + Code -= newBound; + Range -= newBound; + } + Normalize(); + return symbol; + } + + UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); } +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/RangeCoderBit.h b/desmume/src/windows/7z/CPP/7zip/Compress/RangeCoderBit.h new file mode 100644 index 000000000..f2fe45d7f --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/RangeCoderBit.h @@ -0,0 +1,113 @@ +// Compress/RangeCoderBit.h + +#ifndef __COMPRESS_RANGE_CODER_BIT_H +#define __COMPRESS_RANGE_CODER_BIT_H + +#include "RangeCoder.h" + +namespace NCompress { +namespace NRangeCoder { + +const int kNumBitModelTotalBits = 11; +const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits); + +const int kNumMoveReducingBits = 4; + +const int kNumBitPriceShiftBits = 4; +const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits; + +extern UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; + +template +class CBitModel +{ +public: + UInt32 Prob; + void UpdateModel(UInt32 symbol) + { + /* + Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits; + Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits); + */ + if (symbol == 0) + Prob += (kBitModelTotal - Prob) >> numMoveBits; + else + Prob -= (Prob) >> numMoveBits; + } +public: + void Init() { Prob = kBitModelTotal / 2; } +}; + +template +class CBitEncoder: public CBitModel +{ +public: + void Encode(CEncoder *encoder, UInt32 symbol) + { + /* + encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol); + this->UpdateModel(symbol); + */ + UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob; + if (symbol == 0) + { + encoder->Range = newBound; + this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits; + } + else + { + encoder->Low += newBound; + encoder->Range -= newBound; + this->Prob -= (this->Prob) >> numMoveBits; + } + if (encoder->Range < kTopValue) + { + encoder->Range <<= 8; + encoder->ShiftLow(); + } + } + UInt32 GetPrice(UInt32 symbol) const + { + return ProbPrices[(this->Prob ^ ((-(int)symbol)) & (kBitModelTotal - 1)) >> kNumMoveReducingBits]; + } + UInt32 GetPrice0() const { return ProbPrices[this->Prob >> kNumMoveReducingBits]; } + UInt32 GetPrice1() const { return ProbPrices[(this->Prob ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]; } +}; + + +template +class CBitDecoder: public CBitModel +{ +public: + UInt32 Decode(CDecoder *decoder) + { + UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob; + if (decoder->Code < newBound) + { + decoder->Range = newBound; + this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits; + if (decoder->Range < kTopValue) + { + decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte(); + decoder->Range <<= 8; + } + return 0; + } + else + { + decoder->Range -= newBound; + decoder->Code -= newBound; + this->Prob -= (this->Prob) >> numMoveBits; + if (decoder->Range < kTopValue) + { + decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte(); + decoder->Range <<= 8; + } + return 1; + } + } +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/Rar1Decoder.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/Rar1Decoder.cpp new file mode 100644 index 000000000..a6a7c854f --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/Rar1Decoder.cpp @@ -0,0 +1,478 @@ +// Rar1Decoder.cpp +// According to unRAR license, this code may not be used to develop +// a program that creates RAR archives + +#include "StdAfx.h" + +#include "Rar1Decoder.h" + +namespace NCompress { +namespace NRar1 { + +static UInt32 PosL1[]={0,0,0,2,3,5,7,11,16,20,24,32,32, 256}; +static UInt32 PosL2[]={0,0,0,0,5,7,9,13,18,22,26,34,36, 256}; +static UInt32 PosHf0[]={0,0,0,0,0,8,16,24,33,33,33,33,33, 257}; +static UInt32 PosHf1[]={0,0,0,0,0,0,4,44,60,76,80,80,127, 257}; +static UInt32 PosHf2[]={0,0,0,0,0,0,2,7,53,117,233, 257,0}; +static UInt32 PosHf3[]={0,0,0,0,0,0,0,2,16,218,251, 257,0}; +static UInt32 PosHf4[]={0,0,0,0,0,0,0,0,0,255, 257,0,0}; + +static const UInt32 kHistorySize = (1 << 16); + +class CCoderReleaser +{ + CDecoder *m_Coder; +public: + CCoderReleaser(CDecoder *coder): m_Coder(coder) {} + ~CCoderReleaser() { m_Coder->ReleaseStreams(); } +}; + +CDecoder::CDecoder(): m_IsSolid(false) { } + +void CDecoder::InitStructures() +{ + for(int i = 0; i < kNumRepDists; i++) + m_RepDists[i] = 0; + m_RepDistPtr = 0; + LastLength = 0; + LastDist = 0; +} + +UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); } + +HRESULT CDecoder::CopyBlock(UInt32 distance, UInt32 len) +{ + m_UnpackSize -= len; + return m_OutWindowStream.CopyBlock(distance, len) ? S_OK : S_FALSE; +} + + +UInt32 CDecoder::DecodeNum(const UInt32 *posTab) +{ + UInt32 startPos = 2; + UInt32 num = m_InBitStream.GetValue(12); + for (;;) + { + UInt32 cur = (posTab[startPos + 1] - posTab[startPos]) << (12 - startPos); + if (num < cur) + break; + startPos++; + num -= cur; + } + m_InBitStream.MovePos(startPos); + return((num >> (12 - startPos)) + posTab[startPos]); +} + +static Byte kShortLen1[] = {1,3,4,4,5,6,7,8,8,4,4,5,6,6 }; +static Byte kShortLen1a[] = {1,4,4,4,5,6,7,8,8,4,4,5,6,6,4 }; +static Byte kShortLen2[] = {2,3,3,3,4,4,5,6,6,4,4,5,6,6 }; +static Byte kShortLen2a[] = {2,3,3,4,4,4,5,6,6,4,4,5,6,6,4 }; +static UInt32 kShortXor1[] = {0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0}; +static UInt32 kShortXor2[] = {0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0}; + +HRESULT CDecoder::ShortLZ() +{ + UInt32 len, saveLen, dist; + int distancePlace; + Byte *kShortLen; + const UInt32 *kShortXor; + NumHuf = 0; + + if (LCount == 2) + { + if (ReadBits(1)) + return CopyBlock(LastDist, LastLength); + LCount = 0; + } + + UInt32 bitField = m_InBitStream.GetValue(8); + + if (AvrLn1 < 37) + { + kShortLen = Buf60 ? kShortLen1a : kShortLen1; + kShortXor = kShortXor1; + } + else + { + kShortLen = Buf60 ? kShortLen2a : kShortLen2; + kShortXor = kShortXor2; + } + + for (len = 0; ((bitField ^ kShortXor[len]) & (~(0xff >> kShortLen[len]))) != 0; len++); + m_InBitStream.MovePos(kShortLen[len]); + + if (len >= 9) + { + if (len == 9) + { + LCount++; + return CopyBlock(LastDist, LastLength); + } + if (len == 14) + { + LCount = 0; + len = DecodeNum(PosL2) + 5; + dist = 0x8000 + ReadBits(15) - 1; + LastLength = len; + LastDist = dist; + return CopyBlock(dist, len); + } + + LCount = 0; + saveLen = len; + dist = m_RepDists[(m_RepDistPtr - (len - 9)) & 3]; + len = DecodeNum(PosL1) + 2; + if (len == 0x101 && saveLen == 10) + { + Buf60 ^= 1; + return S_OK; + } + if (dist >= 256) + len++; + if (dist >= MaxDist3 - 1) + len++; + } + else + { + LCount = 0; + AvrLn1 += len; + AvrLn1 -= AvrLn1 >> 4; + + distancePlace = DecodeNum(PosHf2) & 0xff; + dist = ChSetA[distancePlace]; + if (--distancePlace != -1) + { + PlaceA[dist]--; + UInt32 lastDistance = ChSetA[distancePlace]; + PlaceA[lastDistance]++; + ChSetA[distancePlace + 1] = lastDistance; + ChSetA[distancePlace] = dist; + } + len += 2; + } + m_RepDists[m_RepDistPtr++] = dist; + m_RepDistPtr &= 3; + LastLength = len; + LastDist = dist; + return CopyBlock(dist, len); +} + + +HRESULT CDecoder::LongLZ() +{ + UInt32 len; + UInt32 dist; + UInt32 distancePlace, newDistancePlace; + UInt32 oldAvr2, oldAvr3; + + NumHuf = 0; + Nlzb += 16; + if (Nlzb > 0xff) + { + Nlzb = 0x90; + Nhfb >>= 1; + } + oldAvr2=AvrLn2; + + if (AvrLn2 >= 122) + len = DecodeNum(PosL2); + else if (AvrLn2 >= 64) + len = DecodeNum(PosL1); + else + { + UInt32 bitField = m_InBitStream.GetValue(16); + if (bitField < 0x100) + { + len = bitField; + m_InBitStream.MovePos(16); + } + else + { + for (len = 0; ((bitField << len) & 0x8000) == 0; len++) + ; + m_InBitStream.MovePos(len + 1); + } + } + + AvrLn2 += len; + AvrLn2 -= AvrLn2 >> 5; + + if (AvrPlcB > 0x28ff) + distancePlace = DecodeNum(PosHf2); + else if (AvrPlcB > 0x6ff) + distancePlace = DecodeNum(PosHf1); + else + distancePlace = DecodeNum(PosHf0); + + AvrPlcB += distancePlace; + AvrPlcB -= AvrPlcB >> 8; + for (;;) + { + dist = ChSetB[distancePlace & 0xff]; + newDistancePlace = NToPlB[dist++ & 0xff]++; + if (!(dist & 0xff)) + CorrHuff(ChSetB,NToPlB); + else + break; + } + + ChSetB[distancePlace] = ChSetB[newDistancePlace]; + ChSetB[newDistancePlace] = dist; + + dist = ((dist & 0xff00) >> 1) | ReadBits(7); + + oldAvr3 = AvrLn3; + if (len != 1 && len != 4) + if (len == 0 && dist <= MaxDist3) + { + AvrLn3++; + AvrLn3 -= AvrLn3 >> 8; + } + else + if (AvrLn3 > 0) + AvrLn3--; + len += 3; + if (dist >= MaxDist3) + len++; + if (dist <= 256) + len += 8; + if (oldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && oldAvr2 < 0x40) + MaxDist3 = 0x7f00; + else + MaxDist3 = 0x2001; + m_RepDists[m_RepDistPtr++] = --dist; + m_RepDistPtr &= 3; + LastLength = len; + LastDist = dist; + return CopyBlock(dist, len); +} + + +HRESULT CDecoder::HuffDecode() +{ + UInt32 curByte, newBytePlace; + UInt32 len; + UInt32 dist; + int bytePlace; + + if (AvrPlc > 0x75ff) bytePlace = DecodeNum(PosHf4); + else if (AvrPlc > 0x5dff) bytePlace = DecodeNum(PosHf3); + else if (AvrPlc > 0x35ff) bytePlace = DecodeNum(PosHf2); + else if (AvrPlc > 0x0dff) bytePlace = DecodeNum(PosHf1); + else bytePlace = DecodeNum(PosHf0); + if (StMode) + { + if (--bytePlace == -1) + { + if (ReadBits(1)) + { + NumHuf = StMode = 0; + return S_OK; + } + else + { + len = (ReadBits(1)) ? 4 : 3; + dist = DecodeNum(PosHf2); + dist = (dist << 5) | ReadBits(5); + return CopyBlock(dist - 1, len); + } + } + } + else if (NumHuf++ >= 16 && FlagsCnt == 0) + StMode = 1; + bytePlace &= 0xff; + AvrPlc += bytePlace; + AvrPlc -= AvrPlc >> 8; + Nhfb+=16; + if (Nhfb > 0xff) + { + Nhfb=0x90; + Nlzb >>= 1; + } + + m_UnpackSize --; + m_OutWindowStream.PutByte((Byte)(ChSet[bytePlace] >> 8)); + + for (;;) + { + curByte = ChSet[bytePlace]; + newBytePlace = NToPl[curByte++ & 0xff]++; + if ((curByte & 0xff) > 0xa1) + CorrHuff(ChSet, NToPl); + else + break; + } + + ChSet[bytePlace] = ChSet[newBytePlace]; + ChSet[newBytePlace] = curByte; + return S_OK; +} + + +void CDecoder::GetFlagsBuf() +{ + UInt32 flags, newFlagsPlace; + UInt32 flagsPlace = DecodeNum(PosHf2); + + for (;;) + { + flags = ChSetC[flagsPlace]; + FlagBuf = flags >> 8; + newFlagsPlace = NToPlC[flags++ & 0xff]++; + if ((flags & 0xff) != 0) + break; + CorrHuff(ChSetC, NToPlC); + } + + ChSetC[flagsPlace] = ChSetC[newFlagsPlace]; + ChSetC[newFlagsPlace] = flags; +} + +void CDecoder::InitData() +{ + if (!m_IsSolid) + { + AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0; + AvrPlc = 0x3500; + MaxDist3 = 0x2001; + Nhfb = Nlzb = 0x80; + } + FlagsCnt = 0; + FlagBuf = 0; + StMode = 0; + LCount = 0; +} + +void CDecoder::CorrHuff(UInt32 *CharSet,UInt32 *NumToPlace) +{ + int i; + for (i = 7; i >= 0; i--) + for (int j = 0; j < 32; j++, CharSet++) + *CharSet = (*CharSet & ~0xff) | i; + memset(NumToPlace, 0, sizeof(NToPl)); + for (i = 6; i >= 0; i--) + NumToPlace[i] = (7 - i) * 32; +} + +void CDecoder::InitHuff() +{ + for (UInt32 i = 0; i < 256; i++) + { + Place[i] = PlaceA[i] = PlaceB[i] = i; + PlaceC[i] = (~i + 1) & 0xff; + ChSet[i] = ChSetB[i] = i << 8; + ChSetA[i] = i; + ChSetC[i] = ((~i + 1) & 0xff) << 8; + } + memset(NToPl, 0, sizeof(NToPl)); + memset(NToPlB, 0, sizeof(NToPlB)); + memset(NToPlC, 0, sizeof(NToPlC)); + CorrHuff(ChSetB, NToPlB); +} + +HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo * /* progress */) +{ + if (inSize == NULL || outSize == NULL) + return E_INVALIDARG; + + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + + m_UnpackSize = (Int64)*outSize; + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(m_IsSolid); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + + CCoderReleaser coderReleaser(this); + InitData(); + if (!m_IsSolid) + { + InitStructures(); + InitHuff(); + } + if (m_UnpackSize > 0) + { + GetFlagsBuf(); + FlagsCnt = 8; + } + + while (m_UnpackSize > 0) + { + if (StMode) + { + RINOK(HuffDecode()); + continue; + } + + if (--FlagsCnt < 0) + { + GetFlagsBuf(); + FlagsCnt=7; + } + + if (FlagBuf & 0x80) + { + FlagBuf <<= 1; + if (Nlzb > Nhfb) + { + RINOK(LongLZ()); + } + else + { + RINOK(HuffDecode()); + } + } + else + { + FlagBuf <<= 1; + if (--FlagsCnt < 0) + { + GetFlagsBuf(); + FlagsCnt = 7; + } + if (FlagBuf & 0x80) + { + FlagBuf <<= 1; + if (Nlzb > Nhfb) + { + RINOK(HuffDecode()); + } + else + { + RINOK(LongLZ()); + } + } + else + { + FlagBuf <<= 1; + RINOK(ShortLZ()); + } + } + } + if (m_UnpackSize < 0) + return S_FALSE; + return m_OutWindowStream.Flush(); +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const CLzOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + if (size < 1) + return E_INVALIDARG; + m_IsSolid = (data[0] != 0); + return S_OK; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/Rar1Decoder.h b/desmume/src/windows/7z/CPP/7zip/Compress/Rar1Decoder.h new file mode 100644 index 000000000..1b960e457 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/Rar1Decoder.h @@ -0,0 +1,88 @@ +// Rar1Decoder.h +// According to unRAR license, this code may not be used to develop +// a program that creates RAR archives + +#ifndef __COMPRESS_RAR1_DECODER_H +#define __COMPRESS_RAR1_DECODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "../Common/InBuffer.h" + +#include "BitmDecoder.h" +#include "HuffmanDecoder.h" +#include "LzOutWindow.h" + +namespace NCompress { +namespace NRar1 { + +const UInt32 kNumRepDists = 4; + +typedef NBitm::CDecoder CBitDecoder; + +class CDecoder : + public ICompressCoder, + public ICompressSetDecoderProperties2, + public CMyUnknownImp +{ +public: + CLzOutWindow m_OutWindowStream; + CBitDecoder m_InBitStream; + + UInt32 m_RepDists[kNumRepDists]; + UInt32 m_RepDistPtr; + + UInt32 LastDist; + UInt32 LastLength; + + Int64 m_UnpackSize; + bool m_IsSolid; + + UInt32 ReadBits(int numBits); + HRESULT CopyBlock(UInt32 distance, UInt32 len); + + UInt32 DecodeNum(const UInt32 *posTab); + HRESULT ShortLZ(); + HRESULT LongLZ(); + HRESULT HuffDecode(); + void GetFlagsBuf(); + void InitData(); + void InitHuff(); + void CorrHuff(UInt32 *CharSet, UInt32 *NumToPlace); + void OldUnpWriteBuf(); + + UInt32 ChSet[256],ChSetA[256],ChSetB[256],ChSetC[256]; + UInt32 Place[256],PlaceA[256],PlaceB[256],PlaceC[256]; + UInt32 NToPl[256],NToPlB[256],NToPlC[256]; + UInt32 FlagBuf,AvrPlc,AvrPlcB,AvrLn1,AvrLn2,AvrLn3; + int Buf60,NumHuf,StMode,LCount,FlagsCnt; + UInt32 Nhfb,Nlzb,MaxDist3; + + void InitStructures(); + + HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + +public: + CDecoder(); + + MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) + + void ReleaseStreams() + { + m_OutWindowStream.ReleaseStream(); + m_InBitStream.ReleaseStream(); + } + + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/Rar2Decoder.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/Rar2Decoder.cpp new file mode 100644 index 000000000..194a4bdf3 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/Rar2Decoder.cpp @@ -0,0 +1,389 @@ +// Rar2Decoder.cpp +// According to unRAR license, this code may not be used to develop +// a program that creates RAR archives + +#include "StdAfx.h" + +#include "Rar2Decoder.h" + +namespace NCompress { +namespace NRar2 { + +namespace NMultimedia { + +Byte CFilter::Decode(int &channelDelta, Byte deltaByte) +{ + D4 = D3; + D3 = D2; + D2 = LastDelta - D1; + D1 = LastDelta; + int predictedValue = ((8 * LastChar + K1 * D1 + K2 * D2 + K3 * D3 + K4 * D4 + K5 * channelDelta) >> 3); + + Byte realValue = (Byte)(predictedValue - deltaByte); + int i = ((int)(signed char)deltaByte) << 3; + + Dif[0] += abs(i); + Dif[1] += abs(i - D1); + Dif[2] += abs(i + D1); + Dif[3] += abs(i - D2); + Dif[4] += abs(i + D2); + Dif[5] += abs(i - D3); + Dif[6] += abs(i + D3); + Dif[7] += abs(i - D4); + Dif[8] += abs(i + D4); + Dif[9] += abs(i - channelDelta); + Dif[10] += abs(i + channelDelta); + + channelDelta = LastDelta = (signed char)(realValue - LastChar); + LastChar = realValue; + + if (((++ByteCount) & 0x1F) == 0) + { + UInt32 minDif = Dif[0]; + UInt32 numMinDif = 0; + Dif[0] = 0; + for (i = 1; i < sizeof(Dif) / sizeof(Dif[0]); i++) + { + if (Dif[i] < minDif) + { + minDif = Dif[i]; + numMinDif = i; + } + Dif[i] = 0; + } + switch(numMinDif) + { + case 1: if (K1 >= -16) K1--; break; + case 2: if (K1 < 16) K1++; break; + case 3: if (K2 >= -16) K2--; break; + case 4: if (K2 < 16) K2++; break; + case 5: if (K3 >= -16) K3--; break; + case 6: if (K3 < 16) K3++; break; + case 7: if (K4 >= -16) K4--; break; + case 8: if (K4 < 16) K4++; break; + case 9: if (K5 >= -16) K5--; break; + case 10:if (K5 < 16) K5++; break; + } + } + return realValue; +} +} + +static const char *kNumberErrorMessage = "Number error"; + +static const UInt32 kHistorySize = 1 << 20; + +static const int kNumStats = 11; + +static const UInt32 kWindowReservSize = (1 << 22) + 256; + +CDecoder::CDecoder(): + m_IsSolid(false) +{ +} + +void CDecoder::InitStructures() +{ + m_MmFilter.Init(); + for(int i = 0; i < kNumRepDists; i++) + m_RepDists[i] = 0; + m_RepDistPtr = 0; + m_LastLength = 0; + memset(m_LastLevels, 0, kMaxTableSize); +} + +UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); } + +#define RIF(x) { if (!(x)) return false; } + +bool CDecoder::ReadTables(void) +{ + Byte levelLevels[kLevelTableSize]; + Byte newLevels[kMaxTableSize]; + m_AudioMode = (ReadBits(1) == 1); + + if (ReadBits(1) == 0) + memset(m_LastLevels, 0, kMaxTableSize); + int numLevels; + if (m_AudioMode) + { + m_NumChannels = ReadBits(2) + 1; + if (m_MmFilter.CurrentChannel >= m_NumChannels) + m_MmFilter.CurrentChannel = 0; + numLevels = m_NumChannels * kMMTableSize; + } + else + numLevels = kHeapTablesSizesSum; + + int i; + for (i = 0; i < kLevelTableSize; i++) + levelLevels[i] = (Byte)ReadBits(4); + RIF(m_LevelDecoder.SetCodeLengths(levelLevels)); + i = 0; + while (i < numLevels) + { + UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); + if (number < kTableDirectLevels) + { + newLevels[i] = (Byte)((number + m_LastLevels[i]) & kLevelMask); + i++; + } + else + { + if (number == kTableLevelRepNumber) + { + int t = ReadBits(2) + 3; + for (int reps = t; reps > 0 && i < numLevels ; reps--, i++) + newLevels[i] = newLevels[i - 1]; + } + else + { + int num; + if (number == kTableLevel0Number) + num = ReadBits(3) + 3; + else if (number == kTableLevel0Number2) + num = ReadBits(7) + 11; + else + return false; + for (;num > 0 && i < numLevels; num--) + newLevels[i++] = 0; + } + } + } + if (m_AudioMode) + for (i = 0; i < m_NumChannels; i++) + { + RIF(m_MMDecoders[i].SetCodeLengths(&newLevels[i * kMMTableSize])); + } + else + { + RIF(m_MainDecoder.SetCodeLengths(&newLevels[0])); + RIF(m_DistDecoder.SetCodeLengths(&newLevels[kMainTableSize])); + RIF(m_LenDecoder.SetCodeLengths(&newLevels[kMainTableSize + kDistTableSize])); + } + memcpy(m_LastLevels, newLevels, kMaxTableSize); + return true; +} + +bool CDecoder::ReadLastTables() +{ + // it differs a little from pure RAR sources; + // UInt64 ttt = m_InBitStream.GetProcessedSize() + 2; + // + 2 works for: return 0xFF; in CInBuffer::ReadByte. + if (m_InBitStream.GetProcessedSize() + 7 <= m_PackSize) // test it: probably incorrect; + // if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect; + if (m_AudioMode) + { + UInt32 symbol = m_MMDecoders[m_MmFilter.CurrentChannel].DecodeSymbol(&m_InBitStream); + if (symbol == 256) + return ReadTables(); + if (symbol >= kMMTableSize) + return false; + } + else + { + UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); + if (number == kReadTableNumber) + return ReadTables(); + if (number >= kMainTableSize) + return false; + } + return true; +} + +class CCoderReleaser +{ + CDecoder *m_Coder; +public: + CCoderReleaser(CDecoder *coder): m_Coder(coder) {} + ~CCoderReleaser() + { + m_Coder->ReleaseStreams(); + } +}; + +bool CDecoder::DecodeMm(UInt32 pos) +{ + while (pos-- > 0) + { + UInt32 symbol = m_MMDecoders[m_MmFilter.CurrentChannel].DecodeSymbol(&m_InBitStream); + if (symbol == 256) + return true; + if (symbol >= kMMTableSize) + return false; + /* + Byte byPredict = m_Predictor.Predict(); + Byte byReal = (Byte)(byPredict - (Byte)symbol); + m_Predictor.Update(byReal, byPredict); + */ + Byte byReal = m_MmFilter.Decode((Byte)symbol); + m_OutWindowStream.PutByte(byReal); + if (++m_MmFilter.CurrentChannel == m_NumChannels) + m_MmFilter.CurrentChannel = 0; + } + return true; +} + +bool CDecoder::DecodeLz(Int32 pos) +{ + while (pos > 0) + { + UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); + UInt32 length, distance; + if (number < 256) + { + m_OutWindowStream.PutByte(Byte(number)); + pos--; + continue; + } + else if (number >= kMatchNumber) + { + number -= kMatchNumber; + length = kNormalMatchMinLen + UInt32(kLenStart[number]) + + m_InBitStream.ReadBits(kLenDirectBits[number]); + number = m_DistDecoder.DecodeSymbol(&m_InBitStream); + if (number >= kDistTableSize) + return false; + distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]); + if (distance >= kDistLimit3) + { + length += 2 - ((distance - kDistLimit4) >> 31); + // length++; + // if (distance >= kDistLimit4) + // length++; + } + } + else if (number == kRepBothNumber) + { + length = m_LastLength; + distance = m_RepDists[(m_RepDistPtr + 4 - 1) & 3]; + } + else if (number < kLen2Number) + { + distance = m_RepDists[(m_RepDistPtr - (number - kRepNumber + 1)) & 3]; + number = m_LenDecoder.DecodeSymbol(&m_InBitStream); + if (number >= kLenTableSize) + return false; + length = 2 + kLenStart[number] + m_InBitStream.ReadBits(kLenDirectBits[number]); + if (distance >= kDistLimit2) + { + length++; + if (distance >= kDistLimit3) + { + length += 2 - ((distance - kDistLimit4) >> 31); + // length++; + // if (distance >= kDistLimit4) + // length++; + } + } + } + else if (number < kReadTableNumber) + { + number -= kLen2Number; + distance = kLen2DistStarts[number] + + m_InBitStream.ReadBits(kLen2DistDirectBits[number]); + length = 2; + } + else if (number == kReadTableNumber) + return true; + else + return false; + m_RepDists[m_RepDistPtr++ & 3] = distance; + m_LastLength = length; + if (!m_OutWindowStream.CopyBlock(distance, length)) + return false; + pos -= length; + } + return true; +} + +HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + if (inSize == NULL || outSize == NULL) + return E_INVALIDARG; + + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + + m_PackSize = *inSize; + + UInt64 pos = 0, unPackSize = *outSize; + + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(m_IsSolid); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + + CCoderReleaser coderReleaser(this); + if (!m_IsSolid) + { + InitStructures(); + if (unPackSize == 0) + { + if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect; + if (!ReadTables()) + return S_FALSE; + return S_OK; + } + if (!ReadTables()) + return S_FALSE; + } + + UInt64 startPos = m_OutWindowStream.GetProcessedSize(); + while(pos < unPackSize) + { + UInt32 blockSize = 1 << 20; + if (blockSize > unPackSize - pos) + blockSize = (UInt32)(unPackSize - pos); + UInt64 blockStartPos = m_OutWindowStream.GetProcessedSize(); + if (m_AudioMode) + { + if (!DecodeMm(blockSize)) + return S_FALSE; + } + else + { + if (!DecodeLz((Int32)blockSize)) + return S_FALSE; + } + UInt64 globalPos = m_OutWindowStream.GetProcessedSize(); + pos = globalPos - blockStartPos; + if (pos < blockSize) + if (!ReadTables()) + return S_FALSE; + pos = globalPos - startPos; + if (progress != 0) + { + UInt64 packSize = m_InBitStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &pos)); + } + } + if (pos > unPackSize) + return S_FALSE; + + if (!ReadLastTables()) + return S_FALSE; + return m_OutWindowStream.Flush(); +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const CLzOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + if (size < 1) + return E_INVALIDARG; + m_IsSolid = (data[0] != 0); + return S_OK; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/Rar2Decoder.h b/desmume/src/windows/7z/CPP/7zip/Compress/Rar2Decoder.h new file mode 100644 index 000000000..65cc97307 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/Rar2Decoder.h @@ -0,0 +1,174 @@ +// Rar2Decoder.h +// According to unRAR license, this code may not be used to develop +// a program that creates RAR archives + +#ifndef __COMPRESS_RAR2_DECODER_H +#define __COMPRESS_RAR2_DECODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "../Common/InBuffer.h" + +#include "BitmDecoder.h" +#include "HuffmanDecoder.h" +#include "LzOutWindow.h" + +namespace NCompress { +namespace NRar2 { + +const UInt32 kNumRepDists = 4; +const UInt32 kDistTableSize = 48; + +const int kMMTableSize = 256 + 1; + +const UInt32 kMainTableSize = 298; +const UInt32 kLenTableSize = 28; + +const UInt32 kDistTableStart = kMainTableSize; +const UInt32 kLenTableStart = kDistTableStart + kDistTableSize; + +const UInt32 kHeapTablesSizesSum = kMainTableSize + kDistTableSize + kLenTableSize; + +const UInt32 kLevelTableSize = 19; + +const UInt32 kMMTablesSizesSum = kMMTableSize * 4; + +const UInt32 kMaxTableSize = kMMTablesSizesSum; + +const UInt32 kTableDirectLevels = 16; +const UInt32 kTableLevelRepNumber = kTableDirectLevels; +const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1; +const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1; + +const UInt32 kLevelMask = 0xF; + + +const UInt32 kRepBothNumber = 256; +const UInt32 kRepNumber = kRepBothNumber + 1; +const UInt32 kLen2Number = kRepNumber + 4; + +const UInt32 kLen2NumNumbers = 8; +const UInt32 kReadTableNumber = kLen2Number + kLen2NumNumbers; +const UInt32 kMatchNumber = kReadTableNumber + 1; + +const Byte kLenStart[kLenTableSize] = {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}; +const Byte kLenDirectBits[kLenTableSize] = {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}; + +const UInt32 kDistStart[kDistTableSize] = {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,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040}; +const Byte kDistDirectBits[kDistTableSize] = {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, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}; + +const Byte kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; + +const Byte kLen2DistStarts[kLen2NumNumbers]={0,4,8,16,32,64,128,192}; +const Byte kLen2DistDirectBits[kLen2NumNumbers]={2,2,3, 4, 5, 6, 6, 6}; + +const UInt32 kDistLimit2 = 0x101 - 1; +const UInt32 kDistLimit3 = 0x2000 - 1; +const UInt32 kDistLimit4 = 0x40000 - 1; + +const UInt32 kMatchMaxLen = 255 + 2; +const UInt32 kMatchMaxLenMax = 255 + 5; +const UInt32 kNormalMatchMinLen = 3; + +namespace NMultimedia { + +struct CFilter +{ + int K1,K2,K3,K4,K5; + int D1,D2,D3,D4; + int LastDelta; + UInt32 Dif[11]; + UInt32 ByteCount; + int LastChar; + + Byte Decode(int &channelDelta, Byte delta); + + void Init() { memset(this, 0, sizeof(*this)); } + +}; + +const int kNumChanelsMax = 4; + +class CFilter2 +{ +public: + CFilter m_Filters[kNumChanelsMax]; + int m_ChannelDelta; + int CurrentChannel; + + void Init() { memset(this, 0, sizeof(*this)); } + Byte Decode(Byte delta) + { + return m_Filters[CurrentChannel].Decode(m_ChannelDelta, delta); + } + +}; + +} + +typedef NBitm::CDecoder CBitDecoder; + +const int kNumHuffmanBits = 15; + +class CDecoder : + public ICompressCoder, + public ICompressSetDecoderProperties2, + public CMyUnknownImp +{ + CLzOutWindow m_OutWindowStream; + CBitDecoder m_InBitStream; + NHuffman::CDecoder m_MainDecoder; + NHuffman::CDecoder m_DistDecoder; + NHuffman::CDecoder m_LenDecoder; + NHuffman::CDecoder m_MMDecoders[NMultimedia::kNumChanelsMax]; + NHuffman::CDecoder m_LevelDecoder; + + bool m_AudioMode; + + NMultimedia::CFilter2 m_MmFilter; + int m_NumChannels; + + UInt32 m_RepDists[kNumRepDists]; + UInt32 m_RepDistPtr; + + UInt32 m_LastLength; + + Byte m_LastLevels[kMaxTableSize]; + + UInt64 m_PackSize; + bool m_IsSolid; + + void InitStructures(); + UInt32 ReadBits(int numBits); + bool ReadTables(); + bool ReadLastTables(); + + bool DecodeMm(UInt32 pos); + bool DecodeLz(Int32 pos); + + HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + +public: + CDecoder(); + + MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) + + void ReleaseStreams() + { + m_OutWindowStream.ReleaseStream(); + m_InBitStream.ReleaseStream(); + } + + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/Rar3Decoder.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/Rar3Decoder.cpp new file mode 100644 index 000000000..fb52437e7 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/Rar3Decoder.cpp @@ -0,0 +1,834 @@ +// Rar3Decoder.cpp +// According to unRAR license, this code may not be used to develop +// a program that creates RAR archives + +#include "StdAfx.h" + +#include "../Common/StreamUtils.h" + +#include "Rar3Decoder.h" + +namespace NCompress { +namespace NRar3 { + +static const UInt32 kNumAlignReps = 15; + +static const UInt32 kSymbolReadTable = 256; +static const UInt32 kSymbolRep = 259; +static const UInt32 kSymbolLen2 = kSymbolRep + kNumReps; + +static const Byte kLenStart[kLenTableSize] = {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}; +static const Byte kLenDirectBits[kLenTableSize] = {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}; + +static const Byte kDistDirectBits[kDistTableSize] = + {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,14,14,15,15, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 18,18,18,18,18,18,18,18,18,18,18,18}; + +static const Byte kLevelDirectBits[kLevelTableSize] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +static const Byte kLen2DistStarts[kNumLen2Symbols]={0,4,8,16,32,64,128,192}; +static const Byte kLen2DistDirectBits[kNumLen2Symbols]={2,2,3, 4, 5, 6, 6, 6}; + +static const UInt32 kDistLimit3 = 0x2000 - 2; +static const UInt32 kDistLimit4 = 0x40000 - 2; + +static const UInt32 kNormalMatchMinLen = 3; + +static const UInt32 kVmDataSizeMax = 1 << 16; +static const UInt32 kVmCodeSizeMax = 1 << 16; + +CDecoder::CDecoder(): + _window(0), + _winPos(0), + _wrPtr(0), + _lzSize(0), + _writtenFileSize(0), + _vmData(0), + _vmCode(0), + m_IsSolid(false) +{ +} + +CDecoder::~CDecoder() +{ + InitFilters(); + ::MidFree(_vmData); + ::MidFree(_window); +} + +HRESULT CDecoder::WriteDataToStream(const Byte *data, UInt32 size) +{ + return WriteStream(_outStream, data, size); +} + +HRESULT CDecoder::WriteData(const Byte *data, UInt32 size) +{ + HRESULT res = S_OK; + if (_writtenFileSize < _unpackSize) + { + UInt32 curSize = size; + UInt64 remain = _unpackSize - _writtenFileSize; + if (remain < curSize) + curSize = (UInt32)remain; + res = WriteDataToStream(data, curSize); + } + _writtenFileSize += size; + return res; +} + +HRESULT CDecoder::WriteArea(UInt32 startPtr, UInt32 endPtr) +{ + if (startPtr <= endPtr) + return WriteData(_window + startPtr, endPtr - startPtr); + RINOK(WriteData(_window + startPtr, kWindowSize - startPtr)); + return WriteData(_window, endPtr); +} + +void CDecoder::ExecuteFilter(int tempFilterIndex, NVm::CBlockRef &outBlockRef) +{ + CTempFilter *tempFilter = _tempFilters[tempFilterIndex]; + tempFilter->InitR[6] = (UInt32)_writtenFileSize; + NVm::SetValue32(&tempFilter->GlobalData[0x24], (UInt32)_writtenFileSize); + NVm::SetValue32(&tempFilter->GlobalData[0x28], (UInt32)(_writtenFileSize >> 32)); + CFilter *filter = _filters[tempFilter->FilterIndex]; + _vm.Execute(filter, tempFilter, outBlockRef, filter->GlobalData); + delete tempFilter; + _tempFilters[tempFilterIndex] = 0; +} + +HRESULT CDecoder::WriteBuf() +{ + UInt32 writtenBorder = _wrPtr; + UInt32 writeSize = (_winPos - writtenBorder) & kWindowMask; + for (int i = 0; i < _tempFilters.Size(); i++) + { + CTempFilter *filter = _tempFilters[i]; + if (filter == NULL) + continue; + if (filter->NextWindow) + { + filter->NextWindow = false; + continue; + } + UInt32 blockStart = filter->BlockStart; + UInt32 blockSize = filter->BlockSize; + if (((blockStart - writtenBorder) & kWindowMask) < writeSize) + { + if (writtenBorder != blockStart) + { + RINOK(WriteArea(writtenBorder, blockStart)); + writtenBorder = blockStart; + writeSize = (_winPos - writtenBorder) & kWindowMask; + } + if (blockSize <= writeSize) + { + UInt32 blockEnd = (blockStart + blockSize) & kWindowMask; + if (blockStart < blockEnd || blockEnd == 0) + _vm.SetMemory(0, _window + blockStart, blockSize); + else + { + UInt32 tailSize = kWindowSize - blockStart; + _vm.SetMemory(0, _window + blockStart, tailSize); + _vm.SetMemory(tailSize, _window, blockEnd); + } + NVm::CBlockRef outBlockRef; + ExecuteFilter(i, outBlockRef); + while (i + 1 < _tempFilters.Size()) + { + CTempFilter *nextFilter = _tempFilters[i + 1]; + if (nextFilter == NULL || nextFilter->BlockStart != blockStart || + nextFilter->BlockSize != outBlockRef.Size || nextFilter->NextWindow) + break; + _vm.SetMemory(0, _vm.GetDataPointer(outBlockRef.Offset), outBlockRef.Size); + ExecuteFilter(++i, outBlockRef); + } + WriteDataToStream(_vm.GetDataPointer(outBlockRef.Offset), outBlockRef.Size); + _writtenFileSize += outBlockRef.Size; + writtenBorder = blockEnd; + writeSize = (_winPos - writtenBorder) & kWindowMask; + } + else + { + for (int j = i; j < _tempFilters.Size(); j++) + { + CTempFilter *filter = _tempFilters[j]; + if (filter != NULL && filter->NextWindow) + filter->NextWindow = false; + } + _wrPtr = writtenBorder; + return S_OK; // check it + } + } + } + + _wrPtr = _winPos; + return WriteArea(writtenBorder, _winPos); +} + +void CDecoder::InitFilters() +{ + _lastFilter = 0; + int i; + for (i = 0; i < _tempFilters.Size(); i++) + delete _tempFilters[i]; + _tempFilters.Clear(); + for (i = 0; i < _filters.Size(); i++) + delete _filters[i]; + _filters.Clear(); +} + +bool CDecoder::AddVmCode(UInt32 firstByte, UInt32 codeSize) +{ + CMemBitDecoder inp; + inp.Init(_vmData, codeSize); + + UInt32 filterIndex; + if (firstByte & 0x80) + { + filterIndex = NVm::ReadEncodedUInt32(inp); + if (filterIndex == 0) + InitFilters(); + else + filterIndex--; + } + else + filterIndex = _lastFilter; + if (filterIndex > (UInt32)_filters.Size()) + return false; + _lastFilter = filterIndex; + bool newFilter = (filterIndex == (UInt32)_filters.Size()); + + CFilter *filter; + if (newFilter) + { + // check if too many filters + if (filterIndex > 1024) + return false; + filter = new CFilter; + _filters.Add(filter); + } + else + { + filter = _filters[filterIndex]; + filter->ExecCount++; + } + + int numEmptyItems = 0; + int i; + for (i = 0; i < _tempFilters.Size(); i++) + { + _tempFilters[i - numEmptyItems] = _tempFilters[i]; + if (_tempFilters[i] == NULL) + numEmptyItems++; + if (numEmptyItems > 0) + _tempFilters[i] = NULL; + } + if (numEmptyItems == 0) + { + _tempFilters.Add(NULL); + numEmptyItems = 1; + } + CTempFilter *tempFilter = new CTempFilter; + _tempFilters[_tempFilters.Size() - numEmptyItems] = tempFilter; + tempFilter->FilterIndex = filterIndex; + tempFilter->ExecCount = filter->ExecCount; + + UInt32 blockStart = NVm::ReadEncodedUInt32(inp); + if (firstByte & 0x40) + blockStart += 258; + tempFilter->BlockStart = (blockStart + _winPos) & kWindowMask; + if (firstByte & 0x20) + filter->BlockSize = NVm::ReadEncodedUInt32(inp); + tempFilter->BlockSize = filter->BlockSize; + tempFilter->NextWindow = _wrPtr != _winPos && ((_wrPtr - _winPos) & kWindowMask) <= blockStart; + + memset(tempFilter->InitR, 0, sizeof(tempFilter->InitR)); + tempFilter->InitR[3] = NVm::kGlobalOffset; + tempFilter->InitR[4] = tempFilter->BlockSize; + tempFilter->InitR[5] = tempFilter->ExecCount; + if (firstByte & 0x10) + { + UInt32 initMask = inp.ReadBits(NVm::kNumGpRegs); + for (int i = 0; i < NVm::kNumGpRegs; i++) + if (initMask & (1 << i)) + tempFilter->InitR[i] = NVm::ReadEncodedUInt32(inp); + } + if (newFilter) + { + UInt32 vmCodeSize = NVm::ReadEncodedUInt32(inp); + if (vmCodeSize >= kVmCodeSizeMax || vmCodeSize == 0) + return false; + for (UInt32 i = 0; i < vmCodeSize; i++) + _vmCode[i] = (Byte)inp.ReadBits(8); + _vm.PrepareProgram(_vmCode, vmCodeSize, filter); + } + + tempFilter->AllocateEmptyFixedGlobal(); + + Byte *globalData = &tempFilter->GlobalData[0]; + for (i = 0; i < NVm::kNumGpRegs; i++) + NVm::SetValue32(&globalData[i * 4], tempFilter->InitR[i]); + NVm::SetValue32(&globalData[NVm::NGlobalOffset::kBlockSize], tempFilter->BlockSize); + NVm::SetValue32(&globalData[NVm::NGlobalOffset::kBlockPos], 0); // It was commented. why? + NVm::SetValue32(&globalData[NVm::NGlobalOffset::kExecCount], tempFilter->ExecCount); + + if (firstByte & 8) + { + UInt32 dataSize = NVm::ReadEncodedUInt32(inp); + if (dataSize > NVm::kGlobalSize - NVm::kFixedGlobalSize) + return false; + CRecordVector &globalData = tempFilter->GlobalData; + int requredSize = (int)(dataSize + NVm::kFixedGlobalSize); + if (globalData.Size() < requredSize) + { + globalData.Reserve(requredSize); + for (; globalData.Size() < requredSize; i++) + globalData.Add(0); + } + for (UInt32 i = 0; i < dataSize; i++) + globalData[NVm::kFixedGlobalSize + i] = (Byte)inp.ReadBits(8); + } + return true; +} + +bool CDecoder::ReadVmCodeLZ() +{ + UInt32 firstByte = m_InBitStream.ReadBits(8); + UInt32 length = (firstByte & 7) + 1; + if (length == 7) + length = m_InBitStream.ReadBits(8) + 7; + else if (length == 8) + length = m_InBitStream.ReadBits(16); + if (length > kVmDataSizeMax) + return false; + for (UInt32 i = 0; i < length; i++) + _vmData[i] = (Byte)m_InBitStream.ReadBits(8); + return AddVmCode(firstByte, length); +} + +bool CDecoder::ReadVmCodePPM() +{ + int firstByte = DecodePpmSymbol(); + if (firstByte == -1) + return false; + UInt32 length = (firstByte & 7) + 1; + if (length == 7) + { + int b1 = DecodePpmSymbol(); + if (b1 == -1) + return false; + length = b1 + 7; + } + else if (length == 8) + { + int b1 = DecodePpmSymbol(); + if (b1 == -1) + return false; + int b2 = DecodePpmSymbol(); + if (b2 == -1) + return false; + length = b1 * 256 + b2; + } + if (length > kVmDataSizeMax) + return false; + for (UInt32 i = 0; i < length; i++) + { + int b = DecodePpmSymbol(); + if (b == -1) + return false; + _vmData[i] = (Byte)b; + } + return AddVmCode(firstByte, length); +} + +#define RIF(x) { if (!(x)) return S_FALSE; } + +UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); } + +///////////////////////////////////////////////// +// PPM + +HRESULT CDecoder::InitPPM() +{ + Byte maxOrder = (Byte)ReadBits(7); + + bool reset = ((maxOrder & 0x20) != 0); + int maxMB = 0; + if (reset) + maxMB = (Byte)ReadBits(8); + else + { + if (_ppm.SubAllocator.GetSubAllocatorSize()== 0) + return S_FALSE; + } + if (maxOrder & 0x40) + PpmEscChar = (Byte)ReadBits(8); + m_InBitStream.InitRangeCoder(); + /* + if (m_InBitStream.m_BitPos != 0) + return S_FALSE; + */ + if (reset) + { + maxOrder = (maxOrder & 0x1F) + 1; + if (maxOrder > 16) + maxOrder = 16 + (maxOrder - 16) * 3; + if (maxOrder == 1) + { + // SubAlloc.StopSubAllocator(); + _ppm.SubAllocator.StopSubAllocator(); + return S_FALSE; + } + // SubAlloc.StartSubAllocator(MaxMB+1); + // StartModelRare(maxOrder); + + if (!_ppm.SubAllocator.StartSubAllocator((maxMB + 1) << 20)) + return E_OUTOFMEMORY; + _ppm.MaxOrder = 0; + _ppm.StartModelRare(maxOrder); + + } + // return (minContext != NULL); + + return S_OK; +} + +int CDecoder::DecodePpmSymbol() { return _ppm.DecodeSymbol(&m_InBitStream); } + +HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing) +{ + keepDecompressing = false; + do + { + if (((_wrPtr - _winPos) & kWindowMask) < 260 && _wrPtr != _winPos) + { + RINOK(WriteBuf()); + if (_writtenFileSize > _unpackSize) + { + keepDecompressing = false; + return S_OK; + } + } + int c = DecodePpmSymbol(); + if (c == -1) + { + // Original code sets PPMError=true here and then it returns S_OK. Why ??? + // return S_OK; + return S_FALSE; + } + if (c == PpmEscChar) + { + int nextCh = DecodePpmSymbol(); + if (nextCh == 0) + return ReadTables(keepDecompressing); + if (nextCh == 2 || nextCh == -1) + return S_OK; + if (nextCh == 3) + { + if (!ReadVmCodePPM()) + return S_FALSE; + continue; + } + if (nextCh == 4 || nextCh == 5) + { + UInt32 distance = 0; + UInt32 length = 4; + if (nextCh == 4) + { + for (int i = 0; i < 3; i++) + { + int c = DecodePpmSymbol(); + if (c == -1) + return S_OK; + distance = (distance << 8) + (Byte)c; + } + distance++; + length += 28; + } + int c = DecodePpmSymbol(); + if (c == -1) + return S_OK; + length += c; + if (distance >= _lzSize) + return S_FALSE; + CopyBlock(distance, length); + num -= (Int32)length; + continue; + } + } + PutByte((Byte)c); + num--; + } + while (num >= 0); + keepDecompressing = true; + return S_OK; +} + +///////////////////////////////////////////////// +// LZ + +HRESULT CDecoder::ReadTables(bool &keepDecompressing) +{ + keepDecompressing = true; + ReadBits((8 - m_InBitStream.GetBitPosition()) & 7); + if (ReadBits(1) != 0) + { + _lzMode = false; + return InitPPM(); + } + + _lzMode = true; + PrevAlignBits = 0; + PrevAlignCount = 0; + + Byte levelLevels[kLevelTableSize]; + Byte newLevels[kTablesSizesSum]; + + if (ReadBits(1) == 0) + memset(m_LastLevels, 0, kTablesSizesSum); + + int i; + for (i = 0; i < kLevelTableSize; i++) + { + UInt32 length = ReadBits(4); + if (length == 15) + { + UInt32 zeroCount = ReadBits(4); + if (zeroCount != 0) + { + zeroCount += 2; + while (zeroCount-- > 0 && i < kLevelTableSize) + levelLevels[i++]=0; + i--; + continue; + } + } + levelLevels[i] = (Byte)length; + } + RIF(m_LevelDecoder.SetCodeLengths(levelLevels)); + i = 0; + while (i < kTablesSizesSum) + { + UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); + if (number < 16) + { + newLevels[i] = Byte((number + m_LastLevels[i]) & 15); + i++; + } + else if (number > kLevelTableSize) + return S_FALSE; + else + { + int num; + if (((number - 16) & 1) == 0) + num = ReadBits(3) + 3; + else + num = ReadBits(7) + 11; + if (number < 18) + { + if (i == 0) + return S_FALSE; + for (; num > 0 && i < kTablesSizesSum; num--, i++) + newLevels[i] = newLevels[i - 1]; + } + else + { + for (; num > 0 && i < kTablesSizesSum; num--) + newLevels[i++] = 0; + } + } + } + TablesRead = true; + + // original code has check here: + /* + if (InAddr > ReadTop) + { + keepDecompressing = false; + return true; + } + */ + + RIF(m_MainDecoder.SetCodeLengths(&newLevels[0])); + RIF(m_DistDecoder.SetCodeLengths(&newLevels[kMainTableSize])); + RIF(m_AlignDecoder.SetCodeLengths(&newLevels[kMainTableSize + kDistTableSize])); + RIF(m_LenDecoder.SetCodeLengths(&newLevels[kMainTableSize + kDistTableSize + kAlignTableSize])); + + memcpy(m_LastLevels, newLevels, kTablesSizesSum); + return S_OK; +} + +class CCoderReleaser +{ + CDecoder *m_Coder; +public: + CCoderReleaser(CDecoder *coder): m_Coder(coder) {} + ~CCoderReleaser() + { + // m_Coder->m_OutWindowStream.Flush(); + m_Coder->ReleaseStreams(); + } +}; + +HRESULT CDecoder::ReadEndOfBlock(bool &keepDecompressing) +{ + if (ReadBits(1) != 0) + { + // old file + TablesRead = false; + return ReadTables(keepDecompressing); + } + // new file + keepDecompressing = false; + TablesRead = (ReadBits(1) == 0); + return S_OK; +} + +UInt32 kDistStart[kDistTableSize]; + +class CDistInit +{ +public: + CDistInit() { Init(); } + void Init() + { + UInt32 start = 0; + for (UInt32 i = 0; i < kDistTableSize; i++) + { + kDistStart[i] = start; + start += (1 << kDistDirectBits[i]); + } + } +} g_DistInit; + +HRESULT CDecoder::DecodeLZ(bool &keepDecompressing) +{ + UInt32 rep0 = _reps[0]; + UInt32 rep1 = _reps[1]; + UInt32 rep2 = _reps[2]; + UInt32 rep3 = _reps[3]; + UInt32 length = _lastLength; + for (;;) + { + if (((_wrPtr - _winPos) & kWindowMask) < 260 && _wrPtr != _winPos) + { + RINOK(WriteBuf()); + if (_writtenFileSize > _unpackSize) + { + keepDecompressing = false; + return S_OK; + } + } + UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); + if (number < 256) + { + PutByte(Byte(number)); + + continue; + } + else if (number == kSymbolReadTable) + { + RINOK(ReadEndOfBlock(keepDecompressing)); + break; + } + else if (number == 257) + { + if (!ReadVmCodeLZ()) + return S_FALSE; + continue; + } + else if (number == 258) + { + } + else if (number < kSymbolRep + 4) + { + if (number != kSymbolRep) + { + UInt32 distance; + if (number == kSymbolRep + 1) + distance = rep1; + else + { + if (number == kSymbolRep + 2) + distance = rep2; + else + { + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + + UInt32 number = m_LenDecoder.DecodeSymbol(&m_InBitStream); + if (number >= kLenTableSize) + return S_FALSE; + length = 2 + kLenStart[number] + m_InBitStream.ReadBits(kLenDirectBits[number]); + } + else + { + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + if (number < 271) + { + number -= 263; + rep0 = kLen2DistStarts[number] + m_InBitStream.ReadBits(kLen2DistDirectBits[number]); + length = 2; + } + else if (number < 299) + { + number -= 271; + length = kNormalMatchMinLen + (UInt32)kLenStart[number] + m_InBitStream.ReadBits(kLenDirectBits[number]); + UInt32 number = m_DistDecoder.DecodeSymbol(&m_InBitStream); + if (number >= kDistTableSize) + return S_FALSE; + rep0 = kDistStart[number]; + int numBits = kDistDirectBits[number]; + if (number >= (kNumAlignBits * 2) + 2) + { + if (numBits > kNumAlignBits) + rep0 += (m_InBitStream.ReadBits(numBits - kNumAlignBits) << kNumAlignBits); + if (PrevAlignCount > 0) + { + PrevAlignCount--; + rep0 += PrevAlignBits; + } + else + { + UInt32 number = m_AlignDecoder.DecodeSymbol(&m_InBitStream); + if (number < (1 << kNumAlignBits)) + { + rep0 += number; + PrevAlignBits = number; + } + else if (number == (1 << kNumAlignBits)) + { + PrevAlignCount = kNumAlignReps; + rep0 += PrevAlignBits; + } + else + return S_FALSE; + } + } + else + rep0 += m_InBitStream.ReadBits(numBits); + length += ((kDistLimit4 - rep0) >> 31) + ((kDistLimit3 - rep0) >> 31); + } + else + return S_FALSE; + } + if (rep0 >= _lzSize) + return S_FALSE; + CopyBlock(rep0, length); + } + _reps[0] = rep0; + _reps[1] = rep1; + _reps[2] = rep2; + _reps[3] = rep3; + _lastLength = length; + + return S_OK; +} + +HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) +{ + _writtenFileSize = 0; + if (!m_IsSolid) + { + _lzSize = 0; + _winPos = 0; + _wrPtr = 0; + for (int i = 0; i < kNumReps; i++) + _reps[i] = 0; + _lastLength = 0; + memset(m_LastLevels, 0, kTablesSizesSum); + TablesRead = false; + PpmEscChar = 2; + InitFilters(); + } + if (!m_IsSolid || !TablesRead) + { + bool keepDecompressing; + RINOK(ReadTables(keepDecompressing)); + if (!keepDecompressing) + return S_OK; + } + + for(;;) + { + bool keepDecompressing; + if (_lzMode) + { + RINOK(DecodeLZ(keepDecompressing)) + } + else + { + RINOK(DecodePPM(1 << 18, keepDecompressing)) + } + UInt64 packSize = m_InBitStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize)); + if (!keepDecompressing) + break; + } + RINOK(WriteBuf()); + if (_writtenFileSize < _unpackSize) + return S_FALSE; + // return m_OutWindowStream.Flush(); + return S_OK; +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + try + { + if (inSize == NULL || outSize == NULL) + return E_INVALIDARG; + + if (_vmData == 0) + { + _vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax); + if (_vmData == 0) + return E_OUTOFMEMORY; + _vmCode = _vmData + kVmDataSizeMax; + } + + if (_window == 0) + { + _window = (Byte *)::MidAlloc(kWindowSize); + if (_window == 0) + return E_OUTOFMEMORY; + } + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_vm.Create()) + return E_OUTOFMEMORY; + + + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + _outStream = outStream; + + CCoderReleaser coderReleaser(this); + _unpackSize = *outSize; + return CodeReal(progress); + } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } + // CNewException is possible here. But probably CNewException is caused + // by error in data stream. +} + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + if (size < 1) + return E_INVALIDARG; + m_IsSolid = (data[0] != 0); + return S_OK; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/Rar3Decoder.h b/desmume/src/windows/7z/CPP/7zip/Compress/Rar3Decoder.h new file mode 100644 index 000000000..da0b73f19 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/Rar3Decoder.h @@ -0,0 +1,301 @@ +// Rar3Decoder.h +// According to unRAR license, this code may not be used to develop +// a program that creates RAR archives + +#ifndef __COMPRESS_RAR3_DECODER_H +#define __COMPRESS_RAR3_DECODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "../Common/InBuffer.h" + +#include "BitmDecoder.h" +#include "HuffmanDecoder.h" +#include "PpmdDecode.h" +#include "Rar3Vm.h" + +namespace NCompress { +namespace NRar3 { + +const UInt32 kWindowSize = 1 << 22; +const UInt32 kWindowMask = (kWindowSize - 1); + +const UInt32 kNumReps = 4; +const UInt32 kNumLen2Symbols = 8; +const UInt32 kLenTableSize = 28; +const UInt32 kMainTableSize = 256 + 1 + 1 + 1 + kNumReps + kNumLen2Symbols + kLenTableSize; +const UInt32 kDistTableSize = 60; + +const int kNumAlignBits = 4; +const UInt32 kAlignTableSize = (1 << kNumAlignBits) + 1; + +const UInt32 kLevelTableSize = 20; + +const UInt32 kTablesSizesSum = kMainTableSize + kDistTableSize + kAlignTableSize + kLenTableSize; + +class CBitDecoder +{ + UInt32 m_Value; +public: + UInt32 m_BitPos; + CInBuffer m_Stream; + bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } + void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);} + void ReleaseStream() { m_Stream.ReleaseStream();} + + void Init() + { + m_Stream.Init(); + m_BitPos = 0; + m_Value = 0; + // m_BitPos = kNumBigValueBits; + // Normalize(); + } + + UInt64 GetProcessedSize() const + { return m_Stream.GetProcessedSize() - (m_BitPos) / 8; } + UInt32 GetBitPosition() const { return ((8 - m_BitPos) & 7); } + + /* + void Normalize() + { + for (;m_BitPos >= 8; m_BitPos -= 8) + m_Value = (m_Value << 8) | m_Stream.ReadByte(); + } + */ + + UInt32 GetValue(UInt32 numBits) + { + // return (m_Value << m_BitPos) >> (kNumBigValueBits - numBits); + // return ((m_Value >> (8 - m_BitPos)) & kMask) >> (kNumValueBits - numBits); + if (m_BitPos < numBits) + { + m_BitPos += 8; + m_Value = (m_Value << 8) | m_Stream.ReadByte(); + if (m_BitPos < numBits) + { + m_BitPos += 8; + m_Value = (m_Value << 8) | m_Stream.ReadByte(); + } + } + return m_Value >> (m_BitPos - numBits); + } + + void MovePos(UInt32 numBits) + { + m_BitPos -= numBits; + m_Value = m_Value & ((1 << m_BitPos) - 1); + } + + UInt32 ReadBits(UInt32 numBits) + { + UInt32 res = GetValue(numBits); + MovePos(numBits); + return res; + } +}; + +const int kNumTopBits = 24; +const UInt32 kTopValue = (1 << kNumTopBits); +const UInt32 kBot = (1 << 15); + +class CRangeDecoder:public NPpmd::CRangeDecoderVirt, public CBitDecoder +{ +public: + UInt32 Range; + UInt32 Low; + UInt32 Code; + + void Normalize() + { + while ((Low ^ (Low + Range)) < kTopValue || + Range < kBot && ((Range = (0 - Low) & (kBot - 1)), 1)) + { + Code = (Code << 8) | m_Stream.ReadByte(); + Range <<= 8; + Low <<= 8; + } + } + + void InitRangeCoder() + { + Code = 0; + Low = 0; + Range = 0xFFFFFFFF; + for(int i = 0; i < 4; i++) + Code = (Code << 8) | ReadBits(8); + } + + virtual UInt32 GetThreshold(UInt32 total) + { + return (Code - Low) / ( Range /= total); + } + + virtual void Decode(UInt32 start, UInt32 size) + { + Low += start * Range; + Range *= size; + Normalize(); + } + + virtual UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) + { + if (((Code - Low) / (Range >>= numTotalBits)) < size0) + { + Decode(0, size0); + return 0; + } + else + { + Decode(size0, (1 << numTotalBits) - size0); + return 1; + } + } + + // UInt64 GetProcessedSizeRangeCoder() {return Stream.GetProcessedSize(); } +}; + + +struct CFilter: public NVm::CProgram +{ + CRecordVector GlobalData; + UInt32 BlockStart; + UInt32 BlockSize; + UInt32 ExecCount; + CFilter(): BlockStart(0), BlockSize(0), ExecCount(0) {} +}; + +struct CTempFilter: public NVm::CProgramInitState +{ + UInt32 BlockStart; + UInt32 BlockSize; + UInt32 ExecCount; + bool NextWindow; + + UInt32 FilterIndex; +}; + +const int kNumHuffmanBits = 15; + +class CDecoder: + public ICompressCoder, + public ICompressSetDecoderProperties2, + public CMyUnknownImp +{ + CRangeDecoder m_InBitStream; + Byte *_window; + UInt32 _winPos; + UInt32 _wrPtr; + UInt64 _lzSize; + UInt64 _unpackSize; + UInt64 _writtenFileSize; // if it's > _unpackSize, then _unpackSize only written + CMyComPtr _outStream; + NHuffman::CDecoder m_MainDecoder; + NHuffman::CDecoder m_DistDecoder; + NHuffman::CDecoder m_AlignDecoder; + NHuffman::CDecoder m_LenDecoder; + NHuffman::CDecoder m_LevelDecoder; + + UInt32 _reps[kNumReps]; + UInt32 _lastLength; + + Byte m_LastLevels[kTablesSizesSum]; + + Byte *_vmData; + Byte *_vmCode; + NVm::CVm _vm; + CRecordVector _filters; + CRecordVector _tempFilters; + UInt32 _lastFilter; + + bool m_IsSolid; + + bool _lzMode; + + UInt32 PrevAlignBits; + UInt32 PrevAlignCount; + + bool TablesRead; + + NPpmd::CDecodeInfo _ppm; + int PpmEscChar; + + HRESULT WriteDataToStream(const Byte *data, UInt32 size); + HRESULT WriteData(const Byte *data, UInt32 size); + HRESULT WriteArea(UInt32 startPtr, UInt32 endPtr); + void ExecuteFilter(int tempFilterIndex, NVm::CBlockRef &outBlockRef); + HRESULT WriteBuf(); + + void InitFilters(); + bool AddVmCode(UInt32 firstByte, UInt32 codeSize); + bool ReadVmCodeLZ(); + bool ReadVmCodePPM(); + + UInt32 ReadBits(int numBits); + + HRESULT InitPPM(); + int DecodePpmSymbol(); + HRESULT DecodePPM(Int32 num, bool &keepDecompressing); + + HRESULT ReadTables(bool &keepDecompressing); + HRESULT ReadEndOfBlock(bool &keepDecompressing); + HRESULT DecodeLZ(bool &keepDecompressing); + HRESULT CodeReal(ICompressProgressInfo *progress); +public: + CDecoder(); + ~CDecoder(); + + MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) + + void ReleaseStreams() + { + _outStream.Release(); + m_InBitStream.ReleaseStream(); + } + + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + + void CopyBlock(UInt32 distance, UInt32 len) + { + _lzSize += len; + UInt32 pos = (_winPos - distance - 1) & kWindowMask; + Byte *window = _window; + UInt32 winPos = _winPos; + if (kWindowSize - winPos > len && kWindowSize - pos > len) + { + const Byte *src = window + pos; + Byte *dest = window + winPos; + _winPos += len; + do + *dest++ = *src++; + while(--len != 0); + return; + } + do + { + window[winPos] = window[pos]; + winPos = (winPos + 1) & kWindowMask; + pos = (pos + 1) & kWindowMask; + } + while(--len != 0); + _winPos = winPos; + } + + void PutByte(Byte b) + { + _window[_winPos] = b; + _winPos = (_winPos + 1) & kWindowMask; + _lzSize++; + } + + +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/Rar3Vm.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/Rar3Vm.cpp new file mode 100644 index 000000000..6aeabbccc --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/Rar3Vm.cpp @@ -0,0 +1,1094 @@ +// Rar3Vm.cpp +// According to unRAR license, this code may not be used to develop +// a program that creates RAR archives + +/* +Note: + Due to performance considerations Rar VM may set Flags C incorrectly + for some operands (SHL x, 0, ... ). + Check implementation of concrete VM command + to see if it sets flags right. +*/ + +#include "StdAfx.h" + +extern "C" +{ +#include "../../../C/7zCrc.h" +#include "../../../C/Alloc.h" +} + +#include "Rar3Vm.h" + +namespace NCompress { +namespace NRar3 { + +UInt32 CMemBitDecoder::ReadBits(int numBits) +{ + UInt32 res = 0; + for (;;) + { + Byte b = _bitPos < _bitSize ? _data[_bitPos >> 3] : 0; + int avail = (int)(8 - (_bitPos & 7)); + if (numBits <= avail) + { + _bitPos += numBits; + return res | (b >> (avail - numBits)) & ((1 << numBits) - 1); + } + numBits -= avail; + res |= (UInt32)(b & ((1 << avail) - 1)) << numBits; + _bitPos += avail; + } +} + +UInt32 CMemBitDecoder::ReadBit() { return ReadBits(1); } + +namespace NVm { + +static const UInt32 kStackRegIndex = kNumRegs - 1; + +static const UInt32 FLAG_C = 1; +static const UInt32 FLAG_Z = 2; +static const UInt32 FLAG_S = 0x80000000; + +static const Byte CF_OP0 = 0; +static const Byte CF_OP1 = 1; +static const Byte CF_OP2 = 2; +static const Byte CF_OPMASK = 3; +static const Byte CF_BYTEMODE = 4; +static const Byte CF_JUMP = 8; +static const Byte CF_PROC = 16; +static const Byte CF_USEFLAGS = 32; +static const Byte CF_CHFLAGS = 64; + +static Byte kCmdFlags[]= +{ + /* CMD_MOV */ CF_OP2 | CF_BYTEMODE, + /* CMD_CMP */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_ADD */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_SUB */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_JZ */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_JNZ */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_INC */ CF_OP1 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_DEC */ CF_OP1 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_JMP */ CF_OP1 | CF_JUMP, + /* CMD_XOR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_AND */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_OR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_TEST */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_JS */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_JNS */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_JB */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_JBE */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_JA */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_JAE */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_PUSH */ CF_OP1, + /* CMD_POP */ CF_OP1, + /* CMD_CALL */ CF_OP1 | CF_PROC, + /* CMD_RET */ CF_OP0 | CF_PROC, + /* CMD_NOT */ CF_OP1 | CF_BYTEMODE, + /* CMD_SHL */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_SHR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_SAR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_NEG */ CF_OP1 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_PUSHA */ CF_OP0, + /* CMD_POPA */ CF_OP0, + /* CMD_PUSHF */ CF_OP0 | CF_USEFLAGS, + /* CMD_POPF */ CF_OP0 | CF_CHFLAGS, + /* CMD_MOVZX */ CF_OP2, + /* CMD_MOVSX */ CF_OP2, + /* CMD_XCHG */ CF_OP2 | CF_BYTEMODE, + /* CMD_MUL */ CF_OP2 | CF_BYTEMODE, + /* CMD_DIV */ CF_OP2 | CF_BYTEMODE, + /* CMD_ADC */ CF_OP2 | CF_BYTEMODE | CF_USEFLAGS | CF_CHFLAGS , + /* CMD_SBB */ CF_OP2 | CF_BYTEMODE | CF_USEFLAGS | CF_CHFLAGS , + /* CMD_PRINT */ CF_OP0 +}; + +CVm::CVm(): Mem(NULL) {} + +bool CVm::Create() +{ + if (Mem == NULL) + Mem = (Byte *)::MyAlloc(kSpaceSize + 4); + return (Mem != NULL); +} + +CVm::~CVm() +{ + ::MyFree(Mem); +} + +// CVm::Execute can change CProgram object: it clears progarm if VM returns error. + +bool CVm::Execute(CProgram *prg, const CProgramInitState *initState, + CBlockRef &outBlockRef, CRecordVector &outGlobalData) +{ + memcpy(R, initState->InitR, sizeof(initState->InitR)); + R[kStackRegIndex] = kSpaceSize; + R[kNumRegs] = 0; + Flags = 0; + + UInt32 globalSize = MyMin((UInt32)initState->GlobalData.Size(), kGlobalSize); + if (globalSize != 0) + memcpy(Mem + kGlobalOffset, &initState->GlobalData[0], globalSize); + UInt32 staticSize = MyMin((UInt32)prg->StaticData.Size(), kGlobalSize - globalSize); + if (staticSize != 0) + memcpy(Mem + kGlobalOffset + globalSize, &prg->StaticData[0], staticSize); + + bool res = true; + #ifdef RARVM_STANDARD_FILTERS + if (prg->StandardFilterIndex >= 0) + ExecuteStandardFilter(prg->StandardFilterIndex); + else + #endif + { + res = ExecuteCode(prg); + if (!res) + prg->Commands[0].OpCode = CMD_RET; + } + UInt32 newBlockPos = GetFixedGlobalValue32(NGlobalOffset::kBlockPos) & kSpaceMask; + UInt32 newBlockSize = GetFixedGlobalValue32(NGlobalOffset::kBlockSize) & kSpaceMask; + if (newBlockPos + newBlockSize >= kSpaceSize) + newBlockPos = newBlockSize = 0; + outBlockRef.Offset = newBlockPos; + outBlockRef.Size = newBlockSize; + + outGlobalData.Clear(); + UInt32 dataSize = GetFixedGlobalValue32(NGlobalOffset::kGlobalMemOutSize); + dataSize = MyMin(dataSize, kGlobalSize - kFixedGlobalSize); + if (dataSize != 0) + { + dataSize += kFixedGlobalSize; + outGlobalData.Reserve(dataSize); + for (UInt32 i = 0; i < dataSize; i++) + outGlobalData.Add(Mem[kGlobalOffset + i]); + } + return res; +} + + +#define SET_IP(IP) \ + if ((IP) >= numCommands) return true; \ + if (--maxOpCount <= 0) return false; \ + cmd = commands + (IP); + +#define GET_FLAG_S_B(res) (((res) & 0x80) ? FLAG_S : 0) +#define SET_IP_OP1 { UInt32 val = GetOperand32(&cmd->Op1); SET_IP(val); } +#define FLAGS_UPDATE_SZ Flags = res == 0 ? FLAG_Z : res & FLAG_S +#define FLAGS_UPDATE_SZ_B Flags = (res & 0xFF) == 0 ? FLAG_Z : GET_FLAG_S_B(res) + +UInt32 CVm::GetOperand32(const COperand *op) const +{ + switch(op->Type) + { + case OP_TYPE_REG: return R[op->Data]; + case OP_TYPE_REGMEM: return GetValue32(&Mem[(op->Base + R[op->Data]) & kSpaceMask]); + default: return op->Data; + } +} + +void CVm::SetOperand32(const COperand *op, UInt32 val) +{ + switch(op->Type) + { + case OP_TYPE_REG: R[op->Data] = val; return; + case OP_TYPE_REGMEM: SetValue32(&Mem[(op->Base + R[op->Data]) & kSpaceMask], val); return; + } +} + +Byte CVm::GetOperand8(const COperand *op) const +{ + switch(op->Type) + { + case OP_TYPE_REG: return (Byte)R[op->Data]; + case OP_TYPE_REGMEM: return Mem[(op->Base + R[op->Data]) & kSpaceMask];; + default: return (Byte)op->Data; + } +} + +void CVm::SetOperand8(const COperand *op, Byte val) +{ + switch(op->Type) + { + case OP_TYPE_REG: R[op->Data] = (R[op->Data] & 0xFFFFFF00) | val; return; + case OP_TYPE_REGMEM: Mem[(op->Base + R[op->Data]) & kSpaceMask] = val; return; + } +} + +UInt32 CVm::GetOperand(bool byteMode, const COperand *op) const +{ + if (byteMode) + return GetOperand8(op); + return GetOperand32(op); +} + +void CVm::SetOperand(bool byteMode, const COperand *op, UInt32 val) +{ + if (byteMode) + SetOperand8(op, (Byte)(val & 0xFF)); + else + SetOperand32(op, val); +} + +bool CVm::ExecuteCode(const CProgram *prg) +{ + Int32 maxOpCount = 25000000; + const CCommand *commands = &prg->Commands[0]; + const CCommand *cmd = commands; + UInt32 numCommands = prg->Commands.Size(); + for (;;) + { + switch(cmd->OpCode) + { + #ifndef RARVM_NO_VM + + case CMD_MOV: + SetOperand32(&cmd->Op1, GetOperand32(&cmd->Op2)); + break; + case CMD_MOVB: + SetOperand8(&cmd->Op1, GetOperand8(&cmd->Op2)); + break; + case CMD_CMP: + { + UInt32 v1 = GetOperand32(&cmd->Op1); + UInt32 res = v1 - GetOperand32(&cmd->Op2); + Flags = res == 0 ? FLAG_Z : (res > v1) | (res & FLAG_S); + } + break; + case CMD_CMPB: + { + Byte v1 = GetOperand8(&cmd->Op1); + Byte res = v1 - GetOperand8(&cmd->Op2); + res &= 0xFF; + Flags = res == 0 ? FLAG_Z : (res > v1) | GET_FLAG_S_B(res); + } + break; + case CMD_ADD: + { + UInt32 v1 = GetOperand32(&cmd->Op1); + UInt32 res = v1 + GetOperand32(&cmd->Op2); + SetOperand32(&cmd->Op1, res); + Flags = (res < v1) | (res == 0 ? FLAG_Z : (res & FLAG_S)); + } + break; + case CMD_ADDB: + { + Byte v1 = GetOperand8(&cmd->Op1); + Byte res = v1 + GetOperand8(&cmd->Op2); + res &= 0xFF; + SetOperand8(&cmd->Op1, (Byte)res); + Flags = (res < v1) | (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)); + } + break; + case CMD_ADC: + { + UInt32 v1 = GetOperand(cmd->ByteMode, &cmd->Op1); + UInt32 FC = (Flags & FLAG_C); + UInt32 res = v1 + GetOperand(cmd->ByteMode, &cmd->Op2) + FC; + if (cmd->ByteMode) + res &= 0xFF; + SetOperand(cmd->ByteMode, &cmd->Op1, res); + Flags = (res < v1 || res == v1 && FC) | (res == 0 ? FLAG_Z : (res & FLAG_S)); + } + break; + case CMD_SUB: + { + UInt32 v1 = GetOperand32(&cmd->Op1); + UInt32 res = v1 - GetOperand32(&cmd->Op2); + SetOperand32(&cmd->Op1, res); + Flags = res == 0 ? FLAG_Z : (res > v1) | (res & FLAG_S); + } + break; + case CMD_SUBB: + { + UInt32 v1 = GetOperand8(&cmd->Op1); + UInt32 res = v1 - GetOperand8(&cmd->Op2); + SetOperand8(&cmd->Op1, (Byte)res); + Flags = res == 0 ? FLAG_Z : (res > v1) | (res & FLAG_S); + } + break; + case CMD_SBB: + { + UInt32 v1 = GetOperand(cmd->ByteMode, &cmd->Op1); + UInt32 FC = (Flags & FLAG_C); + UInt32 res = v1 - GetOperand(cmd->ByteMode, &cmd->Op2) - FC; + // Flags = res == 0 ? FLAG_Z : (res > v1 || res == v1 && FC) | (res & FLAG_S); + if (cmd->ByteMode) + res &= 0xFF; + SetOperand(cmd->ByteMode, &cmd->Op1, res); + Flags = (res > v1 || res == v1 && FC) | (res == 0 ? FLAG_Z : (res & FLAG_S)); + } + break; + case CMD_INC: + { + UInt32 res = GetOperand32(&cmd->Op1) + 1; + SetOperand32(&cmd->Op1, res); + FLAGS_UPDATE_SZ; + } + break; + case CMD_INCB: + { + Byte res = GetOperand8(&cmd->Op1) + 1; + SetOperand8(&cmd->Op1, res);; + FLAGS_UPDATE_SZ_B; + } + break; + case CMD_DEC: + { + UInt32 res = GetOperand32(&cmd->Op1) - 1; + SetOperand32(&cmd->Op1, res); + FLAGS_UPDATE_SZ; + } + break; + case CMD_DECB: + { + Byte res = GetOperand8(&cmd->Op1) - 1; + SetOperand8(&cmd->Op1, res);; + FLAGS_UPDATE_SZ_B; + } + break; + case CMD_XOR: + { + UInt32 res = GetOperand32(&cmd->Op1) ^ GetOperand32(&cmd->Op2); + SetOperand32(&cmd->Op1, res); + FLAGS_UPDATE_SZ; + } + break; + case CMD_XORB: + { + Byte res = GetOperand8(&cmd->Op1) ^ GetOperand8(&cmd->Op2); + SetOperand8(&cmd->Op1, res); + FLAGS_UPDATE_SZ_B; + } + break; + case CMD_AND: + { + UInt32 res = GetOperand32(&cmd->Op1) & GetOperand32(&cmd->Op2); + SetOperand32(&cmd->Op1, res); + FLAGS_UPDATE_SZ; + } + break; + case CMD_ANDB: + { + Byte res = GetOperand8(&cmd->Op1) & GetOperand8(&cmd->Op2); + SetOperand8(&cmd->Op1, res); + FLAGS_UPDATE_SZ_B; + } + break; + case CMD_OR: + { + UInt32 res = GetOperand32(&cmd->Op1) | GetOperand32(&cmd->Op2); + SetOperand32(&cmd->Op1, res); + FLAGS_UPDATE_SZ; + } + break; + case CMD_ORB: + { + Byte res = GetOperand8(&cmd->Op1) | GetOperand8(&cmd->Op2); + SetOperand8(&cmd->Op1, res); + FLAGS_UPDATE_SZ_B; + } + break; + case CMD_TEST: + { + UInt32 res = GetOperand32(&cmd->Op1) & GetOperand32(&cmd->Op2); + FLAGS_UPDATE_SZ; + } + break; + case CMD_TESTB: + { + Byte res = GetOperand8(&cmd->Op1) & GetOperand8(&cmd->Op2); + FLAGS_UPDATE_SZ_B; + } + break; + case CMD_NOT: + SetOperand(cmd->ByteMode, &cmd->Op1, ~GetOperand(cmd->ByteMode, &cmd->Op1)); + break; + case CMD_NEG: + { + UInt32 res = 0 - GetOperand32(&cmd->Op1); + SetOperand32(&cmd->Op1, res); + Flags = res == 0 ? FLAG_Z : FLAG_C | (res & FLAG_S); + } + break; + case CMD_NEGB: + { + Byte res = (Byte)(0 - GetOperand8(&cmd->Op1)); + SetOperand8(&cmd->Op1, res); + Flags = res == 0 ? FLAG_Z : FLAG_C | GET_FLAG_S_B(res); + } + break; + + case CMD_SHL: + { + UInt32 v1 = GetOperand32(&cmd->Op1); + int v2 = (int)GetOperand32(&cmd->Op2); + UInt32 res = v1 << v2; + SetOperand32(&cmd->Op1, res); + Flags = (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 << (v2 - 1)) & 0x80000000 ? FLAG_C : 0); + } + break; + case CMD_SHLB: + { + Byte v1 = GetOperand8(&cmd->Op1); + int v2 = (int)GetOperand8(&cmd->Op2); + Byte res = (Byte)(v1 << v2); + SetOperand8(&cmd->Op1, res); + Flags = (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 << (v2 - 1)) & 0x80 ? FLAG_C : 0); + } + break; + case CMD_SHR: + { + UInt32 v1 = GetOperand32(&cmd->Op1); + int v2 = (int)GetOperand32(&cmd->Op2); + UInt32 res = v1 >> v2; + SetOperand32(&cmd->Op1, res); + Flags = (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 >> (v2 - 1)) & FLAG_C); + } + break; + case CMD_SHRB: + { + Byte v1 = GetOperand8(&cmd->Op1); + int v2 = (int)GetOperand8(&cmd->Op2); + Byte res = (Byte)(v1 >> v2); + SetOperand8(&cmd->Op1, res); + Flags = (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 >> (v2 - 1)) & FLAG_C); + } + break; + case CMD_SAR: + { + UInt32 v1 = GetOperand32(&cmd->Op1); + int v2 = (int)GetOperand32(&cmd->Op2); + UInt32 res = UInt32(((Int32)v1) >> v2); + SetOperand32(&cmd->Op1, res); + Flags= (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 >> (v2 - 1)) & FLAG_C); + } + break; + case CMD_SARB: + { + Byte v1 = GetOperand8(&cmd->Op1); + int v2 = (int)GetOperand8(&cmd->Op2); + Byte res = (Byte)(((signed char)v1) >> v2); + SetOperand8(&cmd->Op1, res); + Flags= (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 >> (v2 - 1)) & FLAG_C); + } + break; + + case CMD_JMP: + SET_IP_OP1; + continue; + case CMD_JZ: + if ((Flags & FLAG_Z) != 0) + { + SET_IP_OP1; + continue; + } + break; + case CMD_JNZ: + if ((Flags & FLAG_Z) == 0) + { + SET_IP_OP1; + continue; + } + break; + case CMD_JS: + if ((Flags & FLAG_S) != 0) + { + SET_IP_OP1; + continue; + } + break; + case CMD_JNS: + if ((Flags & FLAG_S) == 0) + { + SET_IP_OP1; + continue; + } + break; + case CMD_JB: + if ((Flags & FLAG_C) != 0) + { + SET_IP_OP1; + continue; + } + break; + case CMD_JBE: + if ((Flags & (FLAG_C | FLAG_Z)) != 0) + { + SET_IP_OP1; + continue; + } + break; + case CMD_JA: + if ((Flags & (FLAG_C | FLAG_Z)) == 0) + { + SET_IP_OP1; + continue; + } + break; + case CMD_JAE: + if ((Flags & FLAG_C) == 0) + { + SET_IP_OP1; + continue; + } + break; + + case CMD_PUSH: + R[kStackRegIndex] -= 4; + SetValue32(&Mem[R[kStackRegIndex] & kSpaceMask], GetOperand32(&cmd->Op1)); + break; + case CMD_POP: + SetOperand32(&cmd->Op1, GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask])); + R[kStackRegIndex] += 4; + break; + case CMD_CALL: + R[kStackRegIndex] -= 4; + SetValue32(&Mem[R[kStackRegIndex] & kSpaceMask], (UInt32)(cmd - commands + 1)); + SET_IP_OP1; + continue; + + case CMD_PUSHA: + { + for (UInt32 i = 0, SP = R[kStackRegIndex] - 4; i < kNumRegs; i++, SP -= 4) + SetValue32(&Mem[SP & kSpaceMask], R[i]); + R[kStackRegIndex] -= kNumRegs * 4; + } + break; + case CMD_POPA: + { + for (UInt32 i = 0, SP = R[kStackRegIndex]; i < kNumRegs; i++, SP += 4) + R[kStackRegIndex - i] = GetValue32(&Mem[SP & kSpaceMask]); + } + break; + case CMD_PUSHF: + R[kStackRegIndex] -= 4; + SetValue32(&Mem[R[kStackRegIndex]&kSpaceMask], Flags); + break; + case CMD_POPF: + Flags = GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask]); + R[kStackRegIndex] += 4; + break; + + case CMD_MOVZX: + SetOperand32(&cmd->Op1, GetOperand8(&cmd->Op2)); + break; + case CMD_MOVSX: + SetOperand32(&cmd->Op1, (UInt32)(Int32)(signed char)GetOperand8(&cmd->Op2)); + break; + case CMD_XCHG: + { + UInt32 v1 = GetOperand(cmd->ByteMode, &cmd->Op1); + SetOperand(cmd->ByteMode, &cmd->Op1, GetOperand(cmd->ByteMode, &cmd->Op2)); + SetOperand(cmd->ByteMode, &cmd->Op2, v1); + } + break; + case CMD_MUL: + { + UInt32 res = GetOperand32(&cmd->Op1) * GetOperand32(&cmd->Op2); + SetOperand32(&cmd->Op1, res); + } + break; + case CMD_MULB: + { + Byte res = GetOperand8(&cmd->Op1) * GetOperand8(&cmd->Op2); + SetOperand8(&cmd->Op1, res); + } + break; + case CMD_DIV: + { + UInt32 divider = GetOperand(cmd->ByteMode, &cmd->Op2); + if (divider != 0) + { + UInt32 res = GetOperand(cmd->ByteMode, &cmd->Op1) / divider; + SetOperand(cmd->ByteMode, &cmd->Op1, res); + } + } + break; + + #endif + + case CMD_RET: + { + if (R[kStackRegIndex] >= kSpaceSize) + return true; + UInt32 ip = GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask]); + SET_IP(ip); + R[kStackRegIndex] += 4; + continue; + } + case CMD_PRINT: + break; + } + cmd++; + --maxOpCount; + } +} + + +////////////////////////////////////////////////////// +// Read program + +UInt32 ReadEncodedUInt32(CMemBitDecoder &inp) +{ + switch(inp.ReadBits(2)) + { + case 0: + return inp.ReadBits(4); + case 1: + { + UInt32 v = inp.ReadBits(4); + if (v == 0) + return 0xFFFFFF00 | inp.ReadBits(8); + else + return (v << 4) | inp.ReadBits(4); + } + case 2: + return inp.ReadBits(16); + default: + return inp.ReadBits(32); + } +} + +void CVm::DecodeArg(CMemBitDecoder &inp, COperand &op, bool byteMode) +{ + if (inp.ReadBit()) + { + op.Type = OP_TYPE_REG; + op.Data = inp.ReadBits(kNumRegBits); + } + else if (inp.ReadBit() == 0) + { + op.Type = OP_TYPE_INT; + if (byteMode) + op.Data = inp.ReadBits(8); + else + op.Data = ReadEncodedUInt32(inp); + } + else + { + op.Type = OP_TYPE_REGMEM; + if (inp.ReadBit() == 0) + { + op.Data = inp.ReadBits(kNumRegBits); + op.Base = 0; + } + else + { + if (inp.ReadBit() == 0) + op.Data = inp.ReadBits(kNumRegBits); + else + op.Data = kNumRegs; + op.Base = ReadEncodedUInt32(inp); + } + } +} + +void CVm::ReadVmProgram(const Byte *code, UInt32 codeSize, CProgram *prg) +{ + CMemBitDecoder inp; + inp.Init(code, codeSize); + + prg->StaticData.Clear(); + if (inp.ReadBit()) + { + UInt32 dataSize = ReadEncodedUInt32(inp) + 1; + for (UInt32 i = 0; inp.Avail() && i < dataSize; i++) + prg->StaticData.Add((Byte)inp.ReadBits(8)); + } + while (inp.Avail()) + { + prg->Commands.Add(CCommand()); + CCommand *cmd = &prg->Commands.Back(); + if (inp.ReadBit() == 0) + cmd->OpCode = (ECommand)inp.ReadBits(3); + else + cmd->OpCode = (ECommand)(8 + inp.ReadBits(5)); + if (kCmdFlags[cmd->OpCode] & CF_BYTEMODE) + cmd->ByteMode = (inp.ReadBit()) ? true : false; + else + cmd->ByteMode = 0; + int opNum = (kCmdFlags[cmd->OpCode] & CF_OPMASK); + if (opNum > 0) + { + DecodeArg(inp, cmd->Op1, cmd->ByteMode); + if (opNum == 2) + DecodeArg(inp, cmd->Op2, cmd->ByteMode); + else + { + if (cmd->Op1.Type == OP_TYPE_INT && (kCmdFlags[cmd->OpCode] & (CF_JUMP | CF_PROC))) + { + int Distance = cmd->Op1.Data; + if (Distance >= 256) + Distance -= 256; + else + { + if (Distance >= 136) + Distance -= 264; + else if (Distance >= 16) + Distance -= 8; + else if (Distance >= 8) + Distance -= 16; + Distance += prg->Commands.Size() - 1; + } + cmd->Op1.Data = Distance; + } + } + } + if (cmd->ByteMode) + { + switch (cmd->OpCode) + { + case CMD_MOV: cmd->OpCode = CMD_MOVB; break; + case CMD_CMP: cmd->OpCode = CMD_CMPB; break; + case CMD_ADD: cmd->OpCode = CMD_ADDB; break; + case CMD_SUB: cmd->OpCode = CMD_SUBB; break; + case CMD_INC: cmd->OpCode = CMD_INCB; break; + case CMD_DEC: cmd->OpCode = CMD_DECB; break; + case CMD_XOR: cmd->OpCode = CMD_XORB; break; + case CMD_AND: cmd->OpCode = CMD_ANDB; break; + case CMD_OR: cmd->OpCode = CMD_ORB; break; + case CMD_TEST: cmd->OpCode = CMD_TESTB; break; + case CMD_NEG: cmd->OpCode = CMD_NEGB; break; + case CMD_SHL: cmd->OpCode = CMD_SHLB; break; + case CMD_SHR: cmd->OpCode = CMD_SHRB; break; + case CMD_SAR: cmd->OpCode = CMD_SARB; break; + case CMD_MUL: cmd->OpCode = CMD_MULB; break; + } + } + } +} + +#ifdef RARVM_STANDARD_FILTERS + +enum EStandardFilter +{ + SF_E8, + SF_E8E9, + SF_ITANIUM, + SF_RGB, + SF_AUDIO, + SF_DELTA, + SF_UPCASE +}; + +struct StandardFilterSignature +{ + UInt32 Length; + UInt32 CRC; + EStandardFilter Type; +} +kStdFilters[]= +{ + 53, 0xad576887, SF_E8, + 57, 0x3cd7e57e, SF_E8E9, + 120, 0x3769893f, SF_ITANIUM, + 29, 0x0e06077d, SF_DELTA, + 149, 0x1c2c5dc8, SF_RGB, + 216, 0xbc85e701, SF_AUDIO, + 40, 0x46b9c560, SF_UPCASE +}; + +static int FindStandardFilter(const Byte *code, UInt32 codeSize) +{ + UInt32 crc = CrcCalc(code, codeSize); + for (int i = 0; i < sizeof(kStdFilters) / sizeof(kStdFilters[0]); i++) + { + StandardFilterSignature &sfs = kStdFilters[i]; + if (sfs.CRC == crc && sfs.Length == codeSize) + return i; + } + return -1; +} + +#endif + +void CVm::PrepareProgram(const Byte *code, UInt32 codeSize, CProgram *prg) +{ + Byte xorSum = 0; + for (UInt32 i = 1; i < codeSize; i++) + xorSum ^= code[i]; + + prg->Commands.Clear(); + #ifdef RARVM_STANDARD_FILTERS + prg->StandardFilterIndex = -1; + #endif + + if (xorSum == code[0] && codeSize > 0) + { + #ifdef RARVM_STANDARD_FILTERS + prg->StandardFilterIndex = FindStandardFilter(code, codeSize); + if (prg->StandardFilterIndex >= 0) + return; + #endif + // 1 byte for checksum + ReadVmProgram(code + 1, codeSize - 1, prg); + } + prg->Commands.Add(CCommand()); + CCommand *cmd = &prg->Commands.Back(); + cmd->OpCode = CMD_RET; +} + +void CVm::SetMemory(UInt32 pos, const Byte *data, UInt32 dataSize) +{ + if (pos < kSpaceSize && data != Mem + pos) + memmove(Mem + pos, data, MyMin(dataSize, kSpaceSize - pos)); +} + +#ifdef RARVM_STANDARD_FILTERS + +static void E8E9Decode(Byte *data, UInt32 dataSize, UInt32 fileOffset, bool e9) +{ + if (dataSize <= 4) + return; + dataSize -= 4; + const UInt32 kFileSize = 0x1000000; + Byte cmpByte2 = (e9 ? 0xE9 : 0xE8); + for (UInt32 curPos = 0; curPos < dataSize;) + { + Byte curByte = *(data++); + curPos++; + if (curByte == 0xE8 || curByte == cmpByte2) + { + UInt32 offset = curPos + fileOffset; + UInt32 addr = (Int32)GetValue32(data); + if (addr < kFileSize) + SetValue32(data, addr - offset); + else if ((Int32)addr < 0 && (Int32)(addr + offset) >= 0) + SetValue32(data, addr + kFileSize); + data += 4; + curPos += 4; + } + } +} + +static inline UInt32 ItaniumGetOpType(const Byte *data, int bitPos) +{ + return (data[(unsigned int)bitPos >> 3] >> (bitPos & 7)) & 0xF; +} + + +static void ItaniumDecode(Byte *data, UInt32 dataSize, UInt32 fileOffset) +{ + UInt32 curPos = 0; + fileOffset >>= 4; + while (curPos < dataSize - 21) + { + int b = (data[0] & 0x1F) - 0x10; + if (b >= 0) + { + static Byte kCmdMasks[16] = {4,4,6,6,0,0,7,7,4,4,0,0,4,4,0,0}; + Byte cmdMask = kCmdMasks[b]; + if (cmdMask != 0) + for (int i = 0; i < 3; i++) + if (cmdMask & (1 << i)) + { + int startPos = i * 41 + 18; + if (ItaniumGetOpType(data, startPos + 24) == 5) + { + const UInt32 kMask = 0xFFFFF; + Byte *p = data + ((unsigned int)startPos >> 3); + UInt32 bitField = ((UInt32)p[0]) | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16); + int inBit = (startPos & 7); + UInt32 offset = (bitField >> inBit) & kMask; + UInt32 andMask = ~(kMask << inBit); + bitField = ((offset - fileOffset) & kMask) << inBit; + for (int j = 0; j < 3; j++) + { + p[j] &= andMask; + p[j] |= bitField; + andMask >>= 8; + bitField >>= 8; + } + } + } + } + data += 16; + curPos += 16; + fileOffset++; + } +} + +static void DeltaDecode(Byte *data, UInt32 dataSize, UInt32 numChannels) +{ + UInt32 srcPos = 0; + UInt32 border = dataSize * 2; + for (UInt32 curChannel = 0; curChannel < numChannels; curChannel++) + { + Byte prevByte = 0; + for (UInt32 destPos = dataSize + curChannel; destPos < border; destPos += numChannels) + data[destPos] = (prevByte = prevByte - data[srcPos++]); + } +} + +static void RgbDecode(Byte *srcData, UInt32 dataSize, UInt32 width, UInt32 posR) +{ + Byte *destData = srcData + dataSize; + const UInt32 numChannels = 3; + for (UInt32 curChannel = 0; curChannel < numChannels; curChannel++) + { + Byte prevByte = 0; + + for (UInt32 i = curChannel; i < dataSize; i+= numChannels) + { + unsigned int predicted; + if (i < width) + predicted = prevByte; + else + { + unsigned int upperLeftByte = destData[i - width]; + unsigned int upperByte = destData[i - width + 3]; + predicted = prevByte + upperByte - upperLeftByte; + int pa = abs((int)(predicted - prevByte)); + int pb = abs((int)(predicted - upperByte)); + int pc = abs((int)(predicted - upperLeftByte)); + if (pa <= pb && pa <= pc) + predicted = prevByte; + else + if (pb <= pc) + predicted = upperByte; + else + predicted = upperLeftByte; + } + destData[i] = prevByte = (Byte)(predicted - *(srcData++)); + } + } + if (dataSize < 3) + return; + for (UInt32 i = posR, border = dataSize - 2; i < border; i += 3) + { + Byte g = destData[i + 1]; + destData[i] = destData[i] + g; + destData[i + 2] = destData[i + 2] + g; + } +} + +static void AudioDecode(Byte *srcData, UInt32 dataSize, UInt32 numChannels) +{ + Byte *destData = srcData + dataSize; + for (UInt32 curChannel = 0; curChannel < numChannels; curChannel++) + { + UInt32 prevByte = 0, prevDelta = 0, dif[7]; + Int32 D1 = 0, D2 = 0, D3; + Int32 K1 = 0, K2 = 0, K3 = 0; + memset(dif, 0, sizeof(dif)); + + for (UInt32 i = curChannel, byteCount = 0; i < dataSize; i += numChannels, byteCount++) + { + D3 = D2; + D2 = prevDelta - D1; + D1 = prevDelta; + + UInt32 predicted = 8 * prevByte + K1 * D1 + K2 * D2 + K3 * D3; + predicted = (predicted >> 3) & 0xFF; + + UInt32 curByte = *(srcData++); + + predicted -= curByte; + destData[i] = (Byte)predicted; + prevDelta = (UInt32)(Int32)(signed char)(predicted - prevByte); + prevByte = predicted; + + Int32 D = ((Int32)(signed char)curByte) << 3; + + dif[0] += abs(D); + dif[1] += abs(D - D1); + dif[2] += abs(D + D1); + dif[3] += abs(D - D2); + dif[4] += abs(D + D2); + dif[5] += abs(D - D3); + dif[6] += abs(D + D3); + + if ((byteCount & 0x1F) == 0) + { + UInt32 minDif = dif[0], numMinDif = 0; + dif[0] = 0; + for (int j = 1; j < sizeof(dif) / sizeof(dif[0]); j++) + { + if (dif[j] < minDif) + { + minDif = dif[j]; + numMinDif = j; + } + dif[j] = 0; + } + switch (numMinDif) + { + case 1: if (K1 >= -16) K1--; break; + case 2: if (K1 < 16) K1++; break; + case 3: if (K2 >= -16) K2--; break; + case 4: if (K2 < 16) K2++; break; + case 5: if (K3 >= -16) K3--; break; + case 6: if (K3 < 16) K3++; break; + } + } + } + } +} + +static UInt32 UpCaseDecode(Byte *data, UInt32 dataSize) +{ + UInt32 srcPos = 0, destPos = dataSize; + while (srcPos < dataSize) + { + Byte curByte = data[srcPos++]; + if (curByte == 2 && (curByte = data[srcPos++]) != 2) + curByte -= 32; + data[destPos++] = curByte; + } + return destPos - dataSize; +} + +void CVm::ExecuteStandardFilter(int filterIndex) +{ + UInt32 dataSize = R[4]; + if (dataSize >= kGlobalOffset) + return; + EStandardFilter filterType = kStdFilters[filterIndex].Type; + + switch (filterType) + { + case SF_E8: + case SF_E8E9: + E8E9Decode(Mem, dataSize, R[6], (filterType == SF_E8E9)); + break; + case SF_ITANIUM: + ItaniumDecode(Mem, dataSize, R[6]); + break; + case SF_DELTA: + if (dataSize >= kGlobalOffset / 2) + break; + SetBlockPos(dataSize); + DeltaDecode(Mem, dataSize, R[0]); + break; + case SF_RGB: + if (dataSize >= kGlobalOffset / 2) + break; + { + UInt32 width = R[0]; + if (width <= 3) + break; + SetBlockPos(dataSize); + RgbDecode(Mem, dataSize, width, R[1]); + } + break; + case SF_AUDIO: + if (dataSize >= kGlobalOffset / 2) + break; + SetBlockPos(dataSize); + AudioDecode(Mem, dataSize, R[0]); + break; + case SF_UPCASE: + if (dataSize >= kGlobalOffset / 2) + break; + UInt32 destSize = UpCaseDecode(Mem, dataSize); + SetBlockSize(destSize); + SetBlockPos(dataSize); + break; + } +} + +#endif + +}}} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/Rar3Vm.h b/desmume/src/windows/7z/CPP/7zip/Compress/Rar3Vm.h new file mode 100644 index 000000000..0d16e42cc --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/Rar3Vm.h @@ -0,0 +1,179 @@ +// Rar3Vm.h +// According to unRAR license, this code may not be used to develop +// a program that creates RAR archives + +#ifndef __COMPRESS_RAR3_VM_H +#define __COMPRESS_RAR3_VM_H + +#include "../../../C/CpuArch.h" + +#include "Common/MyVector.h" +#include "Common/Types.h" + +#define RARVM_STANDARD_FILTERS + +namespace NCompress { +namespace NRar3 { + +class CMemBitDecoder +{ + const Byte *_data; + UInt32 _bitSize; + UInt32 _bitPos; +public: + void Init(const Byte *data, UInt32 byteSize) + { + _data = data; + _bitSize = (byteSize << 3); + _bitPos = 0; + } + UInt32 ReadBits(int numBits); + UInt32 ReadBit(); + bool Avail() const { return (_bitPos < _bitSize); } +}; + +namespace NVm { + +inline UInt32 GetValue32(const void *addr) { return GetUi32(addr); } +inline void SetValue32(void *addr, UInt32 value) { SetUi32(addr, value); } + +UInt32 ReadEncodedUInt32(CMemBitDecoder &inp); + +const int kNumRegBits = 3; +const UInt32 kNumRegs = 1 << kNumRegBits; +const UInt32 kNumGpRegs = kNumRegs - 1; + +const UInt32 kSpaceSize = 0x40000; +const UInt32 kSpaceMask = kSpaceSize -1; +const UInt32 kGlobalOffset = 0x3C000; +const UInt32 kGlobalSize = 0x2000; +const UInt32 kFixedGlobalSize = 64; + +namespace NGlobalOffset +{ + const UInt32 kBlockSize = 0x1C; + const UInt32 kBlockPos = 0x20; + const UInt32 kExecCount = 0x2C; + const UInt32 kGlobalMemOutSize = 0x30; +} + +enum ECommand +{ + CMD_MOV, CMD_CMP, CMD_ADD, CMD_SUB, CMD_JZ, CMD_JNZ, CMD_INC, CMD_DEC, + CMD_JMP, CMD_XOR, CMD_AND, CMD_OR, CMD_TEST, CMD_JS, CMD_JNS, CMD_JB, + CMD_JBE, CMD_JA, CMD_JAE, CMD_PUSH, CMD_POP, CMD_CALL, CMD_RET, CMD_NOT, + CMD_SHL, CMD_SHR, CMD_SAR, CMD_NEG, CMD_PUSHA,CMD_POPA, CMD_PUSHF,CMD_POPF, + CMD_MOVZX,CMD_MOVSX,CMD_XCHG, CMD_MUL, CMD_DIV, CMD_ADC, CMD_SBB, CMD_PRINT, + + CMD_MOVB, CMD_CMPB, CMD_ADDB, CMD_SUBB, CMD_INCB, CMD_DECB, + CMD_XORB, CMD_ANDB, CMD_ORB, CMD_TESTB,CMD_NEGB, + CMD_SHLB, CMD_SHRB, CMD_SARB, CMD_MULB +}; + +enum EOpType {OP_TYPE_REG, OP_TYPE_INT, OP_TYPE_REGMEM, OP_TYPE_NONE}; + +// Addr in COperand object can link (point) to CVm object!!! + +struct COperand +{ + EOpType Type; + UInt32 Data; + UInt32 Base; + COperand(): Type(OP_TYPE_NONE), Data(0), Base(0) {} +}; + +struct CCommand +{ + ECommand OpCode; + bool ByteMode; + COperand Op1, Op2; +}; + +struct CBlockRef +{ + UInt32 Offset; + UInt32 Size; +}; + +struct CProgram +{ + CRecordVector Commands; + #ifdef RARVM_STANDARD_FILTERS + int StandardFilterIndex; + #endif + CRecordVector StaticData; +}; + +struct CProgramInitState +{ + UInt32 InitR[kNumGpRegs]; + CRecordVector GlobalData; + + void AllocateEmptyFixedGlobal() + { + GlobalData.Clear(); + GlobalData.Reserve(NVm::kFixedGlobalSize); + for (UInt32 i = 0; i < NVm::kFixedGlobalSize; i++) + GlobalData.Add(0); + } +}; + +class CVm +{ + static UInt32 GetValue(bool byteMode, const void *addr) + { + if (byteMode) + return(*(const Byte *)addr); + else + return GetUi32(addr); + } + + static void SetValue(bool byteMode, void *addr, UInt32 value) + { + if (byteMode) + *(Byte *)addr = (Byte)value; + else + SetUi32(addr, value); + } + + UInt32 GetFixedGlobalValue32(UInt32 globalOffset) { return GetValue(false, &Mem[kGlobalOffset + globalOffset]); } + + void SetBlockSize(UInt32 v) { SetValue(&Mem[kGlobalOffset + NGlobalOffset::kBlockSize], v); } + void SetBlockPos(UInt32 v) { SetValue(&Mem[kGlobalOffset + NGlobalOffset::kBlockPos], v); } +public: + static void SetValue(void *addr, UInt32 value) { SetValue(false, addr, value); } +private: + UInt32 GetOperand32(const COperand *op) const; + void SetOperand32(const COperand *op, UInt32 val); + Byte GetOperand8(const COperand *op) const; + void SetOperand8(const COperand *op, Byte val); + UInt32 GetOperand(bool byteMode, const COperand *op) const; + void SetOperand(bool byteMode, const COperand *op, UInt32 val); + + void DecodeArg(CMemBitDecoder &inp, COperand &op, bool byteMode); + + bool ExecuteCode(const CProgram *prg); + + #ifdef RARVM_STANDARD_FILTERS + void ExecuteStandardFilter(int filterIndex); + #endif + + Byte *Mem; + UInt32 R[kNumRegs + 1]; // R[kNumRegs] = 0 always (speed optimization) + UInt32 Flags; + void ReadVmProgram(const Byte *code, UInt32 codeSize, CProgram *prg); +public: + CVm(); + ~CVm(); + bool Create(); + void PrepareProgram(const Byte *code, UInt32 codeSize, CProgram *prg); + void SetMemory(UInt32 pos, const Byte *data, UInt32 dataSize); + bool Execute(CProgram *prg, const CProgramInitState *initState, + CBlockRef &outBlockRef, CRecordVector &outGlobalData); + const Byte *GetDataPointer(UInt32 offset) const { return Mem + offset; } + +}; + +#endif + +}}} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/RarCodecsRegister.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/RarCodecsRegister.cpp new file mode 100644 index 000000000..cb6242b3d --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/RarCodecsRegister.cpp @@ -0,0 +1,26 @@ +// RarCodecsRegister.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "Rar1Decoder.h" +#include "Rar2Decoder.h" +#include "Rar3Decoder.h" + +#define CREATE_CODEC(x) static void *CreateCodec ## x() { return (void *)(ICompressCoder *)(new NCompress::NRar ## x::CDecoder); } + +CREATE_CODEC(1) +CREATE_CODEC(2) +CREATE_CODEC(3) + +#define RAR_CODEC(x, name) { CreateCodec ## x, 0, 0x040300 + x, L"Rar" name, 1, false } + +static CCodecInfo g_CodecsInfo[] = +{ + RAR_CODEC(1, L"1"), + RAR_CODEC(2, L"2"), + RAR_CODEC(3, L"3"), +}; + +REGISTER_CODECS(Rar) diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/ShrinkDecoder.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/ShrinkDecoder.cpp new file mode 100644 index 000000000..2146fa733 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/ShrinkDecoder.cpp @@ -0,0 +1,148 @@ +// ShrinkDecoder.cpp + +#include "StdAfx.h" + +extern "C" +{ +#include "../../../C/Alloc.h" +} + +#include "../Common/InBuffer.h" +#include "../Common/OutBuffer.h" + +#include "BitlDecoder.h" +#include "ShrinkDecoder.h" + +namespace NCompress { +namespace NShrink { + +static const UInt32 kBufferSize = (1 << 20); +static const int kNumMinBits = 9; + +HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) +{ + NBitl::CBaseDecoder inBuffer; + COutBuffer outBuffer; + + if (!inBuffer.Create(kBufferSize)) + return E_OUTOFMEMORY; + inBuffer.SetStream(inStream); + inBuffer.Init(); + + if (!outBuffer.Create(kBufferSize)) + return E_OUTOFMEMORY; + outBuffer.SetStream(outStream); + outBuffer.Init(); + + UInt64 prevPos = 0; + int numBits = kNumMinBits; + UInt32 head = 257; + bool needPrev = false; + UInt32 lastSymbol = 0; + + int i; + for (i = 0; i < kNumItems; i++) + _parents[i] = 0; + for (i = 0; i < kNumItems; i++) + _suffixes[i] = 0; + for (i = 0; i < 257; i++) + _isFree[i] = false; + for (; i < kNumItems; i++) + _isFree[i] = true; + + for (;;) + { + UInt32 symbol = inBuffer.ReadBits(numBits); + if (inBuffer.ExtraBitsWereRead()) + break; + if (_isFree[symbol]) + return S_FALSE; + if (symbol == 256) + { + UInt32 symbol = inBuffer.ReadBits(numBits); + if (symbol == 1) + { + if (numBits < kNumMaxBits) + numBits++; + } + else if (symbol == 2) + { + if (needPrev) + _isFree[head - 1] = true; + for (i = 257; i < kNumItems; i++) + _isParent[i] = false; + for (i = 257; i < kNumItems; i++) + if (!_isFree[i]) + _isParent[_parents[i]] = true; + for (i = 257; i < kNumItems; i++) + if (!_isParent[i]) + _isFree[i] = true; + head = 257; + while (head < kNumItems && !_isFree[head]) + head++; + if (head < kNumItems) + { + needPrev = true; + _isFree[head] = false; + _parents[head] = (UInt16)lastSymbol; + head++; + } + } + else + return S_FALSE; + continue; + } + UInt32 cur = symbol; + i = 0; + int corectionIndex = -1; + while (cur >= 256) + { + if (cur == head - 1) + corectionIndex = i; + _stack[i++] = _suffixes[cur]; + cur = _parents[cur]; + } + _stack[i++] = (Byte)cur; + if (needPrev) + { + _suffixes[head - 1] = (Byte)cur; + if (corectionIndex >= 0) + _stack[corectionIndex] = (Byte)cur; + } + while (i > 0) + outBuffer.WriteByte((_stack[--i])); + while (head < kNumItems && !_isFree[head]) + head++; + if (head < kNumItems) + { + needPrev = true; + _isFree[head] = false; + _parents[head] = (UInt16)symbol; + head++; + } + else + needPrev = false; + lastSymbol = symbol; + + UInt64 nowPos = outBuffer.GetProcessedSize(); + if (progress != NULL && nowPos - prevPos > (1 << 18)) + { + prevPos = nowPos; + UInt64 packSize = inBuffer.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &nowPos)); + } + } + return outBuffer.Flush(); +} + +STDMETHODIMP CDecoder ::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/ShrinkDecoder.h b/desmume/src/windows/7z/CPP/7zip/Compress/ShrinkDecoder.h new file mode 100644 index 000000000..00f416402 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/ShrinkDecoder.h @@ -0,0 +1,38 @@ +// ShrinkDecoder.h + +#ifndef __COMPRESS_SHRINK_DECODER_H +#define __COMPRESS_SHRINK_DECODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +namespace NCompress { +namespace NShrink { + +const int kNumMaxBits = 13; +const UInt32 kNumItems = 1 << kNumMaxBits; + +class CDecoder : + public ICompressCoder, + public CMyUnknownImp +{ + UInt16 _parents[kNumItems]; + Byte _suffixes[kNumItems]; + Byte _stack[kNumItems]; + bool _isFree[kNumItems]; + bool _isParent[kNumItems]; + +public: + MY_UNKNOWN_IMP + + HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/StdAfx.h b/desmume/src/windows/7z/CPP/7zip/Compress/StdAfx.h new file mode 100644 index 000000000..c28ffcea7 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../Common/MyWindows.h" + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/ZlibDecoder.cpp b/desmume/src/windows/7z/CPP/7zip/Compress/ZlibDecoder.cpp new file mode 100644 index 000000000..505f21798 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/ZlibDecoder.cpp @@ -0,0 +1,94 @@ +// ZlibDecoder.cpp + +#include "StdAfx.h" + +#include "../Common/StreamUtils.h" + +#include "DeflateDecoder.h" +#include "ZlibDecoder.h" + +namespace NCompress { +namespace NZlib { + +#define DEFLATE_TRY_BEGIN try { +#define DEFLATE_TRY_END } \ + catch(...) { return S_FALSE; } + +#define ADLER_MOD 65521 +#define ADLER_LOOP_MAX 5550 + +static UInt32 Adler32_Update(UInt32 adler, const Byte *buf, size_t size) +{ + UInt32 a = adler & 0xFFFF; + UInt32 b = (adler >> 16) & 0xFFFF; + while (size > 0) + { + unsigned curSize = (size > ADLER_LOOP_MAX) ? ADLER_LOOP_MAX : (unsigned )size; + unsigned i; + for (i = 0; i < curSize; i++) + { + a += buf[i]; + b += a; + } + buf += curSize; + size -= curSize; + a %= ADLER_MOD; + b %= ADLER_MOD; + } + return (b << 16) + a; +} + +STDMETHODIMP COutStreamWithAdler::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + HRESULT result = _stream->Write(data, size, &size); + _adler = Adler32_Update(_adler, (const Byte *)data, size); + if (processedSize != NULL) + *processedSize = size; + return result; +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + DEFLATE_TRY_BEGIN + if (!AdlerStream) + { + AdlerSpec = new COutStreamWithAdler; + AdlerStream = AdlerSpec; + } + if (!DeflateDecoder) + { + DeflateDecoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder; + DeflateDecoderSpec->ZlibMode = true; + DeflateDecoder = DeflateDecoderSpec; + } + + Byte buf[2]; + RINOK(ReadStream_FALSE(inStream, buf, 2)); + int method = buf[0] & 0xF; + if (method != 8) + return S_FALSE; + // int dicSize = buf[0] >> 4; + if ((((UInt32)buf[0] << 8) + buf[1]) % 31 != 0) + return S_FALSE; + if ((buf[1] & 0x20) != 0) // dictPresent + return S_FALSE; + // int level = (buf[1] >> 6); + + AdlerSpec->SetStream(outStream); + AdlerSpec->Init(); + HRESULT res = DeflateDecoder->Code(inStream, AdlerStream, inSize, outSize, progress); + AdlerSpec->ReleaseStream(); + + if (res == S_OK) + { + const Byte *p = DeflateDecoderSpec->ZlibFooter; + UInt32 adler = ((UInt32)p[0] << 24) | ((UInt32)p[1] << 16) | ((UInt32)p[2] << 8) | p[3]; + if (adler != AdlerSpec->GetAdler()) + return S_FALSE; + } + return res; + DEFLATE_TRY_END +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Compress/ZlibDecoder.h b/desmume/src/windows/7z/CPP/7zip/Compress/ZlibDecoder.h new file mode 100644 index 000000000..a7ec07328 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Compress/ZlibDecoder.h @@ -0,0 +1,46 @@ +// ZlibDecoder.h + +#ifndef __ZLIB_DECODER_H +#define __ZLIB_DECODER_H + +#include "DeflateDecoder.h" + +namespace NCompress { +namespace NZlib { + +const UInt32 ADLER_INIT_VAL = 1; + +class COutStreamWithAdler: + public ISequentialOutStream, + public CMyUnknownImp +{ + CMyComPtr _stream; + UInt32 _adler; +public: + MY_UNKNOWN_IMP + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void ReleaseStream() { _stream.Release(); } + void Init() { _adler = ADLER_INIT_VAL; } + UInt32 GetAdler() const { return _adler; } +}; + +class CDecoder: + public ICompressCoder, + public CMyUnknownImp +{ + COutStreamWithAdler *AdlerSpec; + CMyComPtr AdlerStream; + + NCompress::NDeflate::NDecoder::CCOMCoder *DeflateDecoderSpec; + CMyComPtr DeflateDecoder; +public: + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + + MY_UNKNOWN_IMP +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/7zAes.cpp b/desmume/src/windows/7z/CPP/7zip/Crypto/7zAes.cpp new file mode 100644 index 000000000..b5b5b4b43 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/7zAes.cpp @@ -0,0 +1,245 @@ +// 7zAes.cpp + +#include "StdAfx.h" + +extern "C" +{ +#include "../../../C/Sha256.h" +} + +#include "Windows/Synchronization.h" +#include "../Common/StreamObjects.h" +#include "../Common/StreamUtils.h" +#include "7zAes.h" +#include "MyAes.h" + +#ifndef EXTRACT_ONLY +#include "RandGen.h" +#endif + +using namespace NWindows; + +namespace NCrypto { +namespace NSevenZ { + +bool CKeyInfo::IsEqualTo(const CKeyInfo &a) const +{ + if (SaltSize != a.SaltSize || NumCyclesPower != a.NumCyclesPower) + return false; + for (UInt32 i = 0; i < SaltSize; i++) + if (Salt[i] != a.Salt[i]) + return false; + return (Password == a.Password); +} + +void CKeyInfo::CalculateDigest() +{ + if (NumCyclesPower == 0x3F) + { + UInt32 pos; + for (pos = 0; pos < SaltSize; pos++) + Key[pos] = Salt[pos]; + for (UInt32 i = 0; i < Password.GetCapacity() && pos < kKeySize; i++) + Key[pos++] = Password[i]; + for (; pos < kKeySize; pos++) + Key[pos] = 0; + } + else + { + CSha256 sha; + Sha256_Init(&sha); + const UInt64 numRounds = UInt64(1) << (NumCyclesPower); + Byte temp[8] = { 0,0,0,0,0,0,0,0 }; + for (UInt64 round = 0; round < numRounds; round++) + { + Sha256_Update(&sha, Salt, (size_t)SaltSize); + Sha256_Update(&sha, Password, Password.GetCapacity()); + Sha256_Update(&sha, temp, 8); + for (int i = 0; i < 8; i++) + if (++(temp[i]) != 0) + break; + } + Sha256_Final(&sha, Key); + } +} + +bool CKeyInfoCache::Find(CKeyInfo &key) +{ + for (int i = 0; i < Keys.Size(); i++) + { + const CKeyInfo &cached = Keys[i]; + if (key.IsEqualTo(cached)) + { + for (int j = 0; j < kKeySize; j++) + key.Key[j] = cached.Key[j]; + if (i != 0) + { + Keys.Insert(0, cached); + Keys.Delete(i+1); + } + return true; + } + } + return false; +} + +void CKeyInfoCache::Add(CKeyInfo &key) +{ + if (Find(key)) + return; + if (Keys.Size() >= Size) + Keys.DeleteBack(); + Keys.Insert(0, key); +} + +static CKeyInfoCache g_GlobalKeyCache(32); +static NSynchronization::CCriticalSection g_GlobalKeyCacheCriticalSection; + +CBase::CBase(): + _cachedKeys(16), + _ivSize(0) +{ + for (int i = 0; i < sizeof(_iv); i++) + _iv[i] = 0; +} + +void CBase::CalculateDigest() +{ + NSynchronization::CCriticalSectionLock lock(g_GlobalKeyCacheCriticalSection); + if (_cachedKeys.Find(_key)) + g_GlobalKeyCache.Add(_key); + else + { + if (!g_GlobalKeyCache.Find(_key)) + { + _key.CalculateDigest(); + g_GlobalKeyCache.Add(_key); + } + _cachedKeys.Add(_key); + } +} + +#ifndef EXTRACT_ONLY + +/* +STDMETHODIMP CEncoder::ResetSalt() +{ + _key.SaltSize = 4; + g_RandomGenerator.Generate(_key.Salt, _key.SaltSize); + return S_OK; +} +*/ + +STDMETHODIMP CEncoder::ResetInitVector() +{ + _ivSize = 8; + g_RandomGenerator.Generate(_iv, (unsigned)_ivSize); + return S_OK; +} + +STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) +{ + // _key.Init(); + for (UInt32 i = _ivSize; i < sizeof(_iv); i++) + _iv[i] = 0; + + UInt32 ivSize = _ivSize; + + // _key.NumCyclesPower = 0x3F; + _key.NumCyclesPower = 19; + + Byte firstByte = (Byte)(_key.NumCyclesPower | + (((_key.SaltSize == 0) ? 0 : 1) << 7) | + (((ivSize == 0) ? 0 : 1) << 6)); + RINOK(outStream->Write(&firstByte, 1, NULL)); + if (_key.SaltSize == 0 && ivSize == 0) + return S_OK; + Byte saltSizeSpec = (Byte)((_key.SaltSize == 0) ? 0 : (_key.SaltSize - 1)); + Byte ivSizeSpec = (Byte)((ivSize == 0) ? 0 : (ivSize - 1)); + Byte secondByte = (Byte)(((saltSizeSpec) << 4) | ivSizeSpec); + RINOK(outStream->Write(&secondByte, 1, NULL)); + if (_key.SaltSize > 0) + { + RINOK(WriteStream(outStream, _key.Salt, _key.SaltSize)); + } + if (ivSize > 0) + { + RINOK(WriteStream(outStream, _iv, ivSize)); + } + return S_OK; +} + +HRESULT CEncoder::CreateFilter() +{ + _aesFilter = new CAesCbcEncoder; + return S_OK; +} + +#endif + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + _key.Init(); + UInt32 i; + for (i = 0; i < sizeof(_iv); i++) + _iv[i] = 0; + if (size == 0) + return S_OK; + UInt32 pos = 0; + Byte firstByte = data[pos++]; + + _key.NumCyclesPower = firstByte & 0x3F; + if ((firstByte & 0xC0) == 0) + return S_OK; + _key.SaltSize = (firstByte >> 7) & 1; + UInt32 ivSize = (firstByte >> 6) & 1; + + if (pos >= size) + return E_INVALIDARG; + Byte secondByte = data[pos++]; + + _key.SaltSize += (secondByte >> 4); + ivSize += (secondByte & 0x0F); + + if (pos + _key.SaltSize + ivSize > size) + return E_INVALIDARG; + for (i = 0; i < _key.SaltSize; i++) + _key.Salt[i] = data[pos++]; + for (i = 0; i < ivSize; i++) + _iv[i] = data[pos++]; + return S_OK; +} + +STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size) +{ + _key.Password.SetCapacity((size_t)size); + memcpy(_key.Password, data, (size_t)size); + return S_OK; +} + +STDMETHODIMP CBaseCoder::Init() +{ + CalculateDigest(); + if (_aesFilter == 0) + { + RINOK(CreateFilter()); + } + CMyComPtr cp; + RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp)); + RINOK(cp->SetKey(_key.Key, sizeof(_key.Key))); + RINOK(cp->SetInitVector(_iv, sizeof(_iv))); + return S_OK; +} + +STDMETHODIMP_(UInt32) CBaseCoder::Filter(Byte *data, UInt32 size) +{ + return _aesFilter->Filter(data, size); +} + +HRESULT CDecoder::CreateFilter() +{ + _aesFilter = new CAesCbcDecoder; + return S_OK; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/7zAes.h b/desmume/src/windows/7z/CPP/7zip/Crypto/7zAes.h new file mode 100644 index 000000000..08da66649 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/7zAes.h @@ -0,0 +1,117 @@ +// 7zAes.h + +#ifndef __CRYPTO_7Z_AES_H +#define __CRYPTO_7Z_AES_H + +#include "Common/Buffer.h" +#include "Common/MyCom.h" +#include "Common/MyVector.h" + +#include "../ICoder.h" +#include "../IPassword.h" + +namespace NCrypto { +namespace NSevenZ { + +const int kKeySize = 32; + +class CKeyInfo +{ +public: + int NumCyclesPower; + UInt32 SaltSize; + Byte Salt[16]; + CByteBuffer Password; + Byte Key[kKeySize]; + + bool IsEqualTo(const CKeyInfo &a) const; + void CalculateDigest(); + + CKeyInfo() { Init(); } + void Init() + { + NumCyclesPower = 0; + SaltSize = 0; + for (int i = 0; i < sizeof(Salt); i++) + Salt[i] = 0; + } +}; + +class CKeyInfoCache +{ + int Size; + CObjectVector Keys; +public: + CKeyInfoCache(int size): Size(size) {} + bool Find(CKeyInfo &key); + // HRESULT Calculate(CKeyInfo &key); + void Add(CKeyInfo &key); +}; + +class CBase +{ + CKeyInfoCache _cachedKeys; +protected: + CKeyInfo _key; + Byte _iv[16]; + UInt32 _ivSize; + void CalculateDigest(); + CBase(); +}; + +class CBaseCoder: + public ICompressFilter, + public ICryptoSetPassword, + public CMyUnknownImp, + public CBase +{ +protected: + CMyComPtr _aesFilter; + + virtual HRESULT CreateFilter() = 0; + #ifndef CRYPTO_AES + HRESULT CreateFilterFromDLL(REFCLSID clsID); + #endif +public: + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); +}; + +#ifndef EXTRACT_ONLY + +class CEncoder: + public CBaseCoder, + public ICompressWriteCoderProperties, + // public ICryptoResetSalt, + public ICryptoResetInitVector +{ + virtual HRESULT CreateFilter(); +public: + MY_UNKNOWN_IMP3( + ICryptoSetPassword, + ICompressWriteCoderProperties, + // ICryptoResetSalt, + ICryptoResetInitVector) + STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); + // STDMETHOD(ResetSalt)(); + STDMETHOD(ResetInitVector)(); +}; +#endif + +class CDecoder: + public CBaseCoder, + public ICompressSetDecoderProperties2 +{ + virtual HRESULT CreateFilter(); +public: + MY_UNKNOWN_IMP2( + ICryptoSetPassword, + ICompressSetDecoderProperties2) + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/7zAesRegister.cpp b/desmume/src/windows/7z/CPP/7zip/Crypto/7zAesRegister.cpp new file mode 100644 index 000000000..87f8ae9c8 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/7zAesRegister.cpp @@ -0,0 +1,18 @@ +// 7zAesRegister.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" +#include "7zAes.h" + +static void *CreateCodec() { return (void *)(ICompressFilter *)(new NCrypto::NSevenZ::CDecoder()); } +#ifndef EXTRACT_ONLY +static void *CreateCodecOut() { return (void *)(ICompressFilter *)(new NCrypto::NSevenZ::CEncoder()); } +#else +#define CreateCodecOut 0 +#endif + +static CCodecInfo g_CodecInfo = + { CreateCodec, CreateCodecOut, 0x06F10701, L"7zAES", 1, true }; + +REGISTER_CODEC(7zAES) diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/HmacSha1.cpp b/desmume/src/windows/7z/CPP/7zip/Crypto/HmacSha1.cpp new file mode 100644 index 000000000..09621e958 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/HmacSha1.cpp @@ -0,0 +1,109 @@ +// HmacSha1.cpp + +#include "StdAfx.h" + +#include "HmacSha1.h" + +namespace NCrypto { +namespace NSha1 { + +void CHmac::SetKey(const Byte *key, size_t keySize) +{ + Byte keyTemp[kBlockSize]; + size_t i; + for (i = 0; i < kBlockSize; i++) + keyTemp[i] = 0; + if(keySize > kBlockSize) + { + _sha.Init(); + _sha.Update(key, keySize); + _sha.Final(keyTemp); + keySize = kDigestSize; + } + else + for (i = 0; i < keySize; i++) + keyTemp[i] = key[i]; + for (i = 0; i < kBlockSize; i++) + keyTemp[i] ^= 0x36; + _sha.Init(); + _sha.Update(keyTemp, kBlockSize); + for (i = 0; i < kBlockSize; i++) + keyTemp[i] ^= 0x36 ^ 0x5C; + _sha2.Init(); + _sha2.Update(keyTemp, kBlockSize); +} + +void CHmac::Final(Byte *mac, size_t macSize) +{ + Byte digest[kDigestSize]; + _sha.Final(digest); + _sha2.Update(digest, kDigestSize); + _sha2.Final(digest); + for(size_t i = 0; i < macSize; i++) + mac[i] = digest[i]; +} + + +void CHmac32::SetKey(const Byte *key, size_t keySize) +{ + UInt32 keyTemp[kBlockSizeInWords]; + size_t i; + for (i = 0; i < kBlockSizeInWords; i++) + keyTemp[i] = 0; + if(keySize > kBlockSize) + { + CContext sha; + sha.Init(); + sha.Update(key, keySize); + Byte digest[kDigestSize]; + sha.Final(digest); + + for (int i = 0 ; i < kDigestSizeInWords; i++) + keyTemp[i] = + ((UInt32)(digest[i * 4 + 0]) << 24) | + ((UInt32)(digest[i * 4 + 1]) << 16) | + ((UInt32)(digest[i * 4 + 2]) << 8) | + ((UInt32)(digest[i * 4 + 3])); + keySize = kDigestSizeInWords; + } + else + for (size_t i = 0; i < keySize; i++) + keyTemp[i / 4] |= (key[i] << (24 - 8 * (i & 3))); + for (i = 0; i < kBlockSizeInWords; i++) + keyTemp[i] ^= 0x36363636; + _sha.Init(); + _sha.Update(keyTemp, kBlockSizeInWords); + for (i = 0; i < kBlockSizeInWords; i++) + keyTemp[i] ^= 0x36363636 ^ 0x5C5C5C5C; + _sha2.Init(); + _sha2.Update(keyTemp, kBlockSizeInWords); +} + +void CHmac32::Final(UInt32 *mac, size_t macSize) +{ + UInt32 digest[kDigestSizeInWords]; + _sha.Final(digest); + _sha2.Update(digest, kDigestSizeInWords); + _sha2.Final(digest); + for(size_t i = 0; i < macSize; i++) + mac[i] = digest[i]; +} + +void CHmac32::GetLoopXorDigest(UInt32 *mac, UInt32 numIteration) +{ + UInt32 block[kBlockSizeInWords]; + UInt32 block2[kBlockSizeInWords]; + _sha.PrepareBlock(block, kDigestSizeInWords); + _sha2.PrepareBlock(block2, kDigestSizeInWords); + for(unsigned int s = 0; s < kDigestSizeInWords; s++) + block[s] = mac[s]; + for(UInt32 i = 0; i < numIteration; i++) + { + _sha.GetBlockDigest(block, block2); + _sha2.GetBlockDigest(block2, block); + for (unsigned int s = 0; s < kDigestSizeInWords; s++) + mac[s] ^= block[s]; + } +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/HmacSha1.h b/desmume/src/windows/7z/CPP/7zip/Crypto/HmacSha1.h new file mode 100644 index 000000000..2b12340ed --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/HmacSha1.h @@ -0,0 +1,39 @@ +// HmacSha1.h +// Implements HMAC-SHA-1 (RFC2104, FIPS-198) + +#ifndef __CRYPTO_HMAC_SHA1_H +#define __CRYPTO_HMAC_SHA1_H + +#include "Sha1.h" + +namespace NCrypto { +namespace NSha1 { + +// Use: SetKey(key, keySize); for () Update(data, size); Final(mac, macSize); + +class CHmac +{ + CContext _sha; + CContext _sha2; +public: + void SetKey(const Byte *key, size_t keySize); + void Update(const Byte *data, size_t dataSize) { _sha.Update(data, dataSize); } + void Final(Byte *mac, size_t macSize = kDigestSize); +}; + +class CHmac32 +{ + CContext32 _sha; + CContext32 _sha2; +public: + void SetKey(const Byte *key, size_t keySize); + void Update(const UInt32 *data, size_t dataSize) { _sha.Update(data, dataSize); } + void Final(UInt32 *mac, size_t macSize = kDigestSizeInWords); + + // It'sa for hmac function. in,out: mac[kDigestSizeInWords]. + void GetLoopXorDigest(UInt32 *mac, UInt32 numIteration); +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/MyAes.cpp b/desmume/src/windows/7z/CPP/7zip/Crypto/MyAes.cpp new file mode 100644 index 000000000..0f7b74b8d --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/MyAes.cpp @@ -0,0 +1,57 @@ +// Crypto/MyAes.cpp + +#include "StdAfx.h" + +#include "MyAes.h" + +namespace NCrypto { + +struct CAesTabInit { CAesTabInit() { AesGenTables();} } g_AesTabInit; + +STDMETHODIMP CAesCbcEncoder::Init() { return S_OK; } + +STDMETHODIMP_(UInt32) CAesCbcEncoder::Filter(Byte *data, UInt32 size) +{ + return (UInt32)AesCbc_Encode(&Aes, data, size); +} + +STDMETHODIMP CAesCbcEncoder::SetKey(const Byte *data, UInt32 size) +{ + if ((size & 0x7) != 0 || size < 16 || size > 32) + return E_INVALIDARG; + Aes_SetKeyEncode(&Aes.aes, data, size); + return S_OK; +} + +STDMETHODIMP CAesCbcEncoder::SetInitVector(const Byte *data, UInt32 size) +{ + if (size != AES_BLOCK_SIZE) + return E_INVALIDARG; + AesCbc_Init(&Aes, data); + return S_OK; +} + +STDMETHODIMP CAesCbcDecoder::Init() { return S_OK; } + +STDMETHODIMP_(UInt32) CAesCbcDecoder::Filter(Byte *data, UInt32 size) +{ + return (UInt32)AesCbc_Decode(&Aes, data, size); +} + +STDMETHODIMP CAesCbcDecoder::SetKey(const Byte *data, UInt32 size) +{ + if ((size & 0x7) != 0 || size < 16 || size > 32) + return E_INVALIDARG; + Aes_SetKeyDecode(&Aes.aes, data, size); + return S_OK; +} + +STDMETHODIMP CAesCbcDecoder::SetInitVector(const Byte *data, UInt32 size) +{ + if (size != AES_BLOCK_SIZE) + return E_INVALIDARG; + AesCbc_Init(&Aes, data); + return S_OK; +} + +} diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/MyAes.h b/desmume/src/windows/7z/CPP/7zip/Crypto/MyAes.h new file mode 100644 index 000000000..bfa58cdba --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/MyAes.h @@ -0,0 +1,48 @@ +// Crypto/MyAes.h + +#ifndef __CRYPTO_MY_AES_H +#define __CRYPTO_MY_AES_H + +extern "C" +{ +#include "../../../C/Aes.h" +} + +#include "../../Common/MyCom.h" +#include "../../Common/Types.h" + +#include "../ICoder.h" + +namespace NCrypto { + +class CAesCbcEncoder: + public ICompressFilter, + public ICryptoProperties, + public CMyUnknownImp +{ + CAesCbc Aes; +public: + MY_UNKNOWN_IMP1(ICryptoProperties) + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + STDMETHOD(SetKey)(const Byte *data, UInt32 size); + STDMETHOD(SetInitVector)(const Byte *data, UInt32 size); +}; + +class CAesCbcDecoder: + public ICompressFilter, + public ICryptoProperties, + public CMyUnknownImp +{ + CAesCbc Aes; +public: + MY_UNKNOWN_IMP1(ICryptoProperties) + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + STDMETHOD(SetKey)(const Byte *data, UInt32 size); + STDMETHOD(SetInitVector)(const Byte *data, UInt32 size); +}; + +} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp b/desmume/src/windows/7z/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp new file mode 100644 index 000000000..0ac6dc61b --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp @@ -0,0 +1,83 @@ +// Pbkdf2HmacSha1.cpp + +#include "StdAfx.h" + +#include "HmacSha1.h" + +namespace NCrypto { +namespace NSha1 { + +void Pbkdf2Hmac(const Byte *pwd, size_t pwdSize, const Byte *salt, size_t saltSize, + UInt32 numIterations, Byte *key, size_t keySize) +{ + CHmac baseCtx; + baseCtx.SetKey(pwd, pwdSize); + for (UInt32 i = 1; keySize > 0; i++) + { + CHmac ctx = baseCtx; + ctx.Update(salt, saltSize); + Byte u[kDigestSize] = { (Byte)(i >> 24), (Byte)(i >> 16), (Byte)(i >> 8), (Byte)(i) }; + const unsigned int curSize = (keySize < kDigestSize) ? (unsigned int)keySize : kDigestSize; + ctx.Update(u, 4); + ctx.Final(u, kDigestSize); + + unsigned int s; + for (s = 0; s < curSize; s++) + key[s] = u[s]; + + for (UInt32 j = numIterations; j > 1; j--) + { + ctx = baseCtx; + ctx.Update(u, kDigestSize); + ctx.Final(u, kDigestSize); + for (s = 0; s < curSize; s++) + key[s] ^= u[s]; + } + + key += curSize; + keySize -= curSize; + } +} + +void Pbkdf2Hmac32(const Byte *pwd, size_t pwdSize, const UInt32 *salt, size_t saltSize, + UInt32 numIterations, UInt32 *key, size_t keySize) +{ + CHmac32 baseCtx; + baseCtx.SetKey(pwd, pwdSize); + for (UInt32 i = 1; keySize > 0; i++) + { + CHmac32 ctx = baseCtx; + ctx.Update(salt, saltSize); + UInt32 u[kDigestSizeInWords] = { i }; + const unsigned int curSize = (keySize < kDigestSizeInWords) ? (unsigned int)keySize : kDigestSizeInWords; + ctx.Update(u, 1); + ctx.Final(u, kDigestSizeInWords); + + // Speed-optimized code start + ctx = baseCtx; + ctx.GetLoopXorDigest(u, numIterations - 1); + // Speed-optimized code end + + unsigned int s; + for (s = 0; s < curSize; s++) + key[s] = u[s]; + + /* + // Default code start + for (UInt32 j = numIterations; j > 1; j--) + { + ctx = baseCtx; + ctx.Update(u, kDigestSizeInWords); + ctx.Final(u, kDigestSizeInWords); + for (s = 0; s < curSize; s++) + key[s] ^= u[s]; + } + // Default code end + */ + + key += curSize; + keySize -= curSize; + } +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/Pbkdf2HmacSha1.h b/desmume/src/windows/7z/CPP/7zip/Crypto/Pbkdf2HmacSha1.h new file mode 100644 index 000000000..ea5d99f18 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/Pbkdf2HmacSha1.h @@ -0,0 +1,21 @@ +// Pbkdf2HmacSha1.h +// Password-Based Key Derivation Function (RFC 2898, PKCS #5) based on HMAC-SHA-1 + +#ifndef __CRYPTO_PBKDF2_HMAC_SHA1_H +#define __CRYPTO_PBKDF2_HMAC_SHA1_H + +#include +#include "../../Common/Types.h" + +namespace NCrypto { +namespace NSha1 { + +void Pbkdf2Hmac(const Byte *pwd, size_t pwdSize, const Byte *salt, size_t saltSize, + UInt32 numIterations, Byte *key, size_t keySize); + +void Pbkdf2Hmac32(const Byte *pwd, size_t pwdSize, const UInt32 *salt, size_t saltSize, + UInt32 numIterations, UInt32 *key, size_t keySize); + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/RandGen.cpp b/desmume/src/windows/7z/CPP/7zip/Crypto/RandGen.cpp new file mode 100644 index 000000000..66b323168 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/RandGen.cpp @@ -0,0 +1,107 @@ +// RandGen.cpp + +#include "StdAfx.h" + +#include +#include "Windows/Synchronization.h" +#include "RandGen.h" + +#ifndef _WIN32 +#include +#define USE_POSIX_TIME +#define USE_POSIX_TIME2 +#endif + +#ifdef USE_POSIX_TIME +#include +#ifdef USE_POSIX_TIME2 +#include +#endif +#endif + +// This is not very good random number generator. +// Please use it only for salt. +// First generated data block depends from timer and processID. +// Other generated data blocks depend from previous state +// Maybe it's possible to restore original timer value from generated value. + +void CRandomGenerator::Init() +{ + NCrypto::NSha1::CContext hash; + hash.Init(); + + #ifdef _WIN32 + DWORD w = ::GetCurrentProcessId(); + hash.Update((const Byte *)&w, sizeof(w)); + w = ::GetCurrentThreadId(); + hash.Update((const Byte *)&w, sizeof(w)); + #else + pid_t pid = getpid(); + hash.Update((const Byte *)&pid, sizeof(pid)); + pid = getppid(); + hash.Update((const Byte *)&pid, sizeof(pid)); + #endif + + for (int i = 0; i < 1000; i++) + { + #ifdef _WIN32 + LARGE_INTEGER v; + if (::QueryPerformanceCounter(&v)) + hash.Update((const Byte *)&v.QuadPart, sizeof(v.QuadPart)); + #endif + + #ifdef USE_POSIX_TIME + #ifdef USE_POSIX_TIME2 + timeval v; + if (gettimeofday(&v, 0) == 0) + { + hash.Update((const Byte *)&v.tv_sec, sizeof(v.tv_sec)); + hash.Update((const Byte *)&v.tv_usec, sizeof(v.tv_usec)); + } + #endif + time_t v2 = time(NULL); + hash.Update((const Byte *)&v2, sizeof(v2)); + #endif + + DWORD tickCount = ::GetTickCount(); + hash.Update((const Byte *)&tickCount, sizeof(tickCount)); + + for (int j = 0; j < 100; j++) + { + hash.Final(_buff); + hash.Init(); + hash.Update(_buff, NCrypto::NSha1::kDigestSize); + } + } + hash.Final(_buff); + _needInit = false; +} + +static NWindows::NSynchronization::CCriticalSection g_CriticalSection; + +void CRandomGenerator::Generate(Byte *data, unsigned int size) +{ + g_CriticalSection.Enter(); + if (_needInit) + Init(); + while (size > 0) + { + NCrypto::NSha1::CContext hash; + + hash.Init(); + hash.Update(_buff, NCrypto::NSha1::kDigestSize); + hash.Final(_buff); + + hash.Init(); + UInt32 salt = 0xF672ABD1; + hash.Update((const Byte *)&salt, sizeof(salt)); + hash.Update(_buff, NCrypto::NSha1::kDigestSize); + Byte buff[NCrypto::NSha1::kDigestSize]; + hash.Final(buff); + for (unsigned int i = 0; i < NCrypto::NSha1::kDigestSize && size > 0; i++, size--) + *data++ = buff[i]; + } + g_CriticalSection.Leave(); +} + +CRandomGenerator g_RandomGenerator; diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/RandGen.h b/desmume/src/windows/7z/CPP/7zip/Crypto/RandGen.h new file mode 100644 index 000000000..a457897a9 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/RandGen.h @@ -0,0 +1,21 @@ +// RandGen.h + +#ifndef __CRYPTO_RAND_GEN_H +#define __CRYPTO_RAND_GEN_H + +#include "Sha1.h" + +class CRandomGenerator +{ + Byte _buff[NCrypto::NSha1::kDigestSize]; + bool _needInit; + + void Init(); +public: + CRandomGenerator(): _needInit(true) {}; + void Generate(Byte *data, unsigned size); +}; + +extern CRandomGenerator g_RandomGenerator; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/Rar20Crypto.cpp b/desmume/src/windows/7z/CPP/7zip/Crypto/Rar20Crypto.cpp new file mode 100644 index 000000000..bf5eb9894 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/Rar20Crypto.cpp @@ -0,0 +1,136 @@ +// Crypto/Rar20Crypto.cpp + +#include "StdAfx.h" + +extern "C" +{ + #include "../../../C/7zCrc.h" + #include "../../../C/CpuArch.h" + #include "../../../C/RotateDefs.h" +} + +#include "Rar20Crypto.h" + +namespace NCrypto { +namespace NRar20 { + +static const int kNumRounds = 32; + +static const Byte InitSubstTable[256] = { + 215, 19,149, 35, 73,197,192,205,249, 28, 16,119, 48,221, 2, 42, + 232, 1,177,233, 14, 88,219, 25,223,195,244, 90, 87,239,153,137, + 255,199,147, 70, 92, 66,246, 13,216, 40, 62, 29,217,230, 86, 6, + 71, 24,171,196,101,113,218,123, 93, 91,163,178,202, 67, 44,235, + 107,250, 75,234, 49,167,125,211, 83,114,157,144, 32,193,143, 36, + 158,124,247,187, 89,214,141, 47,121,228, 61,130,213,194,174,251, + 97,110, 54,229,115, 57,152, 94,105,243,212, 55,209,245, 63, 11, + 164,200, 31,156, 81,176,227, 21, 76, 99,139,188,127, 17,248, 51, + 207,120,189,210, 8,226, 41, 72,183,203,135,165,166, 60, 98, 7, + 122, 38,155,170, 69,172,252,238, 39,134, 59,128,236, 27,240, 80, + 131, 3, 85,206,145, 79,154,142,159,220,201,133, 74, 64, 20,129, + 224,185,138,103,173,182, 43, 34,254, 82,198,151,231,180, 58, 10, + 118, 26,102, 12, 50,132, 22,191,136,111,162,179, 45, 4,148,108, + 161, 56, 78,126,242,222, 15,175,146, 23, 33,241,181,190, 77,225, + 0, 46,169,186, 68, 95,237, 65, 53,208,253,168, 9, 18,100, 52, + 116,184,160, 96,109, 37, 30,106,140,104,150, 5,204,117,112, 84 +}; + +void CData::UpdateKeys(const Byte *data) +{ + for (int i = 0; i < 16; i += 4) + for (int j = 0; j < 4; j++) + Keys[j] ^= g_CrcTable[data[i + j]]; +} + +static void Swap(Byte *b1, Byte *b2) +{ + Byte b = *b1; + *b1 = *b2; + *b2 = b; +} + +void CData::SetPassword(const Byte *password, UInt32 passwordLen) +{ + Keys[0] = 0xD3A3B879L; + Keys[1] = 0x3F6D12F7L; + Keys[2] = 0x7515A235L; + Keys[3] = 0xA4E7F123L; + + Byte psw[256]; + memset(psw, 0, sizeof(psw)); + memcpy(psw, password, passwordLen); + memcpy(SubstTable, InitSubstTable, sizeof(SubstTable)); + + for (UInt32 j = 0; j < 256; j++) + for (UInt32 i = 0; i < passwordLen; i += 2) + { + UInt32 n2 = (Byte)g_CrcTable[(psw[i + 1] + j) & 0xFF]; + UInt32 n1 = (Byte)g_CrcTable[(psw[i] - j) & 0xFF]; + for (UInt32 k = 1; (n1 & 0xFF) != n2; n1++, k++) + Swap(&SubstTable[n1 & 0xFF], &SubstTable[(n1 + i + k) & 0xFF]); + } + for (UInt32 i = 0; i < passwordLen; i+= 16) + EncryptBlock(&psw[i]); +} + +void CData::CryptBlock(Byte *buf, bool encrypt) +{ + Byte inBuf[16]; + UInt32 A, B, C, D, T, TA, TB; + + A = GetUi32(buf + 0) ^ Keys[0]; + B = GetUi32(buf + 4) ^ Keys[1]; + C = GetUi32(buf + 8) ^ Keys[2]; + D = GetUi32(buf + 12) ^ Keys[3]; + + if (!encrypt) + memcpy(inBuf, buf, sizeof(inBuf)); + + for (int i = 0; i < kNumRounds; i++) + { + UInt32 key = Keys[(encrypt ? i : (kNumRounds - 1 - i)) & 3]; + T = ((C + rotlFixed(D, 11)) ^ key); + TA = A ^ SubstLong(T); + T = ((D ^ rotlFixed(C, 17)) + key); + TB = B ^ SubstLong(T); + A = C; + B = D; + C = TA; + D = TB; + } + + SetUi32(buf + 0, C ^ Keys[0]); + SetUi32(buf + 4, D ^ Keys[1]); + SetUi32(buf + 8, A ^ Keys[2]); + SetUi32(buf + 12, B ^ Keys[3]); + + UpdateKeys(encrypt ? buf : inBuf); +} + +STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size) +{ + _cipher.SetPassword(data, size); + return S_OK; +} + +STDMETHODIMP CDecoder::Init() +{ + return S_OK; +} + +static const UInt32 kBlockSize = 16; + +STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) +{ + if (size == 0) + return 0; + if (size < kBlockSize) + return kBlockSize; + UInt32 i; + size -= kBlockSize; + for (i = 0; i <= size; i += kBlockSize) + _cipher.DecryptBlock(data + i); + return i; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/Rar20Crypto.h b/desmume/src/windows/7z/CPP/7zip/Crypto/Rar20Crypto.h new file mode 100644 index 000000000..36f5590d1 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/Rar20Crypto.h @@ -0,0 +1,50 @@ +// Crypto/Rar20Crypto.h + +#ifndef __CRYPTO_RAR20_CRYPTO_H +#define __CRYPTO_RAR20_CRYPTO_H + +#include "Common/MyCom.h" + +#include "../ICoder.h" +#include "../IPassword.h" + +namespace NCrypto { +namespace NRar20 { + +class CData +{ + Byte SubstTable[256]; + UInt32 Keys[4]; + + UInt32 SubstLong(UInt32 t) + { + return (UInt32)SubstTable[(int)t & 255] | + ((UInt32)SubstTable[(int)(t >> 8) & 255] << 8) | + ((UInt32)SubstTable[(int)(t >> 16) & 255] << 16) | + ((UInt32)SubstTable[(int)(t >> 24) & 255] << 24); + } + void UpdateKeys(const Byte *data); + void CryptBlock(Byte *buf, bool encrypt); +public: + void EncryptBlock(Byte *buf) { CryptBlock(buf, true); } + void DecryptBlock(Byte *buf) { CryptBlock(buf, false); } + void SetPassword(const Byte *password, UInt32 passwordLen); +}; + +class CDecoder: + public ICompressFilter, + public ICryptoSetPassword, + public CMyUnknownImp +{ + CData _cipher; +public: + MY_UNKNOWN_IMP1(ICryptoSetPassword) + + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/RarAes.cpp b/desmume/src/windows/7z/CPP/7zip/Crypto/RarAes.cpp new file mode 100644 index 000000000..be3cefcc4 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/RarAes.cpp @@ -0,0 +1,139 @@ +// Crypto/RarAes.cpp +// Note: you must include MyAes.cpp to project to initialize AES tables + +#include "StdAfx.h" + +#include "RarAes.h" +#include "Sha1.h" + +namespace NCrypto { +namespace NRar29 { + +CDecoder::CDecoder(): + _thereIsSalt(false), + _needCalculate(true), + _rar350Mode(false) +{ + for (int i = 0; i < sizeof(_salt); i++) + _salt[i] = 0; +} + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + bool thereIsSaltPrev = _thereIsSalt; + _thereIsSalt = false; + if (size == 0) + return S_OK; + if (size < 8) + return E_INVALIDARG; + _thereIsSalt = true; + bool same = false; + if (_thereIsSalt == thereIsSaltPrev) + { + same = true; + if (_thereIsSalt) + { + for (int i = 0; i < sizeof(_salt); i++) + if (_salt[i] != data[i]) + { + same = false; + break; + } + } + } + for (int i = 0; i < sizeof(_salt); i++) + _salt[i] = data[i]; + if (!_needCalculate && !same) + _needCalculate = true; + return S_OK; +} + +static const int kMaxPasswordLength = 127 * 2; + +STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size) +{ + if (size > kMaxPasswordLength) + size = kMaxPasswordLength; + bool same = false; + if (size == buffer.GetCapacity()) + { + same = true; + for (UInt32 i = 0; i < size; i++) + if (data[i] != buffer[i]) + { + same = false; + break; + } + } + if (!_needCalculate && !same) + _needCalculate = true; + buffer.SetCapacity(size); + memcpy(buffer, data, size); + return S_OK; +} + +STDMETHODIMP CDecoder::Init() +{ + Calculate(); + Aes_SetKeyDecode(&Aes.aes, aesKey, kRarAesKeySize); + AesCbc_Init(&Aes, aesInit); + return S_OK; +} + +STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) +{ + return (UInt32)AesCbc_Decode(&Aes, data, size); +} + +void CDecoder::Calculate() +{ + if (_needCalculate) + { + const int kSaltSize = 8; + + Byte rawPassword[kMaxPasswordLength + kSaltSize]; + + memcpy(rawPassword, buffer, buffer.GetCapacity()); + + size_t rawLength = buffer.GetCapacity(); + + if (_thereIsSalt) + { + memcpy(rawPassword + rawLength, _salt, kSaltSize); + rawLength += kSaltSize; + } + + NSha1::CContext sha; + sha.Init(); + + // seems rar reverts hash for sha. + const int hashRounds = 0x40000; + int i; + for (i = 0; i < hashRounds; i++) + { + sha.Update(rawPassword, rawLength, _rar350Mode); + Byte pswNum[3] = { (Byte)i, (Byte)(i >> 8), (Byte)(i >> 16) }; + sha.Update(pswNum, 3, _rar350Mode); + if (i % (hashRounds / 16) == 0) + { + NSha1::CContext shaTemp = sha; + Byte digest[NSha1::kDigestSize]; + shaTemp.Final(digest); + aesInit[i / (hashRounds / 16)] = (Byte)digest[4 * 4 + 3]; + } + } + /* + // it's test message for sha + const char *message = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + sha.Update((const Byte *)message, strlen(message)); + */ + Byte digest[20]; + sha.Final(digest); + for (i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + aesKey[i * 4 + j] = (digest[i * 4 + 3 - j]); + } + _needCalculate = false; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/RarAes.h b/desmume/src/windows/7z/CPP/7zip/Crypto/RarAes.h new file mode 100644 index 000000000..d21d12a55 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/RarAes.h @@ -0,0 +1,62 @@ +// Crypto/RarAes.h + +#ifndef __CRYPTO_RAR_AES_H +#define __CRYPTO_RAR_AES_H + +extern "C" +{ +#include "../../../C/Aes.h" +} + +#include "Common/Buffer.h" +#include "Common/MyCom.h" + +#include "../ICoder.h" +#include "../IPassword.h" + +namespace NCrypto { +namespace NRar29 { + +const UInt32 kRarAesKeySize = 16; + +class CDecoder: + public ICompressFilter, + public ICompressSetDecoderProperties2, + public ICryptoSetPassword, + public CMyUnknownImp +{ + Byte _salt[8]; + bool _thereIsSalt; + CByteBuffer buffer; + Byte aesKey[kRarAesKeySize]; + Byte aesInit[AES_BLOCK_SIZE]; + bool _needCalculate; + + CAesCbc Aes; + + bool _rar350Mode; + + void Calculate(); + +public: + + MY_UNKNOWN_IMP2( + ICryptoSetPassword, + ICompressSetDecoderProperties2) + + STDMETHOD(Init)(); + + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + + STDMETHOD(CryptoSetPassword)(const Byte *aData, UInt32 aSize); + + // ICompressSetDecoderProperties + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + + CDecoder(); + void SetRar350Mode(bool rar350Mode) { _rar350Mode = rar350Mode; } +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/Sha1.cpp b/desmume/src/windows/7z/CPP/7zip/Crypto/Sha1.cpp new file mode 100644 index 000000000..08bb57c94 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/Sha1.cpp @@ -0,0 +1,213 @@ +// Crypto/Sha1.cpp +// This file is based on public domain +// Steve Reid and Wei Dai's code from Crypto++ + +#include "StdAfx.h" + +#include "Sha1.h" +extern "C" +{ +#include "../../../C/RotateDefs.h" +} + +namespace NCrypto { +namespace NSha1 { + +// define it for speed optimization +// #define _SHA1_UNROLL + +static const unsigned kNumW = + #ifdef _SHA1_UNROLL + 16; + #else + 80; + #endif + + +#define w0(i) (W[(i)] = data[(i)]) + +#ifdef _SHA1_UNROLL +#define w1(i) (W[(i)&15] = rotlFixed(W[((i)-3)&15] ^ W[((i)-8)&15] ^ W[((i)-14)&15] ^ W[((i)-16)&15], 1)) +#else +#define w1(i) (W[(i)] = rotlFixed(W[(i)-3] ^ W[(i)-8] ^ W[(i)-14] ^ W[(i)-16], 1)) +#endif + +#define f1(x,y,z) (z^(x&(y^z))) +#define f2(x,y,z) (x^y^z) +#define f3(x,y,z) ((x&y)|(z&(x|y))) +#define f4(x,y,z) (x^y^z) + +#define RK1(a,b,c,d,e,i, f, w, k) e += f(b,c,d) + w(i) + k + rotlFixed(a,5); b = rotlFixed(b,30); + +#define R0(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f1, w0, 0x5A827999) +#define R1(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f1, w1, 0x5A827999) +#define R2(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f2, w1, 0x6ED9EBA1) +#define R3(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f3, w1, 0x8F1BBCDC) +#define R4(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f4, w1, 0xCA62C1D6) + +#define RX_1_4(rx1, rx4, i) rx1(a,b,c,d,e,i); rx4(e,a,b,c,d,i+1); rx4(d,e,a,b,c,i+2); rx4(c,d,e,a,b,i+3); rx4(b,c,d,e,a,i+4); +#define RX_5(rx, i) RX_1_4(rx, rx, i); + +void CContextBase::Init() +{ + _state[0] = 0x67452301; + _state[1] = 0xEFCDAB89; + _state[2] = 0x98BADCFE; + _state[3] = 0x10325476; + _state[4] = 0xC3D2E1F0; + _count = 0; +} + +void CContextBase::GetBlockDigest(UInt32 *data, UInt32 *destDigest, bool returnRes) +{ + UInt32 a, b, c, d, e; + UInt32 W[kNumW]; + + a = _state[0]; + b = _state[1]; + c = _state[2]; + d = _state[3]; + e = _state[4]; + #ifdef _SHA1_UNROLL + RX_5(R0, 0); RX_5(R0, 5); RX_5(R0, 10); + #else + int i; + for (i = 0; i < 15; i += 5) { RX_5(R0, i); } + #endif + + RX_1_4(R0, R1, 15); + + + #ifdef _SHA1_UNROLL + RX_5(R2, 20); RX_5(R2, 25); RX_5(R2, 30); RX_5(R2, 35); + RX_5(R3, 40); RX_5(R3, 45); RX_5(R3, 50); RX_5(R3, 55); + RX_5(R4, 60); RX_5(R4, 65); RX_5(R4, 70); RX_5(R4, 75); + #else + i = 20; + for (; i < 40; i += 5) { RX_5(R2, i); } + for (; i < 60; i += 5) { RX_5(R3, i); } + for (; i < 80; i += 5) { RX_5(R4, i); } + #endif + + destDigest[0] = _state[0] + a; + destDigest[1] = _state[1] + b; + destDigest[2] = _state[2] + c; + destDigest[3] = _state[3] + d; + destDigest[4] = _state[4] + e; + + if (returnRes) + for (int i = 0 ; i < 16; i++) + data[i] = W[kNumW - 16 + i]; + + // Wipe variables + // a = b = c = d = e = 0; +} + +void CContextBase::PrepareBlock(UInt32 *block, unsigned size) const +{ + unsigned curBufferPos = size & 0xF; + block[curBufferPos++] = 0x80000000; + while (curBufferPos != (16 - 2)) + block[curBufferPos++] = 0; + const UInt64 lenInBits = (_count << 9) + ((UInt64)size << 5); + block[curBufferPos++] = (UInt32)(lenInBits >> 32); + block[curBufferPos++] = (UInt32)(lenInBits); +} + +void CContext::Update(Byte *data, size_t size, bool rar350Mode) +{ + bool returnRes = false; + unsigned curBufferPos = _count2; + while (size-- > 0) + { + int pos = (int)(curBufferPos & 3); + if (pos == 0) + _buffer[curBufferPos >> 2] = 0; + _buffer[curBufferPos >> 2] |= ((UInt32)*data++) << (8 * (3 - pos)); + if (++curBufferPos == kBlockSize) + { + curBufferPos = 0; + CContextBase::UpdateBlock(_buffer, returnRes); + if (returnRes) + for (int i = 0; i < kBlockSizeInWords; i++) + { + UInt32 d = _buffer[i]; + data[i * 4 + 0 - kBlockSize] = (Byte)(d); + data[i * 4 + 1 - kBlockSize] = (Byte)(d >> 8); + data[i * 4 + 2 - kBlockSize] = (Byte)(d >> 16); + data[i * 4 + 3 - kBlockSize] = (Byte)(d >> 24); + } + returnRes = rar350Mode; + } + } + _count2 = curBufferPos; +} + +void CContext::Final(Byte *digest) +{ + const UInt64 lenInBits = (_count << 9) + ((UInt64)_count2 << 3); + unsigned curBufferPos = _count2; + int pos = (int)(curBufferPos & 3); + curBufferPos >>= 2; + if (pos == 0) + _buffer[curBufferPos] = 0; + _buffer[curBufferPos++] |= ((UInt32)0x80) << (8 * (3 - pos)); + + while (curBufferPos != (16 - 2)) + { + curBufferPos &= 0xF; + if (curBufferPos == 0) + UpdateBlock(); + _buffer[curBufferPos++] = 0; + } + _buffer[curBufferPos++] = (UInt32)(lenInBits >> 32); + _buffer[curBufferPos++] = (UInt32)(lenInBits); + UpdateBlock(); + + int i; + for (i = 0; i < kDigestSizeInWords; i++) + { + UInt32 state = _state[i] & 0xFFFFFFFF; + *digest++ = (Byte)(state >> 24); + *digest++ = (Byte)(state >> 16); + *digest++ = (Byte)(state >> 8); + *digest++ = (Byte)(state); + } + Init(); +} + +/////////////////////////// +// Words version + +void CContext32::Update(const UInt32 *data, size_t size) +{ + while (size-- > 0) + { + _buffer[_count2++] = *data++; + if (_count2 == kBlockSizeInWords) + { + _count2 = 0; + UpdateBlock(); + } + } +} + +void CContext32::Final(UInt32 *digest) +{ + const UInt64 lenInBits = (_count << 9) + ((UInt64)_count2 << 5); + unsigned curBufferPos = _count2; + _buffer[curBufferPos++] = 0x80000000; + while (curBufferPos != (16 - 2)) + { + curBufferPos &= 0xF; + if (curBufferPos == 0) + UpdateBlock(); + _buffer[curBufferPos++] = 0; + } + _buffer[curBufferPos++] = (UInt32)(lenInBits >> 32); + _buffer[curBufferPos++] = (UInt32)(lenInBits); + GetBlockDigest(_buffer, digest); + Init(); +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/Sha1.h b/desmume/src/windows/7z/CPP/7zip/Crypto/Sha1.h new file mode 100644 index 000000000..06ae27024 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/Sha1.h @@ -0,0 +1,68 @@ +// Crypto/Sha1.h +// This file is based on public domain +// Steve Reid and Wei Dai's code from Crypto++ + +#ifndef __CRYPTO_SHA1_H +#define __CRYPTO_SHA1_H + +#include +#include "../../Common/Types.h" + +// Sha1 implementation in RAR before version 3.60 has bug: +// it changes data bytes in some cases. +// So this class supports both versions: normal_SHA and rar3Mode + +namespace NCrypto { +namespace NSha1 { + +const unsigned kBlockSize = 64; +const unsigned kDigestSize = 20; + +const unsigned kBlockSizeInWords = (kBlockSize >> 2); +const unsigned kDigestSizeInWords = (kDigestSize >> 2); + +class CContextBase +{ +protected: + UInt32 _state[5]; + UInt64 _count; + void UpdateBlock(UInt32 *data, bool returnRes = false) + { + GetBlockDigest(data, _state, returnRes); + _count++; + } +public: + void Init(); + void GetBlockDigest(UInt32 *blockData, UInt32 *destDigest, bool returnRes = false); + // PrepareBlock can be used only when size <= 13. size in Words + void PrepareBlock(UInt32 *block, unsigned int size) const; +}; + +class CContextBase2: public CContextBase +{ +protected: + unsigned _count2; + UInt32 _buffer[kBlockSizeInWords]; + void UpdateBlock() { CContextBase::UpdateBlock(_buffer); } +public: + void Init() { CContextBase::Init(); _count2 = 0; } +}; + +class CContext: public CContextBase2 +{ +public: + void Update(Byte *data, size_t size, bool rar350Mode = false); + void Update(const Byte *data, size_t size) { Update((Byte *)data, size, false); } + void Final(Byte *digest); +}; + +class CContext32: public CContextBase2 +{ +public: + void Update(const UInt32 *data, size_t size); + void Final(UInt32 *digest); +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/StdAfx.h b/desmume/src/windows/7z/CPP/7zip/Crypto/StdAfx.h new file mode 100644 index 000000000..c28ffcea7 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../Common/MyWindows.h" + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/WzAes.cpp b/desmume/src/windows/7z/CPP/7zip/Crypto/WzAes.cpp new file mode 100644 index 000000000..b8f003034 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/WzAes.cpp @@ -0,0 +1,209 @@ +// Crypto/WzAes.cpp +/* +This code implements Brian Gladman's scheme +specified in password Based File Encryption Utility. + +Note: you must include MyAes.cpp to project to initialize AES tables +*/ + +#include "StdAfx.h" + +#include "../Common/StreamObjects.h" +#include "../Common/StreamUtils.h" + +#include "Pbkdf2HmacSha1.h" +#include "RandGen.h" +#include "WzAes.h" + +// define it if you don't want to use speed-optimized version of Pbkdf2HmacSha1 +// #define _NO_WZAES_OPTIMIZATIONS + +namespace NCrypto { +namespace NWzAes { + +const unsigned int kAesKeySizeMax = 32; + +static const UInt32 kNumKeyGenIterations = 1000; + +STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size) +{ + if(size > kPasswordSizeMax) + return E_INVALIDARG; + _key.Password.SetCapacity(size); + memcpy(_key.Password, data, size); + return S_OK; +} + +#define SetUi32(p, d) { UInt32 x = (d); (p)[0] = (Byte)x; (p)[1] = (Byte)(x >> 8); \ + (p)[2] = (Byte)(x >> 16); (p)[3] = (Byte)(x >> 24); } + +void CBaseCoder::EncryptData(Byte *data, UInt32 size) +{ + unsigned int pos = _blockPos; + for (; size > 0; size--) + { + if (pos == AES_BLOCK_SIZE) + { + if (++_counter[0] == 0) + _counter[1]++; + UInt32 temp[4]; + Aes_Encode32(&Aes, temp, _counter); + SetUi32(_buffer, temp[0]); + SetUi32(_buffer + 4, temp[1]); + SetUi32(_buffer + 8, temp[2]); + SetUi32(_buffer + 12, temp[3]); + pos = 0; + } + *data++ ^= _buffer[pos++]; + } + _blockPos = pos; +} + +#ifndef _NO_WZAES_OPTIMIZATIONS + +static void BytesToBeUInt32s(const Byte *src, UInt32 *dest, int destSize) +{ + for (int i = 0 ; i < destSize; i++) + dest[i] = + ((UInt32)(src[i * 4 + 0]) << 24) | + ((UInt32)(src[i * 4 + 1]) << 16) | + ((UInt32)(src[i * 4 + 2]) << 8) | + ((UInt32)(src[i * 4 + 3])); +} + +#endif + +STDMETHODIMP CBaseCoder::Init() +{ + UInt32 keySize = _key.GetKeySize(); + UInt32 keysTotalSize = 2 * keySize + kPwdVerifCodeSize; + Byte buf[2 * kAesKeySizeMax + kPwdVerifCodeSize]; + + // for (int ii = 0; ii < 1000; ii++) + { + #ifdef _NO_WZAES_OPTIMIZATIONS + + NSha1::Pbkdf2Hmac( + _key.Password, _key.Password.GetCapacity(), + _key.Salt, _key.GetSaltSize(), + kNumKeyGenIterations, + buf, keysTotalSize); + + #else + + UInt32 buf32[(2 * kAesKeySizeMax + kPwdVerifCodeSize + 3) / 4]; + UInt32 key32SizeTotal = (keysTotalSize + 3) / 4; + UInt32 salt[kSaltSizeMax * 4]; + UInt32 saltSizeInWords = _key.GetSaltSize() / 4; + BytesToBeUInt32s(_key.Salt, salt, saltSizeInWords); + NSha1::Pbkdf2Hmac32( + _key.Password, _key.Password.GetCapacity(), + salt, saltSizeInWords, + kNumKeyGenIterations, + buf32, key32SizeTotal); + for (UInt32 j = 0; j < keysTotalSize; j++) + buf[j] = (Byte)(buf32[j / 4] >> (24 - 8 * (j & 3))); + + #endif + } + + _hmac.SetKey(buf + keySize, keySize); + memcpy(_key.PwdVerifComputed, buf + 2 * keySize, kPwdVerifCodeSize); + + _blockPos = AES_BLOCK_SIZE; + for (int i = 0; i < 4; i++) + _counter[i] = 0; + + Aes_SetKeyEncode(&Aes, buf, keySize); + return S_OK; +} + +/* +STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) +{ + Byte keySizeMode = 3; + return outStream->Write(&keySizeMode, 1, NULL); +} +*/ + +HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream) +{ + UInt32 saltSize = _key.GetSaltSize(); + g_RandomGenerator.Generate(_key.Salt, saltSize); + Init(); + RINOK(WriteStream(outStream, _key.Salt, saltSize)); + return WriteStream(outStream, _key.PwdVerifComputed, kPwdVerifCodeSize); +} + +HRESULT CEncoder::WriteFooter(ISequentialOutStream *outStream) +{ + Byte mac[kMacSize]; + _hmac.Final(mac, kMacSize); + return WriteStream(outStream, mac, kMacSize); +} + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + if (size != 1) + return E_INVALIDARG; + _key.Init(); + Byte keySizeMode = data[0]; + if (keySizeMode < 1 || keySizeMode > 3) + return E_INVALIDARG; + _key.KeySizeMode = keySizeMode; + return S_OK; +} + +HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream) +{ + UInt32 saltSize = _key.GetSaltSize(); + UInt32 extraSize = saltSize + kPwdVerifCodeSize; + Byte temp[kSaltSizeMax + kPwdVerifCodeSize]; + RINOK(ReadStream_FAIL(inStream, temp, extraSize)); + UInt32 i; + for (i = 0; i < saltSize; i++) + _key.Salt[i] = temp[i]; + for (i = 0; i < kPwdVerifCodeSize; i++) + _pwdVerifFromArchive[i] = temp[saltSize + i]; + return S_OK; +} + +static bool CompareArrays(const Byte *p1, const Byte *p2, UInt32 size) +{ + for (UInt32 i = 0; i < size; i++) + if (p1[i] != p2[i]) + return false; + return true; +} + +bool CDecoder::CheckPasswordVerifyCode() +{ + return CompareArrays(_key.PwdVerifComputed, _pwdVerifFromArchive, kPwdVerifCodeSize); +} + +HRESULT CDecoder::CheckMac(ISequentialInStream *inStream, bool &isOK) +{ + isOK = false; + Byte mac1[kMacSize]; + RINOK(ReadStream_FAIL(inStream, mac1, kMacSize)); + Byte mac2[kMacSize]; + _hmac.Final(mac2, kMacSize); + isOK = CompareArrays(mac1, mac2, kMacSize); + return S_OK; +} + +STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size) +{ + EncryptData(data, size); + _hmac.Update(data, size); + return size; +} + +STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) +{ + _hmac.Update(data, size); + EncryptData(data, size); + return size; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/WzAes.h b/desmume/src/windows/7z/CPP/7zip/Crypto/WzAes.h new file mode 100644 index 000000000..8d68cc2f3 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/WzAes.h @@ -0,0 +1,119 @@ +// Crypto/WzAes.h +/* +This code implements Brian Gladman's scheme +specified in password Based File Encryption Utility: + - AES encryption (128,192,256-bit) in Counter (CTR) mode. + - HMAC-SHA1 authentication for encrypted data (10 bytes) + - Keys are derived by PPKDF2(RFC2898)-HMAC-SHA1 from ASCII password and + Salt (saltSize = aesKeySize / 2). + - 2 bytes contain Password Verifier's Code +*/ + +#ifndef __CRYPTO_WZ_AES_H +#define __CRYPTO_WZ_AES_H + +extern "C" +{ +#include "../../../C/Aes.h" +} + +#include "Common/Buffer.h" +#include "Common/MyCom.h" +#include "Common/MyVector.h" + +#include "../ICoder.h" +#include "../IPassword.h" + +#include "HmacSha1.h" + +namespace NCrypto { +namespace NWzAes { + +const unsigned int kSaltSizeMax = 16; +const unsigned int kMacSize = 10; + +const UInt32 kPasswordSizeMax = 99; // 128; + +// Password Verification Code Size +const unsigned int kPwdVerifCodeSize = 2; + +class CKeyInfo +{ +public: + Byte KeySizeMode; // 1 - 128-bit , 2 - 192-bit , 3 - 256-bit + Byte Salt[kSaltSizeMax]; + Byte PwdVerifComputed[kPwdVerifCodeSize]; + + CByteBuffer Password; + + UInt32 GetKeySize() const { return (8 * (KeySizeMode & 3) + 8); } + UInt32 GetSaltSize() const { return (4 * (KeySizeMode & 3) + 4); } + + CKeyInfo() { Init(); } + void Init() { KeySizeMode = 3; } +}; + +class CBaseCoder: + public ICompressFilter, + public ICryptoSetPassword, + public CMyUnknownImp +{ +protected: + CKeyInfo _key; + UInt32 _counter[AES_BLOCK_SIZE / 4]; + Byte _buffer[AES_BLOCK_SIZE]; + NSha1::CHmac _hmac; + unsigned int _blockPos; + Byte _pwdVerifFromArchive[kPwdVerifCodeSize]; + + void EncryptData(Byte *data, UInt32 size); + + CAes Aes; + +public: + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) = 0; + + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); + + UInt32 GetHeaderSize() const { return _key.GetSaltSize() + kPwdVerifCodeSize; } +}; + +class CEncoder: + public CBaseCoder + // public ICompressWriteCoderProperties +{ +public: + MY_UNKNOWN_IMP1(ICryptoSetPassword) + // ICompressWriteCoderProperties + // STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + HRESULT WriteHeader(ISequentialOutStream *outStream); + HRESULT WriteFooter(ISequentialOutStream *outStream); + bool SetKeyMode(Byte mode) + { + if (mode < 1 || mode > 3) + return false; + _key.KeySizeMode = mode; + return true; + } +}; + +class CDecoder: + public CBaseCoder, + public ICompressSetDecoderProperties2 +{ +public: + MY_UNKNOWN_IMP2( + ICryptoSetPassword, + ICompressSetDecoderProperties2) + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + HRESULT ReadHeader(ISequentialInStream *inStream); + bool CheckPasswordVerifyCode(); + HRESULT CheckMac(ISequentialInStream *inStream, bool &isOK); +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/ZipCrypto.cpp b/desmume/src/windows/7z/CPP/7zip/Crypto/ZipCrypto.cpp new file mode 100644 index 000000000..b699d8950 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/ZipCrypto.cpp @@ -0,0 +1,131 @@ +// Crypto/ZipCrypto.cpp + +#include "StdAfx.h" + +extern "C" +{ +#include "../../../C/7zCrc.h" +} + +#include "../Common/StreamUtils.h" + +#include "RandGen.h" +#include "ZipCrypto.h" + +namespace NCrypto { +namespace NZip { + +void CCipher::UpdateKeys(Byte b) +{ + Keys[0] = CRC_UPDATE_BYTE(Keys[0], b); + Keys[1] += Keys[0] & 0xff; + Keys[1] = Keys[1] * 134775813L + 1; + Keys[2] = CRC_UPDATE_BYTE(Keys[2], (Byte)(Keys[1] >> 24)); +} + +void CCipher::SetPassword(const Byte *password, UInt32 passwordLen) +{ + Keys[0] = 305419896L; + Keys[1] = 591751049L; + Keys[2] = 878082192L; + for (UInt32 i = 0; i < passwordLen; i++) + UpdateKeys(password[i]); +} + +Byte CCipher::DecryptByteSpec() +{ + UInt32 temp = Keys[2] | 2; + return (Byte)((temp * (temp ^ 1)) >> 8); +} + +Byte CCipher::DecryptByte(Byte b) +{ + Byte c = (Byte)(b ^ DecryptByteSpec()); + UpdateKeys(c); + return c; +} + +Byte CCipher::EncryptByte(Byte b) +{ + Byte c = (Byte)(b ^ DecryptByteSpec()); + UpdateKeys(b); + return c; +} + +void CCipher::DecryptHeader(Byte *buf) +{ + for (unsigned i = 0; i < kHeaderSize; i++) + buf[i] = DecryptByte(buf[i]); +} + +void CCipher::EncryptHeader(Byte *buf) +{ + for (unsigned i = 0; i < kHeaderSize; i++) + buf[i] = EncryptByte(buf[i]); +} + +STDMETHODIMP CEncoder::CryptoSetPassword(const Byte *data, UInt32 size) +{ + _cipher.SetPassword(data, size); + return S_OK; +} + +STDMETHODIMP CEncoder::CryptoSetCRC(UInt32 crc) +{ + _crc = crc; + return S_OK; +} + +STDMETHODIMP CEncoder::Init() +{ + return S_OK; +} + +HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream) +{ + Byte header[kHeaderSize]; + g_RandomGenerator.Generate(header, kHeaderSize - 2); + + header[kHeaderSize - 1] = Byte(_crc >> 24); + header[kHeaderSize - 2] = Byte(_crc >> 16); + + _cipher.EncryptHeader(header); + return WriteStream(outStream, header, kHeaderSize); +} + +STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size) +{ + UInt32 i; + for (i = 0; i < size; i++) + data[i] = _cipher.EncryptByte(data[i]); + return i; +} + +STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size) +{ + _cipher.SetPassword(data, size); + return S_OK; +} + +HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream) +{ + Byte header[kHeaderSize]; + RINOK(ReadStream_FAIL(inStream, header, kHeaderSize)); + _cipher.DecryptHeader(header); + return S_OK; +} + +STDMETHODIMP CDecoder::Init() +{ + return S_OK; +} + +STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) +{ + UInt32 i; + for (i = 0; i < size; i++) + data[i] = _cipher.DecryptByte(data[i]); + return i; +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/ZipCrypto.h b/desmume/src/windows/7z/CPP/7zip/Crypto/ZipCrypto.h new file mode 100644 index 000000000..2f8f335ae --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/ZipCrypto.h @@ -0,0 +1,71 @@ +// Crypto/ZipCrypto.h + +#ifndef __CRYPTO_ZIP_CRYPTO_H +#define __CRYPTO_ZIP_CRYPTO_H + +#include "Common/MyCom.h" + +#include "../ICoder.h" +#include "../IPassword.h" + +namespace NCrypto { +namespace NZip { + +const unsigned kHeaderSize = 12; + +class CCipher +{ + UInt32 Keys[3]; + + void UpdateKeys(Byte b); + Byte DecryptByteSpec(); +public: + void SetPassword(const Byte *password, UInt32 passwordLen); + Byte DecryptByte(Byte b); + Byte EncryptByte(Byte b); + void DecryptHeader(Byte *buf); + void EncryptHeader(Byte *buf); +}; + +class CEncoder : + public ICompressFilter, + public ICryptoSetPassword, + public ICryptoSetCRC, + public CMyUnknownImp +{ + CCipher _cipher; + UInt32 _crc; +public: + MY_UNKNOWN_IMP2( + ICryptoSetPassword, + ICryptoSetCRC + ) + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); + STDMETHOD(CryptoSetCRC)(UInt32 crc); + HRESULT WriteHeader(ISequentialOutStream *outStream); +}; + + +class CDecoder: + public ICompressFilter, + public ICryptoSetPassword, + public CMyUnknownImp +{ + CCipher _cipher; +public: + MY_UNKNOWN_IMP1(ICryptoSetPassword) + + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); + + HRESULT ReadHeader(ISequentialInStream *inStream); +}; + + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/ZipStrong.cpp b/desmume/src/windows/7z/CPP/7zip/Crypto/ZipStrong.cpp new file mode 100644 index 000000000..2302450f5 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/ZipStrong.cpp @@ -0,0 +1,180 @@ +// Crypto/ZipStrong.cpp + +#include "StdAfx.h" + +extern "C" +{ +#include "../../../C/7zCrc.h" +#include "../../../C/CpuArch.h" +} + +#include "../Common/StreamUtils.h" + +#include "MyAES.h" +#include "Sha1.h" +#include "ZipStrong.h" + +namespace NCrypto { +namespace NZipStrong { + +static const UInt16 kAES128 = 0x660E; + +// DeriveKey* function is similar to CryptDeriveKey() from Windows. +// But MSDN tells that we need such scheme only if +// "the required key length is longer than the hash value" +// but ZipStrong uses it always. + +static void DeriveKey2(const Byte *digest, Byte c, Byte *dest) +{ + Byte buf[64]; + memset(buf, c, 64); + for (unsigned i = 0; i < NSha1::kDigestSize; i++) + buf[i] ^= digest[i]; + NSha1::CContext sha; + sha.Init(); + sha.Update(buf, 64); + sha.Final(dest); +} + +static void DeriveKey(NSha1::CContext &sha, Byte *key) +{ + Byte digest[NSha1::kDigestSize]; + sha.Final(digest); + Byte temp[NSha1::kDigestSize * 2]; + DeriveKey2(digest, 0x36, temp); + DeriveKey2(digest, 0x5C, temp + NSha1::kDigestSize); + memcpy(key, temp, 32); +} + +void CKeyInfo::SetPassword(const Byte *data, UInt32 size) +{ + NSha1::CContext sha; + sha.Init(); + sha.Update(data, size); + DeriveKey(sha, MasterKey); +} + +STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size) +{ + _key.SetPassword(data, size); + return S_OK; +} + +STDMETHODIMP CBaseCoder::Init() +{ + return S_OK; +} + +HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream, UInt32 /* crc */, UInt64 /* unpackSize */) +{ + Byte temp[4]; + RINOK(ReadStream_FALSE(inStream, temp, 2)); + _ivSize = GetUi16(temp); + if (_ivSize == 0) + { + return E_NOTIMPL; + /* + SetUi32(_iv, crc); + for (int i = 0; i < 8; i++) + _iv[4 + i] = (Byte)(unpackSize >> (8 * i)); + SetUi32(_iv + 12, 0); + */ + } + else if (_ivSize == 16) + { + RINOK(ReadStream_FALSE(inStream, _iv, _ivSize)); + } + else + return E_NOTIMPL; + RINOK(ReadStream_FALSE(inStream, temp, 4)); + _remSize = GetUi32(temp); + if (_remSize > _buf.GetCapacity()) + { + _buf.Free(); + _buf.SetCapacity(_remSize); + } + return ReadStream_FALSE(inStream, _buf, _remSize); +} + +HRESULT CDecoder::CheckPassword(bool &passwOK) +{ + passwOK = false; + if (_remSize < 10) + return E_NOTIMPL; + Byte *p = _buf; + UInt16 format = GetUi16(p); + if (format != 3) + return E_NOTIMPL; + UInt16 algId = GetUi16(p + 2); + if (algId < kAES128) + return E_NOTIMPL; + algId -= kAES128; + if (algId > 2) + return E_NOTIMPL; + UInt16 bitLen = GetUi16(p + 4); + UInt16 flags = GetUi16(p + 6); + if (algId * 64 + 128 != bitLen) + return E_NOTIMPL; + _key.KeySize = 16 + algId * 8; + if ((flags & 1) == 0) + return E_NOTIMPL; + UInt32 rdSize = GetUi16(p + 8); + UInt32 pos = 10; + Byte *rd = p + pos; + pos += rdSize; + if (pos + 4 > _remSize) + return E_NOTIMPL; + UInt32 reserved = GetUi32(p + pos); + pos += 4; + if (reserved != 0) + return E_NOTIMPL; + if (pos + 2 > _remSize) + return E_NOTIMPL; + UInt32 validSize = GetUi16(p + pos); + pos += 2; + Byte *validData = p + pos; + if (pos + validSize != _remSize) + return E_NOTIMPL; + + if (!_aesFilter) + _aesFilter = new CAesCbcDecoder; + + CMyComPtr cp; + RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp)); + { + RINOK(cp->SetKey(_key.MasterKey, _key.KeySize)); + RINOK(cp->SetInitVector(_iv, 16)); + _aesFilter->Init(); + if (_aesFilter->Filter(rd, rdSize) != rdSize) + return E_NOTIMPL; + } + + Byte fileKey[32]; + NSha1::CContext sha; + sha.Init(); + sha.Update(_iv, 16); + sha.Update(rd, rdSize - 16); // we don't use last 16 bytes (PAD bytes) + DeriveKey(sha, fileKey); + + RINOK(cp->SetKey(fileKey, _key.KeySize)); + RINOK(cp->SetInitVector(_iv, 16)); + _aesFilter->Init(); + if (_aesFilter->Filter(validData, validSize) != validSize) + return E_NOTIMPL; + + if (validSize < 4) + return E_NOTIMPL; + validSize -= 4; + if (GetUi32(validData + validSize) != CrcCalc(validData, validSize)) + return S_OK; + passwOK = true; + _aesFilter->Init(); + return S_OK; +} + +STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) +{ + return _aesFilter->Filter(data, size); +} + +}} diff --git a/desmume/src/windows/7z/CPP/7zip/Crypto/ZipStrong.h b/desmume/src/windows/7z/CPP/7zip/Crypto/ZipStrong.h new file mode 100644 index 000000000..33adbaa2a --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/Crypto/ZipStrong.h @@ -0,0 +1,53 @@ +// Crypto/ZipStrong.h + +#ifndef __CRYPTO_ZIP_STRONG_H +#define __CRYPTO_ZIP_STRONG_H + +#include "Common/MyCom.h" +#include "Common/Buffer.h" + +#include "../ICoder.h" +#include "../IPassword.h" + +namespace NCrypto { +namespace NZipStrong { + +struct CKeyInfo +{ + Byte MasterKey[32]; + UInt32 KeySize; + void SetPassword(const Byte *data, UInt32 size); +}; + +class CBaseCoder: + public ICompressFilter, + public ICryptoSetPassword, + public CMyUnknownImp +{ +protected: + CKeyInfo _key; + CMyComPtr _aesFilter; + CByteBuffer _buf; +public: + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) = 0; + + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); +}; + +class CDecoder: + public CBaseCoder +{ + UInt32 _ivSize; + Byte _iv[16]; + UInt32 _remSize; +public: + MY_UNKNOWN_IMP1(ICryptoSetPassword) + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + HRESULT ReadHeader(ISequentialInStream *inStream, UInt32 crc, UInt64 unpackSize); + HRESULT CheckPassword(bool &passwOK); +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/ICoder.h b/desmume/src/windows/7z/CPP/7zip/ICoder.h new file mode 100644 index 000000000..150118c2c --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/ICoder.h @@ -0,0 +1,186 @@ +// ICoder.h + +#ifndef __ICODER_H +#define __ICODER_H + +#include "IStream.h" + +#define CODER_INTERFACE(i, x) DECL_INTERFACE(i, 4, x) + +CODER_INTERFACE(ICompressProgressInfo, 0x04) +{ + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) PURE; +}; + +CODER_INTERFACE(ICompressCoder, 0x05) +{ + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, + const UInt64 *outSize, + ICompressProgressInfo *progress) PURE; +}; + +CODER_INTERFACE(ICompressCoder2, 0x18) +{ + STDMETHOD(Code)(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress) PURE; +}; + +namespace NCoderPropID +{ + enum EEnum + { + kDictionarySize = 0x400, + kUsedMemorySize, + kOrder, + kBlockSize, + kPosStateBits = 0x440, + kLitContextBits, + kLitPosBits, + kNumFastBytes = 0x450, + kMatchFinder, + kMatchFinderCycles, + kNumPasses = 0x460, + kAlgorithm = 0x470, + kMultiThread = 0x480, + kNumThreads, + kEndMarker = 0x490 + }; +} + +CODER_INTERFACE(ICompressSetCoderProperties, 0x20) +{ + STDMETHOD(SetCoderProperties)(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties) PURE; +}; + +/* +CODER_INTERFACE(ICompressSetCoderProperties, 0x21) +{ + STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE; +}; +*/ + +CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22) +{ + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE; +}; + +CODER_INTERFACE(ICompressWriteCoderProperties, 0x23) +{ + STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStreams) PURE; +}; + +CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24) +{ + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE; +}; + +CODER_INTERFACE(ICompressSetCoderMt, 0x25) +{ + STDMETHOD(SetNumberOfThreads)(UInt32 numThreads) PURE; +}; + +CODER_INTERFACE(ICompressGetSubStreamSize, 0x30) +{ + STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE; +}; + +CODER_INTERFACE(ICompressSetInStream, 0x31) +{ + STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE; + STDMETHOD(ReleaseInStream)() PURE; +}; + +CODER_INTERFACE(ICompressSetOutStream, 0x32) +{ + STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE; + STDMETHOD(ReleaseOutStream)() PURE; +}; + +CODER_INTERFACE(ICompressSetInStreamSize, 0x33) +{ + STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE; +}; + +CODER_INTERFACE(ICompressSetOutStreamSize, 0x34) +{ + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE; +}; + +CODER_INTERFACE(ICompressFilter, 0x40) +{ + STDMETHOD(Init)() PURE; + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) PURE; + // Filter return outSize (UInt32) + // if (outSize <= size): Filter have converted outSize bytes + // if (outSize > size): Filter have not converted anything. + // and it needs at least outSize bytes to convert one block + // (it's for crypto block algorithms). +}; + +CODER_INTERFACE(ICompressCodecsInfo, 0x60) +{ + STDMETHOD(GetNumberOfMethods)(UInt32 *numMethods) PURE; + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE; + STDMETHOD(CreateDecoder)(UInt32 index, const GUID *iid, void **coder) PURE; + STDMETHOD(CreateEncoder)(UInt32 index, const GUID *iid, void **coder) PURE; +}; +CODER_INTERFACE(ISetCompressCodecsInfo, 0x61) +{ + STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo) PURE; +}; + +CODER_INTERFACE(ICryptoProperties, 0x80) +{ + STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE; + STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE; +}; + +/* +CODER_INTERFACE(ICryptoResetSalt, 0x88) +{ + STDMETHOD(ResetSalt)() PURE; +}; +*/ + +CODER_INTERFACE(ICryptoResetInitVector, 0x8C) +{ + STDMETHOD(ResetInitVector)() PURE; +}; + +CODER_INTERFACE(ICryptoSetPassword, 0x90) +{ + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE; +}; + +CODER_INTERFACE(ICryptoSetCRC, 0xA0) +{ + STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE; +}; + +////////////////////// +// It's for DLL file +namespace NMethodPropID +{ + enum EEnum + { + kID, + kName, + kDecoder, + kEncoder, + kInStreams, + kOutStreams, + kDescription, + kDecoderIsAssigned, + kEncoderIsAssigned + }; +} + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/IDecl.h b/desmume/src/windows/7z/CPP/7zip/IDecl.h new file mode 100644 index 000000000..768bbe710 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/IDecl.h @@ -0,0 +1,15 @@ +// IDecl.h + +#ifndef __IDECL_H +#define __IDECL_H + +#include "../Common/MyUnknown.h" + +#define DECL_INTERFACE_SUB(i, base, groupId, subId) \ +DEFINE_GUID(IID_ ## i, \ +0x23170F69, 0x40C1, 0x278A, 0, 0, 0, (groupId), 0, (subId), 0, 0); \ +struct i: public base + +#define DECL_INTERFACE(i, groupId, subId) DECL_INTERFACE_SUB(i, IUnknown, groupId, subId) + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/IPassword.h b/desmume/src/windows/7z/CPP/7zip/IPassword.h new file mode 100644 index 000000000..5679d84ce --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/IPassword.h @@ -0,0 +1,24 @@ +// IPassword.h + +#ifndef __IPASSWORD_H +#define __IPASSWORD_H + +#include "../Common/MyUnknown.h" +#include "../Common/Types.h" + +#include "IDecl.h" + +#define PASSWORD_INTERFACE(i, x) DECL_INTERFACE(i, 5, x) + +PASSWORD_INTERFACE(ICryptoGetTextPassword, 0x10) +{ + STDMETHOD(CryptoGetTextPassword)(BSTR *password) PURE; +}; + +PASSWORD_INTERFACE(ICryptoGetTextPassword2, 0x11) +{ + STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password) PURE; +}; + +#endif + diff --git a/desmume/src/windows/7z/CPP/7zip/IProgress.h b/desmume/src/windows/7z/CPP/7zip/IProgress.h new file mode 100644 index 000000000..09486baf3 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/IProgress.h @@ -0,0 +1,33 @@ +// Interface/IProgress.h + +#ifndef __IPROGRESS_H +#define __IPROGRESS_H + +#include "../Common/MyUnknown.h" +#include "../Common/Types.h" + +#include "IDecl.h" + +#define INTERFACE_IProgress(x) \ + STDMETHOD(SetTotal)(UInt64 total) x; \ + STDMETHOD(SetCompleted)(const UInt64 *completeValue) x; \ + +DECL_INTERFACE(IProgress, 0, 5) +{ + INTERFACE_IProgress(PURE) +}; + +/* +// {23170F69-40C1-278A-0000-000000050002} +DEFINE_GUID(IID_IProgress2, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000000050002") +IProgress2: public IUnknown +{ +public: + STDMETHOD(SetTotal)(const UInt64 *total) PURE; + STDMETHOD(SetCompleted)(const UInt64 *completeValue) PURE; +}; +*/ + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/IStream.h b/desmume/src/windows/7z/CPP/7zip/IStream.h new file mode 100644 index 000000000..d5ed723fe --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/IStream.h @@ -0,0 +1,58 @@ +// IStream.h + +#ifndef __ISTREAM_H +#define __ISTREAM_H + +#include "../Common/MyUnknown.h" +#include "../Common/Types.h" + +#include "IDecl.h" + +#define STREAM_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 3, x) +#define STREAM_INTERFACE(i, x) STREAM_INTERFACE_SUB(i, IUnknown, x) + +STREAM_INTERFACE(ISequentialInStream, 0x01) +{ + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE; + /* + Out: if size != 0, return_value = S_OK and (*processedSize == 0), + then there are no more bytes in stream. + if (size > 0) && there are bytes in stream, + this function must read at least 1 byte. + This function is allowed to read less than number of remaining bytes in stream. + You must call Read function in loop, if you need exact amount of data + */ +}; + +STREAM_INTERFACE(ISequentialOutStream, 0x02) +{ + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE; + /* + if (size > 0) this function must write at least 1 byte. + This function is allowed to write less than "size". + You must call Write function in loop, if you need to write exact amount of data + */ +}; + +STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03) +{ + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; +}; + +STREAM_INTERFACE_SUB(IOutStream, ISequentialOutStream, 0x04) +{ + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; + STDMETHOD(SetSize)(Int64 newSize) PURE; +}; + +STREAM_INTERFACE(IStreamGetSize, 0x06) +{ + STDMETHOD(GetSize)(UInt64 *size) PURE; +}; + +STREAM_INTERFACE(IOutStreamFlush, 0x07) +{ + STDMETHOD(Flush)() PURE; +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/7zip/PropID.h b/desmume/src/windows/7z/CPP/7zip/PropID.h new file mode 100644 index 000000000..695f80295 --- /dev/null +++ b/desmume/src/windows/7z/CPP/7zip/PropID.h @@ -0,0 +1,69 @@ +// PropID.h + +#ifndef __7ZIP_PROPID_H +#define __7ZIP_PROPID_H + +enum +{ + kpidNoProperty = 0, + + kpidHandlerItemIndex = 2, + kpidPath, + kpidName, + kpidExtension, + kpidIsDir, + kpidSize, + kpidPackSize, + kpidAttrib, + kpidCTime, + kpidATime, + kpidMTime, + kpidSolid, + kpidCommented, + kpidEncrypted, + kpidSplitBefore, + kpidSplitAfter, + kpidDictionarySize, + kpidCRC, + kpidType, + kpidIsAnti, + kpidMethod, + kpidHostOS, + kpidFileSystem, + kpidUser, + kpidGroup, + kpidBlock, + kpidComment, + kpidPosition, + kpidPrefix, + kpidNumSubDirs, + kpidNumSubFiles, + kpidUnpackVer, + kpidVolume, + kpidIsVolume, + kpidOffset, + kpidLinks, + kpidNumBlocks, + kpidNumVolumes, + kpidTimeType, + kpidBit64, + kpidBigEndian, + kpidCpu, + kpidPhySize, + kpidHeadersSize, + kpidChecksum, + kpidCharacts, + kpidVa, + + kpidTotalSize = 0x1100, + kpidFreeSpace, + kpidClusterSize, + kpidVolumeName, + + kpidLocalName = 0x1200, + kpidProvider, + + kpidUserDefined = 0x10000 +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/Common/Buffer.h b/desmume/src/windows/7z/CPP/Common/Buffer.h new file mode 100644 index 000000000..b0959eddb --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/Buffer.h @@ -0,0 +1,77 @@ +// Common/Buffer.h + +#ifndef __COMMON_BUFFER_H +#define __COMMON_BUFFER_H + +#include "Defs.h" + +template class CBuffer +{ +protected: + size_t _capacity; + T *_items; +public: + void Free() + { + delete []_items; + _items = 0; + _capacity = 0; + } + CBuffer(): _capacity(0), _items(0) {}; + CBuffer(const CBuffer &buffer): _capacity(0), _items(0) { *this = buffer; } + CBuffer(size_t size): _items(0), _capacity(0) { SetCapacity(size); } + virtual ~CBuffer() { delete []_items; } + operator T *() { return _items; }; + operator const T *() const { return _items; }; + size_t GetCapacity() const { return _capacity; } + void SetCapacity(size_t newCapacity) + { + if (newCapacity == _capacity) + return; + T *newBuffer; + if (newCapacity > 0) + { + newBuffer = new T[newCapacity]; + if (_capacity > 0) + memmove(newBuffer, _items, MyMin(_capacity, newCapacity) * sizeof(T)); + } + else + newBuffer = 0; + delete []_items; + _items = newBuffer; + _capacity = newCapacity; + } + CBuffer& operator=(const CBuffer &buffer) + { + Free(); + if (buffer._capacity > 0) + { + SetCapacity(buffer._capacity); + memmove(_items, buffer._items, buffer._capacity * sizeof(T)); + } + return *this; + } +}; + +template +bool operator==(const CBuffer& b1, const CBuffer& b2) +{ + if (b1.GetCapacity() != b2.GetCapacity()) + return false; + for (size_t i = 0; i < b1.GetCapacity(); i++) + if (b1[i] != b2[i]) + return false; + return true; +} + +template +bool operator!=(const CBuffer& b1, const CBuffer& b2) +{ + return !(b1 == b2); +} + +typedef CBuffer CCharBuffer; +typedef CBuffer CWCharBuffer; +typedef CBuffer CByteBuffer; + +#endif diff --git a/desmume/src/windows/7z/CPP/Common/CRC.cpp b/desmume/src/windows/7z/CPP/Common/CRC.cpp new file mode 100644 index 000000000..987b8a03a --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/CRC.cpp @@ -0,0 +1,10 @@ +// Common/CRC.cpp + +#include "StdAfx.h" + +extern "C" +{ +#include "../../C/7zCrc.h" +} + +struct CCRCTableInit { CCRCTableInit() { CrcGenerateTable(); } } g_CRCTableInit; diff --git a/desmume/src/windows/7z/CPP/Common/ComTry.h b/desmume/src/windows/7z/CPP/Common/ComTry.h new file mode 100644 index 000000000..98e592766 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/ComTry.h @@ -0,0 +1,17 @@ +// ComTry.h + +#ifndef __COM_TRY_H +#define __COM_TRY_H + +#include "MyWindows.h" +// #include "Exception.h" +// #include "NewHandler.h" + +#define COM_TRY_BEGIN try { +#define COM_TRY_END } catch(...) { return E_OUTOFMEMORY; } + + // catch(const CNewException &) { return E_OUTOFMEMORY; }\ + // catch(const CSystemException &e) { return e.ErrorCode; }\ + // catch(...) { return E_FAIL; } + +#endif diff --git a/desmume/src/windows/7z/CPP/Common/Defs.h b/desmume/src/windows/7z/CPP/Common/Defs.h new file mode 100644 index 000000000..69b8ecea8 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/Defs.h @@ -0,0 +1,20 @@ +// Common/Defs.h + +#ifndef __COMMON_DEFS_H +#define __COMMON_DEFS_H + +template inline T MyMin(T a, T b) + { return a < b ? a : b; } +template inline T MyMax(T a, T b) + { return a > b ? a : b; } + +template inline int MyCompare(T a, T b) + { return a < b ? -1 : (a == b ? 0 : 1); } + +inline int BoolToInt(bool value) + { return (value ? 1: 0); } + +inline bool IntToBool(int value) + { return (value != 0); } + +#endif diff --git a/desmume/src/windows/7z/CPP/Common/DynamicBuffer.h b/desmume/src/windows/7z/CPP/Common/DynamicBuffer.h new file mode 100644 index 000000000..83ef0ea2c --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/DynamicBuffer.h @@ -0,0 +1,47 @@ +// Common/DynamicBuffer.h + +#ifndef __COMMON_DYNAMICBUFFER_H +#define __COMMON_DYNAMICBUFFER_H + +#include "Buffer.h" + +template class CDynamicBuffer: public CBuffer +{ + void GrowLength(size_t size) + { + size_t delta; + if (this->_capacity > 64) + delta = this->_capacity / 4; + else if (this->_capacity > 8) + delta = 16; + else + delta = 4; + delta = MyMax(delta, size); + SetCapacity(this->_capacity + delta); + } +public: + CDynamicBuffer(): CBuffer() {}; + CDynamicBuffer(const CDynamicBuffer &buffer): CBuffer(buffer) {}; + CDynamicBuffer(size_t size): CBuffer(size) {}; + CDynamicBuffer& operator=(const CDynamicBuffer &buffer) + { + this->Free(); + if (buffer._capacity > 0) + { + SetCapacity(buffer._capacity); + memmove(this->_items, buffer._items, buffer._capacity * sizeof(T)); + } + return *this; + } + void EnsureCapacity(size_t capacity) + { + if (this->_capacity < capacity) + GrowLength(capacity - this->_capacity); + } +}; + +typedef CDynamicBuffer CCharDynamicBuffer; +typedef CDynamicBuffer CWCharDynamicBuffer; +typedef CDynamicBuffer CByteDynamicBuffer; + +#endif diff --git a/desmume/src/windows/7z/CPP/Common/InitializeStaticLib.h b/desmume/src/windows/7z/CPP/Common/InitializeStaticLib.h new file mode 100644 index 000000000..a0d70b6fd --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/InitializeStaticLib.h @@ -0,0 +1,29 @@ +// Common/InitializeStaticLib.h +// +// it's necessary to include this from one cpp file in order to use 7zip as a static library, +// otherwise the linker will optimize away some important internals of 7zip. + +#ifndef __COMMON_INITIALIZESTATICLIB_H +#define __COMMON_INITIALIZESTATICLIB_H + +#define FORCE_REF(dec, var) extern dec var; void* var##ref = (void*)&var; + +#include "../7zip/Common/DeclareCodecs.h" +#include "../7zip/Common/DeclareArcs.h" + +FORCE_REF(struct CCRCTableInit, g_CRCTableInit) + + +// these don't seem to be necessary with my compiler, +// but they're here in case a different compiler more aggressively strips out unreferenced code +FORCE_REF(class CBZip2CrcTableInit, g_BZip2CrcTableInit) +namespace NCrypto { struct CAesTabInit; FORCE_REF(CAesTabInit, g_AesTabInit) } +namespace NBitl { struct CInverterTableInitializer; FORCE_REF(CInverterTableInitializer, g_InverterTableInitializer) } +namespace NCompress { namespace NRar3 { class CDistInit; FORCE_REF(CDistInit, g_DistInit) }} +namespace NArchive { namespace NLzh { class CCRCTableInit; FORCE_REF(CCRCTableInit, g_CRCTableInit) }} +namespace NArchive { namespace N7z { class SignatureInitializer; FORCE_REF(SignatureInitializer, g_SignatureInitializer) }} +namespace NArchive{ namespace NRar{ namespace NHeader{ class CMarkerInitializer; FORCE_REF(CMarkerInitializer, g_MarkerInitializer) }}} +namespace NArchive { namespace NZip { namespace NSignature{ class CMarkersInitializer; FORCE_REF(CMarkersInitializer, g_MarkerInitializer) }}} + + +#endif diff --git a/desmume/src/windows/7z/CPP/Common/IntToString.cpp b/desmume/src/windows/7z/CPP/Common/IntToString.cpp new file mode 100644 index 000000000..f0a499d6b --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/IntToString.cpp @@ -0,0 +1,63 @@ +// Common/IntToString.cpp + +#include "StdAfx.h" + +#include "IntToString.h" + +void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base) +{ + if (base < 2 || base > 36) + { + *s = '\0'; + return; + } + char temp[72]; + int pos = 0; + do + { + int delta = (int)(value % base); + temp[pos++] = (char)((delta < 10) ? ('0' + delta) : ('a' + (delta - 10))); + value /= base; + } + while (value != 0); + do + *s++ = temp[--pos]; + while (pos > 0); + *s = '\0'; +} + +void ConvertUInt64ToString(UInt64 value, wchar_t *s) +{ + wchar_t temp[32]; + int pos = 0; + do + { + temp[pos++] = (wchar_t)(L'0' + (int)(value % 10)); + value /= 10; + } + while (value != 0); + do + *s++ = temp[--pos]; + while (pos > 0); + *s = L'\0'; +} + +void ConvertInt64ToString(Int64 value, char *s) +{ + if (value < 0) + { + *s++ = '-'; + value = -value; + } + ConvertUInt64ToString(value, s); +} + +void ConvertInt64ToString(Int64 value, wchar_t *s) +{ + if (value < 0) + { + *s++ = L'-'; + value = -value; + } + ConvertUInt64ToString(value, s); +} diff --git a/desmume/src/windows/7z/CPP/Common/IntToString.h b/desmume/src/windows/7z/CPP/Common/IntToString.h new file mode 100644 index 000000000..2f50ba95a --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/IntToString.h @@ -0,0 +1,15 @@ +// Common/IntToString.h + +#ifndef __COMMON_INTTOSTRING_H +#define __COMMON_INTTOSTRING_H + +#include +#include "Types.h" + +void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base = 10); +void ConvertUInt64ToString(UInt64 value, wchar_t *s); + +void ConvertInt64ToString(Int64 value, char *s); +void ConvertInt64ToString(Int64 value, wchar_t *s); + +#endif diff --git a/desmume/src/windows/7z/CPP/Common/MyCom.h b/desmume/src/windows/7z/CPP/Common/MyCom.h new file mode 100644 index 000000000..d04fa4c3d --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/MyCom.h @@ -0,0 +1,225 @@ +// MyCom.h + +#ifndef __MYCOM_H +#define __MYCOM_H + +#include "MyWindows.h" + +#ifndef RINOK +#define RINOK(x) { HRESULT __result_ = (x); if (__result_ != S_OK) return __result_; } +#endif + +template +class CMyComPtr +{ + T* _p; +public: + // typedef T _PtrClass; + CMyComPtr() { _p = NULL;} + CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); } + CMyComPtr(const CMyComPtr& lp) + { + if ((_p = lp._p) != NULL) + _p->AddRef(); + } + ~CMyComPtr() { if (_p) _p->Release(); } + void Release() { if (_p) { _p->Release(); _p = NULL; } } + operator T*() const { return (T*)_p; } + // T& operator*() const { return *_p; } + T** operator&() { return &_p; } + T* operator->() const { return _p; } + T* operator=(T* p) + { + if (p != 0) + p->AddRef(); + if (_p) + _p->Release(); + _p = p; + return p; + } + T* operator=(const CMyComPtr& lp) { return (*this = lp._p); } + bool operator!() const { return (_p == NULL); } + // bool operator==(T* pT) const { return _p == pT; } + // Compare two objects for equivalence + void Attach(T* p2) + { + Release(); + _p = p2; + } + T* Detach() + { + T* pt = _p; + _p = NULL; + return pt; + } + #ifdef _WIN32 + HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) + { + return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p); + } + #endif + /* + HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) + { + CLSID clsid; + HRESULT hr = CLSIDFromProgID(szProgID, &clsid); + ATLASSERT(_p == NULL); + if (SUCCEEDED(hr)) + hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p); + return hr; + } + */ + template + HRESULT QueryInterface(REFGUID iid, Q** pp) const + { + return _p->QueryInterface(iid, (void**)pp); + } +}; + +////////////////////////////////////////////////////////// + +inline HRESULT StringToBstr(LPCOLESTR src, BSTR *bstr) +{ + *bstr = ::SysAllocString(src); + return (*bstr != 0) ? S_OK : E_OUTOFMEMORY; +} + +class CMyComBSTR +{ +public: + BSTR m_str; + CMyComBSTR(): m_str(NULL) {} + CMyComBSTR(LPCOLESTR src) { m_str = ::SysAllocString(src); } + // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); } + // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); } + CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); } + /* + CMyComBSTR(REFGUID src) + { + LPOLESTR szGuid; + StringFromCLSID(src, &szGuid); + m_str = ::SysAllocString(szGuid); + CoTaskMemFree(szGuid); + } + */ + ~CMyComBSTR() { ::SysFreeString(m_str); } + CMyComBSTR& operator=(const CMyComBSTR& src) + { + if (m_str != src.m_str) + { + if (m_str) + ::SysFreeString(m_str); + m_str = src.MyCopy(); + } + return *this; + } + CMyComBSTR& operator=(LPCOLESTR src) + { + ::SysFreeString(m_str); + m_str = ::SysAllocString(src); + return *this; + } + unsigned int Length() const { return ::SysStringLen(m_str); } + operator BSTR() const { return m_str; } + BSTR* operator&() { return &m_str; } + BSTR MyCopy() const + { + int byteLen = ::SysStringByteLen(m_str); + BSTR res = ::SysAllocStringByteLen(NULL, byteLen); + memcpy(res, m_str, byteLen); + return res; + } + /* + void Attach(BSTR src) { m_str = src; } + BSTR Detach() + { + BSTR s = m_str; + m_str = NULL; + return s; + } + */ + void Empty() + { + ::SysFreeString(m_str); + m_str = NULL; + } + bool operator!() const { return (m_str == NULL); } +}; + +////////////////////////////////////////////////////////// + +class CMyUnknownImp +{ +public: + ULONG __m_RefCount; + CMyUnknownImp(): __m_RefCount(0) {} +}; + +#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \ + (REFGUID iid, void **outObject) { + +#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \ + { *outObject = (void *)(i *)this; AddRef(); return S_OK; } + +#define MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) if (iid == IID_IUnknown) \ + { *outObject = (void *)(IUnknown *)(i *)this; AddRef(); return S_OK; } + +#define MY_QUERYINTERFACE_BEGIN2(i) MY_QUERYINTERFACE_BEGIN \ + MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \ + MY_QUERYINTERFACE_ENTRY(i) + +#define MY_QUERYINTERFACE_END return E_NOINTERFACE; } + +#define MY_ADDREF_RELEASE \ +STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \ +STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \ + return __m_RefCount; delete this; return 0; } + +#define MY_UNKNOWN_IMP_SPEC(i) \ + MY_QUERYINTERFACE_BEGIN \ + i \ + MY_QUERYINTERFACE_END \ + MY_ADDREF_RELEASE + + +#define MY_UNKNOWN_IMP MY_QUERYINTERFACE_BEGIN \ + MY_QUERYINTERFACE_ENTRY_UNKNOWN(IUnknown) \ + MY_QUERYINTERFACE_END \ + MY_ADDREF_RELEASE + +#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \ + MY_QUERYINTERFACE_ENTRY(i) \ + ) + +#define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + ) + +#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + MY_QUERYINTERFACE_ENTRY(i3) \ + ) + +#define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + MY_QUERYINTERFACE_ENTRY(i3) \ + MY_QUERYINTERFACE_ENTRY(i4) \ + ) + +#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + MY_QUERYINTERFACE_ENTRY(i3) \ + MY_QUERYINTERFACE_ENTRY(i4) \ + MY_QUERYINTERFACE_ENTRY(i5) \ + ) + +#endif diff --git a/desmume/src/windows/7z/CPP/Common/MyException.h b/desmume/src/windows/7z/CPP/Common/MyException.h new file mode 100644 index 000000000..cd9fe6948 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/MyException.h @@ -0,0 +1,14 @@ +// Common/Exception.h + +#ifndef __COMMON_EXCEPTION_H +#define __COMMON_EXCEPTION_H + +#include "MyWindows.h" + +struct CSystemException +{ + HRESULT ErrorCode; + CSystemException(HRESULT errorCode): ErrorCode(errorCode) {} +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/Common/MyInitGuid.h b/desmume/src/windows/7z/CPP/Common/MyInitGuid.h new file mode 100644 index 000000000..b1e70d868 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/MyInitGuid.h @@ -0,0 +1,15 @@ +// Common/MyInitGuid.h + +#ifndef __COMMON_MYINITGUID_H +#define __COMMON_MYINITGUID_H + +#ifdef _WIN32 +#include +#else +#define INITGUID +#include "MyGuidDef.h" +DEFINE_GUID(IID_IUnknown, +0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); +#endif + +#endif diff --git a/desmume/src/windows/7z/CPP/Common/MyMap.cpp b/desmume/src/windows/7z/CPP/Common/MyMap.cpp new file mode 100644 index 000000000..a69c61a04 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/MyMap.cpp @@ -0,0 +1,140 @@ +// MyMap.cpp + +#include "StdAfx.h" + +#include "MyMap.h" + +static const unsigned kNumBitsMax = sizeof(UInt32) * 8; + +static UInt32 GetSubBits(UInt32 value, unsigned startPos, unsigned numBits) +{ + if (startPos == sizeof(value) * 8) + return 0; + value >>= startPos; + if (numBits == sizeof(value) * 8) + return value; + return value & (((UInt32)1 << numBits) - 1); +} + +static inline unsigned GetSubBit(UInt32 v, unsigned n) { return (unsigned)(v >> n) & 1; } + +bool CMap32::Find(UInt32 key, UInt32 &valueRes) const +{ + valueRes = (UInt32)(Int32)-1; + if (Nodes.Size() == 0) + return false; + if (Nodes.Size() == 1) + { + const CNode &n = Nodes[0]; + if (n.Len == kNumBitsMax) + { + valueRes = n.Values[0]; + return (key == n.Key); + } + } + + int cur = 0; + unsigned bitPos = kNumBitsMax; + for (;;) + { + const CNode &n = Nodes[cur]; + bitPos -= n.Len; + if (GetSubBits(key, bitPos, n.Len) != GetSubBits(n.Key, bitPos, n.Len)) + return false; + unsigned bit = GetSubBit(key, --bitPos); + if (n.IsLeaf[bit]) + { + valueRes = n.Values[bit]; + return (key == n.Keys[bit]); + } + cur = (int)n.Keys[bit]; + } +} + +bool CMap32::Set(UInt32 key, UInt32 value) +{ + if (Nodes.Size() == 0) + { + CNode n; + n.Key = n.Keys[0] = n.Keys[1] = key; + n.Values[0] = n.Values[1] = value; + n.IsLeaf[0] = n.IsLeaf[1] = 1; + n.Len = kNumBitsMax; + Nodes.Add(n); + return false; + } + if (Nodes.Size() == 1) + { + CNode &n = Nodes[0]; + if (n.Len == kNumBitsMax) + { + if (key == n.Key) + { + n.Values[0] = n.Values[1] = value; + return true; + } + unsigned i = kNumBitsMax - 1; + for (;GetSubBit(key, i) == GetSubBit(n.Key, i); i--); + n.Len = (UInt16)(kNumBitsMax - (1 + i)); + unsigned newBit = GetSubBit(key, i); + n.Values[newBit] = value; + n.Keys[newBit] = key; + return false; + } + } + + int cur = 0; + unsigned bitPos = kNumBitsMax; + for (;;) + { + CNode &n = Nodes[cur]; + bitPos -= n.Len; + if (GetSubBits(key, bitPos, n.Len) != GetSubBits(n.Key, bitPos, n.Len)) + { + unsigned i = n.Len - 1; + for (; GetSubBit(key, bitPos + i) == GetSubBit(n.Key, bitPos + i); i--); + + CNode e2(n); + e2.Len = (UInt16)i; + + n.Len = (UInt16)(n.Len - (1 + i)); + unsigned newBit = GetSubBit(key, bitPos + i); + n.Values[newBit] = value; + n.IsLeaf[newBit] = 1; + n.IsLeaf[1 - newBit] = 0; + n.Keys[newBit] = key; + n.Keys[1 - newBit] = Nodes.Size(); + Nodes.Add(e2); + return false; + } + unsigned bit = GetSubBit(key, --bitPos); + + if (n.IsLeaf[bit]) + { + if (key == n.Keys[bit]) + { + n.Values[bit] = value; + return true; + } + unsigned i = bitPos - 1; + for (;GetSubBit(key, i) == GetSubBit(n.Keys[bit], i); i--); + + CNode e2; + + unsigned newBit = GetSubBit(key, i); + e2.Values[newBit] = value; + e2.Values[1 - newBit] = n.Values[bit]; + e2.IsLeaf[newBit] = e2.IsLeaf[1 - newBit] = 1; + e2.Keys[newBit] = key; + e2.Keys[1 - newBit] = e2.Key = n.Keys[bit]; + e2.Len = (UInt16)(bitPos - (1 + i)); + + n.IsLeaf[bit] = 0; + n.Keys[bit] = Nodes.Size(); + + Nodes.Add(e2); + return false; + } + cur = (int)n.Keys[bit]; + } +} diff --git a/desmume/src/windows/7z/CPP/Common/MyMap.h b/desmume/src/windows/7z/CPP/Common/MyMap.h new file mode 100644 index 000000000..4545bcef4 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/MyMap.h @@ -0,0 +1,28 @@ +// MyMap.h + +#ifndef __COMMON_MYMAP_H +#define __COMMON_MYMAP_H + +#include "MyVector.h" +#include "Types.h" + +class CMap32 +{ + struct CNode + { + UInt32 Key; + UInt32 Keys[2]; + UInt32 Values[2]; + UInt16 Len; + Byte IsLeaf[2]; + }; + CRecordVector Nodes; + +public: + + void Clear() { Nodes.Clear(); } + bool Find(UInt32 key, UInt32 &valueRes) const; + bool Set(UInt32 key, UInt32 value); // returns true, if there is such key already +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/Common/MyString.cpp b/desmume/src/windows/7z/CPP/Common/MyString.cpp new file mode 100644 index 000000000..efab50350 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/MyString.cpp @@ -0,0 +1,198 @@ +// Common/MyString.cpp + +#include "StdAfx.h" + +#ifdef _WIN32 +#include "StringConvert.h" +#else +#include +#endif + +#include "MyString.h" + + +#ifdef _WIN32 + +#ifndef _UNICODE + +wchar_t MyCharUpper(wchar_t c) +{ + if (c == 0) + return 0; + wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c); + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return (wchar_t)(unsigned int)(UINT_PTR)res; + const int kBufferSize = 4; + char s[kBufferSize + 1]; + int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0); + if (numChars == 0 || numChars > kBufferSize) + return c; + s[numChars] = 0; + ::CharUpperA(s); + ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1); + return c; +} + +wchar_t MyCharLower(wchar_t c) +{ + if (c == 0) + return 0; + wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c); + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return (wchar_t)(unsigned int)(UINT_PTR)res; + const int kBufferSize = 4; + char s[kBufferSize + 1]; + int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0); + if (numChars == 0 || numChars > kBufferSize) + return c; + s[numChars] = 0; + ::CharLowerA(s); + ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1); + return c; +} + +wchar_t * MyStringUpper(wchar_t *s) +{ + if (s == 0) + return 0; + wchar_t *res = CharUpperW(s); + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return res; + AString a = UnicodeStringToMultiByte(s); + a.MakeUpper(); + return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a)); +} + +wchar_t * MyStringLower(wchar_t *s) +{ + if (s == 0) + return 0; + wchar_t *res = CharLowerW(s); + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return res; + AString a = UnicodeStringToMultiByte(s); + a.MakeLower(); + return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a)); +} + +#endif + +/* +inline int ConvertCompareResult(int r) { return r - 2; } + +int MyStringCollate(const wchar_t *s1, const wchar_t *s2) +{ + int res = CompareStringW( + LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1); + #ifdef _UNICODE + return ConvertCompareResult(res); + #else + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return ConvertCompareResult(res); + return MyStringCollate(UnicodeStringToMultiByte(s1), + UnicodeStringToMultiByte(s2)); + #endif +} + +#ifndef _WIN32_WCE +int MyStringCollate(const char *s1, const char *s2) +{ + return ConvertCompareResult(CompareStringA( + LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1)); +} + +int MyStringCollateNoCase(const char *s1, const char *s2) +{ + return ConvertCompareResult(CompareStringA( + LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1)); +} +#endif + +int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2) +{ + int res = CompareStringW( + LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1); + #ifdef _UNICODE + return ConvertCompareResult(res); + #else + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return ConvertCompareResult(res); + return MyStringCollateNoCase(UnicodeStringToMultiByte(s1), + UnicodeStringToMultiByte(s2)); + #endif +} +*/ + +#else + +wchar_t MyCharUpper(wchar_t c) +{ + return toupper(c); +} + +/* +int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2) +{ + for (;;) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + wchar_t u1 = MyCharUpper(c1); + wchar_t u2 = MyCharUpper(c2); + + if (u1 < u2) return -1; + if (u1 > u2) return 1; + if (u1 == 0) return 0; + } +} +*/ + +#endif + +int MyStringCompare(const char *s1, const char *s2) +{ + for (;;) + { + unsigned char c1 = (unsigned char)*s1++; + unsigned char c2 = (unsigned char)*s2++; + if (c1 < c2) return -1; + if (c1 > c2) return 1; + if (c1 == 0) return 0; + } +} + +int MyStringCompare(const wchar_t *s1, const wchar_t *s2) +{ + for (;;) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + if (c1 < c2) return -1; + if (c1 > c2) return 1; + if (c1 == 0) return 0; + } +} + +int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) +{ + for (;;) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + if (c1 != c2) + { + wchar_t u1 = MyCharUpper(c1); + wchar_t u2 = MyCharUpper(c2); + if (u1 < u2) return -1; + if (u1 > u2) return 1; + } + if (c1 == 0) return 0; + } +} + +#ifdef _WIN32 +int MyStringCompareNoCase(const char *s1, const char *s2) +{ + return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2)); +} +#endif diff --git a/desmume/src/windows/7z/CPP/Common/MyString.h b/desmume/src/windows/7z/CPP/Common/MyString.h new file mode 100644 index 000000000..74c8af2fc --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/MyString.h @@ -0,0 +1,631 @@ +// Common/String.h + +#ifndef __COMMON_STRING_H +#define __COMMON_STRING_H + +#include +// #include + +#include "MyVector.h" + +#ifdef _WIN32 +#include "MyWindows.h" +#endif + +template +inline int MyStringLen(const T *s) +{ + int i; + for (i = 0; s[i] != '\0'; i++); + return i; +} + +template +inline T * MyStringCopy(T *dest, const T *src) +{ + T *destStart = dest; + while ((*dest++ = *src++) != 0); + return destStart; +} + +inline wchar_t* MyStringGetNextCharPointer(wchar_t *p) + { return (p + 1); } +inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p) + { return (p + 1); } +inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *, wchar_t *p) + { return (p - 1); } +inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *, const wchar_t *p) + { return (p - 1); } + +#ifdef _WIN32 + +inline char* MyStringGetNextCharPointer(char *p) + { return CharNextA(p); } +inline const char* MyStringGetNextCharPointer(const char *p) + { return CharNextA(p); } + +inline char* MyStringGetPrevCharPointer(char *base, char *p) + { return CharPrevA(base, p); } +inline const char* MyStringGetPrevCharPointer(const char *base, const char *p) + { return CharPrevA(base, p); } + +inline char MyCharUpper(char c) + { return (char)(unsigned int)(UINT_PTR)CharUpperA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); } +#ifdef _UNICODE +inline wchar_t MyCharUpper(wchar_t c) + { return (wchar_t)(unsigned int)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c); } +#else +wchar_t MyCharUpper(wchar_t c); +#endif + +inline char MyCharLower(char c) + { return (char)(unsigned int)(UINT_PTR)CharLowerA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); } +#ifdef _UNICODE +inline wchar_t MyCharLower(wchar_t c) + { return (wchar_t)(unsigned int)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c); } +#else +wchar_t MyCharLower(wchar_t c); +#endif + +inline char * MyStringUpper(char *s) { return CharUpperA(s); } +#ifdef _UNICODE +inline wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); } +#else +wchar_t * MyStringUpper(wchar_t *s); +#endif + +inline char * MyStringLower(char *s) { return CharLowerA(s); } +#ifdef _UNICODE +inline wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); } +#else +wchar_t * MyStringLower(wchar_t *s); +#endif + +#else // Standard-C +wchar_t MyCharUpper(wchar_t c); +#endif + +////////////////////////////////////// +// Compare + +/* +#ifndef _WIN32_WCE +int MyStringCollate(const char *s1, const char *s2); +int MyStringCollateNoCase(const char *s1, const char *s2); +#endif +int MyStringCollate(const wchar_t *s1, const wchar_t *s2); +int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2); +*/ + +int MyStringCompare(const char *s1, const char *s2); +int MyStringCompare(const wchar_t *s1, const wchar_t *s2); + +#ifdef _WIN32 +int MyStringCompareNoCase(const char *s1, const char *s2); +#endif + +int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2); + +template +class CStringBase +{ + void TrimLeftWithCharSet(const CStringBase &charSet) + { + const T *p = _chars; + while (charSet.Find(*p) >= 0 && (*p != 0)) + p = GetNextCharPointer(p); + Delete(0, (int)(p - _chars)); + } + void TrimRightWithCharSet(const CStringBase &charSet) + { + const T *p = _chars; + const T *pLast = NULL; + while (*p != 0) + { + if (charSet.Find(*p) >= 0) + { + if (pLast == NULL) + pLast = p; + } + else + pLast = NULL; + p = GetNextCharPointer(p); + } + if (pLast != NULL) + { + int i = (int)(pLast - _chars); + Delete(i, _length - i); + } + + } + void MoveItems(int destIndex, int srcIndex) + { + memmove(_chars + destIndex, _chars + srcIndex, + sizeof(T) * (_length - srcIndex + 1)); + } + + void InsertSpace(int &index, int size) + { + CorrectIndex(index); + GrowLength(size); + MoveItems(index + size, index); + } + + static T *GetNextCharPointer(T *p) + { return MyStringGetNextCharPointer(p); } + static const T *GetNextCharPointer(const T *p) + { return MyStringGetNextCharPointer(p); } + static T *GetPrevCharPointer(T *base, T *p) + { return MyStringGetPrevCharPointer(base, p); } + static const T *GetPrevCharPointer(const T *base, const T *p) + { return MyStringGetPrevCharPointer(base, p); } +protected: + T *_chars; + int _length; + int _capacity; + + void SetCapacity(int newCapacity) + { + int realCapacity = newCapacity + 1; + if (realCapacity == _capacity) + return; + /* + const int kMaxStringSize = 0x20000000; + #ifndef _WIN32_WCE + if (newCapacity > kMaxStringSize || newCapacity < _length) + throw 1052337; + #endif + */ + T *newBuffer = new T[realCapacity]; + if (_capacity > 0) + { + for (int i = 0; i < _length; i++) + newBuffer[i] = _chars[i]; + delete []_chars; + } + _chars = newBuffer; + _chars[_length] = 0; + _capacity = realCapacity; + } + + void GrowLength(int n) + { + int freeSize = _capacity - _length - 1; + if (n <= freeSize) + return; + int delta; + if (_capacity > 64) + delta = _capacity / 2; + else if (_capacity > 8) + delta = 16; + else + delta = 4; + if (freeSize + delta < n) + delta = n - freeSize; + SetCapacity(_capacity + delta); + } + + void CorrectIndex(int &index) const + { + if (index > _length) + index = _length; + } + +public: + CStringBase(): _chars(0), _length(0), _capacity(0) { SetCapacity(3); } + CStringBase(T c): _chars(0), _length(0), _capacity(0) + { + SetCapacity(1); + _chars[0] = c; + _chars[1] = 0; + _length = 1; + } + CStringBase(const T *chars): _chars(0), _length(0), _capacity(0) + { + int length = MyStringLen(chars); + SetCapacity(length); + MyStringCopy(_chars, chars); // can be optimized by memove() + _length = length; + } + CStringBase(const CStringBase &s): _chars(0), _length(0), _capacity(0) + { + SetCapacity(s._length); + MyStringCopy(_chars, s._chars); + _length = s._length; + } + ~CStringBase() { delete []_chars; } + + operator const T*() const { return _chars;} + + // The minimum size of the character buffer in characters. + // This value does not include space for a null terminator. + T* GetBuffer(int minBufLength) + { + if (minBufLength >= _capacity) + SetCapacity(minBufLength); + return _chars; + } + void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); } + void ReleaseBuffer(int newLength) + { + /* + #ifndef _WIN32_WCE + if (newLength >= _capacity) + throw 282217; + #endif + */ + _chars[newLength] = 0; + _length = newLength; + } + + CStringBase& operator=(T c) + { + Empty(); + SetCapacity(1); + _chars[0] = c; + _chars[1] = 0; + _length = 1; + return *this; + } + CStringBase& operator=(const T *chars) + { + Empty(); + int length = MyStringLen(chars); + SetCapacity(length); + MyStringCopy(_chars, chars); + _length = length; + return *this; + } + CStringBase& operator=(const CStringBase& s) + { + if (&s == this) + return *this; + Empty(); + SetCapacity(s._length); + MyStringCopy(_chars, s._chars); + _length = s._length; + return *this; + } + + CStringBase& operator+=(T c) + { + GrowLength(1); + _chars[_length] = c; + _chars[++_length] = 0; + return *this; + } + CStringBase& operator+=(const T *s) + { + int len = MyStringLen(s); + GrowLength(len); + MyStringCopy(_chars + _length, s); + _length += len; + return *this; + } + CStringBase& operator+=(const CStringBase &s) + { + GrowLength(s._length); + MyStringCopy(_chars + _length, s._chars); + _length += s._length; + return *this; + } + void Empty() + { + _length = 0; + _chars[0] = 0; + } + int Length() const { return _length; } + bool IsEmpty() const { return (_length == 0); } + + CStringBase Mid(int startIndex) const + { return Mid(startIndex, _length - startIndex); } + CStringBase Mid(int startIndex, int count ) const + { + if (startIndex + count > _length) + count = _length - startIndex; + + if (startIndex == 0 && startIndex + count == _length) + return *this; + + CStringBase result; + result.SetCapacity(count); + // MyStringNCopy(result._chars, _chars + startIndex, count); + for (int i = 0; i < count; i++) + result._chars[i] = _chars[startIndex + i]; + result._chars[count] = 0; + result._length = count; + return result; + } + CStringBase Left(int count) const + { return Mid(0, count); } + CStringBase Right(int count) const + { + if (count > _length) + count = _length; + return Mid(_length - count, count); + } + + void MakeUpper() + { MyStringUpper(_chars); } + void MakeLower() + { MyStringLower(_chars); } + + int Compare(const CStringBase& s) const + { return MyStringCompare(_chars, s._chars); } + + int Compare(const T *s) const + { return MyStringCompare(_chars, s); } + + int CompareNoCase(const CStringBase& s) const + { return MyStringCompareNoCase(_chars, s._chars); } + + int CompareNoCase(const T *s) const + { return MyStringCompareNoCase(_chars, s); } + + /* + int Collate(const CStringBase& s) const + { return MyStringCollate(_chars, s._chars); } + int CollateNoCase(const CStringBase& s) const + { return MyStringCollateNoCase(_chars, s._chars); } + */ + + int Find(T c) const { return Find(c, 0); } + int Find(T c, int startIndex) const + { + T *p = _chars + startIndex; + for (;;) + { + if (*p == c) + return (int)(p - _chars); + if (*p == 0) + return -1; + p = GetNextCharPointer(p); + } + } + int Find(const CStringBase &s) const { return Find(s, 0); } + int Find(const CStringBase &s, int startIndex) const + { + if (s.IsEmpty()) + return startIndex; + for (; startIndex < _length; startIndex++) + { + int j; + for (j = 0; j < s._length && startIndex + j < _length; j++) + if (_chars[startIndex+j] != s._chars[j]) + break; + if (j == s._length) + return startIndex; + } + return -1; + } + int ReverseFind(T c) const + { + if (_length == 0) + return -1; + T *p = _chars + _length - 1; + for (;;) + { + if (*p == c) + return (int)(p - _chars); + if (p == _chars) + return -1; + p = GetPrevCharPointer(_chars, p); + } + } + int FindOneOf(const CStringBase &s) const + { + for (int i = 0; i < _length; i++) + if (s.Find(_chars[i]) >= 0) + return i; + return -1; + } + + void TrimLeft(T c) + { + const T *p = _chars; + while (c == *p) + p = GetNextCharPointer(p); + Delete(0, p - _chars); + } + private: + CStringBase GetTrimDefaultCharSet() + { + CStringBase charSet; + charSet += (T)' '; + charSet += (T)'\n'; + charSet += (T)'\t'; + return charSet; + } + public: + + void TrimLeft() + { + TrimLeftWithCharSet(GetTrimDefaultCharSet()); + } + void TrimRight() + { + TrimRightWithCharSet(GetTrimDefaultCharSet()); + } + void TrimRight(T c) + { + const T *p = _chars; + const T *pLast = NULL; + while (*p != 0) + { + if (*p == c) + { + if (pLast == NULL) + pLast = p; + } + else + pLast = NULL; + p = GetNextCharPointer(p); + } + if (pLast != NULL) + { + int i = pLast - _chars; + Delete(i, _length - i); + } + } + void Trim() + { + TrimRight(); + TrimLeft(); + } + + int Insert(int index, T c) + { + InsertSpace(index, 1); + _chars[index] = c; + _length++; + return _length; + } + int Insert(int index, const CStringBase &s) + { + CorrectIndex(index); + if (s.IsEmpty()) + return _length; + int numInsertChars = s.Length(); + InsertSpace(index, numInsertChars); + for (int i = 0; i < numInsertChars; i++) + _chars[index + i] = s[i]; + _length += numInsertChars; + return _length; + } + + // !!!!!!!!!!!!!!! test it if newChar = '\0' + int Replace(T oldChar, T newChar) + { + if (oldChar == newChar) + return 0; + int number = 0; + int pos = 0; + while (pos < Length()) + { + pos = Find(oldChar, pos); + if (pos < 0) + break; + _chars[pos] = newChar; + pos++; + number++; + } + return number; + } + int Replace(const CStringBase &oldString, const CStringBase &newString) + { + if (oldString.IsEmpty()) + return 0; + if (oldString == newString) + return 0; + int oldStringLength = oldString.Length(); + int newStringLength = newString.Length(); + int number = 0; + int pos = 0; + while (pos < _length) + { + pos = Find(oldString, pos); + if (pos < 0) + break; + Delete(pos, oldStringLength); + Insert(pos, newString); + pos += newStringLength; + number++; + } + return number; + } + int Delete(int index, int count = 1 ) + { + if (index + count > _length) + count = _length - index; + if (count > 0) + { + MoveItems(index, index + count); + _length -= count; + } + return _length; + } +}; + +template +CStringBase operator+(const CStringBase& s1, const CStringBase& s2) +{ + CStringBase result(s1); + result += s2; + return result; +} + +template +CStringBase operator+(const CStringBase& s, T c) +{ + CStringBase result(s); + result += c; + return result; +} + +template +CStringBase operator+(T c, const CStringBase& s) +{ + CStringBase result(c); + result += s; + return result; +} + +template +CStringBase operator+(const CStringBase& s, const T * chars) +{ + CStringBase result(s); + result += chars; + return result; +} + +template +CStringBase operator+(const T * chars, const CStringBase& s) +{ + CStringBase result(chars); + result += s; + return result; +} + +template +bool operator==(const CStringBase& s1, const CStringBase& s2) + { return (s1.Compare(s2) == 0); } + +template +bool operator<(const CStringBase& s1, const CStringBase& s2) + { return (s1.Compare(s2) < 0); } + +template +bool operator==(const T *s1, const CStringBase& s2) + { return (s2.Compare(s1) == 0); } + +template +bool operator==(const CStringBase& s1, const T *s2) + { return (s1.Compare(s2) == 0); } + +template +bool operator!=(const CStringBase& s1, const CStringBase& s2) + { return (s1.Compare(s2) != 0); } + +template +bool operator!=(const T *s1, const CStringBase& s2) + { return (s2.Compare(s1) != 0); } + +template +bool operator!=(const CStringBase& s1, const T *s2) + { return (s1.Compare(s2) != 0); } + +typedef CStringBase AString; +typedef CStringBase UString; + +typedef CObjectVector AStringVector; +typedef CObjectVector UStringVector; + +#ifdef _UNICODE + typedef UString CSysString; +#else + typedef AString CSysString; +#endif + +typedef CObjectVector CSysStringVector; + +#endif diff --git a/desmume/src/windows/7z/CPP/Common/MyUnknown.h b/desmume/src/windows/7z/CPP/Common/MyUnknown.h new file mode 100644 index 000000000..257fa4ab7 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/MyUnknown.h @@ -0,0 +1,24 @@ +// MyUnknown.h + +#ifndef __MYUNKNOWN_H +#define __MYUNKNOWN_H + +#ifdef _WIN32 + +#ifdef _WIN32_WCE +#if (_WIN32_WCE > 300) +#include +#else +#define MIDL_INTERFACE(x) struct +#endif +#else +#include +#endif + +#include + +#else +#include "MyWindows.h" +#endif + +#endif diff --git a/desmume/src/windows/7z/CPP/Common/MyVector.cpp b/desmume/src/windows/7z/CPP/Common/MyVector.cpp new file mode 100644 index 000000000..e0788b751 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/MyVector.cpp @@ -0,0 +1,90 @@ +// Common/MyVector.cpp + +#include "StdAfx.h" + +#include + +#include "MyVector.h" + +CBaseRecordVector::~CBaseRecordVector() { ClearAndFree(); } + +void CBaseRecordVector::ClearAndFree() +{ + Clear(); + delete []((unsigned char *)_items); + _capacity = 0; + _size = 0; + _items = 0; +} + +void CBaseRecordVector::Clear() { DeleteFrom(0); } +void CBaseRecordVector::DeleteBack() { Delete(_size - 1); } +void CBaseRecordVector::DeleteFrom(int index) +{ + Delete(index, _size - index); +} + +void CBaseRecordVector::ReserveOnePosition() +{ + if (_size != _capacity) + return; + int delta = 1; + if (_capacity >= 64) + delta = _capacity / 4; + else if (_capacity >= 8) + delta = 8; + Reserve(_capacity + delta); +} + +void CBaseRecordVector::Reserve(int newCapacity) +{ + // if (newCapacity <= _capacity) + if (newCapacity == _capacity) + return; + if ((unsigned)newCapacity >= ((unsigned)1 << (sizeof(unsigned) * 8 - 1))) + throw 1052353; + size_t newSize = (size_t)(unsigned)newCapacity * _itemSize; + if (newSize / _itemSize != (size_t)(unsigned)newCapacity) + throw 1052354; + unsigned char *p = NULL; + if (newSize > 0) + { + p = new unsigned char[newSize]; + if (p == 0) + throw 1052355; + int numRecordsToMove = (_size < newCapacity ? _size : newCapacity); + memcpy(p, _items, _itemSize * numRecordsToMove); + } + delete [](unsigned char *)_items; + _items = p; + _capacity = newCapacity; +} + +void CBaseRecordVector::ReserveDown() +{ + Reserve(_size); +} + +void CBaseRecordVector::MoveItems(int destIndex, int srcIndex) +{ + memmove(((unsigned char *)_items) + destIndex * _itemSize, + ((unsigned char *)_items) + srcIndex * _itemSize, + _itemSize * (_size - srcIndex)); +} + +void CBaseRecordVector::InsertOneItem(int index) +{ + ReserveOnePosition(); + MoveItems(index + 1, index); + _size++; +} + +void CBaseRecordVector::Delete(int index, int num) +{ + TestIndexAndCorrectNum(index, num); + if (num > 0) + { + MoveItems(index, index + num); + _size -= num; + } +} diff --git a/desmume/src/windows/7z/CPP/Common/MyVector.h b/desmume/src/windows/7z/CPP/Common/MyVector.h new file mode 100644 index 000000000..b8f4cd929 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/MyVector.h @@ -0,0 +1,256 @@ +// Common/Vector.h + +#ifndef __COMMON_VECTOR_H +#define __COMMON_VECTOR_H + +#include "Defs.h" + +class CBaseRecordVector +{ + void MoveItems(int destIndex, int srcIndex); +protected: + int _capacity; + int _size; + void *_items; + size_t _itemSize; + + void ReserveOnePosition(); + void InsertOneItem(int index); + void TestIndexAndCorrectNum(int index, int &num) const + { if (index + num > _size) num = _size - index; } +public: + CBaseRecordVector(size_t itemSize): _capacity(0), _size(0), _items(0), _itemSize(itemSize) {} + virtual ~CBaseRecordVector(); + void ClearAndFree(); + int Size() const { return _size; } + bool IsEmpty() const { return (_size == 0); } + void Reserve(int newCapacity); + void ReserveDown(); + virtual void Delete(int index, int num = 1); + void Clear(); + void DeleteFrom(int index); + void DeleteBack(); +}; + +template +class CRecordVector: public CBaseRecordVector +{ +public: + CRecordVector(): CBaseRecordVector(sizeof(T)){}; + CRecordVector(const CRecordVector &v): CBaseRecordVector(sizeof(T)) { *this = v; } + CRecordVector& operator=(const CRecordVector &v) + { + Clear(); + return (*this += v); + } + CRecordVector& operator+=(const CRecordVector &v) + { + int size = v.Size(); + Reserve(Size() + size); + for (int i = 0; i < size; i++) + Add(v[i]); + return *this; + } + int Add(T item) + { + ReserveOnePosition(); + ((T *)_items)[_size] = item; + return _size++; + } + void Insert(int index, T item) + { + InsertOneItem(index); + ((T *)_items)[index] = item; + } + // T* GetPointer() const { return (T*)_items; } + // operator const T *() const { return _items; }; + const T& operator[](int index) const { return ((T *)_items)[index]; } + T& operator[](int index) { return ((T *)_items)[index]; } + const T& Front() const { return operator[](0); } + T& Front() { return operator[](0); } + const T& Back() const { return operator[](_size - 1); } + T& Back() { return operator[](_size - 1); } + + void Swap(int i, int j) + { + T temp = operator[](i); + operator[](i) = operator[](j); + operator[](j) = temp; + } + + int FindInSorted(const T& item) const + { + int left = 0, right = Size(); + while (left != right) + { + int mid = (left + right) / 2; + const T& midValue = (*this)[mid]; + if (item == midValue) + return mid; + if (item < midValue) + right = mid; + else + left = mid + 1; + } + return -1; + } + + int AddToUniqueSorted(const T& item) + { + int left = 0, right = Size(); + while (left != right) + { + int mid = (left + right) / 2; + const T& midValue = (*this)[mid]; + if (item == midValue) + return mid; + if (item < midValue) + right = mid; + else + left = mid + 1; + } + Insert(right, item); + return right; + } + + static void SortRefDown(T* p, int k, int size, int (*compare)(const T*, const T*, void *), void *param) + { + T temp = p[k]; + for (;;) + { + int s = (k << 1); + if (s > size) + break; + if (s < size && compare(p + s + 1, p + s, param) > 0) + s++; + if (compare(&temp, p + s, param) >= 0) + break; + p[k] = p[s]; + k = s; + } + p[k] = temp; + } + + void Sort(int (*compare)(const T*, const T*, void *), void *param) + { + int size = _size; + if (size <= 1) + return; + T* p = (&Front()) - 1; + { + int i = size / 2; + do + SortRefDown(p, i, size, compare, param); + while (--i != 0); + } + do + { + T temp = p[size]; + p[size--] = p[1]; + p[1] = temp; + SortRefDown(p, 1, size, compare, param); + } + while (size > 1); + } +}; + +typedef CRecordVector CIntVector; +typedef CRecordVector CUIntVector; +typedef CRecordVector CBoolVector; +typedef CRecordVector CByteVector; +typedef CRecordVector CPointerVector; + +template +class CObjectVector: public CPointerVector +{ +public: + CObjectVector() {}; + ~CObjectVector() { Clear(); }; + CObjectVector(const CObjectVector &v) { *this = v; } + CObjectVector& operator=(const CObjectVector &v) + { + Clear(); + return (*this += v); + } + CObjectVector& operator+=(const CObjectVector &v) + { + int size = v.Size(); + Reserve(Size() + size); + for (int i = 0; i < size; i++) + Add(v[i]); + return *this; + } + const T& operator[](int index) const + { + return *((T *)CPointerVector::operator[](index)); + } + T& operator[](int index) + { + return *((T *)CPointerVector::operator[](index)); + } + T& Front() { return operator[](0); } + const T& Front() const { return operator[](0); } + T& Back() { return operator[](_size - 1); } + const T& Back() const { return operator[](_size - 1); } + int Add(const T& item) { return CPointerVector::Add(new T(item)); } + void Insert(int index, const T& item) { CPointerVector::Insert(index, new T(item)); } + virtual void Delete(int index, int num = 1) + { + TestIndexAndCorrectNum(index, num); + for (int i = 0; i < num; i++) + delete (T *)(((void **)_items)[index + i]); + CPointerVector::Delete(index, num); + } + int Find(const T& item) const + { + for (int i = 0; i < Size(); i++) + if (item == (*this)[i]) + return i; + return -1; + } + int FindInSorted(const T& item) const + { + int left = 0, right = Size(); + while (left != right) + { + int mid = (left + right) / 2; + const T& midValue = (*this)[mid]; + if (item == midValue) + return mid; + if (item < midValue) + right = mid; + else + left = mid + 1; + } + return -1; + } + int AddToSorted(const T& item) + { + int left = 0, right = Size(); + while (left != right) + { + int mid = (left + right) / 2; + const T& midValue = (*this)[mid]; + if (item == midValue) + { + right = mid + 1; + break; + } + if (item < midValue) + right = mid; + else + left = mid + 1; + } + Insert(right, item); + return right; + } + + void Sort(int (*compare)(void *const *, void *const *, void *), void *param) + { CPointerVector::Sort(compare, param); } + + static int CompareObjectItems(void *const *a1, void *const *a2, void * /* param */) + { return MyCompare(*(*((const T **)a1)), *(*((const T **)a2))); } + void Sort() { CPointerVector::Sort(CompareObjectItems, 0); } +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/Common/MyWindows.h b/desmume/src/windows/7z/CPP/Common/MyWindows.h new file mode 100644 index 000000000..0329ff709 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/MyWindows.h @@ -0,0 +1,214 @@ +// MyWindows.h + +#ifndef __MYWINDOWS_H +#define __MYWINDOWS_H + +#ifdef _WIN32 + +#include + +#define CHAR_PATH_SEPARATOR '\\' +#define WCHAR_PATH_SEPARATOR L'\\' +#define STRING_PATH_SEPARATOR "\\" +#define WSTRING_PATH_SEPARATOR L"\\" + +#else + +#define CHAR_PATH_SEPARATOR '/' +#define WCHAR_PATH_SEPARATOR L'/' +#define STRING_PATH_SEPARATOR "/" +#define WSTRING_PATH_SEPARATOR L"/" + +#include // for wchar_t +#include + +#include "MyGuidDef.h" + +typedef char CHAR; +typedef unsigned char UCHAR; + +#undef BYTE +typedef unsigned char BYTE; + +typedef short SHORT; +typedef unsigned short USHORT; + +#undef WORD +typedef unsigned short WORD; +typedef short VARIANT_BOOL; + +typedef int INT; +typedef Int32 INT32; +typedef unsigned int UINT; +typedef UInt32 UINT32; +typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit +typedef UINT32 ULONG; + +#undef DWORD +typedef UINT32 DWORD; + +typedef Int64 LONGLONG; +typedef UInt64 ULONGLONG; + +typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER; +typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER; + +typedef const CHAR *LPCSTR; +typedef CHAR TCHAR; +typedef const TCHAR *LPCTSTR; +typedef wchar_t WCHAR; +typedef WCHAR OLECHAR; +typedef const WCHAR *LPCWSTR; +typedef OLECHAR *BSTR; +typedef const OLECHAR *LPCOLESTR; +typedef OLECHAR *LPOLESTR; + +typedef struct _FILETIME +{ + DWORD dwLowDateTime; + DWORD dwHighDateTime; +}FILETIME; + +#define HRESULT LONG +#define FAILED(Status) ((HRESULT)(Status)<0) +typedef ULONG PROPID; +typedef LONG SCODE; + +#define S_OK ((HRESULT)0x00000000L) +#define S_FALSE ((HRESULT)0x00000001L) +#define E_NOTIMPL ((HRESULT)0x80004001L) +#define E_NOINTERFACE ((HRESULT)0x80004002L) +#define E_ABORT ((HRESULT)0x80004004L) +#define E_FAIL ((HRESULT)0x80004005L) +#define STG_E_INVALIDFUNCTION ((HRESULT)0x80030001L) +#define E_OUTOFMEMORY ((HRESULT)0x8007000EL) +#define E_INVALIDARG ((HRESULT)0x80070057L) + +#ifdef _MSC_VER +#define STDMETHODCALLTYPE __stdcall +#else +#define STDMETHODCALLTYPE +#endif + +#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f +#define STDMETHOD(f) STDMETHOD_(HRESULT, f) +#define STDMETHODIMP_(type) type STDMETHODCALLTYPE +#define STDMETHODIMP STDMETHODIMP_(HRESULT) + +#define PURE = 0 + +#define MIDL_INTERFACE(x) struct + +#ifdef __cplusplus + +DEFINE_GUID(IID_IUnknown, +0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); +struct IUnknown +{ + STDMETHOD(QueryInterface) (REFIID iid, void **outObject) PURE; + STDMETHOD_(ULONG, AddRef)() PURE; + STDMETHOD_(ULONG, Release)() PURE; + #ifndef _WIN32 + virtual ~IUnknown() {} + #endif +}; + +typedef IUnknown *LPUNKNOWN; + +#endif + +#define VARIANT_TRUE ((VARIANT_BOOL)-1) +#define VARIANT_FALSE ((VARIANT_BOOL)0) + +enum VARENUM +{ + VT_EMPTY = 0, + VT_NULL = 1, + VT_I2 = 2, + VT_I4 = 3, + VT_R4 = 4, + VT_R8 = 5, + VT_CY = 6, + VT_DATE = 7, + VT_BSTR = 8, + VT_DISPATCH = 9, + VT_ERROR = 10, + VT_BOOL = 11, + VT_VARIANT = 12, + VT_UNKNOWN = 13, + VT_DECIMAL = 14, + VT_I1 = 16, + VT_UI1 = 17, + VT_UI2 = 18, + VT_UI4 = 19, + VT_I8 = 20, + VT_UI8 = 21, + VT_INT = 22, + VT_UINT = 23, + VT_VOID = 24, + VT_HRESULT = 25, + VT_FILETIME = 64 +}; + +typedef unsigned short VARTYPE; +typedef WORD PROPVAR_PAD1; +typedef WORD PROPVAR_PAD2; +typedef WORD PROPVAR_PAD3; + +#ifdef __cplusplus + +typedef struct tagPROPVARIANT +{ + VARTYPE vt; + PROPVAR_PAD1 wReserved1; + PROPVAR_PAD2 wReserved2; + PROPVAR_PAD3 wReserved3; + union + { + CHAR cVal; + UCHAR bVal; + SHORT iVal; + USHORT uiVal; + LONG lVal; + ULONG ulVal; + INT intVal; + UINT uintVal; + LARGE_INTEGER hVal; + ULARGE_INTEGER uhVal; + VARIANT_BOOL boolVal; + SCODE scode; + FILETIME filetime; + BSTR bstrVal; + }; +} PROPVARIANT; + +typedef PROPVARIANT tagVARIANT; +typedef tagVARIANT VARIANT; +typedef VARIANT VARIANTARG; + +MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop); +MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src); + +#endif + +MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len); +MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz); +MY_EXTERN_C void SysFreeString(BSTR bstr); +MY_EXTERN_C UINT SysStringByteLen(BSTR bstr); +MY_EXTERN_C UINT SysStringLen(BSTR bstr); + +MY_EXTERN_C DWORD GetLastError(); +MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2); + +#define CP_ACP 0 +#define CP_OEMCP 1 + +typedef enum tagSTREAM_SEEK +{ + STREAM_SEEK_SET = 0, + STREAM_SEEK_CUR = 1, + STREAM_SEEK_END = 2 +} STREAM_SEEK; + +#endif +#endif diff --git a/desmume/src/windows/7z/CPP/Common/MyXml.cpp b/desmume/src/windows/7z/CPP/Common/MyXml.cpp new file mode 100644 index 000000000..c18570e93 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/MyXml.cpp @@ -0,0 +1,209 @@ +// MyXml.cpp + +#include "StdAfx.h" + +#include "MyXml.h" + +static bool IsValidChar(char c) +{ + return + c >= 'a' && c <= 'z' || + c >= 'A' && c <= 'Z' || + c >= '0' && c <= '9' || + c == '-'; +} + +static bool IsSpaceChar(char c) +{ + return (c == ' ' || c == '\t' || c == 0x0D || c == 0x0A); +} + +#define SKEEP_SPACES(s, pos) while (IsSpaceChar(s[pos])) pos++; + +static bool ReadProperty(const AString &s, int &pos, CXmlProp &prop) +{ + prop.Name.Empty(); + prop.Value.Empty(); + for (; pos < s.Length(); pos++) + { + char c = s[pos]; + if (!IsValidChar(c)) + break; + prop.Name += c; + } + + if (prop.Name.IsEmpty()) + return false; + + SKEEP_SPACES(s, pos); + if (s[pos++] != '=') + return false; + + SKEEP_SPACES(s, pos); + if (s[pos++] != '\"') + return false; + + while (pos < s.Length()) + { + char c = s[pos++]; + if (c == '\"') + return true; + prop.Value += c; + } + return false; +} + +int CXmlItem::FindProperty(const AString &propName) const +{ + for (int i = 0; i < Props.Size(); i++) + if (Props[i].Name == propName) + return i; + return -1; +} + +AString CXmlItem::GetPropertyValue(const AString &propName) const +{ + int index = FindProperty(propName); + if (index >= 0) + return Props[index].Value; + return AString(); +} + +bool CXmlItem::IsTagged(const AString &tag) const +{ + return (IsTag && Name == tag); +} + +int CXmlItem::FindSubTag(const AString &tag) const +{ + for (int i = 0; i < SubItems.Size(); i++) + if (SubItems[i].IsTagged(tag)) + return i; + return -1; +} + +AString CXmlItem::GetSubString() const +{ + if (SubItems.Size() == 1) + { + const CXmlItem &item = SubItems[0]; + if (!item.IsTag) + return item.Name; + } + return AString(); +} + +AString CXmlItem::GetSubStringForTag(const AString &tag) const +{ + int index = FindSubTag(tag); + if (index >= 0) + return SubItems[index].GetSubString(); + return AString(); +} + +bool CXmlItem::ParseItems(const AString &s, int &pos, int numAllowedLevels) +{ + if (numAllowedLevels == 0) + return false; + SubItems.Clear(); + AString finishString = "'); + } + if (s[pos] == '>') + { + if (!ParseItems(s, ++pos, numAllowedLevels)) + return false; + AString finishString = AString(""); + if (s.Mid(pos, finishString.Length()) != finishString) + return false; + pos += finishString.Length(); + return true; + } + if (posTemp == pos) + return false; + + CXmlProp prop; + if (!ReadProperty(s, pos, prop)) + return false; + Props.Add(prop); + posTemp = pos; + } +} + +bool SkeepHeader(const AString &s, int &pos, const AString &startString, const AString &endString) +{ + SKEEP_SPACES(s, pos); + if (s.Mid(pos, startString.Length()) == startString) + { + pos = s.Find(endString, pos); + if (pos < 0) + return false; + pos += endString.Length(); + SKEEP_SPACES(s, pos); + } + return true; +} + +bool CXml::Parse(const AString &s) +{ + int pos = 0; + if (!SkeepHeader(s, pos, "")) + return false; + if (!SkeepHeader(s, pos, "")) + return false; + if (!Root.ParseItem(s, pos, 1000)) + return false; + SKEEP_SPACES(s, pos); + return (pos == s.Length() && Root.IsTag); +} diff --git a/desmume/src/windows/7z/CPP/Common/MyXml.h b/desmume/src/windows/7z/CPP/Common/MyXml.h new file mode 100644 index 000000000..52e23d19c --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/MyXml.h @@ -0,0 +1,40 @@ +// MyXml.h + +#ifndef __MYXML_H +#define __MYXML_H + +#include "MyString.h" + +struct CXmlProp +{ + AString Name; + AString Value; +}; + +class CXmlItem +{ + bool ParseItems(const AString &s, int &pos, int numAllowedLevels); + +public: + AString Name; + bool IsTag; + CObjectVector Props; + CObjectVector SubItems; + + bool ParseItem(const AString &s, int &pos, int numAllowedLevels); + + bool IsTagged(const AString &tag) const; + int FindProperty(const AString &propName) const; + AString GetPropertyValue(const AString &propName) const; + AString GetSubString() const; + int FindSubTag(const AString &tag) const; + AString GetSubStringForTag(const AString &tag) const; +}; + +struct CXml +{ + CXmlItem Root; + bool Parse(const AString &s); +}; + +#endif diff --git a/desmume/src/windows/7z/CPP/Common/NewHandler.cpp b/desmume/src/windows/7z/CPP/Common/NewHandler.cpp new file mode 100644 index 000000000..611bbd8f5 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/NewHandler.cpp @@ -0,0 +1,116 @@ +// NewHandler.cpp + +#include "StdAfx.h" + +#include + +#include "NewHandler.h" + +// #define DEBUG_MEMORY_LEAK + +#ifndef DEBUG_MEMORY_LEAK + +#ifdef _WIN32 +void * +#ifdef _MSC_VER +__cdecl +#endif +operator new(size_t size) +{ + // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size); + void *p = ::malloc(size); + if (p == 0) + throw CNewException(); + return p; +} + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p) throw() +{ + /* + if (p == 0) + return; + ::HeapFree(::GetProcessHeap(), 0, p); + */ + ::free(p); +} +#endif + +#else + +#pragma init_seg(lib) +const int kDebugSize = 1000000; +static void *a[kDebugSize]; +static int index = 0; + +static int numAllocs = 0; +void * __cdecl operator new(size_t size) +{ + numAllocs++; + void *p = HeapAlloc(GetProcessHeap(), 0, size); + if (index == 40) + { + int t = 1; + } + if (index < kDebugSize) + { + a[index] = p; + index++; + } + if (p == 0) + throw CNewException(); + printf("Alloc %6d, size = %8d\n", numAllocs, size); + return p; +} + +class CC +{ +public: + CC() + { + for (int i = 0; i < kDebugSize; i++) + a[i] = 0; + } + ~CC() + { + for (int i = 0; i < kDebugSize; i++) + if (a[i] != 0) + return; + } +} g_CC; + + +void __cdecl operator delete(void *p) +{ + if (p == 0) + return; + /* + for (int i = 0; i < index; i++) + if (a[i] == p) + a[i] = 0; + */ + HeapFree(GetProcessHeap(), 0, p); + numAllocs--; + printf("Free %d\n", numAllocs); +} + +#endif + +/* +int MemErrorVC(size_t) +{ + throw CNewException(); + // return 1; +} +CNewHandlerSetter::CNewHandlerSetter() +{ + // MemErrorOldVCFunction = _set_new_handler(MemErrorVC); +} +CNewHandlerSetter::~CNewHandlerSetter() +{ + // _set_new_handler(MemErrorOldVCFunction); +} +*/ diff --git a/desmume/src/windows/7z/CPP/Common/NewHandler.h b/desmume/src/windows/7z/CPP/Common/NewHandler.h new file mode 100644 index 000000000..6f710cda1 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/NewHandler.h @@ -0,0 +1,16 @@ +// Common/NewHandler.h + +#ifndef __COMMON_NEWHANDLER_H +#define __COMMON_NEWHANDLER_H + +class CNewException {}; + +#ifdef _WIN32 +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p) throw(); +#endif + +#endif diff --git a/desmume/src/windows/7z/CPP/Common/StringConvert.cpp b/desmume/src/windows/7z/CPP/Common/StringConvert.cpp new file mode 100644 index 000000000..ebd014831 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/StringConvert.cpp @@ -0,0 +1,102 @@ +// Common/StringConvert.cpp + +#include "StdAfx.h" + +#include "StringConvert.h" + +#ifndef _WIN32 +#include +#endif + +#ifdef _WIN32 +UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) +{ + UString resultString; + if (!srcString.IsEmpty()) + { + int numChars = MultiByteToWideChar(codePage, 0, srcString, + srcString.Length(), resultString.GetBuffer(srcString.Length()), + srcString.Length() + 1); + #ifndef _WIN32_WCE + if (numChars == 0) + throw 282228; + #endif + resultString.ReleaseBuffer(numChars); + } + return resultString; +} + +AString UnicodeStringToMultiByte(const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed) +{ + AString dest; + defaultCharWasUsed = false; + if (!s.IsEmpty()) + { + int numRequiredBytes = s.Length() * 2; + BOOL defUsed; + int numChars = WideCharToMultiByte(codePage, 0, s, s.Length(), + dest.GetBuffer(numRequiredBytes), numRequiredBytes + 1, + &defaultChar, &defUsed); + defaultCharWasUsed = (defUsed != FALSE); + #ifndef _WIN32_WCE + if (numChars == 0) + throw 282229; + #endif + dest.ReleaseBuffer(numChars); + } + return dest; +} + +AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage) +{ + bool defaultCharWasUsed; + return UnicodeStringToMultiByte(srcString, codePage, '_', defaultCharWasUsed); +} + +#ifndef _WIN32_WCE +AString SystemStringToOemString(const CSysString &srcString) +{ + AString result; + CharToOem(srcString, result.GetBuffer(srcString.Length() * 2)); + result.ReleaseBuffer(); + return result; +} +#endif + +#else + +UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) +{ + UString resultString; + for (int i = 0; i < srcString.Length(); i++) + resultString += wchar_t(srcString[i]); + /* + if (!srcString.IsEmpty()) + { + int numChars = mbstowcs(resultString.GetBuffer(srcString.Length()), srcString, srcString.Length() + 1); + if (numChars < 0) throw "Your environment does not support UNICODE"; + resultString.ReleaseBuffer(numChars); + } + */ + return resultString; +} + +AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage) +{ + AString resultString; + for (int i = 0; i < srcString.Length(); i++) + resultString += char(srcString[i]); + /* + if (!srcString.IsEmpty()) + { + int numRequiredBytes = srcString.Length() * 6 + 1; + int numChars = wcstombs(resultString.GetBuffer(numRequiredBytes), srcString, numRequiredBytes); + if (numChars < 0) throw "Your environment does not support UNICODE"; + resultString.ReleaseBuffer(numChars); + } + */ + return resultString; +} + +#endif + diff --git a/desmume/src/windows/7z/CPP/Common/StringConvert.h b/desmume/src/windows/7z/CPP/Common/StringConvert.h new file mode 100644 index 000000000..e0a2332c9 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/StringConvert.h @@ -0,0 +1,73 @@ +// Common/StringConvert.h + +#ifndef __COMMON_STRINGCONVERT_H +#define __COMMON_STRINGCONVERT_H + +#include "MyWindows.h" +#include "MyString.h" +#include "Types.h" + +UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP); +AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage, char defaultChar, bool &defaultCharWasUsed); +AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage = CP_ACP); + + +inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString) + { return unicodeString; } +inline const UString& GetUnicodeString(const UString &unicodeString) + { return unicodeString; } +inline UString GetUnicodeString(const AString &ansiString) + { return MultiByteToUnicodeString(ansiString); } +inline UString GetUnicodeString(const AString &multiByteString, UINT codePage) + { return MultiByteToUnicodeString(multiByteString, codePage); } +inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString, UINT) + { return unicodeString; } +inline const UString& GetUnicodeString(const UString &unicodeString, UINT) + { return unicodeString; } + +inline const char* GetAnsiString(const char* ansiString) + { return ansiString; } +inline const AString& GetAnsiString(const AString &ansiString) + { return ansiString; } +inline AString GetAnsiString(const UString &unicodeString) + { return UnicodeStringToMultiByte(unicodeString); } + +inline const char* GetOemString(const char* oemString) + { return oemString; } +inline const AString& GetOemString(const AString &oemString) + { return oemString; } +inline AString GetOemString(const UString &unicodeString) + { return UnicodeStringToMultiByte(unicodeString, CP_OEMCP); } + + +#ifdef _UNICODE + inline const wchar_t* GetSystemString(const wchar_t* unicodeString) + { return unicodeString;} + inline const UString& GetSystemString(const UString &unicodeString) + { return unicodeString;} + inline const wchar_t* GetSystemString(const wchar_t* unicodeString, UINT /* codePage */) + { return unicodeString;} + inline const UString& GetSystemString(const UString &unicodeString, UINT /* codePage */) + { return unicodeString;} + inline UString GetSystemString(const AString &multiByteString, UINT codePage) + { return MultiByteToUnicodeString(multiByteString, codePage);} + inline UString GetSystemString(const AString &multiByteString) + { return MultiByteToUnicodeString(multiByteString);} +#else + inline const char* GetSystemString(const char *ansiString) + { return ansiString; } + inline const AString& GetSystemString(const AString &multiByteString, UINT) + { return multiByteString; } + inline const char * GetSystemString(const char *multiByteString, UINT) + { return multiByteString; } + inline AString GetSystemString(const UString &unicodeString) + { return UnicodeStringToMultiByte(unicodeString); } + inline AString GetSystemString(const UString &unicodeString, UINT codePage) + { return UnicodeStringToMultiByte(unicodeString, codePage); } +#endif + +#ifndef _WIN32_WCE +AString SystemStringToOemString(const CSysString &srcString); +#endif + +#endif diff --git a/desmume/src/windows/7z/CPP/Common/StringToInt.cpp b/desmume/src/windows/7z/CPP/Common/StringToInt.cpp new file mode 100644 index 000000000..77ce7c50b --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/StringToInt.cpp @@ -0,0 +1,90 @@ +// Common/StringToInt.cpp + +#include "StdAfx.h" + +#include "StringToInt.h" + +UInt64 ConvertStringToUInt64(const char *s, const char **end) +{ + UInt64 result = 0; + for (;;) + { + char c = *s; + if (c < '0' || c > '9') + { + if (end != NULL) + *end = s; + return result; + } + result *= 10; + result += (c - '0'); + s++; + } +} + +UInt64 ConvertOctStringToUInt64(const char *s, const char **end) +{ + UInt64 result = 0; + for (;;) + { + char c = *s; + if (c < '0' || c > '7') + { + if (end != NULL) + *end = s; + return result; + } + result <<= 3; + result += (c - '0'); + s++; + } +} + +UInt64 ConvertHexStringToUInt64(const char *s, const char **end) +{ + UInt64 result = 0; + for (;;) + { + char c = *s; + UInt32 v; + if (c >= '0' && c <= '9') v = (c - '0'); + else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A'); + else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a'); + else + { + if (end != NULL) + *end = s; + return result; + } + result <<= 4; + result |= v; + s++; + } +} + + +UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end) +{ + UInt64 result = 0; + for (;;) + { + wchar_t c = *s; + if (c < '0' || c > '9') + { + if (end != NULL) + *end = s; + return result; + } + result *= 10; + result += (c - '0'); + s++; + } +} + + +Int64 ConvertStringToInt64(const char *s, const char **end) +{ + if (*s == '-') + return -(Int64)ConvertStringToUInt64(s + 1, end); + return ConvertStringToUInt64(s, end); +} diff --git a/desmume/src/windows/7z/CPP/Common/StringToInt.h b/desmume/src/windows/7z/CPP/Common/StringToInt.h new file mode 100644 index 000000000..16a1a4fc8 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/StringToInt.h @@ -0,0 +1,18 @@ +// Common/StringToInt.h + +#ifndef __COMMON_STRINGTOINT_H +#define __COMMON_STRINGTOINT_H + +#include +#include "Types.h" + +UInt64 ConvertStringToUInt64(const char *s, const char **end); +UInt64 ConvertOctStringToUInt64(const char *s, const char **end); +UInt64 ConvertHexStringToUInt64(const char *s, const char **end); +UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end); + +Int64 ConvertStringToInt64(const char *s, const char **end); + +#endif + + diff --git a/desmume/src/windows/7z/CPP/Common/Types.h b/desmume/src/windows/7z/CPP/Common/Types.h new file mode 100644 index 000000000..ba696772d --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/Types.h @@ -0,0 +1,14 @@ +// Common/Types.h + +#ifndef __COMMON_TYPES_H +#define __COMMON_TYPES_H + +extern "C" +{ +#include "../../C/Types.h" +} + +typedef int HRes; + +#endif + diff --git a/desmume/src/windows/7z/CPP/Common/UTFConvert.cpp b/desmume/src/windows/7z/CPP/Common/UTFConvert.cpp new file mode 100644 index 000000000..dae8f551b --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/UTFConvert.cpp @@ -0,0 +1,145 @@ +// UTFConvert.cpp + +#include "StdAfx.h" + +#include "UTFConvert.h" +#include "Types.h" + +static const Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + +static Bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, size_t srcLen) +{ + size_t destPos = 0, srcPos = 0; + for (;;) + { + Byte c; + int numAdds; + if (srcPos == srcLen) + { + *destLen = destPos; + return True; + } + c = (Byte)src[srcPos++]; + + if (c < 0x80) + { + if (dest) + dest[destPos] = (wchar_t)c; + destPos++; + continue; + } + if (c < 0xC0) + break; + for (numAdds = 1; numAdds < 5; numAdds++) + if (c < kUtf8Limits[numAdds]) + break; + UInt32 value = (c - kUtf8Limits[numAdds - 1]); + + do + { + Byte c2; + if (srcPos == srcLen) + break; + c2 = (Byte)src[srcPos++]; + if (c2 < 0x80 || c2 >= 0xC0) + break; + value <<= 6; + value |= (c2 - 0x80); + } + while (--numAdds != 0); + + if (value < 0x10000) + { + if (dest) + dest[destPos] = (wchar_t)value; + destPos++; + } + else + { + value -= 0x10000; + if (value >= 0x100000) + break; + if (dest) + { + dest[destPos + 0] = (wchar_t)(0xD800 + (value >> 10)); + dest[destPos + 1] = (wchar_t)(0xDC00 + (value & 0x3FF)); + } + destPos += 2; + } + } + *destLen = destPos; + return False; +} + +static Bool Utf16_To_Utf8(char *dest, size_t *destLen, const wchar_t *src, size_t srcLen) +{ + size_t destPos = 0, srcPos = 0; + for (;;) + { + unsigned numAdds; + UInt32 value; + if (srcPos == srcLen) + { + *destLen = destPos; + return True; + } + value = src[srcPos++]; + if (value < 0x80) + { + if (dest) + dest[destPos] = (char)value; + destPos++; + continue; + } + if (value >= 0xD800 && value < 0xE000) + { + UInt32 c2; + if (value >= 0xDC00 || srcPos == srcLen) + break; + c2 = src[srcPos++]; + if (c2 < 0xDC00 || c2 >= 0xE000) + break; + value = ((value - 0xD800) << 10) | (c2 - 0xDC00); + } + for (numAdds = 1; numAdds < 5; numAdds++) + if (value < (((UInt32)1) << (numAdds * 5 + 6))) + break; + if (dest) + dest[destPos] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds))); + destPos++; + do + { + numAdds--; + if (dest) + dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); + destPos++; + } + while (numAdds != 0); + } + *destLen = destPos; + return False; +} + +bool ConvertUTF8ToUnicode(const AString &src, UString &dest) +{ + dest.Empty(); + size_t destLen = 0; + Utf8_To_Utf16(NULL, &destLen, src, src.Length()); + wchar_t *p = dest.GetBuffer((int)destLen); + Bool res = Utf8_To_Utf16(p, &destLen, src, src.Length()); + p[destLen] = 0; + dest.ReleaseBuffer(); + return res ? true : false; +} + +bool ConvertUnicodeToUTF8(const UString &src, AString &dest) +{ + dest.Empty(); + size_t destLen = 0; + Utf16_To_Utf8(NULL, &destLen, src, src.Length()); + char *p = dest.GetBuffer((int)destLen); + Bool res = Utf16_To_Utf8(p, &destLen, src, src.Length()); + p[destLen] = 0; + dest.ReleaseBuffer(); + return res ? true : false; +} diff --git a/desmume/src/windows/7z/CPP/Common/UTFConvert.h b/desmume/src/windows/7z/CPP/Common/UTFConvert.h new file mode 100644 index 000000000..d55310144 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/UTFConvert.h @@ -0,0 +1,11 @@ +// Common/UTFConvert.h + +#ifndef __COMMON_UTFCONVERT_H +#define __COMMON_UTFCONVERT_H + +#include "MyString.h" + +bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString); +bool ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString); + +#endif diff --git a/desmume/src/windows/7z/CPP/Common/Wildcard.cpp b/desmume/src/windows/7z/CPP/Common/Wildcard.cpp new file mode 100644 index 000000000..b4a86cadb --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/Wildcard.cpp @@ -0,0 +1,458 @@ +// Common/Wildcard.cpp + +#include "StdAfx.h" + +#include "Wildcard.h" + +bool g_CaseSensitive = + #ifdef _WIN32 + false; + #else + true; + #endif + +static const wchar_t kAnyCharsChar = L'*'; +static const wchar_t kAnyCharChar = L'?'; + +#ifdef _WIN32 +static const wchar_t kDirDelimiter1 = L'\\'; +#endif +static const wchar_t kDirDelimiter2 = L'/'; + +static const UString kWildCardCharSet = L"?*"; + +static const UString kIllegalWildCardFileNameChars= + L"\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA\xB\xC\xD\xE\xF" + L"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" + L"\"/:<>\\|"; + + +static inline bool IsCharDirLimiter(wchar_t c) +{ + return ( + #ifdef _WIN32 + c == kDirDelimiter1 || + #endif + c == kDirDelimiter2); +} + +int CompareFileNames(const UString &s1, const UString &s2) +{ + if (g_CaseSensitive) + return s1.Compare(s2); + return s1.CompareNoCase(s2); +} + +// ----------------------------------------- +// this function compares name with mask +// ? - any char +// * - any char or empty + +static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name) +{ + for (;;) + { + wchar_t m = *mask; + wchar_t c = *name; + if (m == 0) + return (c == 0); + if (m == kAnyCharsChar) + { + if (EnhancedMaskTest(mask + 1, name)) + return true; + if (c == 0) + return false; + } + else + { + if (m == kAnyCharChar) + { + if (c == 0) + return false; + } + else if (m != c) + if (g_CaseSensitive || MyCharUpper(m) != MyCharUpper(c)) + return false; + mask++; + } + name++; + } +} + +// -------------------------------------------------- +// Splits path to strings + +void SplitPathToParts(const UString &path, UStringVector &pathParts) +{ + pathParts.Clear(); + UString name; + int len = path.Length(); + if (len == 0) + return; + for (int i = 0; i < len; i++) + { + wchar_t c = path[i]; + if (IsCharDirLimiter(c)) + { + pathParts.Add(name); + name.Empty(); + } + else + name += c; + } + pathParts.Add(name); +} + +void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name) +{ + int i; + for (i = path.Length() - 1; i >= 0; i--) + if (IsCharDirLimiter(path[i])) + break; + dirPrefix = path.Left(i + 1); + name = path.Mid(i + 1); +} + +UString ExtractDirPrefixFromPath(const UString &path) +{ + int i; + for (i = path.Length() - 1; i >= 0; i--) + if (IsCharDirLimiter(path[i])) + break; + return path.Left(i + 1); +} + +UString ExtractFileNameFromPath(const UString &path) +{ + int i; + for (i = path.Length() - 1; i >= 0; i--) + if (IsCharDirLimiter(path[i])) + break; + return path.Mid(i + 1); +} + + +bool CompareWildCardWithName(const UString &mask, const UString &name) +{ + return EnhancedMaskTest(mask, name); +} + +bool DoesNameContainWildCard(const UString &path) +{ + return (path.FindOneOf(kWildCardCharSet) >= 0); +} + + +// ----------------------------------------------------------' +// NWildcard + +namespace NWildcard { + + +/* +M = MaskParts.Size(); +N = TestNameParts.Size(); + + File Dir +ForFile req M<=N [N-M, N) - + nonreq M=N [0, M) - + +ForDir req M 1) + return true; + } + return false; +} + +bool CCensorNode::AreThereIncludeItems() const +{ + if (IncludeItems.Size() > 0) + return true; + for (int i = 0; i < SubNodes.Size(); i++) + if (SubNodes[i].AreThereIncludeItems()) + return true; + return false; +} + +bool CCensorNode::CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const +{ + const CObjectVector &items = include ? IncludeItems : ExcludeItems; + for (int i = 0; i < items.Size(); i++) + if (items[i].CheckPath(pathParts, isFile)) + return true; + return false; +} + +bool CCensorNode::CheckPath(UStringVector &pathParts, bool isFile, bool &include) const +{ + if (CheckPathCurrent(false, pathParts, isFile)) + { + include = false; + return true; + } + include = true; + bool finded = CheckPathCurrent(true, pathParts, isFile); + if (pathParts.Size() == 1) + return finded; + int index = FindSubNode(pathParts.Front()); + if (index >= 0) + { + UStringVector pathParts2 = pathParts; + pathParts2.Delete(0); + if (SubNodes[index].CheckPath(pathParts2, isFile, include)) + return true; + } + return finded; +} + +bool CCensorNode::CheckPath(const UString &path, bool isFile, bool &include) const +{ + UStringVector pathParts; + SplitPathToParts(path, pathParts); + return CheckPath(pathParts, isFile, include); +} + +bool CCensorNode::CheckPath(const UString &path, bool isFile) const +{ + bool include; + if (CheckPath(path, isFile, include)) + return include; + return false; +} + +bool CCensorNode::CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const +{ + if (CheckPathCurrent(include, pathParts, isFile)) + return true; + if (Parent == 0) + return false; + pathParts.Insert(0, Name); + return Parent->CheckPathToRoot(include, pathParts, isFile); +} + +/* +bool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool isFile) const +{ + UStringVector pathParts; + SplitPathToParts(path, pathParts); + return CheckPathToRoot(include, pathParts, isFile); +} +*/ + +void CCensorNode::AddItem2(bool include, const UString &path, bool recursive) +{ + if (path.IsEmpty()) + return; + bool forFile = true; + bool forFolder = true; + UString path2 = path; + if (IsCharDirLimiter(path[path.Length() - 1])) + { + path2.Delete(path.Length() - 1); + forFile = false; + } + AddItem(include, path2, recursive, forFile, forFolder); +} + +void CCensorNode::ExtendExclude(const CCensorNode &fromNodes) +{ + ExcludeItems += fromNodes.ExcludeItems; + for (int i = 0; i < fromNodes.SubNodes.Size(); i++) + { + const CCensorNode &node = fromNodes.SubNodes[i]; + int subNodeIndex = FindSubNode(node.Name); + if (subNodeIndex < 0) + subNodeIndex = SubNodes.Add(CCensorNode(node.Name, this)); + SubNodes[subNodeIndex].ExtendExclude(node); + } +} + +int CCensor::FindPrefix(const UString &prefix) const +{ + for (int i = 0; i < Pairs.Size(); i++) + if (CompareFileNames(Pairs[i].Prefix, prefix) == 0) + return i; + return -1; +} + +void CCensor::AddItem(bool include, const UString &path, bool recursive) +{ + UStringVector pathParts; + SplitPathToParts(path, pathParts); + bool forFile = true; + if (pathParts.Back().IsEmpty()) + { + forFile = false; + pathParts.DeleteBack(); + } + const UString &front = pathParts.Front(); + bool isAbs = false; + if (front.IsEmpty()) + isAbs = true; + else if (front.Length() == 2 && front[1] == L':') + isAbs = true; + else + { + for (int i = 0; i < pathParts.Size(); i++) + { + const UString &part = pathParts[i]; + if (part == L".." || part == L".") + { + isAbs = true; + break; + } + } + } + int numAbsParts = 0; + if (isAbs) + if (pathParts.Size() > 1) + numAbsParts = pathParts.Size() - 1; + else + numAbsParts = 1; + UString prefix; + for (int i = 0; i < numAbsParts; i++) + { + const UString &front = pathParts.Front(); + if (DoesNameContainWildCard(front)) + break; + prefix += front; + prefix += WCHAR_PATH_SEPARATOR; + pathParts.Delete(0); + } + int index = FindPrefix(prefix); + if (index < 0) + index = Pairs.Add(CPair(prefix)); + + CItem item; + item.PathParts = pathParts; + item.ForDir = true; + item.ForFile = forFile; + item.Recursive = recursive; + Pairs[index].Head.AddItem(include, item); +} + +bool CCensor::CheckPath(const UString &path, bool isFile) const +{ + bool finded = false; + for (int i = 0; i < Pairs.Size(); i++) + { + bool include; + if (Pairs[i].Head.CheckPath(path, isFile, include)) + { + if (!include) + return false; + finded = true; + } + } + return finded; +} + +void CCensor::ExtendExclude() +{ + int i; + for (i = 0; i < Pairs.Size(); i++) + if (Pairs[i].Prefix.IsEmpty()) + break; + if (i == Pairs.Size()) + return; + int index = i; + for (i = 0; i < Pairs.Size(); i++) + if (index != i) + Pairs[i].Head.ExtendExclude(Pairs[index].Head); +} + +} diff --git a/desmume/src/windows/7z/CPP/Common/Wildcard.h b/desmume/src/windows/7z/CPP/Common/Wildcard.h new file mode 100644 index 000000000..e2a42c831 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Common/Wildcard.h @@ -0,0 +1,80 @@ +// Common/Wildcard.h + +#ifndef __COMMON_WILDCARD_H +#define __COMMON_WILDCARD_H + +#include "MyString.h" + +int CompareFileNames(const UString &s1, const UString &s2); + +void SplitPathToParts(const UString &path, UStringVector &pathParts); +void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name); +UString ExtractDirPrefixFromPath(const UString &path); +UString ExtractFileNameFromPath(const UString &path); +bool DoesNameContainWildCard(const UString &path); +bool CompareWildCardWithName(const UString &mask, const UString &name); + +namespace NWildcard { + +struct CItem +{ + UStringVector PathParts; + bool Recursive; + bool ForFile; + bool ForDir; + bool CheckPath(const UStringVector &pathParts, bool isFile) const; +}; + +class CCensorNode +{ + CCensorNode *Parent; + bool CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const; + void AddItemSimple(bool include, CItem &item); + bool CheckPath(UStringVector &pathParts, bool isFile, bool &include) const; +public: + CCensorNode(): Parent(0) { }; + CCensorNode(const UString &name, CCensorNode *parent): Name(name), Parent(parent) { }; + UString Name; + CObjectVector SubNodes; + CObjectVector IncludeItems; + CObjectVector ExcludeItems; + + int FindSubNode(const UString &path) const; + + void AddItem(bool include, CItem &item); + void AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir); + void AddItem2(bool include, const UString &path, bool recursive); + + bool NeedCheckSubDirs() const; + bool AreThereIncludeItems() const; + + bool CheckPath(const UString &path, bool isFile, bool &include) const; + bool CheckPath(const UString &path, bool isFile) const; + + bool CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const; + // bool CheckPathToRoot(const UString &path, bool isFile, bool include) const; + void ExtendExclude(const CCensorNode &fromNodes); +}; + +struct CPair +{ + UString Prefix; + CCensorNode Head; + CPair(const UString &prefix): Prefix(prefix) { }; +}; + +class CCensor +{ + int FindPrefix(const UString &prefix) const; +public: + CObjectVector Pairs; + bool AllAreRelative() const + { return (Pairs.Size() == 1 && Pairs.Front().Prefix.IsEmpty()); } + void AddItem(bool include, const UString &path, bool recursive); + bool CheckPath(const UString &path, bool isFile) const; + void ExtendExclude(); +}; + +} + +#endif diff --git a/desmume/src/windows/7z/CPP/Windows/Defs.h b/desmume/src/windows/7z/CPP/Windows/Defs.h new file mode 100644 index 000000000..e8a655a4b --- /dev/null +++ b/desmume/src/windows/7z/CPP/Windows/Defs.h @@ -0,0 +1,23 @@ +// Windows/Defs.h + +#ifndef __WINDOWS_DEFS_H +#define __WINDOWS_DEFS_H + +inline bool BOOLToBool(BOOL value) + { return (value != FALSE); } + +#ifdef _WIN32 +inline bool LRESULTToBool(LRESULT value) + { return (value != FALSE); } +#endif + +inline BOOL BoolToBOOL(bool value) + { return (value ? TRUE: FALSE); } + +inline VARIANT_BOOL BoolToVARIANT_BOOL(bool value) + { return (value ? VARIANT_TRUE: VARIANT_FALSE); } + +inline bool VARIANT_BOOLToBool(VARIANT_BOOL value) + { return (value != VARIANT_FALSE); } + +#endif diff --git a/desmume/src/windows/7z/CPP/Windows/FileDir.cpp b/desmume/src/windows/7z/CPP/Windows/FileDir.cpp new file mode 100644 index 000000000..38eb1083c --- /dev/null +++ b/desmume/src/windows/7z/CPP/Windows/FileDir.cpp @@ -0,0 +1,841 @@ +// Windows/FileDir.cpp + +#include "StdAfx.h" + +#include "FileDir.h" +#include "FileName.h" +#include "FileFind.h" +#include "Defs.h" +#ifndef _UNICODE +#include "../Common/StringConvert.h" +#endif + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NFile { + +#if defined(WIN_LONG_PATH) && defined(_UNICODE) +#define WIN_LONG_PATH2 +#endif + +// SetCurrentDirectory doesn't support \\?\ prefix + +#ifdef WIN_LONG_PATH +bool GetLongPathBase(LPCWSTR fileName, UString &res); +bool GetLongPath(LPCWSTR fileName, UString &res); +#endif + +namespace NDirectory { + +#ifndef _UNICODE +static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } +static UString GetUnicodePath(const CSysString &sysPath) + { return MultiByteToUnicodeString(sysPath, GetCurrentCodePage()); } +static CSysString GetSysPath(LPCWSTR sysPath) + { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); } +#endif + +bool MyGetWindowsDirectory(CSysString &path) +{ + UINT needLength = ::GetWindowsDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1); + path.ReleaseBuffer(); + return (needLength > 0 && needLength <= MAX_PATH); +} + +bool MyGetSystemDirectory(CSysString &path) +{ + UINT needLength = ::GetSystemDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1); + path.ReleaseBuffer(); + return (needLength > 0 && needLength <= MAX_PATH); +} + +#ifndef _UNICODE +bool MyGetWindowsDirectory(UString &path) +{ + if (g_IsNT) + { + UINT needLength = ::GetWindowsDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1); + path.ReleaseBuffer(); + return (needLength > 0 && needLength <= MAX_PATH); + } + CSysString sysPath; + if (!MyGetWindowsDirectory(sysPath)) + return false; + path = GetUnicodePath(sysPath); + return true; +} + +bool MyGetSystemDirectory(UString &path) +{ + if (g_IsNT) + { + UINT needLength = ::GetSystemDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1); + path.ReleaseBuffer(); + return (needLength > 0 && needLength <= MAX_PATH); + } + CSysString sysPath; + if (!MyGetSystemDirectory(sysPath)) + return false; + path = GetUnicodePath(sysPath); + return true; +} +#endif + +bool SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return false; + } + #endif + HANDLE hDir = ::CreateFileW(fileName, GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + #ifdef WIN_LONG_PATH + if (hDir == INVALID_HANDLE_VALUE) + { + UString longPath; + if (GetLongPath(fileName, longPath)) + hDir = ::CreateFileW(longPath, GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + } + #endif + + bool res = false; + if (hDir != INVALID_HANDLE_VALUE) + { + res = BOOLToBool(::SetFileTime(hDir, cTime, aTime, mTime)); + ::CloseHandle(hDir); + } + return res; +} + +bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes) +{ + if (::SetFileAttributes(fileName, fileAttributes)) + return true; + #ifdef WIN_LONG_PATH2 + UString longPath; + if (GetLongPath(fileName, longPath)) + return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes)); + #endif + return false; +} + +bool MyRemoveDirectory(LPCTSTR pathName) +{ + if (::RemoveDirectory(pathName)) + return true; + #ifdef WIN_LONG_PATH2 + UString longPath; + if (GetLongPath(pathName, longPath)) + return BOOLToBool(::RemoveDirectoryW(longPath)); + #endif + return false; +} + +#ifdef WIN_LONG_PATH +bool GetLongPaths(LPCWSTR s1, LPCWSTR s2, UString &d1, UString &d2) +{ + if (!GetLongPathBase(s1, d1) || !GetLongPathBase(s2, d2)) + return false; + if (d1.IsEmpty() && d2.IsEmpty()) return false; + if (d1.IsEmpty()) d1 = s1; + if (d2.IsEmpty()) d2 = s2; + return true; +} +#endif + +bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName) +{ + if (::MoveFile(existFileName, newFileName)) + return true; + #ifdef WIN_LONG_PATH2 + UString d1, d2; + if (GetLongPaths(existFileName, newFileName, d1, d2)) + return BOOLToBool(::MoveFileW(d1, d2)); + #endif + return false; +} + +#ifndef _UNICODE +bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes) +{ + if (!g_IsNT) + return MySetFileAttributes(GetSysPath(fileName), fileAttributes); + if (::SetFileAttributesW(fileName, fileAttributes)) + return true; + #ifdef WIN_LONG_PATH + UString longPath; + if (GetLongPath(fileName, longPath)) + return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes)); + #endif + return false; +} + + +bool MyRemoveDirectory(LPCWSTR pathName) +{ + if (!g_IsNT) + return MyRemoveDirectory(GetSysPath(pathName)); + if (::RemoveDirectoryW(pathName)) + return true; + #ifdef WIN_LONG_PATH + UString longPath; + if (GetLongPath(pathName, longPath)) + return BOOLToBool(::RemoveDirectoryW(longPath)); + #endif + return false; +} + +bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName) +{ + if (!g_IsNT) + return MyMoveFile(GetSysPath(existFileName), GetSysPath(newFileName)); + if (::MoveFileW(existFileName, newFileName)) + return true; + #ifdef WIN_LONG_PATH + UString d1, d2; + if (GetLongPaths(existFileName, newFileName, d1, d2)) + return BOOLToBool(::MoveFileW(d1, d2)); + #endif + return false; +} +#endif + +bool MyCreateDirectory(LPCTSTR pathName) +{ + if (::CreateDirectory(pathName, NULL)) + return true; + #ifdef WIN_LONG_PATH2 + if (::GetLastError() != ERROR_ALREADY_EXISTS) + { + UString longPath; + if (GetLongPath(pathName, longPath)) + return BOOLToBool(::CreateDirectoryW(longPath, NULL)); + } + #endif + return false; +} + +#ifndef _UNICODE +bool MyCreateDirectory(LPCWSTR pathName) +{ + if (!g_IsNT) + return MyCreateDirectory(GetSysPath(pathName)); + if (::CreateDirectoryW(pathName, NULL)) + return true; + #ifdef WIN_LONG_PATH + if (::GetLastError() != ERROR_ALREADY_EXISTS) + { + UString longPath; + if (GetLongPath(pathName, longPath)) + return BOOLToBool(::CreateDirectoryW(longPath, NULL)); + } + #endif + return false; +} +#endif + +/* +bool CreateComplexDirectory(LPCTSTR pathName) +{ + NName::CParsedPath path; + path.ParsePath(pathName); + CSysString fullPath = path.Prefix; + DWORD errorCode = ERROR_SUCCESS; + for (int i = 0; i < path.PathParts.Size(); i++) + { + const CSysString &string = path.PathParts[i]; + if (string.IsEmpty()) + { + if (i != path.PathParts.Size() - 1) + return false; + return true; + } + fullPath += path.PathParts[i]; + if (!MyCreateDirectory(fullPath)) + { + DWORD errorCode = GetLastError(); + if (errorCode != ERROR_ALREADY_EXISTS) + return false; + } + fullPath += NName::kDirDelimiter; + } + return true; +} +*/ + +bool CreateComplexDirectory(LPCTSTR _aPathName) +{ + CSysString pathName = _aPathName; + int pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR)); + if (pos > 0 && pos == pathName.Length() - 1) + { + if (pathName.Length() == 3 && pathName[1] == ':') + return true; // Disk folder; + pathName.Delete(pos); + } + CSysString pathName2 = pathName; + pos = pathName.Length(); + for (;;) + { + if (MyCreateDirectory(pathName)) + break; + if (::GetLastError() == ERROR_ALREADY_EXISTS) + { + NFind::CFileInfo fileInfo; + if (!NFind::FindFile(pathName, fileInfo)) // For network folders + return true; + if (!fileInfo.IsDir()) + return false; + break; + } + pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR)); + if (pos < 0 || pos == 0) + return false; + if (pathName[pos - 1] == ':') + return false; + pathName = pathName.Left(pos); + } + pathName = pathName2; + while (pos < pathName.Length()) + { + pos = pathName.Find(TEXT(CHAR_PATH_SEPARATOR), pos + 1); + if (pos < 0) + pos = pathName.Length(); + if (!MyCreateDirectory(pathName.Left(pos))) + return false; + } + return true; +} + +#ifndef _UNICODE + +bool CreateComplexDirectory(LPCWSTR _aPathName) +{ + UString pathName = _aPathName; + int pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR); + if (pos > 0 && pos == pathName.Length() - 1) + { + if (pathName.Length() == 3 && pathName[1] == L':') + return true; // Disk folder; + pathName.Delete(pos); + } + UString pathName2 = pathName; + pos = pathName.Length(); + for (;;) + { + if (MyCreateDirectory(pathName)) + break; + if (::GetLastError() == ERROR_ALREADY_EXISTS) + { + NFind::CFileInfoW fileInfo; + if (!NFind::FindFile(pathName, fileInfo)) // For network folders + return true; + if (!fileInfo.IsDir()) + return false; + break; + } + pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR); + if (pos < 0 || pos == 0) + return false; + if (pathName[pos - 1] == L':') + return false; + pathName = pathName.Left(pos); + } + pathName = pathName2; + while (pos < pathName.Length()) + { + pos = pathName.Find(WCHAR_PATH_SEPARATOR, pos + 1); + if (pos < 0) + pos = pathName.Length(); + if (!MyCreateDirectory(pathName.Left(pos))) + return false; + } + return true; +} + +#endif + +bool DeleteFileAlways(LPCTSTR name) +{ + if (!MySetFileAttributes(name, 0)) + return false; + if (::DeleteFile(name)) + return true; + #ifdef WIN_LONG_PATH2 + UString longPath; + if (GetLongPath(name, longPath)) + return BOOLToBool(::DeleteFileW(longPath)); + #endif + return false; +} + +#ifndef _UNICODE +bool DeleteFileAlways(LPCWSTR name) +{ + if (!g_IsNT) + return DeleteFileAlways(GetSysPath(name)); + if (!MySetFileAttributes(name, 0)) + return false; + if (::DeleteFileW(name)) + return true; + #ifdef WIN_LONG_PATH + UString longPath; + if (GetLongPath(name, longPath)) + return BOOLToBool(::DeleteFileW(longPath)); + #endif + return false; +} +#endif + +static bool RemoveDirectorySubItems2(const CSysString pathPrefix, const NFind::CFileInfo &fileInfo) +{ + if (fileInfo.IsDir()) + return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name); + return DeleteFileAlways(pathPrefix + fileInfo.Name); +} + +bool RemoveDirectoryWithSubItems(const CSysString &path) +{ + NFind::CFileInfo fileInfo; + CSysString pathPrefix = path + NName::kDirDelimiter; + { + NFind::CEnumerator enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard)); + while (enumerator.Next(fileInfo)) + if (!RemoveDirectorySubItems2(pathPrefix, fileInfo)) + return false; + } + if (!MySetFileAttributes(path, 0)) + return false; + return MyRemoveDirectory(path); +} + +#ifndef _UNICODE +static bool RemoveDirectorySubItems2(const UString pathPrefix, const NFind::CFileInfoW &fileInfo) +{ + if (fileInfo.IsDir()) + return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name); + return DeleteFileAlways(pathPrefix + fileInfo.Name); +} +bool RemoveDirectoryWithSubItems(const UString &path) +{ + NFind::CFileInfoW fileInfo; + UString pathPrefix = path + UString(NName::kDirDelimiter); + { + NFind::CEnumeratorW enumerator(pathPrefix + UString(NName::kAnyStringWildcard)); + while (enumerator.Next(fileInfo)) + if (!RemoveDirectorySubItems2(pathPrefix, fileInfo)) + return false; + } + if (!MySetFileAttributes(path, 0)) + return false; + return MyRemoveDirectory(path); +} +#endif + +#ifndef _WIN32_WCE + +bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath) +{ + DWORD needLength = ::GetShortPathName(longPath, shortPath.GetBuffer(MAX_PATH + 1), MAX_PATH + 1); + shortPath.ReleaseBuffer(); + return (needLength > 0 && needLength < MAX_PATH); +} + +bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex) +{ + resultPath.Empty(); + LPTSTR fileNamePointer = 0; + LPTSTR buffer = resultPath.GetBuffer(MAX_PATH); + DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1, buffer, &fileNamePointer); + resultPath.ReleaseBuffer(); + if (needLength == 0) + return false; + if (needLength >= MAX_PATH) + { + #ifdef WIN_LONG_PATH2 + needLength++; + buffer = resultPath.GetBuffer(needLength + 1); + DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer); + resultPath.ReleaseBuffer(); + if (needLength2 == 0 || needLength2 > needLength) + #endif + return false; + } + if (fileNamePointer == 0) + fileNamePartStartIndex = lstrlen(fileName); + else + fileNamePartStartIndex = (int)(fileNamePointer - buffer); + return true; +} + +#ifndef _UNICODE +bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex) +{ + resultPath.Empty(); + if (g_IsNT) + { + LPWSTR fileNamePointer = 0; + LPWSTR buffer = resultPath.GetBuffer(MAX_PATH); + DWORD needLength = ::GetFullPathNameW(fileName, MAX_PATH + 1, buffer, &fileNamePointer); + resultPath.ReleaseBuffer(); + if (needLength == 0) + return false; + if (needLength >= MAX_PATH) + { + #ifdef WIN_LONG_PATH + needLength++; + buffer = resultPath.GetBuffer(needLength + 1); + DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer); + resultPath.ReleaseBuffer(); + if (needLength2 == 0 || needLength2 > needLength) + #endif + return false; + } + if (fileNamePointer == 0) + fileNamePartStartIndex = MyStringLen(fileName); + else + fileNamePartStartIndex = (int)(fileNamePointer - buffer); + } + else + { + CSysString sysPath; + if (!MyGetFullPathName(GetSysPath(fileName), sysPath, fileNamePartStartIndex)) + return false; + UString resultPath1 = GetUnicodePath(sysPath.Left(fileNamePartStartIndex)); + UString resultPath2 = GetUnicodePath(sysPath.Mid(fileNamePartStartIndex)); + fileNamePartStartIndex = resultPath1.Length(); + resultPath = resultPath1 + resultPath2; + } + return true; +} +#endif + + +bool MyGetFullPathName(LPCTSTR fileName, CSysString &path) +{ + int index; + return MyGetFullPathName(fileName, path, index); +} + +#ifndef _UNICODE +bool MyGetFullPathName(LPCWSTR fileName, UString &path) +{ + int index; + return MyGetFullPathName(fileName, path, index); +} +#endif + +bool GetOnlyName(LPCTSTR fileName, CSysString &resultName) +{ + int index; + if (!MyGetFullPathName(fileName, resultName, index)) + return false; + resultName = resultName.Mid(index); + return true; +} + +#ifndef _UNICODE +bool GetOnlyName(LPCWSTR fileName, UString &resultName) +{ + int index; + if (!MyGetFullPathName(fileName, resultName, index)) + return false; + resultName = resultName.Mid(index); + return true; +} +#endif + +bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName) +{ + int index; + if (!MyGetFullPathName(fileName, resultName, index)) + return false; + resultName = resultName.Left(index); + return true; +} + +#ifndef _UNICODE +bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName) +{ + int index; + if (!MyGetFullPathName(fileName, resultName, index)) + return false; + resultName = resultName.Left(index); + return true; +} +#endif + +bool MyGetCurrentDirectory(CSysString &path) +{ + DWORD needLength = ::GetCurrentDirectory(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1)); + path.ReleaseBuffer(); + return (needLength > 0 && needLength <= MAX_PATH); +} + +#ifndef _UNICODE +bool MySetCurrentDirectory(LPCWSTR path) +{ + if (g_IsNT) + return BOOLToBool(::SetCurrentDirectoryW(path)); + return MySetCurrentDirectory(GetSysPath(path)); +} +bool MyGetCurrentDirectory(UString &path) +{ + if (g_IsNT) + { + DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1)); + path.ReleaseBuffer(); + return (needLength > 0 && needLength <= MAX_PATH); + } + CSysString sysPath; + if (!MyGetCurrentDirectory(sysPath)) + return false; + path = GetUnicodePath(sysPath); + return true; +} +#endif +#endif + +bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension, + CSysString &resultPath, UINT32 &filePart) +{ + LPTSTR filePartPointer; + DWORD value = ::SearchPath(path, fileName, extension, + MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer); + filePart = (UINT32)(filePartPointer - (LPCTSTR)resultPath); + resultPath.ReleaseBuffer(); + return (value > 0 && value <= MAX_PATH); +} + +#ifndef _UNICODE +bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, + UString &resultPath, UINT32 &filePart) +{ + if (g_IsNT) + { + LPWSTR filePartPointer = 0; + DWORD value = ::SearchPathW(path, fileName, extension, + MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer); + filePart = (UINT32)(filePartPointer - (LPCWSTR)resultPath); + resultPath.ReleaseBuffer(); + return (value > 0 && value <= MAX_PATH); + } + + CSysString sysPath; + if (!MySearchPath( + path != 0 ? (LPCTSTR)GetSysPath(path): 0, + fileName != 0 ? (LPCTSTR)GetSysPath(fileName): 0, + extension != 0 ? (LPCTSTR)GetSysPath(extension): 0, + sysPath, filePart)) + return false; + UString resultPath1 = GetUnicodePath(sysPath.Left(filePart)); + UString resultPath2 = GetUnicodePath(sysPath.Mid(filePart)); + filePart = resultPath1.Length(); + resultPath = resultPath1 + resultPath2; + return true; +} +#endif + +bool MyGetTempPath(CSysString &path) +{ + DWORD needLength = ::GetTempPath(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1)); + path.ReleaseBuffer(); + return (needLength > 0 && needLength <= MAX_PATH); +} + +#ifndef _UNICODE +bool MyGetTempPath(UString &path) +{ + path.Empty(); + if (g_IsNT) + { + DWORD needLength = ::GetTempPathW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1)); + path.ReleaseBuffer(); + return (needLength > 0 && needLength <= MAX_PATH); + } + CSysString sysPath; + if (!MyGetTempPath(sysPath)) + return false; + path = GetUnicodePath(sysPath); + return true; +} +#endif + +UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &path) +{ + UINT number = ::GetTempFileName(dirPath, prefix, 0, path.GetBuffer(MAX_PATH + 1)); + path.ReleaseBuffer(); + return number; +} + +#ifndef _UNICODE +UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &path) +{ + if (g_IsNT) + { + UINT number = ::GetTempFileNameW(dirPath, prefix, 0, path.GetBuffer(MAX_PATH)); + path.ReleaseBuffer(); + return number; + } + CSysString sysPath; + UINT number = MyGetTempFileName( + dirPath ? (LPCTSTR)GetSysPath(dirPath): 0, + prefix ? (LPCTSTR)GetSysPath(prefix): 0, + sysPath); + path = GetUnicodePath(sysPath); + return number; +} +#endif + +UINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath) +{ + Remove(); + UINT number = MyGetTempFileName(dirPath, prefix, resultPath); + if (number != 0) + { + _fileName = resultPath; + _mustBeDeleted = true; + } + return number; +} + +bool CTempFile::Create(LPCTSTR prefix, CSysString &resultPath) +{ + CSysString tempPath; + if (!MyGetTempPath(tempPath)) + return false; + if (Create(tempPath, prefix, resultPath) != 0) + return true; + if (!MyGetWindowsDirectory(tempPath)) + return false; + return (Create(tempPath, prefix, resultPath) != 0); +} + +bool CTempFile::Remove() +{ + if (!_mustBeDeleted) + return true; + _mustBeDeleted = !DeleteFileAlways(_fileName); + return !_mustBeDeleted; +} + +#ifndef _UNICODE + +UINT CTempFileW::Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath) +{ + Remove(); + UINT number = MyGetTempFileName(dirPath, prefix, resultPath); + if (number != 0) + { + _fileName = resultPath; + _mustBeDeleted = true; + } + return number; +} + +bool CTempFileW::Create(LPCWSTR prefix, UString &resultPath) +{ + UString tempPath; + if (!MyGetTempPath(tempPath)) + return false; + if (Create(tempPath, prefix, resultPath) != 0) + return true; + if (!MyGetWindowsDirectory(tempPath)) + return false; + return (Create(tempPath, prefix, resultPath) != 0); +} + +bool CTempFileW::Remove() +{ + if (!_mustBeDeleted) + return true; + _mustBeDeleted = !DeleteFileAlways(_fileName); + return !_mustBeDeleted; +} + +#endif + +bool CreateTempDirectory(LPCTSTR prefix, CSysString &dirName) +{ + /* + CSysString prefix = tempPath + prefixChars; + CRandom random; + random.Init(); + */ + for (;;) + { + CTempFile tempFile; + if (!tempFile.Create(prefix, dirName)) + return false; + if (!::DeleteFile(dirName)) + return false; + /* + UINT32 randomNumber = random.Generate(); + TCHAR randomNumberString[32]; + _stprintf(randomNumberString, _T("%04X"), randomNumber); + dirName = prefix + randomNumberString; + */ + if (NFind::DoesFileExist(dirName)) + continue; + if (MyCreateDirectory(dirName)) + return true; + if (::GetLastError() != ERROR_ALREADY_EXISTS) + return false; + } +} + +bool CTempDirectory::Create(LPCTSTR prefix) +{ + Remove(); + return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir)); +} + +#ifndef _UNICODE + +bool CreateTempDirectory(LPCWSTR prefix, UString &dirName) +{ + /* + CSysString prefix = tempPath + prefixChars; + CRandom random; + random.Init(); + */ + for (;;) + { + CTempFileW tempFile; + if (!tempFile.Create(prefix, dirName)) + return false; + if (!DeleteFileAlways(dirName)) + return false; + /* + UINT32 randomNumber = random.Generate(); + TCHAR randomNumberString[32]; + _stprintf(randomNumberString, _T("%04X"), randomNumber); + dirName = prefix + randomNumberString; + */ + if (NFind::DoesFileExist(dirName)) + continue; + if (MyCreateDirectory(dirName)) + return true; + if (::GetLastError() != ERROR_ALREADY_EXISTS) + return false; + } +} + +bool CTempDirectoryW::Create(LPCWSTR prefix) +{ + Remove(); + return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir)); +} + +#endif + +}}} diff --git a/desmume/src/windows/7z/CPP/Windows/FileDir.h b/desmume/src/windows/7z/CPP/Windows/FileDir.h new file mode 100644 index 000000000..ea49264b5 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Windows/FileDir.h @@ -0,0 +1,178 @@ +// Windows/FileDir.h + +#ifndef __WINDOWS_FILEDIR_H +#define __WINDOWS_FILEDIR_H + +#include "../Common/MyString.h" +#include "Defs.h" + +namespace NWindows { +namespace NFile { +namespace NDirectory { + +#ifdef WIN_LONG_PATH +bool GetLongPaths(LPCWSTR s1, LPCWSTR s2, UString &d1, UString &d2); +#endif + +bool MyGetWindowsDirectory(CSysString &path); +bool MyGetSystemDirectory(CSysString &path); +#ifndef _UNICODE +bool MyGetWindowsDirectory(UString &path); +bool MyGetSystemDirectory(UString &path); +#endif + +bool SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime); + +bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes); +bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName); +bool MyRemoveDirectory(LPCTSTR pathName); +bool MyCreateDirectory(LPCTSTR pathName); +bool CreateComplexDirectory(LPCTSTR pathName); +bool DeleteFileAlways(LPCTSTR name); +bool RemoveDirectoryWithSubItems(const CSysString &path); + +#ifndef _UNICODE +bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes); +bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName); +bool MyRemoveDirectory(LPCWSTR pathName); +bool MyCreateDirectory(LPCWSTR pathName); +bool CreateComplexDirectory(LPCWSTR pathName); +bool DeleteFileAlways(LPCWSTR name); +bool RemoveDirectoryWithSubItems(const UString &path); +#endif + +#ifndef _WIN32_WCE +bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath); + +bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, + int &fileNamePartStartIndex); +bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath); +bool GetOnlyName(LPCTSTR fileName, CSysString &resultName); +bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName); +#ifndef _UNICODE +bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, + int &fileNamePartStartIndex); +bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath); +bool GetOnlyName(LPCWSTR fileName, UString &resultName); +bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName); +#endif + +inline bool MySetCurrentDirectory(LPCTSTR path) + { return BOOLToBool(::SetCurrentDirectory(path)); } +bool MyGetCurrentDirectory(CSysString &resultPath); +#ifndef _UNICODE +bool MySetCurrentDirectory(LPCWSTR path); +bool MyGetCurrentDirectory(UString &resultPath); +#endif +#endif + +bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension, + CSysString &resultPath, UINT32 &filePart); +#ifndef _UNICODE +bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, + UString &resultPath, UINT32 &filePart); +#endif + +inline bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension, + CSysString &resultPath) +{ + UINT32 value; + return MySearchPath(path, fileName, extension, resultPath, value); +} + +#ifndef _UNICODE +inline bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, + UString &resultPath) +{ + UINT32 value; + return MySearchPath(path, fileName, extension, resultPath, value); +} +#endif + +bool MyGetTempPath(CSysString &resultPath); +#ifndef _UNICODE +bool MyGetTempPath(UString &resultPath); +#endif + +UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath); +#ifndef _UNICODE +UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath); +#endif + +class CTempFile +{ + bool _mustBeDeleted; + CSysString _fileName; +public: + CTempFile(): _mustBeDeleted(false) {} + ~CTempFile() { Remove(); } + void DisableDeleting() { _mustBeDeleted = false; } + UINT Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath); + bool Create(LPCTSTR prefix, CSysString &resultPath); + bool Remove(); +}; + +#ifdef _UNICODE +typedef CTempFile CTempFileW; +#else +class CTempFileW +{ + bool _mustBeDeleted; + UString _fileName; +public: + CTempFileW(): _mustBeDeleted(false) {} + ~CTempFileW() { Remove(); } + void DisableDeleting() { _mustBeDeleted = false; } + UINT Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath); + bool Create(LPCWSTR prefix, UString &resultPath); + bool Remove(); +}; +#endif + +bool CreateTempDirectory(LPCTSTR prefixChars, CSysString &dirName); + +class CTempDirectory +{ + bool _mustBeDeleted; + CSysString _tempDir; +public: + const CSysString &GetPath() const { return _tempDir; } + CTempDirectory(): _mustBeDeleted(false) {} + ~CTempDirectory() { Remove(); } + bool Create(LPCTSTR prefix) ; + bool Remove() + { + if (!_mustBeDeleted) + return true; + _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir); + return (!_mustBeDeleted); + } + void DisableDeleting() { _mustBeDeleted = false; } +}; + +#ifdef _UNICODE +typedef CTempDirectory CTempDirectoryW; +#else +class CTempDirectoryW +{ + bool _mustBeDeleted; + UString _tempDir; +public: + const UString &GetPath() const { return _tempDir; } + CTempDirectoryW(): _mustBeDeleted(false) {} + ~CTempDirectoryW() { Remove(); } + bool Create(LPCWSTR prefix) ; + bool Remove() + { + if (!_mustBeDeleted) + return true; + _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir); + return (!_mustBeDeleted); + } + void DisableDeleting() { _mustBeDeleted = false; } +}; +#endif + +}}} + +#endif diff --git a/desmume/src/windows/7z/CPP/Windows/FileFind.cpp b/desmume/src/windows/7z/CPP/Windows/FileFind.cpp new file mode 100644 index 000000000..7e6b30a6b --- /dev/null +++ b/desmume/src/windows/7z/CPP/Windows/FileFind.cpp @@ -0,0 +1,402 @@ +// Windows/FileFind.cpp + +#include "StdAfx.h" + +#include "FileFind.h" +#ifndef _UNICODE +#include "../Common/StringConvert.h" +#endif + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NFile { + +#if defined(WIN_LONG_PATH) && defined(_UNICODE) +#define WIN_LONG_PATH2 +#endif + +bool GetLongPath(LPCWSTR fileName, UString &res); + +namespace NFind { + +static const TCHAR kDot = TEXT('.'); + +bool CFileInfo::IsDots() const +{ + if (!IsDir() || Name.IsEmpty()) + return false; + if (Name[0] != kDot) + return false; + return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2); +} + +#ifndef _UNICODE +bool CFileInfoW::IsDots() const +{ + if (!IsDir() || Name.IsEmpty()) + return false; + if (Name[0] != kDot) + return false; + return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2); +} +#endif + +static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfo &fi) +{ + fi.Attrib = fd.dwFileAttributes; + fi.CTime = fd.ftCreationTime; + fi.ATime = fd.ftLastAccessTime; + fi.MTime = fd.ftLastWriteTime; + fi.Size = (((UInt64)fd.nFileSizeHigh) << 32) + fd.nFileSizeLow; + fi.Name = fd.cFileName; + #ifndef _WIN32_WCE + fi.ReparseTag = fd.dwReserved0; + #else + fi.ObjectID = fd.dwOID; + #endif +} + +#ifndef _UNICODE + +static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } + +static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATAW &fd, CFileInfoW &fi) +{ + fi.Attrib = fd.dwFileAttributes; + fi.CTime = fd.ftCreationTime; + fi.ATime = fd.ftLastAccessTime; + fi.MTime = fd.ftLastWriteTime; + fi.Size = (((UInt64)fd.nFileSizeHigh) << 32) + fd.nFileSizeLow; + fi.Name = fd.cFileName; + #ifndef _WIN32_WCE + fi.ReparseTag = fd.dwReserved0; + #else + fi.ObjectID = fd.dwOID; + #endif +} + +static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfoW &fi) +{ + fi.Attrib = fd.dwFileAttributes; + fi.CTime = fd.ftCreationTime; + fi.ATime = fd.ftLastAccessTime; + fi.MTime = fd.ftLastWriteTime; + fi.Size = (((UInt64)fd.nFileSizeHigh) << 32) + fd.nFileSizeLow; + fi.Name = GetUnicodeString(fd.cFileName, GetCurrentCodePage()); + #ifndef _WIN32_WCE + fi.ReparseTag = fd.dwReserved0; + #else + fi.ObjectID = fd.dwOID; + #endif +} +#endif + +//////////////////////////////// +// CFindFile + +bool CFindFile::Close() +{ + if (_handle == INVALID_HANDLE_VALUE) + return true; + if (!::FindClose(_handle)) + return false; + _handle = INVALID_HANDLE_VALUE; + return true; +} + + +bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo) +{ + if (!Close()) + return false; + WIN32_FIND_DATA fd; + _handle = ::FindFirstFile(wildcard, &fd); + #ifdef WIN_LONG_PATH2 + if (_handle == INVALID_HANDLE_VALUE) + { + UString longPath; + if (GetLongPath(wildcard, longPath)) + _handle = ::FindFirstFileW(longPath, &fd); + } + #endif + if (_handle == INVALID_HANDLE_VALUE) + return false; + ConvertWIN32_FIND_DATA_To_FileInfo(fd, fileInfo); + return true; +} + +#ifndef _UNICODE +bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo) +{ + if (!Close()) + return false; + if (g_IsNT) + { + WIN32_FIND_DATAW fd; + _handle = ::FindFirstFileW(wildcard, &fd); + #ifdef WIN_LONG_PATH + if (_handle == INVALID_HANDLE_VALUE) + { + UString longPath; + if (GetLongPath(wildcard, longPath)) + _handle = ::FindFirstFileW(longPath, &fd); + } + #endif + if (_handle != INVALID_HANDLE_VALUE) + ConvertWIN32_FIND_DATA_To_FileInfo(fd, fileInfo); + } + else + { + WIN32_FIND_DATAA fd; + _handle = ::FindFirstFileA(UnicodeStringToMultiByte(wildcard, + GetCurrentCodePage()), &fd); + if (_handle != INVALID_HANDLE_VALUE) + ConvertWIN32_FIND_DATA_To_FileInfo(fd, fileInfo); + } + return (_handle != INVALID_HANDLE_VALUE); +} +#endif + +bool CFindFile::FindNext(CFileInfo &fileInfo) +{ + WIN32_FIND_DATA fd; + bool result = BOOLToBool(::FindNextFile(_handle, &fd)); + if (result) + ConvertWIN32_FIND_DATA_To_FileInfo(fd, fileInfo); + return result; +} + +#ifndef _UNICODE +bool CFindFile::FindNext(CFileInfoW &fileInfo) +{ + if (g_IsNT) + { + WIN32_FIND_DATAW fd; + if (!::FindNextFileW(_handle, &fd)) + return false; + ConvertWIN32_FIND_DATA_To_FileInfo(fd, fileInfo); + } + else + { + WIN32_FIND_DATAA fd; + if (!::FindNextFileA(_handle, &fd)) + return false; + ConvertWIN32_FIND_DATA_To_FileInfo(fd, fileInfo); + } + return true; +} +#endif + +bool FindFile(LPCTSTR wildcard, CFileInfo &fileInfo) +{ + CFindFile finder; + return finder.FindFirst(wildcard, fileInfo); +} + +#ifndef _UNICODE +bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo) +{ + CFindFile finder; + return finder.FindFirst(wildcard, fileInfo); +} +#endif + +bool DoesFileExist(LPCTSTR name) +{ + CFileInfo fileInfo; + return FindFile(name, fileInfo); +} + +#ifndef _UNICODE +bool DoesFileExist(LPCWSTR name) +{ + CFileInfoW fileInfo; + return FindFile(name, fileInfo); +} +#endif + +///////////////////////////////////// +// CEnumerator + +bool CEnumerator::NextAny(CFileInfo &fileInfo) +{ + if (_findFile.IsHandleAllocated()) + return _findFile.FindNext(fileInfo); + else + return _findFile.FindFirst(_wildcard, fileInfo); +} + +bool CEnumerator::Next(CFileInfo &fileInfo) +{ + for (;;) + { + if (!NextAny(fileInfo)) + return false; + if (!fileInfo.IsDots()) + return true; + } +} + +bool CEnumerator::Next(CFileInfo &fileInfo, bool &found) +{ + if (Next(fileInfo)) + { + found = true; + return true; + } + found = false; + return (::GetLastError() == ERROR_NO_MORE_FILES); +} + +#ifndef _UNICODE +bool CEnumeratorW::NextAny(CFileInfoW &fileInfo) +{ + if (_findFile.IsHandleAllocated()) + return _findFile.FindNext(fileInfo); + else + return _findFile.FindFirst(_wildcard, fileInfo); +} + +bool CEnumeratorW::Next(CFileInfoW &fileInfo) +{ + for (;;) + { + if (!NextAny(fileInfo)) + return false; + if (!fileInfo.IsDots()) + return true; + } +} + +bool CEnumeratorW::Next(CFileInfoW &fileInfo, bool &found) +{ + if (Next(fileInfo)) + { + found = true; + return true; + } + found = false; + return (::GetLastError() == ERROR_NO_MORE_FILES); +} + +#endif + +//////////////////////////////// +// CFindChangeNotification +// FindFirstChangeNotification can return 0. MSDN doesn't tell about it. + +bool CFindChangeNotification::Close() +{ + if (!IsHandleAllocated()) + return true; + if (!::FindCloseChangeNotification(_handle)) + return false; + _handle = INVALID_HANDLE_VALUE; + return true; +} + +HANDLE CFindChangeNotification::FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter) +{ + _handle = ::FindFirstChangeNotification(pathName, BoolToBOOL(watchSubtree), notifyFilter); + #ifdef WIN_LONG_PATH2 + if (!IsHandleAllocated()) + { + UString longPath; + if (GetLongPath(pathName, longPath)) + _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter); + } + #endif + return _handle; +} + +#ifndef _UNICODE +HANDLE CFindChangeNotification::FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter) +{ + if (!g_IsNT) + return FindFirst(UnicodeStringToMultiByte(pathName, GetCurrentCodePage()), watchSubtree, notifyFilter); + _handle = ::FindFirstChangeNotificationW(pathName, BoolToBOOL(watchSubtree), notifyFilter); + #ifdef WIN_LONG_PATH + if (!IsHandleAllocated()) + { + UString longPath; + if (GetLongPath(pathName, longPath)) + _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter); + } + #endif + return _handle; +} +#endif + +#ifndef _WIN32_WCE +bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings) +{ + driveStrings.Clear(); + UINT32 size = GetLogicalDriveStrings(0, NULL); + if (size == 0) + return false; + CSysString buffer; + UINT32 newSize = GetLogicalDriveStrings(size, buffer.GetBuffer(size)); + if (newSize == 0) + return false; + if (newSize > size) + return false; + CSysString string; + for (UINT32 i = 0; i < newSize; i++) + { + TCHAR c = buffer[i]; + if (c == TEXT('\0')) + { + driveStrings.Add(string); + string.Empty(); + } + else + string += c; + } + if (!string.IsEmpty()) + return false; + return true; +} + +#ifndef _UNICODE +bool MyGetLogicalDriveStrings(UStringVector &driveStrings) +{ + driveStrings.Clear(); + if (g_IsNT) + { + UINT32 size = GetLogicalDriveStringsW(0, NULL); + if (size == 0) + return false; + UString buffer; + UINT32 newSize = GetLogicalDriveStringsW(size, buffer.GetBuffer(size)); + if (newSize == 0) + return false; + if (newSize > size) + return false; + UString string; + for (UINT32 i = 0; i < newSize; i++) + { + WCHAR c = buffer[i]; + if (c == L'\0') + { + driveStrings.Add(string); + string.Empty(); + } + else + string += c; + } + return string.IsEmpty(); + } + CSysStringVector driveStringsA; + bool res = MyGetLogicalDriveStrings(driveStringsA); + for (int i = 0; i < driveStringsA.Size(); i++) + driveStrings.Add(GetUnicodeString(driveStringsA[i])); + return res; +} +#endif + +#endif + +}}} diff --git a/desmume/src/windows/7z/CPP/Windows/FileFind.h b/desmume/src/windows/7z/CPP/Windows/FileFind.h new file mode 100644 index 000000000..f01c1357e --- /dev/null +++ b/desmume/src/windows/7z/CPP/Windows/FileFind.h @@ -0,0 +1,153 @@ +// Windows/FileFind.h + +#ifndef __WINDOWS_FILEFIND_H +#define __WINDOWS_FILEFIND_H + +#include "../Common/MyString.h" +#include "../Common/Types.h" +#include "FileName.h" +#include "Defs.h" + +namespace NWindows { +namespace NFile { +namespace NFind { + +namespace NAttributes +{ + inline bool IsReadOnly(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_READONLY) != 0; } + inline bool IsHidden(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_HIDDEN) != 0; } + inline bool IsSystem(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_SYSTEM) != 0; } + inline bool IsDir(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0; } + inline bool IsArchived(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_ARCHIVE) != 0; } + inline bool IsCompressed(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_COMPRESSED) != 0; } + inline bool IsEncrypted(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_ENCRYPTED) != 0; } +} + +class CFileInfoBase +{ + bool MatchesMask(UINT32 mask) const { return ((Attrib & mask) != 0); } +public: + UInt64 Size; + FILETIME CTime; + FILETIME ATime; + FILETIME MTime; + DWORD Attrib; + + #ifndef _WIN32_WCE + UINT32 ReparseTag; + #else + DWORD ObjectID; + #endif + + bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); } + bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); } + bool IsDir() const { return MatchesMask(FILE_ATTRIBUTE_DIRECTORY); } + bool IsEncrypted() const { return MatchesMask(FILE_ATTRIBUTE_ENCRYPTED); } + bool IsHidden() const { return MatchesMask(FILE_ATTRIBUTE_HIDDEN); } + bool IsNormal() const { return MatchesMask(FILE_ATTRIBUTE_NORMAL); } + bool IsOffline() const { return MatchesMask(FILE_ATTRIBUTE_OFFLINE); } + bool IsReadOnly() const { return MatchesMask(FILE_ATTRIBUTE_READONLY); } + bool HasReparsePoint() const { return MatchesMask(FILE_ATTRIBUTE_REPARSE_POINT); } + bool IsSparse() const { return MatchesMask(FILE_ATTRIBUTE_SPARSE_FILE); } + bool IsSystem() const { return MatchesMask(FILE_ATTRIBUTE_SYSTEM); } + bool IsTemporary() const { return MatchesMask(FILE_ATTRIBUTE_TEMPORARY); } +}; + +class CFileInfo: public CFileInfoBase +{ +public: + CSysString Name; + bool IsDots() const; +}; + +#ifdef _UNICODE +typedef CFileInfo CFileInfoW; +#else +class CFileInfoW: public CFileInfoBase +{ +public: + UString Name; + bool IsDots() const; +}; +#endif + +class CFindFile +{ + friend class CEnumerator; + HANDLE _handle; +public: + bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE; } + CFindFile(): _handle(INVALID_HANDLE_VALUE) {} + ~CFindFile() { Close(); } + bool FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo); + bool FindNext(CFileInfo &fileInfo); + #ifndef _UNICODE + bool FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo); + bool FindNext(CFileInfoW &fileInfo); + #endif + bool Close(); +}; + +bool FindFile(LPCTSTR wildcard, CFileInfo &fileInfo); + +bool DoesFileExist(LPCTSTR name); +#ifndef _UNICODE +bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo); +bool DoesFileExist(LPCWSTR name); +#endif + +class CEnumerator +{ + CFindFile _findFile; + CSysString _wildcard; + bool NextAny(CFileInfo &fileInfo); +public: + CEnumerator(): _wildcard(NName::kAnyStringWildcard) {} + CEnumerator(const CSysString &wildcard): _wildcard(wildcard) {} + bool Next(CFileInfo &fileInfo); + bool Next(CFileInfo &fileInfo, bool &found); +}; + +#ifdef _UNICODE +typedef CEnumerator CEnumeratorW; +#else +class CEnumeratorW +{ + CFindFile _findFile; + UString _wildcard; + bool NextAny(CFileInfoW &fileInfo); +public: + CEnumeratorW(): _wildcard(NName::kAnyStringWildcard) {} + CEnumeratorW(const UString &wildcard): _wildcard(wildcard) {} + bool Next(CFileInfoW &fileInfo); + bool Next(CFileInfoW &fileInfo, bool &found); +}; +#endif + +class CFindChangeNotification +{ + HANDLE _handle; +public: + operator HANDLE () { return _handle; } + bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE && _handle != 0; } + CFindChangeNotification(): _handle(INVALID_HANDLE_VALUE) {} + ~CFindChangeNotification() { Close(); } + bool Close(); + HANDLE FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter); + #ifndef _UNICODE + HANDLE FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter); + #endif + bool FindNext() { return BOOLToBool(::FindNextChangeNotification(_handle)); } +}; + +#ifndef _WIN32_WCE +bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings); +#ifndef _UNICODE +bool MyGetLogicalDriveStrings(UStringVector &driveStrings); +#endif +#endif + +}}} + +#endif + diff --git a/desmume/src/windows/7z/CPP/Windows/FileIO.cpp b/desmume/src/windows/7z/CPP/Windows/FileIO.cpp new file mode 100644 index 000000000..520d9a2ba --- /dev/null +++ b/desmume/src/windows/7z/CPP/Windows/FileIO.cpp @@ -0,0 +1,317 @@ +// Windows/FileIO.cpp + +#include "StdAfx.h" + +#include "FileIO.h" +#include "Defs.h" +#ifdef WIN_LONG_PATH +#include "../Common/MyString.h" +#endif +#ifndef _UNICODE +#include "../Common/StringConvert.h" +#endif + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NFile { + +#if defined(WIN_LONG_PATH) && defined(_UNICODE) +#define WIN_LONG_PATH2 +#endif + +#ifdef WIN_LONG_PATH +bool GetLongPathBase(LPCWSTR s, UString &res) +{ + res.Empty(); + int len = MyStringLen(s); + wchar_t c = s[0]; + if (len < 1 || c == L'\\' || c == L'.' && (len == 1 || len == 2 && s[1] == L'.')) + return true; + UString curDir; + bool isAbs = false; + if (len > 3) + isAbs = (s[1] == L':' && s[2] == L'\\' && (c >= L'a' && c <= L'z' || c >= L'A' && c <= L'Z')); + + if (!isAbs) + { + DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, curDir.GetBuffer(MAX_PATH + 1)); + curDir.ReleaseBuffer(); + if (needLength == 0 || needLength > MAX_PATH) + return false; + if (curDir[curDir.Length() - 1] != L'\\') + curDir += L'\\'; + } + res = UString(L"\\\\?\\") + curDir + s; + return true; +} + +bool GetLongPath(LPCWSTR path, UString &longPath) +{ + if (GetLongPathBase(path, longPath)) + return !longPath.IsEmpty(); + return false; +} +#endif + +namespace NIO { + +CFileBase::~CFileBase() { Close(); } + +bool CFileBase::Create(LPCTSTR fileName, DWORD desiredAccess, + DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) +{ + if (!Close()) + return false; + _handle = ::CreateFile(fileName, desiredAccess, shareMode, + (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, + flagsAndAttributes, (HANDLE)NULL); + #ifdef WIN_LONG_PATH2 + if (_handle == INVALID_HANDLE_VALUE) + { + UString longPath; + if (GetLongPath(fileName, longPath)) + _handle = ::CreateFileW(longPath, desiredAccess, shareMode, + (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, + flagsAndAttributes, (HANDLE)NULL); + } + #endif + return (_handle != INVALID_HANDLE_VALUE); +} + +#ifndef _UNICODE +bool CFileBase::Create(LPCWSTR fileName, DWORD desiredAccess, + DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) +{ + if (!g_IsNT) + return Create(UnicodeStringToMultiByte(fileName, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP), + desiredAccess, shareMode, creationDisposition, flagsAndAttributes); + if (!Close()) + return false; + _handle = ::CreateFileW(fileName, desiredAccess, shareMode, + (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, + flagsAndAttributes, (HANDLE)NULL); + #ifdef WIN_LONG_PATH + if (_handle == INVALID_HANDLE_VALUE) + { + UString longPath; + if (GetLongPath(fileName, longPath)) + _handle = ::CreateFileW(longPath, desiredAccess, shareMode, + (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, + flagsAndAttributes, (HANDLE)NULL); + } + #endif + return (_handle != INVALID_HANDLE_VALUE); +} +#endif + +bool CFileBase::Close() +{ + if (_handle == INVALID_HANDLE_VALUE) + return true; + if (!::CloseHandle(_handle)) + return false; + _handle = INVALID_HANDLE_VALUE; + return true; +} + +bool CFileBase::GetPosition(UInt64 &position) const +{ + return Seek(0, FILE_CURRENT, position); +} + +bool CFileBase::GetLength(UInt64 &length) const +{ + DWORD sizeHigh; + DWORD sizeLow = ::GetFileSize(_handle, &sizeHigh); + if (sizeLow == 0xFFFFFFFF) + if (::GetLastError() != NO_ERROR) + return false; + length = (((UInt64)sizeHigh) << 32) + sizeLow; + return true; +} + +bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const +{ + LARGE_INTEGER value; + value.QuadPart = distanceToMove; + value.LowPart = ::SetFilePointer(_handle, value.LowPart, &value.HighPart, moveMethod); + if (value.LowPart == 0xFFFFFFFF) + if (::GetLastError() != NO_ERROR) + return false; + newPosition = value.QuadPart; + return true; +} + +bool CFileBase::Seek(UInt64 position, UInt64 &newPosition) +{ + return Seek(position, FILE_BEGIN, newPosition); +} + +bool CFileBase::SeekToBegin() +{ + UInt64 newPosition; + return Seek(0, newPosition); +} + +bool CFileBase::SeekToEnd(UInt64 &newPosition) +{ + return Seek(0, FILE_END, newPosition); +} + +bool CFileBase::GetFileInformation(CByHandleFileInfo &fileInfo) const +{ + BY_HANDLE_FILE_INFORMATION winFileInfo; + if (!::GetFileInformationByHandle(_handle, &winFileInfo)) + return false; + fileInfo.Attributes = winFileInfo.dwFileAttributes; + fileInfo.CTime = winFileInfo.ftCreationTime; + fileInfo.ATime = winFileInfo.ftLastAccessTime; + fileInfo.MTime = winFileInfo.ftLastWriteTime; + fileInfo.VolumeSerialNumber = winFileInfo.dwFileAttributes; + fileInfo.Size = (((UInt64)winFileInfo.nFileSizeHigh) << 32) + winFileInfo.nFileSizeLow; + fileInfo.NumberOfLinks = winFileInfo.nNumberOfLinks; + fileInfo.FileIndex = (((UInt64)winFileInfo.nFileIndexHigh) << 32) + winFileInfo.nFileIndexLow; + return true; +} + +///////////////////////// +// CInFile + +bool CInFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) + { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); } + +bool CInFile::OpenShared(LPCTSTR fileName, bool shareForWrite) +{ return Open(fileName, FILE_SHARE_READ | (shareForWrite ? FILE_SHARE_WRITE : 0), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); } + +bool CInFile::Open(LPCTSTR fileName) + { return OpenShared(fileName, false); } + +#ifndef _UNICODE +bool CInFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) + { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); } + +bool CInFile::OpenShared(LPCWSTR fileName, bool shareForWrite) +{ return Open(fileName, FILE_SHARE_READ | (shareForWrite ? FILE_SHARE_WRITE : 0), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); } + +bool CInFile::Open(LPCWSTR fileName) + { return OpenShared(fileName, false); } +#endif + +// ReadFile and WriteFile functions in Windows have BUG: +// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) +// from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES +// (Insufficient system resources exist to complete the requested service). + +// Probably in some version of Windows there are problems with other sizes: +// for 32 MB (maybe also for 16 MB). +// And message can be "Network connection was lost" + +static UInt32 kChunkSizeMax = (1 << 22); + +bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize) +{ + if (size > kChunkSizeMax) + size = kChunkSizeMax; + DWORD processedLoc = 0; + bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL)); + processedSize = (UInt32)processedLoc; + return res; +} + +bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize) +{ + processedSize = 0; + do + { + UInt32 processedLoc = 0; + bool res = ReadPart(data, size, processedLoc); + processedSize += processedLoc; + if (!res) + return false; + if (processedLoc == 0) + return true; + data = (void *)((unsigned char *)data + processedLoc); + size -= processedLoc; + } + while (size > 0); + return true; +} + +///////////////////////// +// COutFile + +bool COutFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) + { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); } + +static inline DWORD GetCreationDisposition(bool createAlways) + { return createAlways? CREATE_ALWAYS: CREATE_NEW; } + +bool COutFile::Open(LPCTSTR fileName, DWORD creationDisposition) + { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); } + +bool COutFile::Create(LPCTSTR fileName, bool createAlways) + { return Open(fileName, GetCreationDisposition(createAlways)); } + +#ifndef _UNICODE + +bool COutFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) + { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); } + +bool COutFile::Open(LPCWSTR fileName, DWORD creationDisposition) + { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); } + +bool COutFile::Create(LPCWSTR fileName, bool createAlways) + { return Open(fileName, GetCreationDisposition(createAlways)); } + +#endif + +bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) + { return BOOLToBool(::SetFileTime(_handle, cTime, aTime, mTime)); } + +bool COutFile::SetMTime(const FILETIME *mTime) { return SetTime(NULL, NULL, mTime); } + +bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize) +{ + if (size > kChunkSizeMax) + size = kChunkSizeMax; + DWORD processedLoc = 0; + bool res = BOOLToBool(::WriteFile(_handle, data, size, &processedLoc, NULL)); + processedSize = (UInt32)processedLoc; + return res; +} + +bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize) +{ + processedSize = 0; + do + { + UInt32 processedLoc = 0; + bool res = WritePart(data, size, processedLoc); + processedSize += processedLoc; + if (!res) + return false; + if (processedLoc == 0) + return true; + data = (const void *)((const unsigned char *)data + processedLoc); + size -= processedLoc; + } + while (size > 0); + return true; +} + +bool COutFile::SetEndOfFile() { return BOOLToBool(::SetEndOfFile(_handle)); } + +bool COutFile::SetLength(UInt64 length) +{ + UInt64 newPosition; + if (!Seek(length, newPosition)) + return false; + if (newPosition != length) + return false; + return SetEndOfFile(); +} + +}}} diff --git a/desmume/src/windows/7z/CPP/Windows/FileIO.h b/desmume/src/windows/7z/CPP/Windows/FileIO.h new file mode 100644 index 000000000..930a13d94 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Windows/FileIO.h @@ -0,0 +1,99 @@ +// Windows/FileIO.h + +#ifndef __WINDOWS_FILEIO_H +#define __WINDOWS_FILEIO_H + +#include "../Common/Types.h" + +namespace NWindows { +namespace NFile { +namespace NIO { + +struct CByHandleFileInfo +{ + DWORD Attributes; + FILETIME CTime; + FILETIME ATime; + FILETIME MTime; + DWORD VolumeSerialNumber; + UInt64 Size; + DWORD NumberOfLinks; + UInt64 FileIndex; +}; + +class CFileBase +{ +protected: + HANDLE _handle; + bool Create(LPCTSTR fileName, DWORD desiredAccess, + DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + #ifndef _UNICODE + bool Create(LPCWSTR fileName, DWORD desiredAccess, + DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + #endif + +public: + CFileBase(): _handle(INVALID_HANDLE_VALUE){}; + ~CFileBase(); + + bool Close(); + + bool GetPosition(UInt64 &position) const; + bool GetLength(UInt64 &length) const; + + bool Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const; + bool Seek(UInt64 position, UInt64 &newPosition); + bool SeekToBegin(); + bool SeekToEnd(UInt64 &newPosition); + + bool GetFileInformation(CByHandleFileInfo &fileInfo) const; +}; + +class CInFile: public CFileBase +{ +public: + bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + bool OpenShared(LPCTSTR fileName, bool shareForWrite); + bool Open(LPCTSTR fileName); + #ifndef _UNICODE + bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + bool OpenShared(LPCWSTR fileName, bool shareForWrite); + bool Open(LPCWSTR fileName); + #endif + bool ReadPart(void *data, UInt32 size, UInt32 &processedSize); + bool Read(void *data, UInt32 size, UInt32 &processedSize); +}; + +class COutFile: public CFileBase +{ + // DWORD m_CreationDisposition; +public: + // COutFile(): m_CreationDisposition(CREATE_NEW){}; + bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + bool Open(LPCTSTR fileName, DWORD creationDisposition); + bool Create(LPCTSTR fileName, bool createAlways); + + #ifndef _UNICODE + bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + bool Open(LPCWSTR fileName, DWORD creationDisposition); + bool Create(LPCWSTR fileName, bool createAlways); + #endif + + /* + void SetOpenCreationDisposition(DWORD creationDisposition) + { m_CreationDisposition = creationDisposition; } + void SetOpenCreationDispositionCreateAlways() + { m_CreationDisposition = CREATE_ALWAYS; } + */ + + bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime); + bool SetMTime(const FILETIME *mTime); + bool WritePart(const void *data, UInt32 size, UInt32 &processedSize); + bool Write(const void *data, UInt32 size, UInt32 &processedSize); + bool SetEndOfFile(); + bool SetLength(UInt64 length); +}; + +}}} + +#endif diff --git a/desmume/src/windows/7z/CPP/Windows/FileName.h b/desmume/src/windows/7z/CPP/Windows/FileName.h new file mode 100644 index 000000000..02dba3b69 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Windows/FileName.h @@ -0,0 +1,25 @@ +// Windows/FileName.h + +#ifndef __WINDOWS_FILENAME_H +#define __WINDOWS_FILENAME_H + +#include "../Common/MyString.h" + +namespace NWindows { +namespace NFile { +namespace NName { + +const TCHAR kDirDelimiter = CHAR_PATH_SEPARATOR; +const TCHAR kAnyStringWildcard = '*'; + +void NormalizeDirPathPrefix(CSysString &dirPath); // ensures that it ended with '\\' +#ifndef _UNICODE +void NormalizeDirPathPrefix(UString &dirPath); // ensures that it ended with '\\' +#endif + +void SplitNameToPureNameAndExtension(const UString &fullName, + UString &pureName, UString &extensionDelimiter, UString &extension); + +}}} + +#endif diff --git a/desmume/src/windows/7z/CPP/Windows/Handle.h b/desmume/src/windows/7z/CPP/Windows/Handle.h new file mode 100644 index 000000000..16546079d --- /dev/null +++ b/desmume/src/windows/7z/CPP/Windows/Handle.h @@ -0,0 +1,37 @@ +// Windows/Handle.h + +#ifndef __WINDOWS_HANDLE_H +#define __WINDOWS_HANDLE_H + +namespace NWindows { + +class CHandle +{ +protected: + HANDLE _handle; +public: + operator HANDLE() { return _handle; } + CHandle(): _handle(NULL) {} + ~CHandle() { Close(); } + bool Close() + { + if (_handle == NULL) + return true; + if (!::CloseHandle(_handle)) + return false; + _handle = NULL; + return true; + } + void Attach(HANDLE handle) + { _handle = handle; } + HANDLE Detach() + { + HANDLE handle = _handle; + _handle = NULL; + return handle; + } +}; + +} + +#endif diff --git a/desmume/src/windows/7z/CPP/Windows/PropVariant.cpp b/desmume/src/windows/7z/CPP/Windows/PropVariant.cpp new file mode 100644 index 000000000..fff513d18 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Windows/PropVariant.cpp @@ -0,0 +1,312 @@ +// Windows/PropVariant.cpp + +#include "StdAfx.h" + +#include "PropVariant.h" + +#include "../Common/Defs.h" + +namespace NWindows { +namespace NCOM { + +CPropVariant::CPropVariant(const PROPVARIANT& varSrc) +{ + vt = VT_EMPTY; + InternalCopy(&varSrc); +} + +CPropVariant::CPropVariant(const CPropVariant& varSrc) +{ + vt = VT_EMPTY; + InternalCopy(&varSrc); +} + +CPropVariant::CPropVariant(BSTR bstrSrc) +{ + vt = VT_EMPTY; + *this = bstrSrc; +} + +CPropVariant::CPropVariant(LPCOLESTR lpszSrc) +{ + vt = VT_EMPTY; + *this = lpszSrc; +} + +CPropVariant& CPropVariant::operator=(const CPropVariant& varSrc) +{ + InternalCopy(&varSrc); + return *this; +} +CPropVariant& CPropVariant::operator=(const PROPVARIANT& varSrc) +{ + InternalCopy(&varSrc); + return *this; +} + +CPropVariant& CPropVariant::operator=(BSTR bstrSrc) +{ + *this = (LPCOLESTR)bstrSrc; + return *this; +} + +CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc) +{ + InternalClear(); + vt = VT_BSTR; + wReserved1 = 0; + bstrVal = ::SysAllocString(lpszSrc); + if (bstrVal == NULL && lpszSrc != NULL) + { + vt = VT_ERROR; + scode = E_OUTOFMEMORY; + } + return *this; +} + + +CPropVariant& CPropVariant::operator=(bool bSrc) +{ + if (vt != VT_BOOL) + { + InternalClear(); + vt = VT_BOOL; + } + boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE; + return *this; +} + +CPropVariant& CPropVariant::operator=(UInt32 value) +{ + if (vt != VT_UI4) + { + InternalClear(); + vt = VT_UI4; + } + ulVal = value; + return *this; +} + +CPropVariant& CPropVariant::operator=(UInt64 value) +{ + if (vt != VT_UI8) + { + InternalClear(); + vt = VT_UI8; + } + uhVal.QuadPart = value; + return *this; +} + +CPropVariant& CPropVariant::operator=(const FILETIME &value) +{ + if (vt != VT_FILETIME) + { + InternalClear(); + vt = VT_FILETIME; + } + filetime = value; + return *this; +} + +CPropVariant& CPropVariant::operator=(Int32 value) +{ + if (vt != VT_I4) + { + InternalClear(); + vt = VT_I4; + } + lVal = value; + + return *this; +} + +CPropVariant& CPropVariant::operator=(Byte value) +{ + if (vt != VT_UI1) + { + InternalClear(); + vt = VT_UI1; + } + bVal = value; + return *this; +} + +CPropVariant& CPropVariant::operator=(Int16 value) +{ + if (vt != VT_I2) + { + InternalClear(); + vt = VT_I2; + } + iVal = value; + return *this; +} + +/* +CPropVariant& CPropVariant::operator=(LONG value) +{ + if (vt != VT_I4) + { + InternalClear(); + vt = VT_I4; + } + lVal = value; + return *this; +} +*/ + +static HRESULT MyPropVariantClear(PROPVARIANT *propVariant) +{ + switch(propVariant->vt) + { + case VT_UI1: + case VT_I1: + case VT_I2: + case VT_UI2: + case VT_BOOL: + case VT_I4: + case VT_UI4: + case VT_R4: + case VT_INT: + case VT_UINT: + case VT_ERROR: + case VT_FILETIME: + case VT_UI8: + case VT_R8: + case VT_CY: + case VT_DATE: + propVariant->vt = VT_EMPTY; + propVariant->wReserved1 = 0; + return S_OK; + } + return ::VariantClear((VARIANTARG *)propVariant); +} + +HRESULT CPropVariant::Clear() +{ + return MyPropVariantClear(this); +} + +HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) +{ + ::VariantClear((tagVARIANT *)this); + switch(pSrc->vt) + { + case VT_UI1: + case VT_I1: + case VT_I2: + case VT_UI2: + case VT_BOOL: + case VT_I4: + case VT_UI4: + case VT_R4: + case VT_INT: + case VT_UINT: + case VT_ERROR: + case VT_FILETIME: + case VT_UI8: + case VT_R8: + case VT_CY: + case VT_DATE: + memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT)); + return S_OK; + } + return ::VariantCopy((tagVARIANT *)this, (tagVARIANT *)(pSrc)); +} + + +HRESULT CPropVariant::Attach(PROPVARIANT* pSrc) +{ + HRESULT hr = Clear(); + if (FAILED(hr)) + return hr; + memcpy(this, pSrc, sizeof(PROPVARIANT)); + pSrc->vt = VT_EMPTY; + return S_OK; +} + +HRESULT CPropVariant::Detach(PROPVARIANT* pDest) +{ + HRESULT hr = MyPropVariantClear(pDest); + if (FAILED(hr)) + return hr; + memcpy(pDest, this, sizeof(PROPVARIANT)); + vt = VT_EMPTY; + return S_OK; +} + +HRESULT CPropVariant::InternalClear() +{ + HRESULT hr = Clear(); + if (FAILED(hr)) + { + vt = VT_ERROR; + scode = hr; + } + return hr; +} + +void CPropVariant::InternalCopy(const PROPVARIANT* pSrc) +{ + HRESULT hr = Copy(pSrc); + if (FAILED(hr)) + { + vt = VT_ERROR; + scode = hr; + } +} + +int CPropVariant::Compare(const CPropVariant &a) +{ + if (vt != a.vt) + return 0; // it's mean some bug + switch (vt) + { + case VT_EMPTY: + return 0; + + /* + case VT_I1: + return MyCompare(cVal, a.cVal); + */ + case VT_UI1: + return MyCompare(bVal, a.bVal); + + case VT_I2: + return MyCompare(iVal, a.iVal); + case VT_UI2: + return MyCompare(uiVal, a.uiVal); + + case VT_I4: + return MyCompare(lVal, a.lVal); + /* + case VT_INT: + return MyCompare(intVal, a.intVal); + */ + case VT_UI4: + return MyCompare(ulVal, a.ulVal); + /* + case VT_UINT: + return MyCompare(uintVal, a.uintVal); + */ + case VT_I8: + return MyCompare(hVal.QuadPart, a.hVal.QuadPart); + case VT_UI8: + return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart); + + case VT_BOOL: + return -MyCompare(boolVal, a.boolVal); + + case VT_FILETIME: + return ::CompareFileTime(&filetime, &a.filetime); + case VT_BSTR: + return 0; // Not implemented + // return MyCompare(aPropVarint.cVal); + + default: + return 0; + } +} + +}} diff --git a/desmume/src/windows/7z/CPP/Windows/PropVariant.h b/desmume/src/windows/7z/CPP/Windows/PropVariant.h new file mode 100644 index 000000000..85284e030 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Windows/PropVariant.h @@ -0,0 +1,57 @@ +// Windows/PropVariant.h + +#ifndef __WINDOWS_PROPVARIANT_H +#define __WINDOWS_PROPVARIANT_H + +#include "../Common/MyWindows.h" +#include "../Common/Types.h" + +namespace NWindows { +namespace NCOM { + +class CPropVariant : public tagPROPVARIANT +{ +public: + CPropVariant() { vt = VT_EMPTY; wReserved1 = 0; } + ~CPropVariant() { Clear(); } + CPropVariant(const PROPVARIANT& varSrc); + CPropVariant(const CPropVariant& varSrc); + CPropVariant(BSTR bstrSrc); + CPropVariant(LPCOLESTR lpszSrc); + CPropVariant(bool bSrc) { vt = VT_BOOL; wReserved1 = 0; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); }; + CPropVariant(UInt32 value) { vt = VT_UI4; wReserved1 = 0; ulVal = value; } + CPropVariant(UInt64 value) { vt = VT_UI8; wReserved1 = 0; uhVal = *(ULARGE_INTEGER*)&value; } + CPropVariant(const FILETIME &value) { vt = VT_FILETIME; wReserved1 = 0; filetime = value; } + CPropVariant(Int32 value) { vt = VT_I4; wReserved1 = 0; lVal = value; } + CPropVariant(Byte value) { vt = VT_UI1; wReserved1 = 0; bVal = value; } + CPropVariant(Int16 value) { vt = VT_I2; wReserved1 = 0; iVal = value; } + // CPropVariant(LONG value, VARTYPE vtSrc = VT_I4) { vt = vtSrc; lVal = value; } + + CPropVariant& operator=(const CPropVariant& varSrc); + CPropVariant& operator=(const PROPVARIANT& varSrc); + CPropVariant& operator=(BSTR bstrSrc); + CPropVariant& operator=(LPCOLESTR lpszSrc); + CPropVariant& operator=(bool bSrc); + CPropVariant& operator=(UInt32 value); + CPropVariant& operator=(UInt64 value); + CPropVariant& operator=(const FILETIME &value); + + CPropVariant& operator=(Int32 value); + CPropVariant& operator=(Byte value); + CPropVariant& operator=(Int16 value); + // CPropVariant& operator=(LONG value); + + HRESULT Clear(); + HRESULT Copy(const PROPVARIANT* pSrc); + HRESULT Attach(PROPVARIANT* pSrc); + HRESULT Detach(PROPVARIANT* pDest); + + HRESULT InternalClear(); + void InternalCopy(const PROPVARIANT* pSrc); + + int Compare(const CPropVariant &a1); +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/Windows/StdAfx.h b/desmume/src/windows/7z/CPP/Windows/StdAfx.h new file mode 100644 index 000000000..5308d632d --- /dev/null +++ b/desmume/src/windows/7z/CPP/Windows/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../Common/MyWindows.h" +#include "../Common/NewHandler.h" + +#endif diff --git a/desmume/src/windows/7z/CPP/Windows/Synchronization.h b/desmume/src/windows/7z/CPP/Windows/Synchronization.h new file mode 100644 index 000000000..1aeb91a6e --- /dev/null +++ b/desmume/src/windows/7z/CPP/Windows/Synchronization.h @@ -0,0 +1,168 @@ +// Windows/Synchronization.h + +#ifndef __WINDOWS_SYNCHRONIZATION_H +#define __WINDOWS_SYNCHRONIZATION_H + +#include "Defs.h" + +extern "C" +{ +#include "../../C/Threads.h" +} + +#ifdef _WIN32 +#include "Handle.h" +#endif + +namespace NWindows { +namespace NSynchronization { + +class CBaseEvent +{ +protected: + ::CEvent _object; +public: + bool IsCreated() { return Event_IsCreated(&_object) != 0; } + operator HANDLE() { return _object.handle; } + CBaseEvent() { Event_Construct(&_object); } + ~CBaseEvent() { Close(); } + WRes Close() { return Event_Close(&_object); } + #ifdef _WIN32 + WRes Create(bool manualReset, bool initiallyOwn, LPCTSTR name = NULL, + LPSECURITY_ATTRIBUTES securityAttributes = NULL) + { + _object.handle = ::CreateEvent(securityAttributes, BoolToBOOL(manualReset), + BoolToBOOL(initiallyOwn), name); + if (_object.handle != 0) + return 0; + return ::GetLastError(); + } + WRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name) + { + _object.handle = ::OpenEvent(desiredAccess, BoolToBOOL(inheritHandle), name); + if (_object.handle != 0) + return 0; + return ::GetLastError(); + } + #endif + + WRes Set() { return Event_Set(&_object); } + // bool Pulse() { return BOOLToBool(::PulseEvent(_handle)); } + WRes Reset() { return Event_Reset(&_object); } + WRes Lock() { return Event_Wait(&_object); } +}; + +class CManualResetEvent: public CBaseEvent +{ +public: + WRes Create(bool initiallyOwn = false) + { + return ManualResetEvent_Create(&_object, initiallyOwn ? 1: 0); + } + WRes CreateIfNotCreated() + { + if (IsCreated()) + return 0; + return ManualResetEvent_CreateNotSignaled(&_object); + } + #ifdef _WIN32 + WRes CreateWithName(bool initiallyOwn, LPCTSTR name) + { + return CBaseEvent::Create(true, initiallyOwn, name); + } + #endif +}; + +class CAutoResetEvent: public CBaseEvent +{ +public: + WRes Create() + { + return AutoResetEvent_CreateNotSignaled(&_object); + } + WRes CreateIfNotCreated() + { + if (IsCreated()) + return 0; + return AutoResetEvent_CreateNotSignaled(&_object); + } +}; + +#ifdef _WIN32 +class CObject: public CHandle +{ +public: + WRes Lock(DWORD timeoutInterval = INFINITE) + { return (::WaitForSingleObject(_handle, timeoutInterval) == WAIT_OBJECT_0 ? 0 : ::GetLastError()); } +}; +class CMutex: public CObject +{ +public: + WRes Create(bool initiallyOwn, LPCTSTR name = NULL, + LPSECURITY_ATTRIBUTES securityAttributes = NULL) + { + _handle = ::CreateMutex(securityAttributes, BoolToBOOL(initiallyOwn), name); + if (_handle != 0) + return 0; + return ::GetLastError(); + } + WRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name) + { + _handle = ::OpenMutex(desiredAccess, BoolToBOOL(inheritHandle), name); + if (_handle != 0) + return 0; + return ::GetLastError(); + } + WRes Release() + { + return ::ReleaseMutex(_handle) ? 0 : ::GetLastError(); + } +}; +class CMutexLock +{ + CMutex *_object; +public: + CMutexLock(CMutex &object): _object(&object) { _object->Lock(); } + ~CMutexLock() { _object->Release(); } +}; +#endif + +class CSemaphore +{ + ::CSemaphore _object; +public: + CSemaphore() { Semaphore_Construct(&_object); } + ~CSemaphore() { Close(); } + WRes Close() { return Semaphore_Close(&_object); } + operator HANDLE() { return _object.handle; } + WRes Create(UInt32 initiallyCount, UInt32 maxCount) + { + return Semaphore_Create(&_object, initiallyCount, maxCount); + } + WRes Release() { return Semaphore_Release1(&_object); } + WRes Release(UInt32 releaseCount) { return Semaphore_ReleaseN(&_object, releaseCount); } + WRes Lock() { return Semaphore_Wait(&_object); } +}; + +class CCriticalSection +{ + ::CCriticalSection _object; +public: + CCriticalSection() { CriticalSection_Init(&_object); } + ~CCriticalSection() { CriticalSection_Delete(&_object); } + void Enter() { CriticalSection_Enter(&_object); } + void Leave() { CriticalSection_Leave(&_object); } +}; + +class CCriticalSectionLock +{ + CCriticalSection *_object; + void Unlock() { _object->Leave(); } +public: + CCriticalSectionLock(CCriticalSection &object): _object(&object) {_object->Enter(); } + ~CCriticalSectionLock() { Unlock(); } +}; + +}} + +#endif diff --git a/desmume/src/windows/7z/CPP/Windows/Thread.h b/desmume/src/windows/7z/CPP/Windows/Thread.h new file mode 100644 index 000000000..6a1e63f23 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Windows/Thread.h @@ -0,0 +1,38 @@ +// Windows/Thread.h + +#ifndef __WINDOWS_THREAD_H +#define __WINDOWS_THREAD_H + +#include "Defs.h" + +extern "C" +{ +#include "../../C/Threads.h" +} + +namespace NWindows { + +class CThread +{ + ::CThread thread; +public: + CThread() { Thread_Construct(&thread); } + ~CThread() { Close(); } + bool IsCreated() { return Thread_WasCreated(&thread) != 0; } + WRes Close() { return Thread_Close(&thread); } + WRes Create(THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter) + { return Thread_Create(&thread, startAddress, parameter); } + WRes Wait() { return Thread_Wait(&thread); } + + #ifdef _WIN32 + DWORD Resume() { return ::ResumeThread(thread.handle); } + DWORD Suspend() { return ::SuspendThread(thread.handle); } + bool Terminate(DWORD exitCode) { return BOOLToBool(::TerminateThread(thread.handle, exitCode)); } + int GetPriority() { return ::GetThreadPriority(thread.handle); } + bool SetPriority(int priority) { return BOOLToBool(::SetThreadPriority(thread.handle, priority)); } + #endif +}; + +} + +#endif diff --git a/desmume/src/windows/7z/CPP/Windows/Time.cpp b/desmume/src/windows/7z/CPP/Windows/Time.cpp new file mode 100644 index 000000000..ff49803ab --- /dev/null +++ b/desmume/src/windows/7z/CPP/Windows/Time.cpp @@ -0,0 +1,86 @@ +// Windows/Time.cpp + +#include "StdAfx.h" + +#include "Time.h" +#include "Windows/Defs.h" + +namespace NWindows { +namespace NTime { + +bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime) +{ + return BOOLToBool(::DosDateTimeToFileTime((UInt16)(dosTime >> 16), (UInt16)(dosTime & 0xFFFF), &fileTime)); +} + +static const UInt32 kHighDosTime = 0xFF9FBF7D; +static const UInt32 kLowDosTime = 0x210000; + +bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime) +{ + WORD datePart, timePart; + if (!::FileTimeToDosDateTime(&fileTime, &datePart, &timePart)) + { + dosTime = (fileTime.dwHighDateTime >= 0x01C00000) ? kHighDosTime : kLowDosTime; + return false; + } + dosTime = (((UInt32)datePart) << 16) + timePart; + return true; +} + +static const UInt32 kNumTimeQuantumsInSecond = 10000000; +static const UInt64 kUnixTimeStartValue = ((UInt64)kNumTimeQuantumsInSecond) * 60 * 60 * 24 * 134774; + +void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime) +{ + UInt64 v = kUnixTimeStartValue + ((UInt64)unixTime) * kNumTimeQuantumsInSecond; + fileTime.dwLowDateTime = (DWORD)v; + fileTime.dwHighDateTime = (DWORD)(v >> 32); +} + +bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime) +{ + UInt64 winTime = (((UInt64)fileTime.dwHighDateTime) << 32) + fileTime.dwLowDateTime; + if (winTime < kUnixTimeStartValue) + { + unixTime = 0; + return false; + } + winTime = (winTime - kUnixTimeStartValue) / kNumTimeQuantumsInSecond; + if (winTime > 0xFFFFFFFF) + { + unixTime = 0xFFFFFFFF; + return false; + } + unixTime = (UInt32)winTime; + return true; +} + +bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day, + unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds) +{ + resSeconds = 0; + if (year < 1601 || year >= 10000 || month < 1 || month > 12 || + day < 1 || day > 31 || hour > 23 || min > 59 || sec > 59) + return false; + UInt32 numYears = year - 1601; + UInt32 numDays = numYears * 365 + numYears / 4 - numYears / 100 + numYears / 400; + Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) + ms[1] = 29; + month--; + for (unsigned i = 0; i < month; i++) + numDays += ms[i]; + numDays += day - 1; + resSeconds = ((UInt64)(numDays * 24 + hour) * 60 + min) * 60 + sec; + return true; +} + +void GetCurUtcFileTime(FILETIME &ft) +{ + SYSTEMTIME st; + GetSystemTime(&st); + SystemTimeToFileTime(&st, &ft); +} + +}} diff --git a/desmume/src/windows/7z/CPP/Windows/Time.h b/desmume/src/windows/7z/CPP/Windows/Time.h new file mode 100644 index 000000000..7ecb204b2 --- /dev/null +++ b/desmume/src/windows/7z/CPP/Windows/Time.h @@ -0,0 +1,21 @@ +// Windows/Time.h + +#ifndef __WINDOWS_TIME_H +#define __WINDOWS_TIME_H + +#include "Common/Types.h" + +namespace NWindows { +namespace NTime { + +bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime); +bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime); +void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime); +bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime); +bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day, + unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds); +void GetCurUtcFileTime(FILETIME &ft); + +}} + +#endif diff --git a/desmume/src/windows/7z/DOC/License.txt b/desmume/src/windows/7z/DOC/License.txt new file mode 100644 index 000000000..b472b97a8 --- /dev/null +++ b/desmume/src/windows/7z/DOC/License.txt @@ -0,0 +1,57 @@ +NOTE: The 7-zip library source is available under the LGPL, +however, this copy of it is distributed under the GPL 2.0. +This license has been modified accordingly. + + + 7-Zip source code + ~~~~~~~~~~~~~~~~~ + License for use and distribution + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + 7-Zip Copyright (C) 1999-2009 Igor Pavlov. + + Licenses for files are: + + 1) The 8 files in CPP/7zip/Compress/Rar*: GNU GPL 2.0 + unRAR restriction + 2) All other files: GNU GPL 2.0 + + The GNU GPL + unRAR restriction means that you must follow both + GNU GPL rules and unRAR restriction rules. + + + GNU GPL information + -------------------- + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + + unRAR restriction + ----------------- + + The decompression engine for RAR archives was developed using source + code of unRAR program. + All copyrights to original unRAR code are owned by Alexander Roshal. + + The license for original unRAR code has the following restriction: + + The unRAR sources cannot be used to re-create the RAR compression algorithm, + which is proprietary. Distribution of modified unRAR sources in separate form + or as a part of other software is permitted, provided that it is clearly + stated in the documentation and source comments that the code may + not be used to develop a RAR (WinRAR) compatible archiver. + + + -- + Igor Pavlov diff --git a/desmume/src/windows/7z/DOC/gpl.txt b/desmume/src/windows/7z/DOC/gpl.txt new file mode 100644 index 000000000..82fa1daad --- /dev/null +++ b/desmume/src/windows/7z/DOC/gpl.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/desmume/src/windows/7z/DOC/readme.txt b/desmume/src/windows/7z/DOC/readme.txt new file mode 100644 index 000000000..d7de5c264 --- /dev/null +++ b/desmume/src/windows/7z/DOC/readme.txt @@ -0,0 +1,48 @@ +This copy of the 7-zip source code has been modified as follows: +- Encoding support has been disabled, so only archive extraction is supported. +- Some archive formats have been removed, so only 7z, bzip2, gzip, lzh, lzma, rar, split, tar, and zip are supported. +- Support for using it as a static library has been added. (specifically, a file called InitializeStaticLib.h) +- Occasional minor fixes/customization not really worth describing in detail. +- The LGPL part of the 7-zip library source license has been upgraded to GPL 2.0 (as per condition 3 of the LGPL 2.1) + +You can find most of the files in this library in the "7-Zip Source code" download at http://www.7-zip.org/ distributed under the LGPL 2.1. A small subset of them are in the LZMA SDK which is public domain and can be found at http://www.7-zip.org/sdk.html + + + +7-Zip 4.64 Sources +------------------ + +7-Zip is a file archiver for Windows 95/98/ME/NT/2000/2003/XP/Vista. + +7-Zip Copyright (C) 1999-2009 Igor Pavlov. + + +License Info +------------ + +This copy of 7-Zip is free software distributed under the GNU GPL 2.0 +(with an additional restriction that has always applied to the unRar code). +read License.txt for more infomation about license. + +Notes about unRAR license: + +Please check main restriction from unRar license: + + 2. The unRAR sources may be used in any software to handle RAR + archives without limitations free of charge, but cannot be used + to re-create the RAR compression algorithm, which is proprietary. + Distribution of modified unRAR sources in separate form or as a + part of other software is permitted, provided that it is clearly + stated in the documentation and source comments that the code may + not be used to develop a RAR (WinRAR) compatible archiver. + +In brief it means: +1) You can compile and use compiled files under GNU GPL rules, since + unRAR license almost has no restrictions for compiled files. + You can link these compiled files to GPL programs. +2) You can fix bugs in source code and use compiled fixed version. +3) You can not use unRAR sources to re-create the RAR compression algorithm. + +--- +Igor Pavlov +http://www.7-zip.org diff --git a/desmume/src/windows/7z/DOC/unRarLicense.txt b/desmume/src/windows/7z/DOC/unRarLicense.txt new file mode 100644 index 000000000..5f78b728d --- /dev/null +++ b/desmume/src/windows/7z/DOC/unRarLicense.txt @@ -0,0 +1,41 @@ + ****** ***** ****** unRAR - free utility for RAR archives + ** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ****** ******* ****** License for use and distribution of + ** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ** ** ** ** ** ** FREE portable version + ~~~~~~~~~~~~~~~~~~~~~ + + The source code of unRAR utility is freeware. This means: + + 1. All copyrights to RAR and the utility unRAR are exclusively + owned by the author - Alexander Roshal. + + 2. The unRAR sources may be used in any software to handle RAR + archives without limitations free of charge, but cannot be used + to re-create the RAR compression algorithm, which is proprietary. + Distribution of modified unRAR sources in separate form or as a + part of other software is permitted, provided that it is clearly + stated in the documentation and source comments that the code may + not be used to develop a RAR (WinRAR) compatible archiver. + + 3. The unRAR utility may be freely distributed. No person or company + may charge a fee for the distribution of unRAR without written + permission from the copyright holder. + + 4. THE RAR ARCHIVER AND THE UNRAR UTILITY ARE DISTRIBUTED "AS IS". + NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE AT + YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS, + DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING + OR MISUSING THIS SOFTWARE. + + 5. Installing and using the unRAR utility signifies acceptance of + these terms and conditions of the license. + + 6. If you don't agree with terms of the license you must remove + unRAR files from your storage devices and cease to use the + utility. + + Thank you for your interest in RAR and unRAR. + + + Alexander L. Roshal \ No newline at end of file diff --git a/desmume/src/windows/7zip.cpp b/desmume/src/windows/7zip.cpp new file mode 100644 index 000000000..586c958e3 --- /dev/null +++ b/desmume/src/windows/7zip.cpp @@ -0,0 +1,367 @@ +#include "7zip.h" + +#include "7z/C/Types.h" +#include "7z/CPP/7zip/Archive/IArchive.h" +#include "7z/CPP/Common/InitializeStaticLib.h" // important! (if using a static lib) + +#include +#include +#include + +#include "7zipstreams.h" // defines OutStream and InFileStream + +STDAPI GetNumberOfFormats(UINT32 *numFormats); +STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value); +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject); + +struct ArchiveFormatInfo +{ + std::string name; + std::vector extensions; + std::string signature; + GUID guid; +}; + +static std::vector s_formatInfos; + +static std::string wstrToStr(const wchar_t* wstr) +{ + char* str = (char*)_alloca((wcslen(wstr)+1)); + sprintf(str, "%S", wstr); + return std::string(str); +} + +static std::vector tokenize(const std::string & str, const std::string & delim) +{ + std::vector tokens; + size_t p0 = 0, p1 = std::string::npos; + while(p0 != std::string::npos) + { + p1 = str.find_first_of(delim, p0); + if(p1 != p0) + { + std::string token = str.substr(p0, p1 - p0); + tokens.push_back(token); + } + p0 = str.find_first_not_of(delim, p1); + } + return tokens; +} + +static std::string s_supportedFormatsFilter; +const char* GetSupportedFormatsFilter() +{ + assert(!s_formatInfos.empty()); + if(s_supportedFormatsFilter.empty()) + { + s_supportedFormatsFilter = ""; + for(size_t i = 0; i < s_formatInfos.size(); i++) + { + for(size_t j = 0; j < s_formatInfos[i].extensions.size(); j++) + { + s_supportedFormatsFilter += ";*."; + s_supportedFormatsFilter += s_formatInfos[i].extensions[j]; + } + } + } + return s_supportedFormatsFilter.c_str(); +} + +void InitDecoder() +{ + CleanupDecoder(); + + UINT32 numFormats = 0; + GetNumberOfFormats(&numFormats); + + for(unsigned int i = 0; i < numFormats; i++) + { + PROPVARIANT var = {VT_EMPTY}; + ArchiveFormatInfo info; + + GetHandlerProperty2(i, NArchive::kName, &var); + if(var.vt == VT_BSTR) + info.name = wstrToStr(var.bstrVal); + + GetHandlerProperty2(i, NArchive::kExtension, &var); + if(var.vt == VT_BSTR) + info.extensions = tokenize(wstrToStr(var.bstrVal), " "); + + GetHandlerProperty2(i, NArchive::kStartSignature, &var); + if(var.vt == VT_BSTR) + info.signature = (const char*)var.bstrVal; // note: there's no 100% correct way of doing this with the existing 7-zip interface, but this is much better than using SysStringLen() in any way (it would return 1 for the signature "BZh", for example) + + GetHandlerProperty2(i,NArchive::kClassID,&var); + if(var.vt == VT_BSTR) + memcpy(&info.guid, var.bstrVal, 16); + else + memset(&info.guid, 0, 16); + + s_formatInfos.push_back(info); + + VariantClear((VARIANTARG*)&var); + } +} + +void CleanupDecoder() +{ + s_formatInfos.clear(); + s_supportedFormatsFilter.clear(); +} + +#include "7z/CPP/7zip/Archive/Zip/ZipHandler.h" + + +ArchiveFile::ArchiveFile(const char* filename) +{ + assert(!s_formatInfos.empty()); + + m_typeIndex = -1; + m_numItems = 0; + m_items = NULL; + m_filename = NULL; + + FILE* file = fopen(filename, "rb"); + if(!file) + return; + + m_filename = new char[strlen(filename)+1]; + strcpy(m_filename, filename); + + // detect archive type using format signature in file + for(size_t i = 0; i < s_formatInfos.size() && m_typeIndex < 0; i++) + { + fseek(file, 0, SEEK_SET); + + std::string& formatSig = s_formatInfos[i].signature; + int len = formatSig.size(); + + if(len == 0) + continue; // because some formats have no signature + + char* fileSig = (char*)_alloca(len); + fread(fileSig, 1, len, file); + + if(!memcmp(formatSig.c_str(), fileSig, len)) + m_typeIndex = i; + } + + // if no signature match has been found, detect archive type using filename. + // this is only for signature-less formats + const char* fileExt = strrchr(filename, '.'); + if(fileExt++) + { + for(size_t i = 0; i < s_formatInfos.size() && m_typeIndex < 0; i++) + { + if(s_formatInfos[i].signature.empty()) + { + std::vector& formatExts = s_formatInfos[i].extensions; + for(size_t j = 0; j < formatExts.size(); j++) + { + if(!_stricmp(formatExts[j].c_str(), fileExt)) + { + m_typeIndex = i; + break; + } + } + } + } + } + + if(m_typeIndex < 0) + { + // uncompressed + + m_numItems = 1; + m_items = new ArchiveItem[m_numItems]; + + fseek(file, 0, SEEK_END); + m_items[0].size = ftell(file); + + m_items[0].name = new char[strlen(filename)+1]; + strcpy(m_items[0].name, filename); + } + else + { + IInArchive* object = NULL; + if(SUCCEEDED(CreateObject(&s_formatInfos[m_typeIndex].guid, &IID_IInArchive, (void**)&object))) + { + InFileStream* ifs = new InFileStream(filename); + if(SUCCEEDED(object->Open(ifs,0,0))) + { + UInt32 numItems = 0; + object->GetNumberOfItems(&numItems); + m_numItems = numItems; + m_items = new ArchiveItem[m_numItems]; + + for(int i = 0; i < m_numItems; i++) + { + PROPVARIANT var = {VT_EMPTY}; + ArchiveItem& item = m_items[i]; + + object->GetProperty(i, kpidSize, &var); + item.size = var.uhVal.LowPart; + + object->GetProperty(i, kpidPath, &var); + std::string& path = wstrToStr(var.bstrVal); + item.name = new char[path.size()+1]; + strcpy(item.name, path.c_str()); + + //object->GetProperty(i, kpidMethod, &var); + //std::string& method = wstrToStr(var.bstrVal); + //item.method = new char[method.size()+1]; + //strcpy(item.method, method.c_str()); + + object->GetProperty(i, kpidEncrypted, &var); +#ifdef _NO_CRYPTO + if(var.boolVal) + item.size = 0; // don't support decompressing it, pretend size zero +#else + #error password support NYI... see client7z.cpp + item.encrypted = !!var.boolVal; +#endif + + VariantClear((VARIANTARG*)&var); + } + + object->Close(); + } + + object->Release(); + } + } + + fclose(file); +} + +ArchiveFile::~ArchiveFile() +{ + for(int i = 0; i < m_numItems; i++) + { + delete[] m_items[i].name; + } + delete[] m_items; + delete[] m_filename; +} + +const char* ArchiveFile::GetArchiveTypeName() +{ + assert(!s_formatInfos.empty()); + + if((size_t)m_typeIndex >= s_formatInfos.size()) + return ""; + + return s_formatInfos[m_typeIndex].name.c_str(); +} + +int ArchiveFile::GetNumItems() +{ + return m_numItems; +} + +int ArchiveFile::GetItemSize(int item) +{ + assert(item >= 0 && item < m_numItems); + if(!(item >= 0 && item < m_numItems)) return 0; + return m_items[item].size; +} + +const char* ArchiveFile::GetItemName(int item) +{ + //assert(item >= 0 && item < m_numItems); + if(!(item >= 0 && item < m_numItems)) return ""; + return m_items[item].name; +} + +bool ArchiveFile::IsCompressed() +{ + return (m_typeIndex >= 0); +} + +int ArchiveFile::ExtractItem(int index, unsigned char* outBuffer, int bufSize) const +{ + assert(!s_formatInfos.empty()); + //assert(index >= 0 && index < m_numItems); + if(!(index >= 0 && index < m_numItems)) return 0; + + ArchiveItem& item = m_items[index]; + + if(bufSize < item.size) + return 0; + + if(m_typeIndex < 0) + { + // uncompressed + FILE* file = fopen(m_filename, "rb"); + fread(outBuffer, 1, item.size, file); + fclose(file); + } + else + { + IInArchive* object = NULL; + HRESULT hr = E_FAIL; + if(SUCCEEDED(CreateObject(&s_formatInfos[m_typeIndex].guid, &IID_IInArchive, (void**)&object))) + { + InFileStream* ifs = new InFileStream(m_filename); + if(SUCCEEDED(object->Open(ifs,0,0))) + { + OutStream* os = new OutStream(index, outBuffer, item.size); + const UInt32 indices [1] = {index}; + hr = object->Extract(indices, 1, 0, os); + object->Close(); + } + object->Release(); + } + if(FAILED(hr)) + return 0; + } + + return item.size; +} + + + +int ArchiveFile::ExtractItem(int index, const char* outFilename) const +{ + assert(!s_formatInfos.empty()); + //assert(index >= 0 && index < m_numItems); + if(!(index >= 0 && index < m_numItems)) return 0; + + ArchiveItem& item = m_items[index]; + int rv = item.size; + + DWORD outAttributes = GetFileAttributes(outFilename); + if(outAttributes & FILE_ATTRIBUTE_READONLY) + SetFileAttributes(outFilename, outAttributes & ~FILE_ATTRIBUTE_READONLY); // temporarily remove read-only attribute so we can decompress to there + + if(m_typeIndex < 0) + { + // uncompressed + if(!CopyFile(m_filename, outFilename, false)) + rv = 0; + } + else + { + IInArchive* object = NULL; + HRESULT hr = E_FAIL; + if(SUCCEEDED(CreateObject(&s_formatInfos[m_typeIndex].guid, &IID_IInArchive, (void**)&object))) + { + InFileStream* ifs = new InFileStream(m_filename); + if(SUCCEEDED(object->Open(ifs,0,0))) + { + OutStream* os = new OutStream(index, outFilename); + const UInt32 indices [1] = {index}; + hr = object->Extract(indices, 1, 0, os); + object->Close(); + } + object->Release(); + } + if(FAILED(hr)) + rv = 0; + } + + if(outAttributes & FILE_ATTRIBUTE_READONLY) + SetFileAttributes(outFilename, outAttributes); // restore read-only attribute + + return rv; +} diff --git a/desmume/src/windows/7zip.h b/desmume/src/windows/7zip.h new file mode 100644 index 000000000..c5d6f0af7 --- /dev/null +++ b/desmume/src/windows/7zip.h @@ -0,0 +1,41 @@ +#ifndef _7ZIP_DEC_HEADER +#define _7ZIP_DEC_HEADER + +// 7zip file extraction +// NOTE: if you want to add support for opening files within archives to some part of Gens, +// consider using the higher-level interface provided by OpenArchive.h instead + +void InitDecoder(); +void CleanupDecoder(); +const char* GetSupportedFormatsFilter(); + +// simplest way of extracting a file after calling InitDecoder(): +// int size = ArchiveFile(filename).ExtractItem(0, buf, sizeof(buf)); + +struct ArchiveFile +{ + ArchiveFile(const char* filename); + virtual ~ArchiveFile(); + + int GetNumItems(); + int GetItemSize(int item); + const char* GetItemName(int item); + int ExtractItem(int item, unsigned char* outBuffer, int bufSize) const; // returns size, or 0 if failed + int ExtractItem(int item, const char* outFilename) const; + + bool IsCompressed(); + const char* GetArchiveTypeName(); + +protected: + struct ArchiveItem + { + int size; + char* name; + }; + ArchiveItem* m_items; + int m_numItems; + int m_typeIndex; + char* m_filename; +}; + +#endif diff --git a/desmume/src/windows/7zipstreams.h b/desmume/src/windows/7zipstreams.h new file mode 100644 index 000000000..3f44cab35 --- /dev/null +++ b/desmume/src/windows/7zipstreams.h @@ -0,0 +1,315 @@ +// This file is (modified) from +// FCEUX (2009) +// FCE Ultra - NES/Famicom Emulator +// Copyright (C) 2003 Xodnizel +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#ifndef _7ZIPSTREAMS_HEADER +#define _7ZIPSTREAMS_HEADER + +#include "7z/CPP/Common/MyCom.h" + +class ICountedSequentialOutStream : public ISequentialOutStream +{ +public: + virtual UINT32 Size() const = 0; +}; + +class SeqMemoryOutStream : public ICountedSequentialOutStream, private CMyUnknownImp +{ + UINT8* const output; + UINT32 pos; + const UINT32 size; + ULONG refCount; + + HRESULT STDMETHODCALLTYPE QueryInterface(REFGUID, void**) + { + return E_NOINTERFACE; + } + + HRESULT STDMETHODCALLTYPE Write(const void* data, UInt32 length, UInt32* bytesWritten) + { + if (data != NULL || size == 0) + { + //assert(length <= size - pos); + + if (length > size - pos) + length = size - pos; + + if(data) + memcpy(output + pos, data, length); + pos += length; + + if (bytesWritten) + *bytesWritten = length; + + return S_OK; + } + else + { + return E_INVALIDARG; + } + } + + MY_ADDREF_RELEASE + +public: + + SeqMemoryOutStream(void* d, UINT32 s) : output((UINT8*)d), pos(0), size(s), refCount(0) {} + + virtual ~SeqMemoryOutStream() + { + int a = 0; + } + + UINT32 Size() const + { + return pos; + } +}; + +class SeqFileOutStream : public ICountedSequentialOutStream, private CMyUnknownImp +{ + FILE* file; + UINT32 pos; + ULONG refCount; + + HRESULT STDMETHODCALLTYPE QueryInterface(REFGUID, void**) + { + return E_NOINTERFACE; + } + + HRESULT STDMETHODCALLTYPE Write(const void* data, UInt32 length, UInt32* bytesWritten) + { + if(!file) + return E_FAIL; + + if (data != NULL) + { + int written = 0; + if(data) + written = fwrite(data, 1, length, file); + + pos += written; + if (bytesWritten) + *bytesWritten = written; + + return S_OK; + } + else + { + return E_INVALIDARG; + } + } + + MY_ADDREF_RELEASE + +public: + + SeqFileOutStream(const char* outFilename) : pos(0), refCount(0) + { + file = fopen(outFilename, "wb"); + } + virtual ~SeqFileOutStream() + { + if(file) + fclose(file); + } + + UINT32 Size() const + { + return pos; + } +}; + + +class OutStream : public IArchiveExtractCallback, private CMyUnknownImp +{ + ICountedSequentialOutStream* seqStream; + const UINT32 index; + ULONG refCount; + + HRESULT STDMETHODCALLTYPE QueryInterface(REFGUID, void**) + { + return E_NOINTERFACE; + } + + HRESULT STDMETHODCALLTYPE PrepareOperation(Int32) + { + return S_OK; + } + + HRESULT STDMETHODCALLTYPE SetTotal(UInt64) + { + return S_OK; + } + + HRESULT STDMETHODCALLTYPE SetCompleted(const UInt64*) + { + return S_OK; + } + + HRESULT STDMETHODCALLTYPE SetOperationResult(Int32) + { + return S_OK; + } + + HRESULT STDMETHODCALLTYPE GetStream(UInt32 id, ISequentialOutStream** ptr, Int32 mode) + { + switch (mode) + { + case NArchive::NExtract::NAskMode::kExtract: + case NArchive::NExtract::NAskMode::kTest: + + if (id != index || ptr == NULL) + return S_FALSE; + else + *ptr = seqStream; + // fall through + case NArchive::NExtract::NAskMode::kSkip: + return S_OK; + + default: + return E_INVALIDARG; + } + } + + MY_ADDREF_RELEASE + +public: + + OutStream(UINT32 index, void* data, UINT32 size) : index(index), refCount(0) + { + seqStream = new SeqMemoryOutStream(data, size); + seqStream->AddRef(); + } + OutStream(UINT32 index, const char* outFilename) : index(index), refCount(0) + { + seqStream = new SeqFileOutStream(outFilename); + seqStream->AddRef(); + } + virtual ~OutStream() + { + //seqStream->Release(); // commented out because apparently IInArchive::Extract() calls Release one more time than it calls AddRef + } + UINT32 Size() const + { + return seqStream->Size(); + } +}; + +class InStream : public IInStream, private IStreamGetSize, private CMyUnknownImp +{ + ULONG refCount; + + HRESULT STDMETHODCALLTYPE QueryInterface(REFGUID, void**) + { + return E_NOINTERFACE; + } + + HRESULT STDMETHODCALLTYPE GetSize(UInt64* outSize) + { + if (outSize) + { + *outSize = size; + return S_OK; + } + else + { + return E_INVALIDARG; + } + } + + MY_ADDREF_RELEASE + +protected: + + UINT32 size; + +public: + + explicit InStream() : refCount(0) {} + virtual ~InStream() {} +}; + + +class InFileStream : public InStream +{ +public: + + virtual ~InFileStream() + { + if(file) + fclose(file); + } + + FILE* file; + + InFileStream(const char* fname) : file(NULL) + { + file = fopen(fname, "rb"); + if(file) + { + fseek(file, 0, SEEK_END); + size = ftell(file); + fseek(file, 0, SEEK_SET); + } + } + + HRESULT STDMETHODCALLTYPE Read(void* data, UInt32 length, UInt32* bytesRead) + { + if(!file) + return E_FAIL; + + if (data != NULL || length == 0) + { + int read = fread(data, 1, length, file); + + if (bytesRead) + *bytesRead = read; + + return S_OK; + } + else + { + return E_INVALIDARG; + } + } + + HRESULT STDMETHODCALLTYPE Seek(Int64 offset, UInt32 origin, UInt64* pos) + { + if(!file) + return E_FAIL; + + if (origin < 3) + { + fseek(file, (long)offset, origin); + origin = ftell(file); + + if (pos) + *pos = origin; + + return S_OK; + } + else + { + return E_INVALIDARG; + } + + } +}; + +#endif diff --git a/desmume/src/windows/DeSmuME_2005.vcproj b/desmume/src/windows/DeSmuME_2005.vcproj index 5e82e7673..3555252c4 100644 --- a/desmume/src/windows/DeSmuME_2005.vcproj +++ b/desmume/src/windows/DeSmuME_2005.vcproj @@ -243,7 +243,7 @@ EnableFiberSafeOptimizations="true" WholeProgramOptimization="false" AdditionalIncludeDirectories=".;..;"lua\lua-5.1.4\src";"glib-2.20.1\build";"glib-2.20.1\build\glib";.\zlib123;.\zziplib;.\winpcap;userconfig;defaultconfig" - PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;WIN32;HAVE_LIBZ;HAVE_LIBZZIP;SPU_INTERPOLATE;NOMINMAX;NDEBUG;RELEASE;EXPERIMENTAL_WIFI" + PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;WIN32;HAVE_LIBZ;HAVE_LIBZZIP;SPU_INTERPOLATE;NOMINMAX;NDEBUG;RELEASE;EXPERIMENTAL_WIFI;_NO_CRYPTO" StringPooling="true" ExceptionHandling="1" BasicRuntimeChecks="0" @@ -268,9 +268,9 @@ /> + + + + + + @@ -444,6 +456,10 @@ RelativePath=".\lightView.h" > + + @@ -492,6 +508,14 @@ RelativePath=".\ogl.cpp" > + + + + diff --git a/desmume/src/windows/DeSmuME_2008.vcproj b/desmume/src/windows/DeSmuME_2008.vcproj index 705c3c839..c6af0fd52 100644 --- a/desmume/src/windows/DeSmuME_2008.vcproj +++ b/desmume/src/windows/DeSmuME_2008.vcproj @@ -235,8 +235,8 @@ OmitFramePointers="true" EnableFiberSafeOptimizations="true" WholeProgramOptimization="false" - AdditionalIncludeDirectories=".;..;"lua\lua-5.1.4\src";"glib-2.20.1\build";"glib-2.20.1\build\glib";.\zlib123;.\zziplib;.\winpcap;userconfig;defaultconfig" - PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;WIN32;HAVE_LIBZ;HAVE_LIBZZIP;SSE2;SPU_INTERPOLATE;NOMINMAX;RELEASE;EXPERIMENTAL_WIFI;NDEBUG" + AdditionalIncludeDirectories=".;..;"lua\lua-5.1.4\src";"glib-2.20.1\build";"glib-2.20.1\build\glib";.\zlib123;.\zziplib;.\winpcap;userconfig;defaultconfig;.\7z" + PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;WIN32;HAVE_LIBZ;HAVE_LIBZZIP;SSE2;SPU_INTERPOLATE;NOMINMAX;RELEASE;EXPERIMENTAL_WIFI;NDEBUG;_NO_CRYPTO" StringPooling="true" ExceptionHandling="1" StructMemberAlignment="0" @@ -259,9 +259,9 @@ /> + + + + + + @@ -749,6 +761,10 @@ RelativePath=".\lightView.cpp" > + + @@ -777,6 +793,14 @@ RelativePath=".\ogl.cpp" > + + + + diff --git a/desmume/src/windows/OpenArchive.cpp b/desmume/src/windows/OpenArchive.cpp new file mode 100644 index 000000000..207a19970 --- /dev/null +++ b/desmume/src/windows/OpenArchive.cpp @@ -0,0 +1,674 @@ +#include "common.h" +#include "main.h" +#include "driver.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "7zip.h" +//#include "G_main.h" +//#include "G_dsound.h" +#include "resource.h" +#include "OpenArchive.h" + +static char Str_Tmp[1024]; + +LRESULT CALLBACK ArchiveFileChooser(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +static int s_archiveFileChooserResult = -1; + +static HWND s_parentHWND = NULL; +void SetArchiveParentHWND(void* hwnd) { s_parentHWND = (HWND)hwnd; } +static HWND GetArchiveParentHWND() { return s_parentHWND ? s_parentHWND : MainWindow->getHWnd(); } + +struct ArchiveFileChooserInfo +{ + ArchiveFileChooserInfo(ArchiveFile& theArchive, const char** ignoreExtensions, int& numIgnoreExtensions) : archive(theArchive) + { +tryagain: + int numItems = archive.GetNumItems(); + for(int i = 0; i < numItems; i++) + { + if(archive.GetItemSize(i)) + { + const char* name = archive.GetItemName(i); + const char* ext = strrchr(name, '.'); + bool ok = true; + if(ext++) + { + for(int j = 0; j < numIgnoreExtensions; j++) + { + const char* ext2 = ignoreExtensions[j]; + const char* wild = strchr(ext2, '*'); + if(!wild) + { + if(!_stricmp(ext, ext2)) + { + ok = false; + break; + } + } + else // very limited (end only) wildcard support + { + if(!_strnicmp(ext, ext2, wild - ext2)) + { + ok = false; + break; + } + } + } + } + if(ok) + { + ArchiveFileChooserInfo::FileInfo fi = { name, i }; + files.push_back(fi); + } + } + } + + if(files.empty() && numIgnoreExtensions) + { + // try again without any exclusions if we excluded everything in the archive + numIgnoreExtensions = 0; + goto tryagain; + } + + // strip away prefix paths that are common to all the files + bool stripping = !files.empty(); + while(stripping) + { + const char* firstName = files[0].name.c_str(); + const char* slash = strchr(firstName, '\\'); + const char* slash2 = strchr(firstName, '/'); + slash = std::max(slash, slash2); + if(!slash++) + break; + for(size_t i = 1; i < files.size(); i++) + if(strncmp(firstName, files[i].name.c_str(), slash - firstName)) + stripping = false; + if(stripping) + for(size_t i = 0; i < files.size(); i++) + files[i].name = files[i].name.substr(slash - firstName, files[i].name.length() - (slash - firstName)); + } + + // sort by filename + std::sort(files.begin(), files.end(), FileInfo::Sort); + } + +//protected: + + struct FileInfo + { + std::string name; + int itemIndex; + + static bool Sort(const FileInfo& elem1, const FileInfo& elem2) + { + int comp = elem1.name.compare(elem2.name); + return comp ? (comp < 0) : (elem1.itemIndex < elem2.itemIndex); + } + }; + + ArchiveFile& archive; + std::vector files; +}; + +int ChooseItemFromArchive(ArchiveFile& archive, bool autoChooseIfOnly1, const char** ignoreExtensions, int numIgnoreExtensions) +{ + int prevNumIgnoreExtensions = numIgnoreExtensions; + + // prepare a list of files to choose from the archive + ArchiveFileChooserInfo info (archive, ignoreExtensions, numIgnoreExtensions); + + // based on our list, decide which item in the archive to choose + + // check if there's nothing + if(info.files.size() < 1) + { +// DialogsOpen++; + MessageBox(GetArchiveParentHWND(), "The archive is either empty or encrypted.", "Nothing to load!", MB_OK | MB_ICONWARNING); +// DialogsOpen--; + return -1; + } + + // if there's only 1 item, choose it + if(info.files.size() == 1 && autoChooseIfOnly1 && numIgnoreExtensions == prevNumIgnoreExtensions) + return info.files[0].itemIndex; + + // bring up a dialog to choose the index if there's more than 1 + DialogBoxParam(hAppInst, MAKEINTRESOURCE(IDD_ARCHIVEFILECHOOSER), GetArchiveParentHWND(), (DLGPROC) ArchiveFileChooser,(LPARAM) &info); + return s_archiveFileChooserResult; +} + + + + +#define DEFAULT_EXTENSION ".tmp" +#define DEFAULT_CATEGORY "gens" + +static struct TempFiles +{ + struct TemporaryFile + { + TemporaryFile(const char* cat, const char* ext) + { + if(!ext || !*ext) ext = DEFAULT_EXTENSION; + if(!cat || !*cat) cat = DEFAULT_CATEGORY; + category = cat; + + char tempPath [1024]; + GetTempPath(1024, tempPath); + //GetTempFileName(tempPath, cat, 0, filename, ext); // alas + + char*const fname = tempPath + strlen(tempPath); + unsigned short start = (unsigned short)(timeGetTime() & 0xFFFF); + unsigned short n = start + 1; + while(n != start) + { + _snprintf(fname, 1024 - (fname - tempPath), "%s%04X%s", cat, n, ext); + FILE* file = fopen(tempPath, "wb"); + if(file) + { + // mark the temporary file as read-only and (whatever this does) temporary + DWORD attributes = GetFileAttributes(tempPath); + attributes |= FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_TEMPORARY; + SetFileAttributes(tempPath, attributes); + + fclose(file); + + // add it to our registry of files that need to be deleted, in case we fail to terminate properly + TempFiles::AddEntryToGarbageRegistry(tempPath); + + break; + } + n++; + } + strcpy(filename, tempPath); + } + TemporaryFile(const TemporaryFile& copy) + { + strcpy(filename, copy.filename); + category = copy.category; + } + TemporaryFile() + { + filename[0] = 0; + category[0] = 0; + } + bool Delete(bool returnFalseOnRegistryRemovalFailure=false) + { + if(!*filename) + return true; // guess it already didn't exist + + // remove read-only attribute so Windows will let us delete it + // (our temporary files are read-only to discourage other apps from tampering) + DWORD attributes = GetFileAttributes(filename); + if(attributes & FILE_ATTRIBUTE_READONLY) + SetFileAttributes(filename, attributes & ~FILE_ATTRIBUTE_READONLY); + + if(_unlink(filename) == 0 || errno != EACCES) + { + // remove it from our registry of files that need to be deleted, to reduce accumulation + bool removed = TempFiles::RemoveEntryFromGarbageRegistry(filename); + + *filename = '\0'; + return removed || !returnFalseOnRegistryRemovalFailure; // successfully deleted or already didn't exist, return true unless registry removal failure notification was requested and that failed + } + + // restore read-only if we couldn't delete it (not sure if this ever succeeds or matters though) + if(attributes & FILE_ATTRIBUTE_READONLY) + SetFileAttributes(filename, attributes); + + return false; // failed to delete read-only or in-use file + } + char filename [MAX_PATH]; + std::string category; + }; + + std::vector tempFiles; + + const char* GetFile(const char* category, const char* extension) + { + tempFiles.push_back(TemporaryFile(category, extension)); + return tempFiles.back().filename; + } + + void ReleaseFile(const char* filename) + { + for(int i = (int)tempFiles.size()-1; i >= 0; i--) + { + if(!strcmp(filename, tempFiles[i].filename)) + { + if(tempFiles[i].Delete()) + tempFiles.erase(tempFiles.begin() + i); + } + } + } + + void ReleaseCategory(const char* cat, const char* exceptionFilename) + { + for(int i = (int)tempFiles.size()-1; i >= 0; i--) + { + if(!strcmp(cat, tempFiles[i].category.c_str()) && + (!exceptionFilename || + strcmp(exceptionFilename, tempFiles[i].filename))) + { + if(tempFiles[i].Delete()) + tempFiles.erase(tempFiles.begin() + i); + } + } + } + + // delete all temporary files on shutdown + ~TempFiles() + { + for(size_t i = 0; i < tempFiles.size(); i++) + { + tempFiles[i].Delete(); + } + + TempFiles::CleanOutGarbageRegistry(); + } + + // run this on startup to delete any files that we failed to delete last time + // in case we crashed or were forcefully terminated + TempFiles() + { + TempFiles::CleanOutGarbageRegistry(); + } + + static void AddEntryToGarbageRegistry(const char* filename) + { + char gbgFile[1024]; + GetTempPath(1024, gbgFile); + strcat(gbgFile, "GensTempFileRecords"); + char key[64]; + int i = 0; + while(true) + { + sprintf(key, "File%d", i); + GetPrivateProfileString("Files", key, "", Str_Tmp, 1024, gbgFile); + if(!*Str_Tmp) + break; + i++; + } + WritePrivateProfileString("Files", key, filename, gbgFile); + } + static bool RemoveEntryFromGarbageRegistry(const char* filename) + { + char gbgFile[1024]; + GetTempPath(1024, gbgFile); + strcat(gbgFile, "GensTempFileRecords"); + char key[64]; + int i = 0; + int deleteSlot = -1; + while(true) + { + sprintf(key, "File%d", i); + GetPrivateProfileString("Files", key, "", Str_Tmp, 1024, gbgFile); + if(!*Str_Tmp) + break; + if(!strcmp(Str_Tmp, filename)) + deleteSlot = i; + i++; + } + --i; + if(i >= 0 && deleteSlot >= 0) + { + if(i != deleteSlot) + { + sprintf(key, "File%d", i); + GetPrivateProfileString("Files", key, "", Str_Tmp, 1024, gbgFile); + sprintf(key, "File%d", deleteSlot); + WritePrivateProfileString("Files", key, Str_Tmp, gbgFile); + } + sprintf(key, "File%d", i); + if(0 == WritePrivateProfileString("Files", key, NULL, gbgFile)) + return false; + } + if(i <= 0 && deleteSlot == 0) + _unlink(gbgFile); + return true; + } + +private: + static void CleanOutGarbageRegistry() + { + char gbgFile[1024]; + GetTempPath(1024, gbgFile); + strcat(gbgFile, "GensTempFileRecords"); + + char key[64]; + int i = 0; + while(true) + { + sprintf(key, "File%d", i); + GetPrivateProfileString("Files", key, "", Str_Tmp, 1024, gbgFile); + if(!*Str_Tmp) + break; + TemporaryFile temp; + strcpy(temp.filename, Str_Tmp); + if(!temp.Delete(true)) + i++; + } + } + +} s_tempFiles; + + +const char* GetTempFile(const char* category, const char* extension) +{ + return s_tempFiles.GetFile(category, extension); +} +void ReleaseTempFile(const char* filename) +{ + s_tempFiles.ReleaseFile(filename); +} +void ReleaseTempFileCategory(const char* cat, const char* exceptionFilename) +{ + if(!cat || !*cat) cat = DEFAULT_CATEGORY; + s_tempFiles.ReleaseCategory(cat, exceptionFilename); +} + + + +// example input Name: "C:\games.zip" +// example output LogicalName: "C:\games.zip|Sonic.smd" +// example output PhysicalName: "C:\Documents and Settings\User\Local Settings\Temp\Gens\dec3.tmp" +// assumes arguments are character buffers with 1024 bytes each +bool ObtainFile(const char* Name, char *const & LogicalName, char *const & PhysicalName, const char* category, const char** ignoreExtensions, int numIgnoreExtensions) +{ + char ArchivePaths [1024]; + strcpy(LogicalName, Name); + strcpy(PhysicalName, Name); + strcpy(ArchivePaths, Name); + char* bar = strchr(ArchivePaths, '|'); + if(bar) + { + PhysicalName[bar - ArchivePaths] = 0; // doesn't belong in the physical name + LogicalName[bar - ArchivePaths] = 0; // we'll reconstruct the logical name as we go + *bar++ = 0; // bar becomes the next logical archive path component + } + + while(true) + { + ArchiveFile archive (PhysicalName); + if(!archive.IsCompressed()) + { + return archive.GetNumItems() > 0; + } + else + { + int item = -1; + bool forceManual = false; + if(bar && *bar) // try following the in-archive part of the logical path + { + char* bar2 = strchr(bar, '|'); + if(bar2) *bar2++ = 0; + int numItems = archive.GetNumItems(); + for(int i = 0; i < numItems; i++) + { + if(archive.GetItemSize(i)) + { + const char* itemName = archive.GetItemName(i); + if(!_stricmp(itemName, bar)) + { + item = i; // match found, now we'll auto-follow the path + break; + } + } + } + if(item < 0) + { + forceManual = true; // we don't want it choosing something else without user permission + bar = NULL; // remaining archive path is invalid + } + else + bar = bar2; // advance to next archive path part + } + if(item < 0) + item = ChooseItemFromArchive(archive, !forceManual, ignoreExtensions, numIgnoreExtensions); + + const char* TempFileName = s_tempFiles.GetFile(category, strrchr(archive.GetItemName(item), '.')); + if(!archive.ExtractItem(item, TempFileName)) + s_tempFiles.ReleaseFile(TempFileName); + s_tempFiles.ReleaseFile(PhysicalName); + strcpy(PhysicalName, TempFileName); + _snprintf(LogicalName + strlen(LogicalName), 1024 - (strlen(LogicalName)+1), "|%s", archive.GetItemName(item)); + } + } +} + + + +struct ControlLayoutInfo +{ + int controlID; + + enum LayoutType // what to do when the containing window resizes + { + NONE, // leave the control where it was + RESIZE_END, // resize the control + MOVE_START, // move the control + }; + LayoutType horizontalLayout; + LayoutType verticalLayout; +}; +struct ControlLayoutState +{ + int x,y,width,height; + bool valid; + ControlLayoutState() : valid(false) {} +}; + +static ControlLayoutInfo controlLayoutInfos [] = { + {IDC_LIST1, ControlLayoutInfo::RESIZE_END, ControlLayoutInfo::RESIZE_END}, + {IDOK, ControlLayoutInfo::MOVE_START, ControlLayoutInfo::MOVE_START}, + {IDCANCEL, ControlLayoutInfo::MOVE_START, ControlLayoutInfo::MOVE_START}, +}; +static const int numControlLayoutInfos = sizeof(controlLayoutInfos)/sizeof(*controlLayoutInfos); + +static ControlLayoutState s_layoutState [numControlLayoutInfos]; +static int s_windowWidth = 182, s_windowHeight = 113; + + +LRESULT CALLBACK ArchiveFileChooser(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + RECT r, r2; + int dx1, dy1, dx2, dy2; + static std::map s_listToItemsMap; + + switch(uMsg) + { + case WM_INITDIALOG: + { +// DialogsOpen++; +// Clear_Sound_Buffer(); + +// if(Full_Screen) +// { +// while (ShowCursor(false) >= 0); +// while (ShowCursor(true) < 0); +// } + + GetWindowRect(MainWindow->getHWnd(), &r); + dx1 = (r.right - r.left) / 2; + dy1 = (r.bottom - r.top) / 2; + + GetWindowRect(hDlg, &r2); + dx2 = (r2.right - r2.left) / 2; + dy2 = (r2.bottom - r2.top) / 2; + + //SetWindowPos(hDlg, NULL, max(0, r.left + (dx1 - dx2)), max(0, r.top + (dy1 - dy2)), NULL, NULL, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); + SetWindowPos(hDlg, NULL, r.left, r.top, NULL, NULL, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); + + ArchiveFileChooserInfo& info = *(ArchiveFileChooserInfo*)lParam; + std::vector& files = info.files; + ArchiveFile& archive = info.archive; + + std::string title = "Choose File in "; + title += archive.GetArchiveTypeName(); + title += " Archive"; + SetWindowText(hDlg, title.c_str()); + + // populate list + for(size_t i = 0; i < files.size(); i++) + { + int listIndex = SendDlgItemMessage(hDlg, IDC_LIST1, LB_ADDSTRING, (WPARAM) 0, (LONG) (LPTSTR) files[i].name.c_str()); + s_listToItemsMap[listIndex] = files[i].itemIndex; + } + + SendDlgItemMessage(hDlg, IDC_LIST1, LB_SETCURSEL, (WPARAM) 0, (LPARAM) 0); + + { + RECT r3; + GetClientRect(hDlg, &r3); + s_windowWidth = r3.right - r3.left; + s_windowHeight = r3.bottom - r3.top; + } + + return true; + } break; + + case WM_SIZING: + { + // enforce a minimum window size + + LPRECT r = (LPRECT) lParam; + int minimumWidth = 281; + int minimumHeight = 117; + if(r->right - r->left < minimumWidth) + if(wParam == WMSZ_LEFT || wParam == WMSZ_TOPLEFT || wParam == WMSZ_BOTTOMLEFT) + r->left = r->right - minimumWidth; + else + r->right = r->left + minimumWidth; + if(r->bottom - r->top < minimumHeight) + if(wParam == WMSZ_TOP || wParam == WMSZ_TOPLEFT || wParam == WMSZ_TOPRIGHT) + r->top = r->bottom - minimumHeight; + else + r->bottom = r->top + minimumHeight; + return TRUE; + } + + case WM_SIZE: + { + // resize or move controls in the window as necessary when the window is resized + + int prevDlgWidth = s_windowWidth; + int prevDlgHeight = s_windowHeight; + + int dlgWidth = LOWORD(lParam); + int dlgHeight = HIWORD(lParam); + + int deltaWidth = dlgWidth - prevDlgWidth; + int deltaHeight = dlgHeight - prevDlgHeight; + + for(int i = 0; i < numControlLayoutInfos; i++) + { + ControlLayoutInfo layoutInfo = controlLayoutInfos[i]; + ControlLayoutState& layoutState = s_layoutState[i]; + + HWND hCtrl = GetDlgItem(hDlg,layoutInfo.controlID); + + int x,y,width,height; + if(layoutState.valid) + { + x = layoutState.x; + y = layoutState.y; + width = layoutState.width; + height = layoutState.height; + } + else + { + RECT r; + GetWindowRect(hCtrl, &r); + POINT p = {r.left, r.top}; + ScreenToClient(hDlg, &p); + x = p.x; + y = p.y; + width = r.right - r.left; + height = r.bottom - r.top; + } + + switch(layoutInfo.horizontalLayout) + { + case ControlLayoutInfo::RESIZE_END: width += deltaWidth; break; + case ControlLayoutInfo::MOVE_START: x += deltaWidth; break; + default: break; + } + switch(layoutInfo.verticalLayout) + { + case ControlLayoutInfo::RESIZE_END: height += deltaHeight; break; + case ControlLayoutInfo::MOVE_START: y += deltaHeight; break; + default: break; + } + + SetWindowPos(hCtrl, 0, x,y, width,height, 0); + + layoutState.x = x; + layoutState.y = y; + layoutState.width = width; + layoutState.height = height; + layoutState.valid = true; + } + + s_windowWidth = dlgWidth; + s_windowHeight = dlgHeight; + + RedrawWindow(hDlg, NULL, NULL, RDW_INVALIDATE); + } + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDC_LIST1: + if(HIWORD(wParam) == LBN_DBLCLK) + SendMessage(hDlg, WM_COMMAND, IDOK, 0); + return TRUE; + + case IDOK: + { + int listIndex = SendDlgItemMessage(hDlg, IDC_LIST1, LB_GETCURSEL, (WPARAM) 0, (LPARAM) 0); + s_archiveFileChooserResult = s_listToItemsMap[listIndex]; + s_listToItemsMap.clear(); +// if(Full_Screen) +// { +// while (ShowCursor(true) < 0); +// while (ShowCursor(false) >= 0); +// } +// DialogsOpen--; + EndDialog(hDlg, false); + } return TRUE; + + case IDCANCEL: + s_archiveFileChooserResult = -1; + s_listToItemsMap.clear(); +// if(Full_Screen) +// { +// while (ShowCursor(true) < 0); +// while (ShowCursor(false) >= 0); +// } +// DialogsOpen--; + EndDialog(hDlg, false); + return TRUE; + } + + case WM_CLOSE: + s_archiveFileChooserResult = -1; + s_listToItemsMap.clear(); +// if(Full_Screen) +// { +// while (ShowCursor(true) < 0); +// while (ShowCursor(false) >= 0); +// } +// DialogsOpen--; + EndDialog(hDlg, false); + return TRUE; + } + + return false; +} diff --git a/desmume/src/windows/OpenArchive.h b/desmume/src/windows/OpenArchive.h new file mode 100644 index 000000000..52a04c89c --- /dev/null +++ b/desmume/src/windows/OpenArchive.h @@ -0,0 +1,43 @@ +// for retrieving files from archives and/or managing temporary files + +#ifndef OPENARCHIVE_HEADER +#define OPENARCHIVE_HEADER + +#include "7zip.h" + +// ObtainFile() +// this is the main, high-level function for opening possibly-compressed files. +// you don't need to check whether the file is compressed beforehand, +// this function will figure that out and work correctly either way. +// it also does the work of bringing up a within-archive file selector dialog if necessary, +// which even allows navigating to a file within an archive that's within the archive. +// the output PhysicalName is the filename of an uncompressed file +// for you to load with fopen or whatever, +// unless the function fails (or is cancelled) in which case it will return false. +// example input Name: "C:\games.zip" +// example output LogicalName: "C:\games.zip|Sonic.smd" +// example output PhysicalName: "C:\Documents and Settings\User\Local Settings\Temp\Gens\rom7A37.smd" +// assumes the three name arguments are unique character buffers with exactly 1024 bytes each +bool ObtainFile(const char* Name, char *const & LogicalName, char *const & PhysicalName, const char* category=NULL, const char** ignoreExtensions=NULL, int numIgnoreExtensions=0); + +// ReleaseTempFileCategory() +// this is for deleting the temporary files that ObtainFile() can create. +// using it is optional because they will auto-delete on proper shutdown of the program, +// but it's nice to be able to clean up the files as early as possible. +// pass in the same "category" string you passed into ObtainFile(), +// and this will delete all files of that category. +// you can optionally specify one filename to not delete even if its category matches. +// note that any still-open files cannot be deleted yet and will be skipped. +void ReleaseTempFileCategory(const char* category, const char* exceptionFilename=NULL); + +// sets the parent window of subsequent archive selector dialogs +// NULL resets this to the default (main Gens emulator window) +void SetArchiveParentHWND(void* hwnd=NULL); + +// the rest of these are more internal utility functions, +// but they could be generally useful outside of that +const char* GetTempFile(const char* category=NULL, const char* extension=NULL); // creates a temp file and returns a path to it. extension if any should include the '.' +void ReleaseTempFile(const char* filename); // deletes a particular temporary file, by filename +int ChooseItemFromArchive(ArchiveFile& archive, bool autoChooseIfOnly1=true, const char** ignoreExtensions=0, int numIgnoreExtensions=0); // gets an index to a file within an already-open archive, using the file chooser if there's more than one choice + +#endif \ No newline at end of file diff --git a/desmume/src/windows/luaconsole.cpp b/desmume/src/windows/luaconsole.cpp new file mode 100644 index 000000000..7f638cda8 --- /dev/null +++ b/desmume/src/windows/luaconsole.cpp @@ -0,0 +1,721 @@ +#include "resource.h" +#include +#include +#include +#include +#include +#include + +#include "OpenArchive.h" + +#ifdef WIN32 +#include "common.h" +#include "main.h" +#include "driver.h" +#endif +#include "..\lua-engine.h" + +#define MAX_RECENT_SCRIPTS 15 + +static char Str_Tmp [1024]; // shadow added because the global one is completely unreliable + +char Recent_Scripts[MAX_RECENT_SCRIPTS][1024]; + +struct ControlLayoutInfo +{ + int controlID; + + enum LayoutType // what to do when the containing window resizes + { + NONE, // leave the control where it was + RESIZE_END, // resize the control + MOVE_START, // move the control + }; + LayoutType horizontalLayout; + LayoutType verticalLayout; +}; +struct ControlLayoutState +{ + int x,y,width,height; + bool valid; + ControlLayoutState() : valid(false) {} +}; + +static ControlLayoutInfo controlLayoutInfos [] = { + {IDC_LUACONSOLE, ControlLayoutInfo::RESIZE_END, ControlLayoutInfo::RESIZE_END}, + {IDC_EDIT_LUAPATH, ControlLayoutInfo::RESIZE_END, ControlLayoutInfo::NONE}, + {IDC_BUTTON_LUARUN, ControlLayoutInfo::MOVE_START, ControlLayoutInfo::NONE}, + {IDC_BUTTON_LUASTOP, ControlLayoutInfo::MOVE_START, ControlLayoutInfo::NONE}, +}; +static const int numControlLayoutInfos = sizeof(controlLayoutInfos)/sizeof(*controlLayoutInfos); + + +extern std::vector LuaScriptHWnds; +struct LuaPerWindowInfo { + std::string filename; + HANDLE fileWatcherThread; + bool started; + bool closeOnStop; + bool subservient; + int width; int height; + ControlLayoutState layoutState [numControlLayoutInfos]; + LuaPerWindowInfo() : fileWatcherThread(NULL), started(false), closeOnStop(false), subservient(false), width(405), height(244) {} +}; +std::map LuaWindowInfo; +static char Lua_Dir[1024]=""; + +void RequestAbortLuaScript(int uid, const char* message) { +LUA_LuaStop(); +} + + +int WINAPI FileSysWatcher (LPVOID arg) +{ + HWND hDlg = (HWND)arg; + LuaPerWindowInfo& info = LuaWindowInfo[hDlg]; + + while(true) + { + char filename [1024], directory [1024]; + + strncpy(filename, info.filename.c_str(), 1024); + filename[1023] = 0; + strcpy(directory, filename); + char* slash = strrchr(directory, '/'); + slash = std::max(slash, strrchr(directory, '\\')); + if(slash) + *slash = 0; + + char* bar = strchr(filename, '|'); + if(bar) *bar = '\0'; + + WIN32_FILE_ATTRIBUTE_DATA origData; + GetFileAttributesEx (filename, GetFileExInfoStandard, (LPVOID)&origData); + + HANDLE hNotify = FindFirstChangeNotification(directory, FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE); + + if(hNotify) + { + DWORD dwWaitResult = WaitForSingleObject(hNotify, 500); + + if(dwWaitResult != STATUS_TIMEOUT) + { + if(dwWaitResult == WAIT_ABANDONED) + return dwWaitResult; + + WIN32_FILE_ATTRIBUTE_DATA data; + GetFileAttributesEx (filename, GetFileExInfoStandard, (LPVOID)&data); + + // at this point it could be any file in the directory that changed + // so check to make sure it was the file we care about + if(memcmp(&origData.ftLastWriteTime, &data.ftLastWriteTime, sizeof(FILETIME))) + { + RequestAbortLuaScript((int)hDlg, "terminated to reload the script"); + PostMessage(hDlg, WM_COMMAND, IDC_BUTTON_LUARUN, 0); + } + } + + //FindNextChangeNotification(hNotify); // let's not try to reuse it... + FindCloseChangeNotification(hNotify); // but let's at least make sure to release it! + } + else + { + Sleep(500); + } + } + + return 0; +} + +void RegisterWatcherThread (HWND hDlg) +{ + HANDLE thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) FileSysWatcher, (LPVOID) hDlg, CREATE_SUSPENDED, NULL); + SetThreadPriority(thread, THREAD_PRIORITY_LOWEST); + + LuaPerWindowInfo& info = LuaWindowInfo[hDlg]; + info.fileWatcherThread = thread; + + ResumeThread(thread); +} +void KillWatcherThread (HWND hDlg) +{ + LuaPerWindowInfo& info = LuaWindowInfo[hDlg]; + TerminateThread(info.fileWatcherThread, 0); + info.fileWatcherThread = NULL; +} + + +// some extensions that might commonly be near lua files that almost certainly aren't lua files. +static const char* s_nonLuaExtensions [] = {"txt", "nfo", "htm", "html", "jpg", "jpeg", "png", "bmp", "gif", "mp3", "wav", "lnk", "exe", "bat", "gmv", "gm2", "luasav", "sav", "srm", "brm", "cfg", "wch", "gs*", "bin","smd","gen","32x","cue","iso","raw"}; + + +void Update_Recent_Script(const char* Path, bool dontPutAtTop) +{ + char LogicalName[1024], PhysicalName[1024]; + bool exists = ObtainFile(Path, LogicalName, PhysicalName, "luacheck", s_nonLuaExtensions, sizeof(s_nonLuaExtensions)/sizeof(*s_nonLuaExtensions)); + ReleaseTempFileCategory("luacheck"); // delete the temporary (physical) file if any + + if(!exists) + return; + + int i; + + for(i = 0; i < MAX_RECENT_SCRIPTS; i++) + { + if (!(strcmp(Recent_Scripts[i], Path))) + { + // move recent item to the top of the list + if(i == 0 || dontPutAtTop) + return; + char temp [1024]; + strcpy(temp, Recent_Scripts[i]); + int j; + for(j = i; j > 0; j--) + strcpy(Recent_Scripts[j], Recent_Scripts[j-1]); + strcpy(Recent_Scripts[0], temp); +// MustUpdateMenu = 1; + return; + } + } + + if(!dontPutAtTop) + { + // add to start of recent list + for(i = MAX_RECENT_SCRIPTS-1; i > 0; i--) + strcpy(Recent_Scripts[i], Recent_Scripts[i - 1]); + + strcpy(Recent_Scripts[0], Path); + } + else + { + // add to end of recent list + for(i = 0; i < MAX_RECENT_SCRIPTS; i++) + { + if(!*Recent_Scripts[i]) + { + strcpy(Recent_Scripts[i], Path); + break; + } + } + } + +// MustUpdateMenu = 1; +} + +HWND IsScriptFileOpen(const char* Path) +{ + for(std::map::iterator iter = LuaWindowInfo.begin(); iter != LuaWindowInfo.end(); ++iter) + { + LuaPerWindowInfo& info = iter->second; + const char* filename = info.filename.c_str(); + const char* pathPtr = Path; + + // case-insensitive slash-direction-insensitive compare + bool same = true; + while(*filename || *pathPtr) + { + if((*filename == '/' || *filename == '\\') && (*pathPtr == '/' || *pathPtr == '\\')) + { + do {filename++;} while(*filename == '/' || *filename == '\\'); + do {pathPtr++;} while(*pathPtr == '/' || *pathPtr == '\\'); + } + else if(tolower(*filename) != tolower(*pathPtr)) + { + same = false; + break; + } + else + { + filename++; + pathPtr++; + } + } + + if(same) + return iter->first; + } + return NULL; +} + + +void PrintToWindowConsole(int hDlgAsInt, const char* str) +{ + HWND hDlg = (HWND)hDlgAsInt; + HWND hConsole = GetDlgItem(hDlg, IDC_LUACONSOLE); + + int length = GetWindowTextLength(hConsole); + if(length >= 250000) + { + // discard first half of text if it's getting too long + SendMessage(hConsole, EM_SETSEL, 0, length/2); + SendMessage(hConsole, EM_REPLACESEL, false, (LPARAM)""); + length = GetWindowTextLength(hConsole); + } + SendMessage(hConsole, EM_SETSEL, length, length); + + LuaPerWindowInfo& info = LuaWindowInfo[hDlg]; + + { + SendMessage(hConsole, EM_REPLACESEL, false, (LPARAM)str); + } +} + +extern int Show_Genesis_Screen(HWND hWnd); +void OnStart(int hDlgAsInt) +{ + HWND hDlg = (HWND)hDlgAsInt; + LuaPerWindowInfo& info = LuaWindowInfo[hDlg]; + info.started = true; + EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_LUABROWSE), false); // disable browse while running because it misbehaves if clicked in a frameadvance loop + EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_LUASTOP), true); + SetWindowText(GetDlgItem(hDlg, IDC_BUTTON_LUARUN), "Restart"); + SetWindowText(GetDlgItem(hDlg, IDC_LUACONSOLE), ""); // clear the console +// Show_Genesis_Screen(HWnd); // otherwise we might never show the first thing the script draws +} + +void OnStop(int hDlgAsInt, bool statusOK) +{ + HWND hDlg = (HWND)hDlgAsInt; + LuaPerWindowInfo& info = LuaWindowInfo[hDlg]; + + HWND prevWindow = GetActiveWindow(); + SetActiveWindow(hDlg); // bring to front among other script/secondary windows, since a stopped script will have some message for the user that would be easier to miss otherwise + if(prevWindow == MainWindow->getHWnd()) SetActiveWindow(prevWindow); + + info.started = false; + EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_LUABROWSE), true); + EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_LUASTOP), false); + SetWindowText(GetDlgItem(hDlg, IDC_BUTTON_LUARUN), "Run"); +// if(statusOK) +// Show_Genesis_Screen(MainWindow->getHWnd()); // otherwise we might never show the last thing the script draws + if(info.closeOnStop) + PostMessage(hDlg, WM_CLOSE, 0, 0); +} + +const char* MakeScriptPathAbsolute(const char* filename, const char* extraDirToCheck); + +void UpdateFileEntered(HWND hDlg) +{ + char local_str_tmp [1024]; + SendDlgItemMessage(hDlg,IDC_EDIT_LUAPATH,WM_GETTEXT,(WPARAM)512,(LPARAM)local_str_tmp); + + // if it exists, make sure we're using an absolute path to it + const char* filename = local_str_tmp; + FILE* file = fopen(filename, "rb"); + if(file) + { + fclose(file); + filename = MakeScriptPathAbsolute(local_str_tmp, NULL); + if(filename != local_str_tmp && stricmp(filename, local_str_tmp)) + { + SendDlgItemMessage(hDlg,IDC_EDIT_LUAPATH,WM_SETTEXT,(WPARAM)512,(LPARAM)filename); + SendDlgItemMessage(hDlg,IDC_EDIT_LUAPATH,EM_SETSEL,0,-1); + SendDlgItemMessage(hDlg,IDC_EDIT_LUAPATH,EM_SETSEL,-1,-1); + return; + } + } + + // use ObtainFile to support opening files within archives + char LogicalName[1024], PhysicalName[1024]; + bool exists = ObtainFile(filename, LogicalName, PhysicalName, "luacheck", s_nonLuaExtensions, sizeof(s_nonLuaExtensions)/sizeof(*s_nonLuaExtensions)); + bool readonly = exists ? ((GetFileAttributes(PhysicalName) & FILE_ATTRIBUTE_READONLY) != 0) : (strchr(LogicalName, '|') != NULL || strchr(filename, '|') != NULL); + ReleaseTempFileCategory("luacheck"); // delete the temporary (physical) file if any + + if(exists) + { + LuaPerWindowInfo& info = LuaWindowInfo[hDlg]; + info.filename = LogicalName; + + char* slash = strrchr(LogicalName, '/'); + slash = std::max(slash, strrchr(LogicalName, '\\')); + if(slash) + slash++; + else + slash = LogicalName; + SetWindowText(hDlg, slash); +// Build_Main_Menu(); + + PostMessage(hDlg, WM_COMMAND, IDC_BUTTON_LUARUN, 0); + } + + const char* ext = strrchr(LogicalName, '.'); + bool isLuaFile = ext && !_stricmp(ext, ".lua"); + if(exists) + { + SetWindowText(GetDlgItem(hDlg, IDC_BUTTON_LUAEDIT), isLuaFile ? (readonly ? "View" : "Edit") : "Open"); + EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_LUAEDIT), true); + } + else + { + SetWindowText(GetDlgItem(hDlg, IDC_BUTTON_LUAEDIT), "Create"); + EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_LUAEDIT), isLuaFile && !readonly); + } +} + +//extern "C" int Clear_Sound_Buffer(void); + +void RunLuaScriptFile(int uid, const char* filenameCStr) { +LUA_LoadLuaCode(filenameCStr); +} +void StopLuaScript(int uid) { +LUA_LuaStop(); +} + +static int Change_File_L(char *Dest, char *Dir, char *Titre, char *Filter, char *Ext, HWND hwnd) +{ + OPENFILENAME ofn; + +// SetCurrentDirectory(Desmume_Path); + + if (!strcmp(Dest, "")) + { + strcpy(Dest, "default."); + strcat(Dest, Ext); + } + + memset(&ofn, 0, sizeof(OPENFILENAME)); + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hwnd; + ofn.hInstance = hAppInst; + ofn.lpstrFile = Dest; + ofn.nMaxFile = 2047; + ofn.lpstrFilter = Filter; + ofn.nFilterIndex = 1; + ofn.lpstrInitialDir = Dir; + ofn.lpstrTitle = Titre; + ofn.lpstrDefExt = Ext; + ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + + if (GetOpenFileName(&ofn)) return 1; + + return 0; +} + +LRESULT CALLBACK LuaScriptProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + RECT r; + RECT r2; + int dx1, dy1, dx2, dy2; + + switch(uMsg) + { + case WM_INITDIALOG: { + if(std::find(LuaScriptHWnds.begin(), LuaScriptHWnds.end(), hDlg) == LuaScriptHWnds.end()) + { + LuaScriptHWnds.push_back(hDlg); +// Build_Main_Menu(); + } +// if (Full_Screen) +// { +// while (ShowCursor(false) >= 0); +// while (ShowCursor(true) < 0); +// } + +// HANDLE hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_LUA)); +// SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon); + + // remove the 30000 character limit from the console control + SendMessage(GetDlgItem(hDlg, IDC_LUACONSOLE),EM_LIMITTEXT,0,0); + + GetWindowRect(MainWindow->getHWnd(), &r); + dx1 = (r.right - r.left) / 2; + dy1 = (r.bottom - r.top) / 2; + + GetWindowRect(hDlg, &r2); + dx2 = (r2.right - r2.left) / 2; + dy2 = (r2.bottom - r2.top) / 2; + + int windowIndex = std::find(LuaScriptHWnds.begin(), LuaScriptHWnds.end(), hDlg) - LuaScriptHWnds.begin(); + int staggerOffset = windowIndex * 24; + r.left += staggerOffset; + r.right += staggerOffset; + r.top += staggerOffset; + r.bottom += staggerOffset; + + // push it away from the main window if we can + const int width = (r.right-r.left); + const int width2 = (r2.right-r2.left); + if(r.left+width2 + width < GetSystemMetrics(SM_CXSCREEN)) + { + r.right += width; + r.left += width; + } + else if((int)r.left - (int)width2 > 0) + { + r.right -= width2; + r.left -= width2; + } + + SetWindowPos(hDlg, NULL, r.left, r.top, NULL, NULL, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); + + LuaPerWindowInfo info; + { + RECT r3; + GetClientRect(hDlg, &r3); + info.width = r3.right - r3.left; + info.height = r3.bottom - r3.top; + } + LuaWindowInfo[hDlg] = info; + RegisterWatcherThread(hDlg); + +// OpenLuaContext((int)hDlg, PrintToWindowConsole, OnStart, OnStop); + + DragAcceptFiles(hDlg, TRUE); + + return true; + } break; + + case WM_MENUSELECT: + case WM_ENTERSIZEMOVE: +// Clear_Sound_Buffer(); + break; + + case WM_SIZING: + { + // enforce a minimum window size + + LPRECT r = (LPRECT) lParam; + int minimumWidth = 333; + int minimumHeight = 117; + if(r->right - r->left < minimumWidth) + if(wParam == WMSZ_LEFT || wParam == WMSZ_TOPLEFT || wParam == WMSZ_BOTTOMLEFT) + r->left = r->right - minimumWidth; + else + r->right = r->left + minimumWidth; + if(r->bottom - r->top < minimumHeight) + if(wParam == WMSZ_TOP || wParam == WMSZ_TOPLEFT || wParam == WMSZ_TOPRIGHT) + r->top = r->bottom - minimumHeight; + else + r->bottom = r->top + minimumHeight; + } + return TRUE; + + case WM_SIZE: + { + // resize or move controls in the window as necessary when the window is resized + + LuaPerWindowInfo& windowInfo = LuaWindowInfo[hDlg]; + int prevDlgWidth = windowInfo.width; + int prevDlgHeight = windowInfo.height; + + int dlgWidth = LOWORD(lParam); + int dlgHeight = HIWORD(lParam); + + int deltaWidth = dlgWidth - prevDlgWidth; + int deltaHeight = dlgHeight - prevDlgHeight; + + for(int i = 0; i < numControlLayoutInfos; i++) + { + ControlLayoutInfo layoutInfo = controlLayoutInfos[i]; + ControlLayoutState& layoutState = windowInfo.layoutState[i]; + + HWND hCtrl = GetDlgItem(hDlg,layoutInfo.controlID); + + int x,y,width,height; + if(layoutState.valid) + { + x = layoutState.x; + y = layoutState.y; + width = layoutState.width; + height = layoutState.height; + } + else + { + RECT r; + GetWindowRect(hCtrl, &r); + POINT p = {r.left, r.top}; + ScreenToClient(hDlg, &p); + x = p.x; + y = p.y; + width = r.right - r.left; + height = r.bottom - r.top; + } + + switch(layoutInfo.horizontalLayout) + { + case ControlLayoutInfo::RESIZE_END: width += deltaWidth; break; + case ControlLayoutInfo::MOVE_START: x += deltaWidth; break; + default: break; + } + switch(layoutInfo.verticalLayout) + { + case ControlLayoutInfo::RESIZE_END: height += deltaHeight; break; + case ControlLayoutInfo::MOVE_START: y += deltaHeight; break; + default: break; + } + + SetWindowPos(hCtrl, 0, x,y, width,height, 0); + + layoutState.x = x; + layoutState.y = y; + layoutState.width = width; + layoutState.height = height; + layoutState.valid = true; + } + + windowInfo.width = dlgWidth; + windowInfo.height = dlgHeight; + + RedrawWindow(hDlg, NULL, NULL, RDW_INVALIDATE); + } + break; + + case WM_COMMAND: + { + switch(LOWORD(wParam)) + { + case IDC_BUTTON_LUABROWSE: + { + LuaPerWindowInfo& info = LuaWindowInfo[hDlg]; + char Str_Tmp [1024]; // shadow added because the global one is unreliable + strcpy(Str_Tmp,info.filename.c_str()); + SendDlgItemMessage(hDlg,IDC_EDIT_LUAPATH,WM_GETTEXT,(WPARAM)512,(LPARAM)Str_Tmp); + char* bar = strchr(Str_Tmp, '|'); + if(bar) *bar = '\0'; +// DialogsOpen++; +// Clear_Sound_Buffer(); + if(Change_File_L(Str_Tmp, Lua_Dir, "Load Lua Script", "Lua Script\0*.lua*\0All Files\0*.*\0\0", "lua", hDlg)) + { + SendDlgItemMessage(hDlg,IDC_EDIT_LUAPATH,WM_SETTEXT,0,(LPARAM)Str_Tmp); + } +// DialogsOpen--; + + } break; + case IDC_BUTTON_LUAEDIT: + { + LuaPerWindowInfo& info = LuaWindowInfo[hDlg]; + char Str_Tmp [1024]; // shadow added because the global one is unreliable + strcpy(Str_Tmp,info.filename.c_str()); + SendDlgItemMessage(hDlg,IDC_EDIT_LUAPATH,WM_GETTEXT,(WPARAM)512,(LPARAM)Str_Tmp); + char LogicalName[1024], PhysicalName[1024]; + bool exists = ObtainFile(Str_Tmp, LogicalName, PhysicalName, "luaview", s_nonLuaExtensions, sizeof(s_nonLuaExtensions)/sizeof(*s_nonLuaExtensions)); + bool created = false; + if(!exists) + { + FILE* file = fopen(Str_Tmp, "r"); + if(!file) + { + file = fopen(Str_Tmp, "w"); + if(file) + { + created = true; + exists = true; + strcpy(PhysicalName, Str_Tmp); + } + } + if(file) + fclose(file); + } + if(exists) + { + // tell the OS to open the file with its associated editor, + // without blocking on it or leaving a command window open. + ShellExecute(NULL, "open", PhysicalName, NULL, NULL, SW_SHOWNORMAL); + } + if(created) + { + UpdateFileEntered(hDlg); + } + } break; + case IDC_EDIT_LUAPATH: + { + switch(HIWORD(wParam)) + { + case EN_CHANGE: + { + UpdateFileEntered(hDlg); + } break; + } + } break; + case IDC_BUTTON_LUARUN: + { + HWND focus = GetFocus(); + HWND textbox = GetDlgItem(hDlg, IDC_EDIT_LUAPATH); + if(focus != textbox) + SetActiveWindow(MainWindow->getHWnd()); + + LuaPerWindowInfo& info = LuaWindowInfo[hDlg]; + strcpy(Str_Tmp,info.filename.c_str()); + char LogicalName[1024], PhysicalName[1024]; + bool exists = ObtainFile(Str_Tmp, LogicalName, PhysicalName, "luarun", s_nonLuaExtensions, sizeof(s_nonLuaExtensions)/sizeof(*s_nonLuaExtensions)); + Update_Recent_Script(LogicalName, info.subservient); + RunLuaScriptFile((int)hDlg, PhysicalName); + } break; + case IDC_BUTTON_LUASTOP: + { + PrintToWindowConsole((int)hDlg, "user clicked stop button\r\n"); + SetActiveWindow(MainWindow->getHWnd()); + StopLuaScript((int)hDlg); + } break; + case IDC_NOTIFY_SUBSERVIENT: + { + LuaPerWindowInfo& info = LuaWindowInfo[hDlg]; + info.subservient = lParam ? true : false; + } break; + //case IDOK: + case IDCANCEL: + { LuaPerWindowInfo& info = LuaWindowInfo[hDlg]; + if(info.filename.empty()) + { +// if (Full_Screen) +// { +// while (ShowCursor(true) < 0); +// while (ShowCursor(false) >= 0); +// } +// DialogsOpen--; + DragAcceptFiles(hDlg, FALSE); + KillWatcherThread(hDlg); + LuaScriptHWnds.erase(remove(LuaScriptHWnds.begin(), LuaScriptHWnds.end(), hDlg), LuaScriptHWnds.end()); + LuaWindowInfo.erase(hDlg); +// CloseLuaContext((int)hDlg); +// Build_Main_Menu(); + EndDialog(hDlg, true); + } + } return true; + } + + return false; + } break; + + case WM_CLOSE: + { + LuaPerWindowInfo& info = LuaWindowInfo[hDlg]; + + PrintToWindowConsole((int)hDlg, "user closed script window\r\n"); + StopLuaScript((int)hDlg); + if(info.started) + { + // not stopped yet, wait to close until we are, otherwise we'll crash + info.closeOnStop = true; + return false; + } + +// if (Full_Screen) +// { +// while (ShowCursor(true) < 0); +// while (ShowCursor(false) >= 0); +// } +// DialogsOpen--; + DragAcceptFiles(hDlg, FALSE); + KillWatcherThread(hDlg); + LuaScriptHWnds.erase(remove(LuaScriptHWnds.begin(), LuaScriptHWnds.end(), hDlg), LuaScriptHWnds.end()); + LuaWindowInfo.erase(hDlg); +// CloseLuaContext((int)hDlg); +// Build_Main_Menu(); + EndDialog(hDlg, true); + } return true; + + case WM_DROPFILES: + { + HDROP hDrop = (HDROP)wParam; + DragQueryFile(hDrop, 0, Str_Tmp, 1024); + DragFinish(hDrop); + SendDlgItemMessage(hDlg,IDC_EDIT_LUAPATH,WM_SETTEXT,0,(LPARAM)Str_Tmp ); + UpdateFileEntered(hDlg); + } return true; + } + + return false; +} + diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index 3ace6a222..fe1831979 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -84,6 +84,7 @@ #include "soundView.h" #include "commandline.h" #include "../lua-engine.h" +#include "7zip.h" #include "directx/ddraw.h" @@ -206,6 +207,9 @@ static BOOL lostFocusPause = TRUE; static BOOL lastPauseFromLostFocus = FALSE; static int FrameLimit = 1; +std::vector LuaScriptHWnds; +LRESULT CALLBACK LuaScriptProc(HWND, UINT, WPARAM, LPARAM); + //=========================== view tools TOOLSCLASS *ViewDisasm_ARM7 = NULL; TOOLSCLASS *ViewDisasm_ARM9 = NULL; @@ -1924,6 +1928,8 @@ int _main() HK_StateLoadSlot(cmdline.load_slot); } + InitDecoder(); + MainWindow->Show(SW_NORMAL); run(); SaveRecentRoms(); @@ -2385,6 +2391,9 @@ void OpenRecentROM(int listNum) NDS_UnPause(); } +#include "OpenArchive.h" +#include "utils/xstring.h" + LRESULT OpenFile() { HWND hwnd = MainWindow->getHWnd(); @@ -2405,7 +2414,7 @@ LRESULT OpenFile() // should be, and later transform prior assigning to the OPENFILENAME structure strncpy (fileFilter, "NDS ROM file (*.nds)|*.nds|NDS/GBA ROM File (*.ds.gba)|*.ds.gba|",512); #ifdef HAVE_LIBZZIP - strncpy (fileFilter, "All Usable Files (*.nds, *.ds.gba, *.zip, *.gz)|*.nds;*.ds.gba;*.zip;*.gz|",512); + strncpy (fileFilter, "All Usable Files (*.nds, *.ds.gba, *.zip, *.gz, *.7z, *.rar, *.bz2)|*.nds;*.ds.gba;*.zip;*.gz;*.7z;*.rar;*.bz2|",512); #endif #ifdef HAVE_LIBZZIP @@ -2414,6 +2423,10 @@ LRESULT OpenFile() #ifdef HAVE_LIBZ strncat (fileFilter, "GZipped NDS ROM file (*.gz)|*.gz|",512 - strlen(fileFilter)); #endif + strncat (fileFilter, "7Zipped NDS ROM file (*.7z)|*.7z|",512 - strlen(fileFilter)); + strncat (fileFilter, "RARed NDS ROM file (*.rar)|*.rar|",512 - strlen(fileFilter)); + strncat (fileFilter, "BZipped NDS ROM file (*.bz2)|*.bz2|",512 - strlen(fileFilter)); + strncat (fileFilter, "Any file (*.*)|*.*||",512 - strlen(fileFilter)); filterSize = strlen(fileFilter); @@ -2428,19 +2441,39 @@ LRESULT OpenFile() ofn.lpstrDefExt = "nds"; ofn.Flags = OFN_NOCHANGEDIR; - if(!GetOpenFileName(&ofn)) - { - if (romloaded) - { - CheatsSearchReset(); - NDS_UnPause(); //Restart emulation if no new rom chosen - } + const char* s_nonRomExtensions [] = {"txt", "nfo", "htm", "html", "jpg", "jpeg", "png", "bmp", "gif", "mp3", "wav", "lnk", "exe", "bat", "gmv", "gm2", "lua", "luasav", "sav", "srm", "brm", "cfg", "wch", "gs*"}; + + if (GetOpenFileName(&ofn) == NULL) { + NDS_UnPause(); return 0; } + char LogicalName[1024], PhysicalName[1024]; + + if(!strcmp(getExtension(filename).c_str(), "gz") || !strcmp(getExtension(filename).c_str(), "nds.gz")) { + if(LoadROM(filename)) { + NDS_UnPause(); + return 0; + } + } + + if(!ObtainFile(filename, LogicalName, PhysicalName, "rom", s_nonRomExtensions, sizeof(s_nonRomExtensions)/sizeof(*s_nonRomExtensions))) { + return 0; + } + +// if(!GetOpenFileName(&ofn)) +// { +// if (romloaded) +// { +// CheatsSearchReset(); +// NDS_UnPause(); //Restart emulation if no new rom chosen +// } +// return 0; +// } + //LOG("%s\r\n", filename); #ifdef EXPERIMENTAL_GBASLOT - if(LoadROM(filename)) + if(LoadROM(PhysicalName)) #else if(LoadROM(filename, bad_glob_cflash_disk_image_file)) #endif @@ -3494,6 +3527,13 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM } } return 0; + case IDC_NEW_LUA_SCRIPT: + if(LuaScriptHWnds.size() < 16) + { + CreateDialog(hAppInst, MAKEINTRESOURCE(IDD_LUA), MainWindow->getHWnd(), (DLGPROC) LuaScriptProc); + // DialogsOpen++; + } + break; case IDC_LANGENGLISH: SaveLanguage(0); ChangeLanguage(0); @@ -4460,3 +4500,81 @@ void UpdateLuaMenus() if (!LUA_LuaRunning()) mii.fState |= MFS_DISABLED; SetMenuItemInfo (mainMenu, ID_FILE_STOPLUASCRIPT, FALSE, &mii); } + +static char Lua_Dir [1024]; +char Desmume_Path [1024]; + +static const char* PathWithoutPrefixDotOrSlash(const char* path) +{ + while(*path && + ((*path == '.' && (path[1] == '\\' || path[1] == '/')) || + *path == '\\' || *path == '/' || *path == ' ')) + path++; + return path; +} + +const char* MakeScriptPathAbsolute(const char* filename, const char* extraDirToCheck) +{ + static char filename2 [1024]; + if(filename[0] && filename[1] != ':') + { + char tempFile [1024], curDir [1024]; + strncpy(tempFile, filename, 1024); + tempFile[1023] = 0; + const char* tempFilePtr = PathWithoutPrefixDotOrSlash(tempFile); + for(int i=0; i<=4; i++) + { + if((!*tempFilePtr || tempFilePtr[1] != ':') && i != 2) + strcpy(curDir, i!=1 ? ((i!=3||!extraDirToCheck) ? Lua_Dir : extraDirToCheck) : Desmume_Path); + else + curDir[0] = 0; + _snprintf(filename2, 1024, "%s%s", curDir, tempFilePtr); + char* bar = strchr(filename2, '|'); + if(bar) *bar = 0; + FILE* file = fopen(filename2, "rb"); + if(bar) *bar = '|'; + if(file || i==4) + filename = filename2; + if(file) + { + fclose(file); + break; + } + } + } + return filename; +} + +extern void RequestAbortLuaScript(int uid, const char* message); + +const char* OpenLuaScriptConsole(const char* filename, const char* extraDirToCheck) +{ + if(LuaScriptHWnds.size() < 16) + { + // make the filename absolute before loading + filename = MakeScriptPathAbsolute(filename, extraDirToCheck); + + // now check if it's already open and load it if it isn't + HWND IsScriptFileOpen(const char* Path); + HWND scriptHWnd = IsScriptFileOpen(filename); + if(!scriptHWnd) + { + HWND prevWindow = GetActiveWindow(); + + HWND hDlg = CreateDialog(hAppInst, MAKEINTRESOURCE(IDD_LUA), MainWindow->getHWnd(), (DLGPROC) LuaScriptProc); + SendMessage(hDlg,WM_COMMAND,IDC_NOTIFY_SUBSERVIENT,TRUE); + SendDlgItemMessage(hDlg,IDC_EDIT_LUAPATH,WM_SETTEXT,0,(LPARAM)filename); +// DialogsOpen++; + + SetActiveWindow(prevWindow); + } + else + { + RequestAbortLuaScript((int)scriptHWnd, "terminated to restart because of a call to gens.openscript"); + SendMessage(scriptHWnd, WM_COMMAND, IDC_BUTTON_LUARUN, 0); + } + } + else return "Too many script windows are already open."; + + return NULL; +} \ No newline at end of file diff --git a/desmume/src/windows/ram_search.cpp b/desmume/src/windows/ram_search.cpp index 57dd662d0..e07d7099e 100644 --- a/desmume/src/windows/ram_search.cpp +++ b/desmume/src/windows/ram_search.cpp @@ -51,7 +51,7 @@ HWND RamSearchHWnd = NULL; extern HWND RamWatchHWnd; -extern char Str_Tmp[1024]; +static char Str_Tmp[1024]; int Rom_Size; //TODO unsigned char* Rom_Data; //TODO diff --git a/desmume/src/windows/ramwatch.cpp b/desmume/src/windows/ramwatch.cpp index 35f373f12..ca0244602 100644 --- a/desmume/src/windows/ramwatch.cpp +++ b/desmume/src/windows/ramwatch.cpp @@ -16,7 +16,7 @@ HWND RamWatchHWnd = NULL; #define MESSAGEBOXPARENT (RamWatchHWnd ? RamWatchHWnd : MainWindow->getHWnd()) -char Str_Tmp[1024]; +static char Str_Tmp[1024]; std::string Rom_Name; static HMENU ramwatchmenu; @@ -552,7 +552,7 @@ bool Load_Watches(bool clear, const char* filename) -int Change_File_L(char *Dest, char *Dir, char *Titre, char *Filter, char *Ext, HWND hwnd) +static int Change_File_L(char *Dest, char *Dir, char *Titre, char *Filter, char *Ext, HWND hwnd) { OPENFILENAME ofn; diff --git a/desmume/src/windows/resource.h b/desmume/src/windows/resource.h index 9d9df60a3..bd0ba45a7 100644 --- a/desmume/src/windows/resource.h +++ b/desmume/src/windows/resource.h @@ -104,6 +104,16 @@ #define ID_FILE_RUNLUASCRIPT 306 #define ID_FILE_STOPLUASCRIPT 307 #define ID_FILE_RELOADLUASCRIPT 308 +#define IDC_LUACONSOLE 309 +#define IDC_EDIT_LUAPATH 310 +#define IDC_BUTTON_LUARUN 311 +#define IDC_BUTTON_LUASTOP 312 +#define IDC_BUTTON_LUABROWSE 313 +#define IDC_BUTTON_LUAEDIT 314 +#define IDC_NOTIFY_SUBSERVIENT 315 +#define IDD_ARCHIVEFILECHOOSER 316 +#define IDD_LUA 317 +#define IDC_NEW_LUA_SCRIPT 318 #define IDC_DES_BOX 402 #define IDC_R0 403 #define IDC_R1 404 diff --git a/desmume/src/windows/resources.rc b/desmume/src/windows/resources.rc index 8f1ed69422ece0753b0207faa98692e41eded2c6..ecf209e2b0697d74483e4596b14b3cef1eaf3b42 100644 GIT binary patch delta 864 zcmZ`%O=}ZT6upy~*G!7(hbb1TB}qkMu}UU!(v*TEjp+wXlbA-ka1o33qY{#qwiHCv zLcxU~)`4E=u7cpsF2t+^T}Yv{3;%)b&Rsw&C@wtnrV170@$QBD?m6$A``+7^-P^V9 zN6X5xYgv7xZS5-_{L7Lpt{H+T#NdZbxl`1rcSZ3p!cFy|j)ta-ErU@!hhOSVO zO107N+UtZrNd>eI(+FL~`5J)tHsN7WNe-EJdS$ z6+k&gX0K&vTJO@wnG$Z5TPa515omPEHbDNUK;an4c=)0=Kua8yOHyKnyy5xFEi9+LPPh5WqB8ve6AR1qH(yz@KwPEi4?eNjOy~Q^!nWP! sJByXW_B<=rtW(ny#2NXvpAu%&U~J#O%?8BmK+FNeoZB~WbIAk%0Px}?5dZ)H