Skip to content

Instantly share code, notes, and snippets.

@vi
Last active May 4, 2017 01:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vi/76c6c9074d253a60852176a352afd92a to your computer and use it in GitHub Desktop.
Save vi/76c6c9074d253a60852176a352afd92a to your computer and use it in GitHub Desktop.
Compress short files with a pre-defined zlib dictionary from command line
#include <stdio.h>
#include <string.h>
#include <zlib.h>
#include <inttypes.h>
#include <assert.h>
uint8_t dict[4096];
size_t dict_size;
uint8_t input[65536];
size_t input_size;
uint8_t output[65536];
int main(int argc, char* argv[])
{
assert(!strcmp(zlibVersion(),ZLIB_VERSION));
if (argc < 3 || !strcmp(argv[1], "--help")) {
printf("Compress short files with a pre-defined zlib dictionary from command line.\n");
printf("Try using some input file as a basis for the dictionary.\n");
printf("Usage:\n");
printf(" zlibdict compress dictfile < input > output\n");
printf(" zlibdict decompress dictfile < input > output\n");
return 1;
}
{
FILE* d;
d = fopen(argv[2], "r");
if (!d) { perror("fopen"); return 1; }
dict_size = fread(dict, 1, sizeof dict, d);
if (!dict_size) {
fprintf(stderr, "Warning: empty dictionary\n");
}
fclose(d);
}
{
input_size = fread(input, 1, sizeof input, stdin);
if (input_size == sizeof input) {
fprintf(stderr, "Warning: input size may be too large\n");
}
}
z_stream s;
memset(&s, 0, sizeof s);
s.zalloc = Z_NULL;
s.zfree = Z_NULL;
s.opaque = Z_NULL;
s.next_in = input;
s.avail_in = input_size;
s.next_out = output;
s.avail_out = sizeof output;
if (!strcmp(argv[1], "compress")) {
if (Z_OK != deflateInit2(&s, 8, Z_DEFLATED, -12, 8, Z_DEFAULT_STRATEGY)) {
fprintf(stderr, "deflateInit2 error\n");
fprintf(stderr, "%s\n", s.msg);
return 2;
}
if (Z_OK != deflateSetDictionary(&s, dict, dict_size)) {
fprintf(stderr, "deflateSetDictionary error\n");
return 3;
}
if (Z_STREAM_END != deflate(&s, Z_FINISH)) {
fprintf(stderr, "deflate error or too large output\n");
return 4;
};
} else
if (!strcmp(argv[1], "decompress")) {
if (Z_OK != inflateInit2(&s, -12)) {
fprintf(stderr, "inflateInit2 error\n");
fprintf(stderr, "%s\n", s.msg);
return 2;
}
if (Z_OK != inflateSetDictionary(&s, dict, dict_size)) {
fprintf(stderr, "inflateSetDictionary error\n");
return 3;
}
if (Z_STREAM_END != inflate(&s, Z_FINISH)) {
fprintf(stderr, "inflate error or too large output\n");
return 4;
};
} else {
fprintf(stderr, "zlibdict: Unknown command %s\n", argv[1]);
return 1;
}
fwrite(output, 1, s.total_out, stdout);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment