Leptonica  1.77.0
Image processing and image analysis suite
zlibmem.c
Go to the documentation of this file.
1 /*====================================================================*
2  - Copyright (C) 2001 Leptonica. All rights reserved.
3  -
4  - Redistribution and use in source and binary forms, with or without
5  - modification, are permitted provided that the following conditions
6  - are met:
7  - 1. Redistributions of source code must retain the above copyright
8  - notice, this list of conditions and the following disclaimer.
9  - 2. Redistributions in binary form must reproduce the above
10  - copyright notice, this list of conditions and the following
11  - disclaimer in the documentation and/or other materials
12  - provided with the distribution.
13  -
14  - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18  - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23  - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *====================================================================*/
26 
27 
50 #ifdef HAVE_CONFIG_H
51 #include "config_auto.h"
52 #endif /* HAVE_CONFIG_H */
53 
54 #include "allheaders.h"
55 
56 /* --------------------------------------------*/
57 #if HAVE_LIBZ /* defined in environ.h */
58 /* --------------------------------------------*/
59 
60 #include "zlib.h"
61 
62 static const l_int32 L_BUF_SIZE = 32768;
63 static const l_int32 ZLIB_COMPRESSION_LEVEL = 6;
64 
65 #ifndef NO_CONSOLE_IO
66 #define DEBUG 0
67 #endif /* ~NO_CONSOLE_IO */
68 
69 
91 l_uint8 *
92 zlibCompress(l_uint8 *datain,
93  size_t nin,
94  size_t *pnout)
95 {
96 l_uint8 *dataout;
97 l_int32 status, success;
98 l_int32 flush;
99 size_t nbytes;
100 l_uint8 *bufferin, *bufferout;
101 L_BBUFFER *bbin, *bbout;
102 z_stream z;
103 
104  PROCNAME("zlibCompress");
105 
106  if (!datain)
107  return (l_uint8 *)ERROR_PTR("datain not defined", procName, NULL);
108 
109  /* Set up fixed size buffers used in z_stream */
110  bufferin = (l_uint8 *)LEPT_CALLOC(L_BUF_SIZE, sizeof(l_uint8));
111  bufferout = (l_uint8 *)LEPT_CALLOC(L_BUF_SIZE, sizeof(l_uint8));
112 
113  /* Set up bbuffers and load bbin with the data */
114  bbin = bbufferCreate(datain, nin);
115  bbout = bbufferCreate(NULL, 0);
116 
117  success = TRUE;
118  if (!bufferin || !bufferout || !bbin || !bbout) {
119  L_ERROR("calloc fail for buffer\n", procName);
120  success = FALSE;
121  goto cleanup_arrays;
122  }
123 
124  z.zalloc = (alloc_func)0;
125  z.zfree = (free_func)0;
126  z.opaque = (voidpf)0;
127 
128  z.next_in = bufferin;
129  z.avail_in = 0;
130  z.next_out = bufferout;
131  z.avail_out = L_BUF_SIZE;
132 
133  status = deflateInit(&z, ZLIB_COMPRESSION_LEVEL);
134  if (status != Z_OK) {
135  L_ERROR("deflateInit failed\n", procName);
136  success = FALSE;
137  goto cleanup_arrays;
138  }
139 
140  do {
141  if (z.avail_in == 0) {
142  z.next_in = bufferin;
143  bbufferWrite(bbin, bufferin, L_BUF_SIZE, &nbytes);
144 #if DEBUG
145  fprintf(stderr, " wrote %lu bytes to bufferin\n",
146  (unsigned long)nbytes);
147 #endif /* DEBUG */
148  z.avail_in = nbytes;
149  }
150  flush = (bbin->n) ? Z_SYNC_FLUSH : Z_FINISH;
151  status = deflate(&z, flush);
152 #if DEBUG
153  fprintf(stderr, " status is %d, bytesleft = %u, totalout = %lu\n",
154  status, z.avail_out, z.total_out);
155 #endif /* DEBUG */
156  nbytes = L_BUF_SIZE - z.avail_out;
157  if (nbytes) {
158  bbufferRead(bbout, bufferout, nbytes);
159 #if DEBUG
160  fprintf(stderr, " read %lu bytes from bufferout\n",
161  (unsigned long)nbytes);
162 #endif /* DEBUG */
163  }
164  z.next_out = bufferout;
165  z.avail_out = L_BUF_SIZE;
166  } while (flush != Z_FINISH);
167 
168  deflateEnd(&z);
169 
170 cleanup_arrays:
171  if (success) {
172  dataout = bbufferDestroyAndSaveData(&bbout, pnout);
173  } else {
174  dataout = NULL;
175  bbufferDestroy(&bbout);
176  }
177  bbufferDestroy(&bbin);
178  LEPT_FREE(bufferin);
179  LEPT_FREE(bufferout);
180  return dataout;
181 }
182 
183 
197 l_uint8 *
198 zlibUncompress(l_uint8 *datain,
199  size_t nin,
200  size_t *pnout)
201 {
202 l_uint8 *dataout;
203 l_uint8 *bufferin, *bufferout;
204 l_int32 status, success;
205 size_t nbytes;
206 L_BBUFFER *bbin, *bbout;
207 z_stream z;
208 
209  PROCNAME("zlibUncompress");
210 
211  if (!datain)
212  return (l_uint8 *)ERROR_PTR("datain not defined", procName, NULL);
213 
214  /* Set up fixed size buffers used in z_stream */
215  bufferin = (l_uint8 *)LEPT_CALLOC(L_BUF_SIZE, sizeof(l_uint8));
216  bufferout = (l_uint8 *)LEPT_CALLOC(L_BUF_SIZE, sizeof(l_uint8));
217 
218  /* Set up bbuffers and load bbin with the data */
219  bbin = bbufferCreate(datain, nin);
220  bbout = bbufferCreate(NULL, 0);
221 
222  success = TRUE;
223  if (!bufferin || !bufferout || !bbin || !bbout) {
224  L_ERROR("calloc fail for buffer\n", procName);
225  success = FALSE;
226  goto cleanup_arrays;
227  }
228 
229  z.zalloc = (alloc_func)0;
230  z.zfree = (free_func)0;
231 
232  z.next_in = bufferin;
233  z.avail_in = 0;
234  z.next_out = bufferout;
235  z.avail_out = L_BUF_SIZE;
236 
237  inflateInit(&z);
238 
239 
240  for ( ; ; ) {
241  if (z.avail_in == 0) {
242  z.next_in = bufferin;
243  bbufferWrite(bbin, bufferin, L_BUF_SIZE, &nbytes);
244 #if DEBUG
245  fprintf(stderr, " wrote %d bytes to bufferin\n", nbytes);
246 #endif /* DEBUG */
247  z.avail_in = nbytes;
248  }
249  if (z.avail_in == 0)
250  break;
251  status = inflate(&z, Z_SYNC_FLUSH);
252 #if DEBUG
253  fprintf(stderr, " status is %d, bytesleft = %d, totalout = %d\n",
254  status, z.avail_out, z.total_out);
255 #endif /* DEBUG */
256  nbytes = L_BUF_SIZE - z.avail_out;
257  if (nbytes) {
258  bbufferRead(bbout, bufferout, nbytes);
259 #if DEBUG
260  fprintf(stderr, " read %d bytes from bufferout\n", nbytes);
261 #endif /* DEBUG */
262  }
263  z.next_out = bufferout;
264  z.avail_out = L_BUF_SIZE;
265  }
266 
267  inflateEnd(&z);
268 
269 cleanup_arrays:
270  if (success) {
271  dataout = bbufferDestroyAndSaveData(&bbout, pnout);
272  } else {
273  dataout = NULL;
274  bbufferDestroy(&bbout);
275  }
276  bbufferDestroy(&bbin);
277  LEPT_FREE(bufferin);
278  LEPT_FREE(bufferout);
279  return dataout;
280 }
281 
282 /* --------------------------------------------*/
283 #endif /* HAVE_LIBZ */
284 /* --------------------------------------------*/
l_int32 n
Definition: bbuffer.h:53
l_uint8 * zlibCompress(l_uint8 *datain, size_t nin, size_t *pnout)
zlibCompress()
Definition: zlibmem.c:92
L_BBUFFER * bbufferCreate(const l_uint8 *indata, l_int32 nalloc)
bbufferCreate()
Definition: bbuffer.c:124
l_ok bbufferWrite(L_BBUFFER *bb, l_uint8 *dest, size_t nbytes, size_t *pnout)
bbufferWrite()
Definition: bbuffer.c:390
l_uint8 * bbufferDestroyAndSaveData(L_BBUFFER **pbb, size_t *pnbytes)
bbufferDestroyAndSaveData()
Definition: bbuffer.c:203
l_uint8 * zlibUncompress(l_uint8 *datain, size_t nin, size_t *pnout)
zlibUncompress()
Definition: zlibmem.c:198
void bbufferDestroy(L_BBUFFER **pbb)
bbufferDestroy()
Definition: bbuffer.c:167
l_ok bbufferRead(L_BBUFFER *bb, l_uint8 *src, l_int32 nbytes)
bbufferRead()
Definition: bbuffer.c:262
static const l_int32 L_BUF_SIZE
Definition: classapp.c:55