/// <summary> Based on pattern of odd-even ('L' and 'G') patterns used to encoded the explicitly-encoded
 /// digits in a barcode, determines the implicitly encoded first digit and adds it to the
 /// result string.
 /// 
 /// </summary>
 /// <param name="resultString">string to insert decoded first digit into
 /// </param>
 /// <param name="lgPatternFound">int whose bits indicates the pattern of odd/even L/G patterns used to
 /// encode digits
 /// </param>
 /// <throws>  ReaderException if first digit cannot be determined </throws>
 private static void determineFirstDigit(StringBuilder resultString, int lgPatternFound)
 {
     for (int d = 0; d < 10; d++)
     {
         if (lgPatternFound == FIRST_DIGIT_ENCODINGS[d])
         {
             string s = resultString.ToString().Insert(0, (Int32Extend.ToChar(CharExtend.ToInt32('0') + d)).ToString());
             resultString.Clear();
             resultString.Append(s);
             return ;
         }
     }
     throw new Exception("ReaderException");
 }
 /// <summary> See ISO 16022:2006, 5.2.3 and Annex C, Table C.2</summary>
 private static int decodeAsciiSegment(BitSource bits, StringBuilder result, StringBuilder resultTrailer)
 {
     bool upperShift = false;
     do
     {
         int oneByte = bits.readBits(8);
         if (oneByte == 0)
         {
             throw new Exception("ReaderException");
         }
         else if (oneByte <= 128)
         {
             // ASCII data (ASCII value + 1)
             oneByte = upperShift?(oneByte + 128):oneByte;
             upperShift = false;
             result.Append((char) (oneByte - 1));
             return ASCII_ENCODE;
         }
         else if (oneByte == 129)
         {
             // Pad
             return PAD_ENCODE;
         }
         else if (oneByte <= 229)
         {
             // 2-digit data 00-99 (Numeric Value + 130)
             int value_Renamed = oneByte - 130;
             if (value_Renamed < 10)
             {
                 // padd with '0' for single digit values
                 result.Append('0');
             }
             result.Append(value_Renamed);
         }
         else if (oneByte == 230)
         {
             // Latch to C40 encodation
             return C40_ENCODE;
         }
         else if (oneByte == 231)
         {
             // Latch to Base 256 encodation
             return BASE256_ENCODE;
         }
         else if (oneByte == 232)
         {
             // FNC1
             //throw ReaderException.getInstance();
             // Ignore this symbol for now
         }
         else if (oneByte == 233)
         {
             // Structured Append
             //throw ReaderException.getInstance();
             // Ignore this symbol for now
         }
         else if (oneByte == 234)
         {
             // Reader Programming
             //throw ReaderException.getInstance();
             // Ignore this symbol for now
         }
         else if (oneByte == 235)
         {
             // Upper Shift (shift to Extended ASCII)
             upperShift = true;
         }
         else if (oneByte == 236)
         {
             // 05 Macro
             result.Append("[)>\u001E05\u001D");
             string s = resultTrailer.ToString().Insert(0, "\u001E\u0004");
             resultTrailer.Clear();
             resultTrailer.Append(s);
         }
         else if (oneByte == 237)
         {
             // 06 Macro
             result.Append("[)>\u001E06\u001D");
             string s = resultTrailer.ToString().Insert(0, "\u001E\u0004");
             resultTrailer.Clear();
             resultTrailer.Append(s);
         }
         else if (oneByte == 238)
         {
             // Latch to ANSI X12 encodation
             return ANSIX12_ENCODE;
         }
         else if (oneByte == 239)
         {
             // Latch to Text encodation
             return TEXT_ENCODE;
         }
         else if (oneByte == 240)
         {
             // Latch to EDIFACT encodation
             return EDIFACT_ENCODE;
         }
         else if (oneByte == 241)
         {
             // ECI Character
             // TODO(bbrown): I think we need to support ECI
             //throw ReaderException.getInstance();
             // Ignore this symbol for now
         }
         else if (oneByte >= 242)
         {
             // Not to be used in ASCII encodation
             throw new Exception("ReaderException");
         }
     }
     while (bits.available() > 0);
     return ASCII_ENCODE;
 }
        private static void decodeAlphanumericSegment(BitSource bits, StringBuilder result, int count, bool fc1InEffect)
        {
            // Read two characters at a time
            int start = result.ToString().Length;
            while (count > 1)
            {
                int nextTwoCharsBits = bits.readBits(11);
                result.Append(ALPHANUMERIC_CHARS[Math.Floor(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)]);
            }

            char[] c = new char[result.ToString().Length];
            SupportClass.GetCharsFromString(result.ToString(), 0, result.ToString().Length, c, 0);
            List<char> list = new List<char>(c);
            // 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 < list.Count; i++)
                {
                    if (list[i] == '%')
                    {
                        if (i < list.Count - 1 && list[i + 1] == '%')
                        {
                            // %% is rendered as %
                            list = list.RemoveRange(i + 1, 1);
                        }
                        else
                        {
                            // In alpha mode, % should be converted to FNC1 separator 0x1D
                            list[i] = Int32Extend.ToChar(0x1D);
                        }
                    }
                }
                result.Clear();
                result.Append(list.Join());
            }
        }
        public override Result decodeRow2(int rowNumber, BitArray row, Dictionary<object, object> hints)
        {
            int[] startPatternInfo = findStartPattern(row);
            int startCode = startPatternInfo[2];
            int codeSet;
            switch (startCode)
            {

                case CODE_START_A:
                    codeSet = CODE_CODE_A;
                    break;

                case CODE_START_B:
                    codeSet = CODE_CODE_B;
                    break;

                case CODE_START_C:
                    codeSet = CODE_CODE_C;
                    break;

                default:
                    throw new Exception("ReaderException");

            }

            bool done = false;
            bool isNextShifted = false;

            StringBuilder result = new StringBuilder();
            int lastStart = startPatternInfo[0];
            int nextStart = startPatternInfo[1];
            int[] counters = new int[6];

            int lastCode = 0;
            int code = 0;
            int checksumTotal = startCode;
            int multiplier = 0;
            bool lastCharacterWasPrintable = true;

            while (!done)
            {

                bool unshift = isNextShifted;
                isNextShifted = false;

                // Save off last code
                lastCode = code;

                // Decode another code from image
                code = decodeCode(row, counters, nextStart);

                // Remember whether the last code was printable or not (excluding CODE_STOP)
                if (code != CODE_STOP)
                {
                    lastCharacterWasPrintable = true;
                }

                // Add to checksum computation (if not CODE_STOP of course)
                if (code != CODE_STOP)
                {
                    multiplier++;
                    checksumTotal += multiplier * code;
                }

                // Advance to where the next code will to start
                lastStart = nextStart;
                for (int i = 0; i < counters.Length; i++)
                {
                    nextStart += counters[i];
                }

                // Take care of illegal start codes
                switch (code)
                {

                    case CODE_START_A:
                    case CODE_START_B:
                    case CODE_START_C:
                        throw new Exception("ReaderException");
                    }

                switch (codeSet)
                {

                    case CODE_CODE_A:
                        if (code < 64)
                        {
                            result.Append((char) (' ' + code));
                        }
                        else if (code < 96)
                        {
                            result.Append((char) (code - 64));
                        }
                        else
                        {
                            // Don't let CODE_STOP, which always appears, affect whether whether we think the last
                            // code was printable or not.
                            if (code != CODE_STOP)
                            {
                                lastCharacterWasPrintable = false;
                            }
                            switch (code)
                            {

                                case CODE_FNC_1:
                                case CODE_FNC_2:
                                case CODE_FNC_3:
                                case CODE_FNC_4_A:
                                    // do nothing?
                                    break;

                                case CODE_SHIFT:
                                    isNextShifted = true;
                                    codeSet = CODE_CODE_B;
                                    break;

                                case CODE_CODE_B:
                                    codeSet = CODE_CODE_B;
                                    break;

                                case CODE_CODE_C:
                                    codeSet = CODE_CODE_C;
                                    break;

                                case CODE_STOP:
                                    done = true;
                                    break;
                                }
                        }
                        break;

                    case CODE_CODE_B:
                        if (code < 96)
                        {
                            result.Append((char) (' ' + code));
                        }
                        else
                        {
                            if (code != CODE_STOP)
                            {
                                lastCharacterWasPrintable = false;
                            }
                            switch (code)
                            {

                                case CODE_FNC_1:
                                case CODE_FNC_2:
                                case CODE_FNC_3:
                                case CODE_FNC_4_B:
                                    // do nothing?
                                    break;

                                case CODE_SHIFT:
                                    isNextShifted = true;
                                    codeSet = CODE_CODE_C;
                                    break;

                                case CODE_CODE_A:
                                    codeSet = CODE_CODE_A;
                                    break;

                                case CODE_CODE_C:
                                    codeSet = CODE_CODE_C;
                                    break;

                                case CODE_STOP:
                                    done = true;
                                    break;
                                }
                        }
                        break;

                    case CODE_CODE_C:
                        if (code < 100)
                        {
                            if (code < 10)
                            {
                                result.Append('0');
                            }
                            result.Append(code);
                        }
                        else
                        {
                            if (code != CODE_STOP)
                            {
                                lastCharacterWasPrintable = false;
                            }
                            switch (code)
                            {

                                case CODE_FNC_1:
                                    // do nothing?
                                    break;

                                case CODE_CODE_A:
                                    codeSet = CODE_CODE_A;
                                    break;

                                case CODE_CODE_B:
                                    codeSet = CODE_CODE_B;
                                    break;

                                case CODE_STOP:
                                    done = true;
                                    break;
                                }
                        }
                        break;
                    }

                // Unshift back to another code set if we were shifted
                if (unshift)
                {
                    switch (codeSet)
                    {

                        case CODE_CODE_A:
                            codeSet = CODE_CODE_C;
                            break;

                        case CODE_CODE_B:
                            codeSet = CODE_CODE_A;
                            break;

                        case CODE_CODE_C:
                            codeSet = CODE_CODE_B;
                            break;
                        }
                }
            }

            // Check for ample whitespace following pattern, but, to do this we first need to remember that
            // we fudged decoding CODE_STOP since it actually has 7 bars, not 6. There is a black bar left
            // to read off. Would be slightly better to properly read. Here we just skip it:
            int width = row.Size;
            while (nextStart < width && row.get_Renamed(nextStart))
            {
                nextStart++;
            }
            if (!row.isRange(nextStart, Math.Min(width, nextStart + Math.Floor((nextStart - lastStart) / 2)), false))
            {
                throw new Exception("ReaderException");
            }

            // Pull out from sum the value of the penultimate check code
            checksumTotal -= multiplier * lastCode;
            // lastCode is the checksum then:
            if (checksumTotal % 103 != lastCode)
            {
                throw new Exception("ReaderException");
            }

            // Need to pull out the check digits from string
            int resultLength = result.ToString().Length;
            // Only bother if the result had at least one character, and if the checksum digit happened to
            // be a printable character. If it was just interpreted as a control code, nothing to remove.
            if (resultLength > 0 && lastCharacterWasPrintable)
            {
                if (codeSet == CODE_CODE_C)
                {
                    string s = result.ToString().Remove(resultLength - 2, resultLength - (resultLength - 2));
                    result.Clear();
                    result.Append(s);
                }
                else
                {
                    string s = result.ToString().Remove(resultLength - 1, resultLength - (resultLength - 1));
                    result.Clear();
                    result.Append(s);
                }
            }

            String resultString = result.ToString();

            if (resultString.Length == 0)
            {
                // Almost surely a false positive
                throw new Exception("ReaderException");
            }

            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            float left = (float) (startPatternInfo[1] + startPatternInfo[0]) / 2.0f;
            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            float right = (float) (nextStart + lastStart) / 2.0f;
            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            return new Result(resultString, null, new ResultPoint[]{new ResultPoint(left, (float) rowNumber), new ResultPoint(right, (float) rowNumber)}, BarcodeFormat.CODE_128);
        }
Exemple #5
0
 private static void determineNumSysAndCheckDigit(StringBuilder resultString, int lgPatternFound)
 {
     for (int numSys = 0; numSys <= 1; numSys++)
     {
         for (int d = 0; d < 10; d++)
         {
             if (lgPatternFound == NUMSYS_AND_CHECK_DIGIT_PATTERNS[numSys][d])
             {
                 string s = Int32Extend.ToChar(CharExtend.ToInt32('0') + numSys) + resultString.ToString() + Int32Extend.ToChar(CharExtend.ToInt32('0') + d);
                 resultString.Clear();
                 resultString.Append(s);
                 //resultString.Insert(0, (char) ('0' + numSys));
                 //resultString.Append((char) ('0' + d));
                 return ;
             }
         }
     }
     throw new Exception("ReaderException");
 }
        /// <summary> Add two numbers which are represented as strings.
        /// 
        /// </summary>
        /// <param name="value1">
        /// </param>
        /// <param name="value2">
        /// </param>
        /// <returns> the result of value1 + value2
        /// </returns>
        private static StringBuilder add(String value1, String value2)
        {
            StringBuilder temp1 = new StringBuilder();
            StringBuilder temp2 = new StringBuilder();
            //System.StringBuilder result = new System.StringBuilder();
            char[] result = new char[value1.Length];
            for (int i = 0; i < value1.Length; i++)
            {
                // Put zeros into the result.
                result[i] = '0';
            }
            int carry = 0;
            for (int i = value1.Length - 3; i > - 1; i -= 3)
            {

                temp1.Clear();
                temp1.Append(value1.CharAt(i));
                temp1.Append(value1.CharAt(i + 1));
                temp1.Append(value1.CharAt(i + 2));

                temp2.Clear();
                temp2.Append(value2.CharAt(i));
                temp2.Append(value2.CharAt(i + 1));
                temp2.Append(value2.CharAt(i + 2));

                int intValue1 = Int32.Parse(temp1.ToString());
                int intValue2 = Int32.Parse(temp2.ToString());

                int sumval = (intValue1 + intValue2 + carry) % 1000;
                carry = Math.Floor((intValue1 + intValue2 + carry) / 1000);

                result[i + 2] = Int32Extend.ToChar((sumval % 10) + CharExtend.ToInt32('0'));
                result[i + 1] = Int32Extend.ToChar((Math.Floor(sumval / 10) % 10) + CharExtend.ToInt32('0'));
                result[i] = Int32Extend.ToChar(Math.Floor(sumval / 100) + CharExtend.ToInt32('0'));
            }
            return new StringBuilder(result.Join());
        }
        /// <summary> Creates a reader that can be configured to check the last character as a check digit,
        /// or optionally attempt to decode "extended Code 39" sequences that are used to encode
        /// the full ASCII character set.
        /// 
        /// </summary>
        /// <param name="usingCheckDigit">if true, treat the last data character as a check digit, not
        /// data, and verify that the checksum passes.
        /// </param>
        /// <param name="extendedMode">if true, will attempt to decode extended Code 39 sequences in the
        /// text.
        /// </param>
        //public Code39Reader(bool usingCheckDigit, bool extendedMode)
        //{
        //    this.usingCheckDigit = usingCheckDigit;
        //    this.extendedMode = extendedMode;
        //}
        public override Result decodeRow2(int rowNumber, BitArray row, Dictionary<object, object> hints)
        {
            int[] start = findAsteriskPattern(row);
            int nextStart = start[1];
            int end = row.Size;

            // Read off white space
            while (nextStart < end && !row.get_Renamed(nextStart))
            {
                nextStart++;
            }

            StringBuilder result = new StringBuilder();
            int[] counters = new int[9];
            char decodedChar;
            int lastStart;
            do
            {
                recordPattern(row, nextStart, counters);
                int pattern = toNarrowWidePattern(counters);
                if (pattern < 0)
                {
                    throw new Exception("ReaderException");
                }
                decodedChar = patternToChar(pattern);
                result.Append(decodedChar);
                lastStart = nextStart;
                for (int i = 0; i < counters.Length; i++)
                {
                    nextStart += counters[i];
                }
                // Read off white space
                while (nextStart < end && !row.get_Renamed(nextStart))
                {
                    nextStart++;
                }
            }
            while (decodedChar != '*');
            string s = result.ToString().Remove(result.ToString().Length - 1, 1);
            result.Clear();
            result.Append(s); // remove asterisk

            // Look for whitespace after pattern:
            int lastPatternSize = 0;
            for (int i = 0; i < counters.Length; i++)
            {
                lastPatternSize += counters[i];
            }
            int whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize;
            // If 50% of last pattern size, following last pattern, is not whitespace, fail
            // (but if it's whitespace to the very end of the image, that's OK)
            if (nextStart != end && Math.Floor(whiteSpaceAfterEnd / 2) < lastPatternSize)
            {
                throw new Exception("ReaderException");
            }

            if (usingCheckDigit)
            {
                int max = result.ToString().Length - 1;
                int total = 0;
                for (int i = 0; i < max; i++)
                {
                    total += ALPHABET_STRING.IndexOf(result.ToString().CharAt(i));
                }
                if (total % 43 != ALPHABET_STRING.IndexOf(result.ToString().CharAt(max)))
                {
                    throw new Exception("ReaderException");
                }
                s = result.ToString().Remove(max, 1);
                result.Clear();
                result.Append(s);
            }

            String resultString = result.ToString();
            if (extendedMode)
            {
                resultString = decodeExtended(resultString);
            }

            if (resultString.Length == 0)
            {
                // Almost surely a false positive
                throw new Exception("ReaderException");
            }

            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            float left = (float) (start[1] + start[0]) / 2.0f;
            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            float right = (float) (nextStart + lastStart) / 2.0f;
            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            return new Result(resultString, null, new ResultPoint[]{new ResultPoint(left, (float) rowNumber), new ResultPoint(right, (float) rowNumber)}, BarcodeFormat.CODE_39);
        }
Exemple #8
0
 public static List<string> SeparateTokens(string input)
 {
     var result = new List<string>();
     var number = new StringBuilder();
     for (int i = 0; i < input.Length; i++)
     {
         if (input[i] == '-' && (i == 0 || input[i - 1] == ',' || input[i - 1] == '('))
         {
             number.Append('-');
         }
         else if (char.IsDigit(input[i]) || input[i] == '.')
         {
             number.Append(input[i]);
         }
         else if (!char.IsDigit(input[i]) && input[i] != '.' && number.Length != 0)
         {
             result.Add(number.ToString());
             number.Clear();
             i--;
         }
         else if (brackets.Contains(input[i]))
         {
             result.Add(input[i].ToString());
         }
         else if (arithmeticOperations.Contains(input[i]))
         {
             result.Add(input[i].ToString());
         }
         else if (input[i] == ',')
         {
             result.Add(",");
         }
         else if (i + 1 < input.Length && input.Substring(i, 2).ToLower() == "ln")
         {
             result.Add("ln");
             i++;
         }
         else if (i + 2 < input.Length && input.Substring(i, 3).ToLower() == "pow")
         {
             result.Add("pow");
             i += 2;
         }
         else if (i + 3 < input.Length && input.Substring(i, 4).ToLower() == "sqrt")
         {
             result.Add("sqrt");
             i += 3;
         }
         else
         {
             throw new ArgumentException("Invalid input");
         }
     }
     if (number.Length != 0)
     {
         result.Add(number.ToString());
     }
     return result;
 }