1 /*
2 Copyright 1996-2014 Han The Thanh, <thanh@pdftex.org>
3
4 This file is part of pdfTeX.
5
6 pdfTeX is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 pdfTeX is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License along
17 with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "ptexlib.h"
21 #include "zlib.h"
22 #include <assert.h>
23
24 #define ZIP_BUF_SIZE 32768
25
26 #define check_err(f, fn) \
27 if (f != Z_OK) \
28 pdftex_fail("zlib: %s() failed (error code %d)", fn, f)
29
30 static char *zipbuf = NULL;
31 static z_stream c_stream; /* compression stream */
32
writezip(boolean finish)33 void writezip(boolean finish)
34 {
35 int err;
36 static int level_old = 0;
37 int level = getpdfcompresslevel();
38 assert(level > 0);
39 cur_file_name = NULL;
40 if (pdfstreamlength == 0) {
41 if (zipbuf == NULL) {
42 zipbuf = xtalloc(ZIP_BUF_SIZE, char);
43 c_stream.zalloc = (alloc_func) 0;
44 c_stream.zfree = (free_func) 0;
45 c_stream.opaque = (voidpf) 0;
46 check_err(deflateInit(&c_stream, level), "deflateInit");
47 } else {
48 if (level != level_old) { /* \pdfcompresslevel change in mid document */
49 check_err(deflateEnd(&c_stream), "deflateEnd");
50 c_stream.zalloc = (alloc_func) 0; /* these 3 lines no need, just to be safe */
51 c_stream.zfree = (free_func) 0;
52 c_stream.opaque = (voidpf) 0;
53 check_err(deflateInit(&c_stream, level), "deflateInit");
54 } else
55 check_err(deflateReset(&c_stream), "deflateReset");
56 }
57 level_old = level;
58 c_stream.next_out = (Bytef *) zipbuf;
59 c_stream.avail_out = ZIP_BUF_SIZE;
60 }
61 assert(zipbuf != NULL);
62 c_stream.next_in = pdfbuf;
63 c_stream.avail_in = pdfptr;
64 for (;;) {
65 if (c_stream.avail_out == 0) {
66 pdfgone += xfwrite(zipbuf, 1, ZIP_BUF_SIZE, pdffile);
67 pdflastbyte = zipbuf[ZIP_BUF_SIZE - 1]; /* not needed */
68 c_stream.next_out = (Bytef *) zipbuf;
69 c_stream.avail_out = ZIP_BUF_SIZE;
70 }
71 err = deflate(&c_stream, finish ? Z_FINISH : Z_NO_FLUSH);
72 if (finish && err == Z_STREAM_END)
73 break;
74 check_err(err, "deflate");
75 if (!finish && c_stream.avail_in == 0)
76 break;
77 }
78 if (finish) {
79 if (c_stream.avail_out < ZIP_BUF_SIZE) { /* at least one byte has been output */
80 pdfgone +=
81 xfwrite(zipbuf, 1, ZIP_BUF_SIZE - c_stream.avail_out, pdffile);
82 pdflastbyte = zipbuf[ZIP_BUF_SIZE - c_stream.avail_out - 1];
83 }
84 xfflush(pdffile);
85 }
86 pdfstreamlength = c_stream.total_out;
87 }
88
zip_free(void)89 void zip_free(void)
90 {
91 if (zipbuf != NULL) {
92 check_err(deflateEnd(&c_stream), "deflateEnd");
93 free(zipbuf);
94 }
95 }
96