mirror of
https://github.com/zxing/zxing.git
synced 2024-11-10 04:54:04 -08:00
PDF417 compact from Joseph Lau
git-svn-id: https://zxing.googlecode.com/svn/trunk@1911 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
ea218233b9
commit
a335ff5fb7
|
@ -506,16 +506,30 @@ final class PDF417 {
|
|||
0x107a4, 0x107a2, 0x10396, 0x107b6, 0x187d4, 0x187d2,
|
||||
0x10794, 0x10fb4, 0x10792, 0x10fb2, 0x1c7ea}};
|
||||
|
||||
private static final int MIN_COLS = 2;
|
||||
private static final int MAX_COLS = 30;
|
||||
private static final int MAX_ROWS = 30;
|
||||
private static final int MIN_ROWS = 2;
|
||||
private static final float DEFAULT_MODULE_WIDTH = 0.357f; //1px in mm
|
||||
private static final float HEIGHT = 16.0f; //mm
|
||||
private static final float HEIGHT = 2.0f; //mm
|
||||
|
||||
private int errorCorrectionLevel;
|
||||
private BarcodeMatrix barcodeMatrix;
|
||||
private boolean compact;
|
||||
private boolean byteCompaction;
|
||||
private int minCols;
|
||||
private int maxCols;
|
||||
private int maxRows;
|
||||
private int minRows;
|
||||
|
||||
public PDF417() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
public PDF417(boolean compact) {
|
||||
this.compact = compact;
|
||||
minCols = 2;
|
||||
maxCols = 30;
|
||||
maxRows = 30;
|
||||
minRows = 2;
|
||||
}
|
||||
|
||||
BarcodeMatrix getBarcodeMatrix() {
|
||||
return barcodeMatrix;
|
||||
}
|
||||
|
@ -548,7 +562,7 @@ final class PDF417 {
|
|||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the necessary number of rows as described in annex Q of ISO/IEC 15438:2001(E).
|
||||
*
|
||||
|
@ -650,10 +664,14 @@ final class PDF417 {
|
|||
idx++;
|
||||
}
|
||||
|
||||
pattern = CODEWORD_TABLE[cluster][right];
|
||||
encodeChar(pattern, 17, logic.getCurrentRow());
|
||||
|
||||
encodeChar(STOP_PATTERN, 18, logic.getCurrentRow());
|
||||
if (compact) {
|
||||
encodeChar(STOP_PATTERN, 1, logic.getCurrentRow()); // encodes stop line for compact pdf417
|
||||
} else {
|
||||
pattern = CODEWORD_TABLE[cluster][right];
|
||||
encodeChar(pattern, 17, logic.getCurrentRow());
|
||||
|
||||
encodeChar(STOP_PATTERN, 18, logic.getCurrentRow());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -666,7 +684,7 @@ final class PDF417 {
|
|||
|
||||
//1. step: High-level encoding
|
||||
int errorCorrectionCodeWords = PDF417ErrorCorrection.getErrorCorrectionCodewordCount(errorCorrectionLevel);
|
||||
String highLevel = PDF417HighLevelEncoder.encodeHighLevel(msg);
|
||||
String highLevel = PDF417HighLevelEncoder.encodeHighLevel(msg, byteCompaction);
|
||||
int sourceCodeWords = highLevel.length();
|
||||
|
||||
int[] dimension = determineDimensions(sourceCodeWords);
|
||||
|
@ -717,15 +735,15 @@ final class PDF417 {
|
|||
int[] dimension = null;
|
||||
int errorCorrectionCodeWords = PDF417ErrorCorrection.getErrorCorrectionCodewordCount(errorCorrectionLevel);
|
||||
|
||||
for (int cols = MIN_COLS; cols <= MAX_COLS; cols++) {
|
||||
for (int cols = minCols; cols <= maxCols; cols++) {
|
||||
|
||||
int rows = calculateNumberOfRows(sourceCodeWords, errorCorrectionCodeWords, cols);
|
||||
|
||||
if (rows < MIN_ROWS) {
|
||||
if (rows < minRows) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (rows > MAX_ROWS) {
|
||||
if (rows > maxRows) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -743,6 +761,32 @@ final class PDF417 {
|
|||
|
||||
return dimension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets max/min row/col values
|
||||
*/
|
||||
void setDimensions(int maxCols, int minCols, int maxRows, int minRows) {
|
||||
this.maxCols = maxCols;
|
||||
this.minCols = minCols;
|
||||
this.maxRows = maxRows;
|
||||
this.minRows = minRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets byte compaction to be true or false
|
||||
* @param byteCompaction
|
||||
*/
|
||||
void setByteCompaction(boolean byteCompaction) {
|
||||
this.byteCompaction = byteCompaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets compact to be true or false
|
||||
* @param compact
|
||||
*/
|
||||
void setCompact(boolean compact) {
|
||||
this.compact = compact;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -143,12 +143,13 @@ final class PDF417HighLevelEncoder {
|
|||
|
||||
/**
|
||||
* Performs high-level encoding of a PDF417 message using the algorithm described in annex P
|
||||
* of ISO/IEC 15438:2001(E).
|
||||
* of ISO/IEC 15438:2001(E). If byte compaction has been selected, then only byte compaction
|
||||
* is used.
|
||||
*
|
||||
* @param msg the message
|
||||
* @return the encoded message (the char values range from 0 to 928)
|
||||
*/
|
||||
static String encodeHighLevel(String msg) throws WriterException {
|
||||
static String encodeHighLevel(String msg, boolean byteCompaction) throws WriterException {
|
||||
byte[] bytes = null; //Fill later and only if needed
|
||||
|
||||
//the codewords 0..928 are encoded as Unicode characters
|
||||
|
@ -158,42 +159,67 @@ final class PDF417HighLevelEncoder {
|
|||
int p = 0;
|
||||
int encodingMode = TEXT_COMPACTION; //Default mode, see 4.4.2.1
|
||||
int textSubMode = SUBMODE_ALPHA;
|
||||
while (p < len) {
|
||||
int n = determineConsecutiveDigitCount(msg, p);
|
||||
if (n >= 13) {
|
||||
sb.append((char) LATCH_TO_NUMERIC);
|
||||
encodingMode = NUMERIC_COMPACTION;
|
||||
textSubMode = SUBMODE_ALPHA; //Reset after latch
|
||||
encodeNumeric(msg, p, n, sb);
|
||||
p += n;
|
||||
} else {
|
||||
int t = determineConsecutiveTextCount(msg, p);
|
||||
if (t >= 5 || n == len) {
|
||||
if (encodingMode != TEXT_COMPACTION) {
|
||||
sb.append((char) LATCH_TO_TEXT);
|
||||
encodingMode = TEXT_COMPACTION;
|
||||
textSubMode = SUBMODE_ALPHA; //start with submode alpha after latch
|
||||
}
|
||||
textSubMode = encodeText(msg, p, t, sb, textSubMode);
|
||||
p += t;
|
||||
|
||||
if (byteCompaction) { // Can choose only byte compaction
|
||||
encodingMode = BYTE_COMPACTION;
|
||||
while (p < len) {
|
||||
|
||||
if (bytes == null) {
|
||||
bytes = getBytesForMessage(msg);
|
||||
}
|
||||
int b = determineConsecutiveBinaryCount(msg, bytes, p);
|
||||
if (b == 0) {
|
||||
b = 1;
|
||||
}
|
||||
if (b == 1 && encodingMode == TEXT_COMPACTION) {
|
||||
//Switch for one byte (instead of latch)
|
||||
encodeBinary(bytes, p, 1, TEXT_COMPACTION, sb);
|
||||
} else {
|
||||
if (bytes == null) {
|
||||
bytes = getBytesForMessage(msg);
|
||||
}
|
||||
int b = determineConsecutiveBinaryCount(msg, bytes, p);
|
||||
if (b == 0) {
|
||||
b = 1;
|
||||
}
|
||||
if (b == 1 && encodingMode == TEXT_COMPACTION) {
|
||||
//Switch for one byte (instead of latch)
|
||||
encodeBinary(bytes, p, 1, TEXT_COMPACTION, sb);
|
||||
//Mode latch performed by encodeBinary()
|
||||
encodeBinary(bytes, p, b, encodingMode, sb);
|
||||
encodingMode = BYTE_COMPACTION;
|
||||
textSubMode = SUBMODE_ALPHA; //Reset after latch
|
||||
}
|
||||
p += b;
|
||||
}
|
||||
} else {
|
||||
while (p < len) {
|
||||
int n = determineConsecutiveDigitCount(msg, p);
|
||||
if (n >= 13) {
|
||||
sb.append((char) LATCH_TO_NUMERIC);
|
||||
encodingMode = NUMERIC_COMPACTION;
|
||||
textSubMode = SUBMODE_ALPHA; //Reset after latch
|
||||
encodeNumeric(msg, p, n, sb);
|
||||
p += n;
|
||||
} else {
|
||||
int t = determineConsecutiveTextCount(msg, p);
|
||||
if (t >= 5 || n == len) {
|
||||
if (encodingMode != TEXT_COMPACTION) {
|
||||
sb.append((char) LATCH_TO_TEXT);
|
||||
encodingMode = TEXT_COMPACTION;
|
||||
textSubMode = SUBMODE_ALPHA; //start with submode alpha after latch
|
||||
}
|
||||
textSubMode = encodeText(msg, p, t, sb, textSubMode);
|
||||
p += t;
|
||||
} else {
|
||||
//Mode latch performed by encodeBinary()
|
||||
encodeBinary(bytes, p, b, encodingMode, sb);
|
||||
encodingMode = BYTE_COMPACTION;
|
||||
textSubMode = SUBMODE_ALPHA; //Reset after latch
|
||||
if (bytes == null) {
|
||||
bytes = getBytesForMessage(msg);
|
||||
}
|
||||
int b = determineConsecutiveBinaryCount(msg, bytes, p);
|
||||
if (b == 0) {
|
||||
b = 1;
|
||||
}
|
||||
if (b == 1 && encodingMode == TEXT_COMPACTION) {
|
||||
//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);
|
||||
encodingMode = BYTE_COMPACTION;
|
||||
textSubMode = SUBMODE_ALPHA; //Reset after latch
|
||||
}
|
||||
p += b;
|
||||
}
|
||||
p += b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,25 +34,52 @@ public final class PDF417Writer implements Writer {
|
|||
}
|
||||
|
||||
public BitMatrix encode(String contents, BarcodeFormat format, int width, int height) throws WriterException {
|
||||
|
||||
PDF417 encoder = initializeEncoder(format, false);
|
||||
return bitMatrixFromEncoder(encoder, contents, width, height);
|
||||
}
|
||||
|
||||
public BitMatrix encode(String contents,
|
||||
BarcodeFormat format,
|
||||
boolean compact,
|
||||
int width,
|
||||
int height,
|
||||
int minCols,
|
||||
int maxCols,
|
||||
int minRows,
|
||||
int maxRows,
|
||||
boolean byteCompaction) throws WriterException {
|
||||
PDF417 encoder = initializeEncoder(format, compact);
|
||||
|
||||
// Set options: dimensions and byte compaction
|
||||
encoder.setDimensions(maxCols, minCols, maxRows, minRows);
|
||||
encoder.setByteCompaction(byteCompaction);
|
||||
|
||||
return bitMatrixFromEncoder(encoder, contents, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the encoder based on the format (whether it's compact or not)
|
||||
*/
|
||||
private PDF417 initializeEncoder(BarcodeFormat format, boolean compact) {
|
||||
if (format != BarcodeFormat.PDF_417) {
|
||||
throw new IllegalArgumentException("Can only encode PDF_417, but got " + format);
|
||||
}
|
||||
|
||||
PDF417 encoder = new PDF417();
|
||||
encoder.setCompact(compact);
|
||||
return encoder;
|
||||
}
|
||||
|
||||
//No error correction at the moment
|
||||
int errorCorrectionLevel = 3;
|
||||
/**
|
||||
* Takes encoder, accounts for width/height, and retrieves bit matrix
|
||||
*/
|
||||
private BitMatrix bitMatrixFromEncoder(PDF417 encoder, String contents, int width, int height)
|
||||
throws WriterException {
|
||||
int errorCorrectionLevel = 2;
|
||||
encoder.generateBarcodeLogic(contents, errorCorrectionLevel);
|
||||
|
||||
// Give it data to be encoded
|
||||
//encoderExt.setData(content.getBytes());
|
||||
// Find the Error correction level automatically
|
||||
|
||||
//encoderExt.encode();
|
||||
//encoderExt.createArray();
|
||||
int lineThickness = 3;
|
||||
int aspectRatio = 8;
|
||||
|
||||
int lineThickness = 2;
|
||||
int aspectRatio = 4;
|
||||
byte[][] originalScale = encoder.getBarcodeMatrix().getScaledMatrix(lineThickness, aspectRatio * lineThickness);
|
||||
boolean rotated = false;
|
||||
if ((height > width) ^ (originalScale[0].length < originalScale.length)) {
|
||||
|
@ -80,7 +107,7 @@ public final class PDF417Writer implements Writer {
|
|||
}
|
||||
return bitMatrixFrombitArray(originalScale);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This takes an array holding the values of the PDF 417
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue