"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "core/src/main/java/com/google/zxing/pdf417/decoder/DecodedBitStreamParser.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).

DecodedBitStreamParser.java  (zxing-zxing-3.4.1):DecodedBitStreamParser.java  (zxing-zxing-3.5.0)
skipping to change at line 20 skipping to change at line 20
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* 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.pdf417.decoder; package com.google.zxing.pdf417.decoder;
import com.google.zxing.FormatException; import com.google.zxing.FormatException;
import com.google.zxing.common.CharacterSetECI; import com.google.zxing.common.ECIStringBuilder;
import com.google.zxing.common.DecoderResult; import com.google.zxing.common.DecoderResult;
import com.google.zxing.pdf417.PDF417ResultMetadata; import com.google.zxing.pdf417.PDF417ResultMetadata;
import java.io.ByteArrayOutputStream;
import java.math.BigInteger; import java.math.BigInteger;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays; import java.util.Arrays;
/** /**
* <p>This class contains the methods for decoding the PDF417 codewords.</p> * <p>This class contains the methods for decoding the PDF417 codewords.</p>
* *
* @author SITA Lab (kevin.osullivan@sita.aero) * @author SITA Lab (kevin.osullivan@sita.aero)
* @author Guenther Grau * @author Guenther Grau
*/ */
final class DecodedBitStreamParser { final class DecodedBitStreamParser {
skipping to change at line 104 skipping to change at line 101
EXP900[i] = EXP900[i - 1].multiply(nineHundred); EXP900[i] = EXP900[i - 1].multiply(nineHundred);
} }
} }
private static final int NUMBER_OF_SEQUENCE_CODEWORDS = 2; private static final int NUMBER_OF_SEQUENCE_CODEWORDS = 2;
private DecodedBitStreamParser() { private DecodedBitStreamParser() {
} }
static DecoderResult decode(int[] codewords, String ecLevel) throws FormatExce ption { static DecoderResult decode(int[] codewords, String ecLevel) throws FormatExce ption {
StringBuilder result = new StringBuilder(codewords.length * 2); ECIStringBuilder result = new ECIStringBuilder(codewords.length * 2);
Charset encoding = StandardCharsets.ISO_8859_1; int codeIndex = textCompaction(codewords, 1, result);
// Get compaction mode
int codeIndex = 1;
int code = codewords[codeIndex++];
PDF417ResultMetadata resultMetadata = new PDF417ResultMetadata(); PDF417ResultMetadata resultMetadata = new PDF417ResultMetadata();
while (codeIndex < codewords[0]) { while (codeIndex < codewords[0]) {
int code = codewords[codeIndex++];
switch (code) { switch (code) {
case TEXT_COMPACTION_MODE_LATCH: case TEXT_COMPACTION_MODE_LATCH:
codeIndex = textCompaction(codewords, codeIndex, result); codeIndex = textCompaction(codewords, codeIndex, result);
break; break;
case BYTE_COMPACTION_MODE_LATCH: case BYTE_COMPACTION_MODE_LATCH:
case BYTE_COMPACTION_MODE_LATCH_6: case BYTE_COMPACTION_MODE_LATCH_6:
codeIndex = byteCompaction(code, codewords, encoding, codeIndex, resul t); codeIndex = byteCompaction(code, codewords, codeIndex, result);
break; break;
case MODE_SHIFT_TO_BYTE_COMPACTION_MODE: case MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
result.append((char) codewords[codeIndex++]); result.append((char) codewords[codeIndex++]);
break; break;
case NUMERIC_COMPACTION_MODE_LATCH: case NUMERIC_COMPACTION_MODE_LATCH:
codeIndex = numericCompaction(codewords, codeIndex, result); codeIndex = numericCompaction(codewords, codeIndex, result);
break; break;
case ECI_CHARSET: case ECI_CHARSET:
CharacterSetECI charsetECI = result.appendECI(codewords[codeIndex++]);
CharacterSetECI.getCharacterSetECIByValue(codewords[codeIndex++]);
encoding = Charset.forName(charsetECI.name());
break; break;
case ECI_GENERAL_PURPOSE: case ECI_GENERAL_PURPOSE:
// Can't do anything with generic ECI; skip its 2 characters // Can't do anything with generic ECI; skip its 2 characters
codeIndex += 2; codeIndex += 2;
break; break;
case ECI_USER_DEFINED: case ECI_USER_DEFINED:
// Can't do anything with user ECI; skip its 1 character // Can't do anything with user ECI; skip its 1 character
codeIndex++; codeIndex++;
break; break;
case BEGIN_MACRO_PDF417_CONTROL_BLOCK: case BEGIN_MACRO_PDF417_CONTROL_BLOCK:
skipping to change at line 153 skipping to change at line 146
// Should not see these outside a macro block // Should not see these outside a macro block
throw FormatException.getFormatInstance(); throw FormatException.getFormatInstance();
default: default:
// Default to text compaction. During testing numerous barcodes // Default to text compaction. During testing numerous barcodes
// appeared to be missing the starting mode. In these cases defaulting // appeared to be missing the starting mode. In these cases defaulting
// to text compaction seems to work. // to text compaction seems to work.
codeIndex--; codeIndex--;
codeIndex = textCompaction(codewords, codeIndex, result); codeIndex = textCompaction(codewords, codeIndex, result);
break; break;
} }
if (codeIndex < codewords.length) {
code = codewords[codeIndex++];
} else {
throw FormatException.getFormatInstance();
}
} }
if (result.length() == 0) { if (result.isEmpty() && resultMetadata.getFileId() == null) {
throw FormatException.getFormatInstance(); throw FormatException.getFormatInstance();
} }
DecoderResult decoderResult = new DecoderResult(null, result.toString(), nul l, ecLevel); DecoderResult decoderResult = new DecoderResult(null, result.toString(), nul l, ecLevel);
decoderResult.setOther(resultMetadata); decoderResult.setOther(resultMetadata);
return decoderResult; return decoderResult;
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
static int decodeMacroBlock(int[] codewords, int codeIndex, PDF417ResultMetada ta resultMetadata) static int decodeMacroBlock(int[] codewords, int codeIndex, PDF417ResultMetada ta resultMetadata)
throws FormatException { throws FormatException {
if (codeIndex + NUMBER_OF_SEQUENCE_CODEWORDS > codewords[0]) { if (codeIndex + NUMBER_OF_SEQUENCE_CODEWORDS > codewords[0]) {
// we must have at least two bytes left for the segment index // we must have at least two bytes left for the segment index
throw FormatException.getFormatInstance(); throw FormatException.getFormatInstance();
} }
int[] segmentIndexArray = new int[NUMBER_OF_SEQUENCE_CODEWORDS]; int[] segmentIndexArray = new int[NUMBER_OF_SEQUENCE_CODEWORDS];
for (int i = 0; i < NUMBER_OF_SEQUENCE_CODEWORDS; i++, codeIndex++) { for (int i = 0; i < NUMBER_OF_SEQUENCE_CODEWORDS; i++, codeIndex++) {
segmentIndexArray[i] = codewords[codeIndex]; segmentIndexArray[i] = codewords[codeIndex];
} }
resultMetadata.setSegmentIndex(Integer.parseInt(decodeBase900toBase10(segmen String segmentIndexString = decodeBase900toBase10(segmentIndexArray, NUMBER_
tIndexArray, OF_SEQUENCE_CODEWORDS);
NUMBER_OF_SEQUENCE_CODEWORDS))); if (segmentIndexString.isEmpty()) {
resultMetadata.setSegmentIndex(0);
} else {
try {
resultMetadata.setSegmentIndex(Integer.parseInt(segmentIndexString));
} catch (NumberFormatException nfe) {
// too large; bad input?
throw FormatException.getFormatInstance();
}
}
// Decoding the fileId codewords as 0-899 numbers, each 0-filled to width 3.
This follows the spec
// (See ISO/IEC 15438:2015 Annex H.6) and preserves all info, but some gener
ators (e.g. TEC-IT) write
// the fileId using text compaction, so in those cases the fileId will appea
r mangled.
StringBuilder fileId = new StringBuilder(); StringBuilder fileId = new StringBuilder();
codeIndex = textCompaction(codewords, codeIndex, fileId); while (codeIndex < codewords[0] &&
codeIndex < codewords.length &&
codewords[codeIndex] != MACRO_PDF417_TERMINATOR &&
codewords[codeIndex] != BEGIN_MACRO_PDF417_OPTIONAL_FIELD) {
fileId.append(String.format("%03d", codewords[codeIndex]));
codeIndex++;
}
if (fileId.length() == 0) {
// at least one fileId codeword is required (Annex H.2)
throw FormatException.getFormatInstance();
}
resultMetadata.setFileId(fileId.toString()); resultMetadata.setFileId(fileId.toString());
int optionalFieldsStart = -1; int optionalFieldsStart = -1;
if (codewords[codeIndex] == BEGIN_MACRO_PDF417_OPTIONAL_FIELD) { if (codewords[codeIndex] == BEGIN_MACRO_PDF417_OPTIONAL_FIELD) {
optionalFieldsStart = codeIndex + 1; optionalFieldsStart = codeIndex + 1;
} }
while (codeIndex < codewords[0]) { while (codeIndex < codewords[0]) {
switch (codewords[codeIndex]) { switch (codewords[codeIndex]) {
case BEGIN_MACRO_PDF417_OPTIONAL_FIELD: case BEGIN_MACRO_PDF417_OPTIONAL_FIELD:
codeIndex++; codeIndex++;
switch (codewords[codeIndex]) { switch (codewords[codeIndex]) {
case MACRO_PDF417_OPTIONAL_FIELD_FILE_NAME: case MACRO_PDF417_OPTIONAL_FIELD_FILE_NAME:
StringBuilder fileName = new StringBuilder(); ECIStringBuilder fileName = new ECIStringBuilder();
codeIndex = textCompaction(codewords, codeIndex + 1, fileName); codeIndex = textCompaction(codewords, codeIndex + 1, fileName);
resultMetadata.setFileName(fileName.toString()); resultMetadata.setFileName(fileName.toString());
break; break;
case MACRO_PDF417_OPTIONAL_FIELD_SENDER: case MACRO_PDF417_OPTIONAL_FIELD_SENDER:
StringBuilder sender = new StringBuilder(); ECIStringBuilder sender = new ECIStringBuilder();
codeIndex = textCompaction(codewords, codeIndex + 1, sender); codeIndex = textCompaction(codewords, codeIndex + 1, sender);
resultMetadata.setSender(sender.toString()); resultMetadata.setSender(sender.toString());
break; break;
case MACRO_PDF417_OPTIONAL_FIELD_ADDRESSEE: case MACRO_PDF417_OPTIONAL_FIELD_ADDRESSEE:
StringBuilder addressee = new StringBuilder(); ECIStringBuilder addressee = new ECIStringBuilder();
codeIndex = textCompaction(codewords, codeIndex + 1, addressee); codeIndex = textCompaction(codewords, codeIndex + 1, addressee);
resultMetadata.setAddressee(addressee.toString()); resultMetadata.setAddressee(addressee.toString());
break; break;
case MACRO_PDF417_OPTIONAL_FIELD_SEGMENT_COUNT: case MACRO_PDF417_OPTIONAL_FIELD_SEGMENT_COUNT:
StringBuilder segmentCount = new StringBuilder(); ECIStringBuilder segmentCount = new ECIStringBuilder();
codeIndex = numericCompaction(codewords, codeIndex + 1, segmentCou nt); codeIndex = numericCompaction(codewords, codeIndex + 1, segmentCou nt);
resultMetadata.setSegmentCount(Integer.parseInt(segmentCount.toStr ing())); resultMetadata.setSegmentCount(Integer.parseInt(segmentCount.toStr ing()));
break; break;
case MACRO_PDF417_OPTIONAL_FIELD_TIME_STAMP: case MACRO_PDF417_OPTIONAL_FIELD_TIME_STAMP:
StringBuilder timestamp = new StringBuilder(); ECIStringBuilder timestamp = new ECIStringBuilder();
codeIndex = numericCompaction(codewords, codeIndex + 1, timestamp) ; codeIndex = numericCompaction(codewords, codeIndex + 1, timestamp) ;
resultMetadata.setTimestamp(Long.parseLong(timestamp.toString())); resultMetadata.setTimestamp(Long.parseLong(timestamp.toString()));
break; break;
case MACRO_PDF417_OPTIONAL_FIELD_CHECKSUM: case MACRO_PDF417_OPTIONAL_FIELD_CHECKSUM:
StringBuilder checksum = new StringBuilder(); ECIStringBuilder checksum = new ECIStringBuilder();
codeIndex = numericCompaction(codewords, codeIndex + 1, checksum); codeIndex = numericCompaction(codewords, codeIndex + 1, checksum);
resultMetadata.setChecksum(Integer.parseInt(checksum.toString())); resultMetadata.setChecksum(Integer.parseInt(checksum.toString()));
break; break;
case MACRO_PDF417_OPTIONAL_FIELD_FILE_SIZE: case MACRO_PDF417_OPTIONAL_FIELD_FILE_SIZE:
StringBuilder fileSize = new StringBuilder(); ECIStringBuilder fileSize = new ECIStringBuilder();
codeIndex = numericCompaction(codewords, codeIndex + 1, fileSize); codeIndex = numericCompaction(codewords, codeIndex + 1, fileSize);
resultMetadata.setFileSize(Long.parseLong(fileSize.toString())); resultMetadata.setFileSize(Long.parseLong(fileSize.toString()));
break; break;
default: default:
throw FormatException.getFormatInstance(); throw FormatException.getFormatInstance();
} }
break; break;
case MACRO_PDF417_TERMINATOR: case MACRO_PDF417_TERMINATOR:
codeIndex++; codeIndex++;
resultMetadata.setLastSegment(true); resultMetadata.setLastSegment(true);
skipping to change at line 250 skipping to change at line 260
} }
} }
// copy optional fields to additional options // copy optional fields to additional options
if (optionalFieldsStart != -1) { if (optionalFieldsStart != -1) {
int optionalFieldsLength = codeIndex - optionalFieldsStart; int optionalFieldsLength = codeIndex - optionalFieldsStart;
if (resultMetadata.isLastSegment()) { if (resultMetadata.isLastSegment()) {
// do not include terminator // do not include terminator
optionalFieldsLength--; optionalFieldsLength--;
} }
resultMetadata.setOptionalData(Arrays.copyOfRange(codewords, optionalField resultMetadata.setOptionalData(
sStart, optionalFieldsStart + optionalFieldsLength)); Arrays.copyOfRange(codewords, optionalFieldsStart, optionalFieldsStart
+ optionalFieldsLength));
} }
return codeIndex; return codeIndex;
} }
/** /**
* Text Compaction mode (see 5.4.1.5) permits all printable ASCII characters t o be * Text Compaction mode (see 5.4.1.5) permits all printable ASCII characters t o be
* encoded, i.e. values 32 - 126 inclusive in accordance with ISO/IEC 646 (IRV ), as * encoded, i.e. values 32 - 126 inclusive in accordance with ISO/IEC 646 (IRV ), as
* well as selected control characters. * well as selected control characters.
* *
* @param codewords The array of codewords (data + error) * @param codewords The array of codewords (data + error)
* @param codeIndex The current index into the codeword array. * @param codeIndex The current index into the codeword array.
* @param result The decoded data is appended to the result. * @param result The decoded data is appended to the result.
* @return The next index into the codeword array. * @return The next index into the codeword array.
*/ */
private static int textCompaction(int[] codewords, int codeIndex, StringBuilde r result) { private static int textCompaction(int[] codewords, int codeIndex, ECIStringBui lder result) throws FormatException {
// 2 character per codeword // 2 character per codeword
int[] textCompactionData = new int[(codewords[0] - codeIndex) * 2]; int[] textCompactionData = new int[(codewords[0] - codeIndex) * 2];
// Used to hold the byte compaction value if there is a mode shift // Used to hold the byte compaction value if there is a mode shift
int[] byteCompactionData = new int[(codewords[0] - codeIndex) * 2]; int[] byteCompactionData = new int[(codewords[0] - codeIndex) * 2];
int index = 0; int index = 0;
boolean end = false; boolean end = false;
Mode subMode = Mode.ALPHA;
while ((codeIndex < codewords[0]) && !end) { while ((codeIndex < codewords[0]) && !end) {
int code = codewords[codeIndex++]; int code = codewords[codeIndex++];
if (code < TEXT_COMPACTION_MODE_LATCH) { if (code < TEXT_COMPACTION_MODE_LATCH) {
textCompactionData[index] = code / 30; textCompactionData[index] = code / 30;
textCompactionData[index + 1] = code % 30; textCompactionData[index + 1] = code % 30;
index += 2; index += 2;
} else { } else {
switch (code) { switch (code) {
case TEXT_COMPACTION_MODE_LATCH: case TEXT_COMPACTION_MODE_LATCH:
// reinitialize text compaction mode to alpha sub mode // reinitialize text compaction mode to alpha sub mode
skipping to change at line 307 skipping to change at line 319
// switch from Text Compaction mode to Byte Compaction mode. // switch from Text Compaction mode to Byte Compaction mode.
// This switch shall be in effect for only the next codeword, // This switch shall be in effect for only the next codeword,
// after which the mode shall revert to the prevailing sub-mode // after which the mode shall revert to the prevailing sub-mode
// of the Text Compaction mode. Codeword 913 is only available // of the Text Compaction mode. Codeword 913 is only available
// in Text Compaction mode; its use is described in 5.4.2.4. // in Text Compaction mode; its use is described in 5.4.2.4.
textCompactionData[index] = MODE_SHIFT_TO_BYTE_COMPACTION_MODE; textCompactionData[index] = MODE_SHIFT_TO_BYTE_COMPACTION_MODE;
code = codewords[codeIndex++]; code = codewords[codeIndex++];
byteCompactionData[index] = code; byteCompactionData[index] = code;
index++; index++;
break; break;
case ECI_CHARSET:
subMode = decodeTextCompaction(textCompactionData, byteCompactionDat
a, index, result, subMode);
result.appendECI(codewords[codeIndex++]);
textCompactionData = new int[(codewords[0] - codeIndex) * 2];
byteCompactionData = new int[(codewords[0] - codeIndex) * 2];
index = 0;
break;
} }
} }
} }
decodeTextCompaction(textCompactionData, byteCompactionData, index, result); decodeTextCompaction(textCompactionData, byteCompactionData, index, result, subMode);
return codeIndex; return codeIndex;
} }
/** /**
* The Text Compaction mode includes all the printable ASCII characters * The Text Compaction mode includes all the printable ASCII characters
* (i.e. values from 32 to 126) and three ASCII control characters: HT or tab * (i.e. values from 32 to 126) and three ASCII control characters: HT or tab
* (ASCII value 9), LF or line feed (ASCII value 10), and CR or carriage * (ASCII value 9), LF or line feed (ASCII value 10), and CR or carriage
* return (ASCII value 13). The Text Compaction mode also includes various lat ch * return (ASCII value 13). The Text Compaction mode also includes various lat ch
* and shift characters which are used exclusively within the mode. The Text * and shift characters which are used exclusively within the mode. The Text
* Compaction mode encodes up to 2 characters per codeword. The compaction rul es * Compaction mode encodes up to 2 characters per codeword. The compaction rul es
* for converting data into PDF417 codewords are defined in 5.4.2.2. The sub-m ode * for converting data into PDF417 codewords are defined in 5.4.2.2. The sub-m ode
* switches are defined in 5.4.2.3. * switches are defined in 5.4.2.3.
* *
* @param textCompactionData The text compaction data. * @param textCompactionData The text compaction data.
* @param byteCompactionData The byte compaction data if there * @param byteCompactionData The byte compaction data if there
* was a mode shift. * was a mode shift.
* @param length The size of the text compaction and byte compacti on data. * @param length The size of the text compaction and byte compacti on data.
* @param result The decoded data is appended to the result. * @param result The decoded data is appended to the result.
* @param startMode The mode in which decoding starts
* @return The mode in which decoding ended
*/ */
private static void decodeTextCompaction(int[] textCompactionData, private static Mode decodeTextCompaction(int[] textCompactionData,
int[] byteCompactionData, int[] byteCompactionData,
int length, int length,
StringBuilder result) { ECIStringBuilder result,
// Beginning from an initial state of the Alpha sub-mode Mode startMode) {
// Beginning from an initial state
// The default compaction mode for PDF417 in effect at the start of each sym bol shall always be Text // The default compaction mode for PDF417 in effect at the start of each sym bol shall always be Text
// Compaction mode Alpha sub-mode (uppercase alphabetic). A latch codeword f rom another mode to the Text // Compaction mode Alpha sub-mode (uppercase alphabetic). A latch codeword f rom another mode to the Text
// Compaction mode shall always switch to the Text Compaction Alpha sub-mode . // Compaction mode shall always switch to the Text Compaction Alpha sub-mode .
Mode subMode = Mode.ALPHA; Mode subMode = startMode;
Mode priorToShiftMode = Mode.ALPHA; Mode priorToShiftMode = startMode;
Mode latchedMode = startMode;
int i = 0; int i = 0;
while (i < length) { while (i < length) {
int subModeCh = textCompactionData[i]; int subModeCh = textCompactionData[i];
char ch = 0; char ch = 0;
switch (subMode) { switch (subMode) {
case ALPHA: case ALPHA:
// Alpha (uppercase alphabetic) // Alpha (uppercase alphabetic)
if (subModeCh < 26) { if (subModeCh < 26) {
// Upper case Alpha Character // Upper case Alpha Character
ch = (char) ('A' + subModeCh); ch = (char) ('A' + subModeCh);
} else { } else {
switch (subModeCh) { switch (subModeCh) {
case 26: case 26:
ch = ' '; ch = ' ';
break; break;
case LL: case LL:
subMode = Mode.LOWER; subMode = Mode.LOWER;
latchedMode = subMode;
break; break;
case ML: case ML:
subMode = Mode.MIXED; subMode = Mode.MIXED;
latchedMode = subMode;
break; break;
case PS: case PS:
// Shift to punctuation // Shift to punctuation
priorToShiftMode = subMode; priorToShiftMode = subMode;
subMode = Mode.PUNCT_SHIFT; subMode = Mode.PUNCT_SHIFT;
break; break;
case MODE_SHIFT_TO_BYTE_COMPACTION_MODE: case MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
result.append((char) byteCompactionData[i]); result.append((char) byteCompactionData[i]);
break; break;
case TEXT_COMPACTION_MODE_LATCH: case TEXT_COMPACTION_MODE_LATCH:
subMode = Mode.ALPHA; subMode = Mode.ALPHA;
latchedMode = subMode;
break; break;
} }
} }
break; break;
case LOWER: case LOWER:
// Lower (lowercase alphabetic) // Lower (lowercase alphabetic)
if (subModeCh < 26) { if (subModeCh < 26) {
ch = (char) ('a' + subModeCh); ch = (char) ('a' + subModeCh);
} else { } else {
skipping to change at line 392 skipping to change at line 418
case 26: case 26:
ch = ' '; ch = ' ';
break; break;
case AS: case AS:
// Shift to alpha // Shift to alpha
priorToShiftMode = subMode; priorToShiftMode = subMode;
subMode = Mode.ALPHA_SHIFT; subMode = Mode.ALPHA_SHIFT;
break; break;
case ML: case ML:
subMode = Mode.MIXED; subMode = Mode.MIXED;
latchedMode = subMode;
break; break;
case PS: case PS:
// Shift to punctuation // Shift to punctuation
priorToShiftMode = subMode; priorToShiftMode = subMode;
subMode = Mode.PUNCT_SHIFT; subMode = Mode.PUNCT_SHIFT;
break; break;
case MODE_SHIFT_TO_BYTE_COMPACTION_MODE: case MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
// TODO Does this need to use the current character encoding? Se e other occurrences below
result.append((char) byteCompactionData[i]); result.append((char) byteCompactionData[i]);
break; break;
case TEXT_COMPACTION_MODE_LATCH: case TEXT_COMPACTION_MODE_LATCH:
subMode = Mode.ALPHA; subMode = Mode.ALPHA;
latchedMode = subMode;
break; break;
} }
} }
break; break;
case MIXED: case MIXED:
// Mixed (numeric and some punctuation) // Mixed (numeric and some punctuation)
if (subModeCh < PL) { if (subModeCh < PL) {
ch = MIXED_CHARS[subModeCh]; ch = MIXED_CHARS[subModeCh];
} else { } else {
switch (subModeCh) { switch (subModeCh) {
case PL: case PL:
subMode = Mode.PUNCT; subMode = Mode.PUNCT;
latchedMode = subMode;
break; break;
case 26: case 26:
ch = ' '; ch = ' ';
break; break;
case LL: case LL:
subMode = Mode.LOWER; subMode = Mode.LOWER;
latchedMode = subMode;
break; break;
case AL: case AL:
case TEXT_COMPACTION_MODE_LATCH: case TEXT_COMPACTION_MODE_LATCH:
subMode = Mode.ALPHA; subMode = Mode.ALPHA;
latchedMode = subMode;
break; break;
case PS: case PS:
// Shift to punctuation // Shift to punctuation
priorToShiftMode = subMode; priorToShiftMode = subMode;
subMode = Mode.PUNCT_SHIFT; subMode = Mode.PUNCT_SHIFT;
break; break;
case MODE_SHIFT_TO_BYTE_COMPACTION_MODE: case MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
result.append((char) byteCompactionData[i]); result.append((char) byteCompactionData[i]);
break; break;
} }
skipping to change at line 449 skipping to change at line 479
case PUNCT: case PUNCT:
// Punctuation // Punctuation
if (subModeCh < PAL) { if (subModeCh < PAL) {
ch = PUNCT_CHARS[subModeCh]; ch = PUNCT_CHARS[subModeCh];
} else { } else {
switch (subModeCh) { switch (subModeCh) {
case PAL: case PAL:
case TEXT_COMPACTION_MODE_LATCH: case TEXT_COMPACTION_MODE_LATCH:
subMode = Mode.ALPHA; subMode = Mode.ALPHA;
latchedMode = subMode;
break; break;
case MODE_SHIFT_TO_BYTE_COMPACTION_MODE: case MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
result.append((char) byteCompactionData[i]); result.append((char) byteCompactionData[i]);
break; break;
} }
} }
break; break;
case ALPHA_SHIFT: case ALPHA_SHIFT:
// Restore sub-mode // Restore sub-mode
skipping to change at line 500 skipping to change at line 531
} }
} }
break; break;
} }
if (ch != 0) { if (ch != 0) {
// Append decoded character to result // Append decoded character to result
result.append(ch); result.append(ch);
} }
i++; i++;
} }
return latchedMode;
} }
/** /**
* Byte Compaction mode (see 5.4.3) permits all 256 possible 8-bit byte values to be encoded. * Byte Compaction mode (see 5.4.3) permits all 256 possible 8-bit byte values to be encoded.
* This includes all ASCII characters value 0 to 127 inclusive and provides fo r international * This includes all ASCII characters value 0 to 127 inclusive and provides fo r international
* character set support. * character set support.
* *
* @param mode The byte compaction mode i.e. 901 or 924 * @param mode The byte compaction mode i.e. 901 or 924
* @param codewords The array of codewords (data + error) * @param codewords The array of codewords (data + error)
* @param encoding Currently active character encoding
* @param codeIndex The current index into the codeword array. * @param codeIndex The current index into the codeword array.
* @param result The decoded data is appended to the result. * @param result The decoded data is appended to the result.
* @return The next index into the codeword array. * @return The next index into the codeword array.
*/ */
private static int byteCompaction(int mode, private static int byteCompaction(int mode,
int[] codewords, int[] codewords,
Charset encoding,
int codeIndex, int codeIndex,
StringBuilder result) { ECIStringBuilder result) throws FormatExcept
ByteArrayOutputStream decodedBytes = new ByteArrayOutputStream(); ion {
int count = 0;
long value = 0;
boolean end = false; boolean end = false;
switch (mode) { while (codeIndex < codewords[0] && !end) {
case BYTE_COMPACTION_MODE_LATCH: //handle leading ECIs
// Total number of Byte Compaction characters to be encoded while (codeIndex < codewords[0] && codewords[codeIndex] == ECI_CHARSET) {
// is not a multiple of 6 result.appendECI(codewords[++codeIndex]);
codeIndex++;
int[] byteCompactedCodewords = new int[6]; }
int nextCode = codewords[codeIndex++];
while ((codeIndex < codewords[0]) && !end) {
byteCompactedCodewords[count++] = nextCode;
// Base 900
value = 900 * value + nextCode;
nextCode = codewords[codeIndex++];
// perhaps it should be ok to check only nextCode >= TEXT_COMPACTION_M
ODE_LATCH
switch (nextCode) {
case TEXT_COMPACTION_MODE_LATCH:
case BYTE_COMPACTION_MODE_LATCH:
case NUMERIC_COMPACTION_MODE_LATCH:
case BYTE_COMPACTION_MODE_LATCH_6:
case BEGIN_MACRO_PDF417_CONTROL_BLOCK:
case BEGIN_MACRO_PDF417_OPTIONAL_FIELD:
case MACRO_PDF417_TERMINATOR:
codeIndex--;
end = true;
break;
default:
if ((count % 5 == 0) && (count > 0)) {
// Decode every 5 codewords
// Convert to Base 256
for (int j = 0; j < 6; ++j) {
decodedBytes.write((byte) (value >> (8 * (5 - j))));
}
value = 0;
count = 0;
}
break;
}
}
// if the end of all codewords is reached the last codeword needs to be
added
if (codeIndex == codewords[0] && nextCode < TEXT_COMPACTION_MODE_LATCH)
{
byteCompactedCodewords[count++] = nextCode;
}
// If Byte Compaction mode is invoked with codeword 901,
// the last group of codewords is interpreted directly
// as one byte per codeword, without compaction.
for (int i = 0; i < count; i++) {
decodedBytes.write((byte) byteCompactedCodewords[i]);
}
break;
case BYTE_COMPACTION_MODE_LATCH_6: if (codeIndex >= codewords[0] || codewords[codeIndex] >= TEXT_COMPACTION_M
// Total number of Byte Compaction characters to be encoded ODE_LATCH) {
// is an integer multiple of 6 end = true;
while (codeIndex < codewords[0] && !end) { } else {
int code = codewords[codeIndex++]; //decode one block of 5 codewords to 6 bytes
if (code < TEXT_COMPACTION_MODE_LATCH) { long value = 0;
count++; int count = 0;
// Base 900 do {
value = 900 * value + code; value = 900 * value + codewords[codeIndex++];
} else { count++;
switch (code) { } while (count < 5 &&
case TEXT_COMPACTION_MODE_LATCH: codeIndex < codewords[0] &&
case BYTE_COMPACTION_MODE_LATCH: codewords[codeIndex] < TEXT_COMPACTION_MODE_LATCH);
case NUMERIC_COMPACTION_MODE_LATCH: if (count == 5 && (mode == BYTE_COMPACTION_MODE_LATCH_6 ||
case BYTE_COMPACTION_MODE_LATCH_6: codeIndex < codewords[0] &&
case BEGIN_MACRO_PDF417_CONTROL_BLOCK: codewords[codeIndex] < TEXT_COMPACTION_MODE_LATCH)) {
case BEGIN_MACRO_PDF417_OPTIONAL_FIELD: for (int i = 0; i < 6; i++) {
case MACRO_PDF417_TERMINATOR: result.append((byte) (value >> (8 * (5 - i))));
codeIndex--;
end = true;
break;
}
} }
if ((count % 5 == 0) && (count > 0)) { } else {
// Decode every 5 codewords codeIndex -= count;
// Convert to Base 256 while ((codeIndex < codewords[0]) && !end) {
for (int j = 0; j < 6; ++j) { int code = codewords[codeIndex++];
decodedBytes.write((byte) (value >> (8 * (5 - j)))); if (code < TEXT_COMPACTION_MODE_LATCH) {
result.append((byte) code);
} else if (code == ECI_CHARSET) {
result.appendECI(codewords[codeIndex++]);
} else {
codeIndex--;
end = true;
} }
value = 0;
count = 0;
} }
} }
break; }
} }
result.append(new String(decodedBytes.toByteArray(), encoding));
return codeIndex; return codeIndex;
} }
/** /**
* Numeric Compaction mode (see 5.4.4) permits efficient encoding of numeric d ata strings. * Numeric Compaction mode (see 5.4.4) permits efficient encoding of numeric d ata strings.
* *
* @param codewords The array of codewords (data + error) * @param codewords The array of codewords (data + error)
* @param codeIndex The current index into the codeword array. * @param codeIndex The current index into the codeword array.
* @param result The decoded data is appended to the result. * @param result The decoded data is appended to the result.
* @return The next index into the codeword array. * @return The next index into the codeword array.
*/ */
private static int numericCompaction(int[] codewords, int codeIndex, StringBui lder result) throws FormatException { private static int numericCompaction(int[] codewords, int codeIndex, ECIString Builder result) throws FormatException {
int count = 0; int count = 0;
boolean end = false; boolean end = false;
int[] numericCodewords = new int[MAX_NUMERIC_CODEWORDS]; int[] numericCodewords = new int[MAX_NUMERIC_CODEWORDS];
while (codeIndex < codewords[0] && !end) { while (codeIndex < codewords[0] && !end) {
int code = codewords[codeIndex++]; int code = codewords[codeIndex++];
if (codeIndex == codewords[0]) { if (codeIndex == codewords[0]) {
end = true; end = true;
} }
skipping to change at line 645 skipping to change at line 625
numericCodewords[count] = code; numericCodewords[count] = code;
count++; count++;
} else { } else {
switch (code) { switch (code) {
case TEXT_COMPACTION_MODE_LATCH: case TEXT_COMPACTION_MODE_LATCH:
case BYTE_COMPACTION_MODE_LATCH: case BYTE_COMPACTION_MODE_LATCH:
case BYTE_COMPACTION_MODE_LATCH_6: case BYTE_COMPACTION_MODE_LATCH_6:
case BEGIN_MACRO_PDF417_CONTROL_BLOCK: case BEGIN_MACRO_PDF417_CONTROL_BLOCK:
case BEGIN_MACRO_PDF417_OPTIONAL_FIELD: case BEGIN_MACRO_PDF417_OPTIONAL_FIELD:
case MACRO_PDF417_TERMINATOR: case MACRO_PDF417_TERMINATOR:
case ECI_CHARSET:
codeIndex--; codeIndex--;
end = true; end = true;
break; break;
} }
} }
if ((count % MAX_NUMERIC_CODEWORDS == 0 || code == NUMERIC_COMPACTION_MODE _LATCH || end) && count > 0) { if ((count % MAX_NUMERIC_CODEWORDS == 0 || code == NUMERIC_COMPACTION_MODE _LATCH || end) && count > 0) {
// Re-invoking Numeric Compaction mode (by using codeword 902 // Re-invoking Numeric Compaction mode (by using codeword 902
// while in Numeric Compaction mode) serves to terminate the // while in Numeric Compaction mode) serves to terminate the
// current Numeric Compaction mode grouping as described in 5.4.4.2, // current Numeric Compaction mode grouping as described in 5.4.4.2,
// and then to start a new one grouping. // and then to start a new one grouping.
 End of changes. 50 change blocks. 
132 lines changed or deleted 116 lines changed or added

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