mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-10 22:07:08 -06:00
3.13
This commit is contained in:
8
7zip/Compress/Deflate/Deflate.def
Executable file
8
7zip/Compress/Deflate/Deflate.def
Executable file
@@ -0,0 +1,8 @@
|
||||
; Deflate.def
|
||||
|
||||
LIBRARY Deflate.dll
|
||||
|
||||
EXPORTS
|
||||
CreateObject PRIVATE
|
||||
GetNumberOfMethods PRIVATE
|
||||
GetMethodProperty PRIVATE
|
||||
275
7zip/Compress/Deflate/Deflate.dsp
Executable file
275
7zip/Compress/Deflate/Deflate.dsp
Executable file
@@ -0,0 +1,275 @@
|
||||
# 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" /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" /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=.\Deflate.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DllExports.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.h
|
||||
# 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
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Huffman\HuffmanEncoder.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=..\Huffman\HuffmanEncoder.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\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\LZInWindow.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\LZInWindow.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\LZOutWindow.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\LZOutWindow.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
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DeflateExtConst.h
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
29
7zip/Compress/Deflate/Deflate.dsw
Executable file
29
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>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
106
7zip/Compress/Deflate/DeflateConst.h
Executable file
106
7zip/Compress/Deflate/DeflateConst.h
Executable file
@@ -0,0 +1,106 @@
|
||||
// DeflateConst.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DEFLATE_CONST_H
|
||||
#define __DEFLATE_CONST_H
|
||||
|
||||
#include "DeflateExtConst.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
|
||||
const UINT32 kLenTableSize = 29;
|
||||
|
||||
const UINT32 kStaticDistTableSize = 32;
|
||||
const UINT32 kStaticLenTableSize = 31;
|
||||
|
||||
const UINT32 kReadTableNumber = 0x100;
|
||||
const UINT32 kMatchNumber = kReadTableNumber + 1;
|
||||
|
||||
const UINT32 kMainTableSize = kMatchNumber + kLenTableSize; //298;
|
||||
const UINT32 kStaticMainTableSize = kMatchNumber + kStaticLenTableSize; //298;
|
||||
|
||||
const UINT32 kDistTableStart = kMainTableSize;
|
||||
|
||||
const UINT32 kHeapTablesSizesSum32 = kMainTableSize + kDistTableSize32;
|
||||
const UINT32 kHeapTablesSizesSum64 = kMainTableSize + kDistTableSize64;
|
||||
|
||||
const UINT32 kLevelTableSize = 19;
|
||||
|
||||
const UINT32 kMaxTableSize32 = kHeapTablesSizesSum32; // test it
|
||||
const UINT32 kMaxTableSize64 = kHeapTablesSizesSum64; // test it
|
||||
|
||||
const UINT32 kStaticMaxTableSize = kStaticMainTableSize + kStaticDistTableSize;
|
||||
|
||||
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[kLenTableSize] =
|
||||
{0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 255};
|
||||
const BYTE kLenStart64[kLenTableSize] =
|
||||
{0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 0};
|
||||
|
||||
const BYTE kLenDirectBits32[kLenTableSize] =
|
||||
{0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
|
||||
const BYTE kLenDirectBits64[kLenTableSize] =
|
||||
{0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 16};
|
||||
|
||||
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[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 = kNumLenCombinations32 + kMatchMinLen - 1; //256 + 2; test it
|
||||
const UINT32 kMatchMaxLen64 = kNumLenCombinations64 + kMatchMinLen - 1; //255 + 2; test it
|
||||
|
||||
const int kFinalBlockFieldSize = 1;
|
||||
|
||||
namespace NFinalBlockField
|
||||
{
|
||||
enum
|
||||
{
|
||||
kNotFinalBlock = 0,
|
||||
kFinalBlock = 1
|
||||
};
|
||||
}
|
||||
|
||||
const int kBlockTypeFieldSize = 2;
|
||||
|
||||
namespace NBlockType
|
||||
{
|
||||
enum
|
||||
{
|
||||
kStored = 0,
|
||||
kFixedHuffman = 1,
|
||||
kDynamicHuffman = 2,
|
||||
kReserved = 3
|
||||
};
|
||||
}
|
||||
|
||||
const UINT32 kDeflateNumberOfLengthCodesFieldSize = 5;
|
||||
const UINT32 kDeflateNumberOfDistanceCodesFieldSize = 5;
|
||||
const UINT32 kDeflateNumberOfLevelCodesFieldSize = 4;
|
||||
|
||||
const UINT32 kDeflateNumberOfLitLenCodesMin = 257;
|
||||
|
||||
const UINT32 kDeflateNumberOfDistanceCodesMin = 1;
|
||||
const UINT32 kDeflateNumberOfLevelCodesMin = 4;
|
||||
|
||||
const UINT32 kDeflateLevelCodeFieldSize = 3;
|
||||
|
||||
const UINT32 kDeflateStoredBlockLengthFieldSizeSize = 16;
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
291
7zip/Compress/Deflate/DeflateDecoder.cpp
Executable file
291
7zip/Compress/Deflate/DeflateDecoder.cpp
Executable file
@@ -0,0 +1,291 @@
|
||||
// DeflateDecoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "DeflateDecoder.h"
|
||||
#include "DeflateConst.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
namespace NDecoder {
|
||||
|
||||
CCoder::CCoder(bool deflate64Mode):
|
||||
m_MainDecoder(kStaticMainTableSize),
|
||||
m_DistDecoder(kStaticDistTableSize),
|
||||
m_LevelDecoder(kLevelTableSize),
|
||||
_deflate64Mode(deflate64Mode)
|
||||
{}
|
||||
|
||||
void CCoder::DeCodeLevelTable(BYTE *newLevels, int numLevels)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < numLevels)
|
||||
{
|
||||
UINT32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number < kTableDirectLevels)
|
||||
newLevels[i++] = BYTE(number);
|
||||
else
|
||||
{
|
||||
if (number == kTableLevelRepNumber)
|
||||
{
|
||||
int t = m_InBitStream.ReadBits(2) + 3;
|
||||
for (int reps = t; reps > 0 && i < numLevels ; reps--, i++)
|
||||
newLevels[i] = newLevels[i - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
int num;
|
||||
if (number == kTableLevel0Number)
|
||||
num = m_InBitStream.ReadBits(3) + 3;
|
||||
else
|
||||
num = m_InBitStream.ReadBits(7) + 11;
|
||||
for (;num > 0 && i < numLevels; num--)
|
||||
newLevels[i++] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCoder::ReadTables(void)
|
||||
{
|
||||
if(m_FinalBlock) // test it
|
||||
throw CException(CException::kData);
|
||||
|
||||
m_FinalBlock = (m_InBitStream.ReadBits(kFinalBlockFieldSize) == NFinalBlockField::kFinalBlock);
|
||||
|
||||
int blockType = m_InBitStream.ReadBits(kBlockTypeFieldSize);
|
||||
|
||||
switch(blockType)
|
||||
{
|
||||
case NBlockType::kStored:
|
||||
{
|
||||
m_StoredMode = true;
|
||||
UINT32 currentBitPosition = m_InBitStream.GetBitPosition();
|
||||
UINT32 numBitsForAlign = currentBitPosition > 0 ? (8 - currentBitPosition): 0;
|
||||
if (numBitsForAlign > 0)
|
||||
m_InBitStream.ReadBits(numBitsForAlign);
|
||||
m_StoredBlockSize = m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize);
|
||||
WORD onesComplementReverse = ~WORD(m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize));
|
||||
if (m_StoredBlockSize != onesComplementReverse)
|
||||
throw CException(CException::kData);
|
||||
break;
|
||||
}
|
||||
case NBlockType::kFixedHuffman:
|
||||
case NBlockType::kDynamicHuffman:
|
||||
{
|
||||
m_StoredMode = false;
|
||||
BYTE litLenLevels[kStaticMainTableSize];
|
||||
BYTE distLevels[kStaticDistTableSize];
|
||||
if (blockType == NBlockType::kFixedHuffman)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Leteral / length levels
|
||||
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++) /* make a complete, but wrong code set */
|
||||
litLenLevels[i] = 8;
|
||||
|
||||
// Distance levels
|
||||
for (i = 0; i < kStaticDistTableSize; i++) // test it: infozip only use kDistTableSize
|
||||
distLevels[i] = 5;
|
||||
}
|
||||
else // in case when (blockType == kDeflateBlockTypeFixedHuffman)
|
||||
{
|
||||
int numLitLenLevels = m_InBitStream.ReadBits(kDeflateNumberOfLengthCodesFieldSize) +
|
||||
kDeflateNumberOfLitLenCodesMin;
|
||||
int numDistLevels = m_InBitStream.ReadBits(kDeflateNumberOfDistanceCodesFieldSize) +
|
||||
kDeflateNumberOfDistanceCodesMin;
|
||||
int numLevelCodes = m_InBitStream.ReadBits(kDeflateNumberOfLevelCodesFieldSize) +
|
||||
kDeflateNumberOfLevelCodesMin;
|
||||
|
||||
int numLevels = _deflate64Mode ? kHeapTablesSizesSum64 :
|
||||
kHeapTablesSizesSum32;
|
||||
|
||||
BYTE levelLevels[kLevelTableSize];
|
||||
int i;
|
||||
for (i = 0; i < kLevelTableSize; i++)
|
||||
{
|
||||
int position = kCodeLengthAlphabetOrder[i];
|
||||
if(i < numLevelCodes)
|
||||
levelLevels[position] = BYTE(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize));
|
||||
else
|
||||
levelLevels[position] = 0;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_LevelDecoder.SetCodeLengths(levelLevels);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
throw CException(CException::kData);
|
||||
}
|
||||
|
||||
BYTE tmpLevels[kStaticMaxTableSize];
|
||||
DeCodeLevelTable(tmpLevels, numLitLenLevels + numDistLevels);
|
||||
|
||||
memmove(litLenLevels, tmpLevels, numLitLenLevels);
|
||||
memset(litLenLevels + numLitLenLevels, 0,
|
||||
kStaticMainTableSize - numLitLenLevels);
|
||||
|
||||
memmove(distLevels, tmpLevels + numLitLenLevels, numDistLevels);
|
||||
memset(distLevels + numDistLevels, 0, kStaticDistTableSize - numDistLevels);
|
||||
}
|
||||
try
|
||||
{
|
||||
m_MainDecoder.SetCodeLengths(litLenLevels);
|
||||
m_DistDecoder.SetCodeLengths(distLevels);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
throw CException(CException::kData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw CException(CException::kData);
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
{
|
||||
try
|
||||
{
|
||||
m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32 /* , kMatchMaxLen */);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
UINT64 pos = 0;
|
||||
m_OutWindowStream.Init(outStream, false);
|
||||
m_InBitStream.Init(inStream);
|
||||
// CCoderReleaser coderReleaser(this);
|
||||
|
||||
m_FinalBlock = false;
|
||||
|
||||
while(!m_FinalBlock)
|
||||
{
|
||||
if (progress != NULL)
|
||||
{
|
||||
UINT64 packSize = m_InBitStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&packSize, &pos));
|
||||
}
|
||||
ReadTables();
|
||||
if(m_StoredMode)
|
||||
{
|
||||
for (UINT32 i = 0; i < m_StoredBlockSize; i++)
|
||||
m_OutWindowStream.PutOneByte(BYTE(m_InBitStream.ReadBits(8)));
|
||||
pos += m_StoredBlockSize;
|
||||
continue;
|
||||
}
|
||||
while(true)
|
||||
{
|
||||
if (m_InBitStream.NumExtraBytes > 4)
|
||||
throw CException(CException::kData);
|
||||
|
||||
UINT32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number < 256)
|
||||
{
|
||||
if (outSize != NULL)
|
||||
if (pos >= *outSize)
|
||||
throw CException(CException::kData);
|
||||
m_OutWindowStream.PutOneByte(BYTE(number));
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
else if (number >= kMatchNumber)
|
||||
{
|
||||
if (outSize != NULL)
|
||||
if (pos >= *outSize)
|
||||
throw CException(CException::kData);
|
||||
number -= kMatchNumber;
|
||||
|
||||
UINT32 length;
|
||||
if (_deflate64Mode)
|
||||
{
|
||||
length = UINT32(kLenStart64[number]) + kMatchMinLen;
|
||||
UINT32 numBits = kLenDirectBits64[number];
|
||||
if (numBits > 0)
|
||||
length += m_InBitStream.ReadBits(numBits);
|
||||
}
|
||||
else
|
||||
{
|
||||
length = UINT32(kLenStart32[number]) + kMatchMinLen;
|
||||
UINT32 numBits = kLenDirectBits32[number];
|
||||
if (numBits > 0)
|
||||
length += m_InBitStream.ReadBits(numBits);
|
||||
}
|
||||
|
||||
|
||||
number = m_DistDecoder.DecodeSymbol(&m_InBitStream);
|
||||
UINT32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]);
|
||||
if (distance >= pos)
|
||||
throw "data error";
|
||||
m_OutWindowStream.CopyBackBlock(distance, length);
|
||||
pos += length;
|
||||
}
|
||||
else if (number == kReadTableNumber)
|
||||
break;
|
||||
else
|
||||
throw CException(CException::kData);
|
||||
}
|
||||
}
|
||||
return m_OutWindowStream.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 CInBufferException &e) { return e.ErrorCode; }
|
||||
catch(const CLZOutWindowException &e) { return e.ErrorCode; }
|
||||
catch(...) { return S_FALSE; }
|
||||
}
|
||||
|
||||
HRESULT CCoder::BaseGetInStreamProcessedSize(UINT64 *value)
|
||||
{
|
||||
if (value == NULL)
|
||||
return E_INVALIDARG;
|
||||
*value = m_InBitStream.GetProcessedSize();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CCOMCoder::GetInStreamProcessedSize(UINT64 *value)
|
||||
{
|
||||
return BaseGetInStreamProcessedSize(value);
|
||||
}
|
||||
|
||||
HRESULT CCOMCoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
return BaseCode(inStream, outStream, inSize, outSize, progress);
|
||||
}
|
||||
|
||||
STDMETHODIMP CCOMCoder64::GetInStreamProcessedSize(UINT64 *value)
|
||||
{
|
||||
return BaseGetInStreamProcessedSize(value);
|
||||
}
|
||||
|
||||
HRESULT CCOMCoder64::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
return BaseCode(inStream, outStream, inSize, outSize, progress);
|
||||
}
|
||||
|
||||
|
||||
}}}
|
||||
128
7zip/Compress/Deflate/DeflateDecoder.h
Executable file
128
7zip/Compress/Deflate/DeflateDecoder.h
Executable file
@@ -0,0 +1,128 @@
|
||||
// DeflateDecoder.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#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 "DeflateExtConst.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
namespace NDecoder {
|
||||
|
||||
class CException
|
||||
{
|
||||
public:
|
||||
enum ECauseType
|
||||
{
|
||||
kData
|
||||
} m_Cause;
|
||||
CException(ECauseType aCause): m_Cause(aCause) {}
|
||||
};
|
||||
|
||||
typedef NStream::NLSBF::CDecoder<CInBuffer> CInBit;
|
||||
typedef NCompress::NHuffman::CDecoder<kNumHuffmanBits> CHuffmanDecoder;
|
||||
|
||||
class CCoder
|
||||
{
|
||||
CLZOutWindow m_OutWindowStream;
|
||||
CInBit m_InBitStream;
|
||||
CHuffmanDecoder m_MainDecoder;
|
||||
CHuffmanDecoder m_DistDecoder;
|
||||
CHuffmanDecoder m_LevelDecoder; // table for decoding other tables;
|
||||
|
||||
bool m_FinalBlock;
|
||||
bool m_StoredMode;
|
||||
UINT32 m_StoredBlockSize;
|
||||
|
||||
bool _deflate64Mode;
|
||||
|
||||
void DeCodeLevelTable(BYTE *newLevels, int numLevels);
|
||||
void ReadTables();
|
||||
|
||||
/*
|
||||
void CCoder::ReleaseStreams()
|
||||
{
|
||||
m_OutWindowStream.ReleaseStream();
|
||||
m_InBitStream.ReleaseStream();
|
||||
}
|
||||
class CCoderReleaser
|
||||
{
|
||||
CCoder *m_Coder;
|
||||
public:
|
||||
CCoderReleaser(CCoder *coder): m_Coder(coder) {}
|
||||
~CCoderReleaser()
|
||||
{
|
||||
m_Coder->m_OutWindowStream.Flush();
|
||||
m_Coder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
friend class CCoderReleaser;
|
||||
*/
|
||||
|
||||
public:
|
||||
CCoder(bool deflate64Mode = false);
|
||||
|
||||
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);
|
||||
|
||||
// IGetInStreamProcessedSize
|
||||
HRESULT BaseGetInStreamProcessedSize(UINT64 *aValue);
|
||||
};
|
||||
|
||||
class CCOMCoder :
|
||||
public ICompressCoder,
|
||||
public ICompressGetInStreamProcessedSize,
|
||||
public CMyUnknownImp,
|
||||
public CCoder
|
||||
{
|
||||
public:
|
||||
|
||||
MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
// IGetInStreamProcessedSize
|
||||
STDMETHOD(GetInStreamProcessedSize)(UINT64 *aValue);
|
||||
|
||||
CCOMCoder(): CCoder(false) {}
|
||||
};
|
||||
|
||||
class CCOMCoder64 :
|
||||
public ICompressCoder,
|
||||
public ICompressGetInStreamProcessedSize,
|
||||
public CMyUnknownImp,
|
||||
public CCoder
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
// IGetInStreamProcessedSize
|
||||
STDMETHOD(GetInStreamProcessedSize)(UINT64 *aValue);
|
||||
|
||||
CCOMCoder64(): CCoder(true) {}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
785
7zip/Compress/Deflate/DeflateEncoder.cpp
Executable file
785
7zip/Compress/Deflate/DeflateEncoder.cpp
Executable file
@@ -0,0 +1,785 @@
|
||||
// DeflateEncoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "DeflateEncoder.h"
|
||||
#include "DeflateConst.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "Common/ComTry.h"
|
||||
#include "../LZ/BinTree/BinTree3ZMain.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
namespace NEncoder {
|
||||
|
||||
class CMatchFinderException
|
||||
{
|
||||
public:
|
||||
HRESULT m_Result;
|
||||
CMatchFinderException(HRESULT result): m_Result (result) {}
|
||||
};
|
||||
|
||||
static const int kValueBlockSize = 0x2000;
|
||||
|
||||
static const int kMaxCodeBitLength = 15;
|
||||
static const int kMaxLevelBitLength = 7;
|
||||
|
||||
static const BYTE kFlagImm = 0;
|
||||
static const BYTE kFlagLenPos = 4;
|
||||
|
||||
static const UINT32 kMaxUncompressedBlockSize = 0xFFFF; // test it !!!
|
||||
|
||||
static const UINT32 kBlockUncompressedSizeThreshold =
|
||||
kMaxUncompressedBlockSize - kMatchMaxLen32 - kNumOpts;
|
||||
|
||||
static const int kNumGoodBacks = 0x10000;
|
||||
|
||||
static BYTE kNoLiteralDummy = 13;
|
||||
static BYTE kNoLenDummy = 13;
|
||||
static BYTE kNoPosDummy = 6;
|
||||
|
||||
static BYTE g_LenSlots[kNumLenCombinations32];
|
||||
static BYTE g_FastPos[1 << 9];
|
||||
|
||||
class CFastPosInit
|
||||
{
|
||||
public:
|
||||
CFastPosInit()
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < kLenTableSize; i++)
|
||||
{
|
||||
int c = kLenStart32[i];
|
||||
int j = 1 << kLenDirectBits32[i];
|
||||
for(int k = 0; k < j; k++, c++)
|
||||
g_LenSlots[c] = 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)
|
||||
{
|
||||
// for (UINT32 i = 1; pos >= kDistStart[i]; i++);
|
||||
// return i - 1;
|
||||
if (pos < 0x200)
|
||||
return g_FastPos[pos];
|
||||
return g_FastPos[pos >> 8] + 16;
|
||||
}
|
||||
|
||||
CCoder::CCoder(bool deflate64Mode):
|
||||
_deflate64Mode(deflate64Mode),
|
||||
m_MainCoder(kMainTableSize,
|
||||
deflate64Mode ? kLenDirectBits64 : kLenDirectBits32,
|
||||
kMatchNumber, kMaxCodeBitLength),
|
||||
m_DistCoder(deflate64Mode ? kDistTableSize64 : kDistTableSize32, kDistDirectBits, 0, kMaxCodeBitLength),
|
||||
m_LevelCoder(kLevelTableSize, kLevelDirectBits, 0, kMaxLevelBitLength),
|
||||
m_NumPasses(1),
|
||||
m_NumFastBytes(32),
|
||||
m_OnePosMatchesMemory(0),
|
||||
m_OnePosMatchesArray(0),
|
||||
m_MatchDistances(0),
|
||||
m_Created(false),
|
||||
m_Values(0)
|
||||
{
|
||||
m_MatchMaxLen = deflate64Mode ? kMatchMaxLen64 : kMatchMaxLen32;
|
||||
m_NumLenCombinations = deflate64Mode ? kNumLenCombinations64 :
|
||||
kNumLenCombinations32;
|
||||
m_LenStart = deflate64Mode ? kLenStart64 : kLenStart32;
|
||||
m_LenDirectBits = deflate64Mode ? kLenDirectBits64 : kLenDirectBits32;
|
||||
|
||||
m_Values = new CCodeValue[kValueBlockSize + kNumOpts];
|
||||
}
|
||||
|
||||
HRESULT CCoder::Create()
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
m_MatchFinder.Create(
|
||||
_deflate64Mode ? kHistorySize64 : kHistorySize32,
|
||||
kNumOpts + kNumGoodBacks, m_NumFastBytes,
|
||||
m_MatchMaxLen - m_NumFastBytes);
|
||||
m_MatchLengthEdge = m_NumFastBytes + 1;
|
||||
|
||||
if (m_NumPasses > 1)
|
||||
{
|
||||
m_OnePosMatchesMemory = new UINT16[kNumGoodBacks * (m_NumFastBytes + 1)];
|
||||
try
|
||||
{
|
||||
m_OnePosMatchesArray = new COnePosMatches[kNumGoodBacks];
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
delete []m_OnePosMatchesMemory;
|
||||
m_OnePosMatchesMemory = 0;
|
||||
throw;
|
||||
}
|
||||
UINT16 *goodBacksWordsCurrent = m_OnePosMatchesMemory;
|
||||
for(int i = 0; i < kNumGoodBacks; i++, goodBacksWordsCurrent += (m_NumFastBytes + 1))
|
||||
m_OnePosMatchesArray[i].Init(goodBacksWordsCurrent);
|
||||
}
|
||||
else
|
||||
m_MatchDistances = new UINT16[m_NumFastBytes + 1];
|
||||
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 &property = properties[i];
|
||||
switch(propIDs[i])
|
||||
{
|
||||
case NCoderPropID::kNumPasses:
|
||||
if (property.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
m_NumPasses = property.ulVal;
|
||||
if(m_NumPasses == 0 || m_NumPasses > 255)
|
||||
return E_INVALIDARG;
|
||||
break;
|
||||
case NCoderPropID::kNumFastBytes:
|
||||
if (property.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
m_NumFastBytes = property.ulVal;
|
||||
if(m_NumFastBytes < 3 || m_NumFastBytes > m_MatchMaxLen)
|
||||
return E_INVALIDARG;
|
||||
break;
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CCoder::Free()
|
||||
{
|
||||
if(m_NumPasses > 0)
|
||||
{
|
||||
if (m_NumPasses > 1)
|
||||
{
|
||||
delete []m_OnePosMatchesMemory;
|
||||
delete []m_OnePosMatchesArray;
|
||||
}
|
||||
else
|
||||
delete []m_MatchDistances;
|
||||
}
|
||||
}
|
||||
|
||||
CCoder::~CCoder()
|
||||
{
|
||||
Free();
|
||||
delete []m_Values;
|
||||
}
|
||||
|
||||
void CCoder::ReadGoodBacks()
|
||||
{
|
||||
UINT32 goodIndex;
|
||||
if (m_NumPasses > 1)
|
||||
{
|
||||
goodIndex = m_FinderPos % kNumGoodBacks;
|
||||
m_MatchDistances = m_OnePosMatchesArray[goodIndex].MatchDistances;
|
||||
}
|
||||
UINT32 distanceTmp[kMatchMaxLen32 + 1];
|
||||
UINT32 len = m_MatchFinder.GetLongestMatch(distanceTmp);
|
||||
for(UINT32 i = kMatchMinLen; i <= len; i++)
|
||||
m_MatchDistances[i] = distanceTmp[i];
|
||||
|
||||
m_LongestMatchDistance = m_MatchDistances[len];
|
||||
if (len == m_NumFastBytes && m_NumFastBytes != m_MatchMaxLen)
|
||||
m_LongestMatchLength = len + m_MatchFinder.GetMatchLen(len,
|
||||
m_LongestMatchDistance, m_MatchMaxLen - len);
|
||||
else
|
||||
m_LongestMatchLength = len;
|
||||
if (m_NumPasses > 1)
|
||||
{
|
||||
m_OnePosMatchesArray[goodIndex].LongestMatchDistance = UINT16(m_LongestMatchDistance);
|
||||
m_OnePosMatchesArray[goodIndex].LongestMatchLength = UINT16(m_LongestMatchLength);
|
||||
}
|
||||
HRESULT result = m_MatchFinder.MovePos();
|
||||
if (result != S_OK)
|
||||
throw CMatchFinderException(result);
|
||||
m_FinderPos++;
|
||||
m_AdditionalOffset++;
|
||||
}
|
||||
|
||||
void CCoder::GetBacks(UINT32 pos)
|
||||
{
|
||||
if(pos == m_FinderPos)
|
||||
ReadGoodBacks();
|
||||
else
|
||||
{
|
||||
if (m_NumPasses == 1)
|
||||
{
|
||||
if(pos + 1 == m_FinderPos)
|
||||
return;
|
||||
throw 1932;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT32 goodIndex = pos % kNumGoodBacks;
|
||||
m_MatchDistances = m_OnePosMatchesArray[goodIndex].MatchDistances;
|
||||
m_LongestMatchDistance = m_OnePosMatchesArray[goodIndex].LongestMatchDistance;
|
||||
m_LongestMatchLength = m_OnePosMatchesArray[goodIndex].LongestMatchLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CCoder::MovePos(UINT32 num)
|
||||
{
|
||||
if (m_NumPasses > 1)
|
||||
{
|
||||
for(UINT32 i = 0; i < num; i++)
|
||||
GetBacks(UINT32(m_BlockStartPostion + m_CurrentBlockUncompressedSize + i + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (;num > 0; num--)
|
||||
{
|
||||
m_MatchFinder.DummyLongestMatch();
|
||||
HRESULT result = m_MatchFinder.MovePos();
|
||||
if (result != S_OK)
|
||||
throw CMatchFinderException(result);
|
||||
m_FinderPos++;
|
||||
m_AdditionalOffset++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const UINT32 kIfinityPrice = 0xFFFFFFF;
|
||||
|
||||
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 = cur;
|
||||
cur = posPrev;
|
||||
}
|
||||
while(cur > 0);
|
||||
backRes = m_Optimum[0].BackPrev;
|
||||
m_OptimumCurrentIndex = m_Optimum[0].PosPrev;
|
||||
return m_OptimumCurrentIndex;
|
||||
}
|
||||
|
||||
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 = 0;
|
||||
m_OptimumEndIndex = 0;
|
||||
|
||||
GetBacks(UINT32(m_BlockStartPostion + m_CurrentBlockUncompressedSize));
|
||||
|
||||
UINT32 lenMain = m_LongestMatchLength;
|
||||
UINT32 backMain = m_LongestMatchDistance;
|
||||
|
||||
if(lenMain < kMatchMinLen)
|
||||
return 1;
|
||||
if(lenMain >= m_MatchLengthEdge)
|
||||
{
|
||||
backRes = backMain;
|
||||
MovePos(lenMain - 1);
|
||||
return lenMain;
|
||||
}
|
||||
m_Optimum[1].Price = m_LiteralPrices[m_MatchFinder.GetIndexByte(0 - m_AdditionalOffset)];
|
||||
m_Optimum[1].PosPrev = 0;
|
||||
|
||||
m_Optimum[2].Price = kIfinityPrice;
|
||||
m_Optimum[2].PosPrev = 1;
|
||||
|
||||
for(UINT32 i = kMatchMinLen; i <= lenMain; i++)
|
||||
{
|
||||
m_Optimum[i].PosPrev = 0;
|
||||
m_Optimum[i].BackPrev = m_MatchDistances[i];
|
||||
m_Optimum[i].Price = m_LenPrices[i - kMatchMinLen] + m_PosPrices[GetPosSlot(m_MatchDistances[i])];
|
||||
}
|
||||
|
||||
|
||||
UINT32 cur = 0;
|
||||
UINT32 lenEnd = lenMain;
|
||||
while(true)
|
||||
{
|
||||
cur++;
|
||||
if(cur == lenEnd)
|
||||
return Backward(backRes, cur);
|
||||
GetBacks(UINT32(m_BlockStartPostion + m_CurrentBlockUncompressedSize + cur));
|
||||
UINT32 newLen = m_LongestMatchLength;
|
||||
if(newLen >= m_MatchLengthEdge)
|
||||
return Backward(backRes, cur);
|
||||
|
||||
UINT32 curPrice = m_Optimum[cur].Price;
|
||||
UINT32 curAnd1Price = curPrice +
|
||||
m_LiteralPrices[m_MatchFinder.GetIndexByte(cur - m_AdditionalOffset)];
|
||||
COptimal &optimum = m_Optimum[cur + 1];
|
||||
if (curAnd1Price < optimum.Price)
|
||||
{
|
||||
optimum.Price = curAnd1Price;
|
||||
optimum.PosPrev = cur;
|
||||
}
|
||||
if (newLen < kMatchMinLen)
|
||||
continue;
|
||||
if(cur + newLen > lenEnd)
|
||||
{
|
||||
if (cur + newLen > kNumOpts - 1)
|
||||
newLen = kNumOpts - 1 - cur;
|
||||
UINT32 lenEndNew = cur + newLen;
|
||||
if (lenEnd < lenEndNew)
|
||||
{
|
||||
for(UINT32 i = lenEnd + 1; i <= lenEndNew; i++)
|
||||
m_Optimum[i].Price = kIfinityPrice;
|
||||
lenEnd = lenEndNew;
|
||||
}
|
||||
}
|
||||
for(UINT32 lenTest = kMatchMinLen; lenTest <= newLen; lenTest++)
|
||||
{
|
||||
UINT16 curBack = m_MatchDistances[lenTest];
|
||||
UINT32 curAndLenPrice = curPrice +
|
||||
m_LenPrices[lenTest - kMatchMinLen] + m_PosPrices[GetPosSlot(curBack)];
|
||||
COptimal &optimum = m_Optimum[cur + lenTest];
|
||||
if (curAndLenPrice < optimum.Price)
|
||||
{
|
||||
optimum.Price = curAndLenPrice;
|
||||
optimum.PosPrev = cur;
|
||||
optimum.BackPrev = curBack;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CCoder::InitStructures()
|
||||
{
|
||||
memset(m_LastLevels, 0, kMaxTableSize64);
|
||||
|
||||
m_ValueIndex = 0;
|
||||
m_OptimumEndIndex = 0;
|
||||
m_OptimumCurrentIndex = 0;
|
||||
m_AdditionalOffset = 0;
|
||||
|
||||
m_BlockStartPostion = 0;
|
||||
m_CurrentBlockUncompressedSize = 0;
|
||||
|
||||
m_MainCoder.StartNewBlock();
|
||||
m_DistCoder.StartNewBlock();
|
||||
|
||||
UINT32 i;
|
||||
for(i = 0; i < 256; i++)
|
||||
m_LiteralPrices[i] = 8;
|
||||
for(i = 0; i < m_NumLenCombinations; i++)
|
||||
m_LenPrices[i] = 5 + m_LenDirectBits[g_LenSlots[i]]; // test it
|
||||
for(i = 0; i < kDistTableSize64; i++)
|
||||
m_PosPrices[i] = 5 + kDistDirectBits[i];
|
||||
}
|
||||
|
||||
void CCoder::WriteBlockData(bool writeMode, bool finalBlock)
|
||||
{
|
||||
m_MainCoder.AddSymbol(kReadTableNumber);
|
||||
int method = WriteTables(writeMode, finalBlock);
|
||||
|
||||
if (writeMode)
|
||||
{
|
||||
if(method == NBlockType::kStored)
|
||||
{
|
||||
for(UINT32 i = 0; i < m_CurrentBlockUncompressedSize; i++)
|
||||
{
|
||||
BYTE b = m_MatchFinder.GetIndexByte(i - m_AdditionalOffset -
|
||||
m_CurrentBlockUncompressedSize);
|
||||
m_OutStream.WriteBits(b, 8);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (UINT32 i = 0; i < m_ValueIndex; i++)
|
||||
{
|
||||
if (m_Values[i].Flag == kFlagImm)
|
||||
m_MainCoder.CodeOneValue(&m_ReverseOutStream, m_Values[i].Imm);
|
||||
else if (m_Values[i].Flag == kFlagLenPos)
|
||||
{
|
||||
UINT32 len = m_Values[i].Len;
|
||||
UINT32 lenSlot = g_LenSlots[len];
|
||||
m_MainCoder.CodeOneValue(&m_ReverseOutStream, kMatchNumber + lenSlot);
|
||||
m_OutStream.WriteBits(len - m_LenStart[lenSlot], m_LenDirectBits[lenSlot]);
|
||||
UINT32 dist = m_Values[i].Pos;
|
||||
UINT32 posSlot = GetPosSlot(dist);
|
||||
m_DistCoder.CodeOneValue(&m_ReverseOutStream, posSlot);
|
||||
m_OutStream.WriteBits(dist - kDistStart[posSlot], kDistDirectBits[posSlot]);
|
||||
}
|
||||
}
|
||||
m_MainCoder.CodeOneValue(&m_ReverseOutStream, kReadTableNumber);
|
||||
}
|
||||
}
|
||||
m_MainCoder.StartNewBlock();
|
||||
m_DistCoder.StartNewBlock();
|
||||
m_ValueIndex = 0;
|
||||
UINT32 i;
|
||||
for(i = 0; i < 256; i++)
|
||||
if(m_LastLevels[i] != 0)
|
||||
m_LiteralPrices[i] = m_LastLevels[i];
|
||||
else
|
||||
m_LiteralPrices[i] = kNoLiteralDummy;
|
||||
|
||||
// -------------- Normal match -----------------------------
|
||||
|
||||
for(i = 0; i < m_NumLenCombinations; i++)
|
||||
{
|
||||
UINT32 slot = g_LenSlots[i];
|
||||
BYTE dummy = m_LastLevels[kMatchNumber + slot];
|
||||
if (dummy != 0)
|
||||
m_LenPrices[i] = dummy;
|
||||
else
|
||||
m_LenPrices[i] = kNoLenDummy;
|
||||
m_LenPrices[i] += m_LenDirectBits[slot];
|
||||
}
|
||||
for(i = 0; i < kDistTableSize64; i++)
|
||||
{
|
||||
BYTE dummy = m_LastLevels[kDistTableStart + i];
|
||||
if (dummy != 0)
|
||||
m_PosPrices[i] = dummy;
|
||||
else
|
||||
m_PosPrices[i] = kNoPosDummy;
|
||||
m_PosPrices[i] += kDistDirectBits[i];
|
||||
}
|
||||
}
|
||||
|
||||
void CCoder::CodeLevelTable(BYTE *newLevels, int numLevels, bool codeMode)
|
||||
{
|
||||
int prevLen = 0xFF; // last emitted length
|
||||
int nextLen = newLevels[0]; // length of next code
|
||||
int count = 0; // repeat count of the current code
|
||||
int maxCount = 7; // max repeat count
|
||||
int minCount = 4; // min repeat count
|
||||
if (nextLen == 0)
|
||||
{
|
||||
maxCount = 138;
|
||||
minCount = 3;
|
||||
}
|
||||
BYTE oldValueInGuardElement = newLevels[numLevels]; // push guard value
|
||||
try
|
||||
{
|
||||
newLevels[numLevels] = 0xFF; // guard already set
|
||||
for (int n = 0; n < numLevels; n++)
|
||||
{
|
||||
int curLen = nextLen;
|
||||
nextLen = newLevels[n + 1];
|
||||
count++;
|
||||
if (count < maxCount && curLen == nextLen)
|
||||
continue;
|
||||
else if (count < minCount)
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
int codeLen = curLen;
|
||||
if (codeMode)
|
||||
m_LevelCoder.CodeOneValue(&m_ReverseOutStream, codeLen);
|
||||
else
|
||||
m_LevelCoder.AddSymbol(codeLen);
|
||||
}
|
||||
else if (curLen != 0)
|
||||
{
|
||||
if (curLen != prevLen)
|
||||
{
|
||||
int codeLen = curLen;
|
||||
if (codeMode)
|
||||
m_LevelCoder.CodeOneValue(&m_ReverseOutStream, codeLen);
|
||||
else
|
||||
m_LevelCoder.AddSymbol(codeLen);
|
||||
count--;
|
||||
}
|
||||
if (codeMode)
|
||||
{
|
||||
m_LevelCoder.CodeOneValue(&m_ReverseOutStream, kTableLevelRepNumber);
|
||||
m_OutStream.WriteBits(count - 3, 2);
|
||||
}
|
||||
else
|
||||
m_LevelCoder.AddSymbol(kTableLevelRepNumber);
|
||||
}
|
||||
else if (count <= 10)
|
||||
{
|
||||
if (codeMode)
|
||||
{
|
||||
m_LevelCoder.CodeOneValue(&m_ReverseOutStream, kTableLevel0Number);
|
||||
m_OutStream.WriteBits(count - 3, 3);
|
||||
}
|
||||
else
|
||||
m_LevelCoder.AddSymbol(kTableLevel0Number);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (codeMode)
|
||||
{
|
||||
m_LevelCoder.CodeOneValue(&m_ReverseOutStream, kTableLevel0Number2);
|
||||
m_OutStream.WriteBits(count - 11, 7);
|
||||
}
|
||||
else
|
||||
m_LevelCoder.AddSymbol(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
newLevels[numLevels] = oldValueInGuardElement; // old guard
|
||||
throw;
|
||||
}
|
||||
newLevels[numLevels] = oldValueInGuardElement; // old guard
|
||||
}
|
||||
|
||||
int CCoder::WriteTables(bool writeMode, bool finalBlock)
|
||||
{
|
||||
BYTE newLevels[kMaxTableSize64 + 1]; // (+ 1) for guard
|
||||
|
||||
m_MainCoder.BuildTree(&newLevels[0]);
|
||||
m_DistCoder.BuildTree(&newLevels[kDistTableStart]);
|
||||
|
||||
|
||||
memset(m_LastLevels, 0, kMaxTableSize64);
|
||||
|
||||
if (writeMode)
|
||||
{
|
||||
if(finalBlock)
|
||||
m_OutStream.WriteBits(NFinalBlockField::kFinalBlock, kFinalBlockFieldSize);
|
||||
else
|
||||
m_OutStream.WriteBits(NFinalBlockField::kNotFinalBlock, kFinalBlockFieldSize);
|
||||
|
||||
m_LevelCoder.StartNewBlock();
|
||||
|
||||
int numLitLenLevels = kMainTableSize;
|
||||
while(numLitLenLevels > kDeflateNumberOfLitLenCodesMin && newLevels[numLitLenLevels - 1] == 0)
|
||||
numLitLenLevels--;
|
||||
|
||||
int numDistLevels = _deflate64Mode ? kDistTableSize64 : kDistTableSize32;
|
||||
while(numDistLevels > kDeflateNumberOfDistanceCodesMin &&
|
||||
newLevels[kDistTableStart + numDistLevels - 1] == 0)
|
||||
numDistLevels--;
|
||||
|
||||
|
||||
/////////////////////////
|
||||
// First Pass
|
||||
|
||||
CodeLevelTable(newLevels, numLitLenLevels, false);
|
||||
CodeLevelTable(&newLevels[kDistTableStart], numDistLevels, false);
|
||||
|
||||
memcpy(m_LastLevels, newLevels, kMaxTableSize64);
|
||||
|
||||
|
||||
BYTE levelLevels[kLevelTableSize];
|
||||
m_LevelCoder.BuildTree(levelLevels);
|
||||
|
||||
BYTE levelLevelsStream[kLevelTableSize];
|
||||
int numLevelCodes = kDeflateNumberOfLevelCodesMin;
|
||||
int i;
|
||||
for (i = 0; i < kLevelTableSize; i++)
|
||||
{
|
||||
int streamPos = kCodeLengthAlphabetOrder[i];
|
||||
int level = levelLevels[streamPos];
|
||||
if (level > 0 && i >= numLevelCodes)
|
||||
numLevelCodes = i + 1;
|
||||
levelLevelsStream[i] = level;
|
||||
}
|
||||
|
||||
UINT32 numLZHuffmanBits = m_MainCoder.GetBlockBitLength();
|
||||
numLZHuffmanBits += m_DistCoder.GetBlockBitLength();
|
||||
numLZHuffmanBits += m_LevelCoder.GetBlockBitLength();
|
||||
numLZHuffmanBits += kDeflateNumberOfLengthCodesFieldSize +
|
||||
kDeflateNumberOfDistanceCodesFieldSize +
|
||||
kDeflateNumberOfLevelCodesFieldSize;
|
||||
numLZHuffmanBits += numLevelCodes * kDeflateLevelCodeFieldSize;
|
||||
|
||||
UINT32 nextBitPosition =
|
||||
(m_OutStream.GetBitPosition() + kBlockTypeFieldSize) % 8;
|
||||
UINT32 numBitsForAlign = nextBitPosition > 0 ? (8 - nextBitPosition): 0;
|
||||
|
||||
UINT32 numStoreBits = numBitsForAlign + (2 * sizeof(UINT16)) * 8;
|
||||
numStoreBits += m_CurrentBlockUncompressedSize * 8;
|
||||
if(numStoreBits < numLZHuffmanBits)
|
||||
{
|
||||
m_OutStream.WriteBits(NBlockType::kStored, kBlockTypeFieldSize); // test it
|
||||
m_OutStream.WriteBits(0, numBitsForAlign); // test it
|
||||
UINT16 currentBlockUncompressedSize = UINT16(m_CurrentBlockUncompressedSize);
|
||||
UINT16 currentBlockUncompressedSizeNot = ~currentBlockUncompressedSize;
|
||||
m_OutStream.WriteBits(currentBlockUncompressedSize, kDeflateStoredBlockLengthFieldSizeSize);
|
||||
m_OutStream.WriteBits(currentBlockUncompressedSizeNot, kDeflateStoredBlockLengthFieldSizeSize);
|
||||
return NBlockType::kStored;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_OutStream.WriteBits(NBlockType::kDynamicHuffman, kBlockTypeFieldSize);
|
||||
m_OutStream.WriteBits(numLitLenLevels - kDeflateNumberOfLitLenCodesMin, kDeflateNumberOfLengthCodesFieldSize);
|
||||
m_OutStream.WriteBits(numDistLevels - kDeflateNumberOfDistanceCodesMin,
|
||||
kDeflateNumberOfDistanceCodesFieldSize);
|
||||
m_OutStream.WriteBits(numLevelCodes - kDeflateNumberOfLevelCodesMin,
|
||||
kDeflateNumberOfLevelCodesFieldSize);
|
||||
|
||||
for (i = 0; i < numLevelCodes; i++)
|
||||
m_OutStream.WriteBits(levelLevelsStream[i], kDeflateLevelCodeFieldSize);
|
||||
|
||||
/////////////////////////
|
||||
// Second Pass
|
||||
|
||||
CodeLevelTable(newLevels, numLitLenLevels, true);
|
||||
CodeLevelTable(&newLevels[kDistTableStart], numDistLevels, true);
|
||||
return NBlockType::kDynamicHuffman;
|
||||
}
|
||||
}
|
||||
else
|
||||
memcpy(m_LastLevels, newLevels, kMaxTableSize64);
|
||||
return -1;
|
||||
}
|
||||
|
||||
HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (!m_Created)
|
||||
{
|
||||
RINOK(Create());
|
||||
m_Created = true;
|
||||
}
|
||||
|
||||
UINT64 nowPos = 0;
|
||||
m_FinderPos = 0;
|
||||
|
||||
RINOK(m_MatchFinder.Init(inStream));
|
||||
m_OutStream.Init(outStream);
|
||||
m_ReverseOutStream.Init(&m_OutStream);
|
||||
|
||||
// CCoderReleaser coderReleaser(this);
|
||||
InitStructures();
|
||||
|
||||
while(true)
|
||||
{
|
||||
int currentPassIndex = 0;
|
||||
bool noMoreBytes;
|
||||
while (true)
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
noMoreBytes = (m_AdditionalOffset == 0 && m_MatchFinder.GetNumAvailableBytes() == 0);
|
||||
|
||||
if (((m_CurrentBlockUncompressedSize >= kBlockUncompressedSizeThreshold ||
|
||||
m_ValueIndex >= kValueBlockSize) &&
|
||||
(m_OptimumEndIndex == m_OptimumCurrentIndex))
|
||||
|| noMoreBytes)
|
||||
break;
|
||||
UINT32 pos;
|
||||
UINT32 len = GetOptimal(pos);
|
||||
if (len >= kMatchMinLen)
|
||||
{
|
||||
UINT32 newLen = len - kMatchMinLen;
|
||||
m_Values[m_ValueIndex].Flag = kFlagLenPos;
|
||||
m_Values[m_ValueIndex].Len = BYTE(newLen);
|
||||
UINT32 lenSlot = g_LenSlots[newLen];
|
||||
m_MainCoder.AddSymbol(kMatchNumber + lenSlot);
|
||||
m_Values[m_ValueIndex].Pos = UINT16(pos);
|
||||
UINT32 posSlot = GetPosSlot(pos);
|
||||
m_DistCoder.AddSymbol(posSlot);
|
||||
}
|
||||
else if (len == 1)
|
||||
{
|
||||
BYTE b = m_MatchFinder.GetIndexByte(0 - m_AdditionalOffset);
|
||||
len = 1;
|
||||
m_MainCoder.AddSymbol(b);
|
||||
m_Values[m_ValueIndex].Flag = kFlagImm;
|
||||
m_Values[m_ValueIndex].Imm = b;
|
||||
}
|
||||
else
|
||||
throw 12112342;
|
||||
m_ValueIndex++;
|
||||
m_AdditionalOffset -= len;
|
||||
nowPos += len;
|
||||
m_CurrentBlockUncompressedSize += len;
|
||||
|
||||
}
|
||||
currentPassIndex++;
|
||||
bool writeMode = (currentPassIndex == m_NumPasses);
|
||||
WriteBlockData(writeMode, noMoreBytes);
|
||||
if (writeMode)
|
||||
break;
|
||||
nowPos = m_BlockStartPostion;
|
||||
m_AdditionalOffset = UINT32(m_FinderPos - m_BlockStartPostion);
|
||||
m_CurrentBlockUncompressedSize = 0;
|
||||
}
|
||||
m_BlockStartPostion += m_CurrentBlockUncompressedSize;
|
||||
m_CurrentBlockUncompressedSize = 0;
|
||||
if (progress != NULL)
|
||||
{
|
||||
UINT64 packSize = m_OutStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&nowPos, &packSize));
|
||||
}
|
||||
if (noMoreBytes)
|
||||
break;
|
||||
}
|
||||
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(CMatchFinderException &e) { return e.m_Result; }
|
||||
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); }
|
||||
|
||||
}}}
|
||||
197
7zip/Compress/Deflate/DeflateEncoder.h
Executable file
197
7zip/Compress/Deflate/DeflateEncoder.h
Executable file
@@ -0,0 +1,197 @@
|
||||
// DeflateEncoder.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DEFLATE_ENCODER_H
|
||||
#define __DEFLATE_ENCODER_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/LSBFEncoder.h"
|
||||
#include "../LZ/BinTree/BinTree3Z.h"
|
||||
#include "../Huffman/HuffmanEncoder.h"
|
||||
|
||||
#include "DeflateConst.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
namespace NEncoder {
|
||||
|
||||
struct CCodeValue
|
||||
{
|
||||
BYTE Flag;
|
||||
union
|
||||
{
|
||||
BYTE Imm;
|
||||
BYTE Len;
|
||||
};
|
||||
UINT16 Pos;
|
||||
};
|
||||
|
||||
class COnePosMatches
|
||||
{
|
||||
public:
|
||||
UINT16 *MatchDistances;
|
||||
UINT16 LongestMatchLength;
|
||||
UINT16 LongestMatchDistance;
|
||||
void Init(UINT16 *matchDistances)
|
||||
{
|
||||
MatchDistances = matchDistances;
|
||||
};
|
||||
};
|
||||
|
||||
struct COptimal
|
||||
{
|
||||
UINT32 Price;
|
||||
UINT16 PosPrev;
|
||||
UINT16 BackPrev;
|
||||
};
|
||||
|
||||
const int kNumOpts = 0x1000;
|
||||
|
||||
class CCoder
|
||||
{
|
||||
UINT32 m_FinderPos;
|
||||
|
||||
COptimal m_Optimum[kNumOpts];
|
||||
|
||||
// CComPtr<IInWindowStreamMatch> m_MatchFinder;
|
||||
NBT3Z::CInTree m_MatchFinder;
|
||||
|
||||
NStream::NLSBF::CEncoder m_OutStream;
|
||||
NStream::NLSBF::CReverseEncoder m_ReverseOutStream;
|
||||
|
||||
NCompression::NHuffman::CEncoder m_MainCoder;
|
||||
NCompression::NHuffman::CEncoder m_DistCoder;
|
||||
NCompression::NHuffman::CEncoder m_LevelCoder;
|
||||
|
||||
BYTE m_LastLevels[kMaxTableSize64];
|
||||
|
||||
UINT32 m_ValueIndex;
|
||||
CCodeValue *m_Values;
|
||||
|
||||
UINT32 m_OptimumEndIndex;
|
||||
UINT32 m_OptimumCurrentIndex;
|
||||
UINT32 m_AdditionalOffset;
|
||||
|
||||
UINT32 m_LongestMatchLength;
|
||||
UINT32 m_LongestMatchDistance;
|
||||
UINT16 *m_MatchDistances;
|
||||
|
||||
UINT32 m_NumFastBytes;
|
||||
UINT32 m_MatchLengthEdge;
|
||||
|
||||
BYTE m_LiteralPrices[256];
|
||||
|
||||
BYTE m_LenPrices[kNumLenCombinations32];
|
||||
BYTE m_PosPrices[kDistTableSize64];
|
||||
|
||||
UINT32 m_CurrentBlockUncompressedSize;
|
||||
|
||||
COnePosMatches *m_OnePosMatchesArray;
|
||||
UINT16 *m_OnePosMatchesMemory;
|
||||
|
||||
UINT64 m_BlockStartPostion;
|
||||
int m_NumPasses;
|
||||
|
||||
bool m_Created;
|
||||
|
||||
bool _deflate64Mode;
|
||||
UINT32 m_NumLenCombinations;
|
||||
UINT32 m_MatchMaxLen;
|
||||
const BYTE *m_LenStart;
|
||||
const BYTE *m_LenDirectBits;
|
||||
|
||||
HRESULT Create();
|
||||
void Free();
|
||||
|
||||
void GetBacks(UINT32 aPos);
|
||||
|
||||
void ReadGoodBacks();
|
||||
void MovePos(UINT32 num);
|
||||
UINT32 Backward(UINT32 &backRes, UINT32 cur);
|
||||
UINT32 GetOptimal(UINT32 &backRes);
|
||||
|
||||
void InitStructures();
|
||||
void CodeLevelTable(BYTE *newLevels, int numLevels, bool codeMode);
|
||||
int WriteTables(bool writeMode, bool finalBlock);
|
||||
void CopyBackBlockOp(UINT32 distance, UINT32 length);
|
||||
void WriteBlockData(bool writeMode, bool finalBlock);
|
||||
|
||||
/*
|
||||
void CCoder::ReleaseStreams()
|
||||
{
|
||||
m_MatchFinder.ReleaseStream();
|
||||
m_OutStream.ReleaseStream();
|
||||
}
|
||||
class CCoderReleaser
|
||||
{
|
||||
CCoder *m_Coder;
|
||||
public:
|
||||
CCoderReleaser(CCoder *aCoder): m_Coder(aCoder) {}
|
||||
~CCoderReleaser()
|
||||
{
|
||||
m_Coder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
friend class CCoderReleaser;
|
||||
*/
|
||||
|
||||
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
|
||||
27
7zip/Compress/Deflate/DeflateExtConst.h
Executable file
27
7zip/Compress/Deflate/DeflateExtConst.h
Executable file
@@ -0,0 +1,27 @@
|
||||
// DeflateExtConst.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DEFLATE_EXTCONST_H
|
||||
#define __DEFLATE_EXTCONST_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
|
||||
// const UINT32 kDistTableSize = 30;
|
||||
const UINT32 kDistTableSize32 = 30;
|
||||
const UINT32 kDistTableSize64 = 32;
|
||||
|
||||
const UINT32 kHistorySize32 = 0x8000;
|
||||
const UINT32 kHistorySize64 = 0x10000;
|
||||
const UINT32 kNumLenCombinations32 = 256;
|
||||
const UINT32 kNumLenCombinations64 = 255;
|
||||
// don't change kNumLenCombinations64. It must be less than 255.
|
||||
|
||||
const UINT32 kNumHuffmanBits = 15;
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
126
7zip/Compress/Deflate/DllExports.cpp
Executable file
126
7zip/Compress/Deflate/DllExports.cpp
Executable file
@@ -0,0 +1,126 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#define INITGUID
|
||||
|
||||
#include "DeflateEncoder.h"
|
||||
#include "DeflateDecoder.h"
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
|
||||
// {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);
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
{
|
||||
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_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 }
|
||||
|
||||
|
||||
static CDeflateMethodItem g_Methods[] =
|
||||
{
|
||||
METHOD_ITEM(Deflate, 0x08, L"Deflate"),
|
||||
METHOD_ITEM(Deflate64, 0x09, L"Deflate64")
|
||||
};
|
||||
|
||||
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 ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)method.Encoder, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
3
7zip/Compress/Deflate/StdAfx.cpp
Executable file
3
7zip/Compress/Deflate/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
8
7zip/Compress/Deflate/StdAfx.h
Executable file
8
7zip/Compress/Deflate/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#endif
|
||||
15
7zip/Compress/Deflate/resource.h
Executable file
15
7zip/Compress/Deflate/resource.h
Executable file
@@ -0,0 +1,15 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by resource.rc
|
||||
//
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
121
7zip/Compress/Deflate/resource.rc
Executable file
121
7zip/Compress/Deflate/resource.rc
Executable file
@@ -0,0 +1,121 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Russian resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
|
||||
#pragma code_page(1251)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // Russian resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifndef _MAC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,9,2,0
|
||||
PRODUCTVERSION 3,9,2,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", " \0"
|
||||
VALUE "FileDescription", "Deflate Coder\0"
|
||||
VALUE "FileVersion", "3, 9, 2, 0\0"
|
||||
VALUE "InternalName", "Deflate\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "Deflate.dll\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "7-Zip\0"
|
||||
VALUE "ProductVersion", "3, 9, 2, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // !_MAC
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
Reference in New Issue
Block a user