]> Pileus Git - aweather/blob - src/wsr88ddec.c
Rename aweather-colormap.[ch] to radar-info.[ch]
[aweather] / src / wsr88ddec.c
1 /*
2  * Copyright (C) 2009-2010 Andy Spencer <andy753421@gmail.com>
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 <glib.h>
19 #include <bzlib.h>
20
21 #define SANITY_MAX_SIZE 50*1024*1024 // 50 MB/bzip
22
23 char *bunzip2(char *input, int input_len, int *output_len)
24 {
25         bz_stream *stream = g_new0(bz_stream, 1);
26
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;
33         }
34
35         int   status;
36         int   output_size = 512;
37         char *output      = NULL;
38
39         do {
40                 stream->next_in   = input       + stream->total_in_lo32;
41                 stream->avail_in  = input_len   - stream->total_in_lo32;
42                 output_size *= 2;
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"
48                 //      "  next_in   = %p\n"
49                 //      "  avail_in  = %u\n"
50                 //      "  next_out  = %p\n"
51                 //      "  avail_out = %u",
52                 //      stream->next_in,
53                 //      stream->avail_in,
54                 //      stream->next_out,
55                 //      stream->avail_out);
56         } while ((status = BZ2_bzDecompress(stream)) == BZ_OK && output_size < SANITY_MAX_SIZE);
57
58         //g_debug("done with status %d = %d", status, BZ_STREAM_END);
59
60         *output_len = stream->total_out_lo32;
61         BZ2_bzDecompressEnd(stream);
62         return output;
63 }
64
65 int main(int argc, char **argv)
66 {
67         if (argc != 3) {
68                 g_print("usage: %s <input> <output>\n", argv[0]);
69                 return 0;
70         }
71
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");
76
77         int st;
78         int size = 0;
79         char *buf = g_malloc(24);
80
81         /* Clear header */
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");
87
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));
94                 if (size < 0)
95                         return 0;
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
103
104                 int dec_len;
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");
109                 g_free(dec);
110                 //g_debug("decompressed %-6x -> %x", size, dec_len);
111         }
112
113         return 0;
114 }