Mercurial > hgrepos > Python2 > PyMuPDF
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /* | |
| 2 * Copyright 2020 Axel Waggershauser | |
| 3 */ | |
| 4 // SPDX-License-Identifier: Apache-2.0 | |
| 5 | |
| 6 #include "BinaryBitmap.h" | |
| 7 | |
| 8 #include "BitMatrix.h" | |
| 9 | |
| 10 #include <mutex> | |
| 11 | |
| 12 namespace ZXing { | |
| 13 | |
| 14 struct BinaryBitmap::Cache | |
| 15 { | |
| 16 std::once_flag once; | |
| 17 std::shared_ptr<const BitMatrix> matrix; | |
| 18 }; | |
| 19 | |
| 20 BitMatrix BinaryBitmap::binarize(const uint8_t threshold) const | |
| 21 { | |
| 22 BitMatrix res(width(), height()); | |
| 23 | |
| 24 if (_buffer.pixStride() == 1 && _buffer.rowStride() == _buffer.width()) { | |
| 25 // Specialize for a packed buffer with pixStride 1 to support auto vectorization (16x speedup on AVX2) | |
| 26 auto dst = res.row(0).begin(); | |
| 27 for (auto src = _buffer.data(0, 0), end = _buffer.data(0, height()); src != end; ++src, ++dst) | |
| 28 *dst = (*src <= threshold) * BitMatrix::SET_V; | |
| 29 } else { | |
| 30 auto processLine = [&res, threshold](int y, const auto* src, const int stride) { | |
| 31 for (auto& dst : res.row(y)) { | |
| 32 dst = (*src <= threshold) * BitMatrix::SET_V; | |
| 33 src += stride; | |
| 34 } | |
| 35 }; | |
| 36 for (int y = 0; y < res.height(); ++y) { | |
| 37 auto src = _buffer.data(0, y) + GreenIndex(_buffer.format()); | |
| 38 // Specialize the inner loop for strides 1 and 4 to support auto vectorization | |
| 39 switch (_buffer.pixStride()) { | |
| 40 case 1: processLine(y, src, 1); break; | |
| 41 case 4: processLine(y, src, 4); break; | |
| 42 default: processLine(y, src, _buffer.pixStride()); break; | |
| 43 } | |
| 44 } | |
| 45 } | |
| 46 | |
| 47 return res; | |
| 48 } | |
| 49 | |
| 50 BinaryBitmap::BinaryBitmap(const ImageView& buffer) : _cache(new Cache), _buffer(buffer) {} | |
| 51 | |
| 52 BinaryBitmap::~BinaryBitmap() = default; | |
| 53 | |
| 54 const BitMatrix* BinaryBitmap::getBitMatrix() const | |
| 55 { | |
| 56 std::call_once(_cache->once, [&](){_cache->matrix = getBlackMatrix();}); | |
| 57 return _cache->matrix.get(); | |
| 58 } | |
| 59 | |
| 60 void BinaryBitmap::invert() | |
| 61 { | |
| 62 if (_cache->matrix) { | |
| 63 auto matrix = const_cast<BitMatrix*>(_cache->matrix.get()); | |
| 64 matrix->flipAll(); | |
| 65 } | |
| 66 _inverted = true; | |
| 67 } | |
| 68 | |
| 69 template <typename F> | |
| 70 void SumFilter(const BitMatrix& in, BitMatrix& out, F func) | |
| 71 { | |
| 72 assert(in.height() >= 3); | |
| 73 | |
| 74 const auto* in0 = in.row(0).begin(); | |
| 75 const auto* in1 = in.row(1).begin(); | |
| 76 const auto* in2 = in.row(2).begin(); | |
| 77 | |
| 78 for (auto *out1 = out.row(1).begin() + 1, *end = out.row(out.height() - 1).begin() - 1; out1 != end; ++in0, ++in1, ++in2, ++out1) { | |
| 79 int sum = 0; | |
| 80 for (int j = 0; j < 3; ++j) | |
| 81 sum += in0[j] + in1[j] + in2[j]; | |
| 82 | |
| 83 *out1 = func(sum); | |
| 84 } | |
| 85 } | |
| 86 | |
| 87 void BinaryBitmap::close() | |
| 88 { | |
| 89 if (_cache->matrix) { | |
| 90 auto& matrix = *const_cast<BitMatrix*>(_cache->matrix.get()); | |
| 91 BitMatrix tmp(matrix.width(), matrix.height()); | |
| 92 | |
| 93 // dilate | |
| 94 SumFilter(matrix, tmp, [](int sum) { return (sum > 0 * BitMatrix::SET_V) * BitMatrix::SET_V; }); | |
| 95 // erode | |
| 96 SumFilter(tmp, matrix, [](int sum) { return (sum == 9 * BitMatrix::SET_V) * BitMatrix::SET_V; }); | |
| 97 } | |
| 98 _closed = true; | |
| 99 } | |
| 100 | |
| 101 } // ZXing |
