Beispiel #1
0
        /// <summary> Append length info. On success, store the result in "bits".</summary>
        internal static void  appendLengthInfo(int numLetters, int version, Mode mode, BitVector bits)
        {
            int numBits = mode.getCharacterCountBits(Version.getVersionForNumber(version));

            if (numLetters > ((1 << numBits) - 1))
            {
                throw new WriterException(numLetters + "is bigger than" + ((1 << numBits) - 1));
            }
            bits.appendBits(numLetters, numBits);
        }
 // Build 2D matrix of QR Code from "dataBits" with "ecLevel", "version" and "getMaskPattern". On
 // success, store the result in "matrix" and return true.
 //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
 //ORIGINAL LINE: static void buildMatrix(com.google.zxing.common.BitArray dataBits, com.google.zxing.qrcode.decoder.ErrorCorrectionLevel ecLevel, com.google.zxing.qrcode.decoder.Version version, int maskPattern, ByteMatrix matrix) throws com.google.zxing.WriterException
 internal static void buildMatrix(BitArray dataBits, ErrorCorrectionLevel ecLevel, Version version, int maskPattern, ByteMatrix matrix)
 {
     clearMatrix(matrix);
     embedBasicPatterns(version, matrix);
     // Type information appear with any version.
     embedTypeInfo(ecLevel, maskPattern, matrix);
     // Version info appear if version >= 7.
     maybeEmbedVersionInfo(version, matrix);
     // Data should be embedded at end.
     embedDataBits(dataBits, maskPattern, matrix);
 }
Beispiel #3
0
        /// <summary> Initialize "qrCode" according to "numInputBytes", "ecLevel", and "mode". On success,
        /// modify "qrCode".
        /// </summary>
        private static void  initQRCode(int numInputBytes, ErrorCorrectionLevel ecLevel, Mode mode, QRCode qrCode)
        {
            qrCode.ECLevel = ecLevel;
            qrCode.Mode    = mode;

            // In the following comments, we use numbers of Version 7-H.
            for (int versionNum = 1; versionNum <= 40; versionNum++)
            {
                Version version = Version.getVersionForNumber(versionNum);
                // numBytes = 196
                int numBytes = version.TotalCodewords;
                // getNumECBytes = 130
                Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel);
                int numEcBytes            = ecBlocks.TotalECCodewords;
                // getNumRSBlocks = 5
                int numRSBlocks = ecBlocks.NumBlocks;
                // getNumDataBytes = 196 - 130 = 66
                int numDataBytes = numBytes - numEcBytes;
                // We want to choose the smallest version which can contain data of "numInputBytes" + some
                // extra bits for the header (mode info and length info). The header can be three bytes
                // (precisely 4 + 16 bits) at most. Hence we do +3 here.
                if (numDataBytes >= numInputBytes + 3)
                {
                    // Yay, we found the proper rs block info!
                    qrCode.Version       = versionNum;
                    qrCode.NumTotalBytes = numBytes;
                    qrCode.NumDataBytes  = numDataBytes;
                    qrCode.NumRSBlocks   = numRSBlocks;
                    // getNumECBytes = 196 - 66 = 130
                    qrCode.NumECBytes = numEcBytes;
                    // matrix width = 21 + 6 * 4 = 45
                    qrCode.MatrixWidth = version.DimensionForVersion;
                    return;
                }
            }
            throw new WriterException("Cannot find proper rs block info (input data too big?)");
        }
        protected internal virtual DetectorResult processFinderPatternInfo(FinderPatternInfo info)
        {
            FinderPattern topLeft    = info.TopLeft;
            FinderPattern topRight   = info.TopRight;
            FinderPattern bottomLeft = info.BottomLeft;

            float moduleSize = calculateModuleSize(topLeft, topRight, bottomLeft);

            if (moduleSize < 1.0f)
            {
                throw ReaderException.Instance;
            }
            int     dimension               = computeDimension(topLeft, topRight, bottomLeft, moduleSize);
            Version provisionalVersion      = Version.getProvisionalVersionForDimension(dimension);
            int     modulesBetweenFPCenters = provisionalVersion.DimensionForVersion - 7;

            AlignmentPattern alignmentPattern = null;

            // Anything above version 1 has an alignment pattern
            if (provisionalVersion.AlignmentPatternCenters.Length > 0)
            {
                // Guess where a "bottom right" finder pattern would have been
                float bottomRightX = topRight.X - topLeft.X + bottomLeft.X;
                float bottomRightY = topRight.Y - topLeft.Y + bottomLeft.Y;

                // Estimate that alignment pattern is closer by 3 modules
                // from "bottom right" to known top left location
                //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 correctionToTopLeft = 1.0f - 3.0f / (float)modulesBetweenFPCenters;
                //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'"
                int estAlignmentX = (int)(topLeft.X + correctionToTopLeft * (bottomRightX - topLeft.X));
                //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'"
                int estAlignmentY = (int)(topLeft.Y + correctionToTopLeft * (bottomRightY - topLeft.Y));

                // Kind of arbitrary -- expand search radius before giving up
                for (int i = 4; i <= 16; i <<= 1)
                {
                    try
                    {
                        //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'"
                        alignmentPattern = findAlignmentInRegion(moduleSize, estAlignmentX, estAlignmentY, (float)i);
                        break;
                    }
                    catch (ReaderException re)
                    {
                        // try next round
                    }
                }
                // If we didn't find alignment pattern... well try anyway without it
            }

            PerspectiveTransform transform = createTransform(topLeft, topRight, bottomLeft, alignmentPattern, dimension);

            BitMatrix bits = sampleGrid(image, transform, dimension);

            ResultPoint[] points;
            if (alignmentPattern == null)
            {
                points = new ResultPoint[] { bottomLeft, topLeft, topRight };
            }
            else
            {
                points = new ResultPoint[] { bottomLeft, topLeft, topRight, alignmentPattern };
            }
            return(new DetectorResult(bits, points));
        }
 // Embed position adjustment patterns if need be.
 private static void maybeEmbedPositionAdjustmentPatterns(Version version, ByteMatrix matrix)
 {
     if (version.VersionNumber < 2) // The patterns appear if version >= 2
     {
       return;
     }
     int index = version.VersionNumber - 1;
     int[] coordinates = POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index];
     int numCoordinates = POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index].Length;
     for (int i = 0; i < numCoordinates; ++i)
     {
       for (int j = 0; j < numCoordinates; ++j)
       {
     int y = coordinates[i];
     int x = coordinates[j];
     if (x == -1 || y == -1)
     {
       continue;
     }
     // If the cell is unset, we embed the position adjustment pattern here.
     if (isEmpty(matrix.get(x, y)))
     {
       // -2 is necessary since the x/y coordinates point to the center of the pattern, not the
       // left top corner.
       embedPositionAdjustmentPattern(x - 2, y - 2, matrix);
     }
       }
     }
 }
        // Embed version information if need be. On success, modify the matrix and return true.
        // See 8.10 of JISX0510:2004 (p.47) for how to embed version information.
        //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
        //ORIGINAL LINE: static void maybeEmbedVersionInfo(com.google.zxing.qrcode.decoder.Version version, ByteMatrix matrix) throws com.google.zxing.WriterException
        internal static void maybeEmbedVersionInfo(Version version, ByteMatrix matrix)
        {
            if (version.VersionNumber < 7) // Version info is necessary if version >= 7.
            {
              return; // Don't need version info.
            }
            BitArray versionInfoBits = new BitArray();
            makeVersionInfoBits(version, versionInfoBits);

            int bitIndex = 6 * 3 - 1; // It will decrease from 17 to 0.
            for (int i = 0; i < 6; ++i)
            {
              for (int j = 0; j < 3; ++j)
              {
            // Place bits in LSB (least significant bit) to MSB order.
            bool bit = versionInfoBits.get(bitIndex);
            bitIndex--;
            // Left bottom corner.
            matrix.set(i, matrix.Height - 11 + j, bit);
            // Right bottom corner.
            matrix.set(matrix.Height - 11 + j, i, bit);
              }
            }
        }
        // Make bit vector of version information. On success, store the result in "bits" and return true.
        // See 8.10 of JISX0510:2004 (p.45) for details.
        //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
        //ORIGINAL LINE: static void makeVersionInfoBits(com.google.zxing.qrcode.decoder.Version version, com.google.zxing.common.BitArray bits) throws com.google.zxing.WriterException
        internal static void makeVersionInfoBits(Version version, BitArray bits)
        {
            bits.appendBits(version.VersionNumber, 6);
            int bchCode = calculateBCHCode(version.VersionNumber, VERSION_INFO_POLY);
            bits.appendBits(bchCode, 12);

            if (bits.Size != 18) // Just in case.
            {
              throw new WriterException("should not happen but we got: " + bits.Size);
            }
        }
        // Embed basic patterns. On success, modify the matrix and return true.
        // The basic patterns are:
        // - Position detection patterns
        // - Timing patterns
        // - Dark dot at the left bottom corner
        // - Position adjustment patterns, if need be
        //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
        //ORIGINAL LINE: static void embedBasicPatterns(com.google.zxing.qrcode.decoder.Version version, ByteMatrix matrix) throws com.google.zxing.WriterException
        internal static void embedBasicPatterns(Version version, ByteMatrix matrix)
        {
            // Let's get started with embedding big squares at corners.
            embedPositionDetectionPatternsAndSeparators(matrix);
            // Then, embed the dark dot at the left bottom corner.
            embedDarkDotAtLeftBottomCorner(matrix);

            // Position adjustment patterns appear if version >= 2.
            maybeEmbedPositionAdjustmentPatterns(version, matrix);
            // Timing patterns should be embedded after position adj. patterns.
            embedTimingPatterns(matrix);
        }