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
11 struct CDelta
12 {
13 unsigned _delta;
14 Byte _state[DELTA_STATE_SIZE];
CDeltaCDelta15 CDelta(): _delta(1) {}
DeltaInitCDelta16 void DeltaInit() { Delta_Init(_state); }
17 };
18
19 class CDeltaEncoder:
20 public ICompressFilter,
21 public ICompressSetCoderProperties,
22 public ICompressWriteCoderProperties,
23 CDelta,
24 public CMyUnknownImp
25 {
26 public:
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
34 class CDeltaDecoder:
35 public ICompressFilter,
36 public ICompressSetDecoderProperties2,
37 CDelta,
38 public CMyUnknownImp
39 {
40 public:
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
Init()47 STDMETHODIMP CDeltaEncoder::Init()
48 {
49 DeltaInit();
50 return S_OK;
51 }
52
STDMETHODIMP_(UInt32)53 STDMETHODIMP_(UInt32) CDeltaEncoder::Filter(Byte *data, UInt32 size)
54 {
55 Delta_Encode(_state, _delta, data, size);
56 return size;
57 }
58
SetCoderProperties(const PROPID * propIDs,const PROPVARIANT * props,UInt32 numProps)59 STDMETHODIMP 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
WriteCoderProperties(ISequentialOutStream * outStream)86 STDMETHODIMP CDeltaEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
87 {
88 Byte prop = (Byte)(_delta - 1);
89 return outStream->Write(&prop, 1, NULL);
90 }
91
Init()92 STDMETHODIMP CDeltaDecoder::Init()
93 {
94 DeltaInit();
95 return S_OK;
96 }
97
STDMETHODIMP_(UInt32)98 STDMETHODIMP_(UInt32) CDeltaDecoder::Filter(Byte *data, UInt32 size)
99 {
100 Delta_Decode(_state, _delta, data, size);
101 return size;
102 }
103
SetDecoderProperties2(const Byte * props,UInt32 size)104 STDMETHODIMP 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
116 CREATE_CODEC(Delta)
117
118 #define METHOD_ITEM(x, id, name) { CreateCodec ## x, CreateCodec ## x ## Out, id, name, 1, true }
119
120 static CCodecInfo g_CodecsInfo[] =
121 {
122 METHOD_ITEM(Delta, 3, L"Delta")
123 };
124
125 REGISTER_CODECS(Delta)
126