| 134 | } |
| 135 | |
| 136 | Results ReadBarcodes(const ImageView& _iv, const DecodeHints& hints) |
| 137 | { |
| 138 | if (sizeof(PatternType) < 4 && hints.hasFormat(BarcodeFormat::LinearCodes) && (_iv.width() > 0xffff || _iv.height() > 0xffff)) |
| 139 | throw std::invalid_argument("maximum image width/height is 65535"); |
| 140 | |
| 141 | LumImage lum; |
| 142 | ImageView iv = SetupLumImageView(_iv, lum, hints); |
| 143 | MultiFormatReader reader(hints); |
| 144 | |
| 145 | if (hints.isPure()) |
| 146 | return {reader.read(*CreateBitmap(hints.binarizer(), iv))}; |
| 147 | |
| 148 | auto formatsBenefittingFromClosing = BarcodeFormat::Aztec | BarcodeFormat::DataMatrix | BarcodeFormat::QRCode | BarcodeFormat::MicroQRCode; |
| 149 | DecodeHints closedHints = hints; |
| 150 | std::unique_ptr<MultiFormatReader> closedReader; |
| 151 | if (hints.tryDenoise() && hints.hasFormat(formatsBenefittingFromClosing)) { |
| 152 | closedHints.setFormats((hints.formats().empty() ? BarcodeFormat::Any : hints.formats()) & formatsBenefittingFromClosing); |
| 153 | closedReader = std::make_unique<MultiFormatReader>(closedHints); |
| 154 | } |
| 155 | |
| 156 | LumImagePyramid pyramid(iv, hints.downscaleThreshold() * hints.tryDownscale(), hints.downscaleFactor()); |
| 157 | |
| 158 | Results results; |
| 159 | int maxSymbols = hints.maxNumberOfSymbols() ? hints.maxNumberOfSymbols() : INT_MAX; |
| 160 | for (auto&& iv : pyramid.layers) { |
| 161 | auto bitmap = CreateBitmap(hints.binarizer(), iv); |
| 162 | for (int close = 0; close <= (closedReader ? 1 : 0); ++close) { |
| 163 | if (close) |
| 164 | bitmap->close(); |
| 165 | |
| 166 | // TODO: check if closing after invert would be beneficial |
| 167 | for (int invert = 0; invert <= static_cast<int>(hints.tryInvert() && !close); ++invert) { |
| 168 | if (invert) |
| 169 | bitmap->invert(); |
| 170 | auto rs = (close ? *closedReader : reader).readMultiple(*bitmap, maxSymbols); |
| 171 | for (auto& r : rs) { |
| 172 | if (iv.width() != _iv.width()) |
| 173 | r.setPosition(Scale(r.position(), _iv.width() / iv.width())); |
| 174 | if (!Contains(results, r)) { |
| 175 | r.setDecodeHints(hints); |
| 176 | r.setIsInverted(bitmap->inverted()); |
| 177 | results.push_back(std::move(r)); |
| 178 | --maxSymbols; |
| 179 | } |
| 180 | } |
| 181 | if (maxSymbols <= 0) |
| 182 | return results; |
| 183 | } |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | return results; |
| 188 | } |
| 189 | |
| 190 | } // ZXing |
no test coverage detected