comparison mupdf-source/source/tools/mubar.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) 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 /*
24 * mudraw -- command line tool for drawing and converting documents
25 */
26
27 #include "mupdf/fitz.h"
28
29 #if FZ_ENABLE_BARCODE
30
31 #if FZ_ENABLE_PDF
32 #include "mupdf/pdf.h" /* for pdf output */
33 #endif
34
35 static int mubar_usage(void)
36 {
37 int i, n, c;
38 const char *s;
39 fprintf(stderr,
40 "usage to decode: mutool barcode -d [options] input [pages]\n"
41 "\t-p -\tpassword for encrypted PDF files\n"
42 "\t-o -\toutput file (default: stdout)\n"
43 "\t-r -\trotation\n"
44 );
45 fprintf(stderr,
46 "usage to create: mutool barcode -c [options] text\n"
47 "\t-o -\toutput file (default: out.png)\n"
48 "\t-q\tadd quiet zones\n"
49 "\t-t\tadd human readable text (when possible)\n"
50 "\t-e -\terror correction level (0-8)\n"
51 "\t-s -\tsize of barcode image\n"
52 "\t-F -\tbarcode format (default: qrcode)\n"
53 );
54 for (c = 0, i = FZ_BARCODE_NONE + 1; i < FZ_BARCODE__LIMIT; i++)
55 {
56 s = fz_string_from_barcode_type(i);
57 n = (int)strlen(s);
58 if (c + 2 + n > 78)
59 {
60 fprintf(stderr, ",\n\t\t%s", s);
61 c = 8 + n;
62 }
63 else
64 {
65 if (c == 0)
66 {
67 fprintf(stderr, "\t\t%s", s);
68 c += 8 + n;
69 }
70 else
71 {
72 fprintf(stderr, ", %s", s);
73 c += n + 2;
74 }
75 }
76 }
77 fprintf(stderr, "\n");
78 return EXIT_FAILURE;
79 }
80
81 int mubar_create(int argc, char **argv)
82 {
83 fz_context *ctx;
84 fz_pixmap *pixmap = NULL;
85 int retval = EXIT_SUCCESS;
86
87 const char *output = "out.png";
88 const char *format = "png";
89
90 fz_barcode_type bartype = FZ_BARCODE_QRCODE;
91 int quiet = 0;
92 int hrt = 0;
93 int ec_level = 0;
94 int size = 256;
95 int c;
96
97 while ((c = fz_getopt(argc, argv, "F:ce:o:qs:td:")) != -1)
98 {
99 switch (c)
100 {
101 case 'F':
102 bartype = fz_barcode_type_from_string(fz_optarg);
103 if (bartype == FZ_BARCODE_NONE)
104 return mubar_usage();
105 break;
106 case 'c': break;
107 case 'e': ec_level = fz_atoi(fz_optarg); break;
108 case 'o': output = fz_optpath(fz_optarg); break;
109 case 'q': quiet = 1; break;
110 case 's': size = fz_atoi(fz_optarg); break;
111 case 't': hrt = 1; break;
112 default: return mubar_usage();
113 }
114 }
115
116 if (fz_optind == argc)
117 return mubar_usage();
118
119 ctx = fz_new_context(NULL, NULL, FZ_STORE_DEFAULT);
120 if (!ctx)
121 {
122 fprintf(stderr, "cannot initialise context\n");
123 return EXIT_FAILURE;
124 }
125
126 format = strrchr(output, '.');
127 if (format == NULL)
128 return mubar_usage();
129
130 fz_var(pixmap);
131
132 fz_try(ctx)
133 {
134 pixmap = fz_new_barcode_pixmap(ctx, bartype, argv[fz_optind], size, ec_level, quiet, hrt);
135
136 if (!fz_strcasecmp(format, ".png"))
137 {
138 fz_save_pixmap_as_png(ctx, pixmap, output);
139 }
140 else if (!fz_strcasecmp(format, ".pdf"))
141 {
142 fz_pclm_options opts = { 0 };
143 opts.compress = 1;
144 opts.strip_height = pixmap->h;
145 fz_save_pixmap_as_pclm(ctx, pixmap, output, 0, &opts);
146 }
147 else
148 {
149 fz_throw(ctx, FZ_ERROR_ARGUMENT, "invalid output format (must be PNG or PDF)\n");
150 }
151 }
152 fz_always(ctx)
153 {
154 fz_drop_pixmap(ctx, pixmap);
155 }
156 fz_catch(ctx)
157 {
158 fz_report_error(ctx);
159 retval = EXIT_FAILURE;
160 }
161
162 fz_drop_context(ctx);
163
164 return retval;
165 }
166
167 static void mubar_decode_page(fz_context *ctx, fz_output *out, fz_document *doc, int page_no, int rotation)
168 {
169 fz_barcode_type type;
170 fz_page *page = fz_load_page(ctx, doc, page_no-1);
171 char *text;
172 fz_try(ctx)
173 {
174 text = fz_decode_barcode_from_page(ctx, &type, page, fz_infinite_rect, rotation);
175 if (text && type != FZ_BARCODE_NONE)
176 fz_write_printf(ctx, out, "%s: %s\n", fz_string_from_barcode_type(type), text);
177 else
178 fz_write_string(ctx, out, "none\n");
179 }
180 fz_always(ctx)
181 {
182 fz_free(ctx, text);
183 fz_drop_page(ctx, page);
184 }
185 fz_catch(ctx)
186 fz_rethrow(ctx);
187 }
188
189 int mubar_decode(int argc, char **argv)
190 {
191 fz_context *ctx;
192 fz_document *doc = NULL;
193 fz_output *out = NULL;
194 int i, c, start, end, p, count;
195 const char *range = NULL;
196 int retval = EXIT_SUCCESS;
197
198 const char *output = NULL;
199 const char *password = NULL;
200 int rotation = 0;
201
202 while ((c = fz_getopt(argc, argv, "do:r:p:")) != -1)
203 {
204 switch (c)
205 {
206 case 'd': break;
207 case 'o': output = fz_optarg; break;
208 case 'r': rotation = fz_atof(fz_optarg); break;
209 case 'p': password = fz_optarg; break;
210 default: return mubar_usage();
211 }
212 }
213
214 if (fz_optind == argc)
215 return mubar_usage();
216
217 ctx = fz_new_context(NULL, NULL, FZ_STORE_DEFAULT);
218 if (!ctx)
219 {
220 fprintf(stderr, "cannot initialise context\n");
221 return EXIT_FAILURE;
222 }
223
224 fz_try(ctx)
225 fz_register_document_handlers(ctx);
226 fz_catch(ctx)
227 {
228 fz_report_error(ctx);
229 fprintf(stderr, "cannot register document handlers\n");
230 fz_drop_context(ctx);
231 return EXIT_FAILURE;
232 }
233
234 fz_var(doc);
235 fz_var(out);
236 fz_try(ctx)
237 {
238 if (output)
239 out = fz_new_output_with_path(ctx, output, 0);
240 else
241 out = fz_stdout(ctx);
242
243 for (i = fz_optind; i < argc; ++i)
244 {
245 doc = fz_open_document(ctx, argv[i]);
246 if (fz_needs_password(ctx, doc))
247 if (!fz_authenticate_password(ctx, doc, password))
248 fz_throw(ctx, FZ_ERROR_ARGUMENT, "cannot authenticate password: %s", argv[i]);
249 count = fz_count_pages(ctx, doc);
250
251 if (i+1 < argc && fz_is_page_range(ctx, argv[i+1]))
252 range = argv[++i];
253 else
254 range = "1-N";
255
256 while ((range = fz_parse_page_range(ctx, range, &start, &end, count)))
257 {
258 if (start < end)
259 for (p = start; p <= end; ++p)
260 mubar_decode_page(ctx, out, doc, p, rotation);
261 else
262 for (p = start; p >= end; --p)
263 mubar_decode_page(ctx, out, doc, p, rotation);
264 }
265
266 fz_drop_document(ctx, doc);
267 doc = NULL;
268 }
269
270 if (output)
271 fz_close_output(ctx, out);
272 }
273 fz_always(ctx)
274 {
275 if (output)
276 fz_drop_output(ctx, out);
277 fz_drop_document(ctx, doc);
278 }
279 fz_catch(ctx)
280 {
281 fz_report_error(ctx);
282 retval = EXIT_FAILURE;
283 }
284
285 fz_drop_context(ctx);
286
287 return retval;
288 }
289
290 int mubar_main(int argc, char **argv)
291 {
292 if (argc > 2 && !strcmp(argv[1], "-c"))
293 return mubar_create(argc, argv);
294 if (argc > 2 && !strcmp(argv[1], "-d"))
295 return mubar_decode(argc, argv);
296 return mubar_usage();
297 }
298
299 #else
300
301 #include <stdio.h>
302
303 int mubar_main(int argc, char **argv)
304 {
305 fprintf(stderr, "barcode support disabled\n");
306 return 1;
307 }
308
309 #endif