Leptonica  1.82.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(const 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  lept_stderr(" wrote %zu bytes to bufferin\n", nbytes);
146 #endif /* DEBUG */
147  z.avail_in = nbytes;
148  }
149  flush = (bbin->n) ? Z_SYNC_FLUSH : Z_FINISH;
150  status = deflate(&z, flush);
151 #if DEBUG
152  lept_stderr(" status is %d, bytesleft = %u, totalout = %zu\n",
153  status, z.avail_out, z.total_out);
154 #endif /* DEBUG */
155  nbytes = L_BUF_SIZE - z.avail_out;
156  if (nbytes) {
157  bbufferRead(bbout, bufferout, nbytes);
158 #if DEBUG
159  lept_stderr(" read %zu bytes from bufferout\n", nbytes);
160 #endif /* DEBUG */
161  }
162  z.next_out = bufferout;
163  z.avail_out = L_BUF_SIZE;
164  } while (flush != Z_FINISH);
165 
166  deflateEnd(&z);
167 
168 cleanup_arrays:
169  if (success) {
170  dataout = bbufferDestroyAndSaveData(&bbout, pnout);
171  } else {
172  dataout = NULL;
173  bbufferDestroy(&bbout);
174  }
175  bbufferDestroy(&bbin);
176  LEPT_FREE(bufferin);
177  LEPT_FREE(bufferout);
178  return dataout;
179 }
180 
181 
195 l_uint8 *
196 zlibUncompress(const l_uint8 *datain,
197  size_t nin,
198  size_t *pnout)
199 {
200 l_uint8 *dataout;
201 l_uint8 *bufferin, *bufferout;
202 l_int32 status, success;
203 size_t nbytes;
204 L_BBUFFER *bbin, *bbout;
205 z_stream z;
206 
207  PROCNAME("zlibUncompress");
208 
209  if (!datain)
210  return (l_uint8 *)ERROR_PTR("datain not defined", procName, NULL);
211 
212  /* Set up fixed size buffers used in z_stream */
213  bufferin = (l_uint8 *)LEPT_CALLOC(L_BUF_SIZE, sizeof(l_uint8));
214  bufferout = (l_uint8 *)LEPT_CALLOC(L_BUF_SIZE, sizeof(l_uint8));
215 
216  /* Set up bbuffers and load bbin with the data */
217  bbin = bbufferCreate(datain, nin);
218  bbout = bbufferCreate(NULL, 0);
219 
220  success = TRUE;
221  if (!bufferin || !bufferout || !bbin || !bbout) {
222  L_ERROR("calloc fail for buffer\n", procName);
223  success = FALSE;
224  goto cleanup_arrays;
225  }
226 
227  z.zalloc = (alloc_func)0;
228  z.zfree = (free_func)0;
229 
230  z.next_in = bufferin;
231  z.avail_in = 0;
232  z.next_out = bufferout;
233  z.avail_out = L_BUF_SIZE;
234 
235  inflateInit(&z);
236 
237 
238  for ( ; ; ) {
239  if (z.avail_in == 0) {
240  z.next_in = bufferin;
241  bbufferWrite(bbin, bufferin, L_BUF_SIZE, &nbytes);
242 #if DEBUG
243  lept_stderr(" wrote %d bytes to bufferin\n", nbytes);
244 #endif /* DEBUG */
245  z.avail_in = nbytes;
246  }
247  if (z.avail_in == 0)
248  break;
249  status = inflate(&z, Z_SYNC_FLUSH);
250 #if DEBUG
251  lept_stderr(" status is %d, bytesleft = %d, totalout = %d\n",
252  status, z.avail_out, z.total_out);
253 #endif /* DEBUG */
254  nbytes = L_BUF_SIZE - z.avail_out;
255  if (nbytes) {
256  bbufferRead(bbout, bufferout, nbytes);
257 #if DEBUG
258  lept_stderr(" read %d bytes from bufferout\n", nbytes);
259 #endif /* DEBUG */
260  }
261  z.next_out = bufferout;
262  z.avail_out = L_BUF_SIZE;
263  }
264 
265  inflateEnd(&z);
266 
267 cleanup_arrays:
268  if (success) {
269  dataout = bbufferDestroyAndSaveData(&bbout, pnout);
270  } else {
271  dataout = NULL;
272  bbufferDestroy(&bbout);
273  }
274  bbufferDestroy(&bbin);
275  LEPT_FREE(bufferin);
276  LEPT_FREE(bufferout);
277  return dataout;
278 }
279 
280 /* --------------------------------------------*/
281 #endif /* HAVE_LIBZ */
282 /* --------------------------------------------*/
l_ok bbufferWrite(L_BBUFFER *bb, l_uint8 *dest, size_t nbytes, size_t *pnout)
bbufferWrite()
Definition: bbuffer.c:394
l_ok bbufferRead(L_BBUFFER *bb, l_uint8 *src, l_int32 nbytes)
bbufferRead()
Definition: bbuffer.c:265
L_BBUFFER * bbufferCreate(const l_uint8 *indata, l_int32 nalloc)
bbufferCreate()
Definition: bbuffer.c:130
l_uint8 * bbufferDestroyAndSaveData(L_BBUFFER **pbb, size_t *pnbytes)
bbufferDestroyAndSaveData()
Definition: bbuffer.c:206
void bbufferDestroy(L_BBUFFER **pbb)
bbufferDestroy()
Definition: bbuffer.c:172
#define L_BUF_SIZE
Definition: classapp.c:59
l_int32 n
Definition: bbuffer.h:53
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306
l_uint8 * zlibUncompress(const l_uint8 *datain, size_t nin, size_t *pnout)
zlibUncompress()
Definition: zlibmem.c:196
l_uint8 * zlibCompress(const l_uint8 *datain, size_t nin, size_t *pnout)
zlibCompress()
Definition: zlibmem.c:92