7z support + Rom selection for archives containing multiple rom files + General fixes/improvements when dealing with archives (cheats, save states, saved data, etc.)

This commit is contained in:
Souryo 2016-06-17 20:53:05 -04:00
parent 47ecfa5954
commit 298a789cfc
87 changed files with 9481 additions and 513 deletions

View file

@ -164,9 +164,9 @@ void AutoRomTest::RecordFromMovie(string testFilename, string movieFilename)
void AutoRomTest::RecordFromTest(string newTestFilename, string existingTestFilename) void AutoRomTest::RecordFromTest(string newTestFilename, string existingTestFilename)
{ {
ZipReader zipReader; ZipReader zipReader;
zipReader.LoadZipArchive(existingTestFilename); zipReader.LoadArchive(existingTestFilename);
std::stringstream testMovie = zipReader.ExtractFile("TestMovie.mmo"); std::stringstream testMovie = zipReader.GetStream("TestMovie.mmo");
std::stringstream testRom = zipReader.ExtractFile("TestRom.nes"); std::stringstream testRom = zipReader.GetStream("TestRom.nes");
if(testMovie && testRom) { if(testMovie && testRom) {
Console::Pause(); Console::Pause();
@ -182,10 +182,10 @@ void AutoRomTest::RecordFromTest(string newTestFilename, string existingTestFile
int32_t AutoRomTest::Run(string filename) int32_t AutoRomTest::Run(string filename)
{ {
ZipReader zipReader; ZipReader zipReader;
zipReader.LoadZipArchive(filename); zipReader.LoadArchive(filename);
std::stringstream testData = zipReader.ExtractFile("TestData.mrt"); std::stringstream testData = zipReader.GetStream("TestData.mrt");
std::stringstream testMovie = zipReader.ExtractFile("TestMovie.mmo"); std::stringstream testMovie = zipReader.GetStream("TestMovie.mmo");
std::stringstream testRom = zipReader.ExtractFile("TestRom.nes"); std::stringstream testRom = zipReader.GetStream("TestRom.nes");
if(testData) { if(testData) {
char header[3]; char header[3];

View file

@ -250,7 +250,7 @@ uint32_t BaseMapper::GetCHRPageCount()
string BaseMapper::GetBatteryFilename() string BaseMapper::GetBatteryFilename()
{ {
return FolderUtilities::GetSaveFolder() + FolderUtilities::GetFilename(_romFilename, false) + ".sav"; return FolderUtilities::GetSaveFolder() + FolderUtilities::GetFilename(_romName, false) + ".sav";
} }
void BaseMapper::RestoreOriginalPrgRam() void BaseMapper::RestoreOriginalPrgRam()
@ -330,6 +330,7 @@ void BaseMapper::Initialize(RomData &romData)
_mapperID = romData.MapperID; _mapperID = romData.MapperID;
_subMapperID = romData.SubMapperID; _subMapperID = romData.SubMapperID;
_romName = romData.RomName;
_romFilename = romData.Filename; _romFilename = romData.Filename;
_batteryFilename = GetBatteryFilename(); _batteryFilename = GetBatteryFilename();
_saveRamSize = GetSaveRamSize(); //Needed because we need to call SaveBattery() in the destructor (and calling virtual functions in the destructor doesn't work correctly) _saveRamSize = GetSaveRamSize(); //Needed because we need to call SaveBattery() in the destructor (and calling virtual functions in the destructor doesn't work correctly)
@ -522,6 +523,11 @@ GameSystem BaseMapper::GetGameSystem()
return _gameSystem; return _gameSystem;
} }
string BaseMapper::GetRomName()
{
return _romName;
}
uint32_t BaseMapper::GetCrc32() uint32_t BaseMapper::GetCrc32()
{ {
return _crc32; return _crc32;

View file

@ -54,7 +54,9 @@ private:
bool _onlyChrRam = false; bool _onlyChrRam = false;
GameSystem _gameSystem; GameSystem _gameSystem;
bool _hasBusConflicts = false; bool _hasBusConflicts = false;
string _romFilename; string _romFilename;
string _romName;
bool _allowRegisterRead = false; bool _allowRegisterRead = false;
uint8_t _isReadRegisterAddr[0x10000]; uint8_t _isReadRegisterAddr[0x10000];
@ -170,6 +172,7 @@ public:
GameSystem GetGameSystem(); GameSystem GetGameSystem();
uint32_t GetCrc32(); uint32_t GetCrc32();
string GetRomName();
uint8_t ReadRAM(uint16_t addr); uint8_t ReadRAM(uint16_t addr);
virtual void WriteRAM(uint16_t addr, uint8_t value); virtual void WriteRAM(uint16_t addr, uint8_t value);

View file

@ -3,6 +3,7 @@
#include "MessageManager.h" #include "MessageManager.h"
#include "../Utilities/PNGHelper.h" #include "../Utilities/PNGHelper.h"
#include "../Utilities/FolderUtilities.h" #include "../Utilities/FolderUtilities.h"
#include "Console.h"
BaseVideoFilter::BaseVideoFilter() BaseVideoFilter::BaseVideoFilter()
{ {
@ -55,8 +56,9 @@ uint8_t* BaseVideoFilter::GetOutputBuffer()
return _outputBuffer; return _outputBuffer;
} }
void BaseVideoFilter::TakeScreenshot(string romFilename) void BaseVideoFilter::TakeScreenshot()
{ {
string romFilename = FolderUtilities::GetFilename(Console::GetRomName(), false);
uint32_t* frameBuffer = (uint32_t*)new uint8_t[_bufferSize]; uint32_t* frameBuffer = (uint32_t*)new uint8_t[_bufferSize];
_frameLock.Acquire(); _frameLock.Acquire();

View file

@ -31,7 +31,7 @@ public:
uint8_t* GetOutputBuffer(); uint8_t* GetOutputBuffer();
void SendFrame(uint16_t *ppuOutputBuffer); void SendFrame(uint16_t *ppuOutputBuffer);
void TakeScreenshot(string romFilename); void TakeScreenshot();
virtual FrameInfo GetFrameInfo() = 0; virtual FrameInfo GetFrameInfo() = 0;
}; };

View file

@ -36,10 +36,10 @@ void Console::Release()
Console::Instance.reset(new Console()); Console::Instance.reset(new Console());
} }
void Console::Initialize(string romFilename, stringstream *filestream, string ipsFilename) void Console::Initialize(string romFilename, stringstream *filestream, string ipsFilename, int32_t archiveFileIndex)
{ {
MessageManager::SendNotification(ConsoleNotificationType::GameStopped); MessageManager::SendNotification(ConsoleNotificationType::GameStopped);
shared_ptr<BaseMapper> mapper = MapperFactory::InitializeFromFile(romFilename, filestream, ipsFilename); shared_ptr<BaseMapper> mapper = MapperFactory::InitializeFromFile(romFilename, filestream, ipsFilename, archiveFileIndex);
if(mapper) { if(mapper) {
_romFilepath = romFilename; _romFilepath = romFilename;
@ -77,7 +77,7 @@ void Console::Initialize(string romFilename, stringstream *filestream, string ip
VideoDecoder::GetInstance()->StartThread(); VideoDecoder::GetInstance()->StartThread();
FolderUtilities::AddKnowGameFolder(FolderUtilities::GetFolderName(romFilename)); FolderUtilities::AddKnowGameFolder(FolderUtilities::GetFolderName(romFilename));
MessageManager::DisplayMessage("GameLoaded", FolderUtilities::GetFilename(romFilename, false)); MessageManager::DisplayMessage("GameLoaded", FolderUtilities::GetFilename(_mapper->GetRomName(), false));
if(EmulationSettings::GetOverclockRate() != 100) { if(EmulationSettings::GetOverclockRate() != 100) {
MessageManager::DisplayMessage("ClockRate", std::to_string(EmulationSettings::GetOverclockRate()) + "%"); MessageManager::DisplayMessage("ClockRate", std::to_string(EmulationSettings::GetOverclockRate()) + "%");
} }
@ -93,10 +93,10 @@ void Console::ApplyIpsPatch(string ipsFilename)
Console::Resume(); Console::Resume();
} }
void Console::LoadROM(string filepath, stringstream *filestream) void Console::LoadROM(string filepath, stringstream *filestream, int32_t archiveFileIndex)
{ {
Console::Pause(); Console::Pause();
Instance->Initialize(filepath, filestream); Instance->Initialize(filepath, filestream, "", archiveFileIndex);
Console::Resume(); Console::Resume();
} }
@ -105,25 +105,26 @@ bool Console::LoadROM(string filename, uint32_t crc32Hash)
string currentRomFilepath = Console::GetROMPath(); string currentRomFilepath = Console::GetROMPath();
string currentFolder = FolderUtilities::GetFolderName(currentRomFilepath); string currentFolder = FolderUtilities::GetFolderName(currentRomFilepath);
if(!currentRomFilepath.empty()) { if(!currentRomFilepath.empty()) {
if(RomLoader::GetCRC32(Console::GetROMPath()) == crc32Hash) { if(Console::GetCrc32() == crc32Hash) {
//Current game matches, no need to do anything //Current game matches, no need to do anything
return true; return true;
} }
} }
int32_t archiveFileIndex = -1;
for(string folder : FolderUtilities::GetKnowGameFolders()) { for(string folder : FolderUtilities::GetKnowGameFolders()) {
string match = RomLoader::FindMatchingRomInFolder(folder, filename, crc32Hash, true); string match = RomLoader::FindMatchingRomInFolder(folder, filename, crc32Hash, true, archiveFileIndex);
if(!match.empty()) { if(!match.empty()) {
Console::LoadROM(match); Console::LoadROM(match, nullptr, archiveFileIndex);
return true; return true;
} }
} }
//Perform slow CRC32 search for ROM //Perform slow CRC32 search for ROM
for(string folder : FolderUtilities::GetKnowGameFolders()) { for(string folder : FolderUtilities::GetKnowGameFolders()) {
string match = RomLoader::FindMatchingRomInFolder(folder, filename, crc32Hash, false); string match = RomLoader::FindMatchingRomInFolder(folder, filename, crc32Hash, false, archiveFileIndex);
if(!match.empty()) { if(!match.empty()) {
Console::LoadROM(match); Console::LoadROM(match, nullptr, archiveFileIndex);
return true; return true;
} }
} }
@ -136,9 +137,22 @@ string Console::GetROMPath()
return Instance->_romFilepath; return Instance->_romFilepath;
} }
string Console::GetRomName()
{
if(Instance->_mapper) {
return Instance->_mapper->GetRomName();
} else {
return "";
}
}
uint32_t Console::GetCrc32() uint32_t Console::GetCrc32()
{ {
if(Instance->_mapper) {
return Instance->_mapper->GetCrc32(); return Instance->_mapper->GetCrc32();
} else {
return 0;
}
} }
void Console::Reset(bool softReset) void Console::Reset(bool softReset)

View file

@ -37,7 +37,7 @@ class Console
bool _initialized = false; bool _initialized = false;
void ResetComponents(bool softReset); void ResetComponents(bool softReset);
void Initialize(string filename, stringstream *filestream = nullptr, string ipsFilename = ""); void Initialize(string filename, stringstream *filestream = nullptr, string ipsFilename = "", int32_t archiveFileIndex = -1);
double UpdateNesModel(bool sendNotification); double UpdateNesModel(bool sendNotification);
public: public:
@ -61,10 +61,11 @@ class Console
static void LoadState(istream &loadStream); static void LoadState(istream &loadStream);
static void LoadState(uint8_t *buffer, uint32_t bufferSize); static void LoadState(uint8_t *buffer, uint32_t bufferSize);
static void LoadROM(string filepath, stringstream *filestream = nullptr); static void LoadROM(string filepath, stringstream *filestream = nullptr, int32_t archiveFileIndex = -1);
static bool LoadROM(string romName, uint32_t crc32Hash); static bool LoadROM(string romName, uint32_t crc32Hash);
static void ApplyIpsPatch(string ipsFilename); static void ApplyIpsPatch(string ipsFilename);
static string GetROMPath(); static string GetROMPath();
static string GetRomName();
static uint32_t GetCrc32(); static uint32_t GetCrc32();
static bool IsRunning(); static bool IsRunning();

View file

@ -15,7 +15,7 @@ Debugger* Debugger::Instance = nullptr;
Debugger::Debugger(shared_ptr<Console> console, shared_ptr<CPU> cpu, shared_ptr<PPU> ppu, shared_ptr<MemoryManager> memoryManager, shared_ptr<BaseMapper> mapper) Debugger::Debugger(shared_ptr<Console> console, shared_ptr<CPU> cpu, shared_ptr<PPU> ppu, shared_ptr<MemoryManager> memoryManager, shared_ptr<BaseMapper> mapper)
{ {
_romFilepath = Console::GetROMPath(); _romName = Console::GetRomName();
_console = console; _console = console;
_cpu = cpu; _cpu = cpu;
_ppu = ppu; _ppu = ppu;
@ -36,14 +36,14 @@ Debugger::Debugger(shared_ptr<Console> console, shared_ptr<CPU> cpu, shared_ptr<
_bpUpdateNeeded = false; _bpUpdateNeeded = false;
_executionStopped = false; _executionStopped = false;
LoadCdlFile(FolderUtilities::CombinePath(FolderUtilities::GetDebuggerFolder(), FolderUtilities::GetFilename(_romFilepath, false) + ".cdl")); LoadCdlFile(FolderUtilities::CombinePath(FolderUtilities::GetDebuggerFolder(), FolderUtilities::GetFilename(_romName, false) + ".cdl"));
Debugger::Instance = this; Debugger::Instance = this;
} }
Debugger::~Debugger() Debugger::~Debugger()
{ {
SaveCdlFile(FolderUtilities::CombinePath(FolderUtilities::GetDebuggerFolder(), FolderUtilities::GetFilename(_romFilepath, false) + ".cdl")); SaveCdlFile(FolderUtilities::CombinePath(FolderUtilities::GetDebuggerFolder(), FolderUtilities::GetFilename(_romName, false) + ".cdl"));
_stopFlag = true; _stopFlag = true;

View file

@ -6,14 +6,14 @@
using std::atomic; using std::atomic;
using std::deque; using std::deque;
#include "CPU.h"
#include "PPU.h"
#include "DebugState.h" #include "DebugState.h"
#include "Breakpoint.h" #include "Breakpoint.h"
#include "TraceLogger.h" #include "TraceLogger.h"
#include "../Utilities/SimpleLock.h" #include "../Utilities/SimpleLock.h"
#include "CodeDataLogger.h" #include "CodeDataLogger.h"
class CPU;
class PPU;
class MemoryManager; class MemoryManager;
class Console; class Console;
class Disassembler; class Disassembler;
@ -75,7 +75,7 @@ private:
uint32_t _flags; uint32_t _flags;
string _romFilepath; string _romName;
string _outputCache; string _outputCache;
atomic<int32_t> _stepCount; atomic<int32_t> _stepCount;
atomic<int32_t> _ppuStepCount; atomic<int32_t> _ppuStepCount;

View file

@ -38,7 +38,7 @@ GameServerConnection::~GameServerConnection()
void GameServerConnection::SendGameInformation() void GameServerConnection::SendGameInformation()
{ {
Console::Pause(); Console::Pause();
GameInformationMessage gameInfo(Console::GetROMPath(), Console::GetCrc32(), _controllerPort, EmulationSettings::CheckFlag(EmulationFlags::Paused)); GameInformationMessage gameInfo(Console::GetRomName(), Console::GetCrc32(), _controllerPort, EmulationSettings::CheckFlag(EmulationFlags::Paused));
SendNetMessage(gameInfo); SendNetMessage(gameInfo);
SaveStateMessage saveState; SaveStateMessage saveState;
SendNetMessage(saveState); SendNetMessage(saveState);
@ -94,7 +94,7 @@ void GameServerConnection::ProcessHandshakeResponse(HandShakeMessage* message)
MessageManager::DisplayToast("Net Play", _connectionData->PlayerName + " (" + playerPortMessage + ") connected.", _connectionData->AvatarData, _connectionData->AvatarSize); MessageManager::DisplayToast("Net Play", _connectionData->PlayerName + " (" + playerPortMessage + ") connected.", _connectionData->AvatarData, _connectionData->AvatarSize);
if(Console::GetROMPath().size() > 0) { if(Console::GetRomName().size() > 0) {
SendGameInformation(); SendGameInformation();
} }

View file

@ -79,7 +79,7 @@ private:
_hdNesTiles.clear(); _hdNesTiles.clear();
_tileInfoByKey.clear(); _tileInfoByKey.clear();
string hdPackFolder = FolderUtilities::CombinePath(FolderUtilities::GetHdPackFolder(), FolderUtilities::GetFilename(Console::GetROMPath(), false)); string hdPackFolder = FolderUtilities::CombinePath(FolderUtilities::GetHdPackFolder(), FolderUtilities::GetFilename(Console::GetRomName(), false));
string hdPackDefinitionFile = FolderUtilities::CombinePath(hdPackFolder, "hires.txt"); string hdPackDefinitionFile = FolderUtilities::CombinePath(hdPackFolder, "hires.txt");
ifstream packDefinition(hdPackDefinitionFile, ios::in | ios::binary); ifstream packDefinition(hdPackDefinitionFile, ios::in | ios::binary);
while(packDefinition.good()) { while(packDefinition.good()) {

View file

@ -232,11 +232,11 @@ BaseMapper* MapperFactory::GetMapperFromID(RomData &romData)
return nullptr; return nullptr;
} }
shared_ptr<BaseMapper> MapperFactory::InitializeFromFile(string romFilename, stringstream *filestream, string ipsFilename) shared_ptr<BaseMapper> MapperFactory::InitializeFromFile(string romFilename, stringstream *filestream, string ipsFilename, int32_t archiveFileIndex)
{ {
RomLoader loader; RomLoader loader;
if(loader.LoadFile(romFilename, filestream, ipsFilename)) { if(loader.LoadFile(romFilename, filestream, ipsFilename, archiveFileIndex)) {
RomData romData = loader.GetRomData(); RomData romData = loader.GetRomData();
shared_ptr<BaseMapper> mapper(GetMapperFromID(romData)); shared_ptr<BaseMapper> mapper(GetMapperFromID(romData));

View file

@ -10,5 +10,5 @@ class MapperFactory
public: public:
static const uint16_t FdsMapperID = 65535; static const uint16_t FdsMapperID = 65535;
static shared_ptr<BaseMapper> InitializeFromFile(string romFilename, stringstream *filestream, string ipsFilename); static shared_ptr<BaseMapper> InitializeFromFile(string romFilename, stringstream *filestream, string ipsFilename, int32_t archiveFileIndex);
}; };

View file

@ -219,14 +219,13 @@ struct MovieHeader
bool Movie::Save() bool Movie::Save()
{ {
string romFilepath = Console::GetROMPath(); string romFilename = Console::GetRomName();
string romFilename = FolderUtilities::GetFilename(romFilepath, true);
MovieHeader header = {}; MovieHeader header = {};
header.MesenVersion = EmulationSettings::GetMesenVersion(); header.MesenVersion = EmulationSettings::GetMesenVersion();
header.MovieFormatVersion = Movie::MovieFormatVersion; header.MovieFormatVersion = Movie::MovieFormatVersion;
header.SaveStateFormatVersion = SaveStateManager::FileFormatVersion; header.SaveStateFormatVersion = SaveStateManager::FileFormatVersion;
header.RomCrc32 = RomLoader::GetCRC32(romFilepath); header.RomCrc32 = Console::GetCrc32();
header.Region = (uint32_t)Console::GetNesModel(); header.Region = (uint32_t)Console::GetNesModel();
header.ConsoleType = (uint32_t)EmulationSettings::GetConsoleType(); header.ConsoleType = (uint32_t)EmulationSettings::GetConsoleType();
header.ExpansionDevice = (uint32_t)EmulationSettings::GetExpansionDevice(); header.ExpansionDevice = (uint32_t)EmulationSettings::GetExpansionDevice();
@ -360,8 +359,8 @@ bool Movie::Load(std::stringstream &file, bool autoLoadRom)
bool loadedGame = true; bool loadedGame = true;
if(autoLoadRom) { if(autoLoadRom) {
string currentRom = Console::GetROMPath(); string currentRom = Console::GetRomName();
if(currentRom.empty() || header.RomCrc32 != RomLoader::GetCRC32(currentRom)) { if(currentRom.empty() || header.RomCrc32 != Console::GetCrc32()) {
//Loaded game isn't the same as the game used for the movie, attempt to load the correct game //Loaded game isn't the same as the game used for the movie, attempt to load the correct game
loadedGame = Console::LoadROM(romFilename, header.RomCrc32); loadedGame = Console::LoadROM(romFilename, header.RomCrc32);
} else { } else {

View file

@ -31,6 +31,7 @@ enum class GameSystem
struct RomData struct RomData
{ {
string RomName;
string Filename; string Filename;
uint16_t MapperID; uint16_t MapperID;

View file

@ -1,46 +1,70 @@
#pragma once #pragma once
#include "stdafx.h" #include "stdafx.h"
#include "../Utilities/ZipReader.h"
#include "../Utilities/SZReader.h"
#include "RomLoader.h" #include "RomLoader.h"
#include "iNesLoader.h" #include "iNesLoader.h"
#include "FdsLoader.h" #include "FdsLoader.h"
bool RomLoader::LoadFromZip(istream &zipFile) vector<string> RomLoader::GetArchiveRomList(string filename)
{
ifstream in(filename, ios::in | ios::binary);
if(in) {
uint8_t header[2];
in.read((char*)header, 2);
in.close();
if(memcmp(header, "PK", 2) == 0) {
ZipReader reader;
reader.LoadArchive(filename);
return reader.GetFileList({ ".nes", ".fds" });
} else if(memcmp(header, "7z", 2) == 0) {
SZReader reader;
reader.LoadArchive(filename);
return reader.GetFileList({ ".nes", ".fds" });
}
}
return{};
}
bool RomLoader::LoadFromArchive(istream &zipFile, ArchiveReader& reader, int32_t archiveFileIndex)
{ {
bool result = false; bool result = false;
uint32_t fileSize; uint32_t fileSize;
uint8_t* buffer = ReadFile(zipFile, fileSize); uint8_t* buffer = ReadFile(zipFile, fileSize);
ZipReader reader; reader.LoadArchive(buffer, fileSize);
reader.LoadZipArchive(buffer, fileSize);
vector<string> fileList = reader.GetFileList({ ".nes", ".fds" });
int32_t currentIndex = 0;
if(archiveFileIndex > (int32_t)fileList.size()) {
return false;
}
vector<string> fileList = reader.GetFileList();
for(string filename : fileList) { for(string filename : fileList) {
std::transform(filename.begin(), filename.end(), filename.begin(), ::tolower); if(archiveFileIndex == -1 || archiveFileIndex == currentIndex) {
if(filename.length() > 4) {
if(filename.substr(filename.length() - 4, 4).compare(".nes") == 0 || filename.substr(filename.length() - 4, 4).compare(".fds") == 0) {
uint8_t* fileBuffer = nullptr; uint8_t* fileBuffer = nullptr;
size_t size = 0; size_t size = 0;
reader.ExtractFile(filename, &fileBuffer, size); reader.ExtractFile(filename, &fileBuffer, size);
if(fileBuffer) { if(fileBuffer) {
result = LoadFromMemory(fileBuffer, size); result = LoadFromMemory(fileBuffer, size, FolderUtilities::GetFilename(filename, true));
delete[] fileBuffer; delete[] fileBuffer;
break; break;
} }
} }
} currentIndex++;
} }
delete[] buffer; delete[] buffer;
return result; return result;
} }
bool RomLoader::LoadFromStream(istream &romFile) bool RomLoader::LoadFromStream(istream &romFile, string romName)
{ {
uint32_t fileSize; uint32_t fileSize;
uint8_t* buffer = ReadFile(romFile, fileSize); uint8_t* buffer = ReadFile(romFile, fileSize);
bool result = LoadFromMemory(buffer, fileSize); bool result = LoadFromMemory(buffer, fileSize, romName);
delete[] buffer; delete[] buffer;
return result; return result;
@ -64,7 +88,7 @@ uint8_t* RomLoader::ReadFile(istream &file, uint32_t &fileSize)
return buffer; return buffer;
} }
bool RomLoader::LoadFromMemory(uint8_t* buffer, size_t length) bool RomLoader::LoadFromMemory(uint8_t* buffer, size_t length, string romName)
{ {
vector<uint8_t> fileData(buffer, buffer + length); vector<uint8_t> fileData(buffer, buffer + length);
@ -85,11 +109,22 @@ bool RomLoader::LoadFromMemory(uint8_t* buffer, size_t length)
_romData.RawData = fileData; _romData.RawData = fileData;
_romData.Crc32 = CRC32::GetCRC(buffer, length); _romData.Crc32 = CRC32::GetCRC(buffer, length);
_romData.RomName = romName;
_romData.Filename = _filename;
if(_romData.System == GameSystem::Unknown) {
//Use filename to detect PAL/VS system games
if(_filename.find("(e)") != string::npos || _filename.find("(E)") != string::npos) {
_romData.System = GameSystem::NesPal;
} else if(_filename.find("(VS)") != string::npos || _filename.find("(vs)") != string::npos || _filename.find("(Vs)") != string::npos || _filename.find("(vS)") != string::npos) {
_romData.System = GameSystem::VsUniSystem;
}
}
return !_romData.Error; return !_romData.Error;
} }
bool RomLoader::LoadFile(string filename, istream *filestream, string ipsFilename) bool RomLoader::LoadFile(string filename, istream *filestream, string ipsFilename, int32_t archiveFileIndex)
{ {
_filename = filename; _filename = filename;
_ipsFilename = ipsFilename; _ipsFilename = ipsFilename;
@ -110,45 +145,44 @@ bool RomLoader::LoadFile(string filename, istream *filestream, string ipsFilenam
input->seekg(0, ios::beg); input->seekg(0, ios::beg);
input->read(header, 15); input->read(header, 15);
input->seekg(0, ios::beg); input->seekg(0, ios::beg);
if(memcmp(header, "PK", 2) == 0) { if(memcmp(header, "PK", 2) == 0) {
return LoadFromZip(*input); ZipReader reader;
return LoadFromArchive(*input, reader, archiveFileIndex);
} else if(memcmp(header, "7z", 2) == 0) {
SZReader reader;
return LoadFromArchive(*input, reader, archiveFileIndex);
} else if(memcmp(header, "NES\x1a", 4) == 0 || memcmp(header, "FDS\x1a", 4) == 0 || memcmp(header, "\x1*NINTENDO-HVC*", 15) == 0) { } else if(memcmp(header, "NES\x1a", 4) == 0 || memcmp(header, "FDS\x1a", 4) == 0 || memcmp(header, "\x1*NINTENDO-HVC*", 15) == 0) {
return LoadFromStream(*input); if(archiveFileIndex > 0) {
return false;
}
return LoadFromStream(*input, FolderUtilities::GetFilename(filename, true));
} }
return false; return false;
} }
RomData RomLoader::GetRomData() RomData RomLoader::GetRomData()
{ {
_romData.Filename = _filename;
if(_romData.System == GameSystem::Unknown) {
//Use filename to detect PAL/VS system games
if(_filename.find("(e)") != string::npos || _filename.find("(E)") != string::npos) {
_romData.System = GameSystem::NesPal;
} else if(_filename.find("(VS)") != string::npos || _filename.find("(vs)") != string::npos || _filename.find("(Vs)") != string::npos || _filename.find("(vS)") != string::npos) {
_romData.System = GameSystem::VsUniSystem;
}
}
return _romData; return _romData;
} }
uint32_t RomLoader::GetCRC32(string filename) int32_t RomLoader::FindMatchingRomInFile(string filename, uint32_t crc32Hash)
{ {
RomLoader loader; RomLoader loader;
uint32_t crc = 0; int32_t fileIndex = 0;
if(loader.LoadFile(filename)) { while(loader.LoadFile(filename, nullptr, "", fileIndex)) {
crc = loader._romData.Crc32; if(crc32Hash == loader._romData.Crc32) {
return fileIndex;
} }
return crc; fileIndex++;
}
return -1;
} }
string RomLoader::FindMatchingRomInFolder(string folder, string romFilename, uint32_t crc32Hash, bool useFastSearch) string RomLoader::FindMatchingRomInFolder(string folder, string romFilename, uint32_t crc32Hash, bool useFastSearch, int32_t &archiveFileIndex)
{ {
std::transform(romFilename.begin(), romFilename.end(), romFilename.begin(), ::tolower); std::transform(romFilename.begin(), romFilename.end(), romFilename.begin(), ::tolower);
vector<string> validExtensions = { { "*.nes", "*.zip", "*.fds" } }; vector<string> validExtensions = { { "*.nes", "*.zip", "*.7z", "*.fds" } };
vector<string> romFiles; vector<string> romFiles;
for(string extension : validExtensions) { for(string extension : validExtensions) {
@ -163,7 +197,8 @@ string RomLoader::FindMatchingRomInFolder(string folder, string romFilename, uin
string originalFilename = romFile; string originalFilename = romFile;
std::transform(romFile.begin(), romFile.end(), romFile.begin(), ::tolower); std::transform(romFile.begin(), romFile.end(), romFile.begin(), ::tolower);
if(FolderUtilities::GetFilename(romFile, true).compare(romFilename) == 0) { if(FolderUtilities::GetFilename(romFile, true).compare(romFilename) == 0) {
if(RomLoader::GetCRC32(romFile) == crc32Hash) { archiveFileIndex = RomLoader::FindMatchingRomInFile(romFile, crc32Hash);
if(archiveFileIndex >= 0) {
return originalFilename; return originalFilename;
} }
} }
@ -171,12 +206,13 @@ string RomLoader::FindMatchingRomInFolder(string folder, string romFilename, uin
} else { } else {
for(string romFile : romFiles) { for(string romFile : romFiles) {
//Slower search by CRC value //Slower search by CRC value
if(RomLoader::GetCRC32(romFile) == crc32Hash) { archiveFileIndex = RomLoader::FindMatchingRomInFile(romFile, crc32Hash);
//Matching ROM found if(archiveFileIndex >= 0) {
return romFile; return romFile;
} }
} }
} }
archiveFileIndex = -1;
return ""; return "";
} }

View file

@ -3,7 +3,7 @@
#include "stdafx.h" #include "stdafx.h"
#include <algorithm> #include <algorithm>
#include "../Utilities/FolderUtilities.h" #include "../Utilities/FolderUtilities.h"
#include "../Utilities/ZipReader.h" #include "../Utilities/ArchiveReader.h"
#include "../Utilities/CRC32.h" #include "../Utilities/CRC32.h"
#include "../Utilities/IpsPatcher.h" #include "../Utilities/IpsPatcher.h"
#include "RomData.h" #include "RomData.h"
@ -15,16 +15,17 @@ class RomLoader
string _filename; string _filename;
string _ipsFilename; string _ipsFilename;
bool LoadFromZip(istream &zipFile); bool LoadFromArchive(istream &zipFile, ArchiveReader& reader, int32_t archiveFileIndex = -1);
bool LoadFromStream(istream &romFile); bool LoadFromStream(istream &romFile, string romName);
uint32_t GetFileSize(istream &file); uint32_t GetFileSize(istream &file);
uint8_t* ReadFile(istream &file, uint32_t &fileSize); uint8_t* ReadFile(istream &file, uint32_t &fileSize);
bool LoadFromMemory(uint8_t* buffer, size_t length); bool LoadFromMemory(uint8_t* buffer, size_t length, string romName);
static int32_t FindMatchingRomInFile(string filename, uint32_t crc32Hash);
public: public:
bool LoadFile(string filename, istream *filestream = nullptr, string ipsFilename = ""); bool LoadFile(string filename, istream *filestream = nullptr, string ipsFilename = "", int32_t archiveFileIndex = -1);
RomData GetRomData(); RomData GetRomData();
static uint32_t GetCRC32(string filename); static string FindMatchingRomInFolder(string folder, string romFilename, uint32_t crc32Hash, bool useFastSearch, int32_t &archiveFileIndex);
static string FindMatchingRomInFolder(string folder, string romFilename, uint32_t crc32Hash, bool useFastSearch); static vector<string> GetArchiveRomList(string filename);
}; };

View file

@ -11,7 +11,7 @@ const uint32_t SaveStateManager::FileFormatVersion;
string SaveStateManager::GetStateFilepath(int stateIndex) string SaveStateManager::GetStateFilepath(int stateIndex)
{ {
string folder = FolderUtilities::GetSaveStateFolder(); string folder = FolderUtilities::GetSaveStateFolder();
string filename = FolderUtilities::GetFilename(Console::GetROMPath(), false) + "_" + std::to_string(stateIndex) + ".mst"; string filename = FolderUtilities::GetFilename(Console::GetRomName(), false) + "_" + std::to_string(stateIndex) + ".mst";
return FolderUtilities::CombinePath(folder, filename); return FolderUtilities::CombinePath(folder, filename);
} }

View file

@ -170,9 +170,9 @@ bool VideoDecoder::IsRunning()
return _decodeThread != nullptr; return _decodeThread != nullptr;
} }
void VideoDecoder::TakeScreenshot(string romFilename) void VideoDecoder::TakeScreenshot()
{ {
if(_videoFilter) { if(_videoFilter) {
_videoFilter->TakeScreenshot(romFilename); _videoFilter->TakeScreenshot();
} }
} }

View file

@ -46,7 +46,7 @@ public:
~VideoDecoder(); ~VideoDecoder();
void DecodeFrame(); void DecodeFrame();
void TakeScreenshot(string romFilename); void TakeScreenshot();
uint32_t GetFrameCount(); uint32_t GetFrameCount();

View file

@ -18,7 +18,7 @@ namespace Mesen.GUI.Config
public bool Enabled = true; public bool Enabled = true;
public string CheatName; public string CheatName;
public string GameName; public string GameName;
public string GameHash; public string GameCrc;
public CheatType CheatType; public CheatType CheatType;
public string GameGenieCode; public string GameGenieCode;
public UInt32 ProActionRockyCode; public UInt32 ProActionRockyCode;
@ -67,10 +67,9 @@ namespace Mesen.GUI.Config
{ {
InteropEmu.CheatClear(); InteropEmu.CheatClear();
string romPath = InteropEmu.GetROMPath(); string crc = InteropEmu.GetRomInfo().GetCrcString();
string md5Hash = MD5Helper.GetMD5Hash(romPath);
int cheatCount = 0; int cheatCount = 0;
foreach(CheatInfo cheat in ConfigManager.Config.Cheats.Where(c => c.GameHash == md5Hash)) { foreach(CheatInfo cheat in ConfigManager.Config.Cheats.Where(c => c.GameCrc == crc)) {
if(cheat.Enabled) { if(cheat.Enabled) {
cheat.ApplyCheat(); cheat.ApplyCheat();
cheatCount++; cheatCount++;

View file

@ -10,22 +10,22 @@ namespace Mesen.GUI.Config
public class VsConfigInfo public class VsConfigInfo
{ {
public string GameID; public string GameID;
public string GameHash; public string GameCrc;
public InteropEmu.PpuModel PpuModel; public InteropEmu.PpuModel PpuModel;
public byte DipSwitches; public byte DipSwitches;
public static VsConfigInfo GetCurrentGameConfig(bool createNew) public static VsConfigInfo GetCurrentGameConfig(bool createNew)
{ {
string hash = MD5Helper.GetMD5Hash(InteropEmu.GetROMPath()); string crc = InteropEmu.GetRomInfo().GetCrcString();
foreach(VsConfigInfo config in ConfigManager.Config.VsConfig) { foreach(VsConfigInfo config in ConfigManager.Config.VsConfig) {
if(config.GameHash == hash) { if(config.GameCrc == crc) {
return config; return config;
} }
} }
if(createNew) { if(createNew) {
VsConfigInfo newConfig = new VsConfigInfo(); VsConfigInfo newConfig = new VsConfigInfo();
newConfig.GameHash = hash; newConfig.GameCrc = crc;
ConfigManager.Config.VsConfig.Add(newConfig); ConfigManager.Config.VsConfig.Add(newConfig);
return newConfig; return newConfig;
} else { } else {

View file

@ -5,8 +5,8 @@
<Message ID="FilterMovie">Movie files (*.mmo)|*.mmo|All Files (*.*)|*.*</Message> <Message ID="FilterMovie">Movie files (*.mmo)|*.mmo|All Files (*.*)|*.*</Message>
<Message ID="FilterWave">Wave files (*.wav)|*.wav|All Files (*.*)|*.*</Message> <Message ID="FilterWave">Wave files (*.wav)|*.wav|All Files (*.*)|*.*</Message>
<Message ID="FilterPalette">Palette Files (*.pal)|*.pal|All Files (*.*)|*.*</Message> <Message ID="FilterPalette">Palette Files (*.pal)|*.pal|All Files (*.*)|*.*</Message>
<Message ID="FilterRom">All supported formats (*.nes, *.zip, *.fds)|*.NES;*.ZIP;*.FDS|NES Roms (*.nes)|*.NES|Famicom Disk System Roms (*.fds)|*.FDS|ZIP Archives (*.zip)|*.ZIP|All (*.*)|*.*</Message> <Message ID="FilterRom">All supported formats (*.nes, *.zip, *.7z, *.fds)|*.NES;*.ZIP;*.7z;*.FDS|NES Roms (*.nes)|*.NES|Famicom Disk System Roms (*.fds)|*.FDS|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|All (*.*)|*.*</Message>
<Message ID="FilterRomIps">All supported formats (*.nes, *.zip, *.fds, *.ips)|*.NES;*.ZIP;*.IPS;*.FDS|NES Roms (*.nes)|*.NES|Famicom Disk System Roms (*.fds)|*.FDS|ZIP Archives (*.zip)|*.ZIP|IPS Patches (*.ips)|*.IPS|All (*.*)|*.*</Message> <Message ID="FilterRomIps">All supported formats (*.nes, *.zip, *.7z, *.fds, *.ips)|*.NES;*.ZIP;*.7z;*.IPS;*.FDS|NES Roms (*.nes)|*.NES|Famicom Disk System Roms (*.fds)|*.FDS|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|IPS Patches (*.ips)|*.IPS|All (*.*)|*.*</Message>
<Message ID="FilterTest">Test files (*.mtp)|*.mtp|All (*.*)|*.*</Message> <Message ID="FilterTest">Test files (*.mtp)|*.mtp|All (*.*)|*.*</Message>
<Message ID="Resume">Resume</Message> <Message ID="Resume">Resume</Message>
@ -17,6 +17,8 @@
<Message ID="Disconnect">Disconnect</Message> <Message ID="Disconnect">Disconnect</Message>
<Message ID="PlayerNumber">Player {0}</Message> <Message ID="PlayerNumber">Player {0}</Message>
<Message ID="RomsFound">{0} roms found</Message>
<Message ID="CouldNotInstallRuntime">The Visual Studio Runtime could not be installed properly.</Message> <Message ID="CouldNotInstallRuntime">The Visual Studio Runtime could not be installed properly.</Message>
<Message ID="EmptyState">&lt;empty&gt;</Message> <Message ID="EmptyState">&lt;empty&gt;</Message>
<Message ID="ErrorWhileCheckingUpdates">An error has occurred while trying to check for updates.&#xA;&#xA;Error details:&#xA;{0}</Message> <Message ID="ErrorWhileCheckingUpdates">An error has occurred while trying to check for updates.&#xA;&#xA;Error details:&#xA;{0}</Message>

View file

@ -315,14 +315,16 @@
<Control ID="btnUpdate">Mettre à jour</Control> <Control ID="btnUpdate">Mettre à jour</Control>
<Control ID="btnCancel">Annuler</Control> <Control ID="btnCancel">Annuler</Control>
</Form> </Form>
<Form ID="frmSelectRom" Title="Sélection du jeu...">
</Form>
</Forms> </Forms>
<Messages> <Messages>
<Message ID="FilterAll">Tous les fichiers (*.*)|*.*</Message> <Message ID="FilterAll">Tous les fichiers (*.*)|*.*</Message>
<Message ID="FilterMovie">Films (*.mmo)|*.mmo|Tous les fichiers (*.*)|*.*</Message> <Message ID="FilterMovie">Films (*.mmo)|*.mmo|Tous les fichiers (*.*)|*.*</Message>
<Message ID="FilterWave">Fichiers wave (*.wav)|*.wav|Tous les fichiers (*.*)|*.*</Message> <Message ID="FilterWave">Fichiers wave (*.wav)|*.wav|Tous les fichiers (*.*)|*.*</Message>
<Message ID="FilterPalette">Fichier de palette (*.pal)|*.pal|Tous les fichiers (*.*)|*.*</Message> <Message ID="FilterPalette">Fichier de palette (*.pal)|*.pal|Tous les fichiers (*.*)|*.*</Message>
<Message ID="FilterRom">Tous les formats supportés (*.nes, *.zip, *.fds)|*.NES;*.ZIP;*.FDS|Roms de NES (*.nes)|*.NES|Roms du Famicom Disk System (*.fds)|*.FDS|Fichiers ZIP (*.zip)|*.ZIP|Tous les fichiers (*.*)|*.*</Message> <Message ID="FilterRom">Tous les formats supportés (*.nes, *.zip, *.7z, *.fds)|*.NES;*.ZIP;*.7z;*.FDS|Roms de NES (*.nes)|*.NES|Roms du Famicom Disk System (*.fds)|*.FDS|Fichiers ZIP (*.zip)|*.ZIP|Fichiers 7-Zip (*.7z)|*.7z|Tous les fichiers (*.*)|*.*</Message>
<Message ID="FilterRomIps">Tous les formats supportés (*.nes, *.zip, *.fds, *.ips)|*.NES;*.ZIP;*.IPS;*.FDS|Roms de NES(*.nes)|*.NES|Roms du Famicom Disk System (*.fds)|*.FDS|Fichiers ZIP (*.zip)|*.ZIP|Fichiers IPS (*.ips)|*.IPS|Tous les fichiers (*.*)|*.*</Message> <Message ID="FilterRomIps">Tous les formats supportés (*.nes, *.zip, *.7z, *.fds, *.ips)|*.NES;*.ZIP;*.7z;*.IPS;*.FDS|Roms de NES(*.nes)|*.NES|Roms du Famicom Disk System (*.fds)|*.FDS|Fichiers ZIP (*.zip)|*.ZIP|Fichiers 7-Zip (*.7z)|*.7z|Fichiers IPS (*.ips)|*.IPS|Tous les fichiers (*.*)|*.*</Message>
<Message ID="FilterTest">Fichiers de test (*.mtp)|*.mtp|Tous les fichiers (*.*)|*.*</Message> <Message ID="FilterTest">Fichiers de test (*.mtp)|*.mtp|Tous les fichiers (*.*)|*.*</Message>
<Message ID="Resume">Continuer</Message> <Message ID="Resume">Continuer</Message>
@ -333,6 +335,8 @@
<Message ID="Disconnect">Deconnexion</Message> <Message ID="Disconnect">Deconnexion</Message>
<Message ID="PlayerNumber">Joueur {0}</Message> <Message ID="PlayerNumber">Joueur {0}</Message>
<Message ID="RomsFound">{0} roms trouvés</Message>
<Message ID="CouldNotInstallRuntime">Le package Redistribuable Visual C++ pour Visual Studio 2015 n'a pas été installé correctement.</Message> <Message ID="CouldNotInstallRuntime">Le package Redistribuable Visual C++ pour Visual Studio 2015 n'a pas été installé correctement.</Message>
<Message ID="EmptyState">&lt;aucune sauvegarde&gt;</Message> <Message ID="EmptyState">&lt;aucune sauvegarde&gt;</Message>
<Message ID="ErrorWhileCheckingUpdates">Une erreur s'est produite lors de la recherche de mises-à-jour.&#xA;&#xA;Détails de l'erreur :&#xA;{0}</Message> <Message ID="ErrorWhileCheckingUpdates">Une erreur s'est produite lors de la recherche de mises-à-jour.&#xA;&#xA;Détails de l'erreur :&#xA;{0}</Message>

View file

@ -308,14 +308,16 @@
<Control ID="btnUpdate">更新</Control> <Control ID="btnUpdate">更新</Control>
<Control ID="btnCancel">キャンセル</Control> <Control ID="btnCancel">キャンセル</Control>
</Form> </Form>
<Form ID="frmSelectRom" Title="ゲーム選択">
</Form>
</Forms> </Forms>
<Messages> <Messages>
<Message ID="FilterAll">すべてのファイル (*.*)|*.*</Message> <Message ID="FilterAll">すべてのファイル (*.*)|*.*</Message>
<Message ID="FilterMovie">動画 (*.mmo)|*.mmo|すべてのファイル (*.*)|*.*</Message> <Message ID="FilterMovie">動画 (*.mmo)|*.mmo|すべてのファイル (*.*)|*.*</Message>
<Message ID="FilterWave">WAVファイル (*.wav)|*.wav|すべてのファイル (*.*)|*.*</Message> <Message ID="FilterWave">WAVファイル (*.wav)|*.wav|すべてのファイル (*.*)|*.*</Message>
<Message ID="FilterPalette">パレットファイル (*.pal)|*.pal|すべてのファイル (*.*)|*.*</Message> <Message ID="FilterPalette">パレットファイル (*.pal)|*.pal|すべてのファイル (*.*)|*.*</Message>
<Message ID="FilterRom">対応するすべてのファイル (*.nes, *.zip, *.fds)|*.NES;*.ZIP;*.FDS|ファミコンゲーム (*.nes)|*.NES|ファミコンディスクシステムのゲーム (*.fds)|*.FDS|ZIPファイル (*.zip)|*.ZIP|すべてのファイル (*.*)|*.*</Message> <Message ID="FilterRom">対応するすべてのファイル (*.nes, *.zip, *.7z, *.fds)|*.NES;*.ZIP;*.FDS;*.7z|ファミコンゲーム (*.nes)|*.NES|ファミコンディスクシステムのゲーム (*.fds)|*.FDS|ZIPファイル (*.zip)|*.ZIP|7-Zipファイル (*.7z)|*.7z|すべてのファイル (*.*)|*.*</Message>
<Message ID="FilterRomIps">対応するすべてのファイル (*.nes, *.zip, *.fds, *.ips)|*.NES;*.ZIP;*.IPS;*.FDS|ファミコンゲーム (*.nes)|*.NES|ファミコンディスクシステムのゲーム (*.fds)|*.FDS|ZIPファイル (*.zip)|*.ZIP|IPSファイル (*.ips)|*.IPS|すべてのファイル (*.*)|*.*</Message> <Message ID="FilterRomIps">対応するすべてのファイル (*.nes, *.zip, *.7z, *.fds, *.ips)|*.NES;*.ZIP;*.7z;*.IPS;*.FDS|ファミコンゲーム (*.nes)|*.NES|ファミコンディスクシステムのゲーム (*.fds)|*.FDS|ZIPファイル (*.zip)|*.ZIP|7-Zipファイル (*.7z)|*.7z|IPSファイル (*.ips)|*.IPS|すべてのファイル (*.*)|*.*</Message>
<Message ID="FilterTest">テストファイル (*.mtp)|*.mtp|すべてのファイル (*.*)|*.*</Message> <Message ID="FilterTest">テストファイル (*.mtp)|*.mtp|すべてのファイル (*.*)|*.*</Message>
<Message ID="Resume">再開</Message> <Message ID="Resume">再開</Message>
@ -326,6 +328,8 @@
<Message ID="Disconnect">切断</Message> <Message ID="Disconnect">切断</Message>
<Message ID="PlayerNumber">プレーヤー {0}</Message> <Message ID="PlayerNumber">プレーヤー {0}</Message>
<Message ID="RomsFound">{0}個</Message>
<Message ID="CouldNotInstallRuntime">Microsoft Visual Studio 2015のVisual C++再頒布可能パッケージはインストールできませんでした。</Message> <Message ID="CouldNotInstallRuntime">Microsoft Visual Studio 2015のVisual C++再頒布可能パッケージはインストールできませんでした。</Message>
<Message ID="EmptyState">&lt;なし&gt;</Message> <Message ID="EmptyState">&lt;なし&gt;</Message>
<Message ID="ErrorWhileCheckingUpdates">アップデートを確認する時にエラーが発生しました。&#xA;&#xA;エラーの詳細:&#xA;{0}</Message> <Message ID="ErrorWhileCheckingUpdates">アップデートを確認する時にエラーが発生しました。&#xA;&#xA;エラーの詳細:&#xA;{0}</Message>

View file

@ -19,7 +19,7 @@ namespace Mesen.GUI.Forms.Cheats
const int GGLongCodeLength = 8; const int GGLongCodeLength = 8;
const int PARCodeLength = 8; const int PARCodeLength = 8;
private string _gameHash; private string _gameCrc;
public frmCheat(CheatInfo cheat) public frmCheat(CheatInfo cheat)
{ {
@ -27,10 +27,13 @@ namespace Mesen.GUI.Forms.Cheats
Entity = cheat; Entity = cheat;
_gameHash = cheat.GameHash; _gameCrc = cheat.GameCrc;
if(string.IsNullOrWhiteSpace(cheat.GameName)) { if(string.IsNullOrWhiteSpace(cheat.GameName)) {
LoadGame(InteropEmu.GetROMPath()); RomInfo romInfo = InteropEmu.GetRomInfo();
_gameCrc = romInfo.GetCrcString();
((CheatInfo)Entity).GameName = romInfo.GetRomName();
txtGameName.Text = ((CheatInfo)Entity).GameName;
} }
radGameGenie.Tag = CheatType.GameGenie; radGameGenie.Tag = CheatType.GameGenie;
@ -65,17 +68,21 @@ namespace Mesen.GUI.Forms.Cheats
protected override void UpdateConfig() protected override void UpdateConfig()
{ {
UpdateObject(); UpdateObject();
((CheatInfo)Entity).GameHash = _gameHash; ((CheatInfo)Entity).GameCrc = _gameCrc;
} }
private void LoadGame(string romPath) private void LoadGame(string romPath)
{ {
_gameHash = MD5Helper.GetMD5Hash(romPath); int archiveFileIndex;
if(_gameHash != null) { if(frmSelectRom.SelectRom(romPath, out archiveFileIndex)) {
((CheatInfo)Entity).GameName = Path.GetFileNameWithoutExtension(romPath); RomInfo romInfo = InteropEmu.GetRomInfo(romPath, archiveFileIndex);
_gameCrc = romInfo.GetCrcString();
if(_gameCrc != null) {
((CheatInfo)Entity).GameName = Path.GetFileNameWithoutExtension(romInfo.RomName);
txtGameName.Text = ((CheatInfo)Entity).GameName; txtGameName.Text = ((CheatInfo)Entity).GameName;
} }
} }
}
private void btnBrowse_Click(object sender, EventArgs e) private void btnBrowse_Click(object sender, EventArgs e)
{ {
@ -89,7 +96,7 @@ namespace Mesen.GUI.Forms.Cheats
protected override bool ValidateInput() protected override bool ValidateInput()
{ {
UInt32 val; UInt32 val;
if(_gameHash == null) { if(_gameCrc == null) {
return false; return false;
} }

View file

@ -37,10 +37,10 @@ namespace Mesen.GUI.Forms.Cheats
private void UpdateCheatList() private void UpdateCheatList()
{ {
string md5hash = MD5Helper.GetMD5Hash(InteropEmu.GetROMPath()); string crc32 = InteropEmu.GetRomInfo().GetCrcString();
lstCheats.Items.Clear(); lstCheats.Items.Clear();
foreach(CheatInfo cheat in ConfigManager.Config.Cheats) { foreach(CheatInfo cheat in ConfigManager.Config.Cheats) {
if(!chkCurrentGameOnly.Checked || cheat.GameHash == md5hash) { if(!chkCurrentGameOnly.Checked || cheat.GameCrc == crc32) {
ListViewItem item = lstCheats.Items.Add(cheat.GameName); ListViewItem item = lstCheats.Items.Add(cheat.GameName);
item.SubItems.AddRange(new string[] { cheat.CheatName, cheat.ToString() }); item.SubItems.AddRange(new string[] { cheat.CheatName, cheat.ToString() });
item.Tag = cheat; item.Tag = cheat;

View file

@ -20,7 +20,7 @@ namespace Mesen.GUI.Forms.Config
Entity = configInfo; Entity = configInfo;
if(string.IsNullOrWhiteSpace(configInfo.GameID)) { if(string.IsNullOrWhiteSpace(configInfo.GameID)) {
configInfo.GameID = VsGameConfig.GetGameID(InteropEmu.GetROMPath()); configInfo.GameID = VsGameConfig.GetGameID(InteropEmu.GetRomInfo().GetRomName());
} }
AddBinding("PpuModel", cboPpuModel); AddBinding("PpuModel", cboPpuModel);

View file

@ -323,7 +323,7 @@ namespace Mesen.GUI.Forms
{ {
switch(e.NotificationType) { switch(e.NotificationType) {
case InteropEmu.ConsoleNotificationType.GameLoaded: case InteropEmu.ConsoleNotificationType.GameLoaded:
_currentGame = Path.GetFileNameWithoutExtension(InteropEmu.GetROMPath()); _currentGame = InteropEmu.GetRomInfo().GetRomName();
InitializeFdsDiskMenu(); InitializeFdsDiskMenu();
InitializeVsSystemMenu(); InitializeVsSystemMenu();
CheatInfo.ApplyCheats(); CheatInfo.ApplyCheats();
@ -420,13 +420,17 @@ namespace Mesen.GUI.Forms
_romToLoad = filename; _romToLoad = filename;
if(File.Exists(filename)) { if(File.Exists(filename)) {
ConfigManager.Config.AddRecentFile(filename); ConfigManager.Config.AddRecentFile(filename);
InteropEmu.LoadROM(filename);
int archiveFileIndex;
if(frmSelectRom.SelectRom(filename, out archiveFileIndex)) {
InteropEmu.LoadROM(filename, archiveFileIndex);
UpdateRecentFiles(); UpdateRecentFiles();
string ipsFile = Path.Combine(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(filename)) + ".ips"; string ipsFile = Path.Combine(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(filename)) + ".ips";
if(File.Exists(ipsFile)) { if(File.Exists(ipsFile)) {
InteropEmu.ApplyIpsPatch(ipsFile); InteropEmu.ApplyIpsPatch(ipsFile);
} }
}
} else { } else {
MesenMsgBox.Show("FileNotFound", MessageBoxButtons.OK, MessageBoxIcon.Error, filename); MesenMsgBox.Show("FileNotFound", MessageBoxButtons.OK, MessageBoxIcon.Error, filename);
} }
@ -755,7 +759,7 @@ namespace Mesen.GUI.Forms
SaveFileDialog sfd = new SaveFileDialog(); SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = ResourceHelper.GetMessage("FilterMovie"); sfd.Filter = ResourceHelper.GetMessage("FilterMovie");
sfd.InitialDirectory = ConfigManager.MovieFolder; sfd.InitialDirectory = ConfigManager.MovieFolder;
sfd.FileName = Path.GetFileNameWithoutExtension(InteropEmu.GetROMPath()) + ".mmo"; sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".mmo";
if(sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { if(sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
InteropEmu.MovieRecord(sfd.FileName, resetEmu); InteropEmu.MovieRecord(sfd.FileName, resetEmu);
} }
@ -792,7 +796,7 @@ namespace Mesen.GUI.Forms
SaveFileDialog sfd = new SaveFileDialog(); SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = ResourceHelper.GetMessage("FilterWave"); sfd.Filter = ResourceHelper.GetMessage("FilterWave");
sfd.InitialDirectory = ConfigManager.WaveFolder; sfd.InitialDirectory = ConfigManager.WaveFolder;
sfd.FileName = Path.GetFileNameWithoutExtension(InteropEmu.GetROMPath()) + ".wav"; sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".wav";
if(sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { if(sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
InteropEmu.WaveRecord(sfd.FileName); InteropEmu.WaveRecord(sfd.FileName);
} }
@ -868,7 +872,7 @@ namespace Mesen.GUI.Forms
SaveFileDialog sfd = new SaveFileDialog(); SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = ResourceHelper.GetMessage("FilterTest"); sfd.Filter = ResourceHelper.GetMessage("FilterTest");
sfd.InitialDirectory = ConfigManager.TestFolder; sfd.InitialDirectory = ConfigManager.TestFolder;
sfd.FileName = Path.GetFileNameWithoutExtension(InteropEmu.GetROMPath()) + ".mtp"; sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".mtp";
if(sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { if(sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
InteropEmu.RomTestRecord(sfd.FileName, resetEmu); InteropEmu.RomTestRecord(sfd.FileName, resetEmu);
} }

143
GUI.NET/Forms/frmSelectRom.Designer.cs generated Normal file
View file

@ -0,0 +1,143 @@
namespace Mesen.GUI.Forms
{
partial class frmSelectRom
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.lstRoms = new System.Windows.Forms.ListBox();
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
this.btnOK = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.lblRomCount = new System.Windows.Forms.Label();
this.tableLayoutPanel1.SuspendLayout();
this.flowLayoutPanel1.SuspendLayout();
this.SuspendLayout();
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 2;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Controls.Add(this.lstRoms, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel1, 1, 1);
this.tableLayoutPanel1.Controls.Add(this.lblRomCount, 0, 1);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(463, 242);
this.tableLayoutPanel1.TabIndex = 0;
//
// lstRoms
//
this.tableLayoutPanel1.SetColumnSpan(this.lstRoms, 2);
this.lstRoms.Dock = System.Windows.Forms.DockStyle.Fill;
this.lstRoms.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lstRoms.FormattingEnabled = true;
this.lstRoms.ItemHeight = 18;
this.lstRoms.Location = new System.Drawing.Point(3, 3);
this.lstRoms.Name = "lstRoms";
this.lstRoms.Size = new System.Drawing.Size(457, 207);
this.lstRoms.TabIndex = 1;
this.lstRoms.SelectedIndexChanged += new System.EventHandler(this.lstRoms_SelectedIndexChanged);
this.lstRoms.DoubleClick += new System.EventHandler(this.lstRoms_DoubleClick);
//
// flowLayoutPanel1
//
this.flowLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.flowLayoutPanel1.AutoSize = true;
this.flowLayoutPanel1.Controls.Add(this.btnOK);
this.flowLayoutPanel1.Controls.Add(this.btnCancel);
this.flowLayoutPanel1.Location = new System.Drawing.Point(301, 213);
this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel1.Name = "flowLayoutPanel1";
this.flowLayoutPanel1.Size = new System.Drawing.Size(162, 29);
this.flowLayoutPanel1.TabIndex = 2;
//
// btnOK
//
this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
this.btnOK.Enabled = false;
this.btnOK.Location = new System.Drawing.Point(3, 3);
this.btnOK.Name = "btnOK";
this.btnOK.Size = new System.Drawing.Size(75, 23);
this.btnOK.TabIndex = 0;
this.btnOK.Text = "OK";
this.btnOK.UseVisualStyleBackColor = true;
this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
//
// btnCancel
//
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(84, 3);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 1;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
//
// lblRomCount
//
this.lblRomCount.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblRomCount.AutoSize = true;
this.lblRomCount.Location = new System.Drawing.Point(3, 221);
this.lblRomCount.Name = "lblRomCount";
this.lblRomCount.Size = new System.Drawing.Size(83, 13);
this.lblRomCount.TabIndex = 2;
this.lblRomCount.Text = "### roms found";
//
// frmSelectRom
//
this.AcceptButton = this.btnOK;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(463, 242);
this.Controls.Add(this.tableLayoutPanel1);
this.Name = "frmSelectRom";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Select Rom...";
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
this.flowLayoutPanel1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.ListBox lstRoms;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
private System.Windows.Forms.Button btnOK;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.Label lblRomCount;
}
}

View file

@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Mesen.GUI.Forms
{
public partial class frmSelectRom : BaseForm
{
private List<string> _romFiles;
private int SelectedIndex { get; set; }
public frmSelectRom(List<string> romFiles)
{
InitializeComponent();
_romFiles = romFiles;
lblRomCount.Text = ResourceHelper.GetMessage("RomsFound", _romFiles.Count.ToString());
lstRoms.Items.AddRange(romFiles.ToArray());
lstRoms.Sorted = true;
this.DialogResult = DialogResult.Cancel;
}
public static bool SelectRom(string filename, out int archiveFileIndex)
{
archiveFileIndex = -1;
List<string> archiveRomList = InteropEmu.GetArchiveRomList(filename);
if(archiveRomList.Count > 1) {
frmSelectRom frm = new frmSelectRom(archiveRomList);
if(frm.ShowDialog(null, Application.OpenForms[0]) == DialogResult.OK) {
archiveFileIndex = frm.SelectedIndex;
} else {
return false;
}
}
return true;
}
void SetSelectedIndex()
{
this.SelectedIndex = _romFiles.IndexOf(lstRoms.SelectedItem.ToString());
this.DialogResult = DialogResult.OK;
}
private void lstRoms_SelectedIndexChanged(object sender, EventArgs e)
{
btnOK.Enabled = lstRoms.SelectedItems.Count > 0;
}
private void lstRoms_DoubleClick(object sender, EventArgs e)
{
SetSelectedIndex();
}
private void btnOK_Click(object sender, EventArgs e)
{
SetSelectedIndex();
}
}
}

View file

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View file

@ -445,6 +445,12 @@
<Compile Include="Forms\frmDownloadProgress.Designer.cs"> <Compile Include="Forms\frmDownloadProgress.Designer.cs">
<DependentUpon>frmDownloadProgress.cs</DependentUpon> <DependentUpon>frmDownloadProgress.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Forms\frmSelectRom.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\frmSelectRom.Designer.cs">
<DependentUpon>frmSelectRom.cs</DependentUpon>
</Compile>
<Compile Include="Forms\frmUpdatePrompt.cs"> <Compile Include="Forms\frmUpdatePrompt.cs">
<SubType>Form</SubType> <SubType>Form</SubType>
</Compile> </Compile>
@ -598,6 +604,9 @@
<EmbeddedResource Include="Forms\frmMain.resx"> <EmbeddedResource Include="Forms\frmMain.resx">
<DependentUpon>frmMain.cs</DependentUpon> <DependentUpon>frmMain.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Include="Forms\frmSelectRom.resx">
<DependentUpon>frmSelectRom.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\frmUpdatePrompt.resx"> <EmbeddedResource Include="Forms\frmUpdatePrompt.resx">
<DependentUpon>frmUpdatePrompt.cs</DependentUpon> <DependentUpon>frmUpdatePrompt.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>

View file

@ -25,10 +25,13 @@ namespace Mesen.GUI
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool IsRunning(); [DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool IsRunning();
[DllImport(DLLPath)] public static extern void LoadROM([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string filename); [DllImport(DLLPath)] public static extern void LoadROM([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string filename, Int32 archiveFileIndex = -1);
[DllImport(DLLPath)] public static extern void ApplyIpsPatch([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string filename); [DllImport(DLLPath)] public static extern void ApplyIpsPatch([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string filename);
[DllImport(DLLPath)] public static extern void AddKnowGameFolder([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string folder); [DllImport(DLLPath)] public static extern void AddKnowGameFolder([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string folder);
[DllImport(DLLPath, EntryPoint = "GetArchiveRomList")] private static extern IntPtr GetArchiveRomListWrapper([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string filename);
public static List<string> GetArchiveRomList(string filename) { return new List<string>(PtrToStringUtf8(InteropEmu.GetArchiveRomListWrapper(filename)).Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries)); }
[DllImport(DLLPath)] public static extern void SetMousePosition(double x, double y); [DllImport(DLLPath)] public static extern void SetMousePosition(double x, double y);
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool HasZapper(); [DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool HasZapper();
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool HasArkanoidPaddle(); [DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool HasArkanoidPaddle();
@ -48,7 +51,9 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void Resume(); [DllImport(DLLPath)] public static extern void Resume();
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool IsPaused(); [DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool IsPaused();
[DllImport(DLLPath)] public static extern void Stop(); [DllImport(DLLPath)] public static extern void Stop();
[DllImport(DLLPath, EntryPoint="GetROMPath")] private static extern IntPtr GetROMPathWrapper();
[DllImport(DLLPath, EntryPoint = "GetRomInfo")] private static extern UInt32 GetRomInfoWrapper(ref InteropRomInfo romInfo, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string filename = "", Int32 archiveFileIndex = -1);
[DllImport(DLLPath)] public static extern void Reset(); [DllImport(DLLPath)] public static extern void Reset();
[DllImport(DLLPath)] public static extern void StartServer(UInt16 port, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string hostPlayerName); [DllImport(DLLPath)] public static extern void StartServer(UInt16 port, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string hostPlayerName);
[DllImport(DLLPath)] public static extern void StopServer(); [DllImport(DLLPath)] public static extern void StopServer();
@ -253,6 +258,13 @@ namespace Mesen.GUI
} }
} }
public static RomInfo GetRomInfo(string filename = "", Int32 archiveFileIndex = -1)
{
InteropRomInfo romInfo = new InteropRomInfo();
InteropEmu.GetRomInfoWrapper(ref romInfo, filename, archiveFileIndex);
return new RomInfo(romInfo);
}
public static ScreenSize GetScreenSize(bool ignoreScale) public static ScreenSize GetScreenSize(bool ignoreScale)
{ {
ScreenSize size; ScreenSize size;
@ -292,7 +304,6 @@ namespace Mesen.GUI
return paleteData; return paleteData;
} }
public static string GetROMPath() { return PtrToStringUtf8(InteropEmu.GetROMPathWrapper()); }
public static string GetKeyName(UInt32 key) { return PtrToStringUtf8(InteropEmu.GetKeyNameWrapper(key)); } public static string GetKeyName(UInt32 key) { return PtrToStringUtf8(InteropEmu.GetKeyNameWrapper(key)); }
public static List<string> GetAudioDevices() public static List<string> GetAudioDevices()
{ {
@ -590,6 +601,34 @@ namespace Mesen.GUI
PpuPartialDraw = 1 PpuPartialDraw = 1
} }
public struct InteropRomInfo
{
public IntPtr RomNamePointer;
public UInt32 Crc32;
}
public class RomInfo
{
public string RomName;
public UInt32 Crc32;
public RomInfo(InteropRomInfo romInfo)
{
this.RomName = UTF8Marshaler.GetStringFromIntPtr(romInfo.RomNamePointer);
this.Crc32 = romInfo.Crc32;
}
public string GetRomName()
{
return Path.GetFileNameWithoutExtension(this.RomName);
}
public string GetCrcString()
{
return this.Crc32.ToString("X8");
}
};
public struct InteropBreakpoint public struct InteropBreakpoint
{ {
public BreakpointType Type; public BreakpointType Type;
@ -703,17 +742,7 @@ namespace Mesen.GUI
{ {
if(File.Exists(filename)) { if(File.Exists(filename)) {
var md5 = System.Security.Cryptography.MD5.Create(); var md5 = System.Security.Cryptography.MD5.Create();
if(filename.EndsWith(".nes", StringComparison.InvariantCultureIgnoreCase) || filename.EndsWith(".fds", StringComparison.InvariantCultureIgnoreCase)) {
return BitConverter.ToString(md5.ComputeHash(File.ReadAllBytes(filename))).Replace("-", ""); return BitConverter.ToString(md5.ComputeHash(File.ReadAllBytes(filename))).Replace("-", "");
} else if(filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) {
foreach(var entry in ZipFile.OpenRead(filename).Entries) {
if(entry.Name.EndsWith(".nes", StringComparison.InvariantCultureIgnoreCase) || entry.Name.EndsWith(".fds", StringComparison.InvariantCultureIgnoreCase)) {
return BitConverter.ToString(md5.ComputeHash(entry.Open())).Replace("-", "");
}
}
} else {
return BitConverter.ToString(md5.ComputeHash(File.ReadAllBytes(filename))).Replace("-", "");
}
} }
return null; return null;
} }
@ -744,21 +773,7 @@ namespace Mesen.GUI
public object MarshalNativeToManaged(IntPtr pNativeData) public object MarshalNativeToManaged(IntPtr pNativeData)
{ {
int offset = 0; return GetStringFromIntPtr(pNativeData);
byte b = 0;
do {
b = Marshal.ReadByte(pNativeData, offset);
offset++;
} while(b != 0);
int length = offset - 1;
// should not be null terminated
byte[] strbuf = new byte[length];
// skip the trailing null
Marshal.Copy((IntPtr)pNativeData, strbuf, 0, length);
string data = Encoding.UTF8.GetString(strbuf);
return data;
} }
public void CleanUpNativeData(IntPtr pNativeData) public void CleanUpNativeData(IntPtr pNativeData)
@ -782,5 +797,24 @@ namespace Mesen.GUI
} }
return _instance; return _instance;
} }
public static string GetStringFromIntPtr(IntPtr pNativeData)
{
int offset = 0;
byte b = 0;
do {
b = Marshal.ReadByte(pNativeData, offset);
offset++;
} while(b != 0);
int length = offset - 1;
// should not be null terminated
byte[] strbuf = new byte[length];
// skip the trailing null
Marshal.Copy((IntPtr)pNativeData, strbuf, 0, length);
string data = Encoding.UTF8.GetString(strbuf);
return data;
}
} }
} }

View file

@ -16,6 +16,7 @@
#include "../Core/FDS.h" #include "../Core/FDS.h"
#include "../Core/VsControlManager.h" #include "../Core/VsControlManager.h"
#include "../Core/SoundMixer.h" #include "../Core/SoundMixer.h"
#include "../Core/RomLoader.h"
NES::Renderer *_renderer = nullptr; NES::Renderer *_renderer = nullptr;
SoundManager *_soundManager = nullptr; SoundManager *_soundManager = nullptr;
@ -42,6 +43,12 @@ namespace InteropEmu {
} }
}; };
struct RomInfo
{
const char* RomName;
uint32_t Crc32;
};
extern "C" { extern "C" {
DllExport bool __stdcall TestDll() DllExport bool __stdcall TestDll()
{ {
@ -67,10 +74,19 @@ namespace InteropEmu {
DllExport bool __stdcall IsRunning() { return Console::IsRunning(); } DllExport bool __stdcall IsRunning() { return Console::IsRunning(); }
DllExport void __stdcall LoadROM(char* filename) { Console::LoadROM(filename); } DllExport void __stdcall LoadROM(char* filename, int32_t archiveFileIndex) { Console::LoadROM(filename, nullptr, archiveFileIndex); }
DllExport void __stdcall ApplyIpsPatch(char* filename) { Console::ApplyIpsPatch(filename); } DllExport void __stdcall ApplyIpsPatch(char* filename) { Console::ApplyIpsPatch(filename); }
DllExport void __stdcall AddKnowGameFolder(char* folder) { FolderUtilities::AddKnowGameFolder(folder); } DllExport void __stdcall AddKnowGameFolder(char* folder) { FolderUtilities::AddKnowGameFolder(folder); }
DllExport const char* __stdcall GetArchiveRomList(char* filename) {
std::ostringstream out;
for(string romName : RomLoader::GetArchiveRomList(filename)) {
out << romName << "/";
}
_returnString = out.str();
return _returnString.c_str();
}
DllExport void __stdcall SetControllerType(uint32_t port, ControllerType type) { EmulationSettings::SetControllerType(port, type); } DllExport void __stdcall SetControllerType(uint32_t port, ControllerType type) { EmulationSettings::SetControllerType(port, type); }
DllExport void __stdcall SetControllerKeys(uint32_t port, KeyMappingSet mappings) { EmulationSettings::SetControllerKeys(port, mappings); } DllExport void __stdcall SetControllerKeys(uint32_t port, KeyMappingSet mappings) { EmulationSettings::SetControllerKeys(port, mappings); }
DllExport void __stdcall SetExpansionDevice(ExpansionPortDevice device) { EmulationSettings::SetExpansionDevice(device); } DllExport void __stdcall SetExpansionDevice(ExpansionPortDevice device) { EmulationSettings::SetExpansionDevice(device); }
@ -110,10 +126,24 @@ namespace InteropEmu {
Console::GetInstance()->Stop(); Console::GetInstance()->Stop();
} }
} }
DllExport const char* __stdcall GetROMPath()
DllExport const void __stdcall GetRomInfo(RomInfo &romInfo, char* filename, int32_t archiveFileIndex)
{ {
_returnString = Console::GetROMPath(); string romPath = filename;
return _returnString.c_str(); if(romPath.empty()) {
_returnString = Console::GetRomName();
romInfo.RomName = _returnString.c_str();
romInfo.Crc32 = Console::GetCrc32();
} else {
RomLoader romLoader;
if(romLoader.LoadFile(filename, nullptr, "", archiveFileIndex)) {
RomData romData = romLoader.GetRomData();
_returnString = romData.RomName;
romInfo.RomName = _returnString.c_str();
romInfo.Crc32 = romData.Crc32;
}
}
} }
DllExport void __stdcall Reset() { Console::Reset(); } DllExport void __stdcall Reset() { Console::Reset(); }
@ -184,7 +214,7 @@ namespace InteropEmu {
delete _soundManager; delete _soundManager;
} }
DllExport void __stdcall TakeScreenshot() { VideoDecoder::GetInstance()->TakeScreenshot(FolderUtilities::GetFilename(Console::GetROMPath(), false)); } DllExport void __stdcall TakeScreenshot() { VideoDecoder::GetInstance()->TakeScreenshot(); }
DllExport INotificationListener* __stdcall RegisterNotificationCallback(NotificationListenerCallback callback) DllExport INotificationListener* __stdcall RegisterNotificationCallback(NotificationListenerCallback callback)
{ {

View file

@ -25,14 +25,6 @@
<Configuration>PGO Profile</Configuration> <Configuration>PGO Profile</Configuration>
<Platform>x64</Platform> <Platform>x64</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Release x64|Win32">
<Configuration>Release x64</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release x64|x64">
<Configuration>Release x64</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32"> <ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
@ -103,20 +95,6 @@
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
</ImportGroup> </ImportGroup>
@ -144,12 +122,6 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'" Label="PropertySheets"> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
@ -199,18 +171,6 @@
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\PGO Profile\</OutDir> <OutDir>$(SolutionDir)\bin\$(PlatformTarget)\PGO Profile\</OutDir>
<IntDir>obj\$(Platform)\PGO Profile\</IntDir> <IntDir>obj\$(Platform)\PGO Profile\</IntDir>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">
<LinkIncremental>false</LinkIncremental>
<TargetName>WinMesen</TargetName>
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|x64'">
<LinkIncremental>false</LinkIncremental>
<TargetName>WinMesen</TargetName>
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
@ -391,48 +351,6 @@
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;INTEROPDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;INTEROPDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="stdafx.h" /> <ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" /> <ClInclude Include="targetver.h" />
@ -449,8 +367,6 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='PGO Profile|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='PGO Profile|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release x64|x64'">Create</PrecompiledHeader>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View file

@ -38,6 +38,7 @@
#pragma comment(lib, "Core.lib") #pragma comment(lib, "Core.lib")
#pragma comment(lib, "Utilities.lib") #pragma comment(lib, "Utilities.lib")
#pragma comment(lib, "Windows.lib") #pragma comment(lib, "Windows.lib")
#pragma comment(lib, "SevenZip.lib")
#ifdef PGO #ifdef PGO
#pragma comment(lib, "../Dependencies/DirectXTK." MESEN_LIBRARY_DEBUG_SUFFIX ".Static." MESEN_LIBRARY_SUFFIX) #pragma comment(lib, "../Dependencies/DirectXTK." MESEN_LIBRARY_DEBUG_SUFFIX ".Static." MESEN_LIBRARY_SUFFIX)
#else #else

25
NES.sln
View file

@ -9,6 +9,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Core", "Core\Core.vcxproj",
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Utilities", "Utilities\Utilities.vcxproj", "{B5330148-E8C7-46BA-B54E-69BE59EA337D}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Utilities", "Utilities\Utilities.vcxproj", "{B5330148-E8C7-46BA-B54E-69BE59EA337D}"
ProjectSection(ProjectDependencies) = postProject
{52C4BA3A-E699-4305-B23F-C9083FD07AB6} = {52C4BA3A-E699-4305-B23F-C9083FD07AB6}
EndProjectSection
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GUI.NET", "GUI.NET\GUI.NET.csproj", "{08D83A7E-52A9-451E-A53A-1A7946F8BB77}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GUI.NET", "GUI.NET\GUI.NET.csproj", "{08D83A7E-52A9-451E-A53A-1A7946F8BB77}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
@ -46,6 +49,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DependencyPacker", "Depende
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateHelper", "UpdateHelper\UpdateHelper.csproj", "{36ABBF1C-66E1-4577-828A-619A2EF0DAE9}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateHelper", "UpdateHelper\UpdateHelper.csproj", "{36ABBF1C-66E1-4577-828A-619A2EF0DAE9}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SevenZip", "SevenZip\SevenZip.vcxproj", "{52C4BA3A-E699-4305-B23F-C9083FD07AB6}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -254,6 +259,26 @@ Global
{36ABBF1C-66E1-4577-828A-619A2EF0DAE9}.Release|x64.Build.0 = Release|x64 {36ABBF1C-66E1-4577-828A-619A2EF0DAE9}.Release|x64.Build.0 = Release|x64
{36ABBF1C-66E1-4577-828A-619A2EF0DAE9}.Release|x86.ActiveCfg = Release|x86 {36ABBF1C-66E1-4577-828A-619A2EF0DAE9}.Release|x86.ActiveCfg = Release|x86
{36ABBF1C-66E1-4577-828A-619A2EF0DAE9}.Release|x86.Build.0 = Release|x86 {36ABBF1C-66E1-4577-828A-619A2EF0DAE9}.Release|x86.Build.0 = Release|x86
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.Debug|Any CPU.ActiveCfg = Debug|Win32
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.Debug|x64.ActiveCfg = Debug|x64
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.Debug|x64.Build.0 = Debug|x64
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.Debug|x86.ActiveCfg = Debug|Win32
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.Debug|x86.Build.0 = Debug|Win32
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.PGO Optimize|Any CPU.ActiveCfg = PGO Optimize|Win32
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.PGO Optimize|x64.ActiveCfg = PGO Optimize|x64
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.PGO Optimize|x64.Build.0 = PGO Optimize|x64
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.PGO Optimize|x86.ActiveCfg = PGO Optimize|Win32
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.PGO Optimize|x86.Build.0 = PGO Optimize|Win32
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.PGO Profile|Any CPU.ActiveCfg = PGO Profile|Win32
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.PGO Profile|x64.ActiveCfg = PGO Profile|x64
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.PGO Profile|x64.Build.0 = PGO Profile|x64
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.PGO Profile|x86.ActiveCfg = PGO Profile|Win32
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.PGO Profile|x86.Build.0 = PGO Profile|Win32
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.Release|Any CPU.ActiveCfg = Release|Win32
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.Release|x64.ActiveCfg = Release|x64
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.Release|x64.Build.0 = Release|x64
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.Release|x86.ActiveCfg = Release|Win32
{52C4BA3A-E699-4305-B23F-C9083FD07AB6}.Release|x86.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View file

@ -25,14 +25,6 @@
<Configuration>PGO Profile</Configuration> <Configuration>PGO Profile</Configuration>
<Platform>x64</Platform> <Platform>x64</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Release x64|Win32">
<Configuration>Release x64</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release x64|x64">
<Configuration>Release x64</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32"> <ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
@ -103,20 +95,6 @@
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
</ImportGroup> </ImportGroup>
@ -144,12 +122,6 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'" Label="PropertySheets"> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
@ -191,16 +163,6 @@
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\PGO Profile\</OutDir> <OutDir>$(SolutionDir)\bin\$(PlatformTarget)\PGO Profile\</OutDir>
<IntDir>obj\$(Platform)\PGO Profile\</IntDir> <IntDir>obj\$(Platform)\PGO Profile\</IntDir>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<PrecompiledHeader> <PrecompiledHeader>
@ -355,46 +317,6 @@
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="PGOHelper.cpp" /> <ClCompile Include="PGOHelper.cpp" />
</ItemGroup> </ItemGroup>

202
SevenZip/7z.h Normal file
View file

@ -0,0 +1,202 @@
/* 7z.h -- 7z interface
2015-11-18 : Igor Pavlov : Public domain */
#ifndef __7Z_H
#define __7Z_H
#include "7zTypes.h"
EXTERN_C_BEGIN
#define k7zStartHeaderSize 0x20
#define k7zSignatureSize 6
extern const Byte k7zSignature[k7zSignatureSize];
typedef struct
{
const Byte *Data;
size_t Size;
} CSzData;
/* CSzCoderInfo & CSzFolder support only default methods */
typedef struct
{
size_t PropsOffset;
UInt32 MethodID;
Byte NumStreams;
Byte PropsSize;
} CSzCoderInfo;
typedef struct
{
UInt32 InIndex;
UInt32 OutIndex;
} CSzBond;
#define SZ_NUM_CODERS_IN_FOLDER_MAX 4
#define SZ_NUM_BONDS_IN_FOLDER_MAX 3
#define SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX 4
typedef struct
{
UInt32 NumCoders;
UInt32 NumBonds;
UInt32 NumPackStreams;
UInt32 UnpackStream;
UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX];
CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX];
CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX];
} CSzFolder;
SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd);
typedef struct
{
UInt32 Low;
UInt32 High;
} CNtfsFileTime;
typedef struct
{
Byte *Defs; /* MSB 0 bit numbering */
UInt32 *Vals;
} CSzBitUi32s;
typedef struct
{
Byte *Defs; /* MSB 0 bit numbering */
// UInt64 *Vals;
CNtfsFileTime *Vals;
} CSzBitUi64s;
#define SzBitArray_Check(p, i) (((p)[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)
#define SzBitWithVals_Check(p, i) ((p)->Defs && ((p)->Defs[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)
typedef struct
{
UInt32 NumPackStreams;
UInt32 NumFolders;
UInt64 *PackPositions; // NumPackStreams + 1
CSzBitUi32s FolderCRCs; // NumFolders
size_t *FoCodersOffsets; // NumFolders + 1
UInt32 *FoStartPackStreamIndex; // NumFolders + 1
UInt32 *FoToCoderUnpackSizes; // NumFolders + 1
Byte *FoToMainUnpackSizeIndex; // NumFolders
UInt64 *CoderUnpackSizes; // for all coders in all folders
Byte *CodersData;
} CSzAr;
UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex);
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *stream, UInt64 startPos,
Byte *outBuffer, size_t outSize,
ISzAlloc *allocMain);
typedef struct
{
CSzAr db;
UInt64 startPosAfterHeader;
UInt64 dataPos;
UInt32 NumFiles;
UInt64 *UnpackPositions; // NumFiles + 1
// Byte *IsEmptyFiles;
Byte *IsDirs;
CSzBitUi32s CRCs;
CSzBitUi32s Attribs;
// CSzBitUi32s Parents;
CSzBitUi64s MTime;
CSzBitUi64s CTime;
UInt32 *FolderToFile; // NumFolders + 1
UInt32 *FileToFolder; // NumFiles
size_t *FileNameOffsets; /* in 2-byte steps */
Byte *FileNames; /* UTF-16-LE */
} CSzArEx;
#define SzArEx_IsDir(p, i) (SzBitArray_Check((p)->IsDirs, i))
#define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i])
void SzArEx_Init(CSzArEx *p);
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
/*
if dest == NULL, the return value specifies the required size of the buffer,
in 16-bit characters, including the null-terminating character.
if dest != NULL, the return value specifies the number of 16-bit characters that
are written to the dest, including the null-terminating character. */
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
/*
size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex);
UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
*/
/*
SzArEx_Extract extracts file from archive
*outBuffer must be 0 before first call for each new archive.
Extracting cache:
If you need to decompress more than one file, you can send
these values from previous call:
*blockIndex,
*outBuffer,
*outBufferSize
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
it will increase decompression speed.
If you use external function, you can declare these 3 cache variables
(blockIndex, outBuffer, outBufferSize) as static in that external function.
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
*/
SRes SzArEx_Extract(
const CSzArEx *db,
ILookInStream *inStream,
UInt32 fileIndex, /* index of file */
UInt32 *blockIndex, /* index of solid block */
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
size_t *outBufferSize, /* buffer size for output buffer */
size_t *offset, /* offset of stream for required file in *outBuffer */
size_t *outSizeProcessed, /* size of file in *outBuffer */
ISzAlloc *allocMain,
ISzAlloc *allocTemp);
/*
SzArEx_Open Errors:
SZ_ERROR_NO_ARCHIVE
SZ_ERROR_ARCHIVE
SZ_ERROR_UNSUPPORTED
SZ_ERROR_MEM
SZ_ERROR_CRC
SZ_ERROR_INPUT_EOF
SZ_ERROR_FAIL
*/
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
ISzAlloc *allocMain, ISzAlloc *allocTemp);
EXTERN_C_END
#endif

78
SevenZip/7zAlloc.c Normal file
View file

@ -0,0 +1,78 @@
/* 7zAlloc.c -- Allocation functions
2015-11-09 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "7zAlloc.h"
/* #define _SZ_ALLOC_DEBUG */
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
#ifdef _SZ_ALLOC_DEBUG
#ifdef _WIN32
#include <windows.h>
#endif
#include <stdio.h>
int g_allocCount = 0;
int g_allocCountTemp = 0;
#endif
void *SzAlloc(void *p, size_t size)
{
UNUSED_VAR(p);
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc %10u bytes; count = %10d", (unsigned)size, g_allocCount);
g_allocCount++;
#endif
return malloc(size);
}
void SzFree(void *p, void *address)
{
UNUSED_VAR(p);
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
{
g_allocCount--;
fprintf(stderr, "\nFree; count = %10d", g_allocCount);
}
#endif
free(address);
}
void *SzAllocTemp(void *p, size_t size)
{
UNUSED_VAR(p);
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_temp %10u bytes; count = %10d", (unsigned)size, g_allocCountTemp);
g_allocCountTemp++;
#ifdef _WIN32
return HeapAlloc(GetProcessHeap(), 0, size);
#endif
#endif
return malloc(size);
}
void SzFreeTemp(void *p, void *address)
{
UNUSED_VAR(p);
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
{
g_allocCountTemp--;
fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp);
}
#ifdef _WIN32
HeapFree(GetProcessHeap(), 0, address);
return;
#endif
#endif
free(address);
}

23
SevenZip/7zAlloc.h Normal file
View file

@ -0,0 +1,23 @@
/* 7zAlloc.h -- Allocation functions
2013-03-25 : Igor Pavlov : Public domain */
#ifndef __7Z_ALLOC_H
#define __7Z_ALLOC_H
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
void *SzAlloc(void *p, size_t size);
void SzFree(void *p, void *address);
void *SzAllocTemp(void *p, size_t size);
void SzFreeTemp(void *p, void *address);
#ifdef __cplusplus
}
#endif
#endif

1771
SevenZip/7zArcIn.c Normal file

File diff suppressed because it is too large Load diff

36
SevenZip/7zBuf.c Normal file
View file

@ -0,0 +1,36 @@
/* 7zBuf.c -- Byte Buffer
2013-01-21 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "7zBuf.h"
void Buf_Init(CBuf *p)
{
p->data = 0;
p->size = 0;
}
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
{
p->size = 0;
if (size == 0)
{
p->data = 0;
return 1;
}
p->data = (Byte *)alloc->Alloc(alloc, size);
if (p->data != 0)
{
p->size = size;
return 1;
}
return 0;
}
void Buf_Free(CBuf *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->data);
p->data = 0;
p->size = 0;
}

35
SevenZip/7zBuf.h Normal file
View file

@ -0,0 +1,35 @@
/* 7zBuf.h -- Byte Buffer
2013-01-18 : Igor Pavlov : Public domain */
#ifndef __7Z_BUF_H
#define __7Z_BUF_H
#include "7zTypes.h"
EXTERN_C_BEGIN
typedef struct
{
Byte *data;
size_t size;
} CBuf;
void Buf_Init(CBuf *p);
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc);
void Buf_Free(CBuf *p, ISzAlloc *alloc);
typedef struct
{
Byte *data;
size_t size;
size_t pos;
} CDynBuf;
void DynBuf_Construct(CDynBuf *p);
void DynBuf_SeekToBeg(CDynBuf *p);
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc);
void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc);
EXTERN_C_END
#endif

128
SevenZip/7zCrc.c Normal file
View file

@ -0,0 +1,128 @@
/* 7zCrc.c -- CRC32 init
2015-03-10 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "7zCrc.h"
#include "CpuArch.h"
#define kCrcPoly 0xEDB88320
#ifdef MY_CPU_LE
#define CRC_NUM_TABLES 8
#else
#define CRC_NUM_TABLES 9
#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
#endif
#ifndef MY_CPU_BE
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
#endif
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
CRC_FUNC g_CrcUpdateT4;
CRC_FUNC g_CrcUpdateT8;
CRC_FUNC g_CrcUpdate;
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
{
return g_CrcUpdate(v, data, size, g_CrcTable);
}
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
{
return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL;
}
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
const Byte *pEnd = p + size;
for (; p != pEnd; p++)
v = CRC_UPDATE_BYTE_2(v, *p);
return v;
}
void MY_FAST_CALL CrcGenerateTable()
{
UInt32 i;
for (i = 0; i < 256; i++)
{
UInt32 r = i;
unsigned j;
for (j = 0; j < 8; j++)
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
g_CrcTable[i] = r;
}
for (; i < 256 * CRC_NUM_TABLES; i++)
{
UInt32 r = g_CrcTable[i - 256];
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
}
#if CRC_NUM_TABLES < 4
g_CrcUpdate = CrcUpdateT1;
#else
#ifdef MY_CPU_LE
g_CrcUpdateT4 = CrcUpdateT4;
g_CrcUpdate = CrcUpdateT4;
#if CRC_NUM_TABLES >= 8
g_CrcUpdateT8 = CrcUpdateT8;
#ifdef MY_CPU_X86_OR_AMD64
if (!CPU_Is_InOrder())
g_CrcUpdate = CrcUpdateT8;
#endif
#endif
#else
{
#ifndef MY_CPU_BE
UInt32 k = 0x01020304;
const Byte *p = (const Byte *)&k;
if (p[0] == 4 && p[1] == 3)
{
g_CrcUpdateT4 = CrcUpdateT4;
g_CrcUpdate = CrcUpdateT4;
#if CRC_NUM_TABLES >= 8
g_CrcUpdateT8 = CrcUpdateT8;
// g_CrcUpdate = CrcUpdateT8;
#endif
}
else if (p[0] != 1 || p[1] != 2)
g_CrcUpdate = CrcUpdateT1;
else
#endif
{
for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
{
UInt32 x = g_CrcTable[i - 256];
g_CrcTable[i] = CRC_UINT32_SWAP(x);
}
g_CrcUpdateT4 = CrcUpdateT1_BeT4;
g_CrcUpdate = CrcUpdateT1_BeT4;
#if CRC_NUM_TABLES >= 8
g_CrcUpdateT8 = CrcUpdateT1_BeT8;
// g_CrcUpdate = CrcUpdateT1_BeT8;
#endif
}
}
#endif
#endif
}

25
SevenZip/7zCrc.h Normal file
View file

@ -0,0 +1,25 @@
/* 7zCrc.h -- CRC32 calculation
2013-01-18 : Igor Pavlov : Public domain */
#ifndef __7Z_CRC_H
#define __7Z_CRC_H
#include "7zTypes.h"
EXTERN_C_BEGIN
extern UInt32 g_CrcTable[];
/* Call CrcGenerateTable one time before other CRC functions */
void MY_FAST_CALL CrcGenerateTable(void);
#define CRC_INIT_VAL 0xFFFFFFFF
#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL)
#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);
EXTERN_C_END
#endif

115
SevenZip/7zCrcOpt.c Normal file
View file

@ -0,0 +1,115 @@
/* 7zCrcOpt.c -- CRC32 calculation
2015-03-01 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "CpuArch.h"
#ifndef MY_CPU_BE
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
for (; size >= 4; size -= 4, p += 4)
{
v ^= *(const UInt32 *)p;
v =
table[0x300 + ((v ) & 0xFF)]
^ table[0x200 + ((v >> 8) & 0xFF)]
^ table[0x100 + ((v >> 16) & 0xFF)]
^ table[0x000 + ((v >> 24))];
}
for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
return v;
}
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
for (; size >= 8; size -= 8, p += 8)
{
UInt32 d;
v ^= *(const UInt32 *)p;
v =
table[0x700 + ((v ) & 0xFF)]
^ table[0x600 + ((v >> 8) & 0xFF)]
^ table[0x500 + ((v >> 16) & 0xFF)]
^ table[0x400 + ((v >> 24))];
d = *((const UInt32 *)p + 1);
v ^=
table[0x300 + ((d ) & 0xFF)]
^ table[0x200 + ((d >> 8) & 0xFF)]
^ table[0x100 + ((d >> 16) & 0xFF)]
^ table[0x000 + ((d >> 24))];
}
for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
return v;
}
#endif
#ifndef MY_CPU_LE
#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
#define CRC_UPDATE_BYTE_2_BE(crc, b) (table[(((crc) >> 24) ^ (b))] ^ ((crc) << 8))
UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
table += 0x100;
v = CRC_UINT32_SWAP(v);
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2_BE(v, *p);
for (; size >= 4; size -= 4, p += 4)
{
v ^= *(const UInt32 *)p;
v =
table[0x000 + ((v ) & 0xFF)]
^ table[0x100 + ((v >> 8) & 0xFF)]
^ table[0x200 + ((v >> 16) & 0xFF)]
^ table[0x300 + ((v >> 24))];
}
for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2_BE(v, *p);
return CRC_UINT32_SWAP(v);
}
UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
table += 0x100;
v = CRC_UINT32_SWAP(v);
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2_BE(v, *p);
for (; size >= 8; size -= 8, p += 8)
{
UInt32 d;
v ^= *(const UInt32 *)p;
v =
table[0x400 + ((v ) & 0xFF)]
^ table[0x500 + ((v >> 8) & 0xFF)]
^ table[0x600 + ((v >> 16) & 0xFF)]
^ table[0x700 + ((v >> 24))];
d = *((const UInt32 *)p + 1);
v ^=
table[0x000 + ((d ) & 0xFF)]
^ table[0x100 + ((d >> 8) & 0xFF)]
^ table[0x200 + ((d >> 16) & 0xFF)]
^ table[0x300 + ((d >> 24))];
}
for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2_BE(v, *p);
return CRC_UINT32_SWAP(v);
}
#endif

591
SevenZip/7zDec.c Normal file
View file

@ -0,0 +1,591 @@
/* 7zDec.c -- Decoding from 7z folder
2015-11-18 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <string.h>
/* #define _7ZIP_PPMD_SUPPPORT */
#include "7z.h"
#include "7zCrc.h"
#include "Bcj2.h"
#include "Bra.h"
#include "CpuArch.h"
#include "Delta.h"
#include "LzmaDec.h"
#include "Lzma2Dec.h"
#ifdef _7ZIP_PPMD_SUPPPORT
#include "Ppmd7.h"
#endif
#define k_Copy 0
#define k_Delta 3
#define k_LZMA2 0x21
#define k_LZMA 0x30101
#define k_BCJ 0x3030103
#define k_BCJ2 0x303011B
#define k_PPC 0x3030205
#define k_IA64 0x3030401
#define k_ARM 0x3030501
#define k_ARMT 0x3030701
#define k_SPARC 0x3030805
#ifdef _7ZIP_PPMD_SUPPPORT
#define k_PPMD 0x30401
typedef struct
{
IByteIn p;
const Byte *cur;
const Byte *end;
const Byte *begin;
UInt64 processed;
Bool extra;
SRes res;
ILookInStream *inStream;
} CByteInToLook;
static Byte ReadByte(void *pp)
{
CByteInToLook *p = (CByteInToLook *)pp;
if (p->cur != p->end)
return *p->cur++;
if (p->res == SZ_OK)
{
size_t size = p->cur - p->begin;
p->processed += size;
p->res = p->inStream->Skip(p->inStream, size);
size = (1 << 25);
p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size);
p->cur = p->begin;
p->end = p->begin + size;
if (size != 0)
return *p->cur++;;
}
p->extra = True;
return 0;
}
static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
{
CPpmd7 ppmd;
CByteInToLook s;
SRes res = SZ_OK;
s.p.Read = ReadByte;
s.inStream = inStream;
s.begin = s.end = s.cur = NULL;
s.extra = False;
s.res = SZ_OK;
s.processed = 0;
if (propsSize != 5)
return SZ_ERROR_UNSUPPORTED;
{
unsigned order = props[0];
UInt32 memSize = GetUi32(props + 1);
if (order < PPMD7_MIN_ORDER ||
order > PPMD7_MAX_ORDER ||
memSize < PPMD7_MIN_MEM_SIZE ||
memSize > PPMD7_MAX_MEM_SIZE)
return SZ_ERROR_UNSUPPORTED;
Ppmd7_Construct(&ppmd);
if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))
return SZ_ERROR_MEM;
Ppmd7_Init(&ppmd, order);
}
{
CPpmd7z_RangeDec rc;
Ppmd7z_RangeDec_CreateVTable(&rc);
rc.Stream = &s.p;
if (!Ppmd7z_RangeDec_Init(&rc))
res = SZ_ERROR_DATA;
else if (s.extra)
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
else
{
SizeT i;
for (i = 0; i < outSize; i++)
{
int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p);
if (s.extra || sym < 0)
break;
outBuffer[i] = (Byte)sym;
}
if (i != outSize)
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc))
res = SZ_ERROR_DATA;
}
}
Ppmd7_Free(&ppmd, allocMain);
return res;
}
#endif
static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
{
CLzmaDec state;
SRes res = SZ_OK;
LzmaDec_Construct(&state);
RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain));
state.dic = outBuffer;
state.dicBufSize = outSize;
LzmaDec_Init(&state);
for (;;)
{
const void *inBuf = NULL;
size_t lookahead = (1 << 18);
if (lookahead > inSize)
lookahead = (size_t)inSize;
res = inStream->Look(inStream, &inBuf, &lookahead);
if (res != SZ_OK)
break;
{
SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
ELzmaStatus status;
res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
lookahead -= inProcessed;
inSize -= inProcessed;
if (res != SZ_OK)
break;
if (status == LZMA_STATUS_FINISHED_WITH_MARK)
{
if (outSize != state.dicPos || inSize != 0)
res = SZ_ERROR_DATA;
break;
}
if (outSize == state.dicPos && inSize == 0 && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
break;
if (inProcessed == 0 && dicPos == state.dicPos)
{
res = SZ_ERROR_DATA;
break;
}
res = inStream->Skip((void *)inStream, inProcessed);
if (res != SZ_OK)
break;
}
}
LzmaDec_FreeProbs(&state, allocMain);
return res;
}
#ifndef _7Z_NO_METHOD_LZMA2
static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
{
CLzma2Dec state;
SRes res = SZ_OK;
Lzma2Dec_Construct(&state);
if (propsSize != 1)
return SZ_ERROR_DATA;
RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain));
state.decoder.dic = outBuffer;
state.decoder.dicBufSize = outSize;
Lzma2Dec_Init(&state);
for (;;)
{
const void *inBuf = NULL;
size_t lookahead = (1 << 18);
if (lookahead > inSize)
lookahead = (size_t)inSize;
res = inStream->Look(inStream, &inBuf, &lookahead);
if (res != SZ_OK)
break;
{
SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;
ELzmaStatus status;
res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
lookahead -= inProcessed;
inSize -= inProcessed;
if (res != SZ_OK)
break;
if (status == LZMA_STATUS_FINISHED_WITH_MARK)
{
if (outSize != state.decoder.dicPos || inSize != 0)
res = SZ_ERROR_DATA;
break;
}
if (inProcessed == 0 && dicPos == state.decoder.dicPos)
{
res = SZ_ERROR_DATA;
break;
}
res = inStream->Skip((void *)inStream, inProcessed);
if (res != SZ_OK)
break;
}
}
Lzma2Dec_FreeProbs(&state, allocMain);
return res;
}
#endif
static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
{
while (inSize > 0)
{
const void *inBuf;
size_t curSize = (1 << 18);
if (curSize > inSize)
curSize = (size_t)inSize;
RINOK(inStream->Look(inStream, &inBuf, &curSize));
if (curSize == 0)
return SZ_ERROR_INPUT_EOF;
memcpy(outBuffer, inBuf, curSize);
outBuffer += curSize;
inSize -= curSize;
RINOK(inStream->Skip((void *)inStream, curSize));
}
return SZ_OK;
}
static Bool IS_MAIN_METHOD(UInt32 m)
{
switch (m)
{
case k_Copy:
case k_LZMA:
#ifndef _7Z_NO_METHOD_LZMA2
case k_LZMA2:
#endif
#ifdef _7ZIP_PPMD_SUPPPORT
case k_PPMD:
#endif
return True;
}
return False;
}
static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
{
return
c->NumStreams == 1
/* && c->MethodID <= (UInt32)0xFFFFFFFF */
&& IS_MAIN_METHOD((UInt32)c->MethodID);
}
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumStreams == 4)
static SRes CheckSupportedFolder(const CSzFolder *f)
{
if (f->NumCoders < 1 || f->NumCoders > 4)
return SZ_ERROR_UNSUPPORTED;
if (!IS_SUPPORTED_CODER(&f->Coders[0]))
return SZ_ERROR_UNSUPPORTED;
if (f->NumCoders == 1)
{
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBonds != 0)
return SZ_ERROR_UNSUPPORTED;
return SZ_OK;
}
#ifndef _7Z_NO_METHODS_FILTERS
if (f->NumCoders == 2)
{
const CSzCoderInfo *c = &f->Coders[1];
if (
/* c->MethodID > (UInt32)0xFFFFFFFF || */
c->NumStreams != 1
|| f->NumPackStreams != 1
|| f->PackStreams[0] != 0
|| f->NumBonds != 1
|| f->Bonds[0].InIndex != 1
|| f->Bonds[0].OutIndex != 0)
return SZ_ERROR_UNSUPPORTED;
switch ((UInt32)c->MethodID)
{
case k_Delta:
case k_BCJ:
case k_PPC:
case k_IA64:
case k_SPARC:
case k_ARM:
case k_ARMT:
break;
default:
return SZ_ERROR_UNSUPPORTED;
}
return SZ_OK;
}
#endif
if (f->NumCoders == 4)
{
if (!IS_SUPPORTED_CODER(&f->Coders[1])
|| !IS_SUPPORTED_CODER(&f->Coders[2])
|| !IS_BCJ2(&f->Coders[3]))
return SZ_ERROR_UNSUPPORTED;
if (f->NumPackStreams != 4
|| f->PackStreams[0] != 2
|| f->PackStreams[1] != 6
|| f->PackStreams[2] != 1
|| f->PackStreams[3] != 0
|| f->NumBonds != 3
|| f->Bonds[0].InIndex != 5 || f->Bonds[0].OutIndex != 0
|| f->Bonds[1].InIndex != 4 || f->Bonds[1].OutIndex != 1
|| f->Bonds[2].InIndex != 3 || f->Bonds[2].OutIndex != 2)
return SZ_ERROR_UNSUPPORTED;
return SZ_OK;
}
return SZ_ERROR_UNSUPPORTED;
}
#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;
static SRes SzFolder_Decode2(const CSzFolder *folder,
const Byte *propsData,
const UInt64 *unpackSizes,
const UInt64 *packPositions,
ILookInStream *inStream, UInt64 startPos,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
Byte *tempBuf[])
{
UInt32 ci;
SizeT tempSizes[3] = { 0, 0, 0};
SizeT tempSize3 = 0;
Byte *tempBuf3 = 0;
RINOK(CheckSupportedFolder(folder));
for (ci = 0; ci < folder->NumCoders; ci++)
{
const CSzCoderInfo *coder = &folder->Coders[ci];
if (IS_MAIN_METHOD((UInt32)coder->MethodID))
{
UInt32 si = 0;
UInt64 offset;
UInt64 inSize;
Byte *outBufCur = outBuffer;
SizeT outSizeCur = outSize;
if (folder->NumCoders == 4)
{
UInt32 indices[] = { 3, 2, 0 };
UInt64 unpackSize = unpackSizes[ci];
si = indices[ci];
if (ci < 2)
{
Byte *temp;
outSizeCur = (SizeT)unpackSize;
if (outSizeCur != unpackSize)
return SZ_ERROR_MEM;
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
if (!temp && outSizeCur != 0)
return SZ_ERROR_MEM;
outBufCur = tempBuf[1 - ci] = temp;
tempSizes[1 - ci] = outSizeCur;
}
else if (ci == 2)
{
if (unpackSize > outSize) /* check it */
return SZ_ERROR_PARAM;
tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
tempSize3 = outSizeCur = (SizeT)unpackSize;
}
else
return SZ_ERROR_UNSUPPORTED;
}
offset = packPositions[si];
inSize = packPositions[si + 1] - offset;
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
if (coder->MethodID == k_Copy)
{
if (inSize != outSizeCur) /* check it */
return SZ_ERROR_DATA;
RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
}
else if (coder->MethodID == k_LZMA)
{
RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
}
#ifndef _7Z_NO_METHOD_LZMA2
else if (coder->MethodID == k_LZMA2)
{
RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
}
#endif
#ifdef _7ZIP_PPMD_SUPPPORT
else if (coder->MethodID == k_PPMD)
{
RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
}
#endif
else
return SZ_ERROR_UNSUPPORTED;
}
else if (coder->MethodID == k_BCJ2)
{
UInt64 offset = packPositions[1];
UInt64 s3Size = packPositions[2] - offset;
if (ci != 3)
return SZ_ERROR_UNSUPPORTED;
tempSizes[2] = (SizeT)s3Size;
if (tempSizes[2] != s3Size)
return SZ_ERROR_MEM;
tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
if (!tempBuf[2] && tempSizes[2] != 0)
return SZ_ERROR_MEM;
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2]));
if ((tempSizes[0] & 3) != 0 ||
(tempSizes[1] & 3) != 0 ||
tempSize3 + tempSizes[0] + tempSizes[1] != outSize)
return SZ_ERROR_DATA;
{
CBcj2Dec p;
p.bufs[0] = tempBuf3; p.lims[0] = tempBuf3 + tempSize3;
p.bufs[1] = tempBuf[0]; p.lims[1] = tempBuf[0] + tempSizes[0];
p.bufs[2] = tempBuf[1]; p.lims[2] = tempBuf[1] + tempSizes[1];
p.bufs[3] = tempBuf[2]; p.lims[3] = tempBuf[2] + tempSizes[2];
p.dest = outBuffer;
p.destLim = outBuffer + outSize;
Bcj2Dec_Init(&p);
RINOK(Bcj2Dec_Decode(&p));
{
unsigned i;
for (i = 0; i < 4; i++)
if (p.bufs[i] != p.lims[i])
return SZ_ERROR_DATA;
if (!Bcj2Dec_IsFinished(&p))
return SZ_ERROR_DATA;
if (p.dest != p.destLim
|| p.state != BCJ2_STREAM_MAIN)
return SZ_ERROR_DATA;
}
}
}
#ifndef _7Z_NO_METHODS_FILTERS
else if (ci == 1)
{
if (coder->MethodID == k_Delta)
{
if (coder->PropsSize != 1)
return SZ_ERROR_UNSUPPORTED;
{
Byte state[DELTA_STATE_SIZE];
Delta_Init(state);
Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize);
}
}
else
{
if (coder->PropsSize != 0)
return SZ_ERROR_UNSUPPORTED;
switch (coder->MethodID)
{
case k_BCJ:
{
UInt32 state;
x86_Convert_Init(state);
x86_Convert(outBuffer, outSize, 0, &state, 0);
break;
}
CASE_BRA_CONV(PPC)
CASE_BRA_CONV(IA64)
CASE_BRA_CONV(SPARC)
CASE_BRA_CONV(ARM)
CASE_BRA_CONV(ARMT)
default:
return SZ_ERROR_UNSUPPORTED;
}
}
}
#endif
else
return SZ_ERROR_UNSUPPORTED;
}
return SZ_OK;
}
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *inStream, UInt64 startPos,
Byte *outBuffer, size_t outSize,
ISzAlloc *allocMain)
{
SRes res;
CSzFolder folder;
CSzData sd;
const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
sd.Data = data;
sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex];
res = SzGetNextFolderItem(&folder, &sd);
if (res != SZ_OK)
return res;
if (sd.Size != 0
|| folder.UnpackStream != p->FoToMainUnpackSizeIndex[folderIndex]
|| outSize != SzAr_GetFolderUnpackSize(p, folderIndex))
return SZ_ERROR_FAIL;
{
unsigned i;
Byte *tempBuf[3] = { 0, 0, 0};
res = SzFolder_Decode2(&folder, data,
&p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex]],
p->PackPositions + p->FoStartPackStreamIndex[folderIndex],
inStream, startPos,
outBuffer, (SizeT)outSize, allocMain, tempBuf);
for (i = 0; i < 3; i++)
IAlloc_Free(allocMain, tempBuf[i]);
if (res == SZ_OK)
if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))
if (CrcCalc(outBuffer, outSize) != p->FolderCRCs.Vals[folderIndex])
res = SZ_ERROR_CRC;
return res;
}
}

286
SevenZip/7zFile.c Normal file
View file

@ -0,0 +1,286 @@
/* 7zFile.c -- File IO
2009-11-24 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "7zFile.h"
#ifndef USE_WINDOWS_FILE
#ifndef UNDER_CE
#include <errno.h>
#endif
#else
/*
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"
*/
#define kChunkSizeMax (1 << 22)
#endif
void File_Construct(CSzFile *p)
{
#ifdef USE_WINDOWS_FILE
p->handle = INVALID_HANDLE_VALUE;
#else
p->file = NULL;
#endif
}
#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
static WRes File_Open(CSzFile *p, const char *name, int writeMode)
{
#ifdef USE_WINDOWS_FILE
p->handle = CreateFileA(name,
writeMode ? GENERIC_WRITE : GENERIC_READ,
FILE_SHARE_READ, NULL,
writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
#else
p->file = fopen(name, writeMode ? "wb+" : "rb");
return (p->file != 0) ? 0 :
#ifdef UNDER_CE
2; /* ENOENT */
#else
errno;
#endif
#endif
}
WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); }
#endif
#ifdef USE_WINDOWS_FILE
static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode)
{
p->handle = CreateFileW(name,
writeMode ? GENERIC_WRITE : GENERIC_READ,
FILE_SHARE_READ, NULL,
writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
}
WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); }
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); }
#endif
WRes File_Close(CSzFile *p)
{
#ifdef USE_WINDOWS_FILE
if (p->handle != INVALID_HANDLE_VALUE)
{
if (!CloseHandle(p->handle))
return GetLastError();
p->handle = INVALID_HANDLE_VALUE;
}
#else
if (p->file != NULL)
{
int res = fclose(p->file);
if (res != 0)
return res;
p->file = NULL;
}
#endif
return 0;
}
WRes File_Read(CSzFile *p, void *data, size_t *size)
{
size_t originalSize = *size;
if (originalSize == 0)
return 0;
#ifdef USE_WINDOWS_FILE
*size = 0;
do
{
DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
DWORD processed = 0;
BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL);
data = (void *)((Byte *)data + processed);
originalSize -= processed;
*size += processed;
if (!res)
return GetLastError();
if (processed == 0)
break;
}
while (originalSize > 0);
return 0;
#else
*size = fread(data, 1, originalSize, p->file);
if (*size == originalSize)
return 0;
return ferror(p->file);
#endif
}
WRes File_Write(CSzFile *p, const void *data, size_t *size)
{
size_t originalSize = *size;
if (originalSize == 0)
return 0;
#ifdef USE_WINDOWS_FILE
*size = 0;
do
{
DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
DWORD processed = 0;
BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL);
data = (void *)((Byte *)data + processed);
originalSize -= processed;
*size += processed;
if (!res)
return GetLastError();
if (processed == 0)
break;
}
while (originalSize > 0);
return 0;
#else
*size = fwrite(data, 1, originalSize, p->file);
if (*size == originalSize)
return 0;
return ferror(p->file);
#endif
}
WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin)
{
#ifdef USE_WINDOWS_FILE
LARGE_INTEGER value;
DWORD moveMethod;
value.LowPart = (DWORD)*pos;
value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */
switch (origin)
{
case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break;
case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break;
case SZ_SEEK_END: moveMethod = FILE_END; break;
default: return ERROR_INVALID_PARAMETER;
}
value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod);
if (value.LowPart == 0xFFFFFFFF)
{
WRes res = GetLastError();
if (res != NO_ERROR)
return res;
}
*pos = ((Int64)value.HighPart << 32) | value.LowPart;
return 0;
#else
int moveMethod;
int res;
switch (origin)
{
case SZ_SEEK_SET: moveMethod = SEEK_SET; break;
case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break;
case SZ_SEEK_END: moveMethod = SEEK_END; break;
default: return 1;
}
res = fseek(p->file, (long)*pos, moveMethod);
*pos = ftell(p->file);
return res;
#endif
}
WRes File_GetLength(CSzFile *p, UInt64 *length)
{
#ifdef USE_WINDOWS_FILE
DWORD sizeHigh;
DWORD sizeLow = GetFileSize(p->handle, &sizeHigh);
if (sizeLow == 0xFFFFFFFF)
{
DWORD res = GetLastError();
if (res != NO_ERROR)
return res;
}
*length = (((UInt64)sizeHigh) << 32) + sizeLow;
return 0;
#else
long pos = ftell(p->file);
int res = fseek(p->file, 0, SEEK_END);
*length = ftell(p->file);
fseek(p->file, pos, SEEK_SET);
return res;
#endif
}
/* ---------- FileSeqInStream ---------- */
static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size)
{
CFileSeqInStream *p = (CFileSeqInStream *)pp;
return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
}
void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
{
p->s.Read = FileSeqInStream_Read;
}
/* ---------- FileInStream ---------- */
static SRes FileInStream_Read(void *pp, void *buf, size_t *size)
{
CFileInStream *p = (CFileInStream *)pp;
return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
}
static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin)
{
CFileInStream *p = (CFileInStream *)pp;
return File_Seek(&p->file, pos, origin);
}
void FileInStream_CreateVTable(CFileInStream *p)
{
p->s.Read = FileInStream_Read;
p->s.Seek = FileInStream_Seek;
}
/* ---------- FileOutStream ---------- */
static size_t FileOutStream_Write(void *pp, const void *data, size_t size)
{
CFileOutStream *p = (CFileOutStream *)pp;
File_Write(&p->file, data, &size);
return size;
}
void FileOutStream_CreateVTable(CFileOutStream *p)
{
p->s.Write = FileOutStream_Write;
}

83
SevenZip/7zFile.h Normal file
View file

@ -0,0 +1,83 @@
/* 7zFile.h -- File IO
2013-01-18 : Igor Pavlov : Public domain */
#ifndef __7Z_FILE_H
#define __7Z_FILE_H
#ifdef _WIN32
#define USE_WINDOWS_FILE
#endif
#ifdef USE_WINDOWS_FILE
#include <windows.h>
#else
#include <stdio.h>
#endif
#include "7zTypes.h"
EXTERN_C_BEGIN
/* ---------- File ---------- */
typedef struct
{
#ifdef USE_WINDOWS_FILE
HANDLE handle;
#else
FILE *file;
#endif
} CSzFile;
void File_Construct(CSzFile *p);
#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
WRes InFile_Open(CSzFile *p, const char *name);
WRes OutFile_Open(CSzFile *p, const char *name);
#endif
#ifdef USE_WINDOWS_FILE
WRes InFile_OpenW(CSzFile *p, const WCHAR *name);
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name);
#endif
WRes File_Close(CSzFile *p);
/* reads max(*size, remain file's size) bytes */
WRes File_Read(CSzFile *p, void *data, size_t *size);
/* writes *size bytes */
WRes File_Write(CSzFile *p, const void *data, size_t *size);
WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin);
WRes File_GetLength(CSzFile *p, UInt64 *length);
/* ---------- FileInStream ---------- */
typedef struct
{
ISeqInStream s;
CSzFile file;
} CFileSeqInStream;
void FileSeqInStream_CreateVTable(CFileSeqInStream *p);
typedef struct
{
ISeekInStream s;
CSzFile file;
} CFileInStream;
void FileInStream_CreateVTable(CFileInStream *p);
typedef struct
{
ISeqOutStream s;
CSzFile file;
} CFileOutStream;
void FileOutStream_CreateVTable(CFileOutStream *p);
EXTERN_C_END
#endif

53
SevenZip/7zMemBuffer.c Normal file
View file

@ -0,0 +1,53 @@
#include "Precomp.h"
#include "7zMemBuffer.h"
#include <memory.h>
WRes MemBuffer_Read(CSzMemBuffer *p, void *data, size_t *size)
{
size_t originalSize = *size;
if(originalSize == 0)
return 0;
size_t length = p->pos + *size > p->size ? p->size - p->pos - 1 : *size;
memcpy(data, (char*)(p->buffer) + p->pos, length);
p->pos += length;
return 0;
}
WRes MemBuffer_Seek(CSzMemBuffer *p, Int64 *pos, ESzSeek origin)
{
switch(origin) {
case SZ_SEEK_SET: p->pos = 0 + *pos; break;
case SZ_SEEK_CUR: p->pos += *pos; break;
case SZ_SEEK_END: p->pos = p->size - *pos; break;
default: return 1;
}
*pos = p->pos;
return 0;
}
static SRes MemBufferInStream_Read(void *pp, void *buf, size_t *size)
{
CMemBufferInStream *p = (CMemBufferInStream *)pp;
return (MemBuffer_Read(&p->buffer, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
}
static SRes MemBufferInStream_Seek(void *pp, Int64 *pos, ESzSeek origin)
{
CMemBufferInStream *p = (CMemBufferInStream *)pp;
return MemBuffer_Seek(&p->buffer, pos, origin);
}
void MemBufferInit(CMemBufferInStream *memBuferStream, CLookToRead *lookStream, void* buffer, size_t size)
{
memBuferStream->buffer.buffer = buffer;
memBuferStream->buffer.pos = 0;
memBuferStream->buffer.size = size;
memBuferStream->s.Read = MemBufferInStream_Read;
memBuferStream->s.Seek = MemBufferInStream_Seek;
LookToRead_CreateVTable(lookStream, False);
lookStream->realStream = &memBuferStream->s;
LookToRead_Init(lookStream);
}

29
SevenZip/7zMemBuffer.h Normal file
View file

@ -0,0 +1,29 @@
#pragma once
#include "7zTypes.h"
EXTERN_C_BEGIN
/* ---------- File ---------- */
typedef struct
{
void* buffer;
size_t size;
size_t pos;
} CSzMemBuffer;
/* reads max(*size, remain file's size) bytes */
WRes MemBuffer_Read(CSzMemBuffer *p, void *data, size_t *size);
WRes MemBuffer_Seek(CSzMemBuffer *p, Int64 *pos, ESzSeek origin);
/* ---------- FileInStream ---------- */
typedef struct
{
ISeekInStream s;
CSzMemBuffer buffer;
} CMemBufferInStream;
void MemBufferInit(CMemBufferInStream *memBuferStream, CLookToRead *lookStream, void* buffer, size_t size);
EXTERN_C_END

171
SevenZip/7zStream.c Normal file
View file

@ -0,0 +1,171 @@
/* 7zStream.c -- 7z Stream functions
2013-11-12 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <string.h>
#include "7zTypes.h"
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
{
while (size != 0)
{
size_t processed = size;
RINOK(stream->Read(stream, buf, &processed));
if (processed == 0)
return errorType;
buf = (void *)((Byte *)buf + processed);
size -= processed;
}
return SZ_OK;
}
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
{
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
}
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)
{
size_t processed = 1;
RINOK(stream->Read(stream, buf, &processed));
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
}
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
{
Int64 t = offset;
return stream->Seek(stream, &t, SZ_SEEK_SET);
}
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
{
const void *lookBuf;
if (*size == 0)
return SZ_OK;
RINOK(stream->Look(stream, &lookBuf, size));
memcpy(buf, lookBuf, *size);
return stream->Skip(stream, *size);
}
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
{
while (size != 0)
{
size_t processed = size;
RINOK(stream->Read(stream, buf, &processed));
if (processed == 0)
return errorType;
buf = (void *)((Byte *)buf + processed);
size -= processed;
}
return SZ_OK;
}
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
{
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
}
static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size)
{
SRes res = SZ_OK;
CLookToRead *p = (CLookToRead *)pp;
size_t size2 = p->size - p->pos;
if (size2 == 0 && *size > 0)
{
p->pos = 0;
size2 = LookToRead_BUF_SIZE;
res = p->realStream->Read(p->realStream, p->buf, &size2);
p->size = size2;
}
if (size2 < *size)
*size = size2;
*buf = p->buf + p->pos;
return res;
}
static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size)
{
SRes res = SZ_OK;
CLookToRead *p = (CLookToRead *)pp;
size_t size2 = p->size - p->pos;
if (size2 == 0 && *size > 0)
{
p->pos = 0;
if (*size > LookToRead_BUF_SIZE)
*size = LookToRead_BUF_SIZE;
res = p->realStream->Read(p->realStream, p->buf, size);
size2 = p->size = *size;
}
if (size2 < *size)
*size = size2;
*buf = p->buf + p->pos;
return res;
}
static SRes LookToRead_Skip(void *pp, size_t offset)
{
CLookToRead *p = (CLookToRead *)pp;
p->pos += offset;
return SZ_OK;
}
static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
{
CLookToRead *p = (CLookToRead *)pp;
size_t rem = p->size - p->pos;
if (rem == 0)
return p->realStream->Read(p->realStream, buf, size);
if (rem > *size)
rem = *size;
memcpy(buf, p->buf + p->pos, rem);
p->pos += rem;
*size = rem;
return SZ_OK;
}
static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
{
CLookToRead *p = (CLookToRead *)pp;
p->pos = p->size = 0;
return p->realStream->Seek(p->realStream, pos, origin);
}
void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
{
p->s.Look = lookahead ?
LookToRead_Look_Lookahead :
LookToRead_Look_Exact;
p->s.Skip = LookToRead_Skip;
p->s.Read = LookToRead_Read;
p->s.Seek = LookToRead_Seek;
}
void LookToRead_Init(CLookToRead *p)
{
p->pos = p->size = 0;
}
static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
{
CSecToLook *p = (CSecToLook *)pp;
return LookInStream_LookRead(p->realStream, buf, size);
}
void SecToLook_CreateVTable(CSecToLook *p)
{
p->s.Read = SecToLook_Read;
}
static SRes SecToRead_Read(void *pp, void *buf, size_t *size)
{
CSecToRead *p = (CSecToRead *)pp;
return p->realStream->Read(p->realStream, buf, size);
}
void SecToRead_CreateVTable(CSecToRead *p)
{
p->s.Read = SecToRead_Read;
}

256
SevenZip/7zTypes.h Normal file
View file

@ -0,0 +1,256 @@
/* 7zTypes.h -- Basic types
2013-11-12 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H
#define __7Z_TYPES_H
#ifdef _WIN32
/* #include <windows.h> */
#endif
#include <stddef.h>
#ifndef EXTERN_C_BEGIN
#ifdef __cplusplus
#define EXTERN_C_BEGIN extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C_BEGIN
#define EXTERN_C_END
#endif
#endif
EXTERN_C_BEGIN
#define SZ_OK 0
#define SZ_ERROR_DATA 1
#define SZ_ERROR_MEM 2
#define SZ_ERROR_CRC 3
#define SZ_ERROR_UNSUPPORTED 4
#define SZ_ERROR_PARAM 5
#define SZ_ERROR_INPUT_EOF 6
#define SZ_ERROR_OUTPUT_EOF 7
#define SZ_ERROR_READ 8
#define SZ_ERROR_WRITE 9
#define SZ_ERROR_PROGRESS 10
#define SZ_ERROR_FAIL 11
#define SZ_ERROR_THREAD 12
#define SZ_ERROR_ARCHIVE 16
#define SZ_ERROR_NO_ARCHIVE 17
typedef int SRes;
#ifdef _WIN32
/* typedef DWORD WRes; */
typedef unsigned 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;
#define UINT64_CONST(n) n
#else
typedef long long int Int64;
typedef unsigned long long int UInt64;
#define UINT64_CONST(n) n ## ULL
#endif
#endif
#ifdef _LZMA_NO_SYSTEM_SIZE_T
typedef UInt32 SizeT;
#else
typedef size_t SizeT;
#endif
typedef int Bool;
#define True 1
#define False 0
#ifdef _WIN32
#define MY_STD_CALL __stdcall
#else
#define MY_STD_CALL
#endif
#ifdef _MSC_VER
#if _MSC_VER >= 1300
#define MY_NO_INLINE __declspec(noinline)
#else
#define MY_NO_INLINE
#endif
#define MY_CDECL __cdecl
#define MY_FAST_CALL __fastcall
#else
#define MY_NO_INLINE
#define MY_CDECL
#define MY_FAST_CALL
#endif
/* The following interfaces use first parameter as pointer to structure */
typedef struct
{
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
} IByteIn;
typedef struct
{
void (*Write)(void *p, Byte b);
} IByteOut;
typedef struct
{
SRes (*Read)(void *p, void *buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */
} ISeqInStream;
/* it can return SZ_ERROR_INPUT_EOF */
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
typedef struct
{
size_t (*Write)(void *p, const void *buf, size_t size);
/* Returns: result - the number of actually written bytes.
(result < size) means error */
} ISeqOutStream;
typedef enum
{
SZ_SEEK_SET = 0,
SZ_SEEK_CUR = 1,
SZ_SEEK_END = 2
} ESzSeek;
typedef struct
{
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
} ISeekInStream;
typedef struct
{
SRes (*Look)(void *p, const void **buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) > input(*size)) is not allowed
(output(*size) < input(*size)) is allowed */
SRes (*Skip)(void *p, size_t offset);
/* offset must be <= output(*size) of Look */
SRes (*Read)(void *p, void *buf, size_t *size);
/* reads directly (without buffer). It's same as ISeqInStream::Read */
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
} ILookInStream;
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
/* reads via ILookInStream::Read */
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
#define LookToRead_BUF_SIZE (1 << 14)
typedef struct
{
ILookInStream s;
ISeekInStream *realStream;
size_t pos;
size_t size;
Byte buf[LookToRead_BUF_SIZE];
} CLookToRead;
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
void LookToRead_Init(CLookToRead *p);
typedef struct
{
ISeqInStream s;
ILookInStream *realStream;
} CSecToLook;
void SecToLook_CreateVTable(CSecToLook *p);
typedef struct
{
ISeqInStream s;
ILookInStream *realStream;
} CSecToRead;
void SecToRead_CreateVTable(CSecToRead *p);
typedef struct
{
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
/* Returns: result. (result != SZ_OK) means break.
Value (UInt64)(Int64)-1 for size means unknown value. */
} ICompressProgress;
typedef struct
{
void *(*Alloc)(void *p, size_t size);
void (*Free)(void *p, void *address); /* address can be 0 */
} ISzAlloc;
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
#define IAlloc_Free(p, a) (p)->Free((p), a)
#ifdef _WIN32
#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"/"
#endif
EXTERN_C_END
#endif

256
SevenZip/Bcj2.c Normal file
View file

@ -0,0 +1,256 @@
/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
2015-08-01 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "Bcj2.h"
#include "CpuArch.h"
#define CProb UInt16
#define kTopValue ((UInt32)1 << 24)
#define kNumModelBits 11
#define kBitModelTotal (1 << kNumModelBits)
#define kNumMoveBits 5
#define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound)
#define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
#define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits));
void Bcj2Dec_Init(CBcj2Dec *p)
{
unsigned i;
p->state = BCJ2_DEC_STATE_OK;
p->ip = 0;
p->temp[3] = 0;
p->range = 0;
p->code = 0;
for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++)
p->probs[i] = kBitModelTotal >> 1;
}
SRes Bcj2Dec_Decode(CBcj2Dec *p)
{
if (p->range <= 5)
{
p->state = BCJ2_DEC_STATE_OK;
for (; p->range != 5; p->range++)
{
if (p->range == 1 && p->code != 0)
return SZ_ERROR_DATA;
if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
{
p->state = BCJ2_STREAM_RC;
return SZ_OK;
}
p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
}
if (p->code == 0xFFFFFFFF)
return SZ_ERROR_DATA;
p->range = 0xFFFFFFFF;
}
else if (p->state >= BCJ2_DEC_STATE_ORIG_0)
{
while (p->state <= BCJ2_DEC_STATE_ORIG_3)
{
Byte *dest = p->dest;
if (dest == p->destLim)
return SZ_OK;
*dest = p->temp[p->state++ - BCJ2_DEC_STATE_ORIG_0];
p->dest = dest + 1;
}
}
/*
if (BCJ2_IS_32BIT_STREAM(p->state))
{
const Byte *cur = p->bufs[p->state];
if (cur == p->lims[p->state])
return SZ_OK;
p->bufs[p->state] = cur + 4;
{
UInt32 val;
Byte *dest;
SizeT rem;
p->ip += 4;
val = GetBe32(cur) - p->ip;
dest = p->dest;
rem = p->destLim - dest;
if (rem < 4)
{
SizeT i;
SetUi32(p->temp, val);
for (i = 0; i < rem; i++)
dest[i] = p->temp[i];
p->dest = dest + rem;
p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
return SZ_OK;
}
SetUi32(dest, val);
p->temp[3] = (Byte)(val >> 24);
p->dest = dest + 4;
p->state = BCJ2_DEC_STATE_OK;
}
}
*/
for (;;)
{
if (BCJ2_IS_32BIT_STREAM(p->state))
p->state = BCJ2_DEC_STATE_OK;
else
{
if (p->range < kTopValue)
{
if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
{
p->state = BCJ2_STREAM_RC;
return SZ_OK;
}
p->range <<= 8;
p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
}
{
const Byte *src = p->bufs[BCJ2_STREAM_MAIN];
const Byte *srcLim;
Byte *dest;
SizeT num = p->lims[BCJ2_STREAM_MAIN] - src;
if (num == 0)
{
p->state = BCJ2_STREAM_MAIN;
return SZ_OK;
}
dest = p->dest;
if (num > (SizeT)(p->destLim - dest))
{
num = p->destLim - dest;
if (num == 0)
{
p->state = BCJ2_DEC_STATE_ORIG;
return SZ_OK;
}
}
srcLim = src + num;
if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80)
*dest = src[0];
else for (;;)
{
Byte b = *src;
*dest = b;
if (b != 0x0F)
{
if ((b & 0xFE) == 0xE8)
break;
dest++;
if (++src != srcLim)
continue;
break;
}
dest++;
if (++src == srcLim)
break;
if ((*src & 0xF0) != 0x80)
continue;
*dest = *src;
break;
}
num = src - p->bufs[BCJ2_STREAM_MAIN];
if (src == srcLim)
{
p->temp[3] = src[-1];
p->bufs[BCJ2_STREAM_MAIN] = src;
p->ip += (UInt32)num;
p->dest += num;
p->state =
p->bufs[BCJ2_STREAM_MAIN] ==
p->lims[BCJ2_STREAM_MAIN] ?
(unsigned)BCJ2_STREAM_MAIN :
(unsigned)BCJ2_DEC_STATE_ORIG;
return SZ_OK;
}
{
UInt32 bound, ttt;
CProb *prob;
Byte b = src[0];
Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]);
p->temp[3] = b;
p->bufs[BCJ2_STREAM_MAIN] = src + 1;
num++;
p->ip += (UInt32)num;
p->dest += num;
prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0));
_IF_BIT_0
{
_UPDATE_0
continue;
}
_UPDATE_1
}
}
}
{
UInt32 val;
unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;
const Byte *cur = p->bufs[cj];
Byte *dest;
SizeT rem;
if (cur == p->lims[cj])
{
p->state = cj;
break;
}
val = GetBe32(cur);
p->bufs[cj] = cur + 4;
p->ip += 4;
val -= p->ip;
dest = p->dest;
rem = p->destLim - dest;
if (rem < 4)
{
SizeT i;
SetUi32(p->temp, val);
for (i = 0; i < rem; i++)
dest[i] = p->temp[i];
p->dest = dest + rem;
p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
break;
}
SetUi32(dest, val);
p->temp[3] = (Byte)(val >> 24);
p->dest = dest + 4;
}
}
if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC])
{
p->range <<= 8;
p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
}
return SZ_OK;
}

146
SevenZip/Bcj2.h Normal file
View file

@ -0,0 +1,146 @@
/* Bcj2.h -- BCJ2 Converter for x86 code
2014-11-10 : Igor Pavlov : Public domain */
#ifndef __BCJ2_H
#define __BCJ2_H
#include "7zTypes.h"
EXTERN_C_BEGIN
#define BCJ2_NUM_STREAMS 4
enum
{
BCJ2_STREAM_MAIN,
BCJ2_STREAM_CALL,
BCJ2_STREAM_JUMP,
BCJ2_STREAM_RC
};
enum
{
BCJ2_DEC_STATE_ORIG_0 = BCJ2_NUM_STREAMS,
BCJ2_DEC_STATE_ORIG_1,
BCJ2_DEC_STATE_ORIG_2,
BCJ2_DEC_STATE_ORIG_3,
BCJ2_DEC_STATE_ORIG,
BCJ2_DEC_STATE_OK
};
enum
{
BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS,
BCJ2_ENC_STATE_OK
};
#define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP)
/*
CBcj2Dec / CBcj2Enc
bufs sizes:
BUF_SIZE(n) = lims[n] - bufs[n]
bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be mutliply of 4:
(BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0
(BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0
*/
/*
CBcj2Dec:
dest is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions:
bufs[BCJ2_STREAM_MAIN] >= dest &&
bufs[BCJ2_STREAM_MAIN] - dest >= tempReserv +
BUF_SIZE(BCJ2_STREAM_CALL) +
BUF_SIZE(BCJ2_STREAM_JUMP)
tempReserv = 0 : for first call of Bcj2Dec_Decode
tempReserv = 4 : for any other calls of Bcj2Dec_Decode
overlap with offset = 1 is not allowed
*/
typedef struct
{
const Byte *bufs[BCJ2_NUM_STREAMS];
const Byte *lims[BCJ2_NUM_STREAMS];
Byte *dest;
const Byte *destLim;
unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */
UInt32 ip;
Byte temp[4];
UInt32 range;
UInt32 code;
UInt16 probs[2 + 256];
} CBcj2Dec;
void Bcj2Dec_Init(CBcj2Dec *p);
/* Returns: SZ_OK or SZ_ERROR_DATA */
SRes Bcj2Dec_Decode(CBcj2Dec *p);
#define Bcj2Dec_IsFinished(_p_) ((_p_)->code == 0)
typedef enum
{
BCJ2_ENC_FINISH_MODE_CONTINUE,
BCJ2_ENC_FINISH_MODE_END_BLOCK,
BCJ2_ENC_FINISH_MODE_END_STREAM
} EBcj2Enc_FinishMode;
typedef struct
{
Byte *bufs[BCJ2_NUM_STREAMS];
const Byte *lims[BCJ2_NUM_STREAMS];
const Byte *src;
const Byte *srcLim;
unsigned state;
EBcj2Enc_FinishMode finishMode;
Byte prevByte;
Byte cache;
UInt32 range;
UInt64 low;
UInt64 cacheSize;
UInt32 ip;
/* 32-bit ralative offset in JUMP/CALL commands is
- (mod 4 GB) in 32-bit mode
- signed Int32 in 64-bit mode
We use (mod 4 GB) check for fileSize.
Use fileSize up to 2 GB, if you want to support 32-bit and 64-bit code conversion. */
UInt32 fileIp;
UInt32 fileSize; /* (fileSize <= ((UInt32)1 << 31)), 0 means no_limit */
UInt32 relatLimit; /* (relatLimit <= ((UInt32)1 << 31)), 0 means desable_conversion */
UInt32 tempTarget;
unsigned tempPos;
Byte temp[4 * 2];
unsigned flushPos;
UInt16 probs[2 + 256];
} CBcj2Enc;
void Bcj2Enc_Init(CBcj2Enc *p);
void Bcj2Enc_Encode(CBcj2Enc *p);
#define Bcj2Enc_Get_InputData_Size(p) ((SizeT)((p)->srcLim - (p)->src) + (p)->tempPos)
#define Bcj2Enc_IsFinished(p) ((p)->flushPos == 5)
#define BCJ2_RELAT_LIMIT_NUM_BITS 26
#define BCJ2_RELAT_LIMIT ((UInt32)1 << BCJ2_RELAT_LIMIT_NUM_BITS)
/* limit for CBcj2Enc::fileSize variable */
#define BCJ2_FileSize_MAX ((UInt32)1 << 31)
EXTERN_C_END
#endif

135
SevenZip/Bra.c Normal file
View file

@ -0,0 +1,135 @@
/* Bra.c -- Converters for RISC code
2010-04-16 : Igor Pavlov : Public domain */
#include "Precomp.h"
#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;
}

64
SevenZip/Bra.h Normal file
View file

@ -0,0 +1,64 @@
/* Bra.h -- Branch converters for executables
2013-01-18 : Igor Pavlov : Public domain */
#ifndef __BRA_H
#define __BRA_H
#include "7zTypes.h"
EXTERN_C_BEGIN
/*
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);
EXTERN_C_END
#endif

82
SevenZip/Bra86.c Normal file
View file

@ -0,0 +1,82 @@
/* Bra86.c -- Converter for x86 code (BCJ)
2013-11-12 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "Bra.h"
#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0)
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
{
SizeT pos = 0;
UInt32 mask = *state & 7;
if (size < 5)
return 0;
size -= 4;
ip += 5;
for (;;)
{
Byte *p = data + pos;
const Byte *limit = data + size;
for (; p < limit; p++)
if ((*p & 0xFE) == 0xE8)
break;
{
SizeT d = (SizeT)(p - data - pos);
pos = (SizeT)(p - data);
if (p >= limit)
{
*state = (d > 2 ? 0 : mask >> (unsigned)d);
return pos;
}
if (d > 2)
mask = 0;
else
{
mask >>= (unsigned)d;
if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(mask >> 1) + 1])))
{
mask = (mask >> 1) | 4;
pos++;
continue;
}
}
}
if (Test86MSByte(p[4]))
{
UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
UInt32 cur = ip + (UInt32)pos;
pos += 5;
if (encoding)
v += cur;
else
v -= cur;
if (mask != 0)
{
unsigned sh = (mask & 6) << 2;
if (Test86MSByte((Byte)(v >> sh)))
{
v ^= (((UInt32)0x100 << sh) - 1);
if (encoding)
v += cur;
else
v -= cur;
}
mask = 0;
}
p[1] = (Byte)v;
p[2] = (Byte)(v >> 8);
p[3] = (Byte)(v >> 16);
p[4] = (Byte)(0 - ((v >> 24) & 1));
}
else
{
mask = (mask >> 1) | 4;
pos++;
}
}
}

69
SevenZip/BraIA64.c Normal file
View file

@ -0,0 +1,69 @@
/* BraIA64.c -- Converter for IA-64 code
2013-11-12 : Igor Pavlov : Public domain */
#include "Precomp.h"
#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;
}

32
SevenZip/Compiler.h Normal file
View file

@ -0,0 +1,32 @@
/* Compiler.h
2015-08-02 : Igor Pavlov : Public domain */
#ifndef __7Z_COMPILER_H
#define __7Z_COMPILER_H
#ifdef _MSC_VER
#ifdef UNDER_CE
#define RPC_NO_WINDOWS_H
/* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */
#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union
#pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int
#endif
#if _MSC_VER >= 1300
#pragma warning(disable : 4996) // This function or variable may be unsafe
#else
#pragma warning(disable : 4511) // copy constructor could not be generated
#pragma warning(disable : 4512) // assignment operator could not be generated
#pragma warning(disable : 4514) // unreferenced inline function has been removed
#pragma warning(disable : 4702) // unreachable code
#pragma warning(disable : 4710) // not inlined
#pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
#endif
#endif
#define UNUSED_VAR(x) (void)x;
/* #define UNUSED_VAR(x) x=x; */
#endif

200
SevenZip/CpuArch.c Normal file
View file

@ -0,0 +1,200 @@
/* CpuArch.c -- CPU specific code
2016-02-25: Igor Pavlov : Public domain */
#include "Precomp.h"
#include "CpuArch.h"
#ifdef MY_CPU_X86_OR_AMD64
#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
#define USE_ASM
#endif
#if !defined(USE_ASM) && _MSC_VER >= 1500
#include <intrin.h>
#endif
#if defined(USE_ASM) && !defined(MY_CPU_AMD64)
static UInt32 CheckFlag(UInt32 flag)
{
#ifdef _MSC_VER
__asm pushfd;
__asm pop EAX;
__asm mov EDX, EAX;
__asm xor EAX, flag;
__asm push EAX;
__asm popfd;
__asm pushfd;
__asm pop EAX;
__asm xor EAX, EDX;
__asm push EDX;
__asm popfd;
__asm and flag, EAX;
#else
__asm__ __volatile__ (
"pushf\n\t"
"pop %%EAX\n\t"
"movl %%EAX,%%EDX\n\t"
"xorl %0,%%EAX\n\t"
"push %%EAX\n\t"
"popf\n\t"
"pushf\n\t"
"pop %%EAX\n\t"
"xorl %%EDX,%%EAX\n\t"
"push %%EDX\n\t"
"popf\n\t"
"andl %%EAX, %0\n\t":
"=c" (flag) : "c" (flag) :
"%eax", "%edx");
#endif
return flag;
}
#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
#else
#define CHECK_CPUID_IS_SUPPORTED
#endif
void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
{
#ifdef USE_ASM
#ifdef _MSC_VER
UInt32 a2, b2, c2, d2;
__asm xor EBX, EBX;
__asm xor ECX, ECX;
__asm xor EDX, EDX;
__asm mov EAX, function;
__asm cpuid;
__asm mov a2, EAX;
__asm mov b2, EBX;
__asm mov c2, ECX;
__asm mov d2, EDX;
*a = a2;
*b = b2;
*c = c2;
*d = d2;
#else
__asm__ __volatile__ (
#if defined(MY_CPU_AMD64) && defined(__PIC__)
"mov %%rbx, %%rdi;"
"cpuid;"
"xchg %%rbx, %%rdi;"
: "=a" (*a) ,
"=D" (*b) ,
#elif defined(MY_CPU_X86) && defined(__PIC__)
"mov %%ebx, %%edi;"
"cpuid;"
"xchgl %%ebx, %%edi;"
: "=a" (*a) ,
"=D" (*b) ,
#else
"cpuid"
: "=a" (*a) ,
"=b" (*b) ,
#endif
"=c" (*c) ,
"=d" (*d)
: "0" (function)) ;
#endif
#else
int CPUInfo[4];
__cpuid(CPUInfo, function);
*a = CPUInfo[0];
*b = CPUInfo[1];
*c = CPUInfo[2];
*d = CPUInfo[3];
#endif
}
Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
{
CHECK_CPUID_IS_SUPPORTED
MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
return True;
}
static const UInt32 kVendors[][3] =
{
{ 0x756E6547, 0x49656E69, 0x6C65746E},
{ 0x68747541, 0x69746E65, 0x444D4163},
{ 0x746E6543, 0x48727561, 0x736C7561}
};
int x86cpuid_GetFirm(const Cx86cpuid *p)
{
unsigned i;
for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
{
const UInt32 *v = kVendors[i];
if (v[0] == p->vendor[0] &&
v[1] == p->vendor[1] &&
v[2] == p->vendor[2])
return (int)i;
}
return -1;
}
Bool CPU_Is_InOrder()
{
Cx86cpuid p;
int firm;
UInt32 family, model;
if (!x86cpuid_CheckAndRead(&p))
return True;
family = x86cpuid_GetFamily(p.ver);
model = x86cpuid_GetModel(p.ver);
firm = x86cpuid_GetFirm(&p);
switch (firm)
{
case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && (
/* In-Order Atom CPU */
model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
|| model == 0x26 /* 45 nm, Z6xx */
|| model == 0x27 /* 32 nm, Z2460 */
|| model == 0x35 /* 32 nm, Z2760 */
|| model == 0x36 /* 32 nm, N2xxx, D2xxx */
)));
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
}
return True;
}
#if !defined(MY_CPU_AMD64) && defined(_WIN32)
#include <windows.h>
static Bool CPU_Sys_Is_SSE_Supported()
{
OSVERSIONINFO vi;
vi.dwOSVersionInfoSize = sizeof(vi);
if (!GetVersionEx(&vi))
return False;
return (vi.dwMajorVersion >= 5);
}
#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
#else
#define CHECK_SYS_SSE_SUPPORT
#endif
Bool CPU_Is_Aes_Supported()
{
Cx86cpuid p;
CHECK_SYS_SSE_SUPPORT
if (!x86cpuid_CheckAndRead(&p))
return False;
return (p.c >> 25) & 1;
}
#endif

222
SevenZip/CpuArch.h Normal file
View file

@ -0,0 +1,222 @@
/* CpuArch.h -- CPU specific code
2015-12-01: Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H
#define __CPU_ARCH_H
#include "7zTypes.h"
EXTERN_C_BEGIN
/*
MY_CPU_LE means that CPU is LITTLE ENDIAN.
MY_CPU_BE means that CPU is BIG ENDIAN.
If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
*/
#if defined(_M_X64) \
|| defined(_M_AMD64) \
|| defined(__x86_64__) \
|| defined(__AMD64__) \
|| defined(__amd64__)
#define MY_CPU_AMD64
#endif
#if defined(MY_CPU_AMD64) \
|| defined(_M_IA64) \
|| defined(__AARCH64EL__) \
|| defined(__AARCH64EB__)
#define MY_CPU_64BIT
#endif
#if defined(_M_IX86) || defined(__i386__)
#define MY_CPU_X86
#endif
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
#define MY_CPU_X86_OR_AMD64
#endif
#if defined(MY_CPU_X86) \
|| defined(_M_ARM) \
|| defined(__ARMEL__) \
|| defined(__THUMBEL__) \
|| defined(__ARMEB__) \
|| defined(__THUMBEB__)
#define MY_CPU_32BIT
#endif
#if defined(_WIN32) && defined(_M_ARM)
#define MY_CPU_ARM_LE
#endif
#if defined(_WIN32) && defined(_M_IA64)
#define MY_CPU_IA64_LE
#endif
#if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM_LE) \
|| defined(MY_CPU_IA64_LE) \
|| defined(__LITTLE_ENDIAN__) \
|| defined(__ARMEL__) \
|| defined(__THUMBEL__) \
|| defined(__AARCH64EL__) \
|| defined(__MIPSEL__) \
|| defined(__MIPSEL) \
|| defined(_MIPSEL) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
#define MY_CPU_LE
#endif
#if defined(__BIG_ENDIAN__) \
|| defined(__ARMEB__) \
|| defined(__THUMBEB__) \
|| defined(__AARCH64EB__) \
|| defined(__MIPSEB__) \
|| defined(__MIPSEB) \
|| defined(_MIPSEB) \
|| defined(__m68k__) \
|| defined(__s390__) \
|| defined(__s390x__) \
|| defined(__zarch__) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
#define MY_CPU_BE
#endif
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
Stop_Compiling_Bad_Endian
#endif
#ifdef MY_CPU_LE
#if defined(MY_CPU_X86_OR_AMD64) \
/* || defined(__AARCH64EL__) */
#define MY_CPU_LE_UNALIGN
#endif
#endif
#ifdef MY_CPU_LE_UNALIGN
#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
#define SetUi16(p, v) { *(UInt16 *)(p) = (v); }
#define SetUi32(p, v) { *(UInt32 *)(p) = (v); }
#define SetUi64(p, v) { *(UInt64 *)(p) = (v); }
#else
#define GetUi16(p) ( (UInt16) ( \
((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 SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
_ppp_[0] = (Byte)_vvv_; \
_ppp_[1] = (Byte)(_vvv_ >> 8); }
#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
_ppp_[0] = (Byte)_vvv_; \
_ppp_[1] = (Byte)(_vvv_ >> 8); \
_ppp_[2] = (Byte)(_vvv_ >> 16); \
_ppp_[3] = (Byte)(_vvv_ >> 24); }
#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
SetUi32(_ppp2_ , (UInt32)_vvv2_); \
SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }
#endif
#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
/* Note: we use bswap instruction, that is unsupported in 386 cpu */
#include <stdlib.h>
#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))
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
#elif defined(MY_CPU_LE_UNALIGN) && defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v)
#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))
#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
_ppp_[0] = (Byte)(_vvv_ >> 24); \
_ppp_[1] = (Byte)(_vvv_ >> 16); \
_ppp_[2] = (Byte)(_vvv_ >> 8); \
_ppp_[3] = (Byte)_vvv_; }
#endif
#define GetBe16(p) ( (UInt16) ( \
((UInt16)((const Byte *)(p))[0] << 8) | \
((const Byte *)(p))[1] ))
#ifdef MY_CPU_X86_OR_AMD64
typedef struct
{
UInt32 maxFunc;
UInt32 vendor[3];
UInt32 ver;
UInt32 b;
UInt32 c;
UInt32 d;
} Cx86cpuid;
enum
{
CPU_FIRM_INTEL,
CPU_FIRM_AMD,
CPU_FIRM_VIA
};
void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
int x86cpuid_GetFirm(const Cx86cpuid *p);
#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))
#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF))
#define x86cpuid_GetStepping(ver) (ver & 0xF)
Bool CPU_Is_InOrder();
Bool CPU_Is_Aes_Supported();
#endif
EXTERN_C_END
#endif

64
SevenZip/Delta.c Normal file
View file

@ -0,0 +1,64 @@
/* Delta.c -- Delta converter
2009-05-26 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "Delta.h"
void Delta_Init(Byte *state)
{
unsigned i;
for (i = 0; i < DELTA_STATE_SIZE; i++)
state[i] = 0;
}
static void MyMemCpy(Byte *dest, const Byte *src, unsigned size)
{
unsigned i;
for (i = 0; i < size; i++)
dest[i] = src[i];
}
void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size)
{
Byte buf[DELTA_STATE_SIZE];
unsigned j = 0;
MyMemCpy(buf, state, delta);
{
SizeT i;
for (i = 0; i < size;)
{
for (j = 0; j < delta && i < size; i++, j++)
{
Byte b = data[i];
data[i] = (Byte)(b - buf[j]);
buf[j] = b;
}
}
}
if (j == delta)
j = 0;
MyMemCpy(state, buf + j, delta - j);
MyMemCpy(state + delta - j, buf, j);
}
void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size)
{
Byte buf[DELTA_STATE_SIZE];
unsigned j = 0;
MyMemCpy(buf, state, delta);
{
SizeT i;
for (i = 0; i < size;)
{
for (j = 0; j < delta && i < size; i++, j++)
{
buf[j] = data[i] = (Byte)(buf[j] + data[i]);
}
}
}
if (j == delta)
j = 0;
MyMemCpy(state, buf + j, delta - j);
MyMemCpy(state + delta - j, buf, j);
}

19
SevenZip/Delta.h Normal file
View file

@ -0,0 +1,19 @@
/* Delta.h -- Delta converter
2013-01-18 : Igor Pavlov : Public domain */
#ifndef __DELTA_H
#define __DELTA_H
#include "7zTypes.h"
EXTERN_C_BEGIN
#define DELTA_STATE_SIZE 256
void Delta_Init(Byte *state);
void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size);
void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size);
EXTERN_C_END
#endif

378
SevenZip/Lzma2Dec.c Normal file
View file

@ -0,0 +1,378 @@
/* Lzma2Dec.c -- LZMA2 Decoder
2015-11-09 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */
#include "Precomp.h"
#ifdef SHOW_DEBUG_INFO
#include <stdio.h>
#endif
#include <string.h>
#include "Lzma2Dec.h"
/*
00000000 - EOS
00000001 U U - Uncompressed Reset Dic
00000010 U U - Uncompressed No Reset
100uuuuu U U P P - LZMA no reset
101uuuuu U U P P - LZMA reset state
110uuuuu U U P P S - LZMA reset state + new prop
111uuuuu U U P P S - LZMA reset state + new prop + reset dic
u, U - Unpack Size
P - Pack Size
S - Props
*/
#define LZMA2_CONTROL_LZMA (1 << 7)
#define LZMA2_CONTROL_COPY_NO_RESET 2
#define LZMA2_CONTROL_COPY_RESET_DIC 1
#define LZMA2_CONTROL_EOF 0
#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0)
#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3)
#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
#define LZMA2_LCLP_MAX 4
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
#ifdef SHOW_DEBUG_INFO
#define PRF(x) x
#else
#define PRF(x)
#endif
typedef enum
{
LZMA2_STATE_CONTROL,
LZMA2_STATE_UNPACK0,
LZMA2_STATE_UNPACK1,
LZMA2_STATE_PACK0,
LZMA2_STATE_PACK1,
LZMA2_STATE_PROP,
LZMA2_STATE_DATA,
LZMA2_STATE_DATA_CONT,
LZMA2_STATE_FINISHED,
LZMA2_STATE_ERROR
} ELzma2State;
static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
{
UInt32 dicSize;
if (prop > 40)
return SZ_ERROR_UNSUPPORTED;
dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
props[0] = (Byte)LZMA2_LCLP_MAX;
props[1] = (Byte)(dicSize);
props[2] = (Byte)(dicSize >> 8);
props[3] = (Byte)(dicSize >> 16);
props[4] = (Byte)(dicSize >> 24);
return SZ_OK;
}
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
{
Byte props[LZMA_PROPS_SIZE];
RINOK(Lzma2Dec_GetOldProps(prop, props));
return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
}
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
{
Byte props[LZMA_PROPS_SIZE];
RINOK(Lzma2Dec_GetOldProps(prop, props));
return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
}
void Lzma2Dec_Init(CLzma2Dec *p)
{
p->state = LZMA2_STATE_CONTROL;
p->needInitDic = True;
p->needInitState = True;
p->needInitProp = True;
LzmaDec_Init(&p->decoder);
}
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
{
switch (p->state)
{
case LZMA2_STATE_CONTROL:
p->control = b;
PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos));
PRF(printf(" %2X", (unsigned)b));
if (p->control == 0)
return LZMA2_STATE_FINISHED;
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{
if ((p->control & 0x7F) > 2)
return LZMA2_STATE_ERROR;
p->unpackSize = 0;
}
else
p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
return LZMA2_STATE_UNPACK0;
case LZMA2_STATE_UNPACK0:
p->unpackSize |= (UInt32)b << 8;
return LZMA2_STATE_UNPACK1;
case LZMA2_STATE_UNPACK1:
p->unpackSize |= (UInt32)b;
p->unpackSize++;
PRF(printf(" %8u", (unsigned)p->unpackSize));
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
case LZMA2_STATE_PACK0:
p->packSize = (UInt32)b << 8;
return LZMA2_STATE_PACK1;
case LZMA2_STATE_PACK1:
p->packSize |= (UInt32)b;
p->packSize++;
PRF(printf(" %8u", (unsigned)p->packSize));
return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
(p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
case LZMA2_STATE_PROP:
{
unsigned lc, lp;
if (b >= (9 * 5 * 5))
return LZMA2_STATE_ERROR;
lc = b % 9;
b /= 9;
p->decoder.prop.pb = b / 5;
lp = b % 5;
if (lc + lp > LZMA2_LCLP_MAX)
return LZMA2_STATE_ERROR;
p->decoder.prop.lc = lc;
p->decoder.prop.lp = lp;
p->needInitProp = False;
return LZMA2_STATE_DATA;
}
}
return LZMA2_STATE_ERROR;
}
static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
{
memcpy(p->dic + p->dicPos, src, size);
p->dicPos += size;
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
p->checkDicSize = p->prop.dicSize;
p->processedPos += (UInt32)size;
}
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{
SizeT inSize = *srcLen;
*srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED;
while (p->state != LZMA2_STATE_FINISHED)
{
SizeT dicPos = p->decoder.dicPos;
if (p->state == LZMA2_STATE_ERROR)
return SZ_ERROR_DATA;
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
{
*status = LZMA_STATUS_NOT_FINISHED;
return SZ_OK;
}
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
{
if (*srcLen == inSize)
{
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
(*srcLen)++;
p->state = Lzma2Dec_UpdateState(p, *src++);
if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
{
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
continue;
}
{
SizeT destSizeCur = dicLimit - dicPos;
SizeT srcSizeCur = inSize - *srcLen;
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
if (p->unpackSize <= destSizeCur)
{
destSizeCur = (SizeT)p->unpackSize;
curFinishMode = LZMA_FINISH_END;
}
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{
if (*srcLen == inSize)
{
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
if (p->state == LZMA2_STATE_DATA)
{
Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
if (initDic)
p->needInitProp = p->needInitState = True;
else if (p->needInitDic)
{
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
p->needInitDic = False;
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
}
if (srcSizeCur > destSizeCur)
srcSizeCur = destSizeCur;
if (srcSizeCur == 0)
{
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
src += srcSizeCur;
*srcLen += srcSizeCur;
p->unpackSize -= (UInt32)srcSizeCur;
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
}
else
{
SizeT outSizeProcessed;
SRes res;
if (p->state == LZMA2_STATE_DATA)
{
unsigned mode = LZMA2_GET_LZMA_MODE(p);
Bool initDic = (mode == 3);
Bool initState = (mode != 0);
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
{
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
p->needInitDic = False;
p->needInitState = False;
p->state = LZMA2_STATE_DATA_CONT;
}
if (srcSizeCur > p->packSize)
srcSizeCur = (SizeT)p->packSize;
res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);
src += srcSizeCur;
*srcLen += srcSizeCur;
p->packSize -= (UInt32)srcSizeCur;
outSizeProcessed = p->decoder.dicPos - dicPos;
p->unpackSize -= (UInt32)outSizeProcessed;
RINOK(res);
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
return res;
if (srcSizeCur == 0 && outSizeProcessed == 0)
{
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|| p->unpackSize != 0
|| p->packSize != 0)
{
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
p->state = LZMA2_STATE_CONTROL;
}
if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
*status = LZMA_STATUS_NOT_FINISHED;
}
}
}
*status = LZMA_STATUS_FINISHED_WITH_MARK;
return SZ_OK;
}
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{
SizeT outSize = *destLen, inSize = *srcLen;
*srcLen = *destLen = 0;
for (;;)
{
SizeT srcSizeCur = inSize, outSizeCur, dicPos;
ELzmaFinishMode curFinishMode;
SRes res;
if (p->decoder.dicPos == p->decoder.dicBufSize)
p->decoder.dicPos = 0;
dicPos = p->decoder.dicPos;
if (outSize > p->decoder.dicBufSize - dicPos)
{
outSizeCur = p->decoder.dicBufSize;
curFinishMode = LZMA_FINISH_ANY;
}
else
{
outSizeCur = dicPos + outSize;
curFinishMode = finishMode;
}
res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);
src += srcSizeCur;
inSize -= srcSizeCur;
*srcLen += srcSizeCur;
outSizeCur = p->decoder.dicPos - dicPos;
memcpy(dest, p->decoder.dic + dicPos, outSizeCur);
dest += outSizeCur;
outSize -= outSizeCur;
*destLen += outSizeCur;
if (res != 0)
return res;
if (outSizeCur == 0 || outSize == 0)
return SZ_OK;
}
}
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
{
CLzma2Dec p;
SRes res;
SizeT outSize = *destLen, inSize = *srcLen;
*destLen = *srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED;
Lzma2Dec_Construct(&p);
RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc));
p.decoder.dic = dest;
p.decoder.dicBufSize = outSize;
Lzma2Dec_Init(&p);
*srcLen = inSize;
res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
*destLen = p.decoder.dicPos;
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
res = SZ_ERROR_INPUT_EOF;
Lzma2Dec_FreeProbs(&p, alloc);
return res;
}

80
SevenZip/Lzma2Dec.h Normal file
View file

@ -0,0 +1,80 @@
/* Lzma2Dec.h -- LZMA2 Decoder
2015-05-13 : Igor Pavlov : Public domain */
#ifndef __LZMA2_DEC_H
#define __LZMA2_DEC_H
#include "LzmaDec.h"
EXTERN_C_BEGIN
/* ---------- State Interface ---------- */
typedef struct
{
CLzmaDec decoder;
UInt32 packSize;
UInt32 unpackSize;
unsigned state;
Byte control;
Bool needInitDic;
Bool needInitState;
Bool needInitProp;
} CLzma2Dec;
#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder)
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc);
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc);
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
void Lzma2Dec_Init(CLzma2Dec *p);
/*
finishMode:
It has meaning only if the decoding reaches output limit (*destLen or dicLimit).
LZMA_FINISH_ANY - use smallest number of input bytes
LZMA_FINISH_END - read EndOfStream marker after decoding
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_NEEDS_MORE_INPUT
SZ_ERROR_DATA - Data error
*/
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- One Call Interface ---------- */
/*
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - use smallest number of input bytes
LZMA_FINISH_END - read EndOfStream marker after decoding
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
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 Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc);
EXTERN_C_END
#endif

1100
SevenZip/LzmaDec.c Normal file

File diff suppressed because it is too large Load diff

227
SevenZip/LzmaDec.h Normal file
View file

@ -0,0 +1,227 @@
/* LzmaDec.h -- LZMA Decoder
2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZMA_DEC_H
#define __LZMA_DEC_H
#include "7zTypes.h"
EXTERN_C_BEGIN
/* #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);
EXTERN_C_END
#endif

85
SevenZip/Ppmd.h Normal file
View file

@ -0,0 +1,85 @@
/* Ppmd.h -- PPMD codec common code
2016-05-16 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#ifndef __PPMD_H
#define __PPMD_H
#include "CpuArch.h"
EXTERN_C_BEGIN
#ifdef MY_CPU_32BIT
#define PPMD_32BIT
#endif
#define PPMD_INT_BITS 7
#define PPMD_PERIOD_BITS 7
#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS))
#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift))
#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2)
#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob))
#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob))
#define PPMD_N1 4
#define PPMD_N2 4
#define PPMD_N3 4
#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
#pragma pack(push, 1)
/* Most compilers works OK here even without #pragma pack(push, 1), but some GCC compilers need it. */
/* SEE-contexts for PPM-contexts with masked symbols */
typedef struct
{
UInt16 Summ; /* Freq */
Byte Shift; /* Speed of Freq change; low Shift is for fast change */
Byte Count; /* Count to next change of Shift */
} CPpmd_See;
#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \
{ (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); }
typedef struct
{
Byte Symbol;
Byte Freq;
UInt16 SuccessorLow;
UInt16 SuccessorHigh;
} CPpmd_State;
#pragma pack(pop)
typedef
#ifdef PPMD_32BIT
CPpmd_State *
#else
UInt32
#endif
CPpmd_State_Ref;
typedef
#ifdef PPMD_32BIT
void *
#else
UInt32
#endif
CPpmd_Void_Ref;
typedef
#ifdef PPMD_32BIT
Byte *
#else
UInt32
#endif
CPpmd_Byte_Ref;
#define PPMD_SetAllBitsIn256Bytes(p) \
{ unsigned z; for (z = 0; z < 256 / sizeof(p[0]); z += 8) { \
p[z+7] = p[z+6] = p[z+5] = p[z+4] = p[z+3] = p[z+2] = p[z+1] = p[z+0] = ~(size_t)0; }}
EXTERN_C_END
#endif

710
SevenZip/Ppmd7.c Normal file
View file

@ -0,0 +1,710 @@
/* Ppmd7.c -- PPMdH codec
2016-05-21 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Precomp.h"
#include <string.h>
#include "Ppmd7.h"
const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051};
#define MAX_FREQ 124
#define UNIT_SIZE 12
#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
#define U2I(nu) (p->Units2Indx[(nu) - 1])
#define I2U(indx) (p->Indx2Units[indx])
#ifdef PPMD_32BIT
#define REF(ptr) (ptr)
#else
#define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base))
#endif
#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr))
#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref))
#define STATS(ctx) Ppmd7_GetStats(p, ctx)
#define ONE_STATE(ctx) Ppmd7Context_OneState(ctx)
#define SUFFIX(ctx) CTX((ctx)->Suffix)
typedef CPpmd7_Context * CTX_PTR;
struct CPpmd7_Node_;
typedef
#ifdef PPMD_32BIT
struct CPpmd7_Node_ *
#else
UInt32
#endif
CPpmd7_Node_Ref;
typedef struct CPpmd7_Node_
{
UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */
UInt16 NU;
CPpmd7_Node_Ref Next; /* must be at offset >= 4 */
CPpmd7_Node_Ref Prev;
} CPpmd7_Node;
#ifdef PPMD_32BIT
#define NODE(ptr) (ptr)
#else
#define NODE(offs) ((CPpmd7_Node *)(p->Base + (offs)))
#endif
void Ppmd7_Construct(CPpmd7 *p)
{
unsigned i, k, m;
p->Base = 0;
for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
{
unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
do { p->Units2Indx[k++] = (Byte)i; } while (--step);
p->Indx2Units[i] = (Byte)k;
}
p->NS2BSIndx[0] = (0 << 1);
p->NS2BSIndx[1] = (1 << 1);
memset(p->NS2BSIndx + 2, (2 << 1), 9);
memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11);
for (i = 0; i < 3; i++)
p->NS2Indx[i] = (Byte)i;
for (m = i, k = 1; i < 256; i++)
{
p->NS2Indx[i] = (Byte)m;
if (--k == 0)
k = (++m) - 2;
}
memset(p->HB2Flag, 0, 0x40);
memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40);
}
void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->Base);
p->Size = 0;
p->Base = 0;
}
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc)
{
if (p->Base == 0 || p->Size != size)
{
Ppmd7_Free(p, alloc);
p->AlignOffset =
#ifdef PPMD_32BIT
(4 - size) & 3;
#else
4 - (size & 3);
#endif
if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size
#ifndef PPMD_32BIT
+ UNIT_SIZE
#endif
)) == 0)
return False;
p->Size = size;
}
return True;
}
static void InsertNode(CPpmd7 *p, void *node, unsigned indx)
{
*((CPpmd_Void_Ref *)node) = p->FreeList[indx];
p->FreeList[indx] = REF(node);
}
static void *RemoveNode(CPpmd7 *p, unsigned indx)
{
CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]);
p->FreeList[indx] = *node;
return node;
}
static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx)
{
unsigned i, nu = I2U(oldIndx) - I2U(newIndx);
ptr = (Byte *)ptr + U2B(I2U(newIndx));
if (I2U(i = U2I(nu)) != nu)
{
unsigned k = I2U(--i);
InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1);
}
InsertNode(p, ptr, i);
}
static void GlueFreeBlocks(CPpmd7 *p)
{
#ifdef PPMD_32BIT
CPpmd7_Node headItem;
CPpmd7_Node_Ref head = &headItem;
#else
CPpmd7_Node_Ref head = p->AlignOffset + p->Size;
#endif
CPpmd7_Node_Ref n = head;
unsigned i;
p->GlueCount = 255;
/* create doubly-linked list of free blocks */
for (i = 0; i < PPMD_NUM_INDEXES; i++)
{
UInt16 nu = I2U(i);
CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i];
p->FreeList[i] = 0;
while (next != 0)
{
CPpmd7_Node *node = NODE(next);
node->Next = n;
n = NODE(n)->Prev = next;
next = *(const CPpmd7_Node_Ref *)node;
node->Stamp = 0;
node->NU = (UInt16)nu;
}
}
NODE(head)->Stamp = 1;
NODE(head)->Next = n;
NODE(n)->Prev = head;
if (p->LoUnit != p->HiUnit)
((CPpmd7_Node *)p->LoUnit)->Stamp = 1;
/* Glue free blocks */
while (n != head)
{
CPpmd7_Node *node = NODE(n);
UInt32 nu = (UInt32)node->NU;
for (;;)
{
CPpmd7_Node *node2 = NODE(n) + nu;
nu += node2->NU;
if (node2->Stamp != 0 || nu >= 0x10000)
break;
NODE(node2->Prev)->Next = node2->Next;
NODE(node2->Next)->Prev = node2->Prev;
node->NU = (UInt16)nu;
}
n = node->Next;
}
/* Fill lists of free blocks */
for (n = NODE(head)->Next; n != head;)
{
CPpmd7_Node *node = NODE(n);
unsigned nu;
CPpmd7_Node_Ref next = node->Next;
for (nu = node->NU; nu > 128; nu -= 128, node += 128)
InsertNode(p, node, PPMD_NUM_INDEXES - 1);
if (I2U(i = U2I(nu)) != nu)
{
unsigned k = I2U(--i);
InsertNode(p, node + k, nu - k - 1);
}
InsertNode(p, node, i);
n = next;
}
}
static void *AllocUnitsRare(CPpmd7 *p, unsigned indx)
{
unsigned i;
void *retVal;
if (p->GlueCount == 0)
{
GlueFreeBlocks(p);
if (p->FreeList[indx] != 0)
return RemoveNode(p, indx);
}
i = indx;
do
{
if (++i == PPMD_NUM_INDEXES)
{
UInt32 numBytes = U2B(I2U(indx));
p->GlueCount--;
return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL);
}
}
while (p->FreeList[i] == 0);
retVal = RemoveNode(p, i);
SplitBlock(p, retVal, i, indx);
return retVal;
}
static void *AllocUnits(CPpmd7 *p, unsigned indx)
{
UInt32 numBytes;
if (p->FreeList[indx] != 0)
return RemoveNode(p, indx);
numBytes = U2B(I2U(indx));
if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit))
{
void *retVal = p->LoUnit;
p->LoUnit += numBytes;
return retVal;
}
return AllocUnitsRare(p, indx);
}
#define MyMem12Cpy(dest, src, num) \
{ UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while (--n); }
static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
{
unsigned i0 = U2I(oldNU);
unsigned i1 = U2I(newNU);
if (i0 == i1)
return oldPtr;
if (p->FreeList[i1] != 0)
{
void *ptr = RemoveNode(p, i1);
MyMem12Cpy(ptr, oldPtr, newNU);
InsertNode(p, oldPtr, i0);
return ptr;
}
SplitBlock(p, oldPtr, i0, i1);
return oldPtr;
}
#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16)))
static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v)
{
(p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF);
(p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF);
}
static void RestartModel(CPpmd7 *p)
{
unsigned i, k, m;
memset(p->FreeList, 0, sizeof(p->FreeList));
p->Text = p->Base + p->AlignOffset;
p->HiUnit = p->Text + p->Size;
p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE;
p->GlueCount = 0;
p->OrderFall = p->MaxOrder;
p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1;
p->PrevSuccess = 0;
p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */
p->MinContext->Suffix = 0;
p->MinContext->NumStats = 256;
p->MinContext->SummFreq = 256 + 1;
p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */
p->LoUnit += U2B(256 / 2);
p->MinContext->Stats = REF(p->FoundState);
for (i = 0; i < 256; i++)
{
CPpmd_State *s = &p->FoundState[i];
s->Symbol = (Byte)i;
s->Freq = 1;
SetSuccessor(s, 0);
}
for (i = 0; i < 128; i++)
for (k = 0; k < 8; k++)
{
UInt16 *dest = p->BinSumm[i] + k;
UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2));
for (m = 0; m < 64; m += 8)
dest[m] = val;
}
for (i = 0; i < 25; i++)
for (k = 0; k < 16; k++)
{
CPpmd_See *s = &p->See[i][k];
s->Summ = (UInt16)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4));
s->Count = 4;
}
}
void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder)
{
p->MaxOrder = maxOrder;
RestartModel(p);
p->DummySee.Shift = PPMD_PERIOD_BITS;
p->DummySee.Summ = 0; /* unused */
p->DummySee.Count = 64; /* unused */
}
static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip)
{
CPpmd_State upState;
CTX_PTR c = p->MinContext;
CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState);
CPpmd_State *ps[PPMD7_MAX_ORDER];
unsigned numPs = 0;
if (!skip)
ps[numPs++] = p->FoundState;
while (c->Suffix)
{
CPpmd_Void_Ref successor;
CPpmd_State *s;
c = SUFFIX(c);
if (c->NumStats != 1)
{
for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++);
}
else
s = ONE_STATE(c);
successor = SUCCESSOR(s);
if (successor != upBranch)
{
c = CTX(successor);
if (numPs == 0)
return c;
break;
}
ps[numPs++] = s;
}
upState.Symbol = *(const Byte *)Ppmd7_GetPtr(p, upBranch);
SetSuccessor(&upState, upBranch + 1);
if (c->NumStats == 1)
upState.Freq = ONE_STATE(c)->Freq;
else
{
UInt32 cf, s0;
CPpmd_State *s;
for (s = STATS(c); s->Symbol != upState.Symbol; s++);
cf = s->Freq - 1;
s0 = c->SummFreq - c->NumStats - cf;
upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0))));
}
do
{
/* Create Child */
CTX_PTR c1; /* = AllocContext(p); */
if (p->HiUnit != p->LoUnit)
c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE);
else if (p->FreeList[0] != 0)
c1 = (CTX_PTR)RemoveNode(p, 0);
else
{
c1 = (CTX_PTR)AllocUnitsRare(p, 0);
if (!c1)
return NULL;
}
c1->NumStats = 1;
*ONE_STATE(c1) = upState;
c1->Suffix = REF(c);
SetSuccessor(ps[--numPs], REF(c1));
c = c1;
}
while (numPs != 0);
return c;
}
static void SwapStates(CPpmd_State *t1, CPpmd_State *t2)
{
CPpmd_State tmp = *t1;
*t1 = *t2;
*t2 = tmp;
}
static void UpdateModel(CPpmd7 *p)
{
CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState);
CTX_PTR c;
unsigned s0, ns;
if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0)
{
c = SUFFIX(p->MinContext);
if (c->NumStats == 1)
{
CPpmd_State *s = ONE_STATE(c);
if (s->Freq < 32)
s->Freq++;
}
else
{
CPpmd_State *s = STATS(c);
if (s->Symbol != p->FoundState->Symbol)
{
do { s++; } while (s->Symbol != p->FoundState->Symbol);
if (s[0].Freq >= s[-1].Freq)
{
SwapStates(&s[0], &s[-1]);
s--;
}
}
if (s->Freq < MAX_FREQ - 9)
{
s->Freq += 2;
c->SummFreq += 2;
}
}
}
if (p->OrderFall == 0)
{
p->MinContext = p->MaxContext = CreateSuccessors(p, True);
if (p->MinContext == 0)
{
RestartModel(p);
return;
}
SetSuccessor(p->FoundState, REF(p->MinContext));
return;
}
*p->Text++ = p->FoundState->Symbol;
successor = REF(p->Text);
if (p->Text >= p->UnitsStart)
{
RestartModel(p);
return;
}
if (fSuccessor)
{
if (fSuccessor <= successor)
{
CTX_PTR cs = CreateSuccessors(p, False);
if (cs == NULL)
{
RestartModel(p);
return;
}
fSuccessor = REF(cs);
}
if (--p->OrderFall == 0)
{
successor = fSuccessor;
p->Text -= (p->MaxContext != p->MinContext);
}
}
else
{
SetSuccessor(p->FoundState, successor);
fSuccessor = REF(p->MinContext);
}
s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - (p->FoundState->Freq - 1);
for (c = p->MaxContext; c != p->MinContext; c = SUFFIX(c))
{
unsigned ns1;
UInt32 cf, sf;
if ((ns1 = c->NumStats) != 1)
{
if ((ns1 & 1) == 0)
{
/* Expand for one UNIT */
unsigned oldNU = ns1 >> 1;
unsigned i = U2I(oldNU);
if (i != U2I(oldNU + 1))
{
void *ptr = AllocUnits(p, i + 1);
void *oldPtr;
if (!ptr)
{
RestartModel(p);
return;
}
oldPtr = STATS(c);
MyMem12Cpy(ptr, oldPtr, oldNU);
InsertNode(p, oldPtr, i);
c->Stats = STATS_REF(ptr);
}
}
c->SummFreq = (UInt16)(c->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & (c->SummFreq <= 8 * ns1)));
}
else
{
CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0);
if (!s)
{
RestartModel(p);
return;
}
*s = *ONE_STATE(c);
c->Stats = REF(s);
if (s->Freq < MAX_FREQ / 4 - 1)
s->Freq <<= 1;
else
s->Freq = MAX_FREQ - 4;
c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 3));
}
cf = 2 * (UInt32)p->FoundState->Freq * (c->SummFreq + 6);
sf = (UInt32)s0 + c->SummFreq;
if (cf < 6 * sf)
{
cf = 1 + (cf > sf) + (cf >= 4 * sf);
c->SummFreq += 3;
}
else
{
cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf);
c->SummFreq = (UInt16)(c->SummFreq + cf);
}
{
CPpmd_State *s = STATS(c) + ns1;
SetSuccessor(s, successor);
s->Symbol = p->FoundState->Symbol;
s->Freq = (Byte)cf;
c->NumStats = (UInt16)(ns1 + 1);
}
}
p->MaxContext = p->MinContext = CTX(fSuccessor);
}
static void Rescale(CPpmd7 *p)
{
unsigned i, adder, sumFreq, escFreq;
CPpmd_State *stats = STATS(p->MinContext);
CPpmd_State *s = p->FoundState;
{
CPpmd_State tmp = *s;
for (; s != stats; s--)
s[0] = s[-1];
*s = tmp;
}
escFreq = p->MinContext->SummFreq - s->Freq;
s->Freq += 4;
adder = (p->OrderFall != 0);
s->Freq = (Byte)((s->Freq + adder) >> 1);
sumFreq = s->Freq;
i = p->MinContext->NumStats - 1;
do
{
escFreq -= (++s)->Freq;
s->Freq = (Byte)((s->Freq + adder) >> 1);
sumFreq += s->Freq;
if (s[0].Freq > s[-1].Freq)
{
CPpmd_State *s1 = s;
CPpmd_State tmp = *s1;
do
s1[0] = s1[-1];
while (--s1 != stats && tmp.Freq > s1[-1].Freq);
*s1 = tmp;
}
}
while (--i);
if (s->Freq == 0)
{
unsigned numStats = p->MinContext->NumStats;
unsigned n0, n1;
do { i++; } while ((--s)->Freq == 0);
escFreq += i;
p->MinContext->NumStats = (UInt16)(p->MinContext->NumStats - i);
if (p->MinContext->NumStats == 1)
{
CPpmd_State tmp = *stats;
do
{
tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1));
escFreq >>= 1;
}
while (escFreq > 1);
InsertNode(p, stats, U2I(((numStats + 1) >> 1)));
*(p->FoundState = ONE_STATE(p->MinContext)) = tmp;
return;
}
n0 = (numStats + 1) >> 1;
n1 = (p->MinContext->NumStats + 1) >> 1;
if (n0 != n1)
p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1));
}
p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1));
p->FoundState = STATS(p->MinContext);
}
CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)
{
CPpmd_See *see;
unsigned nonMasked = p->MinContext->NumStats - numMasked;
if (p->MinContext->NumStats != 256)
{
see = p->See[(unsigned)p->NS2Indx[nonMasked - 1]] +
(nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
2 * (unsigned)(p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
4 * (unsigned)(numMasked > nonMasked) +
p->HiBitsFlag;
{
unsigned r = (see->Summ >> see->Shift);
see->Summ = (UInt16)(see->Summ - r);
*escFreq = r + (r == 0);
}
}
else
{
see = &p->DummySee;
*escFreq = 1;
}
return see;
}
static void NextContext(CPpmd7 *p)
{
CTX_PTR c = CTX(SUCCESSOR(p->FoundState));
if (p->OrderFall == 0 && (Byte *)c > p->Text)
p->MinContext = p->MaxContext = c;
else
UpdateModel(p);
}
void Ppmd7_Update1(CPpmd7 *p)
{
CPpmd_State *s = p->FoundState;
s->Freq += 4;
p->MinContext->SummFreq += 4;
if (s[0].Freq > s[-1].Freq)
{
SwapStates(&s[0], &s[-1]);
p->FoundState = --s;
if (s->Freq > MAX_FREQ)
Rescale(p);
}
NextContext(p);
}
void Ppmd7_Update1_0(CPpmd7 *p)
{
p->PrevSuccess = (2 * p->FoundState->Freq > p->MinContext->SummFreq);
p->RunLength += p->PrevSuccess;
p->MinContext->SummFreq += 4;
if ((p->FoundState->Freq += 4) > MAX_FREQ)
Rescale(p);
NextContext(p);
}
void Ppmd7_UpdateBin(CPpmd7 *p)
{
p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 128 ? 1: 0));
p->PrevSuccess = 1;
p->RunLength++;
NextContext(p);
}
void Ppmd7_Update2(CPpmd7 *p)
{
p->MinContext->SummFreq += 4;
if ((p->FoundState->Freq += 4) > MAX_FREQ)
Rescale(p);
p->RunLength = p->InitRL;
UpdateModel(p);
}

140
SevenZip/Ppmd7.h Normal file
View file

@ -0,0 +1,140 @@
/* Ppmd7.h -- PPMdH compression codec
2016-05-21 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
/* This code supports virtual RangeDecoder and includes the implementation
of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H.
If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */
#ifndef __PPMD7_H
#define __PPMD7_H
#include "Ppmd.h"
EXTERN_C_BEGIN
#define PPMD7_MIN_ORDER 2
#define PPMD7_MAX_ORDER 64
#define PPMD7_MIN_MEM_SIZE (1 << 11)
#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3)
struct CPpmd7_Context_;
typedef
#ifdef PPMD_32BIT
struct CPpmd7_Context_ *
#else
UInt32
#endif
CPpmd7_Context_Ref;
typedef struct CPpmd7_Context_
{
UInt16 NumStats;
UInt16 SummFreq;
CPpmd_State_Ref Stats;
CPpmd7_Context_Ref Suffix;
} CPpmd7_Context;
#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
typedef struct
{
CPpmd7_Context *MinContext, *MaxContext;
CPpmd_State *FoundState;
unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag;
Int32 RunLength, InitRL; /* must be 32-bit at least */
UInt32 Size;
UInt32 GlueCount;
Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
UInt32 AlignOffset;
Byte Indx2Units[PPMD_NUM_INDEXES];
Byte Units2Indx[128];
CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
CPpmd_See DummySee, See[25][16];
UInt16 BinSumm[128][64];
} CPpmd7;
void Ppmd7_Construct(CPpmd7 *p);
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc);
void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc);
void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder);
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
/* ---------- Internal Functions ---------- */
extern const Byte PPMD7_kExpEscape[16];
#ifdef PPMD_32BIT
#define Ppmd7_GetPtr(p, ptr) (ptr)
#define Ppmd7_GetContext(p, ptr) (ptr)
#define Ppmd7_GetStats(p, ctx) ((ctx)->Stats)
#else
#define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
#define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs)))
#define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats)))
#endif
void Ppmd7_Update1(CPpmd7 *p);
void Ppmd7_Update1_0(CPpmd7 *p);
void Ppmd7_Update2(CPpmd7 *p);
void Ppmd7_UpdateBin(CPpmd7 *p);
#define Ppmd7_GetBinSumm(p) \
&p->BinSumm[(unsigned)Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
(p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
2 * p->HB2Flag[(unsigned)Ppmd7Context_OneState(p->MinContext)->Symbol] + \
((p->RunLength >> 26) & 0x20)]
CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
/* ---------- Decode ---------- */
typedef struct
{
UInt32 (*GetThreshold)(void *p, UInt32 total);
void (*Decode)(void *p, UInt32 start, UInt32 size);
UInt32 (*DecodeBit)(void *p, UInt32 size0);
} IPpmd7_RangeDec;
typedef struct
{
IPpmd7_RangeDec p;
UInt32 Range;
UInt32 Code;
IByteIn *Stream;
} CPpmd7z_RangeDec;
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p);
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p);
#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc);
/* ---------- Encode ---------- */
typedef struct
{
UInt64 Low;
UInt32 Range;
Byte Cache;
UInt64 CacheSize;
IByteOut *Stream;
} CPpmd7z_RangeEnc;
void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p);
void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p);
void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol);
EXTERN_C_END
#endif

189
SevenZip/Ppmd7Dec.c Normal file
View file

@ -0,0 +1,189 @@
/* Ppmd7Dec.c -- PPMdH Decoder
2010-03-12 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Precomp.h"
#include "Ppmd7.h"
#define kTopValue (1 << 24)
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)
{
unsigned i;
p->Code = 0;
p->Range = 0xFFFFFFFF;
if (p->Stream->Read((void *)p->Stream) != 0)
return False;
for (i = 0; i < 4; i++)
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
return (p->Code < 0xFFFFFFFF);
}
static UInt32 Range_GetThreshold(void *pp, UInt32 total)
{
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
return (p->Code) / (p->Range /= total);
}
static void Range_Normalize(CPpmd7z_RangeDec *p)
{
if (p->Range < kTopValue)
{
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
p->Range <<= 8;
if (p->Range < kTopValue)
{
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
p->Range <<= 8;
}
}
}
static void Range_Decode(void *pp, UInt32 start, UInt32 size)
{
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
p->Code -= start * p->Range;
p->Range *= size;
Range_Normalize(p);
}
static UInt32 Range_DecodeBit(void *pp, UInt32 size0)
{
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
UInt32 newBound = (p->Range >> 14) * size0;
UInt32 symbol;
if (p->Code < newBound)
{
symbol = 0;
p->Range = newBound;
}
else
{
symbol = 1;
p->Code -= newBound;
p->Range -= newBound;
}
Range_Normalize(p);
return symbol;
}
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
{
p->p.GetThreshold = Range_GetThreshold;
p->p.Decode = Range_Decode;
p->p.DecodeBit = Range_DecodeBit;
}
#define MASK(sym) ((signed char *)charMask)[sym]
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
{
size_t charMask[256 / sizeof(size_t)];
if (p->MinContext->NumStats != 1)
{
CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
unsigned i;
UInt32 count, hiCnt;
if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq))
{
Byte symbol;
rc->Decode(rc, 0, s->Freq);
p->FoundState = s;
symbol = s->Symbol;
Ppmd7_Update1_0(p);
return symbol;
}
p->PrevSuccess = 0;
i = p->MinContext->NumStats - 1;
do
{
if ((hiCnt += (++s)->Freq) > count)
{
Byte symbol;
rc->Decode(rc, hiCnt - s->Freq, s->Freq);
p->FoundState = s;
symbol = s->Symbol;
Ppmd7_Update1(p);
return symbol;
}
}
while (--i);
if (count >= p->MinContext->SummFreq)
return -2;
p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt);
PPMD_SetAllBitsIn256Bytes(charMask);
MASK(s->Symbol) = 0;
i = p->MinContext->NumStats - 1;
do { MASK((--s)->Symbol) = 0; } while (--i);
}
else
{
UInt16 *prob = Ppmd7_GetBinSumm(p);
if (rc->DecodeBit(rc, *prob) == 0)
{
Byte symbol;
*prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol;
Ppmd7_UpdateBin(p);
return symbol;
}
*prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
PPMD_SetAllBitsIn256Bytes(charMask);
MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0;
p->PrevSuccess = 0;
}
for (;;)
{
CPpmd_State *ps[256], *s;
UInt32 freqSum, count, hiCnt;
CPpmd_See *see;
unsigned i, num, numMasked = p->MinContext->NumStats;
do
{
p->OrderFall++;
if (!p->MinContext->Suffix)
return -1;
p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
}
while (p->MinContext->NumStats == numMasked);
hiCnt = 0;
s = Ppmd7_GetStats(p, p->MinContext);
i = 0;
num = p->MinContext->NumStats - numMasked;
do
{
int k = (int)(MASK(s->Symbol));
hiCnt += (s->Freq & k);
ps[i] = s++;
i -= k;
}
while (i != num);
see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum);
freqSum += hiCnt;
count = rc->GetThreshold(rc, freqSum);
if (count < hiCnt)
{
Byte symbol;
CPpmd_State **pps = ps;
for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++);
s = *pps;
rc->Decode(rc, hiCnt - s->Freq, s->Freq);
Ppmd_See_Update(see);
p->FoundState = s;
symbol = s->Symbol;
Ppmd7_Update2(p);
return symbol;
}
if (count >= freqSum)
return -2;
rc->Decode(rc, hiCnt, freqSum - hiCnt);
see->Summ = (UInt16)(see->Summ + freqSum);
do { MASK(ps[--i]->Symbol) = 0; } while (i != 0);
}
}

4
SevenZip/Precomp.c Normal file
View file

@ -0,0 +1,4 @@
/* Precomp.c -- StdAfx
2013-01-21 : Igor Pavlov : Public domain */
#include "Precomp.h"

10
SevenZip/Precomp.h Normal file
View file

@ -0,0 +1,10 @@
/* Precomp.h -- StdAfx
2013-11-12 : Igor Pavlov : Public domain */
#ifndef __7Z_PRECOMP_H
#define __7Z_PRECOMP_H
#include "Compiler.h"
/* #include "7zTypes.h" */
#endif

341
SevenZip/SevenZip.vcxproj Normal file
View file

@ -0,0 +1,341 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGO Optimize|Win32">
<Configuration>PGO Optimize</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGO Optimize|x64">
<Configuration>PGO Optimize</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGO Profile|Win32">
<Configuration>PGO Profile</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGO Profile|x64">
<Configuration>PGO Profile</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="7z.h" />
<ClInclude Include="7zAlloc.h" />
<ClInclude Include="7zBuf.h" />
<ClInclude Include="7zCrc.h" />
<ClInclude Include="7zFile.h" />
<ClInclude Include="7zMemBuffer.h" />
<ClInclude Include="7zTypes.h" />
<ClInclude Include="Bcj2.h" />
<ClInclude Include="Bra.h" />
<ClInclude Include="Compiler.h" />
<ClInclude Include="CpuArch.h" />
<ClInclude Include="Delta.h" />
<ClInclude Include="Lzma2Dec.h" />
<ClInclude Include="LzmaDec.h" />
<ClInclude Include="Ppmd.h" />
<ClInclude Include="Ppmd7.h" />
<ClInclude Include="Precomp.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="7zAlloc.c" />
<ClCompile Include="7zArcIn.c" />
<ClCompile Include="7zBuf.c" />
<ClCompile Include="7zCrc.c" />
<ClCompile Include="7zCrcOpt.c" />
<ClCompile Include="7zDec.c" />
<ClCompile Include="7zFile.c" />
<ClCompile Include="7zMemBuffer.c" />
<ClCompile Include="7zStream.c" />
<ClCompile Include="Bcj2.c" />
<ClCompile Include="Bra.c" />
<ClCompile Include="Bra86.c" />
<ClCompile Include="BraIA64.c" />
<ClCompile Include="CpuArch.c" />
<ClCompile Include="Delta.c" />
<ClCompile Include="Lzma2Dec.c" />
<ClCompile Include="LzmaDec.c" />
<ClCompile Include="Ppmd7.c" />
<ClCompile Include="Ppmd7Dec.c" />
<ClCompile Include="Precomp.c" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{52C4BA3A-E699-4305-B23F-C9083FD07AB6}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>SevenZip</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PGO Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PGO Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='PGO Profile|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='PGO Profile|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PGO Profile|x64'">
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'">
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PGO Profile|Win32'">
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|Win32'">
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='PGO Profile|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='PGO Profile|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="7z.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="7zAlloc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="7zBuf.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="7zCrc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="7zFile.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="7zMemBuffer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="7zTypes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Bcj2.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Bra.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Compiler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CpuArch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Delta.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Lzma2Dec.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="LzmaDec.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Ppmd.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Ppmd7.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Precomp.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="7zAlloc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="7zArcIn.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="7zBuf.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="7zCrc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="7zCrcOpt.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="7zDec.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="7zFile.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="7zMemBuffer.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="7zStream.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Bcj2.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Bra.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Bra86.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="BraIA64.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CpuArch.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Delta.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Lzma2Dec.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LzmaDec.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Ppmd7.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Ppmd7Dec.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Precomp.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View file

@ -0,0 +1,78 @@
#include "stdafx.h"
#include "ArchiveReader.h"
#include <string.h>
#include <sstream>
#include <algorithm>
#include "FolderUtilities.h"
ArchiveReader::~ArchiveReader()
{
if(_buffer) {
delete[] _buffer;
_buffer = nullptr;
}
}
std::stringstream ArchiveReader::GetStream(string filename)
{
std::stringstream ss;
if(_initialized) {
uint8_t* buffer = nullptr;
size_t size = 0;
ExtractFile(filename, &buffer, size);
ss.write((char*)buffer, size);
delete[] buffer;
}
return ss;
}
vector<string> ArchiveReader::GetFileList(std::initializer_list<string> extensions)
{
vector<string> filenames;
for(string filename : InternalGetFileList()) {
string lcFilename = filename;
std::transform(lcFilename.begin(), lcFilename.end(), lcFilename.begin(), ::tolower);
if(filename.length() > 4) {
for(string ext : extensions) {
if(lcFilename.substr(lcFilename.length() - 4, 4).compare(ext) == 0) {
filenames.push_back(filename);
}
}
}
}
return filenames;
}
bool ArchiveReader::LoadArchive(void* buffer, size_t size)
{
if(InternalLoadArchive(buffer, size)) {
_initialized = true;
return true;
}
return false;
}
bool ArchiveReader::LoadArchive(string filename)
{
ifstream in(filename, std::ios::binary | std::ios::in);
if(in) {
in.seekg(0, std::ios::end);
size_t filesize = in.tellg();
in.seekg(0, std::ios::beg);
if(_buffer) {
delete[] _buffer;
_buffer = nullptr;
}
_buffer = new uint8_t[filesize];
in.read((char*)_buffer, filesize);
bool result = LoadArchive(_buffer, filesize);
return result;
}
return false;
}

21
Utilities/ArchiveReader.h Normal file
View file

@ -0,0 +1,21 @@
#pragma once
#include "stdafx.h"
class ArchiveReader
{
protected:
bool _initialized = false;
uint8_t* _buffer = nullptr;
virtual bool InternalLoadArchive(void* buffer, size_t size) = 0;
virtual vector<string> InternalGetFileList() = 0;
public:
~ArchiveReader();
bool LoadArchive(void* buffer, size_t size);
bool LoadArchive(string filename);
std::stringstream GetStream(string filename);
vector<string> GetFileList(std::initializer_list<string> extensions);
virtual void ExtractFile(string filename, uint8_t **fileBuffer, size_t &fileSize) = 0;
};

84
Utilities/SZReader.cpp Normal file
View file

@ -0,0 +1,84 @@
#include "stdafx.h"
#include <algorithm>
#include "SZReader.h"
#include "../SevenZip/7zMemBuffer.h"
SZReader::SZReader()
{
}
SZReader::~SZReader()
{
SzArEx_Free(&_archive, &_allocImp);
}
bool SZReader::InternalLoadArchive(void* buffer, size_t size)
{
ISzAlloc allocImp{ SzAlloc, SzFree };
ISzAlloc allocTempImp{ SzAllocTemp, SzFreeTemp };
MemBufferInit(&_memBufferStream, &_lookStream, buffer, size);
CrcGenerateTable();
SzArEx_Init(&_archive);
return !SzArEx_Open(&_archive, &_lookStream.s, &allocImp, &allocTempImp);
}
void SZReader::ExtractFile(string filename, uint8_t **fileBuffer, size_t &fileSize)
{
if(_initialized) {
wchar_t *utf16Filename = (wchar_t*)SzAlloc(nullptr, 2000);
uint32_t blockIndex = 0xFFFFFFFF;
uint8_t *outBuffer = 0;
size_t outBufferSize = 0;
for(uint32_t i = 0; i < _archive.NumFiles; i++) {
size_t offset = 0;
size_t outSizeProcessed = 0;
unsigned isDir = SzArEx_IsDir(&_archive, i);
if(isDir) {
continue;
}
SzArEx_GetFileNameUtf16(&_archive, i, (uint16_t*)utf16Filename);
string entryName = utf8::utf8::encode(std::wstring(utf16Filename));
if(filename == entryName) {
WRes res = SzArEx_Extract(&_archive, &_lookStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &_allocImp, &_allocTempImp);
if(res == SZ_OK) {
uint8_t* buf = new uint8_t[outSizeProcessed];
memcpy(buf, outBuffer+offset, outSizeProcessed);
*fileBuffer = buf;
fileSize = outSizeProcessed;
}
IAlloc_Free(&_allocImp, outBuffer);
break;
}
}
SzFree(nullptr, utf16Filename);
}
}
vector<string> SZReader::InternalGetFileList()
{
vector<string> filenames;
wchar_t *utf16Filename = (wchar_t*)SzAlloc(nullptr, 2000);
if(_initialized) {
for(uint32_t i = 0; i < _archive.NumFiles; i++) {
size_t offset = 0;
size_t outSizeProcessed = 0;
unsigned isDir = SzArEx_IsDir(&_archive, i);
if(isDir) {
continue;
}
SzArEx_GetFileNameUtf16(&_archive, i, (uint16_t*)utf16Filename);
string filename = utf8::utf8::encode(std::wstring(utf16Filename));
filenames.push_back(filename);
}
}
SzFree(nullptr, utf16Filename);
return filenames;
}

28
Utilities/SZReader.h Normal file
View file

@ -0,0 +1,28 @@
#pragma once
#include "stdafx.h"
#include "ArchiveReader.h"
#include "../SevenZip/7z.h"
#include "../SevenZip/7zAlloc.h"
#include "../SevenZip/7zCrc.h"
#include "../SevenZip/7zTypes.h"
#include "../SevenZip/7zMemBuffer.h"
class SZReader : public ArchiveReader
{
private:
CMemBufferInStream _memBufferStream;
CLookToRead _lookStream;
CSzArEx _archive;
ISzAlloc _allocImp{ SzAlloc, SzFree };
ISzAlloc _allocTempImp{ SzAllocTemp, SzFreeTemp };
protected:
bool InternalLoadArchive(void* buffer, size_t size);
vector<string> InternalGetFileList();
public:
SZReader();
virtual ~SZReader();
void ExtractFile(string filename, uint8_t **fileBuffer, size_t &fileSize);
};

View file

@ -25,14 +25,6 @@
<Configuration>PGO Profile</Configuration> <Configuration>PGO Profile</Configuration>
<Platform>x64</Platform> <Platform>x64</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Release x64|Win32">
<Configuration>Release x64</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release x64|x64">
<Configuration>Release x64</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32"> <ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
@ -103,20 +95,6 @@
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
</ImportGroup> </ImportGroup>
@ -144,17 +122,7 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'" Label="PropertySheets"> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir> <IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
@ -171,10 +139,6 @@
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\PGO Profile\</OutDir> <OutDir>$(SolutionDir)\bin\$(PlatformTarget)\PGO Profile\</OutDir>
<IntDir>obj\$(Platform)\PGO Profile\</IntDir> <IntDir>obj\$(Platform)\PGO Profile\</IntDir>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|x64'">
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir> <IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
@ -356,47 +320,8 @@
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="ArchiveReader.h" />
<ClInclude Include="blip_buf.h" /> <ClInclude Include="blip_buf.h" />
<ClInclude Include="CRC32.h" /> <ClInclude Include="CRC32.h" />
<ClInclude Include="FolderUtilities.h" /> <ClInclude Include="FolderUtilities.h" />
@ -415,6 +340,7 @@
<ClInclude Include="Scale2x\scale2x.h" /> <ClInclude Include="Scale2x\scale2x.h" />
<ClInclude Include="Scale2x\scale3x.h" /> <ClInclude Include="Scale2x\scale3x.h" />
<ClInclude Include="Scale2x\scalebit.h" /> <ClInclude Include="Scale2x\scalebit.h" />
<ClInclude Include="SZReader.h" />
<ClInclude Include="UPnPPortMapper.h" /> <ClInclude Include="UPnPPortMapper.h" />
<ClInclude Include="SimpleLock.h" /> <ClInclude Include="SimpleLock.h" />
<ClInclude Include="Socket.h" /> <ClInclude Include="Socket.h" />
@ -428,6 +354,7 @@
<ClInclude Include="ZipWriter.h" /> <ClInclude Include="ZipWriter.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="ArchiveReader.cpp" />
<ClCompile Include="blip_buf.cpp" /> <ClCompile Include="blip_buf.cpp" />
<ClCompile Include="CRC32.cpp" /> <ClCompile Include="CRC32.cpp" />
<ClCompile Include="FolderUtilities.cpp" /> <ClCompile Include="FolderUtilities.cpp" />
@ -458,9 +385,8 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='PGO Profile|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='PGO Profile|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release x64|x64'">Create</PrecompiledHeader>
</ClCompile> </ClCompile>
<ClCompile Include="SZReader.cpp" />
<ClCompile Include="Timer.cpp" /> <ClCompile Include="Timer.cpp" />
<ClCompile Include="UPnPPortMapper.cpp" /> <ClCompile Include="UPnPPortMapper.cpp" />
<ClCompile Include="UTF8Util.cpp" /> <ClCompile Include="UTF8Util.cpp" />

View file

@ -110,6 +110,12 @@
<ClInclude Include="KreedSaiEagle\SaiEagle.h"> <ClInclude Include="KreedSaiEagle\SaiEagle.h">
<Filter>KreedSaiEagle</Filter> <Filter>KreedSaiEagle</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="SZReader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ArchiveReader.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="stdafx.cpp"> <ClCompile Include="stdafx.cpp">
@ -196,5 +202,11 @@
<ClCompile Include="KreedSaiEagle\2xSai.cpp"> <ClCompile Include="KreedSaiEagle\2xSai.cpp">
<Filter>KreedSaiEagle</Filter> <Filter>KreedSaiEagle</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="SZReader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ArchiveReader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -15,21 +15,12 @@ ZipReader::~ZipReader()
} }
} }
void ZipReader::LoadZipArchive(void* buffer, size_t size) bool ZipReader::InternalLoadArchive(void* buffer, size_t size)
{ {
if(mz_zip_reader_init_mem(&_zipArchive, buffer, size, 0)) { return mz_zip_reader_init_mem(&_zipArchive, buffer, size, 0) != 0;
_initialized = true;
}
} }
void ZipReader::LoadZipArchive(string filepath) vector<string> ZipReader::InternalGetFileList()
{
if(mz_zip_reader_init_file(&_zipArchive, filepath.c_str(), 0)) {
_initialized = true;
}
}
vector<string> ZipReader::GetFileList()
{ {
vector<string> fileList; vector<string> fileList;
if(_initialized) { if(_initialized) {
@ -63,19 +54,3 @@ void ZipReader::ExtractFile(string filename, uint8_t **fileBuffer, size_t &fileS
fileSize = uncompSize; fileSize = uncompSize;
} }
} }
std::stringstream ZipReader::ExtractFile(string filename)
{
std::stringstream ss;
if(_initialized) {
uint8_t* buffer = nullptr;
size_t size = 0;
ExtractFile(filename, &buffer, size);
ss.write((char*)buffer, size);
delete[] buffer;
}
return ss;
}

View file

@ -1,21 +1,20 @@
#pragma once #pragma once
#include "stdafx.h" #include "stdafx.h"
#include "miniz.h" #include "miniz.h"
#include "ArchiveReader.h"
class ZipReader class ZipReader : public ArchiveReader
{ {
private: private:
mz_zip_archive _zipArchive; mz_zip_archive _zipArchive;
bool _initialized = false;
protected:
bool InternalLoadArchive(void* buffer, size_t size);
vector<string> InternalGetFileList();
public: public:
ZipReader(); ZipReader();
~ZipReader(); virtual ~ZipReader();
void LoadZipArchive(void* buffer, size_t size);
void LoadZipArchive(string filepath);
vector<string> GetFileList();
void ExtractFile(string filename, uint8_t **fileBuffer, size_t &fileSize); void ExtractFile(string filename, uint8_t **fileBuffer, size_t &fileSize);
std::stringstream ExtractFile(string filename);
}; };

View file

@ -25,14 +25,6 @@
<Configuration>PGO Profile</Configuration> <Configuration>PGO Profile</Configuration>
<Platform>x64</Platform> <Platform>x64</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Release x64|Win32">
<Configuration>Release x64</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release x64|x64">
<Configuration>Release x64</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32"> <ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
@ -103,20 +95,6 @@
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
</ImportGroup> </ImportGroup>
@ -144,17 +122,7 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'" Label="PropertySheets"> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir> <IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
@ -171,10 +139,6 @@
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\PGO Profile\</OutDir> <OutDir>$(SolutionDir)\bin\$(PlatformTarget)\PGO Profile\</OutDir>
<IntDir>obj\$(Platform)\PGO Profile\</IntDir> <IntDir>obj\$(Platform)\PGO Profile\</IntDir>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|x64'">
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)\bin\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir> <IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
@ -331,40 +295,6 @@
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release x64|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="DirectXTK\Audio.h" /> <ClInclude Include="DirectXTK\Audio.h" />
<ClInclude Include="DirectXTK\CommonStates.h" /> <ClInclude Include="DirectXTK\CommonStates.h" />
@ -404,8 +334,6 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='PGO Profile|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='PGO Profile|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release x64|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release x64|x64'">Create</PrecompiledHeader>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>