getCharacterCountBits() public method

public getCharacterCountBits ( Version version ) : int
version Version version in question ///
return int
                /// <summary>
                /// returns the size in bits
                /// </summary>
                /// <returns></returns>
                public int getSize(Version version)
                {
                    int size = 4 + mode.getCharacterCountBits(resultList.version);

                    switch (mode.Name)
                    {
                    case Mode.Names.KANJI:
                        size += 13 * characterLength;
                        break;

                    case Mode.Names.ALPHANUMERIC:
                        size += (characterLength / 2) * 11;
                        size += (characterLength % 2) == 1 ? 6 : 0;
                        break;

                    case Mode.Names.NUMERIC:
                        size += (characterLength / 3) * 10;
                        int rest = characterLength % 3;
                        size += rest == 1 ? 4 : rest == 2 ? 7 : 0;
                        break;

                    case Mode.Names.BYTE:
                        size += 8 * CharacterCountIndicator;
                        break;

                    case Mode.Names.ECI:
                        size += 8;     // the ECI assignment numbers for ISO-8859-x, UTF-8 and UTF-16 are all 8 bit long
                        break;
                    }
                    return(size);
                }
Example #2
0
        /// <summary>
        /// Append length info. On success, store the result in "bits".
        /// </summary>
        /// <param name="numLetters">The num letters.</param>
        /// <param name="version">The version.</param>
        /// <param name="mode">The mode.</param>
        /// <param name="bits">The bits.</param>
        internal static void appendLengthInfo(int numLetters, Version version, Mode mode, BitArray bits)
        {
            int numBits = mode.getCharacterCountBits(version);

            if (numLetters >= (1 << numBits))
            {
                throw new WriterException(numLetters + " is bigger than " + ((1 << numBits) - 1));
            }
            bits.appendBits(numLetters, numBits);
        }
            public Edge(Mode mode, int fromPosition, int charsetEncoderIndex, int characterLength, Edge previous, Version version, MinimalEncoder encoder)
            {
                this.mode                = mode;
                this.fromPosition        = fromPosition;
                this.charsetEncoderIndex = mode == Mode.BYTE || previous == null ? charsetEncoderIndex :
                                           previous.charsetEncoderIndex; // inherit the encoding if not of type BYTE
                this.characterLength = characterLength;
                this.previous        = previous;

                int size = previous != null ? previous.cachedTotalSize : 0;

                bool needECI = mode == Mode.BYTE &&
                               (previous == null && this.charsetEncoderIndex != 0) || // at the beginning and charset is not ISO-8859-1
                               (previous != null && this.charsetEncoderIndex != previous.charsetEncoderIndex);

                if (previous == null || mode != previous.mode || needECI)
                {
                    size += 4 + mode.getCharacterCountBits(version);
                }
                switch (mode.Name)
                {
                case Mode.Names.KANJI:
                    size += 13;
                    break;

                case Mode.Names.ALPHANUMERIC:
                    size += characterLength == 1 ? 6 : 11;
                    break;

                case Mode.Names.NUMERIC:
                    size += characterLength == 1 ? 4 : characterLength == 2 ? 7 : 10;
                    break;

                case Mode.Names.BYTE:
                    size += 8 * encoder.encoders[charsetEncoderIndex].GetBytes(encoder.stringToEncode.Substring(fromPosition, characterLength)).Length;
                    if (needECI)
                    {
                        size += 4 + 8;     // the ECI assignment numbers for ISO-8859-x, UTF-8 and UTF-16 are all 8 bit long
                    }
                    break;
                }
                cachedTotalSize = size;
            }
Example #4
0
 /// <summary>
 /// Append length info. On success, store the result in "bits".
 /// </summary>
 /// <param name="numLetters">The num letters.</param>
 /// <param name="version">The version.</param>
 /// <param name="mode">The mode.</param>
 /// <param name="bits">The bits.</param>
 internal static void appendLengthInfo(int numLetters, Version version, Mode mode, BitArray bits)
 {
    int numBits = mode.getCharacterCountBits(version);
    if (numLetters >= (1 << numBits))
    {
       throw new WriterException(numLetters + " is bigger than " + ((1 << numBits) - 1));
    }
    bits.appendBits(numLetters, numBits);
 }
Example #5
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)
        {
            // Determine what character encoding has been specified by the caller, if any
#if !SILVERLIGHT || WINDOWS_PHONE
            String encoding = hints == null || !hints.ContainsKey(EncodeHintType.CHARACTER_SET) ? null : (String)hints[EncodeHintType.CHARACTER_SET];
            if (encoding == null)
            {
                encoding = DEFAULT_BYTE_MODE_ENCODING;
            }
            bool generateECI = !DEFAULT_BYTE_MODE_ENCODING.Equals(encoding);
#else
            // Silverlight supports only UTF-8 and UTF-16 out-of-the-box
            const string encoding = "UTF-8";
            // 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
            bool generateECI = (hints != null && hints.ContainsKey(EncodeHintType.CHARACTER_SET));
#endif
            // http://zxingnet.codeplex.com/discussions/399045
            if (hints != null && hints.ContainsKey(EncodeHintType.DISABLE_ECI) && (bool)hints[EncodeHintType.DISABLE_ECI])
            {
                generateECI = false;
            }

            // 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. Twould be nice.
            Mode mode = chooseMode(content, encoding);

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

            // Append ECI segment if applicable
            if (mode == Mode.BYTE && generateECI)
            {
                CharacterSetECI eci = CharacterSetECI.getCharacterSetECIByName(encoding);
                if (eci != null)
                {
                    appendECI(eci, 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.
            BitArray dataBits = new BitArray();
            appendBytes(content, mode, dataBits, encoding);

            // Hard part: need to know version to know how many bits length takes. But need to know how many
            // bits it takes to know version. First we take a guess at version by assuming version will be
            // the minimum, 1:

            int provisionalBitsNeeded = headerBits.Size
                                        + mode.getCharacterCountBits(Version.getVersionForNumber(1))
                                        + dataBits.Size;
            Version provisionalVersion = chooseVersion(provisionalBitsNeeded, ecLevel);

            // Use that guess to calculate the right version. I am still not sure this works in 100% of cases.
            int bitsNeeded = headerBits.Size
                             + mode.getCharacterCountBits(provisionalVersion)
                             + dataBits.Size;
            Version version = chooseVersion(bitsNeeded, ecLevel);

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

            Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel);
            int numDataBytes          = version.TotalCodewords - ecBlocks.TotalECCodewords;

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

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

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

            //  Choose the mask pattern and set to "qrCode".
            int        dimension   = version.DimensionForVersion;
            ByteMatrix matrix      = new ByteMatrix(dimension, dimension);
            int        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);
        }
Example #6
0
 private static int calculateBitsNeeded(Mode mode, BitArray headerBits, BitArray dataBits, Version version)
 {
     return(headerBits.Size + mode.getCharacterCountBits(version) + dataBits.Size);
 }
Example #7
0
        public static QRCode encode(String content,
                                    ErrorCorrectionLevel ecLevel,
                                    IDictionary hints)
        {
            // Determine what character encoding has been specified by the caller, if any
            String encoding = hints == null || !hints.Contains(EncodeHintType.CHARACTER_SET) ? null : (String)hints[EncodeHintType.CHARACTER_SET];

            if (encoding == null)
            {
                encoding = DEFAULT_BYTE_MODE_ENCODING;
            }
            bool doSelectMask = hints == null || !hints.Contains(EncodeHintType.QR_DO_MASK_SELECTION) ? false : (bool)hints[EncodeHintType.QR_DO_MASK_SELECTION];

            // 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. Twould be nice.
            Mode mode = chooseMode(content, encoding);

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

            // Append ECI segment if applicable
            if (mode == Mode.BYTE && !DEFAULT_BYTE_MODE_ENCODING.Equals(encoding))
            {
                CharacterSetECI eci = CharacterSetECI.getCharacterSetECIByName(encoding);
                if (eci != null)
                {
                    appendECI(eci, 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.
            BitArray dataBits = new BitArray();

            appendBytes(content, mode, dataBits, encoding);

            // Hard part: need to know version to know how many bits length takes. But need to know how many
            // bits it takes to know version. To pick version size assume length takes maximum bits
            int bitsNeeded = headerBits.Size
                             + mode.getCharacterCountBits(Version.getVersionForNumber(40))
                             + dataBits.Size;
            Version version = chooseVersion(bitsNeeded, ecLevel);

            BitArray headerAndDataBits = new BitArray();

            headerAndDataBits.appendBitArray(headerBits);
            // Find "length" of main segment and write it
            int numLetters = mode == Mode.BYTE ? dataBits.SizeInBytes : content.Length;

            appendLengthInfo(numLetters, version, mode, headerAndDataBits);
            // Put data together into the overall payload
            headerAndDataBits.appendBitArray(dataBits);

            Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel);
            int numDataBytes          = version.TotalCodewords - ecBlocks.TotalECCodewords;

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

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

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

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

            if (doSelectMask)
            {
                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);
        }