-
-
Save arq5x/5315739 to your computer and use it in GitHub Desktop.
# compile | |
$ g++ zlib-example.cpp -lz -o zlib-example | |
# run | |
$ ./zlib-example | |
Uncompressed size is: 36 | |
Uncompressed string is: Hello Hello Hello Hello Hello Hello! | |
---------- | |
Compressed size is: 13 | |
Compressed string is: x��H���W��G*2 | |
---------- | |
Uncompressed size is: 36 | |
Uncompressed string is: Hello Hello Hello Hello Hello Hello! |
#include <stdio.h> | |
#include <string.h> // for strlen | |
#include <assert.h> | |
#include "zlib.h" | |
// adapted from: http://stackoverflow.com/questions/7540259/deflate-and-inflate-zlib-h-in-c | |
int main(int argc, char* argv[]) | |
{ | |
// original string len = 36 | |
char a[50] = "Hello Hello Hello Hello Hello Hello!"; | |
// placeholder for the compressed (deflated) version of "a" | |
char b[50]; | |
// placeholder for the UNcompressed (inflated) version of "b" | |
char c[50]; | |
printf("Uncompressed size is: %lu\n", strlen(a)); | |
printf("Uncompressed string is: %s\n", a); | |
printf("\n----------\n\n"); | |
// STEP 1. | |
// deflate a into b. (that is, compress a into b) | |
// zlib struct | |
z_stream defstream; | |
defstream.zalloc = Z_NULL; | |
defstream.zfree = Z_NULL; | |
defstream.opaque = Z_NULL; | |
// setup "a" as the input and "b" as the compressed output | |
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 | |
// the actual compression work. | |
deflateInit(&defstream, Z_BEST_COMPRESSION); | |
deflate(&defstream, Z_FINISH); | |
deflateEnd(&defstream); | |
// This is one way of getting the size of the output | |
printf("Compressed size is: %lu\n", strlen(b)); | |
printf("Compressed string is: %s\n", b); | |
printf("\n----------\n\n"); | |
// STEP 2. | |
// inflate b into c | |
// zlib struct | |
z_stream infstream; | |
infstream.zalloc = Z_NULL; | |
infstream.zfree = Z_NULL; | |
infstream.opaque = Z_NULL; | |
// setup "b" as the input and "c" as the compressed output | |
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 | |
// the actual DE-compression work. | |
inflateInit(&infstream); | |
inflate(&infstream, Z_NO_FLUSH); | |
inflateEnd(&infstream); | |
printf("Uncompressed size is: %lu\n", strlen(c)); | |
printf("Uncompressed string is: %s\n", c); | |
// make sure uncompressed is exactly equal to original. | |
assert(strcmp(a,c)==0); | |
return 0; | |
} |
Thanks a lot for the comment of @hitxiang, it's really helpful.
line 45 should be
printf("Compressed size is: %lu\n", defstream.total_out);
I was looking for a quick example and found this.
Very helpful, thanks!
I have modified your code to use random string by merging another example i found for random string generation; i found that with random string generated the compression doesn't work; meaning compressed and uncompressed length are same ; furthermore compressing compressed string always results in 3 less chars from tail . with default "hello" string as in original example it does compress and results are identical as you have shown.
do you see any reason, why this code should fail for random strings?
#include <stdio.h>
#include <string.h> // for strlen
#include <assert.h>
#include "zlib.h"
//#include <random.h>
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
// adapted from: http://stackoverflow.com/questions/7540259/deflate-and-inflate-zlib-h-in-c
static const char alphanum[] =
"0123456789"
"!@#$%^&*"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
int stringLength = sizeof(alphanum) - 1;
int length = 50;
int main(int argc, char* argv[])
{
// original string len = 36
//char a[50] = "Hello Hello Hello Hello Hello Hello!";
char a[length];
// placeholder for the compressed (deflated) version of "a"
char b[length];
// placeholder for the UNcompressed (inflated) version of "b"
char c[length];
srand(time(0));
//std::string a;
for(unsigned int j = 0; j < 1; ++j)
{
//a = "";
for(unsigned int i = 0; i < length ; ++i)
{
a[i]= alphanum[rand() % stringLength];
}
//char a[50]="Hello Hello Hello Hello Hello Hello!";
printf("Uncompressed size is: %lu\n", strlen(a));
printf("Uncompressed string is: %s\n", a);
printf("\n----------\n\n");
// STEP 1.
// deflate a into b. (that is, compress a into b)
// zlib struct
z_stream defstream;
defstream.zalloc = Z_NULL;
defstream.zfree = Z_NULL;
defstream.opaque = Z_NULL;
// setup "a" as the input and "b" as the compressed output
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
// the actual compression work.
deflateInit(&defstream, Z_BEST_COMPRESSION);
deflate(&defstream, Z_FINISH);
deflateEnd(&defstream);
// This is one way of getting the size of the output
printf("Compressed size is: %lu\n", strlen(b));
printf("Compressed string is: %s\n", b);
printf("\n----------\n\n");
// STEP 2.
// inflate b into c
// zlib struct
z_stream infstream;
infstream.zalloc = Z_NULL;
infstream.zfree = Z_NULL;
infstream.opaque = Z_NULL;
// setup "b" as the input and "c" as the compressed output
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
// the actual DE-compression work.
inflateInit(&infstream);
inflate(&infstream, Z_NO_FLUSH);
inflateEnd(&infstream);
printf("Uncompressed size is: %lu\n", strlen(c));
printf("Uncompressed string is: %s\n", c);
// make sure uncompressed is exactly equal to original.
}
return 0;
}
and results are
./c.out
Uncompressed size is: 50
Uncompressed string is: i5dY0LNq4^yilrkQqJYuW037$u^CDcw^hlzu^NwNou%Zx!8zfg
----------
Compressed size is: 50
706W)�svI.���*���/U��P��4M�4�+4���)�,�
----------
Uncompressed size is: 47
Uncompressed string is: i5dY0LNq4^yilrkQqJYuW037$u^CDcw^hlzu^NwNou%Zx!8
Your length of array should be 51.
does this run on windows ?
when i am running this code this in giving me this error
error C2275: 'z_stream' : illegal use of this type as an expression
be ware using strlen() with binary data
// defstream.avail_in = (uInt)strlen(a)+1;
How to execute these programs in windows
does this run on windows ?
no ig
How to execute these programs in windows
install windows subsystem for linux and run the code from the linux environment
Input File: file size: 52946 Aug 23 17:23 RGB_16bits_palette_sample_image.png
Output Comp File: file size: 52972 Aug 23 17:35 zlib_comp_16bits.j2k
Output DeComp File: file size: 52946 Aug 23 17:35 zlib_decomp_16bits.png
Why the output Compressed file size becoming greater then the ( 52972 > 52946) Input file size ?
It's normal.
recompressing data almost always increases the size.
Is this possible without the array length? like instead of [90]
we could have []
?
Yes. without array length
use const char* myvar;
How do I use this dynamically without knowing the output size, (when decompressing)
@anasouardini Did you find any answer?
strlen should be replaced by infstream.total_out
printf("Uncompressed size is: %lu\n", infstream.total_out);
printf("Uncompressed string is: %.*s\n", infstream.total_out, c);