Exemple #1
0
        private void WriteSegments(BitSequence bs)
        {
            foreach (QRCodeEncoder segment in _segments)
            {
                bs.Append(segment.ModeIndicator, ModeIndicator.LENGTH);
                bs.Append(segment.CharCount,
                          CharCountIndicator.GetLength(
                              _currVersion, segment.EncodingMode)
                          );

                byte[] data = segment.GetBytes();

                for (int i = 0; i < data.Length - 1; ++i)
                {
                    bs.Append(data[i], 8);
                }

                int codewordBitLength = segment.BitCount % 8;

                if (codewordBitLength == 0)
                {
                    codewordBitLength = 8;
                }

                bs.Append(data[data.Length - 1] >> (8 - codewordBitLength),
                          codewordBitLength);
            }
        }
Exemple #2
0
        /// <summary>
        /// 符号化モードを設定します。
        /// </summary>
        /// <param name="encMode">符号化モード</param>
        /// <param name="c">符号化する最初の文字。この文字はシンボルに追加されません。</param>
        /// <returns>シンボル容量が不足している場合は false を返します。</returns>
        internal bool TrySetEncodingMode(EncodingMode encMode, char c)
        {
            QRCodeEncoder encoder;
            Encoding      encoding = _parent.Encoding;

            switch (encMode)
            {
            case EncodingMode.NUMERIC:
                encoder = new NumericEncoder(encoding);
                break;

            case EncodingMode.ALPHA_NUMERIC:
                encoder = new AlphanumericEncoder(encoding);
                break;

            case EncodingMode.EIGHT_BIT_BYTE:
                encoder = new ByteEncoder(encoding);
                break;

            case EncodingMode.KANJI:
                if (Charset.IsJP(encoding.WebName))
                {
                    encoder = new KanjiEncoder(encoding);
                }
                else
                {
                    throw new InvalidOperationException();
                }
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(encMode));
            }

            int bitLength = encoder.GetCodewordBitLength(c);

            while (_dataBitCapacity <
                   _dataBitCounter
                   + ModeIndicator.LENGTH
                   + CharCountIndicator.GetLength(_currVersion, encMode)
                   + bitLength)
            {
                if (_currVersion >= _parent.MaxVersion)
                {
                    return(false);
                }

                SelectVersion();
            }

            _dataBitCounter += ModeIndicator.LENGTH
                               + CharCountIndicator.GetLength(_currVersion, encMode);
            _currEncoder = encoder;
            _segments.Add(_currEncoder);
            _segmentCounter[encMode]++;
            _currEncodingMode = encMode;

            return(true);
        }
Exemple #3
0
        /// <summary>
        /// 型番を決定します。
        /// </summary>
        private void SelectVersion()
        {
            foreach (EncodingMode encMode in _segmentCounter.Keys)
            {
                int num = _segmentCounter[encMode];

                _dataBitCounter +=
                    num * CharCountIndicator.GetLength(_currVersion + 1, encMode)
                    - num * CharCountIndicator.GetLength(_currVersion + 0, encMode);
            }

            _currVersion++;
            _dataBitCapacity = 8 * DataCodeword.GetTotalNumber(
                _parent.ErrorCorrectionLevel, _currVersion);
            _parent.MinVersion = _currVersion;

            if (_parent.StructuredAppendAllowed)
            {
                _dataBitCapacity -= StructuredAppend.HEADER_LENGTH;
            }
        }