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