GRASS GIS 7 Programmer's Manual  7.4.1(2018)-exported
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. Its 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  * 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_lz4_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 LZ4 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_lz4_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 lz4 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 #include <grass/gis.h>
66 #include <grass/glocale.h>
67 
68 #include "lz4.h"
69 
70 
71 int
72 G_lz4_compress(unsigned char *src, int src_sz, unsigned char *dst,
73  int dst_sz)
74 {
75  int err, nbytes, buf_sz;
76  unsigned char *buf;
77 
78  /* Catch errors early */
79  if (src == NULL || dst == NULL) {
80  if (src == NULL)
81  G_warning(_("No source buffer"));
82 
83  if (dst == NULL)
84  G_warning(_("No destination buffer"));
85  return -1;
86  }
87 
88  /* Don't do anything if either of these are true */
89  if (src_sz <= 0 || dst_sz <= 0) {
90  if (src_sz <= 0)
91  G_warning(_("Invalid source buffer size %d"), src_sz);
92  if (dst_sz <= 0)
93  G_warning(_("Invalid destination buffer size %d"), dst_sz);
94  return 0;
95  }
96 
97  /* Output buffer has to be larger for single pass compression */
98  buf_sz = LZ4_compressBound(src_sz);
99  if (NULL == (buf = (unsigned char *)
100  G_calloc(buf_sz, sizeof(unsigned char))))
101  return -1;
102 
103  /* Do single pass compression */
104  err = LZ4_compress_default((char *)src, (char *)buf, src_sz, buf_sz);
105 
106  if (err <= 0) {
107  G_warning(_("LZ4 compression error"));
108  G_free(buf);
109  return -1;
110  }
111  if (err >= src_sz) {
112  /* compression not possible */
113  G_free(buf);
114  return -2;
115  }
116 
117  /* bytes of compressed data is return value */
118  nbytes = err;
119 
120  /* Copy the data from buf to dst */
121  for (err = 0; err < nbytes; err++)
122  dst[err] = buf[err];
123 
124  G_free(buf);
125 
126  return nbytes;
127 }
128 
129 int
130 G_lz4_expand(unsigned char *src, int src_sz, unsigned char *dst,
131  int dst_sz)
132 {
133  int err, nbytes;
134 
135  /* Catch error condition */
136  if (src == NULL || dst == NULL) {
137  if (src == NULL)
138  G_warning(_("No source buffer"));
139 
140  if (dst == NULL)
141  G_warning(_("No destination buffer"));
142  return -2;
143  }
144 
145  /* Don't do anything if either of these are true */
146  if (src_sz <= 0 || dst_sz <= 0) {
147  if (src_sz <= 0)
148  G_warning(_("Invalid source buffer size %d"), src_sz);
149  if (dst_sz <= 0)
150  G_warning(_("Invalid destination buffer size %d"), dst_sz);
151  return 0;
152  }
153 
154  /* Do single pass decompress */
155  err = LZ4_decompress_safe((char *)src, (char *)dst, src_sz, dst_sz);
156  /* err = LZ4_decompress_fast(src, dst, src_sz); */
157 
158  if (err <= 0) {
159  G_warning(_("LZ4 decompression error"));
160  return -1;
161  }
162 
163  /* Number of bytes inflated to output stream is return value */
164  nbytes = err;
165 
166  if (nbytes != dst_sz) {
167  /* TODO: it is not an error if destination is larger than needed */
168  G_warning(_("Got uncompressed size %d, expected %d"), (int)nbytes, dst_sz);
169  return -1;
170  }
171 
172  return nbytes;
173 }
174 
175 
176 /* vim: set softtabstop=4 shiftwidth=4 expandtab: */
int G_lz4_expand(unsigned char *src, int src_sz, unsigned char *dst, int dst_sz)
Definition: cmprlz4.c:130
char * dst
Definition: lz4.h:354
int LZ4_decompress_safe(const char *source, char *dest, int compressedSize, int maxDecompressedSize)
Definition: lz4.c:1288
int LZ4_compress_default(const char *source, char *dest, int inputSize, int maxOutputSize)
Definition: lz4.c:697
#define NULL
Definition: ccmath.h:32
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
Definition: symbol/read.c:220
int G_lz4_compress(unsigned char *src, int src_sz, unsigned char *dst, int dst_sz)
Definition: cmprlz4.c:72
int LZ4_compressBound(int isize)
Definition: lz4.c:372
void G_free(void *buf)
Free allocated memory.
Definition: alloc.c:149
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: gis/error.c:204