diff --git a/src/zxing/zxing/BarcodeFormat.h b/src/zxing/zxing/BarcodeFormat.h index f9d123d..25d92a6 100644 --- a/src/zxing/zxing/BarcodeFormat.h +++ b/src/zxing/zxing/BarcodeFormat.h @@ -45,7 +45,8 @@ public: RSS_EXPANDED, UPC_A, UPC_E, - UPC_EAN_EXTENSION + UPC_EAN_EXTENSION, + ASSUME_GS1 }; BarcodeFormat(Value v) : value(v) {} diff --git a/src/zxing/zxing/DecodeHints.cpp b/src/zxing/zxing/DecodeHints.cpp index 4415918..82f5504 100644 --- a/src/zxing/zxing/DecodeHints.cpp +++ b/src/zxing/zxing/DecodeHints.cpp @@ -111,6 +111,7 @@ bool DecodeHints::containsFormat(BarcodeFormat tocheck) const { case BarcodeFormat::UPC_A: checkAgainst |= UPC_A_HINT; break; case BarcodeFormat::UPC_E: checkAgainst |= UPC_E_HINT; break; case BarcodeFormat::UPC_EAN_EXTENSION: checkAgainst |= UPC_EAN_EXTENSION_HINT; break; + case BarcodeFormat::ASSUME_GS1: checkAgainst |= ASSUME_GS1; break; default: throw IllegalArgumentException("Unrecognizd barcode format"); } return (hints & checkAgainst) != 0; diff --git a/src/zxing/zxing/DecodeHints.h b/src/zxing/zxing/DecodeHints.h index 57b1c65..6e5da9b 100644 --- a/src/zxing/zxing/DecodeHints.h +++ b/src/zxing/zxing/DecodeHints.h @@ -57,7 +57,7 @@ class DecodeHints { static const DecodeHintType CHARACTER_SET = 1 << 30; // static const DecodeHintType ALLOWED_LENGTHS = 1 << 29; // static const DecodeHintType ASSUME_CODE_39_CHECK_DIGIT = 1 << 28; - static const DecodeHintType ASSUME_GS1 = 1 << 27; + static const DecodeHintType ASSUME_GS1 = 1 << BarcodeFormat::ASSUME_GS1; // static const DecodeHintType NEED_RESULT_POINT_CALLBACK = 1 << 26; static const DecodeHints PRODUCT_HINT; diff --git a/src/zxing/zxing/oned/Code128Reader.cpp b/src/zxing/zxing/oned/Code128Reader.cpp index 7eb7933..11009ff 100644 --- a/src/zxing/zxing/oned/Code128Reader.cpp +++ b/src/zxing/zxing/oned/Code128Reader.cpp @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include #include @@ -248,8 +250,8 @@ int Code128Reader::decodeCode(Ref row, vector& counters, int rowO } Ref Code128Reader::decodeRow(int rowNumber, Ref row) { - // boolean convertFNC1 = hints != null && hints.containsKey(DecodeHintType.ASSUME_GS1); - boolean convertFNC1 = false; + //bool convertFNC1 = activeHints.containsFormat(zxing::BarcodeFormat(zxing::BarcodeFormat::Value::ASSUME_GS1)); + bool convertFNC1 = true; vector startPatternInfo (findStartPattern(row)); int startCode = startPatternInfo[2]; int codeSet; @@ -282,6 +284,8 @@ Ref Code128Reader::decodeRow(int rowNumber, Ref row) { int checksumTotal = startCode; int multiplier = 0; bool lastCharacterWasPrintable = true; + bool upperMode = false; + bool shiftUpperMode = false; std::ostringstream oss; @@ -324,9 +328,19 @@ Ref Code128Reader::decodeRow(int rowNumber, Ref row) { case CODE_CODE_A: if (code < 64) { - result.append(1, (byte) (' ' + code)); + if (shiftUpperMode == upperMode) { + result.append(1,(byte) (' ' + code)); + } else { + result.append(1,(byte) (' ' + code + 128)); + } + shiftUpperMode = false; } else if (code < 96) { - result.append(1, (byte) (code - 64)); + if (shiftUpperMode == upperMode) { + result.append(1, (byte) (code - 64)); + } else { + result.append(1, (byte) (code + 64)); + } + shiftUpperMode = false; } else { // Don't let CODE_STOP, which always appears, affect whether whether we think the // last code was printable or not. @@ -348,8 +362,17 @@ Ref Code128Reader::decodeRow(int rowNumber, Ref row) { break; case CODE_FNC_2: case CODE_FNC_3: + break; case CODE_FNC_4_A: - // do nothing? + if (!upperMode && shiftUpperMode) { + upperMode = true; + shiftUpperMode = false; + } else if (upperMode && shiftUpperMode) { + upperMode = false; + shiftUpperMode = false; + } else { + shiftUpperMode = true; + } break; case CODE_SHIFT: isNextShifted = true; @@ -369,17 +392,41 @@ Ref Code128Reader::decodeRow(int rowNumber, Ref row) { break; case CODE_CODE_B: if (code < 96) { - result.append(1, (byte) (' ' + code)); + if (shiftUpperMode == upperMode) { + result.append(1, (byte) (' ' + code)); + } else { + result.append(1, (byte) (' ' + code + 128)); + } + shiftUpperMode = false; } else { if (code != CODE_STOP) { lastCharacterWasPrintable = false; } switch (code) { - case CODE_FNC_1: + case CODE_FNC_1: + if (convertFNC1) { + if (result.length() == 0) { + // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code + // is FNC1 then this is GS1-128. We add the symbology identifier. + result.append("]C1"); + } else { + // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS) + result.append(1, (byte) 29); + } + } + break; case CODE_FNC_2: case CODE_FNC_3: case CODE_FNC_4_B: - // do nothing? + if (!upperMode && shiftUpperMode) { + upperMode = true; + shiftUpperMode = false; + } else if (upperMode && shiftUpperMode) { + upperMode = false; + shiftUpperMode = false; + } else { + shiftUpperMode = true; + } break; case CODE_SHIFT: isNextShifted = true; @@ -412,7 +459,16 @@ Ref Code128Reader::decodeRow(int rowNumber, Ref row) { } switch (code) { case CODE_FNC_1: - // do nothing? + if (convertFNC1) { + if (result.length() == 0) { + // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code + // is FNC1 then this is GS1-128. We add the symbology identifier. + result.append("]C1"); + } else { + // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS) + result.append(1, (byte) 29); + } + } break; case CODE_CODE_A: codeSet = CODE_CODE_A; diff --git a/src/zxing/zxing/oned/OneDReader.cpp b/src/zxing/zxing/oned/OneDReader.cpp index ca0c063..906a60e 100644 --- a/src/zxing/zxing/oned/OneDReader.cpp +++ b/src/zxing/zxing/oned/OneDReader.cpp @@ -121,6 +121,7 @@ Ref OneDReader::doDecode(Ref image, DecodeHints hints) { } // Java hints stuff missing + activeHints = hints; try { // Look for a barcode @@ -145,6 +146,8 @@ Ref OneDReader::doDecode(Ref image, DecodeHints hints) { (void)re; continue; } + + activeHints = DecodeHints(); } } throw NotFoundException(); diff --git a/src/zxing/zxing/oned/OneDReader.h b/src/zxing/zxing/oned/OneDReader.h index 6043e0a..5994dae 100644 --- a/src/zxing/zxing/oned/OneDReader.h +++ b/src/zxing/zxing/oned/OneDReader.h @@ -22,6 +22,7 @@ */ #include +#include namespace zxing { namespace oned { @@ -32,6 +33,7 @@ private: protected: static const int INTEGER_MATH_SHIFT = 8; + DecodeHints activeHints; struct Range { private: diff --git a/tests/resources/code128-gs-1/26881461-c0189156-4b97-11e7-8300-caf88e2837e2.png b/tests/resources/code128-gs-1/26881461-c0189156-4b97-11e7-8300-caf88e2837e2.png new file mode 100644 index 0000000..d724f3b Binary files /dev/null and b/tests/resources/code128-gs-1/26881461-c0189156-4b97-11e7-8300-caf88e2837e2.png differ diff --git a/tests/resources/code128-gs-1/big.png b/tests/resources/code128-gs-1/big.png new file mode 100644 index 0000000..6de819e Binary files /dev/null and b/tests/resources/code128-gs-1/big.png differ diff --git a/tests/resources/code128-gs-1/small.png b/tests/resources/code128-gs-1/small.png new file mode 100644 index 0000000..7a23579 Binary files /dev/null and b/tests/resources/code128-gs-1/small.png differ