"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "core/src/main/java/com/google/zxing/aztec/decoder/Decoder.java" between
zxing-zxing-3.4.1.tar.gz and zxing-zxing-3.5.0.tar.gz

About: ZXing ("zebra crossing") is a multi-format 1D/2D barcode image processing library implemented in Java, with ports to other languages. Info: Project is in maintenance mode (no active development).

Decoder.java  (zxing-zxing-3.4.1):Decoder.java  (zxing-zxing-3.5.0)
skipping to change at line 22 skipping to change at line 22
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.zxing.aztec.decoder; package com.google.zxing.aztec.decoder;
import com.google.zxing.FormatException; import com.google.zxing.FormatException;
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.CharacterSetECI;
import com.google.zxing.common.DecoderResult; import com.google.zxing.common.DecoderResult;
import com.google.zxing.common.reedsolomon.GenericGF; import com.google.zxing.common.reedsolomon.GenericGF;
import com.google.zxing.common.reedsolomon.ReedSolomonDecoder; import com.google.zxing.common.reedsolomon.ReedSolomonDecoder;
import com.google.zxing.common.reedsolomon.ReedSolomonException; import com.google.zxing.common.reedsolomon.ReedSolomonException;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays; import java.util.Arrays;
/** /**
* <p>The main class which implements Aztec Code decoding -- as opposed to locat ing and extracting * <p>The main class which implements Aztec Code decoding -- as opposed to locat ing and extracting
* the Aztec Code from an image.</p> * the Aztec Code from an image.</p>
* *
* @author David Olivier * @author David Olivier
*/ */
public final class Decoder { public final class Decoder {
skipping to change at line 63 skipping to change at line 68
"q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "CTRL_US", "CTRL_ML", "C TRL_DL", "CTRL_BS" "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "CTRL_US", "CTRL_ML", "C TRL_DL", "CTRL_BS"
}; };
private static final String[] MIXED_TABLE = { private static final String[] MIXED_TABLE = {
"CTRL_PS", " ", "\1", "\2", "\3", "\4", "\5", "\6", "\7", "\b", "\t", "\n" , "CTRL_PS", " ", "\1", "\2", "\3", "\4", "\5", "\6", "\7", "\b", "\t", "\n" ,
"\13", "\f", "\r", "\33", "\34", "\35", "\36", "\37", "@", "\\", "^", "_", "\13", "\f", "\r", "\33", "\34", "\35", "\36", "\37", "@", "\\", "^", "_",
"`", "|", "~", "\177", "CTRL_LL", "CTRL_UL", "CTRL_PL", "CTRL_BS" "`", "|", "~", "\177", "CTRL_LL", "CTRL_UL", "CTRL_PL", "CTRL_BS"
}; };
private static final String[] PUNCT_TABLE = { private static final String[] PUNCT_TABLE = {
"", "\r", "\r\n", ". ", ", ", ": ", "!", "\"", "#", "$", "%", "&", "'", "( ", ")", "FLG(n)", "\r", "\r\n", ". ", ", ", ": ", "!", "\"", "#", "$", "%", "&", " '", "(", ")",
"*", "+", ",", "-", ".", "/", ":", ";", "<", "=", ">", "?", "[", "]", "{", "}", "CTRL_UL" "*", "+", ",", "-", ".", "/", ":", ";", "<", "=", ">", "?", "[", "]", "{", "}", "CTRL_UL"
}; };
private static final String[] DIGIT_TABLE = { private static final String[] DIGIT_TABLE = {
"CTRL_PS", " ", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ",", "." , "CTRL_UL", "CTRL_US" "CTRL_PS", " ", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ",", "." , "CTRL_UL", "CTRL_US"
}; };
private static final Charset DEFAULT_ENCODING = StandardCharsets.ISO_8859_1;
private AztecDetectorResult ddata; private AztecDetectorResult ddata;
public DecoderResult decode(AztecDetectorResult detectorResult) throws FormatE xception { public DecoderResult decode(AztecDetectorResult detectorResult) throws FormatE xception {
ddata = detectorResult; ddata = detectorResult;
BitMatrix matrix = detectorResult.getBits(); BitMatrix matrix = detectorResult.getBits();
boolean[] rawbits = extractBits(matrix); boolean[] rawbits = extractBits(matrix);
boolean[] correctedBits = correctBits(rawbits); CorrectedBitsResult correctedBits = correctBits(rawbits);
byte[] rawBytes = convertBoolArrayToByteArray(correctedBits); byte[] rawBytes = convertBoolArrayToByteArray(correctedBits.correctBits);
String result = getEncodedData(correctedBits); String result = getEncodedData(correctedBits.correctBits);
DecoderResult decoderResult = new DecoderResult(rawBytes, result, null, null DecoderResult decoderResult =
); new DecoderResult(rawBytes, result, null, String.format("%d%%", correcte
decoderResult.setNumBits(correctedBits.length); dBits.ecLevel));
decoderResult.setNumBits(correctedBits.correctBits.length);
return decoderResult; return decoderResult;
} }
// This method is used for testing the high-level encoder // This method is used for testing the high-level encoder
public static String highLevelDecode(boolean[] correctedBits) { public static String highLevelDecode(boolean[] correctedBits) throws FormatExc eption {
return getEncodedData(correctedBits); return getEncodedData(correctedBits);
} }
/** /**
* Gets the string encoded in the aztec code bits * Gets the string encoded in the aztec code bits
* *
* @return the decoded string * @return the decoded string
*/ */
private static String getEncodedData(boolean[] correctedBits) { private static String getEncodedData(boolean[] correctedBits) throws FormatExc eption {
int endIndex = correctedBits.length; int endIndex = correctedBits.length;
Table latchTable = Table.UPPER; // table most recently latched to Table latchTable = Table.UPPER; // table most recently latched to
Table shiftTable = Table.UPPER; // table to use for the next read Table shiftTable = Table.UPPER; // table to use for the next read
StringBuilder result = new StringBuilder(20);
// Final decoded string result
// (correctedBits-5) / 4 is an upper bound on the size (all-digit result)
StringBuilder result = new StringBuilder((correctedBits.length - 5) / 4);
// Intermediary buffer of decoded bytes, which is decoded into a string and
flushed
// when character encoding changes (ECI) or input ends.
ByteArrayOutputStream decodedBytes = new ByteArrayOutputStream();
Charset encoding = DEFAULT_ENCODING;
int index = 0; int index = 0;
while (index < endIndex) { while (index < endIndex) {
if (shiftTable == Table.BINARY) { if (shiftTable == Table.BINARY) {
if (endIndex - index < 5) { if (endIndex - index < 5) {
break; break;
} }
int length = readCode(correctedBits, index, 5); int length = readCode(correctedBits, index, 5);
index += 5; index += 5;
if (length == 0) { if (length == 0) {
if (endIndex - index < 11) { if (endIndex - index < 11) {
skipping to change at line 121 skipping to change at line 138
} }
length = readCode(correctedBits, index, 11) + 31; length = readCode(correctedBits, index, 11) + 31;
index += 11; index += 11;
} }
for (int charCount = 0; charCount < length; charCount++) { for (int charCount = 0; charCount < length; charCount++) {
if (endIndex - index < 8) { if (endIndex - index < 8) {
index = endIndex; // Force outer loop to exit index = endIndex; // Force outer loop to exit
break; break;
} }
int code = readCode(correctedBits, index, 8); int code = readCode(correctedBits, index, 8);
result.append((char) code); decodedBytes.write((byte) code);
index += 8; index += 8;
} }
// Go back to whatever mode we had been in // Go back to whatever mode we had been in
shiftTable = latchTable; shiftTable = latchTable;
} else { } else {
int size = shiftTable == Table.DIGIT ? 4 : 5; int size = shiftTable == Table.DIGIT ? 4 : 5;
if (endIndex - index < size) { if (endIndex - index < size) {
break; break;
} }
int code = readCode(correctedBits, index, size); int code = readCode(correctedBits, index, size);
index += size; index += size;
String str = getCharacter(shiftTable, code); String str = getCharacter(shiftTable, code);
if (str.startsWith("CTRL_")) { if ("FLG(n)".equals(str)) {
if (endIndex - index < 3) {
break;
}
int n = readCode(correctedBits, index, 3);
index += 3;
// flush bytes, FLG changes state
try {
result.append(decodedBytes.toString(encoding.name()));
} catch (UnsupportedEncodingException uee) {
throw new IllegalStateException(uee);
}
decodedBytes.reset();
switch (n) {
case 0:
result.append((char) 29); // translate FNC1 as ASCII 29
break;
case 7:
throw FormatException.getFormatInstance(); // FLG(7) is reserved a
nd illegal
default:
// ECI is decimal integer encoded as 1-6 codes in DIGIT mode
int eci = 0;
if (endIndex - index < 4 * n) {
break;
}
while (n-- > 0) {
int nextDigit = readCode(correctedBits, index, 4);
index += 4;
if (nextDigit < 2 || nextDigit > 11) {
throw FormatException.getFormatInstance(); // Not a decimal di
git
}
eci = eci * 10 + (nextDigit - 2);
}
CharacterSetECI charsetECI = CharacterSetECI.getCharacterSetECIByV
alue(eci);
if (charsetECI == null) {
throw FormatException.getFormatInstance();
}
encoding = charsetECI.getCharset();
}
// Go back to whatever mode we had been in
shiftTable = latchTable;
} else if (str.startsWith("CTRL_")) {
// Table changes // Table changes
// ISO/IEC 24778:2008 prescribes ending a shift sequence in the mode f rom which it was invoked. // ISO/IEC 24778:2008 prescribes ending a shift sequence in the mode f rom which it was invoked.
// That's including when that mode is a shift. // That's including when that mode is a shift.
// Our test case dlusbs.png for issue #642 exercises that. // Our test case dlusbs.png for issue #642 exercises that.
latchTable = shiftTable; // Latch the current mode, so as to return t o Upper after U/S B/S latchTable = shiftTable; // Latch the current mode, so as to return t o Upper after U/S B/S
shiftTable = getTable(str.charAt(5)); shiftTable = getTable(str.charAt(5));
if (str.charAt(6) == 'L') { if (str.charAt(6) == 'L') {
latchTable = shiftTable; latchTable = shiftTable;
} }
} else { } else {
result.append(str); // Though stored as a table of strings for convenience, codes actually
represent 1 or 2 *bytes*.
byte[] b = str.getBytes(StandardCharsets.US_ASCII);
decodedBytes.write(b, 0, b.length);
// Go back to whatever mode we had been in // Go back to whatever mode we had been in
shiftTable = latchTable; shiftTable = latchTable;
} }
} }
} }
try {
result.append(decodedBytes.toString(encoding.name()));
} catch (UnsupportedEncodingException uee) {
// can't happen
throw new IllegalStateException(uee);
}
return result.toString(); return result.toString();
} }
/** /**
* gets the table corresponding to the char passed * gets the table corresponding to the char passed
*/ */
private static Table getTable(char t) { private static Table getTable(char t) {
switch (t) { switch (t) {
case 'L': case 'L':
return Table.LOWER; return Table.LOWER;
skipping to change at line 199 skipping to change at line 265
case PUNCT: case PUNCT:
return PUNCT_TABLE[code]; return PUNCT_TABLE[code];
case DIGIT: case DIGIT:
return DIGIT_TABLE[code]; return DIGIT_TABLE[code];
default: default:
// Should not reach here. // Should not reach here.
throw new IllegalStateException("Bad table"); throw new IllegalStateException("Bad table");
} }
} }
static final class CorrectedBitsResult {
private final boolean[] correctBits;
private final int ecLevel;
CorrectedBitsResult(boolean[] correctBits, int ecLevel) {
this.correctBits = correctBits;
this.ecLevel = ecLevel;
}
}
/** /**
* <p>Performs RS error correction on an array of bits.</p> * <p>Performs RS error correction on an array of bits.</p>
* *
* @return the corrected array * @return the corrected array
* @throws FormatException if the input contains too many errors * @throws FormatException if the input contains too many errors
*/ */
private boolean[] correctBits(boolean[] rawbits) throws FormatException { private CorrectedBitsResult correctBits(boolean[] rawbits) throws FormatExcept ion {
GenericGF gf; GenericGF gf;
int codewordSize; int codewordSize;
if (ddata.getNbLayers() <= 2) { if (ddata.getNbLayers() <= 2) {
codewordSize = 6; codewordSize = 6;
gf = GenericGF.AZTEC_DATA_6; gf = GenericGF.AZTEC_DATA_6;
} else if (ddata.getNbLayers() <= 8) { } else if (ddata.getNbLayers() <= 8) {
codewordSize = 8; codewordSize = 8;
gf = GenericGF.AZTEC_DATA_8; gf = GenericGF.AZTEC_DATA_8;
} else if (ddata.getNbLayers() <= 22) { } else if (ddata.getNbLayers() <= 22) {
skipping to change at line 269 skipping to change at line 345
if (dataWord == 1 || dataWord == mask - 1) { if (dataWord == 1 || dataWord == mask - 1) {
// next codewordSize-1 bits are all zeros or all ones // next codewordSize-1 bits are all zeros or all ones
Arrays.fill(correctedBits, index, index + codewordSize - 1, dataWord > 1 ); Arrays.fill(correctedBits, index, index + codewordSize - 1, dataWord > 1 );
index += codewordSize - 1; index += codewordSize - 1;
} else { } else {
for (int bit = codewordSize - 1; bit >= 0; --bit) { for (int bit = codewordSize - 1; bit >= 0; --bit) {
correctedBits[index++] = (dataWord & (1 << bit)) != 0; correctedBits[index++] = (dataWord & (1 << bit)) != 0;
} }
} }
} }
return correctedBits;
return new CorrectedBitsResult(correctedBits, 100 * (numCodewords - numDataC
odewords) / numCodewords);
} }
/** /**
* Gets the array of bits from an Aztec Code matrix * Gets the array of bits from an Aztec Code matrix
* *
* @return the array of bits * @return the array of bits
*/ */
private boolean[] extractBits(BitMatrix matrix) { private boolean[] extractBits(BitMatrix matrix) {
boolean compact = ddata.isCompact(); boolean compact = ddata.isCompact();
int layers = ddata.getNbLayers(); int layers = ddata.getNbLayers();
 End of changes. 15 change blocks. 
15 lines changed or deleted 98 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)