mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-14 08:11:35 -06:00
4.44 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
804edc5756
commit
d9666cf046
341
CPP/7zip/Compress/Deflate/Deflate.dsp
Executable file
341
CPP/7zip/Compress/Deflate/Deflate.dsp
Executable file
@@ -0,0 +1,341 @@
|
||||
# Microsoft Developer Studio Project File - Name="Deflate" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=Deflate - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "Deflate.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "Deflate.mak" CFG="Deflate - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "Deflate - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "Deflate - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "Deflate - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DEFLATE_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DEFLATE_EXPORTS" /D "_ST_MODE" /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\Deflate.dll" /opt:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "Deflate - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DEFLATE_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DEFLATE_EXPORTS" /D "_ST_MODE" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\Deflate.dll" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "Deflate - Win32 Release"
|
||||
# Name "Deflate - Win32 Debug"
|
||||
# Begin Group "Spec"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Codec.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DllExports.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.cpp
|
||||
# ADD CPP /Yc"StdAfx.h"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Huffman"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Huffman\HuffmanDecoder.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Interface"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# End Group
|
||||
# Begin Group "7zip Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\InBuffer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\InBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\LSBFDecoder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\LSBFDecoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\LSBFEncoder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\LSBFEncoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\OutBuffer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\OutBuffer.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\CRC.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\CRC.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\NewHandler.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\NewHandler.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Windows"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# End Group
|
||||
# Begin Group "LZ"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\LZOutWindow.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\LZOutWindow.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "LZ_C"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\7zCrc.c
|
||||
|
||||
!IF "$(CFG)" == "Deflate - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "Deflate - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\7zCrc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Compress\Lz\LzHash.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.c
|
||||
|
||||
!IF "$(CFG)" == "Deflate - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "Deflate - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "C Huffman"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Compress\Huffman\HuffmanEncode.c
|
||||
|
||||
!IF "$(CFG)" == "Deflate - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "Deflate - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Compress\Huffman\HuffmanEncode.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Sort.c
|
||||
|
||||
!IF "$(CFG)" == "Deflate - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "Deflate - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Sort.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DeflateConst.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DeflateDecoder.cpp
|
||||
|
||||
!IF "$(CFG)" == "Deflate - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "Deflate - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DeflateDecoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DeflateEncoder.cpp
|
||||
|
||||
!IF "$(CFG)" == "Deflate - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "Deflate - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DeflateEncoder.h
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
29
CPP/7zip/Compress/Deflate/Deflate.dsw
Executable file
29
CPP/7zip/Compress/Deflate/Deflate.dsw
Executable file
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "Deflate"=.\Deflate.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
134
CPP/7zip/Compress/Deflate/DeflateConst.h
Executable file
134
CPP/7zip/Compress/Deflate/DeflateConst.h
Executable file
@@ -0,0 +1,134 @@
|
||||
// DeflateConst.h
|
||||
|
||||
#ifndef __DEFLATE_CONST_H
|
||||
#define __DEFLATE_CONST_H
|
||||
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
|
||||
const int kNumHuffmanBits = 15;
|
||||
|
||||
const UInt32 kHistorySize32 = (1 << 15);
|
||||
const UInt32 kHistorySize64 = (1 << 16);
|
||||
|
||||
const UInt32 kDistTableSize32 = 30;
|
||||
const UInt32 kDistTableSize64 = 32;
|
||||
|
||||
const UInt32 kNumLenSymbols32 = 256;
|
||||
const UInt32 kNumLenSymbols64 = 255; // don't change it. It must be <= 255.
|
||||
const UInt32 kNumLenSymbolsMax = kNumLenSymbols32;
|
||||
|
||||
const UInt32 kNumLenSlots = 29;
|
||||
|
||||
const UInt32 kFixedDistTableSize = 32;
|
||||
const UInt32 kFixedLenTableSize = 31;
|
||||
|
||||
const UInt32 kSymbolEndOfBlock = 0x100;
|
||||
const UInt32 kSymbolMatch = kSymbolEndOfBlock + 1;
|
||||
|
||||
const UInt32 kMainTableSize = kSymbolMatch + kNumLenSlots;
|
||||
const UInt32 kFixedMainTableSize = kSymbolMatch + kFixedLenTableSize;
|
||||
|
||||
const UInt32 kLevelTableSize = 19;
|
||||
|
||||
const UInt32 kTableDirectLevels = 16;
|
||||
const UInt32 kTableLevelRepNumber = kTableDirectLevels;
|
||||
const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1;
|
||||
const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1;
|
||||
|
||||
const UInt32 kLevelMask = 0xF;
|
||||
|
||||
const Byte kLenStart32[kFixedLenTableSize] =
|
||||
{0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 255, 0, 0};
|
||||
const Byte kLenStart64[kFixedLenTableSize] =
|
||||
{0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 0, 0, 0};
|
||||
|
||||
const Byte kLenDirectBits32[kFixedLenTableSize] =
|
||||
{0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0};
|
||||
const Byte kLenDirectBits64[kFixedLenTableSize] =
|
||||
{0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 16, 0, 0};
|
||||
|
||||
const UInt32 kDistStart[kDistTableSize64] =
|
||||
{0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,
|
||||
1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768,49152};
|
||||
const Byte kDistDirectBits[kDistTableSize64] =
|
||||
{0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14};
|
||||
|
||||
const Byte kLevelDirectBits[3] = {2, 3, 7};
|
||||
|
||||
const Byte kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
|
||||
|
||||
const UInt32 kMatchMinLen = 3;
|
||||
const UInt32 kMatchMaxLen32 = kNumLenSymbols32 + kMatchMinLen - 1; //256 + 2
|
||||
const UInt32 kMatchMaxLen64 = kNumLenSymbols64 + kMatchMinLen - 1; //255 + 2
|
||||
const UInt32 kMatchMaxLen = kMatchMaxLen32;
|
||||
|
||||
const int kFinalBlockFieldSize = 1;
|
||||
|
||||
namespace NFinalBlockField
|
||||
{
|
||||
enum
|
||||
{
|
||||
kNotFinalBlock = 0,
|
||||
kFinalBlock = 1
|
||||
};
|
||||
}
|
||||
|
||||
const int kBlockTypeFieldSize = 2;
|
||||
|
||||
namespace NBlockType
|
||||
{
|
||||
enum
|
||||
{
|
||||
kStored = 0,
|
||||
kFixedHuffman = 1,
|
||||
kDynamicHuffman = 2
|
||||
};
|
||||
}
|
||||
|
||||
const int kNumLenCodesFieldSize = 5;
|
||||
const int kNumDistCodesFieldSize = 5;
|
||||
const int kNumLevelCodesFieldSize = 4;
|
||||
|
||||
const UInt32 kNumLitLenCodesMin = 257;
|
||||
const UInt32 kNumDistCodesMin = 1;
|
||||
const UInt32 kNumLevelCodesMin = 4;
|
||||
|
||||
const int kLevelFieldSize = 3;
|
||||
|
||||
const int kStoredBlockLengthFieldSize = 16;
|
||||
|
||||
struct CLevels
|
||||
{
|
||||
Byte litLenLevels[kFixedMainTableSize];
|
||||
Byte distLevels[kFixedDistTableSize];
|
||||
|
||||
void SubClear()
|
||||
{
|
||||
UInt32 i;
|
||||
for(i = kNumLitLenCodesMin; i < kFixedMainTableSize; i++)
|
||||
litLenLevels[i] = 0;
|
||||
for(i = 0; i < kFixedDistTableSize; i++)
|
||||
distLevels[i] = 0;
|
||||
}
|
||||
|
||||
void SetFixedLevels()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 144; i++)
|
||||
litLenLevels[i] = 8;
|
||||
for (; i < 256; i++)
|
||||
litLenLevels[i] = 9;
|
||||
for (; i < 280; i++)
|
||||
litLenLevels[i] = 7;
|
||||
for (; i < 288; i++)
|
||||
litLenLevels[i] = 8;
|
||||
for (i = 0; i < kFixedDistTableSize; i++) // test it: InfoZip only uses kDistTableSize
|
||||
distLevels[i] = 5;
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
339
CPP/7zip/Compress/Deflate/DeflateDecoder.cpp
Executable file
339
CPP/7zip/Compress/Deflate/DeflateDecoder.cpp
Executable file
@@ -0,0 +1,339 @@
|
||||
// DeflateDecoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "DeflateDecoder.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
namespace NDecoder {
|
||||
|
||||
static const int kLenIdFinished = -1;
|
||||
static const int kLenIdNeedInit = -2;
|
||||
|
||||
CCoder::CCoder(bool deflate64Mode, bool deflateNSIS):
|
||||
_deflate64Mode(deflate64Mode),
|
||||
_deflateNSIS(deflateNSIS),
|
||||
_keepHistory(false) {}
|
||||
|
||||
UInt32 CCoder::ReadBits(int numBits)
|
||||
{
|
||||
return m_InBitStream.ReadBits(numBits);
|
||||
}
|
||||
|
||||
bool CCoder::DeCodeLevelTable(Byte *values, int numSymbols)
|
||||
{
|
||||
int i = 0;
|
||||
do
|
||||
{
|
||||
UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number < kTableDirectLevels)
|
||||
values[i++] = (Byte)number;
|
||||
else if (number < kLevelTableSize)
|
||||
{
|
||||
if (number == kTableLevelRepNumber)
|
||||
{
|
||||
if (i == 0)
|
||||
return false;
|
||||
int num = ReadBits(2) + 3;
|
||||
for (; num > 0 && i < numSymbols; num--, i++)
|
||||
values[i] = values[i - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
int num;
|
||||
if (number == kTableLevel0Number)
|
||||
num = ReadBits(3) + 3;
|
||||
else
|
||||
num = ReadBits(7) + 11;
|
||||
for (;num > 0 && i < numSymbols; num--)
|
||||
values[i++] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
while(i < numSymbols);
|
||||
return true;
|
||||
}
|
||||
|
||||
#define RIF(x) { if (!(x)) return false; }
|
||||
|
||||
bool CCoder::ReadTables(void)
|
||||
{
|
||||
m_FinalBlock = (ReadBits(kFinalBlockFieldSize) == NFinalBlockField::kFinalBlock);
|
||||
UInt32 blockType = ReadBits(kBlockTypeFieldSize);
|
||||
if (blockType > NBlockType::kDynamicHuffman)
|
||||
return false;
|
||||
|
||||
if (blockType == NBlockType::kStored)
|
||||
{
|
||||
m_StoredMode = true;
|
||||
UInt32 currentBitPosition = m_InBitStream.GetBitPosition();
|
||||
int numBitsForAlign = (int)(currentBitPosition > 0 ? (8 - currentBitPosition): 0);
|
||||
ReadBits(numBitsForAlign);
|
||||
m_StoredBlockSize = ReadBits(kStoredBlockLengthFieldSize);
|
||||
if (_deflateNSIS)
|
||||
return true;
|
||||
return (m_StoredBlockSize == (UInt16)~ReadBits(kStoredBlockLengthFieldSize));
|
||||
}
|
||||
|
||||
m_StoredMode = false;
|
||||
|
||||
CLevels levels;
|
||||
if (blockType == NBlockType::kFixedHuffman)
|
||||
{
|
||||
levels.SetFixedLevels();
|
||||
_numDistLevels = _deflate64Mode ? kDistTableSize64 : kDistTableSize32;
|
||||
}
|
||||
else
|
||||
{
|
||||
int numLitLenLevels = ReadBits(kNumLenCodesFieldSize) + kNumLitLenCodesMin;
|
||||
_numDistLevels = ReadBits(kNumDistCodesFieldSize) + kNumDistCodesMin;
|
||||
int numLevelCodes = ReadBits(kNumLevelCodesFieldSize) + kNumLevelCodesMin;
|
||||
|
||||
if (!_deflate64Mode)
|
||||
if (_numDistLevels > kDistTableSize32)
|
||||
return false;
|
||||
|
||||
Byte levelLevels[kLevelTableSize];
|
||||
for (int i = 0; i < kLevelTableSize; i++)
|
||||
{
|
||||
int position = kCodeLengthAlphabetOrder[i];
|
||||
if(i < numLevelCodes)
|
||||
levelLevels[position] = (Byte)ReadBits(kLevelFieldSize);
|
||||
else
|
||||
levelLevels[position] = 0;
|
||||
}
|
||||
|
||||
RIF(m_LevelDecoder.SetCodeLengths(levelLevels));
|
||||
|
||||
Byte tmpLevels[kFixedMainTableSize + kFixedDistTableSize];
|
||||
if (!DeCodeLevelTable(tmpLevels, numLitLenLevels + _numDistLevels))
|
||||
return false;
|
||||
|
||||
levels.SubClear();
|
||||
memcpy(levels.litLenLevels, tmpLevels, numLitLenLevels);
|
||||
memcpy(levels.distLevels, tmpLevels + numLitLenLevels, _numDistLevels);
|
||||
}
|
||||
RIF(m_MainDecoder.SetCodeLengths(levels.litLenLevels));
|
||||
return m_DistDecoder.SetCodeLengths(levels.distLevels);
|
||||
}
|
||||
|
||||
HRESULT CCoder::CodeSpec(UInt32 curSize)
|
||||
{
|
||||
if (_remainLen == kLenIdFinished)
|
||||
return S_OK;
|
||||
if (_remainLen == kLenIdNeedInit)
|
||||
{
|
||||
if (!_keepHistory)
|
||||
if (!m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!m_InBitStream.Create(1 << 17))
|
||||
return E_OUTOFMEMORY;
|
||||
m_OutWindowStream.Init(_keepHistory);
|
||||
m_InBitStream.Init();
|
||||
m_FinalBlock = false;
|
||||
_remainLen = 0;
|
||||
_needReadTable = true;
|
||||
}
|
||||
|
||||
if (curSize == 0)
|
||||
return S_OK;
|
||||
|
||||
while(_remainLen > 0 && curSize > 0)
|
||||
{
|
||||
_remainLen--;
|
||||
Byte b = m_OutWindowStream.GetByte(_rep0);
|
||||
m_OutWindowStream.PutByte(b);
|
||||
curSize--;
|
||||
}
|
||||
|
||||
while(curSize > 0)
|
||||
{
|
||||
if (_needReadTable)
|
||||
{
|
||||
if (m_FinalBlock)
|
||||
{
|
||||
_remainLen = kLenIdFinished;
|
||||
break;
|
||||
}
|
||||
if (!ReadTables())
|
||||
return S_FALSE;
|
||||
_needReadTable = false;
|
||||
}
|
||||
|
||||
if(m_StoredMode)
|
||||
{
|
||||
for (; m_StoredBlockSize > 0 && curSize > 0; m_StoredBlockSize--, curSize--)
|
||||
m_OutWindowStream.PutByte((Byte)m_InBitStream.ReadBits(8));
|
||||
_needReadTable = (m_StoredBlockSize == 0);
|
||||
continue;
|
||||
}
|
||||
while(curSize > 0)
|
||||
{
|
||||
if (m_InBitStream.NumExtraBytes > 4)
|
||||
return S_FALSE;
|
||||
|
||||
UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number < 0x100)
|
||||
{
|
||||
m_OutWindowStream.PutByte((Byte)number);
|
||||
curSize--;
|
||||
continue;
|
||||
}
|
||||
else if (number == kSymbolEndOfBlock)
|
||||
{
|
||||
_needReadTable = true;
|
||||
break;
|
||||
}
|
||||
else if (number < kMainTableSize)
|
||||
{
|
||||
number -= kSymbolMatch;
|
||||
UInt32 len;
|
||||
{
|
||||
int numBits;
|
||||
if (_deflate64Mode)
|
||||
{
|
||||
len = kLenStart64[number];
|
||||
numBits = kLenDirectBits64[number];
|
||||
}
|
||||
else
|
||||
{
|
||||
len = kLenStart32[number];
|
||||
numBits = kLenDirectBits32[number];
|
||||
}
|
||||
len += kMatchMinLen + m_InBitStream.ReadBits(numBits);
|
||||
}
|
||||
UInt32 locLen = len;
|
||||
if (locLen > curSize)
|
||||
locLen = (UInt32)curSize;
|
||||
number = m_DistDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number >= _numDistLevels)
|
||||
return S_FALSE;
|
||||
UInt32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]);
|
||||
if (!m_OutWindowStream.CopyBlock(distance, locLen))
|
||||
return S_FALSE;
|
||||
curSize -= locLen;
|
||||
len -= locLen;
|
||||
if (len != 0)
|
||||
{
|
||||
_remainLen = (Int32)len;
|
||||
_rep0 = distance;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UInt64 *, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
SetInStream(inStream);
|
||||
m_OutWindowStream.SetStream(outStream);
|
||||
SetOutStreamSize(outSize);
|
||||
CCoderReleaser flusher(this);
|
||||
|
||||
const UInt64 start = m_OutWindowStream.GetProcessedSize();
|
||||
for (;;)
|
||||
{
|
||||
UInt32 curSize = 1 << 18;
|
||||
if (outSize != 0)
|
||||
{
|
||||
const UInt64 rem = *outSize - (m_OutWindowStream.GetProcessedSize() - start);
|
||||
if (curSize > rem)
|
||||
curSize = (UInt32)rem;
|
||||
}
|
||||
if (curSize == 0)
|
||||
break;
|
||||
RINOK(CodeSpec(curSize));
|
||||
if (_remainLen == kLenIdFinished)
|
||||
break;
|
||||
if (progress != NULL)
|
||||
{
|
||||
const UInt64 inSize = m_InBitStream.GetProcessedSize();
|
||||
const UInt64 nowPos64 = m_OutWindowStream.GetProcessedSize() - start;
|
||||
RINOK(progress->SetRatioInfo(&inSize, &nowPos64));
|
||||
}
|
||||
}
|
||||
flusher.NeedFlush = false;
|
||||
return Flush();
|
||||
}
|
||||
|
||||
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
|
||||
#define DEFLATE_TRY_BEGIN
|
||||
#define DEFLATE_TRY_END
|
||||
|
||||
#else
|
||||
|
||||
#define DEFLATE_TRY_BEGIN try {
|
||||
#define DEFLATE_TRY_END } \
|
||||
catch(const CInBufferException &e) { return e.ErrorCode; } \
|
||||
catch(const CLZOutWindowException &e) { return e.ErrorCode; } \
|
||||
catch(...) { return S_FALSE; }
|
||||
|
||||
#endif
|
||||
|
||||
HRESULT CCoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
DEFLATE_TRY_BEGIN
|
||||
return CodeReal(inStream, outStream, inSize, outSize, progress);
|
||||
DEFLATE_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CCoder::GetInStreamProcessedSize(UInt64 *value)
|
||||
{
|
||||
if (value == NULL)
|
||||
return E_INVALIDARG;
|
||||
*value = m_InBitStream.GetProcessedSize();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CCoder::SetInStream(ISequentialInStream *inStream)
|
||||
{
|
||||
m_InBitStream.SetStream(inStream);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CCoder::ReleaseInStream()
|
||||
{
|
||||
m_InBitStream.ReleaseStream();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CCoder::SetOutStreamSize(const UInt64 * /* outSize */)
|
||||
{
|
||||
_remainLen = kLenIdNeedInit;
|
||||
m_OutWindowStream.Init(_keepHistory);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#ifdef _ST_MODE
|
||||
|
||||
STDMETHODIMP CCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
DEFLATE_TRY_BEGIN
|
||||
if (processedSize)
|
||||
*processedSize = 0;
|
||||
const UInt64 startPos = m_OutWindowStream.GetProcessedSize();
|
||||
m_OutWindowStream.SetMemStream((Byte *)data);
|
||||
RINOK(CodeSpec(size));
|
||||
if (processedSize)
|
||||
*processedSize = (UInt32)(m_OutWindowStream.GetProcessedSize() - startPos);
|
||||
return Flush();
|
||||
DEFLATE_TRY_END
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}}}
|
||||
134
CPP/7zip/Compress/Deflate/DeflateDecoder.h
Executable file
134
CPP/7zip/Compress/Deflate/DeflateDecoder.h
Executable file
@@ -0,0 +1,134 @@
|
||||
// DeflateDecoder.h
|
||||
|
||||
#ifndef __DEFLATE_DECODER_H
|
||||
#define __DEFLATE_DECODER_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/LSBFDecoder.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
#include "../LZ/LZOutWindow.h"
|
||||
#include "../Huffman/HuffmanDecoder.h"
|
||||
|
||||
#include "DeflateConst.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
namespace NDecoder {
|
||||
|
||||
class CCoder:
|
||||
public ICompressCoder,
|
||||
public ICompressGetInStreamProcessedSize,
|
||||
#ifdef _ST_MODE
|
||||
public ICompressSetInStream,
|
||||
public ICompressSetOutStreamSize,
|
||||
public ISequentialInStream,
|
||||
#endif
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CLZOutWindow m_OutWindowStream;
|
||||
NStream::NLSBF::CDecoder<CInBuffer> m_InBitStream;
|
||||
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kFixedMainTableSize> m_MainDecoder;
|
||||
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kFixedDistTableSize> m_DistDecoder;
|
||||
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder;
|
||||
|
||||
UInt32 m_StoredBlockSize;
|
||||
|
||||
bool m_FinalBlock;
|
||||
bool m_StoredMode;
|
||||
UInt32 _numDistLevels;
|
||||
|
||||
|
||||
bool _deflateNSIS;
|
||||
bool _deflate64Mode;
|
||||
bool _keepHistory;
|
||||
Int32 _remainLen;
|
||||
UInt32 _rep0;
|
||||
bool _needReadTable;
|
||||
|
||||
UInt32 ReadBits(int numBits);
|
||||
|
||||
bool DeCodeLevelTable(Byte *values, int numSymbols);
|
||||
bool ReadTables();
|
||||
|
||||
void ReleaseStreams()
|
||||
{
|
||||
m_OutWindowStream.ReleaseStream();
|
||||
ReleaseInStream();
|
||||
}
|
||||
|
||||
HRESULT Flush() { return m_OutWindowStream.Flush(); }
|
||||
class CCoderReleaser
|
||||
{
|
||||
CCoder *m_Coder;
|
||||
public:
|
||||
bool NeedFlush;
|
||||
CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {}
|
||||
~CCoderReleaser()
|
||||
{
|
||||
if (NeedFlush)
|
||||
m_Coder->Flush();
|
||||
m_Coder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
friend class CCoderReleaser;
|
||||
|
||||
HRESULT CodeSpec(UInt32 curSize);
|
||||
public:
|
||||
CCoder(bool deflate64Mode, bool deflateNSIS = false);
|
||||
void SetKeepHistory(bool keepHistory) { _keepHistory = keepHistory; }
|
||||
|
||||
HRESULT CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
#ifdef _ST_MODE
|
||||
MY_UNKNOWN_IMP4(
|
||||
ICompressGetInStreamProcessedSize,
|
||||
ICompressSetInStream,
|
||||
ICompressSetOutStreamSize,
|
||||
ISequentialInStream
|
||||
)
|
||||
#else
|
||||
MY_UNKNOWN_IMP1(
|
||||
ICompressGetInStreamProcessedSize)
|
||||
#endif
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
|
||||
STDMETHOD(ReleaseInStream)();
|
||||
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
|
||||
|
||||
#ifdef _ST_MODE
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
#endif
|
||||
|
||||
// IGetInStreamProcessedSize
|
||||
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
|
||||
};
|
||||
|
||||
class CCOMCoder : public CCoder
|
||||
{
|
||||
public:
|
||||
CCOMCoder(): CCoder(false) {}
|
||||
};
|
||||
|
||||
class CNsisCOMCoder : public CCoder
|
||||
{
|
||||
public:
|
||||
CNsisCOMCoder(): CCoder(false, true) {}
|
||||
};
|
||||
|
||||
class CCOMCoder64 : public CCoder
|
||||
{
|
||||
public:
|
||||
CCOMCoder64(): CCoder(true) {}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
963
CPP/7zip/Compress/Deflate/DeflateEncoder.cpp
Executable file
963
CPP/7zip/Compress/Deflate/DeflateEncoder.cpp
Executable file
@@ -0,0 +1,963 @@
|
||||
// DeflateEncoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "DeflateEncoder.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "Common/ComTry.h"
|
||||
#include "../../../Common/Alloc.h"
|
||||
// #include "../LZ/BinTree/BinTree3Z.h"
|
||||
|
||||
#if _MSC_VER >= 1300
|
||||
#define NO_INLINE __declspec(noinline)
|
||||
#else
|
||||
#define NO_INLINE
|
||||
#endif
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/Compress/Huffman/HuffmanEncode.h"
|
||||
}
|
||||
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
namespace NEncoder {
|
||||
|
||||
const int kNumDivPassesMax = 10; // [0, 16); ratio/speed/ram tradeoff; use big value for better compression ratio.
|
||||
const UInt32 kNumTables = (1 << kNumDivPassesMax);
|
||||
|
||||
static UInt32 kFixedHuffmanCodeBlockSizeMax = (1 << 8); // [0, (1 << 32)); ratio/speed tradeoff; use big value for better compression ratio.
|
||||
static UInt32 kDivideCodeBlockSizeMin = (1 << 6); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio.
|
||||
static UInt32 kDivideBlockSizeMin = (1 << 6); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio.
|
||||
|
||||
static const UInt32 kMaxUncompressedBlockSize = ((1 << 16) - 1) * 1; // [1, (1 << 32))
|
||||
static const UInt32 kMatchArraySize = kMaxUncompressedBlockSize * 10; // [kMatchMaxLen * 2, (1 << 32))
|
||||
static const UInt32 kMatchArrayLimit = kMatchArraySize - kMatchMaxLen * 4 * sizeof(UInt16);
|
||||
static const UInt32 kBlockUncompressedSizeThreshold = kMaxUncompressedBlockSize -
|
||||
kMatchMaxLen - kNumOpts;
|
||||
|
||||
static const int kMaxCodeBitLength = 15;
|
||||
static const int kMaxLevelBitLength = 7;
|
||||
|
||||
static Byte kNoLiteralStatPrice = 13;
|
||||
static Byte kNoLenStatPrice = 13;
|
||||
static Byte kNoPosStatPrice = 6;
|
||||
|
||||
static Byte g_LenSlots[kNumLenSymbolsMax];
|
||||
static Byte g_FastPos[1 << 9];
|
||||
|
||||
class CFastPosInit
|
||||
{
|
||||
public:
|
||||
CFastPosInit()
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < kNumLenSlots; i++)
|
||||
{
|
||||
int c = kLenStart32[i];
|
||||
int j = 1 << kLenDirectBits32[i];
|
||||
for(int k = 0; k < j; k++, c++)
|
||||
g_LenSlots[c] = (Byte)i;
|
||||
}
|
||||
|
||||
const int kFastSlots = 18;
|
||||
int c = 0;
|
||||
for (Byte slotFast = 0; slotFast < kFastSlots; slotFast++)
|
||||
{
|
||||
UInt32 k = (1 << kDistDirectBits[slotFast]);
|
||||
for (UInt32 j = 0; j < k; j++, c++)
|
||||
g_FastPos[c] = slotFast;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static CFastPosInit g_FastPosInit;
|
||||
|
||||
|
||||
inline UInt32 GetPosSlot(UInt32 pos)
|
||||
{
|
||||
if (pos < 0x200)
|
||||
return g_FastPos[pos];
|
||||
return g_FastPos[pos >> 8] + 16;
|
||||
}
|
||||
|
||||
void *SzAlloc(size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return 0;
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void SzFree(void *address)
|
||||
{
|
||||
free(address);
|
||||
}
|
||||
|
||||
ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||
|
||||
CCoder::CCoder(bool deflate64Mode):
|
||||
m_Deflate64Mode(deflate64Mode),
|
||||
m_NumPasses(1),
|
||||
m_NumDivPasses(1),
|
||||
m_NumFastBytes(32),
|
||||
m_OnePosMatchesMemory(0),
|
||||
m_DistanceMemory(0),
|
||||
m_Created(false),
|
||||
m_Values(0),
|
||||
m_Tables(0),
|
||||
m_MatchFinderCycles(0)
|
||||
// m_SetMfPasses(0)
|
||||
{
|
||||
m_MatchMaxLen = deflate64Mode ? kMatchMaxLen64 : kMatchMaxLen32;
|
||||
m_NumLenCombinations = deflate64Mode ? kNumLenSymbols64 : kNumLenSymbols32;
|
||||
m_LenStart = deflate64Mode ? kLenStart64 : kLenStart32;
|
||||
m_LenDirectBits = deflate64Mode ? kLenDirectBits64 : kLenDirectBits32;
|
||||
MatchFinder_Construct(&_lzInWindow);
|
||||
}
|
||||
|
||||
HRESULT CCoder::Create()
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
if (m_Values == 0)
|
||||
{
|
||||
m_Values = (CCodeValue *)MyAlloc((kMaxUncompressedBlockSize) * sizeof(CCodeValue));
|
||||
if (m_Values == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
if (m_Tables == 0)
|
||||
{
|
||||
m_Tables = (CTables *)MyAlloc((kNumTables) * sizeof(CTables));
|
||||
if (m_Tables == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if (m_IsMultiPass)
|
||||
{
|
||||
if (m_OnePosMatchesMemory == 0)
|
||||
{
|
||||
m_OnePosMatchesMemory = (UInt16 *)::MidAlloc(kMatchArraySize * sizeof(UInt16));
|
||||
if (m_OnePosMatchesMemory == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_DistanceMemory == 0)
|
||||
{
|
||||
m_DistanceMemory = (UInt16 *)MyAlloc((kMatchMaxLen + 2) * 2 * sizeof(UInt16));
|
||||
if (m_DistanceMemory == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
m_MatchDistances = m_DistanceMemory;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_Created)
|
||||
{
|
||||
_lzInWindow.btMode = 1;
|
||||
_lzInWindow.numHashBytes = 3;
|
||||
if (!MatchFinder_Create(&_lzInWindow,
|
||||
m_Deflate64Mode ? kHistorySize64 : kHistorySize32,
|
||||
kNumOpts + kMaxUncompressedBlockSize,
|
||||
m_NumFastBytes, m_MatchMaxLen - m_NumFastBytes, &g_Alloc))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!m_OutStream.Create(1 << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
if (m_MatchFinderCycles != 0)
|
||||
_lzInWindow.cutValue = m_MatchFinderCycles;
|
||||
m_Created = true;
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
// ICompressSetEncoderProperties2
|
||||
HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UInt32 numProperties)
|
||||
{
|
||||
for(UInt32 i = 0; i < numProperties; i++)
|
||||
{
|
||||
const PROPVARIANT &prop = properties[i];
|
||||
switch(propIDs[i])
|
||||
{
|
||||
case NCoderPropID::kNumPasses:
|
||||
if (prop.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
m_NumDivPasses = prop.ulVal;
|
||||
if (m_NumDivPasses == 0)
|
||||
m_NumDivPasses = 1;
|
||||
if (m_NumDivPasses == 1)
|
||||
m_NumPasses = 1;
|
||||
else if (m_NumDivPasses <= kNumDivPassesMax)
|
||||
m_NumPasses = 2;
|
||||
else
|
||||
{
|
||||
m_NumPasses = 2 + (m_NumDivPasses - kNumDivPassesMax);
|
||||
m_NumDivPasses = kNumDivPassesMax;
|
||||
}
|
||||
break;
|
||||
case NCoderPropID::kNumFastBytes:
|
||||
if (prop.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
m_NumFastBytes = prop.ulVal;
|
||||
if(m_NumFastBytes < kMatchMinLen || m_NumFastBytes > m_MatchMaxLen)
|
||||
return E_INVALIDARG;
|
||||
break;
|
||||
case NCoderPropID::kMatchFinderCycles:
|
||||
{
|
||||
if (prop.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
m_MatchFinderCycles = prop.ulVal;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CCoder::Free()
|
||||
{
|
||||
::MidFree(m_OnePosMatchesMemory);
|
||||
m_OnePosMatchesMemory = 0;
|
||||
::MyFree(m_DistanceMemory);
|
||||
m_DistanceMemory = 0;
|
||||
::MyFree(m_Values);
|
||||
m_Values = 0;
|
||||
::MyFree(m_Tables);
|
||||
m_Tables = 0;
|
||||
}
|
||||
|
||||
CCoder::~CCoder()
|
||||
{
|
||||
Free();
|
||||
MatchFinder_Free(&_lzInWindow, &g_Alloc);
|
||||
}
|
||||
|
||||
void CCoder::GetMatches()
|
||||
{
|
||||
if (m_IsMultiPass)
|
||||
{
|
||||
m_MatchDistances = m_OnePosMatchesMemory + m_Pos;
|
||||
if (m_SecondPass)
|
||||
{
|
||||
m_Pos += *m_MatchDistances + 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 distanceTmp[kMatchMaxLen * 2 + 3];
|
||||
|
||||
UInt32 numPairs = Bt3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp);
|
||||
*m_MatchDistances = (UInt16)numPairs;
|
||||
|
||||
if (numPairs > 0)
|
||||
{
|
||||
UInt32 i;
|
||||
for(i = 0; i < numPairs; i += 2)
|
||||
{
|
||||
m_MatchDistances[i + 1] = (UInt16)distanceTmp[i];
|
||||
m_MatchDistances[i + 2] = (UInt16)distanceTmp[i + 1];
|
||||
}
|
||||
UInt32 len = distanceTmp[numPairs - 2];
|
||||
if (len == m_NumFastBytes && m_NumFastBytes != m_MatchMaxLen)
|
||||
{
|
||||
UInt32 numAvail = Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) + 1;
|
||||
const Byte *pby = Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow) - 1;
|
||||
UInt32 distance = distanceTmp[numPairs - 1] + 1;
|
||||
if (numAvail > m_MatchMaxLen)
|
||||
numAvail = m_MatchMaxLen;
|
||||
for (; len < numAvail && pby[len] == pby[(size_t)len - distance]; len++);
|
||||
m_MatchDistances[i - 1] = (UInt16)len;
|
||||
}
|
||||
}
|
||||
if (m_IsMultiPass)
|
||||
m_Pos += numPairs + 1;
|
||||
if (!m_SecondPass)
|
||||
m_AdditionalOffset++;
|
||||
}
|
||||
|
||||
void CCoder::MovePos(UInt32 num)
|
||||
{
|
||||
if (!m_SecondPass && num > 0)
|
||||
{
|
||||
Bt3Zip_MatchFinder_Skip(&_lzInWindow, num);
|
||||
m_AdditionalOffset += num;
|
||||
}
|
||||
}
|
||||
|
||||
static const UInt32 kIfinityPrice = 0xFFFFFFF;
|
||||
|
||||
NO_INLINE UInt32 CCoder::Backward(UInt32 &backRes, UInt32 cur)
|
||||
{
|
||||
m_OptimumEndIndex = cur;
|
||||
UInt32 posMem = m_Optimum[cur].PosPrev;
|
||||
UInt16 backMem = m_Optimum[cur].BackPrev;
|
||||
do
|
||||
{
|
||||
UInt32 posPrev = posMem;
|
||||
UInt16 backCur = backMem;
|
||||
backMem = m_Optimum[posPrev].BackPrev;
|
||||
posMem = m_Optimum[posPrev].PosPrev;
|
||||
m_Optimum[posPrev].BackPrev = backCur;
|
||||
m_Optimum[posPrev].PosPrev = (UInt16)cur;
|
||||
cur = posPrev;
|
||||
}
|
||||
while(cur > 0);
|
||||
backRes = m_Optimum[0].BackPrev;
|
||||
m_OptimumCurrentIndex = m_Optimum[0].PosPrev;
|
||||
return m_OptimumCurrentIndex;
|
||||
}
|
||||
|
||||
NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes)
|
||||
{
|
||||
if(m_OptimumEndIndex != m_OptimumCurrentIndex)
|
||||
{
|
||||
UInt32 len = m_Optimum[m_OptimumCurrentIndex].PosPrev - m_OptimumCurrentIndex;
|
||||
backRes = m_Optimum[m_OptimumCurrentIndex].BackPrev;
|
||||
m_OptimumCurrentIndex = m_Optimum[m_OptimumCurrentIndex].PosPrev;
|
||||
return len;
|
||||
}
|
||||
m_OptimumCurrentIndex = m_OptimumEndIndex = 0;
|
||||
|
||||
GetMatches();
|
||||
|
||||
UInt32 numDistancePairs = m_MatchDistances[0];
|
||||
if(numDistancePairs == 0)
|
||||
return 1;
|
||||
|
||||
const UInt16 *matchDistances = m_MatchDistances + 1;
|
||||
UInt32 lenMain = matchDistances[numDistancePairs - 2];
|
||||
|
||||
if(lenMain > m_NumFastBytes)
|
||||
{
|
||||
backRes = matchDistances[numDistancePairs - 1];
|
||||
MovePos(lenMain - 1);
|
||||
return lenMain;
|
||||
}
|
||||
m_Optimum[1].Price = m_LiteralPrices[Inline_MatchFinder_GetIndexByte(&_lzInWindow, 0 - m_AdditionalOffset)];
|
||||
m_Optimum[1].PosPrev = 0;
|
||||
|
||||
m_Optimum[2].Price = kIfinityPrice;
|
||||
m_Optimum[2].PosPrev = 1;
|
||||
|
||||
|
||||
UInt32 offs = 0;
|
||||
for(UInt32 i = kMatchMinLen; i <= lenMain; i++)
|
||||
{
|
||||
UInt32 distance = matchDistances[offs + 1];
|
||||
m_Optimum[i].PosPrev = 0;
|
||||
m_Optimum[i].BackPrev = (UInt16)distance;
|
||||
m_Optimum[i].Price = m_LenPrices[i - kMatchMinLen] + m_PosPrices[GetPosSlot(distance)];
|
||||
if (i == matchDistances[offs])
|
||||
offs += 2;
|
||||
}
|
||||
|
||||
UInt32 cur = 0;
|
||||
UInt32 lenEnd = lenMain;
|
||||
for (;;)
|
||||
{
|
||||
++cur;
|
||||
if(cur == lenEnd || cur == kNumOptsBase || m_Pos >= kMatchArrayLimit)
|
||||
return Backward(backRes, cur);
|
||||
GetMatches();
|
||||
matchDistances = m_MatchDistances + 1;
|
||||
|
||||
UInt32 numDistancePairs = m_MatchDistances[0];
|
||||
UInt32 newLen = 0;
|
||||
if(numDistancePairs != 0)
|
||||
{
|
||||
newLen = matchDistances[numDistancePairs - 2];
|
||||
if(newLen > m_NumFastBytes)
|
||||
{
|
||||
UInt32 len = Backward(backRes, cur);
|
||||
m_Optimum[cur].BackPrev = matchDistances[numDistancePairs - 1];
|
||||
m_OptimumEndIndex = cur + newLen;
|
||||
m_Optimum[cur].PosPrev = (UInt16)m_OptimumEndIndex;
|
||||
MovePos(newLen - 1);
|
||||
return len;
|
||||
}
|
||||
}
|
||||
UInt32 curPrice = m_Optimum[cur].Price;
|
||||
UInt32 curAnd1Price = curPrice + m_LiteralPrices[Inline_MatchFinder_GetIndexByte(&_lzInWindow, cur - m_AdditionalOffset)];
|
||||
COptimal &optimum = m_Optimum[cur + 1];
|
||||
if (curAnd1Price < optimum.Price)
|
||||
{
|
||||
optimum.Price = curAnd1Price;
|
||||
optimum.PosPrev = (UInt16)cur;
|
||||
}
|
||||
if(numDistancePairs == 0)
|
||||
continue;
|
||||
while(lenEnd < cur + newLen)
|
||||
m_Optimum[++lenEnd].Price = kIfinityPrice;
|
||||
offs = 0;
|
||||
UInt32 distance = matchDistances[offs + 1];
|
||||
curPrice += m_PosPrices[GetPosSlot(distance)];
|
||||
for(UInt32 lenTest = kMatchMinLen; ; lenTest++)
|
||||
{
|
||||
UInt32 curAndLenPrice = curPrice + m_LenPrices[lenTest - kMatchMinLen];
|
||||
COptimal &optimum = m_Optimum[cur + lenTest];
|
||||
if (curAndLenPrice < optimum.Price)
|
||||
{
|
||||
optimum.Price = curAndLenPrice;
|
||||
optimum.PosPrev = (UInt16)cur;
|
||||
optimum.BackPrev = (UInt16)distance;
|
||||
}
|
||||
if (lenTest == matchDistances[offs])
|
||||
{
|
||||
offs += 2;
|
||||
if (offs == numDistancePairs)
|
||||
break;
|
||||
curPrice -= m_PosPrices[GetPosSlot(distance)];
|
||||
distance = matchDistances[offs + 1];
|
||||
curPrice += m_PosPrices[GetPosSlot(distance)];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CTables::InitStructures()
|
||||
{
|
||||
UInt32 i;
|
||||
for(i = 0; i < 256; i++)
|
||||
litLenLevels[i] = 8;
|
||||
litLenLevels[i++] = 13;
|
||||
for(;i < kFixedMainTableSize; i++)
|
||||
litLenLevels[i] = 5;
|
||||
for(i = 0; i < kFixedDistTableSize; i++)
|
||||
distLevels[i] = 5;
|
||||
}
|
||||
|
||||
NO_INLINE void CCoder::LevelTableDummy(const Byte *levels, int numLevels, UInt32 *freqs)
|
||||
{
|
||||
int prevLen = 0xFF;
|
||||
int nextLen = levels[0];
|
||||
int count = 0;
|
||||
int maxCount = 7;
|
||||
int minCount = 4;
|
||||
if (nextLen == 0)
|
||||
{
|
||||
maxCount = 138;
|
||||
minCount = 3;
|
||||
}
|
||||
for (int n = 0; n < numLevels; n++)
|
||||
{
|
||||
int curLen = nextLen;
|
||||
nextLen = (n < numLevels - 1) ? levels[n + 1] : 0xFF;
|
||||
count++;
|
||||
if (count < maxCount && curLen == nextLen)
|
||||
continue;
|
||||
|
||||
if (count < minCount)
|
||||
freqs[curLen] += (UInt32)count;
|
||||
else if (curLen != 0)
|
||||
{
|
||||
if (curLen != prevLen)
|
||||
{
|
||||
freqs[curLen]++;
|
||||
count--;
|
||||
}
|
||||
freqs[kTableLevelRepNumber]++;
|
||||
}
|
||||
else if (count <= 10)
|
||||
freqs[kTableLevel0Number]++;
|
||||
else
|
||||
freqs[kTableLevel0Number2]++;
|
||||
|
||||
count = 0;
|
||||
prevLen = curLen;
|
||||
|
||||
if (nextLen == 0)
|
||||
{
|
||||
maxCount = 138;
|
||||
minCount = 3;
|
||||
}
|
||||
else if (curLen == nextLen)
|
||||
{
|
||||
maxCount = 6;
|
||||
minCount = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxCount = 7;
|
||||
minCount = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define WRITE_HF2(codes, lens, i) m_OutStream.WriteBits(codes[i], lens[i])
|
||||
#define WRITE_HF(i) m_OutStream.WriteBits(codes[i], lens[i])
|
||||
|
||||
NO_INLINE void CCoder::LevelTableCode(const Byte *levels, int numLevels, const Byte *lens, const UInt32 *codes)
|
||||
{
|
||||
int prevLen = 0xFF;
|
||||
int nextLen = levels[0];
|
||||
int count = 0;
|
||||
int maxCount = 7;
|
||||
int minCount = 4;
|
||||
if (nextLen == 0)
|
||||
{
|
||||
maxCount = 138;
|
||||
minCount = 3;
|
||||
}
|
||||
for (int n = 0; n < numLevels; n++)
|
||||
{
|
||||
int curLen = nextLen;
|
||||
nextLen = (n < numLevels - 1) ? levels[n + 1] : 0xFF;
|
||||
count++;
|
||||
if (count < maxCount && curLen == nextLen)
|
||||
continue;
|
||||
|
||||
if (count < minCount)
|
||||
for(int i = 0; i < count; i++)
|
||||
WRITE_HF(curLen);
|
||||
else if (curLen != 0)
|
||||
{
|
||||
if (curLen != prevLen)
|
||||
{
|
||||
WRITE_HF(curLen);
|
||||
count--;
|
||||
}
|
||||
WRITE_HF(kTableLevelRepNumber);
|
||||
m_OutStream.WriteBits(count - 3, 2);
|
||||
}
|
||||
else if (count <= 10)
|
||||
{
|
||||
WRITE_HF(kTableLevel0Number);
|
||||
m_OutStream.WriteBits(count - 3, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITE_HF(kTableLevel0Number2);
|
||||
m_OutStream.WriteBits(count - 11, 7);
|
||||
}
|
||||
|
||||
count = 0;
|
||||
prevLen = curLen;
|
||||
|
||||
if (nextLen == 0)
|
||||
{
|
||||
maxCount = 138;
|
||||
minCount = 3;
|
||||
}
|
||||
else if (curLen == nextLen)
|
||||
{
|
||||
maxCount = 6;
|
||||
minCount = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxCount = 7;
|
||||
minCount = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NO_INLINE void CCoder::MakeTables()
|
||||
{
|
||||
Huffman_Generate(mainFreqs, mainCodes, m_NewLevels.litLenLevels, kFixedMainTableSize, kMaxCodeBitLength);
|
||||
Huffman_Generate(distFreqs, distCodes, m_NewLevels.distLevels, kDistTableSize64, kMaxCodeBitLength);
|
||||
}
|
||||
|
||||
NO_INLINE UInt32 Huffman_GetPrice(const UInt32 *freqs, const Byte *lens, UInt32 num)
|
||||
{
|
||||
UInt32 price = 0;
|
||||
UInt32 i;
|
||||
for (i = 0; i < num; i++)
|
||||
price += lens[i] * freqs[i];
|
||||
return price;
|
||||
};
|
||||
|
||||
NO_INLINE UInt32 Huffman_GetPrice_Spec(const UInt32 *freqs, const Byte *lens, UInt32 num, const Byte *extraBits, UInt32 extraBase)
|
||||
{
|
||||
return Huffman_GetPrice(freqs, lens, num) +
|
||||
Huffman_GetPrice(freqs + extraBase, extraBits, num - extraBase);
|
||||
}
|
||||
|
||||
NO_INLINE UInt32 CCoder::GetLzBlockPrice() const
|
||||
{
|
||||
return
|
||||
Huffman_GetPrice_Spec(mainFreqs, m_NewLevels.litLenLevels, kFixedMainTableSize, m_LenDirectBits, kSymbolMatch) +
|
||||
Huffman_GetPrice_Spec(distFreqs, m_NewLevels.distLevels, kDistTableSize64, kDistDirectBits, 0);
|
||||
}
|
||||
|
||||
NO_INLINE void CCoder::TryBlock()
|
||||
{
|
||||
memset(mainFreqs, 0, sizeof(mainFreqs));
|
||||
memset(distFreqs, 0, sizeof(distFreqs));
|
||||
|
||||
m_ValueIndex = 0;
|
||||
UInt32 blockSize = BlockSizeRes;
|
||||
BlockSizeRes = 0;
|
||||
for (;;)
|
||||
{
|
||||
if (m_OptimumCurrentIndex == m_OptimumEndIndex)
|
||||
{
|
||||
if (m_Pos >= kMatchArrayLimit || BlockSizeRes >= blockSize || !m_SecondPass &&
|
||||
((Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) == 0) || m_ValueIndex >= m_ValueBlockSize))
|
||||
break;
|
||||
}
|
||||
UInt32 pos;
|
||||
UInt32 len = GetOptimal(pos);
|
||||
CCodeValue &codeValue = m_Values[m_ValueIndex++];
|
||||
if (len >= kMatchMinLen)
|
||||
{
|
||||
UInt32 newLen = len - kMatchMinLen;
|
||||
codeValue.Len = (UInt16)newLen;
|
||||
mainFreqs[kSymbolMatch + g_LenSlots[newLen]]++;
|
||||
codeValue.Pos = (UInt16)pos;
|
||||
distFreqs[GetPosSlot(pos)]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Byte b = Inline_MatchFinder_GetIndexByte(&_lzInWindow, 0 - m_AdditionalOffset);
|
||||
mainFreqs[b]++;
|
||||
codeValue.SetAsLiteral();
|
||||
codeValue.Pos = b;
|
||||
}
|
||||
m_AdditionalOffset -= len;
|
||||
BlockSizeRes += len;
|
||||
}
|
||||
mainFreqs[kSymbolEndOfBlock]++;
|
||||
m_AdditionalOffset += BlockSizeRes;
|
||||
m_SecondPass = true;
|
||||
}
|
||||
|
||||
NO_INLINE void CCoder::SetPrices(const CLevels &levels)
|
||||
{
|
||||
UInt32 i;
|
||||
for(i = 0; i < 256; i++)
|
||||
{
|
||||
Byte price = levels.litLenLevels[i];
|
||||
m_LiteralPrices[i] = ((price != 0) ? price : kNoLiteralStatPrice);
|
||||
}
|
||||
|
||||
for(i = 0; i < m_NumLenCombinations; i++)
|
||||
{
|
||||
UInt32 slot = g_LenSlots[i];
|
||||
Byte price = levels.litLenLevels[kSymbolMatch + slot];
|
||||
m_LenPrices[i] = (Byte)(((price != 0) ? price : kNoLenStatPrice) + m_LenDirectBits[slot]);
|
||||
}
|
||||
|
||||
for(i = 0; i < kDistTableSize64; i++)
|
||||
{
|
||||
Byte price = levels.distLevels[i];
|
||||
m_PosPrices[i] = (Byte)(((price != 0) ? price: kNoPosStatPrice) + kDistDirectBits[i]);
|
||||
}
|
||||
}
|
||||
|
||||
NO_INLINE void Huffman_ReverseBits(UInt32 *codes, const Byte *lens, UInt32 num)
|
||||
{
|
||||
for (UInt32 i = 0; i < num; i++)
|
||||
{
|
||||
UInt32 x = codes[i];
|
||||
x = ((x & 0x5555) << 1) | ((x & 0xAAAA) >> 1);
|
||||
x = ((x & 0x3333) << 2) | ((x & 0xCCCC) >> 2);
|
||||
x = ((x & 0x0F0F) << 4) | ((x & 0xF0F0) >> 4);
|
||||
codes[i] = (((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8)) >> (16 - lens[i]);
|
||||
}
|
||||
}
|
||||
|
||||
NO_INLINE void CCoder::WriteBlock()
|
||||
{
|
||||
Huffman_ReverseBits(mainCodes, m_NewLevels.litLenLevels, kFixedMainTableSize);
|
||||
Huffman_ReverseBits(distCodes, m_NewLevels.distLevels, kDistTableSize64);
|
||||
|
||||
for (UInt32 i = 0; i < m_ValueIndex; i++)
|
||||
{
|
||||
const CCodeValue &codeValue = m_Values[i];
|
||||
if (codeValue.IsLiteral())
|
||||
WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, codeValue.Pos);
|
||||
else
|
||||
{
|
||||
UInt32 len = codeValue.Len;
|
||||
UInt32 lenSlot = g_LenSlots[len];
|
||||
WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, kSymbolMatch + lenSlot);
|
||||
m_OutStream.WriteBits(len - m_LenStart[lenSlot], m_LenDirectBits[lenSlot]);
|
||||
UInt32 dist = codeValue.Pos;
|
||||
UInt32 posSlot = GetPosSlot(dist);
|
||||
WRITE_HF2(distCodes, m_NewLevels.distLevels, posSlot);
|
||||
m_OutStream.WriteBits(dist - kDistStart[posSlot], kDistDirectBits[posSlot]);
|
||||
}
|
||||
}
|
||||
WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, kSymbolEndOfBlock);
|
||||
}
|
||||
|
||||
static UInt32 GetStorePrice(UInt32 blockSize, int bitPosition)
|
||||
{
|
||||
UInt32 price = 0;
|
||||
do
|
||||
{
|
||||
UInt32 nextBitPosition = (bitPosition + kFinalBlockFieldSize + kBlockTypeFieldSize) & 7;
|
||||
int numBitsForAlign = nextBitPosition > 0 ? (8 - nextBitPosition): 0;
|
||||
UInt32 curBlockSize = (blockSize < (1 << 16)) ? blockSize : (1 << 16) - 1;
|
||||
price += kFinalBlockFieldSize + kBlockTypeFieldSize + numBitsForAlign + (2 + 2) * 8 + curBlockSize * 8;
|
||||
bitPosition = 0;
|
||||
blockSize -= curBlockSize;
|
||||
}
|
||||
while(blockSize != 0);
|
||||
return price;
|
||||
}
|
||||
|
||||
void CCoder::WriteStoreBlock(UInt32 blockSize, UInt32 additionalOffset, bool finalBlock)
|
||||
{
|
||||
do
|
||||
{
|
||||
UInt32 curBlockSize = (blockSize < (1 << 16)) ? blockSize : (1 << 16) - 1;
|
||||
blockSize -= curBlockSize;
|
||||
m_OutStream.WriteBits((finalBlock && (blockSize == 0) ? NFinalBlockField::kFinalBlock: NFinalBlockField::kNotFinalBlock), kFinalBlockFieldSize);
|
||||
m_OutStream.WriteBits(NBlockType::kStored, kBlockTypeFieldSize);
|
||||
m_OutStream.FlushByte();
|
||||
m_OutStream.WriteBits((UInt16)curBlockSize, kStoredBlockLengthFieldSize);
|
||||
m_OutStream.WriteBits((UInt16)~curBlockSize, kStoredBlockLengthFieldSize);
|
||||
const Byte *data = Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow)- additionalOffset;
|
||||
for(UInt32 i = 0; i < curBlockSize; i++)
|
||||
m_OutStream.WriteByte(data[i]);
|
||||
additionalOffset -= curBlockSize;
|
||||
}
|
||||
while(blockSize != 0);
|
||||
}
|
||||
|
||||
NO_INLINE UInt32 CCoder::TryDynBlock(int tableIndex, UInt32 numPasses)
|
||||
{
|
||||
CTables &t = m_Tables[tableIndex];
|
||||
BlockSizeRes = t.BlockSizeRes;
|
||||
UInt32 posTemp = t.m_Pos;
|
||||
SetPrices(t);
|
||||
|
||||
for (UInt32 p = 0; p < numPasses; p++)
|
||||
{
|
||||
m_Pos = posTemp;
|
||||
TryBlock();
|
||||
MakeTables();
|
||||
SetPrices(m_NewLevels);
|
||||
}
|
||||
|
||||
(CLevels &)t = m_NewLevels;
|
||||
|
||||
m_NumLitLenLevels = kMainTableSize;
|
||||
while(m_NumLitLenLevels > kNumLitLenCodesMin && m_NewLevels.litLenLevels[m_NumLitLenLevels - 1] == 0)
|
||||
m_NumLitLenLevels--;
|
||||
|
||||
m_NumDistLevels = kDistTableSize64;
|
||||
while(m_NumDistLevels > kNumDistCodesMin && m_NewLevels.distLevels[m_NumDistLevels - 1] == 0)
|
||||
m_NumDistLevels--;
|
||||
|
||||
UInt32 levelFreqs[kLevelTableSize];
|
||||
memset(levelFreqs, 0, sizeof(levelFreqs));
|
||||
|
||||
LevelTableDummy(m_NewLevels.litLenLevels, m_NumLitLenLevels, levelFreqs);
|
||||
LevelTableDummy(m_NewLevels.distLevels, m_NumDistLevels, levelFreqs);
|
||||
|
||||
Huffman_Generate(levelFreqs, levelCodes, levelLens, kLevelTableSize, kMaxLevelBitLength);
|
||||
|
||||
m_NumLevelCodes = kNumLevelCodesMin;
|
||||
for (UInt32 i = 0; i < kLevelTableSize; i++)
|
||||
{
|
||||
Byte level = levelLens[kCodeLengthAlphabetOrder[i]];
|
||||
if (level > 0 && i >= m_NumLevelCodes)
|
||||
m_NumLevelCodes = i + 1;
|
||||
m_LevelLevels[i] = level;
|
||||
}
|
||||
|
||||
return GetLzBlockPrice() +
|
||||
Huffman_GetPrice_Spec(levelFreqs, levelLens, kLevelTableSize, kLevelDirectBits, kTableDirectLevels) +
|
||||
kNumLenCodesFieldSize + kNumDistCodesFieldSize + kNumLevelCodesFieldSize +
|
||||
m_NumLevelCodes * kLevelFieldSize + kFinalBlockFieldSize + kBlockTypeFieldSize;
|
||||
}
|
||||
|
||||
NO_INLINE UInt32 CCoder::TryFixedBlock(int tableIndex)
|
||||
{
|
||||
CTables &t = m_Tables[tableIndex];
|
||||
BlockSizeRes = t.BlockSizeRes;
|
||||
m_Pos = t.m_Pos;
|
||||
m_NewLevels.SetFixedLevels();
|
||||
SetPrices(m_NewLevels);
|
||||
TryBlock();
|
||||
return kFinalBlockFieldSize + kBlockTypeFieldSize + GetLzBlockPrice();
|
||||
}
|
||||
|
||||
NO_INLINE UInt32 CCoder::GetBlockPrice(int tableIndex, int numDivPasses)
|
||||
{
|
||||
CTables &t = m_Tables[tableIndex];
|
||||
t.StaticMode = false;
|
||||
UInt32 price = TryDynBlock(tableIndex, m_NumPasses);
|
||||
t.BlockSizeRes = BlockSizeRes;
|
||||
UInt32 numValues = m_ValueIndex;
|
||||
UInt32 posTemp = m_Pos;
|
||||
UInt32 additionalOffsetEnd = m_AdditionalOffset;
|
||||
|
||||
if (m_CheckStatic && m_ValueIndex <= kFixedHuffmanCodeBlockSizeMax)
|
||||
{
|
||||
const UInt32 fixedPrice = TryFixedBlock(tableIndex);
|
||||
t.StaticMode = (fixedPrice < price);
|
||||
if (t.StaticMode)
|
||||
price = fixedPrice;
|
||||
}
|
||||
|
||||
const UInt32 storePrice = GetStorePrice(BlockSizeRes, 0); // bitPosition
|
||||
t.StoreMode = (storePrice <= price);
|
||||
if (t.StoreMode)
|
||||
price = storePrice;
|
||||
|
||||
t.UseSubBlocks = false;
|
||||
|
||||
if (numDivPasses > 1 && numValues >= kDivideCodeBlockSizeMin)
|
||||
{
|
||||
CTables &t0 = m_Tables[(tableIndex << 1)];
|
||||
(CLevels &)t0 = t;
|
||||
t0.BlockSizeRes = t.BlockSizeRes >> 1;
|
||||
t0.m_Pos = t.m_Pos;
|
||||
UInt32 subPrice = GetBlockPrice((tableIndex << 1), numDivPasses - 1);
|
||||
|
||||
UInt32 blockSize2 = t.BlockSizeRes - t0.BlockSizeRes;
|
||||
if (t0.BlockSizeRes >= kDivideBlockSizeMin && blockSize2 >= kDivideBlockSizeMin)
|
||||
{
|
||||
CTables &t1 = m_Tables[(tableIndex << 1) + 1];
|
||||
(CLevels &)t1 = t;
|
||||
t1.BlockSizeRes = blockSize2;
|
||||
t1.m_Pos = m_Pos;
|
||||
m_AdditionalOffset -= t0.BlockSizeRes;
|
||||
subPrice += GetBlockPrice((tableIndex << 1) + 1, numDivPasses - 1);
|
||||
t.UseSubBlocks = (subPrice < price);
|
||||
if (t.UseSubBlocks)
|
||||
price = subPrice;
|
||||
}
|
||||
}
|
||||
m_AdditionalOffset = additionalOffsetEnd;
|
||||
m_Pos = posTemp;
|
||||
return price;
|
||||
}
|
||||
|
||||
void CCoder::CodeBlock(int tableIndex, bool finalBlock)
|
||||
{
|
||||
CTables &t = m_Tables[tableIndex];
|
||||
if (t.UseSubBlocks)
|
||||
{
|
||||
CodeBlock((tableIndex << 1), false);
|
||||
CodeBlock((tableIndex << 1) + 1, finalBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (t.StoreMode)
|
||||
WriteStoreBlock(t.BlockSizeRes, m_AdditionalOffset, finalBlock);
|
||||
else
|
||||
{
|
||||
m_OutStream.WriteBits((finalBlock ? NFinalBlockField::kFinalBlock: NFinalBlockField::kNotFinalBlock), kFinalBlockFieldSize);
|
||||
if (t.StaticMode)
|
||||
{
|
||||
m_OutStream.WriteBits(NBlockType::kFixedHuffman, kBlockTypeFieldSize);
|
||||
TryFixedBlock(tableIndex);
|
||||
int i;
|
||||
for (i = 0; i < kFixedMainTableSize; i++)
|
||||
mainFreqs[i] = (UInt32)1 << (kNumHuffmanBits - m_NewLevels.litLenLevels[i]);
|
||||
for (i = 0; i < kFixedDistTableSize; i++)
|
||||
distFreqs[i] = (UInt32)1 << (kNumHuffmanBits - m_NewLevels.distLevels[i]);
|
||||
MakeTables();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_NumDivPasses > 1 || m_CheckStatic)
|
||||
TryDynBlock(tableIndex, 1);
|
||||
m_OutStream.WriteBits(NBlockType::kDynamicHuffman, kBlockTypeFieldSize);
|
||||
m_OutStream.WriteBits(m_NumLitLenLevels - kNumLitLenCodesMin, kNumLenCodesFieldSize);
|
||||
m_OutStream.WriteBits(m_NumDistLevels - kNumDistCodesMin, kNumDistCodesFieldSize);
|
||||
m_OutStream.WriteBits(m_NumLevelCodes - kNumLevelCodesMin, kNumLevelCodesFieldSize);
|
||||
|
||||
for (UInt32 i = 0; i < m_NumLevelCodes; i++)
|
||||
m_OutStream.WriteBits(m_LevelLevels[i], kLevelFieldSize);
|
||||
|
||||
Huffman_ReverseBits(levelCodes, levelLens, kLevelTableSize);
|
||||
LevelTableCode(m_NewLevels.litLenLevels, m_NumLitLenLevels, levelLens, levelCodes);
|
||||
LevelTableCode(m_NewLevels.distLevels, m_NumDistLevels, levelLens, levelCodes);
|
||||
}
|
||||
WriteBlock();
|
||||
}
|
||||
m_AdditionalOffset -= t.BlockSizeRes;
|
||||
}
|
||||
}
|
||||
|
||||
HRes Read(void *object, void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
return (HRes)((CSeqInStream *)object)->RealStream->Read(data, size, processedSize);
|
||||
}
|
||||
|
||||
HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 * /* inSize */ , const UInt64 * /* outSize */ ,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
m_CheckStatic = (m_NumPasses != 1 || m_NumDivPasses != 1);
|
||||
m_IsMultiPass = (m_CheckStatic || (m_NumPasses != 1 || m_NumDivPasses != 1));
|
||||
|
||||
RINOK(Create());
|
||||
|
||||
m_ValueBlockSize = (1 << 13) + (1 << 12) * m_NumDivPasses;
|
||||
|
||||
UInt64 nowPos = 0;
|
||||
|
||||
_seqInStream.RealStream = inStream;
|
||||
_seqInStream.SeqInStream.Read = Read;
|
||||
_lzInWindow.stream = &_seqInStream.SeqInStream;
|
||||
|
||||
MatchFinder_Init(&_lzInWindow);
|
||||
m_OutStream.SetStream(outStream);
|
||||
m_OutStream.Init();
|
||||
|
||||
CCoderReleaser coderReleaser(this);
|
||||
|
||||
m_OptimumEndIndex = m_OptimumCurrentIndex = 0;
|
||||
|
||||
CTables &t = m_Tables[1];
|
||||
t.m_Pos = 0;
|
||||
t.InitStructures();
|
||||
|
||||
m_AdditionalOffset = 0;
|
||||
do
|
||||
{
|
||||
t.BlockSizeRes = kBlockUncompressedSizeThreshold;
|
||||
m_SecondPass = false;
|
||||
GetBlockPrice(1, m_NumDivPasses);
|
||||
CodeBlock(1, Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) == 0);
|
||||
nowPos += m_Tables[1].BlockSizeRes;
|
||||
if (progress != NULL)
|
||||
{
|
||||
UInt64 packSize = m_OutStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&nowPos, &packSize));
|
||||
}
|
||||
}
|
||||
while (Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) != 0);
|
||||
if (_lzInWindow.result != SZ_OK)
|
||||
return _lzInWindow.result;
|
||||
return m_OutStream.Flush();
|
||||
}
|
||||
|
||||
HRESULT CCoder::BaseCode(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
catch(const COutBufferException &e) { return e.ErrorCode; }
|
||||
catch(...) { return E_FAIL; }
|
||||
}
|
||||
|
||||
STDMETHODIMP CCOMCoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{ return BaseCode(inStream, outStream, inSize, outSize, progress); }
|
||||
|
||||
STDMETHODIMP CCOMCoder::SetCoderProperties(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UInt32 numProperties)
|
||||
{ return BaseSetEncoderProperties2(propIDs, properties, numProperties); }
|
||||
|
||||
STDMETHODIMP CCOMCoder64::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{ return BaseCode(inStream, outStream, inSize, outSize, progress); }
|
||||
|
||||
STDMETHODIMP CCOMCoder64::SetCoderProperties(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UInt32 numProperties)
|
||||
{ return BaseSetEncoderProperties2(propIDs, properties, numProperties); }
|
||||
|
||||
}}}
|
||||
|
||||
221
CPP/7zip/Compress/Deflate/DeflateEncoder.h
Executable file
221
CPP/7zip/Compress/Deflate/DeflateEncoder.h
Executable file
@@ -0,0 +1,221 @@
|
||||
// DeflateEncoder.h
|
||||
|
||||
#ifndef __DEFLATE_ENCODER_H
|
||||
#define __DEFLATE_ENCODER_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/LSBFEncoder.h"
|
||||
|
||||
#include "DeflateConst.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/Compress/Lz/MatchFinder.h"
|
||||
}
|
||||
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
namespace NEncoder {
|
||||
|
||||
struct CCodeValue
|
||||
{
|
||||
UInt16 Len;
|
||||
UInt16 Pos;
|
||||
void SetAsLiteral() { Len = (1 << 15); }
|
||||
bool IsLiteral() const { return ((Len & (1 << 15)) != 0); }
|
||||
};
|
||||
|
||||
struct COptimal
|
||||
{
|
||||
UInt32 Price;
|
||||
UInt16 PosPrev;
|
||||
UInt16 BackPrev;
|
||||
};
|
||||
|
||||
const UInt32 kNumOptsBase = 1 << 12;
|
||||
const UInt32 kNumOpts = kNumOptsBase + kMatchMaxLen;
|
||||
|
||||
class CCoder;
|
||||
|
||||
struct CTables: public CLevels
|
||||
{
|
||||
bool UseSubBlocks;
|
||||
bool StoreMode;
|
||||
bool StaticMode;
|
||||
UInt32 BlockSizeRes;
|
||||
UInt32 m_Pos;
|
||||
void InitStructures();
|
||||
};
|
||||
|
||||
typedef struct _CSeqInStream
|
||||
{
|
||||
ISeqInStream SeqInStream;
|
||||
CMyComPtr<ISequentialInStream> RealStream;
|
||||
} CSeqInStream;
|
||||
|
||||
class CCoder
|
||||
{
|
||||
CMatchFinder _lzInWindow;
|
||||
NStream::NLSBF::CEncoder m_OutStream;
|
||||
|
||||
CSeqInStream _seqInStream;
|
||||
|
||||
public:
|
||||
CCodeValue *m_Values;
|
||||
|
||||
UInt16 *m_MatchDistances;
|
||||
UInt32 m_NumFastBytes;
|
||||
|
||||
UInt16 *m_OnePosMatchesMemory;
|
||||
UInt16 *m_DistanceMemory;
|
||||
|
||||
UInt32 m_Pos;
|
||||
|
||||
int m_NumPasses;
|
||||
int m_NumDivPasses;
|
||||
bool m_CheckStatic;
|
||||
bool m_IsMultiPass;
|
||||
UInt32 m_ValueBlockSize;
|
||||
|
||||
UInt32 m_NumLenCombinations;
|
||||
UInt32 m_MatchMaxLen;
|
||||
const Byte *m_LenStart;
|
||||
const Byte *m_LenDirectBits;
|
||||
|
||||
bool m_Created;
|
||||
bool m_Deflate64Mode;
|
||||
|
||||
Byte m_LevelLevels[kLevelTableSize];
|
||||
int m_NumLitLenLevels;
|
||||
int m_NumDistLevels;
|
||||
UInt32 m_NumLevelCodes;
|
||||
UInt32 m_ValueIndex;
|
||||
|
||||
bool m_SecondPass;
|
||||
UInt32 m_AdditionalOffset;
|
||||
|
||||
UInt32 m_OptimumEndIndex;
|
||||
UInt32 m_OptimumCurrentIndex;
|
||||
|
||||
Byte m_LiteralPrices[256];
|
||||
Byte m_LenPrices[kNumLenSymbolsMax];
|
||||
Byte m_PosPrices[kDistTableSize64];
|
||||
|
||||
CLevels m_NewLevels;
|
||||
UInt32 mainFreqs[kFixedMainTableSize];
|
||||
UInt32 distFreqs[kDistTableSize64];
|
||||
UInt32 mainCodes[kFixedMainTableSize];
|
||||
UInt32 distCodes[kDistTableSize64];
|
||||
UInt32 levelCodes[kLevelTableSize];
|
||||
Byte levelLens[kLevelTableSize];
|
||||
|
||||
UInt32 BlockSizeRes;
|
||||
|
||||
CTables *m_Tables;
|
||||
COptimal m_Optimum[kNumOpts];
|
||||
|
||||
UInt32 m_MatchFinderCycles;
|
||||
// IMatchFinderSetNumPasses *m_SetMfPasses;
|
||||
|
||||
void GetMatches();
|
||||
void MovePos(UInt32 num);
|
||||
UInt32 Backward(UInt32 &backRes, UInt32 cur);
|
||||
UInt32 GetOptimal(UInt32 &backRes);
|
||||
|
||||
void LevelTableDummy(const Byte *levels, int numLevels, UInt32 *freqs);
|
||||
void LevelTableCode(const Byte *levels, int numLevels, const Byte *lens, const UInt32 *codes);
|
||||
|
||||
void MakeTables();
|
||||
UInt32 GetLzBlockPrice() const;
|
||||
void TryBlock();
|
||||
UInt32 TryDynBlock(int tableIndex, UInt32 numPasses);
|
||||
|
||||
UInt32 TryFixedBlock(int tableIndex);
|
||||
|
||||
void SetPrices(const CLevels &levels);
|
||||
void WriteBlock();
|
||||
|
||||
HRESULT Create();
|
||||
void Free();
|
||||
|
||||
void WriteStoreBlock(UInt32 blockSize, UInt32 additionalOffset, bool finalBlock);
|
||||
void WriteTables(bool writeMode, bool finalBlock);
|
||||
|
||||
void WriteBlockData(bool writeMode, bool finalBlock);
|
||||
|
||||
void ReleaseStreams()
|
||||
{
|
||||
_seqInStream.RealStream.Release();
|
||||
m_OutStream.ReleaseStream();
|
||||
}
|
||||
class CCoderReleaser
|
||||
{
|
||||
CCoder *m_Coder;
|
||||
public:
|
||||
CCoderReleaser(CCoder *coder): m_Coder(coder) {}
|
||||
~CCoderReleaser() { m_Coder->ReleaseStreams(); }
|
||||
};
|
||||
friend class CCoderReleaser;
|
||||
|
||||
UInt32 GetBlockPrice(int tableIndex, int numDivPasses);
|
||||
void CodeBlock(int tableIndex, bool finalBlock);
|
||||
|
||||
public:
|
||||
CCoder(bool deflate64Mode = false);
|
||||
~CCoder();
|
||||
|
||||
HRESULT CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
HRESULT BaseCode(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
// ICompressSetCoderProperties
|
||||
HRESULT BaseSetEncoderProperties2(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UInt32 numProperties);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
class CCOMCoder :
|
||||
public ICompressCoder,
|
||||
public ICompressSetCoderProperties,
|
||||
public CMyUnknownImp,
|
||||
public CCoder
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
|
||||
CCOMCoder(): CCoder(false) {};
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
// ICompressSetCoderProperties
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UInt32 numProperties);
|
||||
};
|
||||
|
||||
class CCOMCoder64 :
|
||||
public ICompressCoder,
|
||||
public ICompressSetCoderProperties,
|
||||
public CMyUnknownImp,
|
||||
public CCoder
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
|
||||
CCOMCoder64(): CCoder(true) {};
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
// ICompressSetCoderProperties
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UInt32 numProperties);
|
||||
};
|
||||
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
157
CPP/7zip/Compress/Deflate/DllExports.cpp
Executable file
157
CPP/7zip/Compress/Deflate/DllExports.cpp
Executable file
@@ -0,0 +1,157 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
#include "DeflateEncoder.h"
|
||||
#include "DeflateDecoder.h"
|
||||
|
||||
#ifdef CRC_GENERATE_TABLE
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/7zCrc.h"
|
||||
}
|
||||
#endif
|
||||
|
||||
// {23170F69-40C1-278B-0401-080000000000}
|
||||
DEFINE_GUID(CLSID_CCompressDeflateDecoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-0401-090000000000}
|
||||
DEFINE_GUID(CLSID_CCompressDeflate64Decoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-0401-080000000100}
|
||||
DEFINE_GUID(CLSID_CCompressDeflateEncoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-0401-090000000100}
|
||||
DEFINE_GUID(CLSID_CCompressDeflate64Encoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00);
|
||||
|
||||
|
||||
// {23170F69-40C1-278B-0409-010000000000}
|
||||
DEFINE_GUID(CLSID_CCompressDeflateNsisDecoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
{
|
||||
if (dwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
#ifdef CRC_GENERATE_TABLE
|
||||
CrcGenerateTable();
|
||||
#endif
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*outObject = 0;
|
||||
int correctInterface = (*iid == IID_ICompressCoder);
|
||||
CMyComPtr<ICompressCoder> coder;
|
||||
if (*clsid == CLSID_CCompressDeflateDecoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new NCompress::NDeflate::NDecoder::CCOMCoder();
|
||||
}
|
||||
else if (*clsid == CLSID_CCompressDeflateNsisDecoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new NCompress::NDeflate::NDecoder::CNsisCOMCoder();
|
||||
}
|
||||
else if (*clsid == CLSID_CCompressDeflateEncoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new NCompress::NDeflate::NEncoder::CCOMCoder();
|
||||
}
|
||||
else if (*clsid == CLSID_CCompressDeflate64Decoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new NCompress::NDeflate::NDecoder::CCOMCoder64();
|
||||
}
|
||||
else if (*clsid == CLSID_CCompressDeflate64Encoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new NCompress::NDeflate::NEncoder::CCOMCoder64();
|
||||
}
|
||||
else
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
*outObject = coder.Detach();
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
struct CDeflateMethodItem
|
||||
{
|
||||
char ID[3];
|
||||
const wchar_t *UserName;
|
||||
const GUID *Decoder;
|
||||
const GUID *Encoder;
|
||||
};
|
||||
|
||||
#define METHOD_ITEM(Name, id, UserName) \
|
||||
{ { 0x04, 0x01, id }, UserName, \
|
||||
&CLSID_CCompress ## Name ## Decoder, \
|
||||
&CLSID_CCompress ## Name ## Encoder }
|
||||
|
||||
#define METHOD_ITEM_DE(Name, id1, id2, UserName) \
|
||||
{ { 0x04, id1, id2 }, UserName, \
|
||||
&CLSID_CCompress ## Name ## Decoder, NULL }
|
||||
|
||||
|
||||
static CDeflateMethodItem g_Methods[] =
|
||||
{
|
||||
METHOD_ITEM(Deflate, 0x08, L"Deflate"),
|
||||
METHOD_ITEM(Deflate64, 0x09, L"Deflate64"),
|
||||
METHOD_ITEM_DE(DeflateNsis, 0x09, 0x01, L"DeflateNSIS")
|
||||
};
|
||||
|
||||
STDAPI GetNumberOfMethods(UINT32 *numMethods)
|
||||
{
|
||||
*numMethods = sizeof(g_Methods) / sizeof(g_Methods[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
if (index > sizeof(g_Methods) / sizeof(g_Methods[0]))
|
||||
return E_INVALIDARG;
|
||||
VariantClear((tagVARIANT *)value);
|
||||
const CDeflateMethodItem &method = g_Methods[index];
|
||||
switch(propID)
|
||||
{
|
||||
case NMethodPropID::kID:
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(method.ID,
|
||||
sizeof(method.ID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
case NMethodPropID::kName:
|
||||
if ((value->bstrVal = ::SysAllocString(method.UserName)) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
case NMethodPropID::kDecoder:
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)method.Decoder, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
case NMethodPropID::kEncoder:
|
||||
if (method.Encoder)
|
||||
{
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)method.Encoder, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
3
CPP/7zip/Compress/Deflate/StdAfx.cpp
Executable file
3
CPP/7zip/Compress/Deflate/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
8
CPP/7zip/Compress/Deflate/StdAfx.h
Executable file
8
CPP/7zip/Compress/Deflate/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
63
CPP/7zip/Compress/Deflate/makefile
Executable file
63
CPP/7zip/Compress/Deflate/makefile
Executable file
@@ -0,0 +1,63 @@
|
||||
PROG = Deflate.dll
|
||||
DEF_FILE = ../Codec.def
|
||||
CFLAGS = $(CFLAGS) -I ../../../ -D_ST_MODE
|
||||
LIBS = $(LIBS) oleaut32.lib
|
||||
|
||||
DEFLATE_OBJS = \
|
||||
$O\DllExports.obj \
|
||||
|
||||
DEFLATE_OPT_OBJS = \
|
||||
$O\DeflateDecoder.obj \
|
||||
$O\DeflateEncoder.obj \
|
||||
|
||||
COMMON_OBJS = \
|
||||
$O\Alloc.obj \
|
||||
$O\CRC.obj \
|
||||
|
||||
7ZIP_COMMON_OBJS = \
|
||||
$O\InBuffer.obj \
|
||||
$O\OutBuffer.obj \
|
||||
$O\LSBFDecoder.obj \
|
||||
$O\LSBFEncoder.obj \
|
||||
|
||||
LZ_OBJS = \
|
||||
$O\LZOutWindow.obj \
|
||||
|
||||
C_OBJS = \
|
||||
$O\7zCrc.obj \
|
||||
$O\Sort.obj \
|
||||
|
||||
C_LZ_OBJS = \
|
||||
$O\MatchFinder.obj \
|
||||
|
||||
|
||||
OBJS = \
|
||||
$O\StdAfx.obj \
|
||||
$(DEFLATE_OBJS) \
|
||||
$(DEFLATE_OPT_OBJS) \
|
||||
$(COMMON_OBJS) \
|
||||
$(7ZIP_COMMON_OBJS) \
|
||||
$(LZ_OBJS) \
|
||||
$(C_OBJS) \
|
||||
$(C_LZ_OBJS) \
|
||||
$O\HuffmanEncode.obj \
|
||||
$O\resource.res
|
||||
|
||||
!include "../../../Build.mak"
|
||||
|
||||
$(DEFLATE_OBJS): $(*B).cpp
|
||||
$(COMPL)
|
||||
$(DEFLATE_OPT_OBJS): $(*B).cpp
|
||||
$(COMPL_O2)
|
||||
$(COMMON_OBJS): ../../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(LZ_OBJS): ../LZ/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(C_OBJS): ../../../../C/$(*B).c
|
||||
$(COMPL_O2)
|
||||
$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c
|
||||
$(COMPL_O2)
|
||||
$O\HuffmanEncode.obj: ../../../../C/Compress/Huffman/$(*B).c
|
||||
$(COMPL_O2)
|
||||
3
CPP/7zip/Compress/Deflate/resource.rc
Executable file
3
CPP/7zip/Compress/Deflate/resource.rc
Executable file
@@ -0,0 +1,3 @@
|
||||
#include "../../MyVersionInfo.rc"
|
||||
|
||||
MY_VERSION_INFO_DLL("Deflate Codec", "Deflate")
|
||||
Reference in New Issue
Block a user