Subversion Repositories spk

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
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