X-Git-Url: http://git.rot13.org/?p=zxing.git;a=blobdiff_plain;f=cpp%2Fcore%2Fsrc%2Fzxing%2Foned%2FOneDReader.cpp;h=4ba73abba6f27c1d6dd2dff199ccc696210cd238;hp=7610b870e7804183689bb3eb809549222b72866f;hb=45e643cea495289f6e95112482a3fd3086ef4431;hpb=4430403d20762773119a1db47c0a4c2776d778f1 diff --git a/cpp/core/src/zxing/oned/OneDReader.cpp b/cpp/core/src/zxing/oned/OneDReader.cpp index 7610b870..4ba73abb 100644 --- a/cpp/core/src/zxing/oned/OneDReader.cpp +++ b/cpp/core/src/zxing/oned/OneDReader.cpp @@ -2,7 +2,6 @@ * OneDReader.cpp * ZXing * - * Created by Lukasz Warchol on 10-01-15. * Copyright 2010 ZXing authors All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,24 +19,24 @@ #include "OneDReader.h" #include +#include #include #include namespace zxing { namespace oned { using namespace std; - + OneDReader::OneDReader() { } - - Ref OneDReader::decode(Ref image) { - try { - return doDecode(image); - }catch (ReaderException re) { - if (false /*tryHarder && image.isRotateSupported()*/) { - /* - BinaryBitmap rotatedImage = image.rotateCounterClockwise(); - Result result = doDecode(rotatedImage, hints); + + Ref OneDReader::decode(Ref image, DecodeHints hints) { + Ref result = doDecode(image, hints); + if (result.empty() && hints.getTryHarder() && image->isRotateSupported()) { + Ref rotatedImage(image->rotateCounterClockwise()); + result = doDecode(rotatedImage, hints); + if (!result.empty()) { + /* // Record that we found it rotated 90 degrees CCW / 270 degrees CW Hashtable metadata = result.getResultMetadata(); int orientation = 270; @@ -47,38 +46,36 @@ namespace zxing { ((Integer) metadata.get(ResultMetadataType.ORIENTATION)).intValue()) % 360; } result.putMetadata(ResultMetadataType.ORIENTATION, new Integer(orientation)); - // Update result points - ResultPoint[] points = result.getResultPoints(); - int height = rotatedImage.getHeight(); - for (int i = 0; i < points.length; i++) { - points[i] = new ResultPoint(height - points[i].getY() - 1, points[i].getX()); - } - return result; */ - } else { - throw re; + // Update result points + std::vector > points (result->getResultPoints()); + int height = rotatedImage->getHeight(); + for (size_t i = 0; i < points.size(); i++) { + points[i].reset(new OneDResultPoint(height - points[i]->getY() - 1, points[i]->getX())); + } } - } + } + if (result.empty()) { + throw ReaderException(""); + } + return result; } - - Ref OneDReader::doDecode(Ref image){ + + Ref OneDReader::doDecode(Ref image, DecodeHints hints) { int width = image->getWidth(); int height = image->getHeight(); Ref row(new BitArray(width)); -// BitArray row = new BitArray(width); - int middle = height >> 1; - bool tryHarder = true;//hints != null && hints.containsKey(DecodeHintType.TRY_HARDER); - int rowStep = (int)fmax(1, height >> (tryHarder ? 7 : 4)); + bool tryHarder = hints.getTryHarder(); + int rowStep = (int)fmax(1, height >> (tryHarder ? 8 : 5)); int maxLines; if (tryHarder) { maxLines = height; // Look at the whole image, not just the center } else { - maxLines = 9; // Nine rows spaced 1/16 apart is roughly the middle half of the image + maxLines = 15; // 15 rows spaced 1/32 apart is roughly the middle half of the image } - + for (int x = 0; x < maxLines; x++) { - // Scanning from the middle out. Determine which row we're looking at next: int rowStepsAboveOrBelow = (x + 1) >> 1; bool isAbove = (x & 0x01) == 0; // i.e. is x even? @@ -87,42 +84,54 @@ namespace zxing { // Oops, if we run off the top or bottom, stop break; } - + // Estimate black point for this row and load it: try { row = image->getBlackRow(rowNumber, row); - }catch (ReaderException re) { + } catch (ReaderException re) { continue; + } catch (IllegalArgumentException re) { + continue; } - + // While we have the image data in a BitArray, it's fairly cheap to reverse it in place to // handle decoding upside down barcodes. for (int attempt = 0; attempt < 2; attempt++) { if (attempt == 1) { // trying again? row->reverse(); // reverse the row and continue } - try { - // Look for a barcode - Ref result = decodeRow(rowNumber, row); - // We found our barcode - if (attempt == 1) { - // // But it was upside down, so note that - // result.putMetadata(ResultMetadataType.ORIENTATION, new Integer(180)); - // // And remember to flip the result points horizontally. - // ResultPoint[] points = result.getResultPoints(); - // points[0] = new ResultPoint(width - points[0].getX() - 1, points[0].getY()); - // points[1] = new ResultPoint(width - points[1].getX() - 1, points[1].getY()); - } - return result; - } catch (ReaderException re) { - // continue -- just couldn't decode this row - } + + // Look for a barcode + Ref result = decodeRow(rowNumber, row); + // We found our barcode + if (!result.empty()) { + // // But it was upside down, so note that + // result.putMetadata(ResultMetadataType.ORIENTATION, new Integer(180)); + // // And remember to flip the result points horizontally. + std::vector > points(result->getResultPoints()); + // if there's exactly two points (which there should be), flip the x coordinate + // if there's not exactly 2, I don't know what do do with it + if (points.size() == 2) { + Ref pointZero(new OneDResultPoint(width - points[0]->getX() - 1, + points[0]->getY())); + points[0] = pointZero; + + Ref pointOne(new OneDResultPoint(width - points[1]->getX() - 1, + points[1]->getY())); + points[1] = pointOne; + + result.reset(new Result(result->getText(), result->getRawBytes(), points, + result->getBarcodeFormat())); + } + return result; + } } } - throw ReaderException(""); + return Ref(); } - - unsigned int OneDReader::patternMatchVariance(int counters[], int countersSize, const int pattern[], int maxIndividualVariance) { + + unsigned int OneDReader::patternMatchVariance(int counters[], int countersSize, + const int pattern[], int maxIndividualVariance) { int numCounters = countersSize; unsigned int total = 0; unsigned int patternLength = 0; @@ -140,7 +149,7 @@ namespace zxing { // more "significant digits" unsigned int unitBarWidth = (total << INTEGER_MATH_SHIFT) / patternLength; maxIndividualVariance = (maxIndividualVariance * unitBarWidth) >> INTEGER_MATH_SHIFT; - + unsigned int totalVariance = 0; for (int x = 0; x < numCounters; x++) { int counter = counters[x] << INTEGER_MATH_SHIFT; @@ -153,15 +162,15 @@ namespace zxing { } return totalVariance / total; } - - void OneDReader::recordPattern(Ref row, int start, int counters[], int countersCount){ + + bool OneDReader::recordPattern(Ref row, int start, int counters[], int countersCount) { int numCounters = countersCount;//sizeof(counters) / sizeof(int); for (int i = 0; i < numCounters; i++) { counters[i] = 0; } int end = row->getSize(); if (start >= end) { - throw ReaderException("recordPattern: start >= end"); + return false; } bool isWhite = !row->get(start); int counterPosition = 0; @@ -184,10 +193,11 @@ namespace zxing { // If we read fully the last section of pixels and filled up our counters -- or filled // the last counter but ran off the side of the image, OK. Otherwise, a problem. if (!(counterPosition == numCounters || (counterPosition == numCounters - 1 && i == end))) { - throw ReaderException("recordPattern"); + return false; } + return true; } - + OneDReader::~OneDReader() { } }