comparison mupdf-source/source/fitz/brotli.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-2025 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 #if FZ_ENABLE_BROTLI
26
27 #include "brotli/encode.h"
28
29 #include <limits.h>
30
31 static void *
32 my_brotli_alloc(void *opaque, size_t size)
33 {
34 return fz_malloc_no_throw((fz_context *)opaque, size);
35 }
36
37 static void
38 my_brotli_free(void *opaque, void *ptr)
39 {
40 fz_free((fz_context *)opaque, ptr);
41 }
42
43 void fz_compress_brotli(fz_context *ctx, unsigned char *dest, size_t *dest_len, const unsigned char *source, size_t source_len, fz_brotli_level level)
44 {
45 int ok;
46 BrotliEncoderState *enc_state;
47 unsigned char *outp = dest;
48 size_t avail_out = *dest_len;
49
50 enc_state = BrotliEncoderCreateInstance(my_brotli_alloc, my_brotli_free, ctx);
51
52 if (!BrotliEncoderSetParameter(enc_state, BROTLI_PARAM_QUALITY, level))
53 {
54 BrotliEncoderDestroyInstance(enc_state);
55 fz_throw(ctx, FZ_ERROR_LIBRARY, "Brotli compression failed");
56 }
57
58 do {
59 ok = BrotliEncoderCompressStream(enc_state,
60 (source_len > 0 ? BROTLI_OPERATION_PROCESS : BROTLI_OPERATION_FINISH),
61 &source_len,
62 &source,
63 &avail_out,
64 &outp,
65 NULL);
66 } while (ok && !BrotliEncoderIsFinished(enc_state));
67
68 if (!ok)
69 {
70 BrotliEncoderDestroyInstance(enc_state);
71 fz_throw(ctx, FZ_ERROR_LIBRARY, "Brotli compression failed");
72 }
73 *dest_len = outp - dest;
74
75 BrotliEncoderDestroyInstance(enc_state);
76 }
77
78 unsigned char *fz_new_brotli_data(fz_context *ctx, size_t *compressed_length, const unsigned char *source, size_t source_length, fz_brotli_level level)
79 {
80 size_t bound = fz_brotli_bound(ctx, source_length);
81 unsigned char *cdata = Memento_label(fz_malloc(ctx, bound), "brotli_data");
82 *compressed_length = 0;
83
84 fz_try(ctx)
85 fz_compress_brotli(ctx, cdata, &bound, source, source_length, level);
86 fz_catch(ctx)
87 {
88 fz_free(ctx, cdata);
89 fz_rethrow(ctx);
90 }
91
92 *compressed_length = bound;
93 return cdata;
94 }
95
96 unsigned char *fz_new_brotli_data_from_buffer(fz_context *ctx, size_t *compressed_length, fz_buffer *buffer, fz_brotli_level level)
97 {
98 unsigned char *data;
99 size_t size = fz_buffer_storage(ctx, buffer, &data);
100
101 if (size == 0 || data == NULL)
102 {
103 *compressed_length = 0;
104 return NULL;
105 }
106
107 return fz_new_brotli_data(ctx, compressed_length, data, size, level);
108 }
109
110 size_t fz_brotli_bound(fz_context *ctx, size_t size)
111 {
112 return BrotliEncoderMaxCompressedSize(size);
113 }
114
115 #else
116
117 size_t fz_brotli_bound(fz_context *ctx, size_t size)
118 {
119 return size;
120 }
121
122 void fz_compress_brotli(fz_context *ctx, unsigned char *dest, size_t *dest_len, const unsigned char *source, size_t source_len, fz_brotli_level level)
123 {
124 fz_throw(ctx, FZ_ERROR_UNSUPPORTED, "brotli compression not enabled");
125 }
126
127 unsigned char *fz_new_brotli_data_from_buffer(fz_context *ctx, size_t *compressed_length, fz_buffer *buffer, fz_brotli_level level)
128 {
129 fz_throw(ctx, FZ_ERROR_UNSUPPORTED, "brotli compression not enabled");
130 return NULL;
131 }
132
133 unsigned char *fz_new_brotli_data(fz_context *ctx, size_t *compressed_length, const unsigned char *source, size_t source_length, fz_brotli_level level)
134 {
135 fz_throw(ctx, FZ_ERROR_UNSUPPORTED, "brotli compression not enabled");
136 return NULL;
137 }
138
139 #endif