Home | History | Annotate | Download | only in Compress
      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];
     15   CDelta(): _delta(1) {}
     16   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 
     47 STDMETHODIMP CDeltaEncoder::Init()
     48 {
     49   DeltaInit();
     50   return S_OK;
     51 }
     52 
     53 STDMETHODIMP_(UInt32) CDeltaEncoder::Filter(Byte *data, UInt32 size)
     54 {
     55   Delta_Encode(_state, _delta, data, size);
     56   return size;
     57 }
     58 
     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     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 
     73 STDMETHODIMP CDeltaEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
     74 {
     75   Byte prop = (Byte)(_delta - 1);
     76   return outStream->Write(&prop, 1, NULL);
     77 }
     78 
     79 STDMETHODIMP CDeltaDecoder::Init()
     80 {
     81   DeltaInit();
     82   return S_OK;
     83 }
     84 
     85 STDMETHODIMP_(UInt32) CDeltaDecoder::Filter(Byte *data, UInt32 size)
     86 {
     87   Delta_Decode(_state, _delta, data, size);
     88   return size;
     89 }
     90 
     91 STDMETHODIMP 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 
    103 CREATE_CODEC(Delta)
    104 
    105 #define METHOD_ITEM(x, id, name) { CreateCodec ## x, CreateCodec ## x ## Out, id, name, 1, true  }
    106 
    107 static CCodecInfo g_CodecsInfo[] =
    108 {
    109   METHOD_ITEM(Delta, 3, L"Delta")
    110 };
    111 
    112 REGISTER_CODECS(Delta)
    113