// DeltaFilter.cpp | |
#include "StdAfx.h" | |
#include "../../../C/Delta.h" | |
#include "../Common/RegisterCodec.h" | |
#include "BranchCoder.h" | |
struct CDelta | |
{ | |
unsigned _delta; | |
Byte _state[DELTA_STATE_SIZE]; | |
CDelta(): _delta(1) {} | |
void DeltaInit() { Delta_Init(_state); } | |
}; | |
class CDeltaEncoder: | |
public ICompressFilter, | |
public ICompressSetCoderProperties, | |
public ICompressWriteCoderProperties, | |
CDelta, | |
public CMyUnknownImp | |
{ | |
public: | |
MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties) | |
STDMETHOD(Init)(); | |
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); | |
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); | |
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); | |
}; | |
class CDeltaDecoder: | |
public ICompressFilter, | |
public ICompressSetDecoderProperties2, | |
CDelta, | |
public CMyUnknownImp | |
{ | |
public: | |
MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) | |
STDMETHOD(Init)(); | |
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); | |
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); | |
}; | |
STDMETHODIMP CDeltaEncoder::Init() | |
{ | |
DeltaInit(); | |
return S_OK; | |
} | |
STDMETHODIMP_(UInt32) CDeltaEncoder::Filter(Byte *data, UInt32 size) | |
{ | |
Delta_Encode(_state, _delta, data, size); | |
return size; | |
} | |
STDMETHODIMP CDeltaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) | |
{ | |
UInt32 delta = _delta; | |
for (UInt32 i = 0; i < numProps; i++) | |
{ | |
const PROPVARIANT &prop = props[i]; | |
PROPID propID = propIDs[i]; | |
if (propID >= NCoderPropID::kReduceSize) | |
continue; | |
if (prop.vt != VT_UI4) | |
return E_INVALIDARG; | |
switch (propID) | |
{ | |
case NCoderPropID::kDefaultProp: | |
delta = (UInt32)prop.ulVal; | |
if (delta < 1 || delta > 256) | |
return E_INVALIDARG; | |
break; | |
case NCoderPropID::kNumThreads: break; | |
case NCoderPropID::kLevel: break; | |
default: return E_INVALIDARG; | |
} | |
} | |
_delta = delta; | |
return S_OK; | |
} | |
STDMETHODIMP CDeltaEncoder::WriteCoderProperties(ISequentialOutStream *outStream) | |
{ | |
Byte prop = (Byte)(_delta - 1); | |
return outStream->Write(&prop, 1, NULL); | |
} | |
STDMETHODIMP CDeltaDecoder::Init() | |
{ | |
DeltaInit(); | |
return S_OK; | |
} | |
STDMETHODIMP_(UInt32) CDeltaDecoder::Filter(Byte *data, UInt32 size) | |
{ | |
Delta_Decode(_state, _delta, data, size); | |
return size; | |
} | |
STDMETHODIMP CDeltaDecoder::SetDecoderProperties2(const Byte *props, UInt32 size) | |
{ | |
if (size != 1) | |
return E_INVALIDARG; | |
_delta = (unsigned)props[0] + 1; | |
return S_OK; | |
} | |
#define CREATE_CODEC(x) \ | |
static void *CreateCodec ## x() { return (void *)(ICompressFilter *)(new C ## x ## Decoder); } \ | |
static void *CreateCodec ## x ## Out() { return (void *)(ICompressFilter *)(new C ## x ## Encoder); } | |
CREATE_CODEC(Delta) | |
#define METHOD_ITEM(x, id, name) { CreateCodec ## x, CreateCodec ## x ## Out, id, name, 1, true } | |
static CCodecInfo g_CodecsInfo[] = | |
{ | |
METHOD_ITEM(Delta, 3, L"Delta") | |
}; | |
REGISTER_CODECS(Delta) |