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
62static const l_int32 L_BUF_SIZE = 32768;
63static const l_int32 ZLIB_COMPRESSION_LEVEL = 6;
64
65#ifndef NO_CONSOLE_IO
66#define DEBUG 0
67#endif /* ~NO_CONSOLE_IO */
68
69
91l_uint8 *
92zlibCompress(const l_uint8 *datain,
93 size_t nin,
94 size_t *pnout)
95{
96l_uint8 *dataout;
97l_int32 status, success;
98l_int32 flush;
99size_t nbytes;
100l_uint8 *bufferin, *bufferout;
101L_BBUFFER *bbin, *bbout;
102z_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
168cleanup_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
195l_uint8 *
196zlibUncompress(const l_uint8 *datain,
197 size_t nin,
198 size_t *pnout)
199{
200l_uint8 *dataout;
201l_uint8 *bufferin, *bufferout;
202l_int32 status, success;
203size_t nbytes;
204L_BBUFFER *bbin, *bbout;
205z_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
267cleanup_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_uint8 * bbufferDestroyAndSaveData(L_BBUFFER **pbb, size_t *pnbytes)
bbufferDestroyAndSaveData()
Definition: bbuffer.c:206
L_BBUFFER * bbufferCreate(const l_uint8 *indata, l_int32 nalloc)
bbufferCreate()
Definition: bbuffer.c:130
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 * zlibCompress(const l_uint8 *datain, size_t nin, size_t *pnout)
zlibCompress()
Definition: zlibmem.c:92
l_uint8 * zlibUncompress(const l_uint8 *datain, size_t nin, size_t *pnout)
zlibUncompress()
Definition: zlibmem.c:196