mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
Fixed a few crashes and added a FIXME for another which needs some refactoring.
git-svn-id: https://zxing.googlecode.com/svn/trunk@1814 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
e04e3ef2c1
commit
127839b2b7
|
@ -38,6 +38,7 @@ final class DecodeHandler extends Handler {
|
||||||
|
|
||||||
private final CaptureActivity activity;
|
private final CaptureActivity activity;
|
||||||
private final MultiFormatReader multiFormatReader;
|
private final MultiFormatReader multiFormatReader;
|
||||||
|
private boolean running = true;
|
||||||
|
|
||||||
DecodeHandler(CaptureActivity activity, Hashtable<DecodeHintType, Object> hints) {
|
DecodeHandler(CaptureActivity activity, Hashtable<DecodeHintType, Object> hints) {
|
||||||
multiFormatReader = new MultiFormatReader();
|
multiFormatReader = new MultiFormatReader();
|
||||||
|
@ -47,11 +48,15 @@ final class DecodeHandler extends Handler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message message) {
|
public void handleMessage(Message message) {
|
||||||
|
if (!running) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
switch (message.what) {
|
switch (message.what) {
|
||||||
case R.id.decode:
|
case R.id.decode:
|
||||||
decode((byte[]) message.obj, message.arg1, message.arg2);
|
decode((byte[]) message.obj, message.arg1, message.arg2);
|
||||||
break;
|
break;
|
||||||
case R.id.quit:
|
case R.id.quit:
|
||||||
|
running = false;
|
||||||
Looper.myLooper().quit();
|
Looper.myLooper().quit();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,12 +43,12 @@ final class DecodedBitStreamParser {
|
||||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
|
||||||
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
|
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final char[] C40_SHIFT2_SET_CHARS = {
|
private static final char[] C40_SHIFT2_SET_CHARS = {
|
||||||
'!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.',
|
'!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.',
|
||||||
'/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_'
|
'/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See ISO 16022:2006, Annex C Table C.2
|
* See ISO 16022:2006, Annex C Table C.2
|
||||||
* The Text Basic Character Set (*'s used for placeholders for the shift values)
|
* The Text Basic Character Set (*'s used for placeholders for the shift values)
|
||||||
|
@ -58,12 +58,12 @@ final class DecodedBitStreamParser {
|
||||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
|
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final char[] TEXT_SHIFT3_SET_CHARS = {
|
private static final char[] TEXT_SHIFT3_SET_CHARS = {
|
||||||
'\'', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
|
'\'', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
|
||||||
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '~', (char) 127
|
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '~', (char) 127
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final int PAD_ENCODE = 0; // Not really an encoding
|
private static final int PAD_ENCODE = 0; // Not really an encoding
|
||||||
private static final int ASCII_ENCODE = 1;
|
private static final int ASCII_ENCODE = 1;
|
||||||
private static final int C40_ENCODE = 2;
|
private static final int C40_ENCODE = 2;
|
||||||
|
@ -112,7 +112,7 @@ final class DecodedBitStreamParser {
|
||||||
}
|
}
|
||||||
return new DecoderResult(bytes, result.toString(), byteSegments.isEmpty() ? null : byteSegments, null);
|
return new DecoderResult(bytes, result.toString(), byteSegments.isEmpty() ? null : byteSegments, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See ISO 16022:2006, 5.2.3 and Annex C, Table C.2
|
* See ISO 16022:2006, 5.2.3 and Annex C, Table C.2
|
||||||
*/
|
*/
|
||||||
|
@ -257,7 +257,7 @@ final class DecodedBitStreamParser {
|
||||||
}
|
}
|
||||||
} while (bits.available() > 0);
|
} while (bits.available() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See ISO 16022:2006, 5.2.6 and Annex C, Table C.2
|
* See ISO 16022:2006, 5.2.6 and Annex C, Table C.2
|
||||||
*/
|
*/
|
||||||
|
@ -347,7 +347,7 @@ final class DecodedBitStreamParser {
|
||||||
}
|
}
|
||||||
} while (bits.available() > 0);
|
} while (bits.available() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See ISO 16022:2006, 5.2.7
|
* See ISO 16022:2006, 5.2.7
|
||||||
*/
|
*/
|
||||||
|
@ -398,7 +398,7 @@ final class DecodedBitStreamParser {
|
||||||
result[1] = temp;
|
result[1] = temp;
|
||||||
result[2] = fullBitValue - temp * 40;
|
result[2] = fullBitValue - temp * 40;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See ISO 16022:2006, 5.2.8 and Annex C Table C.3
|
* See ISO 16022:2006, 5.2.8 and Annex C Table C.3
|
||||||
*/
|
*/
|
||||||
|
@ -419,7 +419,7 @@ final class DecodedBitStreamParser {
|
||||||
// If we encounter the unlatch code then continue reading because the Codeword triple
|
// If we encounter the unlatch code then continue reading because the Codeword triple
|
||||||
// is padded with 0's
|
// is padded with 0's
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!unlatch) {
|
if (!unlatch) {
|
||||||
if ((edifactValue & 32) == 0) { // no 1 in the leading (6th) bit
|
if ((edifactValue & 32) == 0) { // no 1 in the leading (6th) bit
|
||||||
edifactValue |= 64; // Add a leading 01 to the 6 bit binary value
|
edifactValue |= 64; // Add a leading 01 to the 6 bit binary value
|
||||||
|
@ -429,7 +429,7 @@ final class DecodedBitStreamParser {
|
||||||
}
|
}
|
||||||
} while (!unlatch && bits.available() > 0);
|
} while (!unlatch && bits.available() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See ISO 16022:2006, 5.2.9 and Annex B, B.2
|
* See ISO 16022:2006, 5.2.9 and Annex B, B.2
|
||||||
*/
|
*/
|
||||||
|
@ -446,6 +446,12 @@ final class DecodedBitStreamParser {
|
||||||
} else {
|
} else {
|
||||||
count = 250 * (d1 - 249) + unrandomize255State(bits.readBits(8), codewordPosition++);
|
count = 250 * (d1 - 249) + unrandomize255State(bits.readBits(8), codewordPosition++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We're seeing NegativeArraySizeException errors from users.
|
||||||
|
if (count < 0) {
|
||||||
|
throw FormatException.getFormatInstance();
|
||||||
|
}
|
||||||
|
|
||||||
byte[] bytes = new byte[count];
|
byte[] bytes = new byte[count];
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
// Have seen this particular error in the wild, such as at
|
// Have seen this particular error in the wild, such as at
|
||||||
|
@ -462,7 +468,7 @@ final class DecodedBitStreamParser {
|
||||||
throw new RuntimeException("Platform does not support required encoding: " + uee);
|
throw new RuntimeException("Platform does not support required encoding: " + uee);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See ISO 16022:2006, Annex B, B.2
|
* See ISO 16022:2006, Annex B, B.2
|
||||||
*/
|
*/
|
||||||
|
@ -472,5 +478,5 @@ final class DecodedBitStreamParser {
|
||||||
int tempVariable = randomizedBase256Codeword - pseudoRandomNumber;
|
int tempVariable = randomizedBase256Codeword - pseudoRandomNumber;
|
||||||
return (byte) (tempVariable >= 0 ? tempVariable : tempVariable + 256);
|
return (byte) (tempVariable >= 0 ? tempVariable : tempVariable + 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,6 +126,11 @@ final class DecodedBitStreamParser {
|
||||||
private static void decodeHanziSegment(BitSource bits,
|
private static void decodeHanziSegment(BitSource bits,
|
||||||
StringBuffer result,
|
StringBuffer result,
|
||||||
int count) throws FormatException {
|
int count) throws FormatException {
|
||||||
|
// Don't crash trying to read more bits than we have available.
|
||||||
|
if (count * 13 > bits.available()) {
|
||||||
|
throw FormatException.getFormatInstance();
|
||||||
|
}
|
||||||
|
|
||||||
// Each character will require 2 bytes. Read the characters as 2-byte pairs
|
// Each character will require 2 bytes. Read the characters as 2-byte pairs
|
||||||
// and decode as GB2312 afterwards
|
// and decode as GB2312 afterwards
|
||||||
byte[] buffer = new byte[2 * count];
|
byte[] buffer = new byte[2 * count];
|
||||||
|
@ -146,7 +151,7 @@ final class DecodedBitStreamParser {
|
||||||
offset += 2;
|
offset += 2;
|
||||||
count--;
|
count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
result.append(new String(buffer, StringUtils.GB2312));
|
result.append(new String(buffer, StringUtils.GB2312));
|
||||||
} catch (UnsupportedEncodingException uee) {
|
} catch (UnsupportedEncodingException uee) {
|
||||||
|
@ -157,6 +162,11 @@ final class DecodedBitStreamParser {
|
||||||
private static void decodeKanjiSegment(BitSource bits,
|
private static void decodeKanjiSegment(BitSource bits,
|
||||||
StringBuffer result,
|
StringBuffer result,
|
||||||
int count) throws FormatException {
|
int count) throws FormatException {
|
||||||
|
// Don't crash trying to read more bits than we have available.
|
||||||
|
if (count * 13 > bits.available()) {
|
||||||
|
throw FormatException.getFormatInstance();
|
||||||
|
}
|
||||||
|
|
||||||
// Each character will require 2 bytes. Read the characters as 2-byte pairs
|
// Each character will require 2 bytes. Read the characters as 2-byte pairs
|
||||||
// and decode as Shift_JIS afterwards
|
// and decode as Shift_JIS afterwards
|
||||||
byte[] buffer = new byte[2 * count];
|
byte[] buffer = new byte[2 * count];
|
||||||
|
@ -191,10 +201,12 @@ final class DecodedBitStreamParser {
|
||||||
CharacterSetECI currentCharacterSetECI,
|
CharacterSetECI currentCharacterSetECI,
|
||||||
Vector byteSegments,
|
Vector byteSegments,
|
||||||
Hashtable hints) throws FormatException {
|
Hashtable hints) throws FormatException {
|
||||||
byte[] readBytes = new byte[count];
|
// Don't crash trying to read more bits than we have available.
|
||||||
if (count << 3 > bits.available()) {
|
if (count << 3 > bits.available()) {
|
||||||
throw FormatException.getFormatInstance();
|
throw FormatException.getFormatInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byte[] readBytes = new byte[count];
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
readBytes[i] = (byte) bits.readBits(8);
|
readBytes[i] = (byte) bits.readBits(8);
|
||||||
}
|
}
|
||||||
|
@ -289,7 +301,7 @@ final class DecodedBitStreamParser {
|
||||||
result.append(toAlphaNumericChar(digitBits));
|
result.append(toAlphaNumericChar(digitBits));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int parseECIValue(BitSource bits) {
|
private static int parseECIValue(BitSource bits) {
|
||||||
int firstByte = bits.readBits(8);
|
int firstByte = bits.readBits(8);
|
||||||
if ((firstByte & 0x80) == 0) {
|
if ((firstByte & 0x80) == 0) {
|
||||||
|
|
|
@ -308,14 +308,19 @@ public class Detector {
|
||||||
int dx = Math.abs(toX - fromX);
|
int dx = Math.abs(toX - fromX);
|
||||||
int dy = Math.abs(toY - fromY);
|
int dy = Math.abs(toY - fromY);
|
||||||
int error = -dx >> 1;
|
int error = -dx >> 1;
|
||||||
int ystep = fromY < toY ? 1 : -1;
|
|
||||||
int xstep = fromX < toX ? 1 : -1;
|
int xstep = fromX < toX ? 1 : -1;
|
||||||
int state = 0; // In black pixels, looking for white, first or second time
|
int ystep = fromY < toY ? 1 : -1;
|
||||||
for (int x = fromX, y = fromY; x != toX; x += xstep) {
|
|
||||||
|
|
||||||
|
// In black pixels, looking for white, first or second time.
|
||||||
|
int state = 0;
|
||||||
|
for (int x = fromX, y = fromY; x != toX; x += xstep) {
|
||||||
int realX = steep ? y : x;
|
int realX = steep ? y : x;
|
||||||
int realY = steep ? x : y;
|
int realY = steep ? x : y;
|
||||||
if (state == 1) { // In white pixels, looking for black
|
|
||||||
|
// In white pixels, looking for black.
|
||||||
|
// FIXME(dswitkin): This method seems to assume square images, which can cause these calls to
|
||||||
|
// BitMatrix.get() to throw ArrayIndexOutOfBoundsException.
|
||||||
|
if (state == 1) {
|
||||||
if (image.get(realX, realY)) {
|
if (image.get(realX, realY)) {
|
||||||
state++;
|
state++;
|
||||||
}
|
}
|
||||||
|
@ -325,7 +330,8 @@ public class Detector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == 3) { // Found black, white, black, and stumbled back onto white; done
|
// Found black, white, black, and stumbled back onto white, so we're done.
|
||||||
|
if (state == 3) {
|
||||||
int diffX = x - fromX;
|
int diffX = x - fromX;
|
||||||
int diffY = y - fromY;
|
int diffY = y - fromY;
|
||||||
if (xstep < 0) {
|
if (xstep < 0) {
|
||||||
|
|
Loading…
Reference in a new issue