Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libpz/pzinflate.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1998-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
22
#include "pzlib.h"
23
24
/*
25
* restore lo+hi into ob
26
*/
27
28
static int
29
restore(register Pz_t* pz, Pzpart_t* pp, register Sfio_t* ip, Sfio_t* op, register unsigned char* pat, register unsigned char* buf, size_t row, size_t m, register size_t* map, register unsigned char** mix, register size_t* inc)
30
{
31
register size_t z;
32
register int i;
33
Pzwrite_f writef;
34
35
writef = pz->disc->writef;
36
for (;;)
37
{
38
PZGETZ(pz, ip, z, i);
39
do
40
{
41
memcpy(buf, pat, row);
42
for (i = 0; i < m; i++)
43
{
44
buf[map[i]] = *mix[i];
45
mix[i] += inc[i];
46
}
47
if (writef)
48
{
49
if ((*writef)(pz, op, buf, pz->disc) < 0)
50
return -1;
51
}
52
else if (sfwrite(op, buf, row) != row)
53
{
54
if (pz->disc->errorf)
55
(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "write error");
56
return -1;
57
}
58
} while (--z);
59
PZGETP(pz, ip, z, i, break);
60
for (;;)
61
{
62
pat[z - 1] = *pz->nxt++;
63
PZGETP(pz, ip, z, i, break);
64
}
65
}
66
return 0;
67
}
68
69
/*
70
* pz inflate from pz->io to op
71
*/
72
73
int
74
pzinflate(register Pz_t* pz, Sfio_t* op)
75
{
76
register Pzpart_t* pp;
77
register int i;
78
register int j;
79
register int k;
80
register size_t n;
81
register size_t m;
82
register unsigned char* pat;
83
ssize_t r;
84
Pzwrite_f writef;
85
86
if (!(pz->flags & PZ_READ))
87
{
88
if (pz->disc->errorf)
89
(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "%s: cannot inflate -- not open for read", pz->path);
90
return -1;
91
}
92
if (pz->flags & PZ_SPLIT)
93
return pzssplit(pz);
94
if (pz->flags & PZ_FORCE)
95
{
96
if (writef = pz->disc->writef)
97
{
98
n = pz->part->row;
99
do
100
{
101
if (!(pat = (unsigned char*)sfreserve(pz->io, n, 0)))
102
{
103
if (sfvalue(pz->io))
104
{
105
if (pz->disc->errorf)
106
(*pz->disc->errorf)(pz, pz->disc, 2, "%s: data corrupted", pz->path);
107
return -1;
108
}
109
break;
110
}
111
} while ((r = (*writef)(pz, op, pat, pz->disc)) >= 0);
112
if (r < 0)
113
return -1;
114
}
115
else if (sfmove(pz->io, op, SF_UNBOUND, -1) < 0 || sferror(pz->io))
116
{
117
if (pz->disc->errorf)
118
(*pz->disc->errorf)(pz, pz->disc, 2, "%s: data corrupted", pz->path);
119
return -1;
120
}
121
if (sfsync(op))
122
{
123
if (pz->disc->errorf)
124
(*pz->disc->errorf)(pz, pz->disc, 2, "%s: output write error", pz->path);
125
return -1;
126
}
127
return 0;
128
}
129
130
/*
131
* copy the prefix
132
*/
133
134
if (pz->prefix.count)
135
{
136
if (!pz->prefix.skip && pz->prefix.data && sfwrite(op, pz->prefix.data, pz->prefix.count) != pz->prefix.count)
137
{
138
if (pz->disc->errorf)
139
(*pz->disc->errorf)(pz, pz->disc, 2, "%s: output write error", pz->path);
140
return -1;
141
}
142
pz->prefix.count = 0;
143
}
144
if ((pz->split.flags & (PZ_SPLIT_INFLATE|PZ_SPLIT_PART)) == PZ_SPLIT_INFLATE)
145
i = pzsinflate(pz, op);
146
else
147
{
148
/*
149
* inflate each file
150
*/
151
152
do
153
{
154
/*
155
* inflate each window
156
*/
157
158
pp = pz->part;
159
pat = pz->pat;
160
while (m = sfgetu(pz->io))
161
{
162
/*
163
* hi frequency data in pz->buf
164
*/
165
166
if (pp->nmap)
167
{
168
if (m > pz->win || (m % pp->nmap) || sfread(pz->io, pz->buf, m) != m)
169
{
170
if (pz->disc->errorf)
171
(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "%s: data corrupted", pz->path);
172
return -1;
173
}
174
n = m / pp->nmap;
175
m = 0;
176
j = 0;
177
k = 0;
178
for (i = 0; i < pp->nmap; i++)
179
{
180
if (i > 0 && pp->lab[i] == pp->lab[i - 1])
181
j++;
182
else
183
j = m;
184
if (!pp->value || pp->value[i] < 0)
185
pp->mix[k++] = pz->buf + j;
186
m += n;
187
}
188
}
189
else if (m != 1)
190
{
191
if (pz->disc->errorf)
192
(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "%s: data corrupted", pz->path);
193
return -1;
194
}
195
196
/*
197
* lo frequency
198
*/
199
200
m = sfgetu(pz->io);
201
if (m < pp->row || sfread(pz->io, pat, pp->row) != pp->row)
202
{
203
if (pz->disc->errorf)
204
(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "%s: data corrupted", pz->path);
205
return -1;
206
}
207
m -= pp->row;
208
if (sfread(pz->io, pz->nxt = pz->val, m) != m)
209
{
210
if (pz->disc->errorf)
211
(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "%s: data corrupted", pz->path);
212
return -1;
213
}
214
215
/*
216
* restore lo+hi on op
217
*/
218
219
if (restore(pz, pp, pz->io, op, pat, pz->wrk, pp->row, k, pp->map, pp->mix, pp->inc))
220
return -1;
221
}
222
if (!(pz->flags & PZ_SECTION))
223
{
224
if ((k = sfgetc(pz->io)) == PZ_MARK_PART)
225
{
226
if ((m = sfgetu(pz->io)) && !sferror(pz->io) && !sfeof(pz->io) && (pat = (unsigned char*)sfreserve(pz->io, m, 0)))
227
sfwrite(op, pat, m);
228
}
229
else if (k != EOF)
230
sfungetc(pz->io, k);
231
}
232
if (sferror(op))
233
{
234
if (pz->disc->errorf)
235
(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "write error");
236
return -1;
237
}
238
} while ((i = !(pz->flags & PZ_SECTION)) && (i = pzfile(pz)) > 0);
239
}
240
if (i >= 0 && !(pz->split.flags & PZ_SPLIT_PART) && sfsync(op))
241
{
242
if (pz->disc->errorf)
243
(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "write error");
244
return -1;
245
}
246
return i;
247
}
248
249