merge
[electrum-nvc.git] / client / pyqrnative.py
1 import math
2
3 #from PIL import Image, ImageDraw
4
5 #QRCode for Python
6 #
7 #Ported from the Javascript library by Sam Curren
8 #
9 #QRCode for Javascript
10 #http://d-project.googlecode.com/svn/trunk/misc/qrcode/js/qrcode.js
11 #
12 #Copyright (c) 2009 Kazuhiko Arase
13 #
14 #URL: http://www.d-project.com/
15 #
16 #Licensed under the MIT license:
17 #   http://www.opensource.org/licenses/mit-license.php
18 #
19 # The word "QR Code" is registered trademark of
20 # DENSO WAVE INCORPORATED
21 #   http://www.denso-wave.com/qrcode/faqpatent-e.html
22
23
24 class QR8bitByte:
25
26     def __init__(self, data):
27         self.mode = QRMode.MODE_8BIT_BYTE
28         self.data = data
29
30     def getLength(self):
31         return len(self.data)
32
33     def write(self, buffer):
34         for i in range(len(self.data)):
35             #// not JIS ...
36             buffer.put(ord(self.data[i]), 8)
37     def __repr__(self):
38         return self.data
39
40 class QRCode:
41     def __init__(self, typeNumber, errorCorrectLevel):
42         self.typeNumber = typeNumber
43         self.errorCorrectLevel = errorCorrectLevel
44         self.modules = None
45         self.moduleCount = 0
46         self.dataCache = None
47         self.dataList = []
48     def addData(self, data):
49         newData = QR8bitByte(data)
50         self.dataList.append(newData)
51         self.dataCache = None
52     def isDark(self, row, col):
53         if (row < 0 or self.moduleCount <= row or col < 0 or self.moduleCount <= col):
54             raise Exception("%s,%s - %s" % (row, col, self.moduleCount))
55         return self.modules[row][col]
56     def getModuleCount(self):
57         return self.moduleCount
58     def make(self):
59         self.makeImpl(False, self.getBestMaskPattern() )
60     def makeImpl(self, test, maskPattern):
61
62         self.moduleCount = self.typeNumber * 4 + 17
63         self.modules = [None for x in range(self.moduleCount)]
64
65         for row in range(self.moduleCount):
66
67             self.modules[row] = [None for x in range(self.moduleCount)]
68
69             for col in range(self.moduleCount):
70                 self.modules[row][col] = None #//(col + row) % 3;
71
72         self.setupPositionProbePattern(0, 0)
73         self.setupPositionProbePattern(self.moduleCount - 7, 0)
74         self.setupPositionProbePattern(0, self.moduleCount - 7)
75         self.setupPositionAdjustPattern()
76         self.setupTimingPattern()
77         self.setupTypeInfo(test, maskPattern)
78
79         if (self.typeNumber >= 7):
80             self.setupTypeNumber(test)
81
82         if (self.dataCache == None):
83             self.dataCache = QRCode.createData(self.typeNumber, self.errorCorrectLevel, self.dataList)
84         self.mapData(self.dataCache, maskPattern)
85
86     def setupPositionProbePattern(self, row, col):
87
88         for r in range(-1, 8):
89
90             if (row + r <= -1 or self.moduleCount <= row + r): continue
91
92             for c in range(-1, 8):
93
94                 if (col + c <= -1 or self.moduleCount <= col + c): continue
95
96                 if ( (0 <= r and r <= 6 and (c == 0 or c == 6) )
97                         or (0 <= c and c <= 6 and (r == 0 or r == 6) )
98                         or (2 <= r and r <= 4 and 2 <= c and c <= 4) ):
99                     self.modules[row + r][col + c] = True;
100                 else:
101                     self.modules[row + r][col + c] = False;
102
103     def getBestMaskPattern(self):
104
105         minLostPoint = 0
106         pattern = 0
107
108         for i in range(8):
109
110             self.makeImpl(True, i);
111
112             lostPoint = QRUtil.getLostPoint(self);
113
114             if (i == 0 or minLostPoint > lostPoint):
115                 minLostPoint = lostPoint
116                 pattern = i
117
118         return pattern
119
120
121     def setupTimingPattern(self):
122
123         for r in range(8, self.moduleCount - 8):
124             if (self.modules[r][6] != None):
125                 continue
126             self.modules[r][6] = (r % 2 == 0)
127
128         for c in range(8, self.moduleCount - 8):
129             if (self.modules[6][c] != None):
130                 continue
131             self.modules[6][c] = (c % 2 == 0)
132
133     def setupPositionAdjustPattern(self):
134
135         pos = QRUtil.getPatternPosition(self.typeNumber)
136
137         for i in range(len(pos)):
138
139             for j in range(len(pos)):
140
141                 row = pos[i]
142                 col = pos[j]
143
144                 if (self.modules[row][col] != None):
145                     continue
146
147                 for r in range(-2, 3):
148
149                     for c in range(-2, 3):
150
151                         if (r == -2 or r == 2 or c == -2 or c == 2 or (r == 0 and c == 0) ):
152                             self.modules[row + r][col + c] = True
153                         else:
154                             self.modules[row + r][col + c] = False
155
156     def setupTypeNumber(self, test):
157
158         bits = QRUtil.getBCHTypeNumber(self.typeNumber)
159
160         for i in range(18):
161             mod = (not test and ( (bits >> i) & 1) == 1)
162             self.modules[i // 3][i % 3 + self.moduleCount - 8 - 3] = mod;
163
164         for i in range(18):
165             mod = (not test and ( (bits >> i) & 1) == 1)
166             self.modules[i % 3 + self.moduleCount - 8 - 3][i // 3] = mod;
167
168     def setupTypeInfo(self, test, maskPattern):
169
170         data = (self.errorCorrectLevel << 3) | maskPattern
171         bits = QRUtil.getBCHTypeInfo(data)
172
173         #// vertical
174         for i in range(15):
175
176             mod = (not test and ( (bits >> i) & 1) == 1)
177
178             if (i < 6):
179                 self.modules[i][8] = mod
180             elif (i < 8):
181                 self.modules[i + 1][8] = mod
182             else:
183                 self.modules[self.moduleCount - 15 + i][8] = mod
184
185         #// horizontal
186         for i in range(15):
187
188             mod = (not test and ( (bits >> i) & 1) == 1);
189
190             if (i < 8):
191                 self.modules[8][self.moduleCount - i - 1] = mod
192             elif (i < 9):
193                 self.modules[8][15 - i - 1 + 1] = mod
194             else:
195                 self.modules[8][15 - i - 1] = mod
196
197         #// fixed module
198         self.modules[self.moduleCount - 8][8] = (not test)
199
200     def mapData(self, data, maskPattern):
201
202         inc = -1
203         row = self.moduleCount - 1
204         bitIndex = 7
205         byteIndex = 0
206
207         for col in range(self.moduleCount - 1, 0, -2):
208
209             if (col == 6): col-=1
210
211             while (True):
212
213                 for c in range(2):
214
215                     if (self.modules[row][col - c] == None):
216
217                         dark = False
218
219                         if (byteIndex < len(data)):
220                             dark = ( ( (data[byteIndex] >> bitIndex) & 1) == 1)
221
222                         mask = QRUtil.getMask(maskPattern, row, col - c)
223
224                         if (mask):
225                             dark = not dark
226
227                         self.modules[row][col - c] = dark
228                         bitIndex-=1
229
230                         if (bitIndex == -1):
231                             byteIndex+=1
232                             bitIndex = 7
233
234                 row += inc
235
236                 if (row < 0 or self.moduleCount <= row):
237                     row -= inc
238                     inc = -inc
239                     break
240     PAD0 = 0xEC
241     PAD1 = 0x11
242
243     @staticmethod
244     def createData(typeNumber, errorCorrectLevel, dataList):
245
246         rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel)
247
248         buffer = QRBitBuffer();
249
250         for i in range(len(dataList)):
251             data = dataList[i]
252             buffer.put(data.mode, 4)
253             buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber) )
254             data.write(buffer)
255
256         #// calc num max data.
257         totalDataCount = 0;
258         for i in range(len(rsBlocks)):
259             totalDataCount += rsBlocks[i].dataCount
260
261         if (buffer.getLengthInBits() > totalDataCount * 8):
262             raise Exception("code length overflow. ("
263                 + buffer.getLengthInBits()
264                 + ">"
265                 +  totalDataCount * 8
266                 + ")")
267
268         #// end code
269         if (buffer.getLengthInBits() + 4 <= totalDataCount * 8):
270             buffer.put(0, 4)
271
272         #// padding
273         while (buffer.getLengthInBits() % 8 != 0):
274             buffer.putBit(False)
275
276         #// padding
277         while (True):
278
279             if (buffer.getLengthInBits() >= totalDataCount * 8):
280                 break
281             buffer.put(QRCode.PAD0, 8)
282
283             if (buffer.getLengthInBits() >= totalDataCount * 8):
284                 break
285             buffer.put(QRCode.PAD1, 8)
286
287         return QRCode.createBytes(buffer, rsBlocks)
288
289     @staticmethod
290     def createBytes(buffer, rsBlocks):
291
292         offset = 0
293
294         maxDcCount = 0
295         maxEcCount = 0
296
297         dcdata = [0 for x in range(len(rsBlocks))]
298         ecdata = [0 for x in range(len(rsBlocks))]
299
300         for r in range(len(rsBlocks)):
301
302             dcCount = rsBlocks[r].dataCount
303             ecCount = rsBlocks[r].totalCount - dcCount
304
305             maxDcCount = max(maxDcCount, dcCount)
306             maxEcCount = max(maxEcCount, ecCount)
307
308             dcdata[r] = [0 for x in range(dcCount)]
309
310             for i in range(len(dcdata[r])):
311                 dcdata[r][i] = 0xff & buffer.buffer[i + offset]
312             offset += dcCount
313
314             rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount)
315             rawPoly = QRPolynomial(dcdata[r], rsPoly.getLength() - 1)
316
317             modPoly = rawPoly.mod(rsPoly)
318             ecdata[r] = [0 for x in range(rsPoly.getLength()-1)]
319             for i in range(len(ecdata[r])):
320                 modIndex = i + modPoly.getLength() - len(ecdata[r])
321                 if (modIndex >= 0):
322                     ecdata[r][i] = modPoly.get(modIndex)
323                 else:
324                     ecdata[r][i] = 0
325
326         totalCodeCount = 0
327         for i in range(len(rsBlocks)):
328             totalCodeCount += rsBlocks[i].totalCount
329
330         data = [None for x in range(totalCodeCount)]
331         index = 0
332
333         for i in range(maxDcCount):
334             for r in range(len(rsBlocks)):
335                 if (i < len(dcdata[r])):
336                     data[index] = dcdata[r][i]
337                     index+=1
338
339         for i in range(maxEcCount):
340             for r in range(len(rsBlocks)):
341                 if (i < len(ecdata[r])):
342                     data[index] = ecdata[r][i]
343                     index+=1
344
345         return data
346
347
348 class QRMode:
349     MODE_NUMBER = 1 << 0
350     MODE_ALPHA_NUM = 1 << 1
351     MODE_8BIT_BYTE = 1 << 2
352     MODE_KANJI = 1 << 3
353
354 class QRErrorCorrectLevel:
355     L = 1
356     M = 0
357     Q = 3
358     H = 2
359
360 class QRMaskPattern:
361     PATTERN000 = 0
362     PATTERN001 = 1
363     PATTERN010 = 2
364     PATTERN011 = 3
365     PATTERN100 = 4
366     PATTERN101 = 5
367     PATTERN110 = 6
368     PATTERN111 = 7
369
370 class QRUtil(object):
371     PATTERN_POSITION_TABLE = [
372         [],
373         [6, 18],
374         [6, 22],
375         [6, 26],
376         [6, 30],
377         [6, 34],
378         [6, 22, 38],
379         [6, 24, 42],
380         [6, 26, 46],
381         [6, 28, 50],
382         [6, 30, 54],
383         [6, 32, 58],
384         [6, 34, 62],
385         [6, 26, 46, 66],
386         [6, 26, 48, 70],
387         [6, 26, 50, 74],
388         [6, 30, 54, 78],
389         [6, 30, 56, 82],
390         [6, 30, 58, 86],
391         [6, 34, 62, 90],
392         [6, 28, 50, 72, 94],
393         [6, 26, 50, 74, 98],
394         [6, 30, 54, 78, 102],
395         [6, 28, 54, 80, 106],
396         [6, 32, 58, 84, 110],
397         [6, 30, 58, 86, 114],
398         [6, 34, 62, 90, 118],
399         [6, 26, 50, 74, 98, 122],
400         [6, 30, 54, 78, 102, 126],
401         [6, 26, 52, 78, 104, 130],
402         [6, 30, 56, 82, 108, 134],
403         [6, 34, 60, 86, 112, 138],
404         [6, 30, 58, 86, 114, 142],
405         [6, 34, 62, 90, 118, 146],
406         [6, 30, 54, 78, 102, 126, 150],
407         [6, 24, 50, 76, 102, 128, 154],
408         [6, 28, 54, 80, 106, 132, 158],
409         [6, 32, 58, 84, 110, 136, 162],
410         [6, 26, 54, 82, 110, 138, 166],
411         [6, 30, 58, 86, 114, 142, 170]
412     ]
413
414     G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0)
415     G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0)
416     G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1)
417
418     @staticmethod
419     def getBCHTypeInfo(data):
420         d = data << 10;
421         while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0):
422             d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) ) )
423
424         return ( (data << 10) | d) ^ QRUtil.G15_MASK
425     @staticmethod
426     def getBCHTypeNumber(data):
427         d = data << 12;
428         while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0):
429             d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) ) )
430         return (data << 12) | d
431     @staticmethod
432     def getBCHDigit(data):
433         digit = 0;
434         while (data != 0):
435             digit += 1
436             data >>= 1
437         return digit
438     @staticmethod
439     def getPatternPosition(typeNumber):
440         return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]
441     @staticmethod
442     def getMask(maskPattern, i, j):
443         if maskPattern == QRMaskPattern.PATTERN000 : return (i + j) % 2 == 0
444         if maskPattern == QRMaskPattern.PATTERN001 : return i % 2 == 0
445         if maskPattern == QRMaskPattern.PATTERN010 : return j % 3 == 0
446         if maskPattern == QRMaskPattern.PATTERN011 : return (i + j) % 3 == 0
447         if maskPattern == QRMaskPattern.PATTERN100 : return (math.floor(i / 2) + math.floor(j / 3) ) % 2 == 0
448         if maskPattern == QRMaskPattern.PATTERN101 : return (i * j) % 2 + (i * j) % 3 == 0
449         if maskPattern == QRMaskPattern.PATTERN110 : return ( (i * j) % 2 + (i * j) % 3) % 2 == 0
450         if maskPattern == QRMaskPattern.PATTERN111 : return ( (i * j) % 3 + (i + j) % 2) % 2 == 0
451         raise Exception("bad maskPattern:" + maskPattern);
452     @staticmethod
453     def getErrorCorrectPolynomial(errorCorrectLength):
454         a = QRPolynomial([1], 0);
455         for i in range(errorCorrectLength):
456             a = a.multiply(QRPolynomial([1, QRMath.gexp(i)], 0) )
457         return a
458     @staticmethod
459     def getLengthInBits(mode, type):
460
461         if 1 <= type and type < 10:
462
463             #// 1 - 9
464
465             if mode == QRMode.MODE_NUMBER     : return 10
466             if mode == QRMode.MODE_ALPHA_NUM     : return 9
467             if mode == QRMode.MODE_8BIT_BYTE    : return 8
468             if mode == QRMode.MODE_KANJI      : return 8
469             raise Exception("mode:" + mode)
470
471         elif (type < 27):
472
473             #// 10 - 26
474
475             if mode == QRMode.MODE_NUMBER     : return 12
476             if mode == QRMode.MODE_ALPHA_NUM     : return 11
477             if mode == QRMode.MODE_8BIT_BYTE    : return 16
478             if mode == QRMode.MODE_KANJI      : return 10
479             raise Exception("mode:" + mode)
480
481         elif (type < 41):
482
483             #// 27 - 40
484
485             if mode == QRMode.MODE_NUMBER     : return 14
486             if mode == QRMode.MODE_ALPHA_NUM    : return 13
487             if mode == QRMode.MODE_8BIT_BYTE    : return 16
488             if mode == QRMode.MODE_KANJI      : return 12
489             raise Exception("mode:" + mode)
490
491         else:
492             raise Exception("type:" + type)
493     @staticmethod
494     def getLostPoint(qrCode):
495
496         moduleCount = qrCode.getModuleCount();
497
498         lostPoint = 0;
499
500         #// LEVEL1
501
502         for row in range(moduleCount):
503
504             for col in range(moduleCount):
505
506                 sameCount = 0;
507                 dark = qrCode.isDark(row, col);
508
509                 for r in range(-1, 2):
510
511                     if (row + r < 0 or moduleCount <= row + r):
512                         continue
513
514                     for c in range(-1, 2):
515
516                         if (col + c < 0 or moduleCount <= col + c):
517                             continue
518                         if (r == 0 and c == 0):
519                             continue
520
521                         if (dark == qrCode.isDark(row + r, col + c) ):
522                             sameCount+=1
523                 if (sameCount > 5):
524                     lostPoint += (3 + sameCount - 5)
525
526         #// LEVEL2
527
528         for row in range(moduleCount - 1):
529             for col in range(moduleCount - 1):
530                 count = 0;
531                 if (qrCode.isDark(row,     col    ) ): count+=1
532                 if (qrCode.isDark(row + 1, col    ) ): count+=1
533                 if (qrCode.isDark(row,     col + 1) ): count+=1
534                 if (qrCode.isDark(row + 1, col + 1) ): count+=1
535                 if (count == 0 or count == 4):
536                     lostPoint += 3
537
538         #// LEVEL3
539
540         for row in range(moduleCount):
541             for col in range(moduleCount - 6):
542                 if (qrCode.isDark(row, col)
543                         and not qrCode.isDark(row, col + 1)
544                         and  qrCode.isDark(row, col + 2)
545                         and  qrCode.isDark(row, col + 3)
546                         and  qrCode.isDark(row, col + 4)
547                         and not qrCode.isDark(row, col + 5)
548                         and  qrCode.isDark(row, col + 6) ):
549                     lostPoint += 40
550
551         for col in range(moduleCount):
552             for row in range(moduleCount - 6):
553                 if (qrCode.isDark(row, col)
554                         and not qrCode.isDark(row + 1, col)
555                         and  qrCode.isDark(row + 2, col)
556                         and  qrCode.isDark(row + 3, col)
557                         and  qrCode.isDark(row + 4, col)
558                         and not qrCode.isDark(row + 5, col)
559                         and  qrCode.isDark(row + 6, col) ):
560                     lostPoint += 40
561
562         #// LEVEL4
563
564         darkCount = 0;
565
566         for col in range(moduleCount):
567             for row in range(moduleCount):
568                 if (qrCode.isDark(row, col) ):
569                     darkCount+=1
570
571         ratio = abs(100 * darkCount / moduleCount / moduleCount - 50) / 5
572         lostPoint += ratio * 10
573
574         return lostPoint
575
576 class QRMath:
577
578     @staticmethod
579     def glog(n):
580         if (n < 1):
581             raise Exception("glog(" + n + ")")
582         return LOG_TABLE[n];
583     @staticmethod
584     def gexp(n):
585         while n < 0:
586             n += 255
587         while n >= 256:
588             n -= 255
589         return EXP_TABLE[n];
590
591 EXP_TABLE = [x for x in range(256)]
592
593 LOG_TABLE = [x for x in range(256)]
594
595 for i in range(8):
596     EXP_TABLE[i] = 1 << i;
597
598 for i in range(8, 256):
599     EXP_TABLE[i] = EXP_TABLE[i - 4] ^ EXP_TABLE[i - 5] ^ EXP_TABLE[i - 6] ^ EXP_TABLE[i - 8]
600
601 for i in range(255):
602     LOG_TABLE[EXP_TABLE[i] ] = i
603
604 class QRPolynomial:
605
606     def __init__(self, num, shift):
607
608         if (len(num) == 0):
609             raise Exception(num.length + "/" + shift)
610
611         offset = 0
612
613         while offset < len(num) and num[offset] == 0:
614             offset += 1
615
616         self.num = [0 for x in range(len(num)-offset+shift)]
617         for i in range(len(num) - offset):
618             self.num[i] = num[i + offset]
619
620
621     def get(self, index):
622         return self.num[index]
623     def getLength(self):
624         return len(self.num)
625     def multiply(self, e):
626         num = [0 for x in range(self.getLength() + e.getLength() - 1)];
627
628         for i in range(self.getLength()):
629             for j in range(e.getLength()):
630                 num[i + j] ^= QRMath.gexp(QRMath.glog(self.get(i) ) + QRMath.glog(e.get(j) ) )
631
632         return QRPolynomial(num, 0);
633     def mod(self, e):
634
635         if (self.getLength() - e.getLength() < 0):
636             return self;
637
638         ratio = QRMath.glog(self.get(0) ) - QRMath.glog(e.get(0) )
639
640         num = [0 for x in range(self.getLength())]
641
642         for i in range(self.getLength()):
643             num[i] = self.get(i);
644
645         for i in range(e.getLength()):
646             num[i] ^= QRMath.gexp(QRMath.glog(e.get(i) ) + ratio)
647
648         # recursive call
649         return QRPolynomial(num, 0).mod(e);
650
651 class QRRSBlock:
652
653     RS_BLOCK_TABLE = [
654
655         #// L
656         #// M
657         #// Q
658         #// H
659
660         #// 1
661         [1, 26, 19],
662         [1, 26, 16],
663         [1, 26, 13],
664         [1, 26, 9],
665
666         #// 2
667         [1, 44, 34],
668         [1, 44, 28],
669         [1, 44, 22],
670         [1, 44, 16],
671
672         #// 3
673         [1, 70, 55],
674         [1, 70, 44],
675         [2, 35, 17],
676         [2, 35, 13],
677
678         #// 4
679         [1, 100, 80],
680         [2, 50, 32],
681         [2, 50, 24],
682         [4, 25, 9],
683
684         #// 5
685         [1, 134, 108],
686         [2, 67, 43],
687         [2, 33, 15, 2, 34, 16],
688         [2, 33, 11, 2, 34, 12],
689
690         #// 6
691         [2, 86, 68],
692         [4, 43, 27],
693         [4, 43, 19],
694         [4, 43, 15],
695
696         #// 7
697         [2, 98, 78],
698         [4, 49, 31],
699         [2, 32, 14, 4, 33, 15],
700         [4, 39, 13, 1, 40, 14],
701
702         #// 8
703         [2, 121, 97],
704         [2, 60, 38, 2, 61, 39],
705         [4, 40, 18, 2, 41, 19],
706         [4, 40, 14, 2, 41, 15],
707
708         #// 9
709         [2, 146, 116],
710         [3, 58, 36, 2, 59, 37],
711         [4, 36, 16, 4, 37, 17],
712         [4, 36, 12, 4, 37, 13],
713
714         #// 10
715         [2, 86, 68, 2, 87, 69],
716         [4, 69, 43, 1, 70, 44],
717         [6, 43, 19, 2, 44, 20],
718         [6, 43, 15, 2, 44, 16],
719
720       # 11
721       [4, 101, 81],
722       [1, 80, 50, 4, 81, 51],
723       [4, 50, 22, 4, 51, 23],
724       [3, 36, 12, 8, 37, 13],
725
726       # 12
727       [2, 116, 92, 2, 117, 93],
728       [6, 58, 36, 2, 59, 37],
729       [4, 46, 20, 6, 47, 21],
730       [7, 42, 14, 4, 43, 15],
731
732       # 13
733       [4, 133, 107],
734       [8, 59, 37, 1, 60, 38],
735       [8, 44, 20, 4, 45, 21],
736       [12, 33, 11, 4, 34, 12],
737
738       # 14
739       [3, 145, 115, 1, 146, 116],
740       [4, 64, 40, 5, 65, 41],
741       [11, 36, 16, 5, 37, 17],
742       [11, 36, 12, 5, 37, 13],
743
744       # 15
745       [5, 109, 87, 1, 110, 88],
746       [5, 65, 41, 5, 66, 42],
747       [5, 54, 24, 7, 55, 25],
748       [11, 36, 12],
749
750       # 16
751       [5, 122, 98, 1, 123, 99],
752       [7, 73, 45, 3, 74, 46],
753       [15, 43, 19, 2, 44, 20],
754       [3, 45, 15, 13, 46, 16],
755
756       # 17
757       [1, 135, 107, 5, 136, 108],
758       [10, 74, 46, 1, 75, 47],
759       [1, 50, 22, 15, 51, 23],
760       [2, 42, 14, 17, 43, 15],
761
762       # 18
763       [5, 150, 120, 1, 151, 121],
764       [9, 69, 43, 4, 70, 44],
765       [17, 50, 22, 1, 51, 23],
766       [2, 42, 14, 19, 43, 15],
767
768       # 19
769       [3, 141, 113, 4, 142, 114],
770       [3, 70, 44, 11, 71, 45],
771       [17, 47, 21, 4, 48, 22],
772       [9, 39, 13, 16, 40, 14],
773
774       # 20
775       [3, 135, 107, 5, 136, 108],
776       [3, 67, 41, 13, 68, 42],
777       [15, 54, 24, 5, 55, 25],
778       [15, 43, 15, 10, 44, 16],
779
780       # 21
781       [4, 144, 116, 4, 145, 117],
782       [17, 68, 42],
783       [17, 50, 22, 6, 51, 23],
784       [19, 46, 16, 6, 47, 17],
785
786       # 22
787       [2, 139, 111, 7, 140, 112],
788       [17, 74, 46],
789       [7, 54, 24, 16, 55, 25],
790       [34, 37, 13],
791
792       # 23
793       [4, 151, 121, 5, 152, 122],
794       [4, 75, 47, 14, 76, 48],
795       [11, 54, 24, 14, 55, 25],
796       [16, 45, 15, 14, 46, 16],
797
798       # 24
799       [6, 147, 117, 4, 148, 118],
800       [6, 73, 45, 14, 74, 46],
801       [11, 54, 24, 16, 55, 25],
802       [30, 46, 16, 2, 47, 17],
803
804       # 25
805       [8, 132, 106, 4, 133, 107],
806       [8, 75, 47, 13, 76, 48],
807       [7, 54, 24, 22, 55, 25],
808       [22, 45, 15, 13, 46, 16],
809
810       # 26
811       [10, 142, 114, 2, 143, 115],
812       [19, 74, 46, 4, 75, 47],
813       [28, 50, 22, 6, 51, 23],
814       [33, 46, 16, 4, 47, 17],
815
816       # 27
817       [8, 152, 122, 4, 153, 123],
818       [22, 73, 45, 3, 74, 46],
819       [8, 53, 23, 26, 54, 24],
820       [12, 45, 15, 28, 46, 16],
821
822       # 28
823       [3, 147, 117, 10, 148, 118],
824       [3, 73, 45, 23, 74, 46],
825       [4, 54, 24, 31, 55, 25],
826       [11, 45, 15, 31, 46, 16],
827
828       # 29
829       [7, 146, 116, 7, 147, 117],
830       [21, 73, 45, 7, 74, 46],
831       [1, 53, 23, 37, 54, 24],
832       [19, 45, 15, 26, 46, 16],
833
834       # 30
835       [5, 145, 115, 10, 146, 116],
836       [19, 75, 47, 10, 76, 48],
837       [15, 54, 24, 25, 55, 25],
838       [23, 45, 15, 25, 46, 16],
839
840       # 31
841       [13, 145, 115, 3, 146, 116],
842       [2, 74, 46, 29, 75, 47],
843       [42, 54, 24, 1, 55, 25],
844       [23, 45, 15, 28, 46, 16],
845
846       # 32
847       [17, 145, 115],
848       [10, 74, 46, 23, 75, 47],
849       [10, 54, 24, 35, 55, 25],
850       [19, 45, 15, 35, 46, 16],
851
852       # 33
853       [17, 145, 115, 1, 146, 116],
854       [14, 74, 46, 21, 75, 47],
855       [29, 54, 24, 19, 55, 25],
856       [11, 45, 15, 46, 46, 16],
857
858       # 34
859       [13, 145, 115, 6, 146, 116],
860       [14, 74, 46, 23, 75, 47],
861       [44, 54, 24, 7, 55, 25],
862       [59, 46, 16, 1, 47, 17],
863
864       # 35
865       [12, 151, 121, 7, 152, 122],
866       [12, 75, 47, 26, 76, 48],
867       [39, 54, 24, 14, 55, 25],
868       [22, 45, 15, 41, 46, 16],
869
870       # 36
871       [6, 151, 121, 14, 152, 122],
872       [6, 75, 47, 34, 76, 48],
873       [46, 54, 24, 10, 55, 25],
874       [2, 45, 15, 64, 46, 16],
875
876       # 37
877       [17, 152, 122, 4, 153, 123],
878       [29, 74, 46, 14, 75, 47],
879       [49, 54, 24, 10, 55, 25],
880       [24, 45, 15, 46, 46, 16],
881
882       # 38
883       [4, 152, 122, 18, 153, 123],
884       [13, 74, 46, 32, 75, 47],
885       [48, 54, 24, 14, 55, 25],
886       [42, 45, 15, 32, 46, 16],
887
888       # 39
889       [20, 147, 117, 4, 148, 118],
890       [40, 75, 47, 7, 76, 48],
891       [43, 54, 24, 22, 55, 25],
892       [10, 45, 15, 67, 46, 16],
893
894       # 40
895       [19, 148, 118, 6, 149, 119],
896       [18, 75, 47, 31, 76, 48],
897       [34, 54, 24, 34, 55, 25],
898       [20, 45, 15, 61, 46, 16]
899
900     ]
901
902     def __init__(self, totalCount, dataCount):
903         self.totalCount = totalCount
904         self.dataCount = dataCount
905
906     @staticmethod
907     def getRSBlocks(typeNumber, errorCorrectLevel):
908         rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
909         if rsBlock == None:
910             raise Exception("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel)
911
912         length = len(rsBlock) / 3
913
914         list = []
915
916         for i in range(length):
917
918             count = rsBlock[i * 3 + 0]
919             totalCount = rsBlock[i * 3 + 1]
920             dataCount  = rsBlock[i * 3 + 2]
921
922             for j in range(count):
923                 list.append(QRRSBlock(totalCount, dataCount))
924
925         return list;
926
927     @staticmethod
928     def getRsBlockTable(typeNumber, errorCorrectLevel):
929         if errorCorrectLevel == QRErrorCorrectLevel.L:
930             return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
931         elif errorCorrectLevel == QRErrorCorrectLevel.M:
932             return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
933         elif errorCorrectLevel ==  QRErrorCorrectLevel.Q:
934             return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
935         elif errorCorrectLevel ==  QRErrorCorrectLevel.H:
936             return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
937         else:
938             return None;
939
940 class QRBitBuffer:
941     def __init__(self):
942         self.buffer = []
943         self.length = 0
944     def __repr__(self):
945         return ".".join([str(n) for n in self.buffer])
946     def get(self, index):
947         bufIndex = math.floor(index / 8)
948         val = ( (self.buffer[bufIndex] >> (7 - index % 8) ) & 1) == 1
949         print "get ", val
950         return ( (self.buffer[bufIndex] >> (7 - index % 8) ) & 1) == 1
951     def put(self, num, length):
952         for i in range(length):
953             self.putBit( ( (num >> (length - i - 1) ) & 1) == 1)
954     def getLengthInBits(self):
955         return self.length
956     def putBit(self, bit):
957         bufIndex = self.length // 8
958         if len(self.buffer) <= bufIndex:
959             self.buffer.append(0)
960         if bit:
961             self.buffer[bufIndex] |= (0x80 >> (self.length % 8) )
962         self.length+=1