GRASS GIS 7 Programmer's Manual
7.8.2(2019)-exported
cmprzlib.c
Go to the documentation of this file.
1
/*
2
****************************************************************************
3
* -- GRASS Development Team --
4
*
5
* MODULE: GRASS gis library
6
* FILENAME: cmprzlib.c
7
* AUTHOR(S): Eric G. Miller <egm2@jps.net>
8
* Markus Metz
9
* PURPOSE: To provide an interface to libz for compressing and
10
* decompressing data using DEFLATE. It's primary use is in
11
* the storage and reading of GRASS floating point rasters.
12
* It replaces the patented LZW compression interface.
13
*
14
* ALGORITHM: http://www.gzip.org/zlib/feldspar.html
15
* DATE CREATED: Dec 17 2015
16
* COPYRIGHT: (C) 2015 by the GRASS Development Team
17
*
18
* This program is free software under the GNU General Public
19
* License (version 2 or greater). Read the file COPYING that
20
* comes with GRASS for details.
21
*
22
*****************************************************************************/
23
24
/********************************************************************
25
* int *
26
* G_zlib_compress (src, srz_sz, dst, dst_sz) *
27
* int src_sz, dst_sz; *
28
* unsigned char *src, *dst; *
29
* ---------------------------------------------------------------- *
30
* This function is a wrapper around the zlib deflate() function. *
31
* It uses an all or nothing call to deflate(). If you need a *
32
* continuous compression scheme, you'll have to code your own. *
33
* In order to do a single pass compression, the input src must be *
34
* copied to a buffer 1% + 12 bytes larger than the data. This may *
35
* cause performance degradation. *
36
* *
37
* The function either returns the number of bytes of compressed *
38
* data in dst, or an error code. *
39
* *
40
* Errors include: *
41
* -1 -- Compression failed. *
42
* -2 -- dst is too small. *
43
* *
44
* ================================================================ *
45
* int *
46
* G_zlib_expand (src, src_sz, dst, dst_sz) *
47
* int src_sz, dst_sz; *
48
* unsigned char *src, *dst; *
49
* ---------------------------------------------------------------- *
50
* This function is a wrapper around the zlib inflate() function. *
51
* It uses a single pass call to inflate(). If you need a contin- *
52
* uous expansion scheme, you'll have to code your own. *
53
* *
54
* The function returns the number of bytes expanded into 'dst' or *
55
* and error code. *
56
* *
57
* Errors include: *
58
* -1 -- Expansion failed. *
59
* *
60
********************************************************************
61
*/
62
63
#include <grass/config.h>
64
65
#ifndef HAVE_ZLIB_H
66
67
#error "GRASS requires libz to compile"
68
69
#else
70
71
#include <zlib.h>
72
#include <grass/gis.h>
73
#include <grass/glocale.h>
74
75
#include "
G.h
"
76
77
78
int
79
G_zlib_compress_bound
(
int
src_sz)
80
{
81
/* from zlib.h:
82
* "when using compress or compress2,
83
* destLen must be at least the value returned by
84
* compressBound(sourceLen)"
85
* no explanation for the "must be"
86
*/
87
return
compressBound(src_sz);
88
}
89
90
int
91
G_zlib_compress(
unsigned
char
*src,
int
src_sz,
unsigned
char
*
dst
,
92
int
dst_sz)
93
{
94
uLong
err
, nbytes, buf_sz;
95
unsigned
char
*buf;
96
97
/* Catch errors early */
98
if
(src ==
NULL
||
dst
==
NULL
) {
99
if
(src ==
NULL
)
100
G_warning
(_(
"No source buffer"
));
101
102
if
(
dst
==
NULL
)
103
G_warning
(_(
"No destination buffer"
));
104
return
-1;
105
}
106
107
/* Don't do anything if either of these are true */
108
if
(src_sz <= 0 || dst_sz <= 0) {
109
if
(src_sz <= 0)
110
G_warning
(_(
"Invalid source buffer size %d"
), src_sz);
111
if
(dst_sz <= 0)
112
G_warning
(_(
"Invalid destination buffer size %d"
), dst_sz);
113
return
0;
114
}
115
116
/* Output buffer has to be 1% + 12 bytes bigger for single pass deflate */
117
/* buf_sz = (int)((double)dst_sz * 1.01 + (double)12); */
118
119
/* Output buffer should be large enough for single pass compression */
120
buf =
dst
;
121
buf_sz =
G_zlib_compress_bound
(src_sz);
122
if
(buf_sz > dst_sz) {
123
G_warning
(
"G_zlib_compress(): programmer error, destination is too small"
);
124
if
(
NULL
== (buf = (
unsigned
char
*)
125
G_calloc(buf_sz,
sizeof
(
unsigned
char
))))
126
return
-1;
127
}
128
else
129
buf_sz = dst_sz;
130
131
/* Valid zlib compression levels -1 - 9 */
132
/* zlib default: Z_DEFAULT_COMPRESSION = -1, equivalent to 6
133
* as used here, 1 gives the best compromise between speed and compression */
134
135
/* Do single pass compression */
136
nbytes = buf_sz;
137
err
= compress2((Bytef *)buf, &nbytes,
/* destination */
138
(
const
Bytef *)src, src_sz,
/* source */
139
G__
.
compression_level
);
/* level */
140
141
if
(
err
!= Z_OK) {
142
G_warning
(_(
"ZLIB compression error %d: %s"
),
143
(
int
)
err
, zError(
err
));
144
if
(buf !=
dst
)
145
G_free
(buf);
146
return
-1;
147
}
148
149
/* updated buf_sz is bytes of compressed data */
150
if
(nbytes >= src_sz) {
151
/* compression not possible */
152
if
(buf !=
dst
)
153
G_free
(buf);
154
return
-2;
155
}
156
157
if
(buf !=
dst
) {
158
/* Copy the data from buf to dst */
159
for
(
err
= 0;
err
< nbytes;
err
++)
160
dst
[
err
] = buf[
err
];
161
162
G_free
(buf);
163
}
164
165
return
nbytes;
166
}
/* G_zlib_compress() */
167
168
169
int
170
G_zlib_expand(
unsigned
char
*src,
int
src_sz,
unsigned
char
*
dst
,
171
int
dst_sz)
172
{
173
int
err
;
174
uLong ss, nbytes;
175
176
/* Catch error condition */
177
if
(src ==
NULL
||
dst
==
NULL
) {
178
if
(src ==
NULL
)
179
G_warning
(_(
"No source buffer"
));
180
181
if
(
dst
==
NULL
)
182
G_warning
(_(
"No destination buffer"
));
183
return
-2;
184
}
185
186
/* Don't do anything if either of these are true */
187
if
(src_sz <= 0 || dst_sz <= 0) {
188
if
(src_sz <= 0)
189
G_warning
(_(
"Invalid source buffer size %d"
), src_sz);
190
if
(dst_sz <= 0)
191
G_warning
(_(
"Invalid destination buffer size %d"
), dst_sz);
192
return
0;
193
}
194
195
ss = src_sz;
196
197
/* Do single pass decompression */
198
nbytes = dst_sz;
199
err
= uncompress((Bytef *)
dst
, &nbytes,
/* destination */
200
(
const
Bytef *)src, ss);
/* source */
201
202
/* If not Z_OK return error -1 */
203
if
(
err
!= Z_OK) {
204
G_warning
(_(
"ZLIB decompression error %d: %s"
),
205
err
, zError(
err
));
206
return
-1;
207
}
208
209
/* Number of bytes inflated to output stream is
210
* updated buffer size
211
*/
212
213
if
(nbytes != dst_sz) {
214
/* TODO: it is not an error if destination is larger than needed */
215
G_warning
(_(
"Got uncompressed size %d, expected %d"
), (
int
)nbytes, dst_sz);
216
return
-1;
217
}
218
219
return
nbytes;
220
}
/* G_zlib_expand() */
221
222
223
#endif
/* HAVE_ZLIB_H */
224
225
226
/* vim: set softtabstop=4 shiftwidth=4 expandtab: */
G_zlib_compress_bound
int G_zlib_compress_bound(int)
err
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
Definition:
symbol/read.c:219
G_free
void G_free(void *buf)
Free allocated memory.
Definition:
alloc.c:149
NULL
#define NULL
Definition:
ccmath.h:32
G.h
G__::compression_level
int compression_level
Definition:
G.h:9
dst
char * dst
Definition:
lz4.h:599
G_warning
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition:
gis/error.c:204
G__
Definition:
G.h:4
gis
cmprzlib.c
Generated on Sat Jan 25 2020 17:06:53 for GRASS GIS 7 Programmer's Manual by
1.8.16