HighLevelEncoder.java (zxing-zxing-3.4.1) | : | HighLevelEncoder.java (zxing-zxing-3.5.0) | ||
---|---|---|---|---|
skipping to change at line 94 | skipping to change at line 94 | |||
*/ | */ | |||
static final char C40_UNLATCH = 254; | static final char C40_UNLATCH = 254; | |||
/** | /** | |||
* Unlatch from X12 encodation | * Unlatch from X12 encodation | |||
*/ | */ | |||
static final char X12_UNLATCH = 254; | static final char X12_UNLATCH = 254; | |||
/** | /** | |||
* 05 Macro header | * 05 Macro header | |||
*/ | */ | |||
private static final String MACRO_05_HEADER = "[)>\u001E05\u001D"; | static final String MACRO_05_HEADER = "[)>\u001E05\u001D"; | |||
/** | /** | |||
* 06 Macro header | * 06 Macro header | |||
*/ | */ | |||
private static final String MACRO_06_HEADER = "[)>\u001E06\u001D"; | static final String MACRO_06_HEADER = "[)>\u001E06\u001D"; | |||
/** | /** | |||
* Macro trailer | * Macro trailer | |||
*/ | */ | |||
private static final String MACRO_TRAILER = "\u001E\u0004"; | static final String MACRO_TRAILER = "\u001E\u0004"; | |||
static final int ASCII_ENCODATION = 0; | static final int ASCII_ENCODATION = 0; | |||
static final int C40_ENCODATION = 1; | static final int C40_ENCODATION = 1; | |||
static final int TEXT_ENCODATION = 2; | static final int TEXT_ENCODATION = 2; | |||
static final int X12_ENCODATION = 3; | static final int X12_ENCODATION = 3; | |||
static final int EDIFACT_ENCODATION = 4; | static final int EDIFACT_ENCODATION = 4; | |||
static final int BASE256_ENCODATION = 5; | static final int BASE256_ENCODATION = 5; | |||
private HighLevelEncoder() { | private HighLevelEncoder() { | |||
} | } | |||
/* | ||||
* 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 | ||||
*/ | ||||
/* | ||||
public static byte[] getBytesForMessage(String msg) { | ||||
return msg.getBytes(Charset.forName("cp437")); //See 4.4.3 and annex B of IS | ||||
O/IEC 15438:2001(E) | ||||
} | ||||
*/ | ||||
private static char randomize253State(int codewordPosition) { | private static char randomize253State(int codewordPosition) { | |||
int pseudoRandom = ((149 * codewordPosition) % 253) + 1; | int pseudoRandom = ((149 * codewordPosition) % 253) + 1; | |||
int tempVariable = PAD + pseudoRandom; | int tempVariable = PAD + pseudoRandom; | |||
return (char) (tempVariable <= 254 ? tempVariable : tempVariable - 254); | return (char) (tempVariable <= 254 ? tempVariable : tempVariable - 254); | |||
} | } | |||
/** | /** | |||
* Performs message encoding of a DataMatrix message using the algorithm descr ibed in annex P | * Performs message encoding of a DataMatrix message using the algorithm descr ibed in annex P | |||
* of ISO/IEC 16022:2000(E). | * of ISO/IEC 16022:2000(E). | |||
* | * | |||
* @param msg the message | * @param msg the message | |||
* @return the encoded message (the char values range from 0 to 255) | * @return the encoded message (the char values range from 0 to 255) | |||
*/ | */ | |||
public static String encodeHighLevel(String msg) { | public static String encodeHighLevel(String msg) { | |||
return encodeHighLevel(msg, SymbolShapeHint.FORCE_NONE, null, null); | return encodeHighLevel(msg, SymbolShapeHint.FORCE_NONE, null, null, false); | |||
} | } | |||
/** | /** | |||
* Performs message encoding of a DataMatrix message using the algorithm descr ibed in annex P | * Performs message encoding of a DataMatrix message using the algorithm descr ibed in annex P | |||
* of ISO/IEC 16022:2000(E). | * of ISO/IEC 16022:2000(E). | |||
* | * | |||
* @param msg the message | * @param msg the message | |||
* @param shape requested shape. May be {@code SymbolShapeHint.FORCE_NONE}, | * @param shape requested shape. May be {@code SymbolShapeHint.FORCE_NONE}, | |||
* {@code SymbolShapeHint.FORCE_SQUARE} or {@code SymbolShapeHi nt.FORCE_RECTANGLE}. | * {@code SymbolShapeHint.FORCE_SQUARE} or {@code SymbolShapeHi nt.FORCE_RECTANGLE}. | |||
* @param minSize the minimum symbol size constraint or null for no constraint | * @param minSize the minimum symbol size constraint or null for no constraint | |||
* @param maxSize the maximum symbol size constraint or null for no constraint | * @param maxSize the maximum symbol size constraint or null for no constraint | |||
* @return the encoded message (the char values range from 0 to 255) | * @return the encoded message (the char values range from 0 to 255) | |||
*/ | */ | |||
public static String encodeHighLevel(String msg, | public static String encodeHighLevel(String msg, | |||
SymbolShapeHint shape, | SymbolShapeHint shape, | |||
Dimension minSize, | Dimension minSize, | |||
Dimension maxSize) { | Dimension maxSize) { | |||
return encodeHighLevel(msg, shape, minSize, maxSize, false); | ||||
} | ||||
/** | ||||
* Performs message encoding of a DataMatrix message using the algorithm descr | ||||
ibed in annex P | ||||
* of ISO/IEC 16022:2000(E). | ||||
* | ||||
* @param msg the message | ||||
* @param shape requested shape. May be {@code SymbolShapeHint.FORCE_NONE}, | ||||
* {@code SymbolShapeHint.FORCE_SQUARE} or {@code SymbolShapeHi | ||||
nt.FORCE_RECTANGLE}. | ||||
* @param minSize the minimum symbol size constraint or null for no constraint | ||||
* @param maxSize the maximum symbol size constraint or null for no constraint | ||||
* @param forceC40 enforce C40 encoding | ||||
* @return the encoded message (the char values range from 0 to 255) | ||||
*/ | ||||
public static String encodeHighLevel(String msg, | ||||
SymbolShapeHint shape, | ||||
Dimension minSize, | ||||
Dimension maxSize, | ||||
boolean forceC40) { | ||||
//the codewords 0..255 are encoded as Unicode characters | //the codewords 0..255 are encoded as Unicode characters | |||
C40Encoder c40Encoder = new C40Encoder(); | ||||
Encoder[] encoders = { | Encoder[] encoders = { | |||
new ASCIIEncoder(), new C40Encoder(), new TextEncoder(), | new ASCIIEncoder(), c40Encoder, new TextEncoder(), | |||
new X12Encoder(), new EdifactEncoder(), new Base256Encoder() | new X12Encoder(), new EdifactEncoder(), new Base256Encoder() | |||
}; | }; | |||
EncoderContext context = new EncoderContext(msg); | EncoderContext context = new EncoderContext(msg); | |||
context.setSymbolShape(shape); | context.setSymbolShape(shape); | |||
context.setSizeConstraints(minSize, maxSize); | context.setSizeConstraints(minSize, maxSize); | |||
if (msg.startsWith(MACRO_05_HEADER) && msg.endsWith(MACRO_TRAILER)) { | if (msg.startsWith(MACRO_05_HEADER) && msg.endsWith(MACRO_TRAILER)) { | |||
context.writeCodeword(MACRO_05); | context.writeCodeword(MACRO_05); | |||
context.setSkipAtEnd(2); | context.setSkipAtEnd(2); | |||
context.pos += MACRO_05_HEADER.length(); | context.pos += MACRO_05_HEADER.length(); | |||
} else if (msg.startsWith(MACRO_06_HEADER) && msg.endsWith(MACRO_TRAILER)) { | } else if (msg.startsWith(MACRO_06_HEADER) && msg.endsWith(MACRO_TRAILER)) { | |||
context.writeCodeword(MACRO_06); | context.writeCodeword(MACRO_06); | |||
context.setSkipAtEnd(2); | context.setSkipAtEnd(2); | |||
context.pos += MACRO_06_HEADER.length(); | context.pos += MACRO_06_HEADER.length(); | |||
} | } | |||
int encodingMode = ASCII_ENCODATION; //Default mode | int encodingMode = ASCII_ENCODATION; //Default mode | |||
if (forceC40) { | ||||
c40Encoder.encodeMaximal(context); | ||||
encodingMode = context.getNewEncoding(); | ||||
context.resetEncoderSignal(); | ||||
} | ||||
while (context.hasMoreCharacters()) { | while (context.hasMoreCharacters()) { | |||
encoders[encodingMode].encode(context); | encoders[encodingMode].encode(context); | |||
if (context.getNewEncoding() >= 0) { | if (context.getNewEncoding() >= 0) { | |||
encodingMode = context.getNewEncoding(); | encodingMode = context.getNewEncoding(); | |||
context.resetEncoderSignal(); | context.resetEncoderSignal(); | |||
} | } | |||
} | } | |||
int len = context.getCodewordCount(); | int len = context.getCodewordCount(); | |||
context.updateSymbolInfo(); | context.updateSymbolInfo(); | |||
int capacity = context.getSymbolInfo().getDataCapacity(); | int capacity = context.getSymbolInfo().getDataCapacity(); | |||
skipping to change at line 210 | skipping to change at line 223 | |||
codewords.append(PAD); | codewords.append(PAD); | |||
} | } | |||
while (codewords.length() < capacity) { | while (codewords.length() < capacity) { | |||
codewords.append(randomize253State(codewords.length() + 1)); | codewords.append(randomize253State(codewords.length() + 1)); | |||
} | } | |||
return context.getCodewords().toString(); | return context.getCodewords().toString(); | |||
} | } | |||
static int lookAheadTest(CharSequence msg, int startpos, int currentMode) { | static int lookAheadTest(CharSequence msg, int startpos, int currentMode) { | |||
int newMode = lookAheadTestIntern(msg, startpos, currentMode); | ||||
if (currentMode == X12_ENCODATION && newMode == X12_ENCODATION) { | ||||
int endpos = Math.min(startpos + 3, msg.length()); | ||||
for (int i = startpos; i < endpos; i++) { | ||||
if (!isNativeX12(msg.charAt(i))) { | ||||
return ASCII_ENCODATION; | ||||
} | ||||
} | ||||
} else if (currentMode == EDIFACT_ENCODATION && newMode == EDIFACT_ENCODATIO | ||||
N) { | ||||
int endpos = Math.min(startpos + 4, msg.length()); | ||||
for (int i = startpos; i < endpos; i++) { | ||||
if (!isNativeEDIFACT(msg.charAt(i))) { | ||||
return ASCII_ENCODATION; | ||||
} | ||||
} | ||||
} | ||||
return newMode; | ||||
} | ||||
static int lookAheadTestIntern(CharSequence msg, int startpos, int currentMode | ||||
) { | ||||
if (startpos >= msg.length()) { | if (startpos >= msg.length()) { | |||
return currentMode; | return currentMode; | |||
} | } | |||
float[] charCounts; | float[] charCounts; | |||
//step J | //step J | |||
if (currentMode == ASCII_ENCODATION) { | if (currentMode == ASCII_ENCODATION) { | |||
charCounts = new float[]{0, 1, 1, 1, 1, 1.25f}; | charCounts = new float[]{0, 1, 1, 1, 1, 1.25f}; | |||
} else { | } else { | |||
charCounts = new float[]{1, 2, 2, 2, 2, 2.25f}; | charCounts = new float[]{1, 2, 2, 2, 2, 2.25f}; | |||
charCounts[currentMode] = 0; | charCounts[currentMode] = 0; | |||
skipping to change at line 312 | skipping to change at line 345 | |||
charCounts[BASE256_ENCODATION] += 4.0f; | charCounts[BASE256_ENCODATION] += 4.0f; | |||
} else { | } else { | |||
charCounts[BASE256_ENCODATION]++; | charCounts[BASE256_ENCODATION]++; | |||
} | } | |||
//step R | //step R | |||
if (charsProcessed >= 4) { | if (charsProcessed >= 4) { | |||
int[] intCharCounts = new int[6]; | int[] intCharCounts = new int[6]; | |||
byte[] mins = new byte[6]; | byte[] mins = new byte[6]; | |||
findMinimums(charCounts, intCharCounts, Integer.MAX_VALUE, mins); | findMinimums(charCounts, intCharCounts, Integer.MAX_VALUE, mins); | |||
int minCount = getMinimumCount(mins); | ||||
if (intCharCounts[ASCII_ENCODATION] < intCharCounts[BASE256_ENCODATION] | if (intCharCounts[ASCII_ENCODATION] < min(intCharCounts[BASE256_ENCODATI | |||
&& intCharCounts[ASCII_ENCODATION] < intCharCounts[C40_ENCODATION] | ON], | |||
&& intCharCounts[ASCII_ENCODATION] < intCharCounts[TEXT_ENCODATION] | intCharCounts[C40_ENCODATION], intCharCounts[TEXT_ENCODATION], int | |||
&& intCharCounts[ASCII_ENCODATION] < intCharCounts[X12_ENCODATION] | CharCounts[X12_ENCODATION], | |||
&& intCharCounts[ASCII_ENCODATION] < intCharCounts[EDIFACT_ENCODATIO | intCharCounts[EDIFACT_ENCODATION])) { | |||
N]) { | ||||
return ASCII_ENCODATION; | return ASCII_ENCODATION; | |||
} | } | |||
if (intCharCounts[BASE256_ENCODATION] < intCharCounts[ASCII_ENCODATION] | if (intCharCounts[BASE256_ENCODATION] < intCharCounts[ASCII_ENCODATION] | |||
|| (mins[C40_ENCODATION] + mins[TEXT_ENCODATION] + mins[X12_ENCODATI | || | |||
ON] + mins[EDIFACT_ENCODATION]) == 0) { | intCharCounts[BASE256_ENCODATION] + 1 < min(intCharCounts[C40_ENCO | |||
DATION], | ||||
intCharCounts[TEXT_ENCODATION], intCharCounts[X12_ENCODATION], int | ||||
CharCounts[EDIFACT_ENCODATION])) { | ||||
return BASE256_ENCODATION; | return BASE256_ENCODATION; | |||
} | } | |||
if (minCount == 1 && mins[EDIFACT_ENCODATION] > 0) { | if (intCharCounts[EDIFACT_ENCODATION] + 1 < min(intCharCounts[BASE256_EN | |||
CODATION], | ||||
intCharCounts[C40_ENCODATION] , intCharCounts[TEXT_ENCODATION] , i | ||||
ntCharCounts[X12_ENCODATION], | ||||
intCharCounts[ASCII_ENCODATION])) { | ||||
return EDIFACT_ENCODATION; | return EDIFACT_ENCODATION; | |||
} | } | |||
if (minCount == 1 && mins[TEXT_ENCODATION] > 0) { | if (intCharCounts[TEXT_ENCODATION] + 1 < min(intCharCounts[BASE256_ENCOD | |||
ATION], | ||||
intCharCounts[C40_ENCODATION] , intCharCounts[EDIFACT_ENCODATION] | ||||
, intCharCounts[X12_ENCODATION], | ||||
intCharCounts[ASCII_ENCODATION])) { | ||||
return TEXT_ENCODATION; | return TEXT_ENCODATION; | |||
} | } | |||
if (minCount == 1 && mins[X12_ENCODATION] > 0) { | if (intCharCounts[X12_ENCODATION] + 1 < min(intCharCounts[BASE256_ENCODA | |||
TION], | ||||
intCharCounts[C40_ENCODATION] , intCharCounts[EDIFACT_ENCODATION] | ||||
, intCharCounts[TEXT_ENCODATION], | ||||
intCharCounts[ASCII_ENCODATION])) { | ||||
return X12_ENCODATION; | return X12_ENCODATION; | |||
} | } | |||
if (intCharCounts[C40_ENCODATION] + 1 < intCharCounts[ASCII_ENCODATION] | if (intCharCounts[C40_ENCODATION] + 1 < min(intCharCounts[ASCII_ENCODATI | |||
&& intCharCounts[C40_ENCODATION] + 1 < intCharCounts[BASE256_ENCODAT | ON], | |||
ION] | intCharCounts[BASE256_ENCODATION] , intCharCounts[EDIFACT_ENCODATI | |||
&& intCharCounts[C40_ENCODATION] + 1 < intCharCounts[EDIFACT_ENCODAT | ON] , intCharCounts[TEXT_ENCODATION])) { | |||
ION] | ||||
&& intCharCounts[C40_ENCODATION] + 1 < intCharCounts[TEXT_ENCODATION | ||||
]) { | ||||
if (intCharCounts[C40_ENCODATION] < intCharCounts[X12_ENCODATION]) { | if (intCharCounts[C40_ENCODATION] < intCharCounts[X12_ENCODATION]) { | |||
return C40_ENCODATION; | return C40_ENCODATION; | |||
} | } | |||
if (intCharCounts[C40_ENCODATION] == intCharCounts[X12_ENCODATION]) { | if (intCharCounts[C40_ENCODATION] == intCharCounts[X12_ENCODATION]) { | |||
int p = startpos + charsProcessed + 1; | int p = startpos + charsProcessed + 1; | |||
while (p < msg.length()) { | while (p < msg.length()) { | |||
char tc = msg.charAt(p); | char tc = msg.charAt(p); | |||
if (isX12TermSep(tc)) { | if (isX12TermSep(tc)) { | |||
return X12_ENCODATION; | return X12_ENCODATION; | |||
} | } | |||
skipping to change at line 360 | skipping to change at line 395 | |||
} | } | |||
p++; | p++; | |||
} | } | |||
return C40_ENCODATION; | return C40_ENCODATION; | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
private static int min(int f1, int f2, int f3, int f4, int f5) { | ||||
return Math.min(min(f1, f2, f3, f4),f5); | ||||
} | ||||
private static int min(int f1, int f2, int f3, int f4) { | ||||
return Math.min(f1, Math.min(f2, Math.min(f3, f4))); | ||||
} | ||||
private static int findMinimums(float[] charCounts, int[] intCharCounts, int m in, byte[] mins) { | private static int findMinimums(float[] charCounts, int[] intCharCounts, int m in, byte[] mins) { | |||
Arrays.fill(mins, (byte) 0); | Arrays.fill(mins, (byte) 0); | |||
for (int i = 0; i < 6; i++) { | for (int i = 0; i < 6; i++) { | |||
intCharCounts[i] = (int) Math.ceil(charCounts[i]); | intCharCounts[i] = (int) Math.ceil(charCounts[i]); | |||
int current = intCharCounts[i]; | int current = intCharCounts[i]; | |||
if (min > current) { | if (min > current) { | |||
min = current; | min = current; | |||
Arrays.fill(mins, (byte) 0); | Arrays.fill(mins, (byte) 0); | |||
} | } | |||
if (min == current) { | if (min == current) { | |||
skipping to change at line 393 | skipping to change at line 436 | |||
} | } | |||
static boolean isDigit(char ch) { | static boolean isDigit(char ch) { | |||
return ch >= '0' && ch <= '9'; | return ch >= '0' && ch <= '9'; | |||
} | } | |||
static boolean isExtendedASCII(char ch) { | static boolean isExtendedASCII(char ch) { | |||
return ch >= 128 && ch <= 255; | return ch >= 128 && ch <= 255; | |||
} | } | |||
private static boolean isNativeC40(char ch) { | static boolean isNativeC40(char ch) { | |||
return (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z'); | return (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z'); | |||
} | } | |||
private static boolean isNativeText(char ch) { | static boolean isNativeText(char ch) { | |||
return (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z'); | return (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z'); | |||
} | } | |||
private static boolean isNativeX12(char ch) { | static boolean isNativeX12(char ch) { | |||
return isX12TermSep(ch) || (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z'); | return isX12TermSep(ch) || (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z'); | |||
} | } | |||
private static boolean isX12TermSep(char ch) { | private static boolean isX12TermSep(char ch) { | |||
return (ch == '\r') //CR | return (ch == '\r') //CR | |||
|| (ch == '*') | || (ch == '*') | |||
|| (ch == '>'); | || (ch == '>'); | |||
} | } | |||
private static boolean isNativeEDIFACT(char ch) { | static boolean isNativeEDIFACT(char ch) { | |||
return ch >= ' ' && ch <= '^'; | return ch >= ' ' && ch <= '^'; | |||
} | } | |||
private static boolean isSpecialB256(char ch) { | private static boolean isSpecialB256(char ch) { | |||
return false; //TODO NOT IMPLEMENTED YET!!! | return false; //TODO NOT IMPLEMENTED YET!!! | |||
} | } | |||
/** | /** | |||
* Determines the number of consecutive characters that are encodable using nu meric compaction. | * Determines the number of consecutive characters that are encodable using nu meric compaction. | |||
* | * | |||
* @param msg the message | * @param msg the message | |||
* @param startpos the start position within the message | * @param startpos the start position within the message | |||
* @return the requested character count | * @return the requested character count | |||
*/ | */ | |||
public static int determineConsecutiveDigitCount(CharSequence msg, int startpo s) { | public static int determineConsecutiveDigitCount(CharSequence msg, int startpo s) { | |||
int count = 0; | ||||
int len = msg.length(); | int len = msg.length(); | |||
int idx = startpos; | int idx = startpos; | |||
if (idx < len) { | while (idx < len && isDigit(msg.charAt(idx))) { | |||
char ch = msg.charAt(idx); | idx++; | |||
while (isDigit(ch) && idx < len) { | ||||
count++; | ||||
idx++; | ||||
if (idx < len) { | ||||
ch = msg.charAt(idx); | ||||
} | ||||
} | ||||
} | } | |||
return count; | return idx - startpos; | |||
} | } | |||
static void illegalCharacter(char c) { | static void illegalCharacter(char c) { | |||
String hex = Integer.toHexString(c); | String hex = Integer.toHexString(c); | |||
hex = "0000".substring(0, 4 - hex.length()) + hex; | hex = "0000".substring(0, 4 - hex.length()) + hex; | |||
throw new IllegalArgumentException("Illegal character: " + c + " (0x" + hex + ')'); | throw new IllegalArgumentException("Illegal character: " + c + " (0x" + hex + ')'); | |||
} | } | |||
} | } | |||
End of changes. 25 change blocks. | ||||
56 lines changed or deleted | 101 lines changed or added |