mirror of
https://github.com/zxing/zxing.git
synced 2025-02-02 05:41:08 -08:00
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:
parent
8388c71213
commit
e5d060bfe7
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue