GRASS 8 Programmer's Manual 8.6.0dev(2026)-c83afef6d3
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 * SPDX-FileCopyrightText: 2017 GRASS Development Team
16 * SPDX-License-Identifier: GPL-2.0-or-later
17 *
18 *****************************************************************************/
19
20/********************************************************************
21 * int *
22 * G_zstd_compress (src, srz_sz, dst, dst_sz) *
23 * int src_sz, dst_sz; *
24 * unsigned char *src, *dst; *
25 * ---------------------------------------------------------------- *
26 * This function is a wrapper around the Zstd compression function. *
27 * It uses an all or nothing call. *
28 * If you need a continuous compression scheme, you'll have to code *
29 * your own. *
30 * In order to do a single pass compression, the input src must be *
31 * copied to a buffer larger than the data. This may cause *
32 * performance degradation. *
33 * *
34 * The function either returns the number of bytes of compressed *
35 * data in dst, or an error code. *
36 * *
37 * Errors include: *
38 * -1 -- Compression failed. *
39 * -2 -- dst is too small. *
40 * *
41 * ================================================================ *
42 * int *
43 * G_zstd_expand (src, src_sz, dst, dst_sz) *
44 * int src_sz, dst_sz; *
45 * unsigned char *src, *dst; *
46 * ---------------------------------------------------------------- *
47 * This function is a wrapper around the zstd decompression *
48 * function. It uses a single pass call. If you need a continuous *
49 * expansion scheme, you'll have to code your own. *
50 * *
51 * The function returns the number of bytes expanded into 'dst' or *
52 * and error code. *
53 * *
54 * Errors include: *
55 * -1 -- Expansion failed. *
56 * *
57 ********************************************************************
58 */
59
60#include <grass/config.h>
61
62#ifdef HAVE_ZSTD_H
63#include <zstd.h>
64#endif
65
66#include <grass/gis.h>
67#include <grass/glocale.h>
68
70{
71 /* ZSTD has a fast version if destLen is large enough
72 * to hold a worst case result
73 */
74#ifndef HAVE_ZSTD_H
76 _("GRASS needs to be compiled with ZSTD for ZSTD compression"));
77 return -1;
78#else
80#endif
81}
82
83int G_zstd_compress(unsigned char *src, int src_sz, unsigned char *dst,
84 int dst_sz)
85{
86 int err, nbytes, buf_sz;
87 unsigned char *buf;
88
89#ifndef HAVE_ZSTD_H
91 _("GRASS needs to be compiled with ZSTD for ZSTD compression"));
92 return -1;
93#else
94
95 /* Catch errors early */
96 if (src == NULL || dst == NULL) {
97 if (src == NULL)
98 G_warning(_("No source buffer"));
99
100 if (dst == NULL)
101 G_warning(_("No destination buffer"));
102 return -1;
103 }
104
105 /* Don't do anything if either of these are true */
106 if (src_sz <= 0 || dst_sz <= 0) {
107 if (src_sz <= 0)
108 G_warning(_("Invalid source buffer size %d"), src_sz);
109 if (dst_sz <= 0)
110 G_warning(_("Invalid destination buffer size %d"), dst_sz);
111 return 0;
112 }
113
114 /* Output buffer has to be larger for single pass compression */
115 buf = dst;
117 if (buf_sz > dst_sz) {
118 G_warning(
119 "G_zstd_compress(): programmer error, destination is too small");
120 if (NULL ==
121 (buf = (unsigned char *)G_calloc(buf_sz, sizeof(unsigned char))))
122 return -1;
123 }
124 else
125 buf_sz = dst_sz;
126
127 /* Do single pass compression */
128 err = ZSTD_compress((char *)buf, buf_sz, (char *)src, src_sz, 3);
129
130 if (err <= 0 || ZSTD_isError(err)) {
131 G_warning(_("ZSTD compression error %d: %s"), err,
133 if (buf != dst)
134 G_free(buf);
135 return -1;
136 }
137 if (err >= src_sz) {
138 /* compression not possible */
139 if (buf != dst)
140 G_free(buf);
141 return -2;
142 }
143
144 /* bytes of compressed data is return value */
145 nbytes = err;
146
147 if (buf != dst) {
148 /* Copy the data from buf to dst */
149 for (err = 0; err < nbytes; err++)
150 dst[err] = buf[err];
151
152 G_free(buf);
153 }
154
155 return nbytes;
156#endif
157}
158
159int G_zstd_expand(unsigned char *src, int src_sz, unsigned char *dst,
160 int dst_sz)
161{
162 int err, nbytes;
163
164#ifndef HAVE_ZSTD_H
166 _("GRASS needs to be compiled with ZSTD for ZSTD compression"));
167 return -1;
168#else
169
170 /* Catch error condition */
171 if (src == NULL || dst == NULL) {
172 if (src == NULL)
173 G_warning(_("No source buffer"));
174
175 if (dst == NULL)
176 G_warning(_("No destination buffer"));
177 return -2;
178 }
179
180 /* Don't do anything if either of these are true */
181 if (src_sz <= 0 || dst_sz <= 0) {
182 if (src_sz <= 0)
183 G_warning(_("Invalid source buffer size %d"), src_sz);
184 if (dst_sz <= 0)
185 G_warning(_("Invalid destination buffer size %d"), dst_sz);
186 return 0;
187 }
188
189 /* Do single pass decompress */
190 err = ZSTD_decompress((char *)dst, dst_sz, (char *)src, src_sz);
191
192 if (err <= 0 || ZSTD_isError(err)) {
193 G_warning(_("ZSTD compression error %d: %s"), err,
195 return -1;
196 }
197
198 /* Number of bytes inflated to output stream is return value */
199 nbytes = err;
200
201 if (nbytes != dst_sz) {
202 /* TODO: it is not an error if destination is larger than needed */
203 G_warning(_("Got uncompressed size %d, expected %d"), (int)nbytes,
204 dst_sz);
205 return -1;
206 }
207
208 return nbytes;
209#endif
210}
211
212/* vim: set softtabstop=4 shiftwidth=4 expandtab: */
#define NULL
Definition ccmath.h:32
int G_zstd_compress_bound(int src_sz)
Definition cmprzstd.c:69
int G_zstd_compress(unsigned char *src, int src_sz, unsigned char *dst, int dst_sz)
Definition cmprzstd.c:83
int G_zstd_expand(unsigned char *src, int src_sz, unsigned char *dst, int dst_sz)
Definition cmprzstd.c:159
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:145
#define G_calloc(m, n)
Definition defs/gis.h:137
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
#define _(str)
Definition glocale.h:10
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)