Avoid stack overflow in some odd case in multiple barcode detection, and don't use multiple threads for one image on the command line

git-svn-id: https://zxing.googlecode.com/svn/trunk@2585 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen@gmail.com 2013-03-05 18:07:45 +00:00
parent 8388c71213
commit e5d060bfe7
2 changed files with 34 additions and 17 deletions

View file

@ -45,6 +45,7 @@ import java.util.Map;
public final class GenericMultipleBarcodeReader implements MultipleBarcodeReader { public final class GenericMultipleBarcodeReader implements MultipleBarcodeReader {
private static final int MIN_DIMENSION_TO_RECUR = 100; private static final int MIN_DIMENSION_TO_RECUR = 100;
private static final int MAX_DEPTH = 4;
private final Reader delegate; private final Reader delegate;
@ -61,7 +62,7 @@ public final class GenericMultipleBarcodeReader implements MultipleBarcodeReader
public Result[] decodeMultiple(BinaryBitmap image, Map<DecodeHintType,?> hints) public Result[] decodeMultiple(BinaryBitmap image, Map<DecodeHintType,?> hints)
throws NotFoundException { throws NotFoundException {
List<Result> results = new ArrayList<Result>(); List<Result> results = new ArrayList<Result>();
doDecodeMultiple(image, hints, results, 0, 0); doDecodeMultiple(image, hints, results, 0, 0, 0);
if (results.isEmpty()) { if (results.isEmpty()) {
throw NotFoundException.getNotFoundInstance(); throw NotFoundException.getNotFoundInstance();
} }
@ -72,7 +73,12 @@ public final class GenericMultipleBarcodeReader implements MultipleBarcodeReader
Map<DecodeHintType,?> hints, Map<DecodeHintType,?> hints,
List<Result> results, List<Result> results,
int xOffset, int xOffset,
int yOffset) { int yOffset,
int currentDepth) {
if (currentDepth > MAX_DEPTH) {
return;
}
Result result; Result result;
try { try {
result = delegate.decode(image, hints); result = delegate.decode(image, hints);
@ -119,22 +125,30 @@ public final class GenericMultipleBarcodeReader implements MultipleBarcodeReader
// Decode left of barcode // Decode left of barcode
if (minX > MIN_DIMENSION_TO_RECUR) { if (minX > MIN_DIMENSION_TO_RECUR) {
doDecodeMultiple(image.crop(0, 0, (int) minX, height), doDecodeMultiple(image.crop(0, 0, (int) minX, height),
hints, results, xOffset, yOffset); hints, results,
xOffset, yOffset,
currentDepth + 1);
} }
// Decode above barcode // Decode above barcode
if (minY > MIN_DIMENSION_TO_RECUR) { if (minY > MIN_DIMENSION_TO_RECUR) {
doDecodeMultiple(image.crop(0, 0, width, (int) minY), doDecodeMultiple(image.crop(0, 0, width, (int) minY),
hints, results, xOffset, yOffset); hints, results,
xOffset, yOffset,
currentDepth + 1);
} }
// Decode right of barcode // Decode right of barcode
if (maxX < width - MIN_DIMENSION_TO_RECUR) { if (maxX < width - MIN_DIMENSION_TO_RECUR) {
doDecodeMultiple(image.crop((int) maxX, 0, width - (int) maxX, height), doDecodeMultiple(image.crop((int) maxX, 0, width - (int) maxX, height),
hints, results, xOffset + (int) maxX, yOffset); hints, results,
xOffset + (int) maxX, yOffset,
currentDepth + 1);
} }
// Decode below barcode // Decode below barcode
if (maxY < height - MIN_DIMENSION_TO_RECUR) { if (maxY < height - MIN_DIMENSION_TO_RECUR) {
doDecodeMultiple(image.crop(0, (int) maxY, width, height - (int) maxY), doDecodeMultiple(image.crop(0, (int) maxY, width, height - (int) maxY),
hints, results, xOffset, yOffset + (int) maxY); hints, results,
xOffset, yOffset + (int) maxY,
currentDepth + 1);
} }
} }

View file

@ -95,18 +95,21 @@ public final class CommandLineRunner {
} }
} }
int numThreads = Runtime.getRuntime().availableProcessors(); int numThreads = Math.min(inputs.size(), Runtime.getRuntime().availableProcessors());
int successful = 0;
if (numThreads > 1) {
ExecutorService executor = Executors.newFixedThreadPool(numThreads); ExecutorService executor = Executors.newFixedThreadPool(numThreads);
Collection<Future<Integer>> futures = new ArrayList<Future<Integer>>(numThreads); Collection<Future<Integer>> futures = new ArrayList<Future<Integer>>(numThreads);
for (int x = 0; x < numThreads; x++) { for (int x = 0; x < numThreads; x++) {
futures.add(executor.submit(new DecodeWorker(config, inputs))); futures.add(executor.submit(new DecodeWorker(config, inputs)));
} }
executor.shutdown(); executor.shutdown();
int successful = 0;
for (Future<Integer> future : futures) { for (Future<Integer> future : futures) {
successful += future.get(); successful += future.get();
} }
} else {
successful += new DecodeWorker(config, inputs).call();
}
int total = inputs.size(); int total = inputs.size();
if (total > 1) { if (total > 1) {