]> Pileus Git - grits/blob - src/wsr88ddec.c
cleanup
[grits] / src / wsr88ddec.c
1 /*
2  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
3  * 
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.
8  * 
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.
13  * 
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/>.
16  */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <stdint.h>
21 #include <err.h>
22 #include <arpa/inet.h>
23 #include <bzlib.h>
24
25 #define debug(...) fprintf(stderr, __VA_ARGS__);
26
27 char *bunzip2(char *input, int input_len, int *output_len)
28 {
29         bz_stream *stream = calloc(1, sizeof(bz_stream));
30
31         switch (BZ2_bzDecompressInit(stream, 0, 0)) {
32         case BZ_CONFIG_ERROR: err(1, "the library has been mis-compiled");
33         case BZ_PARAM_ERROR:  err(1, "Parameter error");
34         case BZ_MEM_ERROR:    err(1, "insufficient memory is available");
35         //case BZ_OK:           debug("success\n"); break;
36         //default:              debug("unknown\n"); break;
37         }
38
39         int   status;
40         int   output_size = 512;
41         char *output      = NULL;
42
43         do {
44                 stream->next_in   = input       + stream->total_in_lo32;
45                 stream->avail_in  = input_len   - stream->total_in_lo32;
46                 output_size *= 2;
47                 output       = realloc(output, output_size);
48                 //debug("alloc %d\n", output_size);
49                 stream->next_out  = output      + stream->total_out_lo32;
50                 stream->avail_out = output_size - stream->total_out_lo32;
51                 //debug("decompressing..\n"
52                 //      "  next_in   = %p\n"
53                 //      "  avail_in  = %u\n"
54                 //      "  next_out  = %p\n"
55                 //      "  avail_out = %u\n",
56                 //      stream->next_in,
57                 //      stream->avail_in,
58                 //      stream->next_out,
59                 //      stream->avail_out);
60         } while ((status = BZ2_bzDecompress(stream)) == BZ_OK && output_size < 1024*1024);
61
62         // debug("done with status %d = %d\n", status, BZ_STREAM_END);
63
64         *output_len = stream->total_out_lo32;
65         BZ2_bzDecompressEnd(stream);
66         return output;
67 }
68
69 int main(int argc, char **argv)
70 {
71         if (argc != 3) {
72                 printf("usage: %s <input> <output>\n", argv[0]);
73                 return 0;
74         }
75
76         FILE *input  = fopen(argv[1], "r");
77         FILE *output = fopen(argv[2], "w+");
78         if (!input)  err(1, "error opening input");
79         if (!output) err(1, "error opening output");
80
81         int st;
82         int size = 0;
83         char *buf = malloc(24);
84
85         /* Clear header */
86         //debug("reading header\n");
87         if (!fread (buf, 24, 1, input))
88                 err(1, "error reading header");
89         if (!fwrite(buf, 24, 1, output))
90                 err(1, "error writing header");
91
92         //debug("reading body\n");
93         while ((st = fread(&size, 1, 4, input))) {
94                 //debug("size=%08x\n", size);
95                 //debug("read %u bytes\n", st);
96                 //fwrite(&size, 1, 4, output); // DEBUG
97                 size = abs(ntohl(size));
98                 if (size < 0)
99                         return 0;
100                 //debug("size = %x\n", size);
101                 if (size > 20*1024*1024)
102                         err(1, "sanity check failed, buf is to big: %d", size);
103                 buf = realloc(buf, size);
104                 if (!fread(buf, size, 1, input))
105                         err(1, "error reading data");
106                 //fwrite(buf, 1, size, output); // DEBUG
107
108                 int dec_len;
109                 char *dec = bunzip2(buf, size, &dec_len);
110                 // debug("decompressed %u bytes\n", dec_len);
111                 if (!fwrite(dec, 1, dec_len, output))
112                         err(1, "error writing data");
113                 free(dec);
114         }
115
116         return 0;
117 }