isValidMaskPattern() public static method

public static isValidMaskPattern ( int maskPattern ) : bool
maskPattern int
return bool
Exemplo n.º 1
0
        /// <summary>
        /// Make bit vector of type information. On success, store the result in "bits" and return true.
        /// Encode error correction level and mask pattern. See 8.9 of
        /// JISX0510:2004 (p.45) for details.
        /// </summary>
        /// <param name="ecLevel">The ec level.</param>
        /// <param name="maskPattern">The mask pattern.</param>
        /// <param name="bits">The bits.</param>
        public static void makeTypeInfoBits(ErrorCorrectionLevel ecLevel, int maskPattern, BitArray bits)
        {
            if (!QRCode.isValidMaskPattern(maskPattern))
            {
                throw new WriterException("Invalid mask pattern");
            }
            int typeInfo = (ecLevel.Bits << 3) | maskPattern;

            bits.appendBits(typeInfo, 5);

            int bchCode = calculateBCHCode(typeInfo, TYPE_INFO_POLY);

            bits.appendBits(bchCode, 10);

            BitArray maskBits = new BitArray();

            maskBits.appendBits(TYPE_INFO_MASK_PATTERN, 15);
            bits.xor(maskBits);

            if (bits.Size != 15)
            {
                // Just in case.
                throw new WriterException("should not happen but we got: " + bits.Size);
            }
        }
Exemplo n.º 2
0
        // Return the mask bit for "getMaskPattern" at "x" and "y". See 8.8 of JISX0510:2004 for mask
        // pattern conditions.
        public static bool getDataMaskBit(int maskPattern, int x, int y)
        {
            if (!QRCode.isValidMaskPattern(maskPattern))
            {
                throw new System.ArgumentException("Invalid mask pattern");
            }
            int intermediate, temp;

            switch (maskPattern)
            {
            case 0:
                intermediate = (y + x) & 0x1;
                break;

            case 1:
                intermediate = y & 0x1;
                break;

            case 2:
                intermediate = x % 3;
                break;

            case 3:
                intermediate = (y + x) % 3;
                break;

            case 4:
                intermediate = (((int)((uint)y >> 1)) + (x / 3)) & 0x1;
                break;

            case 5:
                temp         = y * x;
                intermediate = (temp & 0x1) + (temp % 3);
                break;

            case 6:
                temp         = y * x;
                intermediate = (((temp & 0x1) + (temp % 3)) & 0x1);
                break;

            case 7:
                temp         = y * x;
                intermediate = (((temp % 3) + ((y + x) & 0x1)) & 0x1);
                break;

            default:
                throw new System.ArgumentException("Invalid mask pattern: " + maskPattern);
            }
            return(intermediate == 0);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Encodes the specified content.
        /// </summary>
        /// <param name="content">The content.</param>
        /// <param name="ecLevel">The ec level.</param>
        /// <param name="hints">The hints.</param>
        /// <returns></returns>
        public static QRCode encode(String content,
                                    ErrorCorrectionLevel ecLevel,
                                    IDictionary <EncodeHintType, object> hints)
        {
            Version  version;
            BitArray headerAndDataBits;
            Mode     mode;

            var hasGS1FormatHint = hints != null && hints.ContainsKey(EncodeHintType.GS1_FORMAT) &&
                                   hints[EncodeHintType.GS1_FORMAT] != null && Convert.ToBoolean(hints[EncodeHintType.GS1_FORMAT].ToString());
            var hasCompactionHint = hints != null && hints.ContainsKey(EncodeHintType.QR_COMPACT) &&
                                    hints[EncodeHintType.QR_COMPACT] != null && Convert.ToBoolean(hints[EncodeHintType.QR_COMPACT].ToString());

            // Determine what character encoding has been specified by the caller, if any
            bool hasEncodingHint = hints != null && hints.ContainsKey(EncodeHintType.CHARACTER_SET);

            var encoding = StringUtils.PLATFORM_DEFAULT_ENCODING_T;
            // caller of the method can only control if the ECI segment should be written
            // character set is fixed to UTF-8; but some scanners doesn't like the ECI segment
            var generateECI = hasEncodingHint;

            if (hasCompactionHint)
            {
                mode = Mode.BYTE;

                var priorityEncoding = encoding.Equals(DEFAULT_BYTE_MODE_ENCODING) ? null : encoding;
                var rn = MinimalEncoder.encode(content, null, priorityEncoding, hasGS1FormatHint, ecLevel);

                headerAndDataBits = new BitArray();
                rn.getBits(headerAndDataBits);
                version = rn.getVersion();
            }
            else
            {
                // Pick an encoding mode appropriate for the content. Note that this will not attempt to use
                // multiple modes / segments even if that were more efficient.
                mode = chooseMode(content, encoding);

                // This will store the header information, like mode and
                // length, as well as "header" segments like an ECI segment.
                var headerBits = new BitArray();

                // Append ECI segment if applicable
                if (mode == Mode.BYTE && generateECI)
                {
                    var eci = CharacterSetECI.getCharacterSetECI(encoding);
                    if (eci != null)
                    {
                        var eciIsExplicitDisabled = (hints != null && hints.ContainsKey(EncodeHintType.DISABLE_ECI) && hints[EncodeHintType.DISABLE_ECI] != null && Convert.ToBoolean(hints[EncodeHintType.DISABLE_ECI].ToString()));
                        if (!eciIsExplicitDisabled)
                        {
                            appendECI(eci, headerBits);
                        }
                    }
                }

                // Append the FNC1 mode header for GS1 formatted data if applicable
                if (hasGS1FormatHint)
                {
                    // GS1 formatted codes are prefixed with a FNC1 in first position mode header
                    appendModeInfo(Mode.FNC1_FIRST_POSITION, headerBits);
                }

                // (With ECI in place,) Write the mode marker
                appendModeInfo(mode, headerBits);

                // Collect data within the main segment, separately, to count its size if needed. Don't add it to
                // main payload yet.
                var dataBits = new BitArray();
                appendBytes(content, mode, dataBits, encoding);

                if (hints != null && hints.ContainsKey(EncodeHintType.QR_VERSION))
                {
                    int versionNumber = Int32.Parse(hints[EncodeHintType.QR_VERSION].ToString());
                    version = Version.getVersionForNumber(versionNumber);
                    int bitsNeeded = calculateBitsNeeded(mode, headerBits, dataBits, version);
                    if (!willFit(bitsNeeded, version, ecLevel))
                    {
                        throw new WriterException("Data too big for requested version");
                    }
                }
                else
                {
                    version = recommendVersion(ecLevel, mode, headerBits, dataBits);
                }

                headerAndDataBits = new BitArray();
                headerAndDataBits.appendBitArray(headerBits);
                // Find "length" of main segment and write it
                var numLetters = mode == Mode.BYTE ? dataBits.SizeInBytes : content.Length;
                appendLengthInfo(numLetters, version, mode, headerAndDataBits);
                // Put data together into the overall payload
                headerAndDataBits.appendBitArray(dataBits);
            }

            var ecBlocks     = version.getECBlocksForLevel(ecLevel);
            var numDataBytes = version.TotalCodewords - ecBlocks.TotalECCodewords;

            // Terminate the bits properly.
            terminateBits(numDataBytes, headerAndDataBits);

            // Interleave data bits with error correction code.
            var finalBits = interleaveWithECBytes(headerAndDataBits,
                                                  version.TotalCodewords,
                                                  numDataBytes,
                                                  ecBlocks.NumBlocks);

            var qrCode = new QRCode
            {
                ECLevel = ecLevel,
                Mode    = mode,
                Version = version
            };

            //  Choose the mask pattern and set to "qrCode".
            var dimension = version.DimensionForVersion;
            var matrix    = new ByteMatrix(dimension, dimension);

            // Enable manual selection of the pattern to be used via hint
            var maskPattern = -1;

            if (hints != null && hints.ContainsKey(EncodeHintType.QR_MASK_PATTERN))
            {
                var hintMaskPattern = Int32.Parse(hints[EncodeHintType.QR_MASK_PATTERN].ToString());
                maskPattern = QRCode.isValidMaskPattern(hintMaskPattern) ? hintMaskPattern : -1;
            }

            if (maskPattern == -1)
            {
                maskPattern = chooseMaskPattern(finalBits, ecLevel, version, matrix);
            }
            qrCode.MaskPattern = maskPattern;

            // Build the matrix and set it to "qrCode".
            MatrixUtil.buildMatrix(finalBits, ecLevel, version, maskPattern, matrix);
            qrCode.Matrix = matrix;

            return(qrCode);
        }