1// DeltaFilter.cpp
2
3#include "StdAfx.h"
4
5#include "../../../C/Delta.h"
6
7#include "../Common/RegisterCodec.h"
8
9#include "BranchCoder.h"
10
11struct CDelta
12{
13  unsigned _delta;
14  Byte _state[DELTA_STATE_SIZE];
15  CDelta(): _delta(1) {}
16  void DeltaInit() { Delta_Init(_state); }
17};
18
19class CDeltaEncoder:
20  public ICompressFilter,
21  public ICompressSetCoderProperties,
22  public ICompressWriteCoderProperties,
23  CDelta,
24  public CMyUnknownImp
25{
26public:
27  MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties)
28  STDMETHOD(Init)();
29  STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
30  STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
31  STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
32};
33
34class CDeltaDecoder:
35  public ICompressFilter,
36  public ICompressSetDecoderProperties2,
37  CDelta,
38  public CMyUnknownImp
39{
40public:
41  MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
42  STDMETHOD(Init)();
43  STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
44  STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
45};
46
47STDMETHODIMP CDeltaEncoder::Init()
48{
49  DeltaInit();
50  return S_OK;
51}
52
53STDMETHODIMP_(UInt32) CDeltaEncoder::Filter(Byte *data, UInt32 size)
54{
55  Delta_Encode(_state, _delta, data, size);
56  return size;
57}
58
59STDMETHODIMP CDeltaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
60{
61  UInt32 delta = _delta;
62  for (UInt32 i = 0; i < numProps; i++)
63  {
64    const PROPVARIANT &prop = props[i];
65    PROPID propID = propIDs[i];
66    if (propID >= NCoderPropID::kReduceSize)
67      continue;
68    if (prop.vt != VT_UI4)
69      return E_INVALIDARG;
70    switch (propID)
71    {
72      case NCoderPropID::kDefaultProp:
73        delta = (UInt32)prop.ulVal;
74        if (delta < 1 || delta > 256)
75          return E_INVALIDARG;
76        break;
77      case NCoderPropID::kNumThreads: break;
78      case NCoderPropID::kLevel: break;
79      default: return E_INVALIDARG;
80    }
81  }
82  _delta = delta;
83  return S_OK;
84}
85
86STDMETHODIMP CDeltaEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
87{
88  Byte prop = (Byte)(_delta - 1);
89  return outStream->Write(&prop, 1, NULL);
90}
91
92STDMETHODIMP CDeltaDecoder::Init()
93{
94  DeltaInit();
95  return S_OK;
96}
97
98STDMETHODIMP_(UInt32) CDeltaDecoder::Filter(Byte *data, UInt32 size)
99{
100  Delta_Decode(_state, _delta, data, size);
101  return size;
102}
103
104STDMETHODIMP CDeltaDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)
105{
106  if (size != 1)
107    return E_INVALIDARG;
108  _delta = (unsigned)props[0] + 1;
109  return S_OK;
110}
111
112#define CREATE_CODEC(x) \
113  static void *CreateCodec ## x() { return (void *)(ICompressFilter *)(new C ## x ## Decoder); } \
114  static void *CreateCodec ## x ## Out() { return (void *)(ICompressFilter *)(new C ## x ## Encoder); }
115
116CREATE_CODEC(Delta)
117
118#define METHOD_ITEM(x, id, name) { CreateCodec ## x, CreateCodec ## x ## Out, id, name, 1, true  }
119
120static CCodecInfo g_CodecsInfo[] =
121{
122  METHOD_ITEM(Delta, 3, L"Delta")
123};
124
125REGISTER_CODECS(Delta)
126