comparison mupdf-source/source/fitz/compress.c @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 // Copyright (C) 2004-2021 Artifex Software, Inc.
2 //
3 // This file is part of MuPDF.
4 //
5 // MuPDF is free software: you can redistribute it and/or modify it under the
6 // terms of the GNU Affero General Public License as published by the Free
7 // Software Foundation, either version 3 of the License, or (at your option)
8 // any later version.
9 //
10 // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13 // details.
14 //
15 // You should have received a copy of the GNU Affero General Public License
16 // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
17 //
18 // Alternative licensing terms are available from the licensor.
19 // For commercial licensing, see <https://www.artifex.com/> or contact
20 // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
21 // CA 94129, USA, for further information.
22
23 #include "mupdf/fitz.h"
24
25 #include "z-imp.h"
26
27 #include <limits.h>
28
29 void fz_deflate(fz_context *ctx, unsigned char *dest, size_t *destLen, const unsigned char *source, size_t sourceLen, fz_deflate_level level)
30 {
31 z_stream stream;
32 int err;
33 size_t left;
34
35 left = *destLen;
36 *destLen = 0;
37
38 stream.zalloc = fz_zlib_alloc;
39 stream.zfree = fz_zlib_free;
40 stream.opaque = ctx;
41
42 err = deflateInit(&stream, (int)level);
43 if (err != Z_OK)
44 fz_throw(ctx, FZ_ERROR_LIBRARY, "deflateInit failed: %d", err);
45
46 stream.next_out = dest;
47 stream.avail_out = 0;
48 stream.next_in = (z_const Bytef *)source;
49 stream.avail_in = 0;
50
51 do {
52 if (stream.avail_out == 0) {
53 stream.avail_out = left > UINT_MAX ? UINT_MAX : (uInt)left;
54 left -= stream.avail_out;
55 }
56 if (stream.avail_in == 0) {
57 stream.avail_in = sourceLen > UINT_MAX ? UINT_MAX : (uInt)sourceLen;
58 sourceLen -= stream.avail_in;
59 }
60 err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH);
61 } while (err == Z_OK);
62
63 /* We might have problems if the compressed length > uLong sized. Tough, for now. */
64 *destLen = stream.total_out;
65 deflateEnd(&stream);
66 if (err != Z_STREAM_END)
67 fz_throw(ctx, FZ_ERROR_LIBRARY, "deflate error: %d", err);
68 }
69
70 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)
71 {
72 size_t bound = fz_deflate_bound(ctx, source_length);
73 unsigned char *cdata = Memento_label(fz_malloc(ctx, bound), "deflated_data");
74 *compressed_length = 0;
75
76 fz_try(ctx)
77 fz_deflate(ctx, cdata, &bound, source, source_length, level);
78 fz_catch(ctx)
79 {
80 fz_free(ctx, cdata);
81 fz_rethrow(ctx);
82 }
83
84 *compressed_length = bound;
85 return cdata;
86 }
87
88 unsigned char *fz_new_deflated_data_from_buffer(fz_context *ctx, size_t *compressed_length, fz_buffer *buffer, fz_deflate_level level)
89 {
90 unsigned char *data;
91 size_t size = fz_buffer_storage(ctx, buffer, &data);
92
93 if (size == 0 || data == NULL)
94 {
95 *compressed_length = 0;
96 return NULL;
97 }
98
99 return fz_new_deflated_data(ctx, compressed_length, data, size, level);
100 }
101
102 size_t fz_deflate_bound(fz_context *ctx, size_t size)
103 {
104 /* Copied from zlib to account for size_t vs uLong */
105 return size + (size >> 12) + (size >> 14) + (size >> 25) + 13;
106 }