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    if (propIDs[i] != NCoderPropID::kDefaultProp || prop.vt != VT_UI4 || prop.ulVal < 1 || prop.ulVal > 256)
66      return E_INVALIDARG;
67    delta = prop.ulVal;
68  }
69  _delta = delta;
70  return S_OK;
71}
72
73STDMETHODIMP CDeltaEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
74{
75  Byte prop = (Byte)(_delta - 1);
76  return outStream->Write(&prop, 1, NULL);
77}
78
79STDMETHODIMP CDeltaDecoder::Init()
80{
81  DeltaInit();
82  return S_OK;
83}
84
85STDMETHODIMP_(UInt32) CDeltaDecoder::Filter(Byte *data, UInt32 size)
86{
87  Delta_Decode(_state, _delta, data, size);
88  return size;
89}
90
91STDMETHODIMP CDeltaDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)
92{
93  if (size != 1)
94    return E_INVALIDARG;
95  _delta = (unsigned)props[0] + 1;
96  return S_OK;
97}
98
99#define CREATE_CODEC(x) \
100  static void *CreateCodec ## x() { return (void *)(ICompressFilter *)(new C ## x ## Decoder); } \
101  static void *CreateCodec ## x ## Out() { return (void *)(ICompressFilter *)(new C ## x ## Encoder); }
102
103CREATE_CODEC(Delta)
104
105#define METHOD_ITEM(x, id, name) { CreateCodec ## x, CreateCodec ## x ## Out, id, name, 1, true  }
106
107static CCodecInfo g_CodecsInfo[] =
108{
109  METHOD_ITEM(Delta, 3, L"Delta")
110};
111
112REGISTER_CODECS(Delta)
113