diff mupdf-source/thirdparty/zxing-cpp/core/src/BinaryBitmap.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/BinaryBitmap.cpp	Mon Sep 15 11:43:07 2025 +0200
@@ -0,0 +1,101 @@
+/*
+* Copyright 2020 Axel Waggershauser
+*/
+// SPDX-License-Identifier: Apache-2.0
+
+#include "BinaryBitmap.h"
+
+#include "BitMatrix.h"
+
+#include <mutex>
+
+namespace ZXing {
+
+struct BinaryBitmap::Cache
+{
+	std::once_flag once;
+	std::shared_ptr<const BitMatrix> matrix;
+};
+
+BitMatrix BinaryBitmap::binarize(const uint8_t threshold) const
+{
+	BitMatrix res(width(), height());
+
+	if (_buffer.pixStride() == 1 && _buffer.rowStride() == _buffer.width()) {
+		// Specialize for a packed buffer with pixStride 1 to support auto vectorization (16x speedup on AVX2)
+		auto dst = res.row(0).begin();
+		for (auto src = _buffer.data(0, 0), end = _buffer.data(0, height()); src != end; ++src, ++dst)
+			*dst = (*src <= threshold) * BitMatrix::SET_V;
+	} else {
+		auto processLine = [&res, threshold](int y, const auto* src, const int stride) {
+			for (auto& dst : res.row(y)) {
+				dst = (*src <= threshold) * BitMatrix::SET_V;
+				src += stride;
+			}
+		};
+		for (int y = 0; y < res.height(); ++y) {
+			auto src = _buffer.data(0, y) + GreenIndex(_buffer.format());
+			// Specialize the inner loop for strides 1 and 4 to support auto vectorization
+			switch (_buffer.pixStride()) {
+			case 1: processLine(y, src, 1); break;
+			case 4: processLine(y, src, 4); break;
+			default: processLine(y, src, _buffer.pixStride()); break;
+			}
+		}
+	}
+
+	return res;
+}
+
+BinaryBitmap::BinaryBitmap(const ImageView& buffer) : _cache(new Cache), _buffer(buffer) {}
+
+BinaryBitmap::~BinaryBitmap() = default;
+
+const BitMatrix* BinaryBitmap::getBitMatrix() const
+{
+	std::call_once(_cache->once, [&](){_cache->matrix = getBlackMatrix();});
+	return _cache->matrix.get();
+}
+
+void BinaryBitmap::invert()
+{
+	if (_cache->matrix) {
+		auto matrix = const_cast<BitMatrix*>(_cache->matrix.get());
+		matrix->flipAll();
+	}
+	_inverted = true;
+}
+
+template <typename F>
+void SumFilter(const BitMatrix& in, BitMatrix& out, F func)
+{
+	assert(in.height() >= 3);
+
+	const auto* in0 = in.row(0).begin();
+	const auto* in1 = in.row(1).begin();
+	const auto* in2 = in.row(2).begin();
+
+	for (auto *out1 = out.row(1).begin() + 1, *end = out.row(out.height() - 1).begin() - 1; out1 != end; ++in0, ++in1, ++in2, ++out1) {
+		int sum = 0;
+		for (int j = 0; j < 3; ++j)
+			sum += in0[j] + in1[j] + in2[j];
+
+		*out1 = func(sum);
+	}
+}
+
+void BinaryBitmap::close()
+{
+	if (_cache->matrix) {
+		auto& matrix = *const_cast<BitMatrix*>(_cache->matrix.get());
+		BitMatrix tmp(matrix.width(), matrix.height());
+
+		// dilate
+		SumFilter(matrix, tmp, [](int sum) { return (sum > 0 * BitMatrix::SET_V) * BitMatrix::SET_V; });
+		// erode
+		SumFilter(tmp, matrix, [](int sum) { return (sum == 9 * BitMatrix::SET_V) * BitMatrix::SET_V; });
+	}
+	_closed = true;
+}
+
+} // ZXing