mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
C++ port: some memory leak cleanups
Closes Issue 499 and Issue 496. git-svn-id: https://zxing.googlecode.com/svn/trunk@1510 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
2de913d220
commit
5a4f5c901d
|
@ -62,25 +62,25 @@ namespace zxing {
|
|||
hints.containsFormat(BarcodeFormat_CODE_39) ||
|
||||
hints.containsFormat(BarcodeFormat_ITF);
|
||||
if (addOneDReader && !tryHarder) {
|
||||
readers_.push_back(new zxing::oned::MultiFormatOneDReader(hints));
|
||||
readers_.push_back(Ref<Reader>(new zxing::oned::MultiFormatOneDReader(hints)));
|
||||
}
|
||||
if (hints.containsFormat(BarcodeFormat_QR_CODE)) {
|
||||
readers_.push_back(new zxing::qrcode::QRCodeReader());
|
||||
readers_.push_back(Ref<Reader>(new zxing::qrcode::QRCodeReader()));
|
||||
}
|
||||
if (hints.containsFormat(BarcodeFormat_DATA_MATRIX)) {
|
||||
readers_.push_back(new zxing::datamatrix::DataMatrixReader());
|
||||
readers_.push_back(Ref<Reader>(new zxing::datamatrix::DataMatrixReader()));
|
||||
}
|
||||
//TODO: add PDF417 here once PDF417 reader is implemented
|
||||
if (addOneDReader && tryHarder) {
|
||||
readers_.push_back(new zxing::oned::MultiFormatOneDReader(hints));
|
||||
readers_.push_back(Ref<Reader>(new zxing::oned::MultiFormatOneDReader(hints)));
|
||||
}
|
||||
if (readers_.size() == 0) {
|
||||
if (!tryHarder) {
|
||||
readers_.push_back(new zxing::oned::MultiFormatOneDReader(hints));
|
||||
readers_.push_back(Ref<Reader>(new zxing::oned::MultiFormatOneDReader(hints)));
|
||||
}
|
||||
readers_.push_back(new zxing::qrcode::QRCodeReader());
|
||||
readers_.push_back(Ref<Reader>(new zxing::qrcode::QRCodeReader()));
|
||||
if (tryHarder) {
|
||||
readers_.push_back(new zxing::oned::MultiFormatOneDReader(hints));
|
||||
readers_.push_back(Ref<Reader>(new zxing::oned::MultiFormatOneDReader(hints)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,9 +96,7 @@ namespace zxing {
|
|||
throw ReaderException("No code detected");
|
||||
}
|
||||
|
||||
MultiFormatReader::~MultiFormatReader(){
|
||||
for (unsigned int i = 0; i < readers_.size(); i++) {
|
||||
delete readers_[i];
|
||||
}
|
||||
MultiFormatReader::~MultiFormatReader() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace zxing {
|
|||
private:
|
||||
Ref<Result> decodeInternal(Ref<BinaryBitmap> image);
|
||||
|
||||
std::vector<Reader*> readers_;
|
||||
std::vector<Ref<Reader> > readers_;
|
||||
DecodeHints hints_;
|
||||
|
||||
public:
|
||||
|
|
|
@ -55,7 +55,9 @@ Ref<BitArray> GlobalHistogramBinarizer::getBlackRow(int y, Ref<BitArray> row) {
|
|||
}
|
||||
|
||||
//TODO(flyashi): cache this instead of allocating and deleting per row
|
||||
unsigned char* row_pixels = new unsigned char[width];
|
||||
unsigned char* row_pixels = NULL;
|
||||
try {
|
||||
row_pixels = new unsigned char[width];
|
||||
getLuminanceSource()->getRow(y,row_pixels);
|
||||
for (int x = 0; x < width; x++) {
|
||||
histogram[row_pixels[x] >> LUMINANCE_SHIFT]++;
|
||||
|
@ -84,6 +86,10 @@ Ref<BitArray> GlobalHistogramBinarizer::getBlackRow(int y, Ref<BitArray> row) {
|
|||
|
||||
delete [] row_pixels;
|
||||
return array_ref;
|
||||
} catch (IllegalArgumentException const& iae) {
|
||||
delete [] row_pixels;
|
||||
throw iae;
|
||||
}
|
||||
}
|
||||
|
||||
Ref<BitMatrix> GlobalHistogramBinarizer::getBlackMatrix() {
|
||||
|
|
|
@ -75,9 +75,16 @@ namespace oned {
|
|||
}
|
||||
|
||||
|
||||
Code39Reader::Code39Reader(bool usingCheckDigit_, bool extendedMode_) :
|
||||
alphabet_string(ALPHABET_STRING),
|
||||
usingCheckDigit(usingCheckDigit_),
|
||||
extendedMode(extendedMode_) {
|
||||
}
|
||||
|
||||
Ref<Result> Code39Reader::decodeRow(int rowNumber, Ref<BitArray> row){
|
||||
int* start = findAsteriskPattern(row);
|
||||
int* start = NULL;
|
||||
try {
|
||||
start = findAsteriskPattern(row);
|
||||
int nextStart = start[1];
|
||||
int end = row->getSize();
|
||||
|
||||
|
@ -88,23 +95,17 @@ namespace oned {
|
|||
|
||||
std::string tmpResultString;
|
||||
|
||||
int countersLen = 9;
|
||||
int* counters = new int[countersLen];
|
||||
for (int i=0; i<countersLen; i++) {
|
||||
const int countersLen = 9;
|
||||
int counters[countersLen];
|
||||
for (int i = 0; i < countersLen; i++) {
|
||||
counters[i] = 0;
|
||||
}
|
||||
char decodedChar;
|
||||
int lastStart;
|
||||
do {
|
||||
try {
|
||||
recordPattern(row, nextStart, counters, countersLen);
|
||||
} catch (ReaderException re) {
|
||||
delete [] start;
|
||||
throw re;
|
||||
}
|
||||
int pattern = toNarrowWidePattern(counters, countersLen);
|
||||
if (pattern < 0) {
|
||||
delete [] start;
|
||||
throw ReaderException("pattern < 0");
|
||||
}
|
||||
decodedChar = patternToChar(pattern);
|
||||
|
@ -125,14 +126,10 @@ namespace oned {
|
|||
for (int i = 0; i < countersLen; i++) {
|
||||
lastPatternSize += counters[i];
|
||||
}
|
||||
// IS begin
|
||||
delete [] counters;
|
||||
// IS end
|
||||
int whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize;
|
||||
// If 50% of last pattern size, following last pattern, is not whitespace,
|
||||
// fail (but if it's whitespace to the very end of the image, that's OK)
|
||||
if (nextStart != end && whiteSpaceAfterEnd / 2 < lastPatternSize) {
|
||||
delete [] start;
|
||||
throw ReaderException("too short end white space");
|
||||
}
|
||||
|
||||
|
@ -148,17 +145,12 @@ namespace oned {
|
|||
tmpResultString.erase(max, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Ref<String> resultString(new String(tmpResultString));
|
||||
if (extendedMode) {
|
||||
delete resultString;
|
||||
resultString = decodeExtended(tmpResultString);
|
||||
}
|
||||
|
||||
if (tmpResultString.length() == 0) {
|
||||
delete [] start;
|
||||
// Almost surely a false positive
|
||||
throw ReaderException("");
|
||||
}
|
||||
|
@ -176,11 +168,15 @@ namespace oned {
|
|||
|
||||
ArrayRef<unsigned char> resultBytes(1);
|
||||
|
||||
delete [] start;
|
||||
|
||||
Ref<Result> res(new Result(
|
||||
resultString, resultBytes, resultPoints, BarcodeFormat_CODE_39));
|
||||
|
||||
delete [] start;
|
||||
return res;
|
||||
} catch (ReaderException const& re) {
|
||||
delete [] start;
|
||||
throw re;
|
||||
}
|
||||
}
|
||||
|
||||
int* Code39Reader::findAsteriskPattern(Ref<BitArray> row){
|
||||
|
@ -194,9 +190,9 @@ namespace oned {
|
|||
}
|
||||
|
||||
int counterPosition = 0;
|
||||
int countersLen = 9;
|
||||
int* counters = new int[countersLen];
|
||||
for (int i=0; i<countersLen; i++) {
|
||||
const int countersLen = 9;
|
||||
int counters[countersLen];
|
||||
for (int i = 0; i < countersLen; i++) {
|
||||
counters[i] = 0;
|
||||
}
|
||||
int patternStart = rowOffset;
|
||||
|
@ -235,9 +231,6 @@ namespace oned {
|
|||
isWhite = !isWhite;
|
||||
}
|
||||
}
|
||||
// IS begin
|
||||
delete [] counters;
|
||||
// IS end
|
||||
throw ReaderException("");
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,9 @@ namespace zxing {
|
|||
|
||||
determineFirstDigit(resultString, lgPatternFound);
|
||||
|
||||
int* middleRange = findGuardPattern(row, rowOffset, true, (int*)getMIDDLE_PATTERN(), getMIDDLE_PATTERN_LEN());
|
||||
int* middleRange = 0;
|
||||
try {
|
||||
middleRange = findGuardPattern(row, rowOffset, true, (int*)getMIDDLE_PATTERN(), getMIDDLE_PATTERN_LEN());
|
||||
rowOffset = middleRange[1];
|
||||
|
||||
for (int x = 0; x < 6 && rowOffset < end; x++) {
|
||||
|
@ -63,7 +65,12 @@ namespace zxing {
|
|||
}
|
||||
}
|
||||
|
||||
delete [] middleRange;
|
||||
return rowOffset;
|
||||
} catch (ReaderException const& re) {
|
||||
delete [] middleRange;
|
||||
throw re;
|
||||
}
|
||||
}
|
||||
|
||||
void EAN13Reader::determineFirstDigit(std::string& resultString, int lgPatternFound){
|
||||
|
|
|
@ -41,7 +41,9 @@ namespace zxing {
|
|||
}
|
||||
}
|
||||
|
||||
int* middleRange = findGuardPattern(row, rowOffset, true, (int*)getMIDDLE_PATTERN(), getMIDDLE_PATTERN_LEN());
|
||||
int* middleRange = 0;
|
||||
try {
|
||||
middleRange = findGuardPattern(row, rowOffset, true, (int*)getMIDDLE_PATTERN(), getMIDDLE_PATTERN_LEN());
|
||||
rowOffset = middleRange[1];
|
||||
|
||||
for (int x = 0; x < 4 && rowOffset < end; x++) {
|
||||
|
@ -52,7 +54,12 @@ namespace zxing {
|
|||
}
|
||||
}
|
||||
|
||||
delete [] middleRange;
|
||||
return rowOffset;
|
||||
} catch (ReaderException const& re) {
|
||||
delete [] middleRange;
|
||||
throw re;
|
||||
}
|
||||
}
|
||||
|
||||
BarcodeFormat EAN8Reader::getBarcodeFormat(){
|
||||
|
|
|
@ -67,24 +67,15 @@ namespace zxing {
|
|||
|
||||
|
||||
Ref<Result> ITFReader::decodeRow(int rowNumber, Ref<BitArray> row){
|
||||
// Find out where the Middle section (payload) starts & ends
|
||||
int* startRange = decodeStart(row);
|
||||
int* endRange;
|
||||
int* startRange = 0;
|
||||
int* endRange = 0;
|
||||
try {
|
||||
// Find out where the Middle section (payload) starts & ends
|
||||
startRange = decodeStart(row);
|
||||
endRange = decodeEnd(row);
|
||||
} catch (ReaderException re) {
|
||||
delete [] startRange;
|
||||
throw re;
|
||||
}
|
||||
|
||||
std::string tmpResult;
|
||||
try {
|
||||
decodeMiddle(row, startRange[1], endRange[0], tmpResult);
|
||||
} catch (zxing::ReaderException re) {
|
||||
delete [] startRange;
|
||||
delete [] endRange;
|
||||
throw re;
|
||||
}
|
||||
|
||||
// To avoid false positives with 2D barcodes (and other patterns), make
|
||||
// an assumption that the decoded string must be 6, 10 or 14 digits.
|
||||
|
@ -94,8 +85,6 @@ namespace zxing {
|
|||
lengthOK = true;
|
||||
}
|
||||
if (!lengthOK) {
|
||||
delete [] startRange;
|
||||
delete [] endRange;
|
||||
throw ReaderException("not enough characters count");
|
||||
}
|
||||
|
||||
|
@ -109,11 +98,15 @@ namespace zxing {
|
|||
|
||||
ArrayRef<unsigned char> resultBytes(1);
|
||||
|
||||
Ref<Result> res(new Result(resultString, resultBytes, resultPoints, BarcodeFormat_ITF));
|
||||
delete [] startRange;
|
||||
delete [] endRange;
|
||||
|
||||
Ref<Result> res(new Result(resultString, resultBytes, resultPoints, BarcodeFormat_ITF));
|
||||
return res;
|
||||
} catch (ReaderException re) {
|
||||
delete [] startRange;
|
||||
delete [] endRange;
|
||||
throw re;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -173,7 +166,9 @@ namespace zxing {
|
|||
int* ITFReader::decodeStart(Ref<BitArray> row){
|
||||
int endStart = skipWhiteSpace(row);
|
||||
/// static int* findGuardPattern(Ref<BitArray> row, int rowOffset, bool whiteFirst, const int pattern[], int patternLen);
|
||||
int* startPattern = findGuardPattern(row, endStart, START_PATTERN, START_PATTERN_LEN);
|
||||
int* startPattern = 0;
|
||||
try {
|
||||
startPattern = findGuardPattern(row, endStart, START_PATTERN, START_PATTERN_LEN);
|
||||
|
||||
// Determine the width of a narrow line in pixels. We can do this by
|
||||
// getting the width of the start pattern and dividing by 4 because its
|
||||
|
@ -183,6 +178,10 @@ namespace zxing {
|
|||
validateQuietZone(row, startPattern[0]);
|
||||
|
||||
return startPattern;
|
||||
} catch (ReaderException re) {
|
||||
delete [] startPattern;
|
||||
throw re;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -198,9 +197,10 @@ namespace zxing {
|
|||
// For convenience, reverse the row and then
|
||||
// search from 'the start' for the end block
|
||||
row->reverse();
|
||||
int* endPattern = 0;
|
||||
try {
|
||||
int endStart = skipWhiteSpace(row);
|
||||
int* endPattern = findGuardPattern(row, endStart, END_PATTERN_REVERSED, END_PATTERN_REVERSED_LEN);
|
||||
endPattern = findGuardPattern(row, endStart, END_PATTERN_REVERSED, END_PATTERN_REVERSED_LEN);
|
||||
|
||||
// The start & end patterns must be pre/post fixed by a quiet zone. This
|
||||
// zone must be at least 10 times the width of a narrow line.
|
||||
|
@ -217,6 +217,7 @@ namespace zxing {
|
|||
row->reverse();
|
||||
return endPattern;
|
||||
} catch (ReaderException re) {
|
||||
delete [] endPattern;
|
||||
row->reverse();
|
||||
throw re;
|
||||
}
|
||||
|
|
|
@ -93,25 +93,28 @@ namespace zxing {
|
|||
}
|
||||
|
||||
|
||||
Ref<Result> UPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row){
|
||||
return decodeRow(rowNumber, row, findStartGuardPattern(row));
|
||||
Ref<Result> UPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row) {
|
||||
int* start = NULL;
|
||||
try {
|
||||
start = findStartGuardPattern(row);
|
||||
Ref<Result> result = decodeRow(rowNumber, row, start);
|
||||
delete [] start;
|
||||
return result;
|
||||
} catch (ReaderException const& re) {
|
||||
delete [] start;
|
||||
throw re;
|
||||
}
|
||||
}
|
||||
Ref<Result> UPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row, int startGuardRange[]){
|
||||
|
||||
Ref<Result> UPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row, int startGuardRange[]){
|
||||
int* endRange = NULL;
|
||||
try {
|
||||
std::string tmpResultString;
|
||||
std::string& tmpResultStringRef = tmpResultString;
|
||||
int endStart;
|
||||
try {
|
||||
endStart = decodeMiddle(row, startGuardRange, 2 /*reference findGuardPattern*/ , tmpResultStringRef);
|
||||
} catch (ReaderException re) {
|
||||
if (startGuardRange!=NULL) {
|
||||
delete [] startGuardRange;
|
||||
startGuardRange = NULL;
|
||||
}
|
||||
throw re;
|
||||
}
|
||||
|
||||
int* endRange = decodeEnd(row, endStart);
|
||||
endRange = decodeEnd(row, endStart);
|
||||
|
||||
// Make sure there is a quiet zone at least as big as the end pattern after the barcode. The
|
||||
// spec might want more whitespace, but in practice this is the maximum we can count on.
|
||||
|
@ -122,14 +125,6 @@ namespace zxing {
|
|||
}
|
||||
|
||||
if (!checkChecksum(tmpResultString)) {
|
||||
if (startGuardRange!=NULL) {
|
||||
delete [] startGuardRange;
|
||||
startGuardRange = NULL;
|
||||
}
|
||||
if (endRange!=NULL) {
|
||||
delete [] endRange;
|
||||
endRange = NULL;
|
||||
}
|
||||
throw ReaderException("Checksum fail.");
|
||||
}
|
||||
|
||||
|
@ -146,17 +141,14 @@ namespace zxing {
|
|||
|
||||
ArrayRef<unsigned char> resultBytes(1);
|
||||
|
||||
if (startGuardRange!=NULL) {
|
||||
delete [] startGuardRange;
|
||||
startGuardRange = NULL;
|
||||
}
|
||||
if (endRange!=NULL) {
|
||||
Ref<Result> res(new Result(resultString, resultBytes, resultPoints, getBarcodeFormat()));
|
||||
delete [] endRange;
|
||||
endRange = NULL;
|
||||
return res;
|
||||
} catch (ReaderException const& re) {
|
||||
delete [] endRange;
|
||||
throw re;
|
||||
}
|
||||
|
||||
Ref<Result> res(new Result(resultString, resultBytes, resultPoints, getBarcodeFormat()));
|
||||
return res;
|
||||
}
|
||||
|
||||
int* UPCEANReader::findStartGuardPattern(Ref<BitArray> row){
|
||||
|
@ -164,7 +156,10 @@ namespace zxing {
|
|||
|
||||
int* startRange = NULL;
|
||||
int nextStart = 0;
|
||||
try {
|
||||
while (!foundStart) {
|
||||
delete [] startRange;
|
||||
startRange = NULL;
|
||||
startRange = findGuardPattern(row, nextStart, false, START_END_PATTERN, sizeof(START_END_PATTERN)/sizeof(int));
|
||||
int start = startRange[0];
|
||||
nextStart = startRange[1];
|
||||
|
@ -175,20 +170,21 @@ namespace zxing {
|
|||
if (quietStart >= 0) {
|
||||
foundStart = row->isRange(quietStart, start, false);
|
||||
}
|
||||
if (!foundStart) {
|
||||
delete [] startRange;
|
||||
}
|
||||
}
|
||||
return startRange;
|
||||
} catch (ReaderException const& re) {
|
||||
delete [] startRange;
|
||||
throw re;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(flyashi): Return a pair<int, int> for return value to avoid using the heap.
|
||||
int* UPCEANReader::findGuardPattern(Ref<BitArray> row, int rowOffset, bool whiteFirst, const int pattern[], int patternLen){
|
||||
int patternLength = patternLen;
|
||||
|
||||
int counters[patternLength];
|
||||
int countersCount = sizeof(counters)/sizeof(int);
|
||||
for (int i=0; i<countersCount ; i++) {
|
||||
counters[i]=0;
|
||||
int countersCount = sizeof(counters) / sizeof(int);
|
||||
for (int i = 0; i < countersCount; i++) {
|
||||
counters[i] = 0;
|
||||
}
|
||||
int width = row->getSize();
|
||||
bool isWhite = false;
|
||||
|
|
Loading…
Reference in a new issue