Minor code changes to previous PR merges

This commit is contained in:
Sean Owen 2022-02-17 14:14:37 -06:00
parent f3f73b47d3
commit 29fbff0802
6 changed files with 106 additions and 191 deletions

View file

@ -42,26 +42,26 @@ public final class ECIEncoderSet {
// List of encoders that potentially encode characters not in ISO-8859-1 in one byte. // List of encoders that potentially encode characters not in ISO-8859-1 in one byte.
private static final List<CharsetEncoder> ENCODERS = new ArrayList<>(); private static final List<CharsetEncoder> ENCODERS = new ArrayList<>();
static { static {
final String[] names = { "IBM437", String[] names = { "IBM437",
"ISO-8859-2", "ISO-8859-2",
"ISO-8859-3", "ISO-8859-3",
"ISO-8859-4", "ISO-8859-4",
"ISO-8859-5", "ISO-8859-5",
"ISO-8859-6", "ISO-8859-6",
"ISO-8859-7", "ISO-8859-7",
"ISO-8859-8", "ISO-8859-8",
"ISO-8859-9", "ISO-8859-9",
"ISO-8859-10", "ISO-8859-10",
"ISO-8859-11", "ISO-8859-11",
"ISO-8859-13", "ISO-8859-13",
"ISO-8859-14", "ISO-8859-14",
"ISO-8859-15", "ISO-8859-15",
"ISO-8859-16", "ISO-8859-16",
"windows-1250", "windows-1250",
"windows-1251", "windows-1251",
"windows-1252", "windows-1252",
"windows-1256", "windows-1256",
"Shift_JIS" }; "Shift_JIS" };
for (String name : names) { for (String name : names) {
if (CharacterSetECI.getCharacterSetECIByName(name) != null) { if (CharacterSetECI.getCharacterSetECIByName(name) != null) {
try { try {
@ -150,7 +150,6 @@ public final class ECIEncoderSet {
} }
priorityEncoderIndex = priorityEncoderIndexValue; priorityEncoderIndex = priorityEncoderIndexValue;
//invariants //invariants
assert encoders.length > 0;
assert encoders[0].charset().equals(StandardCharsets.ISO_8859_1); assert encoders[0].charset().equals(StandardCharsets.ISO_8859_1);
} }

View file

@ -73,7 +73,6 @@ public final class MinimalEncoder {
private MinimalEncoder() { private MinimalEncoder() {
assert false;
} }
static boolean isExtendedASCII(char ch, int fnc1) { static boolean isExtendedASCII(char ch, int fnc1) {
@ -81,22 +80,18 @@ public final class MinimalEncoder {
} }
private static boolean isInC40Shift1Set(char ch) { private static boolean isInC40Shift1Set(char ch) {
return ch >= 0 && ch <= 31; return ch <= 31;
} }
private static boolean isInC40Shift2Set(char ch, int fnc1) { private static boolean isInC40Shift2Set(char ch, int fnc1) {
for (int i = 0; i < C40_SHIFT2_CHARS.length; i++) { for (char c40Shift2Char : C40_SHIFT2_CHARS) {
if (C40_SHIFT2_CHARS[i] == ch) { if (c40Shift2Char == ch) {
return true; return true;
} }
} }
return ch == fnc1; return ch == fnc1;
} }
private static boolean isInC40Shift3Set(char ch) {
return ch >= 96 && ch <= 127;
}
private static boolean isInTextShift1Set(char ch) { private static boolean isInTextShift1Set(char ch) {
return isInC40Shift1Set(ch); return isInC40Shift1Set(ch);
} }
@ -105,10 +100,6 @@ public final class MinimalEncoder {
return isInC40Shift2Set(ch, fnc1); return isInC40Shift2Set(ch, fnc1);
} }
private static boolean isInTextShift3Set(char ch) {
return ch == 96 || (ch >= 'A' && ch <= 'Z') || (ch >= 123 && ch <= 127);
}
/** /**
* Performs message encoding of a DataMatrix message * Performs message encoding of a DataMatrix message
* *
@ -227,11 +218,11 @@ public final class MinimalEncoder {
addEdge(edges, new Edge(input, Mode.ASCII, from, 1, previous)); addEdge(edges, new Edge(input, Mode.ASCII, from, 1, previous));
} }
final Mode[] modes = {Mode.C40, Mode.TEXT}; Mode[] modes = {Mode.C40, Mode.TEXT};
for (int m = 0; m < modes.length; m++) { for (Mode mode : modes) {
int[] characterLength = new int[1]; int[] characterLength = new int[1];
if (getNumberOfC40Words(input, from, modes[m] == Mode.C40,characterLength) > 0) { if (getNumberOfC40Words(input, from, mode == Mode.C40, characterLength) > 0) {
addEdge(edges, new Edge(input, modes[m], from, characterLength[0], previous)); addEdge(edges, new Edge(input, mode, from, characterLength[0], previous));
} }
} }
@ -451,7 +442,6 @@ public final class MinimalEncoder {
// Array that represents vertices. There is a vertex for every character and mode. // Array that represents vertices. There is a vertex for every character and mode.
// The last dimension in the array below encodes the 6 modes ASCII, C40, TEXT, X12, EDF and B256 // The last dimension in the array below encodes the 6 modes ASCII, C40, TEXT, X12, EDF and B256
@SuppressWarnings("unchecked")
Edge[][] edges = new Edge[inputLength + 1][6]; Edge[][] edges = new Edge[inputLength + 1][6];
addEdges(input, edges, 0, null); addEdges(input, edges, 0, null);
@ -535,10 +525,7 @@ public final class MinimalEncoder {
if (previousMode == Mode.C40 || if (previousMode == Mode.C40 ||
previousMode == Mode.TEXT || previousMode == Mode.TEXT ||
previousMode == Mode.X12) { previousMode == Mode.X12) {
size++; //unatch 254 to ASCII size++; // unlatch 254 to ASCII
} else if (previousMode == Mode.EDF) {
assert false; // can't happen because we never add any other outgoing edges other than EDF edges to an EDF
// vertex
} }
break; break;
case B256: case B256:
@ -554,9 +541,6 @@ public final class MinimalEncoder {
previousMode == Mode.TEXT || previousMode == Mode.TEXT ||
previousMode == Mode.X12) { previousMode == Mode.X12) {
size += 2; //unlatch to ASCII, latch to B256 size += 2; //unlatch to ASCII, latch to B256
} else if (previousMode == Mode.EDF) {
assert false; // can't happen because we never add any other outgoing edges other than EDF edges to an EDF
// vertex
} }
break; break;
case C40: case C40:
@ -575,9 +559,6 @@ public final class MinimalEncoder {
previousMode == Mode.TEXT || previousMode == Mode.TEXT ||
previousMode == Mode.X12)) { previousMode == Mode.X12)) {
size += 2; //unlatch 254 to ASCII followed by latch to this mode size += 2; //unlatch 254 to ASCII followed by latch to this mode
} else if (previousMode == Mode.EDF) {
assert false; // can't happen because we never add any other outgoing edges other than EDF edges to an EDF
// vertex
} }
break; break;
case EDF: case EDF:
@ -594,7 +575,7 @@ public final class MinimalEncoder {
cachedTotalSize = size; cachedTotalSize = size;
} }
/** does not count beyond 250*/ // does not count beyond 250
int getB256Size() { int getB256Size() {
int cnt = 0; int cnt = 0;
Edge current = this; Edge current = this;
@ -699,23 +680,23 @@ public final class MinimalEncoder {
int getMinSymbolSize(int minimum) { int getMinSymbolSize(int minimum) {
switch (input.getShapeHint()) { switch (input.getShapeHint()) {
case FORCE_SQUARE: case FORCE_SQUARE:
for (int i = 0; i < squareCodewordCapacities.length; i++) { for (int capacity : squareCodewordCapacities) {
if (squareCodewordCapacities[i] >= minimum) { if (capacity >= minimum) {
return squareCodewordCapacities[i]; return capacity;
} }
} }
break; break;
case FORCE_RECTANGLE: case FORCE_RECTANGLE:
for (int i = 0; i < rectangularCodewordCapacities.length; i++) { for (int capacity : rectangularCodewordCapacities) {
if (rectangularCodewordCapacities[i] >= minimum) { if (capacity >= minimum) {
return rectangularCodewordCapacities[i]; return capacity;
} }
} }
break; break;
} }
for (int i = 0; i < allCodewordCapacities.length; i++) { for (int capacity : allCodewordCapacities) {
if (allCodewordCapacities[i] >= minimum) { if (capacity >= minimum) {
return allCodewordCapacities[i]; return capacity;
} }
} }
return allCodewordCapacities[allCodewordCapacities.length - 1]; return allCodewordCapacities[allCodewordCapacities.length - 1];
@ -728,10 +709,6 @@ public final class MinimalEncoder {
return getMinSymbolSize(minimum) - minimum; return getMinSymbolSize(minimum) - minimum;
} }
int getSize() {
return previous == null ? cachedTotalSize : cachedTotalSize - previous.cachedTotalSize;
}
static byte[] getBytes(int c) { static byte[] getBytes(int c) {
byte[] result = new byte[1]; byte[] result = new byte[1];
result[0] = (byte) c; result[0] = (byte) c;
@ -745,15 +722,6 @@ public final class MinimalEncoder {
return result; return result;
} }
static byte[] getBytes(int c1, byte[] bytes) {
byte[] result = new byte[1 + bytes.length];
result[0] = (byte) c1;
for (int i = 0; i < bytes.length; i++) {
result[i + 1] = bytes[i];
}
return result;
}
static void setC40Word(byte[] bytes, int offset, int c1, int c2, int c3) { static void setC40Word(byte[] bytes, int offset, int c1, int c2, int c3) {
int val16 = (1600 * (c1 & 0xff)) + (40 * (c2 & 0xff)) + (c3 & 0xff) + 1; int val16 = (1600 * (c1 & 0xff)) + (40 * (c2 & 0xff)) + (c3 & 0xff) + 1;
bytes[offset] = (byte) (val16 / 256); bytes[offset] = (byte) (val16 / 256);
@ -793,18 +761,18 @@ public final class MinimalEncoder {
return 27; return 27;
} }
if (c40) { if (c40) {
return c >= 0 && c <= 31 ? c : return c <= 31 ? c :
c == 32 ? 3 : c == 32 ? 3 :
c >= 33 && c <= 47 ? c - 33 : c <= 47 ? c - 33 :
c >= 48 && c <= 57 ? c - 44 : c <= 57 ? c - 44 :
c >= 58 && c <= 64 ? c - 43 : c <= 64 ? c - 43 :
c >= 65 && c <= 90 ? c - 51 : c <= 90 ? c - 51 :
c >= 91 && c <= 95 ? c - 69 : c <= 95 ? c - 69 :
c >= 96 && c <= 127 ? c - 96 : c; c <= 127 ? c - 96 : c;
} else { } else {
return c == 0 ? 0 : return c == 0 ? 0 :
setIndex == 0 && c >= 1 && c <= 3 ? c - 1 : //is this a bug in the spec? setIndex == 0 && c <= 3 ? c - 1 : //is this a bug in the spec?
setIndex == 1 && c >= 1 && c <= 31 ? c : setIndex == 1 && c <= 31 ? c :
c == 32 ? 3 : c == 32 ? 3 :
c >= 33 && c <= 47 ? c - 33 : c >= 33 && c <= 47 ? c - 33 :
c >= 48 && c <= 57 ? c - 44 : c >= 48 && c <= 57 ? c - 44 :
@ -818,44 +786,41 @@ public final class MinimalEncoder {
} }
byte[] getC40Words(boolean c40, int fnc1) { byte[] getC40Words(boolean c40, int fnc1) {
List<Byte> c40Values = new ArrayList(); List<Byte> c40Values = new ArrayList<>();
for (int i = 0; i < characterLength; i++) { for (int i = 0; i < characterLength; i++) {
char ci = input.charAt(fromPosition + i); char ci = input.charAt(fromPosition + i);
if (c40 && HighLevelEncoder.isNativeC40(ci) || !c40 && HighLevelEncoder.isNativeText(ci)) { if (c40 && HighLevelEncoder.isNativeC40(ci) || !c40 && HighLevelEncoder.isNativeText(ci)) {
c40Values.add(Byte.valueOf((byte) getC40Value(c40, 0, ci, fnc1))); c40Values.add((byte) getC40Value(c40, 0, ci, fnc1));
} else if (!isExtendedASCII(ci, fnc1)) { } else if (!isExtendedASCII(ci, fnc1)) {
int shiftValue = getShiftValue(ci, c40, fnc1); int shiftValue = getShiftValue(ci, c40, fnc1);
c40Values.add(Byte.valueOf((byte) shiftValue)); //Shift[123] c40Values.add((byte) shiftValue); //Shift[123]
c40Values.add(Byte.valueOf((byte) getC40Value(c40, shiftValue, ci, fnc1))); c40Values.add((byte) getC40Value(c40, shiftValue, ci, fnc1));
} else { } else {
char asciiValue = (char) ((ci & 0xff) - 128); char asciiValue = (char) ((ci & 0xff) - 128);
assert asciiValue >= 0; if (c40 && HighLevelEncoder.isNativeC40(asciiValue) ||
if (c40 && HighLevelEncoder.isNativeC40((char) asciiValue) || !c40 && HighLevelEncoder.isNativeText(asciiValue)) {
!c40 && HighLevelEncoder.isNativeText((char) asciiValue)) { c40Values.add((byte) 1); //Shift 2
c40Values.add(Byte.valueOf((byte) 1)); //Shift 2 c40Values.add((byte) 30); //Upper Shift
c40Values.add(Byte.valueOf((byte) 30)); //Upper Shift c40Values.add((byte) getC40Value(c40, 0, asciiValue, fnc1));
c40Values.add(Byte.valueOf((byte) getC40Value(c40, 0, asciiValue, fnc1)));
} else { } else {
c40Values.add(Byte.valueOf((byte) 1)); //Shift 2 c40Values.add((byte) 1); //Shift 2
c40Values.add(Byte.valueOf((byte) 30)); //Upper Shift c40Values.add((byte) 30); //Upper Shift
int shiftValue = getShiftValue(asciiValue, c40, fnc1); int shiftValue = getShiftValue(asciiValue, c40, fnc1);
c40Values.add(Byte.valueOf((byte) shiftValue)); // Shift[123] c40Values.add((byte) shiftValue); // Shift[123]
c40Values.add(Byte.valueOf((byte) getC40Value(c40, shiftValue, asciiValue, fnc1))); c40Values.add((byte) getC40Value(c40, shiftValue, asciiValue, fnc1));
} }
} }
} }
if ((c40Values.size() % 3) != 0) { if ((c40Values.size() % 3) != 0) {
assert (c40Values.size() - 2) % 3 == 0 && fromPosition + characterLength == input.length(); assert (c40Values.size() - 2) % 3 == 0 && fromPosition + characterLength == input.length();
c40Values.add(Byte.valueOf((byte) 0)); // pad with 0 (Shift 1) c40Values.add((byte) 0); // pad with 0 (Shift 1)
} }
byte[] result = new byte[c40Values.size() / 3 * 2]; byte[] result = new byte[c40Values.size() / 3 * 2];
int byteIndex = 0; int byteIndex = 0;
for (int i = 0; i < c40Values.size(); i += 3) { for (int i = 0; i < c40Values.size(); i += 3) {
setC40Word(result,byteIndex,c40Values.get(i).byteValue() & 0xff, setC40Word(result,byteIndex, c40Values.get(i) & 0xff, c40Values.get(i + 1) & 0xff, c40Values.get(i + 2) & 0xff);
c40Values.get(i + 1).byteValue() & 0xff,
c40Values.get(i + 2).byteValue() & 0xff);
byteIndex += 2; byteIndex += 2;
} }
return result; return result;
@ -887,7 +852,6 @@ public final class MinimalEncoder {
} }
byte[] getLatchBytes() { byte[] getLatchBytes() {
byte[] result;
switch (getPreviousMode()) { switch (getPreviousMode()) {
case ASCII: case ASCII:
case B256: //after B256 ends (via length) we are back to ASCII case B256: //after B256 ends (via length) we are back to ASCII
@ -933,7 +897,6 @@ public final class MinimalEncoder {
// Important: The function does not return the length bytes (one or two) in case of B256 encoding // Important: The function does not return the length bytes (one or two) in case of B256 encoding
byte[] getDataBytes() { byte[] getDataBytes() {
byte[] result;
switch (mode) { switch (mode) {
case ASCII: case ASCII:
if (input.isECI(fromPosition)) { if (input.isECI(fromPosition)) {
@ -965,16 +928,14 @@ public final class MinimalEncoder {
private static final class Result { private static final class Result {
private final Input input;
private final byte[] bytes; private final byte[] bytes;
Result(Edge solution) { Result(Edge solution) {
this.input = solution.input; Input input = solution.input;
int length = 0;
int size = 0; int size = 0;
List<Byte> bytesAL = new ArrayList(); List<Byte> bytesAL = new ArrayList<>();
List<Integer> randomizePostfixLength = new ArrayList(); List<Integer> randomizePostfixLength = new ArrayList<>();
List<Integer> randomizeLengths = new ArrayList(); List<Integer> randomizeLengths = new ArrayList<>();
if ((solution.mode == Mode.C40 || if ((solution.mode == Mode.C40 ||
solution.mode == Mode.TEXT || solution.mode == Mode.TEXT ||
solution.mode == Mode.X12) && solution.mode == Mode.X12) &&
@ -983,41 +944,38 @@ public final class MinimalEncoder {
} }
Edge current = solution; Edge current = solution;
while (current != null) { while (current != null) {
length += current.characterLength;
size += prepend(current.getDataBytes(),bytesAL); size += prepend(current.getDataBytes(),bytesAL);
if (current.previous == null || current.getPreviousStartMode() != current.getMode()) { if (current.previous == null || current.getPreviousStartMode() != current.getMode()) {
if (current.getMode() == Mode.B256) { if (current.getMode() == Mode.B256) {
if (size <= 249) { if (size <= 249) {
bytesAL.add(0, Byte.valueOf((byte) size)); bytesAL.add(0, (byte) size);
size++; size++;
} else { } else {
bytesAL.add(0, Byte.valueOf((byte) (size % 250))); bytesAL.add(0, (byte) (size % 250));
bytesAL.add(0, Byte.valueOf((byte) (size / 250 + 249))); bytesAL.add(0, (byte) (size / 250 + 249));
size += 2; size += 2;
} }
randomizePostfixLength.add(Integer.valueOf(bytesAL.size())); randomizePostfixLength.add(bytesAL.size());
randomizeLengths.add(Integer.valueOf(size)); randomizeLengths.add(size);
} }
size += prepend(current.getLatchBytes(), bytesAL); prepend(current.getLatchBytes(), bytesAL);
length = 0;
size = 0; size = 0;
} }
current = current.previous; current = current.previous;
} }
if (input.getMacroId() == 5) { if (input.getMacroId() == 5) {
size += prepend(MinimalEncoder.Edge.getBytes(236),bytesAL); size += prepend(MinimalEncoder.Edge.getBytes(236), bytesAL);
} else if (input.getMacroId() == 6) { } else if (input.getMacroId() == 6) {
size += prepend(MinimalEncoder.Edge.getBytes(237),bytesAL); size += prepend(MinimalEncoder.Edge.getBytes(237), bytesAL);
} }
if (input.getFNC1Character() > 0) { if (input.getFNC1Character() > 0) {
size += prepend(MinimalEncoder.Edge.getBytes(232),bytesAL); size += prepend(MinimalEncoder.Edge.getBytes(232), bytesAL);
} }
for (int i = 0; i < randomizePostfixLength.size(); i++) { for (int i = 0; i < randomizePostfixLength.size(); i++) {
applyRandomPattern(bytesAL,bytesAL.size() - randomizePostfixLength.get(i).intValue(), applyRandomPattern(bytesAL,bytesAL.size() - randomizePostfixLength.get(i), randomizeLengths.get(i));
randomizeLengths.get(i).intValue());
} }
//add padding //add padding
int capacity = solution.getMinSymbolSize(bytesAL.size()); int capacity = solution.getMinSymbolSize(bytesAL.size());
@ -1030,13 +988,13 @@ public final class MinimalEncoder {
bytes = new byte[bytesAL.size()]; bytes = new byte[bytesAL.size()];
for (int i = 0; i < bytes.length; i++) { for (int i = 0; i < bytes.length; i++) {
bytes[i] = bytesAL.get(i).byteValue(); bytes[i] = bytesAL.get(i);
} }
} }
static int prepend(byte[] bytes, List<Byte> into) { static int prepend(byte[] bytes, List<Byte> into) {
for (int i = bytes.length - 1; i >= 0; i--) { for (int i = bytes.length - 1; i >= 0; i--) {
into.add(0, Byte.valueOf(bytes[i])); into.add(0, bytes[i]);
} }
return bytes.length; return bytes.length;
} }
@ -1054,9 +1012,7 @@ public final class MinimalEncoder {
int Pad_codeword_value = bytesAL.get(Pad_codeword_position) & 0xff; int Pad_codeword_value = bytesAL.get(Pad_codeword_position) & 0xff;
int pseudo_random_number = ((149 * (Pad_codeword_position + 1)) % 255) + 1; int pseudo_random_number = ((149 * (Pad_codeword_position + 1)) % 255) + 1;
int temp_variable = Pad_codeword_value + pseudo_random_number; int temp_variable = Pad_codeword_value + pseudo_random_number;
bytesAL.set(Pad_codeword_position, Byte.valueOf((byte) (temp_variable <= 255 ? bytesAL.set(Pad_codeword_position, (byte) (temp_variable <= 255 ? temp_variable : temp_variable - 256));
temp_variable :
temp_variable - 256)));
} }
} }
@ -1064,17 +1020,11 @@ public final class MinimalEncoder {
return bytes; return bytes;
} }
/**
* @return the size in bytes
*/
int getSize() {
return bytes.length;
}
} }
private static final class Input { private static final class Input {
private static final int COST_PER_ECI = 3; //aproximated (latch to ASCII + 2 codewords) private static final int COST_PER_ECI = 3; // approximated (latch to ASCII + 2 codewords)
private final int[] bytes; private final int[] bytes;
private final int fnc1; private final int fnc1;
private final SymbolShapeHint shape; private final SymbolShapeHint shape;
@ -1108,14 +1058,6 @@ public final class MinimalEncoder {
return shape; return shape;
} }
String encode(int startPos, int length, Charset charset) {
byte[] bs = new byte[length];
for (int i = 0; i < length; i++) {
bs[i] = (byte) charAt(startPos + i);
}
return new String(bs, charset);
}
private int length() { private int length() {
return bytes.length; return bytes.length;
} }
@ -1213,16 +1155,15 @@ public final class MinimalEncoder {
if (minimalJ < 0) { if (minimalJ < 0) {
throw new RuntimeException("Internal error: failed to encode \"" + stringToEncode + "\""); throw new RuntimeException("Internal error: failed to encode \"" + stringToEncode + "\"");
} }
List<Integer> intsAL = new ArrayList(); List<Integer> intsAL = new ArrayList<>();
InputEdge current = edges[inputLength][minimalJ]; InputEdge current = edges[inputLength][minimalJ];
while (current != null) { while (current != null) {
if (current.isFNC1()) { if (current.isFNC1()) {
intsAL.add(0, 1000); intsAL.add(0, 1000);
} else { } else {
byte[] bytes = encoderSet.encode(current.c,current.encoderIndex); byte[] bytes = encoderSet.encode(current.c,current.encoderIndex);
int infoValue = bytes.length * 10 + bytes.length;
for (int i = bytes.length - 1; i >= 0; i--) { for (int i = bytes.length - 1; i >= 0; i--) {
intsAL.add(0, (int) (bytes[i] & 0xff)); intsAL.add(0, (bytes[i] & 0xFF));
} }
} }
int previousEncoderIndex = current.previous == null ? 0 : current.previous.encoderIndex; int previousEncoderIndex = current.previous == null ? 0 : current.previous.encoderIndex;
@ -1233,14 +1174,14 @@ public final class MinimalEncoder {
} }
int[] ints = new int[intsAL.size()]; int[] ints = new int[intsAL.size()];
for (int i = 0; i < ints.length; i++) { for (int i = 0; i < ints.length; i++) {
ints[i] = intsAL.get(i).intValue(); ints[i] = intsAL.get(i);
} }
return ints; return ints;
} }
private static final class InputEdge { private static final class InputEdge {
private final char c; private final char c;
private int encoderIndex; //the encoding of this edge private final int encoderIndex; //the encoding of this edge
private final InputEdge previous; private final InputEdge previous;
private final int cachedTotalSize; private final int cachedTotalSize;
@ -1264,28 +1205,6 @@ public final class MinimalEncoder {
return c == 1000; return c == 1000;
} }
private int getFromPosition() {
int cnt = 0;
InputEdge current = previous;
while (current != null) {
cnt++;
current = current.previous;
}
return cnt;
}
private String getPreviousEncoding(ECIEncoderSet encoderSet) {
return previous == null ? "ISO-8859-1" : previous.getEncoding(encoderSet);
}
private String getEncoding(ECIEncoderSet encoderSet) {
return encoderSet.getCharsetName(encoderIndex);
}
boolean changesEncoding() {
return previous == null && encoderIndex != 0 || previous != null && previous.encoderIndex != encoderIndex;
}
} }
} }
} }

View file

@ -78,7 +78,7 @@ public final class Code128Writer extends OneDimensionalCodeWriter {
boolean hasCompactionHint = hints != null && hints.containsKey(EncodeHintType.CODE128_COMPACT) && boolean hasCompactionHint = hints != null && hints.containsKey(EncodeHintType.CODE128_COMPACT) &&
Boolean.parseBoolean(hints.get(EncodeHintType.CODE128_COMPACT).toString()); Boolean.parseBoolean(hints.get(EncodeHintType.CODE128_COMPACT).toString());
return hasCompactionHint ? new MinimalEncoder().encode(contents) : encodeFast(contents, hints, forcedCodeSet); return hasCompactionHint ? new MinimalEncoder().encode(contents) : encodeFast(contents, forcedCodeSet);
} }
private static int check(String contents, Map<EncodeHintType,?> hints) { private static int check(String contents, Map<EncodeHintType,?> hints) {
@ -152,7 +152,7 @@ public final class Code128Writer extends OneDimensionalCodeWriter {
return forcedCodeSet; return forcedCodeSet;
} }
private static boolean[] encodeFast(String contents, Map<EncodeHintType,?> hints, int forcedCodeSet) { private static boolean[] encodeFast(String contents, int forcedCodeSet) {
int length = contents.length(); int length = contents.length();
Collection<int[]> patterns = new ArrayList<>(); // temporary storage for patterns Collection<int[]> patterns = new ArrayList<>(); // temporary storage for patterns
@ -365,9 +365,10 @@ public final class Code128Writer extends OneDimensionalCodeWriter {
/** /**
* Encodes minimally using Divide-And-Conquer with Memoization * Encodes minimally using Divide-And-Conquer with Memoization
**/ **/
private static class MinimalEncoder { private static final class MinimalEncoder {
private enum Charset { A, B, C, NONE };
private enum Latch { A, B, C, SHIFT, NONE }; private enum Charset { A, B, C, NONE }
private enum Latch { A, B, C, SHIFT, NONE }
static final String A = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_\u0000\u0001\u0002" + static final String A = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_\u0000\u0001\u0002" +
"\u0003\u0004\u0005\u0006\u0007\u0008\u0009\n\u000B\u000C\r\u000E\u000F\u0010\u0011" + "\u0003\u0004\u0005\u0006\u0007\u0008\u0009\n\u000B\u000C\r\u000E\u000F\u0010\u0011" +
@ -509,7 +510,7 @@ public final class Code128Writer extends OneDimensionalCodeWriter {
Latch minLatch = Latch.NONE; Latch minLatch = Latch.NONE;
boolean atEnd = position + 1 >= contents.length(); boolean atEnd = position + 1 >= contents.length();
final Charset[] sets = new Charset[] { Charset.A,Charset.B }; Charset[] sets = new Charset[] { Charset.A, Charset.B };
for (int i = 0; i <= 1; i++) { for (int i = 0; i <= 1; i++) {
if (canEncode(contents, sets[i], position)) { if (canEncode(contents, sets[i], position)) {
int cost = 1; int cost = 1;

View file

@ -90,9 +90,7 @@ final class MinimalEncoder {
* @param ecLevel The error correction level. * @param ecLevel The error correction level.
* @see ResultList#getVersion * @see ResultList#getVersion
*/ */
MinimalEncoder(String stringToEncode, Charset priorityCharset, boolean isGS1, MinimalEncoder(String stringToEncode, Charset priorityCharset, boolean isGS1, ErrorCorrectionLevel ecLevel) {
ErrorCorrectionLevel ecLevel) throws WriterException {
this.stringToEncode = stringToEncode; this.stringToEncode = stringToEncode;
this.isGS1 = isGS1; this.isGS1 = isGS1;
this.encoders = new ECIEncoderSet(stringToEncode, priorityCharset, -1); this.encoders = new ECIEncoderSet(stringToEncode, priorityCharset, -1);
@ -123,12 +121,12 @@ final class MinimalEncoder {
ResultList encode(Version version) throws WriterException { ResultList encode(Version version) throws WriterException {
if (version == null) { // compute minimal encoding trying the three version sizes. if (version == null) { // compute minimal encoding trying the three version sizes.
final Version[] versions = {getVersion(VersionSize.SMALL), Version[] versions = { getVersion(VersionSize.SMALL),
getVersion(VersionSize.MEDIUM), getVersion(VersionSize.MEDIUM),
getVersion(VersionSize.LARGE)}; getVersion(VersionSize.LARGE) };
ResultList[] results = {encodeSpecificVersion(versions[0]), ResultList[] results = { encodeSpecificVersion(versions[0]),
encodeSpecificVersion(versions[1]), encodeSpecificVersion(versions[1]),
encodeSpecificVersion(versions[2])}; encodeSpecificVersion(versions[2]) };
int smallestSize = Integer.MAX_VALUE; int smallestSize = Integer.MAX_VALUE;
int smallestResult = -1; int smallestResult = -1;
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
@ -370,7 +368,6 @@ final class MinimalEncoder {
// The last dimension in the array below encodes the 4 modes KANJI, ALPHANUMERIC, NUMERIC and BYTE via the // The last dimension in the array below encodes the 4 modes KANJI, ALPHANUMERIC, NUMERIC and BYTE via the
// function getCompactedOrdinal(Mode) // function getCompactedOrdinal(Mode)
@SuppressWarnings("unchecked")
Edge[][][] edges = new Edge[inputLength + 1][encoders.length()][4]; Edge[][][] edges = new Edge[inputLength + 1][encoders.length()][4];
addEdges(version, edges, 0, null); addEdges(version, edges, 0, null);

View file

@ -538,8 +538,7 @@ public final class HighLevelEncodeTestCase extends Assert {
private static String encodeHighLevel(String msg, boolean compareSizeToMinimalEncoder) { private static String encodeHighLevel(String msg, boolean compareSizeToMinimalEncoder) {
CharSequence encoded = HighLevelEncoder.encodeHighLevel(msg); CharSequence encoded = HighLevelEncoder.encodeHighLevel(msg);
CharSequence encoded2 = MinimalEncoder.encodeHighLevel(msg); CharSequence encoded2 = MinimalEncoder.encodeHighLevel(msg);
assert !compareSizeToMinimalEncoder || encoded2.length() <= encoded.length(); assertTrue(!compareSizeToMinimalEncoder || encoded2.length() <= encoded.length());
//DecodeHighLevel.decode(encoded);
return visualize(encoded); return visualize(encoded);
} }

View file

@ -130,7 +130,7 @@ public class Code128WriterTestCase extends Assert {
public void testLongCompact() throws Exception { public void testLongCompact() throws Exception {
//test longest possible input //test longest possible input
String toEncode = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; String toEncode = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
BitMatrix result = encode(toEncode, true, toEncode); encode(toEncode, true, toEncode);
} }
@Test @Test
@ -246,7 +246,7 @@ public class Code128WriterTestCase extends Assert {
int width = result.getWidth(); int width = result.getWidth();
result = encode(toEncode, true, toEncode); result = encode(toEncode, true, toEncode);
assert result.getWidth() <= width; assertTrue(result.getWidth() <= width);
} }
@ -257,7 +257,7 @@ public class Code128WriterTestCase extends Assert {
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class); Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
hints.put(EncodeHintType.FORCE_CODE_SET, "A"); hints.put(EncodeHintType.FORCE_CODE_SET, "A");
BitMatrix result = writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0, hints); writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0, hints);
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
@ -267,7 +267,7 @@ public class Code128WriterTestCase extends Assert {
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class); Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
hints.put(EncodeHintType.FORCE_CODE_SET, "B"); hints.put(EncodeHintType.FORCE_CODE_SET, "B");
BitMatrix result = writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0, hints); writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0, hints);
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
@ -277,7 +277,7 @@ public class Code128WriterTestCase extends Assert {
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class); Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
hints.put(EncodeHintType.FORCE_CODE_SET, "C"); hints.put(EncodeHintType.FORCE_CODE_SET, "C");
BitMatrix result = writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0, hints); writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0, hints);
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
@ -287,7 +287,7 @@ public class Code128WriterTestCase extends Assert {
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class); Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
hints.put(EncodeHintType.FORCE_CODE_SET, "C"); hints.put(EncodeHintType.FORCE_CODE_SET, "C");
BitMatrix result = writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0, hints); writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0, hints);
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
@ -297,7 +297,7 @@ public class Code128WriterTestCase extends Assert {
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class); Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
hints.put(EncodeHintType.FORCE_CODE_SET, "C"); hints.put(EncodeHintType.FORCE_CODE_SET, "C");
BitMatrix result = writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0, hints); writer.encode(toEncode, BarcodeFormat.CODE_128, 0, 0, hints);
} }
@Test @Test