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