Mercurial > hgrepos > Python2 > PyMuPDF
diff mupdf-source/thirdparty/zxing-cpp/core/src/BitMatrix.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/BitMatrix.cpp Mon Sep 15 11:43:07 2025 +0200 @@ -0,0 +1,175 @@ +/* +* Copyright 2016 Nu-book Inc. +* Copyright 2016 ZXing authors +*/ +// SPDX-License-Identifier: Apache-2.0 + +#include "BitMatrix.h" + +#include "Pattern.h" + +#include <algorithm> +#include <stdexcept> +#include <utility> + +namespace ZXing { + +void +BitMatrix::setRegion(int left, int top, int width, int height) +{ + if (top < 0 || left < 0) { + throw std::invalid_argument("BitMatrix::setRegion(): Left and top must be nonnegative"); + } + if (height < 1 || width < 1) { + throw std::invalid_argument("BitMatrix::setRegion(): Height and width must be at least 1"); + } + int right = left + width; + int bottom = top + height; + if (bottom > _height || right > _width) { + throw std::invalid_argument("BitMatrix::setRegion(): The region must fit inside the matrix"); + } + for (int y = top; y < bottom; y++) { + auto offset = y * _width; + for (int x = left; x < right; x++) { + _bits[offset + x] = SET_V; + } + } +} + +void +BitMatrix::rotate90() +{ + BitMatrix result(height(), width()); + for (int x = 0; x < width(); ++x) { + for (int y = 0; y < height(); ++y) { + if (get(x, y)) { + result.set(y, width() - x - 1); + } + } + } + *this = std::move(result); +} + +void +BitMatrix::rotate180() +{ + std::reverse(_bits.begin(), _bits.end()); +} + +void +BitMatrix::mirror() +{ + for (int x = 0; x < _width; x++) { + for (int y = x + 1; y < _height; y++) { + if (get(x, y) != get(y, x)) { + flip(y, x); + flip(x, y); + } + } + } +} + +bool +BitMatrix::findBoundingBox(int &left, int& top, int& width, int& height, int minSize) const +{ + int right, bottom; + if (!getTopLeftOnBit(left, top) || !getBottomRightOnBit(right, bottom) || bottom - top + 1 < minSize) + return false; + + for (int y = top; y <= bottom; y++ ) { + for (int x = 0; x < left; ++x) + if (get(x, y)) { + left = x; + break; + } + for (int x = _width-1; x > right; x--) + if (get(x, y)) { + right = x; + break; + } + } + + width = right - left + 1; + height = bottom - top + 1; + return width >= minSize && height >= minSize; +} + +static auto isSet = [](auto v) { return bool(v); }; + +bool +BitMatrix::getTopLeftOnBit(int& left, int& top) const +{ + int bitsOffset = (int)std::distance(_bits.begin(), std::find_if(_bits.begin(), _bits.end(), isSet)); + if (bitsOffset == Size(_bits)) { + return false; + } + top = bitsOffset / _width; + left = (bitsOffset % _width); + return true; +} + +bool +BitMatrix::getBottomRightOnBit(int& right, int& bottom) const +{ + int bitsOffset = Size(_bits) - 1 - (int)std::distance(_bits.rbegin(), std::find_if(_bits.rbegin(), _bits.rend(), isSet)); + if (bitsOffset < 0) { + return false; + } + + bottom = bitsOffset / _width; + right = (bitsOffset % _width); + return true; +} + +void GetPatternRow(const BitMatrix& matrix, int r, std::vector<uint16_t>& pr, bool transpose) +{ + if (transpose) + GetPatternRow(matrix.col(r), pr); + else + GetPatternRow(matrix.row(r), pr); +} + +BitMatrix Inflate(BitMatrix&& input, int width, int height, int quietZone) +{ + const int codeWidth = input.width(); + const int codeHeight = input.height(); + const int outputWidth = std::max(width, codeWidth + 2 * quietZone); + const int outputHeight = std::max(height, codeHeight + 2 * quietZone); + + if (input.width() == outputWidth && input.height() == outputHeight) + return std::move(input); + + const int scale = std::min((outputWidth - 2*quietZone) / codeWidth, (outputHeight - 2*quietZone) / codeHeight); + // Padding includes both the quiet zone and the extra white pixels to + // accommodate the requested dimensions. + const int leftPadding = (outputWidth - (codeWidth * scale)) / 2; + const int topPadding = (outputHeight - (codeHeight * scale)) / 2; + + BitMatrix result(outputWidth, outputHeight); + + for (int inputY = 0, outputY = topPadding; inputY < input.height(); ++inputY, outputY += scale) { + for (int inputX = 0, outputX = leftPadding; inputX < input.width(); ++inputX, outputX += scale) { + if (input.get(inputX, inputY)) + result.setRegion(outputX, outputY, scale, scale); + } + } + + return result; +} + +BitMatrix Deflate(const BitMatrix& input, int width, int height, float top, float left, float subSampling) +{ + BitMatrix result(width, height); + + for (int y = 0; y < result.height(); y++) { + auto yOffset = top + y * subSampling; + for (int x = 0; x < result.width(); x++) { + if (input.get(PointF(left + x * subSampling, yOffset))) + result.set(x, y); + } + } + + return result; +} + +} // ZXing
