GRASS GIS 7 Programmer's Manual  7.5.svn(2017)-r71806
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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  * COPYRIGHT: (C) 2015 by the GRASS Development Team
15  *
16  * This program is free software under the GNU General Public
17  * License (version 2 or greater). Read the file COPYING that
18  * comes with GRASS for details.
19  *
20  *****************************************************************************/
21 
22 /********************************************************************
23  * int *
24  * G_bz2_compress (src, srz_sz, dst, dst_sz) *
25  * int src_sz, dst_sz; *
26  * unsigned char *src, *dst; *
27  * ---------------------------------------------------------------- *
28  * This function is a wrapper around the bzip2 compression *
29  * function. It uses an all or nothing call. *
30  * If you need a continuous compression scheme, you'll have to code *
31  * your own. *
32  * In order to do a single pass compression, the input src must be *
33  * copied to a buffer 1% + 600 bytes larger than the data. This *
34  * may cause performance degradation. *
35  * *
36  * The function either returns the number of bytes of compressed *
37  * data in dst, or an error code. *
38  * *
39  * Errors include: *
40  * -1 -- Compression failed. *
41  * -2 -- dst is too small. *
42  * *
43  * ================================================================ *
44  * int *
45  * G_bz2_expand (src, src_sz, dst, dst_sz) *
46  * int src_sz, dst_sz; *
47  * unsigned char *src, *dst; *
48  * ---------------------------------------------------------------- *
49  * This function is a wrapper around the bzip2 decompression *
50  * function. It uses a single pass call to inflate(). *
51  * If you need a continuous expansion scheme, you'll have to code *
52  * 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_BZLIB_H
66 #include <bzlib.h>
67 #endif
68 
69 #include <grass/gis.h>
70 #include <grass/glocale.h>
71 
72 
73 int
74 G_bz2_compress(unsigned char *src, int src_sz, unsigned char *dst,
75  int dst_sz)
76 {
77  int err;
78  unsigned int i, nbytes, buf_sz;
79  unsigned char *buf;
80 
81 #ifndef HAVE_BZLIB_H
82  G_fatal_error(_("GRASS needs to be compiled with BZIP2 for BZIP2 compression"));
83  return -1;
84 #else
85 
86  /* Catch errors early */
87  if (src == NULL || dst == NULL)
88  return -1;
89 
90  /* Don't do anything if src is empty */
91  if (src_sz <= 0)
92  return 0;
93 
94  /* Output buffer has to be 1% + 600 bytes bigger for single pass compression */
95  buf_sz = (unsigned int)((double)dst_sz * 1.01 + (double)600);
96 
97  if (NULL == (buf = (unsigned char *)
98  G_calloc(buf_sz, sizeof(unsigned char))))
99  return -1;
100 
101  /* Do single pass compression */
102  nbytes = buf_sz;
103  err = BZ2_bzBuffToBuffCompress((char *)buf, &nbytes, /* destination */
104  (char *)src, src_sz, /* source */
105  9, /* blockSize100k */
106  0, /* verbosity */
107  100); /* workFactor */
108  if (err != BZ_OK) {
109  G_free(buf);
110  return -1;
111  }
112 
113  /* updated buf_sz is bytes of compressed data */
114  if (nbytes >= (unsigned int)src_sz) {
115  /* compression not possible */
116  G_free(buf);
117  return -2;
118  }
119 
120  /* dst too small */
121  if ((unsigned int)dst_sz < nbytes)
122  return -2;
123 
124  /* Copy the data from buf to dst */
125  for (i = 0; i < nbytes; i++)
126  dst[i] = buf[i];
127 
128  G_free(buf);
129 
130  return nbytes;
131 #endif
132 } /* G_bz2_compress() */
133 
134 int
135 G_bz2_expand(unsigned char *src, int src_sz, unsigned char *dst,
136  int dst_sz)
137 {
138  int err;
139  unsigned int nbytes;
140 
141 #ifndef HAVE_BZLIB_H
142  G_fatal_error(_("GRASS needs to be compiled with BZIP2 for BZIP2 compression"));
143  return -2;
144 #else
145 
146  /* Catch error condition */
147  if (src == NULL || dst == NULL)
148  return -2;
149 
150  /* Don't do anything if either of these are true */
151  if (src_sz <= 0 || dst_sz <= 0)
152  return 0;
153 
154 
155  /* Do single pass decompression */
156  nbytes = dst_sz;
157  err = BZ2_bzBuffToBuffDecompress((char *)dst, &nbytes, /* destination */
158  (char *)src, src_sz, /* source */
159  0, /* small */
160  0); /* verbosity */
161 
162  /* Number of bytes inflated to output stream is
163  * updated buffer size
164  */
165 
166  if (!(err == BZ_OK)) {
167  return -1;
168  }
169 
170  return nbytes;
171 #endif
172 }
173 
174 
175 /* vim: set softtabstop=4 shiftwidth=4 expandtab: */
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:149
char * dst
Definition: lz4.h:354
#define NULL
Definition: ccmath.h:32
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: gis/error.c:159
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
Definition: symbol/read.c:220
int G_bz2_compress(unsigned char *src, int src_sz, unsigned char *dst, int dst_sz)
Definition: cmprbzip.c:74
#define _(str)
Definition: glocale.h:13
int
Reads the categories file for map name in mapset and stores the categories in the pcats structure...
int G_bz2_expand(unsigned char *src, int src_sz, unsigned char *dst, int dst_sz)
Definition: cmprbzip.c:135