Mercurial > hgrepos > Python2 > PyMuPDF
diff mupdf-source/thirdparty/zxing-cpp/core/src/ZXingC.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/core/src/ZXingC.cpp Mon Sep 15 11:43:07 2025 +0200 @@ -0,0 +1,431 @@ +/* +* Copyright 2023 siiky +* Copyright 2023 Axel Waggershauser +*/ +// SPDX-License-Identifier: Apache-2.0 + +#include "ZXingC.h" + +#include "ZXingCpp.h" +#include "ZXConfig.h" + +#if __has_include("Version.h") +#include "Version.h" +#else // this is mainly a workaround for a missing autogenerated Version.h in the XCode/CocoaPods corner +#define ZXING_VERSION_STR "undefined" +#endif + +#include <cstdlib> +#include <exception> +#include <string> +#include <string_view> +#include <utility> + +using namespace ZXing; + +static ZX_THREAD_LOCAL std::string lastErrorMsg; +static Barcodes emptyBarcodes{}; // used to prevent new heap allocation for each empty result + +template<typename R, typename T> R transmute_cast(const T& v) noexcept +{ + static_assert(sizeof(T) == sizeof(R)); + return *(const R*)(&v); +} + +template<typename C, typename P = typename C::pointer> +P copy(const C& c) noexcept +{ + auto ret = (P)malloc(c.size() + 1); + if (ret) { + memcpy(ret, c.data(), c.size()); + ret[c.size()] = 0; + } + return ret; +} + +static uint8_t* copy(const ByteArray& ba, int* len) noexcept +{ + // for convencience and as a safety measure, we NULL terminate even byte arrays + auto ret = copy(ba); + if (len) + *len = ret ? Size(ba) : 0; + return ret; +} + +#define ZX_CHECK( GOOD, MSG ) \ + if (!(GOOD)) { \ + lastErrorMsg = MSG; \ + return {}; \ + } + +#define ZX_CATCH(...) \ + catch (std::exception & e) { \ + lastErrorMsg = e.what(); \ + } catch (...) { \ + lastErrorMsg = "Unknown error"; \ + } \ + return __VA_ARGS__; + +#define ZX_TRY(...) \ + try { \ + return __VA_ARGS__; \ + } \ + ZX_CATCH({}) + + +extern "C" { +/* + * ZXing/ImageView.h + */ + +ZXing_ImageView* ZXing_ImageView_new(const uint8_t* data, int width, int height, ZXing_ImageFormat format, int rowStride, + int pixStride) +{ + ImageFormat cppformat = static_cast<ImageFormat>(format); + ZX_TRY(new ImageView(data, width, height, cppformat, rowStride, pixStride)) +} + +ZXing_ImageView* ZXing_ImageView_new_checked(const uint8_t* data, int size, int width, int height, ZXing_ImageFormat format, + int rowStride, int pixStride) +{ + ImageFormat cppformat = static_cast<ImageFormat>(format); + ZX_TRY(new ImageView(data, size, width, height, cppformat, rowStride, pixStride)) +} + +void ZXing_ImageView_delete(ZXing_ImageView* iv) +{ + delete iv; +} + +void ZXing_ImageView_crop(ZXing_ImageView* iv, int left, int top, int width, int height) +{ + *iv = iv->cropped(left, top, width, height); +} + +void ZXing_ImageView_rotate(ZXing_ImageView* iv, int degree) +{ + *iv = iv->rotated(degree); +} + +void ZXing_Image_delete(ZXing_Image* img) +{ + delete img; +} + +const uint8_t* ZXing_Image_data(const ZXing_Image* img) +{ + return img->data(); +} + +int ZXing_Image_width(const ZXing_Image* img) +{ + return img->width(); +} + +int ZXing_Image_height(const ZXing_Image* img) +{ + return img->height(); +} + +ZXing_ImageFormat ZXing_Image_format(const ZXing_Image* img) +{ + return static_cast<ZXing_ImageFormat>(img->format()); +} + +/* + * ZXing/BarcodeFormat.h + */ + +ZXing_BarcodeFormats ZXing_BarcodeFormatsFromString(const char* str) +{ + if (!str) + return {}; + try { + return transmute_cast<ZXing_BarcodeFormats>(BarcodeFormatsFromString(str)); + } + ZX_CATCH(ZXing_BarcodeFormat_Invalid) +} + +ZXing_BarcodeFormat ZXing_BarcodeFormatFromString(const char* str) +{ + ZXing_BarcodeFormat res = ZXing_BarcodeFormatsFromString(str); + return BitHacks::CountBitsSet(res) == 1 ? res : ZXing_BarcodeFormat_Invalid; +} + +char* ZXing_BarcodeFormatToString(ZXing_BarcodeFormat format) +{ + return copy(ToString(static_cast<BarcodeFormat>(format))); +} + +/* + * ZXing/ZXingCpp.h + */ + + +#ifdef ZXING_EXPERIMENTAL_API +ZXing_BarcodeFormats ZXing_SupportedBarcodeFormats(ZXing_Operation op) +{ + return transmute_cast<ZXing_BarcodeFormats>(SupportedBarcodeFormats(static_cast<Operation>(op))); +} +#endif + +/* + * ZXing/Barcode.h + */ + +char* ZXing_ContentTypeToString(ZXing_ContentType type) +{ + return copy(ToString(static_cast<ContentType>(type))); +} + +char* ZXing_PositionToString(ZXing_Position position) +{ + return copy(ToString(transmute_cast<Position>(position))); +} + + +bool ZXing_Barcode_isValid(const ZXing_Barcode* barcode) +{ + return barcode != NULL && barcode->isValid(); +} + +ZXing_ErrorType ZXing_Barcode_errorType(const ZXing_Barcode* barcode) +{ + return static_cast<ZXing_ErrorType>(barcode->error().type()); +} + +char* ZXing_Barcode_errorMsg(const ZXing_Barcode* barcode) +{ + return copy(ToString(barcode->error())); +} + +uint8_t* ZXing_Barcode_bytes(const ZXing_Barcode* barcode, int* len) +{ + return copy(barcode->bytes(), len); +} + +uint8_t* ZXing_Barcode_bytesECI(const ZXing_Barcode* barcode, int* len) +{ + return copy(barcode->bytesECI(), len); +} + +#define ZX_GETTER(TYPE, GETTER, TRANS) \ + TYPE ZXing_Barcode_##GETTER(const ZXing_Barcode* barcode) { return TRANS(barcode->GETTER()); } + +ZX_GETTER(ZXing_BarcodeFormat, format, static_cast<ZXing_BarcodeFormat>) +ZX_GETTER(ZXing_ContentType, contentType, static_cast<ZXing_ContentType>) +ZX_GETTER(char*, text, copy) +ZX_GETTER(char*, ecLevel, copy) +ZX_GETTER(char*, symbologyIdentifier, copy) +ZX_GETTER(ZXing_Position, position, transmute_cast<ZXing_Position>) + +ZX_GETTER(int, orientation,) +ZX_GETTER(bool, hasECI,) +ZX_GETTER(bool, isInverted,) +ZX_GETTER(bool, isMirrored,) +ZX_GETTER(int, lineCount,) + +void ZXing_Barcode_delete(ZXing_Barcode* barcode) +{ + delete barcode; +} + +void ZXing_Barcodes_delete(ZXing_Barcodes* barcodes) +{ + if (barcodes != &emptyBarcodes) + delete barcodes; +} + +int ZXing_Barcodes_size(const ZXing_Barcodes* barcodes) +{ + return barcodes ? Size(*barcodes) : 0; +} + +const ZXing_Barcode* ZXing_Barcodes_at(const ZXing_Barcodes* barcodes, int i) +{ + if (!barcodes || i < 0 || i >= Size(*barcodes)) + return NULL; + return &(*barcodes)[i]; +} + +ZXing_Barcode* ZXing_Barcodes_move(ZXing_Barcodes* barcodes, int i) +{ + if (!barcodes || i < 0 || i >= Size(*barcodes)) + return NULL; + + ZX_TRY(new Barcode(std::move((*barcodes)[i]))); +} + +/* + * ZXing/ReaderOptions.h + */ + +ZXing_ReaderOptions* ZXing_ReaderOptions_new() +{ + ZX_TRY(new ReaderOptions()); +} + +void ZXing_ReaderOptions_delete(ZXing_ReaderOptions* opts) +{ + delete opts; +} + +#define ZX_PROPERTY(TYPE, GETTER, SETTER) \ + TYPE ZXing_ReaderOptions_get##SETTER(const ZXing_ReaderOptions* opts) { return opts->GETTER(); } \ + void ZXing_ReaderOptions_set##SETTER(ZXing_ReaderOptions* opts, TYPE val) { opts->set##SETTER(val); } + +ZX_PROPERTY(bool, tryHarder, TryHarder) +ZX_PROPERTY(bool, tryRotate, TryRotate) +ZX_PROPERTY(bool, tryInvert, TryInvert) +ZX_PROPERTY(bool, tryDownscale, TryDownscale) +ZX_PROPERTY(bool, isPure, IsPure) +ZX_PROPERTY(bool, returnErrors, ReturnErrors) +ZX_PROPERTY(int, minLineCount, MinLineCount) +ZX_PROPERTY(int, maxNumberOfSymbols, MaxNumberOfSymbols) + +#undef ZX_PROPERTY + +void ZXing_ReaderOptions_setFormats(ZXing_ReaderOptions* opts, ZXing_BarcodeFormats formats) +{ + opts->setFormats(static_cast<BarcodeFormat>(formats)); +} + +ZXing_BarcodeFormats ZXing_ReaderOptions_getFormats(const ZXing_ReaderOptions* opts) +{ + auto v = opts->formats(); + return transmute_cast<ZXing_BarcodeFormats>(v); +} + +#define ZX_ENUM_PROPERTY(TYPE, GETTER, SETTER) \ + ZXing_##TYPE ZXing_ReaderOptions_get##SETTER(const ZXing_ReaderOptions* opts) { return static_cast<ZXing_##TYPE>(opts->GETTER()); } \ + void ZXing_ReaderOptions_set##SETTER(ZXing_ReaderOptions* opts, ZXing_##TYPE val) { opts->set##SETTER(static_cast<TYPE>(val)); } + +ZX_ENUM_PROPERTY(Binarizer, binarizer, Binarizer) +ZX_ENUM_PROPERTY(EanAddOnSymbol, eanAddOnSymbol, EanAddOnSymbol) +ZX_ENUM_PROPERTY(TextMode, textMode, TextMode) + + +/* + * ZXing/ReadBarcode.h + */ + +ZXing_Barcodes* ZXing_ReadBarcodes(const ZXing_ImageView* iv, const ZXing_ReaderOptions* opts) +{ + ZX_CHECK(iv, "ImageView param is NULL") + try { + auto res = ReadBarcodes(*iv, opts ? *opts : ReaderOptions{}); + return res.empty() ? &emptyBarcodes : new Barcodes(std::move(res)); + } + ZX_CATCH(NULL); +} + + +#ifdef ZXING_EXPERIMENTAL_API +/* + * ZXing/WriteBarcode.h + */ + +ZXing_CreatorOptions* ZXing_CreatorOptions_new(ZXing_BarcodeFormat format) +{ + ZX_TRY(new CreatorOptions(static_cast<BarcodeFormat>(format))); +} + +void ZXing_CreatorOptions_delete(ZXing_CreatorOptions* opts) +{ + delete opts; +} + +#define ZX_PROPERTY(TYPE, GETTER, SETTER) \ + TYPE ZXing_CreatorOptions_get##SETTER(const ZXing_CreatorOptions* opts) { return opts->GETTER(); } \ + void ZXing_CreatorOptions_set##SETTER(ZXing_CreatorOptions* opts, TYPE val) { opts->GETTER(val); } + +ZX_PROPERTY(bool, readerInit, ReaderInit) +ZX_PROPERTY(bool, forceSquareDataMatrix, ForceSquareDataMatrix) + +#undef ZX_PROPERTY + +//ZX_PROPERTY(BarcodeFormat, format, Format) + +char* ZXing_CreatorOptions_getEcLevel(const ZXing_CreatorOptions* opts) +{ + return copy(opts->ecLevel()); +} + +void ZXing_CreatorOptions_setEcLevel(ZXing_CreatorOptions* opts, const char* val) +{ + opts->ecLevel(val); +} + + +ZXing_WriterOptions* ZXing_WriterOptions_new() +{ + ZX_TRY(new ZXing_WriterOptions()); +} + +void ZXing_WriterOptions_delete(ZXing_WriterOptions* opts) +{ + delete opts; +} + +#define ZX_PROPERTY(TYPE, GETTER, SETTER) \ + TYPE ZXing_WriterOptions_get##SETTER(const ZXing_WriterOptions* opts) { return opts->GETTER(); } \ + void ZXing_WriterOptions_set##SETTER(ZXing_WriterOptions* opts, TYPE val) { opts->GETTER(val); } + +ZX_PROPERTY(int, scale, Scale) +ZX_PROPERTY(int, sizeHint, SizeHint) +ZX_PROPERTY(int, rotate, Rotate) +ZX_PROPERTY(bool, withHRT, WithHRT) +ZX_PROPERTY(bool, withQuietZones, WithQuietZones) + +#undef ZX_PROPERTY + +ZXing_Barcode* ZXing_CreateBarcodeFromText(const char* data, int size, const ZXing_CreatorOptions* opts) +{ + ZX_CHECK(data && opts, "Data and/or options param in CreateBarcodeFromText is NULL") + ZX_TRY(new Barcode(CreateBarcodeFromText({data, size ? static_cast<size_t>(size) : strlen(data)}, *opts));) +} + +ZXing_Barcode* ZXing_CreateBarcodeFromBytes(const void* data, int size, const ZXing_CreatorOptions* opts) +{ + ZX_CHECK(data && size && opts, "Data and/or options param in CreateBarcodeFromBytes is NULL") + ZX_TRY(new Barcode(CreateBarcodeFromBytes(data, size, *opts))) +} + +char* ZXing_WriteBarcodeToSVG(const ZXing_Barcode* barcode, const ZXing_WriterOptions* opts) +{ + ZX_CHECK(barcode, "Barcode param in WriteBarcodeToSVG is NULL") + ZX_TRY(copy(opts ? WriteBarcodeToSVG(*barcode, *opts) : WriteBarcodeToSVG(*barcode))) +} + +ZXing_Image* ZXing_WriteBarcodeToImage(const ZXing_Barcode* barcode, const ZXing_WriterOptions* opts) +{ + ZX_CHECK(barcode, "Barcode param in WriteBarcodeToSVG is NULL") + ZX_TRY(new Image(opts ? WriteBarcodeToImage(*barcode, *opts) : WriteBarcodeToImage(*barcode))) +} + +#endif + +/* + * ZXingC.h + */ + +char* ZXing_LastErrorMsg() +{ + if (lastErrorMsg.empty()) + return NULL; + + return copy(std::exchange(lastErrorMsg, {})); +} + +const char* ZXing_Version() +{ + return ZXING_VERSION_STR; +} + +void ZXing_free(void* ptr) +{ + if (ptr != ZXing_Version()) + free(ptr); +} + +} // extern "C"
