/// <summary>
        /// See ISO 16022:2006, 5.2.9 and Annex B, B.2
        /// </summary>
        private static bool decodeBase256Segment(BitSource bits,
                                                 StringBuilder result,
                                                 IList <byte[]> byteSegments)
        {
            // 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++);
            int count;

            if (d1 == 0)
            {
                // Read the remainder of the symbol
                count = bits.available() / 8;
            }
            else if (d1 < 250)
            {
                count = d1;
            }
            else
            {
                count = 250 * (d1 - 249) + unrandomize255State(bits.readBits(8), codewordPosition++);
            }

            // We're seeing NegativeArraySizeException errors from users.
            if (count < 0)
            {
                return(false);
            }

            byte[] bytes = new byte[count];
            for (int i = 0; i < count; i++)
            {
                // Have seen this particular error in the wild, such as at
                // http://www.bcgen.com/demo/IDAutomationStreamingDataMatrix.aspx?MODE=3&D=Fred&PFMT=3&PT=F&X=0.3&O=0&LM=0.2
                if (bits.available() < 8)
                {
                    return(false);
                }
                bytes[i] = (byte)unrandomize255State(bits.readBits(8), codewordPosition++);
            }
            byteSegments.Add(bytes);
            try
            {
#if (WINDOWS_PHONE || SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || WindowsCE || PORTABLE)
#if WindowsCE
                result.Append(Encoding.GetEncoding(1252).GetString(bytes, 0, bytes.Length));
#else
                result.Append(Encoding.GetEncoding("ISO-8859-1").GetString(bytes, 0, bytes.Length));
#endif
#else
                result.Append(Encoding.GetEncoding("ISO-8859-1").GetString(bytes));
#endif
            }
            catch (Exception uee)
            {
                throw new InvalidOperationException("Platform does not support required encoding: " + uee);
            }

            return(true);
        }
Example #2
0
        /**
         * See ISO 16022:2006, 5.2.9 and Annex B, B.2
         */
        private static void decodeBase256Segment(BitSource bits, StringBuilder result, System.Collections.ArrayList byteSegments)
        {
            // Figure out how long the Base 256 Segment is.
            int d1 = bits.readBits(8);
            int count;

            if (d1 == 0)    // Read the remainder of the symbol
            {
                count = bits.available() / 8;
            }
            else if (d1 < 250)
            {
                count = d1;
            }
            else
            {
                count = 250 * (d1 - 249) + bits.readBits(8);
            }
            byte[] bytes = new byte[count];
            for (int i = 0; i < count; i++)
            {
                bytes[i] = unrandomize255State(bits.readBits(8), i);
            }
            byteSegments.Add(bytes);
            try {
                result.Append(System.Text.Encoding.GetEncoding("iso-8859-1").GetString(bytes));
            } catch (Exception uee) {
                throw new Exception("Platform does not support required encoding: " + uee);
            }
        }
        /// <summary>
        /// See ISO 16022:2006, 5.2.8 and Annex C Table C.3
        /// </summary>
        private static void decodeEdifactSegment(BitSource bits, StringBuilder result)
        {
            do
            {
                // If there is only two or less bytes left then it will be encoded as ASCII
                if (bits.available() <= 16)
                {
                    return;
                }

                for (int i = 0; i < 4; i++)
                {
                    int edifactValue = bits.readBits(6);

                    // Check for the unlatch character
                    if (edifactValue == 0x1F)     // 011111
                    {
                        // Read rest of byte, which should be 0, and stop
                        int bitsLeft = 8 - bits.BitOffset;
                        if (bitsLeft != 8)
                        {
                            bits.readBits(bitsLeft);
                        }
                        return;
                    }

                    if ((edifactValue & 0x20) == 0) // no 1 in the leading (6th) bit
                    {
                        edifactValue |= 0x40;       // Add a leading 01 to the 6 bit binary value
                    }
                    result.Append((char)edifactValue);
                }
            } while (bits.available() > 0);
        }
        /// <summary>
        /// See ISO 16022:2006, 5.2.7
        /// </summary>
        private static bool decodeAnsiX12Segment(BitSource bits,
                                                 StringBuilder result)
        {
            // Three ANSI X12 values are encoded in a 16-bit value as
            // (1600 * C1) + (40 * C2) + C3 + 1

            int[] cValues = new int[3];
            do
            {
                // If there is only one byte left then it will be encoded as ASCII
                if (bits.available() == 8)
                {
                    return(true);
                }
                int firstByte = bits.readBits(8);
                if (firstByte == 254)
                { // Unlatch codeword
                    return(true);
                }

                parseTwoBytes(firstByte, bits.readBits(8), cValues);

                for (int i = 0; i < 3; i++)
                {
                    int cValue = cValues[i];
                    if (cValue == 0)
                    { // X12 segment terminator <CR>
                        result.Append('\r');
                    }
                    else if (cValue == 1)
                    { // X12 segment separator *
                        result.Append('*');
                    }
                    else if (cValue == 2)
                    { // X12 sub-element separator >
                        result.Append('>');
                    }
                    else if (cValue == 3)
                    { // space
                        result.Append(' ');
                    }
                    else if (cValue < 14)
                    { // 0 - 9
                        result.Append((char)(cValue + 44));
                    }
                    else if (cValue < 40)
                    { // A - Z
                        result.Append((char)(cValue + 51));
                    }
                    else
                    {
                        return(false);
                    }
                }
            } while (bits.available() > 0);

            return(true);
        }
        private static bool decodeNumericSegment(BitSource bits,
                                                 StringBuilder result,
                                                 int count)
        {
            // Read three digits at a time
            while (count >= 3)
            {
                // Each 10 bits encodes three digits
                if (bits.available() < 10)
                {
                    return(false);
                }
                int threeDigitsBits = bits.readBits(10);
                if (threeDigitsBits >= 1000)
                {
                    return(false);
                }
                result.Append(toAlphaNumericChar(threeDigitsBits / 100));
                result.Append(toAlphaNumericChar((threeDigitsBits / 10) % 10));
                result.Append(toAlphaNumericChar(threeDigitsBits % 10));

                count -= 3;
            }
            if (count == 2)
            {
                // Two digits left over to read, encoded in 7 bits
                if (bits.available() < 7)
                {
                    return(false);
                }
                int twoDigitsBits = bits.readBits(7);
                if (twoDigitsBits >= 100)
                {
                    return(false);
                }
                result.Append(toAlphaNumericChar(twoDigitsBits / 10));
                result.Append(toAlphaNumericChar(twoDigitsBits % 10));
            }
            else if (count == 1)
            {
                // One digit left over to read
                if (bits.available() < 4)
                {
                    return(false);
                }
                int digitBits = bits.readBits(4);
                if (digitBits >= 10)
                {
                    return(false);
                }
                result.Append(toAlphaNumericChar(digitBits));
            }

            return(true);
        }
        private static bool decodeAlphanumericSegment(BitSource bits,
                                                      StringBuilder result,
                                                      int count,
                                                      bool fc1InEffect)
        {
            // Read two characters at a time
            int start = result.Length;

            while (count > 1)
            {
                if (bits.available() < 11)
                {
                    return(false);
                }
                int nextTwoCharsBits = bits.readBits(11);
                result.Append(toAlphaNumericChar(nextTwoCharsBits / 45));
                result.Append(toAlphaNumericChar(nextTwoCharsBits % 45));
                count -= 2;
            }
            if (count == 1)
            {
                // special case: one character left
                if (bits.available() < 6)
                {
                    return(false);
                }
                result.Append(toAlphaNumericChar(bits.readBits(6)));
            }

            // See section 6.4.8.1, 6.4.8.2
            if (fc1InEffect)
            {
                // We need to massage the result a bit if in an FNC1 mode:
                for (int i = start; i < result.Length; i++)
                {
                    if (result [i] == '%')
                    {
                        if (i < result.Length - 1 && result [i + 1] == '%')
                        {
                            // %% is rendered as %
                            result.Remove(i + 1, 1);
                        }
                        else
                        {
                            // In alpha mode, % should be converted to FNC1 separator 0x1D
                            result.Remove(i, 1);
                            result.Insert(i, new[] { (char)0x1D });
                        }
                    }
                }
            }

            return(true);
        }
Example #7
0
        internal static System.String decode(sbyte[] bytes, Version version)
        {
            BitSource bits = new BitSource(bytes);

            System.Text.StringBuilder result = new System.Text.StringBuilder();
            Mode mode;

            do
            {
                // While still another segment to read...
                mode = Mode.forBits(bits.readBits(4)); // mode is encoded by 4 bits
                if (!mode.Equals(Mode.TERMINATOR))
                {
                    // How many characters will follow, encoded in this mode?
                    int count = bits.readBits(mode.getCharacterCountBits(version));
                    if (mode.Equals(Mode.NUMERIC))
                    {
                        decodeNumericSegment(bits, result, count);
                    }
                    else if (mode.Equals(Mode.ALPHANUMERIC))
                    {
                        decodeAlphanumericSegment(bits, result, count);
                    }
                    else if (mode.Equals(Mode.BYTE))
                    {
                        decodeByteSegment(bits, result, count);
                    }
                    else if (mode.Equals(Mode.KANJI))
                    {
                        decodeKanjiSegment(bits, result, count);
                    }
                    else
                    {
                        throw new ReaderException("Unsupported mode indicator");
                    }
                }
            }while (!mode.Equals(Mode.TERMINATOR));

            // I thought it wasn't allowed to leave extra bytes after the terminator but it happens

            /*
             * int bitsLeft = bits.available();
             * if (bitsLeft > 0) {
             * if (bitsLeft > 6 || bits.readBits(bitsLeft) != 0) {
             * throw new ReaderException("Excess bits or non-zero bits after terminator mode indicator");
             * }
             * }
             */
            return(result.ToString());
        }
        /// <summary>
        /// See ISO 16022:2006, 5.2.9 and Annex B, B.2
        /// </summary>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: private static void decodeBase256Segment(com.google.zxing.common.BitSource bits, StringBuilder result, java.util.Collection<byte[]> byteSegments) throws com.google.zxing.FormatException
        private static void decodeBase256Segment(BitSource bits, StringBuilder result, ICollection <sbyte[]> byteSegments)
        {
            // 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++);
            int count;

            if (d1 == 0)     // Read the remainder of the symbol
            {
                count = bits.available() / 8;
            }
            else if (d1 < 250)
            {
                count = d1;
            }
            else
            {
                count = 250 * (d1 - 249) + unrandomize255State(bits.readBits(8), codewordPosition++);
            }

            // We're seeing NegativeArraySizeException errors from users.
            if (count < 0)
            {
                throw FormatException.FormatInstance;
            }

            sbyte[] bytes = new sbyte[count];
            for (int i = 0; i < count; i++)
            {
                // Have seen this particular error in the wild, such as at
                // http://www.bcgen.com/demo/IDAutomationStreamingDataMatrix.aspx?MODE=3&D=Fred&PFMT=3&PT=F&X=0.3&O=0&LM=0.2
                if (bits.available() < 8)
                {
                    throw FormatException.FormatInstance;
                }
                bytes[i] = (sbyte)unrandomize255State(bits.readBits(8), codewordPosition++);
            }
            byteSegments.Add(bytes);
            try
            {
                //result.Append(new string(bytes, "ISO8859_1"));
                result.Append(GetEncodedStringFromBuffer(bytes, "ISO-8859-1"));
            }
            catch (System.IO.IOException uee)
            {
                throw new InvalidOperationException("Platform does not support required encoding: " + uee);
            }
        }
Example #9
0
        /**
         * See ISO 16022:2007, 5.4.1
         */
        private static bool decodeECISegment(BitSource bits, ECIStringBuilder result)
        {
            if (bits.available() < 8)
            {
                return(false);
            }
            int c1 = bits.readBits(8);

            if (c1 <= 127)
            {
                return(result.AppendECI(c1 - 1));
            }
            return(true);
            //currently we only support character set ECIs

            /*} else {
             * if (bits.available() < 8) {
             *  throw FormatException.getFormatInstance();
             * }
             * int c2 = bits.readBits(8);
             * if (c1 >= 128 && c1 <= 191) {
             * } else {
             *  if (bits.available() < 8) {
             *    throw FormatException.getFormatInstance();
             *  }
             *  int c3 = bits.readBits(8);
             * }
             * }*/
        }
Example #10
0
 private static void decodeAlphanumericSegment(BitSource bits, System.Text.StringBuilder result, int count)
 {
     // Read two characters at a time
     while (count > 1)
     {
         int nextTwoCharsBits = bits.readBits(11);
         result.Append(ALPHANUMERIC_CHARS[nextTwoCharsBits / 45]);
         result.Append(ALPHANUMERIC_CHARS[nextTwoCharsBits % 45]);
         count -= 2;
     }
     if (count == 1)
     {
         // special case: one character left
         result.Append(ALPHANUMERIC_CHARS[bits.readBits(6)]);
     }
 }
Example #11
0
 private static void decodeByteSegment(BitSource bits, System.Text.StringBuilder result, int count)
 {
     sbyte[] readBytes = new sbyte[count];
     if (count << 3 > bits.available())
     {
         throw new ReaderException("Count too large: " + count);
     }
     for (int i = 0; i < count; i++)
     {
         readBytes[i] = (sbyte)bits.readBits(8);
     }
     // The spec isn't clear on this mode; see
     // section 6.4.5: t does not say which encoding to assuming
     // upon decoding. I have seen ISO-8859-1 used as well as
     // Shift_JIS -- without anything like an ECI designator to
     // give a hint.
     System.String encoding = guessEncoding(readBytes);
     try
     {
         byte[] bytes = SupportClass.ToByteArray(readBytes);
         //System.Windows.Forms.MessageBox.Show("encodings: "+ System.Text.Encoding.());
         //UPGRADE_TODO: The differences in the Format  of parameters for constructor 'java.lang.String.String'  may cause compilation errors.  "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1092'"
         result.Append(System.Text.Encoding.GetEncoding(encoding).GetString(bytes, 0, bytes.Length));
     }
     catch (System.IO.IOException uce)
     {
         //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Throwable.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
         throw new ReaderException(uce.ToString());
     }
 }
Example #12
0
        private static bool decodeKanjiSegment(BitSource bits,
                                               StringBuilder result,
                                               int count)
        {
            // Don't crash trying to read more bits than we have available.
            if (count * 13 > bits.available())
            {
                return(false);
            }

            // Each character will require 2 bytes. Read the characters as 2-byte pairs
            // and decode as Shift_JIS afterwards
            byte[] buffer = new byte[2 * count];
            int    offset = 0;

            while (count > 0)
            {
                // Each 13 bits encodes a 2-byte character
                int twoBytes          = bits.readBits(13);
                int assembledTwoBytes = ((twoBytes / 0x0C0) << 8) | (twoBytes % 0x0C0);
                if (assembledTwoBytes < 0x01F00)
                {
                    // In the 0x8140 to 0x9FFC range
                    assembledTwoBytes += 0x08140;
                }
                else
                {
                    // In the 0xE040 to 0xEBBF range
                    assembledTwoBytes += 0x0C140;
                }
                buffer[offset]     = (byte)(assembledTwoBytes >> 8);
                buffer[offset + 1] = (byte)assembledTwoBytes;
                offset            += 2;
                count--;
            }
            // Shift_JIS may not be supported in some environments:
            try
            {
                result.Append(Encoding.GetEncoding(StringUtils.SHIFT_JIS).GetString(buffer, 0, buffer.Length));
            }
#if (WINDOWS_PHONE70 || WINDOWS_PHONE71 || SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || MONOANDROID || MONOTOUCH)
            catch (ArgumentException)
            {
                try
                {
                    // Silverlight only supports a limited number of character sets, trying fallback to UTF-8
                    result.Append(Encoding.GetEncoding("UTF-8").GetString(buffer, 0, buffer.Length));
                }
                catch (Exception)
                {
                    return(false);
                }
            }
#endif
            catch (Exception)
            {
                return(false);
            }
            return(true);
        }
Example #13
0
        private static bool decodeByteSegment(BitSource bits,
                                              StringBuilder result,
                                              int count,
                                              CharacterSetECI currentCharacterSetECI,
                                              IList <byte[]> byteSegments,
                                              IDictionary <DecodeHintType, object> hints)
        {
            // Don't crash trying to read more bits than we have available.
            if (count << 3 > bits.available())
            {
                return(false);
            }

            byte[] readBytes = new byte[count];
            for (int i = 0; i < count; i++)
            {
                readBytes[i] = (byte)bits.readBits(8);
            }
            String encoding;

            if (currentCharacterSetECI == null)
            {
                // The spec isn't clear on this mode; see
                // section 6.4.5: t does not say which encoding to assuming
                // upon decoding. I have seen ISO-8859-1 used as well as
                // Shift_JIS -- without anything like an ECI designator to
                // give a hint.
                encoding = StringUtils.guessEncoding(readBytes, hints);
            }
            else
            {
                encoding = currentCharacterSetECI.EncodingName;
            }
            try
            {
                result.Append(Encoding.GetEncoding(encoding).GetString(readBytes, 0, readBytes.Length));
            }
#if WindowsCE
            catch (PlatformNotSupportedException)
            {
                // WindowsCE doesn't support all encodings. But it is device depended.
                // So we try here the some different ones
                if (encoding == "ISO-8859-1")
                {
                    result.Append(Encoding.GetEncoding(1252).GetString(readBytes, 0, readBytes.Length));
                }
                else
                {
                    result.Append(Encoding.GetEncoding("UTF-8").GetString(readBytes, 0, readBytes.Length));
                }
            }
#endif
            catch (Exception)
            {
                return(false);
            }
            byteSegments.Add(readBytes);

            return(true);
        }
Example #14
0
        /**
         * See ISO 16022:2006, 5.2.8 and Annex C Table C.3
         */
        private static void decodeEdifactSegment(BitSource bits, StringBuilder result)
        {
            bool unlatch = false;

            do
            {
                // If there is only two or less bytes left then it will be encoded as ASCII
                if (bits.available() <= 16)
                {
                    return;
                }

                for (int i = 0; i < 4; i++)
                {
                    int edifactValue = bits.readBits(6);

                    // Check for the unlatch character
                    if (edifactValue == 0x2B67) // 011111
                    {
                        unlatch = true;
                        // If we encounter the unlatch code then continue reading because the Codeword triple
                        // is padded with 0's
                    }

                    if (!unlatch)
                    {
                        if ((edifactValue & 32) == 0) // no 1 in the leading (6th) bit
                        {
                            edifactValue |= 64;       // Add a leading 01 to the 6 bit binary value
                        }
                        result.Append(edifactValue);
                    }
                }
            } while (!unlatch && bits.available() > 0);
        }
        /// <summary>
        /// See specification GBT 18284-2000
        /// </summary>
        /// <param name="bits">The bits.</param>
        /// <param name="result">The result.</param>
        /// <param name="count">The count.</param>
        /// <returns></returns>
        private static bool decodeHanziSegment(BitSource bits,
                                               StringBuilder result,
                                               int count)
        {
            // Don't crash trying to read more bits than we have available.
            if (count * 13 > bits.available())
            {
                return(false);
            }

            // Each character will require 2 bytes. Read the characters as 2-byte pairs
            // and decode as GB2312 afterwards
            byte[] buffer = new byte[2 * count];
            int    offset = 0;

            while (count > 0)
            {
                // Each 13 bits encodes a 2-byte character
                int twoBytes          = bits.readBits(13);
                int assembledTwoBytes = ((twoBytes / 0x060) << 8) | (twoBytes % 0x060);
                if (assembledTwoBytes < 0x003BF)
                {
                    // In the 0xA1A1 to 0xAAFE range
                    assembledTwoBytes += 0x0A1A1;
                }
                else
                {
                    // In the 0xB0A1 to 0xFAFE range
                    assembledTwoBytes += 0x0A6A1;
                }
                buffer [offset]     = (byte)((assembledTwoBytes >> 8) & 0xFF);
                buffer [offset + 1] = (byte)(assembledTwoBytes & 0xFF);
                offset += 2;
                count--;
            }

            try {
                result.Append(Encoding.GetEncoding(StringUtils.GB2312).GetString(buffer, 0, buffer.Length));
            }
#if (WINDOWS_PHONE70 || WINDOWS_PHONE71 || SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || MONOANDROID || MONOTOUCH)
            catch (ArgumentException)
            {
                try
                {
                    // Silverlight only supports a limited number of character sets, trying fallback to UTF-8
                    result.Append(Encoding.GetEncoding("UTF-8").GetString(buffer, 0, buffer.Length));
                }
                catch (Exception)
                {
                    return(false);
                }
            }
#endif
            catch (Exception) {
                return(false);
            }

            return(true);
        }
Example #16
0
 private static void decodeNumericSegment(BitSource bits, System.Text.StringBuilder result, int count)
 {
     // Read three digits at a time
     while (count >= 3)
     {
         // Each 10 bits encodes three digits
         int threeDigitsBits = bits.readBits(10);
         if (threeDigitsBits >= 1000)
         {
             throw new ReaderException("Illegal value for 3-digit unit: " + threeDigitsBits);
         }
         result.Append(ALPHANUMERIC_CHARS[threeDigitsBits / 100]);
         result.Append(ALPHANUMERIC_CHARS[(threeDigitsBits / 10) % 10]);
         result.Append(ALPHANUMERIC_CHARS[threeDigitsBits % 10]);
         count -= 3;
     }
     if (count == 2)
     {
         // Two digits left over to read, encoded in 7 bits
         int twoDigitsBits = bits.readBits(7);
         if (twoDigitsBits >= 100)
         {
             throw new ReaderException("Illegal value for 2-digit unit: " + twoDigitsBits);
         }
         result.Append(ALPHANUMERIC_CHARS[twoDigitsBits / 10]);
         result.Append(ALPHANUMERIC_CHARS[twoDigitsBits % 10]);
     }
     else if (count == 1)
     {
         // One digit left over to read
         int digitBits = bits.readBits(4);
         if (digitBits >= 10)
         {
             throw new ReaderException("Illegal value for digit unit: " + digitBits);
         }
         result.Append(ALPHANUMERIC_CHARS[digitBits]);
     }
 }
        private static int parseECIValue(BitSource bits)
        {
            int firstByte = bits.readBits(8);

            if ((firstByte & 0x80) == 0)
            {
                // just one byte
                return(firstByte & 0x7F);
            }
            if ((firstByte & 0xC0) == 0x80)
            {
                // two bytes
                int secondByte = bits.readBits(8);
                return(((firstByte & 0x3F) << 8) | secondByte);
            }
            if ((firstByte & 0xE0) == 0xC0)
            {
                // three bytes
                int secondThirdBytes = bits.readBits(16);
                return(((firstByte & 0x1F) << 16) | secondThirdBytes);
            }
            throw new ArgumentException("Bad ECI bits starting with byte " + firstByte);
        }
Example #18
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: private static int parseECIValue(com.google.zxing.common.BitSource bits) throws com.google.zxing.FormatException
        private static int parseECIValue(BitSource bits)
        {
            int firstByte = bits.readBits(8);

            if ((firstByte & 0x80) == 0)
            {
                // just one byte
                return(firstByte & 0x7F);
            }
            if ((firstByte & 0xC0) == 0x80)
            {
                // two bytes
                int secondByte = bits.readBits(8);
                return(((firstByte & 0x3F) << 8) | secondByte);
            }
            if ((firstByte & 0xE0) == 0xC0)
            {
                // three bytes
                int secondThirdBytes = bits.readBits(16);
                return(((firstByte & 0x1F) << 16) | secondThirdBytes);
            }
            throw FormatException.FormatInstance;
        }
Example #19
0
        /// <summary>
        /// See specification GBT 18284-2000
        /// </summary>
        /// <param name="bits">The bits.</param>
        /// <param name="result">The result.</param>
        /// <param name="count">The count.</param>
        /// <returns></returns>
        private static bool decodeHanziSegment(BitSource bits,
                                               StringBuilder result,
                                               int count)
        {
            // Don't crash trying to read more bits than we have available.
            if (count * 13 > bits.available())
            {
                return(false);
            }

            // Each character will require 2 bytes. Read the characters as 2-byte pairs
            // and decode as GB2312 afterwards
            byte[] buffer = new byte[2 * count];
            int    offset = 0;

            while (count > 0)
            {
                // Each 13 bits encodes a 2-byte character
                int twoBytes          = bits.readBits(13);
                int assembledTwoBytes = ((twoBytes / 0x060) << 8) | (twoBytes % 0x060);
                if (assembledTwoBytes < 0x003BF)
                {
                    // In the 0xA1A1 to 0xAAFE range
                    assembledTwoBytes += 0x0A1A1;
                }
                else
                {
                    // In the 0xB0A1 to 0xFAFE range
                    assembledTwoBytes += 0x0A6A1;
                }
                buffer[offset]     = (byte)((assembledTwoBytes >> 8) & 0xFF);
                buffer[offset + 1] = (byte)(assembledTwoBytes & 0xFF);
                offset            += 2;
                count--;
            }

            try
            {
                result.Append(Encoding.GetEncoding(StringUtils.GB2312).GetString(buffer, 0, buffer.Length));
            }
            catch (Exception)
            {
                return(false);
            }

            return(true);
        }
        private static bool decodeKanjiSegment(BitSource bits,
                                               StringBuilder result,
                                               int count)
        {
            // Don't crash trying to read more bits than we have available.
            if (count * 13 > bits.available())
            {
                return(false);
            }

            // Each character will require 2 bytes. Read the characters as 2-byte pairs
            // and decode as Shift_JIS afterwards
            byte[] buffer = new byte[2 * count];
            int    offset = 0;

            while (count > 0)
            {
                // Each 13 bits encodes a 2-byte character
                int twoBytes          = bits.readBits(13);
                int assembledTwoBytes = ((twoBytes / 0x0C0) << 8) | (twoBytes % 0x0C0);
                if (assembledTwoBytes < 0x01F00)
                {
                    // In the 0x8140 to 0x9FFC range
                    assembledTwoBytes += 0x08140;
                }
                else
                {
                    // In the 0xE040 to 0xEBBF range
                    assembledTwoBytes += 0x0C140;
                }
                buffer[offset]     = (byte)(assembledTwoBytes >> 8);
                buffer[offset + 1] = (byte)assembledTwoBytes;
                offset            += 2;
                count--;
            }
            // Shift_JIS may not be supported in some environments:
            var encoding = StringUtils.SHIFT_JIS_ENCODING;

            if (encoding == null)
            {
                encoding = StringUtils.PLATFORM_DEFAULT_ENCODING_T;
            }

            result.Append(encoding.GetString(buffer, 0, buffer.Length));

            return(true);
        }
Example #21
0
        private static bool decodeByteSegment(BitSource bits,
                                              StringBuilder result,
                                              int count,
                                              CharacterSetECI currentCharacterSetECI,
                                              IList byteSegments,
                                              Hashtable hints)
        {
            // Don't crash trying to read more bits than we have available.
            if (count << 3 > bits.available())
            {
                return(false);
            }

            byte[] readBytes = new byte[count];
            for (int i = 0; i < count; i++)
            {
                readBytes[i] = (byte)bits.readBits(8);
            }
            String encoding;

            if (currentCharacterSetECI == null)
            {
                // The spec isn't clear on this mode; see
                // section 6.4.5: t does not say which encoding to assuming
                // upon decoding. I have seen ISO-8859-1 used as well as
                // Shift_JIS -- without anything like an ECI designator to
                // give a hint.
                encoding = StringUtils.guessEncoding(readBytes, hints);
            }
            else
            {
                encoding = currentCharacterSetECI.EncodingName;
            }
            try
            {
                result.Append(Encoding.UTF8.GetChars(readBytes, 0, readBytes.Length));
            }
            catch (Exception)
            {
                return(false);
            }
            byteSegments.Add(readBytes);

            return(true);
        }
Example #22
0
        /// <summary>
        /// See specification GBT 18284-2000
        /// </summary>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: private static void decodeHanziSegment(com.google.zxing.common.BitSource bits, StringBuilder result, int count) throws com.google.zxing.FormatException
        private static void decodeHanziSegment(BitSource bits, StringBuilder result, int count)
        {
            // Don't crash trying to read more bits than we have available.
            if (count * 13 > bits.available())
            {
                throw FormatException.FormatInstance;
            }

            // Each character will require 2 bytes. Read the characters as 2-byte pairs
            // and decode as GB2312 afterwards
            sbyte[] buffer = new sbyte[2 * count];
            int     offset = 0;

            while (count > 0)
            {
                // Each 13 bits encodes a 2-byte character
                int twoBytes          = bits.readBits(13);
                int assembledTwoBytes = ((twoBytes / 0x060) << 8) | (twoBytes % 0x060);
                if (assembledTwoBytes < 0x003BF)
                {
                    // In the 0xA1A1 to 0xAAFE range
                    assembledTwoBytes += 0x0A1A1;
                }
                else
                {
                    // In the 0xB0A1 to 0xFAFE range
                    assembledTwoBytes += 0x0A6A1;
                }
                buffer[offset]     = (sbyte)((assembledTwoBytes >> 8) & 0xFF);
                buffer[offset + 1] = (sbyte)(assembledTwoBytes & 0xFF);
                offset            += 2;
                count--;
            }

            try
            {
                //result.Append(new string(buffer,  StringUtils.GB2312));
                result.Append(GetEncodedStringFromBuffer(buffer, StringUtils.GB2312));
            }
            catch (System.IO.IOException)
            {
                throw FormatException.FormatInstance;
            }
        }
Example #23
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: private static void decodeKanjiSegment(com.google.zxing.common.BitSource bits, StringBuilder result, int count) throws com.google.zxing.FormatException
        private static void decodeKanjiSegment(BitSource bits, StringBuilder result, int count)
        {
            // Don't crash trying to read more bits than we have available.
            if (count * 13 > bits.available())
            {
                throw FormatException.FormatInstance;
            }

            // Each character will require 2 bytes. Read the characters as 2-byte pairs
            // and decode as Shift_JIS afterwards
            sbyte[] buffer = new sbyte[2 * count];
            int     offset = 0;

            while (count > 0)
            {
                // Each 13 bits encodes a 2-byte character
                int twoBytes          = bits.readBits(13);
                int assembledTwoBytes = ((twoBytes / 0x0C0) << 8) | (twoBytes % 0x0C0);
                if (assembledTwoBytes < 0x01F00)
                {
                    // In the 0x8140 to 0x9FFC range
                    assembledTwoBytes += 0x08140;
                }
                else
                {
                    // In the 0xE040 to 0xEBBF range
                    assembledTwoBytes += 0x0C140;
                }
                buffer[offset]     = (sbyte)(assembledTwoBytes >> 8);
                buffer[offset + 1] = (sbyte)assembledTwoBytes;
                offset            += 2;
                count--;
            }
            // Shift_JIS may not be supported in some environments:
            try
            {
                //result.Append(new string(buffer, StringUtils.SHIFT_JIS));
                result.Append(GetEncodedStringFromBuffer(buffer, StringUtils.SHIFT_JIS));
            }
            catch (System.IO.IOException)
            {
                throw FormatException.FormatInstance;
            }
        }
        private static bool decodeByteSegment(BitSource bits,
                                              StringBuilder result,
                                              int count,
                                              CharacterSetECI currentCharacterSetECI,
                                              IList <byte[]> byteSegments,
                                              IDictionary <DecodeHintType, object> hints)
        {
            // Don't crash trying to read more bits than we have available.
            if (count << 3 > bits.available())
            {
                return(false);
            }

            byte[] readBytes = new byte[count];
            for (int i = 0; i < count; i++)
            {
                readBytes[i] = (byte)bits.readBits(8);
            }
            Encoding encoding;

            if (currentCharacterSetECI == null)
            {
                // The spec isn't clear on this mode; see
                // section 6.4.5: t does not say which encoding to assuming
                // upon decoding. I have seen ISO-8859-1 used as well as
                // Shift_JIS -- without anything like an ECI designator to
                // give a hint.
                encoding = StringUtils.guessCharset(readBytes, hints);
            }
            else
            {
                encoding = CharacterSetECI.getEncoding(currentCharacterSetECI.EncodingName);
            }
            if (encoding == null)
            {
                encoding = StringUtils.PLATFORM_DEFAULT_ENCODING_T;
            }
            result.Append(encoding.GetString(readBytes, 0, readBytes.Length));

            byteSegments.Add(readBytes);

            return(true);
        }
Example #25
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: private static void decodeByteSegment(com.google.zxing.common.BitSource bits, StringBuilder result, int count, com.google.zxing.common.CharacterSetECI currentCharacterSetECI, java.util.Collection<byte[]> byteSegments, java.util.Map<com.google.zxing.DecodeHintType,?> hints) throws com.google.zxing.FormatException
        private static void decodeByteSegment(BitSource bits, StringBuilder result, int count, CharacterSetECI currentCharacterSetECI, ICollection <sbyte[]> byteSegments, IDictionary <DecodeHintType, object> hints)
        {
            // Don't crash trying to read more bits than we have available.
            if (count << 3 > bits.available())
            {
                throw FormatException.FormatInstance;
            }

            sbyte[] readBytes = new sbyte[count];
            for (int i = 0; i < count; i++)
            {
                readBytes[i] = (sbyte)bits.readBits(8);
            }
            string encoding;

            if (currentCharacterSetECI == null)
            {
                // The spec isn't clear on this mode; see
                // section 6.4.5: t does not say which encoding to assuming
                // upon decoding. I have seen ISO-8859-1 used as well as
                // Shift_JIS -- without anything like an ECI designator to
                // give a hint.
                encoding = StringUtils.guessEncoding(readBytes, hints);
            }
            else
            {
                encoding = currentCharacterSetECI.name();
            }
            try
            {
                //result.Append(new string(readBytes, encoding));
                result.Append(GetEncodedStringFromBuffer(readBytes, encoding));
            }
            catch (System.IO.IOException)
            {
                throw FormatException.FormatInstance;
            }
            byteSegments.Add(readBytes);
        }
Example #26
0
 public void testSource()
 {
    byte[] bytes = {1, 2, 3, 4, 5};
    BitSource source = new BitSource(bytes);
    Assert.AreEqual(40, source.available());
    Assert.AreEqual(0, source.readBits(1));
    Assert.AreEqual(39, source.available());
    Assert.AreEqual(0, source.readBits(6));
    Assert.AreEqual(33, source.available());
    Assert.AreEqual(1, source.readBits(1));
    Assert.AreEqual(32, source.available());
    Assert.AreEqual(2, source.readBits(8));
    Assert.AreEqual(24, source.available());
    Assert.AreEqual(12, source.readBits(10));
    Assert.AreEqual(14, source.available());
    Assert.AreEqual(16, source.readBits(8));
    Assert.AreEqual(6, source.available());
    Assert.AreEqual(5, source.readBits(6));
    Assert.AreEqual(0, source.available());
 }
Example #27
0
        private static void decodeKanjiSegment(BitSource bits, System.Text.StringBuilder result, int count)
        {
            // Each character will require 2 bytes. Read the characters as 2-byte pairs
            // and decode as Shift_JIS afterwards
            sbyte[] buffer = new sbyte[2 * count];
            int     offset = 0;

            while (count > 0)
            {
                // Each 13 bits encodes a 2-byte character
                int twoBytes          = bits.readBits(13);
                int assembledTwoBytes = ((twoBytes / 0x0C0) << 8) | (twoBytes % 0x0C0);
                if (assembledTwoBytes < 0x01F00)
                {
                    // In the 0x8140 to 0x9FFC range
                    assembledTwoBytes += 0x08140;
                }
                else
                {
                    // In the 0xE040 to 0xEBBF range
                    assembledTwoBytes += 0x0C140;
                }
                buffer[offset]     = (sbyte)(assembledTwoBytes >> 8);
                buffer[offset + 1] = (sbyte)assembledTwoBytes;
                offset            += 2;
                count--;
            }
            // Shift_JIS may not be supported in some environments:
            try
            {
                byte[] bytes = SupportClass.ToByteArray(buffer);
                //UPGRADE_TODO: The differences in the Format  of parameters for constructor 'java.lang.String.String'  may cause compilation errors.  "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1092'"
                result.Append(System.Text.Encoding.GetEncoding("Shift_JIS").GetString(bytes, 0, bytes.Length));
            }
            catch (System.IO.IOException uee)
            {
                throw new ReaderException("SHIFT_JIS encoding is not supported on this device");
            }
        }
Example #28
0
        public void testSource()
        {
            byte[]    bytes  = { 1, 2, 3, 4, 5 };
            BitSource source = new BitSource(bytes);

            Assert.AreEqual(40, source.available());
            Assert.AreEqual(0, source.readBits(1));
            Assert.AreEqual(39, source.available());
            Assert.AreEqual(0, source.readBits(6));
            Assert.AreEqual(33, source.available());
            Assert.AreEqual(1, source.readBits(1));
            Assert.AreEqual(32, source.available());
            Assert.AreEqual(2, source.readBits(8));
            Assert.AreEqual(24, source.available());
            Assert.AreEqual(12, source.readBits(10));
            Assert.AreEqual(14, source.available());
            Assert.AreEqual(16, source.readBits(8));
            Assert.AreEqual(6, source.available());
            Assert.AreEqual(5, source.readBits(6));
            Assert.AreEqual(0, source.available());
        }
        /// <summary>
        /// See ISO 16022:2006, 5.2.6 and Annex C, Table C.2
        /// </summary>
        private static bool decodeTextSegment(BitSource bits, StringBuilder result)
        {
            // Three Text values are encoded in a 16-bit value as
            // (1600 * C1) + (40 * C2) + C3 + 1
            // TODO(bbrown): The Upper Shift with Text doesn't work in the 4 value scenario all the time
            bool upperShift = false;

            int[] cValues = new int[3];
            int   shift   = 0;

            do
            {
                // If there is only one byte left then it will be encoded as ASCII
                if (bits.available() == 8)
                {
                    return(true);
                }
                int firstByte = bits.readBits(8);
                if (firstByte == 254)
                {
                    // Unlatch codeword
                    return(true);
                }

                parseTwoBytes(firstByte, bits.readBits(8), cValues);

                for (int i = 0; i < 3; i++)
                {
                    int cValue = cValues[i];
                    switch (shift)
                    {
                    case 0:
                        if (cValue < 3)
                        {
                            shift = cValue + 1;
                        }
                        else if (cValue < TEXT_BASIC_SET_CHARS.Length)
                        {
                            char textChar = TEXT_BASIC_SET_CHARS[cValue];
                            if (upperShift)
                            {
                                result.Append((char)(textChar + 128));
                                upperShift = false;
                            }
                            else
                            {
                                result.Append(textChar);
                            }
                        }
                        else
                        {
                            return(false);
                        }
                        break;

                    case 1:
                        if (upperShift)
                        {
                            result.Append((char)(cValue + 128));
                            upperShift = false;
                        }
                        else
                        {
                            result.Append((char)cValue);
                        }
                        shift = 0;
                        break;

                    case 2:
                        // Shift 2 for Text is the same encoding as C40
                        if (cValue < C40_SHIFT2_SET_CHARS.Length)
                        {
                            char c40char = C40_SHIFT2_SET_CHARS[cValue];
                            if (upperShift)
                            {
                                result.Append((char)(c40char + 128));
                                upperShift = false;
                            }
                            else
                            {
                                result.Append(c40char);
                            }
                        }
                        else if (cValue == 27)
                        {                            // FNC1
                            result.Append((char)29); // translate as ASCII 29
                        }
                        else if (cValue == 30)
                        { // Upper Shift
                            upperShift = true;
                        }
                        else
                        {
                            return(false);
                        }
                        shift = 0;
                        break;

                    case 3:
                        if (cValue < TEXT_SHIFT3_SET_CHARS.Length)
                        {
                            char textChar = TEXT_SHIFT3_SET_CHARS[cValue];
                            if (upperShift)
                            {
                                result.Append((char)(textChar + 128));
                                upperShift = false;
                            }
                            else
                            {
                                result.Append(textChar);
                            }
                            shift = 0;
                        }
                        else
                        {
                            return(false);
                        }
                        break;

                    default:
                        return(false);
                    }
                }
            } while (bits.available() > 0);

            return(true);
        }
        /// <summary>
        /// See ISO 16022:2006, 5.2.3 and Annex C, Table C.2
        /// </summary>
        private static bool decodeAsciiSegment(BitSource bits,
                                               StringBuilder result,
                                               StringBuilder resultTrailer,
                                               out Mode mode)
        {
            bool upperShift = false;

            mode = Mode.ASCII_ENCODE;
            do
            {
                int oneByte = bits.readBits(8);
                if (oneByte == 0)
                {
                    return(false);
                }
                else if (oneByte <= 128)
                { // ASCII data (ASCII value + 1)
                    if (upperShift)
                    {
                        oneByte += 128;
                        //upperShift = false;
                    }
                    result.Append((char)(oneByte - 1));
                    mode = Mode.ASCII_ENCODE;
                    return(true);
                }
                else if (oneByte == 129)
                { // Pad
                    mode = Mode.PAD_ENCODE;
                    return(true);
                }
                else if (oneByte <= 229)
                { // 2-digit data 00-99 (Numeric Value + 130)
                    int value = oneByte - 130;
                    if (value < 10)
                    { // padd with '0' for single digit values
                        result.Append('0');
                    }
                    result.Append(value);
                }
                else if (oneByte == 230)
                { // Latch to C40 encodation
                    mode = Mode.C40_ENCODE;
                    return(true);
                }
                else if (oneByte == 231)
                { // Latch to Base 256 encodation
                    mode = Mode.BASE256_ENCODE;
                    return(true);
                }
                else if (oneByte == 232)
                {
                    // FNC1
                    result.Append((char)29); // translate as ASCII 29
                }
                else if (oneByte == 233 || oneByte == 234)
                {
                    // Structured Append, Reader Programming
                    // Ignore these symbols for now
                    //throw ReaderException.Instance;
                }
                else if (oneByte == 235)
                { // Upper Shift (shift to Extended ASCII)
                    upperShift = true;
                }
                else if (oneByte == 236)
                { // 05 Macro
                    result.Append("[)>\u001E05\u001D");
                    resultTrailer.Insert(0, "\u001E\u0004", "\u001E\u0004".Length);
                }
                else if (oneByte == 237)
                { // 06 Macro
                    result.Append("[)>\u001E06\u001D");
                    resultTrailer.Insert(0, "\u001E\u0004", "\u001E\u0004".Length);
                }
                else if (oneByte == 238)
                { // Latch to ANSI X12 encodation
                    mode = Mode.ANSIX12_ENCODE;
                    return(true);
                }
                else if (oneByte == 239)
                { // Latch to Text encodation
                    mode = Mode.TEXT_ENCODE;
                    return(true);
                }
                else if (oneByte == 240)
                { // Latch to EDIFACT encodation
                    mode = Mode.EDIFACT_ENCODE;
                    return(true);
                }
                else if (oneByte == 241)
                { // ECI Character
                  // TODO(bbrown): I think we need to support ECI
                  //throw ReaderException.Instance;
                  // Ignore this symbol for now
                }
                else if (oneByte >= 242)
                { // Not to be used in ASCII encodation
                  // ... but work around encoders that end with 254, latch back to ASCII
                    if (oneByte != 254 || bits.available() != 0)
                    {
                        return(false);
                    }
                }
            } while (bits.available() > 0);
            mode = Mode.ASCII_ENCODE;
            return(true);
        }
        internal static DecoderResult decode(byte[] bytes,
                                             Version version,
                                             ErrorCorrectionLevel ecLevel,
                                             IDictionary <DecodeHintType, object> hints)
        {
            var bits           = new BitSource(bytes);
            var result         = new StringBuilder(50);
            var byteSegments   = new List <byte[]> (1);
            var symbolSequence = -1;
            var parityData     = -1;

            try {
                CharacterSetECI currentCharacterSetECI = null;
                bool            fc1InEffect            = false;
                Mode            mode;
                do
                {
                    // While still another segment to read...
                    if (bits.available() < 4)
                    {
                        // OK, assume we're done. Really, a TERMINATOR mode should have been recorded here
                        mode = Mode.TERMINATOR;
                    }
                    else
                    {
                        try {
                            mode = Mode.forBits(bits.readBits(4));                               // mode is encoded by 4 bits
                        } catch (ArgumentException) {
                            return(null);
                        }
                    }
                    if (mode != Mode.TERMINATOR)
                    {
                        if (mode == Mode.FNC1_FIRST_POSITION || mode == Mode.FNC1_SECOND_POSITION)
                        {
                            // We do little with FNC1 except alter the parsed result a bit according to the spec
                            fc1InEffect = true;
                        }
                        else if (mode == Mode.STRUCTURED_APPEND)
                        {
                            if (bits.available() < 16)
                            {
                                return(null);
                            }
                            // not really supported; but sequence number and parity is added later to the result metadata
                            // Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue
                            symbolSequence = bits.readBits(8);
                            parityData     = bits.readBits(8);
                        }
                        else if (mode == Mode.ECI)
                        {
                            // Count doesn't apply to ECI
                            int value = parseECIValue(bits);
                            currentCharacterSetECI = CharacterSetECI.getCharacterSetECIByValue(value);
                            if (currentCharacterSetECI == null)
                            {
                                return(null);
                            }
                        }
                        else
                        {
                            // First handle Hanzi mode which does not start with character count
                            if (mode == Mode.HANZI)
                            {
                                //chinese mode contains a sub set indicator right after mode indicator
                                int subset     = bits.readBits(4);
                                int countHanzi = bits.readBits(mode.getCharacterCountBits(version));
                                if (subset == GB2312_SUBSET)
                                {
                                    if (!decodeHanziSegment(bits, result, countHanzi))
                                    {
                                        return(null);
                                    }
                                }
                            }
                            else
                            {
                                // "Normal" QR code modes:
                                // How many characters will follow, encoded in this mode?
                                int count = bits.readBits(mode.getCharacterCountBits(version));
                                if (mode == Mode.NUMERIC)
                                {
                                    if (!decodeNumericSegment(bits, result, count))
                                    {
                                        return(null);
                                    }
                                }
                                else if (mode == Mode.ALPHANUMERIC)
                                {
                                    if (!decodeAlphanumericSegment(bits, result, count, fc1InEffect))
                                    {
                                        return(null);
                                    }
                                }
                                else if (mode == Mode.BYTE)
                                {
                                    if (!decodeByteSegment(bits, result, count, currentCharacterSetECI, byteSegments, hints))
                                    {
                                        return(null);
                                    }
                                }
                                else if (mode == Mode.KANJI)
                                {
                                    if (!decodeKanjiSegment(bits, result, count))
                                    {
                                        return(null);
                                    }
                                }
                                else
                                {
                                    return(null);
                                }
                            }
                        }
                    }
                } while (mode != Mode.TERMINATOR);
            } catch (ArgumentException) {
                // from readBits() calls
                return(null);
            }

#if WindowsCE
            var resultString = result.ToString().Replace("\n", "\r\n");
#else
            var resultString = result.ToString().Replace("\r\n", "\n").Replace("\n", Environment.NewLine);
#endif
            return(new DecoderResult(bytes,
                                     resultString,
                                     byteSegments.Count == 0 ? null : byteSegments,
                                     ecLevel == null ? null : ecLevel.ToString(),
                                     symbolSequence, parityData));
        }