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