summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/fitz/compress.c97
-rw-r--r--source/fitz/output-pclm.c6
-rw-r--r--source/fitz/output-png.c24
3 files changed, 103 insertions, 24 deletions
diff --git a/source/fitz/compress.c b/source/fitz/compress.c
new file mode 100644
index 00000000..439c461e
--- /dev/null
+++ b/source/fitz/compress.c
@@ -0,0 +1,97 @@
+#include "mupdf/fitz.h"
+
+#include <zlib.h>
+
+static void *fz_z_alloc(void *opaque, unsigned int count, unsigned int size)
+{
+ fz_context *ctx = (fz_context *)opaque;
+ size_t c = count * size;
+
+ return fz_malloc_no_throw(ctx, c);
+}
+
+static void fz_z_free(void *opaque, void *addr)
+{
+ fz_context *ctx = (fz_context *)opaque;
+
+ fz_free(ctx, addr);
+}
+
+void fz_deflate(fz_context *ctx, unsigned char *dest, size_t *destLen, const unsigned char *source, size_t sourceLen, fz_deflate_level level)
+{
+ z_stream stream;
+ int err;
+ size_t left;
+
+ left = *destLen;
+ *destLen = 0;
+
+ stream.zalloc = fz_z_alloc;
+ stream.zfree = fz_z_free;
+ stream.opaque = ctx;
+
+ err = deflateInit(&stream, (int)level);
+ if (err != Z_OK)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "zlib compression failed: %d", err);
+
+ stream.next_out = dest;
+ stream.avail_out = 0;
+ stream.next_in = (z_const Bytef *)source;
+ stream.avail_in = 0;
+
+ do {
+ if (stream.avail_out == 0) {
+ stream.avail_out = left > UINT_MAX ? UINT_MAX : (uInt)left;
+ left -= stream.avail_out;
+ }
+ if (stream.avail_in == 0) {
+ stream.avail_in = sourceLen > UINT_MAX ? UINT_MAX : (uInt)sourceLen;
+ sourceLen -= stream.avail_in;
+ }
+ err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH);
+ } while (err == Z_OK);
+
+ /* We might have problems if the compressed length > uLong sized. Tough, for now. */
+ *destLen = stream.total_out;
+ deflateEnd(&stream);
+ if (err != Z_STREAM_END)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "Zlib failure: %d", err);
+}
+
+unsigned char *fz_new_deflated_data(fz_context *ctx, size_t *compressed_length, const unsigned char *source, size_t source_length, fz_deflate_level level)
+{
+ size_t bound = fz_deflate_bound(ctx, source_length);
+ unsigned char *cdata = fz_malloc(ctx, bound);
+ *compressed_length = 0;
+
+ fz_try(ctx)
+ fz_deflate(ctx, cdata, &bound, source, source_length, level);
+ fz_catch(ctx)
+ {
+ fz_free(ctx, cdata);
+ fz_rethrow(ctx);
+ }
+
+ *compressed_length = bound;
+ return cdata;
+}
+
+unsigned char *fz_new_deflated_data_from_buffer(fz_context *ctx, size_t *compressed_length, fz_buffer *buffer, fz_deflate_level level)
+{
+ unsigned char *data;
+ size_t size = fz_buffer_storage(ctx, buffer, &data);
+
+ if (size == 0 || data == NULL)
+ {
+ *compressed_length = 0;
+ return NULL;
+ }
+
+ return fz_new_deflated_data(ctx, compressed_length, data, size, level);
+}
+
+size_t fz_deflate_bound(fz_context *ctx, size_t size)
+{
+ /* Copied from zlib to account for size_t vs uLong */
+ return size + (size >> 12) + (size >> 14) + (size >> 25) + 13;
+}
diff --git a/source/fitz/output-pclm.c b/source/fitz/output-pclm.c
index 52f673a1..0d1f728c 100644
--- a/source/fitz/output-pclm.c
+++ b/source/fitz/output-pclm.c
@@ -122,7 +122,7 @@ pclm_write_header(fz_context *ctx, fz_band_writer *writer_, const fz_colorspace
fz_free(ctx, writer->stripbuf);
fz_free(ctx, writer->compbuf);
writer->stripbuf = fz_malloc(ctx, w * sh * n);
- writer->complen = compressBound(w * sh * n);
+ writer->complen = fz_deflate_bound(ctx, w * sh * n);
writer->compbuf = fz_malloc(ctx, writer->complen);
/* Send the file header on the first page */
@@ -193,9 +193,7 @@ flush_strip(fz_context *ctx, pclm_band_writer *writer, int fill)
if (writer->options.compress)
{
uLongf destLen = writer->complen;
- int err = compress(writer->compbuf, &destLen, data, (uLongf)len);
- if (err != Z_OK)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot compress strip: %d", err);
+ fz_deflate(ctx, writer->compbuf, &destLen, data, len, FZ_DEFLATE_DEFAULT);
len = destLen;
data = writer->compbuf;
}
diff --git a/source/fitz/output-png.c b/source/fitz/output-png.c
index 38bfa778..d21bc59b 100644
--- a/source/fitz/output-png.c
+++ b/source/fitz/output-png.c
@@ -86,34 +86,18 @@ static void
png_write_icc(fz_context *ctx, png_band_writer *writer, const fz_colorspace *cs)
{
fz_output *out = writer->super.out;
- int size;
+ size_t size, csize;
fz_buffer *buffer = fz_icc_data_from_icc_colorspace(ctx, cs);
- unsigned char *data;
unsigned char *pos, *cdata, *chunk = NULL;
- uLong bound;
- uLongf csize;
- uLong long_size;
- int t;
- long_size = (uLong)fz_buffer_storage(ctx, buffer, &data);
+ /* Deflate the profile */
+ cdata = fz_new_deflated_data_from_buffer(ctx, &csize, buffer, FZ_DEFLATE_DEFAULT);
- if (!data)
+ if (!cdata)
return;
- /* Deflate the profile */
- bound = compressBound(long_size);
- cdata = fz_malloc(ctx, bound);
- csize = (uLongf)bound;
- t = compress(cdata, &csize, data, long_size);
- if (t != Z_OK)
- {
- fz_free(ctx, cdata);
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot deflate icc buffer");
- }
size = csize + strlen("MuPDF Profile") + 2;
- fz_var(cdata);
-
fz_try(ctx)
{
chunk = fz_calloc(ctx, size, 1);