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