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