/// <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); }
public MicroQRCode() { mode = null; ecLevel = null; version = - 1; matrixWidth = - 1; maskPattern = - 1; numTotalBytes = - 1; numDataBytes = - 1; numECBytes = - 1; numRSBlocks = - 1; matrix = null; }
public MicroQRCode() { mode = null; ecLevel = null; version = -1; matrixWidth = -1; maskPattern = -1; numTotalBytes = -1; numDataBytes = -1; numECBytes = -1; numRSBlocks = -1; matrix = null; }
/// <summary> Append "bytes" in "mode" mode (encoding) into "bits". On success, store the result in "bits".</summary> internal static void appendBytes(System.String content, Mode mode, BitVector bits, System.String encoding, int versionNum) { if (mode.Equals(Mode.NUMERIC)) { appendNumericBytes(content, bits); } else if (mode.Equals(Mode.ALPHANUMERIC) && versionNum >= 2) { appendAlphanumericBytes(content, bits); } else if (mode.Equals(Mode.BYTE) && versionNum >= 3) { append8BitBytes(content, bits, encoding); } else if (mode.Equals(Mode.KANJI) && versionNum >= 3) { appendKanjiBytes(content, bits); } else { throw new WriterException("Invalid mode: " + mode); } }
/// <summary> /// /// </summary> /// <param name="content"></param> /// <param name="ecLevel"></param> /// <param name="hints"></param> /// <param name="qrCode"></param> public static void encode(System.String content, ErrorCorrectionLevel ecLevel, System.Collections.Hashtable hints, MicroQRCode qrCode, int versionNum) { if (versionNum < 1 || versionNum > 4) { throw new ArgumentOutOfRangeException("versionNum", "versionNum [1, 4]"); } System.String encoding = hints == null ? null : (System.String)hints[EncodeHintType.CHARACTER_SET]; if (encoding == null) { encoding = DEFAULT_BYTE_MODE_ENCODING; } // Step 1: Choose the mode (encoding). Mode mode = chooseMode(content, encoding); // Step 2: Append "bytes" into "dataBits" in appropriate encoding. BitVector dataBits = new BitVector(); appendBytes(content, mode, dataBits, encoding, versionNum); // Step 3: Initialize QR code that can contain "dataBits". int numInputBytes = dataBits.sizeInBytes(); initQRCode(numInputBytes, ecLevel, mode, qrCode, versionNum); // Step 4: Build another bit vector that contains header and data. BitVector headerAndDataBits = new BitVector(); //INFO ECB+Mode+Length+Data[+terminate] // Step 4.5: Append ECI message if applicable appendModeInfo(mode, headerAndDataBits, versionNum); int numLetters = mode.Equals(Mode.BYTE) ? dataBits.sizeInBytes() : content.Length; appendLengthInfo(numLetters, qrCode.Version, mode, headerAndDataBits); headerAndDataBits.appendBitVector(dataBits); // Step 5: Terminate the bits properly. terminateBits(qrCode.NumDataBytes, headerAndDataBits, versionNum); // Step 6: Interleave data bits with error correction code. BitVector finalBits = new BitVector(); interleaveWithECBytes(headerAndDataBits, versionNum, qrCode.NumTotalBytes, qrCode.NumDataBytes, qrCode.NumRSBlocks, finalBits); // Step 7: Choose the mask pattern and set to "qrCode". ByteMatrix matrix = new ByteMatrix(qrCode.MatrixWidth, qrCode.MatrixWidth); qrCode.MaskPattern = chooseMaskPattern(finalBits, qrCode.ECLevel, qrCode.Version, matrix); // Step 8. Build the matrix and set it to "qrCode". MatrixUtil.buildMatrix(finalBits, qrCode.ECLevel, qrCode.Version, qrCode.MaskPattern, matrix); qrCode.Matrix = matrix; //var decoder = new com.google.zxing.microqrcode.decoder.Decoder(); //var res = decoder.decode(com.google.zxing.common.BitMatrix.FromByteMatrix(matrix)); //Console.WriteLine(res.Text); // Step 9. Make sure we have a valid QR Code. if (!qrCode.Valid) { throw new WriterException("Invalid QR code: " + qrCode.ToString()); } }
/// <summary> Append mode info. On success, store the result in "bits".</summary> internal static void appendModeInfo(Mode mode, BitVector bits, int versionNum) { bits.appendBits(mode.Bits, mode.getBitsLength(versionNum)); }
/// <summary> Initialize "qrCode" according to "numInputBytes", "ecLevel", and "mode". On success, /// modify "qrCode". /// </summary> private static void initQRCode(int numInputBytes, ErrorCorrectionLevel ecLevel, Mode mode, MicroQRCode qrCode, int versionNum) { qrCode.ECLevel = ecLevel; qrCode.Mode = mode; // In the following comments, we use numbers of Version 7-H. 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) { // 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?)"); }