From 248c35725bd51f3215bf0c8c0f446c0228c08100 Mon Sep 17 00:00:00 2001 From: guel99 Date: Tue, 6 Sep 2022 11:09:51 +0100 Subject: [PATCH 1/5] Added field data (only implemented for QR and Datamatrix) byte array with the content readed before being submited to a specific encoding --- Source/lib/Result.cs | 23 +++++++ Source/lib/common/DecoderResult.cs | 69 +++++++++++++++++++ Source/lib/datamatrix/DataMatrixReader.cs | 2 +- .../decoder/DecodedBitStreamParser.cs | 11 ++- Source/lib/qrcode/QRCodeReader.cs | 2 +- .../qrcode/decoder/DecodedBitStreamParser.cs | 10 ++- 6 files changed, 111 insertions(+), 6 deletions(-) diff --git a/Source/lib/Result.cs b/Source/lib/Result.cs index 647dfb04..e3bed92e 100644 --- a/Source/lib/Result.cs +++ b/Source/lib/Result.cs @@ -27,6 +27,9 @@ public sealed class Result /// raw text encoded by the barcode, if applicable, otherwise null public String Text { get; private set; } + /// raw text binary representation, if applicable, otherwise null + public byte[] Data { get; private set; } + /// raw bytes encoded by the barcode, if applicable, otherwise null public byte[] RawBytes { get; private set; } @@ -72,6 +75,20 @@ public Result(String text, { } + /// + /// Initizalizes a new instance of the class. + /// + /// + /// + /// + /// + /// + public Result(String text, byte[] data, byte[] rawBytes, ResultPoint[] resultPoints, BarcodeFormat format) + : this(text, rawBytes, resultPoints, format) + { + Data = data; + } + /// /// Initializes a new instance of the class. /// @@ -112,12 +129,18 @@ public Result(String text, byte[] rawBytes, ResultPoint[] resultPoints, BarcodeF /// The format. /// The timestamp. public Result(String text, byte[] rawBytes, int numBits, ResultPoint[] resultPoints, BarcodeFormat format, long timestamp) + : this(text, null, rawBytes, numBits, resultPoints, format, timestamp) + { + } + + public Result(String text, byte[] data, byte[] rawBytes, int numBits, ResultPoint[] resultPoints, BarcodeFormat format, long timestamp) { if (text == null && rawBytes == null) { throw new ArgumentException("Text and bytes are null"); } Text = text; + Data = data; RawBytes = rawBytes; NumBits = numBits; ResultPoints = resultPoints; diff --git a/Source/lib/common/DecoderResult.cs b/Source/lib/common/DecoderResult.cs index 2782102f..8497ead6 100644 --- a/Source/lib/common/DecoderResult.cs +++ b/Source/lib/common/DecoderResult.cs @@ -42,6 +42,11 @@ public sealed class DecoderResult /// public String Text { get; private set; } + /// + /// bytes representing the encoded text field + /// + public byte[] Data { get; private set; } + /// /// list of byte segments in the result, or null if not applicable /// @@ -104,6 +109,20 @@ public DecoderResult(byte[] rawBytes, String text, List byteSegments, St } + /// + /// initilizing constructor + /// + /// + /// + /// + /// + /// + public DecoderResult(byte[] rawBytes, byte[] data, String text, List byteSegments, String ecLevel) + : this(rawBytes, text, byteSegments, ecLevel) + { + Data = data; + } + /// /// initializing constructor /// @@ -116,6 +135,22 @@ public DecoderResult(byte[] rawBytes, String text, IList byteSegments, S : this(rawBytes, text, byteSegments, ecLevel, -1, -1, symbologyModifier) { } + + /// + /// initializing constructor + /// + /// + /// + /// + /// + /// + /// + public DecoderResult(byte[] rawBytes, byte[] data, String text, IList byteSegments, String ecLevel, int symbologyModifier) + : this(rawBytes, text, byteSegments, ecLevel, -1, -1, symbologyModifier) + { + this.Data = data; + } + /// /// initializing constructor /// @@ -151,6 +186,23 @@ public DecoderResult(byte[] rawBytes, String text, IList byteSegments, S { } + /// + /// initializing constructor + /// + /// + /// + /// + /// + /// + /// + /// + /// + public DecoderResult(byte[] rawBytes, byte[] data, String text, IList byteSegments, String ecLevel, int saSequence, int saParity, int symbologyModifier) + : this(rawBytes, text, byteSegments, ecLevel, saSequence, saParity, symbologyModifier) + { + Data = data; + } + /// /// initializing constructor /// @@ -176,12 +228,29 @@ public DecoderResult(byte[] rawBytes, int numBits, String text, IList by /// /// public DecoderResult(byte[] rawBytes, int numBits, String text, IList byteSegments, String ecLevel, int saSequence, int saParity, int symbologyModifier) + : this(rawBytes, null, numBits, text, byteSegments, ecLevel, saSequence, saParity, symbologyModifier) + { + } + + /// + /// initializing constructor + /// + /// + /// + /// + /// + /// + /// + /// + /// + public DecoderResult(byte[] rawBytes, byte[] data, int numBits, String text, IList byteSegments, String ecLevel, int saSequence, int saParity, int symbologyModifier) { if (rawBytes == null && text == null) { throw new ArgumentException(); } RawBytes = rawBytes; + Data = data; NumBits = numBits; Text = text; ByteSegments = byteSegments; diff --git a/Source/lib/datamatrix/DataMatrixReader.cs b/Source/lib/datamatrix/DataMatrixReader.cs index 8ff339ad..e22d219d 100644 --- a/Source/lib/datamatrix/DataMatrixReader.cs +++ b/Source/lib/datamatrix/DataMatrixReader.cs @@ -71,7 +71,7 @@ public Result decode(BinaryBitmap image, IDictionary hin if (decoderResult == null) return null; - Result result = new Result(decoderResult.Text, decoderResult.RawBytes, points, + Result result = new Result(decoderResult.Text, decoderResult.Data, decoderResult.RawBytes, points, BarcodeFormat.DATA_MATRIX); IList byteSegments = decoderResult.ByteSegments; if (byteSegments != null) diff --git a/Source/lib/datamatrix/decoder/DecodedBitStreamParser.cs b/Source/lib/datamatrix/decoder/DecodedBitStreamParser.cs index 5f6ab1a0..be54910a 100644 --- a/Source/lib/datamatrix/decoder/DecodedBitStreamParser.cs +++ b/Source/lib/datamatrix/decoder/DecodedBitStreamParser.cs @@ -86,6 +86,7 @@ internal static DecoderResult decode(byte[] bytes) { BitSource bits = new BitSource(bytes); ECIStringBuilder result = new ECIStringBuilder(100); + byte[] encodedResult = new byte[100]; StringBuilder resultTrailer = new StringBuilder(0); List byteSegments = new List(1); Mode mode = Mode.ASCII_ENCODE; @@ -120,7 +121,7 @@ internal static DecoderResult decode(byte[] bytes) return null; break; case Mode.BASE256_ENCODE: - if (!decodeBase256Segment(bits, result, byteSegments)) + if (!decodeBase256Segment(bits, out encodedResult, result, byteSegments)) return null; break; case Mode.ECI_ENCODE: @@ -169,7 +170,7 @@ internal static DecoderResult decode(byte[] bytes) symbologyModifier = 1; } } - return new DecoderResult(bytes, result.ToString(), byteSegments.Count == 0 ? null : byteSegments, null, symbologyModifier); + return new DecoderResult(bytes, encodedResult, result.ToString(), byteSegments.Count == 0 ? null : byteSegments, null, symbologyModifier); } /// @@ -649,9 +650,11 @@ private static bool decodeEdifactSegment(BitSource bits, ECIStringBuilder result /// See ISO 16022:2006, 5.2.9 and Annex B, B.2 /// private static bool decodeBase256Segment(BitSource bits, + out byte[] encodedResult, ECIStringBuilder result, IList byteSegments) { + encodedResult = null; // Figure out how long the Base 256 Segment is. int codewordPosition = 1 + bits.ByteOffset; // position is 1-indexed int d1 = unrandomize255State(bits.readBits(8), codewordPosition++); @@ -688,6 +691,7 @@ private static bool decodeBase256Segment(BitSource bits, bytes[i] = (byte)unrandomize255State(bits.readBits(8), codewordPosition++); } byteSegments.Add(bytes); + try { #if (NETFX_CORE || PORTABLE || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2) @@ -701,6 +705,9 @@ private static bool decodeBase256Segment(BitSource bits, throw new InvalidOperationException("Platform does not support required encoding: " + uee); } + encodedResult = new byte[bytes.Length]; + Array.Copy(bytes, encodedResult, bytes.Length); + return true; } diff --git a/Source/lib/qrcode/QRCodeReader.cs b/Source/lib/qrcode/QRCodeReader.cs index 82cce52c..151ad87c 100644 --- a/Source/lib/qrcode/QRCodeReader.cs +++ b/Source/lib/qrcode/QRCodeReader.cs @@ -98,7 +98,7 @@ public Result decode(BinaryBitmap image, IDictionary hin data.applyMirroredCorrection(points); } - var result = new Result(decoderResult.Text, decoderResult.RawBytes, points, BarcodeFormat.QR_CODE); + var result = new Result(decoderResult.Text, decoderResult.Data, decoderResult.RawBytes, points, BarcodeFormat.QR_CODE); var byteSegments = decoderResult.ByteSegments; if (byteSegments != null) { diff --git a/Source/lib/qrcode/decoder/DecodedBitStreamParser.cs b/Source/lib/qrcode/decoder/DecodedBitStreamParser.cs index 1a59b539..2be7b2e7 100644 --- a/Source/lib/qrcode/decoder/DecodedBitStreamParser.cs +++ b/Source/lib/qrcode/decoder/DecodedBitStreamParser.cs @@ -43,6 +43,7 @@ internal static DecoderResult decode(byte[] bytes, { var bits = new BitSource(bytes); var result = new StringBuilder(50); + var encodedResult = new byte[50]; var byteSegments = new List(1); var symbolSequence = -1; var parityData = -1; @@ -133,7 +134,7 @@ internal static DecoderResult decode(byte[] bytes, return null; break; case Mode.Names.BYTE: - if (!decodeByteSegment(bits, result, count, currentCharacterSetECI, byteSegments, hints)) + if (!decodeByteSegment(bits, result, out encodedResult, count, currentCharacterSetECI, byteSegments, hints)) return null; break; case Mode.Names.KANJI: @@ -184,7 +185,7 @@ internal static DecoderResult decode(byte[] bytes, return null; } - return new DecoderResult(bytes, + return new DecoderResult(bytes, encodedResult, result.ToString(), byteSegments.Count == 0 ? null : byteSegments, ecLevel == null ? null : ecLevel.ToString(), @@ -288,11 +289,13 @@ private static bool decodeKanjiSegment(BitSource bits, private static bool decodeByteSegment(BitSource bits, StringBuilder result, + out byte[] encodedResult, int count, CharacterSetECI currentCharacterSetECI, IList byteSegments, IDictionary hints) { + encodedResult = null; // Don't crash trying to read more bits than we have available. if (count << 3 > bits.available()) { @@ -324,6 +327,9 @@ private static bool decodeByteSegment(BitSource bits, } result.Append(encoding.GetString(readBytes, 0, readBytes.Length)); + encodedResult = new byte[readBytes.Length]; + Array.Copy(readBytes, encodedResult, readBytes.Length); + byteSegments.Add(readBytes); return true; From 40d23e036d38969cb790597d62aca7c21c8a4702 Mon Sep 17 00:00:00 2001 From: guel99 Date: Wed, 7 Sep 2022 11:08:00 +0100 Subject: [PATCH 2/5] Build encodedData (byte array) at the same time we build result (text) for QR and Datamatrix -> corrected ADD-HOC solution --- .../decoder/DecodedBitStreamParser.cs | 66 ++++++++++++++----- .../qrcode/decoder/DecodedBitStreamParser.cs | 53 +++++++++++---- 2 files changed, 92 insertions(+), 27 deletions(-) diff --git a/Source/lib/datamatrix/decoder/DecodedBitStreamParser.cs b/Source/lib/datamatrix/decoder/DecodedBitStreamParser.cs index be54910a..e45bb389 100644 --- a/Source/lib/datamatrix/decoder/DecodedBitStreamParser.cs +++ b/Source/lib/datamatrix/decoder/DecodedBitStreamParser.cs @@ -16,6 +16,7 @@ using System; using System.Collections.Generic; +using System.IO; using System.Text; using ZXing.Common; @@ -86,7 +87,7 @@ internal static DecoderResult decode(byte[] bytes) { BitSource bits = new BitSource(bytes); ECIStringBuilder result = new ECIStringBuilder(100); - byte[] encodedResult = new byte[100]; + MemoryStream encodedResult = new MemoryStream(); StringBuilder resultTrailer = new StringBuilder(0); List byteSegments = new List(1); Mode mode = Mode.ASCII_ENCODE; @@ -97,7 +98,7 @@ internal static DecoderResult decode(byte[] bytes) { if (mode == Mode.ASCII_ENCODE) { - if (!decodeAsciiSegment(bits, result, resultTrailer, fnc1Positions, out mode)) + if (!decodeAsciiSegment(bits, encodedResult, result, resultTrailer, fnc1Positions, out mode)) return null; } else @@ -105,23 +106,23 @@ internal static DecoderResult decode(byte[] bytes) switch (mode) { case Mode.C40_ENCODE: - if (!decodeC40Segment(bits, result, fnc1Positions)) + if (!decodeC40Segment(bits, encodedResult, result, fnc1Positions)) return null; break; case Mode.TEXT_ENCODE: - if (!decodeTextSegment(bits, result, fnc1Positions)) + if (!decodeTextSegment(bits, encodedResult, result, fnc1Positions)) return null; break; case Mode.ANSIX12_ENCODE: - if (!decodeAnsiX12Segment(bits, result)) + if (!decodeAnsiX12Segment(bits, encodedResult, result)) return null; break; case Mode.EDIFACT_ENCODE: - if (!decodeEdifactSegment(bits, result)) + if (!decodeEdifactSegment(bits, encodedResult, result)) return null; break; case Mode.BASE256_ENCODE: - if (!decodeBase256Segment(bits, out encodedResult, result, byteSegments)) + if (!decodeBase256Segment(bits, encodedResult, result, byteSegments)) return null; break; case Mode.ECI_ENCODE: @@ -137,6 +138,8 @@ internal static DecoderResult decode(byte[] bytes) if (resultTrailer.Length > 0) { result.Append(resultTrailer.ToString()); + var resultTrailerBytes = Encoding.UTF8.GetBytes(resultTrailer.ToString()); + encodedResult.Write(resultTrailerBytes, 0, resultTrailerBytes.Length); } if (isECIencoded) { @@ -170,13 +173,14 @@ internal static DecoderResult decode(byte[] bytes) symbologyModifier = 1; } } - return new DecoderResult(bytes, encodedResult, result.ToString(), byteSegments.Count == 0 ? null : byteSegments, null, symbologyModifier); + return new DecoderResult(bytes, encodedResult.ToArray(), result.ToString(), byteSegments.Count == 0 ? null : byteSegments, null, symbologyModifier); } /// /// See ISO 16022:2006, 5.2.3 and Annex C, Table C.2 /// private static bool decodeAsciiSegment(BitSource bits, + MemoryStream encodedResult, ECIStringBuilder result, StringBuilder resultTrailer, List fnc1positions, @@ -199,6 +203,7 @@ private static bool decodeAsciiSegment(BitSource bits, oneByte += 128; //upperShift = false; } + encodedResult.WriteByte((byte) (oneByte - 1)); result.Append((char)(oneByte - 1)); mode = Mode.ASCII_ENCODE; return true; @@ -216,8 +221,10 @@ private static bool decodeAsciiSegment(BitSource bits, if (value < 10) { // pad with '0' for single digit values + encodedResult.WriteByte((byte)48); // ASCII representation of byte 48 is the caracter '0' result.Append('0'); } + encodedResult.WriteByte((byte)value); result.Append(value); } else @@ -233,6 +240,7 @@ private static bool decodeAsciiSegment(BitSource bits, case 232: // FNC1 fnc1positions.Add(result.Length); result.Append((char)29); // translate as ASCII 29 + encodedResult.WriteByte((byte)29); break; case 233: // Structured Append case 234: // Reader Programming @@ -244,10 +252,14 @@ private static bool decodeAsciiSegment(BitSource bits, break; case 236: // 05 Macro result.Append("[)>\u001E05\u001D"); + byte[] macro05 = Encoding.UTF8.GetBytes("[)>\u001E05\u001D"); + encodedResult.Write(macro05, 0, macro05.Length); resultTrailer.Insert(0, "\u001E\u0004"); break; case 237: // 06 Macro result.Append("[)>\u001E06\u001D"); + byte[] macro06 = Encoding.UTF8.GetBytes("[)>\u001E06\u001D"); + encodedResult.Write(macro06, 0, macro06.Length); resultTrailer.Insert(0, "\u001E\u0004"); break; case 238: // Latch to ANSI X12 encodation @@ -280,7 +292,7 @@ private static bool decodeAsciiSegment(BitSource bits, /// /// See ISO 16022:2006, 5.2.5 and Annex C, Table C.1 /// - private static bool decodeC40Segment(BitSource bits, ECIStringBuilder result, List fnc1positions) + private static bool decodeC40Segment(BitSource bits, MemoryStream encodedResult, ECIStringBuilder result, List fnc1positions) { // Three C40 values are encoded in a 16-bit value as // (1600 * C1) + (40 * C2) + C3 + 1 @@ -322,11 +334,13 @@ private static bool decodeC40Segment(BitSource bits, ECIStringBuilder result, Li if (upperShift) { result.Append((char)(c40char + 128)); + encodedResult.WriteByte((byte)(c40char + 128)); upperShift = false; } else { result.Append(c40char); + encodedResult.WriteByte((byte)c40char); } } else @@ -338,11 +352,13 @@ private static bool decodeC40Segment(BitSource bits, ECIStringBuilder result, Li if (upperShift) { result.Append((char)(cValue + 128)); + encodedResult.WriteByte((byte)(cValue + 128)); upperShift = false; } else { result.Append((char)cValue); + encodedResult.WriteByte((byte)cValue); } shift = 0; break; @@ -353,11 +369,13 @@ private static bool decodeC40Segment(BitSource bits, ECIStringBuilder result, Li if (upperShift) { result.Append((char)(c40char + 128)); + encodedResult.WriteByte((byte)(c40char + 128)); upperShift = false; } else { result.Append(c40char); + encodedResult.WriteByte((byte)c40char); } } else @@ -367,6 +385,7 @@ private static bool decodeC40Segment(BitSource bits, ECIStringBuilder result, Li case 27: // FNC1 fnc1positions.Add(result.Length); result.Append((char)29); // translate as ASCII 29 + encodedResult.WriteByte((byte)29); break; case 30: // Upper Shift upperShift = true; @@ -381,11 +400,13 @@ private static bool decodeC40Segment(BitSource bits, ECIStringBuilder result, Li if (upperShift) { result.Append((char)(cValue + 224)); + encodedResult.WriteByte((byte)(cValue + 224)); upperShift = false; } else { result.Append((char)(cValue + 96)); + encodedResult.WriteByte((byte)(cValue + 96)); } shift = 0; break; @@ -401,7 +422,7 @@ private static bool decodeC40Segment(BitSource bits, ECIStringBuilder result, Li /// /// See ISO 16022:2006, 5.2.6 and Annex C, Table C.2 /// - private static bool decodeTextSegment(BitSource bits, ECIStringBuilder result, List fnc1positions) + private static bool decodeTextSegment(BitSource bits, MemoryStream encodedResult, ECIStringBuilder result, List fnc1positions) { // Three Text values are encoded in a 16-bit value as // (1600 * C1) + (40 * C2) + C3 + 1 @@ -442,11 +463,13 @@ private static bool decodeTextSegment(BitSource bits, ECIStringBuilder result, L if (upperShift) { result.Append((char)(textChar + 128)); + encodedResult.WriteByte((byte)(textChar + 128)); upperShift = false; } else { result.Append(textChar); + encodedResult.WriteByte((byte)textChar); } } else @@ -458,11 +481,13 @@ private static bool decodeTextSegment(BitSource bits, ECIStringBuilder result, L if (upperShift) { result.Append((char)(cValue + 128)); + encodedResult.WriteByte((byte)(cValue + 128)); upperShift = false; } else { result.Append((char)cValue); + encodedResult.WriteByte((byte)cValue); } shift = 0; break; @@ -474,11 +499,13 @@ private static bool decodeTextSegment(BitSource bits, ECIStringBuilder result, L if (upperShift) { result.Append((char)(textChar + 128)); + encodedResult.WriteByte((byte)(textChar + 128)); upperShift = false; } else { result.Append(textChar); + encodedResult.WriteByte((byte)textChar); } } else @@ -488,6 +515,7 @@ private static bool decodeTextSegment(BitSource bits, ECIStringBuilder result, L case 27: // FNC1 fnc1positions.Add(result.Length); result.Append((char)29); // translate as ASCII 29 + encodedResult.WriteByte((byte)29); break; case 30: // Upper Shift upperShift = true; @@ -505,11 +533,13 @@ private static bool decodeTextSegment(BitSource bits, ECIStringBuilder result, L if (upperShift) { result.Append((char)(textChar + 128)); + encodedResult.WriteByte((byte)(textChar + 128)); upperShift = false; } else { result.Append(textChar); + encodedResult.WriteByte((byte)textChar); } shift = 0; } @@ -531,6 +561,7 @@ private static bool decodeTextSegment(BitSource bits, ECIStringBuilder result, L /// See ISO 16022:2006, 5.2.7 /// private static bool decodeAnsiX12Segment(BitSource bits, + MemoryStream encodedResult, ECIStringBuilder result) { // Three ANSI X12 values are encoded in a 16-bit value as @@ -560,26 +591,32 @@ private static bool decodeAnsiX12Segment(BitSource bits, { case 0: // X12 segment terminator result.Append('\r'); + encodedResult.WriteByte((byte)'\r'); break; case 1: // X12 segment separator * result.Append('*'); + encodedResult.WriteByte((byte)'*'); break; case 2: // X12 sub-element separator > result.Append('>'); + encodedResult.WriteByte((byte)'>'); break; case 3: // space result.Append(' '); + encodedResult.WriteByte((byte)' '); break; default: if (cValue < 14) { // 0 - 9 result.Append((char)(cValue + 44)); + encodedResult.WriteByte((byte)(cValue + 44)); } else if (cValue < 40) { // A - Z result.Append((char)(cValue + 51)); + encodedResult.WriteByte((byte)(cValue + 51)); } else { @@ -607,7 +644,7 @@ private static void parseTwoBytes(int firstByte, int secondByte, int[] result) /// /// See ISO 16022:2006, 5.2.8 and Annex C Table C.3 /// - private static bool decodeEdifactSegment(BitSource bits, ECIStringBuilder result) + private static bool decodeEdifactSegment(BitSource bits, MemoryStream encodedResult, ECIStringBuilder result) { do { @@ -640,6 +677,7 @@ private static bool decodeEdifactSegment(BitSource bits, ECIStringBuilder result edifactValue |= 0x40; // Add a leading 01 to the 6 bit binary value } result.Append((char)edifactValue); + encodedResult.WriteByte((byte)edifactValue); } } while (bits.available() > 0); @@ -650,11 +688,10 @@ private static bool decodeEdifactSegment(BitSource bits, ECIStringBuilder result /// See ISO 16022:2006, 5.2.9 and Annex B, B.2 /// private static bool decodeBase256Segment(BitSource bits, - out byte[] encodedResult, + MemoryStream encodedResult, ECIStringBuilder result, IList byteSegments) { - encodedResult = null; // Figure out how long the Base 256 Segment is. int codewordPosition = 1 + bits.ByteOffset; // position is 1-indexed int d1 = unrandomize255State(bits.readBits(8), codewordPosition++); @@ -705,8 +742,7 @@ private static bool decodeBase256Segment(BitSource bits, throw new InvalidOperationException("Platform does not support required encoding: " + uee); } - encodedResult = new byte[bytes.Length]; - Array.Copy(bytes, encodedResult, bytes.Length); + encodedResult.Write(bytes, 0, bytes.Length); return true; } diff --git a/Source/lib/qrcode/decoder/DecodedBitStreamParser.cs b/Source/lib/qrcode/decoder/DecodedBitStreamParser.cs index 2be7b2e7..b50fcf19 100644 --- a/Source/lib/qrcode/decoder/DecodedBitStreamParser.cs +++ b/Source/lib/qrcode/decoder/DecodedBitStreamParser.cs @@ -16,6 +16,8 @@ using System; using System.Collections.Generic; +using System.IO; +using System.Linq; using System.Text; using ZXing.Common; @@ -43,7 +45,7 @@ internal static DecoderResult decode(byte[] bytes, { var bits = new BitSource(bytes); var result = new StringBuilder(50); - var encodedResult = new byte[50]; + var encodedResult = new MemoryStream(); var byteSegments = new List(1); var symbolSequence = -1; var parityData = -1; @@ -115,7 +117,7 @@ internal static DecoderResult decode(byte[] bytes, int countHanzi = bits.readBits(mode.getCharacterCountBits(version)); if (subset == GB2312_SUBSET) { - if (!decodeHanziSegment(bits, result, countHanzi)) + if (!decodeHanziSegment(bits, encodedResult, result, countHanzi)) return null; } break; @@ -126,19 +128,19 @@ internal static DecoderResult decode(byte[] bytes, switch (mode.Name) { case Mode.Names.NUMERIC: - if (!decodeNumericSegment(bits, result, count)) + if (!decodeNumericSegment(bits, encodedResult, result, count)) return null; break; case Mode.Names.ALPHANUMERIC: - if (!decodeAlphanumericSegment(bits, result, count, fc1InEffect)) + if (!decodeAlphanumericSegment(bits, encodedResult, result, count, fc1InEffect)) return null; break; case Mode.Names.BYTE: - if (!decodeByteSegment(bits, result, out encodedResult, count, currentCharacterSetECI, byteSegments, hints)) + if (!decodeByteSegment(bits, encodedResult, result, count, currentCharacterSetECI, byteSegments, hints)) return null; break; case Mode.Names.KANJI: - if (!decodeKanjiSegment(bits, result, count)) + if (!decodeKanjiSegment(bits, encodedResult, result, count)) return null; break; default: @@ -185,7 +187,7 @@ internal static DecoderResult decode(byte[] bytes, return null; } - return new DecoderResult(bytes, encodedResult, + return new DecoderResult(bytes, encodedResult.ToArray(), result.ToString(), byteSegments.Count == 0 ? null : byteSegments, ecLevel == null ? null : ecLevel.ToString(), @@ -200,6 +202,7 @@ internal static DecoderResult decode(byte[] bytes, /// The count. /// private static bool decodeHanziSegment(BitSource bits, + MemoryStream encodedResult, StringBuilder result, int count) { @@ -239,11 +242,13 @@ private static bool decodeHanziSegment(BitSource bits, encoding = StringUtils.PLATFORM_DEFAULT_ENCODING_T; result.Append(encoding.GetString(buffer, 0, buffer.Length)); + encodedResult.Write(buffer, 0, buffer.Length); return true; } private static bool decodeKanjiSegment(BitSource bits, + MemoryStream encodedResult, StringBuilder result, int count) { @@ -283,19 +288,19 @@ private static bool decodeKanjiSegment(BitSource bits, encoding = StringUtils.PLATFORM_DEFAULT_ENCODING_T; result.Append(encoding.GetString(buffer, 0, buffer.Length)); + encodedResult.Write(buffer, 0, buffer.Length); return true; } private static bool decodeByteSegment(BitSource bits, + MemoryStream encodedResult, StringBuilder result, - out byte[] encodedResult, int count, CharacterSetECI currentCharacterSetECI, IList byteSegments, IDictionary hints) { - encodedResult = null; // Don't crash trying to read more bits than we have available. if (count << 3 > bits.available()) { @@ -326,9 +331,7 @@ private static bool decodeByteSegment(BitSource bits, encoding = StringUtils.PLATFORM_DEFAULT_ENCODING_T; } result.Append(encoding.GetString(readBytes, 0, readBytes.Length)); - - encodedResult = new byte[readBytes.Length]; - Array.Copy(readBytes, encodedResult, readBytes.Length); + encodedResult.Write(readBytes, 0, readBytes.Length); byteSegments.Add(readBytes); @@ -345,6 +348,7 @@ private static char toAlphaNumericChar(int value) } private static bool decodeAlphanumericSegment(BitSource bits, + MemoryStream encodedResult, StringBuilder result, int count, bool fc1InEffect) @@ -359,7 +363,11 @@ private static bool decodeAlphanumericSegment(BitSource bits, } int nextTwoCharsBits = bits.readBits(11); result.Append(toAlphaNumericChar(nextTwoCharsBits / 45)); + encodedResult.WriteByte((byte)(nextTwoCharsBits / 45)); + result.Append(toAlphaNumericChar(nextTwoCharsBits % 45)); + encodedResult.WriteByte((byte)(nextTwoCharsBits % 45)); + count -= 2; } if (count == 1) @@ -370,8 +378,14 @@ private static bool decodeAlphanumericSegment(BitSource bits, return false; } result.Append(toAlphaNumericChar(bits.readBits(6))); + encodedResult.WriteByte((byte)(bits.readBits(6))); } +#if NET20 + var encodedResultList = new List(encodedResult.ToArray()); +#else + var encodedResultList = encodedResult.ToArray().ToList(); +#endif // See section 6.4.8.1, 6.4.8.2 if (fc1InEffect) { @@ -384,21 +398,27 @@ private static bool decodeAlphanumericSegment(BitSource bits, { // %% is rendered as % result.Remove(i + 1, 1); + encodedResultList.RemoveAt(i + 1); } else { // In alpha mode, % should be converted to FNC1 separator 0x1D result.Remove(i, 1); + encodedResultList.RemoveAt(i); + result.Insert(i, new[] { (char)0x1D }); + encodedResultList.Insert(i, (byte)0x1D ); } } } + encodedResult = new MemoryStream(encodedResultList.ToArray()); } return true; } private static bool decodeNumericSegment(BitSource bits, + MemoryStream encodedResult, StringBuilder result, int count) { @@ -416,8 +436,13 @@ private static bool decodeNumericSegment(BitSource bits, return false; } result.Append(toAlphaNumericChar(threeDigitsBits / 100)); + encodedResult.WriteByte((byte)(threeDigitsBits / 100)); + result.Append(toAlphaNumericChar((threeDigitsBits / 10) % 10)); + encodedResult.WriteByte((byte)((threeDigitsBits / 10) % 10)); + result.Append(toAlphaNumericChar(threeDigitsBits % 10)); + encodedResult.WriteByte((byte)(threeDigitsBits % 10)); count -= 3; } @@ -434,7 +459,10 @@ private static bool decodeNumericSegment(BitSource bits, return false; } result.Append(toAlphaNumericChar(twoDigitsBits / 10)); + encodedResult.WriteByte((byte)(twoDigitsBits / 10)); + result.Append(toAlphaNumericChar(twoDigitsBits % 10)); + encodedResult.WriteByte((byte)(twoDigitsBits % 10)); } else if (count == 1) { @@ -449,6 +477,7 @@ private static bool decodeNumericSegment(BitSource bits, return false; } result.Append(toAlphaNumericChar(digitBits)); + encodedResult.WriteByte((byte)digitBits); } return true; From cba506f8b726c06638f21b0b6e69126379264081 Mon Sep 17 00:00:00 2001 From: guel99 Date: Thu, 8 Sep 2022 10:55:13 +0100 Subject: [PATCH 3/5] The same alteration for aztec code --- Source/lib/Result.cs | 20 ++++++++++++++++++++ Source/lib/aztec/AztecReader.cs | 2 +- Source/lib/aztec/decoder/Decoder.cs | 19 ++++++++++++------- Source/lib/common/DecoderResult.cs | 20 ++++++++++++++++++-- 4 files changed, 51 insertions(+), 10 deletions(-) diff --git a/Source/lib/Result.cs b/Source/lib/Result.cs index e3bed92e..4e2177d0 100644 --- a/Source/lib/Result.cs +++ b/Source/lib/Result.cs @@ -106,6 +106,26 @@ public Result(String text, { } + /// + /// Initializes a new instance of the class. + /// + /// + /// + /// + /// + /// + /// + public Result(String text, + byte[] data, + byte[] rawBytes, + int numBits, + ResultPoint[] resultPoints, + BarcodeFormat format) + : this(text,rawBytes, numBits, resultPoints, format) + { + this.Data = data; + } + /// /// Initializes a new instance of the class. /// diff --git a/Source/lib/aztec/AztecReader.cs b/Source/lib/aztec/AztecReader.cs index bbef8ab1..e4834ef7 100644 --- a/Source/lib/aztec/AztecReader.cs +++ b/Source/lib/aztec/AztecReader.cs @@ -92,7 +92,7 @@ public Result decode(BinaryBitmap image, IDictionary hin } } - var result = new Result(decoderResult.Text, decoderResult.RawBytes, decoderResult.NumBits, points, BarcodeFormat.AZTEC); + var result = new Result(decoderResult.Text, decoderResult.Data, decoderResult.RawBytes, decoderResult.NumBits, points, BarcodeFormat.AZTEC); IList byteSegments = decoderResult.ByteSegments; if (byteSegments != null) diff --git a/Source/lib/aztec/decoder/Decoder.cs b/Source/lib/aztec/decoder/Decoder.cs index 8864eef3..10a24474 100644 --- a/Source/lib/aztec/decoder/Decoder.cs +++ b/Source/lib/aztec/decoder/Decoder.cs @@ -16,8 +16,8 @@ using System; using System.Collections.Generic; +using System.IO; using System.Text; - using ZXing.Common; using ZXing.Common.ReedSolomon; @@ -111,13 +111,14 @@ public DecoderResult decode(AztecDetectorResult detectorResult) if (correctedBits == null) return null; - var result = getEncodedData(correctedBits.correctBits); + byte[] encodedResult; + var result = getEncodedData(correctedBits.correctBits, out encodedResult); if (result == null) return null; var rawBytes = convertBoolArrayToByteArray(correctedBits.correctBits); - var decoderResult = new DecoderResult(rawBytes, correctedBits.correctBits.Length, result, null, String.Format("{0}", correctedBits.ecLevel)); + var decoderResult = new DecoderResult(rawBytes, correctedBits.correctBits.Length, encodedResult, result, null, String.Format("{0}", correctedBits.ecLevel)); return decoderResult; } @@ -126,9 +127,9 @@ public DecoderResult decode(AztecDetectorResult detectorResult) /// /// /// - public static String highLevelDecode(bool[] correctedBits) + public static String highLevelDecode(bool[] correctedBits, out byte[] encodedResult) { - return getEncodedData(correctedBits); + return getEncodedData(correctedBits, out encodedResult); } /// @@ -136,7 +137,7 @@ public static String highLevelDecode(bool[] correctedBits) /// /// The corrected bits. /// the decoded string - private static String getEncodedData(bool[] correctedBits) + private static String getEncodedData(bool[] correctedBits, out byte[] encodedResult) { var endIndex = correctedBits.Length; var latchTable = Table.UPPER; // table most recently latched to @@ -148,6 +149,7 @@ private static String getEncodedData(bool[] correctedBits) // Final decoded string result // (correctedBits-5) / 4 is an upper bound on the size (all-digit result) var result = new StringBuilder((correctedBits.Length - 5) / 4); + var encodedResultStream = new MemoryStream(); // Intermediary buffer of decoded bytes, which is decoded into a string and flushed // when character encoding changes (ECI) or input ends. @@ -212,12 +214,14 @@ private static String getEncodedData(bool[] correctedBits) { var byteArray = decodedBytes.ToArray(); result.Append(encoding.GetString(byteArray, 0, byteArray.Length)); + encodedResultStream.Write(byteArray, 0, byteArray.Length); decodedBytes.SetLength(0); } switch (n) { case 0: result.Append((char)29); // translate FNC1 as ASCII 29 + encodedResultStream.WriteByte((byte)29); break; case 7: throw new FormatException("FLG(7) is reserved and illegal"); @@ -270,7 +274,6 @@ private static String getEncodedData(bool[] correctedBits) #if (PORTABLE || NETSTANDARD1_0 || NETSTANDARD1_1 || NETFX_CORE) var b = StringUtils.PLATFORM_DEFAULT_ENCODING_T.GetBytes(str); #else - var b = Encoding.ASCII.GetBytes(str); #endif decodedBytes.Write(b, 0, b.Length); @@ -285,7 +288,9 @@ private static String getEncodedData(bool[] correctedBits) { var byteArray = decodedBytes.ToArray(); result.Append(encoding.GetString(byteArray, 0, byteArray.Length)); + encodedResultStream.Write(byteArray, 0, byteArray.Length); } + encodedResult = encodedResultStream.ToArray(); } return result.ToString(); } diff --git a/Source/lib/common/DecoderResult.cs b/Source/lib/common/DecoderResult.cs index 8497ead6..5f8b81df 100644 --- a/Source/lib/common/DecoderResult.cs +++ b/Source/lib/common/DecoderResult.cs @@ -106,7 +106,7 @@ public bool StructuredAppend public DecoderResult(byte[] rawBytes, String text, List byteSegments, String ecLevel) : this(rawBytes, text, byteSegments, ecLevel, -1, -1, 0) { - + } /// @@ -168,7 +168,7 @@ public DecoderResult(byte[] rawBytes, int saParity) : this(rawBytes, text, byteSegments, ecLevel, saSequence, saParity, 0) { - + } /// @@ -216,6 +216,22 @@ public DecoderResult(byte[] rawBytes, int numBits, String text, IList by { } + /// + /// initializing constructor + /// + /// + /// + /// + /// + /// + /// + public DecoderResult(byte[] rawBytes, int numBits, byte[] data, String text, IList byteSegments, String ecLevel) + : this(rawBytes, numBits, text, byteSegments, ecLevel) + { + this.Data = data; + } + + /// /// initializing constructor /// From 1edf408196858fefebe8297fe09445703ffc831a Mon Sep 17 00:00:00 2001 From: guel99 Date: Thu, 8 Sep 2022 15:39:56 +0100 Subject: [PATCH 4/5] Implementation the data value for maxi code --- Source/lib/maxicode/MaxiCodeReader.cs | 2 +- Source/lib/maxicode/decoder/DecodedBitStreamParser.cs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Source/lib/maxicode/MaxiCodeReader.cs b/Source/lib/maxicode/MaxiCodeReader.cs index 2c2e90d9..b742e706 100644 --- a/Source/lib/maxicode/MaxiCodeReader.cs +++ b/Source/lib/maxicode/MaxiCodeReader.cs @@ -66,7 +66,7 @@ public Result decode(BinaryBitmap image, IDictionary hin if (decoderResult == null) return null; - var result = new Result(decoderResult.Text, decoderResult.RawBytes, NO_POINTS, BarcodeFormat.MAXICODE); + var result = new Result(decoderResult.Text, decoderResult.Data, decoderResult.RawBytes, NO_POINTS, BarcodeFormat.MAXICODE); var ecLevel = decoderResult.ECLevel; if (ecLevel != null) diff --git a/Source/lib/maxicode/decoder/DecodedBitStreamParser.cs b/Source/lib/maxicode/decoder/DecodedBitStreamParser.cs index dfb2133d..05d35afe 100644 --- a/Source/lib/maxicode/decoder/DecodedBitStreamParser.cs +++ b/Source/lib/maxicode/decoder/DecodedBitStreamParser.cs @@ -77,6 +77,8 @@ internal static DecoderResult decode(byte[] bytes, int mode) } String country = getCountry(bytes).ToString(THREE_DIGITS); String service = getServiceClass(bytes).ToString(THREE_DIGITS); + + var msg = getMessage(bytes, 10, 84); result.Append(getMessage(bytes, 10, 84)); if (result.ToString().StartsWith("[)>" + RS + "01" + GS)) { @@ -95,7 +97,7 @@ internal static DecoderResult decode(byte[] bytes, int mode) break; } - return new DecoderResult(bytes, result.ToString(), null, mode.ToString()); + return new DecoderResult(bytes, Encoding.UTF8.GetBytes(result.ToString()), result.ToString(), null, mode.ToString()); } private static int getBit(int bit, byte[] bytes) From 00388c545f09d60e992d06a46a64268b1b68318d Mon Sep 17 00:00:00 2001 From: guel99 Date: Fri, 9 Sep 2022 09:28:13 +0100 Subject: [PATCH 5/5] Corrected build error causes --- Source/lib/qrcode/decoder/DecodedBitStreamParser.cs | 2 ++ Source/test/src/aztec/decoder/DecoderTest.cs | 3 ++- Source/test/src/aztec/encoder/EncoderTest.cs | 6 ++++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Source/lib/qrcode/decoder/DecodedBitStreamParser.cs b/Source/lib/qrcode/decoder/DecodedBitStreamParser.cs index b50fcf19..7fbff3b0 100644 --- a/Source/lib/qrcode/decoder/DecodedBitStreamParser.cs +++ b/Source/lib/qrcode/decoder/DecodedBitStreamParser.cs @@ -17,7 +17,9 @@ using System; using System.Collections.Generic; using System.IO; +#if !NET20 using System.Linq; +#endif using System.Text; using ZXing.Common; diff --git a/Source/test/src/aztec/decoder/DecoderTest.cs b/Source/test/src/aztec/decoder/DecoderTest.cs index db6841cf..5f783af1 100644 --- a/Source/test/src/aztec/decoder/DecoderTest.cs +++ b/Source/test/src/aztec/decoder/DecoderTest.cs @@ -54,8 +54,9 @@ public void testHighLevelDecode() private static void testHighLevelDecodeString(String expectedString, String b) { + byte[] encodedResult; BitArray bits = EncoderTest.toBitArray(EncoderTest.stripSpace(b)); - Assert.AreEqual(expectedString, Decoder.highLevelDecode(EncoderTest.toBooleanArray(bits)), "highLevelDecode() failed for input bits: " + b); + Assert.AreEqual(expectedString, Decoder.highLevelDecode(EncoderTest.toBooleanArray(bits), out encodedResult), "highLevelDecode() failed for input bits: " + b); } [Test] diff --git a/Source/test/src/aztec/encoder/EncoderTest.cs b/Source/test/src/aztec/encoder/EncoderTest.cs index f49064d9..62267f6d 100644 --- a/Source/test/src/aztec/encoder/EncoderTest.cs +++ b/Source/test/src/aztec/encoder/EncoderTest.cs @@ -625,18 +625,20 @@ public static bool[] toBooleanArray(BitArray bitArray) private static void testHighLevelEncodeString(String s, String expectedBits) { + byte[] encodedResult; BitArray bits = new HighLevelEncoder(ISO_8859_1.GetBytes(s)).encode(); String receivedBits = stripSpace(bits.ToString()); Assert.AreEqual(stripSpace(expectedBits), receivedBits, "highLevelEncode() failed for input string: " + s); - Assert.AreEqual(s, Internal.Decoder.highLevelDecode(toBooleanArray(bits))); + Assert.AreEqual(s, Internal.Decoder.highLevelDecode(toBooleanArray(bits), out encodedResult)); } private static void testHighLevelEncodeString(String s, int expectedReceivedBits) { + byte[] encodedResult; BitArray bits = new HighLevelEncoder(ISO_8859_1.GetBytes(s)).encode(); int receivedBitCount = stripSpace(bits.ToString()).Length; Assert.AreEqual(expectedReceivedBits, receivedBitCount, "highLevelEncode() failed for input string: " + s); - Assert.AreEqual(s, Internal.Decoder.highLevelDecode(toBooleanArray(bits))); + Assert.AreEqual(s, Internal.Decoder.highLevelDecode(toBooleanArray(bits), out encodedResult)); } public static String stripSpace(String s)