2 * Copyright (C) 2009-2011 Andy Spencer <andy753421@gmail.com>
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #define SANITY_MAX_SIZE 50*1024*1024 // 50 MB/bzip
23 char *bunzip2(char *input, int input_len, int *output_len)
25 bz_stream *stream = g_new0(bz_stream, 1);
27 switch (BZ2_bzDecompressInit(stream, 0, 0)) {
28 case BZ_CONFIG_ERROR: g_error("the library has been mis-compiled");
29 case BZ_PARAM_ERROR: g_error("Parameter error");
30 case BZ_MEM_ERROR: g_error("insufficient memory is available");
31 //case BZ_OK: g_debug("success"); break;
32 //default: g_debug("unknown"); break;
36 int output_size = 512;
40 stream->next_in = input + stream->total_in_lo32;
41 stream->avail_in = input_len - stream->total_in_lo32;
43 output = g_realloc(output, output_size);
44 //g_debug("alloc %d", output_size);
45 stream->next_out = output + stream->total_out_lo32;
46 stream->avail_out = output_size - stream->total_out_lo32;
47 //g_debug("decompressing..\n"
55 // stream->avail_out);
56 } while ((status = BZ2_bzDecompress(stream)) == BZ_OK && output_size < SANITY_MAX_SIZE);
58 //g_debug("done with status %d = %d", status, BZ_STREAM_END);
60 *output_len = stream->total_out_lo32;
61 BZ2_bzDecompressEnd(stream);
65 int main(int argc, char **argv)
68 g_print("usage: %s <input> <output>\n", argv[0]);
72 FILE *input = fopen(argv[1], "rb");
73 FILE *output = fopen(argv[2], "wb+");
74 if (!input) g_error("error opening input");
75 if (!output) g_error("error opening output");
79 char *buf = g_malloc(24);
82 //g_debug("reading header");
83 if (!fread (buf, 24, 1, input))
84 g_error("error reading header");
85 if (!fwrite(buf, 24, 1, output))
86 g_error("error writing header");
88 //g_debug("reading body");
89 while ((st = fread(&size, 1, 4, input))) {
90 //g_debug("size=%08x", size);
91 //g_debug("read %u bytes", st);
92 //fwrite(&size, 1, 4, output); // DEBUG
93 size = ABS(g_ntohl(size));
96 //g_debug("size = %x", size);
97 if (size > SANITY_MAX_SIZE)
98 g_error("sanity check failed, buf is to big: %d", size);
99 buf = g_realloc(buf, size);
100 if (fread(buf, 1, size, input) != size)
101 g_error("error reading data");
102 //fwrite(buf, 1, size, output); // DEBUG
105 char *dec = bunzip2(buf, size, &dec_len);
106 //g_debug("decompressed %u bytes", dec_len);
107 if (fwrite(dec, 1, dec_len, output) != dec_len)
108 g_error("error writing data");
110 //g_debug("decompressed %-6x -> %x", size, dec_len);