cocos 二维码

前端之家收集整理的这篇文章主要介绍了cocos 二维码前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

QR_Encode.h

  1. // QR_Encode.h : CQR_Encode クラス宣言およびインターフェイス定義
  2. // Date 2006/05/17 Ver. 1.22 Psytec Inc.
  3.  
  4. #ifndef AFX_QR_ENCODE_H__AC886DF7_C0AE_4C9F_AC7A_FCDA8CB1DD37__INCLUDED_
  5. #define AFX_QR_ENCODE_H__AC886DF7_C0AE_4C9F_AC7A_FCDA8CB1DD37__INCLUDED_
  6.  
  7.  
  8.  
  9. // 誤り訂正レベル
  10. #define QR_LEVEL_L 0
  11. #define QR_LEVEL_M 1
  12. #define QR_LEVEL_Q 2
  13. #define QR_LEVEL_H 3
  14.  
  15. // データモード
  16. #define QR_MODE_NUMERAL 0
  17. #define QR_MODE_ALPHABET 1
  18. #define QR_MODE_8BIT 2
  19. #define QR_MODE_KANJI 3
  20.  
  21. // バージョン(型番)グループ
  22. #define QR_VRESION_S 0 // 1 ~ 9
  23. #define QR_VRESION_M 1 // 10 ~ 26
  24. #define QR_VRESION_L 2 // 27 ~ 40
  25.  
  26. #define MAX_ALLCODEWORD 3706 //
  27. #define MAX_DATACODEWORD 2956 //
  28. #define MAX_CODEBLOCK 153 //
  29. #define MAX_MODULESIZE 177 //
  30.  
  31. // ビットマップ描画時マージン
  32. #define QR_MARGIN 1
  33. #define min(x,y) ((x)<(y)?(x):(y))
  34.  
  35. /////////////////////////////////////////////////////////////////////////////
  36. typedef struct tagRS_BLOCKINFO
  37. {
  38. int ncRSBlock; // RSブロック数
  39. int ncAllCodeWord; // ブロック内コードワード数
  40. int ncDataCodeWord; // データコードワード数(コードワード数 - RSコードワード数)
  41.  
  42. } RS_BLOCKINFO,*LPRS_BLOCKINFO;
  43.  
  44.  
  45. /////////////////////////////////////////////////////////////////////////////
  46. // QRコードバージョン(型番)関連情報
  47.  
  48. typedef struct tagQR_VERSIONINFO
  49. {
  50. int nVersionNo; // バージョン(型番)番号(1~40)
  51. int ncAllCodeWord; // 総コードワード数
  52.  
  53. // 以下配列添字は誤り訂正率(0 = L,1 = M,2 = Q,3 = H)
  54. int ncDataCodeWord[4]; // データコードワード数(総コードワード数 - RSコードワード数)
  55.  
  56. int ncAlignPoint; // アライメントパターン座標数
  57. int nAlignPoint[6]; // アライメントパターン中心座標
  58.  
  59. RS_BLOCKINFO RS_BlockInfo1[4]; // RSブロック情報(1)
  60. RS_BLOCKINFO RS_BlockInfo2[4]; // RSブロック情報(2)
  61.  
  62. } QR_VERSIONINFO,*LPQR_VERSIONINFO;
  63.  
  64.  
  65. /////////////////////////////////////////////////////////////////////////////
  66. // CQR_Encode クラス
  67.  
  68. class CQR_Encode
  69. {
  70. // 構築/消滅
  71. public:
  72. CQR_Encode();
  73. ~CQR_Encode();
  74.  
  75. public:
  76. int m_nLevel; //
  77. int m_nVersion; //
  78. bool m_bAutoExtent; //
  79. int m_nMaskingNo; //
  80.  
  81. public:
  82. int m_nSymbleSize;
  83. unsigned char m_byModuleData[MAX_MODULESIZE][MAX_MODULESIZE]; // [x][y]
  84. // bit5:
  85. // bit4:
  86. // bit1:
  87. // bit0:
  88. // 20h
  89.  
  90. private:
  91. int m_ncDataCodeWordBit; //
  92. unsigned char m_byDataCodeWord[MAX_DATACODEWORD]; //
  93.  
  94. int m_ncDataBlock;
  95. unsigned char m_byBlockMode[MAX_DATACODEWORD];
  96. int m_nBlockLength[MAX_DATACODEWORD];
  97.  
  98. int m_ncAllCodeWord; //
  99. unsigned char m_byAllCodeWord[MAX_ALLCODEWORD]; //
  100. unsigned char m_byRSWork[MAX_CODEBLOCK]; //
  101.  
  102. //
  103. public:
  104. bool EncodeData(int nLevel,int nVersion,bool bAutoExtent,int nMaskingNo,char * lpsSource,int ncSource = 0);
  105.  
  106. private:
  107. int GetEncodeVersion(int nVersion,int ncLength);
  108. bool EncodeSourceData(char * lpsSource,int ncLength,int nVerGroup);
  109.  
  110. int GetBitLength(unsigned char nMode,int ncData,int nVerGroup);
  111.  
  112. int SetBitStream(int nIndex,unsigned short wData,int ncData);
  113.  
  114. bool IsNumeralData(unsigned char c);
  115. bool IsAlphabetData(unsigned char c);
  116. bool IsKanjiData(unsigned char c1,unsigned char c2);
  117.  
  118. unsigned char AlphabetToBinaly(unsigned char c);
  119. unsigned short KanjiToBinaly(unsigned short wc);
  120.  
  121. void GetRSCodeWord(unsigned char* lpbyRSWork,int ncDataCodeWord,int ncRSCodeWord);
  122.  
  123. // モジュール配置関連ファンクション
  124. private:
  125. void FormatModule();
  126.  
  127. void SetFunctionModule();
  128. void SetFinderPattern(int x,int y);
  129. void SetAlignmentPattern(int x,int y);
  130. void SetVersionPattern();
  131. void SetCodeWordPattern();
  132. void SetMaskingPattern(int nPatternNo);
  133. void SetFormatInfoPattern(int nPatternNo);
  134. int CountPenalty();
  135.  
  136. };
  137.  
  138. /////////////////////////////////////////////////////////////////////////////
  139.  
  140. #endif // !defined(AFX_QR_ENCODE_H__AC886DF7_C0AE_4C9F_AC7A_FCDA8CB1DD37__INCLUDED_)

QR_Encode.cpp
  1. // QR_Encode.cpp : CQR_Encode クラス インプリメンテーション ファイル
  2. // Date 2006/05/17 Ver. 1.22 Psytec Inc.
  3.  
  4. #include "QR_Encode.h"
  5. #include <stdlib.h>
  6. #include <string.h>
  7.  
  8. static QR_VERSIONINFO QR_VersonInfo[] =
  9. {
  10. {
  11. 0
  12. },//
  13. {
  14. 1,// Ver.1
  15. 26,19,16,13,9,1,26,0
  16. },{
  17. 2,// Ver.2
  18. 44,34,28,22,18,44,{
  19. 3,// Ver.3
  20. 70,55,70,2,35,17,{
  21. 4,// Ver.4
  22. 100,80,64,48,36,100,50,32,24,4,25,{
  23. 5,// Ver.5
  24. 134,108,86,62,46,30,134,67,43,33,15,11,12
  25. },{
  26. 6,// Ver.6
  27. 172,136,76,60,68,27,{
  28. 7,// Ver.7
  29. 196,156,124,88,66,38,98,78,49,31,14,39,40,14
  30. },{
  31. 8,// Ver.8
  32. 242,194,154,110,42,121,97,61,41,15
  33. },{
  34. 9,// Ver.9
  35. 292,232,182,132,146,116,3,58,12,59,37,13
  36. },{
  37. 10,// Ver.10
  38. 346,274,216,122,69,6,87,20,16
  39. },{
  40. 11,// Ver.11
  41. 404,324,254,180,140,54,101,81,51,23,8,{
  42. 12,// Ver.12
  43. 466,370,290,206,158,92,7,117,93,47,21,{
  44. 13,// Ver.13
  45. 532,428,334,244,133,107,45,{
  46. 14,// Ver.14
  47. 581,461,365,261,197,145,115,5,65,{
  48. 15,// Ver.15
  49. 655,523,415,295,223,109,13
  50. },{
  51. 16,// Ver.16
  52. 733,589,453,325,253,74,73,123,99,{
  53. 17,// Ver.17
  54. 815,647,507,367,283,135,10,75,{
  55. 18,// Ver.18
  56. 901,721,563,397,313,56,82,150,120,151,{
  57. 19,// Ver.19
  58. 991,795,627,445,341,141,113,142,114,71,{
  59. 20,// Ver.20
  60. 1085,861,669,485,385,90,{
  61. 21,// Ver.21
  62. 1156,932,714,512,406,72,94,144,17
  63. },{
  64. 22,// Ver.22
  65. 1258,1006,782,568,442,139,111,112,{
  66. 23,// Ver.23
  67. 1364,1094,860,614,464,102,152,{
  68. 24,// Ver.24
  69. 1474,1174,914,664,514,106,147,148,118,{
  70. 25,// Ver.25
  71. 1588,1276,1000,718,538,84,{
  72. 26,// Ver.26
  73. 1706,1370,1062,754,596,143,{
  74. 27,// Ver.27
  75. 1828,1468,1128,808,628,53,153,{
  76. 28,// Ver.28
  77. 1921,1531,1193,871,661,{
  78. 29,// Ver.29
  79. 2051,1631,1267,911,701,126,{
  80. 30,// Ver.30
  81. 2185,1735,1373,985,745,52,104,130,{
  82. 31,// Ver.31
  83. 2323,1843,1455,1033,793,29,{
  84. 32,// Ver.32
  85. 2465,1955,1541,1115,845,138,{
  86. 33,// Ver.33
  87. 2611,2071,1171,901,{
  88. 34,// Ver.34
  89. 2761,2191,1725,1231,961,{
  90. 35,// Ver.35
  91. 2876,2306,1812,1286,986,{
  92. 36,// Ver.36
  93. 3034,2434,1914,1354,1054,128,{
  94. 37,// Ver.37
  95. 3196,2566,1992,1426,1096,{
  96. 38,// Ver.38
  97. 3362,2702,2102,1502,1142,162,{
  98. 39,// Ver.39
  99. 3532,2812,2216,1582,1222,166,{
  100. 40,// Ver.40
  101. 3706,2956,2334,1666,170,149,119,16
  102. }
  103. };
  104.  
  105.  
  106. /////////////////////////////////////////////////////////////////////////////
  107. // GF(2^8)α指数→整数変換テーブル
  108. static unsigned char byExpToInt[] = { 1,205,234,201,96,192,157,212,181,238,193,159,160,186,105,210,185,222,161,95,190,188,202,137,240,231,211,187,214,177,127,225,163,91,226,217,175,208,189,103,129,248,237,199,236,204,184,218,169,79,168,77,164,85,57,228,213,183,230,209,191,198,63,252,229,215,179,246,241,255,227,219,171,196,220,165,174,200,224,221,167,83,89,178,242,249,239,195,155,172,245,247,243,251,235,203,176,125,250,233,207,131,173,1 };
  109.  
  110.  
  111. /////////////////////////////////////////////////////////////////////////////
  112. // GF(2^8)α整数→指数変換テーブル
  113. static unsigned char byIntToExp[] = { 0,175 };
  114.  
  115.  
  116. /////////////////////////////////////////////////////////////////////////////
  117. // 誤り訂正生成多項式α係数
  118. static unsigned char byRSExp7[] = { 87,21 };
  119. static unsigned char byRSExp10[] = { 251,45 };
  120. static unsigned char byRSExp13[] = { 74,78 };
  121. static unsigned char byRSExp15[] = { 8,105 };
  122. static unsigned char byRSExp16[] = { 120,120 };
  123. static unsigned char byRSExp17[] = { 43,136 };
  124. static unsigned char byRSExp18[] = { 215,153 };
  125. static unsigned char byRSExp20[] = { 17,190 };
  126. static unsigned char byRSExp22[] = { 210,231 };
  127. static unsigned char byRSExp24[] = { 229,21 };
  128. static unsigned char byRSExp26[] = { 173,70 };
  129. static unsigned char byRSExp28[] = { 168,123 };
  130. static unsigned char byRSExp30[] = { 41,180 };
  131. static unsigned char byRSExp32[] = { 10,241 };
  132. static unsigned char byRSExp34[] = { 111,51 };
  133. static unsigned char byRSExp36[] = { 200,120 };
  134. static unsigned char byRSExp38[] = { 159,193 };
  135. static unsigned char byRSExp40[] = { 59,15 };
  136. static unsigned char byRSExp42[] = { 250,96 };
  137. static unsigned char byRSExp44[] = { 190,181 };
  138. static unsigned char byRSExp46[] = { 112,15 };
  139. static unsigned char byRSExp48[] = { 228,108 };
  140. static unsigned char byRSExp50[] = { 232,205 };
  141. static unsigned char byRSExp52[] = { 116,51 };
  142. static unsigned char byRSExp54[] = { 183,156 };
  143. static unsigned char byRSExp56[] = { 106,10 };
  144. static unsigned char byRSExp58[] = { 82,123 };
  145. static unsigned char byRSExp60[] = { 107,240 };
  146. static unsigned char byRSExp62[] = { 65,106 };
  147. static unsigned char byRSExp64[] = { 45,231 };
  148. static unsigned char byRSExp66[] = { 5,105 };
  149. static unsigned char byRSExp68[] = { 247,238 };
  150. //
  151. static unsigned char* byRSExp[] = { 0,byRSExp7,byRSExp10,byRSExp13,byRSExp15,byRSExp16,byRSExp17,byRSExp18,byRSExp20,byRSExp22,byRSExp24,byRSExp26,byRSExp28,byRSExp30,byRSExp32,byRSExp34,byRSExp36,byRSExp38,byRSExp40,byRSExp42,byRSExp44,byRSExp46,byRSExp48,byRSExp50,byRSExp52,byRSExp54,byRSExp56,byRSExp58,byRSExp60,byRSExp62,byRSExp64,byRSExp66,byRSExp68 };
  152.  
  153. // 文字数インジケータビット長(バージョングループ別,{S,M,L})
  154. static int nIndicatorLenNumeral[] = { 10,14 };
  155. static int nIndicatorLenAlphabet[] = { 9,13 };
  156. static int nIndicatorLen8Bit[] = { 8,16 };
  157. static int nIndicatorLenKanji[] = { 8,12 };
  158.  
  159.  
  160. /////////////////////////////////////////////////////////////////////////////
  161. // QR_Encode クラスの構築/消滅
  162.  
  163. CQR_Encode::CQR_Encode()
  164. {
  165. }
  166. //
  167. CQR_Encode::~CQR_Encode()
  168. {
  169. }
  170.  
  171. /////////////////////////////////////////////////////////////////////////////
  172. // CQR_Encode::EncodeData
  173.  
  174. bool CQR_Encode::EncodeData(int nLevel,char* lpsSource,int ncSource)
  175. {
  176. int i,j;
  177.  
  178. m_nLevel = nLevel;
  179. m_nMaskingNo = nMaskingNo;
  180.  
  181. // データ長が指定されていない場合は lstrlen によって取得
  182. int ncLength = ncSource > 0 ? ncSource : strlen(lpsSource);
  183.  
  184. if (ncLength == 0)
  185. return 0; // データなし
  186.  
  187. // バージョン(型番)チェック
  188. int nEncodeVersion = GetEncodeVersion(nVersion,lpsSource,ncLength);
  189.  
  190. if (nEncodeVersion == 0)
  191. return 0; // 容量オーバー
  192.  
  193. if (nVersion == 0)
  194. {
  195. // 型番自動
  196. m_nVersion = nEncodeVersion;
  197. }
  198. else
  199. {
  200. if (nEncodeVersion <= nVersion)
  201. {
  202. m_nVersion = nVersion;
  203. }
  204. else
  205. {
  206. if (bAutoExtent)
  207. m_nVersion = nEncodeVersion; // バージョン(型番)自動拡張
  208. else
  209. return 0; // 容量オーバー
  210. }
  211. }
  212.  
  213. // ターミネータコード"0000"付加
  214. int ncDataCodeWord = QR_VersonInfo[m_nVersion].ncDataCodeWord[nLevel];
  215.  
  216. int ncTerminater = min(4,(ncDataCodeWord * 8) - m_ncDataCodeWordBit);
  217.  
  218. if (ncTerminater > 0)
  219. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit,ncTerminater);
  220.  
  221. // パディングコード"11101100,00010001"付加
  222. unsigned char byPaddingCode = 0xec;
  223.  
  224. for (i = (m_ncDataCodeWordBit + 7) / 8; i < ncDataCodeWord; ++i)
  225. {
  226. m_byDataCodeWord[i] = byPaddingCode;
  227.  
  228. byPaddingCode = (unsigned char)(byPaddingCode == 0xec ? 0x11 : 0xec);
  229. }
  230.  
  231. // 総コードワード算出エリアクリア
  232. m_ncAllCodeWord = QR_VersonInfo[m_nVersion].ncAllCodeWord;
  233. memset(m_byAllCodeWord,m_ncAllCodeWord);
  234.  
  235. int nDataCwIndex = 0; // データコードワード処理位置
  236.  
  237. // データブロック分割数
  238. int ncBlock1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[nLevel].ncRSBlock;
  239. int ncBlock2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[nLevel].ncRSBlock;
  240. int ncBlockSum = ncBlock1 + ncBlock2;
  241.  
  242. int nBlockNo = 0; // 処理中ブロック番号
  243.  
  244. // ブロック別データコードワード数
  245. int ncDataCw1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[nLevel].ncDataCodeWord;
  246. int ncDataCw2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[nLevel].ncDataCodeWord;
  247.  
  248. // データコードワードインターリーブ配置
  249. for (i = 0; i < ncBlock1; ++i)
  250. {
  251. for (j = 0; j < ncDataCw1; ++j)
  252. {
  253. m_byAllCodeWord[(ncBlockSum * j) + nBlockNo] = m_byDataCodeWord[nDataCwIndex++];
  254. }
  255.  
  256. ++nBlockNo;
  257. }
  258.  
  259. for (i = 0; i < ncBlock2; ++i)
  260. {
  261. for (j = 0; j < ncDataCw2; ++j)
  262. {
  263. if (j < ncDataCw1)
  264. {
  265. m_byAllCodeWord[(ncBlockSum * j) + nBlockNo] = m_byDataCodeWord[nDataCwIndex++];
  266. }
  267. else
  268. {
  269. // 2種目ブロック端数分配置
  270. m_byAllCodeWord[(ncBlockSum * ncDataCw1) + i] = m_byDataCodeWord[nDataCwIndex++];
  271. }
  272. }
  273.  
  274. ++nBlockNo;
  275. }
  276.  
  277. // ブロック別RSコードワード数(※現状では同数)
  278. int ncRSCw1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[nLevel].ncAllCodeWord - ncDataCw1;
  279. int ncRSCw2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[nLevel].ncAllCodeWord - ncDataCw2;
  280.  
  281. /////////////////////////////////////////////////////////////////////////
  282. // RSコードワード算出
  283.  
  284. nDataCwIndex = 0;
  285. nBlockNo = 0;
  286.  
  287. for (i = 0; i < ncBlock1; ++i)
  288. {
  289. memset(m_byRSWork,sizeof(m_byRSWork));
  290.  
  291. memmove(m_byRSWork,m_byDataCodeWord + nDataCwIndex,ncDataCw1);
  292.  
  293. GetRSCodeWord(m_byRSWork,ncDataCw1,ncRSCw1);
  294.  
  295. // RSコードワード配置
  296. for (j = 0; j < ncRSCw1; ++j)
  297. {
  298. m_byAllCodeWord[ncDataCodeWord + (ncBlockSum * j) + nBlockNo] = m_byRSWork[j];
  299. }
  300.  
  301. nDataCwIndex += ncDataCw1;
  302. ++nBlockNo;
  303. }
  304.  
  305. for (i = 0; i < ncBlock2; ++i)
  306. {
  307. memset(m_byRSWork,ncDataCw2);
  308.  
  309. GetRSCodeWord(m_byRSWork,ncDataCw2,ncRSCw2);
  310.  
  311. // RSコードワード配置
  312. for (j = 0; j < ncRSCw2; ++j)
  313. {
  314. m_byAllCodeWord[ncDataCodeWord + (ncBlockSum * j) + nBlockNo] = m_byRSWork[j];
  315. }
  316.  
  317. nDataCwIndex += ncDataCw2;
  318. ++nBlockNo;
  319. }
  320.  
  321. m_nSymbleSize = m_nVersion * 4 + 17;
  322.  
  323. // モジュール配置
  324. FormatModule();
  325.  
  326. return 1;
  327. }
  328.  
  329. //
  330. ///////////////////////////////////////////////////////////////////////////////
  331. //// CQR_Encode::GetEncodeVersion
  332. //// 用 途:エンコード時バージョン(型番)取得
  333. //// 引 数:調査開始バージョン、エンコードデータ、エンコードデータ長
  334. //// 戻り値:バージョン番号(容量オーバー時=0)
  335. //
  336. int CQR_Encode::GetEncodeVersion(int nVersion,int ncLength)
  337. {
  338. int nVerGroup = nVersion >= 27 ? QR_VRESION_L : (nVersion >= 10 ? QR_VRESION_M : QR_VRESION_S);
  339. int i,j;
  340.  
  341. for (i = nVerGroup; i <= QR_VRESION_L; ++i)
  342. {
  343. if (EncodeSourceData(lpsSource,ncLength,i))
  344. {
  345. if (i == QR_VRESION_S)
  346. {
  347. for (j = 1; j <= 9; ++j)
  348. {
  349. if ((m_ncDataCodeWordBit + 7) / 8 <= QR_VersonInfo[j].ncDataCodeWord[m_nLevel])
  350. return j;
  351. }
  352. }
  353. else if (i == QR_VRESION_M)
  354. {
  355. for (j = 10; j <= 26; ++j)
  356. {
  357. if ((m_ncDataCodeWordBit + 7) / 8 <= QR_VersonInfo[j].ncDataCodeWord[m_nLevel])
  358. return j;
  359. }
  360. }
  361. else if (i == QR_VRESION_L)
  362. {
  363. for (j = 27; j <= 40; ++j)
  364. {
  365. if ((m_ncDataCodeWordBit + 7) / 8 <= QR_VersonInfo[j].ncDataCodeWord[m_nLevel])
  366. return j;
  367. }
  368. }
  369. }
  370. }
  371.  
  372. return 0;
  373. }
  374. //
  375.  
  376. /////////////////////////////////////////////////////////////////////////////
  377. // CQR_Encode::EncodeSourceData
  378. // 用 途:入力データエンコード
  379. // 引 数:入力データ、入力データ長、バージョン(型番)グループ
  380. // 戻り値:エンコード成功時=1
  381.  
  382. bool CQR_Encode::EncodeSourceData(char* lpsSource,int nVerGroup)
  383. {
  384. memset(m_nBlockLength,sizeof(m_nBlockLength));
  385.  
  386. int i,j;
  387.  
  388. // どのモードが何文字(バイト)継続しているかを調査
  389. for (m_ncDataBlock = i = 0; i < ncLength; ++i)
  390. {
  391. unsigned char byMode;
  392.  
  393. if (i < ncLength - 1 && IsKanjiData(lpsSource[i],lpsSource[i + 1]))
  394. byMode = QR_MODE_KANJI;
  395. else if (IsNumeralData(lpsSource[i]))
  396. byMode = QR_MODE_NUMERAL;
  397. else if (IsAlphabetData(lpsSource[i]))
  398. byMode = QR_MODE_ALPHABET;
  399. else
  400. byMode = QR_MODE_8BIT;
  401.  
  402. if (i == 0)
  403. m_byBlockMode[0] = byMode;
  404.  
  405. if (m_byBlockMode[m_ncDataBlock] != byMode)
  406. m_byBlockMode[++m_ncDataBlock] = byMode;
  407.  
  408. ++m_nBlockLength[m_ncDataBlock];
  409.  
  410. if (byMode == QR_MODE_KANJI)
  411. {
  412. // 漢字は文字数ではなく 数で記録
  413. ++m_nBlockLength[m_ncDataBlock];
  414. ++i;
  415. }
  416. }
  417.  
  418. ++m_ncDataBlock;
  419.  
  420. /////////////////////////////////////////////////////////////////////////
  421. // 隣接する英数字モードブロックと数字モードブロックの並びをを条件により結合
  422.  
  423. int ncSrcBits,ncDstBits; // 元のビット長と単一の英数字モードブロック化した場合のビット長
  424.  
  425. int nBlock = 0;
  426.  
  427. while (nBlock < m_ncDataBlock - 1)
  428. {
  429. int ncJoinFront,ncJoinBehind; // 前後8ビットバイトモードブロックと結合した場合のビット長
  430. int nJoinPosition = 0; // 8ビットバイトモードブロックとの結合:-1=前と結合、0=結合しない、1=後ろと結合
  431.  
  432. // 「数字-英数字」または「英数字-数字」の並び
  433. if ((m_byBlockMode[nBlock] == QR_MODE_NUMERAL && m_byBlockMode[nBlock + 1] == QR_MODE_ALPHABET) ||
  434. (m_byBlockMode[nBlock] == QR_MODE_ALPHABET && m_byBlockMode[nBlock + 1] == QR_MODE_NUMERAL))
  435. {
  436. // 元のビット長と単一の英数字モードブロック化した場合のビット長を比較
  437. ncSrcBits = GetBitLength(m_byBlockMode[nBlock],m_nBlockLength[nBlock],nVerGroup) +
  438. GetBitLength(m_byBlockMode[nBlock + 1],m_nBlockLength[nBlock + 1],nVerGroup);
  439.  
  440. ncDstBits = GetBitLength(QR_MODE_ALPHABET,m_nBlockLength[nBlock] + m_nBlockLength[nBlock + 1],nVerGroup);
  441.  
  442. if (ncSrcBits > ncDstBits)
  443. {
  444. // 前後に8ビットバイトモードブロックがある場合、それらとの結合が有利かどうかをチェック
  445. if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT)
  446. {
  447. // 前に8ビットバイトモードブロックあり
  448. ncJoinFront = GetBitLength(QR_MODE_8BIT,m_nBlockLength[nBlock - 1] + m_nBlockLength[nBlock],nVerGroup) +
  449. GetBitLength(m_byBlockMode[nBlock + 1],nVerGroup);
  450.  
  451. if (ncJoinFront > ncDstBits + GetBitLength(QR_MODE_8BIT,m_nBlockLength[nBlock - 1],nVerGroup))
  452. ncJoinFront = 0; // 8ビットバイトモードブロックとは結合しない
  453. }
  454. else
  455. ncJoinFront = 0;
  456.  
  457. if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT)
  458. {
  459. // 後ろに8ビットバイトモードブロックあり
  460. ncJoinBehind = GetBitLength(m_byBlockMode[nBlock],nVerGroup) +
  461. GetBitLength(QR_MODE_8BIT,m_nBlockLength[nBlock + 1] + m_nBlockLength[nBlock + 2],nVerGroup);
  462.  
  463. if (ncJoinBehind > ncDstBits + GetBitLength(QR_MODE_8BIT,m_nBlockLength[nBlock + 2],nVerGroup))
  464. ncJoinBehind = 0; // 8ビットバイトモードブロックとは結合しない
  465. }
  466. else
  467. ncJoinBehind = 0;
  468.  
  469. if (ncJoinFront != 0 && ncJoinBehind != 0)
  470. {
  471. // 前後両方に8ビットバイトモードブロックがある場合はデータ長が短くなる方を優先
  472. nJoinPosition = (ncJoinFront < ncJoinBehind) ? -1 : 1;
  473. }
  474. else
  475. {
  476. nJoinPosition = (ncJoinFront != 0) ? -1 : ((ncJoinBehind != 0) ? 1 : 0);
  477. }
  478.  
  479. if (nJoinPosition != 0)
  480. {
  481. // 8ビットバイトモードブロックとの結合
  482. if (nJoinPosition == -1)
  483. {
  484. m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock];
  485.  
  486. // 後続をシフト
  487. for (i = nBlock; i < m_ncDataBlock - 1; ++i)
  488. {
  489. m_byBlockMode[i] = m_byBlockMode[i + 1];
  490. m_nBlockLength[i] = m_nBlockLength[i + 1];
  491. }
  492. }
  493. else
  494. {
  495. m_byBlockMode[nBlock + 1] = QR_MODE_8BIT;
  496. m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2];
  497.  
  498. // 後続をシフト
  499. for (i = nBlock + 2; i < m_ncDataBlock - 1; ++i)
  500. {
  501. m_byBlockMode[i] = m_byBlockMode[i + 1];
  502. m_nBlockLength[i] = m_nBlockLength[i + 1];
  503. }
  504. }
  505.  
  506. --m_ncDataBlock;
  507. }
  508. else
  509. {
  510. // 英数字と数字の並びを単一の英数字モードブロックに統合
  511.  
  512. if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_ALPHABET)
  513. {
  514. // 結合しようとするブロックの後ろに続く英数字モードブロックを結合
  515. m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2];
  516.  
  517. // 後続をシフト
  518. for (i = nBlock + 2; i < m_ncDataBlock - 1; ++i)
  519. {
  520. m_byBlockMode[i] = m_byBlockMode[i + 1];
  521. m_nBlockLength[i] = m_nBlockLength[i + 1];
  522. }
  523.  
  524. --m_ncDataBlock;
  525. }
  526.  
  527. m_byBlockMode[nBlock] = QR_MODE_ALPHABET;
  528. m_nBlockLength[nBlock] += m_nBlockLength[nBlock + 1];
  529.  
  530. // 後続をシフト
  531. for (i = nBlock + 1; i < m_ncDataBlock - 1; ++i)
  532. {
  533. m_byBlockMode[i] = m_byBlockMode[i + 1];
  534. m_nBlockLength[i] = m_nBlockLength[i + 1];
  535. }
  536.  
  537. --m_ncDataBlock;
  538.  
  539. if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_ALPHABET)
  540. {
  541. // 結合したブロックの前の英数字モードブロックを結合
  542. m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock];
  543.  
  544. // 後続をシフト
  545. for (i = nBlock; i < m_ncDataBlock - 1; ++i)
  546. {
  547. m_byBlockMode[i] = m_byBlockMode[i + 1];
  548. m_nBlockLength[i] = m_nBlockLength[i + 1];
  549. }
  550.  
  551. --m_ncDataBlock;
  552. }
  553. }
  554.  
  555. continue; // 現在位置のブロックを再調査
  556. }
  557. }
  558.  
  559. ++nBlock; // 次ブロックを調査
  560. }
  561.  
  562. /////////////////////////////////////////////////////////////////////////
  563. // 連続する短いモードブロックを8ビットバイトモードブロック化
  564.  
  565. nBlock = 0;
  566.  
  567. while (nBlock < m_ncDataBlock - 1)
  568. {
  569. ncSrcBits = GetBitLength(m_byBlockMode[nBlock],nVerGroup)
  570. + GetBitLength(m_byBlockMode[nBlock + 1],nVerGroup);
  571.  
  572. ncDstBits = GetBitLength(QR_MODE_8BIT,nVerGroup);
  573.  
  574. // 前に8ビットバイトモードブロックがある場合、重複するインジケータ分を減算
  575. if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT)
  576. ncDstBits -= (4 + nIndicatorLen8Bit[nVerGroup]);
  577.  
  578. // 後ろに8ビットバイトモードブロックがある場合、重複するインジケータ分を減算
  579. if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT)
  580. ncDstBits -= (4 + nIndicatorLen8Bit[nVerGroup]);
  581.  
  582. if (ncSrcBits > ncDstBits)
  583. {
  584. if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT)
  585. {
  586. // 結合するブロックの前にある8ビットバイトモードブロックを結合
  587. m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock];
  588.  
  589. // 後続をシフト
  590. for (i = nBlock; i < m_ncDataBlock - 1; ++i)
  591. {
  592. m_byBlockMode[i] = m_byBlockMode[i + 1];
  593. m_nBlockLength[i] = m_nBlockLength[i + 1];
  594. }
  595.  
  596. --m_ncDataBlock;
  597. --nBlock;
  598. }
  599.  
  600. if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT)
  601. {
  602. // 結合するブロックの後ろにある8ビットバイトモードブロックを結合
  603. m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2];
  604.  
  605. // 後続をシフト
  606. for (i = nBlock + 2; i < m_ncDataBlock - 1; ++i)
  607. {
  608. m_byBlockMode[i] = m_byBlockMode[i + 1];
  609. m_nBlockLength[i] = m_nBlockLength[i + 1];
  610. }
  611.  
  612. --m_ncDataBlock;
  613. }
  614.  
  615. m_byBlockMode[nBlock] = QR_MODE_8BIT;
  616. m_nBlockLength[nBlock] += m_nBlockLength[nBlock + 1];
  617.  
  618. // 後続をシフト
  619. for (i = nBlock + 1; i < m_ncDataBlock - 1; ++i)
  620. {
  621. m_byBlockMode[i] = m_byBlockMode[i + 1];
  622. m_nBlockLength[i] = m_nBlockLength[i + 1];
  623. }
  624.  
  625. --m_ncDataBlock;
  626.  
  627. // 結合したブロックの前から再調査
  628. if (nBlock >= 1)
  629. --nBlock;
  630.  
  631. continue;
  632. }
  633.  
  634. ++nBlock; // 次ブロックを調査
  635. }
  636.  
  637. /////////////////////////////////////////////////////////////////////////
  638. // ビット配列化
  639. int ncComplete = 0; // 処理済データカウンタ
  640. unsigned short wBinCode;
  641.  
  642. m_ncDataCodeWordBit = 0; // ビット単位処理カウンタ
  643.  
  644. memset(m_byDataCodeWord,MAX_DATACODEWORD);
  645.  
  646. for (i = 0; i < m_ncDataBlock && m_ncDataCodeWordBit != -1; ++i)
  647. {
  648. if (m_byBlockMode[i] == QR_MODE_NUMERAL)
  649. {
  650. /////////////////////////////////////////////////////////////////
  651. // 数字モード
  652.  
  653. // インジケータ(0001b)
  654. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit,4);
  655.  
  656. // 文字数セット
  657. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit,(unsigned short)m_nBlockLength[i],nIndicatorLenNumeral[nVerGroup]);
  658.  
  659. // ビット列保存
  660. for (j = 0; j < m_nBlockLength[i]; j += 3)
  661. {
  662. if (j < m_nBlockLength[i] - 2)
  663. {
  664. wBinCode = (unsigned short)(((lpsSource[ncComplete + j] - '0') * 100) +
  665. ((lpsSource[ncComplete + j + 1] - '0') * 10) +
  666. (lpsSource[ncComplete + j + 2] - '0'));
  667.  
  668. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit,wBinCode,10);
  669. }
  670. else if (j == m_nBlockLength[i] - 2)
  671. {
  672. // 端数2バイト
  673. wBinCode = (unsigned short)(((lpsSource[ncComplete + j] - '0') * 10) +
  674. (lpsSource[ncComplete + j + 1] - '0'));
  675.  
  676. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit,7);
  677. }
  678. else if (j == m_nBlockLength[i] - 1)
  679. {
  680. // 端数1バイト
  681. wBinCode = (unsigned short)(lpsSource[ncComplete + j] - '0');
  682.  
  683. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit,4);
  684. }
  685. }
  686.  
  687. ncComplete += m_nBlockLength[i];
  688. }
  689.  
  690. else if (m_byBlockMode[i] == QR_MODE_ALPHABET)
  691. {
  692. /////////////////////////////////////////////////////////////////
  693. // 英数字モード
  694.  
  695. // モードインジケータ(0010b)
  696. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit,nIndicatorLenAlphabet[nVerGroup]);
  697.  
  698. // ビット列保存
  699. for (j = 0; j < m_nBlockLength[i]; j += 2)
  700. {
  701. if (j < m_nBlockLength[i] - 1)
  702. {
  703. wBinCode = (unsigned short)((AlphabetToBinaly(lpsSource[ncComplete + j]) * 45) +
  704. AlphabetToBinaly(lpsSource[ncComplete + j + 1]));
  705.  
  706. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit,11);
  707. }
  708. else
  709. {
  710. // 端数1バイト
  711. wBinCode = (unsigned short)AlphabetToBinaly(lpsSource[ncComplete + j]);
  712.  
  713. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit,6);
  714. }
  715. }
  716.  
  717. ncComplete += m_nBlockLength[i];
  718. }
  719.  
  720. else if (m_byBlockMode[i] == QR_MODE_8BIT)
  721. {
  722. /////////////////////////////////////////////////////////////////
  723. // 8ビットバイトモード
  724.  
  725. // モードインジケータ(0100b)
  726. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit,nIndicatorLen8Bit[nVerGroup]);
  727.  
  728. // ビット列保存
  729. for (j = 0; j < m_nBlockLength[i]; ++j)
  730. {
  731. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit,(unsigned short)lpsSource[ncComplete + j],8);
  732. }
  733.  
  734. ncComplete += m_nBlockLength[i];
  735. }
  736. else // m_byBlockMode[i] == QR_MODE_KANJI
  737. {
  738. /////////////////////////////////////////////////////////////////
  739. // 漢字モード
  740.  
  741. // モードインジケータ(1000b)
  742. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit,(unsigned short)(m_nBlockLength[i] / 2),nIndicatorLenKanji[nVerGroup]);
  743.  
  744. // 漢字モードでビット列保存
  745. for (j = 0; j < m_nBlockLength[i] / 2; ++j)
  746. {
  747. unsigned short wBinCode = KanjiToBinaly((unsigned short)(((unsigned char)lpsSource[ncComplete + (j * 2)] << 8) + (unsigned char)lpsSource[ncComplete + (j * 2) + 1]));
  748.  
  749. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit,13);
  750. }
  751.  
  752. ncComplete += m_nBlockLength[i];
  753. }
  754. }
  755.  
  756. return (m_ncDataCodeWordBit != -1);
  757. }
  758.  
  759.  
  760. /////////////////////////////////////////////////////////////////////////////
  761. // CQR_Encode::GetBitLength
  762. int CQR_Encode::GetBitLength(unsigned char nMode,int nVerGroup)
  763. {
  764. int ncBits = 0;
  765.  
  766. switch (nMode)
  767. {
  768. case QR_MODE_NUMERAL:
  769. ncBits = 4 + nIndicatorLenNumeral[nVerGroup] + (10 * (ncData / 3));
  770. switch (ncData % 3)
  771. {
  772. case 1:
  773. ncBits += 4;
  774. break;
  775. case 2:
  776. ncBits += 7;
  777. break;
  778. default: // case 0:
  779. break;
  780. }
  781.  
  782. break;
  783.  
  784. case QR_MODE_ALPHABET:
  785. ncBits = 4 + nIndicatorLenAlphabet[nVerGroup] + (11 * (ncData / 2)) + (6 * (ncData % 2));
  786. break;
  787.  
  788. case QR_MODE_8BIT:
  789. ncBits = 4 + nIndicatorLen8Bit[nVerGroup] + (8 * ncData);
  790. break;
  791.  
  792. default: // case QR_MODE_KANJI:
  793. ncBits = 4 + nIndicatorLenKanji[nVerGroup] + (13 * (ncData / 2));
  794. break;
  795. }
  796.  
  797. return ncBits;
  798. }
  799.  
  800.  
  801. /////////////////////////////////////////////////////////////////////////////
  802. // CQR_Encode::SetBitStream
  803. int CQR_Encode::SetBitStream(int nIndex,int ncData)
  804. {
  805. int i;
  806.  
  807. if (nIndex == -1 || nIndex + ncData > MAX_DATACODEWORD * 8)
  808. return -1;
  809.  
  810. for (i = 0; i < ncData; ++i)
  811. {
  812. if (wData & (1 << (ncData - i - 1)))
  813. {
  814. m_byDataCodeWord[(nIndex + i) / 8] |= 1 << (7 - ((nIndex + i) % 8));
  815. }
  816. }
  817. return nIndex + ncData;
  818. }
  819.  
  820.  
  821. /////////////////////////////////////////////////////////////////////////////
  822. // CQR_Encode::IsNumeralData
  823. bool CQR_Encode::IsNumeralData(unsigned char c)
  824. {
  825. if (c >= '0' && c <= '9')
  826. return 1;
  827.  
  828. return 0;
  829. }
  830.  
  831.  
  832. /////////////////////////////////////////////////////////////////////////////
  833. // CQR_Encode::IsAlphabetData
  834. bool CQR_Encode::IsAlphabetData(unsigned char c)
  835. {
  836. if (c >= '0' && c <= '9')
  837. return 1;
  838.  
  839. if (c >= 'A' && c <= 'Z')
  840. return 1;
  841.  
  842. if (c == ' ' || c == '$' || c == '%' || c == '*' || c == '+' || c == '-' || c == '.' || c == '/' || c == ':')
  843. return 1;
  844.  
  845. return 0;
  846. }
  847.  
  848.  
  849. /////////////////////////////////////////////////////////////////////////////
  850. // CQR_Encode::IsKanjiData
  851. bool CQR_Encode::IsKanjiData(unsigned char c1,unsigned char c2)
  852. {
  853. if (((c1 >= 0x81 && c1 <= 0x9f) || (c1 >= 0xe0 && c1 <= 0xeb)) && (c2 >= 0x40))
  854. {
  855. if ((c1 == 0x9f && c2 > 0xfc) || (c1 == 0xeb && c2 > 0xbf))
  856. return 0;
  857.  
  858. return 1;
  859. }
  860.  
  861. return 0;
  862. }
  863.  
  864.  
  865. /////////////////////////////////////////////////////////////////////////////
  866. // CQR_Encode::AlphabetToBinaly
  867. unsigned char CQR_Encode::AlphabetToBinaly(unsigned char c)
  868. {
  869. if (c >= '0' && c <= '9') return (unsigned char)(c - '0');
  870.  
  871. if (c >= 'A' && c <= 'Z') return (unsigned char)(c - 'A' + 10);
  872.  
  873. if (c == ' ') return 36;
  874.  
  875. if (c == '$') return 37;
  876.  
  877. if (c == '%') return 38;
  878.  
  879. if (c == '*') return 39;
  880.  
  881. if (c == '+') return 40;
  882.  
  883. if (c == '-') return 41;
  884.  
  885. if (c == '.') return 42;
  886.  
  887. if (c == '/') return 43;
  888.  
  889. return 44; // c == ':'
  890. }
  891.  
  892.  
  893. /////////////////////////////////////////////////////////////////////////////
  894. // CQR_Encode::KanjiToBinaly
  895. unsigned short CQR_Encode::KanjiToBinaly(unsigned short wc)
  896. {
  897. if (wc >= 0x8140 && wc <= 0x9ffc)
  898. wc -= 0x8140;
  899. else // (wc >= 0xe040 && wc <= 0xebbf)
  900. wc -= 0xc140;
  901.  
  902. return (unsigned short)(((wc >> 8) * 0xc0) + (wc & 0x00ff));
  903. }
  904.  
  905.  
  906. ///////////////////////////////////////////////////////////////////////////////
  907. //// CQR_Encode::GetRSCodeWord
  908. void CQR_Encode::GetRSCodeWord(unsigned char* lpbyRSWork,int ncRSCodeWord)
  909. {
  910. int i,j;
  911.  
  912. for (i = 0; i < ncDataCodeWord; ++i)
  913. {
  914. if (lpbyRSWork[0] != 0)
  915. {
  916. unsigned char nExpFirst = byIntToExp[lpbyRSWork[0]]; // 初項係数より乗数算出
  917.  
  918. for (j = 0; j < ncRSCodeWord; ++j)
  919. {
  920. // 各項乗数に初項乗数を加算(% 255 → α^255 = 1)
  921. unsigned char nExpElement = (unsigned char)(((int)(byRSExp[ncRSCodeWord][j] + nExpFirst)) % 255);
  922.  
  923. // 排他論理和による剰余算出
  924. lpbyRSWork[j] = (unsigned char)(lpbyRSWork[j + 1] ^ byExpToInt[nExpElement]);
  925. }
  926.  
  927. // 残り桁をシフト
  928. for (j = ncRSCodeWord; j < ncDataCodeWord + ncRSCodeWord - 1; ++j)
  929. lpbyRSWork[j] = lpbyRSWork[j + 1];
  930. }
  931. else
  932. {
  933. // 残り桁をシフト
  934. for (j = 0; j < ncDataCodeWord + ncRSCodeWord - 1; ++j)
  935. lpbyRSWork[j] = lpbyRSWork[j + 1];
  936. }
  937. }
  938. }
  939.  
  940.  
  941. /////////////////////////////////////////////////////////////////////////////
  942. // CQR_Encode::FormatModule
  943. void CQR_Encode::FormatModule()
  944. {
  945. int i,j;
  946.  
  947. memset(m_byModuleData,sizeof(m_byModuleData));
  948.  
  949. SetFunctionModule();
  950.  
  951. // データパターン配置
  952. SetCodeWordPattern();
  953.  
  954. if (m_nMaskingNo == -1)
  955. {
  956. // 最適マスキングパターン選択
  957. m_nMaskingNo = 0;
  958.  
  959. SetMaskingPattern(m_nMaskingNo); // マスキング
  960. SetFormatInfoPattern(m_nMaskingNo); // フォーマット情報パターン配置
  961.  
  962. int nMinPenalty = CountPenalty();
  963.  
  964. for (i = 1; i <= 7; ++i)
  965. {
  966. SetMaskingPattern(i); // マスキング
  967. SetFormatInfoPattern(i); // フォーマット情報パターン配置
  968.  
  969. int nPenalty = CountPenalty();
  970.  
  971. if (nPenalty < nMinPenalty)
  972. {
  973. nMinPenalty = nPenalty;
  974. m_nMaskingNo = i;
  975. }
  976. }
  977. }
  978.  
  979. SetMaskingPattern(m_nMaskingNo); // マスキング
  980. SetFormatInfoPattern(m_nMaskingNo); // フォーマット情報パターン配置
  981.  
  982. // モジュールパターンをブール値に変換
  983. for (i = 0; i < m_nSymbleSize; ++i)
  984. {
  985. for (j = 0; j < m_nSymbleSize; ++j)
  986. {
  987. m_byModuleData[i][j] = (unsigned char)((m_byModuleData[i][j] & 0x11) != 0);
  988. }
  989. }
  990. }
  991.  
  992.  
  993. /////////////////////////////////////////////////////////////////////////////
  994. // CQR_Encode::SetFunctionModule
  995. void CQR_Encode::SetFunctionModule()
  996. {
  997. int i,j;
  998.  
  999. // 位置検出パターン
  1000. SetFinderPattern(0,0);
  1001. SetFinderPattern(m_nSymbleSize - 7,0);
  1002. SetFinderPattern(0,m_nSymbleSize - 7);
  1003.  
  1004. // 位置検出パターンセパレータ
  1005. for (i = 0; i < 8; ++i)
  1006. {
  1007. m_byModuleData[i][7] = m_byModuleData[7][i] = '\x20';
  1008. m_byModuleData[m_nSymbleSize - 8][i] = m_byModuleData[m_nSymbleSize - 8 + i][7] = '\x20';
  1009. m_byModuleData[i][m_nSymbleSize - 8] = m_byModuleData[7][m_nSymbleSize - 8 + i] = '\x20';
  1010. }
  1011.  
  1012. // フォーマット情報記述位置を機能モジュール部として登録
  1013. for (i = 0; i < 9; ++i)
  1014. {
  1015. m_byModuleData[i][8] = m_byModuleData[8][i] = '\x20';
  1016. }
  1017.  
  1018. for (i = 0; i < 8; ++i)
  1019. {
  1020. m_byModuleData[m_nSymbleSize - 8 + i][8] = m_byModuleData[8][m_nSymbleSize - 8 + i] = '\x20';
  1021. }
  1022.  
  1023. // バージョン情報パターン
  1024. SetVersionPattern();
  1025.  
  1026. // 位置合わせパターン
  1027. for (i = 0; i < QR_VersonInfo[m_nVersion].ncAlignPoint; ++i)
  1028. {
  1029. SetAlignmentPattern(QR_VersonInfo[m_nVersion].nAlignPoint[i],6);
  1030. SetAlignmentPattern(6,QR_VersonInfo[m_nVersion].nAlignPoint[i]);
  1031.  
  1032. for (j = 0; j < QR_VersonInfo[m_nVersion].ncAlignPoint; ++j)
  1033. {
  1034. SetAlignmentPattern(QR_VersonInfo[m_nVersion].nAlignPoint[i],QR_VersonInfo[m_nVersion].nAlignPoint[j]);
  1035. }
  1036. }
  1037.  
  1038. // タイミングパターン
  1039. for (i = 8; i <= m_nSymbleSize - 9; ++i)
  1040. {
  1041. m_byModuleData[i][6] = (i % 2) == 0 ? '\x30' : '\x20';
  1042. m_byModuleData[6][i] = (i % 2) == 0 ? '\x30' : '\x20';
  1043. }
  1044. }
  1045.  
  1046.  
  1047. /////////////////////////////////////////////////////////////////////////////
  1048. // CQR_Encode::SetFinderPattern
  1049. void CQR_Encode::SetFinderPattern(int x,int y)
  1050. {
  1051. static unsigned char byPattern[] = { 0x7f,// 1111111b
  1052. 0x41,// 1000001b
  1053. 0x5d,// 1011101b
  1054. 0x5d,// 1011101b
  1055. 0x41,// 1000001b
  1056. 0x7f }; // 1111111b
  1057. int i,j;
  1058.  
  1059. for (i = 0; i < 7; ++i)
  1060. {
  1061. for (j = 0; j < 7; ++j)
  1062. {
  1063. m_byModuleData[x + j][y + i] = (byPattern[i] & (1 << (6 - j))) ? '\x30' : '\x20';
  1064. }
  1065. }
  1066. }
  1067.  
  1068. /////////////////////////////////////////////////////////////////////////////
  1069. // CQR_Encode::SetAlignmentPattern
  1070. void CQR_Encode::SetAlignmentPattern(int x,int y)
  1071. {
  1072. static unsigned char byPattern[] = { 0x1f,// 11111b
  1073. 0x11,// 10001b
  1074. 0x15,// 10101b
  1075. 0x11,// 10001b
  1076. 0x1f }; // 11111b
  1077. int i,j;
  1078.  
  1079. if (m_byModuleData[x][y] & 0x20)
  1080. return; // 機能モジュールと重複するため除外
  1081.  
  1082. x -= 2; y -= 2; // 左上隅座標に変換
  1083.  
  1084. for (i = 0; i < 5; ++i)
  1085. {
  1086. for (j = 0; j < 5; ++j)
  1087. {
  1088. m_byModuleData[x + j][y + i] = (byPattern[i] & (1 << (4 - j))) ? '\x30' : '\x20';
  1089. }
  1090. }
  1091. }
  1092.  
  1093.  
  1094. /////////////////////////////////////////////////////////////////////////////
  1095. // CQR_Encode::SetVersionPattern
  1096. void CQR_Encode::SetVersionPattern()
  1097. {
  1098. int i,j;
  1099.  
  1100. if (m_nVersion <= 6)
  1101. return;
  1102.  
  1103. int nVerData = m_nVersion << 12;
  1104.  
  1105. // 剰余ビット算出
  1106. for (i = 0; i < 6; ++i)
  1107. {
  1108. if (nVerData & (1 << (17 - i)))
  1109. {
  1110. nVerData ^= (0x1f25 << (5 - i));
  1111. }
  1112. }
  1113.  
  1114. nVerData += m_nVersion << 12;
  1115.  
  1116. for (i = 0; i < 6; ++i)
  1117. {
  1118. for (j = 0; j < 3; ++j)
  1119. {
  1120. m_byModuleData[m_nSymbleSize - 11 + j][i] = m_byModuleData[i][m_nSymbleSize - 11 + j] =
  1121. (nVerData & (1 << (i * 3 + j))) ? '\x30' : '\x20';
  1122. }
  1123. }
  1124. }
  1125.  
  1126.  
  1127. /////////////////////////////////////////////////////////////////////////////
  1128. // CQR_Encode::SetCodeWordPattern
  1129. void CQR_Encode::SetCodeWordPattern()
  1130. {
  1131. int x = m_nSymbleSize;
  1132. int y = m_nSymbleSize - 1;
  1133.  
  1134. int nCoef_x = 1; // x軸配置向き
  1135. int nCoef_y = 1; // y軸配置向き
  1136.  
  1137. int i,j;
  1138.  
  1139. for (i = 0; i < m_ncAllCodeWord; ++i)
  1140. {
  1141. for (j = 0; j < 8; ++j)
  1142. {
  1143. do
  1144. {
  1145. x += nCoef_x;
  1146. nCoef_x *= -1;
  1147.  
  1148. if (nCoef_x < 0)
  1149. {
  1150. y += nCoef_y;
  1151.  
  1152. if (y < 0 || y == m_nSymbleSize)
  1153. {
  1154. y = (y < 0) ? 0 : m_nSymbleSize - 1;
  1155. nCoef_y *= -1;
  1156.  
  1157. x -= 2;
  1158.  
  1159. if (x == 6) // タイミングパターン
  1160. --x;
  1161. }
  1162. }
  1163. } while (m_byModuleData[x][y] & 0x20); // 機能モジュールを除外
  1164.  
  1165. m_byModuleData[x][y] = (m_byAllCodeWord[i] & (1 << (7 - j))) ? '\x02' : '\x00';
  1166. }
  1167. }
  1168. }
  1169.  
  1170.  
  1171. /////////////////////////////////////////////////////////////////////////////
  1172. // CQR_Encode::SetMaskingPattern
  1173. void CQR_Encode::SetMaskingPattern(int nPatternNo)
  1174. {
  1175. int i,j;
  1176.  
  1177. for (i = 0; i < m_nSymbleSize; ++i)
  1178. {
  1179. for (j = 0; j < m_nSymbleSize; ++j)
  1180. {
  1181. if (!(m_byModuleData[j][i] & 0x20)) // 機能モジュールを除外
  1182. {
  1183. bool bMask;
  1184.  
  1185. switch (nPatternNo)
  1186. {
  1187. case 0:
  1188. bMask = ((i + j) % 2 == 0);
  1189. break;
  1190.  
  1191. case 1:
  1192. bMask = (i % 2 == 0);
  1193. break;
  1194.  
  1195. case 2:
  1196. bMask = (j % 3 == 0);
  1197. break;
  1198.  
  1199. case 3:
  1200. bMask = ((i + j) % 3 == 0);
  1201. break;
  1202.  
  1203. case 4:
  1204. bMask = (((i / 2) + (j / 3)) % 2 == 0);
  1205. break;
  1206.  
  1207. case 5:
  1208. bMask = (((i * j) % 2) + ((i * j) % 3) == 0);
  1209. break;
  1210.  
  1211. case 6:
  1212. bMask = ((((i * j) % 2) + ((i * j) % 3)) % 2 == 0);
  1213. break;
  1214.  
  1215. default: // case 7:
  1216. bMask = ((((i * j) % 3) + ((i + j) % 2)) % 2 == 0);
  1217. break;
  1218. }
  1219.  
  1220. m_byModuleData[j][i] = (unsigned char)((m_byModuleData[j][i] & 0xfe) | (((m_byModuleData[j][i] & 0x02) > 1) ^ bMask));
  1221. }
  1222. }
  1223. }
  1224. }
  1225.  
  1226.  
  1227. /////////////////////////////////////////////////////////////////////////////
  1228. // CQR_Encode::SetFormatInfoPattern
  1229. void CQR_Encode::SetFormatInfoPattern(int nPatternNo)
  1230. {
  1231. int nFormatInfo;
  1232. int i;
  1233.  
  1234. switch (m_nLevel)
  1235. {
  1236. case QR_LEVEL_M:
  1237. nFormatInfo = 0x00; // 00nnnb
  1238. break;
  1239.  
  1240. case QR_LEVEL_L:
  1241. nFormatInfo = 0x08; // 01nnnb
  1242. break;
  1243.  
  1244. case QR_LEVEL_Q:
  1245. nFormatInfo = 0x18; // 11nnnb
  1246. break;
  1247.  
  1248. default: // case QR_LEVEL_H:
  1249. nFormatInfo = 0x10; // 10nnnb
  1250. break;
  1251. }
  1252.  
  1253. nFormatInfo += nPatternNo;
  1254.  
  1255. int nFormatData = nFormatInfo << 10;
  1256.  
  1257. // 剰余ビット算出
  1258. for (i = 0; i < 5; ++i)
  1259. {
  1260. if (nFormatData & (1 << (14 - i)))
  1261. {
  1262. nFormatData ^= (0x0537 << (4 - i)); // 10100110111b
  1263. }
  1264. }
  1265.  
  1266. nFormatData += nFormatInfo << 10;
  1267.  
  1268. // マスキング
  1269. nFormatData ^= 0x5412; // 101010000010010b
  1270.  
  1271. // 左上位置検出パターン周り配置
  1272. for (i = 0; i <= 5; ++i)
  1273. m_byModuleData[8][i] = (nFormatData & (1 << i)) ? '\x30' : '\x20';
  1274.  
  1275. m_byModuleData[8][7] = (nFormatData & (1 << 6)) ? '\x30' : '\x20';
  1276. m_byModuleData[8][8] = (nFormatData & (1 << 7)) ? '\x30' : '\x20';
  1277. m_byModuleData[7][8] = (nFormatData & (1 << 8)) ? '\x30' : '\x20';
  1278.  
  1279. for (i = 9; i <= 14; ++i)
  1280. m_byModuleData[14 - i][8] = (nFormatData & (1 << i)) ? '\x30' : '\x20';
  1281.  
  1282. // 右上位置検出パターン下配置
  1283. for (i = 0; i <= 7; ++i)
  1284. m_byModuleData[m_nSymbleSize - 1 - i][8] = (nFormatData & (1 << i)) ? '\x30' : '\x20';
  1285.  
  1286. // 左下位置検出パターン右配置
  1287. m_byModuleData[8][m_nSymbleSize - 8] = '\x30'; // 固定暗モジュール
  1288.  
  1289. for (i = 8; i <= 14; ++i)
  1290. m_byModuleData[8][m_nSymbleSize - 15 + i] = (nFormatData & (1 << i)) ? '\x30' : '\x20';
  1291. }
  1292.  
  1293.  
  1294. /////////////////////////////////////////////////////////////////////////////
  1295. // CQR_Encode::CountPenalty
  1296. int CQR_Encode::CountPenalty()
  1297. {
  1298. int nPenalty = 0;
  1299. int i,j,k;
  1300.  
  1301. // 同色の列の隣接モジュール
  1302. for (i = 0; i < m_nSymbleSize; ++i)
  1303. {
  1304. for (j = 0; j < m_nSymbleSize - 4; ++j)
  1305. {
  1306. int nCount = 1;
  1307.  
  1308. for (k = j + 1; k < m_nSymbleSize; k++)
  1309. {
  1310. if (((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i][k] & 0x11) == 0))
  1311. ++nCount;
  1312. else
  1313. break;
  1314. }
  1315.  
  1316. if (nCount >= 5)
  1317. {
  1318. nPenalty += 3 + (nCount - 5);
  1319. }
  1320.  
  1321. j = k - 1;
  1322. }
  1323. }
  1324.  
  1325. // 同色の行の隣接モジュール
  1326. for (i = 0; i < m_nSymbleSize; ++i)
  1327. {
  1328. for (j = 0; j < m_nSymbleSize - 4; ++j)
  1329. {
  1330. int nCount = 1;
  1331.  
  1332. for (k = j + 1; k < m_nSymbleSize; k++)
  1333. {
  1334. if (((m_byModuleData[j][i] & 0x11) == 0) == ((m_byModuleData[k][i] & 0x11) == 0))
  1335. ++nCount;
  1336. else
  1337. break;
  1338. }
  1339.  
  1340. if (nCount >= 5)
  1341. {
  1342. nPenalty += 3 + (nCount - 5);
  1343. }
  1344.  
  1345. j = k - 1;
  1346. }
  1347. }
  1348.  
  1349.  
  1350. for (i = 0; i < m_nSymbleSize - 1; ++i)
  1351. {
  1352. for (j = 0; j < m_nSymbleSize - 1; ++j)
  1353. {
  1354. if ((((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i + 1][j] & 0x11) == 0)) &&
  1355. (((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i][j + 1] & 0x11) == 0)) &&
  1356. (((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i + 1][j + 1] & 0x11) == 0)))
  1357. {
  1358. nPenalty += 3;
  1359. }
  1360. }
  1361. }
  1362.  
  1363.  
  1364. for (i = 0; i < m_nSymbleSize; ++i)
  1365. {
  1366. for (j = 0; j < m_nSymbleSize - 6; ++j)
  1367. {
  1368. if (((j == 0) || (!(m_byModuleData[i][j - 1] & 0x11))) &&
  1369. (m_byModuleData[i][j] & 0x11) &&
  1370. (!(m_byModuleData[i][j + 1] & 0x11)) &&
  1371. (m_byModuleData[i][j + 2] & 0x11) &&
  1372. (m_byModuleData[i][j + 3] & 0x11) &&
  1373. (m_byModuleData[i][j + 4] & 0x11) &&
  1374. (!(m_byModuleData[i][j + 5] & 0x11)) &&
  1375. (m_byModuleData[i][j + 6] & 0x11) &&
  1376. ((j == m_nSymbleSize - 7) || (!(m_byModuleData[i][j + 7] & 0x11))))
  1377. {
  1378. // 前または後に4以上の明パターン
  1379. if (((j < 2 || !(m_byModuleData[i][j - 2] & 0x11)) &&
  1380. (j < 3 || !(m_byModuleData[i][j - 3] & 0x11)) &&
  1381. (j < 4 || !(m_byModuleData[i][j - 4] & 0x11))) ||
  1382. ((j >= m_nSymbleSize - 8 || !(m_byModuleData[i][j + 8] & 0x11)) &&
  1383. (j >= m_nSymbleSize - 9 || !(m_byModuleData[i][j + 9] & 0x11)) &&
  1384. (j >= m_nSymbleSize - 10 || !(m_byModuleData[i][j + 10] & 0x11))))
  1385. {
  1386. nPenalty += 40;
  1387. }
  1388. }
  1389. }
  1390. }
  1391.  
  1392. // 同一行における 1:1:3:1:1 比率(暗:明:暗:明:暗)のパターン
  1393. for (i = 0; i < m_nSymbleSize; ++i)
  1394. {
  1395. for (j = 0; j < m_nSymbleSize - 6; ++j)
  1396. {
  1397. if (((j == 0) || (!(m_byModuleData[j - 1][i] & 0x11))) && // 明 または シンボル外
  1398. (m_byModuleData[j][i] & 0x11) && // 暗 - 1
  1399. (!(m_byModuleData[j + 1][i] & 0x11)) && // 明 - 1
  1400. (m_byModuleData[j + 2][i] & 0x11) && // 暗 ┐
  1401. (m_byModuleData[j + 3][i] & 0x11) && // 暗 │3
  1402. (m_byModuleData[j + 4][i] & 0x11) && // 暗 ┘
  1403. (!(m_byModuleData[j + 5][i] & 0x11)) && // 明 - 1
  1404. (m_byModuleData[j + 6][i] & 0x11) && // 暗 - 1
  1405. ((j == m_nSymbleSize - 7) || (!(m_byModuleData[j + 7][i] & 0x11)))) // 明 または シンボル外
  1406. {
  1407. // 前または後に4以上の明パターン
  1408. if (((j < 2 || !(m_byModuleData[j - 2][i] & 0x11)) &&
  1409. (j < 3 || !(m_byModuleData[j - 3][i] & 0x11)) &&
  1410. (j < 4 || !(m_byModuleData[j - 4][i] & 0x11))) ||
  1411. ((j >= m_nSymbleSize - 8 || !(m_byModuleData[j + 8][i] & 0x11)) &&
  1412. (j >= m_nSymbleSize - 9 || !(m_byModuleData[j + 9][i] & 0x11)) &&
  1413. (j >= m_nSymbleSize - 10 || !(m_byModuleData[j + 10][i] & 0x11))))
  1414. {
  1415. nPenalty += 40;
  1416. }
  1417. }
  1418. }
  1419. }
  1420.  
  1421. // 全体に対する暗モジュールの占める割合
  1422. int nCount = 0;
  1423.  
  1424. for (i = 0; i < m_nSymbleSize; ++i)
  1425. {
  1426. for (j = 0; j < m_nSymbleSize; ++j)
  1427. {
  1428. if (!(m_byModuleData[i][j] & 0x11))
  1429. {
  1430. ++nCount;
  1431. }
  1432. }
  1433. }
  1434.  
  1435. nPenalty += (abs(50 - ((nCount * 100) / (m_nSymbleSize * m_nSymbleSize))) / 5) * 10;
  1436.  
  1437. return nPenalty;
  1438. }
QrNode.h @H_403_7@#ifndef QrNode_h #define QrNode_h #include <stdio.h> #include "cocos2d.h" #include "QR_Encode.h" USING_NS_CC; int register_all_QrNode(); class QrNode : public Node { public: ~QrNode(); /* * @brief 创建 二维码 node * @param[content] 二维码内容 * @param[nNodeSize] node 尺寸 * @param[nQrSize] 点大小 * @param[nLevel] 二维码level (容错率) * @param[nVersion] 二维码版本 * @param[bAutoExtent] 自动扩展二维码版本 * @param[nMaskinNo] 屏蔽模式 */ static QrNode* createQrNode(const std::string &content,const int &nNodeSize,const int &nQrSize = 5,const int &nLevel = 0,const int &nVersion = 0,const bool &bAutoExtent = true,const int &nMaskingNo = -1); /* * @brief 二维码图片存储 * @param[filename] 文件名 * @param[nLuaCallFunC] lua回调函数 * @return 是否存储成功 */ bool saveQrToFile( const std::string &filename,const int &nLuaCallFunC); private: bool initQrNode(const std::string &content,const int &nMaskingNo = -1); Node* drawQr(); private: int m_nQrSize; int m_nNodeSize; float m_fScaleRate; int m_nQrOriginSize; std::string m_strContent; CQR_Encode m_QREncode; Vector<Node*> m_vecQrFileChild; }; #endif /* QrNode_hpp */
QrNode.cpp
  1. #include "QrNode.h"
  2. #include "ui/CocosGUI.h"
  3. #if CC_ENABLE_SCRIPT_BINDING
  4. #include "CCLuaEngine.h"
  5. #include "tolua_fix.h"
  6. #include "LuaBasicConversions.h"
  7. #endif
  8.  
  9. static const std::string QR_NODE_NAME = "_@@_qr_node_name_@@_";
  10. QrNode::~QrNode()
  11. {
  12. m_vecQrFileChild.clear();
  13. }
  14.  
  15. QrNode* QrNode::createQrNode(const std::string &content,const int &nQrSize /*= 5*/,const int &nLevel /*= 0*/,const int &nVersion /*= 0*/,const bool &bAutoExtent /*= true*/,const int &nMaskingNo /*= -1*/)
  16. {
  17. QrNode *qr = new QrNode();
  18. if (nullptr != qr && qr->initQrNode(content,nNodeSize,nQrSize,nLevel,nVersion,bAutoExtent,nMaskingNo))
  19. {
  20. qr->autorelease();
  21. return qr;
  22. }
  23. CC_SAFE_DELETE(qr);
  24. return nullptr;
  25. }
  26.  
  27. void onCaptureScreenArea(const std::function<void(bool,const std::string&)>& afterCaptured,const std::string& filename,const Rect &area)
  28. {
  29. static bool startedCapture = false;
  30. if (startedCapture)
  31. {
  32. CCLOG("Screen capture is already working");
  33. if (afterCaptured)
  34. {
  35. afterCaptured(false,filename);
  36. }
  37. return;
  38. }
  39. else
  40. {
  41. startedCapture = true;
  42. }
  43. int width = area.size.width;
  44. int height = area.size.height;
  45. bool succeed = false;
  46. std::string outputFile = "";
  47. do
  48. {
  49. std::shared_ptr<GLubyte> buffer(new GLubyte[width * height * 4],[](GLubyte* p){ CC_SAFE_DELETE_ARRAY(p); });
  50. if (!buffer)
  51. {
  52. break;
  53. }
  54. glPixelStorei(GL_PACK_ALIGNMENT,1);
  55. glReadPixels(area.origin.x,area.origin.y,width,height,GL_RGBA,GL_UNSIGNED_BYTE,buffer.get());
  56. std::shared_ptr<GLubyte> flippedBuffer(new GLubyte[width * height * 4],[](GLubyte* p) { CC_SAFE_DELETE_ARRAY(p); });
  57. if (!flippedBuffer)
  58. {
  59. break;
  60. }
  61. for (int row = 0; row < height; ++row)
  62. {
  63. memcpy(flippedBuffer.get() + (height - row - 1) * width * 4,buffer.get() + row * width * 4,width * 4);
  64. }
  65. Image* image = new (std::nothrow) Image;
  66. if (image)
  67. {
  68. image->initWithRawData(flippedBuffer.get(),width * height * 4,8);
  69. if (FileUtils::getInstance()->isAbsolutePath(filename))
  70. {
  71. outputFile = filename;
  72. }
  73. else
  74. {
  75. CCASSERT(filename.find("/") == std::string::npos,"The existence of a relative path is not guaranteed!");
  76. outputFile = FileUtils::getInstance()->getWritablePath() + filename;
  77. }
  78. // Save image in AsyncTaskPool::TaskType::TASK_IO thread,and call afterCaptured in mainThread
  79. static bool succeedSaveToFile = false;
  80. std::function<void(void*)> mainThread = [afterCaptured,outputFile](void* param)
  81. {
  82. if (afterCaptured)
  83. {
  84. afterCaptured(succeedSaveToFile,outputFile);
  85. }
  86. startedCapture = false;
  87. };
  88. AsyncTaskPool::getInstance()->enqueue(AsyncTaskPool::TaskType::TASK_IO,mainThread,(void*)NULL,[image,outputFile]()
  89. {
  90. succeedSaveToFile = image->saveToFile(outputFile);
  91. delete image;
  92. });
  93. }
  94. else
  95. {
  96. CCLOG("Malloc Image memory Failed!");
  97. if (afterCaptured)
  98. {
  99. afterCaptured(succeed,outputFile);
  100. }
  101. startedCapture = false;
  102. }
  103. } while (0);
  104. }
  105.  
  106. /*
  107. * Capture screen interface
  108. */
  109. static EventListenerCustom* s_captureScreenListener;
  110. static CustomCommand s_captureScreenCommand;
  111. void captureScreenArea(const std::function<void(bool,const Rect &area)
  112. {
  113. if (s_captureScreenListener)
  114. {
  115. CCLOG("Warning: CaptureScreen has been called already,don't call more than once in one frame.");
  116. return;
  117. }
  118. s_captureScreenCommand.init(std::numeric_limits<float>::max());
  119. s_captureScreenCommand.func = std::bind(onCaptureScreenArea,afterCaptured,filename,area);
  120. s_captureScreenListener = Director::getInstance()->getEventDispatcher()->addCustomEventListener(Director::EVENT_AFTER_DRAW,[](EventCustom *event) {
  121. auto director = Director::getInstance();
  122. director->getEventDispatcher()->removeEventListener((EventListener*)(s_captureScreenListener));
  123. s_captureScreenListener = nullptr;
  124. director->getRenderer()->addCommand(&s_captureScreenCommand);
  125. director->getRenderer()->render();
  126. });
  127. }
  128.  
  129. bool QrNode::saveQrToFile(const std::string &filename,const int &nLuaCallFunC)
  130. {
  131. if (0 == nLuaCallFunC)
  132. {
  133. return false;
  134. }
  135. auto size = this->getContentSize();
  136. auto qr = this->drawQr();
  137. auto node = Node::create();
  138. node->addChild(qr);
  139. qr->setPositionY(m_nQrOriginSize);
  140. node->setScale(m_fScaleRate);
  141. auto render = RenderTexture::create(size.width,size.height);
  142. render->retain();
  143. render->beginWithClear(0,0);
  144. node->visit();
  145. render->end();
  146. Director::getInstance()->getRenderer()->render();
  147. return render->saveToFile(filename,true,[=](RenderTexture* render,const std::string& fullpath)
  148. {
  149. #if CC_ENABLE_SCRIPT_BINDING
  150. lua_State* tolua_S=LuaEngine::getInstance()->getLuaStack()->getLuaState();
  151. toluafix_get_function_by_refid(tolua_S,nLuaCallFunC);
  152. int result = 0;
  153. if (lua_isfunction(tolua_S,-1))
  154. {
  155. lua_pushstring(tolua_S,fullpath.c_str());
  156. result = LuaEngine::getInstance()->getLuaStack()->executeFunctionByHandler(nLuaCallFunC,1);
  157. }
  158. if (result)
  159. {
  160. CCLOG("saveQrToFile-luacallback-handler-false:%d",nLuaCallFunC);
  161. }
  162. #endif
  163. render->release();
  164. });
  165. }
  166.  
  167. bool QrNode::initQrNode(const std::string &content,const int &nMaskingNo /*= -1*/)
  168. {
  169. bool bRes = false;
  170. do
  171. {
  172. m_strContent = content;
  173. m_nQrSize = nQrSize;
  174. m_nNodeSize = nNodeSize;
  175. if (m_QREncode.EncodeData(nLevel,nMaskingNo,(char*)content.c_str()))
  176. {
  177. Node *qrNode = this->drawQr();
  178. if (nullptr != qrNode)
  179. {
  180. m_nQrOriginSize = (m_QREncode.m_nSymbleSize + QR_MARGIN * 2) * m_nQrSize;
  181. m_fScaleRate = (float)nNodeSize / m_nQrOriginSize;
  182. this->setScale(m_fScaleRate);
  183. this->setContentSize(Size(m_fScaleRate * m_nQrOriginSize,m_fScaleRate * m_nQrOriginSize));
  184. this->addChild(qrNode);
  185. qrNode->setName(QR_NODE_NAME);
  186. qrNode->setPosition(-m_nQrOriginSize * 0.5,m_nQrOriginSize * 0.5);
  187. bRes = true;
  188. }
  189. }
  190. } while (false);
  191. return bRes;
  192. }
  193.  
  194. Node* QrNode::drawQr()
  195. {
  196. int nSize = m_nQrSize;
  197. DrawNode *pQRNode = DrawNode::create();
  198. for (int i = 0; i < m_QREncode.m_nSymbleSize; ++i)
  199. {
  200. for (int j = 0; j < m_QREncode.m_nSymbleSize; ++j)
  201. {
  202. if (m_QREncode.m_byModuleData[i][j] == 1)
  203. {
  204. Vec2 Vec2_1 = Vec2((i + QR_MARGIN) * nSize,(j + QR_MARGIN) * nSize);
  205. Vec2 Vec2_2 = Vec2(((i + QR_MARGIN) + 1)*nSize,((j + QR_MARGIN) + 1)*nSize);
  206. pQRNode->drawSolidRect(Vec2_1,Vec2_2,Color4F(0,1));
  207. }
  208. else
  209. {
  210.  
  211. pQRNode->drawSolidRect(Vec2((i + QR_MARGIN)*nSize,(j + QR_MARGIN)*nSize),Vec2(((i + QR_MARGIN) + 1)*nSize,((j + QR_MARGIN) + 1)*nSize),Color4F(1,1));
  212. }
  213. }
  214. }
  215. pQRNode->drawSolidRect(Vec2(0,0),Vec2((m_QREncode.m_nSymbleSize + QR_MARGIN * 2) * nSize,(QR_MARGIN) * nSize),1));
  216. pQRNode->drawSolidRect(Vec2(0,Vec2((QR_MARGIN) * nSize,(m_QREncode.m_nSymbleSize + QR_MARGIN * 2) * nSize),1));
  217. pQRNode->drawSolidRect(Vec2((m_QREncode.m_nSymbleSize + QR_MARGIN) * nSize,(m_QREncode.m_nSymbleSize + QR_MARGIN) * nSize),1));
  218. pQRNode->setScaleY(-1);
  219.  
  220. return pQRNode;
  221. }
  222.  
  223. #if CC_ENABLE_SCRIPT_BINDING
  224. static int toLua_QrNode_createQrNode(lua_State *tolua_S)
  225. {
  226. int argc = lua_gettop(tolua_S);
  227. QrNode *obj = nullptr;
  228. std::string content = "";
  229. int nodesize = 0;
  230. int qrsize = 5;
  231. int level = 0;
  232. int version = 0;
  233. bool autoextent = true;
  234. int maskingno = -1;
  235. if (argc >= 3)
  236. {
  237. content = lua_tostring(tolua_S,2);
  238. nodesize = (int)lua_tonumber(tolua_S,3);
  239. if (argc >= 4)
  240. {
  241. qrsize = (int)lua_tonumber(tolua_S,4);
  242. }
  243. if (argc >= 5)
  244. {
  245. level = (int)lua_tonumber(tolua_S,5);
  246. }
  247. if (argc >= 6)
  248. {
  249. version = (int)lua_tonumber(tolua_S,6);
  250. }
  251. if (argc >= 7)
  252. {
  253. autoextent = (lua_toboolean(tolua_S,7) == 1);
  254. }
  255. if (argc >= 8)
  256. {
  257. maskingno = (int)lua_tonumber(tolua_S,8);
  258. }
  259. obj = QrNode::createQrNode(content,nodesize,qrsize,level,version,autoextent,maskingno);
  260. }
  261. int nID = (nullptr != obj) ? obj->_ID : -1;
  262. int *pLuaID = (nullptr != obj) ? &obj->_luaID : nullptr;
  263. toluafix_pushusertype_ccobject(tolua_S,nID,pLuaID,(void*)obj,"cc.QrNode");
  264. return 1;
  265. }
  266.  
  267. static int toLua_QrNode_saveQrToFile(lua_State *tolua_S)
  268. {
  269. bool bRes = false;
  270. int argc = lua_gettop(tolua_S);
  271. if (argc == 3)
  272. {
  273. QrNode *obj = (QrNode*)tolua_tousertype(tolua_S,nullptr);
  274. if (nullptr != obj)
  275. {
  276. std::string filename = lua_tostring(tolua_S,2);
  277. int handler = toluafix_ref_function(tolua_S,0);
  278. bRes = obj->saveQrToFile(filename,handler);
  279. }
  280. }
  281. lua_pushboolean(tolua_S,bRes);
  282. return 1;
  283. }
  284.  
  285. static int toLua_captureScreenWithArea(lua_State *tolua_S)
  286. {
  287. bool bRes = false;
  288. int argc = lua_gettop(tolua_S);
  289. if (argc == 3)
  290. {
  291. cocos2d::Rect arg0;
  292. bRes &= luaval_to_rect(tolua_S,&arg0,"captureScreenWithArea");
  293. std::string filename = lua_tostring(tolua_S,2);
  294. int handler = toluafix_ref_function(tolua_S,0);
  295. if (0 != handler)
  296. {
  297. captureScreenArea([=](bool ok,const std::string& savepath)
  298. {
  299. toluafix_get_function_by_refid(tolua_S,handler);
  300. int result = 0;
  301. if (lua_isfunction(tolua_S,-1))
  302. {
  303. lua_pushboolean(tolua_S,ok);
  304. lua_pushstring(tolua_S,savepath.c_str());
  305. result = LuaEngine::getInstance()->getLuaStack()->executeFunctionByHandler(handler,2);
  306. }
  307. if (result)
  308. {
  309. CCLOG("saveQrToFile-luacallback-handler-false:%d",handler);
  310. }
  311. },arg0);
  312. }
  313. }
  314. lua_pushboolean(tolua_S,bRes);
  315. return 1;
  316. }
  317. #endif
  318.  
  319. int register_all_QrNode()
  320. {
  321. #if CC_ENABLE_SCRIPT_BINDING
  322. lua_State* tolua_S = LuaEngine::getInstance()->getLuaStack()->getLuaState();
  323. tolua_usertype(tolua_S,"cc.QrNode");
  324. tolua_cclass(tolua_S,"QrNode","cc.QrNode","cc.Node",nullptr);
  325. tolua_beginmodule(tolua_S,"QrNode");
  326. tolua_function(tolua_S,"createQrNode",toLua_QrNode_createQrNode);
  327. tolua_function(tolua_S,"saveQrToFile",toLua_QrNode_saveQrToFile);
  328. tolua_endmodule(tolua_S);
  329. //全局函数
  330. lua_register(tolua_S,"captureScreenWithArea",toLua_captureScreenWithArea);
  331. std::string typeName = typeid(QrNode).name();
  332. g_luaType[typeName] = "cc.QrNode";
  333. g_typeCast["QrNode"] = "cc.QrNode";
  334. #endif
  335. return 1;
  336. }

猜你在找的Cocos2d-x相关文章