• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // ICoder.h
2 
3 #ifndef ZIP7_INC_ICODER_H
4 #define ZIP7_INC_ICODER_H
5 
6 #include "IStream.h"
7 
8 Z7_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))
16 Z7_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))
31 Z7_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))
37 Z7_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 
104 namespace 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))
171 Z7_IFACE_CONSTR_CODER(ICompressSetCoderPropertiesOpt, 0x1F)
172 
173 
174 #define Z7_IFACEM_ICompressSetCoderProperties(x) \
175   x(SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps))
176 Z7_IFACE_CONSTR_CODER(ICompressSetCoderProperties, 0x20)
177 
178 /*
179 #define Z7_IFACEM_ICompressSetDecoderProperties(x) \
180   x(SetDecoderProperties(ISequentialInStream *inStream))
181 Z7_IFACE_CONSTR_CODER(ICompressSetDecoderProperties, 0x21)
182 */
183 
184 #define Z7_IFACEM_ICompressSetDecoderProperties2(x) \
185   x(SetDecoderProperties2(const Byte *data, UInt32 size))
186 Z7_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))
197 Z7_IFACE_CONSTR_CODER(ICompressWriteCoderProperties, 0x23)
198 
199 #define Z7_IFACEM_ICompressGetInStreamProcessedSize(x) \
200   x(GetInStreamProcessedSize(UInt64 *value))
201 Z7_IFACE_CONSTR_CODER(ICompressGetInStreamProcessedSize, 0x24)
202 
203 #define Z7_IFACEM_ICompressSetCoderMt(x) \
204   x(SetNumberOfThreads(UInt32 numThreads))
205 Z7_IFACE_CONSTR_CODER(ICompressSetCoderMt, 0x25)
206 
207 #define Z7_IFACEM_ICompressSetFinishMode(x) \
208   x(SetFinishMode(UInt32 finishMode))
209 Z7_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))
216 Z7_IFACE_CONSTR_CODER(ICompressGetInStreamProcessedSize2, 0x27)
217 
218 #define Z7_IFACEM_ICompressSetMemLimit(x) \
219   x(SetMemLimit(UInt64 memUsage))
220 Z7_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))
234 Z7_IFACE_CONSTR_CODER(ICompressReadUnusedFromInBuf, 0x29)
235 
236 
237 #define Z7_IFACEM_ICompressGetSubStreamSize(x) \
238   x(GetSubStreamSize(UInt64 subStream, UInt64 *value))
239 Z7_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())
257 Z7_IFACE_CONSTR_CODER(ICompressSetInStream, 0x31)
258 
259 #define Z7_IFACEM_ICompressSetOutStream(x) \
260   x(SetOutStream(ISequentialOutStream *outStream)) \
261   x(ReleaseOutStream())
262 Z7_IFACE_CONSTR_CODER(ICompressSetOutStream, 0x32)
263 
264 /*
265 #define Z7_IFACEM_ICompressSetInStreamSize(x) \
266   x(SetInStreamSize(const UInt64 *inSize)) \
267 Z7_IFACE_CONSTR_CODER(ICompressSetInStreamSize, 0x33)
268 */
269 
270 #define Z7_IFACEM_ICompressSetOutStreamSize(x) \
271   x(SetOutStreamSize(const UInt64 *outSize))
272 Z7_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 
282 Z7_IFACE_CONSTR_CODER(ICompressSetBufSize, 0x35)
283 
284 #define Z7_IFACEM_ICompressInitEncoder(x) \
285   x(InitEncoder())
286 Z7_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))
293 Z7_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))
299 Z7_IFACE_CONSTR_CODER(ICompressSetOutStream2, 0x38)
300 
301 #define Z7_IFACEM_ICompressSetInStreamSize2(x) \
302   x(SetInStreamSize2(UInt32 streamIndex, const UInt64 *inSize))
303 Z7_IFACE_CONSTR_CODER(ICompressSetInStreamSize2, 0x39)
304 */
305 
306 /*
307 #define Z7_IFACEM_ICompressInSubStreams(x) \
308   x(GetNextInSubStream(UInt64 *streamIndexRes, ISequentialInStream **stream))
309 Z7_IFACE_CONSTR_CODER(ICompressInSubStreams, 0x3A)
310 
311 #define Z7_IFACEM_ICompressOutSubStreams(x) \
312   x(GetNextOutSubStream(UInt64 *streamIndexRes, ISequentialOutStream **stream))
313 Z7_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))
362 Z7_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))
370 Z7_IFACE_CONSTR_CODER(ICompressCodecsInfo, 0x60)
371 
372 #define Z7_IFACEM_ISetCompressCodecsInfo(x) \
373   x(SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo))
374 Z7_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))
379 Z7_IFACE_CONSTR_CODER(ICryptoProperties, 0x80)
380 
381 /*
382   x(ResetSalt())
383 Z7_IFACE_CONSTR_CODER(ICryptoResetSalt, 0x88)
384 */
385 
386 #define Z7_IFACEM_ICryptoResetInitVector(x) \
387   x(ResetInitVector())
388 Z7_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))
395 Z7_IFACE_CONSTR_CODER(ICryptoSetPassword, 0x90)
396 
397 #define Z7_IFACEM_ICryptoSetCRC(x) \
398   x(CryptoSetCRC(UInt32 crc))
399 Z7_IFACE_CONSTR_CODER(ICryptoSetCRC, 0xA0)
400 
401 
402 namespace 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 
420 namespace 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 
440 namespace 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())
455 Z7_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))
461 Z7_IFACE_CONSTR_CODER(IHashers, 0xC1)
462 
463 extern "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 
476 Z7_PURE_INTERFACES_END
477 #endif
478