| 1 | cycrow | 1 | /* compress.c -- compress a memory buffer
 | 
        
           |  |  | 2 |  * Copyright (C) 1995-2003 Jean-loup Gailly.
 | 
        
           |  |  | 3 |  * For conditions of distribution and use, see copyright notice in zlib.h
 | 
        
           |  |  | 4 |  */
 | 
        
           |  |  | 5 |   | 
        
           |  |  | 6 | /* @(#) $Id$ */
 | 
        
           |  |  | 7 |   | 
        
           |  |  | 8 | #define ZLIB_INTERNAL
 | 
        
           |  |  | 9 | #include "zlib.h"
 | 
        
           |  |  | 10 | #include <stdio.h>
 | 
        
           |  |  | 11 | #include <string.h>
 | 
        
           |  |  | 12 | #include <stdlib.h>
 | 
        
           |  |  | 13 |   | 
        
           |  |  | 14 | /* ===========================================================================
 | 
        
           |  |  | 15 |      Compresses the source buffer into the destination buffer. The level
 | 
        
           |  |  | 16 |    parameter has the same meaning as in deflateInit.  sourceLen is the byte
 | 
        
           |  |  | 17 |    length of the source buffer. Upon entry, destLen is the total size of the
 | 
        
           |  |  | 18 |    destination buffer, which must be at least 0.1% larger than sourceLen plus
 | 
        
           |  |  | 19 |    12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
 | 
        
           |  |  | 20 |   | 
        
           |  |  | 21 |      compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
 | 
        
           |  |  | 22 |    memory, Z_BUF_ERROR if there was not enough room in the output buffer,
 | 
        
           |  |  | 23 |    Z_STREAM_ERROR if the level parameter is invalid.
 | 
        
           |  |  | 24 | */
 | 
        
           |  |  | 25 | int ZEXPORT compress2 (dest, destLen, source, sourceLen, doneSize, level)
 | 
        
           |  |  | 26 |     Bytef *dest;
 | 
        
           |  |  | 27 |     uLongf *destLen;
 | 
        
           |  |  | 28 |     const Bytef *source;
 | 
        
           |  |  | 29 |     uLong sourceLen;
 | 
        
           |  |  | 30 | 	unsigned long *doneSize;
 | 
        
           |  |  | 31 |     int level;
 | 
        
           |  |  | 32 | {
 | 
        
           |  |  | 33 |     z_stream strm;
 | 
        
           |  |  | 34 |     int err, flush, ret, destRemain;
 | 
        
           |  |  | 35 |     unsigned have;
 | 
        
           |  |  | 36 |     unsigned char in[CHUNK];
 | 
        
           |  |  | 37 |     unsigned char out[CHUNK];
 | 
        
           |  |  | 38 | 	unsigned int doneAmount;
 | 
        
           |  |  | 39 | 	unsigned int pos, remaining;
 | 
        
           |  |  | 40 | 	Bytef *destPos;
 | 
        
           |  |  | 41 |   | 
        
           |  |  | 42 | 	destRemain = *destLen;
 | 
        
           |  |  | 43 |     strm.zalloc = Z_NULL;
 | 
        
           |  |  | 44 |     strm.zfree = Z_NULL;
 | 
        
           |  |  | 45 |     strm.opaque = Z_NULL;
 | 
        
           |  |  | 46 |     err = deflateInit(&strm, level);
 | 
        
           |  |  | 47 |     if (err != Z_OK) return err;
 | 
        
           |  |  | 48 |   | 
        
           |  |  | 49 | 	pos = 0;
 | 
        
           |  |  | 50 | 	destPos = dest;
 | 
        
           |  |  | 51 |     do {
 | 
        
           |  |  | 52 | 		flush = Z_NO_FLUSH;
 | 
        
           |  |  | 53 | 		remaining = sourceLen - pos;
 | 
        
           |  |  | 54 |         strm.avail_in = CHUNK;
 | 
        
           |  |  | 55 | 		if ( strm.avail_in >= remaining )
 | 
        
           |  |  | 56 | 		{
 | 
        
           |  |  | 57 | 			strm.avail_in = remaining;
 | 
        
           |  |  | 58 | 			flush = Z_FINISH;
 | 
        
           |  |  | 59 | 		}
 | 
        
           |  |  | 60 |   | 
        
           |  |  | 61 | 		memcpy(in, source + pos, strm.avail_in);
 | 
        
           |  |  | 62 |         strm.next_in = in;
 | 
        
           |  |  | 63 | 		doneAmount = (unsigned int)strm.avail_in;
 | 
        
           |  |  | 64 | 		pos += doneAmount;
 | 
        
           |  |  | 65 |   | 
        
           |  |  | 66 |         /* run deflate() on input until output buffer not full, finish
 | 
        
           |  |  | 67 |            compression if all of source has been read in */
 | 
        
           |  |  | 68 |         do {
 | 
        
           |  |  | 69 |             strm.avail_out = CHUNK;
 | 
        
           |  |  | 70 |             strm.next_out = out;
 | 
        
           |  |  | 71 |             ret = deflate(&strm, flush);    /* no bad return value */
 | 
        
           |  |  | 72 |             have = CHUNK - strm.avail_out;
 | 
        
           |  |  | 73 | 			destRemain -= have;
 | 
        
           |  |  | 74 | 			if ( destRemain < 0 )
 | 
        
           |  |  | 75 | 				return Z_NOTENOUGH_BUF;
 | 
        
           |  |  | 76 | 			else
 | 
        
           |  |  | 77 | 				memcpy(destPos, out, have);
 | 
        
           |  |  | 78 |   | 
        
           |  |  | 79 | 			destPos += have;
 | 
        
           |  |  | 80 |         } while (strm.avail_out == 0);
 | 
        
           |  |  | 81 |   | 
        
           |  |  | 82 | 		if ( doneSize )
 | 
        
           |  |  | 83 | 			(*doneSize) += doneAmount;
 | 
        
           |  |  | 84 |   | 
        
           |  |  | 85 |         /* done when last data in file processed */
 | 
        
           |  |  | 86 |     } while (flush != Z_FINISH);
 | 
        
           |  |  | 87 |   | 
        
           |  |  | 88 |     *destLen = strm.total_out;
 | 
        
           |  |  | 89 |   | 
        
           |  |  | 90 |     err = deflateEnd(&strm);
 | 
        
           |  |  | 91 |     return err;
 | 
        
           |  |  | 92 | }
 | 
        
           |  |  | 93 |   | 
        
           |  |  | 94 | /* Compress from file source to file dest until EOF on source.
 | 
        
           |  |  | 95 |    def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
 | 
        
           |  |  | 96 |    allocated for processing, Z_STREAM_ERROR if an invalid compression
 | 
        
           |  |  | 97 |    level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
 | 
        
           |  |  | 98 |    version of the library linked do not match, or Z_ERRNO if there is
 | 
        
           |  |  | 99 |    an error reading or writing the files. */
 | 
        
           |  |  | 100 | int zlib_deflevel(FILE *source, FILE *dest, unsigned long *progress, int level)
 | 
        
           |  |  | 101 | {
 | 
        
           |  |  | 102 |     int ret, flush;
 | 
        
           |  |  | 103 |     unsigned have;
 | 
        
           |  |  | 104 |     z_stream strm;
 | 
        
           |  |  | 105 |     unsigned char in[CHUNK];
 | 
        
           |  |  | 106 |     unsigned char out[CHUNK];
 | 
        
           |  |  | 107 | 	unsigned int doneAmount;
 | 
        
           |  |  | 108 |   | 
        
           |  |  | 109 |     /* allocate deflate state */
 | 
        
           |  |  | 110 |     strm.zalloc = Z_NULL;
 | 
        
           |  |  | 111 |     strm.zfree = Z_NULL;
 | 
        
           |  |  | 112 |     strm.opaque = Z_NULL;
 | 
        
           |  |  | 113 |     ret = deflateInit(&strm, level);
 | 
        
           |  |  | 114 |     if (ret != Z_OK)
 | 
        
           |  |  | 115 |         return ret;
 | 
        
           |  |  | 116 |   | 
        
           |  |  | 117 |     /* compress until end of file */
 | 
        
           |  |  | 118 |     do {
 | 
        
           |  |  | 119 |         strm.avail_in = (uInt)fread(in, 1, CHUNK, source);
 | 
        
           |  |  | 120 |         if (ferror(source)) {
 | 
        
           |  |  | 121 |             (void)deflateEnd(&strm);
 | 
        
           |  |  | 122 |             return Z_ERRNO;
 | 
        
           |  |  | 123 |         }
 | 
        
           |  |  | 124 |         flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
 | 
        
           |  |  | 125 |         strm.next_in = in;
 | 
        
           |  |  | 126 |   | 
        
           |  |  | 127 | 		doneAmount = (unsigned int)strm.avail_in;
 | 
        
           |  |  | 128 |         /* run deflate() on input until output buffer not full, finish
 | 
        
           |  |  | 129 |            compression if all of source has been read in */
 | 
        
           |  |  | 130 |         do {
 | 
        
           |  |  | 131 |             strm.avail_out = CHUNK;
 | 
        
           |  |  | 132 |             strm.next_out = out;
 | 
        
           |  |  | 133 |             ret = deflate(&strm, flush);    /* no bad return value */
 | 
        
           |  |  | 134 |             //assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
 | 
        
           |  |  | 135 |             have = CHUNK - strm.avail_out;
 | 
        
           |  |  | 136 |             if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
 | 
        
           |  |  | 137 |                 (void)deflateEnd(&strm);
 | 
        
           |  |  | 138 |                 return Z_ERRNO;
 | 
        
           |  |  | 139 |             }
 | 
        
           |  |  | 140 |         } while (strm.avail_out == 0);
 | 
        
           |  |  | 141 | //        assert(strm.avail_in == 0);     /* all input will be used */
 | 
        
           |  |  | 142 |   | 
        
           |  |  | 143 | 		if ( progress )
 | 
        
           |  |  | 144 | 			(*progress) += doneAmount;
 | 
        
           |  |  | 145 |   | 
        
           |  |  | 146 |         /* done when last data in file processed */
 | 
        
           |  |  | 147 |     } while (flush != Z_FINISH);
 | 
        
           |  |  | 148 | //    assert(ret == Z_STREAM_END);        /* stream will be complete */
 | 
        
           |  |  | 149 |   | 
        
           |  |  | 150 |     /* clean up and return */
 | 
        
           |  |  | 151 |     (void)deflateEnd(&strm);
 | 
        
           |  |  | 152 |     return Z_OK;
 | 
        
           |  |  | 153 | }
 | 
        
           |  |  | 154 | int zlib_def(FILE *source, FILE *dest, unsigned long *progress)
 | 
        
           |  |  | 155 | {
 | 
        
           |  |  | 156 | 	return zlib_deflevel(source, dest, progress, Z_DEFAULT_COMPRESSION);
 | 
        
           |  |  | 157 | }
 | 
        
           |  |  | 158 |   | 
        
           |  |  | 159 |   | 
        
           |  |  | 160 | /* ===========================================================================
 | 
        
           |  |  | 161 |  */
 | 
        
           |  |  | 162 | int ZEXPORT compress (dest, destLen, source, sourceLen, doneSize)
 | 
        
           |  |  | 163 |     Bytef *dest;
 | 
        
           |  |  | 164 |     uLongf *destLen;
 | 
        
           |  |  | 165 |     const Bytef *source;
 | 
        
           |  |  | 166 |     uLong sourceLen;
 | 
        
           |  |  | 167 | 	unsigned long *doneSize;
 | 
        
           |  |  | 168 | {
 | 
        
           |  |  | 169 |     return compress2(dest, destLen, source, sourceLen, doneSize, Z_DEFAULT_COMPRESSION);
 | 
        
           |  |  | 170 | }
 | 
        
           |  |  | 171 |   | 
        
           |  |  | 172 | /* ===========================================================================
 | 
        
           |  |  | 173 |      If the default memLevel or windowBits for deflateInit() is changed, then
 | 
        
           |  |  | 174 |    this function needs to be updated.
 | 
        
           |  |  | 175 |  */
 | 
        
           |  |  | 176 | uLong ZEXPORT compressBound (sourceLen)
 | 
        
           |  |  | 177 |     uLong sourceLen;
 | 
        
           |  |  | 178 | {
 | 
        
           |  |  | 179 |     return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
 | 
        
           |  |  | 180 | }
 | 
        
           |  |  | 181 |   | 
        
           |  |  | 182 |   |