This commit is contained in:
Igor Pavlov
2005-05-30 00:00:00 +00:00
committed by Kornel Lesiński
parent 8c1b5c7b7e
commit 3c510ba80b
926 changed files with 40559 additions and 23519 deletions

View 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;
}

View 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;
while (true)
{
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; }
}
}}

View 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

View File

@@ -0,0 +1,3 @@
// StdAfx.cpp
#include "StdAfx.h"

8
7zip/Compress/Shrink/StdAfx.h Executable file
View File

@@ -0,0 +1,8 @@
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/MyWindows.h"
#endif

15
7zip/Compress/Shrink/resource.h Executable file
View 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