Add 'getNumBits' to Result objects to return when not all bits of the raw byte representation are valid (#664)

This commit is contained in:
Sean Owen 2016-09-09 18:44:09 +01:00 committed by GitHub
parent 5848aab09c
commit 75d6000c1d
6 changed files with 114 additions and 4 deletions

View file

@ -28,6 +28,7 @@ public final class Result {
private final String text; private final String text;
private final byte[] rawBytes; private final byte[] rawBytes;
private final int numBits;
private ResultPoint[] resultPoints; private ResultPoint[] resultPoints;
private final BarcodeFormat format; private final BarcodeFormat format;
private Map<ResultMetadataType,Object> resultMetadata; private Map<ResultMetadataType,Object> resultMetadata;
@ -45,8 +46,19 @@ public final class Result {
ResultPoint[] resultPoints, ResultPoint[] resultPoints,
BarcodeFormat format, BarcodeFormat format,
long timestamp) { long timestamp) {
this(text, rawBytes, rawBytes == null ? 0 : 8 * rawBytes.length,
resultPoints, format, timestamp);
}
public Result(String text,
byte[] rawBytes,
int numBits,
ResultPoint[] resultPoints,
BarcodeFormat format,
long timestamp) {
this.text = text; this.text = text;
this.rawBytes = rawBytes; this.rawBytes = rawBytes;
this.numBits = numBits;
this.resultPoints = resultPoints; this.resultPoints = resultPoints;
this.format = format; this.format = format;
this.resultMetadata = null; this.resultMetadata = null;
@ -67,6 +79,14 @@ public final class Result {
return rawBytes; return rawBytes;
} }
/**
* @return how many bits of {@link #getRawBytes()} are valid; typically 8 times its length
* @since 3.3.0
*/
public int getNumBits() {
return numBits;
}
/** /**
* @return points related to the barcode in the image. These are typically points * @return points related to the barcode in the image. These are typically points
* identifying finder patterns or the corners of the barcode. The exact meaning is * identifying finder patterns or the corners of the barcode. The exact meaning is

View file

@ -95,7 +95,12 @@ public final class AztecReader implements Reader {
} }
} }
Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.AZTEC); Result result = new Result(decoderResult.getText(),
decoderResult.getRawBytes(),
decoderResult.getNumBits(),
points,
BarcodeFormat.AZTEC,
System.currentTimeMillis());
List<byte[]> byteSegments = decoderResult.getByteSegments(); List<byte[]> byteSegments = decoderResult.getByteSegments();
if (byteSegments != null) { if (byteSegments != null) {

View file

@ -77,7 +77,9 @@ public final class Decoder {
boolean[] correctedBits = correctBits(rawbits); boolean[] correctedBits = correctBits(rawbits);
byte[] rawBytes = convertBoolArrayToByteArray(correctedBits); byte[] rawBytes = convertBoolArrayToByteArray(correctedBits);
String result = getEncodedData(correctedBits); String result = getEncodedData(correctedBits);
return new DecoderResult(rawBytes, result, null, null); DecoderResult decoderResult = new DecoderResult(rawBytes, result, null, null);
decoderResult.setNumBits(correctedBits.length);
return decoderResult;
} }
// This method is used for testing the high-level encoder // This method is used for testing the high-level encoder

View file

@ -28,6 +28,7 @@ import java.util.List;
public final class DecoderResult { public final class DecoderResult {
private final byte[] rawBytes; private final byte[] rawBytes;
private int numBits;
private final String text; private final String text;
private final List<byte[]> byteSegments; private final List<byte[]> byteSegments;
private final String ecLevel; private final String ecLevel;
@ -51,6 +52,7 @@ public final class DecoderResult {
int saSequence, int saSequence,
int saParity) { int saParity) {
this.rawBytes = rawBytes; this.rawBytes = rawBytes;
this.numBits = rawBytes == null ? 0 : 8 * rawBytes.length;
this.text = text; this.text = text;
this.byteSegments = byteSegments; this.byteSegments = byteSegments;
this.ecLevel = ecLevel; this.ecLevel = ecLevel;
@ -58,22 +60,53 @@ public final class DecoderResult {
this.structuredAppendSequenceNumber = saSequence; this.structuredAppendSequenceNumber = saSequence;
} }
/**
* @return raw bytes representing the result, or {@code null} if not applicable
*/
public byte[] getRawBytes() { public byte[] getRawBytes() {
return rawBytes; return rawBytes;
} }
/**
* @return how many bits of {@link #getRawBytes()} are valid; typically 8 times its length
* @since 3.3.0
*/
public int getNumBits() {
return numBits;
}
/**
* @param numBits overrides the number of bits that are valid in {@link #getRawBytes()}
* @since 3.3.0
*/
public void setNumBits(int numBits) {
this.numBits = numBits;
}
/**
* @return text representation of the result
*/
public String getText() { public String getText() {
return text; return text;
} }
/**
* @return list of byte segments in the result, or {@code null} if not applicable
*/
public List<byte[]> getByteSegments() { public List<byte[]> getByteSegments() {
return byteSegments; return byteSegments;
} }
/**
* @return name of error correction level used, or {@code null} if not applicable
*/
public String getECLevel() { public String getECLevel() {
return ecLevel; return ecLevel;
} }
/**
* @return number of errors corrected, or {@code null} if not applicable
*/
public Integer getErrorsCorrected() { public Integer getErrorsCorrected() {
return errorsCorrected; return errorsCorrected;
} }
@ -82,6 +115,9 @@ public final class DecoderResult {
this.errorsCorrected = errorsCorrected; this.errorsCorrected = errorsCorrected;
} }
/**
* @return number of erasures corrected, or {@code null} if not applicable
*/
public Integer getErasures() { public Integer getErasures() {
return erasures; return erasures;
} }
@ -89,7 +125,10 @@ public final class DecoderResult {
public void setErasures(Integer erasures) { public void setErasures(Integer erasures) {
this.erasures = erasures; this.erasures = erasures;
} }
/**
* @return arbitrary additional metadata
*/
public Object getOther() { public Object getOther() {
return other; return other;
} }

View file

@ -167,7 +167,12 @@ public final class GenericMultipleBarcodeReader implements MultipleBarcodeReader
newResultPoints[i] = new ResultPoint(oldPoint.getX() + xOffset, oldPoint.getY() + yOffset); newResultPoints[i] = new ResultPoint(oldPoint.getX() + xOffset, oldPoint.getY() + yOffset);
} }
} }
Result newResult = new Result(result.getText(), result.getRawBytes(), newResultPoints, result.getBarcodeFormat()); Result newResult = new Result(result.getText(),
result.getRawBytes(),
result.getNumBits(),
newResultPoints,
result.getBarcodeFormat(),
result.getTimestamp());
newResult.putAllMetadata(result.getResultMetadata()); newResult.putAllMetadata(result.getResultMetadata());
return newResult; return newResult;
} }

View file

@ -19,12 +19,51 @@ import com.google.zxing.FormatException;
import com.google.zxing.ResultPoint; import com.google.zxing.ResultPoint;
import com.google.zxing.aztec.AztecDetectorResult; import com.google.zxing.aztec.AztecDetectorResult;
import com.google.zxing.common.BitMatrix; import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.DecoderResult;
import org.junit.Test; import org.junit.Test;
import org.junit.Assert; import org.junit.Assert;
public final class DecoderTest extends Assert { public final class DecoderTest extends Assert {
private static final ResultPoint[] NO_POINTS = new ResultPoint[0]; private static final ResultPoint[] NO_POINTS = new ResultPoint[0];
@Test
public void testAztecResult() throws FormatException {
BitMatrix matrix = BitMatrix.parse(
"X X X X X X X X X X X X X X \n" +
"X X X X X X X X X X X X X X X \n" +
" X X X X X X X X X X X X \n" +
" X X X X X X X X X X \n" +
" X X X X X X X X \n" +
" X X X X X X X X X X X X X X X X X X \n" +
" X X X X X X X X X \n" +
" X X X X X X X X X X X X X X X X X \n" +
" X X X X X X X X X \n" +
" X X X X X X X X X X X X X X X X \n" +
" X X X X X X X X X X X X \n" +
" X X X X X X X X X X X \n" +
" X X X X X X X X X X X X \n" +
" X X X X X X X X X X X X X X X X X \n" +
"X X X X X X X X X X X \n" +
" X X X X X X X X X X X X X X \n" +
" X X X X X X X X \n" +
" X X X X X X X X X X X X X X X X X X X \n" +
"X X X X X X X X X \n" +
"X X X X X X X X X X X X X X X \n" +
"X X X X X X X X X X X X \n" +
"X X X X X X X X X X X X X X \n" +
" X X X X X X X X X X X X X \n",
"X ", " ");
AztecDetectorResult r = new AztecDetectorResult(matrix, NO_POINTS, false, 30, 2);
DecoderResult result = new Decoder().decode(r);
assertEquals("88888TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT", result.getText());
assertArrayEquals(
new byte[] {-11, 85, 85, 117, 107, 90, -42, -75, -83, 107,
90, -42, -75, -83, 107, 90, -42, -75, -83, 107,
90, -42, -80},
result.getRawBytes());
assertEquals(180, result.getNumBits());
}
/** /**
* throws * throws