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