comparison mupdf-source/thirdparty/zxing-cpp/wrappers/wasm/BarcodeReader.cpp @ 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 /*
2 * Copyright 2016 Nu-book Inc.
3 * Copyright 2023 Axel Waggershauser
4 */
5 // SPDX-License-Identifier: Apache-2.0
6
7 #include "ReadBarcode.h"
8
9 #include <emscripten/bind.h>
10 #include <emscripten/val.h>
11 #include <memory>
12 #include <stdexcept>
13 #include <string>
14
15 #define STB_IMAGE_IMPLEMENTATION
16 #include <stb_image.h>
17
18 using namespace ZXing;
19
20 struct ReadResult
21 {
22 std::string format{};
23 std::string text{};
24 emscripten::val bytes;
25 std::string error{};
26 Position position{};
27 std::string symbologyIdentifier{};
28 };
29
30 std::vector<ReadResult> readBarcodes(ImageView iv, bool tryHarder, const std::string& format, int maxSymbols)
31 {
32 try {
33 ReaderOptions opts;
34 opts.setTryHarder(tryHarder);
35 opts.setTryRotate(tryHarder);
36 opts.setTryInvert(tryHarder);
37 opts.setTryDownscale(tryHarder);
38 opts.setFormats(BarcodeFormatsFromString(format));
39 opts.setMaxNumberOfSymbols(maxSymbols);
40 // opts.setReturnErrors(maxSymbols > 1);
41
42 auto barcodes = ReadBarcodes(iv, opts);
43
44 std::vector<ReadResult> readResults{};
45 readResults.reserve(barcodes.size());
46
47 thread_local const emscripten::val Uint8Array = emscripten::val::global("Uint8Array");
48
49 for (auto&& barcode : barcodes) {
50 const ByteArray& bytes = barcode.bytes();
51 readResults.push_back({
52 ToString(barcode.format()),
53 barcode.text(),
54 Uint8Array.new_(emscripten::typed_memory_view(bytes.size(), bytes.data())),
55 ToString(barcode.error()),
56 barcode.position(),
57 barcode.symbologyIdentifier()
58 });
59 }
60
61 return readResults;
62 } catch (const std::exception& e) {
63 return {{"", "", {}, e.what()}};
64 } catch (...) {
65 return {{"", "", {}, "Unknown error"}};
66 }
67 return {};
68 }
69
70 std::vector<ReadResult> readBarcodesFromImage(int bufferPtr, int bufferLength, bool tryHarder, std::string format, int maxSymbols)
71 {
72 int width, height, channels;
73 std::unique_ptr<stbi_uc, void (*)(void*)> buffer(
74 stbi_load_from_memory(reinterpret_cast<const unsigned char*>(bufferPtr), bufferLength, &width, &height, &channels, 1),
75 stbi_image_free);
76 if (buffer == nullptr)
77 return {{"", "", {}, "Error loading image"}};
78
79 return readBarcodes({buffer.get(), width, height, ImageFormat::Lum}, tryHarder, format, maxSymbols);
80 }
81
82 ReadResult readBarcodeFromImage(int bufferPtr, int bufferLength, bool tryHarder, std::string format)
83 {
84 return FirstOrDefault(readBarcodesFromImage(bufferPtr, bufferLength, tryHarder, format, 1));
85 }
86
87 std::vector<ReadResult> readBarcodesFromPixmap(int bufferPtr, int imgWidth, int imgHeight, bool tryHarder, std::string format, int maxSymbols)
88 {
89 return readBarcodes({reinterpret_cast<uint8_t*>(bufferPtr), imgWidth, imgHeight, ImageFormat::RGBA}, tryHarder, format, maxSymbols);
90 }
91
92 ReadResult readBarcodeFromPixmap(int bufferPtr, int imgWidth, int imgHeight, bool tryHarder, std::string format)
93 {
94 return FirstOrDefault(readBarcodesFromPixmap(bufferPtr, imgWidth, imgHeight, tryHarder, format, 1));
95 }
96
97 EMSCRIPTEN_BINDINGS(BarcodeReader)
98 {
99 using namespace emscripten;
100
101 value_object<ReadResult>("ReadResult")
102 .field("format", &ReadResult::format)
103 .field("text", &ReadResult::text)
104 .field("bytes", &ReadResult::bytes)
105 .field("error", &ReadResult::error)
106 .field("position", &ReadResult::position)
107 .field("symbologyIdentifier", &ReadResult::symbologyIdentifier);
108
109 value_object<ZXing::PointI>("Point").field("x", &ZXing::PointI::x).field("y", &ZXing::PointI::y);
110
111 value_object<ZXing::Position>("Position")
112 .field("topLeft", emscripten::index<0>())
113 .field("topRight", emscripten::index<1>())
114 .field("bottomRight", emscripten::index<2>())
115 .field("bottomLeft", emscripten::index<3>());
116
117 register_vector<ReadResult>("vector<ReadResult>");
118
119 function("readBarcodeFromImage", &readBarcodeFromImage);
120 function("readBarcodeFromPixmap", &readBarcodeFromPixmap);
121
122 function("readBarcodesFromImage", &readBarcodesFromImage);
123 function("readBarcodesFromPixmap", &readBarcodesFromPixmap);
124 };