public void testDecodeDataCharacter()
        {
            RSSExpandedReader rssExpandedReader = new RSSExpandedReader();

            String path = "test/data/blackbox/rssexpanded-1/3.png";

            if (!File.Exists(path))
            {
                // Support running from project root too
                path = Path.Combine("..\\..\\..\\Source", path);
            }

#if !SILVERLIGHT
            var image = new Bitmap(Image.FromFile(path));
#else
            var image = new WriteableBitmap(0, 0);
            image.SetSource(File.OpenRead(path));
#endif
            BinaryBitmap binaryMap = new BinaryBitmap(new GlobalHistogramBinarizer(new BitmapLuminanceSource(image)));
            BitArray     row       = binaryMap.getBlackRow(binaryMap.Height / 2, null);

            int[] startEnd = { 145, 243 }; //image pixels where the A1 pattern starts (at 124) and ends (at 214)
            int   value    = 0;            // A
#if !SILVERLIGHT
            FinderPattern finderPatternA1 = new FinderPattern(value, startEnd, startEnd[0], startEnd[1], image.Height / 2);
#else
            FinderPattern finderPatternA1 = new FinderPattern(value, startEnd, startEnd[0], startEnd[1], image.PixelHeight / 2);
#endif
            //{1, 8, 4, 1, 1};
            DataCharacter dataCharacter = rssExpandedReader.decodeDataCharacter(row, finderPatternA1, true, false);

            Assert.AreEqual(19, dataCharacter.Value);
            Assert.AreEqual(1007, dataCharacter.ChecksumPortion);
        }
        public void testRetrieveNextPairPatterns()
        {
            RSSExpandedReader rssExpandedReader = new RSSExpandedReader();

            String path = "test/data/blackbox/rssexpanded-1/3.png";

            if (!File.Exists(path))
            {
                // Support running from project root too
                path = Path.Combine("..\\..\\..\\Source", path);
            }

#if !SILVERLIGHT
            var image = new Bitmap(Image.FromFile(path));
#else
            var image = new WriteableBitmap(0, 0);
            image.SetSource(File.OpenRead(path));
#endif
            BinaryBitmap        binaryMap     = new BinaryBitmap(new GlobalHistogramBinarizer(new BitmapLuminanceSource(image)));
            int                 rowNumber     = binaryMap.Height / 2;
            BitArray            row           = binaryMap.getBlackRow(rowNumber, null);
            List <ExpandedPair> previousPairs = new List <ExpandedPair>();

            ExpandedPair pair1 = rssExpandedReader.retrieveNextPair(row, previousPairs, rowNumber);
            previousPairs.Add(pair1);
            FinderPattern finderPattern = pair1.FinderPattern;
            Assert.IsNotNull(finderPattern);
            Assert.AreEqual(0, finderPattern.Value);

            ExpandedPair pair2 = rssExpandedReader.retrieveNextPair(row, previousPairs, rowNumber);
            previousPairs.Add(pair2);
            finderPattern = pair2.FinderPattern;
            Assert.IsNotNull(finderPattern);
            Assert.AreEqual(0, finderPattern.Value);
        }
 internal ExpandedPair(DataCharacter leftChar,
                       DataCharacter rightChar,
                       FinderPattern finderPattern)
 {
     LeftChar      = leftChar;
     RightChar     = rightChar;
     FinderPattern = finderPattern;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="FinderPatternInfo"/> class.
 /// </summary>
 /// <param name="patternCenters">The pattern centers.</param>
 public FinderPatternInfo(FinderPattern[] patternCenters)
 {
     /*
      * this.bottomLeft = patternCenters[0];
      * this.topLeft = patternCenters[1];
      * this.topRight = patternCenters[2];
      */
     this.topLeft = patternCenters[0];
 }
Exemple #5
0
 internal ExpandedPair(DataCharacter leftChar,
              DataCharacter rightChar,
              FinderPattern finderPattern,
              bool mayBeLast)
 {
    LeftChar = leftChar;
    RightChar = rightChar;
    FinderPattern = finderPattern;
    MayBeLast = mayBeLast;
 }
 internal ExpandedPair(DataCharacter leftChar,
                       DataCharacter rightChar,
                       FinderPattern finderPattern,
                       bool mayBeLast)
 {
     LeftChar      = leftChar;
     RightChar     = rightChar;
     FinderPattern = finderPattern;
     MayBeLast     = mayBeLast;
 }
        public void testDecodeCheckCharacter()
        {
            var rssExpandedReader = new RSSExpandedReader();

            var image     = TestCaseUtil.readImage("test/data/blackbox/rssexpanded-1", "3.png");
            var binaryMap = new BinaryBitmap(new GlobalHistogramBinarizer(new BitmapLuminanceSource(image)));
            var row       = binaryMap.getBlackRow(binaryMap.Height / 2, null);

            int[] startEnd        = { 145, 243 }; //image pixels where the A1 pattern starts (at 124) and ends (at 214)
            int   value           = 0;            // A
            var   finderPatternA1 = new FinderPattern(value, startEnd, startEnd[0], startEnd[1], image.Height / 2);
            //{1, 8, 4, 1, 1};
            var dataCharacter = rssExpandedReader.decodeDataCharacter(row, finderPatternA1, true, true);

            Assert.AreEqual(98, dataCharacter.Value);
        }
Exemple #8
0
        /// <summary>
        /// Orders an array of three ResultPoints in an order [A,B,C] such that AB is less than AC and
        /// BC is less than AC and the angle between BC and BA is less than 180 degrees.
        /// </summary>
        /// <param name="patterns">array of three <see cref="ResultPoint" /> to order</param>
        internal static void orderBestPatterns(FinderPattern[] patterns)
        {
            // Find distances between pattern centers
            float zeroOneDistance = distance(patterns[0], patterns[1]);
            float oneTwoDistance  = distance(patterns[1], patterns[2]);
            float zeroTwoDistance = distance(patterns[0], patterns[2]);

            FinderPattern pointA, pointB, pointC;

            // Assume one closest to other two is B; A and C will just be guesses at first
            if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance)
            {
                pointB = patterns[0];
                pointA = patterns[1];
                pointC = patterns[2];
            }
            else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance)
            {
                pointB = patterns[1];
                pointA = patterns[0];
                pointC = patterns[2];
            }
            else
            {
                pointB = patterns[2];
                pointA = patterns[0];
                pointC = patterns[1];
            }

            // Use cross product to figure out whether A and C are correct or flipped.
            // This asks whether BC x BA has a positive z component, which is the arrangement
            // we want for A, B, C. If it's negative, then we've got it flipped around and
            // should swap A and C.
            if (crossProductZ(pointA, pointB, pointC) < 0.0f)
            {
                FinderPattern temp = pointA;
                pointA = pointC;
                pointC = temp;
            }

            patterns[0] = pointA;
            patterns[1] = pointB;
            patterns[2] = pointC;
        }
Exemple #9
0
        private bool checkPairSequence(List <ExpandedPair> previousPairs, FinderPattern pattern, out bool mayBeLast)
        {
            mayBeLast = false;
            int currentSequenceLength = previousPairs.Count + 1;

            if (currentSequenceLength > currentSequence.Length)
            {
                return(false);
            }

            for (int pos = 0; pos < previousPairs.Count; ++pos)
            {
                currentSequence[pos] = previousPairs[pos].FinderPattern.Value;
            }

            currentSequence[currentSequenceLength - 1] = pattern.Value;

            foreach (int[] validSequence in FINDER_PATTERN_SEQUENCES)
            {
                if (validSequence.Length >= currentSequenceLength)
                {
                    bool valid = true;
                    for (int pos = 0; pos < currentSequenceLength; ++pos)
                    {
                        if (currentSequence[pos] != validSequence[pos])
                        {
                            valid = false;
                            break;
                        }
                    }

                    if (valid)
                    {
                        mayBeLast = currentSequenceLength == validSequence.Length;
                        return(true);
                    }
                }
            }

            return(false);
        }
Exemple #10
0
        public virtual QRCodeSymbol getQRCodeSymbol(int[][] image)
        {
            int num = (image.Length < image[0].Length) ? image[0].Length : image.Length;

            DECIMAL_POINT = 0x17 - QRCodeUtility.sqrt(num / 0x100);
            this.bitmap   = this.filterImage(image);
            this.canvas.println("Drawing matrix.");
            this.canvas.drawMatrix(this.bitmap);
            this.canvas.println("Scanning Finder Pattern.");
            FinderPattern finderPattern = null;

            try
            {
                finderPattern = FinderPattern.findFinderPattern(this.bitmap);
            }
            catch (FinderPatternNotFoundException)
            {
                this.canvas.println("Not found, now retrying...");
                this.bitmap = this.applyCrossMaskingMedianFilter(this.bitmap, 5);
                this.canvas.drawMatrix(this.bitmap);
                int num2 = 0;
                while (true)
                {
                    if (num2 >= 0x3b9aca00)
                    {
                        break;
                    }
                    num2++;
                }
                try
                {
                    finderPattern = FinderPattern.findFinderPattern(this.bitmap);
                }
                catch (FinderPatternNotFoundException exception2)
                {
                    throw new SymbolNotFoundException(exception2.Message);
                }
                catch (VersionInformationException exception3)
                {
                    throw new SymbolNotFoundException(exception3.Message);
                }
            }
            catch (VersionInformationException exception4)
            {
                throw new SymbolNotFoundException(exception4.Message);
            }
            this.canvas.println("FinderPattern at");
            string str = finderPattern.getCenter(0).ToString() + finderPattern.getCenter(1).ToString() + finderPattern.getCenter(2).ToString();

            this.canvas.println(str);
            int[] numArray = finderPattern.getAngle();
            this.canvas.println("Angle*4098: Sin " + Convert.ToString(numArray[0]) + "  Cos " + Convert.ToString(numArray[1]));
            int version = finderPattern.Version;

            this.canvas.println("Version: " + Convert.ToString(version));
            if ((version < 1) || (version > 40))
            {
                throw new InvalidVersionException("Invalid version: " + version);
            }
            AlignmentPattern alignmentPattern = null;

            try
            {
                alignmentPattern = AlignmentPattern.findAlignmentPattern(this.bitmap, finderPattern);
            }
            catch (AlignmentPatternNotFoundException exception5)
            {
                throw new SymbolNotFoundException(exception5.Message);
            }
            int length = alignmentPattern.getCenter().Length;

            this.canvas.println("AlignmentPatterns at");
            for (int i = 0; i < length; i++)
            {
                string str2 = "";
                for (int j = 0; j < length; j++)
                {
                    str2 = str2 + alignmentPattern.getCenter()[j][i].ToString();
                }
                this.canvas.println(str2);
            }
            this.canvas.println("Creating sampling grid.");
            this.samplingGrid = this.getSamplingGrid(finderPattern, alignmentPattern);
            this.canvas.println("Reading grid.");
            bool[][] moduleMatrix = null;
            try
            {
                moduleMatrix = this.getQRCodeMatrix(this.bitmap, this.samplingGrid);
            }
            catch (IndexOutOfRangeException)
            {
                throw new SymbolNotFoundException("Sampling grid exceeded image boundary");
            }
            return(new QRCodeSymbol(moduleMatrix));
        }
Exemple #11
0
 private static bool isNotA1left(FinderPattern pattern, bool isOddPattern, bool leftChar)
 {
    // A1: pattern.getValue is 0 (A), and it's an oddPattern, and it is a left char
    return !(pattern.Value == 0 && isOddPattern && leftChar);
 }
Exemple #12
0
            public int Compare(FinderPattern center1, FinderPattern center2)
            {
                float value = center2.EstimatedModuleSize - center1.EstimatedModuleSize;

                return(value <0.0 ? -1 : value> 0.0 ? 1 : 0);
            }
Exemple #13
0
        internal virtual SamplingGrid getSamplingGrid(FinderPattern finderPattern, AlignmentPattern alignmentPattern)
        {
            Point[][] centers     = alignmentPattern.getCenter();
            int       version     = finderPattern.Version;
            int       sqrtCenters = version / 7 + 2;

            centers[0][0] = finderPattern.getCenter(0);
            centers[sqrtCenters - 1][0] = finderPattern.getCenter(1);
            centers[0][sqrtCenters - 1] = finderPattern.getCenter(2);
            int          sqrtNumArea  = sqrtCenters - 1;
            SamplingGrid samplingGrid = new SamplingGrid(sqrtNumArea);
            Axis         axis         = new Axis(finderPattern.getAngle(), finderPattern.getModuleSize());

            for (int ay = 0; ay < sqrtNumArea; ay++)
            {
                for (int ax = 0; ax < sqrtNumArea; ax++)
                {
                    QRCodeImageReader.ModulePitch modulePitch = new QRCodeImageReader.ModulePitch(this);
                    Line baseLineX = new Line();
                    Line baseLineY = new Line();
                    axis.ModulePitch = finderPattern.getModuleSize();
                    Point[][] logicalCenters         = AlignmentPattern.getLogicalCenter(finderPattern);
                    Point     upperLeftPoint         = centers[ax][ay];
                    Point     upperRightPoint        = centers[ax + 1][ay];
                    Point     lowerLeftPoint         = centers[ax][ay + 1];
                    Point     lowerRightPoint        = centers[ax + 1][ay + 1];
                    Point     logicalUpperLeftPoint  = logicalCenters[ax][ay];
                    Point     logicalUpperRightPoint = logicalCenters[ax + 1][ay];
                    Point     logicalLowerLeftPoint  = logicalCenters[ax][ay + 1];
                    Point     logicalLowerRightPoint = logicalCenters[ax + 1][ay + 1];
                    if (ax == 0 && ay == 0)
                    {
                        if (sqrtNumArea == 1)
                        {
                            upperLeftPoint  = axis.translate(upperLeftPoint, -3, -3);
                            upperRightPoint = axis.translate(upperRightPoint, 3, -3);
                            lowerLeftPoint  = axis.translate(lowerLeftPoint, -3, 3);
                            lowerRightPoint = axis.translate(lowerRightPoint, 6, 6);
                            logicalUpperLeftPoint.translate(-6, -6);
                            logicalUpperRightPoint.translate(3, -3);
                            logicalLowerLeftPoint.translate(-3, 3);
                            logicalLowerRightPoint.translate(6, 6);
                        }
                        else
                        {
                            upperLeftPoint  = axis.translate(upperLeftPoint, -3, -3);
                            upperRightPoint = axis.translate(upperRightPoint, 0, -6);
                            lowerLeftPoint  = axis.translate(lowerLeftPoint, -6, 0);
                            logicalUpperLeftPoint.translate(-6, -6);
                            logicalUpperRightPoint.translate(0, -6);
                            logicalLowerLeftPoint.translate(-6, 0);
                        }
                    }
                    else
                    {
                        if (ax == 0 && ay == sqrtNumArea - 1)
                        {
                            upperLeftPoint  = axis.translate(upperLeftPoint, -6, 0);
                            lowerLeftPoint  = axis.translate(lowerLeftPoint, -3, 3);
                            lowerRightPoint = axis.translate(lowerRightPoint, 0, 6);
                            logicalUpperLeftPoint.translate(-6, 0);
                            logicalLowerLeftPoint.translate(-6, 6);
                            logicalLowerRightPoint.translate(0, 6);
                        }
                        else
                        {
                            if (ax == sqrtNumArea - 1 && ay == 0)
                            {
                                upperLeftPoint  = axis.translate(upperLeftPoint, 0, -6);
                                upperRightPoint = axis.translate(upperRightPoint, 3, -3);
                                lowerRightPoint = axis.translate(lowerRightPoint, 6, 0);
                                logicalUpperLeftPoint.translate(0, -6);
                                logicalUpperRightPoint.translate(6, -6);
                                logicalLowerRightPoint.translate(6, 0);
                            }
                            else
                            {
                                if (ax == sqrtNumArea - 1 && ay == sqrtNumArea - 1)
                                {
                                    lowerLeftPoint  = axis.translate(lowerLeftPoint, 0, 6);
                                    upperRightPoint = axis.translate(upperRightPoint, 6, 0);
                                    lowerRightPoint = axis.translate(lowerRightPoint, 6, 6);
                                    logicalLowerLeftPoint.translate(0, 6);
                                    logicalUpperRightPoint.translate(6, 0);
                                    logicalLowerRightPoint.translate(6, 6);
                                }
                                else
                                {
                                    if (ax == 0)
                                    {
                                        upperLeftPoint = axis.translate(upperLeftPoint, -6, 0);
                                        lowerLeftPoint = axis.translate(lowerLeftPoint, -6, 0);
                                        logicalUpperLeftPoint.translate(-6, 0);
                                        logicalLowerLeftPoint.translate(-6, 0);
                                    }
                                    else
                                    {
                                        if (ax == sqrtNumArea - 1)
                                        {
                                            upperRightPoint = axis.translate(upperRightPoint, 6, 0);
                                            lowerRightPoint = axis.translate(lowerRightPoint, 6, 0);
                                            logicalUpperRightPoint.translate(6, 0);
                                            logicalLowerRightPoint.translate(6, 0);
                                        }
                                        else
                                        {
                                            if (ay == 0)
                                            {
                                                upperLeftPoint  = axis.translate(upperLeftPoint, 0, -6);
                                                upperRightPoint = axis.translate(upperRightPoint, 0, -6);
                                                logicalUpperLeftPoint.translate(0, -6);
                                                logicalUpperRightPoint.translate(0, -6);
                                            }
                                            else
                                            {
                                                if (ay == sqrtNumArea - 1)
                                                {
                                                    lowerLeftPoint  = axis.translate(lowerLeftPoint, 0, 6);
                                                    lowerRightPoint = axis.translate(lowerRightPoint, 0, 6);
                                                    logicalLowerLeftPoint.translate(0, 6);
                                                    logicalLowerRightPoint.translate(0, 6);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (ax == 0)
                    {
                        logicalUpperRightPoint.translate(1, 0);
                        logicalLowerRightPoint.translate(1, 0);
                    }
                    else
                    {
                        logicalUpperLeftPoint.translate(-1, 0);
                        logicalLowerLeftPoint.translate(-1, 0);
                    }
                    if (ay == 0)
                    {
                        logicalLowerLeftPoint.translate(0, 1);
                        logicalLowerRightPoint.translate(0, 1);
                    }
                    else
                    {
                        logicalUpperLeftPoint.translate(0, -1);
                        logicalUpperRightPoint.translate(0, -1);
                    }
                    int logicalWidth  = logicalUpperRightPoint.X - logicalUpperLeftPoint.X;
                    int logicalHeight = logicalLowerLeftPoint.Y - logicalUpperLeftPoint.Y;
                    if (version < 7)
                    {
                        logicalWidth  += 3;
                        logicalHeight += 3;
                    }
                    modulePitch.top    = this.getAreaModulePitch(upperLeftPoint, upperRightPoint, logicalWidth - 1);
                    modulePitch.left   = this.getAreaModulePitch(upperLeftPoint, lowerLeftPoint, logicalHeight - 1);
                    modulePitch.bottom = this.getAreaModulePitch(lowerLeftPoint, lowerRightPoint, logicalWidth - 1);
                    modulePitch.right  = this.getAreaModulePitch(upperRightPoint, lowerRightPoint, logicalHeight - 1);
                    baseLineX.setP1(upperLeftPoint);
                    baseLineY.setP1(upperLeftPoint);
                    baseLineX.setP2(lowerLeftPoint);
                    baseLineY.setP2(upperRightPoint);
                    samplingGrid.initGrid(ax, ay, logicalWidth, logicalHeight);
                    for (int i = 0; i < logicalWidth; i++)
                    {
                        Line gridLineX = new Line(baseLineX.getP1(), baseLineX.getP2());
                        axis.Origin      = gridLineX.getP1();
                        axis.ModulePitch = modulePitch.top;
                        gridLineX.setP1(axis.translate(i, 0));
                        axis.Origin      = gridLineX.getP2();
                        axis.ModulePitch = modulePitch.bottom;
                        gridLineX.setP2(axis.translate(i, 0));
                        samplingGrid.setXLine(ax, ay, i, gridLineX);
                    }
                    for (int i = 0; i < logicalHeight; i++)
                    {
                        Line gridLineY = new Line(baseLineY.getP1(), baseLineY.getP2());
                        axis.Origin      = gridLineY.getP1();
                        axis.ModulePitch = modulePitch.left;
                        gridLineY.setP1(axis.translate(0, i));
                        axis.Origin      = gridLineY.getP2();
                        axis.ModulePitch = modulePitch.right;
                        gridLineY.setP2(axis.translate(0, i));
                        samplingGrid.setYLine(ax, ay, i, gridLineY);
                    }
                }
            }
            return(samplingGrid);
        }
Exemple #14
0
        public FinderPatternInfo[] findMulti(IDictionary <DecodeHintType, object> hints)
        {
            bool      tryHarder   = hints != null && hints.ContainsKey(DecodeHintType.TRY_HARDER);
            bool      pureBarcode = hints != null && hints.ContainsKey(DecodeHintType.PURE_BARCODE);
            BitMatrix image       = Image;
            int       maxI        = image.Height;
            int       maxJ        = image.Width;
            // We are looking for black/white/black/white/black modules in
            // 1:1:3:1:1 ratio; this tracks the number of such modules seen so far

            // Let's assume that the maximum version QR Code we support takes up 1/4 the height of the
            // image, and then account for the center being 3 modules in size. This gives the smallest
            // number of pixels the center could be, so skip this often. When trying harder, look for all
            // QR versions regardless of how dense they are.
            int iSkip = (int)(maxI / (MAX_MODULES * 4.0f) * 3);

            if (iSkip < MIN_SKIP || tryHarder)
            {
                iSkip = MIN_SKIP;
            }

            int[] stateCount = new int[5];
            for (int i = iSkip - 1; i < maxI; i += iSkip)
            {
                // Get a row of black/white values
                stateCount[0] = 0;
                stateCount[1] = 0;
                stateCount[2] = 0;
                stateCount[3] = 0;
                stateCount[4] = 0;
                int currentState = 0;
                for (int j = 0; j < maxJ; j++)
                {
                    if (image[j, i])
                    {
                        // Black pixel
                        if ((currentState & 1) == 1)
                        { // Counting white pixels
                            currentState++;
                        }
                        stateCount[currentState]++;
                    }
                    else
                    {             // White pixel
                        if ((currentState & 1) == 0)
                        {         // Counting black pixels
                            if (currentState == 4)
                            {     // A winner?
                                if (foundPatternCross(stateCount) && handlePossibleCenter(stateCount, i, j, pureBarcode))
                                { // Yes
                                    // Clear state to start looking again
                                    currentState  = 0;
                                    stateCount[0] = 0;
                                    stateCount[1] = 0;
                                    stateCount[2] = 0;
                                    stateCount[3] = 0;
                                    stateCount[4] = 0;
                                }
                                else
                                { // No, shift counts back by two
                                    stateCount[0] = stateCount[2];
                                    stateCount[1] = stateCount[3];
                                    stateCount[2] = stateCount[4];
                                    stateCount[3] = 1;
                                    stateCount[4] = 0;
                                    currentState  = 3;
                                }
                            }
                            else
                            {
                                stateCount[++currentState]++;
                            }
                        }
                        else
                        { // Counting white pixels
                            stateCount[currentState]++;
                        }
                    }
                } // for j=...

                if (foundPatternCross(stateCount))
                {
                    handlePossibleCenter(stateCount, i, maxJ, pureBarcode);
                } // end if foundPatternCross
            }     // for i=iSkip-1 ...
            FinderPattern[][] patternInfo = selectMutipleBestPatterns();
            if (patternInfo == null)
            {
                return(EMPTY_RESULT_ARRAY);
            }
            List <FinderPatternInfo> result = new List <FinderPatternInfo>();

            foreach (FinderPattern[] pattern in patternInfo)
            {
                FinderPattern.orderBestPatterns(pattern);
                result.Add(new FinderPatternInfo(pattern));
            }

            if (result.Count == 0)
            {
                return(EMPTY_RESULT_ARRAY);
            }
            else
            {
                return(result.ToArray());
            }
        }
        /// <summary>
        /// </summary>
        /// <returns>the 3 best <see cref="FinderPattern" />s from our list of candidates. The "best" are
        ///         those that have been detected at least CENTER_QUORUM times, and whose module
        ///         size differs from the average among those patterns the least
        /// </returns>
        private FinderPattern[][] selectMultipleBestPatterns()
        {
            List <FinderPattern> possibleCenters = PossibleCenters;
            int size = possibleCenters.Count;

            if (size < 3)
            {
                // Couldn't find enough finder patterns
                return(null);
            }

            /*
             * Begin HE modifications to safely detect multiple codes of equal size
             */
            if (size == 3)
            {
                return(new FinderPattern[][]
                {
                    new FinderPattern[]
                    {
                        possibleCenters[0],
                        possibleCenters[1],
                        possibleCenters[2]
                    }
                });
            }

            // Sort by estimated module size to speed up the upcoming checks
            possibleCenters.Sort(new ModuleSizeComparator());

            /*
             * Now lets start: build a list of tuples of three finder locations that
             *  - feature similar module sizes
             *  - are placed in a distance so the estimated module count is within the QR specification
             *  - have similar distance between upper left/right and left top/bottom finder patterns
             *  - form a triangle with 90° angle (checked by comparing top right/bottom left distance
             *    with pythagoras)
             *
             * Note: we allow each point to be used for more than one code region: this might seem
             * counterintuitive at first, but the performance penalty is not that big. At this point,
             * we cannot make a good quality decision whether the three finders actually represent
             * a QR code, or are just by chance layouted so it looks like there might be a QR code there.
             * So, if the layout seems right, lets have the decoder try to decode.
             */

            List <FinderPattern[]> results = new List <FinderPattern[]>(); // holder for the results

            for (int i1 = 0; i1 < (size - 2); i1++)
            {
                FinderPattern p1 = possibleCenters[i1];
                if (p1 == null)
                {
                    continue;
                }

                for (int i2 = i1 + 1; i2 < (size - 1); i2++)
                {
                    FinderPattern p2 = possibleCenters[i2];
                    if (p2 == null)
                    {
                        continue;
                    }

                    // Compare the expected module sizes; if they are really off, skip
                    float vModSize12 = (p1.EstimatedModuleSize - p2.EstimatedModuleSize) /
                                       Math.Min(p1.EstimatedModuleSize, p2.EstimatedModuleSize);
                    float vModSize12A = Math.Abs(p1.EstimatedModuleSize - p2.EstimatedModuleSize);
                    if (vModSize12A > DIFF_MODSIZE_CUTOFF && vModSize12 >= DIFF_MODSIZE_CUTOFF_PERCENT)
                    {
                        // break, since elements are ordered by the module size deviation there cannot be
                        // any more interesting elements for the given p1.
                        break;
                    }

                    for (int i3 = i2 + 1; i3 < size; i3++)
                    {
                        FinderPattern p3 = possibleCenters[i3];
                        if (p3 == null)
                        {
                            continue;
                        }

                        // Compare the expected module sizes; if they are really off, skip
                        float vModSize23 = (p2.EstimatedModuleSize - p3.EstimatedModuleSize) /
                                           Math.Min(p2.EstimatedModuleSize, p3.EstimatedModuleSize);
                        float vModSize23A = Math.Abs(p2.EstimatedModuleSize - p3.EstimatedModuleSize);
                        if (vModSize23A > DIFF_MODSIZE_CUTOFF && vModSize23 >= DIFF_MODSIZE_CUTOFF_PERCENT)
                        {
                            // break, since elements are ordered by the module size deviation there cannot be
                            // any more interesting elements for the given p1.
                            break;
                        }

                        FinderPattern[] test = { p1, p2, p3 };
                        ResultPoint.orderBestPatterns(test);

                        // Calculate the distances: a = topleft-bottomleft, b=topleft-topright, c = diagonal
                        FinderPatternInfo info = new FinderPatternInfo(test);
                        float             dA   = ResultPoint.distance(info.TopLeft, info.BottomLeft);
                        float             dC   = ResultPoint.distance(info.TopRight, info.BottomLeft);
                        float             dB   = ResultPoint.distance(info.TopLeft, info.TopRight);

                        // Check the sizes
                        float estimatedModuleCount = (dA + dB) / (p1.EstimatedModuleSize * 2.0f);
                        if (estimatedModuleCount > MAX_MODULE_COUNT_PER_EDGE ||
                            estimatedModuleCount < MIN_MODULE_COUNT_PER_EDGE)
                        {
                            continue;
                        }

                        // Calculate the difference of the edge lengths in percent
                        float vABBC = Math.Abs((dA - dB) / Math.Min(dA, dB));
                        if (vABBC >= 0.1f)
                        {
                            continue;
                        }

                        // Calculate the diagonal length by assuming a 90° angle at topleft
                        float dCpy = (float)Math.Sqrt((double)dA * dA + (double)dB * dB);
                        // Compare to the real distance in %
                        float vPyC = Math.Abs((dC - dCpy) / Math.Min(dC, dCpy));

                        if (vPyC >= 0.1f)
                        {
                            continue;
                        }

                        // All tests passed!
                        results.Add(test);
                    } // end iterate p3
                }     // end iterate p2
            }         // end iterate p1

            if (results.Count != 0)
            {
                return(results.ToArray());
            }

            // Nothing found!
            return(null);
        }
        public virtual QRCodeSymbol getQRCodeSymbol(int[][] image)
        {
            int longSide = (image.Length < image[0].Length)?image[0].Length:image.Length;

            QRCodeImageReader.DECIMAL_POINT = 23 - QRCodeUtility.sqrt(longSide / 256);
            bitmap = filterImage(image);
            canvas.println("Drawing matrix.");
            canvas.drawMatrix(bitmap);

            canvas.println("Scanning Finder Pattern.");
            FinderPattern finderPattern = null;

            try
            {
                finderPattern = FinderPattern.findFinderPattern(bitmap);
            }
            catch (FinderPatternNotFoundException)
            {
                canvas.println("Not found, now retrying...");
                bitmap = applyCrossMaskingMedianFilter(bitmap, 5);
                canvas.drawMatrix(bitmap);
                for (int i = 0; i < 1000000000; i++)
                {
                    ;
                }
                try
                {
                    finderPattern = FinderPattern.findFinderPattern(bitmap);
                }
                catch (FinderPatternNotFoundException e2)
                {
                    throw new SymbolNotFoundException(e2.Message);
                }
                catch (VersionInformationException e2)
                {
                    throw new SymbolNotFoundException(e2.Message);
                }
            }
            catch (VersionInformationException e)
            {
                throw new SymbolNotFoundException(e.Message);
            }


            canvas.println("FinderPattern at");
            String finderPatternCoordinates = finderPattern.getCenter(FinderPattern.UL).ToString() + finderPattern.getCenter(FinderPattern.UR).ToString() + finderPattern.getCenter(FinderPattern.DL).ToString();

            canvas.println(finderPatternCoordinates);
            int[] sincos = finderPattern.getAngle();
            canvas.println("Angle*4098: Sin " + System.Convert.ToString(sincos[0]) + "  " + "Cos " + System.Convert.ToString(sincos[1]));

            int version = finderPattern.Version;

            canvas.println("Version: " + System.Convert.ToString(version));
            if (version < 1 || version > 40)
            {
                throw new InvalidVersionException("Invalid version: " + version);
            }

            AlignmentPattern alignmentPattern = null;

            try
            {
                alignmentPattern = AlignmentPattern.findAlignmentPattern(bitmap, finderPattern);
            }
            catch (AlignmentPatternNotFoundException e)
            {
                throw new SymbolNotFoundException(e.Message);
            }

            int matrixLength = alignmentPattern.getCenter().Length;

            canvas.println("AlignmentPatterns at");
            for (int y = 0; y < matrixLength; y++)
            {
                String alignmentPatternCoordinates = "";
                for (int x = 0; x < matrixLength; x++)
                {
                    alignmentPatternCoordinates += alignmentPattern.getCenter()[x][y].ToString();
                }
                canvas.println(alignmentPatternCoordinates);
            }
            //for(int i = 0; i < 500000; i++) Console.out.println("");

            canvas.println("Creating sampling grid.");
            //[TODO] need all-purpose method
            //samplingGrid = getSamplingGrid2_6(finderPattern, alignmentPattern);
            samplingGrid = getSamplingGrid(finderPattern, alignmentPattern);
            canvas.println("Reading grid.");
            bool[][] qRCodeMatrix = null;
            try
            {
                qRCodeMatrix = getQRCodeMatrix(bitmap, samplingGrid);
            }
            catch (System.IndexOutOfRangeException)
            {
                throw new SymbolNotFoundException("Sampling grid exceeded image boundary");
            }
            //canvas.drawMatrix(qRCodeMatrix);
            return(new QRCodeSymbol(qRCodeMatrix));
        }
Exemple #17
0
        internal virtual SamplingGrid getSamplingGrid(FinderPattern finderPattern, AlignmentPattern alignmentPattern)
        {
            Point[][] pointArray = alignmentPattern.getCenter();
            int       version    = finderPattern.Version;
            int       num2       = (version / 7) + 2;

            pointArray[0][0]        = finderPattern.getCenter(0);
            pointArray[num2 - 1][0] = finderPattern.getCenter(1);
            pointArray[0][num2 - 1] = finderPattern.getCenter(2);
            int          sqrtNumArea = num2 - 1;
            SamplingGrid grid        = new SamplingGrid(sqrtNumArea);
            Axis         axis        = new Axis(finderPattern.getAngle(), finderPattern.getModuleSize());

            for (int i = 0; i < sqrtNumArea; i++)
            {
                for (int j = 0; j < sqrtNumArea; j++)
                {
                    ModulePitch pitch = new ModulePitch(this);
                    Line        line  = new Line();
                    Line        line2 = new Line();
                    axis.ModulePitch = finderPattern.getModuleSize();
                    Point[][] pointArray2 = AlignmentPattern.getLogicalCenter(finderPattern);
                    Point     origin      = pointArray[j][i];
                    Point     point2      = pointArray[j + 1][i];
                    Point     point3      = pointArray[j][i + 1];
                    Point     point4      = pointArray[j + 1][i + 1];
                    Point     point5      = pointArray2[j][i];
                    Point     point6      = pointArray2[j + 1][i];
                    Point     point7      = pointArray2[j][i + 1];
                    Point     point8      = pointArray2[j + 1][i + 1];
                    if ((j == 0) && (i == 0))
                    {
                        if (sqrtNumArea == 1)
                        {
                            origin = axis.translate(origin, -3, -3);
                            point2 = axis.translate(point2, 3, -3);
                            point3 = axis.translate(point3, -3, 3);
                            point4 = axis.translate(point4, 6, 6);
                            point5.translate(-6, -6);
                            point6.translate(3, -3);
                            point7.translate(-3, 3);
                            point8.translate(6, 6);
                        }
                        else
                        {
                            origin = axis.translate(origin, -3, -3);
                            point2 = axis.translate(point2, 0, -6);
                            point3 = axis.translate(point3, -6, 0);
                            point5.translate(-6, -6);
                            point6.translate(0, -6);
                            point7.translate(-6, 0);
                        }
                    }
                    else if ((j == 0) && (i == (sqrtNumArea - 1)))
                    {
                        origin = axis.translate(origin, -6, 0);
                        point3 = axis.translate(point3, -3, 3);
                        point4 = axis.translate(point4, 0, 6);
                        point5.translate(-6, 0);
                        point7.translate(-6, 6);
                        point8.translate(0, 6);
                    }
                    else if ((j == (sqrtNumArea - 1)) && (i == 0))
                    {
                        origin = axis.translate(origin, 0, -6);
                        point2 = axis.translate(point2, 3, -3);
                        point4 = axis.translate(point4, 6, 0);
                        point5.translate(0, -6);
                        point6.translate(6, -6);
                        point8.translate(6, 0);
                    }
                    else if ((j == (sqrtNumArea - 1)) && (i == (sqrtNumArea - 1)))
                    {
                        point3 = axis.translate(point3, 0, 6);
                        point2 = axis.translate(point2, 6, 0);
                        point4 = axis.translate(point4, 6, 6);
                        point7.translate(0, 6);
                        point6.translate(6, 0);
                        point8.translate(6, 6);
                    }
                    else if (j == 0)
                    {
                        origin = axis.translate(origin, -6, 0);
                        point3 = axis.translate(point3, -6, 0);
                        point5.translate(-6, 0);
                        point7.translate(-6, 0);
                    }
                    else if (j == (sqrtNumArea - 1))
                    {
                        point2 = axis.translate(point2, 6, 0);
                        point4 = axis.translate(point4, 6, 0);
                        point6.translate(6, 0);
                        point8.translate(6, 0);
                    }
                    else if (i == 0)
                    {
                        origin = axis.translate(origin, 0, -6);
                        point2 = axis.translate(point2, 0, -6);
                        point5.translate(0, -6);
                        point6.translate(0, -6);
                    }
                    else if (i == (sqrtNumArea - 1))
                    {
                        point3 = axis.translate(point3, 0, 6);
                        point4 = axis.translate(point4, 0, 6);
                        point7.translate(0, 6);
                        point8.translate(0, 6);
                    }
                    if (j == 0)
                    {
                        point6.translate(1, 0);
                        point8.translate(1, 0);
                    }
                    else
                    {
                        point5.translate(-1, 0);
                        point7.translate(-1, 0);
                    }
                    if (i == 0)
                    {
                        point7.translate(0, 1);
                        point8.translate(0, 1);
                    }
                    else
                    {
                        point5.translate(0, -1);
                        point6.translate(0, -1);
                    }
                    int width  = point6.X - point5.X;
                    int height = point7.Y - point5.Y;
                    if (version < 7)
                    {
                        width  += 3;
                        height += 3;
                    }
                    pitch.top    = this.getAreaModulePitch(origin, point2, width - 1);
                    pitch.left   = this.getAreaModulePitch(origin, point3, height - 1);
                    pitch.bottom = this.getAreaModulePitch(point3, point4, width - 1);
                    pitch.right  = this.getAreaModulePitch(point2, point4, height - 1);
                    line.setP1(origin);
                    line2.setP1(origin);
                    line.setP2(point3);
                    line2.setP2(point2);
                    grid.initGrid(j, i, width, height);
                    int moveX = 0;
                    while (moveX < width)
                    {
                        Line line3 = new Line(line.getP1(), line.getP2());
                        axis.Origin      = line3.getP1();
                        axis.ModulePitch = pitch.top;
                        line3.setP1(axis.translate(moveX, 0));
                        axis.Origin      = line3.getP2();
                        axis.ModulePitch = pitch.bottom;
                        line3.setP2(axis.translate(moveX, 0));
                        grid.setXLine(j, i, moveX, line3);
                        moveX++;
                    }
                    for (moveX = 0; moveX < height; moveX++)
                    {
                        Line line4 = new Line(line2.getP1(), line2.getP2());
                        axis.Origin      = line4.getP1();
                        axis.ModulePitch = pitch.left;
                        line4.setP1(axis.translate(0, moveX));
                        axis.Origin      = line4.getP2();
                        axis.ModulePitch = pitch.right;
                        line4.setP2(axis.translate(0, moveX));
                        grid.setYLine(j, i, moveX, line4);
                    }
                }
            }
            return(grid);
        }
Exemple #18
0
        public virtual QRCodeSymbol getQRCodeSymbol(int[][] image)
        {
            QRCodeImageReader.DECIMAL_POINT = 23 - QRCodeUtility.sqrt((image.Length < image[0].Length ? image[0].Length : image.Length) / 256);
            this.bitmap = this.filterImage(image);
            this.canvas.println("Drawing matrix.");
            this.canvas.drawMatrix(this.bitmap);
            this.canvas.println("Scanning Finder Pattern.");
            FinderPattern finderPattern;

            try
            {
                finderPattern = FinderPattern.findFinderPattern(this.bitmap);
            }
            catch (FinderPatternNotFoundException ex1)
            {
                this.canvas.println("Not found, now retrying...");
                this.bitmap = this.applyCrossMaskingMedianFilter(this.bitmap, 5);
                this.canvas.drawMatrix(this.bitmap);
                int num = 0;
                while (num < 1000000000)
                {
                    ++num;
                }
                try
                {
                    finderPattern = FinderPattern.findFinderPattern(this.bitmap);
                }
                catch (FinderPatternNotFoundException ex2)
                {
                    throw new SymbolNotFoundException(ex2.Message);
                }
                catch (VersionInformationException ex2)
                {
                    throw new SymbolNotFoundException(ex2.Message);
                }
            }
            catch (VersionInformationException ex)
            {
                throw new SymbolNotFoundException(ex.Message);
            }
            this.canvas.println("FinderPattern at");
            this.canvas.println(finderPattern.getCenter(0).ToString() + finderPattern.getCenter(1).ToString() + finderPattern.getCenter(2).ToString());
            int[] angle = finderPattern.getAngle();
            this.canvas.println("Angle*4098: Sin " + Convert.ToString(angle[0]) + "  Cos " + Convert.ToString(angle[1]));
            int version = finderPattern.Version;

            this.canvas.println("Version: " + Convert.ToString(version));
            if (version < 1 || version > 40)
            {
                throw new InvalidVersionException("Invalid version: " + (object)version);
            }
            AlignmentPattern alignmentPattern;

            try
            {
                alignmentPattern = AlignmentPattern.findAlignmentPattern(this.bitmap, finderPattern);
            }
            catch (AlignmentPatternNotFoundException ex)
            {
                throw new SymbolNotFoundException(ex.Message);
            }
            int length = alignmentPattern.getCenter().Length;

            this.canvas.println("AlignmentPatterns at");
            for (int index1 = 0; index1 < length; ++index1)
            {
                string str = "";
                for (int index2 = 0; index2 < length; ++index2)
                {
                    str += alignmentPattern.getCenter()[index2][index1].ToString();
                }
                this.canvas.println(str);
            }
            this.canvas.println("Creating sampling grid.");
            this.samplingGrid = this.getSamplingGrid(finderPattern, alignmentPattern);
            this.canvas.println("Reading grid.");
            bool[][] qrCodeMatrix;
            try
            {
                qrCodeMatrix = this.getQRCodeMatrix(this.bitmap, this.samplingGrid);
            }
            catch (IndexOutOfRangeException ex)
            {
                throw new SymbolNotFoundException("Sampling grid exceeded image boundary");
            }
            return(new QRCodeSymbol(qrCodeMatrix));
        }
Exemple #19
0
 internal Pair(int value, int checksumPortion, FinderPattern finderPattern)
     : base(value, checksumPortion)
 {
     FinderPattern = finderPattern;
 }
Exemple #20
0
        //UPGRADE_NOTE: Final was removed from the declaration of 'bottomLeft '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
        //UPGRADE_NOTE: Final was removed from the declaration of 'topLeft '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
        //UPGRADE_NOTE: Final was removed from the declaration of 'topRight '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"

        public FinderPatternInfo(FinderPattern[] patternCenters)
        {
            BottomLeft = patternCenters[0];
            TopLeft    = patternCenters[1];
            TopRight   = patternCenters[2];
        }
        public virtual QRCodeSymbol getQRCodeSymbol(int[][] image)
        {
            int num = ((image.Length < image[0].Length) ? image[0].Length : image.Length);

            DECIMAL_POINT = 23 - QRCodeUtility.sqrt(num / 256);
            bitmap        = filterImage(image);
            canvas.println("Drawing matrix.");
            canvas.drawMatrix(bitmap);
            canvas.println("Scanning Finder Pattern.");
            FinderPattern finderPattern = null;

            try
            {
                finderPattern = FinderPattern.findFinderPattern(bitmap);
            }
            catch (FinderPatternNotFoundException)
            {
                canvas.println("Not found, now retrying...");
                bitmap = applyCrossMaskingMedianFilter(bitmap, 5);
                canvas.drawMatrix(bitmap);
                for (int i = 0; i < 1000000000; i++)
                {
                }
                try
                {
                    finderPattern = FinderPattern.findFinderPattern(bitmap);
                }
                catch (FinderPatternNotFoundException ex)
                {
                    throw new SymbolNotFoundException(ex.Message);
                }
                catch (VersionInformationException ex2)
                {
                    throw new SymbolNotFoundException(ex2.Message);
                }
            }
            catch (VersionInformationException ex4)
            {
                throw new SymbolNotFoundException(ex4.Message);
            }
            canvas.println("FinderPattern at");
            string str = finderPattern.getCenter(0).ToString() + finderPattern.getCenter(1).ToString() + finderPattern.getCenter(2).ToString();

            canvas.println(str);
            int[] angle = finderPattern.getAngle();
            canvas.println("Angle*4098: Sin " + Convert.ToString(angle[0]) + "  Cos " + Convert.ToString(angle[1]));
            int version = finderPattern.Version;

            canvas.println("Version: " + Convert.ToString(version));
            if (version < 1 || version > 40)
            {
                throw new InvalidVersionException("Invalid version: " + version);
            }
            AlignmentPattern alignmentPattern = null;

            try
            {
                alignmentPattern = AlignmentPattern.findAlignmentPattern(bitmap, finderPattern);
            }
            catch (AlignmentPatternNotFoundException ex5)
            {
                throw new SymbolNotFoundException(ex5.Message);
            }
            int num2 = alignmentPattern.getCenter().Length;

            canvas.println("AlignmentPatterns at");
            for (int j = 0; j < num2; j++)
            {
                string text = "";
                for (int k = 0; k < num2; k++)
                {
                    text += alignmentPattern.getCenter()[k][j].ToString();
                }
                canvas.println(text);
            }
            canvas.println("Creating sampling grid.");
            samplingGrid = getSamplingGrid(finderPattern, alignmentPattern);
            canvas.println("Reading grid.");
            bool[][] array = null;
            try
            {
                array = getQRCodeMatrix(bitmap, samplingGrid);
            }
            catch (IndexOutOfRangeException)
            {
                throw new SymbolNotFoundException("Sampling grid exceeded image boundary");
            }
            return(new QRCodeSymbol(array));
        }
      public void testDecodeDataCharacter()
      {
         RSSExpandedReader rssExpandedReader = new RSSExpandedReader();

         String path = "test/data/blackbox/rssexpanded-1/3.png";
         if (!File.Exists(path))
         {
            // Support running from project root too
            path = Path.Combine("..\\..\\..\\Source", path);
         }

#if !SILVERLIGHT
         var image = new Bitmap(Image.FromFile(path));
#else
         var image = new WriteableBitmap(0, 0);
         image.SetSource(File.OpenRead(path));
#endif
         BinaryBitmap binaryMap = new BinaryBitmap(new GlobalHistogramBinarizer(new BitmapLuminanceSource(image)));
         BitArray row = binaryMap.getBlackRow(binaryMap.Height / 2, null);

         int[] startEnd = { 145, 243 };//image pixels where the A1 pattern starts (at 124) and ends (at 214)
         int value = 0; // A
#if !SILVERLIGHT
         FinderPattern finderPatternA1 = new FinderPattern(value, startEnd, startEnd[0], startEnd[1], image.Height / 2);
#else
         FinderPattern finderPatternA1 = new FinderPattern(value, startEnd, startEnd[0], startEnd[1], image.PixelHeight / 2);
#endif
         //{1, 8, 4, 1, 1};
         DataCharacter dataCharacter = rssExpandedReader.decodeDataCharacter(row, finderPatternA1, true, false);

         Assert.AreEqual(19, dataCharacter.Value);
         Assert.AreEqual(1007, dataCharacter.ChecksumPortion);
      }
        internal virtual SamplingGrid getSamplingGrid(FinderPattern finderPattern, AlignmentPattern alignmentPattern)
        {
            Point[][] center  = alignmentPattern.getCenter();
            int       version = finderPattern.Version;
            int       num     = version / 7 + 2;

            center[0][0]       = finderPattern.getCenter(0);
            center[num - 1][0] = finderPattern.getCenter(1);
            center[0][num - 1] = finderPattern.getCenter(2);
            int          num2         = num - 1;
            SamplingGrid samplingGrid = new SamplingGrid(num2);
            Axis         axis         = new Axis(finderPattern.getAngle(), finderPattern.getModuleSize());

            for (int i = 0; i < num2; i++)
            {
                for (int j = 0; j < num2; j++)
                {
                    ModulePitch modulePitch = new ModulePitch(this);
                    Line        line        = new Line();
                    Line        line2       = new Line();
                    axis.ModulePitch = finderPattern.getModuleSize();
                    Point[][] logicalCenter = AlignmentPattern.getLogicalCenter(finderPattern);
                    Point     point         = center[j][i];
                    Point     point2        = center[j + 1][i];
                    Point     point3        = center[j][i + 1];
                    Point     point4        = center[j + 1][i + 1];
                    Point     point5        = logicalCenter[j][i];
                    Point     point6        = logicalCenter[j + 1][i];
                    Point     point7        = logicalCenter[j][i + 1];
                    Point     point8        = logicalCenter[j + 1][i + 1];
                    if (j == 0 && i == 0)
                    {
                        if (num2 == 1)
                        {
                            point  = axis.translate(point, -3, -3);
                            point2 = axis.translate(point2, 3, -3);
                            point3 = axis.translate(point3, -3, 3);
                            point4 = axis.translate(point4, 6, 6);
                            point5.translate(-6, -6);
                            point6.translate(3, -3);
                            point7.translate(-3, 3);
                            point8.translate(6, 6);
                        }
                        else
                        {
                            point  = axis.translate(point, -3, -3);
                            point2 = axis.translate(point2, 0, -6);
                            point3 = axis.translate(point3, -6, 0);
                            point5.translate(-6, -6);
                            point6.translate(0, -6);
                            point7.translate(-6, 0);
                        }
                    }
                    else if (j == 0 && i == num2 - 1)
                    {
                        point  = axis.translate(point, -6, 0);
                        point3 = axis.translate(point3, -3, 3);
                        point4 = axis.translate(point4, 0, 6);
                        point5.translate(-6, 0);
                        point7.translate(-6, 6);
                        point8.translate(0, 6);
                    }
                    else if (j == num2 - 1 && i == 0)
                    {
                        point  = axis.translate(point, 0, -6);
                        point2 = axis.translate(point2, 3, -3);
                        point4 = axis.translate(point4, 6, 0);
                        point5.translate(0, -6);
                        point6.translate(6, -6);
                        point8.translate(6, 0);
                    }
                    else if (j == num2 - 1 && i == num2 - 1)
                    {
                        point3 = axis.translate(point3, 0, 6);
                        point2 = axis.translate(point2, 6, 0);
                        point4 = axis.translate(point4, 6, 6);
                        point7.translate(0, 6);
                        point6.translate(6, 0);
                        point8.translate(6, 6);
                    }
                    else if (j == 0)
                    {
                        point  = axis.translate(point, -6, 0);
                        point3 = axis.translate(point3, -6, 0);
                        point5.translate(-6, 0);
                        point7.translate(-6, 0);
                    }
                    else if (j == num2 - 1)
                    {
                        point2 = axis.translate(point2, 6, 0);
                        point4 = axis.translate(point4, 6, 0);
                        point6.translate(6, 0);
                        point8.translate(6, 0);
                    }
                    else if (i == 0)
                    {
                        point  = axis.translate(point, 0, -6);
                        point2 = axis.translate(point2, 0, -6);
                        point5.translate(0, -6);
                        point6.translate(0, -6);
                    }
                    else if (i == num2 - 1)
                    {
                        point3 = axis.translate(point3, 0, 6);
                        point4 = axis.translate(point4, 0, 6);
                        point7.translate(0, 6);
                        point8.translate(0, 6);
                    }
                    if (j == 0)
                    {
                        point6.translate(1, 0);
                        point8.translate(1, 0);
                    }
                    else
                    {
                        point5.translate(-1, 0);
                        point7.translate(-1, 0);
                    }
                    if (i == 0)
                    {
                        point7.translate(0, 1);
                        point8.translate(0, 1);
                    }
                    else
                    {
                        point5.translate(0, -1);
                        point6.translate(0, -1);
                    }
                    int num3 = point6.X - point5.X;
                    int num4 = point7.Y - point5.Y;
                    if (version < 7)
                    {
                        num3 += 3;
                        num4 += 3;
                    }
                    modulePitch.top    = getAreaModulePitch(point, point2, num3 - 1);
                    modulePitch.left   = getAreaModulePitch(point, point3, num4 - 1);
                    modulePitch.bottom = getAreaModulePitch(point3, point4, num3 - 1);
                    modulePitch.right  = getAreaModulePitch(point2, point4, num4 - 1);
                    line.setP1(point);
                    line2.setP1(point);
                    line.setP2(point3);
                    line2.setP2(point2);
                    samplingGrid.initGrid(j, i, num3, num4);
                    for (int k = 0; k < num3; k++)
                    {
                        Line line3 = new Line(line.getP1(), line.getP2());
                        axis.Origin      = line3.getP1();
                        axis.ModulePitch = modulePitch.top;
                        line3.setP1(axis.translate(k, 0));
                        axis.Origin      = line3.getP2();
                        axis.ModulePitch = modulePitch.bottom;
                        line3.setP2(axis.translate(k, 0));
                        samplingGrid.setXLine(j, i, k, line3);
                    }
                    for (int k = 0; k < num4; k++)
                    {
                        Line line4 = new Line(line2.getP1(), line2.getP2());
                        axis.Origin      = line4.getP1();
                        axis.ModulePitch = modulePitch.left;
                        line4.setP1(axis.translate(0, k));
                        axis.Origin      = line4.getP2();
                        axis.ModulePitch = modulePitch.right;
                        line4.setP2(axis.translate(0, k));
                        samplingGrid.setYLine(j, i, k, line4);
                    }
                }
            }
            return(samplingGrid);
        }
        /// <returns> the 3 best {@link FinderPattern}s from our list of candidates. The "best" are
        /// those that have been detected at least {@link #CENTER_QUORUM} times, and whose module
        /// size differs from the average among those patterns the least
        /// </returns>
        /// <throws>  ReaderException if 3 such finder patterns do not exist </throws>
        private FinderPattern[][] selectBestPatterns()
        {
            var possibleCenters = PossibleCenters;
            int size = possibleCenters.Count;

            if (size < 3)
            {
                // Couldn't find enough finder patterns
                throw ReaderException.Instance;
            }

            /*
            * Begin HE modifications to safely detect multiple codes of equal size
            */
            if (size == 3)
            {
                return new FinderPattern[][]{new FinderPattern[]{(FinderPattern) possibleCenters[0], (FinderPattern) possibleCenters[1], (FinderPattern) possibleCenters[2]}};
            }

            // Sort by estimated module size to speed up the upcoming checks
            Collections.insertionSort(possibleCenters, new ModuleSizeComparator());

            /*
            * Now lets start: build a list of tuples of three finder locations that
            *  - feature similar module sizes
            *  - are placed in a distance so the estimated module count is within the QR specification
            *  - have similar distance between upper left/right and left top/bottom finder patterns
            *  - form a triangle with 90° angle (checked by comparing top right/bottom left distance
            *    with pythagoras)
            *
            * Note: we allow each point to be used for more than one code region: this might seem
            * counterintuitive at first, but the performance penalty is not that big. At this point,
            * we cannot make a good quality decision whether the three finders actually represent
            * a QR code, or are just by chance layouted so it looks like there might be a QR code there.
            * So, if the layout seems right, lets have the decoder try to decode.
            */

            List<FinderPattern[]> results = new List<FinderPattern[]>(10); // holder for the results

            for (int i1 = 0; i1 < (size - 2); i1++)
            {
                FinderPattern p1 = (FinderPattern) possibleCenters[i1];
                if (p1 == null)
                {
                    continue;
                }

                for (int i2 = i1 + 1; i2 < (size - 1); i2++)
                {
                    FinderPattern p2 = (FinderPattern) possibleCenters[i2];
                    if (p2 == null)
                    {
                        continue;
                    }

                    // Compare the expected module sizes; if they are really off, skip
                    float vModSize12 = (p1.EstimatedModuleSize - p2.EstimatedModuleSize) / (System.Math.Min(p1.EstimatedModuleSize, p2.EstimatedModuleSize));
                    float vModSize12A = System.Math.Abs(p1.EstimatedModuleSize - p2.EstimatedModuleSize);
                    if (vModSize12A > DIFF_MODSIZE_CUTOFF && vModSize12 >= DIFF_MODSIZE_CUTOFF_PERCENT)
                    {
                        // break, since elements are ordered by the module size deviation there cannot be
                        // any more interesting elements for the given p1.
                        break;
                    }

                    for (int i3 = i2 + 1; i3 < size; i3++)
                    {
                        FinderPattern p3 = (FinderPattern) possibleCenters[i3];
                        if (p3 == null)
                        {
                            continue;
                        }

                        // Compare the expected module sizes; if they are really off, skip
                        float vModSize23 = (p2.EstimatedModuleSize - p3.EstimatedModuleSize) / (System.Math.Min(p2.EstimatedModuleSize, p3.EstimatedModuleSize));
                        float vModSize23A = System.Math.Abs(p2.EstimatedModuleSize - p3.EstimatedModuleSize);
                        if (vModSize23A > DIFF_MODSIZE_CUTOFF && vModSize23 >= DIFF_MODSIZE_CUTOFF_PERCENT)
                        {
                            // break, since elements are ordered by the module size deviation there cannot be
                            // any more interesting elements for the given p1.
                            break;
                        }

                        FinderPattern[] test = new FinderPattern[]{p1, p2, p3};
                        ResultPoint.orderBestPatterns(test);

                        // Calculate the distances: a = topleft-bottomleft, b=topleft-topright, c = diagonal
                        FinderPatternInfo info = new FinderPatternInfo(test);
                        float dA = ResultPoint.distance(info.TopLeft, info.BottomLeft);
                        float dC = ResultPoint.distance(info.TopRight, info.BottomLeft);
                        float dB = ResultPoint.distance(info.TopLeft, info.TopRight);

                        // Check the sizes
                        float estimatedModuleCount = ((dA + dB) / p1.EstimatedModuleSize) / 2;
                        if (estimatedModuleCount > MAX_MODULE_COUNT_PER_EDGE || estimatedModuleCount < MIN_MODULE_COUNT_PER_EDGE)
                        {
                            continue;
                        }

                        // Calculate the difference of the edge lengths in percent
                        float vABBC = System.Math.Abs(((dA - dB) / System.Math.Min(dA, dB)));
                        if (vABBC >= 0.1f)
                        {
                            continue;
                        }

                        // Calculate the diagonal length by assuming a 90° angle at topleft
                        //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 dCpy = (float) System.Math.Sqrt(dA * dA + dB * dB);
                        // Compare to the real distance in %
                        float vPyC = System.Math.Abs(((dC - dCpy) / System.Math.Min(dC, dCpy)));

                        if (vPyC >= 0.1f)
                        {
                            continue;
                        }

                        // All tests passed!
                        results.Add(test);
                    } // end iterate p3
                } // end iterate p2
            } // end iterate p1

            if (!(results.Count == 0))
            {
                FinderPattern[][] resultArray = new FinderPattern[results.Count][];
                for (int i = 0; i < results.Count; i++)
                {
                    resultArray[i] = (FinderPattern[]) results[i];
                }
                return resultArray;
            }

            // Nothing found!
            throw ReaderException.Instance;
        }
Exemple #25
0
 internal Pair(int value, int checksumPortion, FinderPattern finderPattern)
    : base(value, checksumPortion)
 {
    FinderPattern = finderPattern;
 }
Exemple #26
0
        internal virtual SamplingGrid getSamplingGrid(FinderPattern finderPattern, AlignmentPattern alignmentPattern)
        {
            Point[][] center  = alignmentPattern.getCenter();
            int       version = finderPattern.Version;
            int       num     = version / 7 + 2;

            center[0][0]       = finderPattern.getCenter(0);
            center[num - 1][0] = finderPattern.getCenter(1);
            center[0][num - 1] = finderPattern.getCenter(2);
            int          sqrtNumArea  = num - 1;
            SamplingGrid samplingGrid = new SamplingGrid(sqrtNumArea);
            Axis         axis         = new Axis(finderPattern.getAngle(), finderPattern.getModuleSize());

            for (int ay = 0; ay < sqrtNumArea; ++ay)
            {
                for (int ax = 0; ax < sqrtNumArea; ++ax)
                {
                    QRCodeImageReader.ModulePitch modulePitch = new QRCodeImageReader.ModulePitch(this);
                    Line line1 = new Line();
                    Line line2 = new Line();
                    axis.ModulePitch = finderPattern.getModuleSize();
                    Point[][] logicalCenter = AlignmentPattern.getLogicalCenter(finderPattern);
                    Point     point1        = center[ax][ay];
                    Point     point2        = center[ax + 1][ay];
                    Point     point3        = center[ax][ay + 1];
                    Point     point4        = center[ax + 1][ay + 1];
                    Point     point5        = logicalCenter[ax][ay];
                    Point     point6        = logicalCenter[ax + 1][ay];
                    Point     point7        = logicalCenter[ax][ay + 1];
                    Point     point8        = logicalCenter[ax + 1][ay + 1];
                    if (ax == 0 && ay == 0)
                    {
                        if (sqrtNumArea == 1)
                        {
                            point1 = axis.translate(point1, -3, -3);
                            point2 = axis.translate(point2, 3, -3);
                            point3 = axis.translate(point3, -3, 3);
                            point4 = axis.translate(point4, 6, 6);
                            point5.translate(-6, -6);
                            point6.translate(3, -3);
                            point7.translate(-3, 3);
                            point8.translate(6, 6);
                        }
                        else
                        {
                            point1 = axis.translate(point1, -3, -3);
                            point2 = axis.translate(point2, 0, -6);
                            point3 = axis.translate(point3, -6, 0);
                            point5.translate(-6, -6);
                            point6.translate(0, -6);
                            point7.translate(-6, 0);
                        }
                    }
                    else if (ax == 0 && ay == sqrtNumArea - 1)
                    {
                        point1 = axis.translate(point1, -6, 0);
                        point3 = axis.translate(point3, -3, 3);
                        point4 = axis.translate(point4, 0, 6);
                        point5.translate(-6, 0);
                        point7.translate(-6, 6);
                        point8.translate(0, 6);
                    }
                    else if (ax == sqrtNumArea - 1 && ay == 0)
                    {
                        point1 = axis.translate(point1, 0, -6);
                        point2 = axis.translate(point2, 3, -3);
                        point4 = axis.translate(point4, 6, 0);
                        point5.translate(0, -6);
                        point6.translate(6, -6);
                        point8.translate(6, 0);
                    }
                    else if (ax == sqrtNumArea - 1 && ay == sqrtNumArea - 1)
                    {
                        point3 = axis.translate(point3, 0, 6);
                        point2 = axis.translate(point2, 6, 0);
                        point4 = axis.translate(point4, 6, 6);
                        point7.translate(0, 6);
                        point6.translate(6, 0);
                        point8.translate(6, 6);
                    }
                    else if (ax == 0)
                    {
                        point1 = axis.translate(point1, -6, 0);
                        point3 = axis.translate(point3, -6, 0);
                        point5.translate(-6, 0);
                        point7.translate(-6, 0);
                    }
                    else if (ax == sqrtNumArea - 1)
                    {
                        point2 = axis.translate(point2, 6, 0);
                        point4 = axis.translate(point4, 6, 0);
                        point6.translate(6, 0);
                        point8.translate(6, 0);
                    }
                    else if (ay == 0)
                    {
                        point1 = axis.translate(point1, 0, -6);
                        point2 = axis.translate(point2, 0, -6);
                        point5.translate(0, -6);
                        point6.translate(0, -6);
                    }
                    else if (ay == sqrtNumArea - 1)
                    {
                        point3 = axis.translate(point3, 0, 6);
                        point4 = axis.translate(point4, 0, 6);
                        point7.translate(0, 6);
                        point8.translate(0, 6);
                    }
                    if (ax == 0)
                    {
                        point6.translate(1, 0);
                        point8.translate(1, 0);
                    }
                    else
                    {
                        point5.translate(-1, 0);
                        point7.translate(-1, 0);
                    }
                    if (ay == 0)
                    {
                        point7.translate(0, 1);
                        point8.translate(0, 1);
                    }
                    else
                    {
                        point5.translate(0, -1);
                        point6.translate(0, -1);
                    }
                    int width  = point6.X - point5.X;
                    int height = point7.Y - point5.Y;
                    if (version < 7)
                    {
                        width  += 3;
                        height += 3;
                    }
                    modulePitch.top    = this.getAreaModulePitch(point1, point2, width - 1);
                    modulePitch.left   = this.getAreaModulePitch(point1, point3, height - 1);
                    modulePitch.bottom = this.getAreaModulePitch(point3, point4, width - 1);
                    modulePitch.right  = this.getAreaModulePitch(point2, point4, height - 1);
                    line1.setP1(point1);
                    line2.setP1(point1);
                    line1.setP2(point3);
                    line2.setP2(point2);
                    samplingGrid.initGrid(ax, ay, width, height);
                    for (int index = 0; index < width; ++index)
                    {
                        Line line3 = new Line(line1.getP1(), line1.getP2());
                        axis.Origin      = line3.getP1();
                        axis.ModulePitch = modulePitch.top;
                        line3.setP1(axis.translate(index, 0));
                        axis.Origin      = line3.getP2();
                        axis.ModulePitch = modulePitch.bottom;
                        line3.setP2(axis.translate(index, 0));
                        samplingGrid.setXLine(ax, ay, index, line3);
                    }
                    for (int index = 0; index < height; ++index)
                    {
                        Line line3 = new Line(line2.getP1(), line2.getP2());
                        axis.Origin      = line3.getP1();
                        axis.ModulePitch = modulePitch.left;
                        line3.setP1(axis.translate(0, index));
                        axis.Origin      = line3.getP2();
                        axis.ModulePitch = modulePitch.right;
                        line3.setP2(axis.translate(0, index));
                        samplingGrid.setYLine(ax, ay, index, line3);
                    }
                }
            }
            return(samplingGrid);
        }
        internal DataCharacter decodeDataCharacter(BitArray row,
                                                   FinderPattern pattern,
                                                   bool isOddPattern,
                                                   bool leftChar)
        {
            int[] counters = getDataCharacterCounters();
            for (int x = 0; x < counters.Length; x++)
            {
                counters[x] = 0;
            }

            if (leftChar)
            {
                if (!recordPatternInReverse(row, pattern.StartEnd[0], counters))
                {
                    return(null);
                }
            }
            else
            {
                if (!recordPattern(row, pattern.StartEnd[1], counters))
                {
                    return(null);
                }
                // reverse it
                for (int i = 0, j = counters.Length - 1; i < j; i++, j--)
                {
                    int temp = counters[i];
                    counters[i] = counters[j];
                    counters[j] = temp;
                }
            }//counters[] has the pixels of the module

            const int numModules   = 17; //left and right data characters have all the same length
            float     elementWidth = (float)ZXing.Common.Detector.MathUtils.sum(counters) / (float)numModules;

            // Sanity check: element width for pattern and the character should match
            float expectedElementWidth = (pattern.StartEnd[1] - pattern.StartEnd[0]) / 15.0f;

            if (Math.Abs(elementWidth - expectedElementWidth) / expectedElementWidth > 0.3f)
            {
                return(null);
            }

            int[]   oddCounts          = getOddCounts();
            int[]   evenCounts         = getEvenCounts();
            float[] oddRoundingErrors  = getOddRoundingErrors();
            float[] evenRoundingErrors = getEvenRoundingErrors();

            for (int i = 0; i < counters.Length; i++)
            {
                float divided = 1.0f * counters[i] / elementWidth;
                int   rounded = (int)(divided + 0.5f); // Round
                if (rounded < 1)
                {
                    if (divided < 0.3f)
                    {
                        return(null);
                    }
                    rounded = 1;
                }
                else if (rounded > 8)
                {
                    if (divided > 8.7f)
                    {
                        return(null);
                    }
                    rounded = 8;
                }
                int offset = i >> 1;
                if ((i & 0x01) == 0)
                {
                    oddCounts[offset]         = rounded;
                    oddRoundingErrors[offset] = divided - rounded;
                }
                else
                {
                    evenCounts[offset]         = rounded;
                    evenRoundingErrors[offset] = divided - rounded;
                }
            }

            if (!adjustOddEvenCounts(numModules))
            {
                return(null);
            }

            int weightRowNumber = 4 * pattern.Value + (isOddPattern ? 0 : 2) + (leftChar ? 0 : 1) - 1;

            int oddSum             = 0;
            int oddChecksumPortion = 0;

            for (int i = oddCounts.Length - 1; i >= 0; i--)
            {
                if (isNotA1left(pattern, isOddPattern, leftChar))
                {
                    int weight = WEIGHTS[weightRowNumber][2 * i];
                    oddChecksumPortion += oddCounts[i] * weight;
                }
                oddSum += oddCounts[i];
            }
            int evenChecksumPortion = 0;

            //int evenSum = 0;
            for (int i = evenCounts.Length - 1; i >= 0; i--)
            {
                if (isNotA1left(pattern, isOddPattern, leftChar))
                {
                    int weight = WEIGHTS[weightRowNumber][2 * i + 1];
                    evenChecksumPortion += evenCounts[i] * weight;
                }
                //evenSum += evenCounts[i];
            }
            int checksumPortion = oddChecksumPortion + evenChecksumPortion;

            if ((oddSum & 0x01) != 0 || oddSum > 13 || oddSum < 4)
            {
                return(null);
            }

            int group      = (13 - oddSum) / 2;
            int oddWidest  = SYMBOL_WIDEST[group];
            int evenWidest = 9 - oddWidest;
            int vOdd       = RSSUtils.getRSSvalue(oddCounts, oddWidest, true);
            int vEven      = RSSUtils.getRSSvalue(evenCounts, evenWidest, false);
            int tEven      = EVEN_TOTAL_SUBSET[group];
            int gSum       = GSUM[group];
            int value      = vOdd * tEven + vEven + gSum;

            return(new DataCharacter(value, checksumPortion));
        }
 public FinderPatternInfo(FinderPattern[] patternCenters)
 {
     this.bottomLeft = patternCenters[0];
     this.topLeft = patternCenters[1];
     this.topRight = patternCenters[2];
 }
Exemple #29
0
        public virtual QRCodeSymbol getQRCodeSymbol(int[][] image)
        {
            int longSide = (image.Length < image[0].Length) ? image[0].Length : image.Length;

            QRCodeImageReader.DECIMAL_POINT = 23 - QRCodeUtility.sqrt(longSide / 256);
            this.bitmap = this.filterImage(image);
            this.canvas.println("Drawing matrix.");
            this.canvas.drawMatrix(this.bitmap);
            this.canvas.println("Scanning Finder Pattern.");
            FinderPattern finderPattern = null;

            try
            {
                finderPattern = FinderPattern.findFinderPattern(this.bitmap);
            }
            catch (FinderPatternNotFoundException e_80)
            {
                this.canvas.println("Not found, now retrying...");
                this.bitmap = this.applyCrossMaskingMedianFilter(this.bitmap, 5);
                this.canvas.drawMatrix(this.bitmap);
                for (int i = 0; i < 1000000000; i++)
                {
                }
                try
                {
                    finderPattern = FinderPattern.findFinderPattern(this.bitmap);
                }
                catch (FinderPatternNotFoundException e2)
                {
                    throw new SymbolNotFoundException(e2.Message);
                }
                catch (VersionInformationException e3)
                {
                    throw new SymbolNotFoundException(e3.Message);
                }
            }
            catch (VersionInformationException e4)
            {
                throw new SymbolNotFoundException(e4.Message);
            }
            this.canvas.println("FinderPattern at");
            string finderPatternCoordinates = finderPattern.getCenter(0).ToString() + finderPattern.getCenter(1).ToString() + finderPattern.getCenter(2).ToString();

            this.canvas.println(finderPatternCoordinates);
            int[] sincos = finderPattern.getAngle();
            this.canvas.println("Angle*4098: Sin " + Convert.ToString(sincos[0]) + "  Cos " + Convert.ToString(sincos[1]));
            int version = finderPattern.Version;

            this.canvas.println("Version: " + Convert.ToString(version));
            if (version < 1 || version > 40)
            {
                throw new InvalidVersionException("Invalid version: " + version);
            }
            AlignmentPattern alignmentPattern = null;

            try
            {
                alignmentPattern = AlignmentPattern.findAlignmentPattern(this.bitmap, finderPattern);
            }
            catch (AlignmentPatternNotFoundException e5)
            {
                throw new SymbolNotFoundException(e5.Message);
            }
            int matrixLength = alignmentPattern.getCenter().Length;

            this.canvas.println("AlignmentPatterns at");
            for (int y = 0; y < matrixLength; y++)
            {
                string alignmentPatternCoordinates = "";
                for (int x = 0; x < matrixLength; x++)
                {
                    alignmentPatternCoordinates += alignmentPattern.getCenter()[x][y].ToString();
                }
                this.canvas.println(alignmentPatternCoordinates);
            }
            this.canvas.println("Creating sampling grid.");
            this.samplingGrid = this.getSamplingGrid(finderPattern, alignmentPattern);
            this.canvas.println("Reading grid.");
            bool[][] qRCodeMatrix = null;
            try
            {
                qRCodeMatrix = this.getQRCodeMatrix(this.bitmap, this.samplingGrid);
            }
            catch (IndexOutOfRangeException e_2D5)
            {
                throw new SymbolNotFoundException("Sampling grid exceeded image boundary");
            }
            return(new QRCodeSymbol(qRCodeMatrix));
        }
        // For only version 1 which has no Alignement Patterns

        /*	SamplingGrid getSamplingGrid1(FinderPattern finderPattern) {
         * int sqrtNumArea = 1;
         * int sqrtNumModules = finderPattern.getSqrtNumModules(); //get nummber of modules at side
         * int sqrtNumAreaModules = sqrtNumModules / sqrtNumArea;
         * Point[] centers = finderPattern.getCenter();
         * int logicalDistance = 14;
         * SamplingGrid samplingGrid = new SamplingGrid(sqrtNumArea);
         * Line baseLineX, baseLineY, gridLineX, gridLineY;
         *
         *
         * ModulePitch modulePitch = new ModulePitch(); //store (up,left) order
         * modulePitch.top = getAreaModulePitch(centers[0], centers[1], logicalDistance);
         * modulePitch.left = getAreaModulePitch(centers[0], centers[2], logicalDistance);
         *
         * //X軸に垂直の基線(一般に縦)
         * baseLineX = new Line(
         * finderPattern.getCenter(FinderPattern.UL),
         * finderPattern.getCenter(FinderPattern.DL));
         *
         * Axis axis = new Axis(finderPattern.getAngle(), modulePitch.top);
         * axis.setOrigin(baseLineX.getP1());
         * baseLineX.setP1(axis.translate(-3, -3));
         *
         * axis.setModulePitch(modulePitch.left);
         * axis.setOrigin(baseLineX.getP2());
         * baseLineX.setP2(axis.translate(-3, 3));
         *
         * //Y軸に垂直の基線(一般に横)
         * baseLineY =
         * new Line(finderPattern.getCenter(FinderPattern.UL),
         * finderPattern.getCenter(FinderPattern.UR));
         *
         * axis.setModulePitch(modulePitch.left);
         * axis.setOrigin(baseLineY.getP1());
         * baseLineY.setP1(axis.translate(-3, -3));
         *
         *
         * axis.setModulePitch(modulePitch.left);
         * axis.setOrigin(baseLineY.getP2());
         * baseLineY.setP2(axis.translate(3, -3));
         *
         * //baseLineX.translate(1,1);
         * //baseLineY.translate(1,1);
         *
         * samplingGrid.initGrid(0, 0, sqrtNumAreaModules, sqrtNumAreaModules);
         *
         * for (int i = 0; i < sqrtNumAreaModules; i++) {
         *
         * gridLineX = new Line(baseLineX.getP1(), baseLineX.getP2());
         *
         * axis.setOrigin(gridLineX.getP1());
         * axis.setModulePitch(modulePitch.top);
         * gridLineX.setP1(axis.translate(i,0));
         *
         * axis.setOrigin(gridLineX.getP2());
         * axis.setModulePitch(modulePitch.top);
         * gridLineX.setP2(axis.translate(i,0));
         *
         *
         * gridLineY = new Line(baseLineY.getP1(), baseLineY.getP2());
         * axis.setOrigin(gridLineY.getP1());
         * axis.setModulePitch(modulePitch.left);
         * gridLineY.setP1(axis.translate(0,i));
         *
         * axis.setOrigin(gridLineY.getP2());
         * axis.setModulePitch(modulePitch.left);
         * gridLineY.setP2(axis.translate(0,i));
         *
         *
         * samplingGrid.setXLine(0,0,i,gridLineX);
         * samplingGrid.setYLine(0,0,i,gridLineY);
         * }
         * for (int ay = 0; ay < samplingGrid.getHeight(); ay++) {
         * for (int ax = 0; ax < samplingGrid.getWidth();ax++) {
         * canvas.drawLines(samplingGrid.getXLines(ax,ay), Color.BLUE);
         * canvas.drawLines(samplingGrid.getYLines(ax,ay), Color.BLUE);
         * }
         * }
         * return samplingGrid;
         * }*/

        //sampllingGrid[areaX][areaY][direction(x=0,y=1)][EachLines]

        /*	SamplingGrid getSamplingGrid2_6(FinderPattern finderPattern, AlignmentPattern alignmentPattern) {
         *
         * Point centers[][] = alignmentPattern.getCenter();
         * centers[0][0] = finderPattern.getCenter(FinderPattern.UL);
         * centers[1][0] = finderPattern.getCenter(FinderPattern.UR);
         * centers[0][1] = finderPattern.getCenter(FinderPattern.DL);
         * int sqrtNumModules = finderPattern.getSqrtNumModules(); //一辺当たりのモジュール数を得る
         *
         * SamplingGrid samplingGrid = new SamplingGrid(1);
         * Line baseLineX, baseLineY, gridLineX, gridLineY;
         *
         * int logicalDistance = alignmentPattern.getLogicalDistance();
         * Axis axis = new Axis(finderPattern.getAngle(), finderPattern.getModuleSize());
         *
         * ModulePitch modulePitch = new ModulePitch(); //top left bottom rightの順に格納
         *
         * modulePitch.top = getAreaModulePitch(centers[0][0], centers[1][0], logicalDistance + 6);
         * modulePitch.left = getAreaModulePitch(centers[0][0], centers[0][1], logicalDistance + 6);
         * axis.setModulePitch(modulePitch.top);
         * axis.setOrigin(centers[0][1]);
         * modulePitch.bottom = getAreaModulePitch(axis.translate(0, -3), centers[1][1], logicalDistance + 3);
         * axis.setModulePitch(modulePitch.left);
         * axis.setOrigin(centers[1][0]);
         * modulePitch.right = getAreaModulePitch(axis.translate(-3, 0), centers[1][1], logicalDistance + 3);
         *
         * //X軸に垂直の基線(一般に縦)
         * baseLineX = new Line();
         * baseLineY = new Line();
         *
         * axis.setOrigin(centers[0][0]);
         * modulePitch.top = getAreaModulePitch(centers[0][0], centers[1][0], logicalDistance + 6);
         * modulePitch.left = getAreaModulePitch(centers[0][0], centers[0][1], logicalDistance + 6);
         * axis.setModulePitch(modulePitch.top);
         * axis.setOrigin(centers[0][1]);
         * modulePitch.bottom = getAreaModulePitch(axis.translate(0,-3), centers[1][1], logicalDistance + 3);
         * axis.setModulePitch(modulePitch.left);
         * axis.setOrigin(centers[1][0]);
         * modulePitch.right = getAreaModulePitch(axis.translate(-3,0), centers[1][1], logicalDistance + 3);
         *
         *
         * axis.setOrigin(centers[0][0]);
         * axis.setModulePitch(modulePitch.top);
         * baseLineX.setP1(axis.translate(-3,-3));
         *
         * axis.setModulePitch(modulePitch.left);
         * baseLineY.setP1(axis.translate(-3,-3));
         *
         * axis.setOrigin(centers[0][1]);
         * axis.setModulePitch(modulePitch.bottom);
         * baseLineX.setP2(axis.translate(-3,3));
         *
         * axis.setOrigin(centers[1][0]);
         * axis.setModulePitch(modulePitch.right);
         * baseLineY.setP2(axis.translate(3,-3));
         *
         *
         * baseLineX.translate(1,1);
         * baseLineY.translate(1,1);
         *
         * samplingGrid.initGrid(0, 0, sqrtNumModules, sqrtNumModules);
         *
         * for (int i = 0; i < sqrtNumModules; i++) {
         * gridLineX = new Line(baseLineX.getP1(), baseLineX.getP2());
         *
         * axis.setOrigin(gridLineX.getP1());
         * axis.setModulePitch(modulePitch.top);
         * gridLineX.setP1(axis.translate(i,0));
         *
         * axis.setOrigin(gridLineX.getP2());
         * axis.setModulePitch(modulePitch.bottom);
         * gridLineX.setP2(axis.translate(i,0));
         *
         *
         * gridLineY = new Line(baseLineY.getP1(), baseLineY.getP2());
         *
         * axis.setOrigin(gridLineY.getP1());
         * axis.setModulePitch(modulePitch.left);
         * gridLineY.setP1(axis.translate(0,i));
         *
         * axis.setOrigin(gridLineY.getP2());
         * axis.setModulePitch(modulePitch.right);
         * gridLineY.setP2(axis.translate(0,i));
         *
         *
         * samplingGrid.setXLine(0,0,i,gridLineX);
         * samplingGrid.setYLine(0,0,i,gridLineY);
         *
         * }
         *
         * for (int ay = 0; ay < samplingGrid.getHeight(); ay++) {
         * for (int ax = 0; ax < samplingGrid.getWidth();ax++) {
         * canvas.drawLines(samplingGrid.getXLines(ax,ay), java.awt.Color.BLUE);
         * canvas.drawLines(samplingGrid.getYLines(ax,ay), java.awt.Color.BLUE);
         * }
         * }
         * return samplingGrid;
         * }
         *
         *
         *
         * //for version 7-13
         * SamplingGrid getSamplingGrid7_13(FinderPattern finderPattern, AlignmentPattern alignmentPattern) {
         *
         * Point centers[][] = alignmentPattern.getCenter();
         * centers[0][0] = finderPattern.getCenter(FinderPattern.UL);
         * centers[2][0] = finderPattern.getCenter(FinderPattern.UR);
         * centers[0][2] = finderPattern.getCenter(FinderPattern.DL);
         * int sqrtNumModules = finderPattern.getSqrtNumModules(); //一辺当たりのモジュール数を得る
         * int sqrtNumArea = 2;
         * int sqrtNumAreaModules = sqrtNumModules / sqrtNumArea;
         * sqrtNumAreaModules++;
         * SamplingGrid samplingGrid = new SamplingGrid(sqrtNumArea);
         * Line baseLineX, baseLineY, gridLineX, gridLineY;
         *
         * int logicalDistance = alignmentPattern.getLogicalDistance();
         * Axis axis = new Axis(finderPattern.getAngle(), finderPattern.getModuleSize());
         * ModulePitch modulePitch;
         * for (int ay = 0; ay < sqrtNumArea; ay++) {
         * for (int ax = 0; ax < sqrtNumArea; ax++) {
         * modulePitch = new ModulePitch(); //top left bottom rightの順に格納
         * baseLineX = new Line();
         * baseLineY = new Line();
         * axis.setModulePitch(finderPattern.getModuleSize());
         * if (ax == 0 && ay == 0) {
         * axis.setOrigin(centers[0][0]);
         * modulePitch.top = getAreaModulePitch(axis.translate(0,3), centers[1][0], logicalDistance + 3);
         * modulePitch.left = getAreaModulePitch(axis.translate(3,0), centers[0][1], logicalDistance + 3);
         * axis.setModulePitch(modulePitch.top);
         * modulePitch.bottom = getAreaModulePitch(centers[0][1], centers[1][1], logicalDistance);
         * axis.setModulePitch(modulePitch.left);
         * modulePitch.right = getAreaModulePitch(centers[1][0], centers[1][1], logicalDistance);
         *
         * axis.setModulePitch(modulePitch.top);
         * baseLineX.setP1(axis.translate(-3,-3));
         *
         * axis.setModulePitch(modulePitch.left);
         * baseLineY.setP1(axis.translate(-3,-3));
         *
         * axis.setOrigin(centers[0][1]);
         * axis.setModulePitch(modulePitch.bottom);
         * baseLineX.setP2(axis.translate(-6,0));
         *
         * axis.setOrigin(centers[1][0]);
         * axis.setModulePitch(modulePitch.right);
         * baseLineY.setP2(axis.translate(0,-6));
         * }
         * else if (ax == 1 && ay == 0) {
         * axis.setOrigin(centers[1][0]);
         * modulePitch.top = getAreaModulePitch(axis.translate(0,-3), centers[2][0], logicalDistance + 3);
         * modulePitch.left = getAreaModulePitch(centers[1][0], centers[1][1], logicalDistance);
         * axis.setModulePitch(modulePitch.top);
         * modulePitch.bottom = getAreaModulePitch(centers[1][1], centers[2][1], logicalDistance);
         * axis.setModulePitch(modulePitch.left);
         * axis.setOrigin(centers[2][0]);
         * modulePitch.right = getAreaModulePitch(axis.translate(-3,0), centers[2][1], logicalDistance + 3);
         *
         * axis.setOrigin(centers[1][0]);
         * axis.setModulePitch(modulePitch.left);
         * baseLineX.setP1(axis.translate(0,-6));
         *
         * baseLineY.setP1(axis.translate(0,-6));
         *
         * baseLineX.setP2(centers[1][1]);
         *
         * axis.setOrigin(centers[2][0]);
         * axis.setModulePitch(modulePitch.right);
         * baseLineY.setP2(axis.translate(3,-3));
         * }
         * else if (ax == 0 && ay == 1) {
         * modulePitch.top = getAreaModulePitch(centers[0][1], centers[1][1], logicalDistance);
         * axis.setOrigin(centers[0][2]);
         * modulePitch.left = getAreaModulePitch(centers[0][1], axis.translate(3,0), logicalDistance + 3);
         * axis.setModulePitch(modulePitch.top);
         * modulePitch.bottom = getAreaModulePitch(axis.translate(0,-3), centers[1][2], logicalDistance + 3);
         * axis.setModulePitch(modulePitch.bottom);
         * modulePitch.right = getAreaModulePitch(centers[1][1], centers[1][2], logicalDistance);
         *
         * axis.setOrigin(centers[0][1]);
         * axis.setModulePitch(modulePitch.top);
         * baseLineX.setP1(axis.translate(-6,0));
         *
         * baseLineY.setP1(axis.translate(-6,0));
         *
         * axis.setOrigin(centers[0][2]);
         * axis.setModulePitch(modulePitch.bottom);
         * baseLineX.setP2(axis.translate(-3, 3));
         *
         * baseLineY.setP2(centers[1][1]);
         * }
         * else if (ax == 1 && ay == 1) {
         * modulePitch.top = getAreaModulePitch(centers[1][1], centers[2][1], logicalDistance);
         * modulePitch.left = getAreaModulePitch(centers[1][1], centers[1][2], logicalDistance);
         * modulePitch.bottom = getAreaModulePitch(centers[1][2], centers[2][2], logicalDistance);
         * modulePitch.right = getAreaModulePitch(centers[2][1], centers[2][2], logicalDistance);
         *
         * baseLineX.setP1(centers[1][1]);
         * baseLineY.setP1(centers[1][1]);
         *
         * axis.setOrigin(centers[1][2]);
         * axis.setModulePitch(modulePitch.left);
         * baseLineX.setP2(axis.translate(0,6));
         *
         * axis.setOrigin(centers[2][1]);
         * axis.setModulePitch(modulePitch.top);
         * baseLineY.setP2(axis.translate(6,0));
         * }
         *
         * samplingGrid.initGrid(ax,ay, sqrtNumAreaModules, sqrtNumAreaModules);
         *
         * for (int i = 0; i < sqrtNumAreaModules; i++) {
         * gridLineX = new Line(baseLineX.getP1(), baseLineX.getP2());
         *
         * axis.setOrigin(gridLineX.getP1());
         * axis.setModulePitch(modulePitch.top);
         * gridLineX.setP1(axis.translate(i,0));
         *
         * axis.setOrigin(gridLineX.getP2());
         * axis.setModulePitch(modulePitch.bottom);
         * gridLineX.setP2(axis.translate(i,0));
         *
         *
         * gridLineY = new Line(baseLineY.getP1(), baseLineY.getP2());
         *
         * axis.setOrigin(gridLineY.getP1());
         * axis.setModulePitch(modulePitch.left);
         * gridLineY.setP1(axis.translate(0,i));
         *
         * axis.setOrigin(gridLineY.getP2());
         * axis.setModulePitch(modulePitch.right);
         * gridLineY.setP2(axis.translate(0,i));
         *
         * samplingGrid.setXLine(ax,ay,i,gridLineX);
         * samplingGrid.setYLine(ax,ay,i,gridLineY);
         *
         * }
         * }
         * }
         *
         * for (int ay = 0; ay < samplingGrid.getHeight(); ay++) {
         * for (int ax = 0; ax < samplingGrid.getWidth();ax++) {
         * canvas.drawLines(samplingGrid.getXLines(ax,ay), java.awt.Color.BLUE);
         * canvas.drawLines(samplingGrid.getYLines(ax,ay), java.awt.Color.BLUE);
         * }
         * }
         *
         * return samplingGrid;
         * }*/
        /// <summary> Generic Sampling grid method</summary>
        internal virtual SamplingGrid getSamplingGrid(FinderPattern finderPattern, AlignmentPattern alignmentPattern)
        {
            Point[][] centers = alignmentPattern.getCenter();

            int version     = finderPattern.Version;
            int sqrtCenters = (version / 7) + 2;

            centers[0][0] = finderPattern.getCenter(FinderPattern.UL);
            centers[sqrtCenters - 1][0] = finderPattern.getCenter(FinderPattern.UR);
            centers[0][sqrtCenters - 1] = finderPattern.getCenter(FinderPattern.DL);
            //int sqrtNumModules = finderPattern.getSqrtNumModules(); /// The number of modules per one side is obtained
            int sqrtNumArea = sqrtCenters - 1;

            //--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//
            SamplingGrid samplingGrid = new SamplingGrid(sqrtNumArea);

            Line baseLineX, baseLineY, gridLineX, gridLineY;

            ///???
            //Point[] targetCenters;

            //int logicalDistance = alignmentPattern.getLogicalDistance();
            Axis        axis = new Axis(finderPattern.getAngle(), finderPattern.getModuleSize());
            ModulePitch modulePitch;

            // for each area :
            for (int ay = 0; ay < sqrtNumArea; ay++)
            {
                for (int ax = 0; ax < sqrtNumArea; ax++)
                {
                    modulePitch      = new ModulePitch(this);                /// Housing to order
                    baseLineX        = new Line();
                    baseLineY        = new Line();
                    axis.ModulePitch = finderPattern.getModuleSize();

                    Point[][] logicalCenters = AlignmentPattern.getLogicalCenter(finderPattern);

                    Point upperLeftPoint  = centers[ax][ay];
                    Point upperRightPoint = centers[ax + 1][ay];
                    Point lowerLeftPoint  = centers[ax][ay + 1];
                    Point lowerRightPoint = centers[ax + 1][ay + 1];

                    Point logicalUpperLeftPoint  = logicalCenters[ax][ay];
                    Point logicalUpperRightPoint = logicalCenters[ax + 1][ay];
                    Point logicalLowerLeftPoint  = logicalCenters[ax][ay + 1];
                    Point logicalLowerRightPoint = logicalCenters[ax + 1][ay + 1];

                    if (ax == 0 && ay == 0)
                    // left upper corner
                    {
                        if (sqrtNumArea == 1)
                        {
                            upperLeftPoint  = axis.translate(upperLeftPoint, -3, -3);
                            upperRightPoint = axis.translate(upperRightPoint, 3, -3);
                            lowerLeftPoint  = axis.translate(lowerLeftPoint, -3, 3);
                            lowerRightPoint = axis.translate(lowerRightPoint, 6, 6);

                            logicalUpperLeftPoint.translate(-6, -6);
                            logicalUpperRightPoint.translate(3, -3);
                            logicalLowerLeftPoint.translate(-3, 3);
                            logicalLowerRightPoint.translate(6, 6);
                        }
                        else
                        {
                            upperLeftPoint  = axis.translate(upperLeftPoint, -3, -3);
                            upperRightPoint = axis.translate(upperRightPoint, 0, -6);
                            lowerLeftPoint  = axis.translate(lowerLeftPoint, -6, 0);

                            logicalUpperLeftPoint.translate(-6, -6);
                            logicalUpperRightPoint.translate(0, -6);
                            logicalLowerLeftPoint.translate(-6, 0);
                        }
                    }
                    else if (ax == 0 && ay == sqrtNumArea - 1)
                    // left bottom corner
                    {
                        upperLeftPoint  = axis.translate(upperLeftPoint, -6, 0);
                        lowerLeftPoint  = axis.translate(lowerLeftPoint, -3, 3);
                        lowerRightPoint = axis.translate(lowerRightPoint, 0, 6);


                        logicalUpperLeftPoint.translate(-6, 0);
                        logicalLowerLeftPoint.translate(-6, 6);
                        logicalLowerRightPoint.translate(0, 6);
                    }
                    else if (ax == sqrtNumArea - 1 && ay == 0)
                    // right upper corner
                    {
                        upperLeftPoint  = axis.translate(upperLeftPoint, 0, -6);
                        upperRightPoint = axis.translate(upperRightPoint, 3, -3);
                        lowerRightPoint = axis.translate(lowerRightPoint, 6, 0);

                        logicalUpperLeftPoint.translate(0, -6);
                        logicalUpperRightPoint.translate(6, -6);
                        logicalLowerRightPoint.translate(6, 0);
                    }
                    else if (ax == sqrtNumArea - 1 && ay == sqrtNumArea - 1)
                    // right bottom corner
                    {
                        lowerLeftPoint  = axis.translate(lowerLeftPoint, 0, 6);
                        upperRightPoint = axis.translate(upperRightPoint, 6, 0);
                        lowerRightPoint = axis.translate(lowerRightPoint, 6, 6);

                        logicalLowerLeftPoint.translate(0, 6);
                        logicalUpperRightPoint.translate(6, 0);
                        logicalLowerRightPoint.translate(6, 6);
                    }
                    else if (ax == 0)
                    // left side
                    {
                        upperLeftPoint = axis.translate(upperLeftPoint, -6, 0);
                        lowerLeftPoint = axis.translate(lowerLeftPoint, -6, 0);

                        logicalUpperLeftPoint.translate(-6, 0);
                        logicalLowerLeftPoint.translate(-6, 0);
                    }
                    else if (ax == sqrtNumArea - 1)
                    // right
                    {
                        upperRightPoint = axis.translate(upperRightPoint, 6, 0);
                        lowerRightPoint = axis.translate(lowerRightPoint, 6, 0);

                        logicalUpperRightPoint.translate(6, 0);
                        logicalLowerRightPoint.translate(6, 0);
                    }
                    else if (ay == 0)
                    // top
                    {
                        upperLeftPoint  = axis.translate(upperLeftPoint, 0, -6);
                        upperRightPoint = axis.translate(upperRightPoint, 0, -6);

                        logicalUpperLeftPoint.translate(0, -6);
                        logicalUpperRightPoint.translate(0, -6);
                    }
                    else if (ay == sqrtNumArea - 1)
                    // bottom
                    {
                        lowerLeftPoint  = axis.translate(lowerLeftPoint, 0, 6);
                        lowerRightPoint = axis.translate(lowerRightPoint, 0, 6);

                        logicalLowerLeftPoint.translate(0, 6);
                        logicalLowerRightPoint.translate(0, 6);
                    }

                    if (ax == 0)
                    {
                        logicalUpperRightPoint.translate(1, 0);
                        logicalLowerRightPoint.translate(1, 0);
                    }
                    else
                    {
                        logicalUpperLeftPoint.translate(-1, 0);
                        logicalLowerLeftPoint.translate(-1, 0);
                    }

                    if (ay == 0)
                    {
                        logicalLowerLeftPoint.translate(0, 1);
                        logicalLowerRightPoint.translate(0, 1);
                    }
                    else
                    {
                        logicalUpperLeftPoint.translate(0, -1);
                        logicalUpperRightPoint.translate(0, -1);
                    }

                    int logicalWidth  = logicalUpperRightPoint.X - logicalUpperLeftPoint.X;
                    int logicalHeight = logicalLowerLeftPoint.Y - logicalUpperLeftPoint.Y;

                    if (version < 7)
                    {
                        logicalWidth  += 3;
                        logicalHeight += 3;
                    }
                    modulePitch.top    = getAreaModulePitch(upperLeftPoint, upperRightPoint, logicalWidth - 1);
                    modulePitch.left   = getAreaModulePitch(upperLeftPoint, lowerLeftPoint, logicalHeight - 1);
                    modulePitch.bottom = getAreaModulePitch(lowerLeftPoint, lowerRightPoint, logicalWidth - 1);
                    modulePitch.right  = getAreaModulePitch(upperRightPoint, lowerRightPoint, logicalHeight - 1);

                    baseLineX.setP1(upperLeftPoint);
                    baseLineY.setP1(upperLeftPoint);
                    baseLineX.setP2(lowerLeftPoint);
                    baseLineY.setP2(upperRightPoint);

                    samplingGrid.initGrid(ax, ay, logicalWidth, logicalHeight);

                    for (int i = 0; i < logicalWidth; i++)
                    {
                        gridLineX = new Line(baseLineX.getP1(), baseLineX.getP2());

                        axis.Origin      = gridLineX.getP1();
                        axis.ModulePitch = modulePitch.top;
                        gridLineX.setP1(axis.translate(i, 0));

                        axis.Origin      = gridLineX.getP2();
                        axis.ModulePitch = modulePitch.bottom;
                        gridLineX.setP2(axis.translate(i, 0));

                        samplingGrid.setXLine(ax, ay, i, gridLineX);
                    }

                    for (int i = 0; i < logicalHeight; i++)
                    {
                        gridLineY = new Line(baseLineY.getP1(), baseLineY.getP2());

                        axis.Origin      = gridLineY.getP1();
                        axis.ModulePitch = modulePitch.left;
                        gridLineY.setP1(axis.translate(0, i));

                        axis.Origin      = gridLineY.getP2();
                        axis.ModulePitch = modulePitch.right;
                        gridLineY.setP2(axis.translate(0, i));

                        samplingGrid.setYLine(ax, ay, i, gridLineY);
                    }
                }
            }

            return(samplingGrid);
        }
Exemple #31
0
      private bool checkPairSequence(List<ExpandedPair> previousPairs, FinderPattern pattern, out bool mayBeLast)
      {
         mayBeLast = false;
         int currentSequenceLength = previousPairs.Count + 1;
         if (currentSequenceLength > currentSequence.Length)
         {
            return false;
         }

         for (int pos = 0; pos < previousPairs.Count; ++pos)
         {
            currentSequence[pos] = previousPairs[pos].FinderPattern.Value;
         }

         currentSequence[currentSequenceLength - 1] = pattern.Value;

         foreach (int[] validSequence in FINDER_PATTERN_SEQUENCES)
         {
            if (validSequence.Length >= currentSequenceLength)
            {
               bool valid = true;
               for (int pos = 0; pos < currentSequenceLength; ++pos)
               {
                  if (currentSequence[pos] != validSequence[pos])
                  {
                     valid = false;
                     break;
                  }
               }

               if (valid)
               {
                  mayBeLast = currentSequenceLength == validSequence.Length;
                  return true;
               }
            }
         }

         return false;
      }
Exemple #32
0
      internal DataCharacter decodeDataCharacter(BitArray row,
                                        FinderPattern pattern,
                                        bool isOddPattern,
                                        bool leftChar)
      {
         int[] counters = getDataCharacterCounters();
         counters[0] = 0;
         counters[1] = 0;
         counters[2] = 0;
         counters[3] = 0;
         counters[4] = 0;
         counters[5] = 0;
         counters[6] = 0;
         counters[7] = 0;

         if (leftChar)
         {
            if (!recordPatternInReverse(row, pattern.StartEnd[0], counters))
               return null;
         }
         else
         {
            if (!recordPattern(row, pattern.StartEnd[1] + 1, counters))
               return null;
            // reverse it
            for (int i = 0, j = counters.Length - 1; i < j; i++, j--)
            {
               int temp = counters[i];
               counters[i] = counters[j];
               counters[j] = temp;
            }
         }//counters[] has the pixels of the module

         int numModules = 17; //left and right data characters have all the same length
         float elementWidth = (float)count(counters) / (float)numModules;

         int[] oddCounts = getOddCounts();
         int[] evenCounts = getEvenCounts();
         float[] oddRoundingErrors = getOddRoundingErrors();
         float[] evenRoundingErrors = getEvenRoundingErrors();

         for (int i = 0; i < counters.Length; i++)
         {
            float divided = 1.0f * counters[i] / elementWidth;
            int rounded = (int)(divided + 0.5f); // Round
            if (rounded < 1)
            {
               rounded = 1;
            }
            else if (rounded > 8)
            {
               rounded = 8;
            }
            int offset = i >> 1;
            if ((i & 0x01) == 0)
            {
               oddCounts[offset] = rounded;
               oddRoundingErrors[offset] = divided - rounded;
            }
            else
            {
               evenCounts[offset] = rounded;
               evenRoundingErrors[offset] = divided - rounded;
            }
         }

         if (!adjustOddEvenCounts(numModules))
            return null;

         int weightRowNumber = 4 * pattern.Value + (isOddPattern ? 0 : 2) + (leftChar ? 0 : 1) - 1;

         int oddSum = 0;
         int oddChecksumPortion = 0;
         for (int i = oddCounts.Length - 1; i >= 0; i--)
         {
            if (isNotA1left(pattern, isOddPattern, leftChar))
            {
               int weight = WEIGHTS[weightRowNumber][2 * i];
               oddChecksumPortion += oddCounts[i] * weight;
            }
            oddSum += oddCounts[i];
         }
         int evenChecksumPortion = 0;
         int evenSum = 0;
         for (int i = evenCounts.Length - 1; i >= 0; i--)
         {
            if (isNotA1left(pattern, isOddPattern, leftChar))
            {
               int weight = WEIGHTS[weightRowNumber][2 * i + 1];
               evenChecksumPortion += evenCounts[i] * weight;
            }
            evenSum += evenCounts[i];
         }
         int checksumPortion = oddChecksumPortion + evenChecksumPortion;

         if ((oddSum & 0x01) != 0 || oddSum > 13 || oddSum < 4)
         {
            return null;
         }

         int group = (13 - oddSum) / 2;
         int oddWidest = SYMBOL_WIDEST[group];
         int evenWidest = 9 - oddWidest;
         int vOdd = RSSUtils.getRSSvalue(oddCounts, oddWidest, true);
         int vEven = RSSUtils.getRSSvalue(evenCounts, evenWidest, false);
         int tEven = EVEN_TOTAL_SUBSET[group];
         int gSum = GSUM[group];
         int value = vOdd * tEven + vEven + gSum;

         return new DataCharacter(value, checksumPortion);
      }
Exemple #33
0
        /// <summary>
        /// Refines the width of a finder pattern by following a line between two finder patterns in one direction and then the other.
        /// </summary>
        /// <param name="startFinderPattern">The finder pattern whose width will be refined.</param>
        /// <param name="endFinderPattern">The second finder pattern which determines the direction in which the width of the first pattern will be measured.</param>
        /// <returns></returns>
        private static int[] finderPatternWidth(FinderPattern startFinderPattern, FinderPattern endFinderPattern)
        {
            int startX = startFinderPattern.X;
            int startY = startFinderPattern.Y;
            int endX = endFinderPattern.X;
            int endY = endFinderPattern.Y;

            // Bresenham's line algorithm implementation, see http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
            bool steep = Math.Abs(endY - startY) > Math.Abs(endX - startX);
            if (steep)
            {
                int temp = startX;
                startX = startY;
                startY = temp;
                temp = endX;
                endX = endY;
                endY = temp;
            }

            int dx = Math.Abs(endX - startX);
            int dy = Math.Abs(endY - startY);
            int error = -dx >> 1;
            int ystep = startY < endY ? 1 : -1;
            int xstep = startX < endX ? 1 : -1;
            int currentState = 0;
            int x1 = 0;
            int x2 = 0;
            int y1 = 0;
            int y2 = 0;
            int[] stateCount = new int[5];

            for (int x = startX, y = startY; x != endX; x += xstep)
            {
                int realX = steep ? y : x;
                int realY = steep ? x : y;
                if (currentState == 0)
                {
                    // Current pixel is black, looking for white
                    if (_imageArray[realY * _width + realX] == 0) currentState++;
                    else stateCount[2]++;
                }

                if (currentState == 1)
                {
                    if (_imageArray[realY * _width + realX] == 1) currentState++;
                    else stateCount[1]++;
                }

                if (currentState == 2)
                {
                    if (_imageArray[realY * _width + realX] == 0) currentState++;
                    else stateCount[0]++;
                }

                if (currentState == 3)
                {
                    // Got black/white/black and white again, we're done
                    x1 = x;
                    y1 = y;
                    ystep = (ystep == 1) ? -1 : 1;
                    xstep = (xstep == 1) ? -1 : 1;
                    x = endX - xstep;
                    continue;
                }
                error += dy;
                if (error > 0)
                {
                    if (y == endY) break;
                    y += ystep;
                    error -= dx;
                }
            }

            currentState = 0;
            x2 = 0;
            y2 = 0;

            for (int x = startX, y = startY; x != endX; x += xstep)
            {
                int realX = steep ? y : x;
                int realY = steep ? x : y;

                if (currentState == 0)
                {
                    // Current pixel is black, looking for white
                    if (_imageArray[realY * _width + realX] == 0) currentState++;
                    else stateCount[2]++;
                }

                if (currentState == 1)
                {
                    if (_imageArray[realY * _width + realX] == 1) currentState++;
                    else stateCount[3]++;
                }

                if (currentState == 2)
                {
                    if (_imageArray[realY * _width + realX] == 0) currentState++;
                    else stateCount[4]++;
                }

                if (currentState == 3)
                {
                    // Got black and white again, we're done
                    x2 = x;
                    y2 = y;
                    ystep = (ystep == 1) ? -1 : 1;
                    xstep = (xstep == 1) ? -1 : 1;
                    x = endX - xstep;
                    continue;
                }
                error += dy;
                if (error > 0)
                {
                    if (y == endY) break;
                    y += ystep;
                    error -= dx;
                }
            }

            int xDifference = Math.Abs(x2 - x1);
            int yDifference = Math.Abs(y2 - y1);

            float distance = (float)Math.Sqrt(xDifference * xDifference + yDifference * yDifference);

            stateCount[0] = stateCount[1] = stateCount[3] = stateCount[4] = (int)Math.Round(distance / 7.0f);
            stateCount[2] = (int)Math.Round(distance / 7.0f * 3.0f);

            //stateCount[2]--; // Decrement the state count of the middle black pattern by 1 (we counted one pixel twice)
            return stateCount;
        }
 private static bool isNotA1left(FinderPattern pattern, bool isOddPattern, bool leftChar)
 {
     // A1: pattern.getValue is 0 (A), and it's an oddPattern, and it is a left char
     return(!(pattern.Value == 0 && isOddPattern && leftChar));
 }
 /// <summary> <p>This is called when a horizontal scan finds a possible alignment pattern. It will
 /// cross check with a vertical scan, and if successful, will, ah, cross-cross-check
 /// with another horizontal scan. This is needed primarily to locate the real horizontal
 /// center of the pattern in cases of extreme skew.</p>
 /// 
 /// <p>If that succeeds the finder pattern location is added to a list that tracks
 /// the number of times each location has been nearly-matched as a finder pattern.
 /// Each additional find is more evidence that the location is in fact a finder
 /// pattern center
 /// 
 /// </summary>
 /// <param name="stateCount">reading state module counts from horizontal scan
 /// </param>
 /// <param name="i">row where finder pattern may be found
 /// </param>
 /// <param name="j">end of possible finder pattern in row
 /// </param>
 /// <returns> true if a finder pattern candidate was found this time
 /// </returns>
 protected internal virtual bool handlePossibleCenter(int[] stateCount, int i, int j)
 {
     int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
     float centerJ = centerFromEnd(stateCount, j);
     //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 centerI = crossCheckVertical(i, (int)centerJ, stateCount[2], stateCountTotal);
     if (!System.Single.IsNaN(centerI))
     {
         // Re-cross check
         //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'"
         centerJ = crossCheckHorizontal((int)centerJ, (int)centerI, stateCount[2], stateCountTotal);
         if (!System.Single.IsNaN(centerJ))
         {
             //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 estimatedModuleSize = (float)stateCountTotal / 7.0f;
             bool found = false;
             int max = possibleCenters.Count;
             for (int index = 0; index < max; index++)
             {
                 FinderPattern center = (FinderPattern)possibleCenters[index];
                 // Look for about the same center and module size:
                 if (center.aboutEquals(estimatedModuleSize, centerI, centerJ))
                 {
                     center.incrementCount();
                     found = true;
                     break;
                 }
             }
             if (!found)
             {
                 ResultPoint point = new FinderPattern(centerJ, centerI, estimatedModuleSize);
                 possibleCenters.Add(point);
                 if (resultPointCallback != null)
                 {
                     resultPointCallback.foundPossibleResultPoint(point);
                 }
             }
             return true;
         }
     }
     return false;
 }