Leptonica  1.83.1
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  if (!datain)
105  return (l_uint8 *)ERROR_PTR("datain not defined", __func__, NULL);
106 
107  /* Set up fixed size buffers used in z_stream */
108  bufferin = (l_uint8 *)LEPT_CALLOC(L_BUF_SIZE, sizeof(l_uint8));
109  bufferout = (l_uint8 *)LEPT_CALLOC(L_BUF_SIZE, sizeof(l_uint8));
110 
111  /* Set up bbuffers and load bbin with the data */
112  bbin = bbufferCreate(datain, nin);
113  bbout = bbufferCreate(NULL, 0);
114 
115  success = TRUE;
116  if (!bufferin || !bufferout || !bbin || !bbout) {
117  L_ERROR("calloc fail for buffer\n", __func__);
118  success = FALSE;
119  goto cleanup_arrays;
120  }
121 
122  z.zalloc = (alloc_func)0;
123  z.zfree = (free_func)0;
124  z.opaque = (voidpf)0;
125  z.next_in = bufferin;
126  z.avail_in = 0;
127  z.next_out = bufferout;
128  z.avail_out = L_BUF_SIZE;
129 
130  status = deflateInit(&z, ZLIB_COMPRESSION_LEVEL);
131  if (status != Z_OK) {
132  L_ERROR("deflateInit failed\n", __func__);
133  success = FALSE;
134  goto cleanup_arrays;
135  }
136 
137  do {
138  if (z.avail_in == 0) {
139  z.next_in = bufferin;
140  bbufferWrite(bbin, bufferin, L_BUF_SIZE, &nbytes);
141 #if DEBUG
142  lept_stderr(" wrote %zu bytes to bufferin\n", nbytes);
143 #endif /* DEBUG */
144  z.avail_in = nbytes;
145  }
146  flush = (bbin->n) ? Z_SYNC_FLUSH : Z_FINISH;
147  status = deflate(&z, flush);
148 #if DEBUG
149  lept_stderr(" status is %d, bytesleft = %u, totalout = %zu\n",
150  status, z.avail_out, z.total_out);
151 #endif /* DEBUG */
152  nbytes = L_BUF_SIZE - z.avail_out;
153  if (nbytes) {
154  bbufferRead(bbout, bufferout, nbytes);
155 #if DEBUG
156  lept_stderr(" read %zu bytes from bufferout\n", nbytes);
157 #endif /* DEBUG */
158  }
159  z.next_out = bufferout;
160  z.avail_out = L_BUF_SIZE;
161  } while (flush != Z_FINISH);
162 
163  deflateEnd(&z);
164 
165 cleanup_arrays:
166  if (success) {
167  dataout = bbufferDestroyAndSaveData(&bbout, pnout);
168  } else {
169  dataout = NULL;
170  bbufferDestroy(&bbout);
171  }
172  bbufferDestroy(&bbin);
173  LEPT_FREE(bufferin);
174  LEPT_FREE(bufferout);
175  return dataout;
176 }
177 
178 
192 l_uint8 *
193 zlibUncompress(const l_uint8 *datain,
194  size_t nin,
195  size_t *pnout)
196 {
197 l_uint8 *dataout;
198 l_uint8 *bufferin, *bufferout;
199 l_int32 status, success;
200 size_t nbytes;
201 L_BBUFFER *bbin, *bbout;
202 z_stream z;
203 
204  if (!datain)
205  return (l_uint8 *)ERROR_PTR("datain not defined", __func__, NULL);
206 
207  /* Set up fixed size buffers used in z_stream */
208  bufferin = (l_uint8 *)LEPT_CALLOC(L_BUF_SIZE, sizeof(l_uint8));
209  bufferout = (l_uint8 *)LEPT_CALLOC(L_BUF_SIZE, sizeof(l_uint8));
210 
211  /* Set up bbuffers and load bbin with the data */
212  bbin = bbufferCreate(datain, nin);
213  bbout = bbufferCreate(NULL, 0);
214 
215  success = TRUE;
216  if (!bufferin || !bufferout || !bbin || !bbout) {
217  L_ERROR("calloc fail for buffer\n", __func__);
218  success = FALSE;
219  goto cleanup_arrays;
220  }
221 
222  z.zalloc = (alloc_func)0;
223  z.zfree = (free_func)0;
224  z.next_in = bufferin;
225  z.avail_in = 0;
226  z.next_out = bufferout;
227  z.avail_out = L_BUF_SIZE;
228 
229  status = inflateInit(&z);
230  if (status != Z_OK) {
231  L_ERROR("inflateInit fail for buffer\n", __func__);
232  success = FALSE;
233  goto cleanup_arrays;
234  }
235 
236  for ( ; ; ) {
237  if (z.avail_in == 0) {
238  z.next_in = bufferin;
239  bbufferWrite(bbin, bufferin, L_BUF_SIZE, &nbytes);
240 #if DEBUG
241  lept_stderr(" wrote %d bytes to bufferin\n", nbytes);
242 #endif /* DEBUG */
243  z.avail_in = nbytes;
244  }
245  if (z.avail_in == 0)
246  break;
247  status = inflate(&z, Z_SYNC_FLUSH);
248 #if DEBUG
249  lept_stderr(" status is %d, bytesleft = %d, totalout = %d\n",
250  status, z.avail_out, z.total_out);
251 #endif /* DEBUG */
252  nbytes = L_BUF_SIZE - z.avail_out;
253  if (nbytes) {
254  bbufferRead(bbout, bufferout, nbytes);
255 #if DEBUG
256  lept_stderr(" read %d bytes from bufferout\n", nbytes);
257 #endif /* DEBUG */
258  }
259  z.next_out = bufferout;
260  z.avail_out = L_BUF_SIZE;
261  }
262 
263  inflateEnd(&z);
264 
265 cleanup_arrays:
266  if (success) {
267  dataout = bbufferDestroyAndSaveData(&bbout, pnout);
268  } else {
269  dataout = NULL;
270  bbufferDestroy(&bbout);
271  }
272  bbufferDestroy(&bbin);
273  LEPT_FREE(bufferin);
274  LEPT_FREE(bufferout);
275  return dataout;
276 }
277 
278 /* --------------------------------------------*/
279 #endif /* HAVE_LIBZ */
280 /* --------------------------------------------*/
l_ok bbufferWrite(L_BBUFFER *bb, l_uint8 *dest, size_t nbytes, size_t *pnout)
bbufferWrite()
Definition: bbuffer.c:382
l_ok bbufferRead(L_BBUFFER *bb, l_uint8 *src, l_int32 nbytes)
bbufferRead()
Definition: bbuffer.c:259
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:202
void bbufferDestroy(L_BBUFFER **pbb)
bbufferDestroy()
Definition: bbuffer.c:170
#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:193
l_uint8 * zlibCompress(const l_uint8 *datain, size_t nin, size_t *pnout)
zlibCompress()
Definition: zlibmem.c:92