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:
flyashi 2010-08-06 18:59:07 +00:00
parent 2de913d220
commit 5a4f5c901d
8 changed files with 903 additions and 895 deletions

View file

@ -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() {
}
}

View file

@ -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:

View file

@ -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() {

View file

@ -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("");
}

View file

@ -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){

View file

@ -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(){

View file

@ -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;
}

View file

@ -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;