示例#1
0
        /// <summary>
        ///   <p>Like <see cref="decodeRow(int,ZXing.Common.BitArray,System.Collections.Generic.IDictionary{ZXing.DecodeHintType,object})"/>, but
        /// allows caller to inform method about where the UPC/EAN start pattern is
        /// found. This allows this to be computed once and reused across many implementations.</p>
        /// </summary>
        /// <param name="rowNumber">row index into the image</param>
        /// <param name="row">encoding of the row of the barcode image</param>
        /// <param name="startGuardRange">start/end column where the opening start pattern was found</param>
        /// <param name="hints">optional hints that influence decoding</param>
        /// <returns><see cref="Result"/> encapsulating the result of decoding a barcode in the row</returns>
        public virtual Result decodeRow(int rowNumber,
                                        BitArray row,
                                        int[] startGuardRange,
                                        IDictionary <DecodeHintType, object> hints)
        {
            var resultPointCallback = hints == null || !hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK) ? null :
                                      (ResultPointCallback)hints[DecodeHintType.NEED_RESULT_POINT_CALLBACK];

            if (resultPointCallback != null)
            {
                resultPointCallback(new ResultPoint(
                                        (startGuardRange[0] + startGuardRange[1]) / 2.0f, rowNumber
                                        ));
            }

            var result = decodeRowStringBuffer;

            result.Length = 0;
            var endStart = decodeMiddle(row, startGuardRange, result);

            if (endStart < 0)
            {
                return(null);
            }

            if (resultPointCallback != null)
            {
                resultPointCallback(new ResultPoint(
                                        endStart, rowNumber
                                        ));
            }

            var endRange = decodeEnd(row, endStart);

            if (endRange == null)
            {
                return(null);
            }

            if (resultPointCallback != null)
            {
                resultPointCallback(new ResultPoint(
                                        (endRange[0] + endRange[1]) / 2.0f, rowNumber
                                        ));
            }


            // Make sure there is a quiet zone at least as big as the end pattern after the barcode. The
            // spec might want more whitespace, but in practice this is the maximum we can count on.
            var end      = endRange[1];
            var quietEnd = end + (end - endRange[0]);

            if (quietEnd >= row.Size || !row.isRange(end, quietEnd, false))
            {
                return(null);
            }

            var resultString = result.ToString();

            // UPC/EAN should never be less than 8 chars anyway
            if (resultString.Length < 8)
            {
                return(null);
            }
            if (!checkChecksum(resultString))
            {
                return(null);
            }

            var left         = (startGuardRange[1] + startGuardRange[0]) / 2.0f;
            var right        = (endRange[1] + endRange[0]) / 2.0f;
            var format       = BarcodeFormat;
            var decodeResult = new Result(resultString,
                                          null, // no natural byte representation for these barcodes
                                          new ResultPoint[]
            {
                new ResultPoint(left, rowNumber),
                new ResultPoint(right, rowNumber)
            },
                                          format);

            var extensionResult = extensionReader.decodeRow(rowNumber, row, endRange[1]);

            if (extensionResult != null)
            {
                decodeResult.putMetadata(ResultMetadataType.UPC_EAN_EXTENSION, extensionResult.Text);
                decodeResult.putAllMetadata(extensionResult.ResultMetadata);
                decodeResult.addResultPoints(extensionResult.ResultPoints);
                int   extensionLength   = extensionResult.Text.Length;
                int[] allowedExtensions = hints != null && hints.ContainsKey(DecodeHintType.ALLOWED_EAN_EXTENSIONS) ?
                                          (int[])hints[DecodeHintType.ALLOWED_EAN_EXTENSIONS] : null;
                if (allowedExtensions != null)
                {
                    bool valid = false;
                    foreach (int length in allowedExtensions)
                    {
                        if (extensionLength == length)
                        {
                            valid = true;
                            break;
                        }
                    }
                    if (!valid)
                    {
                        return(null);
                    }
                }
            }

            if (format == BarcodeFormat.EAN_13 || format == BarcodeFormat.UPC_A)
            {
                String countryID = eanManSupport.lookupCountryIdentifier(resultString);
                if (countryID != null)
                {
                    decodeResult.putMetadata(ResultMetadataType.POSSIBLE_COUNTRY, countryID);
                }
            }

            return(decodeResult);
        }
示例#2
0
        /// <summary>
        /// <p>Like decodeRow(int, BitArray, java.util.Map), but
        /// allows caller to inform method about where the UPC/EAN start pattern is
        /// found. This allows this to be computed once and reused across many implementations.</p>
        /// </summary>
        virtual public Result decodeRow(int rowNumber,
                                        BitArray row,
                                        int[] startGuardRange,
                                        IDictionary <DecodeHintType, object> hints)
        {
            ResultPointCallback resultPointCallback = hints == null || !hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK) ? null :
                                                      (ResultPointCallback)hints[DecodeHintType.NEED_RESULT_POINT_CALLBACK];

            if (resultPointCallback != null)
            {
                resultPointCallback(new ResultPoint(
                                        (startGuardRange[0] + startGuardRange[1]) / 2.0f, rowNumber
                                        ));
            }

            StringBuilder result = decodeRowStringBuffer;

            result.Length = 0;
            int endStart = decodeMiddle(row, startGuardRange, result);

            if (endStart < 0)
            {
                return(null);
            }

            if (resultPointCallback != null)
            {
                resultPointCallback(new ResultPoint(
                                        endStart, rowNumber
                                        ));
            }

            int[] endRange = decodeEnd(row, endStart);
            if (endRange == null)
            {
                return(null);
            }

            if (resultPointCallback != null)
            {
                resultPointCallback(new ResultPoint(
                                        (endRange[0] + endRange[1]) / 2.0f, rowNumber
                                        ));
            }


            // Make sure there is a quiet zone at least as big as the end pattern after the barcode. The
            // spec might want more whitespace, but in practice this is the maximum we can count on.
            int end      = endRange[1];
            int quietEnd = end + (end - endRange[0]);

            if (quietEnd >= row.Size || !row.isRange(end, quietEnd, false))
            {
                return(null);
            }

            String resultString = result.ToString();

            if (!checkChecksum(resultString))
            {
                return(null);
            }

            float         left         = (startGuardRange[1] + startGuardRange[0]) / 2.0f;
            float         right        = (endRange[1] + endRange[0]) / 2.0f;
            BarcodeFormat format       = BarcodeFormat;
            Result        decodeResult = new Result(resultString,
                                                    null, // no natural byte representation for these barcodes
                                                    new ResultPoint[]
            {
                new ResultPoint(left, rowNumber),
                new ResultPoint(right, rowNumber)
            },
                                                    format);

            Result extensionResult = extensionReader.decodeRow(rowNumber, row, endRange[1]);

            if (extensionResult != null)
            {
                decodeResult.putMetadata(ResultMetadataType.UPC_EAN_EXTENSION, extensionResult.Text);
                decodeResult.putAllMetadata(extensionResult.ResultMetadata);
                decodeResult.addResultPoints(extensionResult.ResultPoints);
            }

            if (format == BarcodeFormat.EAN_13 || format == BarcodeFormat.UPC_A)
            {
                String countryID = eanManSupport.lookupCountryIdentifier(resultString);
                if (countryID != null)
                {
                    decodeResult.putMetadata(ResultMetadataType.POSSIBLE_COUNTRY, countryID);
                }
            }

            return(decodeResult);
        }