From e5d060bfe749a9bbafe3b773a3091b4eb381b076 Mon Sep 17 00:00:00 2001 From: "srowen@gmail.com" Date: Tue, 5 Mar 2013 18:07:45 +0000 Subject: [PATCH] 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 --- .../multi/GenericMultipleBarcodeReader.java | 26 ++++++++++++++----- .../zxing/client/j2se/CommandLineRunner.java | 25 ++++++++++-------- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/core/src/com/google/zxing/multi/GenericMultipleBarcodeReader.java b/core/src/com/google/zxing/multi/GenericMultipleBarcodeReader.java index 7a32b5ec2..6a94623b3 100644 --- a/core/src/com/google/zxing/multi/GenericMultipleBarcodeReader.java +++ b/core/src/com/google/zxing/multi/GenericMultipleBarcodeReader.java @@ -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 hints) throws NotFoundException { List results = new ArrayList(); - 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 hints, List 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); } } diff --git a/javase/src/com/google/zxing/client/j2se/CommandLineRunner.java b/javase/src/com/google/zxing/client/j2se/CommandLineRunner.java index e265bbca8..9ac15a7f0 100644 --- a/javase/src/com/google/zxing/client/j2se/CommandLineRunner.java +++ b/javase/src/com/google/zxing/client/j2se/CommandLineRunner.java @@ -95,17 +95,20 @@ public final class CommandLineRunner { } } - int numThreads = Runtime.getRuntime().availableProcessors(); - ExecutorService executor = Executors.newFixedThreadPool(numThreads); - Collection> futures = new ArrayList>(numThreads); - for (int x = 0; x < numThreads; x++) { - futures.add(executor.submit(new DecodeWorker(config, inputs))); - } - executor.shutdown(); - - int successful = 0; - for (Future 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> futures = new ArrayList>(numThreads); + for (int x = 0; x < numThreads; x++) { + futures.add(executor.submit(new DecodeWorker(config, inputs))); + } + executor.shutdown(); + for (Future future : futures) { + successful += future.get(); + } + } else { + successful += new DecodeWorker(config, inputs).call(); } int total = inputs.size();