Mercurial > hgrepos > Python2 > PyMuPDF
diff mupdf-source/thirdparty/zxing-cpp/example/ZXingWriter.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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mupdf-source/thirdparty/zxing-cpp/example/ZXingWriter.cpp Mon Sep 15 11:43:07 2025 +0200 @@ -0,0 +1,230 @@ +/* +* Copyright 2016 Nu-book Inc. +*/ +// SPDX-License-Identifier: Apache-2.0 + +#ifdef ZXING_EXPERIMENTAL_API +#include "WriteBarcode.h" +#else +#include "BitMatrix.h" +#include "BitMatrixIO.h" +#include "CharacterSet.h" +#include "MultiFormatWriter.h" +#endif +#include "Version.h" + +#include <algorithm> +#include <cctype> +#include <cstring> +#include <fstream> +#include <iostream> +#include <string> + +#define STB_IMAGE_WRITE_IMPLEMENTATION +#include <stb_image_write.h> + +using namespace ZXing; + +static void PrintUsage(const char* exePath) +{ + std::cout << "Usage: " << exePath + << " [-size <width/height>] [-eclevel <level>] [-noqz] [-hrt] <format> <text> <output>\n" + << " -size Size of generated image\n" +// << " -margin Margin around barcode\n" +// << " -encoding Encoding used to encode input text\n" + << " -eclevel Error correction level, [0-8]\n" + << " -binary Interpret <text> as a file name containing binary data\n" + << " -noqz Print barcode witout quiet zone\n" + << " -hrt Print human readable text below the barcode (if supported)\n" + << " -help Print usage information\n" + << " -version Print version information\n" + << "\n" + << "Supported formats are:\n"; +#ifdef ZXING_EXPERIMENTAL_API + for (auto f : BarcodeFormats::all()) +#else + for (auto f : BarcodeFormatsFromString("Aztec Codabar Code39 Code93 Code128 DataMatrix EAN8 EAN13 ITF PDF417 QRCode UPCA UPCE")) +#endif + std::cout << " " << ToString(f) << "\n"; + + std::cout << "Format can be lowercase letters, with or without '-'.\n" + << "Output format is determined by file name, supported are png, jpg and svg.\n"; +} + +static bool ParseSize(std::string str, int* width, int* height) +{ + std::transform(str.begin(), str.end(), str.begin(), [](char c) { return (char)std::tolower(c); }); + auto xPos = str.find('x'); + if (xPos != std::string::npos) { + *width = std::stoi(str.substr(0, xPos)); + *height = std::stoi(str.substr(xPos + 1)); + return true; + } + return false; +} + +struct CLI +{ + BarcodeFormat format; + int sizeHint = 0; + std::string input; + std::string outPath; + std::string ecLevel; + bool inputIsFile = false; + bool withHRT = false; + bool withQZ = true; + bool verbose = false; +// CharacterSet encoding = CharacterSet::Unknown; +}; + +static bool ParseOptions(int argc, char* argv[], CLI& cli) +{ + int nonOptArgCount = 0; + for (int i = 1; i < argc; ++i) { + auto is = [&](const char* str) { return strncmp(argv[i], str, strlen(argv[i])) == 0; }; + if (is("-size")) { + if (++i == argc) + return false; + cli.sizeHint = std::stoi(argv[i]); + } else if (is("-eclevel")) { + if (++i == argc) + return false; + cli.ecLevel = argv[i]; + // } else if (is("-margin")) { + // if (++i == argc) + // return false; + // cli.margin = std::stoi(argv[i]); + // } else if (is("-encoding")) { + // if (++i == argc) + // return false; + // cli.encoding = CharacterSetFromString(argv[i]); + } else if (is("-binary")) { + cli.inputIsFile = true; + } else if (is("-hrt")) { + cli.withHRT = true; + } else if (is("-noqz")) { + cli.withQZ = false; + } else if (is("-verbose")) { + cli.verbose = true; + } else if (is("-help") || is("--help")) { + PrintUsage(argv[0]); + exit(0); + } else if (is("-version") || is("--version")) { + std::cout << "ZXingWriter " << ZXING_VERSION_STR << "\n"; + exit(0); + } else if (nonOptArgCount == 0) { + cli.format = BarcodeFormatFromString(argv[i]); + if (cli.format == BarcodeFormat::None) { + std::cerr << "Unrecognized format: " << argv[i] << std::endl; + return false; + } + ++nonOptArgCount; + } else if (nonOptArgCount == 1) { + cli.input = argv[i]; + ++nonOptArgCount; + } else if (nonOptArgCount == 2) { + cli.outPath = argv[i]; + ++nonOptArgCount; + } else { + return false; + } + } + + return nonOptArgCount == 3; +} + +static std::string GetExtension(const std::string& path) +{ + auto fileNameStart = path.find_last_of("/\\"); + auto fileName = fileNameStart == std::string::npos ? path : path.substr(fileNameStart + 1); + auto extStart = fileName.find_last_of('.'); + auto ext = extStart == std::string::npos ? "" : fileName.substr(extStart + 1); + std::transform(ext.begin(), ext.end(), ext.begin(), [](char c) { return std::tolower(c); }); + return ext; +} + +template <typename T = char> +std::vector<T> ReadFile(const std::string& fn) +{ + std::basic_ifstream<T> ifs(fn, std::ios::binary); + if (!ifs.good()) + throw std::runtime_error("failed to open/read file " + fn); + return ifs ? std::vector(std::istreambuf_iterator<T>(ifs), std::istreambuf_iterator<T>()) : std::vector<T>(); +}; + +int main(int argc, char* argv[]) +{ + CLI cli; + + if (!ParseOptions(argc, argv, cli)) { + PrintUsage(argv[0]); + return -1; + } + + try { +#ifdef ZXING_EXPERIMENTAL_API + auto cOpts = CreatorOptions(cli.format).ecLevel(cli.ecLevel); + auto barcode = cli.inputIsFile ? CreateBarcodeFromBytes(ReadFile(cli.input), cOpts) : CreateBarcodeFromText(cli.input, cOpts); + + auto wOpts = WriterOptions().sizeHint(cli.sizeHint).withQuietZones(cli.withQZ).withHRT(cli.withHRT).rotate(0); + auto bitmap = WriteBarcodeToImage(barcode, wOpts); + + if (cli.verbose) { + std::cout << "Text: \"" << barcode.text() << "\"\n" + << "Bytes: " << ToHex(barcode.bytes()) << "\n" + << "Format: " << ToString(barcode.format()) << "\n" + << "Identifier: " << barcode.symbologyIdentifier() << "\n" + << "Content: " << ToString(barcode.contentType()) << "\n" + << "HasECI: " << barcode.hasECI() << "\n" + << "Position: " << ToString(barcode.position()) << "\n" + << "Rotation: " << barcode.orientation() << " deg\n" + << "IsMirrored: " << barcode.isMirrored() << "\n" + << "IsInverted: " << barcode.isInverted() << "\n" + << "ecLevel: " << barcode.ecLevel() << "\n"; + std::cout << WriteBarcodeToUtf8(barcode); + } +#else + auto writer = MultiFormatWriter(cli.format).setMargin(cli.withQZ ? 10 : 0); + if (!cli.ecLevel.empty()) + writer.setEccLevel(std::stoi(cli.ecLevel)); + + BitMatrix matrix; + if (cli.inputIsFile) { + auto file = ReadFile(cli.input); + std::wstring bytes; + for (uint8_t c : file) + bytes.push_back(c); + writer.setEncoding(CharacterSet::BINARY); + matrix = writer.encode(bytes, cli.sizeHint, std::clamp(cli.sizeHint / 2, 50, 300)); + } else { + writer.setEncoding(CharacterSet::UTF8); + matrix = writer.encode(cli.input, cli.sizeHint, std::clamp(cli.sizeHint / 2, 50, 300)); + } + auto bitmap = ToMatrix<uint8_t>(matrix); +#endif + + auto ext = GetExtension(cli.outPath); + int success = 0; + if (ext == "" || ext == "png") { + success = stbi_write_png(cli.outPath.c_str(), bitmap.width(), bitmap.height(), 1, bitmap.data(), 0); + } else if (ext == "jpg" || ext == "jpeg") { + success = stbi_write_jpg(cli.outPath.c_str(), bitmap.width(), bitmap.height(), 1, bitmap.data(), 0); + } else if (ext == "svg") { +#ifdef ZXING_EXPERIMENTAL_API + success = (std::ofstream(cli.outPath) << WriteBarcodeToSVG(barcode, wOpts)).good(); +#else + success = (std::ofstream(cli.outPath) << ToSVG(matrix)).good(); +#endif + } + + if (!success) { + std::cerr << "Failed to write image: " << cli.outPath << std::endl; + return -1; + } + } catch (const std::exception& e) { + std::cerr << e.what() << std::endl; + return -1; + } + + return 0; +}
