Kuin Advent Calendar 2016 - 9日目

この記事は【Kuin Advent Calendar 2016】の9日目の記事です。

←前の日の記事   →次の日の記事

【記事中で紹介しているコードについて】
コンパイルが通らない場合など、不具合があれば、@tatt61880まで連絡いただけると助かります。よろしくお願いいたします。


QRコードを生成するKuinのコードです。
[Image:qr.kn.png]
qr.kn
{
	文字列からQRコードを作成します。

	下記のサイトの QR_Image_Source.zip を参考にさせていただきました。
	コメントにC++のコードとの対応関係を書いている場合があります。
	ソースコードを公開してくださっていることを感謝いたします。
		http://www.psytec.co.jp/freesoft/02/
		上記のライセンスに関しては、
			・本ソフトウェアの配布は自由です。
			・ソースコードの一部または全部の使用、及び改変しての使用を認めます。
			・ソースコードを使用する際に弊社に許可を求める必要はなく、また弊社名の記載も不要です。
		とのことです。
	
	QRコードは株式会社デンソーウェーブの登録商標です。
		http://www.qrcode.com/faq.html
}

func main()
	var data: []bit8 :: #[0]bit8
	const inputData: []char :: "Hello, QR!! (Created by Kuin)"
	for i(0, ^inputData - 1)
		do data :~ [inputData[i] $ bit8]
	end for

	var qrEncode: @QrEncode :: #@QrEncode
	do qrEncode.encodeData(@QR_LEVEL_H, 0, false, -1, data, 0)

	const size: int :: 220
	const margin: int :: 10
	const wndSize: int :: size + 2 * margin
	var wndMain: wnd@Wnd :: wnd@makeWnd(null, %aspect, wndSize, wndSize, "Hello, QR!")
	var drawMain: wnd@Draw :: wnd@makeDraw(wndMain, 0, 0, wndSize, wndSize, %scale, %scale, false)

	while(wnd@act())
		do draw@rect(0.0, 0.0, wndSize $ float, wndSize $ float, 0xFF6188FF)
		do qrEncode.draw(margin $ float, margin $float, size $ float, false)
		do draw@render(30)
	end while
end func

const x00: bit8 :: 0x00b8 {'\x00'}
const x11: bit8 :: 0x11b8 {'\x11'}
const x20: bit8 :: 0x20b8 {'\x20'}
const x30: bit8 :: 0x30b8 {'\x30'}

{誤り訂正レベル}
const QR_LEVEL_L: int :: 0
const QR_LEVEL_M: int :: 1
const QR_LEVEL_Q: int :: 2
const QR_LEVEL_H: int :: 3
{データモード}
const QR_MODE_NUMERAL:  bit8 :: 0b8
const QR_MODE_ALPHABET: bit8 :: 1b8
const QR_MODE_8BIT:     bit8 :: 2b8
const QR_MODE_KANJI:    bit8 :: 3b8
{バージョン(型番)グループ}
const QR_VRESION_S: int :: 0 { 1 ~  9}
const QR_VRESION_M: int :: 1 {10 ~ 26}
const QR_VRESION_L: int :: 2 {27 ~ 40}

const MAX_ALLCODEWORD:  int :: 3706 {総コードワード数最大値}
const MAX_DATACODEWORD: int :: 2956 {データコードワード最大値(バージョン40-L)}
const MAX_CODEBLOCK:    int ::  153 {ブロックデータコードワード数最大値(RSコードワードを含む)}
const MAX_MODULESIZE:   int ::  177 {一辺モジュール数最大値}

{ビットマップ描画時マージン}
const QR_MARGIN: int :: 4

{QRコードバージョン(型番)関連情報}
{struct QR_VERSIONINFO}
class QrVersionInfo()
	var nVersionNo: int {バージョン(型番)番号(1~40)}
	+var ncAllCodeWord: int {総コードワード数}
	{以下配列添字は誤り訂正率(0 = L, 1 = M, 2 = Q, 3 = H)}
	+var ncDataCodeWord: []int {データコードワード数(総コードワード数 - RSコードワード数)}
	+var ncAlignPoint: int {アライメントパターン座標数}
	+var nAlignPoint: []int {アライメントパターン中心座標}
	+var rsBlockInfo1: []RsBlockInfo {RSブロック情報(1)}
	+var rsBlockInfo2: []RsBlockInfo {RSブロック情報(2)}
	+func init(nVersionNo: int, ncAllCodeWord: int, ncDataCodeWord: []int, ncAlignPoint: int, nAlignPoint: []int, rsBlockInfo1: []int, rsBlockInfo2: []int): @QrVersionInfo
		do me.nVersionNo :: nVersionNo
		do me.ncAllCodeWord :: ncAllCodeWord
		do me.ncDataCodeWord :: #[4]int
		do me.ncDataCodeWord :: ##ncDataCodeWord
		do me.ncAlignPoint :: ncAlignPoint
		do me.nAlignPoint :: #[6]int
		do me.nAlignPoint :: ##nAlignPoint
		do me.rsBlockInfo1 :: #[4]RsBlockInfo
		do me.rsBlockInfo2 :: #[4]RsBlockInfo
		for i(0, 3)
			do me.rsBlockInfo1[i] :: (#RsBlockInfo).init(rsBlockInfo1, 3 * i)
			do me.rsBlockInfo2[i] :: (#RsBlockInfo).init(rsBlockInfo2, 3 * i)
		end for
		ret me
	end func

	{struct RS_BLOCKINFO}
	class RsBlockInfo()
		+var ncRSBlock: int {RSブロック数}
		+var ncBlockAllCodeWord: int {ブロック内コードワード数}
		+var ncBlockDataCodeWord: int {データコードワード数(コードワード数 - RSコードワード数)}
		+func init(rsBlockInfo: []int, n: int): RsBlockInfo
			do me.ncRSBlock :: rsBlockInfo[n]
			do me.ncBlockAllCodeWord :: rsBlockInfo[n + 1]
			do me.ncBlockDataCodeWord :: rsBlockInfo[n + 2]
			ret me
		end func
	end class
end class

var qrVersionInfo: []@QrVersionInfo
var byExpToInt: []bit8
var byIntToExp: []bit8
var byRSExp: [][]int
var nIndicatorLenNumeral: []int
var nIndicatorLenAlphabet: []int
var nIndicatorLen8Bit: []int
var nIndicatorLenKanji: []int

{static変数の初期化用}
var initializeFlag: bool
func initialize()
	{QRコードバージョン(型番)情報}
	do @qrVersionInfo :: #[41]@QrVersionInfo
	do @qrVersionInfo[ 1] :: (#@QrVersionInfo).init( 1,  26,[  19,  16,  13,   9],0,[ 0, 0, 0,  0,  0,  0],[ 1, 26, 19, 1,26,16, 1,26,13, 1,26, 9],[ 0,  0,  0, 0,0 , 0, 0, 0, 0, 0, 0, 0])
	do @qrVersionInfo[ 2] :: (#@QrVersionInfo).init( 2,  44,[  34,  28,  22,  16],1,[18, 0, 0,  0,  0,  0],[ 1, 44, 34, 1,44,28, 1,44,22, 1,44,16],[ 0,  0,  0, 0,0 , 0, 0, 0, 0, 0, 0, 0])
	do @qrVersionInfo[ 3] :: (#@QrVersionInfo).init( 3,  70,[  55,  44,  34,  26],1,[22, 0, 0,  0,  0,  0],[ 1, 70, 55, 1,70,44, 2,35,17, 2,35,13],[ 0,  0,  0, 0,0 , 0, 0, 0, 0, 0, 0, 0])
	do @qrVersionInfo[ 4] :: (#@QrVersionInfo).init( 4, 100,[  80,  64,  48,  36],1,[26, 0, 0,  0,  0,  0],[ 1,100, 80, 2,50,32, 2,50,24, 4,25, 9],[ 0,  0,  0, 0,0 , 0, 0, 0, 0, 0, 0, 0])
	do @qrVersionInfo[ 5] :: (#@QrVersionInfo).init( 5, 134,[ 108,  86,  62,  46],1,[30, 0, 0,  0,  0,  0],[ 1,134,108, 2,67,43, 2,33,15, 2,33,11],[ 0,  0,  0, 0,0 , 0, 2,34,16, 2,34,12])
	do @qrVersionInfo[ 6] :: (#@QrVersionInfo).init( 6, 172,[ 136, 108,  76,  60],1,[34, 0, 0,  0,  0,  0],[ 2, 86, 68, 4,43,27, 4,43,19, 4,43,15],[ 0,  0,  0, 0,0 , 0, 0, 0, 0, 0, 0, 0])
	do @qrVersionInfo[ 7] :: (#@QrVersionInfo).init( 7, 196,[ 156, 124,  88,  66],2,[22,38, 0,  0,  0,  0],[ 2, 98, 78, 4,49,31, 2,32,14, 4,39,13],[ 0,  0,  0, 0,0 , 0, 4,33,15, 1,40,14])
	do @qrVersionInfo[ 8] :: (#@QrVersionInfo).init( 8, 242,[ 194, 154, 110,  86],2,[24,42, 0,  0,  0,  0],[ 2,121, 97, 2,60,38, 4,40,18, 4,40,14],[ 0,  0,  0, 2,61,39, 2,41,19, 2,41,15])
	do @qrVersionInfo[ 9] :: (#@QrVersionInfo).init( 9, 292,[ 232, 182, 132, 100],2,[26,46, 0,  0,  0,  0],[ 2,146,116, 3,58,36, 4,36,16, 4,36,12],[ 0,  0,  0, 2,59,37, 4,37,17, 4,37,13])
	do @qrVersionInfo[10] :: (#@QrVersionInfo).init(10, 346,[ 274, 216, 154, 122],2,[28,50, 0,  0,  0,  0],[ 2, 86, 68, 4,69,43, 6,43,19, 6,43,15],[ 2, 87, 69, 1,70,44, 2,44,20, 2,44,16])
	do @qrVersionInfo[11] :: (#@QrVersionInfo).init(11, 404,[ 324, 254, 180, 140],2,[30,54, 0,  0,  0,  0],[ 4,101, 81, 1,80,50, 4,50,22, 3,36,12],[ 0,  0,  0, 4,81,51, 4,51,23, 8,37,13])
	do @qrVersionInfo[12] :: (#@QrVersionInfo).init(12, 466,[ 370, 290, 206, 158],2,[32,58, 0,  0,  0,  0],[ 2,116, 92, 6,58,36, 4,46,20, 7,42,14],[ 2,117, 93, 2,59,37, 6,47,21, 4,43,15])
	do @qrVersionInfo[13] :: (#@QrVersionInfo).init(13, 532,[ 428, 334, 244, 180],2,[34,62, 0,  0,  0,  0],[ 4,133,107, 8,59,37, 8,44,20,12,33,11],[ 0,  0,  0, 1,60,38, 4,45,21, 4,34,12])
	do @qrVersionInfo[14] :: (#@QrVersionInfo).init(14, 581,[ 461, 365, 261, 197],3,[26,46,66,  0,  0,  0],[ 3,145,115, 4,64,40,11,36,16,11,36,12],[ 1,146,116, 5,65,41, 5,37,17, 5,37,13])
	do @qrVersionInfo[15] :: (#@QrVersionInfo).init(15, 655,[ 523, 415, 295, 223],3,[26,48,70,  0,  0,  0],[ 5,109, 87, 5,65,41, 5,54,24,11,36,12],[ 1,110, 88, 5,66,42, 7,55,25, 7,37,13])
	do @qrVersionInfo[16] :: (#@QrVersionInfo).init(16, 733,[ 589, 453, 325, 253],3,[26,50,74,  0,  0,  0],[ 5,122, 98, 7,73,45,15,43,19, 3,45,15],[ 1,123, 99, 3,74,46, 2,44,20,13,46,16])
	do @qrVersionInfo[17] :: (#@QrVersionInfo).init(17, 815,[ 647, 507, 367, 283],3,[30,54,78,  0,  0,  0],[ 1,135,107,10,74,46, 1,50,22, 2,42,14],[ 5,136,108, 1,75,47,15,51,23,17,43,15])
	do @qrVersionInfo[18] :: (#@QrVersionInfo).init(18, 901,[ 721, 563, 397, 313],3,[30,56,82,  0,  0,  0],[ 5,150,120, 9,69,43,17,50,22, 2,42,14],[ 1,151,121, 4,70,44, 1,51,23,19,43,15])
	do @qrVersionInfo[19] :: (#@QrVersionInfo).init(19, 991,[ 795, 627, 445, 341],3,[30,58,86,  0,  0,  0],[ 3,141,113, 3,70,44,17,47,21, 9,39,13],[ 4,142,114,11,71,45, 4,48,22,16,40,14])
	do @qrVersionInfo[20] :: (#@QrVersionInfo).init(20,1085,[ 861, 669, 485, 385],3,[34,62,90,  0,  0,  0],[ 3,135,107, 3,67,41,15,54,24,15,43,15],[ 5,136,108,13,68,42, 5,55,25,10,44,16])
	do @qrVersionInfo[21] :: (#@QrVersionInfo).init(21,1156,[ 932, 714, 512, 406],4,[28,50,72, 94,  0,  0],[ 4,144,116,17,68,42,17,50,22,19,46,16],[ 4,145,117, 0, 0, 0, 6,51,23, 6,47,17])
	do @qrVersionInfo[22] :: (#@QrVersionInfo).init(22,1258,[1006, 782, 568, 442],4,[26,50,74, 98,  0,  0],[ 2,139,111,17,74,46, 7,54,24,34,37,13],[ 7,140,112, 0, 0, 0,16,55,25, 0, 0, 0])
	do @qrVersionInfo[23] :: (#@QrVersionInfo).init(23,1364,[1094, 860, 614, 464],4,[30,54,78,102,  0,  0],[ 4,151,121, 4,75,47,11,54,24,16,45,15],[ 5,152,122,14,76,48,14,55,25,14,46,16])
	do @qrVersionInfo[24] :: (#@QrVersionInfo).init(24,1474,[1174, 914, 664, 514],4,[28,54,80,106,  0,  0],[ 6,147,117, 6,73,45,11,54,24,30,46,16],[ 4,148,118,14,74,46,16,55,25, 2,47,17])
	do @qrVersionInfo[25] :: (#@QrVersionInfo).init(25,1588,[1276,1000, 718, 538],4,[32,58,84,110,  0,  0],[ 8,132,106, 8,75,47, 7,54,24,22,45,15],[ 4,133,107,13,76,48,22,55,25,13,46,16])
	do @qrVersionInfo[26] :: (#@QrVersionInfo).init(26,1706,[1370,1062, 754, 596],4,[30,58,86,114,  0,  0],[10,142,114,19,74,46,28,50,22,33,46,16],[ 2,143,115, 4,75,47, 6,51,23, 4,47,17])
	do @qrVersionInfo[27] :: (#@QrVersionInfo).init(27,1828,[1468,1128, 808, 628],4,[34,62,90,118,  0,  0],[ 8,152,122,22,73,45, 8,53,23,12,45,15],[ 4,153,123, 3,74,46,26,54,24,28,46,16])
	do @qrVersionInfo[28] :: (#@QrVersionInfo).init(28,1921,[1531,1193, 871, 661],5,[26,50,74, 98,122,  0],[ 3,147,117, 3,73,45, 4,54,24,11,45,15],[10,148,118,23,74,46,31,55,25,31,46,16])
	do @qrVersionInfo[29] :: (#@QrVersionInfo).init(29,2051,[1631,1267, 911, 701],5,[30,54,78,102,126,  0],[ 7,146,116,21,73,45, 1,53,23,19,45,15],[ 7,147,117, 7,74,46,37,54,24,26,46,16])
	do @qrVersionInfo[30] :: (#@QrVersionInfo).init(30,2185,[1735,1373, 985, 745],5,[26,52,78,104,130,  0],[ 5,145,115,19,75,47,15,54,24,23,45,15],[10,146,116,10,76,48,25,55,25,25,46,16])
	do @qrVersionInfo[31] :: (#@QrVersionInfo).init(31,2323,[1843,1455,1033, 793],5,[30,56,82,108,134,  0],[13,145,115, 2,74,46,42,54,24,23,45,15],[ 3,146,116,29,75,47, 1,55,25,28,46,16])
	do @qrVersionInfo[32] :: (#@QrVersionInfo).init(32,2465,[1955,1541,1115, 845],5,[34,60,86,112,138,  0],[17,145,115,10,74,46,10,54,24,19,45,15],[ 0,  0,  0,23,75,47,35,55,25,35,46,16])
	do @qrVersionInfo[33] :: (#@QrVersionInfo).init(33,2611,[2071,1631,1171, 901],5,[30,58,86,114,142,  0],[17,145,115,14,74,46,29,54,24,11,45,15],[ 1,146,116,21,75,47,19,55,25,46,46,16])
	do @qrVersionInfo[34] :: (#@QrVersionInfo).init(34,2761,[2191,1725,1231, 961],5,[34,62,90,118,146,  0],[13,145,115,14,74,46,44,54,24,59,46,16],[ 6,146,116,23,75,47, 7,55,25, 1,47,17])
	do @qrVersionInfo[35] :: (#@QrVersionInfo).init(35,2876,[2306,1812,1286, 986],6,[30,54,78,102,126,150],[12,151,121,12,75,47,39,54,24,22,45,15],[ 7,152,122,26,76,48,14,55,25,41,46,16])
	do @qrVersionInfo[36] :: (#@QrVersionInfo).init(36,3034,[2434,1914,1354,1054],6,[24,50,76,102,128,154],[ 6,151,121, 6,75,47,46,54,24, 2,45,15],[14,152,122,34,76,48,10,55,25,64,46,16])
	do @qrVersionInfo[37] :: (#@QrVersionInfo).init(37,3196,[2566,1992,1426,1096],6,[28,54,80,106,132,158],[17,152,122,29,74,46,49,54,24,24,45,15],[ 4,153,123,14,75,47,10,55,25,46,46,16])
	do @qrVersionInfo[38] :: (#@QrVersionInfo).init(38,3362,[2702,2102,1502,1142],6,[32,58,84,110,136,162],[ 4,152,122,13,74,46,48,54,24,42,45,15],[18,153,123,32,75,47,14,55,25,32,46,16])
	do @qrVersionInfo[39] :: (#@QrVersionInfo).init(39,3532,[2812,2216,1582,1222],6,[26,54,82,110,138,166],[20,147,117,40,75,47,43,54,24,10,45,15],[ 4,148,118, 7,76,48,22,55,25,67,46,16])
	do @qrVersionInfo[40] :: (#@QrVersionInfo).init(40,3706,[2956,2334,1666,1276],6,[30,58,86,114,142,170],[19,148,118,18,75,47,34,54,24,20,45,15],[ 6,149,119,31,76,48,34,55,25,61,46,16])

	{GF(2^8)α指数→整数変換テーブル}
	do @byExpToInt :: [1b8,   2b8,   4b8,   8b8,  16b8,  32b8,  64b8, 128b8,  29b8,  58b8, 116b8, 232b8, 205b8, 135b8,  19b8,  38b8, 
	|                 76b8, 152b8,  45b8,  90b8, 180b8, 117b8, 234b8, 201b8, 143b8,   3b8,   6b8,  12b8,  24b8,  48b8,  96b8, 192b8,
	|                157b8,  39b8,  78b8, 156b8,  37b8,  74b8, 148b8,  53b8, 106b8, 212b8, 181b8, 119b8, 238b8, 193b8, 159b8,  35b8,
	|                 70b8, 140b8,   5b8,  10b8,  20b8,  40b8,  80b8, 160b8,  93b8, 186b8, 105b8, 210b8, 185b8, 111b8, 222b8, 161b8,
	|                 95b8, 190b8,  97b8, 194b8, 153b8,  47b8,  94b8, 188b8, 101b8, 202b8, 137b8,  15b8,  30b8,  60b8, 120b8, 240b8,
	|                253b8, 231b8, 211b8, 187b8, 107b8, 214b8, 177b8, 127b8, 254b8, 225b8, 223b8, 163b8,  91b8, 182b8, 113b8, 226b8,
	|                217b8, 175b8,  67b8, 134b8,  17b8,  34b8,  68b8, 136b8,  13b8,  26b8,  52b8, 104b8, 208b8, 189b8, 103b8, 206b8,
	|                129b8,  31b8,  62b8, 124b8, 248b8, 237b8, 199b8, 147b8,  59b8, 118b8, 236b8, 197b8, 151b8,  51b8, 102b8, 204b8,
	|                133b8,  23b8,  46b8,  92b8, 184b8, 109b8, 218b8, 169b8,  79b8, 158b8,  33b8,  66b8, 132b8,  21b8,  42b8,  84b8,
	|                168b8,  77b8, 154b8,  41b8,  82b8, 164b8,  85b8, 170b8,  73b8, 146b8,  57b8, 114b8, 228b8, 213b8, 183b8, 115b8,
	|                230b8, 209b8, 191b8,  99b8, 198b8, 145b8,  63b8, 126b8, 252b8, 229b8, 215b8, 179b8, 123b8, 246b8, 241b8, 255b8,
	|                227b8, 219b8, 171b8,  75b8, 150b8,  49b8,  98b8, 196b8, 149b8,  55b8, 110b8, 220b8, 165b8,  87b8, 174b8,  65b8,
	|                130b8,  25b8,  50b8, 100b8, 200b8, 141b8,   7b8,  14b8,  28b8,  56b8, 112b8, 224b8, 221b8, 167b8,  83b8, 166b8,
	|                 81b8, 162b8,  89b8, 178b8, 121b8, 242b8, 249b8, 239b8, 195b8, 155b8,  43b8,  86b8, 172b8,  69b8, 138b8,   9b8,
	|                 18b8,  36b8,  72b8, 144b8,  61b8, 122b8, 244b8, 245b8, 247b8, 243b8, 251b8, 235b8, 203b8, 139b8,  11b8,  22b8,
	|                 44b8,  88b8, 176b8, 125b8, 250b8, 233b8, 207b8, 131b8,  27b8,  54b8, 108b8, 216b8, 173b8,  71b8, 142b8,   1b8]

	{GF(2^8)α整数→指数変換テーブル}
	do @byIntToExp :: [0b8,   0b8,   1b8,  25b8,   2b8,  50b8,  26b8, 198b8,   3b8, 223b8,  51b8, 238b8,  27b8, 104b8, 199b8,  75b8,
	|                  4b8, 100b8, 224b8,  14b8,  52b8, 141b8, 239b8, 129b8,  28b8, 193b8, 105b8, 248b8, 200b8,   8b8,  76b8, 113b8,
	|                  5b8, 138b8, 101b8,  47b8, 225b8,  36b8,  15b8,  33b8,  53b8, 147b8, 142b8, 218b8, 240b8,  18b8, 130b8,  69b8,
	|                 29b8, 181b8, 194b8, 125b8, 106b8,  39b8, 249b8, 185b8, 201b8, 154b8,   9b8, 120b8,  77b8, 228b8, 114b8, 166b8,
	|                  6b8, 191b8, 139b8,  98b8, 102b8, 221b8,  48b8, 253b8, 226b8, 152b8,  37b8, 179b8,  16b8, 145b8,  34b8, 136b8,
	|                 54b8, 208b8, 148b8, 206b8, 143b8, 150b8, 219b8, 189b8, 241b8, 210b8,  19b8,  92b8, 131b8,  56b8,  70b8,  64b8,
	|                 30b8,  66b8, 182b8, 163b8, 195b8,  72b8, 126b8, 110b8, 107b8,  58b8,  40b8,  84b8, 250b8, 133b8, 186b8,  61b8,
	|                202b8,  94b8, 155b8, 159b8,  10b8,  21b8, 121b8,  43b8,  78b8, 212b8, 229b8, 172b8, 115b8, 243b8, 167b8,  87b8,
	|                  7b8, 112b8, 192b8, 247b8, 140b8, 128b8,  99b8,  13b8, 103b8,  74b8, 222b8, 237b8,  49b8, 197b8, 254b8,  24b8,
	|                227b8, 165b8, 153b8, 119b8,  38b8, 184b8, 180b8, 124b8,  17b8,  68b8, 146b8, 217b8,  35b8,  32b8, 137b8,  46b8,
	|                 55b8,  63b8, 209b8,  91b8, 149b8, 188b8, 207b8, 205b8, 144b8, 135b8, 151b8, 178b8, 220b8, 252b8, 190b8,  97b8,
	|                242b8,  86b8, 211b8, 171b8,  20b8,  42b8,  93b8, 158b8, 132b8,  60b8,  57b8,  83b8,  71b8, 109b8,  65b8, 162b8,
	|                 31b8,  45b8,  67b8, 216b8, 183b8, 123b8, 164b8, 118b8, 196b8,  23b8,  73b8, 236b8, 127b8,  12b8, 111b8, 246b8,
	|                108b8, 161b8,  59b8,  82b8,  41b8, 157b8,  85b8, 170b8, 251b8,  96b8, 134b8, 177b8, 187b8, 204b8,  62b8,  90b8,
	|                203b8,  89b8,  95b8, 176b8, 156b8, 169b8, 160b8,  81b8,  11b8, 245b8,  22b8, 235b8, 122b8, 117b8,  44b8, 215b8,
	|                 79b8, 174b8, 213b8, 233b8, 230b8, 231b8, 173b8, 232b8, 116b8, 214b8, 244b8, 234b8, 168b8,  80b8,  88b8, 175b8]

	{誤り訂正生成多項式α係数}
	var byRSExp7 : []int :: [ 87,229,146,149,238,102, 21]
	var byRSExp10: []int :: [251, 67, 46, 61,118, 70, 64, 94, 32, 45]
	var byRSExp13: []int :: [ 74,152,176,100, 86,100,106,104,130,218,206,140, 78]
	var byRSExp15: []int :: [  8,183, 61, 91,202, 37, 51, 58, 58,237,140,124,  5, 99,105]
	var byRSExp16: []int :: [120,104,107,109,102,161, 76,  3, 91,191,147,169,182,194,225,120]
	var byRSExp17: []int :: [ 43,139,206, 78, 43,239,123,206,214,147, 24, 99,150, 39,243,163,136]
	var byRSExp18: []int :: [215,234,158, 94,184, 97,118,170, 79,187,152,148,252,179,  5, 98, 96,153]
	var byRSExp20: []int :: [ 17, 60, 79, 50, 61,163, 26,187,202,180,221,225, 83,239,156,164,212,212,188,190]
	var byRSExp22: []int :: [210,171,247,242, 93,230, 14,109,221, 53,200, 74,  8,172, 98, 80,219,134,160,105,165,231]
	var byRSExp24: []int :: [229,121,135, 48,211,117,251,126,159,180,169,152,192,226,228,218,111,  0,117,232, 87, 96,227, 21]
	var byRSExp26: []int :: [173,125,158,  2,103,182,118, 17,145,201,111, 28,165, 53,161, 21,245,142, 13,102, 48,227,153,145,218, 70]
	var byRSExp28: []int :: [168,223,200,104,224,234,108,180,110,190,195,147,205, 27,232,201, 21, 43,245, 87, 42,195,212,119,242, 37,  9,123]
	var byRSExp30: []int :: [ 41,173,145,152,216, 31,179,182, 50, 48,110, 86,239, 96,222,125, 42,173,226,193,224,130,156, 37,251,216,238, 40,192,180]
	var byRSExp32: []int :: [ 10,  6,106,190,249,167,  4, 67,209,138,138, 32,242,123, 89, 27,120,185, 80,156, 38, 69,171, 60, 28,222, 80, 52,254,185,220,241]
	var byRSExp34: []int :: [111, 77,146, 94, 26, 21,108, 19,105, 94,113,193, 86,140,163,125, 58,158,229,239,218,103, 56, 70,114, 61,183,129,167, 13, 98, 62,129, 51]
	var byRSExp36: []int :: [200,183, 98, 16,172, 31,246,234, 60,152,115,  0,167,152,113,248,238,107, 18, 63,218, 37, 87,210,105,177,120, 74,121,196,117,251,113,233, 30,120]
	var byRSExp38: []int :: [159, 34, 38,228,230, 59,243, 95, 49,218,176,164, 20, 65, 45,111, 39, 81, 49,118,113,222,193,250,242,168,217, 41,164,247,177, 30,238, 18,120,153, 60,193]
	var byRSExp40: []int :: [ 59,116, 79,161,252, 98,128,205,128,161,247, 57,163, 56,235,106, 53, 26,187,174,226,104,170,  7,175, 35,181,114, 88, 41, 47,163,125,134, 72, 20,232, 53, 35, 15]
	var byRSExp42: []int :: [250,103,221,230, 25, 18,137,231,  0,  3, 58,242,221,191,110, 84,230,  8,188,106, 96,147, 15,131,139, 34,101,223, 39,101,213,199,237,254,201,123,171,162,194,117, 50, 96]
	var byRSExp44: []int :: [190,  7, 61,121, 71,246, 69, 55,168,188, 89,243,191, 25, 72,123,  9,145, 14,247,  1,238, 44, 78,143, 62,224,126,118,114, 68,163, 52,194,217,147,204,169, 37,130,113,102, 73,181]
	var byRSExp46: []int :: [112, 94, 88,112,253,224,202,115,187, 99, 89,  5, 54,113,129, 44, 58, 16,135,216,169,211, 36,  1,  4, 96, 60,241, 73,104,234,  8,249,245,119,174, 52, 25,157,224, 43,202,223, 19, 82, 15]
	var byRSExp48: []int :: [228, 25,196,130,211,146, 60, 24,251, 90, 39,102,240, 61,178, 63, 46,123,115, 18,221,111,135,160,182,205,107,206, 95,150,120,184, 91, 21,247,156,140,238,191, 11, 94,227, 84, 50,163, 39, 34,108]
	var byRSExp50: []int :: [232,125,157,161,164,  9,118, 46,209, 99,203,193, 35,  3,209,111,195,242,203,225, 46, 13, 32,160,126,209,130,160,242,215,242, 75, 77, 42,189, 32,113, 65,124, 69,228,114,235,175,124,170,215,232,133,205]
	var byRSExp52: []int :: [116, 50, 86,186, 50,220,251, 89,192, 46, 86,127,124, 19,184,233,151,215, 22, 14, 59,145, 37,242,203,134,254, 89,190, 94, 59, 65,124,113,100,233,235,121, 22, 76, 86, 97, 39,242,200,220,101, 33,239,254,116, 51]
	var byRSExp54: []int :: [183, 26,201, 87,210,221,113, 21, 46, 65, 45, 50,238,184,249,225,102, 58,209,218,109,165, 26, 95,184,192, 52,245, 35,254,238,175,172, 79,123, 25,122, 43,120,108,215, 80,128,201,235,  8,153, 59,101, 31,198, 76, 31,156]
	var byRSExp56: []int :: [106,120,107,157,164,216,112,116,  2, 91,248,163, 36,201,202,229,  6,144,254,155,135,208,170,209, 12,139,127,142,182,249,177,174,190, 28, 10, 85,239,184,101,124,152,206, 96, 23,163, 61, 27,196,247,151,154,202,207, 20, 61, 10]
	var byRSExp58: []int :: [ 82,116, 26,247, 66, 27, 62,107,252,182,200,185,235, 55,251,242,210,144,154,237,176,141,192,248,152,249,206, 85,253,142, 65,165,125, 23, 24, 30,122,240,214,  6,129,218, 29,145,127,134,206,245,117, 29, 41, 63,159,142,233,125,148,123]
	var byRSExp60: []int :: [107,140, 26, 12,  9,141,243,197,226,197,219, 45,211,101,219,120, 28,181,127,  6,100,247,  2,205,198, 57,115,219,101,109,160, 82, 37, 38,238, 49,160,209,121, 86, 11,124, 30,181, 84, 25,194, 87, 65,102,190,220, 70, 27,209, 16, 89,  7, 33,240]
	var byRSExp62: []int :: [ 65,202,113, 98, 71,223,248,118,214, 94,  0,122, 37, 23,  2,228, 58,121,  7,105,135, 78,243,118, 70, 76,223, 89, 72, 50, 70,111,194, 17,212,126,181, 35,221,117,235, 11,229,149,147,123,213, 40,115,  6,200,100, 26,246,182,218,127,215, 36,186,110,106]
	var byRSExp64: []int :: [ 45, 51,175,  9,  7,158,159, 49, 68,119, 92,123,177,204,187,254,200, 78,141,149,119, 26,127, 53,160, 93,199,212, 29, 24,145,156,208,150,218,209,  4,216, 91, 47,184,146, 47,140,195,195,125,242,238, 63, 99,108,140,230,242, 31,204, 11,178,243,217,156,213,231]
	var byRSExp66: []int :: [  5,118,222,180,136,136,162, 51, 46,117, 13,215, 81, 17,139,247,197,171, 95,173, 65,137,178, 68,111, 95,101, 41, 72,214,169,197, 95,  7, 44,154, 77,111,236, 40,121,143, 63, 87, 80,253,240,126,217, 77, 34,232,106, 50,168, 82, 76,146, 67,106,171, 25,132, 93, 45,105]
	var byRSExp68: []int :: [247,159,223, 33,224, 93, 77, 70, 90,160, 32,254, 43,150, 84,101,190,205,133, 52, 60,202,165,220,203,151, 93, 84, 15, 84,253,173,160, 89,227, 52,199, 97, 95,231, 52,177, 41,125,137,241,166,225,118,  2, 54, 32, 82,215,175,198, 43,238,235, 27,101,184,127,  3,  5,  8,163,238]
	do @byRSExp :: [     null, null,      null,       null,      null,      null,      null,  byRSExp7,      null, null,
	|               byRSExp10, null,      null,  byRSExp13,      null, byRSExp15, byRSExp16, byRSExp17, byRSExp18, null,
	|               byRSExp20, null, byRSExp22,       null, byRSExp24,      null, byRSExp26,      null, byRSExp28, null,
	|               byRSExp30, null, byRSExp32,       null, byRSExp34,      null, byRSExp36,      null, byRSExp38, null,
	|               byRSExp40, null, byRSExp42,       null, byRSExp44,      null, byRSExp46,      null, byRSExp48, null,
	|               byRSExp50, null, byRSExp52,       null, byRSExp54,      null, byRSExp56,      null, byRSExp58, null,
	|               byRSExp60, null, byRSExp62,       null, byRSExp64,      null, byRSExp66,      null, byRSExp68]

	{文字数インジケータビット長(バージョングループ別, {S, M, L})}
	do @nIndicatorLenNumeral  :: [10, 12, 14]
	do @nIndicatorLenAlphabet :: [ 9, 11, 13]
	do @nIndicatorLen8Bit     :: [ 8, 16, 16]
	do @nIndicatorLenKanji    :: [ 8, 10, 12]
end func

class QrEncode()
	var m_nLevel: int {誤り訂正レベル}
	var m_nVersion: int {バージョン(型番)}
	var m_bAutoExtent: int {バージョン(型番)自動拡張指定フラグ}
	var m_nMaskingNo: int {マスキングパターン番号}

	var m_nSymbleSize: int
	var m_byModuleData: [][]bit8 {[x][y]}
	{
	bit5:機能モジュール(マスキング対象外)フラグ
	bit4:機能モジュール描画データ
	bit1:エンコードデータ
	bit0:マスク後エンコード描画データ
	20hとの論理和により機能モジュール判定、11hとの論理和により描画(最終的にはBOOL値化)
	}

	var m_ncDataCodeWordBit: int {データコードワードビット長}
	var m_byDataCodeWord: []bit8 {入力データエンコードエリア}

	var m_ncDataBlock: int
	var m_byBlockMode: []bit8
	var m_nBlockLength: []int

	var m_ncAllCodeWord: int {総コードワード数(RS誤り訂正データを含む)}
	var m_byAllCodeWord: []bit8 {総コードワード算出エリア}
	var m_byRSWork: []bit8 {RSコードワード算出ワーク}

	func init(): @QrEncode
		if(@initializeFlag = false)
			do @initializeFlag :: true
			do @initialize()
		end if
		do me.m_nLevel :: 0
		do me.m_nVersion :: 0
		do me.m_bAutoExtent :: 0
		do me.m_nMaskingNo :: 0

		do me.m_nSymbleSize :: 0
		do me.m_byModuleData :: #[@MAX_MODULESIZE, @MAX_MODULESIZE]bit8

		do me.m_ncDataCodeWordBit :: 0
		do me.m_byDataCodeWord :: #[@MAX_DATACODEWORD]bit8

		do me.m_ncDataBlock :: 0
		do me.m_byBlockMode :: #[@MAX_DATACODEWORD]bit8
		do me.m_nBlockLength :: #[@MAX_DATACODEWORD]int

		do me.m_ncAllCodeWord :: 0
		do me.m_byAllCodeWord :: #[@MAX_ALLCODEWORD]bit8
		do me.m_byRSWork :: #[@MAX_CODEBLOCK]bit8
		ret me
	end func

	{
	用  途:データエンコード
	引  数:誤り訂正レベル、型番(0=自動)、型番自動拡張フラグ、マスキング番号(-1=自動)、エンコードしたいデータ、エンコードしたいデータの長さ(0=自動)
	戻り値:エンコード成功時=true、データなし、または容量オーバー時=false
	}
	+func encodeData(nLevel: int, nVersion: int, bAutoExtent: bool, nMaskingNo: int, lpsSource: []bit8, ncSource: int): bool
		do me.init()
		do me.m_nLevel :: nLevel
		do me.m_nMaskingNo :: nMaskingNo

		{データ長が指定されていない場合は lstrlen によって取得}
		var ncLength: int :: ncSource > 0 ?(ncSource, ^lpsSource)

		if(ncLength = 0)
			ret false {データなし}
		end if

		{バージョン(型番)チェック}
		var nEncodeVersion: int :: me.getEncodeVersion(nVersion, lpsSource, ncLength)

		if(nEncodeVersion = 0)
			ret false {容量オーバー}
		end if

		if(nVersion = 0)
			{型番自動}
			do me.m_nVersion :: nEncodeVersion
		else
			if(nEncodeVersion <= nVersion)
				do me.m_nVersion :: nVersion
			else
				if(bAutoExtent)
					do me.m_nVersion :: nEncodeVersion {バージョン(型番)自動拡張}
				else
					ret false {容量オーバー}
				end if
			end if
		end if

		{ターミネータコード"0000"付加}
		var ncDataCodeWord: int :: @qrVersionInfo[me.m_nVersion].ncDataCodeWord[nLevel]
		var ncTerminater: int :: lib@min(4, (ncDataCodeWord * 8) - me.m_ncDataCodeWordBit)

		if(ncTerminater > 0)
			do me.m_ncDataCodeWordBit :: me.SetBitStream(me.m_ncDataCodeWordBit, 0b16, ncTerminater)
		end if

		{パディングコード"11101100, 00010001"付加}
		const x_ec : bit8 :: 0xECb8
		var byPaddingCode: bit8 :: x_ec

		for i((me.m_ncDataCodeWordBit + 7) / 8, ncDataCodeWord - 1)
			do me.m_byDataCodeWord[i] :: byPaddingCode
			do byPaddingCode :: ((byPaddingCode = x_ec) ?(@x11, x_ec))
		end for

		{総コードワード算出エリアクリア}
		do me.m_ncAllCodeWord :: @qrVersionInfo[me.m_nVersion].ncAllCodeWord
		{ do ZeroMemory(me.m_byAllCodeWord, me.m_ncAllCodeWord) }
		do me.m_byAllCodeWord :: #[@MAX_ALLCODEWORD]bit8 {総コードワード算出エリア}

		var nDataCwIndex: int :: 0 {データコードワード処理位置}

		{データブロック分割数}
		var ncBlock1: int :: @qrVersionInfo[me.m_nVersion].rsBlockInfo1[nLevel].ncRSBlock
		var ncBlock2: int :: @qrVersionInfo[me.m_nVersion].rsBlockInfo2[nLevel].ncRSBlock
		var ncBlockSum: int :: ncBlock1 + ncBlock2

		var nBlockNo: int :: 0 {処理中ブロック番号}

		{ブロック別データコードワード数}
		var ncDataCw1: int :: @qrVersionInfo[me.m_nVersion].rsBlockInfo1[nLevel].ncBlockDataCodeWord
		var ncDataCw2: int :: @qrVersionInfo[me.m_nVersion].rsBlockInfo2[nLevel].ncBlockDataCodeWord

		{データコードワードインターリーブ配置}
		for i(0, ncBlock1 - 1)
			for j(0, ncDataCw1 - 1)
				do me.m_byAllCodeWord[(ncBlockSum * j) + nBlockNo] :: me.m_byDataCodeWord[nDataCwIndex]
				do nDataCwIndex :+ 1
			end for
			do nBlockNo :+ 1
		end for

		for i(0, ncBlock2 - 1)
			for j(0, ncDataCw2 - 1)
				if(j < ncDataCw1)
					do me.m_byAllCodeWord[(ncBlockSum * j) + nBlockNo] :: me.m_byDataCodeWord[nDataCwIndex]
				else
					{2種目ブロック端数分配置}
					do me.m_byAllCodeWord[(ncBlockSum * ncDataCw1) + i] :: me.m_byDataCodeWord[nDataCwIndex]
				end if
				do nDataCwIndex :+ 1
			end for
			do nBlockNo :+ 1
		end for

		{ブロック別RSコードワード数(※現状では同数)}
		var ncRSCw1: int :: @qrVersionInfo[me.m_nVersion].rsBlockInfo1[nLevel].ncBlockAllCodeWord - ncDataCw1
		var ncRSCw2: int :: @qrVersionInfo[me.m_nVersion].rsBlockInfo2[nLevel].ncBlockAllCodeWord - ncDataCw2

		{RSコードワード算出}
		do nDataCwIndex :: 0
		do nBlockNo :: 0

		for i(0, ncBlock1 - 1)
			{ do ZeroMemory(me.m_byRSWork, sizeof(me.m_byRSWork)) }
			do me.m_byRSWork :: #[@MAX_CODEBLOCK]bit8 {RSコードワード算出ワーク}
			do @memmove(me.m_byRSWork, me.m_byDataCodeWord, nDataCwIndex, ncDataCw1)
			do me.GetRSCodeWord(me.m_byRSWork, ncDataCw1, ncRSCw1)

			{RSコードワード配置}
			for j(0, ncRSCw1 - 1)
				do me.m_byAllCodeWord[ncDataCodeWord + (ncBlockSum * j) + nBlockNo] :: me.m_byRSWork[j]
			end for

			do nDataCwIndex :+ ncDataCw1
			do nBlockNo :+ 1
		end for

		for i(0, ncBlock2 - 1)
			{ do ZeroMemory(me.m_byRSWork, sizeof(me.m_byRSWork)) }
			do me.m_byRSWork :: #[@MAX_CODEBLOCK]bit8 {RSコードワード算出ワーク}
			do @memmove(me.m_byRSWork, me.m_byDataCodeWord, nDataCwIndex, ncDataCw2)
			do me.GetRSCodeWord(me.m_byRSWork, ncDataCw2, ncRSCw2)

			{RSコードワード配置}
			for j(0, ncRSCw2 - 1)
				do me.m_byAllCodeWord[ncDataCodeWord + (ncBlockSum * j) + nBlockNo] :: me.m_byRSWork[j]
			end for

			do nDataCwIndex :+ ncDataCw2
			do nBlockNo :+ 1
		end for

		do me.m_nSymbleSize :: me.m_nVersion * 4 + 17

		{モジュール配置}
		do me.formatModule()
		ret true
	end func

	{
	用  途:エンコード時バージョン(型番)取得
	引  数:調査開始バージョン、エンコードデータ、エンコードデータ長
	戻り値:バージョン番号(容量オーバー時=0)
	}
	func getEncodeVersion(nVersion: int, lpsSource: []bit8, ncLength: int): int
		var nVerGroup: int :: nVersion >= 27 ?(@QR_VRESION_L, (nVersion >= 10 ?(@QR_VRESION_M, @QR_VRESION_S)))

		for i(nVerGroup, @QR_VRESION_L)
			if(me.EncodeSourceData(lpsSource, ncLength, i))
				if(i = @QR_VRESION_S)
					for j(1, 9)
						if((me.m_ncDataCodeWordBit + 7) / 8 <= @qrVersionInfo[j].ncDataCodeWord[me.m_nLevel])
							ret j
						end if
					end for
				elif(i = @QR_VRESION_M)
					for j(10, 26)
						if((me.m_ncDataCodeWordBit + 7) / 8 <= @qrVersionInfo[j].ncDataCodeWord[me.m_nLevel])
							ret j
						end if
					end for
				elif(i = @QR_VRESION_L)
					for j(27, 40)
						if((me.m_ncDataCodeWordBit + 7) / 8 <= @qrVersionInfo[j].ncDataCodeWord[me.m_nLevel])
							ret j
						end if
					end for
				end if
			end if
		end for

		ret 0
	end func

	{
	用  途:入力データエンコード
	引  数:入力データ、入力データ長、バージョン(型番)グループ
	戻り値:エンコード成功時=true
	}
	func EncodeSourceData(lpsSource: []bit8, ncLength: int, nVerGroup: int): bool
		{ do ZeroMemory(me.m_nBlockLength, sizeof(me.m_nBlockLength)) }
		do me.m_nBlockLength :: #[@MAX_DATACODEWORD]int

		{どのモードが何文字(バイト)継続しているかを調査}
		do me.m_ncDataBlock :: 0
		for i(0, ncLength - 1)
			var byMode: bit8
			if(i < ncLength - 1 & me.IsKanjiData(lpsSource[i], lpsSource[i + 1]))
				do byMode :: @QR_MODE_KANJI
			elif(me.IsNumeralData(lpsSource[i]))
				do byMode :: @QR_MODE_NUMERAL
			elif(me.IsAlphabetData(lpsSource[i]))
				do byMode :: @QR_MODE_ALPHABET
			else
				do byMode :: @QR_MODE_8BIT
			end if

			if(i = 0)
				do me.m_byBlockMode[0] :: byMode
			end if

			if(me.m_byBlockMode[me.m_ncDataBlock] <> byMode)
				do me.m_ncDataBlock :+ 1
				do me.m_byBlockMode[me.m_ncDataBlock] :: byMode
			end if

			if(byMode = @QR_MODE_KANJI)
				do me.m_nBlockLength[me.m_ncDataBlock] :+ 2
				do i :+ 1
			else
				do me.m_nBlockLength[me.m_ncDataBlock] :+ 1
			end if
		end for

		do me.m_ncDataBlock :+ 1

		{隣接する英数字モードブロックと数字モードブロックの並びをを条件により結合}
		var ncSrcBits: int {元のビット長}
		var ncDstBits: int {単一の英数字モードブロック化した場合のビット長}
		var nBlock: int :: 0
		while a(nBlock < me.m_ncDataBlock - 1)
			var ncJoinFront:   int {前8ビットバイトモードブロックと結合した場合のビット長}
			var ncJoinBehind:  int {後8ビットバイトモードブロックと結合した場合のビット長}
			var nJoinPosition: int :: 0 {8ビットバイトモードブロックとの結合:-1=前と結合、0=結合しない、1=後ろと結合}

			{「数字-英数字」または「英数字-数字」の並び}
			if(  (me.m_byBlockMode[nBlock] = @QR_MODE_NUMERAL  & me.m_byBlockMode[nBlock + 1] = @QR_MODE_ALPHABET) |
				|(me.m_byBlockMode[nBlock] = @QR_MODE_ALPHABET & me.m_byBlockMode[nBlock + 1] = @QR_MODE_NUMERAL))
				{元のビット長と単一の英数字モードブロック化した場合のビット長を比較}
				do ncSrcBits :: me.GetBitLength(me.m_byBlockMode[nBlock    ], me.m_nBlockLength[nBlock    ], nVerGroup) +
				|               me.GetBitLength(me.m_byBlockMode[nBlock + 1], me.m_nBlockLength[nBlock + 1], nVerGroup)
				do ncDstBits :: me.GetBitLength(@QR_MODE_ALPHABET, me.m_nBlockLength[nBlock] + me.m_nBlockLength[nBlock + 1], nVerGroup)
				if(ncSrcBits > ncDstBits)
					{前後に8ビットバイトモードブロックがある場合、それらとの結合が有利かどうかをチェック}
					if(nBlock >= 1 & me.m_byBlockMode[nBlock - 1] = @QR_MODE_8BIT)
						{前に8ビットバイトモードブロックあり}
						do ncJoinFront :: me.GetBitLength(@QR_MODE_8BIT, me.m_nBlockLength[nBlock - 1] + me.m_nBlockLength[nBlock], nVerGroup) +
						|                 me.GetBitLength(me.m_byBlockMode[nBlock + 1], me.m_nBlockLength[nBlock + 1], nVerGroup)

						if(ncJoinFront > ncDstBits + me.GetBitLength(@QR_MODE_8BIT, me.m_nBlockLength[nBlock - 1], nVerGroup))
							do ncJoinFront :: 0 {8ビットバイトモードブロックとは結合しない}
						end if
					else
						do ncJoinFront :: 0
					end if

					if(nBlock < me.m_ncDataBlock - 2 & me.m_byBlockMode[nBlock + 2] = @QR_MODE_8BIT)
						{後ろに8ビットバイトモードブロックあり}
						do ncJoinBehind :: me.GetBitLength(me.m_byBlockMode[nBlock], me.m_nBlockLength[nBlock], nVerGroup) +
						|                  me.GetBitLength(@QR_MODE_8BIT, me.m_nBlockLength[nBlock + 1] + me.m_nBlockLength[nBlock + 2], nVerGroup)

						if(ncJoinBehind > ncDstBits + me.GetBitLength(@QR_MODE_8BIT, me.m_nBlockLength[nBlock + 2], nVerGroup))
							do ncJoinBehind :: 0 {8ビットバイトモードブロックとは結合しない}
						end if
					else
						do ncJoinBehind :: 0
					end if

					if(ncJoinFront <> 0 & ncJoinBehind <> 0)
						{前後両方に8ビットバイトモードブロックがある場合はデータ長が短くなる方を優先}
						do nJoinPosition :: (ncJoinFront < ncJoinBehind) ?(-1, 1)
					else
						do nJoinPosition :: (ncJoinFront <> 0) ?(-1, (ncJoinBehind <> 0) ?(1, 0))
					end if

					if(nJoinPosition <> 0)
						{8ビットバイトモードブロックとの結合}
						if(nJoinPosition = -1)
							do me.m_nBlockLength[nBlock - 1] :+ me.m_nBlockLength[nBlock]

							{後続をシフト}
							for i(nBlock, me.m_ncDataBlock - 2)
								do me.m_byBlockMode[i]  :: me.m_byBlockMode[i + 1]
								do me.m_nBlockLength[i] :: me.m_nBlockLength[i + 1]
							end for
						else
							do me.m_byBlockMode[nBlock + 1] :: @QR_MODE_8BIT
							do me.m_nBlockLength[nBlock + 1] :+ me.m_nBlockLength[nBlock + 2]

							{後続をシフト}
							for i(nBlock + 2, me.m_ncDataBlock - 2)
								do me.m_byBlockMode[i]  :: me.m_byBlockMode[i + 1]
								do me.m_nBlockLength[i] :: me.m_nBlockLength[i + 1]
							end for
						end if
						do me.m_ncDataBlock :- 1
					else
						{英数字と数字の並びを単一の英数字モードブロックに統合}
						if(nBlock < me.m_ncDataBlock - 2 & me.m_byBlockMode[nBlock + 2] = @QR_MODE_ALPHABET)
							{結合しようとするブロックの後ろに続く英数字モードブロックを結合}
							do me.m_nBlockLength[nBlock + 1] :+ me.m_nBlockLength[nBlock + 2]
							{後続をシフト}
							for i(nBlock + 2, me.m_ncDataBlock - 2)
								do me.m_byBlockMode[i]  :: me.m_byBlockMode[i + 1]
								do me.m_nBlockLength[i] :: me.m_nBlockLength[i + 1]
							end for
							do me.m_ncDataBlock :- 1
						end if

						do me.m_byBlockMode[nBlock] :: @QR_MODE_ALPHABET
						do me.m_nBlockLength[nBlock] :+ me.m_nBlockLength[nBlock + 1]

						{後続をシフト}
						for i(nBlock + 1, me.m_ncDataBlock - 2)
							do me.m_byBlockMode[i]  :: me.m_byBlockMode[i + 1]
							do me.m_nBlockLength[i] :: me.m_nBlockLength[i + 1]
						end for

						do me.m_ncDataBlock :- 1

						if(nBlock >= 1 & me.m_byBlockMode[nBlock - 1] = @QR_MODE_ALPHABET)
							{結合したブロックの前の英数字モードブロックを結合}
							do me.m_nBlockLength[nBlock - 1] :+ me.m_nBlockLength[nBlock]

							{後続をシフト}
							for i(nBlock, me.m_ncDataBlock - 2)
								do me.m_byBlockMode[i]  :: me.m_byBlockMode[i + 1]
								do me.m_nBlockLength[i] :: me.m_nBlockLength[i + 1]
							end for

							do me.m_ncDataBlock :- 1
						end if
					end if

					skip a {現在位置のブロックを再調査}
				end if
			end if

			do nBlock :+ 1 {次ブロックを調査}
		end while

		{連続する短いモードブロックを8ビットバイトモードブロック化}
		do nBlock :: 0
		while a(nBlock < me.m_ncDataBlock - 1)
			do ncSrcBits :: me.GetBitLength(me.m_byBlockMode[nBlock    ], me.m_nBlockLength[nBlock    ], nVerGroup) +
			|               me.GetBitLength(me.m_byBlockMode[nBlock + 1], me.m_nBlockLength[nBlock + 1], nVerGroup)
			do ncDstBits :: me.GetBitLength(@QR_MODE_8BIT, me.m_nBlockLength[nBlock] + me.m_nBlockLength[nBlock + 1], nVerGroup)

			{前に8ビットバイトモードブロックがある場合、重複するインジケータ分を減算}
			if(nBlock >= 1 & me.m_byBlockMode[nBlock - 1] = @QR_MODE_8BIT)
				do ncDstBits :- (4 + @nIndicatorLen8Bit[nVerGroup])
			end if

			{後ろに8ビットバイトモードブロックがある場合、重複するインジケータ分を減算}
			if(nBlock < me.m_ncDataBlock - 2 & me.m_byBlockMode[nBlock + 2] = @QR_MODE_8BIT)
				do ncDstBits :- (4 + @nIndicatorLen8Bit[nVerGroup])
			end if

			if(ncSrcBits > ncDstBits)
				if(nBlock >= 1 & me.m_byBlockMode[nBlock - 1] = @QR_MODE_8BIT)
					{結合するブロックの前にある8ビットバイトモードブロックを結合}
					do me.m_nBlockLength[nBlock - 1] :+ me.m_nBlockLength[nBlock]

					{後続をシフト}
					for i(nBlock, me.m_ncDataBlock - 2)
						do me.m_byBlockMode[i]  :: me.m_byBlockMode[i + 1]
						do me.m_nBlockLength[i] :: me.m_nBlockLength[i + 1]
					end for

					do me.m_ncDataBlock :- 1
					do nBlock :- 1
				end if

				if(nBlock < me.m_ncDataBlock - 2 & me.m_byBlockMode[nBlock + 2] = @QR_MODE_8BIT)
					{結合するブロックの後ろにある8ビットバイトモードブロックを結合}
					do me.m_nBlockLength[nBlock + 1] :+ me.m_nBlockLength[nBlock + 2]

					{後続をシフト}
					for i(nBlock + 2, me.m_ncDataBlock - 2)
						do me.m_byBlockMode[i]  :: me.m_byBlockMode[i + 1]
						do me.m_nBlockLength[i] :: me.m_nBlockLength[i + 1]
					end for

					do me.m_ncDataBlock :- 1
				end if

				do me.m_byBlockMode[nBlock] :: @QR_MODE_8BIT
				do me.m_nBlockLength[nBlock] :+ me.m_nBlockLength[nBlock + 1]

				{後続をシフト}
				for i(nBlock + 1, me.m_ncDataBlock - 2)
					do me.m_byBlockMode[i]  :: me.m_byBlockMode[i + 1]
					do me.m_nBlockLength[i] :: me.m_nBlockLength[i + 1]
				end for

				do me.m_ncDataBlock :- 1

				{結合したブロックの前から再調査}
				if(nBlock >= 1)
					do nBlock :- 1
				end if
				skip a
			end if

			do nBlock :+ 1 {次ブロックを調査}
		end while

		{ビット配列化}
		var ncComplete: int :: 0 {処理済データカウンタ}
		var wBinCode: bit16

		do me.m_ncDataCodeWordBit :: 0 {ビット単位処理カウンタ}

		{ do ZeroMemory(me.m_byDataCodeWord, @MAX_DATACODEWORD) }
		do me.m_byDataCodeWord :: #[@MAX_DATACODEWORD]bit8 {入力データエンコードエリア}

		var i: int :: 0
		while(i < me.m_ncDataBlock & me.m_ncDataCodeWordBit <> -1)
			if(me.m_byBlockMode[i] = @QR_MODE_NUMERAL) {数字モード}
				{インジケータ(0001b)}
				do me.m_ncDataCodeWordBit :: me.SetBitStream(me.m_ncDataCodeWordBit, 1b16, 4)
				{文字数セット}
				do me.m_ncDataCodeWordBit :: me.SetBitStream(me.m_ncDataCodeWordBit, me.m_nBlockLength[i] $ bit16, @nIndicatorLenNumeral[nVerGroup])
				{ビット列保存}
				for j(0, me.m_nBlockLength[i] - 1, 3)
					if(j < me.m_nBlockLength[i] - 2)
						do wBinCode :: (  ((lpsSource[ncComplete + j    ] $ int - '0' $ int) * 100) +
						|                 ((lpsSource[ncComplete + j + 1] $ int - '0' $ int) *  10) +
						|                  (lpsSource[ncComplete + j + 2] $ int - '0' $ int)) $ bit16
						do me.m_ncDataCodeWordBit :: me.SetBitStream(me.m_ncDataCodeWordBit, wBinCode, 10)
					elif(j = me.m_nBlockLength[i] - 2)
						{端数2バイト}
						do wBinCode :: (  ((lpsSource[ncComplete + j    ] $ int - '0' $ int) *  10) +
						|                  (lpsSource[ncComplete + j + 1] $ int - '0' $ int)) $ bit16
						do me.m_ncDataCodeWordBit :: me.SetBitStream(me.m_ncDataCodeWordBit, wBinCode,  7)
					elif(j = me.m_nBlockLength[i] - 1)
						{端数1バイト}
						do wBinCode ::     (lpsSource[ncComplete + j    ] $ int - '0' $ int) $ bit16
						do me.m_ncDataCodeWordBit :: me.SetBitStream(me.m_ncDataCodeWordBit, wBinCode,  4)
					end if
				end for
				do ncComplete :+ me.m_nBlockLength[i]

			elif(me.m_byBlockMode[i] = @QR_MODE_ALPHABET) {英数字モード}
				{モードインジケータ(0010b)}
				do me.m_ncDataCodeWordBit :: me.SetBitStream(me.m_ncDataCodeWordBit, 2b16, 4)
				{文字数セット}
				do me.m_ncDataCodeWordBit :: me.SetBitStream(me.m_ncDataCodeWordBit, me.m_nBlockLength[i] $ bit16, @nIndicatorLenAlphabet[nVerGroup])
				{ビット列保存}
				for j(0, me.m_nBlockLength[i] - 1, 2)
					if(j < me.m_nBlockLength[i] - 1)
						do wBinCode :: ((me.AlphabetToBinaly(lpsSource[ncComplete + j    ]) * 45) +
						|                me.AlphabetToBinaly(lpsSource[ncComplete + j + 1])) $ bit16
						do me.m_ncDataCodeWordBit :: me.SetBitStream(me.m_ncDataCodeWordBit, wBinCode, 11)
					else
						{端数1バイト}
						do wBinCode :: me.AlphabetToBinaly(lpsSource[ncComplete + j]) $ bit16
						do me.m_ncDataCodeWordBit :: me.SetBitStream(me.m_ncDataCodeWordBit, wBinCode, 6)
					end if
				end for
				do ncComplete :+ me.m_nBlockLength[i]
			elif(me.m_byBlockMode[i] = @QR_MODE_8BIT) {8ビットバイトモード}
				{モードインジケータ(0100b)}
				do me.m_ncDataCodeWordBit :: me.SetBitStream(me.m_ncDataCodeWordBit, 4b16, 4)
				{文字数セット}
				do me.m_ncDataCodeWordBit :: me.SetBitStream(me.m_ncDataCodeWordBit, me.m_nBlockLength[i] $ bit16, @nIndicatorLen8Bit[nVerGroup])
				{ビット列保存}
				for j(0, me.m_nBlockLength[i] - 1)
					do me.m_ncDataCodeWordBit :: me.SetBitStream(me.m_ncDataCodeWordBit, lpsSource[ncComplete + j] $ bit16, 8)
				end for
				do ncComplete :+ me.m_nBlockLength[i]
			else {me.m_byBlockMode[i] = @QR_MODE_KANJI} {漢字モード}
				{モードインジケータ(1000b)}
				do me.m_ncDataCodeWordBit :: me.SetBitStream(me.m_ncDataCodeWordBit, 8b16, 4)
				{文字数セット}
				do me.m_ncDataCodeWordBit :: me.SetBitStream(me.m_ncDataCodeWordBit, (me.m_nBlockLength[i] / 2) $ bit16, @nIndicatorLenKanji[nVerGroup])
				{漢字モードでビット列保存}
				for j(0, me.m_nBlockLength[i] - 1, 2)
					do wBinCode :: me.KanjiToBinaly((lpsSource[ncComplete + j] $ bit16).shl(8) + lpsSource[ncComplete + j + 1] $ bit16)
					do me.m_ncDataCodeWordBit :: me.SetBitStream(me.m_ncDataCodeWordBit, wBinCode, 13)
				end for
				do ncComplete :+ me.m_nBlockLength[i]
			end if
			do i :+ 1
		end while

		ret (me.m_ncDataCodeWordBit <> -1)
	end func

	{
	用  途:ビット長取得
	引  数:データモード種別、データ長、バージョン(型番)グループ
	戻り値:データビット長
	備  考:漢字モードでのデータ長引数は文字数ではなくバイト数
	}
	func GetBitLength(nMode: bit8, ncData: int, nVerGroup: int): int
		var ncBits: int ::  0

		switch (nMode)
		case @QR_MODE_NUMERAL
			do ncBits :: 4 + @nIndicatorLenNumeral[nVerGroup] + (10 * (ncData / 3))
			switch(ncData % 3)
			case 1
				do ncBits :+ 4
			case 2
				do ncBits :+ 7
			default {case (0)}
			end switch
		case @QR_MODE_ALPHABET
			do ncBits :: 4 + @nIndicatorLenAlphabet[nVerGroup] + (11 * (ncData / 2)) + (6 * (ncData % 2))
		case @QR_MODE_8BIT
			do ncBits :: 4 + @nIndicatorLen8Bit[nVerGroup]     + ( 8 * ncData)
		default {case @QR_MODE_KANJI}
			do ncBits :: 4 + @nIndicatorLenKanji[nVerGroup]    + (13 * (ncData / 2))
		end switch

		ret ncBits
	end func

	{
	用  途:ビットセット
	引  数:挿入位置、ビット配列データ、データビット長(最大16)
	戻り値:次回挿入位置(バッファオーバー時=-1)
	備  考:me.m_byDataCodeWord に結果をセット(要ゼロ初期化)
	}
	func SetBitStream(nIndex: int, wData: bit16, ncData: int): int
		if(nIndex = -1 | nIndex + ncData > @MAX_DATACODEWORD * 8)
			ret -1
		end if

		for i(0, ncData - 1)
			if(wData.and((1b16).shl(ncData - i - 1)) <> 0b16)
				do me.m_byDataCodeWord[(nIndex + i) / 8] :: me.m_byDataCodeWord[(nIndex + i) / 8].or((1b8).shl(7 - ((nIndex + i) % 8)))
			end if
		end for

		ret nIndex + ncData
	end func

	{
	用  途:数字モード該当チェック
	引  数:調査文字
	戻り値:該当時=true
	}
	func IsNumeralData(c: bit8): bool
		switch(c $ char)
		case '0' to '9'
			ret true
		end switch
		ret false
	end func

	{
	用  途:英数字モード該当チェック
	引  数:調査文字
	戻り値:該当時=true
	}
	func IsAlphabetData(c: bit8): bool
		switch(c $ char)
		case '0' to '9'
			ret true
		case 'A' to 'Z'
			ret true
		case ' ',  '$',  '%',  '*',  '+',  '-',  '.',  '/',  ':'
			ret true
		end switch
		ret false
	end func

	{
	用  途:漢字モード該当チェック
	引  数:調査文字(16ビット文字)
	戻り値:該当時=true
	備  考:EBBFh 以降の S-JIS は対象外
	}
	func IsKanjiData(c1: bit8, c2: bit8): bool
		if(   ((c1 >= 0x81b8 & c1 <= 0x9Fb8) | (c1 >= 0xE0b8 & c1 <= 0xEBb8)) & (c2 >= 0x40b8))
			if((c1  = 0x9Fb8 & c2 >  0xFCb8) | (c1  = 0xEBb8 & c2 >  0xBFb8))
				ret false
			end if
			ret true
		end if
		ret false
	end func

	{
	用  途:英数字モード文字のバイナリ化
	引  数:対象文字
	戻り値:バイナリ値
	}
	func AlphabetToBinaly(c: bit8): int
		switch(c $ char)
		case '0' to '9'
			ret (c $ int - '0' $ int)
		case 'A' to 'Z'
			ret (c $ int - 'A' $ int + 10)
		case ' '
			ret 36
		case '$'
			ret 37
		case '%'
			ret 38
		case '*'
			ret 39
		case '+'
			ret 40
		case '-'
			ret 41
		case '.'
			ret 42
		case '/'
			ret 43
		default
			ret 44 {case ':'}
		end switch
	end func

	{
	用  途:漢字モード文字のバイナリ化
	引  数:対象文字
	戻り値:バイナリ値
	}
	func KanjiToBinaly(wc: bit16): bit16
		switch(wc)
		case 0x8140b16 to 0x9FFCb16
			do wc :: (wc $ int - 0x8140) $ bit16
		default {case 0xe040 to 0xebbf}
			do wc :: (wc $ int - 0xC140) $ bit16
		end switch
		ret wc.shr(8) * 0xC0b16 + wc.and(0x00FFb16)
	end func

	{
	用  途:RS誤り訂正コードワード取得
	引  数:データコードワードアドレス、データコードワード長、RSコードワード長
	備  考:総コードワード分のエリアを確保してから呼び出し
	}
	func GetRSCodeWord(lpbyRSWork: []bit8, ncDataCodeWord: int, ncRSCodeWord: int)
		for(1, ncDataCodeWord)
			if(lpbyRSWork[0] <> @x00)
				var nExpFirst: bit8 :: @byIntToExp[lpbyRSWork[0] $ int] {初項係数より乗数算出}

				for j(0, ncRSCodeWord - 1)
					{各項乗数に初項乗数を加算(% 255 → α^255 = 1}
					var nExpElement: bit8 :: (((@byRSExp[ncRSCodeWord][j] + nExpFirst $ int)) % 255) $ bit8

					{排他論理和による剰余算出}
					do lpbyRSWork[j] :: lpbyRSWork[j + 1].xor(@byExpToInt[nExpElement $ int])
				end for

				{残り桁をシフト}
				for j(ncRSCodeWord, ncDataCodeWord + ncRSCodeWord - 2)
					do lpbyRSWork[j] :: lpbyRSWork[j + 1]
				end for
			else
				{残り桁をシフト}
				for j(0, ncDataCodeWord + ncRSCodeWord - 2)
					do lpbyRSWork[j] :: lpbyRSWork[j + 1]
				end for
			end if
		end for
	end func

	{
	用  途:モジュールへのデータ配置
	戻り値:一辺のモジュール数
	}
	func formatModule()
		{ do ZeroMemory(me.m_byModuleData, sizeof(me.m_byModuleData)) }
		do me.m_byModuleData :: #[@MAX_MODULESIZE, @MAX_MODULESIZE]bit8

		{機能モジュール配置}
		do me.setFunctionModule()

		{データパターン配置}
		do me.setCodeWordPattern()

		if(me.m_nMaskingNo = -1)
			{最適マスキングパターン選択}
			do me.m_nMaskingNo :: 0

			do me.SetMaskingPattern(me.m_nMaskingNo) {マスキング}
			do me.SetFormatInfoPattern(me.m_nMaskingNo) {フォーマット情報パターン配置}

			var nMinPenalty: int :: me.countPenalty()

			for i(1, 7)
				do me.SetMaskingPattern(i) {マスキング}
				do me.SetFormatInfoPattern(i) {フォーマット情報パターン配置}

				var nPenalty: int :: me.countPenalty()

				if(nPenalty < nMinPenalty)
					do nMinPenalty :: nPenalty
					do me.m_nMaskingNo :: i
				end if
			end for
		end if

		do me.SetMaskingPattern(me.m_nMaskingNo) {マスキング}
		do me.SetFormatInfoPattern(me.m_nMaskingNo) {フォーマット情報パターン配置}

		{モジュールパターンをブール値に変換}
		for i(0, me.m_nSymbleSize - 1)
			for j(0, me.m_nSymbleSize - 1)
				do me.m_byModuleData[i][j] :: (me.m_byModuleData[i][j].and(@x11) <> @x00) $ bit8
			end for
		end for
	end func

	{
	用  途:機能モジュール配置
	備  考:フォーマット情報は機能モジュール登録のみ(実データは空白)
	}
	func setFunctionModule()
		{位置検出パターン}
		do me.SetFinderPattern(0, 0)
		do me.SetFinderPattern(me.m_nSymbleSize - 7, 0)
		do me.SetFinderPattern(0, me.m_nSymbleSize - 7)

		{位置検出パターンセパレータ}
		for i(0, 7)
			do me.m_byModuleData[i][7] :: @x20
			do me.m_byModuleData[7][i] :: @x20
			do me.m_byModuleData[me.m_nSymbleSize - 8    ][i] :: @x20
			do me.m_byModuleData[me.m_nSymbleSize - 8 + i][7] :: @x20
			do me.m_byModuleData[i][me.m_nSymbleSize - 8    ] :: @x20
			do me.m_byModuleData[7][me.m_nSymbleSize - 8 + i] :: @x20
		end for

		{フォーマット情報記述位置を機能モジュール部として登録}
		for i(0, 8)
			do me.m_byModuleData[i][8] :: @x20
			do me.m_byModuleData[8][i] :: @x20
		end for

		for i(0, 7)
			do me.m_byModuleData[me.m_nSymbleSize - 8 + i][8] :: @x20
			do me.m_byModuleData[8][me.m_nSymbleSize - 8 + i] :: @x20
		end for

		{バージョン情報パターン}
		do me.SetVersionPattern()

		{位置合わせパターン}
		for i(0, @qrVersionInfo[me.m_nVersion].ncAlignPoint - 1)
			do me.SetAlignmentPattern(@qrVersionInfo[me.m_nVersion].nAlignPoint[i], 6)
			do me.SetAlignmentPattern(6, @qrVersionInfo[me.m_nVersion].nAlignPoint[i])
			for j(0, @qrVersionInfo[me.m_nVersion].ncAlignPoint - 1)
				do me.SetAlignmentPattern(@qrVersionInfo[me.m_nVersion].nAlignPoint[i], @qrVersionInfo[me.m_nVersion].nAlignPoint[j])
			end for
		end for

		{タイミングパターン}
		for i(8, me.m_nSymbleSize - 9)
			do me.m_byModuleData[i][6] :: ((i % 2) = 0) ?(@x30, @x20)
			do me.m_byModuleData[6][i] :: ((i % 2) = 0) ?(@x30, @x20)
		end for
	end func

	{
	用  途:位置検出パターン配置
	引  数:配置左上座標
	}
	func SetFinderPattern(x: int, y: int)
		var byPattern: []bit8 :: [0x7Fb8, {1111111b}
		|                         0x41b8, {1000001b}
		|                         0x5Db8, {1011101b}
		|                         0x5Db8, {1011101b}
		|                         0x5Db8, {1011101b}
		|                         0x41b8, {1000001b}
		|                         0x7Fb8] {1111111b}
		for i(0, 6)
			for j(0, 6)
				do me.m_byModuleData[x + j][y + i] :: (byPattern[i].and((1b8).shl(6 - j)) <> @x00) ?(@x30, @x20)
			end for
		end for
	end func

	{
	用  途:位置合わせパターン配置
	引  数:配置中央座標
	}
	func SetAlignmentPattern(x: int, y: int)
		var byPattern: []bit8 :: [0x1Fb8, {11111b}
		|                         0x11b8, {10001b}
		|                         0x15b8, {10101b}
		|                         0x11b8, {10001b}
		|                         0x1Fb8] {11111b}
		if(me.m_byModuleData[x][y].and(@x20) <> @x00)
			ret {機能モジュールと重複するため除外}
		end if

		{左上隅座標に変換}
		do x :- 2
		do y :- 2

		for i(0, 4)
			for j(0, 4)
				do me.m_byModuleData[x + j][y + i] :: (byPattern[i].and((1b8).shl(4 - j)) <> @x00) ?(@x30, @x20)
			end for
		end for
	end func

	{
	用  途:バージョン(型番)情報パターン配置
	備  考:拡張BCH(18,6)符号を誤り訂正として使用
	}
	func SetVersionPattern()
		if(me.m_nVersion <= 6)
			ret
		end if

		var nVerData: bit64 :: (me.m_nVersion $ bit64).shl(12)

		{剰余ビット算出}
		for i(0, 5)
			if(nVerData.and((1b64).shl(17 - i)) <> 0b64)
				do nVerData :: nVerData.xor((0x1F25b64).shl(5 - i))
			end if
		end for

		do nVerData :+ (me.m_nVersion $ bit64).shl(12)

		for i(0, 5)
			for j(0, 2)
				do me.m_byModuleData[i][me.m_nSymbleSize - 11 + j] :: (nVerData.and((1b64).shl(i * 3 + j)) <> 0b64) ?(@x30, @x20)
				do me.m_byModuleData[me.m_nSymbleSize - 11 + j][i] :: me.m_byModuleData[i][me.m_nSymbleSize - 11 + j]
			end for
		end for
	end func

	{
	用  途:データパターン配置
	}
	func setCodeWordPattern()
		var x: int :: me.m_nSymbleSize
		var y: int :: me.m_nSymbleSize - 1

		var nCoef_x:int :: 1 {x軸配置向き}
		var nCoef_y:int :: 1 {y軸配置向き}

		for i(0, me.m_ncAllCodeWord - 1)
			for j(0, 7)
				while(me.m_byModuleData[x][y].and(0x20b8) <> @x00, skip) {機能モジュールを除外}
					do x :+ nCoef_x
					do nCoef_x :* -1
					if(nCoef_x < 0)
						do y :+ nCoef_y
						if(y < 0 | y = me.m_nSymbleSize)
							do y :: (y < 0) ?(0, me.m_nSymbleSize - 1)
							do nCoef_y :* -1
							do x :- 2
							if(x = 6) {タイミングパターン}
								do x :- 1
							end if
						end if
					end if
				end while

				do me.m_byModuleData[x][y] :: (me.m_byAllCodeWord[i].and((1b8).shl(7 - j)) <> @x00) ?(0x02b8, 0x00b8)
			end for
		end for
	end func

	{
	用  途:マスキングパターン配置
	引  数:マスキングパターン番号
	}
	func SetMaskingPattern(nPatternNo: int)
		for i(0, me.m_nSymbleSize - 1)
			for j(0, me.m_nSymbleSize - 1)
				if(! (me.m_byModuleData[j][i].and(@x20) <> @x00)) {機能モジュールを除外}
					var bMask: bool
					switch (nPatternNo)
					case 0
						do bMask :: ((i + j) % 2 = 0)
					case 1
						do bMask :: (i % 2 = 0)
					case 2
						do bMask :: (j % 3 = 0)
					case 3
						do bMask :: ((i + j) % 3 = 0)
					case 4
						do bMask :: (((i / 2) + (j / 3)) % 2 = 0)
					case 5
						do bMask :: (((i * j) % 2) + ((i * j) % 3) = 0)
					case 6
						do bMask :: ((((i * j) % 2) + ((i * j) % 3)) % 2 = 0)
					default {case 7}
						do bMask :: ((((i * j) % 3) + ((i + j) % 2)) % 2 = 0)
					end switch
					do me.m_byModuleData[j][i] :: me.m_byModuleData[j][i].and(0xFEb8).or(((me.m_byModuleData[j][i].and(0x02b8) $ int > 1) $ bit8).xor(bMask $ bit8))
				end if
			end for
		end for
	end func

	{
	用  途:フォーマット情報配置
	引  数:マスキングパターン番号
	}
	func SetFormatInfoPattern(nPatternNo: int)
		var nFormatInfo: int

		switch(me.m_nLevel)
		case @QR_LEVEL_M
			do nFormatInfo :: 0x00 {00nnnb}
		case @QR_LEVEL_L
			do nFormatInfo :: 0x08 {01nnnb}
		case @QR_LEVEL_Q
			do nFormatInfo :: 0x18 {11nnnb}
		default {case @QR_LEVEL_H}
			do nFormatInfo :: 0x10 {10nnnb}
		end switch

		do nFormatInfo :+ nPatternNo

		var nFormatData: bit64 :: (nFormatInfo $ bit64).shl(10)

		{剰余ビット算出}
		for i(0, 4)
			if(nFormatData.and((1b64).shl(14 - i)) <> 0b64)
				do nFormatData :: nFormatData.xor((0x0537b64).shl(4 - i)) {10100110111b}
			end if
		end for

		do nFormatData :+ (nFormatInfo $ bit64).shl(10)

		{マスキング}
		do nFormatData :: nFormatData.xor(0x5412b64) {101010000010010b}

		{左上位置検出パターン周り配置}
		for i(0, 5)
			do me.m_byModuleData[8][i] :: (nFormatData.and((1b64).shl(i)) <> 0b64) ?(@x30, @x20)
		end for

		do me.m_byModuleData[8][7] :: (nFormatData.and((1b64).shl(6)) <> 0b64) ?(@x30, @x20)
		do me.m_byModuleData[8][8] :: (nFormatData.and((1b64).shl(7)) <> 0b64) ?(@x30, @x20)
		do me.m_byModuleData[7][8] :: (nFormatData.and((1b64).shl(8)) <> 0b64) ?(@x30, @x20)

		for i(9, 14)
			do me.m_byModuleData[14 - i][8] :: (nFormatData.and((1b64).shl(i)) <> 0b64) ?(@x30, @x20)
		end for

		{右上位置検出パターン下配置}
		for i(0, 7)
			do me.m_byModuleData[me.m_nSymbleSize - 1 - i][8] :: (nFormatData.and((1b64).shl(i)) <> 0b64) ?(@x30, @x20)
		end for

		{左下位置検出パターン右配置}
		do me.m_byModuleData[8][me.m_nSymbleSize - 8] :: @x30 {固定暗モジュール}

		for i(8, 14)
			do me.m_byModuleData[8][me.m_nSymbleSize - 15 + i] :: (nFormatData.and((1b64).shl(i)) <> 0b64) ?(@x30, @x20)
		end for
	end func

	{
	用  途:マスク後ペナルティスコア算出
	}
	func countPenalty(): int
		var nPenalty: int :: 0

		{同色の列の隣接モジュール}
		for i(0, me.m_nSymbleSize - 1)
			for j(0, me.m_nSymbleSize - 5)
				var nCount: int :: 1

				var k: int
				for k_(j + 1, me.m_nSymbleSize - 1)
					do k :: k_
					if((me.m_byModuleData[i][j].and(@x11) = @x00) = ((me.m_byModuleData[i][k_].and(@x11) = @x00)))
						do nCount :+ 1
					else
						break k_
					end if
				end for

				if(nCount >= 5)
					do nPenalty :+ 3 + (nCount - 5)
				end if

				do j :: k - 1
			end for
		end for

		{同色の行の隣接モジュール}
		for i(0, me.m_nSymbleSize - 1)
			for j(0, me.m_nSymbleSize - 5)
				var nCount: int :: 1
				var k: int
				for k_(j + 1, me.m_nSymbleSize - 1)
					do k :: k_
					if((me.m_byModuleData[j][i].and(@x11) = @x00) = ((me.m_byModuleData[k_][i].and(@x11) = @x00)))
						do nCount :+ 1
					else
						break k_
					end if
				end for

				if(nCount >= 5)
					do nPenalty :+ 3 + (nCount - 5)
				end if

				do j :: k - 1
			end for
		end for

		{同色のモジュールブロック(2×2)}
		for i(0, me.m_nSymbleSize - 2)
			for j(0, me.m_nSymbleSize - 2)
				if(  ((me.m_byModuleData[i][j].and(@x11) = @x00) = (me.m_byModuleData[i + 1][j    ].and(@x11) = @x00)) &
					|((me.m_byModuleData[i][j].and(@x11) = @x00) = (me.m_byModuleData[i    ][j + 1].and(@x11) = @x00)) &
					|((me.m_byModuleData[i][j].and(@x11) = @x00) = (me.m_byModuleData[i + 1][j + 1].and(@x11) = @x00)))
					do nPenalty :+ 3
				end if
			end for
		end for

		{同一列における 1:1:3:1:1 比率(暗:明:暗:明:暗)のパターン}
		for i(0, me.m_nSymbleSize - 1)
			for j(0, me.m_nSymbleSize - 7)
				if(((j = 0) |                      (!(me.m_byModuleData[i][j - 1].and(@x11) <> @x00))) & {明 または シンボル外}
					|                              (  me.m_byModuleData[i][j    ].and(@x11) <> @x00)   & {暗 - 1}
					|                              (!(me.m_byModuleData[i][j + 1].and(@x11) <> @x00))  & {明 - 1}
					|                              (  me.m_byModuleData[i][j + 2].and(@x11) <> @x00)   & {暗 ┐ }
					|                              (  me.m_byModuleData[i][j + 3].and(@x11) <> @x00)   & {暗 │3}
					|                              (  me.m_byModuleData[i][j + 4].and(@x11) <> @x00)   & {暗 ┘ }
					|                              (!(me.m_byModuleData[i][j + 5].and(@x11) <> @x00))  & {明 - 1}
					|                              (  me.m_byModuleData[i][j + 6].and(@x11) <> @x00)   & {暗 - 1}
					|((j = me.m_nSymbleSize - 7) | (!(me.m_byModuleData[i][j + 7].and(@x11) <> @x00))))  {明 または シンボル外}
					{前または後に4以上の明パターン}
					if(                       ((j < 2 | !(me.m_byModuleData[i][j - 2].and(@x11) <> @x00)) &
						|                      (j < 3 | !(me.m_byModuleData[i][j - 3].and(@x11) <> @x00)) &
						|                      (j < 4 | !(me.m_byModuleData[i][j - 4].and(@x11) <> @x00))) |
						|((j >= me.m_nSymbleSize -  8 | !(me.m_byModuleData[i][j + 8].and(@x11) <> @x00)) &
						| (j >= me.m_nSymbleSize -  9 | !(me.m_byModuleData[i][j + 9].and(@x11) <> @x00)) &
						| (j >= me.m_nSymbleSize - 10 | !(me.m_byModuleData[i][j +10].and(@x11) <> @x00))))
						do nPenalty :+ 40
					end if
				end if
			end for
		end for

		{同一行における 1:1:3:1:1 比率(暗:明:暗:明:暗)のパターン}
		for i(0, me.m_nSymbleSize - 1)
			for j(0, me.m_nSymbleSize - 7)
				if(((j = 0) |                      (!(me.m_byModuleData[j - 1][i].and(@x11) <> @x00))) & {明 または シンボル外}
					|                              (  me.m_byModuleData[j    ][i].and(@x11) <> @x00)   & {暗 - 1}
					|                              (!(me.m_byModuleData[j + 1][i].and(@x11) <> @x00))  & {明 - 1}
					|                              (  me.m_byModuleData[j + 2][i].and(@x11) <> @x00)   & {暗 ┐ }
					|                              (  me.m_byModuleData[j + 3][i].and(@x11) <> @x00)   & {暗 │3}
					|                              (  me.m_byModuleData[j + 4][i].and(@x11) <> @x00)   & {暗 ┘ }
					|                              (!(me.m_byModuleData[j + 5][i].and(@x11) <> @x00))  & {明 - 1}
					|                              (  me.m_byModuleData[j + 6][i].and(@x11) <> @x00)   & {暗 - 1}
					|((j = me.m_nSymbleSize - 7) | (!(me.m_byModuleData[j + 7][i].and(@x11) <> @x00))))  {明 または シンボル外}
					{前または後に4以上の明パターン}
					if(                       ((j < 2 | !(me.m_byModuleData[j - 2][i].and(@x11) <> @x00)) &
						|                      (j < 3 | !(me.m_byModuleData[j - 3][i].and(@x11) <> @x00)) &
						|                      (j < 4 | !(me.m_byModuleData[j - 4][i].and(@x11) <> @x00))) |
						|((j >= me.m_nSymbleSize -  8 | !(me.m_byModuleData[j + 8][i].and(@x11) <> @x00)) &
						| (j >= me.m_nSymbleSize -  9 | !(me.m_byModuleData[j + 9][i].and(@x11) <> @x00)) &
						| (j >= me.m_nSymbleSize - 10 | !(me.m_byModuleData[j +10][i].and(@x11) <> @x00))))
						do nPenalty :+ 40
					end if
				end if
			end for
		end for

		{全体に対する暗モジュールの占める割合}
		var nCount: int :: 0
		for i(0, me.m_nSymbleSize - 1)
			for j(0, me.m_nSymbleSize - 1)
				if(! (me.m_byModuleData[i][j].and(@x11) <> @x00))
					do nCount :+ 1
				end if
			end for
		end for

		do nPenalty :+ ((50 - ((nCount * 100) / (me.m_nSymbleSize * me.m_nSymbleSize))).abs() / 5) * 10
		ret nPenalty
	end func

	+*func toStr(): []char
		var retVal: []char :: ""
		for y(0, me.m_nSymbleSize - 1)
			for x(0, me.m_nSymbleSize - 1)
				if(me.m_byModuleData[x][y] <> @x00)
					do retVal :~ "0"
				else
					do retVal :~ " "
				end if
			end for
			do retVal :~ "\n"
		end for
		ret retVal
	end func

	+func draw(x0: float, y0: float, size: float, bCellSizeMode: bool)
		var cellSize: float
		if(bCellSizeMode)
			do cellSize :: size
		else
			do cellSize :: size / (me.m_nSymbleSize + 2 * @QR_MARGIN) $ float
		end if
		do draw@rect(x0, y0, (me.m_nSymbleSize + 2 * @QR_MARGIN) $ float * cellSize, (me.m_nSymbleSize + 2 * @QR_MARGIN) $ float * cellSize, 0xFFFFFFFF)
		for x(0, me.m_nSymbleSize - 1)
			for y(0, me.m_nSymbleSize - 1)
				if(me.m_byModuleData[x][y] <> @x00)
					do draw@rect(x0 + (x + @QR_MARGIN) $ float * cellSize, y0 + (y + @QR_MARGIN) $ float * cellSize, cellSize, cellSize, 0xFF000000)
				else
					do draw@rect(x0 + (x + @QR_MARGIN) $ float * cellSize, y0 + (y + @QR_MARGIN) $ float * cellSize, cellSize, cellSize, 0xFFFFFFFF)
				end if
			end for
		end for
	end func
end class

func memmove(toByte8s: []bit8, fromByte8s: []bit8, startIndex: int, num: int)
	var i: int :: 0
	for j(startIndex, startIndex + num - 1)
		do toByte8s[i] :: fromByte8s[j]
		do i :+ 1
	end for
end func


←前の日の記事   →次の日の記事