Mercurial > hgrepos > Python2 > PyMuPDF
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /* | |
| 2 * Copyright 2016 Nu-book Inc. | |
| 3 * Copyright 2016 ZXing authors | |
| 4 */ | |
| 5 // SPDX-License-Identifier: Apache-2.0 | |
| 6 | |
| 7 #include "BitMatrix.h" | |
| 8 | |
| 9 #include "Pattern.h" | |
| 10 | |
| 11 #include <algorithm> | |
| 12 #include <stdexcept> | |
| 13 #include <utility> | |
| 14 | |
| 15 namespace ZXing { | |
| 16 | |
| 17 void | |
| 18 BitMatrix::setRegion(int left, int top, int width, int height) | |
| 19 { | |
| 20 if (top < 0 || left < 0) { | |
| 21 throw std::invalid_argument("BitMatrix::setRegion(): Left and top must be nonnegative"); | |
| 22 } | |
| 23 if (height < 1 || width < 1) { | |
| 24 throw std::invalid_argument("BitMatrix::setRegion(): Height and width must be at least 1"); | |
| 25 } | |
| 26 int right = left + width; | |
| 27 int bottom = top + height; | |
| 28 if (bottom > _height || right > _width) { | |
| 29 throw std::invalid_argument("BitMatrix::setRegion(): The region must fit inside the matrix"); | |
| 30 } | |
| 31 for (int y = top; y < bottom; y++) { | |
| 32 auto offset = y * _width; | |
| 33 for (int x = left; x < right; x++) { | |
| 34 _bits[offset + x] = SET_V; | |
| 35 } | |
| 36 } | |
| 37 } | |
| 38 | |
| 39 void | |
| 40 BitMatrix::rotate90() | |
| 41 { | |
| 42 BitMatrix result(height(), width()); | |
| 43 for (int x = 0; x < width(); ++x) { | |
| 44 for (int y = 0; y < height(); ++y) { | |
| 45 if (get(x, y)) { | |
| 46 result.set(y, width() - x - 1); | |
| 47 } | |
| 48 } | |
| 49 } | |
| 50 *this = std::move(result); | |
| 51 } | |
| 52 | |
| 53 void | |
| 54 BitMatrix::rotate180() | |
| 55 { | |
| 56 std::reverse(_bits.begin(), _bits.end()); | |
| 57 } | |
| 58 | |
| 59 void | |
| 60 BitMatrix::mirror() | |
| 61 { | |
| 62 for (int x = 0; x < _width; x++) { | |
| 63 for (int y = x + 1; y < _height; y++) { | |
| 64 if (get(x, y) != get(y, x)) { | |
| 65 flip(y, x); | |
| 66 flip(x, y); | |
| 67 } | |
| 68 } | |
| 69 } | |
| 70 } | |
| 71 | |
| 72 bool | |
| 73 BitMatrix::findBoundingBox(int &left, int& top, int& width, int& height, int minSize) const | |
| 74 { | |
| 75 int right, bottom; | |
| 76 if (!getTopLeftOnBit(left, top) || !getBottomRightOnBit(right, bottom) || bottom - top + 1 < minSize) | |
| 77 return false; | |
| 78 | |
| 79 for (int y = top; y <= bottom; y++ ) { | |
| 80 for (int x = 0; x < left; ++x) | |
| 81 if (get(x, y)) { | |
| 82 left = x; | |
| 83 break; | |
| 84 } | |
| 85 for (int x = _width-1; x > right; x--) | |
| 86 if (get(x, y)) { | |
| 87 right = x; | |
| 88 break; | |
| 89 } | |
| 90 } | |
| 91 | |
| 92 width = right - left + 1; | |
| 93 height = bottom - top + 1; | |
| 94 return width >= minSize && height >= minSize; | |
| 95 } | |
| 96 | |
| 97 static auto isSet = [](auto v) { return bool(v); }; | |
| 98 | |
| 99 bool | |
| 100 BitMatrix::getTopLeftOnBit(int& left, int& top) const | |
| 101 { | |
| 102 int bitsOffset = (int)std::distance(_bits.begin(), std::find_if(_bits.begin(), _bits.end(), isSet)); | |
| 103 if (bitsOffset == Size(_bits)) { | |
| 104 return false; | |
| 105 } | |
| 106 top = bitsOffset / _width; | |
| 107 left = (bitsOffset % _width); | |
| 108 return true; | |
| 109 } | |
| 110 | |
| 111 bool | |
| 112 BitMatrix::getBottomRightOnBit(int& right, int& bottom) const | |
| 113 { | |
| 114 int bitsOffset = Size(_bits) - 1 - (int)std::distance(_bits.rbegin(), std::find_if(_bits.rbegin(), _bits.rend(), isSet)); | |
| 115 if (bitsOffset < 0) { | |
| 116 return false; | |
| 117 } | |
| 118 | |
| 119 bottom = bitsOffset / _width; | |
| 120 right = (bitsOffset % _width); | |
| 121 return true; | |
| 122 } | |
| 123 | |
| 124 void GetPatternRow(const BitMatrix& matrix, int r, std::vector<uint16_t>& pr, bool transpose) | |
| 125 { | |
| 126 if (transpose) | |
| 127 GetPatternRow(matrix.col(r), pr); | |
| 128 else | |
| 129 GetPatternRow(matrix.row(r), pr); | |
| 130 } | |
| 131 | |
| 132 BitMatrix Inflate(BitMatrix&& input, int width, int height, int quietZone) | |
| 133 { | |
| 134 const int codeWidth = input.width(); | |
| 135 const int codeHeight = input.height(); | |
| 136 const int outputWidth = std::max(width, codeWidth + 2 * quietZone); | |
| 137 const int outputHeight = std::max(height, codeHeight + 2 * quietZone); | |
| 138 | |
| 139 if (input.width() == outputWidth && input.height() == outputHeight) | |
| 140 return std::move(input); | |
| 141 | |
| 142 const int scale = std::min((outputWidth - 2*quietZone) / codeWidth, (outputHeight - 2*quietZone) / codeHeight); | |
| 143 // Padding includes both the quiet zone and the extra white pixels to | |
| 144 // accommodate the requested dimensions. | |
| 145 const int leftPadding = (outputWidth - (codeWidth * scale)) / 2; | |
| 146 const int topPadding = (outputHeight - (codeHeight * scale)) / 2; | |
| 147 | |
| 148 BitMatrix result(outputWidth, outputHeight); | |
| 149 | |
| 150 for (int inputY = 0, outputY = topPadding; inputY < input.height(); ++inputY, outputY += scale) { | |
| 151 for (int inputX = 0, outputX = leftPadding; inputX < input.width(); ++inputX, outputX += scale) { | |
| 152 if (input.get(inputX, inputY)) | |
| 153 result.setRegion(outputX, outputY, scale, scale); | |
| 154 } | |
| 155 } | |
| 156 | |
| 157 return result; | |
| 158 } | |
| 159 | |
| 160 BitMatrix Deflate(const BitMatrix& input, int width, int height, float top, float left, float subSampling) | |
| 161 { | |
| 162 BitMatrix result(width, height); | |
| 163 | |
| 164 for (int y = 0; y < result.height(); y++) { | |
| 165 auto yOffset = top + y * subSampling; | |
| 166 for (int x = 0; x < result.width(); x++) { | |
| 167 if (input.get(PointF(left + x * subSampling, yOffset))) | |
| 168 result.set(x, y); | |
| 169 } | |
| 170 } | |
| 171 | |
| 172 return result; | |
| 173 } | |
| 174 | |
| 175 } // ZXing |
