GRASS 8 Programmer's Manual 8.6.0dev(2026)-55de52a352
Loading...
Searching...
No Matches
cmprbzip.c
Go to the documentation of this file.
1/*
2 ****************************************************************************
3 * -- GRASS Development Team --
4 *
5 * MODULE: GRASS gis library
6 * FILENAME: cmprbzip.c
7 * AUTHOR(S): Markus Metz
8 * PURPOSE: To provide an interface to libbzip2 for compressing and
9 * decompressing data. Its primary use is in
10 * the storage and reading of GRASS rasters.
11 *
12 * ALGORITHM: http://www.bzip.org
13 * DATE CREATED: Nov 19 2015
14 * SPDX-FileCopyrightText: 2015 GRASS Development Team
15 * SPDX-License-Identifier: GPL-2.0-or-later
16 *
17 *****************************************************************************/
18
19/********************************************************************
20 * int *
21 * G_bz2_compress (src, srz_sz, dst, dst_sz) *
22 * int src_sz, dst_sz; *
23 * unsigned char *src, *dst; *
24 * ---------------------------------------------------------------- *
25 * This function is a wrapper around the bzip2 compression *
26 * function. It uses an all or nothing call. *
27 * If you need a continuous compression scheme, you'll have to code *
28 * your own. *
29 * In order to do a single pass compression, the input src must be *
30 * copied to a buffer 1% + 600 bytes larger than the data. This *
31 * may cause performance degradation. *
32 * *
33 * The function either returns the number of bytes of compressed *
34 * data in dst, or an error code. *
35 * *
36 * Errors include: *
37 * -1 -- Compression failed. *
38 * -2 -- dst is too small. *
39 * *
40 * ================================================================ *
41 * int *
42 * G_bz2_expand (src, src_sz, dst, dst_sz) *
43 * int src_sz, dst_sz; *
44 * unsigned char *src, *dst; *
45 * ---------------------------------------------------------------- *
46 * This function is a wrapper around the bzip2 decompression *
47 * function. It uses a single pass call to inflate(). *
48 * If you need a continuous expansion scheme, you'll have to code *
49 * 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_BZLIB_H
63#include <bzlib.h>
64#endif
65
66#include <grass/gis.h>
67#include <grass/glocale.h>
68
70{
71 /* from the documentation:
72 * To guarantee that the compressed data will fit in its buffer,
73 * allocate an output buffer of size 1% larger than the uncompressed data,
74 * plus six hundred extra bytes.
75 * bzip2 does not provide a compressbound fn
76 * and apparently does not have a fast version if destLen is
77 * large enough to hold a worst case result
78 */
79 return src_sz;
80}
81
82int G_bz2_compress(unsigned char *src, int src_sz, unsigned char *dst,
83 int dst_sz)
84{
85 int err;
86 int buf_sz;
87 unsigned int i, nbytes;
88 unsigned char *buf;
89
90#ifndef HAVE_BZLIB_H
92 _("GRASS needs to be compiled with BZIP2 for BZIP2 compression"));
93 return -1;
94#else
95
96 /* Catch errors early */
97 if (src == NULL || dst == NULL) {
98 if (src == NULL)
99 G_warning(_("No source buffer"));
100
101 if (dst == NULL)
102 G_warning(_("No destination buffer"));
103 return -1;
104 }
105
106 /* Don't do anything if either of these are true */
107 if (src_sz <= 0 || dst_sz <= 0) {
108 if (src_sz <= 0)
109 G_warning(_("Invalid source buffer size %d"), src_sz);
110 if (dst_sz <= 0)
111 G_warning(_("Invalid destination buffer size %d"), dst_sz);
112 return 0;
113 }
114
115 /* Output buffer has to be 1% + 600 bytes bigger for single pass compression
116 */
117 buf = dst;
119 if (buf_sz > dst_sz) {
120 G_warning(
121 "G_bz2_compress(): programmer error, destination is too small");
122 if (NULL ==
123 (buf = (unsigned char *)G_calloc(buf_sz, sizeof(unsigned char))))
124 return -1;
125 }
126 else
127 buf_sz = dst_sz;
128
129 /* Do single pass compression */
130 nbytes = buf_sz;
131 err = BZ2_bzBuffToBuffCompress((char *)buf, &nbytes, /* destination */
132 (char *)src, src_sz, /* source */
133 9, /* blockSize100k */
134 0, /* verbosity */
135 100); /* workFactor */
136
137 if (err != BZ_OK) {
138 G_warning(_("BZIP2 version %s compression error %d"),
140 if (buf != dst)
141 G_free(buf);
142 return -1;
143 }
144
145 /* updated buf_sz is bytes of compressed data */
146 if (nbytes >= (unsigned int)src_sz) {
147 /* compression not possible */
148 if (buf != dst)
149 G_free(buf);
150 return -2;
151 }
152
153 if (buf != dst) {
154 /* Copy the data from buf to dst */
155 for (i = 0; i < nbytes; i++)
156 dst[i] = buf[i];
157
158 G_free(buf);
159 }
160
161 return nbytes;
162#endif
163} /* G_bz2_compress() */
164
165int G_bz2_expand(unsigned char *src, int src_sz, unsigned char *dst, int dst_sz)
166{
167 int err;
168 unsigned int nbytes;
169
170#ifndef HAVE_BZLIB_H
172 _("GRASS needs to be compiled with BZIP2 for BZIP2 compression"));
173 return -2;
174#else
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 /* Do single pass decompression */
196 nbytes = dst_sz;
197 err = BZ2_bzBuffToBuffDecompress((char *)dst, &nbytes, /* destination */
198 (char *)src, src_sz, /* source */
199 0, /* small */
200 0); /* verbosity */
201
202 if (err != BZ_OK) {
203 G_warning(_("BZIP2 version %s decompression error %d"),
205 return -1;
206 }
207
208 /* Number of bytes inflated to output stream is
209 * updated buffer size
210 */
211
212 if (dst_sz < 0 || nbytes != (unsigned int)dst_sz) {
213 /* TODO: it is not an error if destination is larger than needed */
214 G_warning(_("Got uncompressed size %d, expected %d"), (int)nbytes,
215 dst_sz);
216 return -1;
217 }
218
219 return nbytes;
220#endif
221}
222
223/* vim: set softtabstop=4 shiftwidth=4 expandtab: */
#define NULL
Definition ccmath.h:32
int G_bz2_compress(unsigned char *src, int src_sz, unsigned char *dst, int dst_sz)
Definition cmprbzip.c:82
int G_bz2_expand(unsigned char *src, int src_sz, unsigned char *dst, int dst_sz)
Definition cmprbzip.c:165
int G_bz2_compress_bound(int src_sz)
Definition cmprbzip.c:69
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)