спустить и надуть (zlib.h) в C - PullRequest
8 голосов
/ 24 сентября 2011

Я пытаюсь реализовать функции deflate и inflate zlib.h для сжатия и распаковки массива char (не файла).

Я хотел бы знать, правильный ли следующий синтаксис? Я что-то упустил или определил что-то неправильно?

char a[50] = "Hello World!";
char b[50];
char c[50];

// deflate
// zlib struct
z_stream defstream;
defstream.zalloc = Z_NULL;
defstream.zfree = Z_NULL;
defstream.opaque = Z_NULL;
defstream.avail_in = (uInt)sizeof(a); // size of input
defstream.next_in = (Bytef *)a; // input char array
defstream.avail_out = (uInt)sizeof(b); // size of output
defstream.next_out = (Bytef *)b; // output char array

deflateInit(&defstream, Z_DEFAULT_COMPRESSION);
deflate(&defstream, Z_FINISH);
deflateEnd(&defstream);

printf("Deflate:\n%lu\n%s\n", strlen(b), b);

// inflate
// zlib struct
z_stream infstream;
infstream.zalloc = Z_NULL;
infstream.zfree = Z_NULL;
infstream.opaque = Z_NULL;
infstream.avail_in = (uInt)sizeof(b); // size of input
infstream.next_in = (Bytef *)b; // input char array
infstream.avail_out = (uInt)sizeof(c); // size of output
infstream.next_out = (Bytef *)c; // output char array

inflateInit(&infstream);
inflate(&infstream, Z_NO_FLUSH);
inflateEnd(&infstream);

printf("Inflate:\n%lu\n%s\n", strlen(c), c);

Ответы [ 3 ]

25 голосов
/ 19 мая 2012

zlib уже имеет простую функцию надувания / выкачивания, которую вы можете использовать.

char a[50] = "Hello, world!";
char b[50];
char c[50];

uLong ucompSize = strlen(a)+1; // "Hello, world!" + NULL delimiter.
uLong compSize = compressBound(ucompSize);

// Deflate
compress((Bytef *)b, &compSize, (Bytef *)a, ucompSize);

// Inflate
uncompress((Bytef *)c, &ucompSize, (Bytef *)b, compSize);

Если сомневаетесь, ознакомьтесь с zlib manual . Мой код дерьмовый, извините = /

7 голосов
/ 24 сентября 2011

Вы не можете распечатать дефлированный вывод, как это. Это не нулевое окончание. Ты тоже не можешь это сделать.

Поскольку ваш ввод - строка, хотя вы, вероятно, хотите передать только содержимое строки, включая нулевой терминатор. Поэтому установите для vend_in значение strlen (a) + 1.

Вам нужно проверить поля next_out и util_out после вызова deflate, чтобы увидеть, сколько данных было записано в выходной буфер.

См. Документацию здесь под вызовом deflate.

Вот ваш модифицированный код. Обратите внимание, что если вы сжимаете что-то, что не является строкой, вам нужно это изменить, а также с помощью строк, которые вы можете сжать без конечного нуля и добавить обратно после распаковки.

char a[50] = "Hello World!";
char b[50];
char c[50];

// deflate
// zlib struct
z_stream defstream;
defstream.zalloc = Z_NULL;
defstream.zfree = Z_NULL;
defstream.opaque = Z_NULL;
defstream.avail_in = (uInt)strlen(a)+1; // size of input, string + terminator
defstream.next_in = (Bytef *)a; // input char array
defstream.avail_out = (uInt)sizeof(b); // size of output
defstream.next_out = (Bytef *)b; // output char array

deflateInit(&defstream, Z_DEFAULT_COMPRESSION);
deflate(&defstream, Z_FINISH);
deflateEnd(&defstream);

// This is one way of getting the size of the output
printf("Deflated size is: %lu\n", (char*)defstream.next_out - b);

// inflate
// zlib struct
z_stream infstream;
infstream.zalloc = Z_NULL;
infstream.zfree = Z_NULL;
infstream.opaque = Z_NULL;
infstream.avail_in = (uInt)((char*)defstream.next_out - b); // size of input
infstream.next_in = (Bytef *)b; // input char array
infstream.avail_out = (uInt)sizeof(c); // size of output
infstream.next_out = (Bytef *)c; // output char array

inflateInit(&infstream);
inflate(&infstream, Z_NO_FLUSH);
inflateEnd(&infstream);

printf("Inflate:\n%lu\n%s\n", strlen(c), c);
2 голосов
/ 24 сентября 2011

Пример zpipe (http://zlib.net/zpipe.c) в значительной степени покрывает это, просто удалите файл ops (функция с префиксом f), и вы замените in и out буферами в памяти, хотя этого может быть достаточно для только замените in или оставьте буферы как есть в зависимости от вашего использования. Просто обратите внимание, что вам нужно будет сделать размер буфера out изменяемым для учета декомпрессии данных произвольного размера, если вы планируете иметь куски неизвестного размера

...