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,    // VT_UI4
108     kUsedMemorySize,    // VT_UI4
109     kOrder,             // VT_UI4
110     kBlockSize,         // VT_UI4 or VT_UI8
111     kPosStateBits,      // VT_UI4
112     kLitContextBits,    // VT_UI4
113     kLitPosBits,        // VT_UI4
114     kNumFastBytes,      // VT_UI4
115     kMatchFinder,       // VT_BSTR
116     kMatchFinderCycles, // VT_UI4
117     kNumPasses,         // VT_UI4
118     kAlgorithm,         // VT_UI4
119     kNumThreads,        // VT_UI4
120     kEndMarker,         // VT_BOOL
121     kLevel,             // VT_UI4
122     kReduceSize,        // VT_UI8 : it's estimated size of largest data stream that will be compressed
123                         //   encoder can use this value to reduce dictionary size and allocate data buffers
124 
125     kExpectedDataSize,  // VT_UI8 : for ICompressSetCoderPropertiesOpt :
126                         //   it's estimated size of current data stream
127                         //   real data size can differ from that size
128                         //   encoder can use this value to optimize encoder initialization
129 
130     kBlockSize2,        // VT_UI4 or VT_UI8
131     kCheckSize,         // VT_UI4 : size of digest in bytes
132     kFilter             // VT_BSTR
133   };
134 }
135 
136 CODER_INTERFACE(ICompressSetCoderPropertiesOpt, 0x1F)
137 {
138   STDMETHOD(SetCoderPropertiesOpt)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) PURE;
139 };
140 
141 CODER_INTERFACE(ICompressSetCoderProperties, 0x20)
142 {
143   STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) PURE;
144 };
145 
146 /*
147 CODER_INTERFACE(ICompressSetCoderProperties, 0x21)
148 {
149   STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE;
150 };
151 */
152 
153 CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22)
154 {
155   /* returns:
156     S_OK
157     E_NOTIMP      : unsupported properties
158     E_INVALIDARG  : incorrect (or unsupported) properties
159     E_OUTOFMEMORY : memory allocation error
160   */
161   STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE;
162 };
163 
164 CODER_INTERFACE(ICompressWriteCoderProperties, 0x23)
165 {
166   STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream) PURE;
167 };
168 
169 CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24)
170 {
171   STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE;
172 };
173 
174 CODER_INTERFACE(ICompressSetCoderMt, 0x25)
175 {
176   STDMETHOD(SetNumberOfThreads)(UInt32 numThreads) PURE;
177 };
178 
179 CODER_INTERFACE(ICompressSetFinishMode, 0x26)
180 {
181   STDMETHOD(SetFinishMode)(UInt32 finishMode) PURE;
182 
183   /* finishMode:
184     0 : partial decoding is allowed. It's default mode for ICompressCoder::Code(), if (outSize) is defined.
185     1 : full decoding. The stream must be finished at the end of decoding. */
186 };
187 
188 CODER_INTERFACE(ICompressGetInStreamProcessedSize2, 0x27)
189 {
190   STDMETHOD(GetInStreamProcessedSize2)(UInt32 streamIndex, UInt64 *value) PURE;
191 };
192 
193 
194 CODER_INTERFACE(ICompressGetSubStreamSize, 0x30)
195 {
196   STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE;
197 
198   /* returns:
199     S_OK     : (*value) contains the size or estimated size (can be incorrect size)
200     S_FALSE  : size is undefined
201     E_NOTIMP : the feature is not implemented
202 
203   Let's (read_size) is size of data that was already read by ISequentialInStream::Read().
204   The caller should call GetSubStreamSize() after each Read() and check sizes:
205     if (start_of_subStream + *value < read_size)
206     {
207       // (*value) is correct, and it's allowed to call GetSubStreamSize() for next subStream:
208       start_of_subStream += *value;
209       subStream++;
210     }
211   */
212 };
213 
214 CODER_INTERFACE(ICompressSetInStream, 0x31)
215 {
216   STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE;
217   STDMETHOD(ReleaseInStream)() PURE;
218 };
219 
220 CODER_INTERFACE(ICompressSetOutStream, 0x32)
221 {
222   STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE;
223   STDMETHOD(ReleaseOutStream)() PURE;
224 };
225 
226 /*
227 CODER_INTERFACE(ICompressSetInStreamSize, 0x33)
228 {
229   STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE;
230 };
231 */
232 
233 CODER_INTERFACE(ICompressSetOutStreamSize, 0x34)
234 {
235   STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE;
236 
237   /* That function initializes decoder structures.
238      Call this function only for stream version of decoder.
239        if (outSize == NULL), then output size is unknown
240        if (outSize != NULL), then the decoder must stop decoding after (*outSize) bytes. */
241 };
242 
243 CODER_INTERFACE(ICompressSetBufSize, 0x35)
244 {
245   STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size) PURE;
246   STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size) PURE;
247 };
248 
249 CODER_INTERFACE(ICompressInitEncoder, 0x36)
250 {
251   STDMETHOD(InitEncoder)() PURE;
252 
253   /* That function initializes encoder structures.
254      Call this function only for stream version of encoder. */
255 };
256 
257 CODER_INTERFACE(ICompressSetInStream2, 0x37)
258 {
259   STDMETHOD(SetInStream2)(UInt32 streamIndex, ISequentialInStream *inStream) PURE;
260   STDMETHOD(ReleaseInStream2)(UInt32 streamIndex) PURE;
261 };
262 
263 /*
264 CODER_INTERFACE(ICompressSetOutStream2, 0x38)
265 {
266   STDMETHOD(SetOutStream2)(UInt32 streamIndex, ISequentialOutStream *outStream) PURE;
267   STDMETHOD(ReleaseOutStream2)(UInt32 streamIndex) PURE;
268 };
269 
270 CODER_INTERFACE(ICompressSetInStreamSize2, 0x39)
271 {
272   STDMETHOD(SetInStreamSize2)(UInt32 streamIndex, const UInt64 *inSize) PURE;
273 };
274 */
275 
276 
277 /*
278   ICompressFilter
279   Filter() converts as most as possible bytes
280      returns: (outSize):
281        if (outSize <= size) : Filter have converted outSize bytes
282        if (outSize >  size) : Filter have not converted anything.
283            and it needs at least outSize bytes to convert one block
284            (it's for crypto block algorithms).
285 */
286 
287 #define INTERFACE_ICompressFilter(x) \
288   STDMETHOD(Init)() x; \
289   STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) x; \
290 
291 CODER_INTERFACE(ICompressFilter, 0x40)
292 {
293   INTERFACE_ICompressFilter(PURE);
294 };
295 
296 
297 CODER_INTERFACE(ICompressCodecsInfo, 0x60)
298 {
299   STDMETHOD(GetNumMethods)(UInt32 *numMethods) PURE;
300   STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE;
301   STDMETHOD(CreateDecoder)(UInt32 index, const GUID *iid, void **coder) PURE;
302   STDMETHOD(CreateEncoder)(UInt32 index, const GUID *iid, void **coder) PURE;
303 };
304 
305 CODER_INTERFACE(ISetCompressCodecsInfo, 0x61)
306 {
307   STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo) PURE;
308 };
309 
310 CODER_INTERFACE(ICryptoProperties, 0x80)
311 {
312   STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE;
313   STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE;
314 };
315 
316 /*
317 CODER_INTERFACE(ICryptoResetSalt, 0x88)
318 {
319   STDMETHOD(ResetSalt)() PURE;
320 };
321 */
322 
323 CODER_INTERFACE(ICryptoResetInitVector, 0x8C)
324 {
325   STDMETHOD(ResetInitVector)() PURE;
326 
327   /* Call ResetInitVector() only for encoding.
328      Call ResetInitVector() before encoding and before WriteCoderProperties().
329      Crypto encoder can create random IV in that function. */
330 };
331 
332 CODER_INTERFACE(ICryptoSetPassword, 0x90)
333 {
334   STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE;
335 };
336 
337 CODER_INTERFACE(ICryptoSetCRC, 0xA0)
338 {
339   STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE;
340 };
341 
342 
343 namespace NMethodPropID
344 {
345   enum EEnum
346   {
347     kID,
348     kName,
349     kDecoder,
350     kEncoder,
351     kPackStreams,
352     kUnpackStreams,
353     kDescription,
354     kDecoderIsAssigned,
355     kEncoderIsAssigned,
356     kDigestSize
357   };
358 }
359 
360 
361 #define INTERFACE_IHasher(x) \
362   STDMETHOD_(void, Init)() throw() x; \
363   STDMETHOD_(void, Update)(const void *data, UInt32 size) throw() x; \
364   STDMETHOD_(void, Final)(Byte *digest) throw() x; \
365   STDMETHOD_(UInt32, GetDigestSize)() throw() x; \
366 
367 CODER_INTERFACE(IHasher, 0xC0)
368 {
369   INTERFACE_IHasher(PURE)
370 };
371 
372 CODER_INTERFACE(IHashers, 0xC1)
373 {
374   STDMETHOD_(UInt32, GetNumHashers)() PURE;
375   STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE;
376   STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher) PURE;
377 };
378 
379 extern "C"
380 {
381   typedef HRESULT (WINAPI *Func_GetNumberOfMethods)(UInt32 *numMethods);
382   typedef HRESULT (WINAPI *Func_GetMethodProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
383   typedef HRESULT (WINAPI *Func_CreateDecoder)(UInt32 index, const GUID *iid, void **outObject);
384   typedef HRESULT (WINAPI *Func_CreateEncoder)(UInt32 index, const GUID *iid, void **outObject);
385 
386   typedef HRESULT (WINAPI *Func_GetHashers)(IHashers **hashers);
387 
388   typedef HRESULT (WINAPI *Func_SetCodecs)(ICompressCodecsInfo *compressCodecsInfo);
389 }
390 
391 #endif
392