1 /************
2 *
3 * This file is part of a tool for reading 3D content in the PRC format.
4 * Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 *************/
20
21 #include "inflation.h"
22
23 using std::istream;
24 using std::ios;
25 using std::cout;
26 using std::cerr;
27 using std::endl;
28 using std::exit;
29
decompress(char * inb,int fileLength,char * & outb)30 int decompress(char* inb, int fileLength, char* &outb)
31 {
32 const int CHUNK = 16384;
33 unsigned int resultSize = 0;
34
35 outb = (char*) realloc(outb,CHUNK);
36 z_stream strm;
37 strm.zalloc = Z_NULL;
38 strm.zfree = Z_NULL;
39 strm.avail_in = fileLength;
40 strm.next_in = (unsigned char*)inb;
41 strm.opaque = Z_NULL;
42 int code = inflateInit(&strm);
43
44 if(code != Z_OK)
45 return -1;
46
47 strm.next_out = (unsigned char*)outb;
48 strm.avail_out = CHUNK;
49 code = inflate(&strm,Z_NO_FLUSH);
50 resultSize = CHUNK-strm.avail_out;
51
52 unsigned int size = CHUNK;
53 while(code == Z_OK)
54 {
55 outb = (char*) realloc(outb,2*size);
56 if(outb == NULL)
57 {
58 cerr << "Ran out of memory while decompressing." << endl;
59 exit(1);
60 }
61 strm.next_out = (Bytef*)(outb + resultSize);
62 strm.avail_out += size;
63 size *= 2;
64 code = inflate(&strm,Z_NO_FLUSH);
65 resultSize = size - strm.avail_out;
66 }
67
68 code = inflateEnd(&strm);
69 if(code != Z_OK)
70 {
71 free(outb);
72 return 0;
73 }
74
75 return resultSize;
76 }
77
decompress(istream & input,char * & result)78 int decompress(istream &input,char* &result)
79 {
80 input.seekg(0,ios::end);
81 int fileLength = input.tellg();
82 input.seekg(0,ios::beg);
83
84 char *inb = new char[fileLength];
85 input.read(inb,fileLength);
86
87 int code = decompress(inb,fileLength,result);
88 delete[] inb;
89 return code;
90 }
91