mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
Minor code changes to previous PR merges
This commit is contained in:
parent
f3f73b47d3
commit
29fbff0802
|
@ -42,7 +42,7 @@ 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",
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue