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 {
private static final int MIN_DIMENSION_TO_RECUR = 100;
private static final int MAX_DEPTH = 4;
private final Reader delegate;
@ -61,7 +62,7 @@ public final class GenericMultipleBarcodeReader implements MultipleBarcodeReader
public Result[] decodeMultiple(BinaryBitmap image, Map<DecodeHintType,?> hints)
throws NotFoundException {
List<Result> results = new ArrayList<Result>();
doDecodeMultiple(image, hints, results, 0, 0);
doDecodeMultiple(image, hints, results, 0, 0, 0);
if (results.isEmpty()) {
throw NotFoundException.getNotFoundInstance();
}
@ -72,7 +73,12 @@ public final class GenericMultipleBarcodeReader implements MultipleBarcodeReader
Map<DecodeHintType,?> hints,
List<Result> results,
int xOffset,
int yOffset) {
int yOffset,
int currentDepth) {
if (currentDepth > MAX_DEPTH) {
return;
}
Result result;
try {
result = delegate.decode(image, hints);
@ -119,22 +125,30 @@ public final class GenericMultipleBarcodeReader implements MultipleBarcodeReader
// Decode left of barcode
if (minX > MIN_DIMENSION_TO_RECUR) {
doDecodeMultiple(image.crop(0, 0, (int) minX, height),
hints, results, xOffset, yOffset);
hints, results,
xOffset, yOffset,
currentDepth + 1);
}
// Decode above barcode
if (minY > MIN_DIMENSION_TO_RECUR) {
doDecodeMultiple(image.crop(0, 0, width, (int) minY),
hints, results, xOffset, yOffset);
hints, results,
xOffset, yOffset,
currentDepth + 1);
}
// Decode right of barcode
if (maxX < width - MIN_DIMENSION_TO_RECUR) {
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
if (maxY < height - MIN_DIMENSION_TO_RECUR) {
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,17 +95,20 @@ public final class CommandLineRunner {
}
}
int numThreads = Runtime.getRuntime().availableProcessors();
ExecutorService executor = Executors.newFixedThreadPool(numThreads);
Collection<Future<Integer>> futures = new ArrayList<Future<Integer>>(numThreads);
for (int x = 0; x < numThreads; x++) {
futures.add(executor.submit(new DecodeWorker(config, inputs)));
}
executor.shutdown();
int successful = 0;
for (Future<Integer> future : futures) {
successful += future.get();
int numThreads = Math.min(inputs.size(), Runtime.getRuntime().availableProcessors());
int successful = 0;
if (numThreads > 1) {
ExecutorService executor = Executors.newFixedThreadPool(numThreads);
Collection<Future<Integer>> futures = new ArrayList<Future<Integer>>(numThreads);
for (int x = 0; x < numThreads; x++) {
futures.add(executor.submit(new DecodeWorker(config, inputs)));
}
executor.shutdown();
for (Future<Integer> future : futures) {
successful += future.get();
}
} else {
successful += new DecodeWorker(config, inputs).call();
}
int total = inputs.size();