public static isValidMaskPattern ( int maskPattern ) : bool | ||
maskPattern | int | |
return | bool |
/// <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); } }
// 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); }
/// <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); }