Where are the parameters for Indy TIdCompressorZLib.CompressStream Method?

The TIdComproessorZLib component is used for compression and decompression in the Indy Delphi / C ++ Builder library. The CompressStream method has the following definition:

public: virtual __fastcall CompressStream(TStream AInStream, TStream AOutStream, const TIdCompressionLevel ALevel, const int AWindowBits, const int AMemLevel, const int AStrategy); 

A full description of these options in the help file:

CompressStream is a publicly overridden procedure. which implements an abstract virtual method declared in an ancestor class.

AInStream is a stream containing uncompressed content used in a compression operation.

AOutStream is a stream used to store compressed content from a compression operation. AOutStream is flushed before outputting the compressed content from the operation. When AOutStream is omitted, the stream in AInStream is cleared and reused to exit the compression operation.

Use ALevel to specify the desired compression level for the operation.

Use AWindowsBits and AMemLevel to manage the memory required for in-memory compression using the ZLib library.

Use AStrategy to control the RLE coding strategy used in the compression operation.

The ALevel values โ€‹โ€‹are defined on the help page for TIdCompressionLevel, but I cannot find any indication of which values โ€‹โ€‹should be used for AWindowBits, AMemLevel, or AStrategy, which are integers.

I looked at the source code, but CompressStream simply delegates to IndyCompressStream, which is listed in the help file as:

 IndyCompressStream(TStream InStream, TStream OutStream, const int level = Z_DEFAULT_COMPRESSION, const int WinBits = MAX_WBITS, const int MemLevel = MAX_MEM_LEVEL, const int Stratagy = Z_DEFAULT_STRATEGY); 

The Help for IndyCompressStream does not even list the minimum description of the parameters that CompressStream performs.

I looked at the file where (I think) these default constants mentioned in IndyCompressStream live, source \ Indy10 \ Protocols \ IdZLibHeaders.pas, and they

  Z_DEFAULT_STRATEGY = 0; Z_DEFAULT_COMPRESSION = -1; MAX_WBITS = 15; { 32K LZ77 window } MAX_MEM_LEVEL = 9; 

However, the value specified for Z_DEFAULT_COMPRESSION is not even a legal value for this parameter, according to the documentation for TIdCompressionLevel

Is there some kind of documentation somewhere about what AWindowBits, AMemLevel and AStrategy mean for this component and what values โ€‹โ€‹are reasonable to use for them? Are the values โ€‹โ€‹above the actual recommended defaults? In addition, the source files include the indy, indy10 and indyimpl directories. Which one should we use to find the source for the current Indy components?

Thanks!

+6
source share
2 answers

You will need to look at the zlib documentation in zlib.h. In particular, parameters before deflateInit2() .

In almost all cases, the only ones you need to interact with are the compression level and window bits. For window bits, you usually leave the window size at 32K (15), but either add 16 for the gzip format (31) or deny (-15) to get the raw deflate format without a header or trailer. For some special types of data, you can get an improvement with a different compression strategy, for example. images or other numerical data arrays.

+4
source

Thanks for the comments and answers, especially Remy and Mark. I did not understand that Indy units are wrappers around zlib and that the parameters were defined in the zlib library.

I tried to create a gzip format stream for upload to the server that gzip was expecting.

Here is the working code for gzip compression and decompression:

 void __fastcall TForm1::Button1Click(TObject *Sender) { TStringStream* streamIn = new TStringStream(String("This is some data to compress")); TMemoryStream* streamCompressed = new TMemoryStream; TStringStream* streamOut = new TStringStream; /* this also works to compress to gzip format, but you must #include <IdZlib.hpp> CompressStreamEx(streamIn, streamCompressed, Idzlib::clDefault, zsGZip); */ // NOTE: according to docs, you can leave outstream null, and instream // will be replaced and reused, but I could not get that to work IdCompressorZLib1->CompressStream( streamIn, // System::Classes::TStream* AInStream, streamCompressed, // System::Classes::TStream* AOutStream, 1, // const Idzlibcompressorbase::TIdCompressionLevel ALevel, 15 + 16, // const int AWindowBits, -- add 16 to get gzip format 8, // const int AMemLevel, -- see note below 0); // const int AStrategy); streamCompressed->Position = 0; IdCompressorZLib1->DecompressGZipStream(streamCompressed, streamOut); String out = streamOut->DataString; ShowMessage(out); } 

In particular, note that passing -1 for ALevel causes ZLib Error -2, Z_STREAM_ERROR, which means an invalid parameter, despite the default values โ€‹โ€‹found. In addition, AWindowBits is usually between 8 and 15, but adding 16 gives you the gzip format, and negative numbers give you the raw format, as described in the zlib documentation referenced by Mark Adler, one of the authors of the zlib library. I changed Indy's default AMemLevel to Mark Adler comment.

In addition, as noted, the CompressStreamEx function performs gzip compression using the parameters included in the comments above.

Above was tested in RAD Studio XE3. Thanks again for your help!

+3
source

Source: https://habr.com/ru/post/955263/


All Articles