GRASS 8 Programmer's Manual 8.6.0dev(2026)-8843f13794
Loading...
Searching...
No Matches
cmprlz4.c
Go to the documentation of this file.
1/*
2 ****************************************************************************
3 * -- GRASS Development Team --
4 *
5 * MODULE: GRASS gis library
6 * FILENAME: cmprlz4.c
7 * AUTHOR(S): Eric G. Miller <egm2@jps.net>
8 * Markus Metz
9 * PURPOSE: To provide an interface to lz4 for compressing and
10 * decompressing data using LZ4. It's primary use is in
11 * the storage and reading of GRASS floating point rasters.
12 *
13 * ALGORITHM: https://code.google.com/p/lz4/
14 * DATE CREATED: Dec 18 2015
15 * SPDX-FileCopyrightText: 2015 GRASS Development Team
16 * SPDX-License-Identifier: GPL-2.0-or-later
17 *
18 *****************************************************************************/
19
20/********************************************************************
21 * int *
22 * G_lz4_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 LZ4 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_lz4_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 lz4 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#include <grass/gis.h>
63#include <grass/glocale.h>
64
65#include "lz4.h"
66
68{
69 /* LZ4 has a fast version if destLen is large enough
70 * to hold a worst case result
71 */
73}
74
75int G_lz4_compress(unsigned char *src, int src_sz, unsigned char *dst,
76 int dst_sz)
77{
78 int err, nbytes, buf_sz;
79 unsigned char *buf;
80
81 /* Catch errors early */
82 if (src == NULL || dst == NULL) {
83 if (src == NULL)
84 G_warning(_("No source buffer"));
85
86 if (dst == NULL)
87 G_warning(_("No destination buffer"));
88 return -1;
89 }
90
91 /* Don't do anything if either of these are true */
92 if (src_sz <= 0 || dst_sz <= 0) {
93 if (src_sz <= 0)
94 G_warning(_("Invalid source buffer size %d"), src_sz);
95 if (dst_sz <= 0)
96 G_warning(_("Invalid destination buffer size %d"), dst_sz);
97 return 0;
98 }
99
100 /* Output buffer should be large enough for single pass compression */
101 buf = dst;
103 if (buf_sz > dst_sz) {
104 G_warning(
105 "G_lz4_compress(): programmer error, destination is too small");
106 if (NULL ==
107 (buf = (unsigned char *)G_calloc(buf_sz, sizeof(unsigned char))))
108 return -1;
109 }
110 else
111 buf_sz = dst_sz;
112
113 /* Do single pass compression */
114 err = LZ4_compress_default((char *)src, (char *)buf, src_sz, buf_sz);
115
116 if (err <= 0) {
117 G_warning(_("LZ4 compression error"));
118 if (buf != dst)
119 G_free(buf);
120 return -1;
121 }
122 if (err >= src_sz) {
123 /* compression not possible */
124 if (buf != dst)
125 G_free(buf);
126 return -2;
127 }
128
129 /* bytes of compressed data is return value */
130 nbytes = err;
131
132 if (buf != dst) {
133 /* Copy the data from buf to dst */
134 for (err = 0; err < nbytes; err++)
135 dst[err] = buf[err];
136
137 G_free(buf);
138 }
139
140 return nbytes;
141}
142
143int G_lz4_expand(unsigned char *src, int src_sz, unsigned char *dst, int dst_sz)
144{
145 int err, nbytes;
146
147 /* Catch error condition */
148 if (src == NULL || dst == NULL) {
149 if (src == NULL)
150 G_warning(_("No source buffer"));
151
152 if (dst == NULL)
153 G_warning(_("No destination buffer"));
154 return -2;
155 }
156
157 /* Don't do anything if either of these are true */
158 if (src_sz <= 0 || dst_sz <= 0) {
159 if (src_sz <= 0)
160 G_warning(_("Invalid source buffer size %d"), src_sz);
161 if (dst_sz <= 0)
162 G_warning(_("Invalid destination buffer size %d"), dst_sz);
163 return 0;
164 }
165
166 /* Do single pass decompress */
167 err = LZ4_decompress_safe((char *)src, (char *)dst, src_sz, dst_sz);
168 /* err = LZ4_decompress_fast(src, dst, src_sz); */
169
170 if (err <= 0) {
171 G_warning(_("LZ4 decompression error"));
172 return -1;
173 }
174
175 /* Number of bytes inflated to output stream is return value */
176 nbytes = err;
177
178 if (nbytes != dst_sz) {
179 /* TODO: it is not an error if destination is larger than needed */
180 G_warning(_("Got uncompressed size %d, expected %d"), (int)nbytes,
181 dst_sz);
182 return -1;
183 }
184
185 return nbytes;
186}
187
188/* vim: set softtabstop=4 shiftwidth=4 expandtab: */
#define NULL
Definition ccmath.h:32
int G_lz4_compress(unsigned char *src, int src_sz, unsigned char *dst, int dst_sz)
Definition cmprlz4.c:75
int G_lz4_expand(unsigned char *src, int src_sz, unsigned char *dst, int dst_sz)
Definition cmprlz4.c:143
int G_lz4_compress_bound(int src_sz)
Definition cmprlz4.c:67
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:145
#define G_calloc(m, n)
Definition defs/gis.h:137
void G_warning(const char *,...) __attribute__((format(printf
#define _(str)
Definition glocale.h:10
int LZ4_compressBound(int isize)
Definition lz4.c:879
int LZ4_compress_default(const char *src, char *dst, int srcSize, int dstCapacity)
Definition lz4.c:1808
int LZ4_decompress_safe(const char *src, char *dst, int compressedSize, int dstCapacity)
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)