xref: /third_party/lzma/CPP/7zip/ICoder.h (revision 370b324c)
1// ICoder.h
2
3#ifndef ZIP7_INC_ICODER_H
4#define ZIP7_INC_ICODER_H
5
6#include "IStream.h"
7
8Z7_PURE_INTERFACES_BEGIN
9
10#define Z7_IFACE_CONSTR_CODER(i, n) \
11  Z7_DECL_IFACE_7ZIP(i, 4, n) \
12  { Z7_IFACE_COM7_PURE(i) };
13
14#define Z7_IFACEM_ICompressProgressInfo(x) \
15  x(SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize))
16Z7_IFACE_CONSTR_CODER(ICompressProgressInfo, 0x04)
17  /*
18    SetRatioInfo()
19     (inSize)  can be NULL, if unknown
20     (outSize) can be NULL, if unknown
21  returns:
22    S_OK
23    E_ABORT  : Break by user
24    another error codes
25  */
26
27#define Z7_IFACEM_ICompressCoder(x) \
28  x(Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, \
29      const UInt64 *inSize, const UInt64 *outSize, \
30      ICompressProgressInfo *progress))
31Z7_IFACE_CONSTR_CODER(ICompressCoder, 0x05)
32
33#define Z7_IFACEM_ICompressCoder2(x) \
34  x(Code(ISequentialInStream * const *inStreams, const UInt64  *const *inSizes, UInt32 numInStreams, \
35      ISequentialOutStream *const *outStreams, const UInt64 *const *outSizes, UInt32 numOutStreams, \
36      ICompressProgressInfo *progress))
37Z7_IFACE_CONSTR_CODER(ICompressCoder2, 0x18)
38
39/*
40  ICompressCoder::Code
41  ICompressCoder2::Code
42
43  returns:
44    S_OK     : OK
45    S_FALSE  : data error (for decoders)
46    E_OUTOFMEMORY : memory allocation error
47    E_NOTIMPL : unsupported encoding method (for decoders)
48    another error code : some error. For example, it can be error code received from inStream or outStream function.
49
50  Parameters:
51    (inStream != NULL)
52    (outStream != NULL)
53
54    if (inSize != NULL)
55    {
56      Encoders in 7-Zip ignore (inSize).
57      Decoder can use (*inSize) to check that stream was decoded correctly.
58      Some decoders in 7-Zip check it, if (full_decoding mode was set via ICompressSetFinishMode)
59    }
60
61    If it's required to limit the reading from input stream (inStream), it can
62      be done with ISequentialInStream implementation.
63
64    if (outSize != NULL)
65    {
66      Encoders in 7-Zip ignore (outSize).
67      Decoder unpacks no more than (*outSize) bytes.
68    }
69
70    (progress == NULL) is allowed.
71
72
73  Decoding with Code() function
74  -----------------------------
75
76  You can request some interfaces before decoding
77   - ICompressSetDecoderProperties2
78   - ICompressSetFinishMode
79
80  If you need to decode full stream:
81  {
82    1) try to set full_decoding mode with ICompressSetFinishMode::SetFinishMode(1);
83    2) call the Code() function with specified (inSize) and (outSize), if these sizes are known.
84  }
85
86  If you need to decode only part of stream:
87  {
88    1) try to set partial_decoding mode with ICompressSetFinishMode::SetFinishMode(0);
89    2) Call the Code() function with specified (inSize = NULL) and specified (outSize).
90  }
91
92  Encoding with Code() function
93  -----------------------------
94
95  You can request some interfaces :
96  - ICompressSetCoderProperties   - use it before encoding to set properties
97  - ICompressWriteCoderProperties - use it before or after encoding to request encoded properties.
98
99  ICompressCoder2 is used when (numInStreams != 1 || numOutStreams != 1)
100     The rules are similar to ICompressCoder rules
101*/
102
103
104namespace NCoderPropID
105{
106  enum EEnum
107  {
108    kDefaultProp = 0,
109    kDictionarySize,    // VT_UI4
110    kUsedMemorySize,    // VT_UI4
111    kOrder,             // VT_UI4
112    kBlockSize,         // VT_UI4 or VT_UI8
113    kPosStateBits,      // VT_UI4
114    kLitContextBits,    // VT_UI4
115    kLitPosBits,        // VT_UI4
116    kNumFastBytes,      // VT_UI4
117    kMatchFinder,       // VT_BSTR
118    kMatchFinderCycles, // VT_UI4
119    kNumPasses,         // VT_UI4
120    kAlgorithm,         // VT_UI4
121    kNumThreads,        // VT_UI4
122    kEndMarker,         // VT_BOOL
123    kLevel,             // VT_UI4
124    kReduceSize,        // VT_UI8 : it's estimated size of largest data stream that will be compressed
125                        //   encoder can use this value to reduce dictionary size and allocate data buffers
126
127    kExpectedDataSize,  // VT_UI8 : for ICompressSetCoderPropertiesOpt :
128                        //   it's estimated size of current data stream
129                        //   real data size can differ from that size
130                        //   encoder can use this value to optimize encoder initialization
131
132    kBlockSize2,        // VT_UI4 or VT_UI8
133    kCheckSize,         // VT_UI4 : size of digest in bytes
134    kFilter,            // VT_BSTR
135    kMemUse,            // VT_UI8
136    kAffinity,          // VT_UI8
137    kBranchOffset,      // VT_UI4
138    kHashBits,          // VT_UI4
139    /*
140    // kHash3Bits,          // VT_UI4
141    // kHash2Bits,          // VT_UI4
142    // kChainBits,         // VT_UI4
143    kChainSize,         // VT_UI4
144    kNativeLevel,       // VT_UI4
145    kFast,              // VT_UI4
146    kMinMatch,          // VT_UI4 The minimum slen is 3 and the maximum is 7.
147    kOverlapLog,        // VT_UI4 The minimum ovlog is 0 and the maximum is 9.  (default: 6)
148    kRowMatchFinder,    // VT_BOOL
149    kLdmEnable,         // VT_BOOL
150    // kLdmWindowSizeLog,  // VT_UI4
151    kLdmWindowSize,     // VT_UI4
152    kLdmHashLog,        // VT_UI4 The minimum ldmhlog is 6 and the maximum is 26 (default: 20).
153    kLdmMinMatchLength, // VT_UI4 The minimum ldmslen is 4 and the maximum is 4096 (default: 64).
154    kLdmBucketSizeLog,  // VT_UI4 The minimum ldmblog is 0 and the maximum is 8 (default: 3).
155    kLdmHashRateLog,    // VT_UI4 The default value is wlog - ldmhlog.
156    kWriteUnpackSizeFlag, // VT_BOOL
157    kUsePledged,        // VT_BOOL
158    kUseSizeHintPledgedForSmall, // VT_BOOL
159    kUseSizeHintForEach, // VT_BOOL
160    kUseSizeHintGlobal, // VT_BOOL
161    kParamSelectMode,   // VT_UI4
162    // kSearchLog,         // VT_UI4 The minimum slog is 1 and the maximum is 26
163    // kTargetLen,         // VT_UI4 The minimum tlen is 0 and the maximum is 999.
164    */
165    k_NUM_DEFINED
166  };
167}
168
169#define Z7_IFACEM_ICompressSetCoderPropertiesOpt(x) \
170  x(SetCoderPropertiesOpt(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps))
171Z7_IFACE_CONSTR_CODER(ICompressSetCoderPropertiesOpt, 0x1F)
172
173
174#define Z7_IFACEM_ICompressSetCoderProperties(x) \
175  x(SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps))
176Z7_IFACE_CONSTR_CODER(ICompressSetCoderProperties, 0x20)
177
178/*
179#define Z7_IFACEM_ICompressSetDecoderProperties(x) \
180  x(SetDecoderProperties(ISequentialInStream *inStream))
181Z7_IFACE_CONSTR_CODER(ICompressSetDecoderProperties, 0x21)
182*/
183
184#define Z7_IFACEM_ICompressSetDecoderProperties2(x) \
185  x(SetDecoderProperties2(const Byte *data, UInt32 size))
186Z7_IFACE_CONSTR_CODER(ICompressSetDecoderProperties2, 0x22)
187  /* returns:
188    S_OK
189    E_NOTIMP      : unsupported properties
190    E_INVALIDARG  : incorrect (or unsupported) properties
191    E_OUTOFMEMORY : memory allocation error
192  */
193
194
195#define Z7_IFACEM_ICompressWriteCoderProperties(x) \
196  x(WriteCoderProperties(ISequentialOutStream *outStream))
197Z7_IFACE_CONSTR_CODER(ICompressWriteCoderProperties, 0x23)
198
199#define Z7_IFACEM_ICompressGetInStreamProcessedSize(x) \
200  x(GetInStreamProcessedSize(UInt64 *value))
201Z7_IFACE_CONSTR_CODER(ICompressGetInStreamProcessedSize, 0x24)
202
203#define Z7_IFACEM_ICompressSetCoderMt(x) \
204  x(SetNumberOfThreads(UInt32 numThreads))
205Z7_IFACE_CONSTR_CODER(ICompressSetCoderMt, 0x25)
206
207#define Z7_IFACEM_ICompressSetFinishMode(x) \
208  x(SetFinishMode(UInt32 finishMode))
209Z7_IFACE_CONSTR_CODER(ICompressSetFinishMode, 0x26)
210  /* finishMode:
211    0 : partial decoding is allowed. It's default mode for ICompressCoder::Code(), if (outSize) is defined.
212    1 : full decoding. The stream must be finished at the end of decoding. */
213
214#define Z7_IFACEM_ICompressGetInStreamProcessedSize2(x) \
215  x(GetInStreamProcessedSize2(UInt32 streamIndex, UInt64 *value))
216Z7_IFACE_CONSTR_CODER(ICompressGetInStreamProcessedSize2, 0x27)
217
218#define Z7_IFACEM_ICompressSetMemLimit(x) \
219  x(SetMemLimit(UInt64 memUsage))
220Z7_IFACE_CONSTR_CODER(ICompressSetMemLimit, 0x28)
221
222
223/*
224  ICompressReadUnusedFromInBuf is supported by ICoder object
225  call ReadUnusedFromInBuf() after ICoder::Code(inStream, ...).
226  ICoder::Code(inStream, ...) decodes data, and the ICoder object is allowed
227  to read from inStream to internal buffers more data than minimal data required for decoding.
228  So we can call ReadUnusedFromInBuf() from same ICoder object to read unused input
229  data from the internal buffer.
230  in ReadUnusedFromInBuf(): the Coder is not allowed to use (ISequentialInStream *inStream) object, that was sent to ICoder::Code().
231*/
232#define Z7_IFACEM_ICompressReadUnusedFromInBuf(x) \
233  x(ReadUnusedFromInBuf(void *data, UInt32 size, UInt32 *processedSize))
234Z7_IFACE_CONSTR_CODER(ICompressReadUnusedFromInBuf, 0x29)
235
236
237#define Z7_IFACEM_ICompressGetSubStreamSize(x) \
238  x(GetSubStreamSize(UInt64 subStream, UInt64 *value))
239Z7_IFACE_CONSTR_CODER(ICompressGetSubStreamSize, 0x30)
240  /* returns:
241    S_OK     : (*value) contains the size or estimated size (can be incorrect size)
242    S_FALSE  : size is undefined
243    E_NOTIMP : the feature is not implemented
244  Let's (read_size) is size of data that was already read by ISequentialInStream::Read().
245  The caller should call GetSubStreamSize() after each Read() and check sizes:
246    if (start_of_subStream + *value < read_size)
247    {
248      // (*value) is correct, and it's allowed to call GetSubStreamSize() for next subStream:
249      start_of_subStream += *value;
250      subStream++;
251    }
252  */
253
254#define Z7_IFACEM_ICompressSetInStream(x) \
255  x(SetInStream(ISequentialInStream *inStream)) \
256  x(ReleaseInStream())
257Z7_IFACE_CONSTR_CODER(ICompressSetInStream, 0x31)
258
259#define Z7_IFACEM_ICompressSetOutStream(x) \
260  x(SetOutStream(ISequentialOutStream *outStream)) \
261  x(ReleaseOutStream())
262Z7_IFACE_CONSTR_CODER(ICompressSetOutStream, 0x32)
263
264/*
265#define Z7_IFACEM_ICompressSetInStreamSize(x) \
266  x(SetInStreamSize(const UInt64 *inSize)) \
267Z7_IFACE_CONSTR_CODER(ICompressSetInStreamSize, 0x33)
268*/
269
270#define Z7_IFACEM_ICompressSetOutStreamSize(x) \
271  x(SetOutStreamSize(const UInt64 *outSize))
272Z7_IFACE_CONSTR_CODER(ICompressSetOutStreamSize, 0x34)
273  /* That function initializes decoder structures.
274     Call this function only for stream version of decoder.
275       if (outSize == NULL), then output size is unknown
276       if (outSize != NULL), then the decoder must stop decoding after (*outSize) bytes. */
277
278#define Z7_IFACEM_ICompressSetBufSize(x) \
279  x(SetInBufSize(UInt32 streamIndex, UInt32 size)) \
280  x(SetOutBufSize(UInt32 streamIndex, UInt32 size))
281
282Z7_IFACE_CONSTR_CODER(ICompressSetBufSize, 0x35)
283
284#define Z7_IFACEM_ICompressInitEncoder(x) \
285  x(InitEncoder())
286Z7_IFACE_CONSTR_CODER(ICompressInitEncoder, 0x36)
287  /* That function initializes encoder structures.
288     Call this function only for stream version of encoder. */
289
290#define Z7_IFACEM_ICompressSetInStream2(x) \
291  x(SetInStream2(UInt32 streamIndex, ISequentialInStream *inStream)) \
292  x(ReleaseInStream2(UInt32 streamIndex))
293Z7_IFACE_CONSTR_CODER(ICompressSetInStream2, 0x37)
294
295/*
296#define Z7_IFACEM_ICompressSetOutStream2(x) \
297  x(SetOutStream2(UInt32 streamIndex, ISequentialOutStream *outStream))
298  x(ReleaseOutStream2(UInt32 streamIndex))
299Z7_IFACE_CONSTR_CODER(ICompressSetOutStream2, 0x38)
300
301#define Z7_IFACEM_ICompressSetInStreamSize2(x) \
302  x(SetInStreamSize2(UInt32 streamIndex, const UInt64 *inSize))
303Z7_IFACE_CONSTR_CODER(ICompressSetInStreamSize2, 0x39)
304*/
305
306/*
307#define Z7_IFACEM_ICompressInSubStreams(x) \
308  x(GetNextInSubStream(UInt64 *streamIndexRes, ISequentialInStream **stream))
309Z7_IFACE_CONSTR_CODER(ICompressInSubStreams, 0x3A)
310
311#define Z7_IFACEM_ICompressOutSubStreams(x) \
312  x(GetNextOutSubStream(UInt64 *streamIndexRes, ISequentialOutStream **stream))
313Z7_IFACE_CONSTR_CODER(ICompressOutSubStreams, 0x3B)
314*/
315
316/*
317  ICompressFilter
318  Filter(Byte *data, UInt32 size)
319  (size)
320     converts as most as possible bytes required for fast processing.
321     Some filters have (smallest_fast_block).
322     For example, (smallest_fast_block == 16) for AES CBC/CTR filters.
323     If data stream is not finished, caller must call Filter() for larger block:
324     where (size >= smallest_fast_block).
325     if (size >= smallest_fast_block)
326     {
327       The filter can leave some bytes at the end of data without conversion:
328       if there are data alignment reasons or speed reasons.
329       The caller can read additional data from stream and call Filter() again.
330     }
331     If data stream was finished, caller can call Filter() for (size < smallest_fast_block)
332
333  (data) parameter:
334     Some filters require alignment for any Filter() call:
335        1) (stream_offset % alignment_size) == (data % alignment_size)
336        2) (alignment_size == 2^N)
337     where (stream_offset) - is the number of bytes that were already filtered before.
338     The callers of Filter() are required to meet these requirements.
339     (alignment_size) can be different:
340           16 : for AES filters
341       4 or 2 : for some branch convert filters
342            1 : for another filters
343     (alignment_size >= 16) is enough for all current filters of 7-Zip.
344     But the caller can use larger (alignment_size).
345     Recommended alignment for (data) of Filter() call is (alignment_size == 64).
346     Also it's recommended to use aligned value for (size):
347       (size % alignment_size == 0),
348     if it's not last call of Filter() for current stream.
349
350  returns: (outSize):
351       if (outSize == 0) : Filter have not converted anything.
352           So the caller can stop processing, if data stream was finished.
353       if (outSize <= size) : Filter have converted outSize bytes
354       if (outSize >  size) : Filter have not converted anything.
355           and it needs at least outSize bytes to convert one block
356           (it's for crypto block algorithms).
357*/
358
359#define Z7_IFACEM_ICompressFilter(x) \
360  x(Init()) \
361  x##2(UInt32, Filter(Byte *data, UInt32 size))
362Z7_IFACE_CONSTR_CODER(ICompressFilter, 0x40)
363
364
365#define Z7_IFACEM_ICompressCodecsInfo(x) \
366  x(GetNumMethods(UInt32 *numMethods)) \
367  x(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \
368  x(CreateDecoder(UInt32 index, const GUID *iid, void* *coder)) \
369  x(CreateEncoder(UInt32 index, const GUID *iid, void* *coder))
370Z7_IFACE_CONSTR_CODER(ICompressCodecsInfo, 0x60)
371
372#define Z7_IFACEM_ISetCompressCodecsInfo(x) \
373  x(SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo))
374Z7_IFACE_CONSTR_CODER(ISetCompressCodecsInfo, 0x61)
375
376#define Z7_IFACEM_ICryptoProperties(x) \
377  x(SetKey(const Byte *data, UInt32 size)) \
378  x(SetInitVector(const Byte *data, UInt32 size))
379Z7_IFACE_CONSTR_CODER(ICryptoProperties, 0x80)
380
381/*
382  x(ResetSalt())
383Z7_IFACE_CONSTR_CODER(ICryptoResetSalt, 0x88)
384*/
385
386#define Z7_IFACEM_ICryptoResetInitVector(x) \
387  x(ResetInitVector())
388Z7_IFACE_CONSTR_CODER(ICryptoResetInitVector, 0x8C)
389  /* Call ResetInitVector() only for encoding.
390     Call ResetInitVector() before encoding and before WriteCoderProperties().
391     Crypto encoder can create random IV in that function. */
392
393#define Z7_IFACEM_ICryptoSetPassword(x) \
394  x(CryptoSetPassword(const Byte *data, UInt32 size))
395Z7_IFACE_CONSTR_CODER(ICryptoSetPassword, 0x90)
396
397#define Z7_IFACEM_ICryptoSetCRC(x) \
398  x(CryptoSetCRC(UInt32 crc))
399Z7_IFACE_CONSTR_CODER(ICryptoSetCRC, 0xA0)
400
401
402namespace NMethodPropID
403{
404  enum EEnum
405  {
406    kID,
407    kName,
408    kDecoder,
409    kEncoder,
410    kPackStreams,
411    kUnpackStreams,
412    kDescription,
413    kDecoderIsAssigned,
414    kEncoderIsAssigned,
415    kDigestSize,
416    kIsFilter
417  };
418}
419
420namespace NModuleInterfaceType
421{
422  /*
423    virtual destructor in IUnknown:
424    - no  : 7-Zip (Windows)
425    - no  : 7-Zip (Linux) (v23) in default mode
426    - yes : p7zip
427    - yes : 7-Zip (Linux) before v23
428    - yes : 7-Zip (Linux) (v23), if Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN is defined
429  */
430  const UInt32 k_IUnknown_VirtDestructor_No  = 0;
431  const UInt32 k_IUnknown_VirtDestructor_Yes = 1;
432  const UInt32 k_IUnknown_VirtDestructor_ThisModule =
433  #if !defined(_WIN32) && defined(Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN)
434    k_IUnknown_VirtDestructor_Yes;
435  #else
436    k_IUnknown_VirtDestructor_No;
437  #endif
438}
439
440namespace NModulePropID
441{
442  enum EEnum
443  {
444    kInterfaceType,   // VT_UI4
445    kVersion          // VT_UI4
446  };
447}
448
449
450#define Z7_IFACEM_IHasher(x) \
451  x##2(void, Init()) \
452  x##2(void, Update(const void *data, UInt32 size)) \
453  x##2(void, Final(Byte *digest)) \
454  x##2(UInt32, GetDigestSize())
455Z7_IFACE_CONSTR_CODER(IHasher, 0xC0)
456
457#define Z7_IFACEM_IHashers(x) \
458  x##2(UInt32, GetNumHashers()) \
459  x(GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value)) \
460  x(CreateHasher(UInt32 index, IHasher **hasher))
461Z7_IFACE_CONSTR_CODER(IHashers, 0xC1)
462
463extern "C"
464{
465  typedef HRESULT (WINAPI *Func_GetNumberOfMethods)(UInt32 *numMethods);
466  typedef HRESULT (WINAPI *Func_GetMethodProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
467  typedef HRESULT (WINAPI *Func_CreateDecoder)(UInt32 index, const GUID *iid, void **outObject);
468  typedef HRESULT (WINAPI *Func_CreateEncoder)(UInt32 index, const GUID *iid, void **outObject);
469
470  typedef HRESULT (WINAPI *Func_GetHashers)(IHashers **hashers);
471
472  typedef HRESULT (WINAPI *Func_SetCodecs)(ICompressCodecsInfo *compressCodecsInfo);
473  typedef HRESULT (WINAPI *Func_GetModuleProp)(PROPID propID, PROPVARIANT *value);
474}
475
476Z7_PURE_INTERFACES_END
477#endif
478