diff --git a/Source/lib/Result.cs b/Source/lib/Result.cs index 647dfb04..4e2177d0 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. /// @@ -89,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. /// @@ -112,12 +149,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/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 2782102f..5f8b81df 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 /// @@ -101,7 +106,21 @@ public bool StructuredAppend public DecoderResult(byte[] rawBytes, String text, List byteSegments, String ecLevel) : this(rawBytes, text, byteSegments, ecLevel, -1, -1, 0) { - + + } + + /// + /// initilizing constructor + /// + /// + /// + /// + /// + /// + public DecoderResult(byte[] rawBytes, byte[] data, String text, List byteSegments, String ecLevel) + : this(rawBytes, text, byteSegments, ecLevel) + { + Data = data; } /// @@ -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 /// @@ -133,7 +168,7 @@ public DecoderResult(byte[] rawBytes, int saParity) : this(rawBytes, text, byteSegments, ecLevel, saSequence, saParity, 0) { - + } /// @@ -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 /// @@ -164,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 /// @@ -176,12 +244,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..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,6 +87,7 @@ internal static DecoderResult decode(byte[] bytes) { BitSource bits = new BitSource(bytes); ECIStringBuilder result = new ECIStringBuilder(100); + MemoryStream encodedResult = new MemoryStream(); StringBuilder resultTrailer = new StringBuilder(0); List byteSegments = new List(1); Mode mode = Mode.ASCII_ENCODE; @@ -96,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 @@ -104,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, result, byteSegments)) + if (!decodeBase256Segment(bits, encodedResult, result, byteSegments)) return null; break; case Mode.ECI_ENCODE: @@ -136,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) { @@ -169,13 +173,14 @@ 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.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, @@ -198,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; @@ -215,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 @@ -232,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 @@ -243,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 @@ -279,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 @@ -321,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 @@ -337,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; @@ -352,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 @@ -366,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; @@ -380,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; @@ -400,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 @@ -441,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 @@ -457,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; @@ -473,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 @@ -487,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; @@ -504,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; } @@ -530,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 @@ -559,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 { @@ -606,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 { @@ -639,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); @@ -649,6 +688,7 @@ 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, + MemoryStream encodedResult, ECIStringBuilder result, IList byteSegments) { @@ -688,6 +728,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 +742,8 @@ private static bool decodeBase256Segment(BitSource bits, throw new InvalidOperationException("Platform does not support required encoding: " + uee); } + encodedResult.Write(bytes, 0, bytes.Length); + return true; } 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) 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..7fbff3b0 100644 --- a/Source/lib/qrcode/decoder/DecodedBitStreamParser.cs +++ b/Source/lib/qrcode/decoder/DecodedBitStreamParser.cs @@ -16,6 +16,10 @@ using System; using System.Collections.Generic; +using System.IO; +#if !NET20 +using System.Linq; +#endif using System.Text; using ZXing.Common; @@ -43,6 +47,7 @@ internal static DecoderResult decode(byte[] bytes, { var bits = new BitSource(bytes); var result = new StringBuilder(50); + var encodedResult = new MemoryStream(); var byteSegments = new List(1); var symbolSequence = -1; var parityData = -1; @@ -114,7 +119,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; @@ -125,19 +130,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, 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: @@ -184,7 +189,7 @@ internal static DecoderResult decode(byte[] bytes, return null; } - return new DecoderResult(bytes, + return new DecoderResult(bytes, encodedResult.ToArray(), result.ToString(), byteSegments.Count == 0 ? null : byteSegments, ecLevel == null ? null : ecLevel.ToString(), @@ -199,6 +204,7 @@ internal static DecoderResult decode(byte[] bytes, /// The count. /// private static bool decodeHanziSegment(BitSource bits, + MemoryStream encodedResult, StringBuilder result, int count) { @@ -238,11 +244,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) { @@ -282,11 +290,13 @@ 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, int count, CharacterSetECI currentCharacterSetECI, @@ -323,6 +333,7 @@ private static bool decodeByteSegment(BitSource bits, encoding = StringUtils.PLATFORM_DEFAULT_ENCODING_T; } result.Append(encoding.GetString(readBytes, 0, readBytes.Length)); + encodedResult.Write(readBytes, 0, readBytes.Length); byteSegments.Add(readBytes); @@ -339,6 +350,7 @@ private static char toAlphaNumericChar(int value) } private static bool decodeAlphanumericSegment(BitSource bits, + MemoryStream encodedResult, StringBuilder result, int count, bool fc1InEffect) @@ -353,7 +365,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) @@ -364,8 +380,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) { @@ -378,21 +400,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) { @@ -410,8 +438,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; } @@ -428,7 +461,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) { @@ -443,6 +479,7 @@ private static bool decodeNumericSegment(BitSource bits, return false; } result.Append(toAlphaNumericChar(digitBits)); + encodedResult.WriteByte((byte)digitBits); } return true; 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)