mirror of
https://github.com/zxing/zxing.git
synced 2025-01-12 11:47:26 -08:00
Closes Issue #27 : add basic character set ECI support in PDF417
This commit is contained in:
parent
7169d1ad18
commit
7199f4ad17
|
@ -25,6 +25,7 @@ import com.google.zxing.pdf417.encoder.Compaction;
|
|||
import com.google.zxing.pdf417.encoder.Dimensions;
|
||||
import com.google.zxing.pdf417.encoder.PDF417;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
@ -68,6 +69,10 @@ public final class PDF417Writer implements Writer {
|
|||
if (hints.containsKey(EncodeHintType.MARGIN)) {
|
||||
margin = ((Number) hints.get(EncodeHintType.MARGIN)).intValue();
|
||||
}
|
||||
if (hints.containsKey(EncodeHintType.CHARACTER_SET)) {
|
||||
String encoding = (String) hints.get(EncodeHintType.CHARACTER_SET);
|
||||
encoder.setEncoding(Charset.forName(encoding));
|
||||
}
|
||||
}
|
||||
|
||||
return bitMatrixFromEncoder(encoder, contents, width, height, margin);
|
||||
|
|
|
@ -22,6 +22,8 @@ package com.google.zxing.pdf417.encoder;
|
|||
|
||||
import com.google.zxing.WriterException;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* Top-level class for the logic part of the PDF417 implementation.
|
||||
*/
|
||||
|
@ -513,6 +515,7 @@ public final class PDF417 {
|
|||
private BarcodeMatrix barcodeMatrix;
|
||||
private boolean compact;
|
||||
private Compaction compaction;
|
||||
private Charset encoding;
|
||||
private int minCols;
|
||||
private int maxCols;
|
||||
private int maxRows;
|
||||
|
@ -525,6 +528,7 @@ public final class PDF417 {
|
|||
public PDF417(boolean compact) {
|
||||
this.compact = compact;
|
||||
compaction = Compaction.AUTO;
|
||||
encoding = PDF417HighLevelEncoder.DEFAULT_ENCODING;
|
||||
minCols = 2;
|
||||
maxCols = 30;
|
||||
maxRows = 30;
|
||||
|
@ -642,7 +646,7 @@ public final class PDF417 {
|
|||
|
||||
//1. step: High-level encoding
|
||||
int errorCorrectionCodeWords = PDF417ErrorCorrection.getErrorCorrectionCodewordCount(errorCorrectionLevel);
|
||||
String highLevel = PDF417HighLevelEncoder.encodeHighLevel(msg, compaction);
|
||||
String highLevel = PDF417HighLevelEncoder.encodeHighLevel(msg, compaction, encoding);
|
||||
int sourceCodeWords = highLevel.length();
|
||||
|
||||
int[] dimension = determineDimensions(sourceCodeWords, errorCorrectionCodeWords);
|
||||
|
@ -749,5 +753,12 @@ public final class PDF417 {
|
|||
this.compact = compact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets output encoding.
|
||||
*/
|
||||
public void setEncoding(Charset encoding) {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
package com.google.zxing.pdf417.encoder;
|
||||
|
||||
import com.google.zxing.WriterException;
|
||||
import com.google.zxing.common.CharacterSetECI;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.Charset;
|
||||
|
@ -92,6 +93,21 @@ final class PDF417HighLevelEncoder {
|
|||
*/
|
||||
private static final int LATCH_TO_BYTE = 924;
|
||||
|
||||
/**
|
||||
* identifier for a user defined Extended Channel Interpretation (ECI)
|
||||
*/
|
||||
private static final int ECI_USER_DEFINED = 925;
|
||||
|
||||
/**
|
||||
* identifier for a general purpose ECO format
|
||||
*/
|
||||
private static final int ECI_GENERAL_PURPOSE = 926;
|
||||
|
||||
/**
|
||||
* identifier for an ECI of a character set of code page
|
||||
*/
|
||||
private static final int ECI_CHARSET = 927;
|
||||
|
||||
/**
|
||||
* Raw code table for text compaction Mixed sub-mode
|
||||
*/
|
||||
|
@ -132,17 +148,6 @@ final class PDF417HighLevelEncoder {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the message to a byte array using the default encoding (Cp437) as defined by the
|
||||
* specification
|
||||
*
|
||||
* @param msg the message
|
||||
* @return the byte array of the message
|
||||
*/
|
||||
private static byte[] getBytesForMessage(String msg) {
|
||||
return msg.getBytes(DEFAULT_ENCODING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs high-level encoding of a PDF417 message using the algorithm described in annex P
|
||||
* of ISO/IEC 15438:2001(E). If byte compaction has been selected, then only byte compaction
|
||||
|
@ -151,22 +156,29 @@ final class PDF417HighLevelEncoder {
|
|||
* @param msg the message
|
||||
* @return the encoded message (the char values range from 0 to 928)
|
||||
*/
|
||||
static String encodeHighLevel(String msg, Compaction compaction) throws WriterException {
|
||||
byte[] bytes = null; //Fill later and only if needed
|
||||
static String encodeHighLevel(String msg, Compaction compaction, Charset encoding) throws WriterException {
|
||||
|
||||
//the codewords 0..928 are encoded as Unicode characters
|
||||
StringBuilder sb = new StringBuilder(msg.length());
|
||||
|
||||
if (!DEFAULT_ENCODING.equals(encoding)) {
|
||||
CharacterSetECI eci = CharacterSetECI.getCharacterSetECIByName(encoding.name());
|
||||
if (eci != null) {
|
||||
encodingECI(eci.getValue(), sb);
|
||||
}
|
||||
}
|
||||
|
||||
int len = msg.length();
|
||||
int p = 0;
|
||||
int textSubMode = SUBMODE_ALPHA;
|
||||
|
||||
// User selected encoding mode
|
||||
byte[] bytes = null; //Fill later and only if needed
|
||||
if (compaction == Compaction.TEXT) {
|
||||
encodeText(msg, p, len, sb, textSubMode);
|
||||
|
||||
} else if (compaction == Compaction.BYTE) {
|
||||
bytes = getBytesForMessage(msg);
|
||||
bytes = msg.getBytes(encoding);
|
||||
encodeBinary(bytes, p, bytes.length, BYTE_COMPACTION, sb);
|
||||
|
||||
} else if (compaction == Compaction.NUMERIC) {
|
||||
|
@ -195,7 +207,7 @@ final class PDF417HighLevelEncoder {
|
|||
p += t;
|
||||
} else {
|
||||
if (bytes == null) {
|
||||
bytes = getBytesForMessage(msg);
|
||||
bytes = msg.getBytes(encoding);
|
||||
}
|
||||
int b = determineConsecutiveBinaryCount(msg, bytes, p);
|
||||
if (b == 0) {
|
||||
|
@ -562,5 +574,20 @@ final class PDF417HighLevelEncoder {
|
|||
return idx - startpos;
|
||||
}
|
||||
|
||||
private static void encodingECI(int eci, StringBuilder sb) throws WriterException {
|
||||
if (eci >= 0 && eci < 900) {
|
||||
sb.append((char) ECI_CHARSET);
|
||||
sb.append((char) eci);
|
||||
} else if (eci < 810900) {
|
||||
sb.append((char) ECI_GENERAL_PURPOSE);
|
||||
sb.append((char) (eci / 900 - 1));
|
||||
sb.append((char) (eci % 900));
|
||||
} else if (eci < 811800) {
|
||||
sb.append((char) ECI_USER_DEFINED);
|
||||
sb.append((char) (810900 - eci));
|
||||
} else {
|
||||
throw new WriterException("ECI number not in valid range from 0..811799, but was " + eci);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue