mirror of
https://github.com/zxing/zxing.git
synced 2025-02-02 05:41:08 -08:00
Issue 1026 PDF417 encoding improvements
git-svn-id: https://zxing.googlecode.com/svn/trunk@2006 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
d148e9ff9d
commit
5d47b0f8d0
26
core/src/com/google/zxing/pdf417/encoder/Compaction.java
Normal file
26
core/src/com/google/zxing/pdf417/encoder/Compaction.java
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright 2011 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.zxing.pdf417.encoder;
|
||||
|
||||
public enum Compaction {
|
||||
|
||||
AUTO,
|
||||
TEXT,
|
||||
BYTE,
|
||||
NUMERIC
|
||||
|
||||
}
|
|
@ -510,10 +510,9 @@ final class PDF417 {
|
|||
private static final float DEFAULT_MODULE_WIDTH = 0.357f; //1px in mm
|
||||
private static final float HEIGHT = 2.0f; //mm
|
||||
|
||||
private int errorCorrectionLevel;
|
||||
private BarcodeMatrix barcodeMatrix;
|
||||
private boolean compact;
|
||||
private boolean byteCompaction;
|
||||
private Compaction compaction;
|
||||
private int minCols;
|
||||
private int maxCols;
|
||||
private int maxRows;
|
||||
|
@ -525,6 +524,7 @@ final class PDF417 {
|
|||
|
||||
PDF417(boolean compact) {
|
||||
this.compact = compact;
|
||||
compaction = Compaction.AUTO;
|
||||
minCols = 2;
|
||||
maxCols = 30;
|
||||
maxRows = 30;
|
||||
|
@ -639,8 +639,6 @@ final class PDF417 {
|
|||
int errorCorrectionLevel,
|
||||
BarcodeMatrix logic) {
|
||||
|
||||
this.errorCorrectionLevel = errorCorrectionLevel;
|
||||
|
||||
int idx = 0;
|
||||
for (int y = 0; y < r; y++) {
|
||||
int cluster = y % 3;
|
||||
|
@ -689,10 +687,10 @@ final class PDF417 {
|
|||
|
||||
//1. step: High-level encoding
|
||||
int errorCorrectionCodeWords = PDF417ErrorCorrection.getErrorCorrectionCodewordCount(errorCorrectionLevel);
|
||||
String highLevel = PDF417HighLevelEncoder.encodeHighLevel(msg, byteCompaction);
|
||||
String highLevel = PDF417HighLevelEncoder.encodeHighLevel(msg, compaction);
|
||||
int sourceCodeWords = highLevel.length();
|
||||
|
||||
int[] dimension = determineDimensions(sourceCodeWords);
|
||||
int[] dimension = determineDimensions(sourceCodeWords, errorCorrectionCodeWords);
|
||||
|
||||
int cols = dimension[0];
|
||||
int rows = dimension[1];
|
||||
|
@ -700,12 +698,11 @@ final class PDF417 {
|
|||
int pad = getNumberOfPadCodewords(sourceCodeWords, errorCorrectionCodeWords, cols, rows);
|
||||
|
||||
//2. step: construct data codewords
|
||||
int n = getNumberOfDataCodewords(sourceCodeWords, errorCorrectionLevel, cols);
|
||||
if (n > 929) {
|
||||
if (sourceCodeWords + errorCorrectionCodeWords + 1 > 929) { // +1 for symbol length CW
|
||||
throw new WriterException(
|
||||
"Encoded message contains to many code words, message to big (" + msg.length() + " bytes)");
|
||||
}
|
||||
|
||||
int n = sourceCodeWords + pad + 1;
|
||||
StringBuilder sb = new StringBuilder(n);
|
||||
sb.append((char) n);
|
||||
sb.append(highLevel);
|
||||
|
@ -728,13 +725,12 @@ final class PDF417 {
|
|||
* codewords.
|
||||
*
|
||||
* @param sourceCodeWords number of code words
|
||||
* @param errorCorrectionCodeWords number of error correction code words
|
||||
* @return dimension object containing cols as width and rows as height
|
||||
*/
|
||||
int[] determineDimensions(int sourceCodeWords) throws WriterException {
|
||||
|
||||
int[] determineDimensions(int sourceCodeWords, int errorCorrectionCodeWords) throws WriterException {
|
||||
float ratio = 0.0f;
|
||||
int[] dimension = null;
|
||||
int errorCorrectionCodeWords = PDF417ErrorCorrection.getErrorCorrectionCodewordCount(errorCorrectionLevel);
|
||||
|
||||
for (int cols = minCols; cols <= maxCols; cols++) {
|
||||
|
||||
|
@ -759,9 +755,18 @@ final class PDF417 {
|
|||
dimension = new int[] {cols, rows};
|
||||
}
|
||||
|
||||
// Handle case when min values were larger than necessary
|
||||
if (dimension == null) {
|
||||
int rows = calculateNumberOfRows(sourceCodeWords, errorCorrectionCodeWords, minCols);
|
||||
if (rows < minRows) {
|
||||
dimension = new int[]{minCols, minRows};
|
||||
}
|
||||
}
|
||||
|
||||
if (dimension == null) {
|
||||
throw new WriterException("Unable to fit message in columns");
|
||||
}
|
||||
|
||||
return dimension;
|
||||
}
|
||||
|
||||
|
@ -776,11 +781,10 @@ final class PDF417 {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets byte compaction to be true or false
|
||||
* @param byteCompaction
|
||||
* Sets compaction to values stored in {@link Compaction} enum
|
||||
*/
|
||||
void setByteCompaction(boolean byteCompaction) {
|
||||
this.byteCompaction = byteCompaction;
|
||||
void setCompaction(Compaction compaction) {
|
||||
this.compaction = compaction;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -148,7 +148,7 @@ final class PDF417HighLevelEncoder {
|
|||
* @param msg the message
|
||||
* @return the encoded message (the char values range from 0 to 928)
|
||||
*/
|
||||
static String encodeHighLevel(String msg, boolean byteCompaction) throws WriterException {
|
||||
static String encodeHighLevel(String msg, Compaction compaction) throws WriterException {
|
||||
byte[] bytes = null; //Fill later and only if needed
|
||||
|
||||
//the codewords 0..928 are encoded as Unicode characters
|
||||
|
@ -159,31 +159,20 @@ final class PDF417HighLevelEncoder {
|
|||
int encodingMode = TEXT_COMPACTION; //Default mode, see 4.4.2.1
|
||||
int textSubMode = SUBMODE_ALPHA;
|
||||
|
||||
if (byteCompaction) { // Can choose only byte compaction
|
||||
encodingMode = BYTE_COMPACTION;
|
||||
while (p < len) {
|
||||
// User selected encoding mode
|
||||
if (compaction == Compaction.TEXT) {
|
||||
encodeText(msg, p, len, sb, textSubMode);
|
||||
|
||||
} else if (compaction == Compaction.BYTE) {
|
||||
encodingMode = BYTE_COMPACTION;
|
||||
bytes = getBytesForMessage(msg);
|
||||
encodeBinary(bytes, p, bytes.length, encodingMode, sb);
|
||||
|
||||
} else if (compaction == Compaction.NUMERIC) {
|
||||
encodingMode = NUMERIC_COMPACTION;
|
||||
sb.append((char) LATCH_TO_NUMERIC);
|
||||
encodeNumeric(msg, p, len, sb);
|
||||
|
||||
if (bytes == null) {
|
||||
bytes = getBytesForMessage(msg);
|
||||
}
|
||||
int b = determineConsecutiveBinaryCount(msg, bytes, p);
|
||||
if (b == 0) {
|
||||
b = 1;
|
||||
}
|
||||
// I don't see how this ever takes value TEXT_COMPACTION?
|
||||
//if (b == 1 && encodingMode == TEXT_COMPACTION) {
|
||||
if (b == 1) {
|
||||
//Switch for one byte (instead of latch)
|
||||
encodeBinary(bytes, p, 1, TEXT_COMPACTION, sb);
|
||||
} else {
|
||||
//Mode latch performed by encodeBinary()
|
||||
encodeBinary(bytes, p, b, encodingMode, sb);
|
||||
// ... so this is redundant?
|
||||
//encodingMode = BYTE_COMPACTION;
|
||||
//textSubMode = SUBMODE_ALPHA; //Reset after latch
|
||||
}
|
||||
p += b;
|
||||
}
|
||||
} else {
|
||||
while (p < len) {
|
||||
int n = determineConsecutiveDigitCount(msg, p);
|
||||
|
@ -373,33 +362,33 @@ final class PDF417HighLevelEncoder {
|
|||
StringBuilder sb) {
|
||||
if (count == 1 && startmode == TEXT_COMPACTION) {
|
||||
sb.append((char) SHIFT_TO_BYTE);
|
||||
} else {
|
||||
boolean sixpack = (count % 6) == 0;
|
||||
if (sixpack) {
|
||||
sb.append((char) LATCH_TO_BYTE);
|
||||
} else {
|
||||
sb.append((char) LATCH_TO_BYTE_PADDED);
|
||||
}
|
||||
}
|
||||
|
||||
char[] chars = new char[5];
|
||||
int idx = startpos;
|
||||
while ((startpos + count - idx) >= 6) {
|
||||
long t = 0;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
t <<= 8;
|
||||
t += bytes[idx + i] & 0xff;
|
||||
// Encode sixpacks
|
||||
if (count >= 6) {
|
||||
sb.append((char) LATCH_TO_BYTE);
|
||||
char[] chars = new char[5];
|
||||
while ((startpos + count - idx) >= 6) {
|
||||
long t = 0;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
t <<= 8;
|
||||
t += bytes[idx + i] & 0xff;
|
||||
}
|
||||
for (int i = 0; i < 5; i++) {
|
||||
chars[i] = (char) (t % 900);
|
||||
t /= 900;
|
||||
}
|
||||
for (int i = chars.length - 1; i >= 0; i--) {
|
||||
sb.append(chars[i]);
|
||||
}
|
||||
idx += 6;
|
||||
}
|
||||
for (int i = 0; i < 5; i++) {
|
||||
chars[i] = (char) (t % 900);
|
||||
t /= 900;
|
||||
}
|
||||
for (int i = chars.length - 1; i >= 0; i--) {
|
||||
sb.append(chars[i]);
|
||||
}
|
||||
idx += 6;
|
||||
}
|
||||
//Encode rest (remaining n<5 bytes if any)
|
||||
if (idx < startpos + count) {
|
||||
sb.append((char) LATCH_TO_BYTE_PADDED);
|
||||
}
|
||||
for (int i = idx; i < startpos + count; i++) {
|
||||
int ch = bytes[i] & 0xff;
|
||||
sb.append((char) ch);
|
||||
|
|
|
@ -56,12 +56,12 @@ public final class PDF417Writer implements Writer {
|
|||
int maxCols,
|
||||
int minRows,
|
||||
int maxRows,
|
||||
boolean byteCompaction) throws WriterException {
|
||||
Compaction compaction) throws WriterException {
|
||||
PDF417 encoder = initializeEncoder(format, compact);
|
||||
|
||||
// Set options: dimensions and byte compaction
|
||||
encoder.setDimensions(maxCols, minCols, maxRows, minRows);
|
||||
encoder.setByteCompaction(byteCompaction);
|
||||
encoder.setCompaction(compaction);
|
||||
|
||||
return bitMatrixFromEncoder(encoder, contents, width, height);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue