/// <summary> /// The get error bits. /// </summary> /// <param name="err"> /// The err. /// </param> /// <returns> /// The queue of <c>bools</c>. /// </returns> public static Queue <bool> GetErrorBits(QrError err) { Queue <bool> bits = new Queue <bool>(); switch (err) { case QrError.L: bits.Enqueue(false); bits.Enqueue(true); break; case QrError.M: bits.Enqueue(false); bits.Enqueue(false); break; case QrError.Q: bits.Enqueue(true); bits.Enqueue(true); break; default: bits.Enqueue(true); bits.Enqueue(false); break; } return(bits); }
/// <summary> /// The get error bits. /// </summary> /// <param name="err"> /// The err. /// </param> /// <returns> /// The queue of <c>bools</c>. /// </returns> public static Queue<bool> GetErrorBits(QrError err) { Queue<bool> bits = new Queue<bool>(); switch (err) { case QrError.L: bits.Enqueue(false); bits.Enqueue(true); break; case QrError.M: bits.Enqueue(false); bits.Enqueue(false); break; case QrError.Q: bits.Enqueue(true); bits.Enqueue(true); break; default: bits.Enqueue(true); bits.Enqueue(false); break; } return bits; }
/// <summary> /// Calculate <c>QR</c> code format /// </summary> /// <param name="error"> /// The error code information. /// </param> /// <param name="mask"> /// The mask. /// </param> private void CalculateFormat(QrError error, QrMask mask) { // Get error bits if (this.debugData != null) { this.debugData.Append("- Calculating format bits...\n"); } // Get 5 bits of format information int formatInfo = (QrErrorBits.GetBits(error) << 3) | BinaryExtensions.BinToDec(mask.GetBits()); if (this.debugData != null) { this.debugData.Append( "- Format information error and mask bits: " + BinaryExtensions.BinaryToString(BinaryExtensions.DecToBin(formatInfo)) + "\n"); this.debugData.Append("- Calculating BCH (15,5) code for information bits...\n"); } int bchCode = QrBoseChaudhuriHocquenghem.CalculateBch(formatInfo, QrConst.GenPolyFormat); if (this.debugData != null) { this.debugData.Append( "- BCH (15,5) error code: " + BinaryExtensions.BinaryToString(BinaryExtensions.DecToBin(bchCode)) + "\n"); } // Append BCH code to format info formatInfo = (formatInfo << 10) | bchCode; if (this.debugData != null) { this.debugData.Append( "- Format information with appended BCH: " + BinaryExtensions.BinaryToString(BinaryExtensions.DecToBin(formatInfo)) + "\n"); this.debugData.Append( "- Calculating XOR with format constant: " + BinaryExtensions.BinaryToString(BinaryExtensions.DecToBin(QrConst.ConstFormatXor)) + "\n"); } formatInfo = formatInfo ^ QrConst.ConstFormatXor; if (this.debugData != null) { this.debugData.Append( "- Final format: " + BinaryExtensions.BinaryToString(BinaryExtensions.DecToBin(formatInfo, 15)) + "\n"); } List <bool> formatBits = BinaryExtensions.DecToBin(formatInfo, 15); // Reverse, because our QRCode is inserting backwards formatBits.Reverse(); foreach (bool t in formatBits) { this.output.Enqueue(t); } }
/// <summary> /// Initializes a new instance of the <see cref="QrFormat"/> class. /// </summary> /// <param name="error"> /// The error. /// </param> /// <param name="mask"> /// The mask. /// </param> /// <param name="debug"> /// The debug. /// </param> public QrFormat(QrError error, QrMask mask, bool debug) { if (debug) { this.debugData = new StringBuilder(); } this.CalculateFormat(error, mask); }
/// <summary> /// Method writes format to picture. /// </summary> /// <param name="error"> /// The error code information. /// </param> /// <param name="codeMask"> /// The mask mask information. /// </param> private void WriteFormat(QrError error, QrMask codeMask) { QrFormat format; if (this.debugData != null) { this.debugData.Append("------------------ Step 10 ------------------\n- Writing format ...\n"); format = new QrFormat(error, codeMask, true); this.debugData.Append(format.GetDebugData()); } else { format = new QrFormat(error, codeMask); } List <bool> bits = new List <bool>(format.GetFormatBits().ToArray()); // Write format vertically int y = 0; for (int i = 0; i < bits.Count; i++) { if (this.picture[8, y] == QrPixel.Format) { this.picture[8, y] = bits[i] ? QrPixel.Black : QrPixel.White; } else { y++; i--; } } // Write format horizontally int x = this.picture.GetLength(0) - 1; for (int i = 0; i < bits.Count; i++) { if (this.picture[x, 8] == QrPixel.Format) { this.picture[x, 8] = bits[i] ? QrPixel.Black : QrPixel.White; } else { x--; i--; } } if (this.debugData != null) { this.debugData.Append("- Format successfully written.\n\n"); } }
/// <summary> /// The get bits. /// </summary> /// <param name="err"> /// The err. /// </param> /// <returns> /// The <see cref="int"/>. /// </returns> public static int GetBits(QrError err) { switch (err) { case QrError.L: return 0x01; case QrError.M: return 0x00; case QrError.Q: return 0x03; default: return 0x02; } }
/// <summary> /// The get bits. /// </summary> /// <param name="err"> /// The err. /// </param> /// <returns> /// The <see cref="int"/>. /// </returns> public static int GetBits(QrError err) { switch (err) { case QrError.L: return(0x01); case QrError.M: return(0x00); case QrError.Q: return(0x03); default: return(0x02); } }
/// <summary> /// Initializes a new instance of the <see cref="QrFormat"/> class. /// </summary> /// <param name="error"> /// The error. /// </param> /// <param name="mask"> /// The mask. /// </param> public QrFormat(QrError error, QrMask mask) { this.CalculateFormat(error, mask); }
/// <summary> /// Calculate <c>QR</c> code format /// </summary> /// <param name="error"> /// The error code information. /// </param> /// <param name="mask"> /// The mask. /// </param> private void CalculateFormat(QrError error, QrMask mask) { // Get error bits if (this.debugData != null) { this.debugData.Append("- Calculating format bits...\n"); } // Get 5 bits of format information int formatInfo = (QrErrorBits.GetBits(error) << 3) | BinaryExtensions.BinToDec(mask.GetBits()); if (this.debugData != null) { this.debugData.Append( "- Format information error and mask bits: " + BinaryExtensions.BinaryToString(BinaryExtensions.DecToBin(formatInfo)) + "\n"); this.debugData.Append("- Calculating BCH (15,5) code for information bits...\n"); } int bchCode = QrBoseChaudhuriHocquenghem.CalculateBch(formatInfo, QrConst.GenPolyFormat); if (this.debugData != null) { this.debugData.Append( "- BCH (15,5) error code: " + BinaryExtensions.BinaryToString(BinaryExtensions.DecToBin(bchCode)) + "\n"); } // Append BCH code to format info formatInfo = (formatInfo << 10) | bchCode; if (this.debugData != null) { this.debugData.Append( "- Format information with appended BCH: " + BinaryExtensions.BinaryToString(BinaryExtensions.DecToBin(formatInfo)) + "\n"); this.debugData.Append( "- Calculating XOR with format constant: " + BinaryExtensions.BinaryToString(BinaryExtensions.DecToBin(QrConst.ConstFormatXor)) + "\n"); } formatInfo = formatInfo ^ QrConst.ConstFormatXor; if (this.debugData != null) { this.debugData.Append( "- Final format: " + BinaryExtensions.BinaryToString(BinaryExtensions.DecToBin(formatInfo, 15)) + "\n"); } List<bool> formatBits = BinaryExtensions.DecToBin(formatInfo, 15); // Reverse, because our QRCode is inserting backwards formatBits.Reverse(); foreach (bool t in formatBits) { this.output.Enqueue(t); } }
/// <summary> /// Method writes format to picture. /// </summary> /// <param name="error"> /// The error code information. /// </param> /// <param name="codeMask"> /// The mask mask information. /// </param> private void WriteFormat(QrError error, QrMask codeMask) { QrFormat format; if (this.debugData != null) { this.debugData.Append("------------------ Step 10 ------------------\n- Writing format ...\n"); format = new QrFormat(error, codeMask, true); this.debugData.Append(format.GetDebugData()); } else { format = new QrFormat(error, codeMask); } List<bool> bits = new List<bool>(format.GetFormatBits().ToArray()); // Write format vertically int y = 0; for (int i = 0; i < bits.Count; i++) { if (this.picture[8, y] == QrPixel.Format) { this.picture[8, y] = bits[i] ? QrPixel.Black : QrPixel.White; } else { y++; i--; } } // Write format horizontally int x = this.picture.GetLength(0) - 1; for (int i = 0; i < bits.Count; i++) { if (this.picture[x, 8] == QrPixel.Format) { this.picture[x, 8] = bits[i] ? QrPixel.Black : QrPixel.White; } else { x--; i--; } } if (this.debugData != null) { this.debugData.Append("- Format successfully written.\n\n"); } }
/// <summary> /// Initializes a new instance of the <see cref="QrVersion"/> class. /// </summary> /// <param name="ver"> /// The version. /// </param> /// <param name="error"> /// The error. /// </param> public QrVersion(int ver, QrError error) { // Optimization: Dynamically calculate QR Code version this.Version = ver + 1; this.ErrorLevel = error; // Get maximum matrix size this.MatrixSize = Convert.ToByte(21 + (4 * ver)); // Calculate data and error sizes based on error level // Position squares with separators are each 8x8 pixels, we have 4 of them int maxBytes = (this.MatrixSize * this.MatrixSize) - (8 * 8 * 3); // Format bits are 2 times of 15 bits maxBytes -= 2 * 15; // There is 1 dark pixel in bottom format information. maxBytes--; // Through alignment patterns we cannot place bits // Calculate number of alignment patters byte[] alignments = QrAlignment.GetAlignment(this.Version); int alignmentCount = 7; while (alignments[alignmentCount - 1] == 0) { alignmentCount--; } // Number of alignments, minus three, since three are static position patterns int alignmentNum = (alignmentCount * alignmentCount) - 3; // Each alignment takes 5x5 pixels if (alignmentNum > 0) { maxBytes -= (5 * 5) * alignmentNum; } // Versions higher than 7 have version information added if (this.Version >= 7) { maxBytes -= 2 * 18; } // Still need to remove the timing patterns... // - We already removed the bits in alignments, so not removing them twice if (alignmentCount == 1) { alignmentCount = 2; } maxBytes -= (this.MatrixSize - (2 * 8) - ((alignmentCount - 2) * 5)) * 2; // To get actual bytes maxBytes = maxBytes / 8; // Block sizes and counts this.BlockOneSize = CodeBlocks[(ver * 16) + (((int)error) * 4) + 1]; this.BlockTwoSize = CodeBlocks[(ver * 16) + (((int)error) * 4) + 3]; this.BlockOneCount = CodeBlocks[(ver * 16) + (((int)error) * 4) + 0]; this.BlockTwoCount = CodeBlocks[(ver * 16) + (((int)error) * 4) + 2]; // Amount of data size this.DataSize = (this.BlockOneSize * this.BlockOneCount) + (this.BlockTwoSize * this.BlockTwoCount); // Error size this.ErrorSize = maxBytes - this.DataSize; }