Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pack-Ice (Atari love) #73

Merged
merged 3 commits into from
Jun 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Ancient.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@
<ClCompile Include="src\FRLEDecompressor.cpp" />
<ClCompile Include="src\HFMNDecompressor.cpp" />
<ClCompile Include="src\HUFFDecompressor.cpp" />
<ClCompile Include="src\IceDecompressor.cpp" />
<ClCompile Include="src\ILZRDecompressor.cpp" />
<ClCompile Include="src\IMPDecompressor.cpp" />
<ClCompile Include="src\InputStream.cpp" />
Expand Down Expand Up @@ -304,6 +305,7 @@
<ClInclude Include="src\HFMNDecompressor.hpp" />
<ClInclude Include="src\HUFFDecompressor.hpp" />
<ClInclude Include="src\HuffmanDecoder.hpp" />
<ClInclude Include="src\IceDecompressor.hpp" />
<ClInclude Include="src\ILZRDecompressor.hpp" />
<ClInclude Include="src\IMPDecompressor.hpp" />
<ClInclude Include="src\InputStream.hpp" />
Expand Down
2 changes: 2 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ LIBANCIENT_FILES_SRC += src/HFMNDecompressor.hpp
LIBANCIENT_FILES_SRC += src/HUFFDecompressor.cpp
LIBANCIENT_FILES_SRC += src/HUFFDecompressor.hpp
LIBANCIENT_FILES_SRC += src/HuffmanDecoder.hpp
LIBANCIENT_FILES_SRC += src/IceDecompressor.cpp
LIBANCIENT_FILES_SRC += src/IceDecompressor.hpp
LIBANCIENT_FILES_SRC += src/ILZRDecompressor.cpp
LIBANCIENT_FILES_SRC += src/ILZRDecompressor.hpp
LIBANCIENT_FILES_SRC += src/IMPDecompressor.cpp
Expand Down
25 changes: 13 additions & 12 deletions Makefile.unix
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,19 @@ OBJS_N = API.o Buffer.o Common.o MemoryBuffer.o StaticBuffer.o SubBuffer.o Wrapp
Decompressor.o LZWDecoder.o XPKDecompressor.o XPKMain.o \
OutputStream.o InputStream.o RangeDecoder.o \
ACCADecompressor.o ARTMDecompressor.o BLZWDecompressor.o BZIP2Decompressor.o \
CBR0Decompressor.o CompactDecompressor.o CompressDecompressor.o CRMDecompressor.o CYB2Decoder.o \
DEFLATEDecompressor.o DLTADecode.o DMSDecompressor.o FASTDecompressor.o \
FBR2Decompressor.o FreezeDecompressor.o FRLEDecompressor.o HFMNDecompressor.o \
HUFFDecompressor.o ILZRDecompressor.o IMPDecompressor.o LHLBDecompressor.o \
LIN1Decompressor.o LIN2Decompressor.o LOBDecompressor.o LZBSDecompressor.o \
LZCBDecompressor.o LZW2Decompressor.o LZW4Decompressor.o LZW5Decompressor.o \
LZXDecompressor.o MASHDecompressor.o MMCMPDecompressor.o NONEDecompressor.o \
NUKEDecompressor.o PackDecompressor.o PPDecompressor.o PPMQDecompressor.o RAKEDecompressor.o \
RDCNDecompressor.o RLENDecompressor.o RNCDecompressor.o SCOCompressDecompressor.o \
SDHCDecompressor.o SHRXDecompressor.o SLZ3Decompressor.o SMPLDecompressor.o \
StoneCrackerDecompressor.o SQSHDecompressor.o SXSCDecompressor.o TDCSDecompressor.o \
TPWMDecompressor.o VicXDecompressor.o XPKUnimplemented.o ZENODecompressor.o
CBR0Decompressor.o CompactDecompressor.o CompressDecompressor.o CRMDecompressor.o \
CYB2Decoder.o DEFLATEDecompressor.o DLTADecode.o DMSDecompressor.o \
FASTDecompressor.o FBR2Decompressor.o FreezeDecompressor.o FRLEDecompressor.o \
HFMNDecompressor.o HUFFDecompressor.o IceDecompressor.o ILZRDecompressor.o \
IMPDecompressor.o LHLBDecompressor.o LIN1Decompressor.o LIN2Decompressor.o \
LOBDecompressor.o LZBSDecompressor.o LZCBDecompressor.o LZW2Decompressor.o \
LZW4Decompressor.o LZW5Decompressor.o LZXDecompressor.o MASHDecompressor.o \
MMCMPDecompressor.o NONEDecompressor.o NUKEDecompressor.o PackDecompressor.o \
PPDecompressor.o PPMQDecompressor.o RAKEDecompressor.o RDCNDecompressor.o \
RLENDecompressor.o RNCDecompressor.o SCOCompressDecompressor.o SDHCDecompressor.o \
SHRXDecompressor.o SLZ3Decompressor.o SMPLDecompressor.o StoneCrackerDecompressor.o \
SQSHDecompressor.o SXSCDecompressor.o TDCSDecompressor.o TPWMDecompressor.o \
VicXDecompressor.o XPKUnimplemented.o ZENODecompressor.o
TEST_N = test.o
TESTBIN = obj/test

Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ Decompression algorithms provided:
* Does not support mode 8 (as defined by some game files)
* Pack (Unix)
* Supports both old and new formats
* Pack-Ice
* Supports all known versions (3 different formats) and picture mode.
* ID SHE! (Pack-Ice Clone)
* ID TMM! (Pack-Ice Clone)
* ID TSM! (Pack-Ice Clone)
* PowerPacker
* PP 1.1 (verification missing)
* PP 2.0
Expand Down
4 changes: 2 additions & 2 deletions src/API.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,12 @@ VerificationError::~VerificationError() noexcept

bool Decompressor::detect(const std::vector<uint8_t> &packedData) noexcept
{
return internal::Decompressor::detect(internal::ConstStaticBuffer(packedData.data(), packedData.size()));
return internal::Decompressor::detect(internal::ConstStaticBuffer(packedData.data(), packedData.size()),true);
}

bool Decompressor::detect(const uint8_t *packedData, size_t packedSize) noexcept
{
return internal::Decompressor::detect(internal::ConstStaticBuffer(packedData, packedSize));
return internal::Decompressor::detect(internal::ConstStaticBuffer(packedData, packedSize),true);
}

Decompressor::Decompressor(const std::vector<uint8_t> &packedData,bool exactSizeKnown,bool verify) :
Expand Down
6 changes: 3 additions & 3 deletions src/BZIP2Decompressor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
namespace ancient::internal
{

bool BZIP2Decompressor::detectHeader(uint32_t hdr) noexcept
bool BZIP2Decompressor::detectHeader(uint32_t hdr,uint32_t footer) noexcept
{
return ((hdr&0xffff'ff00U)==FourCC("BZh\0") && (hdr&0xffU)>='1' && (hdr&0xffU)<='9');
}
Expand All @@ -41,7 +41,7 @@ BZIP2Decompressor::BZIP2Decompressor(const Buffer &packedData,bool exactSizeKnow
_packedSize{0}
{
uint32_t hdr=packedData.readBE32(0);
if (!detectHeader(hdr))
if (!detectHeader(hdr,0))
throw Decompressor::InvalidFormatError();;
_blockSize=((hdr&0xffU)-'0')*100'000;
}
Expand All @@ -52,7 +52,7 @@ BZIP2Decompressor::BZIP2Decompressor(uint32_t hdr,uint32_t recursionLevel,const
_packedSize{_packedData.size()}
{
uint32_t blockHdr=packedData.readBE32(0);
if (!detectHeader(blockHdr))
if (!detectHeader(blockHdr,0))
throw Decompressor::InvalidFormatError();;
_blockSize=((blockHdr&0xffU)-'0')*100'000;
}
Expand Down
2 changes: 1 addition & 1 deletion src/BZIP2Decompressor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class BZIP2Decompressor : public Decompressor, public XPKDecompressor
void decompressImpl(Buffer &rawData,bool verify) final;
void decompressImpl(Buffer &rawData,const Buffer &previousData,bool verify) final;

static bool detectHeader(uint32_t hdr) noexcept;
static bool detectHeader(uint32_t hdr,uint32_t footer) noexcept;
static bool detectHeaderXPK(uint32_t hdr) noexcept;

static std::shared_ptr<Decompressor> create(const Buffer &packedData,bool exactSizeKnown,bool verify);
Expand Down
4 changes: 2 additions & 2 deletions src/CRMDecompressor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
namespace ancient::internal
{

bool CRMDecompressor::detectHeader(uint32_t hdr) noexcept
bool CRMDecompressor::detectHeader(uint32_t hdr,uint32_t footer) noexcept
{
switch (hdr)
{
Expand Down Expand Up @@ -63,7 +63,7 @@ CRMDecompressor::CRMDecompressor(const Buffer &packedData,uint32_t recursionLeve
_packedData{packedData}
{
uint32_t hdr{packedData.readBE32(0)};
if (!detectHeader(hdr) || packedData.size()<20)
if (!detectHeader(hdr,0) || packedData.size()<20)
throw Decompressor::InvalidFormatError();
if (hdr==0x1805'1973U || hdr==FourCC("CD\xb3\xb9") ||
hdr==FourCC("Iron") || hdr==FourCC("MSS!")) hdr=FourCC("CrM2");
Expand Down
2 changes: 1 addition & 1 deletion src/CRMDecompressor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class CRMDecompressor : public Decompressor, public XPKDecompressor
void decompressImpl(Buffer &rawData,bool verify) final;
void decompressImpl(Buffer &rawData,const Buffer &previousData,bool verify) final;

static bool detectHeader(uint32_t hdr) noexcept;
static bool detectHeader(uint32_t hdr,uint32_t footer) noexcept;
static bool detectHeaderXPK(uint32_t hdr) noexcept;

static std::shared_ptr<Decompressor> create(const Buffer &packedData,bool exactSizeKnown,bool verify);
Expand Down
4 changes: 2 additions & 2 deletions src/CompactDecompressor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
namespace ancient::internal
{

bool CompactDecompressor::detectHeader(uint32_t hdr) noexcept
bool CompactDecompressor::detectHeader(uint32_t hdr,uint32_t footer) noexcept
{
// If a compact file has signature of 0x1fff it means the its endianess is wrongly configured
// (This is easy since it only knows of vax and pdp-11)
Expand All @@ -32,7 +32,7 @@ CompactDecompressor::CompactDecompressor(const Buffer &packedData,bool exactSize
if (_packedData.size()<2U)
throw InvalidFormatError();
uint32_t hdr{_packedData.readBE16(0)};
if (!detectHeader(hdr<<16))
if (!detectHeader(hdr<<16,0))
throw InvalidFormatError();
if (exactSizeKnown)
_packedSize=packedData.size();
Expand Down
2 changes: 1 addition & 1 deletion src/CompactDecompressor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class CompactDecompressor : public Decompressor

void decompressImpl(Buffer &rawData,bool verify) final;

static bool detectHeader(uint32_t hdr) noexcept;
static bool detectHeader(uint32_t hdr,uint32_t footer) noexcept;

static std::shared_ptr<Decompressor> create(const Buffer &packedData,bool exactSizeKnown,bool verify);

Expand Down
4 changes: 2 additions & 2 deletions src/CompressDecompressor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
namespace ancient::internal
{

bool CompressDecompressor::detectHeader(uint32_t hdr) noexcept
bool CompressDecompressor::detectHeader(uint32_t hdr,uint32_t footer) noexcept
{
return ((hdr>>16)==0x1f9dU);
}
Expand All @@ -29,7 +29,7 @@ CompressDecompressor::CompressDecompressor(const Buffer &packedData,bool exactSi
if (_packedData.size()<3U)
throw InvalidFormatError();
uint32_t hdr=_packedData.readBE16(0);
if (!detectHeader(hdr<<16))
if (!detectHeader(hdr<<16,0))
throw InvalidFormatError();
uint8_t tmp{_packedData.read8(2)};
_hasBlocks=tmp&0x80U;
Expand Down
2 changes: 1 addition & 1 deletion src/CompressDecompressor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class CompressDecompressor : public Decompressor

void decompressImpl(Buffer &rawData,bool verify) final;

static bool detectHeader(uint32_t hdr) noexcept;
static bool detectHeader(uint32_t hdr,uint32_t footer) noexcept;

static std::shared_ptr<Decompressor> create(const Buffer &packedData,bool exactSizeKnown,bool verify);

Expand Down
4 changes: 2 additions & 2 deletions src/DEFLATEDecompressor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ static uint32_t Adler32(const Buffer &buffer,size_t offset,size_t len)
return (s2<<16)|s1;
}

bool DEFLATEDecompressor::detectHeader(uint32_t hdr) noexcept
bool DEFLATEDecompressor::detectHeader(uint32_t hdr,uint32_t footer) noexcept
{
return ((hdr>>16U)==0x1f8bU)||((hdr>>16U)==0x1fa1U);
}
Expand Down Expand Up @@ -83,7 +83,7 @@ DEFLATEDecompressor::DEFLATEDecompressor(const Buffer &packedData,bool exactSize
if (_packedData.size()<2U)
throw InvalidFormatError();
uint32_t hdr{_packedData.readBE16(0)};
if (!detectHeader(hdr<<16U))
if (!detectHeader(hdr<<16U,0))
throw InvalidFormatError();

if (hdr==0x1f8bU)
Expand Down
2 changes: 1 addition & 1 deletion src/DEFLATEDecompressor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class DEFLATEDecompressor : public Decompressor, public XPKDecompressor
void decompressImpl(Buffer &rawData,bool verify) final;
void decompressImpl(Buffer &rawData,const Buffer &previousData,bool verify) final;

static bool detectHeader(uint32_t hdr) noexcept;
static bool detectHeader(uint32_t hdr,uint32_t footer) noexcept;
static bool detectHeaderXPK(uint32_t hdr) noexcept;

static std::shared_ptr<Decompressor> create(const Buffer &packedData,bool exactSizeKnown,bool verify);
Expand Down
4 changes: 2 additions & 2 deletions src/DMSDecompressor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
namespace ancient::internal
{

bool DMSDecompressor::detectHeader(uint32_t hdr) noexcept
bool DMSDecompressor::detectHeader(uint32_t hdr,uint32_t footer) noexcept
{
return hdr==FourCC("DMS!");
}
Expand All @@ -33,7 +33,7 @@ DMSDecompressor::DMSDecompressor(const Buffer &packedData,bool verify) :
_packedData{packedData}
{
uint32_t hdr{packedData.readBE32(0)};
if (!detectHeader(hdr) || packedData.size()<56)
if (!detectHeader(hdr,0) || packedData.size()<56)
throw InvalidFormatError();

if (verify && CRC16(packedData,4,50,0)!=packedData.readBE16(54))
Expand Down
2 changes: 1 addition & 1 deletion src/DMSDecompressor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class DMSDecompressor : public Decompressor

void decompressImpl(Buffer &rawData,bool verify) final;

static bool detectHeader(uint32_t hdr) noexcept;
static bool detectHeader(uint32_t hdr,uint32_t footer) noexcept;
static std::shared_ptr<Decompressor> create(const Buffer &packedData,bool exactSizeKnown,bool verify);

private:
Expand Down
12 changes: 8 additions & 4 deletions src/Decompressor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "DEFLATEDecompressor.hpp"
#include "DMSDecompressor.hpp"
#include "FreezeDecompressor.hpp"
#include "IceDecompressor.hpp"
#include "IMPDecompressor.hpp"
#include "LOBDecompressor.hpp"
#include "MMCMPDecompressor.hpp"
Expand All @@ -29,14 +30,15 @@ namespace ancient::internal

// ---

static std::vector<std::pair<bool(*)(uint32_t),std::shared_ptr<Decompressor>(*)(const Buffer&,bool,bool)>> decompressors={
static std::vector<std::pair<bool(*)(uint32_t,uint32_t),std::shared_ptr<Decompressor>(*)(const Buffer&,bool,bool)>> decompressors={
{BZIP2Decompressor::detectHeader,BZIP2Decompressor::create},
{CompactDecompressor::detectHeader,CompactDecompressor::create},
{CompressDecompressor::detectHeader,CompressDecompressor::create},
{CRMDecompressor::detectHeader,CRMDecompressor::create},
{DEFLATEDecompressor::detectHeader,DEFLATEDecompressor::create},
{DMSDecompressor::detectHeader,DMSDecompressor::create},
{FreezeDecompressor::detectHeader,FreezeDecompressor::create},
{IceDecompressor::detectHeader,IceDecompressor::create},
{IMPDecompressor::detectHeader,IMPDecompressor::create},
{LOBDecompressor::detectHeader,LOBDecompressor::create},
{MMCMPDecompressor::detectHeader,MMCMPDecompressor::create},
Expand All @@ -56,24 +58,26 @@ std::shared_ptr<Decompressor> Decompressor::create(const Buffer &packedData,bool
try
{
uint32_t hdr{(packedData.size()>=4)?packedData.readBE32(0):(uint32_t(packedData.readBE16(0))<<16)};
uint32_t footer{(exactSizeKnown&&packedData.size()>=4)?packedData.readBE32(packedData.size()-4):0};
for (auto &it : decompressors)
{
if (it.first(hdr)) return it.second(packedData,exactSizeKnown,verify);
if (it.first(hdr,footer)) return it.second(packedData,exactSizeKnown,verify);
}
throw InvalidFormatError();
} catch (const Buffer::Error&) {
throw InvalidFormatError();
}
}

bool Decompressor::detect(const Buffer &packedData) noexcept
bool Decompressor::detect(const Buffer &packedData,bool exactSizeKnown) noexcept
{
if (packedData.size()<2) return false;
try
{
uint32_t hdr{(packedData.size()>=4)?packedData.readBE32(0):(uint32_t(packedData.readBE16(0))<<16)};
uint32_t footer{(exactSizeKnown&&packedData.size()>=4)?packedData.readBE32(packedData.size()-4):0};
for (auto &it : decompressors)
if (it.first(hdr)) return true;
if (it.first(hdr,footer)) return true;
return false;
} catch (const Buffer::Error&) {
return false;
Expand Down
4 changes: 2 additions & 2 deletions src/Decompressor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ class Decompressor
static std::shared_ptr<Decompressor> create(const Buffer &packedData,bool exactSizeKnown,bool verify);

// Detect signature whether it matches to any known compressor
// This does not guarantee the data is decompressable though, only signature is read
static bool detect(const Buffer &packedData) noexcept;
// This does not guarantee the data is decompressable though, only signature(s) is read
static bool detect(const Buffer &packedData,bool exactSizeKnown) noexcept;

protected:
virtual void decompressImpl(Buffer &rawData,bool verify)=0;
Expand Down
4 changes: 2 additions & 2 deletions src/FreezeDecompressor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
namespace ancient::internal
{

bool FreezeDecompressor::detectHeader(uint32_t hdr) noexcept
bool FreezeDecompressor::detectHeader(uint32_t hdr,uint32_t footer) noexcept
{
return ((hdr>>16)==0x1f9eU||(hdr>>16)==0x1f9fU);
}
Expand All @@ -28,7 +28,7 @@ FreezeDecompressor::FreezeDecompressor(const Buffer &packedData,bool exactSizeKn
if (_packedData.size()<2U)
throw InvalidFormatError();
uint32_t hdr{_packedData.readBE16(0)};
if (!detectHeader(hdr<<16))
if (!detectHeader(hdr<<16,0))
throw InvalidFormatError();
_isOldVersion=hdr==0x1f9eU;
if (_isOldVersion)
Expand Down
2 changes: 1 addition & 1 deletion src/FreezeDecompressor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class FreezeDecompressor : public Decompressor

void decompressImpl(Buffer &rawData,bool verify) final;

static bool detectHeader(uint32_t hdr) noexcept;
static bool detectHeader(uint32_t hdr,uint32_t footer) noexcept;

static std::shared_ptr<Decompressor> create(const Buffer &packedData,bool exactSizeKnown,bool verify);

Expand Down
2 changes: 1 addition & 1 deletion src/IMPDecompressor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ static bool readIMPHeader(uint32_t hdr,uint32_t &addition) noexcept
}
}

bool IMPDecompressor::detectHeader(uint32_t hdr) noexcept
bool IMPDecompressor::detectHeader(uint32_t hdr,uint32_t footer) noexcept
{
uint32_t dummy;
return readIMPHeader(hdr,dummy);
Expand Down
2 changes: 1 addition & 1 deletion src/IMPDecompressor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class IMPDecompressor : public Decompressor, public XPKDecompressor
void decompressImpl(Buffer &rawData,bool verify) final;
void decompressImpl(Buffer &rawData,const Buffer &previousData,bool verify) final;

static bool detectHeader(uint32_t hdr) noexcept;
static bool detectHeader(uint32_t hdr,uint32_t footer) noexcept;
static bool detectHeaderXPK(uint32_t hdr) noexcept;

static std::shared_ptr<Decompressor> create(const Buffer &packedData,bool exactSizeKnown,bool verify);
Expand Down
Loading
Loading