Memory leak in MultiFormatReader fixed and a better fix for the memory leak in MonochromeRectangleDetector

git-svn-id: https://zxing.googlecode.com/svn/trunk@1355 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
luizcroc 2010-05-12 22:11:18 +00:00
parent d5cd0e1901
commit 9f9096b98e
4 changed files with 46 additions and 44 deletions

View file

@ -19,7 +19,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include "MultiFormatReader.h" #include <zxing/MultiFormatReader.h>
#include <zxing/qrcode/QRCodeReader.h> #include <zxing/qrcode/QRCodeReader.h>
#include <zxing/datamatrix/DataMatrixReader.h> #include <zxing/datamatrix/DataMatrixReader.h>
#include <zxing/oned/MultiFormatUPCEANReader.h> #include <zxing/oned/MultiFormatUPCEANReader.h>
@ -27,23 +27,27 @@
#include <zxing/ReaderException.h> #include <zxing/ReaderException.h>
namespace zxing { namespace zxing {
MultiFormatReader::MultiFormatReader() : readers() { MultiFormatReader::MultiFormatReader() {
readers.push_back(Ref<Reader>(new zxing::qrcode::QRCodeReader())); readers.push_back(new zxing::qrcode::QRCodeReader());
readers.push_back(Ref<Reader>(new zxing::datamatrix::DataMatrixReader())); readers.push_back(new zxing::datamatrix::DataMatrixReader());
readers.push_back(Ref<Reader>(new zxing::oned::MultiFormatUPCEANReader())); readers.push_back(new zxing::oned::MultiFormatUPCEANReader());
readers.push_back(Ref<Reader>(new zxing::oned::MultiFormatOneDReader())); readers.push_back(new zxing::oned::MultiFormatOneDReader());
} }
Ref<Result> MultiFormatReader::decode(Ref<BinaryBitmap> image){ Ref<Result> MultiFormatReader::decode(Ref<BinaryBitmap> image){
int size = readers.size(); for (unsigned int i = 0; i < readers.size(); i++) {
for (int i = 0; i < size; i++) {
Ref<Reader> reader = readers[i];
try { try {
return reader->decode(image); return reader[i]->decode(image);
} catch (ReaderException re) { } catch (ReaderException re) {
// continue // continue
} }
} }
throw ReaderException("No code detected"); throw ReaderException("No code detected");
} }
}
MultiFormatReader::~MultiFormatReader(){
for (unsigned int i = 0; i < readers.size(); i++) {
delete readers[i];
}
}
}

View file

@ -3,6 +3,7 @@
* ZXing * ZXing
* *
* Created by Lukasz Warchol on 10-01-26. * Created by Lukasz Warchol on 10-01-26.
* Modified by Luiz Silva on 09/02/2010.
* Copyright 2010 ZXing authors All rights reserved. * Copyright 2010 ZXing authors All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -27,11 +28,12 @@ namespace zxing {
class MultiFormatReader : public Reader { class MultiFormatReader : public Reader {
private: private:
std::vector<Ref<Reader> >readers; std::vector<Reader*>readers;
public: public:
MultiFormatReader(); MultiFormatReader();
Ref<Result> decode(Ref<BinaryBitmap> image); Ref<Result> decode(Ref<BinaryBitmap> image);
~MultiFormatReader();
}; };
} }

View file

@ -53,9 +53,10 @@ std::vector<Ref<CornerPoint> > MonochromeRectangleDetector::detect() {
// Go try to find point A again with better information -- might have been off at first. // Go try to find point A again with better information -- might have been off at first.
pointA.reset(findCornerFromCenter(halfWidth, 0, left, right, pointA.reset(findCornerFromCenter(halfWidth, 0, left, right,
halfHeight, -deltaY, top, bottom, halfWidth >> 2)); halfHeight, -deltaY, top, bottom, halfWidth >> 2));
std::vector<Ref<CornerPoint> > corners(4); std::vector<Ref<CornerPoint> > corners(4);
corners[0].reset(pointA);
corners[1].reset(pointB); corners[0].reset(pointA);
corners[1].reset(pointB);
corners[2].reset(pointC); corners[2].reset(pointC);
corners[3].reset(pointD); corners[3].reset(pointD);
return corners; return corners;
@ -63,11 +64,11 @@ std::vector<Ref<CornerPoint> > MonochromeRectangleDetector::detect() {
Ref<CornerPoint> MonochromeRectangleDetector::findCornerFromCenter(int centerX, int deltaX, int left, int right, Ref<CornerPoint> MonochromeRectangleDetector::findCornerFromCenter(int centerX, int deltaX, int left, int right,
int centerY, int deltaY, int top, int bottom, int maxWhiteRun) { int centerY, int deltaY, int top, int bottom, int maxWhiteRun) {
int* lastRange = NULL; Ref<TwoInts> lastRange(NULL);
for (int y = centerY, x = centerX; for (int y = centerY, x = centerX;
y < bottom && y >= top && x < right && x >= left; y < bottom && y >= top && x < right && x >= left;
y += deltaY, x += deltaX) { y += deltaY, x += deltaX) {
int* range; Ref<TwoInts> range(NULL);
if (deltaX == 0) { if (deltaX == 0) {
// horizontal slices, up and down // horizontal slices, up and down
range = blackWhiteRange(y, maxWhiteRun, left, right, true); range = blackWhiteRange(y, maxWhiteRun, left, right, true);
@ -82,48 +83,40 @@ Ref<CornerPoint> MonochromeRectangleDetector::findCornerFromCenter(int centerX,
// lastRange was found // lastRange was found
if (deltaX == 0) { if (deltaX == 0) {
int lastY = y - deltaY; int lastY = y - deltaY;
if (lastRange[0] < centerX) { if (lastRange->start < centerX) {
if (lastRange[1] > centerX) { if (lastRange->end > centerX) {
// straddle, choose one or the other based on direction // straddle, choose one or the other based on direction
Ref<CornerPoint> result(new CornerPoint(deltaY > 0 ? lastRange[0] : lastRange[1], lastY)); Ref<CornerPoint> result(new CornerPoint(deltaY > 0 ? lastRange->start : lastRange->end, lastY));
delete [] lastRange;
return result; return result;
} }
Ref<CornerPoint> result(new CornerPoint(lastRange[0], lastY)); Ref<CornerPoint> result(new CornerPoint(lastRange->start, lastY));
delete [] lastRange;
return result; return result;
} else { } else {
Ref<CornerPoint> result(new CornerPoint(lastRange[1], lastY)); Ref<CornerPoint> result(new CornerPoint(lastRange->end, lastY));
delete [] lastRange;
return result; return result;
} }
} else { } else {
int lastX = x - deltaX; int lastX = x - deltaX;
if (lastRange[0] < centerY) { if (lastRange->start < centerY) {
if (lastRange[1] > centerY) { if (lastRange->end > centerY) {
Ref<CornerPoint> result(new CornerPoint(lastX, deltaX < 0 ? lastRange[0] : lastRange[1])); Ref<CornerPoint> result(new CornerPoint(lastX, deltaX < 0 ? lastRange->start : lastRange->end));
delete [] lastRange;
return result; return result;
} }
Ref<CornerPoint> result(new CornerPoint(lastX, lastRange[0])); Ref<CornerPoint> result(new CornerPoint(lastX, lastRange->start));
delete [] lastRange;
return result; return result;
} else { } else {
Ref<CornerPoint> result(new CornerPoint(lastX, lastRange[1])); Ref<CornerPoint> result(new CornerPoint(lastX, lastRange->end));
delete [] lastRange;
return result; return result;
} }
} }
} }
} }
delete [] lastRange;
lastRange = range; lastRange = range;
} }
delete [] lastRange;
throw ReaderException("Couldn't find corners"); throw ReaderException("Couldn't find corners");
} }
int* MonochromeRectangleDetector::blackWhiteRange(int fixedDimension, int maxWhiteRun, int minDim, int maxDim, Ref<TwoInts> MonochromeRectangleDetector::blackWhiteRange(int fixedDimension, int maxWhiteRun, int minDim, int maxDim,
bool horizontal) { bool horizontal) {
int center = (minDim + maxDim) >> 1; int center = (minDim + maxDim) >> 1;
@ -167,15 +160,13 @@ int* MonochromeRectangleDetector::blackWhiteRange(int fixedDimension, int maxWhi
} }
} }
end--; end--;
int* result; Ref<TwoInts> result(NULL);
if (end > start) { if (end > start) {
result = new int [2]; result = new TwoInts;
result[0] = start; result->start = start;
result[1] = end; result->end = end;
} }
else return result;
result = NULL;
return result;
} }
} }
} }

View file

@ -31,6 +31,11 @@
namespace zxing { namespace zxing {
namespace datamatrix { namespace datamatrix {
struct TwoInts: public Counted {
int start;
int end;
};
class MonochromeRectangleDetector : public Counted { class MonochromeRectangleDetector : public Counted {
private: private:
static const int MAX_MODULES = 32; static const int MAX_MODULES = 32;
@ -45,7 +50,7 @@ private:
Ref<CornerPoint> findCornerFromCenter(int centerX, int deltaX, int left, int right, Ref<CornerPoint> findCornerFromCenter(int centerX, int deltaX, int left, int right,
int centerY, int deltaY, int top, int bottom, int maxWhiteRun); int centerY, int deltaY, int top, int bottom, int maxWhiteRun);
int* blackWhiteRange(int fixedDimension, int maxWhiteRun, int minDim, int maxDim, Ref<TwoInts> blackWhiteRange(int fixedDimension, int maxWhiteRun, int minDim, int maxDim,
bool horizontal); bool horizontal);
int max(int a, float b) { return (float) a > b ? a : (int) b;}; int max(int a, float b) { return (float) a > b ? a : (int) b;};