mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-10 04:07:12 -06:00
4.44 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
804edc5756
commit
d9666cf046
64
CPP/7zip/Compress/Shrink/DllExports.cpp
Executable file
64
CPP/7zip/Compress/Shrink/DllExports.cpp
Executable file
@@ -0,0 +1,64 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
#include "ShrinkDecoder.h"
|
||||
|
||||
// {23170F69-40C1-278B-0401-010000000000}
|
||||
DEFINE_GUID(CLSID_CCompressShrinkDecoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 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;
|
||||
if (*clsid != CLSID_CCompressShrinkDecoder)
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
if (*iid != IID_ICompressCoder)
|
||||
return E_NOINTERFACE;
|
||||
CMyComPtr<ICompressCoder> coder = (ICompressCoder *)new NCompress::NShrink::CDecoder;
|
||||
*outObject = coder.Detach();
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDAPI GetNumberOfMethods(UINT32 *numMethods)
|
||||
{
|
||||
*numMethods = 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
if (index != 0)
|
||||
return E_INVALIDARG;
|
||||
::VariantClear((tagVARIANT *)value);
|
||||
switch(propID)
|
||||
{
|
||||
case NMethodPropID::kID:
|
||||
{
|
||||
const char id[] = { 0x04, 0x01, 0x01 };
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
case NMethodPropID::kName:
|
||||
if ((value->bstrVal = ::SysAllocString(L"Shrink")) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
case NMethodPropID::kDecoder:
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)&CLSID_CCompressShrinkDecoder, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
149
CPP/7zip/Compress/Shrink/ShrinkDecoder.cpp
Executable file
149
CPP/7zip/Compress/Shrink/ShrinkDecoder.cpp
Executable file
@@ -0,0 +1,149 @@
|
||||
// ShrinkDecoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ShrinkDecoder.h"
|
||||
|
||||
#include "../../../Common/Alloc.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
#include "../../Common/OutBuffer.h"
|
||||
#include "../../Common/LSBFDecoder.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NShrink {
|
||||
|
||||
static const UInt32 kBufferSize = (1 << 20);
|
||||
|
||||
static const int kNumMinBits = 9;
|
||||
|
||||
STDMETHODIMP CDecoder ::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 * /* outSize */,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
NStream::NLSBF::CBaseDecoder<CInBuffer> inBuffer;
|
||||
COutBuffer outBuffer;
|
||||
|
||||
if (!inBuffer.Create(kBufferSize))
|
||||
return E_OUTOFMEMORY;
|
||||
inBuffer.SetStream(inStream);
|
||||
inBuffer.Init();
|
||||
|
||||
if (!outBuffer.Create(kBufferSize))
|
||||
return E_OUTOFMEMORY;
|
||||
outBuffer.SetStream(outStream);
|
||||
outBuffer.Init();
|
||||
|
||||
UInt64 prevPos = 0;
|
||||
int numBits = kNumMinBits;
|
||||
UInt32 head = 257;
|
||||
|
||||
bool needPrev = false;
|
||||
|
||||
_parents[256] = 0; // virus protection
|
||||
_suffixes[256] = 0;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 257; i++)
|
||||
_isFree[i] = false;
|
||||
for (; i < kNumItems; i++)
|
||||
_isFree[i] = true;
|
||||
|
||||
UInt32 lastSymbol = 0;
|
||||
for (;;)
|
||||
{
|
||||
outBuffer.Flush();
|
||||
UInt32 symbol = inBuffer.ReadBits(numBits);
|
||||
if (inBuffer.ExtraBitsWereRead())
|
||||
break;
|
||||
if (_isFree[symbol])
|
||||
return S_FALSE;
|
||||
if (symbol == 256)
|
||||
{
|
||||
// fix it;
|
||||
UInt32 symbol = inBuffer.ReadBits(numBits);
|
||||
if (symbol == 1)
|
||||
{
|
||||
if (numBits < kNumMaxBits)
|
||||
numBits++;
|
||||
}
|
||||
else if (symbol == 2)
|
||||
{
|
||||
/*
|
||||
maybe need delete prev also ?
|
||||
if (needPrev)
|
||||
_isFree[head - 1] = true;
|
||||
*/
|
||||
for (i = 257; i < kNumItems; i++)
|
||||
_isParent[i] = false;
|
||||
for (i = 257; i < kNumItems; i++)
|
||||
if (!_isFree[i])
|
||||
_isParent[_parents[i]] = true;
|
||||
for (i = 257; i < kNumItems; i++)
|
||||
if (!_isParent[i])
|
||||
_isFree[i] = true;
|
||||
head = 257;
|
||||
while(head < ((UInt32)1 << numBits) && !_isFree[head])
|
||||
head++;
|
||||
if (head < ((UInt32)1 << numBits))
|
||||
{
|
||||
needPrev = true;
|
||||
_isFree[head] = false;
|
||||
_parents[head] = (UInt16)lastSymbol;
|
||||
head++;
|
||||
}
|
||||
}
|
||||
else
|
||||
return S_FALSE;
|
||||
continue;
|
||||
}
|
||||
UInt32 cur = symbol;
|
||||
i = 0;
|
||||
while (cur >= 256)
|
||||
{
|
||||
_stack[i++] = _suffixes[cur];
|
||||
cur = _parents[cur];
|
||||
}
|
||||
_stack[i++] = (Byte)cur;
|
||||
if (needPrev)
|
||||
{
|
||||
_suffixes[head - 1] = (Byte)cur;
|
||||
if (symbol == head - 1)
|
||||
_stack[0] = (Byte)cur;
|
||||
}
|
||||
while (i > 0)
|
||||
outBuffer.WriteByte((_stack[--i]));
|
||||
while(head < ((UInt32)1 << numBits) && !_isFree[head])
|
||||
head++;
|
||||
if (head < ((UInt32)1 << numBits))
|
||||
{
|
||||
needPrev = true;
|
||||
_isFree[head] = false;
|
||||
_parents[head] = (UInt16)symbol;
|
||||
head++;
|
||||
}
|
||||
else
|
||||
needPrev = false;
|
||||
lastSymbol = symbol;
|
||||
|
||||
UInt64 nowPos = outBuffer.GetProcessedSize();
|
||||
if (progress != NULL && nowPos - prevPos > (1 << 18))
|
||||
{
|
||||
prevPos = nowPos;
|
||||
UInt64 packSize = inBuffer.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&packSize, &nowPos));
|
||||
}
|
||||
}
|
||||
return outBuffer.Flush();
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder ::Code(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 COutBufferException &e) { return e.ErrorCode; }
|
||||
catch(...) { return S_FALSE; }
|
||||
}
|
||||
|
||||
}}
|
||||
39
CPP/7zip/Compress/Shrink/ShrinkDecoder.h
Executable file
39
CPP/7zip/Compress/Shrink/ShrinkDecoder.h
Executable file
@@ -0,0 +1,39 @@
|
||||
// ShrinkDecoder.h
|
||||
|
||||
#ifndef __SHRINK_DECODER_H
|
||||
#define __SHRINK_DECODER_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NShrink {
|
||||
|
||||
const int kNumMaxBits = 13;
|
||||
const UInt32 kNumItems = 1 << kNumMaxBits;
|
||||
|
||||
class CDecoder :
|
||||
public ICompressCoder,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
UInt16 _parents[kNumItems];
|
||||
Byte _suffixes[kNumItems];
|
||||
Byte _stack[kNumItems];
|
||||
bool _isFree[kNumItems];
|
||||
bool _isParent[kNumItems];
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(CodeReal)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
3
CPP/7zip/Compress/Shrink/StdAfx.cpp
Executable file
3
CPP/7zip/Compress/Shrink/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
8
CPP/7zip/Compress/Shrink/StdAfx.h
Executable file
8
CPP/7zip/Compress/Shrink/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user