GRASS 8 Programmer's Manual
8.5.0(2026)-8d6ceba290
Toggle main menu visibility
Loading...
Searching...
No Matches
cmprzstd.c
Go to the documentation of this file.
1
/*
2
****************************************************************************
3
* -- GRASS Development Team --
4
*
5
* MODULE: GRASS gis library
6
* FILENAME: cmprzstd.c
7
* AUTHOR(S): Eric G. Miller <egm2@jps.net>
8
* Markus Metz
9
* PURPOSE: To provide an interface to ZSTD for compressing and
10
* decompressing data using ZSTD. It's primary use is in
11
* the storage and reading of GRASS floating point rasters.
12
*
13
* ALGORITHM: http://www.zstd.net
14
* DATE CREATED: Dec 18 2017
15
* COPYRIGHT: (C) 2017 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_zstd_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 Zstd compression function. *
30
* It uses an all or nothing call. *
31
* If you need a continuous compression scheme, you'll have to code *
32
* your own. *
33
* In order to do a single pass compression, the input src must be *
34
* copied to a buffer larger than the data. This may cause *
35
* 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_zstd_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 zstd decompression *
51
* function. It uses a single pass call. If you need a continuous *
52
* 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
#ifdef HAVE_ZSTD_H
66
#include <zstd.h>
67
#endif
68
69
#include <grass/gis.h>
70
#include <grass/glocale.h>
71
72
int
G_zstd_compress_bound
(
int
src_sz)
73
{
74
/* ZSTD has a fast version if destLen is large enough
75
* to hold a worst case result
76
*/
77
#ifndef HAVE_ZSTD_H
78
G_fatal_error
(
79
_(
"GRASS needs to be compiled with ZSTD for ZSTD compression"
));
80
return
-1;
81
#else
82
return
ZSTD_compressBound(src_sz);
83
#endif
84
}
85
86
int
G_zstd_compress
(
unsigned
char
*src,
int
src_sz,
unsigned
char
*dst,
87
int
dst_sz)
88
{
89
int
err
, nbytes, buf_sz;
90
unsigned
char
*buf;
91
92
#ifndef HAVE_ZSTD_H
93
G_fatal_error
(
94
_(
"GRASS needs to be compiled with ZSTD for ZSTD compression"
));
95
return
-1;
96
#else
97
98
/* Catch errors early */
99
if
(src ==
NULL
|| dst ==
NULL
) {
100
if
(src ==
NULL
)
101
G_warning
(_(
"No source buffer"
));
102
103
if
(dst ==
NULL
)
104
G_warning
(_(
"No destination buffer"
));
105
return
-1;
106
}
107
108
/* Don't do anything if either of these are true */
109
if
(src_sz <= 0 || dst_sz <= 0) {
110
if
(src_sz <= 0)
111
G_warning
(_(
"Invalid source buffer size %d"
), src_sz);
112
if
(dst_sz <= 0)
113
G_warning
(_(
"Invalid destination buffer size %d"
), dst_sz);
114
return
0;
115
}
116
117
/* Output buffer has to be larger for single pass compression */
118
buf = dst;
119
buf_sz =
G_zstd_compress_bound
(src_sz);
120
if
(buf_sz > dst_sz) {
121
G_warning
(
122
"G_zstd_compress(): programmer error, destination is too small"
);
123
if
(
NULL
==
124
(buf = (
unsigned
char
*)G_calloc(buf_sz,
sizeof
(
unsigned
char
))))
125
return
-1;
126
}
127
else
128
buf_sz = dst_sz;
129
130
/* Do single pass compression */
131
err
= ZSTD_compress((
char
*)buf, buf_sz, (
char
*)src, src_sz, 3);
132
133
if
(
err
<= 0 || ZSTD_isError(
err
)) {
134
G_warning
(_(
"ZSTD compression error %d: %s"
),
err
,
135
ZSTD_getErrorName(
err
));
136
if
(buf != dst)
137
G_free
(buf);
138
return
-1;
139
}
140
if
(
err
>= src_sz) {
141
/* compression not possible */
142
if
(buf != dst)
143
G_free
(buf);
144
return
-2;
145
}
146
147
/* bytes of compressed data is return value */
148
nbytes =
err
;
149
150
if
(buf != dst) {
151
/* Copy the data from buf to dst */
152
for
(
err
= 0;
err
< nbytes;
err
++)
153
dst[
err
] = buf[
err
];
154
155
G_free
(buf);
156
}
157
158
return
nbytes;
159
#endif
160
}
161
162
int
G_zstd_expand
(
unsigned
char
*src,
int
src_sz,
unsigned
char
*dst,
163
int
dst_sz)
164
{
165
int
err
, nbytes;
166
167
#ifndef HAVE_ZSTD_H
168
G_fatal_error
(
169
_(
"GRASS needs to be compiled with ZSTD for ZSTD compression"
));
170
return
-1;
171
#else
172
173
/* Catch error condition */
174
if
(src ==
NULL
|| dst ==
NULL
) {
175
if
(src ==
NULL
)
176
G_warning
(_(
"No source buffer"
));
177
178
if
(dst ==
NULL
)
179
G_warning
(_(
"No destination buffer"
));
180
return
-2;
181
}
182
183
/* Don't do anything if either of these are true */
184
if
(src_sz <= 0 || dst_sz <= 0) {
185
if
(src_sz <= 0)
186
G_warning
(_(
"Invalid source buffer size %d"
), src_sz);
187
if
(dst_sz <= 0)
188
G_warning
(_(
"Invalid destination buffer size %d"
), dst_sz);
189
return
0;
190
}
191
192
/* Do single pass decompress */
193
err
= ZSTD_decompress((
char
*)dst, dst_sz, (
char
*)src, src_sz);
194
195
if
(
err
<= 0 || ZSTD_isError(
err
)) {
196
G_warning
(_(
"ZSTD compression error %d: %s"
),
err
,
197
ZSTD_getErrorName(
err
));
198
return
-1;
199
}
200
201
/* Number of bytes inflated to output stream is return value */
202
nbytes =
err
;
203
204
if
(nbytes != dst_sz) {
205
/* TODO: it is not an error if destination is larger than needed */
206
G_warning
(_(
"Got uncompressed size %d, expected %d"
), (
int
)nbytes,
207
dst_sz);
208
return
-1;
209
}
210
211
return
nbytes;
212
#endif
213
}
214
215
/* vim: set softtabstop=4 shiftwidth=4 expandtab: */
G_free
void G_free(void *buf)
Free allocated memory.
Definition
alloc.c:147
NULL
#define NULL
Definition
ccmath.h:32
G_zstd_compress_bound
int G_zstd_compress_bound(int src_sz)
Definition
cmprzstd.c:72
G_zstd_compress
int G_zstd_compress(unsigned char *src, int src_sz, unsigned char *dst, int dst_sz)
Definition
cmprzstd.c:86
G_zstd_expand
int G_zstd_expand(unsigned char *src, int src_sz, unsigned char *dst, int dst_sz)
Definition
cmprzstd.c:162
G_fatal_error
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition
gis/error.c:159
G_warning
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition
gis/error.c:203
err
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
Definition
symbol/read.c:216
gis
cmprzstd.c
Generated on
for GRASS 8 Programmer's Manual by
1.17.0