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