diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/writezip.c')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/writezip.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/writezip.c b/Build/source/texk/web2c/luatexdir/writezip.c new file mode 100644 index 00000000000..b915413ccfe --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/writezip.c @@ -0,0 +1,98 @@ +/* +Copyright (c) 1996-2007 Han The Thanh, <thanh@pdftex.org> + +This file is part of pdfTeX. + +pdfTeX is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +pdfTeX is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with pdfTeX; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +$Id $ +*/ + +#include "ptexlib.h" +#include "zlib.h" +#include <assert.h> + +#define ZIP_BUF_SIZE 32768 + +#define check_err(f, fn) \ + if (f != Z_OK) \ + pdftex_fail("zlib: %s() failed (error code %d)", fn, f) + +static char *zipbuf = NULL; +static z_stream c_stream; /* compression stream */ + +void write_zip(boolean finish) +{ + int err; + static int level_old = 0; + int level = get_pdf_compress_level(); + assert(level > 0); + cur_file_name = NULL; + if (pdf_stream_length == 0) { + if (zipbuf == NULL) { + zipbuf = xtalloc(ZIP_BUF_SIZE, char); + c_stream.zalloc = (alloc_func) 0; + c_stream.zfree = (free_func) 0; + c_stream.opaque = (voidpf) 0; + check_err(deflateInit(&c_stream, level), "deflateInit"); + } else { + if (level != level_old) { /* \pdfcompresslevel change in mid document */ + check_err(deflateEnd(&c_stream), "deflateEnd"); + c_stream.zalloc = (alloc_func) 0; /* these 3 lines no need, just to be safe */ + c_stream.zfree = (free_func) 0; + c_stream.opaque = (voidpf) 0; + check_err(deflateInit(&c_stream, level), "deflateInit"); + } else + check_err(deflateReset(&c_stream), "deflateReset"); + } + level_old = level; + c_stream.next_out = (Bytef *) zipbuf; + c_stream.avail_out = ZIP_BUF_SIZE; + } + assert(zipbuf != NULL); + c_stream.next_in = pdf_buf; + c_stream.avail_in = pdf_ptr; + for (;;) { + if (c_stream.avail_out == 0) { + pdf_gone += xfwrite(zipbuf, 1, ZIP_BUF_SIZE, pdf_file); + pdf_last_byte = zipbuf[ZIP_BUF_SIZE - 1]; /* not needed */ + c_stream.next_out = (Bytef *) zipbuf; + c_stream.avail_out = ZIP_BUF_SIZE; + } + err = deflate(&c_stream, finish ? Z_FINISH : Z_NO_FLUSH); + if (finish && err == Z_STREAM_END) + break; + check_err(err, "deflate"); + if (!finish && c_stream.avail_in == 0) + break; + } + if (finish) { + if (c_stream.avail_out < ZIP_BUF_SIZE) { /* at least one byte has been output */ + pdf_gone += + xfwrite(zipbuf, 1, ZIP_BUF_SIZE - c_stream.avail_out, pdf_file); + pdf_last_byte = zipbuf[ZIP_BUF_SIZE - c_stream.avail_out - 1]; + } + xfflush(pdf_file); + } + pdf_stream_length = c_stream.total_out; +} + +void zip_free(void) +{ + if (zipbuf != NULL) { + check_err(deflateEnd(&c_stream), "deflateEnd"); + free(zipbuf); + } +} |