annotate src/console/Zlib_Inflater.cxx @ 661:7b65072e2efb trunk

[svn] - id3tag.h -> audacious/id3tag.h
author nenolod
date Sat, 17 Feb 2007 01:34:18 -0800
parents 986f098da058
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
341
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
1 // File_Extractor 0.4.0. http://www.slack.net/~ant/
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
2
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
3 #include "Zlib_Inflater.h"
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
4
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
5 #include <assert.h>
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
6 #include <string.h>
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
7
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
8 /* Copyright (C) 2006 Shay Green. This module is free software; you
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
9 can redistribute it and/or modify it under the terms of the GNU Lesser
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
10 General Public License as published by the Free Software Foundation; either
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
11 version 2.1 of the License, or (at your option) any later version. This
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
12 module is distributed in the hope that it will be useful, but WITHOUT ANY
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
15 details. You should have received a copy of the GNU Lesser General Public
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
16 License along with this module; if not, write to the Free Software Foundation,
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
18
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
19 #include "blargg_source.h"
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
20
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
21 static const char* get_zlib_err( int code )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
22 {
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
23 assert( code != Z_OK );
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
24 if ( code == Z_MEM_ERROR )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
25 return "Out of memory";
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
26
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
27 const char* str = zError( code );
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
28 if ( code == Z_DATA_ERROR )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
29 str = "Zip data is corrupt";
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
30 if ( !str )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
31 str = "Zip error";
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
32 return str;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
33 }
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
34
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
35 void Zlib_Inflater::end()
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
36 {
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
37 if ( deflated_ )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
38 {
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
39 deflated_ = false;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
40 if ( inflateEnd( &zbuf ) )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
41 check( false );
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
42 }
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
43 buf.clear();
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
44
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
45 static z_stream const empty = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
46 memcpy( &zbuf, &empty, sizeof zbuf );
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
47 }
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
48
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
49 Zlib_Inflater::Zlib_Inflater()
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
50 {
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
51 deflated_ = false;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
52 end(); // initialize things
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
53 }
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
54
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
55 Zlib_Inflater::~Zlib_Inflater()
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
56 {
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
57 end();
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
58 }
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
59
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
60 blargg_err_t Zlib_Inflater::begin( mode_t mode, callback_t callback, void* user_data,
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
61 long buf_size )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
62 {
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
63 end();
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
64
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
65 if ( buf_size && buf.resize( buf_size ) )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
66 buf_size = 0; // not enough memory for requested size, so use default
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
67
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
68 if ( !buf_size )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
69 RETURN_ERR( buf.resize( 16 * 1024L ) );
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
70
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
71 // Fill buffer with some data, less than normal buffer size since caller might
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
72 // just be examining beginning of file. 4K is a common disk block size.
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
73 long count = (buf_size ? buf_size : 4096);
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
74 RETURN_ERR( callback( user_data, buf.begin(), &count ) );
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
75 zbuf.avail_in = count;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
76 zbuf.next_in = buf.begin();
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
77
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
78 if ( mode == mode_auto )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
79 {
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
80 // examine buffer for gzip header
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
81 mode = mode_copy;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
82 int const min_gzip_size = 2 + 8 + 8;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
83 if ( count >= min_gzip_size && buf [0] == 0x1F && buf [1] == 0x8B )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
84 mode = mode_ungz;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
85 }
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
86
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
87 if ( mode != mode_copy )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
88 {
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
89 int wb = MAX_WBITS + 16; // have zlib handle gzip header
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
90 if ( mode == mode_raw_deflate )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
91 wb = -MAX_WBITS;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
92
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
93 int zerr = inflateInit2( &zbuf, wb );
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
94 if ( zerr )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
95 return get_zlib_err( zerr );
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
96
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
97 deflated_ = true;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
98 }
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
99 return 0;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
100 }
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
101
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
102
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
103 blargg_err_t Zlib_Inflater::read( void* out, long* count_io,
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
104 callback_t callback, void* user_data )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
105 {
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
106 if ( !*count_io )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
107 return 0;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
108
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
109 if ( !deflated_ )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
110 {
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
111 // copy buffered data
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
112 long first = zbuf.avail_in;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
113 if ( first )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
114 {
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
115 if ( first > *count_io )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
116 first = *count_io;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
117 memcpy( out, zbuf.next_in, first );
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
118 zbuf.next_in += first;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
119 zbuf.avail_in -= first;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
120 if ( !zbuf.avail_in )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
121 buf.clear(); // done with buffer
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
122 }
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
123
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
124 // read remaining directly
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
125 long second = *count_io - first;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
126 if ( second )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
127 {
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
128 long actual = second;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
129 RETURN_ERR( callback( user_data, (char*) out + first, &actual ) );
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
130 *count_io -= second - actual;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
131 }
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
132 }
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
133 else
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
134 {
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
135 zbuf.next_out = (Bytef*) out;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
136 zbuf.avail_out = *count_io;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
137
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
138 while ( 1 )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
139 {
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
140 uInt old_avail_in = zbuf.avail_in;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
141 int err = inflate( &zbuf, Z_NO_FLUSH );
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
142 if ( err == Z_STREAM_END )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
143 {
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
144 *count_io -= zbuf.avail_out;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
145 end();
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
146 break; // all data deflated
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
147 }
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
148
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
149 if ( err == Z_BUF_ERROR && !old_avail_in )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
150 err = 0; // we just need to provide more input
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
151
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
152 if ( err )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
153 return get_zlib_err( err );
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
154
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
155 if ( !zbuf.avail_out )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
156 break; // requested number of bytes deflated
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
157
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
158 if ( zbuf.avail_in )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
159 {
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
160 // inflate() should never leave input if there's still space for output
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
161 assert( false );
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
162 return "Corrupt zip data";
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
163 }
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
164
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
165 // refill buffer
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
166 long count = buf.size();
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
167 RETURN_ERR( callback( user_data, buf.begin(), &count ) );
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
168 zbuf.next_in = buf.begin();
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
169 zbuf.avail_in = count;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
170 if ( !zbuf.avail_in )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
171 return "Corrupt zip data"; // stream didn't end but there's no more data
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
172 }
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
173 }
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
174 return 0;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents:
diff changeset
175 }