Leptonica 1.68
C Image Processing Library

zlibmem.c

Go to the documentation of this file.
00001 /*====================================================================*
00002  -  Copyright (C) 2001 Leptonica.  All rights reserved.
00003  -  This software is distributed in the hope that it will be
00004  -  useful, but with NO WARRANTY OF ANY KIND.
00005  -  No author or distributor accepts responsibility to anyone for the
00006  -  consequences of using this software, or for whether it serves any
00007  -  particular purpose or works at all, unless he or she says so in
00008  -  writing.  Everyone is granted permission to copy, modify and
00009  -  redistribute this source code, for commercial or non-commercial
00010  -  purposes, with the following restrictions: (1) the origin of this
00011  -  source code must not be misrepresented; (2) modified versions must
00012  -  be plainly marked as such; and (3) this notice may not be removed
00013  -  or altered from any source or modified source distribution.
00014  *====================================================================*/
00015 
00016 
00017 /*
00018  *   zlibmem.c
00019  *
00020  *      zlib operations in memory, using bbuffer
00021  *          l_uint8   *zlibCompress()
00022  *          l_uint8   *zlibUncompress()
00023  *
00024  *
00025  *    This provides an example use of the byte buffer utility
00026  *    (see bbuffer.c for details of how the bbuffer works internally).
00027  *    We use zlib to compress and decompress a byte array from
00028  *    one memory buffer to another.  The standard method uses streams,
00029  *    but here we use the bbuffer as an expandable queue of pixels
00030  *    for both the reading and writing sides of each operation.
00031  *
00032  *    With memory mapping, one should be able to compress between
00033  *    memory buffers by using the file system to buffer everything in
00034  *    the background, but the bbuffer implementation is more portable.
00035  */
00036 
00037 #include "allheaders.h"
00038 
00039 #ifdef HAVE_CONFIG_H
00040 #include "config_auto.h"
00041 #endif  /* HAVE_CONFIG_H */
00042 
00043 /* --------------------------------------------*/
00044 #if  HAVE_LIBZ   /* defined in environ.h */
00045 /* --------------------------------------------*/
00046 
00047 #include "zlib.h"
00048 
00049 static const l_int32  L_BUF_SIZE = 32768;
00050 static const l_int32  ZLIB_COMPRESSION_LEVEL = 6;
00051 
00052 
00053 /*!
00054  *  zlibCompress()
00055  *
00056  *      Input:  datain (byte buffer with input data)
00057  *              nin    (number of bytes of input data)
00058  *              &nout  (<return> number of bytes of output data)
00059  *      Return: dataout (compressed data), or null on error
00060  *
00061  *  Notes:
00062  *      (1) We repeatedly read in and fill up an input buffer,
00063  *          compress the data, and read it back out.  zlib
00064  *          uses two byte buffers internally in the z_stream
00065  *          data structure.  We use the bbuffers to feed data
00066  *          into the fixed bufferin, and feed it out of bufferout,
00067  *          in the same way that a pair of streams would normally
00068  *          be used if the data were being read from one file
00069  *          and written to another.  This is done iteratively,
00070  *          compressing L_BUF_SIZE bytes of input data at a time.
00071  */
00072 l_uint8 *
00073 zlibCompress(l_uint8  *datain,
00074              size_t    nin,
00075              size_t   *pnout)
00076 {
00077 l_uint8  *dataout;
00078 l_int32   status;
00079 size_t    nbytes;
00080 l_uint8  *bufferin, *bufferout;
00081 BBUFFER  *bbin, *bbout;
00082 z_stream  z;
00083 
00084     PROCNAME("zlibCompress");
00085 
00086     if (!datain)
00087         return (l_uint8 *)ERROR_PTR("datain not defined", procName, NULL);
00088 
00089         /* Set up fixed size buffers used in z_stream */
00090     if ((bufferin = (l_uint8 *)CALLOC(L_BUF_SIZE, sizeof(l_uint8))) == NULL)
00091         return (l_uint8 *)ERROR_PTR("bufferin not made", procName, NULL);
00092     if ((bufferout = (l_uint8 *)CALLOC(L_BUF_SIZE, sizeof(l_uint8))) == NULL)
00093         return (l_uint8 *)ERROR_PTR("bufferout not made", procName, NULL);
00094 
00095         /* Set up bbuffers and load bbin with the data */
00096     if ((bbin = bbufferCreate(datain, nin)) == NULL)
00097         return (l_uint8 *)ERROR_PTR("bbin not made", procName, NULL);
00098     if ((bbout = bbufferCreate(NULL, 0)) == NULL)
00099         return (l_uint8 *)ERROR_PTR("bbout not made", procName, NULL);
00100 
00101     z.zalloc = (alloc_func)0;
00102     z.zfree = (free_func)0;
00103     z.opaque = (voidpf)0;
00104 
00105     z.next_in = bufferin;
00106     z.avail_in = 0;
00107     z.next_out = bufferout;
00108     z.avail_out = L_BUF_SIZE;
00109 
00110     deflateInit(&z, ZLIB_COMPRESSION_LEVEL);
00111 
00112     for ( ; ; ) {
00113         if (z.avail_in == 0) {
00114             z.next_in = bufferin;
00115             bbufferWrite(bbin, bufferin, L_BUF_SIZE, &nbytes);
00116 /*            fprintf(stderr, " wrote %d bytes to bufferin\n", nbytes); */
00117             z.avail_in = nbytes;
00118         }
00119         if (z.avail_in == 0)
00120             break;
00121         status = deflate(&z, Z_SYNC_FLUSH);
00122 /*        fprintf(stderr, " status is %d, bytesleft = %d, totalout = %d\n",
00123                   status, z.avail_out, z.total_out); */
00124         nbytes = L_BUF_SIZE - z.avail_out;
00125         if (nbytes) {
00126             bbufferRead(bbout, bufferout, nbytes);
00127 /*            fprintf(stderr, " read %d bytes from bufferout\n", nbytes); */
00128         }
00129         z.next_out = bufferout;
00130         z.avail_out = L_BUF_SIZE;
00131     }
00132 
00133     deflateEnd(&z);
00134 
00135     bbufferDestroy(&bbin);
00136     dataout = bbufferDestroyAndSaveData(&bbout, pnout);
00137 
00138     FREE(bufferin);
00139     FREE(bufferout);
00140     return dataout;
00141 }
00142         
00143 
00144 /*!
00145  *  zlibUncompress()
00146  *
00147  *      Input:  datain (byte buffer with compressed input data)
00148  *              nin    (number of bytes of input data)
00149  *              &nout  (<return> number of bytes of output data)
00150  *      Return: dataout (uncompressed data), or null on error
00151  *
00152  *  Notes:
00153  *      (1) See zlibCompress().
00154  */
00155 l_uint8 *
00156 zlibUncompress(l_uint8  *datain,
00157                size_t    nin,
00158                size_t   *pnout)
00159 {
00160 l_uint8  *dataout;
00161 l_uint8  *bufferin, *bufferout;
00162 l_int32   status;
00163 size_t    nbytes;
00164 BBUFFER  *bbin, *bbout;
00165 z_stream  z;
00166 
00167     PROCNAME("zlibUncompress");
00168 
00169     if (!datain)
00170         return (l_uint8 *)ERROR_PTR("datain not defined", procName, NULL);
00171     
00172     if ((bufferin = (l_uint8 *)CALLOC(L_BUF_SIZE, sizeof(l_uint8))) == NULL)
00173         return (l_uint8 *)ERROR_PTR("bufferin not made", procName, NULL);
00174     if ((bufferout = (l_uint8 *)CALLOC(L_BUF_SIZE, sizeof(l_uint8))) == NULL)
00175         return (l_uint8 *)ERROR_PTR("bufferout not made", procName, NULL);
00176 
00177     if ((bbin = bbufferCreate(datain, nin)) == NULL)
00178         return (l_uint8 *)ERROR_PTR("bbin not made", procName, NULL);
00179     if ((bbout = bbufferCreate(NULL, 0)) == NULL)
00180         return (l_uint8 *)ERROR_PTR("bbout not made", procName, NULL);
00181 
00182     z.zalloc = (alloc_func)0;
00183     z.zfree = (free_func)0;
00184 
00185     z.next_in = bufferin;
00186     z.avail_in = 0;
00187     z.next_out = bufferout;
00188     z.avail_out = L_BUF_SIZE;
00189 
00190     inflateInit(&z);
00191 
00192     for ( ; ; ) {
00193         if (z.avail_in == 0) {
00194             z.next_in = bufferin;
00195             bbufferWrite(bbin, bufferin, L_BUF_SIZE, &nbytes);
00196 /*            fprintf(stderr, " wrote %d bytes to bufferin\n", nbytes); */
00197             z.avail_in = nbytes;
00198         }
00199         if (z.avail_in == 0)
00200             break;
00201         status = inflate(&z, Z_SYNC_FLUSH);
00202 /*        fprintf(stderr, " status is %d, bytesleft = %d, totalout = %d\n",
00203                   status, z.avail_out, z.total_out); */
00204         nbytes = L_BUF_SIZE - z.avail_out;
00205         if (nbytes) {
00206             bbufferRead(bbout, bufferout, nbytes);
00207 /*            fprintf(stderr, " read %d bytes from bufferout\n", nbytes); */
00208         }
00209         z.next_out = bufferout;
00210         z.avail_out = L_BUF_SIZE;
00211     }
00212 
00213     inflateEnd(&z);
00214 
00215     bbufferDestroy(&bbin);
00216     dataout = bbufferDestroyAndSaveData(&bbout, pnout);
00217 
00218     FREE(bufferin);
00219     FREE(bufferout);
00220     return dataout;
00221 }
00222 
00223 /* --------------------------------------------*/
00224 #endif  /* HAVE_LIBZ */
00225 /* --------------------------------------------*/
00226 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines