2013-10-04 7 views
6

Компонент TIdComproessorZLib используется для сжатия и декомпрессии в библиотеке Indy Delphi/C++ Builder. Метод CompressStream имеет следующее определение:Где указаны параметры для TIdCompressorZLib.CompressStream метода Indy?

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

Полное описание этих параметров в файле справки является:

CompressStream является публичной переопределяется процедурой. который реализует абстрактную форму виртуального метода, объявленного в классе предков.

AInStream - это поток, содержащий несжатое содержимое, используемое в операции .

AOutStream - это поток, используемый для хранения сжатого содержимого от операции сжатия. AOutStream очищается до вывода сжатого содержимого из операции. Когда AOutStream отключен , поток в AInStream очищается и повторно используется для вывода из операции сжатия.

Используйте ALevel, чтобы указать желаемый уровень сжатия для операции .

Используйте AWindowsBits и AMemLevel для управления площадью памяти , необходимой для сжатия в памяти с использованием библиотеки ZLib.

Используйте AStrategy для управления стратегией RLE-кодирования, используемой в операции сжатия .

значения ALevel, определенные на странице справки для TIdCompressionLevel, но я не могу найти какие-либо признаков того, что значения должны быть использованы для AWindowBits, AMemLevel или AStrategy, которые только целые числа.

Я смотрел в исходном коде, но CompressStream только делегаты IndyCompressStream, который указан в файле справки, как:

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); 

помощь для IndyCompressStream не даже перечислить минимальное описание параметров, CompressStream делает.

Я разыскал файл, где (я думаю) эти константы по умолчанию, указанные в IndyCompressStream жить, источник \ Indy10 \ Protocols \ IdZLibHeaders.pas, и они

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

Однако значение, данное для Z_DEFAULT_COMPRESSION является даже юридическое значение для этого параметра в соответствии с документацией для TIdCompressionLevel

Есть ли какая-то документация где-то о том, что означают AWindowBits, AMemLevel и AStrategy для этого компонента и какие значения разумно использовать для них? Являются ли значения, указанные выше, фактическими рекомендуемыми значениями по умолчанию? Кроме того, исходные файлы включают каталоги indy, indy10 и indyimpl. Какой из них мы должны использовать, чтобы найти источник для текущих компонентов Indy?

Спасибо!

+1

Теперь вот как задать вопрос. Отлично сработано. –

+0

Что с ним делать? –

+0

Имеет ли Indy документацию? –

ответ

4

Вам необходимо будет ознакомиться с документацией zlib в zlib.h.В частности, parameters to deflateInit2().

Почти во всех случаях единственными, с которыми вы должны столкнуться, являются уровень сжатия и оконные биты. Для оконных битов вы обычно оставляете размер окна на 32K (15), но либо добавляете 16 для формата gzip (31), либо отрицаете (-15), чтобы получить формат необработанного дефлята без заголовка или трейлера. Для некоторых специальных видов данных вы можете получить улучшение с другой стратегией сжатия, например. изображения или других числовых массивов данных.

+0

Ничего подобного, если один из авторов zlib ответит на мой вопрос! Благодаря! Единственное, что мне нужно было изменить, это то, что я пытался создать формат gzip, так как ожидал мой сервер, и для этого требуется добавить 16 в windowBits, как описано в ссылке zlib, которую вы указали для deflateInit2(). – nachbar

+0

Ах, да, часто это тоже путается. Я исправлю ответ. –

3

Благодарим вас за комментарии и ответы, особенно Реми и Марк. Я не понял, что единицы Indy являются обертками вокруг zlib и что параметры были определены в библиотеке zlib.

Я пытался создать поток формата gzip для загрузки на сервер, который ожидал gzip.

Вот рабочий код для сжатия и декомпрессии GZIP:

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); 
} 

В частности, заметим, что прохождение -1 для ALevel производит ZLib Error -2, Z_STREAM_ERROR что означает неверный параметр, несмотря на по умолчанию я найдено. Кроме того, AWindowBits обычно составляет от 8 до 15, но добавление 16 дает вам формат gzip, а отрицательные числа дают вам необработанный формат, как описано в документации zlib, на которую ссылается Марк Адлер, один из авторов библиотеки zlib. Я изменил AMemLevel по умолчанию Indy на комментарий Марка Адлера.

Также, как отмечено, функция CompressStreamEx производит сжатие gzip с использованием параметров, включенных в комментарии выше.

Выше было протестировано в RAD Studio XE3. В очередной раз благодарим за помощь!

+0

Оставив 'memLevel' по умолчанию 8, как правило, приводит к лучшему сжатию, благодаря более частому адаптации кодов Хаффмана к данным. –

+0

Спасибо. Я скорректировал код выше, чтобы отразить это, и снова протестирован в RAD Studio XE3. – nachbar

Смежные вопросы