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