API documentation cleanup

pull/45/head
manuelbl 7 years ago
parent 383667452c
commit 714de48ee8

@ -1,5 +1,5 @@
/*
* QR Code generator library (.NET)
* QR code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
@ -27,38 +27,39 @@ using System.Collections;
namespace IO.Nayuki.QrCodeGen
{
/// <summary>
/// Provides extension methods for the <see cref="BitArray"/> class.
/// Extension methods for the <see cref="BitArray"/> class.
/// </summary>
public static class BitArrayExtensions
{
/// <summary>
/// Appends the specified number of low-order bits of the specified value to this
/// bit array. Requires 0 &#x2264; len &#x2264; 31 and 0 &#x2264; val &lt; 2<sup>len</sup>.
/// Appends the specified number bits of the specified value to this bit array.
/// <para>
/// The least significant bits of the specified value are added. They are appended in reverse order,
/// from the most significant to the least significant one, i.e. bits 0 to <i>len-1</i>
/// are appended in the order <i>len-1</i>, <i>len-2</i> ... 1, 0.
/// </para>
/// <para>
/// Requires 0 &#x2264; len &#x2264; 31, and 0 &#x2264; val &lt; 2<sup>len</sup>.
/// </para>
/// </summary>
/// <param name="bitArray">this bit array</param>
/// <param name="val">the value to append</param>
/// <param name="len">the number of low-order bits in the value to take</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if the value or number of bits is out of range</exception>
/// <exception cref="InvalidOperationException">Thrown if appending the data would make bit length exceed <see cref="int.MaxValue"/></exception>
/// <param name="bitArray">The BitArray instance that this method extends.</param>
/// <param name="val">The value to append.</param>
/// <param name="len">The number of low-order bits in the value to append.</param>
/// <exception cref="ArgumentOutOfRangeException">Value or number of bits is out of range.</exception>
public static void AppendBits(this BitArray bitArray, uint val, int len)
{
if (len < 0 || len > 31 || (val >> len) != 0)
if (len < 0 || len > 31 || val >> len != 0)
{
throw new ArgumentOutOfRangeException(nameof(len), "'len' out of range");
}
if (len < 0 || len > 31 || (val >> len) != 0)
if (len < 0 || len > 31 || val >> len != 0)
{
throw new ArgumentOutOfRangeException(nameof(val), "'val' out of range");
}
int bitLength = bitArray.Length;
if (int.MaxValue - bitLength < len)
{
throw new InvalidOperationException("Maximum length reached");
}
bitArray.Length = bitLength + len;
uint mask = 1U << (len - 1);
for (int i = bitLength; i < bitLength + len; i++) // Append bit by bit
@ -74,21 +75,15 @@ namespace IO.Nayuki.QrCodeGen
/// <summary>
/// Appends the content of the specified bit array to this array.
/// Appends the content of the specified bit array to the end of this array.
/// </summary>
/// <param name="bitArray">this bit array</param>
/// <param name="otherArray">the bit array whose data to append (not <c>null</c>)</param>
/// <exception cref="ArgumentNullException">Thrown if the bit array is <c>null</c></exception>
/// <exception cref="InvalidOperationException">Thrown if appending the data would make the bit length exceed <see cref="int.MaxValue"/></exception>
/// <param name="bitArray">The BitArray instance that this method extends.</param>
/// <param name="otherArray">The bit array to append</param>
/// <exception cref="ArgumentNullException">If <c>bitArray</c> is <c>null</c>.</exception>
public static void AppendData(this BitArray bitArray, BitArray otherArray)
{
Objects.RequireNonNull(otherArray);
int bitLength = bitArray.Length;
if (int.MaxValue - bitLength < otherArray.Length)
{
throw new InvalidOperationException("Maximum length reached");
}
bitArray.Length = bitLength + otherArray.Length;
for (int i = 0; i < otherArray.Length; i++, bitLength++) // Append bit by bit
{

@ -1,5 +1,5 @@
/*
* QR Code generator library (.NET)
* QR code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
@ -26,31 +26,34 @@ using System.Collections.Generic;
namespace IO.Nayuki.QrCodeGen
{
/// <summary>
/// Thrown when the supplied data does not fit any QR Code version.
/// The exception that is thrown when the supplied data does not fit in the QR code.
/// </summary>
/// <remarks>
/// Ways to handle this exception include:
/// <ul>
/// <li>Decrease the error correction level if it was greater than <see cref="QrCode.Ecc.Low"/></li>
/// <li><p>If the advanced <see cref=QrCode.EncodeSegments(List{QrSegment}, QrCode.Ecc, int, int, int, bool)"/>
/// function or the <see cref="QrSegmentAdvanced.MakeSegmentsOptimally(string, QrCode.Ecc, int, int)"/> function was called,
/// then increase the maxVersion argument if it was less than <see cref="QrCode.MaxVersion"/>.
/// (This advice does not apply to the other factory functions because they search all versions up to
/// <see cref="QrCode.MaxVersion"/></li>
/// <li>Split the text data into better or optimal segments in order to reduce the number of bits required.
/// (See <see cref="QrSegmentAdvanced.MakeSegmentsOptimally(string, QrCode.Ecc, int, int)"/>.)</li>
/// <li>Change the text or binary data to be shorter.</li>
/// <li>Decrease the error correction level (if it was greater than <see cref="QrCode.Ecc.Low"/>)</li>
/// <li>Increase the <c>maxVersion</c> argument (if it was less than <see cref="QrCode.MaxVersion"/>).
/// This advice applies to the advanced factory functions
/// <see cref="QrCode.EncodeSegments"/> and
/// <see cref="QrSegmentAdvanced.MakeSegmentsOptimally(string, QrCode.Ecc, int, int)"/> only.
/// Other factory functions automatically try all versions up to <see cref="QrCode.MaxVersion"/>.</li>
/// <li>Split the text into several segments and encode them using different encoding modes
/// (see <see cref="QrSegmentAdvanced.MakeSegmentsOptimally(string, QrCode.Ecc, int, int)"/>.)</li>
/// <li>Make the text or binary data shorter.</li>
/// <li>Change the text to fit the character set of a particular segment mode (e.g. alphanumeric).</li>
/// <li>Propagate the error upward to the caller/user.</li>
/// <li>Reject the data and notify the caller/user.</li>
/// </ul>
/// </remarks>
/// <seealso cref="QrCode.EncodeText(string, QrCode.Ecc)"/>
/// <seealso cref="QrCode.EncodeBinary(byte[], QrCode.Ecc)"/>
/// <seealso cref="QrCode.EncodeSegments(List{QrSegment}, QrCode.Ecc)"/>
/// <seealso cref="QrCode.EncodeSegments(List{QrSegment}, QrCode.Ecc, int, int, int, bool)"/>
/// <seealso cref="QrSegmentAdvanced.MakeSegmentsOptimally(string, QrCode.Ecc, int, int)"/>
public class DataTooLongException : ArgumentException
{
/// <summary>
/// Initializes a new instance of the <see cref="DataTooLongException"/> class.
/// </summary>
/// <param name="message">The message that describes the error.</param>
public DataTooLongException(string message)
: base(message)
{ }

@ -1,5 +1,5 @@
/*
* QR Code generator library (.NET)
* QR code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
@ -25,8 +25,21 @@ using System;
namespace IO.Nayuki.QrCodeGen
{
/// <summary>
/// Helper functions to check for valid arguments.
/// </summary>
internal class Objects
{
/// <summary>
/// Ensures that the specified argument is <i>not null</i>.
/// <para>
/// Throws a <see cref="ArgumentNullException"/> exception if the argument is <c>null</c>.
/// </para>
/// </summary>
/// <typeparam name="T">The type of the argument.</typeparam>
/// <param name="arg">The argument to check.</param>
/// <returns>Argument passed to function.</returns>
/// <exception cref="ArgumentNullException">The specified argument is <c>null</c>.</exception>
internal static T RequireNonNull<T>(T arg)
{
if (arg == null)

@ -1,5 +1,5 @@
/*
* QR Code generator library (.NET)
* QR code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
@ -33,26 +33,35 @@ using System.Text;
namespace IO.Nayuki.QrCodeGen
{
/// <summary>
/// A QR Code symbol, which is a type of two-dimension barcode.
/// Represents a QR code containing text or binary data.
/// <para>
/// Instances of this class represent an immutable square grid of black and white pixels
/// (called <i>modules</i> by the QR code specification).
/// Static factory methods are provided to create QR codes from text or binary data.
/// Some of the methods provide detailed control about the encoding parameters such a QR
/// code size (called <i>version</i> by the standard), error correction level and mask.
/// </para>
/// <para>
/// QR codes are a type of two-dimensional barcodes, invented by Denso Wave and
/// described in the ISO/IEC 18004 standard.
/// </para>
/// <para>
/// This class covers the QR Code Model 2 specification, supporting all versions (sizes)
/// from 1 to 40, all 4 error correction levels, and 4 character encoding modes.</para>
/// </summary>
/// <remarks>
/// <para>Invented by Denso Wave and described in the ISO/IEC 18004 standard.</para>
/// <para>araInstances of this class represent an immutable square grid of black and white cells.
/// The class provides static factory functions to create a QR Code from text or binary data.
/// The class covers the QR Code Model 2 specification, supporting all versions (sizes)
/// from 1 to 40, all 4 error correction levels, and 4 character encoding modes.</para>
/// <para>Ways to create a QR Code object:</para>
/// <para>
/// To create a QR code instance:
/// </para>
/// <ul>
/// <li>High level: Take the payload data and call <see cref="EncodeText(string, Ecc)"/>
/// or <see cref="EncodeBinary(byte[], Ecc)"/>.</li>
/// <li>Mid level: Custom-make the list of <see cref="QrSegment"/>
/// and call <see cref="EncodeSegments(List{QrSegment}, Ecc)"/> or
/// <see cref="EncodeSegments(List{QrSegment}, Ecc, int, int, int, bool)"/></li>
/// <li>Low level: Custom-make the array of data codeword bytes (including segment headers and
/// <li>Mid level: Custom-make a list of <see cref="QrSegment"/> instances and call
/// <see cref="EncodeSegments"/></li>
/// <li>Low level: Custom-make an array of data codeword bytes (including segment headers and
/// final padding, excluding error correction codewords), supply the appropriate version number,
/// and call the <see cref="QrCode(int, Ecc, byte[], int)"/>.</li>
/// </ul>
/// <para>(Note that all ways require supplying the desired error correction level.)</para>
/// </remarks>
/// <seealso cref="QrSegment"/>
public class QrCode
@ -60,20 +69,20 @@ namespace IO.Nayuki.QrCodeGen
#region Static factory functions (high level)
/// <summary>
/// Returns a QR Code representing the specified Unicode text string at the specified error correction level.
/// </summary>
/// <remarks>
/// As a conservative upper bound, this function is guaranteed to succeed for strings that have 738 or fewer
/// Creates a QR code representing the specified text using the specified error correction level.
/// <para>
/// As a conservative upper bound, this function is guaranteed to succeed for strings with up to 738
/// Unicode code points (not UTF-16 code units) if the low error correction level is used. The smallest possible
/// QR Code version is automatically chosen for the output.The ECC level of the result may be higher than the
/// ecl argument if it can be done without increasing the version.
/// </remarks>
/// <param name="text">the text to be encoded (not <c>null</c>), which can be any Unicode string</param>
/// <param name="ecl">the error correction level to use (not <c>null</c>) (boostable)</param>
/// <returns>a QR Code (not <c>null</c>) representing the text</returns>
/// <exception cref="ArgumentNullException">Thrown if the text or error correction level is <c>null</c></exception>
/// <exception cref="DataTooLongException">Thrown if the text fails to fit in the
/// largest version QR Code at the ECL, which means it is too long</exception>
/// QR code version (size) is automatically chosen. The resulting ECC level will be higher than the one
/// specified if it can be achieved without increasing the size (version).
/// </para>
/// </summary>
/// <param name="text">The text to be encoded. The full range of Unicode characters may be used.</param>
/// <param name="ecl">The minimum error correction level to use.</param>
/// <returns>The created QR code instance representing the specified text.</returns>
/// <exception cref="ArgumentNullException"><paramref name="text"/> or <paramref name="ecl"/> is <c>null</c>.</exception>
/// <exception cref="DataTooLongException">The text is too long to fit in the largest QR code size (version)
/// at the specified error correction level.</exception>
public static QrCode EncodeText(string text, Ecc ecl)
{
Objects.RequireNonNull(text);
@ -83,19 +92,19 @@ namespace IO.Nayuki.QrCodeGen
}
/// <summary>
/// Returns a QR Code representing the specified binary data at the specified error correction level.
/// Creates a QR code representing the specified binary data using the specified error correction level.
/// <para>
/// This function encodes the data in the binary segment mode. The maximum number of
/// bytes allowed is 2953. The smallest possible QR code version is automatically chosen.
/// The resulting ECC level will be higher than the one specified if it can be achieved without increasing the size (version).
/// </para>
/// </summary>
/// <remarks>
/// This function always encodes using the binary segment mode, not any text mode. The maximum number of
/// bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.
/// The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version.
/// </remarks>
/// <param name="data">the binary data to encode (not <c>null</c>)</param>
/// <param name="ecl">the error correction level to use (not <c>null</c>) (boostable)</param>
/// <returns>a QR Code (not <c>null</c>) representing the data</returns>
/// <exception cref="ArgumentNullException">Thrown if the data or error correction level is <c>null</c></exception>
/// <exception cref="DataTooLongException">Thrown if the data fails to fit in the
/// largest version QR Code at the ECL, which means it is too long</exception>
/// <param name="data">The binary data to encode.</param>
/// <param name="ecl">The minimum error correction level to use.</param>
/// <returns>The created QR code representing the specified data.</returns>
/// <exception cref="ArgumentNullException"><paramref name="data"/> or <paramref name="ecl"/> is <c>null</c>.</exception>
/// <exception cref="DataTooLongException">The specified data is too long to fit in the largest QR code size (version)
/// at the specified error correction level.</exception>
public static QrCode EncodeBinary(byte[] data, Ecc ecl)
{
Objects.RequireNonNull(data);
@ -110,56 +119,44 @@ namespace IO.Nayuki.QrCodeGen
#region Static factory functions (mid level)
/// <summary>
/// Returns a QR Code representing the specified segments at the specified error correction level.
/// Creates a QR code representing the specified segments with the specified encoding parameters.
/// <para>
/// The smallest possible QR code version (size) is used. The range of versions can be
/// restricted by the <paramref name="minVersion"/> and <paramref name="maxVersion"/> parameters.
/// </para>
/// <para>
/// If <paramref name="boostEcl"/> is <c>true</c>, the resulting ECC level will be higher than the
/// one specified if it can be achieved without increasing the size (version).
/// </para>
/// <para>
/// The QR code mask is usually automatically chosen. It can be explicitly set with the <paramref name="mask"/>
/// parameter by using a value between 0 to 7 (inclusive). -1 is for automatic mode (which may be slow).
/// </para>
/// <para>
/// This function allows the user to create a custom sequence of segments that switches
/// between modes (such as alphanumeric and byte) to encode text in less space and gives full control over all
/// encoding paramters.
/// </para>
/// </summary>
/// <remarks>
/// <para>The smallest possible QR Code version is automatically chosen for the output. The ECC level
/// of the result may be higher than the ecl argument if it can be done without increasing the version. </para>
/// <para>This function allows the user to create a custom sequence of segments that switches
/// between modes (such as alphanumeric and byte) to encode text in less space.</para>
/// <para>This is a mid-level API; the high-level API is <see cref="EncodeText(string, Ecc)"/>
/// and <see cref="EncodeBinary(byte[], Ecc)"/></para>
/// This is a mid-level API; the high-level APIs are <see cref="EncodeText(string, Ecc)"/>
/// and <see cref="EncodeBinary(byte[], Ecc)"/>.
/// </remarks>
/// <param name="segs">the segments to encode</param>
/// <param name="ecl">the error correction level to use (not <c>null</c>) (boostable)</param>
/// <returns>a QR Code (not <c>null</c>) representing the segments</returns>
/// <exception cref="ArgumentNullException">Thrown if the data or error correction level is <c>null</c></exception>
/// <exception cref="DataTooLongException">Thrown if the segments fail to fit in the
/// largest version QR Code at the ECL, which means it is too long</exception>
public static QrCode EncodeSegments(List<QrSegment> segs, Ecc ecl)
{
return EncodeSegments(segs, ecl, MinVersion, MaxVersion, -1, true);
}
/// <summary>
/// Returns a QR Code representing the specified segments with the specified encoding parameters.
/// </summary>
/// <remarks>
/// <para>The smallest possible QR Code version within the specified range is automatically
/// chosen for the output. Iff boostEcl is <c>true</c>, then the ECC level of the
/// result may be higher than the ecl argument if it can be done without increasing
/// the version. The mask number is either between 0 to 7 (inclusive) to force that
/// mask, or &#x2212;1 to automatically choose an appropriate mask (which may be slow).</para>
/// <para>This function allows the user to create a custom sequence of segments that switches
/// between modes (such as alphanumeric and byte) to encode text in less space.
/// This is a mid-level API; the high-level API is <see cref="EncodeText(string, Ecc)"/>
/// and <see cref="EncodeBinary(byte[], Ecc)"/>.</para>
/// </remarks>
/// <param name="segs">the segments to encode</param>
/// <param name="ecl">the error correction level to use (not <c>null</c>) (boostable)</param>
/// <param name="minVersion">the minimum allowed version of the QR Code (at least 1)</param>
/// <param name="maxVersion">the maximum allowed version of the QR Code (at most 40)</param>
/// <param name="mask">the mask number to use (between 0 and 7 (inclusive)), or &#x2212;1 for automatic mask</param>
/// <param name="boostEcl">increases the ECC level as long as it doesn't increase the version number</param>
/// <returns>a QR Code (not <c>null</c>) representing the segments</returns>
/// <exception cref="ArgumentNullException">Thrown if the list of segments, any segment, or the error correction level is <c>null</c></exception>
/// <exception cref="ArgumentOutOfRangeException">Thrown if 1 &#x2264; minVersion &#x2264; maxVersion &#x2264; 40
/// or &#x2212;1 &#x2264; mask &#x2264; 7 is violated</exception>
/// <exception cref="DataTooLongException">Thrown DataTooLongException if the segments fail to fit in
/// the maxVersion QR Code at the ECL, which means they are too long</exception>
public static QrCode EncodeSegments(List<QrSegment> segs, Ecc ecl, int minVersion, int maxVersion, int mask, bool boostEcl)
{
Objects.RequireNonNull(segs);
/// <param name="segments">The segments to encode.</param>
/// <param name="ecl">The minimal or fixed error correction level to use .</param>
/// <param name="minVersion">The minimum version (size) of the QR code (between 1 and 40).</param>
/// <param name="maxVersion">The maximum version (size) of the QR code (between 1 and 40).</param>
/// <param name="mask">The mask number to use (between 0 and 7), or -1 for automatic mask selection.</param>
/// <param name="boostEcl">If <c>true</c> the ECC level wil be increased if it can be achieved without increasing the size (version).</param>
/// <returns>The created QR code representing the segments.</returns>
/// <exception cref="ArgumentNullException"><paramref name="segments"/>, any list element, or <paramref name="ecl"/> is <c>null</c>.</exception>
/// <exception cref="ArgumentOutOfRangeException">1 &#x2264; minVersion &#x2264; maxVersion &#x2264; 40
/// or -1 &#x2264; mask &#x2264; 7 is violated.</exception>
/// <exception cref="DataTooLongException">The segments are too long to fit in the largest QR code size (version)
/// at the specified error correction level.</exception>
public static QrCode EncodeSegments(List<QrSegment> segments, Ecc ecl, int minVersion = MinVersion, int maxVersion = MaxVersion, int mask = -1, bool boostEcl = true)
{
Objects.RequireNonNull(segments);
Objects.RequireNonNull(ecl);
if (minVersion < MinVersion || minVersion > maxVersion)
{
@ -179,7 +176,7 @@ namespace IO.Nayuki.QrCodeGen
for (version = minVersion; ; version++)
{
int numDataBits = GetNumDataCodewords(version, ecl) * 8; // Number of data bits available
dataUsedBits = QrSegment.GetTotalBits(segs, version);
dataUsedBits = QrSegment.GetTotalBits(segments, version);
if (dataUsedBits != -1 && dataUsedBits <= numDataBits)
{
break; // This version number is found to be suitable
@ -209,7 +206,7 @@ namespace IO.Nayuki.QrCodeGen
// Concatenate all segments to create the data bit string
BitArray ba = new BitArray(0);
foreach (QrSegment seg in segs)
foreach (QrSegment seg in segments)
{
ba.AppendBits(seg.EncodingMode.ModeBits, 4);
ba.AppendBits((uint)seg.NumChars, seg.EncodingMode.NumCharCountBits(version));
@ -240,7 +237,7 @@ namespace IO.Nayuki.QrCodeGen
}
}
// Create the QR Code object
// Create the QR code object
return new QrCode(version, ecl, dataCodewords, mask);
}
@ -250,28 +247,33 @@ namespace IO.Nayuki.QrCodeGen
#region Public immutable properties
/// <summary>
/// The version number of this QR Code, which is between 1 and 40 (inclusive).
/// This determines the size of this barcode.
/// The version (size) of this QR code (between 1 for the smallest and 40 for the biggest).
/// </summary>
/// <value>The QR code version (size).</value>
public int Version { get; }
/// <summary>
/// The width and height of this QR Code, measured in modules, between
/// 21 and 177 (inclusive). This is equal to version &#xD7; 4 + 17.
/// The width and height of this QR code, in modules (pixels).
/// The size is a value between 21 and 177.
/// This is equal to version &#xD7; 4 + 17.
/// </summary>
/// <value>The QR code size.</value>
public int Size { get; }
/// <summary>
/// The error correction level used in this QR Code, which is not <c>null</c>.
/// The error correction level used for this QR code.
/// </summary>
/// <value>The error correction level.</value>
public Ecc ErrorCorrectionLevel { get; }
/// <summary>
/// The index of the mask pattern used in this QR Code, which is between 0 and 7 (inclusive).
/// The index of the mask pattern used fort this QR code (between 0 and 7).
/// <para>
/// Even if a QR code is created with automatic mask selection (<c>mask</c> = 1),
/// this property returns the effective mask used.
/// </para>
/// </summary>
/// <remarks>Even if a QR Code is created with automatic masking requested (mask =
/// &#x2212;1), the resulting object still has a mask value between 0 and 7.
/// </remarks>
/// <value>The mask pattern index.</value>
public int Mask { get; }
#endregion
@ -279,8 +281,8 @@ namespace IO.Nayuki.QrCodeGen
#region Private grids of modules/pixels, with dimensions of size * size
// The modules of this QR Code (false = white, true = black).
// Immutable after constructor finishes. Accessed through getModule().
// The modules of this QR code (false = white, true = black).
// Immutable after constructor finishes. Accessed through GetModule().
private readonly bool[,] _modules;
// Indicates function modules that are not subjected to masking. Discarded when constructor finishes.
@ -292,26 +294,26 @@ namespace IO.Nayuki.QrCodeGen
#region Constructor (low level)
/// <summary>
/// Constructs a QR Code with the specified version number,
/// Constructs a QR code with the specified version number,
/// error correction level, data codeword bytes, and mask number.
/// </summary>
/// <remarks>
/// This is a low-level API that most users should not use directly. A mid-level
/// API is the <see cref="EncodeSegments(List{QrSegment}, Ecc, int, int, int, bool)"/> function.
/// API is the <see cref="EncodeSegments"/> function.
/// </remarks>
/// <param name="ver">the version number to use, which must be in the range 1 to 40 (inclusive)</param>
/// <param name="ecl">the error correction level to use</param>
/// <param name="dataCodewords">the bytes representing segments to encode (without ECC)</param>
/// <param name="mask">the mask pattern to use, which is either &#x2212;1 for automatic choice or from 0 to 7 for fixed choice</param>
/// <exception cref="ArgumentNullException">Thrown if the byte array or error correction level is <c>null</c></exception>
/// <exception cref="ArgumentOutOfRangeException">Thrown if the version or mask value is out of range,
/// or if the data is the wrong length for the specified version and error correction level</exception>
public QrCode(int ver, Ecc ecl, byte[] dataCodewords, int mask)
/// <param name="version">The version (size) to use (between 1 to 40).</param>
/// <param name="ecl">The error correction level to use.</param>
/// <param name="dataCodewords">The bytes representing segments to encode (without ECC).</param>
/// <param name="mask">The mask pattern to use (either -1 for automatic selection, or a value from 0 to 7 for fixed choice).</param>
/// <exception cref="ArgumentNullException"><paramref name="ecl"/> or <paramref name="dataCodewords"/> is <c>null</c>.</exception>
/// <exception cref="ArgumentOutOfRangeException">The version or mask value is out of range,
/// or the data has an invalid length for the specified version and error correction level.</exception>
public QrCode(int version, Ecc ecl, byte[] dataCodewords, int mask = -1)
{
// Check arguments and initialize fields
if (ver < MinVersion || ver > MaxVersion)
if (version < MinVersion || version > MaxVersion)
{
throw new ArgumentOutOfRangeException(nameof(ver), "Version value out of range");
throw new ArgumentOutOfRangeException(nameof(version), "Version value out of range");
}
if (mask < -1 || mask > 7)
@ -319,8 +321,8 @@ namespace IO.Nayuki.QrCodeGen
throw new ArgumentOutOfRangeException(nameof(mask), "Mask value out of range");
}
Version = ver;
Size = ver * 4 + 17;
Version = version;
Size = version * 4 + 17;
Objects.RequireNonNull(ecl);
ErrorCorrectionLevel = ecl;
Objects.RequireNonNull(dataCodewords);
@ -342,18 +344,19 @@ namespace IO.Nayuki.QrCodeGen
#region Public methods
/// <summary>
/// Returns the color of the module (pixel) at the specified coordinates, which is <c>false</c>
/// for white or <c>true</c> for black.
/// Gets the color of the module (pixel) at the specified coordinates.
/// <para>
/// The top left corner has the coordinates (x=0, y=0). <i>x</i>-coordinates extend from left to right,
/// <i>y</i>-coordinates extend from top to bottom.
/// </para>
/// <para>
/// If coordinates outside the bounds of this QR code are specified, white (<c>false</c>) is returned.
/// </para>
/// </summary>
/// <remarks>
/// The top left corner has the coordinates (x=0, y=0).
/// If the specified coordinates are out of bounds, then <c>false</c>
/// (white) is returned.
/// </remarks>
/// <param name="x">the x coordinate, where 0 is the left edge and size&#x2212;1 is the right edge</param>
/// <param name="y">the y coordinate, where 0 is the top edge and size&#x2212;1 is the bottom edge</param>
/// <returns><c>true</c> if the coordinates are in bounds and the module
/// at that location is black, or <c>false</c> (white) otherwise</returns>
/// <param name="x">The x coordinate.</param>
/// <param name="y">The y coordinate.</param>
/// <returns>The color of the specified module: <c>true</c> for black modules and <c>false</c>
/// for white modules (or if the coordinates are outside the bounds).</returns>
public bool GetModule(int x, int y)
{
return 0 <= x && x < Size && 0 <= y && y < Size && _modules[y, x];
@ -361,18 +364,26 @@ namespace IO.Nayuki.QrCodeGen
/// <summary>
/// Returns a bitmap (raster image) depicting this QR Code, with the specified module scale and border modules.
/// </summary>
/// <remarks>
/// For example, <c>ToBitmap(scale: 10, border: 4)</c> means to pad the QR Code with 4 white
/// Creates a bitmap (raster image) of this QR code.
/// <para>
/// The <paramref name="scale"/> parameter specifies the scale of the image, which is
/// equivalent to the width and height of each QR code module. Additionally, the number
/// of modules to add as a border to all four sides can be specified.
/// </para>
/// <para>
/// For example, <c>ToBitmap(scale: 10, border: 4)</c> means to pad the QR code with 4 white
/// border modules on all four sides, and use 10&#xD7;10 pixels to represent each module.
/// The resulting image only contains the hex colors 000000 and FFFFFF.
/// </remarks>
/// <param name="scale">the side length (measured in pixels, must be positive) of each module</param>
/// <param name="border">the number of border modules to add, which must be non-negative</param>
/// <returns>a new image representing this QR Code, with padding and scaling</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown if the scale is 0 or negative, if the border is negative
/// or if the resulting image is wider than 32,768 pixels</exception>
/// </para>
/// <para>
/// The resulting bitmap uses the pixel format <see cref="PixelFormat.Format24bppRgb"/> and
/// only contains black (0x000000) and white (0xFFFFFF) pixels.
/// </para>
/// </summary>
/// <param name="scale">The width and height, in pixels, of each module.</param>
/// <param name="border">The number of border modules to add to each of the four sides.</param>
/// <returns>The created bitmap representing this QR code.</returns>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="scale"/> is 0 or negative, <paramref name="border"/> is negative
/// or the resulting image is wider than 32,768 pixels.</exception>
public Bitmap ToBitmap(int scale, int border)
{
if (scale <= 0)
@ -408,14 +419,14 @@ namespace IO.Nayuki.QrCodeGen
/// <summary>
/// Returns a string of SVG code for an image depicting this QR Code, with the specified number of border modules.
/// Creates an SVG image of this QR code.
/// <para>
/// The images uses Unix newlines (\n), regardless of the platform.
/// </para>
/// </summary>
/// <remarks>
/// The string always uses Unix newlines (\n), regardless of the platform.
/// </remarks>
/// <param name="border">the number of border modules to add, which must be non-negative</param>
/// <returns>a string representing this QR Code as an SVG XML document</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown if the border is negative</exception>
/// <param name="border">The number of border modules to add on all four sides.</param>
/// <returns>The created SVG XML document of this QR code as a string.</returns>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="border"/> is negative.</exception>
public string ToSvgString(int border)
{
if (border < 0)
@ -424,25 +435,24 @@ namespace IO.Nayuki.QrCodeGen
}
int dim = Size + border * 2;
var sb = new StringBuilder()
StringBuilder sb = new StringBuilder()
.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
.Append("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n")
.Append($"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 {dim} {dim}\" stroke=\"none\">\n")
.Append("\t<rect width=\"100%\" height=\"100%\" fill=\"#FFFFFF\"/>\n")
.Append("\t<path d=\"");
for (var y = 0; y < Size; y++)
{
for (var x = 0; x < Size; x++)
for (int y = 0; y < Size; y++)
{
if (GetModule(x, y))
for (int x = 0; x < Size; x++)
{
if (!GetModule(x, y)) continue;
if (x != 0 || y != 0)
sb.Append(" ");
sb.Append($"M{x + border},{y + border}h1v1h-1z");
}
}
}
return sb
.Append("\" fill=\"#000000\"/>\n")
@ -660,7 +670,7 @@ namespace IO.Nayuki.QrCodeGen
// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire
// data area of this QR Code. Function modules need to be marked off before this is called.
// data area of this QR code. Function modules need to be marked off before this is called.
private void DrawCodewords(byte[] data)
{
Objects.RequireNonNull(data);
@ -689,10 +699,10 @@ namespace IO.Nayuki.QrCodeGen
int y = upward ? Size - 1 - vert : vert; // Actual y coordinate
if (!_isFunction[y, x] && i < data.Length * 8)
{
_modules[y, x] = GetBit(data[((uint)i) >> 3], 7 - (i & 7));
_modules[y, x] = GetBit(data[(uint)i >> 3], 7 - (i & 7));
i++;
}
// If this QR Code has any remainder bits (0 to 7), they were assigned as
// If this QR code has any remainder bits (0 to 7), they were assigned as
// 0/false/white by the constructor and are left unchanged by this method
}
}
@ -701,11 +711,11 @@ namespace IO.Nayuki.QrCodeGen
}
// XORs the codeword modules in this QR Code with the given mask pattern.
// XORs the codeword modules in this QR code with the given mask pattern.
// The function modules must be marked and the codeword bits must be drawn
// before masking. Due to the arithmetic of XOR, calling applyMask() with
// the same mask value a second time will undo the mask. A final well-formed
// QR Code needs exactly one (not zero, two, etc.) mask applied.
// QR code needs exactly one (not zero, two, etc.) mask applied.
private void ApplyMask(uint mask)
{
if (mask > 7)
@ -736,7 +746,7 @@ namespace IO.Nayuki.QrCodeGen
}
// A messy helper function for the constructor. This QR Code must be in an unmasked state when this
// A messy helper function for the constructor. This QR code must be in an unmasked state when this
// method is called. The given argument is the requested mask, which is -1 for auto or 0 to 7 for fixed.
// This method applies and returns the actual mask chosen, from 0 to 7.
private int HandleConstructorMasking(int mask)
@ -765,7 +775,7 @@ namespace IO.Nayuki.QrCodeGen
}
// Calculates and returns the penalty score based on state of this QR Code's current modules.
// Calculates and returns the penalty score based on state of this QR code's current modules.
// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
private int GetPenaltyScore()
{
@ -932,7 +942,7 @@ namespace IO.Nayuki.QrCodeGen
}
}
// Returns the number of data bits that can be stored in a QR Code of the given version number, after
// Returns the number of data bits that can be stored in a QR code of the given version number, after
// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
private static int GetNumRawDataModules(int ver)
@ -943,13 +953,14 @@ namespace IO.Nayuki.QrCodeGen
}
int size = ver * 4 + 17;
int result = size * size; // Number of modules in the whole QR Code square
int result = size * size; // Number of modules in the whole QR code square
result -= 8 * 8 * 3; // Subtract the three finders with separators
result -= 15 * 2 + 1; // Subtract the format information and black module
result -= (size - 16) * 2; // Subtract the timing patterns (excluding finders)
// The five lines above are equivalent to: int result = (16 * ver + 128) * ver + 64;
if (ver >= 2)
{
if (ver < 2) return result;
int numAlign = ver / 7 + 2;
result -= (numAlign - 1) * (numAlign - 1) * 25; // Subtract alignment patterns not overlapping with timing patterns
result -= (numAlign - 2) * 2 * 20; // Subtract alignment patterns that overlap with timing patterns
@ -958,13 +969,12 @@ namespace IO.Nayuki.QrCodeGen
{
result -= 6 * 3 * 2; // Subtract version information
}
}
return result;
}
// Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
// QR Code of the given version number and error correction level, with remainder bits discarded.
// QR code of the given version number and error correction level, with remainder bits discarded.
// This stateless pure function could be implemented as a (40*4)-cell lookup table.
internal static int GetNumDataCodewords(int ver, Ecc ecl)
{
@ -1022,21 +1032,23 @@ namespace IO.Nayuki.QrCodeGen
#region Constants and tables
/// <summary>
/// The minimum version number (1) supported in the QR Code Model 2 standard.
/// The minimum version (size) supported in the QR Code Model 2 standard namely 1.
/// </summary>
public static readonly int MinVersion = 1;
/// <value>The minimum version.</value>
public const int MinVersion = 1;
/// <summary>
/// The maximum version number (40) supported in the QR Code Model 2 standard.
/// The maximum version (size) supported in the QR Code Model 2 standard namely 40.
/// </summary>
public static readonly int MaxVersion = 40;
/// <value>The maximum version.</value>
public const int MaxVersion = 40;
// For use in getPenaltyScore(), when evaluating which mask is best.
private static readonly int PenaltyN1 = 3;
private static readonly int PenaltyN2 = 3;
private static readonly int PenaltyN3 = 40;
private static readonly int PenaltyN4 = 10;
private const int PenaltyN1 = 3;
private const int PenaltyN2 = 3;
private const int PenaltyN3 = 40;
private const int PenaltyN4 = 10;
private static readonly byte[,] EccCodewordsPerBlock = {
@ -1063,28 +1075,32 @@ namespace IO.Nayuki.QrCodeGen
#region Public helper enumeration
/// <summary>
/// The error correction level in a QR Code symbol.
/// Error correction level in QR code symbol.
/// </summary>
public sealed class Ecc
{
/// <summary>
/// The QR Code can tolerate about 7% erroneous codewords.
/// Low error correction level. The QR code can tolerate about 7% erroneous codewords.
/// </summary>
/// <value>Low error correction level.</value>
public static readonly Ecc Low = new Ecc(0, 1);
/// <summary>
/// The QR Code can tolerate about 15% erroneous codewords.
/// Medium error correction level. The QR code can tolerate about 15% erroneous codewords.
/// </summary>
/// <value>Medium error correction level.</value>
public static readonly Ecc Medium = new Ecc(1, 0);
/// <summary>
/// The QR Code can tolerate about 25% erroneous codewords.
/// Quartile error correction level. The QR code can tolerate about 25% erroneous codewords.
/// </summary>
/// <value>Quartile error correction level.</value>
public static readonly Ecc Quartile = new Ecc(2, 3);
/// <summary>
/// The QR Code can tolerate about 30% erroneous codewords.
/// High error correction level. The QR code can tolerate about 30% erroneous codewords.
/// </summary>
/// <value>High error correction level.</value>
public static readonly Ecc High = new Ecc(3, 2);
@ -1096,6 +1112,7 @@ namespace IO.Nayuki.QrCodeGen
/// <remarks>
/// Higher number represent a higher amount of error tolerance.
/// </remarks>
/// <value>Ordinal number.</value>
public int Ordinal { get; }
// In the range 0 to 3 (unsigned 2-bit integer).

@ -1,5 +1,5 @@
/*
* QR Code generator library (.NET)
* QR code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
@ -31,35 +31,45 @@ using System.Text.RegularExpressions;
namespace IO.Nayuki.QrCodeGen
{
/// <summary>
/// A segment of character/binary/control data in a QR Code symbol.
/// Represents a segment of character/binary/control data in a QR code symbol.
/// </summary>
/// <remarks>
/// <para>Instances of this class are immutable.</para>
/// <para>The mid-level way to create a segment is to take the payload data and call a
/// static factory function such as <see cref="MakeNumeric(string)"/>. The low-level
/// way to create a segment is to custom-make the bit buffer and call the
/// <see cref="QrSegment(Mode, int, BitArray)"/> with appropriate values.</para>
/// <para>This segment class imposes no length restrictions, but QR Codes have restrictions.
/// Even in the most favorable conditions, a QR Code can only hold 7089 characters of data.
/// Any segment longer than this is meaningless for the purpose of generating QR Codes.
/// <para>
/// The easiest way to deal with QR code segments is to call
/// <see cref="QrCode.EncodeText"/> or <see cref="QrCode.EncodeBinary"/>, and not
/// to use instances of this class directly. The mid-level way is to take the payload
/// data and call a static factory function such as <see cref="MakeNumeric(string)"/>.
/// The low-level way is to custom-make the bit array and call the
/// <see cref="QrSegment(Mode, int, BitArray)"/> constructor with appropriate values.
/// </para>
/// <para>
/// This segment class imposes no length restrictions, but QR codes have restrictions.
/// Even in the most favorable conditions, a QR code can only hold 7089 characters of data.
/// Any segment longer than this is meaningless for the purpose of generating QR codes.
/// </para>
/// <para>
/// This class can represent kanji mode segments, but provides no help in encoding them
/// - see <see cref="QrSegmentAdvanced"/> for full kanji support.</para>
/// - see <see cref="QrSegmentAdvanced"/> for full kanji support.
/// </para>
/// <para>
/// Instances of this class are immutable.
/// </para>
/// </remarks>
public class QrSegment
{
#region Static factory functions (mid level)
/// <summary>
/// Returns a segment representing the specified binary data
/// Creates a segment representing the specified binary data
/// encoded in byte mode. All input byte arrays are acceptable.
/// </summary>
/// <remarks>
/// Any text string can be converted to UTF-8 bytes (<c>Encoding.UTF8.GetBytes(s)</c>)
/// <para>
/// Any text string can be converted to UTF-8 bytes (using <c>Encoding.UTF8.GetBytes(str)</c>)
/// and encoded as a byte mode segment.
/// </remarks>
/// <param name="data">the binary data (not <c>null</c>)</param>
/// <returns>a segment (not <c>null</c>) containing the data</returns>
/// <exception cref="ArgumentNullException">Thrown if the array is <c>null</c></exception>
/// </para>
/// </summary>
/// <param name="data">The binary data to encode.</param>
/// <returns>The created segment containing the specified data.</returns>
/// <exception cref="ArgumentNullException"><c>data</c> is <c>null</c>.</exception>
public static QrSegment MakeBytes(byte[] data)
{
Objects.RequireNonNull(data);
@ -74,12 +84,13 @@ namespace IO.Nayuki.QrCodeGen
/// <summary>
/// Returns a segment representing the specified string of decimal digits encoded in numeric mode.
/// Creates a segment representing the specified string of decimal digits.
/// The segment is encoded in numeric mode.
/// </summary>
/// <param name="digits">the text (not <c>null</c>), with only digits from 0 to 9 allowed</param>
/// <returns>a segment (not <c>null</c>) containing the text</returns>
/// <exception cref="ArgumentNullException">Thrown if the string is <c>null</c></exception>
/// <exception cref="ArgumentOutOfRangeException">Thrown if the string contains non-digit characters</exception>
/// <param name="digits">The text to encode, consisting of digits from 0 to 9 only.</param>
/// <returns>The created segment containing the text.</returns>
/// <exception cref="ArgumentNullException"><c>digits</c> is <c>null</c>.</exception>
/// <exception cref="ArgumentOutOfRangeException"><c>digits</c> contains non-digit characters</exception>
public static QrSegment MakeNumeric(string digits)
{
Objects.RequireNonNull(digits);
@ -101,14 +112,17 @@ namespace IO.Nayuki.QrCodeGen
/// <summary>
/// Returns a segment representing the specified text string encoded in alphanumeric mode.
/// The characters allowed are: 0 to 9, A to Z(uppercase only), space,
/// Creates a segment representing the specified text string.
/// The segment is encoded in alphanumeric mode.
/// <para>
/// Allowed characters are: 0 to 9, A to Z (uppercase only), space,
/// dollar, percent, asterisk, plus, hyphen, period, slash, colon.
/// </para>
/// </summary>
/// <param name="text">the text (not <c>null</c>), with only certain characters allowed</param>
/// <returns>a segment (not <c>null</c>) containing the text</returns>
/// <exception cref="ArgumentNullException">Thrown if the string is <c>null</c></exception>
/// <exception cref="ArgumentOutOfRangeException">Thrown iif the string contains non-encodable characters</exception>
/// <param name="text">The text to encode, consisting of allowed characters only.</param>
/// <returns>The created segment containing the text.</returns>
/// <exception cref="ArgumentNullException"><c>text</c> is <c>null</c>.</exception>
/// <exception cref="ArgumentOutOfRangeException"><c>text</c> contains non-encodable characters.</exception>
public static QrSegment MakeAlphanumeric(string text)
{
Objects.RequireNonNull(text);
@ -136,18 +150,26 @@ namespace IO.Nayuki.QrCodeGen
/// <summary>
/// Returns a list of zero or more segments to represent the specified Unicode text string.
/// The result may use various segment modes and switch modes to optimize the length of the bit stream.
/// Creates a list of zero or more segments representing the specified text string.
/// <para>
/// The text may contain the full range of Unicode characters.
/// </para>
/// <para>
/// The result may multiple segments with various encoding modes in order to minimize the length of the bit stream.
/// </para>
/// </summary>
/// <param name="text">the text to be encoded, which can be any Unicode string</param>
/// <returns>a new mutable list (not <c>null</c>) of segments (not <c>null</c>) containing the text</returns>
/// <exception cref="ArgumentNullException">Thrown if the text is <c>null</c></exception>
/// <param name="text">The text to be encoded.</param>
/// <returns>The created mutable list of segments representing the specified text.</returns>
/// <exception cref="ArgumentNullException"><c>text</c> is <c>null</c>.</exception>
/// <remarks>
/// The current implementation does not use multiple segments.
/// </remarks>
public static List<QrSegment> MakeSegments(string text)
{
Objects.RequireNonNull(text);
// Select the most efficient segment encoding automatically
List<QrSegment> result = new List<QrSegment>();
var result = new List<QrSegment>();
if (text == "")
{
// Leave result empty
@ -170,12 +192,12 @@ namespace IO.Nayuki.QrCodeGen
/// <summary>
/// Returns a segment representing an Extended Channel Interpretation
/// Creates a segment representing an Extended Channel Interpretation
/// (ECI) designator with the specified assignment value.
/// </summary>
/// <param name="assignVal">the ECI assignment number (see the AIM ECI specification)</param>
/// <returns>a segment (not <c>null</c>) containing the data</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown if the value is outside the range [0, 10<sup>6</sup>)</exception>
/// <param name="assignVal">The ECI assignment number (see the AIM ECI specification).</param>
/// <returns>The created segment containing the data.</returns>
/// <exception cref="ArgumentOutOfRangeException"><c>assignVal</c>is outside the range [0, 10<sup>6</sup>).</exception>
public static QrSegment MakeEci(int assignVal)
{
BitArray ba = new BitArray(0);
@ -184,11 +206,11 @@ namespace IO.Nayuki.QrCodeGen
throw new ArgumentOutOfRangeException(nameof(assignVal), "ECI assignment value out of range");
}
if (assignVal < (1 << 7))
if (assignVal < 1 << 7)
{
ba.AppendBits((uint)assignVal, 8);
}
else if (assignVal < (1 << 14))
else if (assignVal < 1 << 14)
{
ba.AppendBits(2, 2);
ba.AppendBits((uint)assignVal, 14);
@ -211,16 +233,21 @@ namespace IO.Nayuki.QrCodeGen
#region Instance fields
/// <summary>
/// The mode indicator of this segment. Not <c>null</c>.
/// </summary>
/// <summary>The encoding mode of this segment.</summary>
/// <value>Encoding mode.</value>
public Mode EncodingMode { get; }
/// <summary>
/// The length of this segment's unencoded data. Measured in characters for
/// numeric/alphanumeric/kanji mode, bytes for byte mode, and 0 for ECI mode.
/// Always zero or positive. Not the same as the data's bit length.
/// The length of this segment's unencoded data.
/// <para>
/// Measured in characters for numeric/alphanumeric/kanji mode,
/// bytes for byte mode, and 0 for ECI mode.
/// </para>
/// <para>
/// Different from the data's bit length.
/// </para>
/// </summary>
/// <value>Length of the segment's unencoded data.</value>
public int NumChars { get; }
// The data bits of this segment. Not null. Accessed through GetData().
@ -232,25 +259,27 @@ namespace IO.Nayuki.QrCodeGen
#region Constructor (low level)
/// <summary>
/// Constructs a QR Code segment with the specified attributes and data.
/// The character count(numCh) must agree with the mode and the bit buffer length,
/// but the constraint isn't checked. The specified bit buffer is cloned and stored.
/// Initializes a QR code segment with the specified attributes and data.
/// <para>
/// The character count <paramref name="numChars"/> must agree with the mode and the bit array length,
/// but the constraint isn't checked. The specified bit array is cloned.
/// </para>
/// </summary>
/// <param name="md">the mode (not <c>null</c>)</param>
/// <param name="numCh">the data length in characters or bytes, which is non-negative</param>
/// <param name="data">the data bits (not <c>null</c>)</param>
/// <exception cref="ArgumentNullException">Thrown if the mode or data is <c>null</c></exception>
/// <exception cref="ArgumentOutOfRangeException">Thrown if the character count is negative</exception>
public QrSegment(Mode md, int numCh, BitArray data)
{
EncodingMode = Objects.RequireNonNull(md);
/// <param name="mode">The segment mode used to encode this segment.</param>
/// <param name="numChars">The data length in characters or bytes (depending on the segment mode).</param>
/// <param name="data">The data bits.</param>
/// <exception cref="ArgumentNullException"><paramref name="mode"/> or <paramref name="data"/> is <c>null</c>.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="numChars"/> is negative.</exception>
public QrSegment(Mode mode, int numChars, BitArray data)
{
EncodingMode = Objects.RequireNonNull(mode);
Objects.RequireNonNull(data);
if (numCh < 0)
if (numChars < 0)
{
throw new ArgumentOutOfRangeException(nameof(numCh), "Invalid value");
throw new ArgumentOutOfRangeException(nameof(numChars), "Invalid value");
}
NumChars = numCh;
NumChars = numChars;
_data = (BitArray)data.Clone(); // Make defensive copy
}
@ -260,9 +289,9 @@ namespace IO.Nayuki.QrCodeGen
#region Methods
/// <summary>
/// Returns the data bits of this segment.
/// Returns a copy of this segment's data bits.
/// </summary>
/// <returns>a new copy of the data bits(not<c>null</c>)</returns>
/// <returns>A copy of the data bits.</returns>
public BitArray GetData()
{
return (BitArray)_data.Clone(); // Make defensive copy
@ -280,7 +309,7 @@ namespace IO.Nayuki.QrCodeGen
{
Objects.RequireNonNull(seg);
int ccbits = seg.EncodingMode.NumCharCountBits(version);
if (seg.NumChars >= (1 << ccbits))
if (seg.NumChars >= 1 << ccbits)
{
return -1; // The segment's length doesn't fit the field's bit width
}
@ -300,29 +329,35 @@ namespace IO.Nayuki.QrCodeGen
#region Constants
/// <summary>
/// Describes precisely all strings that are encodable in numeric mode.
/// Immutable regular expression describing all strings encodable in <i>numeric mode</i>.
/// <para>
/// A string is encodable iff each character is in the range 0 to 9.
/// </para>
/// </summary>
/// <remarks>
/// To test whether a string <c>s</c> is encodable:
/// <code>
/// bool ok = NumericRegex.IsMatch(s);
/// </code>
/// A string is encodable iff each character is in the range 0 to 9.
/// </remarks>
/// <value>Regular exprression describing strings encodable in numeric mode.</value>
/// <seealso cref="MakeNumeric(string)"/>
public static readonly Regex NumericRegex = new Regex("^[0-9]*$", RegexOptions.Compiled);
/// <summary>
/// Describes precisely all strings that are encodable in alphanumeric mode.
/// Immutable regular expression describing all strings that are encodable in <i>alphanumeric mode</i>.
/// <para>
/// A string is encodable iff each character is in the following set: 0 to 9, A to Z
/// (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon.
/// </para>
/// </summary>
/// <remarks>
/// To test whether a string <c>s</c> is encodable:
/// <code>
/// bool ok = AlphanumericRegex.IsMatch(s);
/// </code>
/// A string is encodable iff each character is in the following set: 0 to 9, A to Z
/// (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon.
/// </remarks>
/// <value>Regular exprression describing strings encodable in alphanumeric mode.</value>
/// <seealso cref="MakeAlphanumeric(string)"/>
public static readonly Regex AlphanumericRegex = new Regex("^[A-Z0-9 $%*+./:-]*$", RegexOptions.Compiled);
@ -337,34 +372,79 @@ namespace IO.Nayuki.QrCodeGen
#region Public helper enumeration
/// <summary>
/// Describes how a segment's data bits are interpreted.
/// Segment encoding mode.
/// <para>
/// Describes how text or binary data is encoded into bits.
/// </para>
/// </summary>
public sealed class Mode
{
/// <summary>
/// Numeric encoding mode.
/// </summary>
/// <value>Numeric encoding mode.</value>
public static readonly Mode Numeric = new Mode(0x1, 10, 12, 14);
/// <summary>
/// Alphanumeric encoding mode.
/// </summary>
/// <value>Alphanumeric encoding mode.</value>
public static readonly Mode Alphanumeric = new Mode(0x2, 9, 11, 13);
/// <summary>
/// Byte encoding mode.
/// </summary>
/// <value>Byte encoding mode.</value>
public static readonly Mode Byte = new Mode(0x4, 8, 16, 16);
/// <summary>
/// Kanji encoding mode.
/// </summary>
/// <value>Kanji encoding mode.</value>
public static readonly Mode Kanji = new Mode(0x8, 8, 10, 12);
/// <summary>
/// ECI encoding mode.
/// </summary>
/// <value>ECI encoding mode.</value>
public static readonly Mode Eci = new Mode(0x7, 0, 0, 0);
// The mode indicator bits, which is a uint4 value (range 0 to 15).
/// <summary>
/// Mode indicator value.
/// <para>
/// 4 bit value in the QR segment header indicating the encoding mode.
/// </para>
/// </summary>
/// <value>Mode indicator value</value>
internal uint ModeBits { get; }
// Number of character count bits for three different version ranges.
/// <summary>
/// Array of character count bit length.
/// <para>
/// Number of bits for character count in QR segment header.
/// The three array values apply to versions 0 to 9, 10 to 26 and 27 to 40
/// respectively. All array values are in the range [0, 16].
/// </para>
/// </summary>
/// <value>Array of character count bit length</value>
internal int[] NumBitsCharCount { get; }
// Returns the bit width of the character count field for a segment in this mode
// in a QR Code at the given version number. The result is in the range [0, 16].
/// <summary>
/// Returns the bith length of the character count in the QR segment header
/// for the specified QR code version. The result is in the range [0, 16].
/// </summary>
/// <param name="ver">the QR code version (between 1 and 40)</param>
/// <returns></returns>
internal int NumCharCountBits(int ver)
{
Debug.Assert(QrCode.MinVersion <= ver && ver <= QrCode.MaxVersion);
return NumBitsCharCount[(ver + 7) / 17];
}
// private constructor to initializes the constants
private Mode(uint modeBits, params int[] numBitsCharCount)
{
ModeBits = modeBits;

@ -1,5 +1,5 @@
/*
* QR Code generator library (.NET)
* QR code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
@ -32,11 +32,8 @@ using static IO.Nayuki.QrCodeGen.QrSegment;
namespace IO.Nayuki.QrCodeGen
{
/// <summary>
/// Splits text into optimal segments and encodes kanji segments.
/// Advanced methods for encoding QR codes using Kanji mode or using multiple segments with different encodings.
/// </summary>
/// <remarks>
/// Provides static functions only; not instantiable.
/// </remarks>
/// <seealso cref="QrSegment"/>
/// <seealso cref="QrCode"/>
public static class QrSegmentAdvanced
@ -44,26 +41,26 @@ namespace IO.Nayuki.QrCodeGen
#region Optimal list of segments encoder
/// <summary>
/// Returns a list of zero or more segments to represent the specified Unicode text string.
/// Creates a list of zero or more segments to represent the specified text string.
/// The resulting list optimally minimizes the total encoded bit length, subjected to the constraints
/// in the specified {error correction level, minimum version number, maximum version number}.
/// of the specified error correction level, minimum and maximum version number.
/// <para>
/// This function potentially uses all four text encoding modes: numeric, alphanumeric, byte (UTF-8),
/// and Kanji. It is a more sophisticated but slower replacement for <see cref="MakeSegments"/>.
/// </para>
/// <para>
/// The text to be encoded can contain the full set of Unicode characters (code points).
/// </para>
/// </summary>
/// <remarks>
/// This function can utilize all four text encoding modes: numeric, alphanumeric, byte (UTF-8),
/// and kanji. This can be considered as a sophisticated but slower replacement for
/// <see cref="MakeSegments"/>. This requires more input parameters because it searches a
/// range of versions, like <see cref="QrCode.EncodeSegments(List{QrSegment},QrCode.Ecc)"/>.
/// </remarks>
/// <param name="text">the text to be encoded (not <c>null</c>), which can be any Unicode string</param>
/// <param name="ecl">the error correction level to use (not <c>null</c>)</param>
/// <param name="minVersion">the minimum allowed version of the QR Code (at least 1)</param>
/// <param name="maxVersion">the maximum allowed version of the QR Code (at most 40)</param>
/// <returns>a new mutable list (not <c>null</c>) of segments (not <c>null</c>)
/// containing the text, minimizing the bit length with respect to the constraints</returns>
/// <exception cref="ArgumentNullException">Thrown if the text or error correction level is <c>null</c></exception>
/// <exception cref="ArgumentOutOfRangeException">Thrown if 1 &#x2264; minVersion &#x2264; maxVersion &#x2264; 40 is violated</exception>
/// <exception cref="DataTooLongException">Thrown if the text fails to fit in the maxVersion QR Code at the ECL</exception>
public static List<QrSegment> MakeSegmentsOptimally(string text, QrCode.Ecc ecl, int minVersion, int maxVersion)
/// <param name="text">The text to be encoded.</param>
/// <param name="ecl">The error correction level to use.</param>
/// <param name="minVersion">The minimum version (size) of the QR code (between 1 and 40).</param>
/// <param name="maxVersion">The maximum version (size) of the QR code (between 1 and 40).</param>
/// <returns>The created mutable list of segments encoding the specified text with a minimal bit length.</returns>
/// <exception cref="ArgumentNullException"><paramref name="text"/> or <paramref name="ecl"/> is <c>null</c>.</exception>
/// <exception cref="ArgumentOutOfRangeException">1 &#x2264; minVersion &#x2264; maxVersion &#x2264; 40 is violated.</exception>
/// <exception cref="DataTooLongException">The text is too long to fit into the QR code with the given encoding parameters.</exception>
public static List<QrSegment> MakeSegmentsOptimally(string text, QrCode.Ecc ecl, int minVersion = QrCode.MinVersion, int maxVersion = QrCode.MaxVersion)
{
// Check arguments
Objects.RequireNonNull(text);
@ -181,7 +178,7 @@ namespace IO.Nayuki.QrCodeGen
{
// From mode
int newCost = (curCosts[k] + 5) / 6 * 6 + headCosts[j];
if (charModes[i, k] == null || (charModes[i, j] != null && newCost >= curCosts[j]))
if (charModes[i, k] == null || charModes[i, j] != null && newCost >= curCosts[j])
continue;
curCosts[j] = newCost;
charModes[i, j] = modeTypes[k];
@ -266,7 +263,7 @@ namespace IO.Nayuki.QrCodeGen
}
public static string FromCodePoints(int[] codepoints, int startIndex, int count)
private static string FromCodePoints(int[] codepoints, int startIndex, int count)
{
bool useBigEndian = !BitConverter.IsLittleEndian;
Encoding utf32 = new UTF32Encoding(useBigEndian, false , true);
@ -321,18 +318,18 @@ namespace IO.Nayuki.QrCodeGen
#region Kanji mode segment encoder
/// <summary>
/// Returns a segment representing the specified text string encoded in kanji mode.
/// Creates a segment encoding the specified text in Kanji mode.
/// <para>
/// Broadly speaking, the set of encodable characters are Kanji used in Japan,
/// Hiragana, Katakana, East Asian punctuation, full-width ASCII, Greek, and Cyrillic.
/// Examples of non-encodable characters include ordinary ASCII, half-width Katakana,
/// more extensive Chinese Hanzi.
/// </para>
/// </summary>
/// <remarks>
/// Broadly speaking, the set of encodable characters are {kanji used in Japan,
/// hiragana, katakana, East Asian punctuation, full-width ASCII, Greek, Cyrillic}.
/// Examples of non-encodable characters include {ordinary ASCII, half-width katakana,
/// more extensive Chinese hanzi}.
/// </remarks>
/// <param name="text">the text (not <c>null</c>), with only certain characters allowed</param>
/// <returns>a segment (not <c>null</c>) containing the text</returns>
/// <exception cref="ArgumentNullException">Thrown if the string is <c>null</c></exception>
/// <exception cref="ArgumentOutOfRangeException">Thrown if the string contains non-encodable characters</exception>
/// <param name="text">The text to encoding, containing only characters allowed by the Kanji encoding.</param>
/// <returns>The created segment respresenting the specified text.</returns>
/// <exception cref="ArgumentNullException"><paramref name="text"/> is <c>null</c>.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="text"/> contains non-encodable characters.</exception>
/// <seealso cref="IsEncodableAsKanji"/>
public static QrSegment MakeKanji(string text)
{
@ -355,17 +352,17 @@ namespace IO.Nayuki.QrCodeGen
/// <summary>
/// Tests whether the specified string can be encoded as a segment in kanji mode.
/// Tests whether the specified string can be encoded as a segment in Kanji mode.
/// <para>
/// Broadly speaking, the set of encodable characters are Kanji used in Japan,
/// Hiragana, Katakana, East Asian punctuation, full-width ASCII, Greek, and Cyrillic.
/// Examples of non-encodable characters include ordinary ASCII, half-width Katakana,
/// more extensive Chinese Hanzi.
/// </para>
/// </summary>
/// <remarks>
/// Broadly speaking, the set of encodable characters are {kanji used in Japan,
/// hiragana, katakana, East Asian punctuation, full-width ASCII, Greek, Cyrillic}.
/// Examples of non-encodable characters include {ordinary ASCII, half-width katakana,
/// more extensive Chinese hanzi}.
/// </remarks>
/// <param name="text">the string to test for encodability (not <c>null</c>)</param>
/// <returns><c>true</c> iff each character is in the kanji mode character set</returns>
/// <exception cref="ArgumentNullException">Thrown if the string is <c>null</c></exception>
/// <param name="text">The text to test for encodability.</param>
/// <returns><c>true</c> iff each character is in the Kanji mode character set.</returns>
/// <exception cref="ArgumentNullException"><paramref name="text"/> is <c>null</c>.</exception>
public static bool IsEncodableAsKanji(string text) {
Objects.RequireNonNull(text);
foreach (char t in text)

@ -1,5 +1,5 @@
/*
* QR Code generator library (.NET)
* QR code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
@ -29,11 +29,11 @@ namespace IO.Nayuki.QrCodeGen
{
/// <summary>
/// Computes the Reed-Solomon error correction codewords for a sequence of data codewords at a given degree.
/// <para>
/// Instances are immutable, and the state only depends on the degree.
/// This class is useful because all data blocks in a QR code share the same the divisor polynomial.
/// </para>
/// </summary>
/// <remarks>
/// Objects are immutable, and the state only depends on the degree.
/// This class exists because each data block in a QR Code shares the same the divisor polynomial.
/// </remarks>
internal class ReedSolomonGenerator
{
#region Fields
@ -48,11 +48,13 @@ namespace IO.Nayuki.QrCodeGen
#region Constructors
/// <summary>
/// Constructs a Reed-Solomon ECC generator for the specified degree. This could be implemented
/// as a lookup table over all possible parameter values, instead of as an algorithm.
/// Initializes a new Reed-Solomon ECC generator for the specified degree.
/// </summary>
/// <param name="degree">the divisor polynomial degree, which must be between 1 and 255 (inclusive)</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if degree &lt; 1 or degree > 255</exception>
/// <remarks>
/// This could be implemented as a lookup table over all possible parameter values, instead of as an algorithm.
/// </remarks>
/// <param name="degree">The divisor polynomial degree (between 1 and 255).</param>
/// <exception cref="ArgumentOutOfRangeException"><c>degree</c> &lt; 1 or <c>degree</c> &gt; 255</exception>
internal ReedSolomonGenerator(int degree)
{
if (degree < 1 || degree > 255)
@ -89,16 +91,15 @@ namespace IO.Nayuki.QrCodeGen
#region Methods
/// <summary>
/// Computes and returns the Reed-Solomon error correction codewords for the specified
/// Computes the Reed-Solomon error correction codewords for the specified
/// sequence of data codewords.
/// <para>
/// This method does not alter this object's state (as it is immutable).
/// </para>
/// </summary>
/// <remarks>
/// The returned object is always a new byte array.
/// This method does not alter this object's state (because it is immutable).
/// </remarks>
/// <param name="data">the sequence of data codewords</param>
/// <returns>the Reed-Solomon error correction codewords</returns>
/// <exception cref="ArgumentNullException">Thrown if the data is <c>null</c></exception>
/// <param name="data">The sequence of data codewords.</param>
/// <returns>The Reed-Solomon error correction codewords, as a byte array.</returns>
/// <exception cref="ArgumentNullException">If <c>data</c> is <c>null</c>.</exception>
internal byte[] GetRemainder(byte[] data)
{
Objects.RequireNonNull(data);
@ -127,7 +128,7 @@ namespace IO.Nayuki.QrCodeGen
// are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8.
private static byte Multiply(uint x, uint y)
{
Debug.Assert((x >> 8) == 0 && (y >> 8) == 0);
Debug.Assert(x >> 8 == 0 && y >> 8 == 0);
// Russian peasant multiplication
uint z = 0;
for (int i = 7; i >= 0; i--)
@ -135,7 +136,7 @@ namespace IO.Nayuki.QrCodeGen
z = (z << 1) ^ ((z >> 7) * 0x11D);
z ^= ((y >> i) & 1) * x;
}
Debug.Assert((z >> 8) == 0);
Debug.Assert(z >> 8 == 0);
return (byte)z;
}

@ -1,5 +1,5 @@
/*
* QR Code generator library (.NET)
* QR code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
@ -42,13 +42,13 @@ namespace IO.Nayuki.QrCodeGen.Demo
#region Demo suite
// Creates a single QR Code, then writes it to a PNG file and an SVG file.
// Creates a single QR code, then writes it to a PNG file and an SVG file.
private static void DoBasicDemo()
{
const string text = "Hello, world!"; // User-supplied Unicode text
var errCorLvl = QrCode.Ecc.Low; // Error correction level
var qr = QrCode.EncodeText(text, errCorLvl); // Make the QR Code symbol
var qr = QrCode.EncodeText(text, errCorLvl); // Make the QR code symbol
using (var img = qr.ToBitmap(10, 4)) // Convert to bitmap image
{
@ -60,7 +60,7 @@ namespace IO.Nayuki.QrCodeGen.Demo
}
// Creates a variety of QR Codes that exercise different features of the library, and writes each one to file.
// Creates a variety of QR codes that exercise different features of the library, and writes each one to file.
private static void DoVarietyDemo() {
// Numeric mode encoding (3.33 bits per digit)
var qr = QrCode.EncodeText("314159265358979323846264338327950288419716939937510", QrCode.Ecc.Medium);
@ -74,7 +74,7 @@ namespace IO.Nayuki.QrCodeGen.Demo
qr = QrCode.EncodeText("こんにちwa、世界 αβγδ", QrCode.Ecc.Quartile);
SaveAsPng(qr, "unicode-QR.png", 10, 3);
// Moderately large QR Code using longer text (from Lewis Carroll's Alice in Wonderland)
// Moderately large QR code using longer text (from Lewis Carroll's Alice in Wonderland)
qr = QrCode.EncodeText(
"Alice was beginning to get very tired of sitting by her sister on the bank, "
+ "and of having nothing to do: once or twice she had peeped into the book her sister was reading, "
@ -87,7 +87,7 @@ namespace IO.Nayuki.QrCodeGen.Demo
}
// Creates QR Codes with manually specified segments for better compactness.
// Creates QR codes with manually specified segments for better compactness.
private static void DoSegmentDemo()
{
// Illustration "silver"
@ -133,24 +133,24 @@ namespace IO.Nayuki.QrCodeGen.Demo
}
// Creates QR Codes with the same size and contents but different mask patterns.
// Creates QR codes with the same size and contents but different mask patterns.
private static void DoMaskDemo() {
// Project Nayuki URL
var segs = QrSegment.MakeSegments("https://www.nayuki.io/");
var qr = QrCode.EncodeSegments(segs, QrCode.Ecc.High, QrCode.MinVersion, QrCode.MaxVersion, -1, true);
var qr = QrCode.EncodeSegments(segs, QrCode.Ecc.High);
SaveAsPng(qr, "project-nayuki-automask-QR.png", 8, 6);
qr = QrCode.EncodeSegments(segs, QrCode.Ecc.High, QrCode.MinVersion, QrCode.MaxVersion, 3, true); // Force mask 3
qr = QrCode.EncodeSegments(segs, QrCode.Ecc.High, QrCode.MinVersion, QrCode.MaxVersion, 3); // Force mask 3
SaveAsPng(qr, "project-nayuki-mask3-QR.png", 8, 6);
// Chinese text as UTF-8
segs = QrSegment.MakeSegments("維基百科Wikipedia聆聽i/ˌwɪkᵻˈpiːdi.ə/)是一個自由內容、公開編輯且多語言的網路百科全書協作計畫");
qr = QrCode.EncodeSegments(segs, QrCode.Ecc.Medium, QrCode.MinVersion, QrCode.MaxVersion, 0, true); // Force mask 0
qr = QrCode.EncodeSegments(segs, QrCode.Ecc.Medium, QrCode.MinVersion, QrCode.MaxVersion, 0); // Force mask 0
SaveAsPng(qr, "unicode-mask0-QR.png", 10, 3);
qr = QrCode.EncodeSegments(segs, QrCode.Ecc.Medium, QrCode.MinVersion, QrCode.MaxVersion, 1, true); // Force mask 1
qr = QrCode.EncodeSegments(segs, QrCode.Ecc.Medium, QrCode.MinVersion, QrCode.MaxVersion, 1); // Force mask 1
SaveAsPng(qr, "unicode-mask1-QR.png", 10, 3);
qr = QrCode.EncodeSegments(segs, QrCode.Ecc.Medium, QrCode.MinVersion, QrCode.MaxVersion, 5, true); // Force mask 5
qr = QrCode.EncodeSegments(segs, QrCode.Ecc.Medium, QrCode.MinVersion, QrCode.MaxVersion, 5); // Force mask 5
SaveAsPng(qr, "unicode-mask5-QR.png", 10, 3);
qr = QrCode.EncodeSegments(segs, QrCode.Ecc.Medium, QrCode.MinVersion, QrCode.MaxVersion, 7, true); // Force mask 7
qr = QrCode.EncodeSegments(segs, QrCode.Ecc.Medium, QrCode.MinVersion, QrCode.MaxVersion, 7); // Force mask 7
SaveAsPng(qr, "unicode-mask7-QR.png", 10, 3);
}

@ -1,5 +1,5 @@
/*
* QR Code generator library (.NET)
* QR code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library

@ -1,5 +1,5 @@
/*
* QR Code generator library (.NET)
* QR code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library

@ -1,5 +1,5 @@
/*
* QR Code generator library (.NET)
* QR code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library

@ -1,5 +1,5 @@
/*
* QR Code generator library (.NET)
* QR code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library

@ -1,5 +1,5 @@
/*
* QR Code generator library (.NET)
* QR code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
@ -613,7 +613,7 @@ namespace IO.Nayuki.QrCodeGen.Test
private void TestCode9()
{
var segments = QrSegment.MakeSegments(Text9);
var qrCode = EncodeSegments(segments, Ecc.High, 1, 40, -1, true);
var qrCode = EncodeSegments(segments, Ecc.High);
Assert.Same(Ecc.High, qrCode.ErrorCorrectionLevel);
Assert.Equal(29, qrCode.Size);
Assert.Equal(1, qrCode.Mask);
@ -658,7 +658,7 @@ namespace IO.Nayuki.QrCodeGen.Test
private void TestCode10()
{
var segments = QrSegment.MakeSegments(Text10);
var qrCode = EncodeSegments(segments, Ecc.High, 1, 40, 3, true);
var qrCode = EncodeSegments(segments, Ecc.High, 1, 40, 3);
Assert.Same(Ecc.High, qrCode.ErrorCorrectionLevel);
Assert.Equal(29, qrCode.Size);
Assert.Equal(3, qrCode.Mask);
@ -723,7 +723,7 @@ namespace IO.Nayuki.QrCodeGen.Test
private void TestCode11()
{
var segments = QrSegment.MakeSegments(Text11);
var qrCode = EncodeSegments(segments, Ecc.Medium, 1, 40, 0, true);
var qrCode = EncodeSegments(segments, Ecc.Medium, 1, 40, 0);
Assert.Same(Ecc.Medium, qrCode.ErrorCorrectionLevel);
Assert.Equal(49, qrCode.Size);
Assert.Equal(0, qrCode.Mask);
@ -788,7 +788,7 @@ namespace IO.Nayuki.QrCodeGen.Test
private void TestCode12()
{
var segments = QrSegment.MakeSegments(Text12);
var qrCode = EncodeSegments(segments, Ecc.Medium, 1, 40, 1, true);
var qrCode = EncodeSegments(segments, Ecc.Medium, 1, 40, 1);
Assert.Same(Ecc.Medium, qrCode.ErrorCorrectionLevel);
Assert.Equal(49, qrCode.Size);
Assert.Equal(1, qrCode.Mask);
@ -853,7 +853,7 @@ namespace IO.Nayuki.QrCodeGen.Test
private void TestCode13()
{
var segments = QrSegment.MakeSegments(Text13);
var qrCode = EncodeSegments(segments, Ecc.Medium, 1, 40, 5, true);
var qrCode = EncodeSegments(segments, Ecc.Medium, 1, 40, 5);
Assert.Same(Ecc.Medium, qrCode.ErrorCorrectionLevel);
Assert.Equal(49, qrCode.Size);
Assert.Equal(5, qrCode.Mask);
@ -918,7 +918,7 @@ namespace IO.Nayuki.QrCodeGen.Test
private void TestCode14()
{
var segments = QrSegment.MakeSegments(Text14);
var qrCode = EncodeSegments(segments, Ecc.Medium, 1, 40, 7, true);
var qrCode = EncodeSegments(segments, Ecc.Medium, 1, 40, 7);
Assert.Same(Ecc.Medium, qrCode.ErrorCorrectionLevel);
Assert.Equal(49, qrCode.Size);
Assert.Equal(7, qrCode.Mask);

@ -1,5 +1,5 @@
/*
* QR Code generator library (.NET)
* QR code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library

@ -1,5 +1,5 @@
/*
* QR Code generator library (.NET)
* QR code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library

@ -1,5 +1,5 @@
/*
* QR Code generator library (.NET)
* QR code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library

@ -1,5 +1,5 @@
/*
* QR Code generator library (.NET)
* QR code generator library (.NET)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library

Loading…
Cancel
Save