Home | History | Annotate | Download | only in 7zip
      1 // ICoder.h
      2 
      3 #ifndef __ICODER_H
      4 #define __ICODER_H
      5 
      6 #include "IStream.h"
      7 
      8 #define CODER_INTERFACE(i, x) DECL_INTERFACE(i, 4, x)
      9 
     10 CODER_INTERFACE(ICompressProgressInfo, 0x04)
     11 {
     12   STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) PURE;
     13 
     14   /* (inSize) can be NULL, if unknown
     15      (outSize) can be NULL, if unknown
     16 
     17   returns:
     18     S_OK
     19     E_ABORT  : Break by user
     20     another error codes
     21   */
     22 };
     23 
     24 CODER_INTERFACE(ICompressCoder, 0x05)
     25 {
     26   STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
     27       const UInt64 *inSize, const UInt64 *outSize,
     28       ICompressProgressInfo *progress) PURE;
     29 };
     30 
     31 CODER_INTERFACE(ICompressCoder2, 0x18)
     32 {
     33   STDMETHOD(Code)(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams,
     34       ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams,
     35       ICompressProgressInfo *progress) PURE;
     36 };
     37 
     38 /*
     39   ICompressCoder::Code
     40   ICompressCoder2::Code
     41 
     42   returns:
     43     S_OK     : OK
     44     S_FALSE  : data error (for decoders)
     45     E_OUTOFMEMORY : memory allocation error
     46     E_NOTIMPL : unsupported encoding method (for decoders)
     47     another error code : some error. For example, it can be error code received from inStream or outStream function.
     48 
     49   Parameters:
     50     (inStream != NULL)
     51     (outStream != NULL)
     52 
     53     if (inSize != NULL)
     54     {
     55       Encoders in 7-Zip ignore (inSize).
     56       Decoder can use (*inSize) to check that stream was decoded correctly.
     57       Some decoder in 7-Zip check it, if (full_decoding mode was set via ICompressSetFinishMode)
     58     }
     59 
     60     If it's required to limit the reading from input stream (inStream), it can
     61       be done with ISequentialInStream implementation.
     62 
     63     if (outSize != NULL)
     64     {
     65       Encoders in 7-Zip ignore (outSize).
     66       Decoder unpacks no more than (*outSize) bytes.
     67     }
     68 
     69     (progress == NULL) is allowed.
     70 
     71 
     72   Decoding with Code() function
     73   -----------------------------
     74 
     75   You can request some interfaces before decoding
     76    - ICompressSetDecoderProperties2
     77    - ICompressSetFinishMode
     78 
     79   If you need to decode full stream:
     80   {
     81     1) try to set full_decoding mode with ICompressSetFinishMode::SetFinishMode(1);
     82     2) call the Code() function with specified (inSize) and (outSize), if these sizes are known.
     83   }
     84 
     85   If you need to decode only part of stream:
     86   {
     87     1) try to set partial_decoding mode with ICompressSetFinishMode::SetFinishMode(0);
     88     2) Call the Code() function with specified (inSize = NULL) and specified (outSize).
     89   }
     90 
     91   Encoding with Code() function
     92   -----------------------------
     93 
     94   You can request some interfaces :
     95   - ICompressSetCoderProperties   - use it before encoding to set properties
     96   - ICompressWriteCoderProperties - use it before or after encoding to request encoded properties.
     97 
     98   ICompressCoder2 is used when (numInStreams != 1 || numOutStreams != 1)
     99      The rules are similar to ICompressCoder rules
    100 */
    101 
    102 
    103 namespace NCoderPropID
    104 {
    105   enum EEnum
    106   {
    107     kDefaultProp = 0,
    108     kDictionarySize,    // VT_UI4
    109     kUsedMemorySize,    // VT_UI4
    110     kOrder,             // VT_UI4
    111     kBlockSize,         // VT_UI4 or VT_UI8
    112     kPosStateBits,      // VT_UI4
    113     kLitContextBits,    // VT_UI4
    114     kLitPosBits,        // VT_UI4
    115     kNumFastBytes,      // VT_UI4
    116     kMatchFinder,       // VT_BSTR
    117     kMatchFinderCycles, // VT_UI4
    118     kNumPasses,         // VT_UI4
    119     kAlgorithm,         // VT_UI4
    120     kNumThreads,        // VT_UI4
    121     kEndMarker,         // VT_BOOL
    122     kLevel,             // VT_UI4
    123     kReduceSize,        // VT_UI8 : it's estimated size of largest data stream that will be compressed
    124                         //   encoder can use this value to reduce dictionary size and allocate data buffers
    125 
    126     kExpectedDataSize,  // VT_UI8 : for ICompressSetCoderPropertiesOpt :
    127                         //   it's estimated size of current data stream
    128                         //   real data size can differ from that size
    129                         //   encoder can use this value to optimize encoder initialization
    130 
    131     kBlockSize2,        // VT_UI4 or VT_UI8
    132     kCheckSize,         // VT_UI4 : size of digest in bytes
    133     kFilter,            // VT_BSTR
    134     kMemUse             // VT_UI8
    135   };
    136 }
    137 
    138 CODER_INTERFACE(ICompressSetCoderPropertiesOpt, 0x1F)
    139 {
    140   STDMETHOD(SetCoderPropertiesOpt)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) PURE;
    141 };
    142 
    143 CODER_INTERFACE(ICompressSetCoderProperties, 0x20)
    144 {
    145   STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) PURE;
    146 };
    147 
    148 /*
    149 CODER_INTERFACE(ICompressSetCoderProperties, 0x21)
    150 {
    151   STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE;
    152 };
    153 */
    154 
    155 CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22)
    156 {
    157   /* returns:
    158     S_OK
    159     E_NOTIMP      : unsupported properties
    160     E_INVALIDARG  : incorrect (or unsupported) properties
    161     E_OUTOFMEMORY : memory allocation error
    162   */
    163   STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE;
    164 };
    165 
    166 CODER_INTERFACE(ICompressWriteCoderProperties, 0x23)
    167 {
    168   STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream) PURE;
    169 };
    170 
    171 CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24)
    172 {
    173   STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE;
    174 };
    175 
    176 CODER_INTERFACE(ICompressSetCoderMt, 0x25)
    177 {
    178   STDMETHOD(SetNumberOfThreads)(UInt32 numThreads) PURE;
    179 };
    180 
    181 CODER_INTERFACE(ICompressSetFinishMode, 0x26)
    182 {
    183   STDMETHOD(SetFinishMode)(UInt32 finishMode) PURE;
    184 
    185   /* finishMode:
    186     0 : partial decoding is allowed. It's default mode for ICompressCoder::Code(), if (outSize) is defined.
    187     1 : full decoding. The stream must be finished at the end of decoding. */
    188 };
    189 
    190 CODER_INTERFACE(ICompressGetInStreamProcessedSize2, 0x27)
    191 {
    192   STDMETHOD(GetInStreamProcessedSize2)(UInt32 streamIndex, UInt64 *value) PURE;
    193 };
    194 
    195 CODER_INTERFACE(ICompressSetMemLimit, 0x28)
    196 {
    197   STDMETHOD(SetMemLimit)(UInt64 memUsage) PURE;
    198 };
    199 
    200 
    201 
    202 CODER_INTERFACE(ICompressGetSubStreamSize, 0x30)
    203 {
    204   STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE;
    205 
    206   /* returns:
    207     S_OK     : (*value) contains the size or estimated size (can be incorrect size)
    208     S_FALSE  : size is undefined
    209     E_NOTIMP : the feature is not implemented
    210 
    211   Let's (read_size) is size of data that was already read by ISequentialInStream::Read().
    212   The caller should call GetSubStreamSize() after each Read() and check sizes:
    213     if (start_of_subStream + *value < read_size)
    214     {
    215       // (*value) is correct, and it's allowed to call GetSubStreamSize() for next subStream:
    216       start_of_subStream += *value;
    217       subStream++;
    218     }
    219   */
    220 };
    221 
    222 CODER_INTERFACE(ICompressSetInStream, 0x31)
    223 {
    224   STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE;
    225   STDMETHOD(ReleaseInStream)() PURE;
    226 };
    227 
    228 CODER_INTERFACE(ICompressSetOutStream, 0x32)
    229 {
    230   STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE;
    231   STDMETHOD(ReleaseOutStream)() PURE;
    232 };
    233 
    234 /*
    235 CODER_INTERFACE(ICompressSetInStreamSize, 0x33)
    236 {
    237   STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE;
    238 };
    239 */
    240 
    241 CODER_INTERFACE(ICompressSetOutStreamSize, 0x34)
    242 {
    243   STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE;
    244 
    245   /* That function initializes decoder structures.
    246      Call this function only for stream version of decoder.
    247        if (outSize == NULL), then output size is unknown
    248        if (outSize != NULL), then the decoder must stop decoding after (*outSize) bytes. */
    249 };
    250 
    251 CODER_INTERFACE(ICompressSetBufSize, 0x35)
    252 {
    253   STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size) PURE;
    254   STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size) PURE;
    255 };
    256 
    257 CODER_INTERFACE(ICompressInitEncoder, 0x36)
    258 {
    259   STDMETHOD(InitEncoder)() PURE;
    260 
    261   /* That function initializes encoder structures.
    262      Call this function only for stream version of encoder. */
    263 };
    264 
    265 CODER_INTERFACE(ICompressSetInStream2, 0x37)
    266 {
    267   STDMETHOD(SetInStream2)(UInt32 streamIndex, ISequentialInStream *inStream) PURE;
    268   STDMETHOD(ReleaseInStream2)(UInt32 streamIndex) PURE;
    269 };
    270 
    271 /*
    272 CODER_INTERFACE(ICompressSetOutStream2, 0x38)
    273 {
    274   STDMETHOD(SetOutStream2)(UInt32 streamIndex, ISequentialOutStream *outStream) PURE;
    275   STDMETHOD(ReleaseOutStream2)(UInt32 streamIndex) PURE;
    276 };
    277 
    278 CODER_INTERFACE(ICompressSetInStreamSize2, 0x39)
    279 {
    280   STDMETHOD(SetInStreamSize2)(UInt32 streamIndex, const UInt64 *inSize) PURE;
    281 };
    282 */
    283 
    284 
    285 /*
    286   ICompressFilter
    287   Filter() converts as most as possible bytes
    288      returns: (outSize):
    289        if (outSize <= size) : Filter have converted outSize bytes
    290        if (outSize >  size) : Filter have not converted anything.
    291            and it needs at least outSize bytes to convert one block
    292            (it's for crypto block algorithms).
    293 */
    294 
    295 #define INTERFACE_ICompressFilter(x) \
    296   STDMETHOD(Init)() x; \
    297   STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) x; \
    298 
    299 CODER_INTERFACE(ICompressFilter, 0x40)
    300 {
    301   INTERFACE_ICompressFilter(PURE);
    302 };
    303 
    304 
    305 CODER_INTERFACE(ICompressCodecsInfo, 0x60)
    306 {
    307   STDMETHOD(GetNumMethods)(UInt32 *numMethods) PURE;
    308   STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE;
    309   STDMETHOD(CreateDecoder)(UInt32 index, const GUID *iid, void **coder) PURE;
    310   STDMETHOD(CreateEncoder)(UInt32 index, const GUID *iid, void **coder) PURE;
    311 };
    312 
    313 CODER_INTERFACE(ISetCompressCodecsInfo, 0x61)
    314 {
    315   STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo) PURE;
    316 };
    317 
    318 CODER_INTERFACE(ICryptoProperties, 0x80)
    319 {
    320   STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE;
    321   STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE;
    322 };
    323 
    324 /*
    325 CODER_INTERFACE(ICryptoResetSalt, 0x88)
    326 {
    327   STDMETHOD(ResetSalt)() PURE;
    328 };
    329 */
    330 
    331 CODER_INTERFACE(ICryptoResetInitVector, 0x8C)
    332 {
    333   STDMETHOD(ResetInitVector)() PURE;
    334 
    335   /* Call ResetInitVector() only for encoding.
    336      Call ResetInitVector() before encoding and before WriteCoderProperties().
    337      Crypto encoder can create random IV in that function. */
    338 };
    339 
    340 CODER_INTERFACE(ICryptoSetPassword, 0x90)
    341 {
    342   STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE;
    343 };
    344 
    345 CODER_INTERFACE(ICryptoSetCRC, 0xA0)
    346 {
    347   STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE;
    348 };
    349 
    350 
    351 namespace NMethodPropID
    352 {
    353   enum EEnum
    354   {
    355     kID,
    356     kName,
    357     kDecoder,
    358     kEncoder,
    359     kPackStreams,
    360     kUnpackStreams,
    361     kDescription,
    362     kDecoderIsAssigned,
    363     kEncoderIsAssigned,
    364     kDigestSize
    365   };
    366 }
    367 
    368 
    369 #define INTERFACE_IHasher(x) \
    370   STDMETHOD_(void, Init)() throw() x; \
    371   STDMETHOD_(void, Update)(const void *data, UInt32 size) throw() x; \
    372   STDMETHOD_(void, Final)(Byte *digest) throw() x; \
    373   STDMETHOD_(UInt32, GetDigestSize)() throw() x; \
    374 
    375 CODER_INTERFACE(IHasher, 0xC0)
    376 {
    377   INTERFACE_IHasher(PURE)
    378 };
    379 
    380 CODER_INTERFACE(IHashers, 0xC1)
    381 {
    382   STDMETHOD_(UInt32, GetNumHashers)() PURE;
    383   STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE;
    384   STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher) PURE;
    385 };
    386 
    387 extern "C"
    388 {
    389   typedef HRESULT (WINAPI *Func_GetNumberOfMethods)(UInt32 *numMethods);
    390   typedef HRESULT (WINAPI *Func_GetMethodProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
    391   typedef HRESULT (WINAPI *Func_CreateDecoder)(UInt32 index, const GUID *iid, void **outObject);
    392   typedef HRESULT (WINAPI *Func_CreateEncoder)(UInt32 index, const GUID *iid, void **outObject);
    393 
    394   typedef HRESULT (WINAPI *Func_GetHashers)(IHashers **hashers);
    395 
    396   typedef HRESULT (WINAPI *Func_SetCodecs)(ICompressCodecsInfo *compressCodecsInfo);
    397 }
    398 
    399 #endif
    400