Update LZMA SDK to 23.01
As a bonus, add support for XZ-compressed files in ZIP
This commit is contained in:
parent
5e96dbc981
commit
4497d7fdaa
89 changed files with 19247 additions and 2061 deletions
|
|
@ -36,6 +36,9 @@
|
|||
// Caution: LzmaDec also pulls in windows.h!
|
||||
#define NOMINMAX
|
||||
#include "LzmaDec.h"
|
||||
#include "Xz.h"
|
||||
// CRC table needs to be generated prior to reading XZ compressed files.
|
||||
#include "7zCrc.h"
|
||||
#include <miniz.h>
|
||||
#include <bzlib.h>
|
||||
#include <algorithm>
|
||||
|
|
@ -505,6 +508,142 @@ public:
|
|||
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DecompressorXZ
|
||||
//
|
||||
// The XZ wrapper
|
||||
// reads data from a XZ compressed stream
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
// Wraps around a Decompressor to decompress a XZ stream
|
||||
class DecompressorXZ : public DecompressorBase
|
||||
{
|
||||
enum { BUFF_SIZE = 4096 };
|
||||
|
||||
bool SawEOF = false;
|
||||
CXzUnpacker Stream;
|
||||
size_t Size;
|
||||
size_t InPos, InSize;
|
||||
size_t OutProcessed;
|
||||
uint8_t InBuff[BUFF_SIZE];
|
||||
|
||||
public:
|
||||
|
||||
bool Open(FileReader *file, size_t uncompressed_size)
|
||||
{
|
||||
if (File != nullptr)
|
||||
{
|
||||
DecompressionError("File already open");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t header[12];
|
||||
int err;
|
||||
File = file;
|
||||
|
||||
Size = uncompressed_size;
|
||||
OutProcessed = 0;
|
||||
|
||||
// Read zip XZ properties header
|
||||
if (File->Read(header, sizeof(header)) < (long)sizeof(header))
|
||||
{
|
||||
DecompressionError("DecompressorXZ: File too short\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
File->Seek(-sizeof(header), FileReader::SeekCur);
|
||||
|
||||
FillBuffer();
|
||||
|
||||
XzUnpacker_Construct(&Stream, &g_Alloc);
|
||||
XzUnpacker_Init(&Stream);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
~DecompressorXZ ()
|
||||
{
|
||||
XzUnpacker_Free(&Stream);
|
||||
}
|
||||
|
||||
ptrdiff_t Read (void *buffer, ptrdiff_t len) override
|
||||
{
|
||||
if (File == nullptr)
|
||||
{
|
||||
DecompressionError("File not open");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (g_CrcTable[1] == 0)
|
||||
{
|
||||
CrcGenerateTable();
|
||||
}
|
||||
|
||||
int err;
|
||||
Byte *next_out = (Byte *)buffer;
|
||||
|
||||
do
|
||||
{
|
||||
ECoderFinishMode finish_mode = CODER_FINISH_ANY;
|
||||
ECoderStatus status;
|
||||
size_t out_processed = len;
|
||||
size_t in_processed = InSize;
|
||||
|
||||
err = XzUnpacker_Code(&Stream, next_out, &out_processed, InBuff + InPos, &in_processed, SawEOF, finish_mode, &status);
|
||||
InPos += in_processed;
|
||||
InSize -= in_processed;
|
||||
next_out += out_processed;
|
||||
len = (long)(len - out_processed);
|
||||
if (err != SZ_OK)
|
||||
{
|
||||
DecompressionError ("Corrupt XZ stream", err);
|
||||
return 0;
|
||||
}
|
||||
if (in_processed == 0 && out_processed == 0)
|
||||
{
|
||||
if (status != CODER_STATUS_FINISHED_WITH_MARK)
|
||||
{
|
||||
DecompressionError ("Corrupt XZ stream");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (InSize == 0 && !SawEOF)
|
||||
{
|
||||
FillBuffer ();
|
||||
}
|
||||
} while (err == SZ_OK && len != 0);
|
||||
|
||||
if (err != Z_OK && err != Z_STREAM_END)
|
||||
{
|
||||
DecompressionError ("Corrupt XZ stream");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (len != 0)
|
||||
{
|
||||
DecompressionError ("Ran out of data in XZ stream");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (long)(next_out - (Byte *)buffer);
|
||||
}
|
||||
|
||||
void FillBuffer ()
|
||||
{
|
||||
auto numread = File->Read(InBuff, BUFF_SIZE);
|
||||
|
||||
if (numread < BUFF_SIZE)
|
||||
{
|
||||
SawEOF = true;
|
||||
}
|
||||
InPos = 0;
|
||||
InSize = numread;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Console Doom LZSS wrapper.
|
||||
|
|
@ -748,6 +887,18 @@ bool FileReader::OpenDecompressor(FileReader &parent, Size length, int method, b
|
|||
}
|
||||
break;
|
||||
}
|
||||
case METHOD_XZ:
|
||||
{
|
||||
auto idec = new DecompressorXZ;
|
||||
dec = idec;
|
||||
idec->EnableExceptions(exceptions);
|
||||
if (!idec->Open(p, length))
|
||||
{
|
||||
delete idec;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case METHOD_LZSS:
|
||||
{
|
||||
auto idec = new DecompressorLZSS;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue