diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..c88669b
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,93 @@
+Metadata-Version: 1.1
+Name: PyQRCode
+Version: 1.2.1
+Summary: A QR code generator written purely in Python with SVG, EPS, PNG and terminal output.
+Home-page: https://github.com/mnooner256/pyqrcode
+Author: Michael Nooner
+Author-email: mnooner256@gmail.com
+License: BSD
+Description: ========
+ PyQRCode
+ ========
+
+ .. contents::
+
+ The pyqrcode module is a QR code generator that is simple to use and written
+ in pure python. The module can automates most of the building process for
+ creating QR codes. Most codes can be created using only two lines of code!
+
+ Unlike other generators, all of the helpers can be controlled manually. You are
+ free to set any or all of the properties of your QR code.
+
+ QR codes can be saved as SVG, PNG (by using the
+ `pypng `_ module), and plain text. They can
+ also be displayed directly in most Linux terminal emulators. PIL is
+ not used to render the image files.
+
+ The pyqrcode module attempts to follow the QR code standard as closely as
+ possible. The terminology and the encodings used in pyqrcode come directly
+ from the standard. This module also follows the algorithm laid out in the
+ standard.
+
+ **Homepage**: https://github.com/mnooner256/pyqrcode
+
+ **Documentation**: http://pythonhosted.org/PyQRCode/
+
+ Requirements
+ ============
+
+ The pyqrcode module only requires Python 2.6, Python 2.7, or Python 3. You may
+ want to install `pypng `_ in order to
+ render PNG files, but it is optional. Note, pypng is a pure python PNG writer
+ which does not require any other libraries.
+
+ Installation
+ ============
+
+ Installation is simple. It can be installed from pip using the following
+ command::
+
+ $ pip install pyqrcode
+
+ Or from the terminal::
+
+ $ python setup.py install
+
+
+ Usage
+ =====
+
+ The pyqrcode module aims to be as simple to use as possible. Below is a simple
+ example of creating a QR code for a URL. The code is rendered out as an svg
+ file.
+ ::
+
+ >>> import pyqrcode
+ >>> url = pyqrcode.create('http://uca.edu')
+ >>> url.svg('uca-url.svg', scale=8)
+ >>> url.eps('uca-url.eps', scale=2)
+ >>> print(url.terminal(quiet_zone=1))
+
+ The pyqrcode module, while easy to use, is powerful. You can set every
+ property of the QR code. If you install the optional
+ `pypng `_ module, you can
+ render the code as a PNG image. Below is a more complex example::
+
+ >>> big_code = pyqrcode.create('0987654321', error='L', version=27, mode='binary')
+ >>> big_code.png('code.png', scale=6, module_color=[0, 0, 0, 128], background=[0xff, 0xff, 0xcc])
+ >>> big_code.show()
+
+Keywords: qrcode,qr
+Platform: UNKNOWN
+Classifier: Development Status :: 4 - Beta
+Classifier: Environment :: Console
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Natural Language :: English
+Classifier: Operating System :: OS Independent
+Classifier: Operating System :: POSIX
+Classifier: Operating System :: Microsoft :: Windows
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
diff --git a/PyQRCode.egg-info/PKG-INFO b/PyQRCode.egg-info/PKG-INFO
new file mode 100644
index 0000000..c88669b
--- /dev/null
+++ b/PyQRCode.egg-info/PKG-INFO
@@ -0,0 +1,93 @@
+Metadata-Version: 1.1
+Name: PyQRCode
+Version: 1.2.1
+Summary: A QR code generator written purely in Python with SVG, EPS, PNG and terminal output.
+Home-page: https://github.com/mnooner256/pyqrcode
+Author: Michael Nooner
+Author-email: mnooner256@gmail.com
+License: BSD
+Description: ========
+ PyQRCode
+ ========
+
+ .. contents::
+
+ The pyqrcode module is a QR code generator that is simple to use and written
+ in pure python. The module can automates most of the building process for
+ creating QR codes. Most codes can be created using only two lines of code!
+
+ Unlike other generators, all of the helpers can be controlled manually. You are
+ free to set any or all of the properties of your QR code.
+
+ QR codes can be saved as SVG, PNG (by using the
+ `pypng `_ module), and plain text. They can
+ also be displayed directly in most Linux terminal emulators. PIL is
+ not used to render the image files.
+
+ The pyqrcode module attempts to follow the QR code standard as closely as
+ possible. The terminology and the encodings used in pyqrcode come directly
+ from the standard. This module also follows the algorithm laid out in the
+ standard.
+
+ **Homepage**: https://github.com/mnooner256/pyqrcode
+
+ **Documentation**: http://pythonhosted.org/PyQRCode/
+
+ Requirements
+ ============
+
+ The pyqrcode module only requires Python 2.6, Python 2.7, or Python 3. You may
+ want to install `pypng `_ in order to
+ render PNG files, but it is optional. Note, pypng is a pure python PNG writer
+ which does not require any other libraries.
+
+ Installation
+ ============
+
+ Installation is simple. It can be installed from pip using the following
+ command::
+
+ $ pip install pyqrcode
+
+ Or from the terminal::
+
+ $ python setup.py install
+
+
+ Usage
+ =====
+
+ The pyqrcode module aims to be as simple to use as possible. Below is a simple
+ example of creating a QR code for a URL. The code is rendered out as an svg
+ file.
+ ::
+
+ >>> import pyqrcode
+ >>> url = pyqrcode.create('http://uca.edu')
+ >>> url.svg('uca-url.svg', scale=8)
+ >>> url.eps('uca-url.eps', scale=2)
+ >>> print(url.terminal(quiet_zone=1))
+
+ The pyqrcode module, while easy to use, is powerful. You can set every
+ property of the QR code. If you install the optional
+ `pypng `_ module, you can
+ render the code as a PNG image. Below is a more complex example::
+
+ >>> big_code = pyqrcode.create('0987654321', error='L', version=27, mode='binary')
+ >>> big_code.png('code.png', scale=6, module_color=[0, 0, 0, 128], background=[0xff, 0xff, 0xcc])
+ >>> big_code.show()
+
+Keywords: qrcode,qr
+Platform: UNKNOWN
+Classifier: Development Status :: 4 - Beta
+Classifier: Environment :: Console
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Natural Language :: English
+Classifier: Operating System :: OS Independent
+Classifier: Operating System :: POSIX
+Classifier: Operating System :: Microsoft :: Windows
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
diff --git a/PyQRCode.egg-info/SOURCES.txt b/PyQRCode.egg-info/SOURCES.txt
new file mode 100644
index 0000000..e1bcc62
--- /dev/null
+++ b/PyQRCode.egg-info/SOURCES.txt
@@ -0,0 +1,10 @@
+README.rst
+setup.py
+PyQRCode.egg-info/PKG-INFO
+PyQRCode.egg-info/SOURCES.txt
+PyQRCode.egg-info/dependency_links.txt
+PyQRCode.egg-info/requires.txt
+PyQRCode.egg-info/top_level.txt
+pyqrcode/__init__.py
+pyqrcode/builder.py
+pyqrcode/tables.py
\ No newline at end of file
diff --git a/PyQRCode.egg-info/dependency_links.txt b/PyQRCode.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/PyQRCode.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/PyQRCode.egg-info/requires.txt b/PyQRCode.egg-info/requires.txt
new file mode 100644
index 0000000..1612941
--- /dev/null
+++ b/PyQRCode.egg-info/requires.txt
@@ -0,0 +1,4 @@
+
+
+[PNG]
+pypng>=0.0.13
\ No newline at end of file
diff --git a/PyQRCode.egg-info/top_level.txt b/PyQRCode.egg-info/top_level.txt
new file mode 100644
index 0000000..6f17668
--- /dev/null
+++ b/PyQRCode.egg-info/top_level.txt
@@ -0,0 +1 @@
+pyqrcode
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..7cf0cf4
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,70 @@
+========
+PyQRCode
+========
+
+.. contents::
+
+The pyqrcode module is a QR code generator that is simple to use and written
+in pure python. The module can automates most of the building process for
+creating QR codes. Most codes can be created using only two lines of code!
+
+Unlike other generators, all of the helpers can be controlled manually. You are
+free to set any or all of the properties of your QR code.
+
+QR codes can be saved as SVG, PNG (by using the
+`pypng `_ module), and plain text. They can
+also be displayed directly in most Linux terminal emulators. PIL is
+not used to render the image files.
+
+The pyqrcode module attempts to follow the QR code standard as closely as
+possible. The terminology and the encodings used in pyqrcode come directly
+from the standard. This module also follows the algorithm laid out in the
+standard.
+
+**Homepage**: https://github.com/mnooner256/pyqrcode
+
+**Documentation**: http://pythonhosted.org/PyQRCode/
+
+Requirements
+============
+
+The pyqrcode module only requires Python 2.6, Python 2.7, or Python 3. You may
+want to install `pypng `_ in order to
+render PNG files, but it is optional. Note, pypng is a pure python PNG writer
+which does not require any other libraries.
+
+Installation
+============
+
+Installation is simple. It can be installed from pip using the following
+command::
+
+ $ pip install pyqrcode
+
+Or from the terminal::
+
+ $ python setup.py install
+
+
+Usage
+=====
+
+The pyqrcode module aims to be as simple to use as possible. Below is a simple
+example of creating a QR code for a URL. The code is rendered out as an svg
+file.
+::
+
+ >>> import pyqrcode
+ >>> url = pyqrcode.create('http://uca.edu')
+ >>> url.svg('uca-url.svg', scale=8)
+ >>> url.eps('uca-url.eps', scale=2)
+ >>> print(url.terminal(quiet_zone=1))
+
+The pyqrcode module, while easy to use, is powerful. You can set every
+property of the QR code. If you install the optional
+`pypng `_ module, you can
+render the code as a PNG image. Below is a more complex example::
+
+ >>> big_code = pyqrcode.create('0987654321', error='L', version=27, mode='binary')
+ >>> big_code.png('code.png', scale=6, module_color=[0, 0, 0, 128], background=[0xff, 0xff, 0xcc])
+ >>> big_code.show()
diff --git a/pyqrcode/__init__.py b/pyqrcode/__init__.py
new file mode 100644
index 0000000..8301f8b
--- /dev/null
+++ b/pyqrcode/__init__.py
@@ -0,0 +1,691 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2013, Michael Nooner
+# All rights reserved.
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"""This module is used to create QR Codes. It is designed to be as simple and
+as possible. It does this by using sane defaults and autodetection to make
+creating a QR Code very simple.
+
+It is recommended that you use the :func:`pyqrcode.create` function to build the
+QRCode object. This results in cleaner looking code.
+
+Examples:
+ >>> import pyqrcode
+ >>> import sys
+ >>> url = pyqrcode.create('http://uca.edu')
+ >>> url.svg(sys.stdout, scale=1)
+ >>> url.svg('uca.svg', scale=4)
+ >>> number = pyqrcode.create(123456789012345)
+ >>> number.png('big-number.png')
+"""
+
+#Imports required for 2.7 support
+from __future__ import absolute_import, division, print_function, with_statement, unicode_literals
+
+import pyqrcode.tables
+import pyqrcode.builder as builder
+
+try:
+ str = unicode # Python 2
+except NameError:
+ pass
+
+def create(content, error='H', version=None, mode=None, encoding=None):
+ """When creating a QR code only the content to be encoded is required,
+ all the other properties of the code will be guessed based on the
+ contents given. This function will return a :class:`QRCode` object.
+
+ Unless you are familiar with QR code's inner workings
+ it is recommended that you just specify the *content* and nothing else.
+ However, there are cases where you may want to specify the various
+ properties of the created code manually, this is what the other
+ parameters do. Below, you will find a lengthy explanation of what
+ each parameter is for. Note, the parameter names and values are taken
+ directly from the standards. You may need to familiarize yourself
+ with the terminology of QR codes for the names and their values to
+ make sense.
+
+ The *error* parameter sets the error correction level of the code. There
+ are four levels defined by the standard. The first is level 'L' which
+ allows for 7% of the code to be corrected. Second, is level 'M' which
+ allows for 15% of the code to be corrected. Next, is level 'Q' which
+ is the most common choice for error correction, it allow 25% of the
+ code to be corrected. Finally, there is the highest level 'H' which
+ allows for 30% of the code to be corrected. There are several ways to
+ specify this parameter, you can use an upper or lower case letter,
+ a float corresponding to the percentage of correction, or a string
+ containing the percentage. See tables.modes for all the possible
+ values. By default this parameter is set to 'H' which is the highest
+ possible error correction, but it has the smallest available data
+ capacity.
+
+ The *version* parameter specifies the size and data capacity of the
+ code. Versions are any integer between 1 and 40. Where version 1 is
+ the smallest QR code, and version 40 is the largest. If this parameter
+ is left unspecified, then the contents and error correction level will
+ be used to guess the smallest possible QR code version that the
+ content will fit inside of. You may want to specify this parameter
+ for consistency when generating several QR codes with varying amounts
+ of data. That way all of the generated codes would have the same size.
+
+ The *mode* parameter specifies how the contents will be encoded. By
+ default, the best possible mode for the contents is guessed. There
+ are four possible modes. First, is 'numeric' which is
+ used to encode integer numbers. Next, is 'alphanumeric' which is
+ used to encode some ASCII characters. This mode uses only a limited
+ set of characters. Most problematic is that it can only use upper case
+ English characters, consequently, the content parameter will be
+ subjected to str.upper() before encoding. See tables.ascii_codes for
+ a complete list of available characters. The is 'kanji' mode can be
+ used for Japanese characters, but only those that can be understood
+ via the shift-jis string encoding. Finally, we then have 'binary' mode
+ which just encodes the bytes directly into the QR code (this encoding
+ is the least efficient).
+
+ The *encoding* parameter specifies how the content will be interpreted.
+ This parameter only matters if the *content* is a string, unicode, or
+ byte array type. This parameter must be a valid encoding string or None.
+ t will be passed the *content*'s encode/decode methods.
+ """
+ return QRCode(content, error, version, mode, encoding)
+
+class QRCode:
+ """This class represents a QR code. To use this class simply give the
+ constructor a string representing the data to be encoded, it will then
+ build a code in memory. You can then save it in various formats. Note,
+ codes can be written out as PNG files but this requires the PyPNG module.
+ You can find the PyPNG module at http://packages.python.org/pypng/.
+
+ Examples:
+ >>> from pyqrcode import QRCode
+ >>> import sys
+ >>> url = QRCode('http://uca.edu')
+ >>> url.svg(sys.stdout, scale=1)
+ >>> url.svg('uca.svg', scale=4)
+ >>> number = QRCode(123456789012345)
+ >>> number.png('big-number.png')
+
+ .. note::
+ For what all of the parameters do, see the :func:`pyqrcode.create`
+ function.
+ """
+ def __init__(self, content, error='H', version=None, mode=None,
+ encoding='iso-8859-1'):
+ #Guess the mode of the code, this will also be used for
+ #error checking
+ guessed_content_type, encoding = self._detect_content_type(content, encoding)
+
+ if encoding is None:
+ encoding = 'iso-8859-1'
+
+ #Store the encoding for use later
+ if guessed_content_type == 'kanji':
+ self.encoding = 'shiftjis'
+ else:
+ self.encoding = encoding
+
+ if version is not None:
+ if 1 <= version <= 40:
+ self.version = version
+ else:
+ raise ValueError("Illegal version {0}, version must be between "
+ "1 and 40.".format(version))
+
+ #Decode a 'byte array' contents into a string format
+ if isinstance(content, bytes):
+ self.data = content.decode(encoding)
+
+ #Give a string an encoding
+ elif hasattr(content, 'encode'):
+ self.data = content.encode(self.encoding)
+
+ #The contents are not a byte array or string, so
+ #try naively converting to a string representation.
+ else:
+ self.data = str(content) # str == unicode in Py 2.x, see file head
+
+ #Force a passed in mode to be lowercase
+ if hasattr(mode, 'lower'):
+ mode = mode.lower()
+
+ #Check that the mode parameter is compatible with the contents
+ if mode is None:
+ #Use the guessed mode
+ self.mode = guessed_content_type
+ self.mode_num = tables.modes[self.mode]
+ elif mode not in tables.modes.keys():
+ #Unknown mode
+ raise ValueError('{0} is not a valid mode.'.format(mode))
+ elif guessed_content_type == 'binary' and \
+ tables.modes[mode] != tables.modes['binary']:
+ #Binary is only guessed as a last resort, if the
+ #passed in mode is not binary the data won't encode
+ raise ValueError('The content provided cannot be encoded with '
+ 'the mode {}, it can only be encoded as '
+ 'binary.'.format(mode))
+ elif tables.modes[mode] == tables.modes['numeric'] and \
+ guessed_content_type != 'numeric':
+ #If numeric encoding is requested make sure the data can
+ #be encoded in that format
+ raise ValueError('The content cannot be encoded as numeric.')
+ elif tables.modes[mode] == tables.modes['kanji'] and \
+ guessed_content_type != 'kanji':
+ raise ValueError('The content cannot be encoded as kanji.')
+ else:
+ #The data should encode with the passed in mode
+ self.mode = mode
+ self.mode_num = tables.modes[self.mode]
+
+ #Check that the user passed in a valid error level
+ if error in tables.error_level.keys():
+ self.error = tables.error_level[error]
+ else:
+ raise ValueError('{0} is not a valid error '
+ 'level.'.format(error))
+
+ #Guess the "best" version
+ self.version = self._pick_best_fit(self.data)
+
+ #If the user supplied a version, then check that it has
+ #sufficient data capacity for the contents passed in
+ if version:
+ if version >= self.version:
+ self.version = version
+ else:
+ raise ValueError('The data will not fit inside a version {} '
+ 'code with the given encoding and error '
+ 'level (the code must be at least a '
+ 'version {}).'.format(version, self.version))
+
+ #Build the QR code
+ self.builder = builder.QRCodeBuilder(data=self.data,
+ version=self.version,
+ mode=self.mode,
+ error=self.error)
+
+ #Save the code for easier reference
+ self.code = self.builder.code
+
+ def __str__(self):
+ return repr(self)
+
+ def __unicode__(self):
+ return self.__repr__()
+
+ def __repr__(self):
+ return "QRCode(content={0}, error='{1}', version={2}, mode='{3}')" \
+ .format(repr(self.data), self.error, self.version, self.mode)
+
+ def _detect_content_type(self, content, encoding):
+ """This method tries to auto-detect the type of the data. It first
+ tries to see if the data is a valid integer, in which case it returns
+ numeric. Next, it tests the data to see if it is 'alphanumeric.' QR
+ Codes use a special table with very limited range of ASCII characters.
+ The code's data is tested to make sure it fits inside this limited
+ range. If all else fails, the data is determined to be of type
+ 'binary.'
+
+ Returns a tuple containing the detected mode and encoding.
+
+ Note, encoding ECI is not yet implemented.
+ """
+ def two_bytes(c):
+ """Output two byte character code as a single integer."""
+ def next_byte(b):
+ """Make sure that character code is an int. Python 2 and
+ 3 compatibility.
+ """
+ if not isinstance(b, int):
+ return ord(b)
+ else:
+ return b
+
+ #Go through the data by looping to every other character
+ for i in range(0, len(c), 2):
+ yield (next_byte(c[i]) << 8) | next_byte(c[i+1])
+
+ #See if the data is a number
+ try:
+ if str(content).isdigit():
+ return 'numeric', encoding
+ except (TypeError, UnicodeError):
+ pass
+
+ #See if that data is alphanumeric based on the standards
+ #special ASCII table
+ valid_characters = ''.join(tables.ascii_codes.keys())
+
+ #Force the characters into a byte array
+ valid_characters = valid_characters.encode('ASCII')
+
+ try:
+ if isinstance(content, bytes):
+ c = content.decode('ASCII')
+ else:
+ c = str(content).encode('ASCII')
+
+ if all(map(lambda x: x in valid_characters, c)):
+ return 'alphanumeric', 'ASCII'
+
+ #This occurs if the content does not contain ASCII characters.
+ #Since the whole point of the if statement is to look for ASCII
+ #characters, the resulting mode should not be alphanumeric.
+ #Hence, this is not an error.
+ except TypeError:
+ pass
+ except UnicodeError:
+ pass
+
+ try:
+ if isinstance(content, bytes):
+ if encoding is None:
+ encoding = 'shiftjis'
+
+ c = content.decode(encoding).encode('shiftjis')
+ else:
+ c = content.encode('shiftjis')
+
+ #All kanji characters must be two bytes long, make sure the
+ #string length is not odd.
+ if len(c) % 2 != 0:
+ return 'binary', encoding
+
+ #Make sure the characters are actually in range.
+ for asint in two_bytes(c):
+ #Shift the two byte value as indicated by the standard
+ if not (0x8140 <= asint <= 0x9FFC or
+ 0xE040 <= asint <= 0xEBBF):
+ return 'binary', encoding
+
+ return 'kanji', encoding
+
+ except UnicodeError:
+ #This occurs if the content does not contain Shift JIS kanji
+ #characters. Hence, the resulting mode should not be kanji.
+ #This is not an error.
+ pass
+
+ #All of the other attempts failed. The content can only be binary.
+ return 'binary', encoding
+
+ def _pick_best_fit(self, content):
+ """This method return the smallest possible QR code version number
+ that will fit the specified data with the given error level.
+ """
+ import math
+
+ for version in range(1, 41):
+ #Get the maximum possible capacity
+ capacity = tables.data_capacity[version][self.error][self.mode_num]
+
+ #Check the capacity
+ #Kanji's count in the table is "characters" which are two bytes
+ if (self.mode_num == tables.modes['kanji'] and
+ capacity >= math.ceil(len(content) / 2)):
+ return version
+ if capacity >= len(content):
+ return version
+
+ raise ValueError('The data will not fit in any QR code version '
+ 'with the given encoding and error level.')
+
+ def show(self, wait=1.2, scale=10, module_color=(0, 0, 0, 255),
+ background=(255, 255, 255, 255), quiet_zone=4):
+ """Displays this QR code.
+
+ This method is mainly intended for debugging purposes.
+
+ This method saves the output of the :py:meth:`png` method (with a default
+ scaling factor of 10) to a temporary file and opens it with the
+ standard PNG viewer application or within the standard webbrowser. The
+ temporary file is deleted afterwards.
+
+ If this method does not show any result, try to increase the `wait`
+ parameter. This parameter specifies the time in seconds to wait till
+ the temporary file is deleted. Note, that this method does not return
+ until the provided amount of seconds (default: 1.2) has passed.
+
+ The other parameters are simply passed on to the `png` method.
+ """
+ import os
+ import time
+ import tempfile
+ import webbrowser
+
+ try: # Python 2
+ from urlparse import urljoin
+ from urllib import pathname2url
+ except ImportError: # Python 3
+ from urllib.parse import urljoin
+ from urllib.request import pathname2url
+
+ f = tempfile.NamedTemporaryFile('wb', suffix='.png', delete=False)
+ self.png(f, scale=scale, module_color=module_color,
+ background=background, quiet_zone=quiet_zone)
+ f.close()
+ webbrowser.open_new_tab(urljoin('file:', pathname2url(f.name)))
+ time.sleep(wait)
+ os.unlink(f.name)
+
+ def get_png_size(self, scale=1, quiet_zone=4):
+ """This is method helps users determine what *scale* to use when
+ creating a PNG of this QR code. It is meant mostly to be used in the
+ console to help the user determine the pixel size of the code
+ using various scales.
+
+ This method will return an integer representing the width and height of
+ the QR code in pixels, as if it was drawn using the given *scale*.
+ Because QR codes are square, the number represents both the width
+ and height dimensions.
+
+ The *quiet_zone* parameter sets how wide the quiet zone around the code
+ should be. According to the standard this should be 4 modules. It is
+ left settable because such a wide quiet zone is unnecessary in many
+ applications where the QR code is not being printed.
+
+ Example:
+ >>> code = pyqrcode.QRCode("I don't like spam!")
+ >>> print(code.get_png_size(1))
+ 31
+ >>> print(code.get_png_size(5))
+ 155
+ """
+ return builder._get_png_size(self.version, scale, quiet_zone)
+
+ def png(self, file, scale=1, module_color=(0, 0, 0, 255),
+ background=(255, 255, 255, 255), quiet_zone=4):
+ """This method writes the QR code out as an PNG image. The resulting
+ PNG has a bit depth of 1. The file parameter is used to specify where
+ to write the image to. It can either be an writable stream or a
+ file path.
+
+ .. note::
+ This method depends on the pypng module to actually create the
+ PNG file.
+
+ This method will write the given *file* out as a PNG file. The file
+ can be either a string file path, or a writable stream. The file
+ will not be automatically closed if a stream is given.
+
+ The *scale* parameter sets how large to draw a single module. By
+ default one pixel is used to draw a single module. This may make the
+ code too small to be read efficiently. Increasing the scale will make
+ the code larger. Only integer scales are usable. This method will
+ attempt to coerce the parameter into an integer (e.g. 2.5 will become 2,
+ and '3' will become 3). You can use the :py:meth:`get_png_size` method
+ to calculate the actual pixel size of the resulting PNG image.
+
+ The *module_color* parameter sets what color to use for the encoded
+ modules (the black part on most QR codes). The *background* parameter
+ sets what color to use for the background (the white part on most
+ QR codes). If either parameter is set, then both must be
+ set or a ValueError is raised. Colors should be specified as either
+ a list or a tuple of length 3 or 4. The components of the list must
+ be integers between 0 and 255. The first three member give the RGB
+ color. The fourth member gives the alpha component, where 0 is
+ transparent and 255 is opaque. Note, many color
+ combinations are unreadable by scanners, so be judicious.
+
+ The *quiet_zone* parameter sets how wide the quiet zone around the code
+ should be. According to the standard this should be 4 modules. It is
+ left settable because such a wide quiet zone is unnecessary in many
+ applications where the QR code is not being printed.
+
+ Example:
+ >>> code = pyqrcode.create('Are you suggesting coconuts migrate?')
+ >>> code.png('swallow.png', scale=5)
+ >>> code.png('swallow.png', scale=5,
+ module_color=(0x66, 0x33, 0x0), #Dark brown
+ background=(0xff, 0xff, 0xff, 0x88)) #50% transparent white
+ """
+ builder._png(self.code, self.version, file, scale,
+ module_color, background, quiet_zone)
+
+ def png_as_base64_str(self, scale=1, module_color=(0, 0, 0, 255),
+ background=(255, 255, 255, 255), quiet_zone=4):
+ """This method uses the png render and returns the PNG image encoded as
+ base64 string. This can be useful for creating dynamic PNG images for
+ web development, since no file needs to be created.
+
+ Example:
+ >>> code = pyqrcode.create('Are you suggesting coconuts migrate?')
+ >>> image_as_str = code.png_as_base64_str(scale=5)
+ >>> html_img = ''.format(image_as_str)
+
+ The parameters are passed directly to the :py:meth:`png` method. Refer
+ to that method's documentation for the meaning behind the parameters.
+
+ .. note::
+ This method depends on the pypng module to actually create the
+ PNG image.
+
+ """
+ import io
+ import base64
+
+ with io.BytesIO() as virtual_file:
+ self.png(file=virtual_file, scale=scale, module_color=module_color,
+ background=background, quiet_zone=quiet_zone)
+ image_as_str = base64.b64encode(virtual_file.getvalue()).decode("ascii")
+ return image_as_str
+
+ def xbm(self, scale=1, quiet_zone=4):
+ """Returns a string representing an XBM image of the QR code.
+ The XBM format is a black and white image format that looks like a
+ C header file.
+
+ Because displaying QR codes in Tkinter is the
+ primary use case for this renderer, this method does not take a file
+ parameter. Instead it retuns the rendered QR code data as a string.
+
+ Example of using this renderer with Tkinter:
+ >>> import pyqrcode
+ >>> import tkinter
+ >>> code = pyqrcode.create('Knights who say ni!')
+ >>> code_xbm = code.xbm(scale=5)
+ >>>
+ >>> top = tkinter.Tk()
+ >>> code_bmp = tkinter.BitmapImage(data=code_xbm)
+ >>> code_bmp.config(foreground="black")
+ >>> code_bmp.config(background="white")
+ >>> label = tkinter.Label(image=code_bmp)
+ >>> label.pack()
+
+
+ The *scale* parameter sets how large to draw a single module. By
+ default one pixel is used to draw a single module. This may make the
+ code too small to be read efficiently. Increasing the scale will make
+ the code larger. Only integer scales are usable. This method will
+ attempt to coerce the parameter into an integer (e.g. 2.5 will become 2,
+ and '3' will become 3). You can use the :py:meth:`get_png_size` method
+ to calculate the actual pixel size of this image when displayed.
+
+ The *quiet_zone* parameter sets how wide the quiet zone around the code
+ should be. According to the standard this should be 4 modules. It is
+ left settable because such a wide quiet zone is unnecessary in many
+ applications where the QR code is not being printed.
+ """
+ return builder._xbm(self.code, scale, quiet_zone)
+
+ def svg(self, file, scale=1, module_color='#000', background=None,
+ quiet_zone=4, xmldecl=True, svgns=True, title=None,
+ svgclass='pyqrcode', lineclass='pyqrline', omithw=False,
+ debug=False):
+ """This method writes the QR code out as an SVG document. The
+ code is drawn by drawing only the modules corresponding to a 1. They
+ are drawn using a line, such that contiguous modules in a row
+ are drawn with a single line.
+
+ The *file* parameter is used to specify where to write the document
+ to. It can either be a writable stream or a file path.
+
+ The *scale* parameter sets how large to draw
+ a single module. By default one pixel is used to draw a single
+ module. This may make the code too small to be read efficiently.
+ Increasing the scale will make the code larger. Unlike the png() method,
+ this method will accept fractional scales (e.g. 2.5).
+
+ Note, three things are done to make the code more appropriate for
+ embedding in a HTML document. The "white" part of the code is actually
+ transparent. The code itself has a class given by *svgclass* parameter.
+ The path making up the QR code uses the class set using the *lineclass*.
+ These should make the code easier to style using CSS.
+
+ By default the output of this function is a complete SVG document. If
+ only the code itself is desired, set the *xmldecl* to false. This will
+ result in a fragment that contains only the "drawn" portion of the code.
+ Likewise, you can set the *title* of the document. The SVG name space
+ attribute can be suppressed by setting *svgns* to False.
+
+ When True the *omithw* indicates if width and height attributes should
+ be omitted. If these attributes are omitted, a ``viewBox`` attribute
+ will be added to the document.
+
+ You can also set the colors directly using the *module_color* and
+ *background* parameters. The *module_color* parameter sets what color to
+ use for the data modules (the black part on most QR codes). The
+ *background* parameter sets what color to use for the background (the
+ white part on most QR codes). The parameters can be set to any valid
+ SVG or HTML color. If the background is set to None, then no background
+ will be drawn, i.e. the background will be transparent. Note, many color
+ combinations are unreadable by scanners, so be careful.
+
+ The *quiet_zone* parameter sets how wide the quiet zone around the code
+ should be. According to the standard this should be 4 modules. It is
+ left settable because such a wide quiet zone is unnecessary in many
+ applications where the QR code is not being printed.
+
+ Example:
+ >>> code = pyqrcode.create('Hello. Uhh, can we have your liver?')
+ >>> code.svg('live-organ-transplants.svg', 3.6)
+ >>> code.svg('live-organ-transplants.svg', scale=4,
+ module_color='brown', background='0xFFFFFF')
+ """
+ builder._svg(self.code, self.version, file, scale=scale,
+ module_color=module_color, background=background,
+ quiet_zone=quiet_zone, xmldecl=xmldecl, svgns=svgns,
+ title=title, svgclass=svgclass, lineclass=lineclass,
+ omithw=omithw, debug=debug)
+
+ def eps(self, file, scale=1, module_color=(0, 0, 0),
+ background=None, quiet_zone=4):
+ """This method writes the QR code out as an EPS document. The
+ code is drawn by only writing the data modules corresponding to a 1.
+ They are drawn using a line, such that contiguous modules in a row
+ are drawn with a single line.
+
+ The *file* parameter is used to specify where to write the document
+ to. It can either be a writable (text) stream or a file path.
+
+ The *scale* parameter sets how large to draw a single module. By
+ default one point (1/72 inch) is used to draw a single module. This may
+ make the code to small to be read efficiently. Increasing the scale
+ will make the code larger. This method will accept fractional scales
+ (e.g. 2.5).
+
+ The *module_color* parameter sets the color of the data modules. The
+ *background* parameter sets the background (page) color to use. They
+ are specified as either a triple of floats, e.g. (0.5, 0.5, 0.5), or a
+ triple of integers, e.g. (128, 128, 128). The default *module_color* is
+ black. The default *background* color is no background at all.
+
+ The *quiet_zone* parameter sets how large to draw the border around
+ the code. As per the standard, the default value is 4 modules.
+
+ Examples:
+ >>> qr = pyqrcode.create('Hello world')
+ >>> qr.eps('hello-world.eps', scale=2.5, module_color='#36C')
+ >>> qr.eps('hello-world2.eps', background='#eee')
+ >>> out = io.StringIO()
+ >>> qr.eps(out, module_color=(.4, .4, .4))
+ """
+ builder._eps(self.code, self.version, file, scale, module_color,
+ background, quiet_zone)
+
+ def terminal(self, module_color='default', background='reverse',
+ quiet_zone=4):
+ """This method returns a string containing ASCII escape codes,
+ such that if printed to a compatible terminal, it will display
+ a vaild QR code. The code is printed using ASCII escape
+ codes that alter the coloring of the background.
+
+ The *module_color* parameter sets what color to
+ use for the data modules (the black part on most QR codes).
+ Likewise, the *background* parameter sets what color to use
+ for the background (the white part on most QR codes).
+
+ There are two options for colors. The first, and most widely
+ supported, is to use the 8 or 16 color scheme. This scheme uses
+ eight to sixteen named colors. The following colors are
+ supported the most widely supported: black, red, green,
+ yellow, blue, magenta, and cyan. There are an some additional
+ named colors that are supported by most terminals: light gray,
+ dark gray, light red, light green, light blue, light yellow,
+ light magenta, light cyan, and white.
+
+ There are two special named colors. The first is the
+ "default" color. This color is the color the background of
+ the terminal is set to. The next color is the "reverse"
+ color. This is not really a color at all but a special
+ property that will reverse the current color. These two colors
+ are the default values for *module_color* and *background*
+ respectively. These values should work on most terminals.
+
+ Finally, there is one more way to specify the color. Some
+ terminals support 256 colors. The actual colors displayed in the
+ terminal is system dependent. This is the least transportable option.
+ To use the 256 color scheme set *module_color* and/or
+ *background* to a number between 0 and 256.
+
+ The *quiet_zone* parameter sets how wide the quiet zone around the code
+ should be. According to the standard this should be 4 modules. It is
+ left settable because such a wide quiet zone is unnecessary in many
+ applications.
+
+ Example:
+ >>> code = pyqrcode.create('Example')
+ >>> text = code.terminal()
+ >>> print(text)
+ """
+ return builder._terminal(self.code, module_color, background,
+ quiet_zone)
+
+ def text(self, quiet_zone=4):
+ """This method returns a string based representation of the QR code.
+ The data modules are represented by 1's and the background modules are
+ represented by 0's. The main purpose of this method is to act a
+ starting point for users to create their own renderers.
+
+ The *quiet_zone* parameter sets how wide the quiet zone around the code
+ should be. According to the standard this should be 4 modules. It is
+ left settable because such a wide quiet zone is unnecessary in many
+ applications.
+
+ Example:
+ >>> code = pyqrcode.create('Example')
+ >>> text = code.text()
+ >>> print(text)
+ """
+ return builder._text(self.code, quiet_zone)
+
diff --git a/pyqrcode/builder.py b/pyqrcode/builder.py
new file mode 100644
index 0000000..7313d5a
--- /dev/null
+++ b/pyqrcode/builder.py
@@ -0,0 +1,1528 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2013, Michael Nooner
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"""This module does the actual generation of the QR codes. The QRCodeBuilder
+builds the code. While the various output methods draw the code into a file.
+"""
+
+#Imports required for 2.x support
+from __future__ import absolute_import, division, print_function, with_statement, unicode_literals
+
+import pyqrcode.tables as tables
+import io
+import itertools
+import math
+
+class QRCodeBuilder:
+ """This class generates a QR code based on the standard. It is meant to
+ be used internally, not by users!!!
+
+ This class implements the tutorials found at:
+
+ * http://www.thonky.com/qr-code-tutorial/
+
+ * http://www.matchadesign.com/blog/qr-code-demystified-part-6/
+
+ This class also uses the standard, which can be read online at:
+ http://raidenii.net/files/datasheets/misc/qr_code.pdf
+
+ Test codes were tested against:
+ http://zxing.org/w/decode.jspx
+
+ Also, reference codes were generat/ed at:
+ http://www.morovia.com/free-online-barcode-generator/qrcode-maker.php
+ http://demos.telerik.com/aspnet-ajax/barcode/examples/qrcode/defaultcs.aspx
+
+ QR code Debugger:
+ http://qrlogo.kaarposoft.dk/qrdecode.html
+ """
+ def __init__(self, data, version, mode, error):
+ """See :py:class:`pyqrcode.QRCode` for information on the parameters."""
+ #Set what data we are going to use to generate
+ #the QR code
+ self.data = data
+
+ #Check that the user passed in a valid mode
+ if mode in tables.modes:
+ self.mode = tables.modes[mode]
+ else:
+ raise ValueError('{0} is not a valid mode.'.format(mode))
+
+ #Check that the user passed in a valid error level
+ if error in tables.error_level:
+ self.error = tables.error_level[error]
+ else:
+ raise ValueError('{0} is not a valid error '
+ 'level.'.format(error))
+
+ if 1 <= version <= 40:
+ self.version = version
+ else:
+ raise ValueError("Illegal version {0}, version must be between "
+ "1 and 40.".format(version))
+
+ #Look up the proper row for error correction code words
+ self.error_code_words = tables.eccwbi[version][self.error]
+
+ #This property will hold the binary string as it is built
+ self.buffer = io.StringIO()
+
+ #Create the binary data block
+ self.add_data()
+
+ #Create the actual QR code
+ self.make_code()
+
+ def grouper(self, n, iterable, fillvalue=None):
+ """This generator yields a set of tuples, where the
+ iterable is broken into n sized chunks. If the
+ iterable is not evenly sized then fillvalue will
+ be appended to the last tuple to make up the difference.
+
+ This function is copied from the standard docs on
+ itertools.
+ """
+ args = [iter(iterable)] * n
+ if hasattr(itertools, 'zip_longest'):
+ return itertools.zip_longest(*args, fillvalue=fillvalue)
+ return itertools.izip_longest(*args, fillvalue=fillvalue)
+
+ def binary_string(self, data, length):
+ """This method returns a string of length n that is the binary
+ representation of the given data. This function is used to
+ basically create bit fields of a given size.
+ """
+ return '{{0:0{0}b}}'.format(length).format(int(data))
+
+ def get_data_length(self):
+ """QR codes contain a "data length" field. This method creates this
+ field. A binary string representing the appropriate length is
+ returned.
+ """
+
+ #The "data length" field varies by the type of code and its mode.
+ #discover how long the "data length" field should be.
+ if 1 <= self.version <= 9:
+ max_version = 9
+ elif 10 <= self.version <= 26:
+ max_version = 26
+ elif 27 <= self.version <= 40:
+ max_version = 40
+
+ data_length = tables.data_length_field[max_version][self.mode]
+
+ if self.mode != tables.modes['kanji']:
+ length_string = self.binary_string(len(self.data), data_length)
+ else:
+ length_string = self.binary_string(len(self.data) / 2, data_length)
+
+ if len(length_string) > data_length:
+ raise ValueError('The supplied data will not fit '
+ 'within this version of a QRCode.')
+ return length_string
+
+ def encode(self):
+ """This method encodes the data into a binary string using
+ the appropriate algorithm specified by the mode.
+ """
+ if self.mode == tables.modes['alphanumeric']:
+ encoded = self.encode_alphanumeric()
+ elif self.mode == tables.modes['numeric']:
+ encoded = self.encode_numeric()
+ elif self.mode == tables.modes['binary']:
+ encoded = self.encode_bytes()
+ elif self.mode == tables.modes['kanji']:
+ encoded = self.encode_kanji()
+ return encoded
+
+ def encode_alphanumeric(self):
+ """This method encodes the QR code's data if its mode is
+ alphanumeric. It returns the data encoded as a binary string.
+ """
+ #Convert the string to upper case
+ self.data = self.data.upper()
+
+ #Change the data such that it uses a QR code ascii table
+ ascii = []
+ for char in self.data:
+ if isinstance(char, int):
+ ascii.append(tables.ascii_codes[chr(char)])
+ else:
+ ascii.append(tables.ascii_codes[char])
+
+ #Now perform the algorithm that will make the ascii into bit fields
+ with io.StringIO() as buf:
+ for (a,b) in self.grouper(2, ascii):
+ if b is not None:
+ buf.write(self.binary_string((45*a)+b, 11))
+ else:
+ #This occurs when there is an odd number
+ #of characters in the data
+ buf.write(self.binary_string(a, 6))
+
+ #Return the binary string
+ return buf.getvalue()
+
+ def encode_numeric(self):
+ """This method encodes the QR code's data if its mode is
+ numeric. It returns the data encoded as a binary string.
+ """
+ with io.StringIO() as buf:
+ #Break the number into groups of three digits
+ for triplet in self.grouper(3, self.data):
+ number = ''
+ for digit in triplet:
+ if isinstance(digit, int):
+ digit = chr(digit)
+
+ #Only build the string if digit is not None
+ if digit:
+ number = ''.join([number, digit])
+ else:
+ break
+
+ #If the number is one digits, make a 4 bit field
+ if len(number) == 1:
+ bin = self.binary_string(number, 4)
+
+ #If the number is two digits, make a 7 bit field
+ elif len(number) == 2:
+ bin = self.binary_string(number, 7)
+
+ #Three digit numbers use a 10 bit field
+ else:
+ bin = self.binary_string(number, 10)
+
+ buf.write(bin)
+ return buf.getvalue()
+
+ def encode_bytes(self):
+ """This method encodes the QR code's data if its mode is
+ 8 bit mode. It returns the data encoded as a binary string.
+ """
+ with io.StringIO() as buf:
+ for char in self.data:
+ if not isinstance(char, int):
+ buf.write('{{0:0{0}b}}'.format(8).format(ord(char)))
+ else:
+ buf.write('{{0:0{0}b}}'.format(8).format(char))
+ return buf.getvalue()
+
+ def encode_kanji(self):
+ """This method encodes the QR code's data if its mode is
+ kanji. It returns the data encoded as a binary string.
+ """
+ def two_bytes(data):
+ """Output two byte character code as a single integer."""
+ def next_byte(b):
+ """Make sure that character code is an int. Python 2 and
+ 3 compatibility.
+ """
+ if not isinstance(b, int):
+ return ord(b)
+ else:
+ return b
+
+ #Go through the data by looping to every other character
+ for i in range(0, len(data), 2):
+ yield (next_byte(data[i]) << 8) | next_byte(data[i+1])
+
+ #Force the data into Kanji encoded bytes
+ if isinstance(self.data, bytes):
+ data = self.data.decode('shiftjis').encode('shiftjis')
+ else:
+ data = self.data.encode('shiftjis')
+
+ #Now perform the algorithm that will make the kanji into 13 bit fields
+ with io.StringIO() as buf:
+ for asint in two_bytes(data):
+ #Shift the two byte value as indicated by the standard
+ if 0x8140 <= asint <= 0x9FFC:
+ difference = asint - 0x8140
+ elif 0xE040 <= asint <= 0xEBBF:
+ difference = asint - 0xC140
+
+ #Split the new value into most and least significant bytes
+ msb = (difference >> 8)
+ lsb = (difference & 0x00FF)
+
+ #Calculate the actual 13 bit binary value
+ buf.write('{0:013b}'.format((msb * 0xC0) + lsb))
+ #Return the binary string
+ return buf.getvalue()
+
+
+ def add_data(self):
+ """This function properly constructs a QR code's data string. It takes
+ into account the interleaving pattern required by the standard.
+ """
+ #Encode the data into a QR code
+ self.buffer.write(self.binary_string(self.mode, 4))
+ self.buffer.write(self.get_data_length())
+ self.buffer.write(self.encode())
+
+ #Converts the buffer into "code word" integers.
+ #The online debugger outputs them this way, makes
+ #for easier comparisons.
+ #s = self.buffer.getvalue()
+ #for i in range(0, len(s), 8):
+ # print(int(s[i:i+8], 2), end=',')
+ #print()
+
+ #Fix for issue #3: https://github.com/mnooner256/pyqrcode/issues/3#
+ #I was performing the terminate_bits() part in the encoding.
+ #As per the standard, terminating bits are only supposed to
+ #be added after the bit stream is complete. I took that to
+ #mean after the encoding, but actually it is after the entire
+ #bit stream has been constructed.
+ bits = self.terminate_bits(self.buffer.getvalue())
+ if bits is not None:
+ self.buffer.write(bits)
+
+ #delimit_words and add_words can return None
+ add_bits = self.delimit_words()
+ if add_bits:
+ self.buffer.write(add_bits)
+
+ fill_bytes = self.add_words()
+ if fill_bytes:
+ self.buffer.write(fill_bytes)
+
+ #Get a numeric representation of the data
+ data = [int(''.join(x),2)
+ for x in self.grouper(8, self.buffer.getvalue())]
+
+ #This is the error information for the code
+ error_info = tables.eccwbi[self.version][self.error]
+
+ #This will hold our data blocks
+ data_blocks = []
+
+ #This will hold our error blocks
+ error_blocks = []
+
+ #Some codes have the data sliced into two different sized blocks
+ #for example, first two 14 word sized blocks, then four 15 word
+ #sized blocks. This means that slicing size can change over time.
+ data_block_sizes = [error_info[2]] * error_info[1]
+ if error_info[3] != 0:
+ data_block_sizes.extend([error_info[4]] * error_info[3])
+
+ #For every block of data, slice the data into the appropriate
+ #sized block
+ current_byte = 0
+ for n_data_blocks in data_block_sizes:
+ data_blocks.append(data[current_byte:current_byte+n_data_blocks])
+ current_byte += n_data_blocks
+
+ #I am not sure about the test after the "and". This was added to
+ #fix a bug where after delimit_words padded the bit stream, a zero
+ #byte ends up being added. After checking around, it seems this extra
+ #byte is supposed to be chopped off, but I cannot find that in the
+ #standard! I am adding it to solve the bug, I believe it is correct.
+ if current_byte < len(data):
+ raise ValueError('Too much data for this code version.')
+
+ #DEBUG CODE!!!!
+ #Print out the data blocks
+ #print('Data Blocks:\n{0}'.format(data_blocks))
+
+ #Calculate the error blocks
+ for n, block in enumerate(data_blocks):
+ error_blocks.append(self.make_error_block(block, n))
+
+ #DEBUG CODE!!!!
+ #Print out the error blocks
+ #print('Error Blocks:\n{0}'.format(error_blocks))
+
+ #Buffer we will write our data blocks into
+ data_buffer = io.StringIO()
+
+ #Add the data blocks
+ #Write the buffer such that: block 1 byte 1, block 2 byte 1, etc.
+ largest_block = max(error_info[2], error_info[4])+error_info[0]
+ for i in range(largest_block):
+ for block in data_blocks:
+ if i < len(block):
+ data_buffer.write(self.binary_string(block[i], 8))
+
+ #Add the error code blocks.
+ #Write the buffer such that: block 1 byte 1, block 2 byte 2, etc.
+ for i in range(error_info[0]):
+ for block in error_blocks:
+ data_buffer.write(self.binary_string(block[i], 8))
+
+ self.buffer = data_buffer
+
+ def terminate_bits(self, payload):
+ """This method adds zeros to the end of the encoded data so that the
+ encoded data is of the correct length. It returns a binary string
+ containing the bits to be added.
+ """
+ data_capacity = tables.data_capacity[self.version][self.error][0]
+
+ if len(payload) > data_capacity:
+ raise ValueError('The supplied data will not fit '
+ 'within this version of a QR code.')
+
+ #We must add up to 4 zeros to make up for any shortfall in the
+ #length of the data field.
+ if len(payload) == data_capacity:
+ return None
+ elif len(payload) <= data_capacity-4:
+ bits = self.binary_string(0,4)
+ else:
+ #Make up any shortfall need with less than 4 zeros
+ bits = self.binary_string(0, data_capacity - len(payload))
+
+ return bits
+
+ def delimit_words(self):
+ """This method takes the existing encoded binary string
+ and returns a binary string that will pad it such that
+ the encoded string contains only full bytes.
+ """
+ bits_short = 8 - (len(self.buffer.getvalue()) % 8)
+
+ #The string already falls on an byte boundary do nothing
+ if bits_short == 0 or bits_short == 8:
+ return None
+ else:
+ return self.binary_string(0, bits_short)
+
+ def add_words(self):
+ """The data block must fill the entire data capacity of the QR code.
+ If we fall short, then we must add bytes to the end of the encoded
+ data field. The value of these bytes are specified in the standard.
+ """
+
+ data_blocks = len(self.buffer.getvalue()) // 8
+ total_blocks = tables.data_capacity[self.version][self.error][0] // 8
+ needed_blocks = total_blocks - data_blocks
+
+ if needed_blocks == 0:
+ return None
+
+ #This will return item1, item2, item1, item2, etc.
+ block = itertools.cycle(['11101100', '00010001'])
+
+ #Create a string of the needed blocks
+ return ''.join([next(block) for x in range(needed_blocks)])
+
+ def make_error_block(self, block, block_number):
+ """This function constructs the error correction block of the
+ given data block. This is *very complicated* process. To
+ understand the code you need to read:
+
+ * http://www.thonky.com/qr-code-tutorial/part-2-error-correction/
+ * http://www.matchadesign.com/blog/qr-code-demystified-part-4/
+ """
+ #Get the error information from the standards table
+ error_info = tables.eccwbi[self.version][self.error]
+
+ #This is the number of 8-bit words per block
+ if block_number < error_info[1]:
+ code_words_per_block = error_info[2]
+ else:
+ code_words_per_block = error_info[4]
+
+ #This is the size of the error block
+ error_block_size = error_info[0]
+
+ #Copy the block as the message polynomial coefficients
+ mp_co = block[:]
+
+ #Add the error blocks to the message polynomial
+ mp_co.extend([0] * (error_block_size))
+
+ #Get the generator polynomial
+ generator = tables.generator_polynomials[error_block_size]
+
+ #This will hold the temporary sum of the message coefficient and the
+ #generator polynomial
+ gen_result = [0] * len(generator)
+
+ #Go through every code word in the block
+ for i in range(code_words_per_block):
+ #Get the first coefficient from the message polynomial
+ coefficient = mp_co.pop(0)
+
+ #Skip coefficients that are zero
+ if coefficient == 0:
+ continue
+ else:
+ #Turn the coefficient into an alpha exponent
+ alpha_exp = tables.galois_antilog[coefficient]
+
+ #Add the alpha to the generator polynomial
+ for n in range(len(generator)):
+ gen_result[n] = alpha_exp + generator[n]
+ if gen_result[n] > 255:
+ gen_result[n] = gen_result[n] % 255
+
+ #Convert the alpha notation back into coefficients
+ gen_result[n] = tables.galois_log[gen_result[n]]
+
+ #XOR the sum with the message coefficients
+ mp_co[n] = gen_result[n] ^ mp_co[n]
+
+ #Pad the end of the error blocks with zeros if needed
+ if len(mp_co) < code_words_per_block:
+ mp_co.extend([0] * (code_words_per_block - len(mp_co)))
+
+ return mp_co
+
+ def make_code(self):
+ """This method returns the best possible QR code."""
+ from copy import deepcopy
+
+ #Get the size of the underlying matrix
+ matrix_size = tables.version_size[self.version]
+
+ #Create a template matrix we will build the codes with
+ row = [' ' for x in range(matrix_size)]
+ template = [deepcopy(row) for x in range(matrix_size)]
+
+ #Add mandatory information to the template
+ self.add_detection_pattern(template)
+ self.add_position_pattern(template)
+ self.add_version_pattern(template)
+
+ #Create the various types of masks of the template
+ self.masks = self.make_masks(template)
+
+ self.best_mask = self.choose_best_mask()
+ self.code = self.masks[self.best_mask]
+
+ def add_detection_pattern(self, m):
+ """This method add the detection patterns to the QR code. This lets
+ the scanner orient the pattern. It is required for all QR codes.
+ The detection pattern consists of three boxes located at the upper
+ left, upper right, and lower left corners of the matrix. Also, two
+ special lines called the timing pattern is also necessary. Finally,
+ a single black pixel is added just above the lower left black box.
+ """
+
+ #Draw outer black box
+ for i in range(7):
+ inv = -(i+1)
+ for j in [0,6,-1,-7]:
+ m[j][i] = 1
+ m[i][j] = 1
+ m[inv][j] = 1
+ m[j][inv] = 1
+
+ #Draw inner white box
+ for i in range(1, 6):
+ inv = -(i+1)
+ for j in [1, 5, -2, -6]:
+ m[j][i] = 0
+ m[i][j] = 0
+ m[inv][j] = 0
+ m[j][inv] = 0
+
+ #Draw inner black box
+ for i in range(2, 5):
+ for j in range(2, 5):
+ inv = -(i+1)
+ m[i][j] = 1
+ m[inv][j] = 1
+ m[j][inv] = 1
+
+ #Draw white border
+ for i in range(8):
+ inv = -(i+1)
+ for j in [7, -8]:
+ m[i][j] = 0
+ m[j][i] = 0
+ m[inv][j] = 0
+ m[j][inv] = 0
+
+ #To keep the code short, it draws an extra box
+ #in the lower right corner, this removes it.
+ for i in range(-8, 0):
+ for j in range(-8, 0):
+ m[i][j] = ' '
+
+ #Add the timing pattern
+ bit = itertools.cycle([1,0])
+ for i in range(8, (len(m)-8)):
+ b = next(bit)
+ m[i][6] = b
+ m[6][i] = b
+
+ #Add the extra black pixel
+ m[-8][8] = 1
+
+ def add_position_pattern(self, m):
+ """This method draws the position adjustment patterns onto the QR
+ Code. All QR code versions larger than one require these special boxes
+ called position adjustment patterns.
+ """
+ #Version 1 does not have a position adjustment pattern
+ if self.version == 1:
+ return
+
+ #Get the coordinates for where to place the boxes
+ coordinates = tables.position_adjustment[self.version]
+
+ #Get the max and min coordinates to handle special cases
+ min_coord = coordinates[0]
+ max_coord = coordinates[-1]
+
+ #Draw a box at each intersection of the coordinates
+ for i in coordinates:
+ for j in coordinates:
+ #Do not draw these boxes because they would
+ #interfere with the detection pattern
+ if (i == min_coord and j == min_coord) or \
+ (i == min_coord and j == max_coord) or \
+ (i == max_coord and j == min_coord):
+ continue
+
+ #Center black pixel
+ m[i][j] = 1
+
+ #Surround the pixel with a white box
+ for x in [-1,1]:
+ m[i+x][j+x] = 0
+ m[i+x][j] = 0
+ m[i][j+x] = 0
+ m[i-x][j+x] = 0
+ m[i+x][j-x] = 0
+
+ #Surround the white box with a black box
+ for x in [-2,2]:
+ for y in [0,-1,1]:
+ m[i+x][j+x] = 1
+ m[i+x][j+y] = 1
+ m[i+y][j+x] = 1
+ m[i-x][j+x] = 1
+ m[i+x][j-x] = 1
+
+ def add_version_pattern(self, m):
+ """For QR codes with a version 7 or higher, a special pattern
+ specifying the code's version is required.
+
+ For further information see:
+ http://www.thonky.com/qr-code-tutorial/format-version-information/#example-of-version-7-information-string
+ """
+ if self.version < 7:
+ return
+
+ #Get the bit fields for this code's version
+ #We will iterate across the string, the bit string
+ #needs the least significant digit in the zero-th position
+ field = iter(tables.version_pattern[self.version][::-1])
+
+ #Where to start placing the pattern
+ start = len(m)-11
+
+ #The version pattern is pretty odd looking
+ for i in range(6):
+ #The pattern is three modules wide
+ for j in range(start, start+3):
+ bit = int(next(field))
+
+ #Bottom Left
+ m[i][j] = bit
+
+ #Upper right
+ m[j][i] = bit
+
+ def make_masks(self, template):
+ """This method generates all seven masks so that the best mask can
+ be determined. The template parameter is a code matrix that will
+ server as the base for all the generated masks.
+ """
+ from copy import deepcopy
+
+ nmasks = len(tables.mask_patterns)
+ masks = [''] * nmasks
+ count = 0
+
+ for n in range(nmasks):
+ cur_mask = deepcopy(template)
+ masks[n] = cur_mask
+
+ #Add the type pattern bits to the code
+ self.add_type_pattern(cur_mask, tables.type_bits[self.error][n])
+
+ #Get the mask pattern
+ pattern = tables.mask_patterns[n]
+
+ #This will read the 1's and 0's one at a time
+ bits = iter(self.buffer.getvalue())
+
+ #These will help us do the up, down, up, down pattern
+ row_start = itertools.cycle([len(cur_mask)-1, 0])
+ row_stop = itertools.cycle([-1,len(cur_mask)])
+ direction = itertools.cycle([-1, 1])
+
+ #The data pattern is added using pairs of columns
+ for column in range(len(cur_mask)-1, 0, -2):
+
+ #The vertical timing pattern is an exception to the rules,
+ #move the column counter over by one
+ if column <= 6:
+ column = column - 1
+
+ #This will let us fill in the pattern
+ #right-left, right-left, etc.
+ column_pair = itertools.cycle([column, column-1])
+
+ #Go through each row in the pattern moving up, then down
+ for row in range(next(row_start), next(row_stop),
+ next(direction)):
+
+ #Fill in the right then left column
+ for i in range(2):
+ col = next(column_pair)
+
+ #Go to the next column if we encounter a
+ #preexisting pattern (usually an alignment pattern)
+ if cur_mask[row][col] != ' ':
+ continue
+
+ #Some versions don't have enough bits. You then fill
+ #in the rest of the pattern with 0's. These are
+ #called "remainder bits."
+ try:
+ bit = int(next(bits))
+ except:
+ bit = 0
+
+
+ #If the pattern is True then flip the bit
+ if pattern(row, col):
+ cur_mask[row][col] = bit ^ 1
+ else:
+ cur_mask[row][col] = bit
+
+ #DEBUG CODE!!!
+ #Save all of the masks as png files
+ #for i, m in enumerate(masks):
+ # _png(m, self.version, 'mask-{0}.png'.format(i), 5)
+
+ return masks
+
+ def choose_best_mask(self):
+ """This method returns the index of the "best" mask as defined by
+ having the lowest total penalty score. The penalty rules are defined
+ by the standard. The mask with the lowest total score should be the
+ easiest to read by optical scanners.
+ """
+ self.scores = []
+ for n in range(len(self.masks)):
+ self.scores.append([0,0,0,0])
+
+ #Score penalty rule number 1
+ #Look for five consecutive squares with the same color.
+ #Each one found gets a penalty of 3 + 1 for every
+ #same color square after the first five in the row.
+ for (n, mask) in enumerate(self.masks):
+ current = mask[0][0]
+ counter = 0
+ total = 0
+
+ #Examine the mask row wise
+ for row in range(0,len(mask)):
+ counter = 0
+ for col in range(0,len(mask)):
+ bit = mask[row][col]
+
+ if bit == current:
+ counter += 1
+ else:
+ if counter >= 5:
+ total += (counter - 5) + 3
+ counter = 1
+ current = bit
+ if counter >= 5:
+ total += (counter - 5) + 3
+
+ #Examine the mask column wise
+ for col in range(0,len(mask)):
+ counter = 0
+ for row in range(0,len(mask)):
+ bit = mask[row][col]
+
+ if bit == current:
+ counter += 1
+ else:
+ if counter >= 5:
+ total += (counter - 5) + 3
+ counter = 1
+ current = bit
+ if counter >= 5:
+ total += (counter - 5) + 3
+
+ self.scores[n][0] = total
+
+ #Score penalty rule 2
+ #This rule will add 3 to the score for each 2x2 block of the same
+ #colored pixels there are.
+ for (n, mask) in enumerate(self.masks):
+ count = 0
+ #Don't examine the 0th and Nth row/column
+ for i in range(0, len(mask)-1):
+ for j in range(0, len(mask)-1):
+ if mask[i][j] == mask[i+1][j] and \
+ mask[i][j] == mask[i][j+1] and \
+ mask[i][j] == mask[i+1][j+1]:
+ count += 1
+
+ self.scores[n][1] = count * 3
+
+ #Score penalty rule 3
+ #This rule looks for 1011101 within the mask prefixed
+ #and/or suffixed by four zeros.
+ patterns = [[0,0,0,0,1,0,1,1,1,0,1],
+ [1,0,1,1,1,0,1,0,0,0,0],]
+ #[0,0,0,0,1,0,1,1,1,0,1,0,0,0,0]]
+
+ for (n, mask) in enumerate(self.masks):
+ nmatches = 0
+
+ for i in range(len(mask)):
+ for j in range(len(mask)):
+ for pattern in patterns:
+ match = True
+ k = j
+ #Look for row matches
+ for p in pattern:
+ if k >= len(mask) or mask[i][k] != p:
+ match = False
+ break
+ k += 1
+ if match:
+ nmatches += 1
+
+ match = True
+ k = j
+ #Look for column matches
+ for p in pattern:
+ if k >= len(mask) or mask[k][i] != p:
+ match = False
+ break
+ k += 1
+ if match:
+ nmatches += 1
+
+
+ self.scores[n][2] = nmatches * 40
+
+ #Score the last rule, penalty rule 4. This rule measures how close
+ #the pattern is to being 50% black. The further it deviates from
+ #this this ideal the higher the penalty.
+ for (n, mask) in enumerate(self.masks):
+ nblack = 0
+ for row in mask:
+ nblack += sum(row)
+
+ total_pixels = len(mask)**2
+ ratio = nblack / total_pixels
+ percent = (ratio * 100) - 50
+ self.scores[n][3] = int((abs(int(percent)) / 5) * 10)
+
+
+ #Calculate the total for each score
+ totals = [0] * len(self.scores)
+ for i in range(len(self.scores)):
+ for j in range(len(self.scores[i])):
+ totals[i] += self.scores[i][j]
+
+ #DEBUG CODE!!!
+ #Prints out a table of scores
+ #print('Rule Scores\n 1 2 3 4 Total')
+ #for i in range(len(self.scores)):
+ # print(i, end='')
+ # for s in self.scores[i]:
+ # print('{0: >6}'.format(s), end='')
+ # print('{0: >7}'.format(totals[i]))
+ #print('Mask Chosen: {0}'.format(totals.index(min(totals))))
+
+ #The lowest total wins
+ return totals.index(min(totals))
+
+ def add_type_pattern(self, m, type_bits):
+ """This will add the pattern to the QR code that represents the error
+ level and the type of mask used to make the code.
+ """
+ field = iter(type_bits)
+ for i in range(7):
+ bit = int(next(field))
+
+ #Skip the timing bits
+ if i < 6:
+ m[8][i] = bit
+ else:
+ m[8][i+1] = bit
+
+ if -8 < -(i+1):
+ m[-(i+1)][8] = bit
+
+ for i in range(-8,0):
+ bit = int(next(field))
+
+ m[8][i] = bit
+
+ i = -i
+ #Skip timing column
+ if i > 6:
+ m[i][8] = bit
+ else:
+ m[i-1][8] = bit
+
+##############################################################################
+##############################################################################
+#
+# Output Functions
+#
+##############################################################################
+##############################################################################
+
+def _get_writable(stream_or_path, mode):
+ """This method returns a tuple containing the stream and a flag to indicate
+ if the stream should be automatically closed.
+
+ The `stream_or_path` parameter is returned if it is an open writable stream.
+ Otherwise, it treats the `stream_or_path` parameter as a file path and
+ opens it with the given mode.
+
+ It is used by the svg and png methods to interpret the file parameter.
+
+ :type stream_or_path: str | io.BufferedIOBase
+ :type mode: str | unicode
+ :rtype: (io.BufferedIOBase, bool)
+ """
+ is_stream = hasattr(stream_or_path, 'write')
+ if not is_stream:
+ # No stream provided, treat "stream_or_path" as path
+ stream_or_path = open(stream_or_path, mode)
+ return stream_or_path, not is_stream
+
+
+def _get_png_size(version, scale, quiet_zone=4):
+ """See: QRCode.get_png_size
+
+ This function was abstracted away from QRCode to allow for the output of
+ QR codes during the build process, i.e. for debugging. It works
+ just the same except you must specify the code's version. This is needed
+ to calculate the PNG's size.
+ """
+ #Formula: scale times number of modules plus the border on each side
+ return (int(scale) * tables.version_size[version]) + (2 * quiet_zone * int(scale))
+
+
+def _terminal(code, module_color='default', background='reverse', quiet_zone=4):
+ """This method returns a string containing ASCII escape codes,
+ such that if printed to a terminal, it will display a vaild
+ QR code. The module_color and the background color should be keys
+ in the tables.term_colors table for printing using the 8/16
+ color scheme. Alternatively, they can be a number between 0 and
+ 256 in order to use the 88/256 color scheme. Otherwise, a
+ ValueError will be raised.
+
+ Note, the code is outputted by changing the background color. Then
+ two spaces are written to the terminal. Finally, the terminal is
+ reset back to how it was.
+ """
+ buf = io.StringIO()
+
+ def draw_border():
+ for i in range(quiet_zone):
+ buf.write(background)
+
+ if module_color in tables.term_colors:
+ data = '\033[{0}m \033[0m'.format(
+ tables.term_colors[module_color])
+ elif 0 <= module_color <= 256:
+ data = '\033[48;5;{0}m \033[0m'.format(module_color)
+ else:
+ raise ValueError('The module color, {0}, must a key in '
+ 'pyqrcode.tables.term_colors or a number '
+ 'between 0 and 256.'.format(
+ module_color))
+
+ if background in tables.term_colors:
+ background = '\033[{0}m \033[0m'.format(
+ tables.term_colors[background])
+ elif 0 <= background <= 256:
+ background = '\033[48;5;{0}m \033[0m'.format(background)
+ else:
+ raise ValueError('The background color, {0}, must a key in '
+ 'pyqrcode.tables.term_colors or a number '
+ 'between 0 and 256.'.format(
+ background))
+
+ #This will be the beginning and ending row for the code.
+ border_row = background * (len(code[0]) + (2 * quiet_zone))
+
+ #Make sure we begin on a new line, and force the terminal back
+ #to normal
+ buf.write('\n')
+
+ #QRCodes have a quiet zone consisting of background modules
+ for i in range(quiet_zone):
+ buf.write(border_row)
+ buf.write('\n')
+
+ for row in code:
+ #Each code has a quiet zone on the left side, this is the left
+ #border for this code
+ draw_border()
+
+ for bit in row:
+ if bit == 1:
+ buf.write(data)
+ elif bit == 0:
+ buf.write(background)
+
+ #Each row ends with a quiet zone on the right side, this is the
+ #right hand border background modules
+ draw_border()
+ buf.write('\n')
+
+ #QRCodes have a background quiet zone row following the code
+ for i in range(quiet_zone):
+ buf.write(border_row)
+ buf.write('\n')
+
+ return buf.getvalue()
+
+def _text(code, quiet_zone=4):
+ """This method returns a text based representation of the QR code.
+ This is useful for debugging purposes.
+ """
+ buf = io.StringIO()
+
+ border_row = '0' * (len(code[0]) + (quiet_zone*2))
+
+ #Every QR code start with a quiet zone at the top
+ for b in range(quiet_zone):
+ buf.write(border_row)
+ buf.write('\n')
+
+ for row in code:
+ #Draw the starting quiet zone
+ for b in range(quiet_zone):
+ buf.write('0')
+
+ #Actually draw the QR code
+ for bit in row:
+ if bit == 1:
+ buf.write('1')
+ elif bit == 0:
+ buf.write('0')
+ #This is for debugging unfinished QR codes,
+ #unset pixels will be spaces.
+ else:
+ buf.write(' ')
+
+ #Draw the ending quiet zone
+ for b in range(quiet_zone):
+ buf.write('0')
+ buf.write('\n')
+
+ #Every QR code ends with a quiet zone at the bottom
+ for b in range(quiet_zone):
+ buf.write(border_row)
+ buf.write('\n')
+
+ return buf.getvalue()
+
+def _xbm(code, scale=1, quiet_zone=4):
+ """This function will format the QR code as a X BitMap.
+ This can be used to display the QR code with Tkinter.
+ """
+ try:
+ str = unicode # Python 2
+ except NameError:
+ str = __builtins__['str']
+
+ buf = io.StringIO()
+
+ # Calculate the width in pixels
+ pixel_width = (len(code[0]) + quiet_zone * 2) * scale
+
+ # Add the size information and open the pixel data section
+ buf.write('#define im_width ')
+ buf.write(str(pixel_width))
+ buf.write('\n')
+ buf.write('#define im_height ')
+ buf.write(str(pixel_width))
+ buf.write('\n')
+ buf.write('static char im_bits[] = {\n')
+
+ # Calculate the number of bytes per row
+ byte_width = int(math.ceil(pixel_width / 8.0))
+
+ # Add the top quiet zone
+ buf.write(('0x00,' * byte_width + '\n') * quiet_zone * scale)
+ for row in code:
+ # Add the left quiet zone
+ row_bits = '0' * quiet_zone * scale
+ # Add the actual QR code
+ for pixel in row:
+ row_bits += str(pixel) * scale
+ # Add the right quiet zone
+ row_bits += '0' * quiet_zone * scale
+ # Format the row
+ formated_row = ''
+ for b in range(byte_width):
+ formated_row += '0x{0:02x},'.format(int(row_bits[:8][::-1], 2))
+ row_bits = row_bits[8:]
+ formated_row += '\n'
+ # Add the formatted row
+ buf.write(formated_row * scale)
+ # Add the bottom quiet zone and close the pixel data section
+ buf.write(('0x00,' * byte_width + '\n') * quiet_zone * scale)
+ buf.write('};')
+
+ return buf.getvalue()
+
+def _svg(code, version, file, scale=1, module_color='#000', background=None,
+ quiet_zone=4, xmldecl=True, svgns=True, title=None, svgclass='pyqrcode',
+ lineclass='pyqrline', omithw=False, debug=False):
+ """This function writes the QR code out as an SVG document. The
+ code is drawn by drawing only the modules corresponding to a 1. They
+ are drawn using a line, such that contiguous modules in a row
+ are drawn with a single line. The file parameter is used to
+ specify where to write the document to. It can either be a writable (binary)
+ stream or a file path. The scale parameter is sets how large to draw
+ a single module. By default one pixel is used to draw a single
+ module. This may make the code to small to be read efficiently.
+ Increasing the scale will make the code larger. This method will accept
+ fractional scales (e.g. 2.5).
+
+ :param module_color: Color of the QR code (default: ``#000`` (black))
+ :param background: Optional background color.
+ (default: ``None`` (no background))
+ :param quiet_zone: Border around the QR code (also known as quiet zone)
+ (default: ``4``). Set to zero (``0``) if the code shouldn't
+ have a border.
+ :param xmldecl: Inidcates if the XML declaration header should be written
+ (default: ``True``)
+ :param svgns: Indicates if the SVG namespace should be written
+ (default: ``True``)
+ :param title: Optional title of the generated SVG document.
+ :param svgclass: The CSS class of the SVG document
+ (if set to ``None``, the SVG element won't have a class).
+ :param lineclass: The CSS class of the path element
+ (if set to ``None``, the path won't have a class).
+ :param omithw: Indicates if width and height attributes should be
+ omitted (default: ``False``). If these attributes are omitted,
+ a ``viewBox`` attribute will be added to the document.
+ :param debug: Inidicates if errors in the QR code should be added to the
+ output (default: ``False``).
+ """
+ from functools import partial
+ from xml.sax.saxutils import quoteattr
+
+ def write_unicode(write_meth, unicode_str):
+ """\
+ Encodes the provided string into UTF-8 and writes the result using
+ the `write_meth`.
+ """
+ write_meth(unicode_str.encode('utf-8'))
+
+ def line(x, y, length, relative):
+ """Returns coordinates to draw a line with the provided length.
+ """
+ return '{0}{1} {2}h{3}'.format(('m' if relative else 'M'), x, y, length)
+
+ def errline(col_number, row_number):
+ """Returns the coordinates to draw an error bit.
+ """
+ # Debug path uses always absolute coordinates
+ # .5 == stroke / 2
+ return line(col_number + quiet_zone, row_number + quiet_zone + .5, 1, False)
+
+ f, autoclose = _get_writable(file, 'wb')
+ write = partial(write_unicode, f.write)
+ write_bytes = f.write
+ # Write the document header
+ if xmldecl:
+ write_bytes(b'\n')
+ write_bytes(b'\n')
+ if autoclose:
+ f.close()
+
+
+def _png(code, version, file, scale=1, module_color=(0, 0, 0, 255),
+ background=(255, 255, 255, 255), quiet_zone=4, debug=False):
+ """See: pyqrcode.QRCode.png()
+
+ This function was abstracted away from QRCode to allow for the output of
+ QR codes during the build process, i.e. for debugging. It works
+ just the same except you must specify the code's version. This is needed
+ to calculate the PNG's size.
+
+ This method will write the given file out as a PNG file. Note, it
+ depends on the PyPNG module to do this.
+
+ :param module_color: Color of the QR code (default: ``(0, 0, 0, 255)`` (black))
+ :param background: Optional background color. If set to ``None`` the PNG
+ will have a transparent background.
+ (default: ``(255, 255, 255, 255)`` (white))
+ :param quiet_zone: Border around the QR code (also known as quiet zone)
+ (default: ``4``). Set to zero (``0``) if the code shouldn't
+ have a border.
+ :param debug: Inidicates if errors in the QR code should be added (as red
+ modules) to the output (default: ``False``).
+ """
+ import png
+
+ # Coerce scale parameter into an integer
+ try:
+ scale = int(scale)
+ except ValueError:
+ raise ValueError('The scale parameter must be an integer')
+
+ def scale_code(size):
+ """To perform the scaling we need to inflate the number of bits.
+ The PNG library expects all of the bits when it draws the PNG.
+ Effectively, we double, tripple, etc. the number of columns and
+ the number of rows.
+ """
+ # This is one row's worth of each possible module
+ # PNG's use 0 for black and 1 for white, this is the
+ # reverse of the QR standard
+ black = [0] * scale
+ white = [1] * scale
+
+ # Tuple to lookup colors
+ # The 3rd color is the module_color unless "debug" is enabled
+ colors = (white, black, (([2] * scale) if debug else black))
+
+ # Whitespace added on the left and right side
+ border_module = white * quiet_zone
+ # This is the row to show up at the top and bottom border
+ border_row = [[1] * size] * scale * quiet_zone
+
+ # This will hold the final PNG's bits
+ bits = []
+
+ # Add scale rows before the code as a border,
+ # as per the standard
+ bits.extend(border_row)
+
+ # Add each row of the to the final PNG bits
+ for row in code:
+ tmp_row = []
+
+ # Add one all white module to the beginning
+ # to create the vertical border
+ tmp_row.extend(border_module)
+
+ # Go through each bit in the code
+ for bit in row:
+ # Use the standard color or the "debug" color
+ tmp_row.extend(colors[(bit if bit in (0, 1) else 2)])
+
+ # Add one all white module to the end
+ # to create the vertical border
+ tmp_row.extend(border_module)
+
+ # Copy each row scale times
+ for n in range(scale):
+ bits.append(tmp_row)
+
+ # Add the bottom border
+ bits.extend(border_row)
+
+ return bits
+
+ def png_pallete_color(color):
+ """This creates a palette color from a list or tuple. The list or
+ tuple must be of length 3 (for rgb) or 4 (for rgba). The values
+ must be between 0 and 255. Note rgb colors will be given an added
+ alpha component set to 255.
+
+ The pallete color is represented as a list, this is what is returned.
+ """
+ if color is None:
+ return ()
+ if not isinstance(color, (tuple, list)):
+ r, g, b = _hex_to_rgb(color)
+ return r, g, b, 255
+ rgba = []
+ if not (3 <= len(color) <= 4):
+ raise ValueError('Colors must be a list or tuple of length '
+ ' 3 or 4. You passed in "{0}".'.format(color))
+ for c in color:
+ c = int(c)
+ if 0 <= c <= 255:
+ rgba.append(int(c))
+ else:
+ raise ValueError('Color components must be between 0 and 255')
+ # Make all colors have an alpha channel
+ if len(rgba) == 3:
+ rgba.append(255)
+ return tuple(rgba)
+
+ if module_color is None:
+ raise ValueError('The module_color must not be None')
+
+ bitdepth = 1
+ # foreground aka module color
+ fg_col = png_pallete_color(module_color)
+ transparent = background is None
+ # If background color is set to None, the inverse color of the
+ # foreground color is calculated
+ bg_col = png_pallete_color(background) if background is not None else tuple([255 - c for c in fg_col])
+ # Assume greyscale if module color is black and background color is white
+ greyscale = fg_col[:3] == (0, 0, 0) and (not debug and transparent or bg_col == (255, 255, 255, 255))
+ transparent_color = 1 if transparent and greyscale else None
+ palette = [fg_col, bg_col] if not greyscale else None
+ if debug:
+ # Add "red" as color for error modules
+ palette.append((255, 0, 0, 255))
+ bitdepth = 2
+
+ # The size of the PNG
+ size = _get_png_size(version, scale, quiet_zone)
+
+ # We need to increase the size of the code to match up to the
+ # scale parameter.
+ code_rows = scale_code(size)
+
+ # Write out the PNG
+ f, autoclose = _get_writable(file, 'wb')
+ w = png.Writer(width=size, height=size, greyscale=greyscale,
+ transparent=transparent_color, palette=palette,
+ bitdepth=bitdepth)
+ try:
+ w.write(f, code_rows)
+ finally:
+ if autoclose:
+ f.close()
+
+
+def _eps(code, version, file_or_path, scale=1, module_color=(0, 0, 0),
+ background=None, quiet_zone=4):
+ """This function writes the QR code out as an EPS document. The
+ code is drawn by drawing only the modules corresponding to a 1. They
+ are drawn using a line, such that contiguous modules in a row
+ are drawn with a single line. The file parameter is used to
+ specify where to write the document to. It can either be a writable (text)
+ stream or a file path. The scale parameter is sets how large to draw
+ a single module. By default one point (1/72 inch) is used to draw a single
+ module. This may make the code to small to be read efficiently.
+ Increasing the scale will make the code larger. This function will accept
+ fractional scales (e.g. 2.5).
+
+ :param module_color: Color of the QR code (default: ``(0, 0, 0)`` (black))
+ The color can be specified as triple of floats (range: 0 .. 1) or
+ triple of integers (range: 0 .. 255) or as hexadecimal value (i.e.
+ ``#36c`` or ``#33B200``).
+ :param background: Optional background color.
+ (default: ``None`` (no background)). See `module_color` for the
+ supported values.
+ :param quiet_zone: Border around the QR code (also known as quiet zone)
+ (default: ``4``). Set to zero (``0``) if the code shouldn't
+ have a border.
+ """
+ from functools import partial
+ import time
+ import textwrap
+
+ def write_line(writemeth, content):
+ """\
+ Writes `content` and ``LF``.
+ """
+ # Postscript: Max. 255 characters per line
+ for line in textwrap.wrap(content, 255):
+ writemeth(line)
+ writemeth('\n')
+
+ def line(offset, length):
+ """\
+ Returns coordinates to draw a line with the provided length.
+ """
+ res = ''
+ if offset > 0:
+ res = ' {0} 0 m'.format(offset)
+ res += ' {0} 0 l'.format(length)
+ return res
+
+ def rgb_to_floats(color):
+ """\
+ Converts the provided color into an acceptable format for Postscript's
+ ``setrgbcolor``
+ """
+ def to_float(clr):
+ if isinstance(clr, float):
+ if not 0.0 <= clr <= 1.0:
+ raise ValueError('Invalid color "{0}". Not in range 0 .. 1'
+ .format(clr))
+ return clr
+ if not 0 <= clr <= 255:
+ raise ValueError('Invalid color "{0}". Not in range 0 .. 255'
+ .format(clr))
+ return 1/255.0 * clr if clr != 1 else clr
+
+ if not isinstance(color, (tuple, list)):
+ color = _hex_to_rgb(color)
+ return tuple([to_float(i) for i in color])
+
+ f, autoclose = _get_writable(file_or_path, 'w')
+ writeline = partial(write_line, f.write)
+ size = tables.version_size[version] * scale + (2 * quiet_zone * scale)
+ # Write common header
+ writeline('%!PS-Adobe-3.0 EPSF-3.0')
+ writeline('%%Creator: PyQRCode ')
+ writeline('%%CreationDate: {0}'.format(time.strftime("%Y-%m-%d %H:%M:%S")))
+ writeline('%%DocumentData: Clean7Bit')
+ writeline('%%BoundingBox: 0 0 {0} {0}'.format(size))
+ # Write the shortcuts
+ writeline('/M { moveto } bind def')
+ writeline('/m { rmoveto } bind def')
+ writeline('/l { rlineto } bind def')
+ mod_color = module_color if module_color == (0, 0, 0) else rgb_to_floats(module_color)
+ if background is not None:
+ writeline('{0:f} {1:f} {2:f} setrgbcolor clippath fill'
+ .format(*rgb_to_floats(background)))
+ if mod_color == (0, 0, 0):
+ # Reset RGB color back to black iff module color is black
+ # In case module color != black set the module RGB color later
+ writeline('0 0 0 setrgbcolor')
+ if mod_color != (0, 0, 0):
+ writeline('{0:f} {1:f} {2:f} setrgbcolor'.format(*mod_color))
+ if scale != 1:
+ writeline('{0} {0} scale'.format(scale))
+ writeline('newpath')
+ # Current pen position y-axis
+ # Note: 0, 0 = lower left corner in PS coordinate system
+ y = tables.version_size[version] + quiet_zone + .5 # .5 = linewidth / 2
+ last_bit = 1
+ # Loop through each row of the code
+ for row in code:
+ offset = 0 # Set x-offset of the pen
+ length = 0
+ y -= 1 # Move pen along y-axis
+ coord = '{0} {1} M'.format(quiet_zone, y) # Move pen to initial pos
+ for bit in row:
+ if bit != last_bit:
+ if length:
+ coord += line(offset, length)
+ offset = 0
+ length = 0
+ last_bit = bit
+ if bit == 1:
+ length += 1
+ else:
+ offset += 1
+ if length:
+ coord += line(offset, length)
+ writeline(coord)
+ writeline('stroke')
+ writeline('%%EOF')
+ if autoclose:
+ f.close()
+
+
+def _hex_to_rgb(color):
+ """\
+ Helper function to convert a color provided in hexadecimal format
+ as RGB triple.
+ """
+ if color[0] == '#':
+ color = color[1:]
+ if len(color) == 3:
+ color = color[0] * 2 + color[1] * 2 + color[2] * 2
+ if len(color) != 6:
+ raise ValueError('Input #{0} is not in #RRGGBB format'.format(color))
+ return [int(n, 16) for n in (color[:2], color[2:4], color[4:])]
diff --git a/pyqrcode/tables.py b/pyqrcode/tables.py
new file mode 100644
index 0000000..dbd2893
--- /dev/null
+++ b/pyqrcode/tables.py
@@ -0,0 +1,794 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2013, Michael Nooner
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"""This module lists out all of the tables needed to create a QR code.
+If you are viewing this in the HTML documentation, I recommend reading the
+actual file instead. The formating for the tables is much more readable.
+"""
+from __future__ import division, unicode_literals
+
+#: This defines the QR Code's 'mode' which sets what
+#: type of code it is along with its size.
+modes = {
+ 'numeric': 1,
+ 'alphanumeric': 2,
+ 'binary': 4,
+ 'kanji': 8,
+}
+
+#: This defines the amount of error correction. The dictionary
+#: allows the user to specify this in several ways.
+error_level = {'L': 'L', 'l': 'L', '7%': 'L', .7: 'L',
+ 'M': 'M', 'm': 'M', '15%': 'M', .15: 'M',
+ 'Q': 'Q', 'q': 'Q', '25%': 'Q', .25: 'Q',
+ 'H': 'H', 'h': 'H', '30%': 'H', .30: 'H'}
+
+#: This is a dictionary holds how long the "data length" field is for
+#: each version and mode of the QR Code.
+data_length_field = {9: {1: 10, 2: 9, 4: 8, 8: 8},
+ 26: {1: 12, 2: 11, 4: 16, 8: 10},
+ 40: {1: 14, 2: 13, 4: 16, 8: 12}}
+
+#: QR Codes uses a unique ASCII-like table for the 'alphanumeric' mode.
+#: This is a dictionary representing that unique table, where the
+#: keys are the possible characters in the data and the values
+#: are the character's numeric representation.
+ascii_codes = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7,
+ '8': 8, '9': 9, 'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14,
+ 'F': 15, 'G': 16, 'H': 17, 'I': 18, 'J': 19, 'K': 20, 'L': 21,
+ 'M': 22, 'N': 23, 'O': 24, 'P': 25, 'Q': 26, 'R': 27, 'S': 28,
+ 'T': 29, 'U': 30, 'V': 31, 'W': 32, 'X': 33, 'Y': 34, 'Z': 35,
+ ' ': 36, '$': 37, '%': 38, '*': 39, '+': 40, '-': 41, '.': 42,
+ '/': 43, ':': 44}
+
+#: This array specifies the size of a QR Code in pixels. These numbers are
+#: defined in the standard. The indexes correspond to the QR Code's
+#: version number. This array was taken from:
+#:
+#: http://www.denso-wave.com/qrcode/vertable1-e.html
+version_size = [None, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57,
+ 61, 65, 69, 73, 77, 81, 85, 89, 93, 97,
+ 101, 105, 109, 113, 117, 121, 125, 129, 133, 137,
+ 141, 145, 149, 153, 157, 161, 165, 169, 173, 177]
+
+#: This dictionary lists the data capacity for all possible QR Codes.
+#: This dictionary is organized where the first key corresponds to the
+#: QR Code version number. The next key corresponds to the error
+#: correction level, see error. The final key corresponds to
+#: the mode number, see modes. The zero mode number represents the
+#: possible "data bits." This table was taken from:
+#:
+#: http://www.denso-wave.com/qrcode/vertable1-e.html
+data_capacity = {
+ 1: {
+ "L": {0: 152, 1: 41, 2: 25, 4: 17, 8: 10, },
+ "M": {0: 128, 1: 34, 2: 20, 4: 14, 8: 8, },
+ "Q": {0: 104, 1: 27, 2: 16, 4: 11, 8: 7, },
+ "H": {0: 72, 1: 17, 2: 10, 4: 7, 8: 4, }},
+ 2: {
+ "L": {0: 272, 1: 77, 2: 47, 4: 32, 8: 20, },
+ "M": {0: 224, 1: 63, 2: 38, 4: 26, 8: 16, },
+ "Q": {0: 176, 1: 48, 2: 29, 4: 20, 8: 12, },
+ "H": {0: 128, 1: 34, 2: 20, 4: 14, 8: 8, }},
+ 3: {
+ "L": {0: 440, 1: 127, 2: 77, 4: 53, 8: 32, },
+ "M": {0: 352, 1: 101, 2: 61, 4: 42, 8: 26, },
+ "Q": {0: 272, 1: 77, 2: 47, 4: 32, 8: 20, },
+ "H": {0: 208, 1: 58, 2: 35, 4: 24, 8: 15, }},
+ 4: {
+ "L": {0: 640, 1: 187, 2: 114, 4: 78, 8: 48, },
+ "M": {0: 512, 1: 149, 2: 90, 4: 62, 8: 38, },
+ "Q": {0: 384, 1: 111, 2: 67, 4: 46, 8: 28, },
+ "H": {0: 288, 1: 82, 2: 50, 4: 34, 8: 21, }},
+ 5: {
+ "L": {0: 864, 1: 255, 2: 154, 4: 106, 8: 65, },
+ "M": {0: 688, 1: 202, 2: 122, 4: 84, 8: 52, },
+ "Q": {0: 496, 1: 144, 2: 87, 4: 60, 8: 37, },
+ "H": {0: 368, 1: 106, 2: 64, 4: 44, 8: 27, }},
+ 6: {
+ "L": {0: 1088, 1: 322, 2: 195, 4: 134, 8: 82, },
+ "M": {0: 864, 1: 255, 2: 154, 4: 106, 8: 65, },
+ "Q": {0: 608, 1: 178, 2: 108, 4: 74, 8: 45, },
+ "H": {0: 480, 1: 139, 2: 84, 4: 58, 8: 36, }},
+ 7: {
+ "L": {0: 1248, 1: 370, 2: 224, 4: 154, 8: 95, },
+ "M": {0: 992, 1: 293, 2: 178, 4: 122, 8: 75, },
+ "Q": {0: 704, 1: 207, 2: 125, 4: 86, 8: 53, },
+ "H": {0: 528, 1: 154, 2: 93, 4: 64, 8: 39, }},
+ 8: {
+ "L": {0: 1552, 1: 461, 2: 279, 4: 192, 8: 118, },
+ "M": {0: 1232, 1: 365, 2: 221, 4: 152, 8: 93, },
+ "Q": {0: 880, 1: 259, 2: 157, 4: 108, 8: 66, },
+ "H": {0: 688, 1: 202, 2: 122, 4: 84, 8: 52, }},
+ 9: {
+ "L": {0: 1856, 1: 552, 2: 335, 4: 230, 8: 141, },
+ "M": {0: 1456, 1: 432, 2: 262, 4: 180, 8: 111, },
+ "Q": {0: 1056, 1: 312, 2: 189, 4: 130, 8: 80, },
+ "H": {0: 800, 1: 235, 2: 143, 4: 98, 8: 60, }},
+ 10: {
+ "L": {0: 2192, 1: 652, 2: 395, 4: 271, 8: 167, },
+ "M": {0: 1728, 1: 513, 2: 311, 4: 213, 8: 131, },
+ "Q": {0: 1232, 1: 364, 2: 221, 4: 151, 8: 93, },
+ "H": {0: 976, 1: 288, 2: 174, 4: 119, 8: 74, }},
+ 11: {
+ "L": {0: 2592, 1: 772, 2: 468, 4: 321, 8: 198, },
+ "M": {0: 2032, 1: 604, 2: 366, 4: 251, 8: 155, },
+ "Q": {0: 1440, 1: 427, 2: 259, 4: 177, 8: 109, },
+ "H": {0: 1120, 1: 331, 2: 200, 4: 137, 8: 85, }},
+ 12: {
+ "L": {0: 2960, 1: 883, 2: 535, 4: 367, 8: 226, },
+ "M": {0: 2320, 1: 691, 2: 419, 4: 287, 8: 177, },
+ "Q": {0: 1648, 1: 489, 2: 296, 4: 203, 8: 125, },
+ "H": {0: 1264, 1: 374, 2: 227, 4: 155, 8: 96, }},
+ 13: {
+ "L": {0: 3424, 1: 1022, 2: 619, 4: 425, 8: 262, },
+ "M": {0: 2672, 1: 796, 2: 483, 4: 331, 8: 204, },
+ "Q": {0: 1952, 1: 580, 2: 352, 4: 241, 8: 149, },
+ "H": {0: 1440, 1: 427, 2: 259, 4: 177, 8: 109, }},
+ 14: {
+ "L": {0: 3688, 1: 1101, 2: 667, 4: 458, 8: 282, },
+ "M": {0: 2920, 1: 871, 2: 528, 4: 362, 8: 223, },
+ "Q": {0: 2088, 1: 621, 2: 376, 4: 258, 8: 159, },
+ "H": {0: 1576, 1: 468, 2: 283, 4: 194, 8: 120, }},
+ 15: {
+ "L": {0: 4184, 1: 1250, 2: 758, 4: 520, 8: 320, },
+ "M": {0: 3320, 1: 991, 2: 600, 4: 412, 8: 254, },
+ "Q": {0: 2360, 1: 703, 2: 426, 4: 292, 8: 180, },
+ "H": {0: 1784, 1: 530, 2: 321, 4: 220, 8: 136, }},
+ 16: {
+ "L": {0: 4712, 1: 1408, 2: 854, 4: 586, 8: 361, },
+ "M": {0: 3624, 1: 1082, 2: 656, 4: 450, 8: 277, },
+ "Q": {0: 2600, 1: 775, 2: 470, 4: 322, 8: 198, },
+ "H": {0: 2024, 1: 602, 2: 365, 4: 250, 8: 154, }},
+ 17: {
+ "L": {0: 5176, 1: 1548, 2: 938, 4: 644, 8: 397, },
+ "M": {0: 4056, 1: 1212, 2: 734, 4: 504, 8: 310, },
+ "Q": {0: 2936, 1: 876, 2: 531, 4: 364, 8: 224, },
+ "H": {0: 2264, 1: 674, 2: 408, 4: 280, 8: 173, }},
+ 18: {
+ "L": {0: 5768, 1: 1725, 2: 1046, 4: 718, 8: 442, },
+ "M": {0: 4504, 1: 1346, 2: 816, 4: 560, 8: 345, },
+ "Q": {0: 3176, 1: 948, 2: 574, 4: 394, 8: 243, },
+ "H": {0: 2504, 1: 746, 2: 452, 4: 310, 8: 191, }},
+ 19: {
+ "L": {0: 6360, 1: 1903, 2: 1153, 4: 792, 8: 488, },
+ "M": {0: 5016, 1: 1500, 2: 909, 4: 624, 8: 384, },
+ "Q": {0: 3560, 1: 1063, 2: 644, 4: 442, 8: 272, },
+ "H": {0: 2728, 1: 813, 2: 493, 4: 338, 8: 208, }},
+ 20: {
+ "L": {0: 6888, 1: 2061, 2: 1249, 4: 858, 8: 528, },
+ "M": {0: 5352, 1: 1600, 2: 970, 4: 666, 8: 410, },
+ "Q": {0: 3880, 1: 1159, 2: 702, 4: 482, 8: 297, },
+ "H": {0: 3080, 1: 919, 2: 557, 4: 382, 8: 235, }},
+ 21: {
+ "L": {0: 7456, 1: 2232, 2: 1352, 4: 929, 8: 572, },
+ "M": {0: 5712, 1: 1708, 2: 1035, 4: 711, 8: 438, },
+ "Q": {0: 4096, 1: 1224, 2: 742, 4: 509, 8: 314, },
+ "H": {0: 3248, 1: 969, 2: 587, 4: 403, 8: 248, }},
+ 22: {
+ "L": {0: 8048, 1: 2409, 2: 1460, 4: 1003, 8: 618, },
+ "M": {0: 6256, 1: 1872, 2: 1134, 4: 779, 8: 480, },
+ "Q": {0: 4544, 1: 1358, 2: 823, 4: 565, 8: 348, },
+ "H": {0: 3536, 1: 1056, 2: 640, 4: 439, 8: 270, }},
+ 23: {
+ "L": {0: 8752, 1: 2620, 2: 1588, 4: 1091, 8: 672, },
+ "M": {0: 6880, 1: 2059, 2: 1248, 4: 857, 8: 528, },
+ "Q": {0: 4912, 1: 1468, 2: 890, 4: 611, 8: 376, },
+ "H": {0: 3712, 1: 1108, 2: 672, 4: 461, 8: 284, }},
+ 24: {
+ "L": {0: 9392, 1: 2812, 2: 1704, 4: 1171, 8: 721, },
+ "M": {0: 7312, 1: 2188, 2: 1326, 4: 911, 8: 561, },
+ "Q": {0: 5312, 1: 1588, 2: 963, 4: 661, 8: 407, },
+ "H": {0: 4112, 1: 1228, 2: 744, 4: 511, 8: 315, }},
+ 25: {
+ "L": {0: 10208, 1: 3057, 2: 1853, 4: 1273, 8: 784, },
+ "M": {0: 8000, 1: 2395, 2: 1451, 4: 997, 8: 614, },
+ "Q": {0: 5744, 1: 1718, 2: 1041, 4: 715, 8: 440, },
+ "H": {0: 4304, 1: 1286, 2: 779, 4: 535, 8: 330, }},
+ 26: {
+ "L": {0: 10960, 1: 3283, 2: 1990, 4: 1367, 8: 842, },
+ "M": {0: 8496, 1: 2544, 2: 1542, 4: 1059, 8: 652, },
+ "Q": {0: 6032, 1: 1804, 2: 1094, 4: 751, 8: 462, },
+ "H": {0: 4768, 1: 1425, 2: 864, 4: 593, 8: 365, }},
+ 27: {
+ "L": {0: 11744, 1: 3514, 2: 2132, 4: 1465, 8: 902, },
+ "M": {0: 9024, 1: 2701, 2: 1637, 4: 1125, 8: 692, },
+ "Q": {0: 6464, 1: 1933, 2: 1172, 4: 805, 8: 496, },
+ "H": {0: 5024, 1: 1501, 2: 910, 4: 625, 8: 385, }},
+ 28: {
+ "L": {0: 12248, 1: 3669, 2: 2223, 4: 1528, 8: 940, },
+ "M": {0: 9544, 1: 2857, 2: 1732, 4: 1190, 8: 732, },
+ "Q": {0: 6968, 1: 2085, 2: 1263, 4: 868, 8: 534, },
+ "H": {0: 5288, 1: 1581, 2: 958, 4: 658, 8: 405, }},
+ 29: {
+ "L": {0: 13048, 1: 3909, 2: 2369, 4: 1628, 8: 1002, },
+ "M": {0: 10136, 1: 3035, 2: 1839, 4: 1264, 8: 778, },
+ "Q": {0: 7288, 1: 2181, 2: 1322, 4: 908, 8: 559, },
+ "H": {0: 5608, 1: 1677, 2: 1016, 4: 698, 8: 430, }},
+ 30: {
+ "L": {0: 13880, 1: 4158, 2: 2520, 4: 1732, 8: 1066, },
+ "M": {0: 10984, 1: 3289, 2: 1994, 4: 1370, 8: 843, },
+ "Q": {0: 7880, 1: 2358, 2: 1429, 4: 982, 8: 604, },
+ "H": {0: 5960, 1: 1782, 2: 1080, 4: 742, 8: 457, }},
+ 31: {
+ "L": {0: 14744, 1: 4417, 2: 2677, 4: 1840, 8: 1132, },
+ "M": {0: 11640, 1: 3486, 2: 2113, 4: 1452, 8: 894, },
+ "Q": {0: 8264, 1: 2473, 2: 1499, 4: 1030, 8: 634, },
+ "H": {0: 6344, 1: 1897, 2: 1150, 4: 790, 8: 486, }},
+ 32: {
+ "L": {0: 15640, 1: 4686, 2: 2840, 4: 1952, 8: 1201, },
+ "M": {0: 12328, 1: 3693, 2: 2238, 4: 1538, 8: 947, },
+ "Q": {0: 8920, 1: 2670, 2: 1618, 4: 1112, 8: 684, },
+ "H": {0: 6760, 1: 2022, 2: 1226, 4: 842, 8: 518, }},
+ 33: {
+ "L": {0: 16568, 1: 4965, 2: 3009, 4: 2068, 8: 1273, },
+ "M": {0: 13048, 1: 3909, 2: 2369, 4: 1628, 8: 1002, },
+ "Q": {0: 9368, 1: 2805, 2: 1700, 4: 1168, 8: 719, },
+ "H": {0: 7208, 1: 2157, 2: 1307, 4: 898, 8: 553, }},
+ 34: {
+ "L": {0: 17528, 1: 5253, 2: 3183, 4: 2188, 8: 1347, },
+ "M": {0: 13800, 1: 4134, 2: 2506, 4: 1722, 8: 1060, },
+ "Q": {0: 9848, 1: 2949, 2: 1787, 4: 1228, 8: 756, },
+ "H": {0: 7688, 1: 2301, 2: 1394, 4: 958, 8: 590, }},
+ 35: {
+ "L": {0: 18448, 1: 5529, 2: 3351, 4: 2303, 8: 1417, },
+ "M": {0: 14496, 1: 4343, 2: 2632, 4: 1809, 8: 1113, },
+ "Q": {0: 10288, 1: 3081, 2: 1867, 4: 1283, 8: 790, },
+ "H": {0: 7888, 1: 2361, 2: 1431, 4: 983, 8: 605, }},
+ 36: {
+ "L": {0: 19472, 1: 5836, 2: 3537, 4: 2431, 8: 1496, },
+ "M": {0: 15312, 1: 4588, 2: 2780, 4: 1911, 8: 1176, },
+ "Q": {0: 10832, 1: 3244, 2: 1966, 4: 1351, 8: 832, },
+ "H": {0: 8432, 1: 2524, 2: 1530, 4: 1051, 8: 647, }},
+ 37: {
+ "L": {0: 20528, 1: 6153, 2: 3729, 4: 2563, 8: 1577, },
+ "M": {0: 15936, 1: 4775, 2: 2894, 4: 1989, 8: 1224, },
+ "Q": {0: 11408, 1: 3417, 2: 2071, 4: 1423, 8: 876, },
+ "H": {0: 8768, 1: 2625, 2: 1591, 4: 1093, 8: 673, }},
+ 38: {
+ "L": {0: 21616, 1: 6479, 2: 3927, 4: 2699, 8: 1661, },
+ "M": {0: 16816, 1: 5039, 2: 3054, 4: 2099, 8: 1292, },
+ "Q": {0: 12016, 1: 3599, 2: 2181, 4: 1499, 8: 923, },
+ "H": {0: 9136, 1: 2735, 2: 1658, 4: 1139, 8: 701, }},
+ 39: {
+ "L": {0: 22496, 1: 6743, 2: 4087, 4: 2809, 8: 1729, },
+ "M": {0: 17728, 1: 5313, 2: 3220, 4: 2213, 8: 1362, },
+ "Q": {0: 12656, 1: 3791, 2: 2298, 4: 1579, 8: 972, },
+ "H": {0: 9776, 1: 2927, 2: 1774, 4: 1219, 8: 750, }},
+ 40: {
+ "L": {0: 23648, 1: 7089, 2: 4296, 4: 2953, 8: 1817, },
+ "M": {0: 18672, 1: 5596, 2: 3391, 4: 2331, 8: 1435, },
+ "Q": {0: 13328, 1: 3993, 2: 2420, 4: 1663, 8: 1024, },
+ "H": {0: 10208, 1: 3057, 2: 1852, 4: 1273, 8: 784, }}
+}
+
+#: This table defines the "Error Correction Code Words and Block Information."
+#: The table lists the number of error correction words that are required
+#: to be generated for each version and error correction level. The table
+#: is accessed by first using the version number as a key and then the
+#: error level. The array values correspond to these columns from the source
+#: table:
+#:
+#: +----------------------------+
+#: |0 | EC Code Words Per Block |
+#: +----------------------------+
+#: |1 | Block 1 Count |
+#: +----------------------------+
+#: |2 | Block 1 Data Code Words |
+#: +----------------------------+
+#: |3 | Block 2 Count |
+#: +----------------------------+
+#: |4 | Block 2 Data Code Words |
+#: +----------------------------+
+#:
+#: This table was taken from:
+#:
+#: http://www.thonky.com/qr-code-tutorial/error-correction-table/
+eccwbi = {
+ 1: {
+ 'L': [7, 1, 19, 0, 0, ],
+ 'M': [10, 1, 16, 0, 0, ],
+ 'Q': [13, 1, 13, 0, 0, ],
+ 'H': [17, 1, 9, 0, 0, ],
+ },
+ 2: {
+ 'L': [10, 1, 34, 0, 0, ],
+ 'M': [16, 1, 28, 0, 0, ],
+ 'Q': [22, 1, 22, 0, 0, ],
+ 'H': [28, 1, 16, 0, 0, ],
+ },
+ 3: {
+ 'L': [15, 1, 55, 0, 0, ],
+ 'M': [26, 1, 44, 0, 0, ],
+ 'Q': [18, 2, 17, 0, 0, ],
+ 'H': [22, 2, 13, 0, 0, ],
+ },
+ 4: {
+ 'L': [20, 1, 80, 0, 0, ],
+ 'M': [18, 2, 32, 0, 0, ],
+ 'Q': [26, 2, 24, 0, 0, ],
+ 'H': [16, 4, 9, 0, 0, ],
+ },
+ 5: {
+ 'L': [26, 1, 108, 0, 0, ],
+ 'M': [24, 2, 43, 0, 0, ],
+ 'Q': [18, 2, 15, 2, 16, ],
+ 'H': [22, 2, 11, 2, 12, ],
+ },
+ 6: {
+ 'L': [18, 2, 68, 0, 0, ],
+ 'M': [16, 4, 27, 0, 0, ],
+ 'Q': [24, 4, 19, 0, 0, ],
+ 'H': [28, 4, 15, 0, 0, ],
+ },
+ 7: {
+ 'L': [20, 2, 78, 0, 0, ],
+ 'M': [18, 4, 31, 0, 0, ],
+ 'Q': [18, 2, 14, 4, 15, ],
+ 'H': [26, 4, 13, 1, 14, ],
+ },
+ 8: {
+ 'L': [24, 2, 97, 0, 0, ],
+ 'M': [22, 2, 38, 2, 39, ],
+ 'Q': [22, 4, 18, 2, 19, ],
+ 'H': [26, 4, 14, 2, 15, ],
+ },
+ 9: {
+ 'L': [30, 2, 116, 0, 0, ],
+ 'M': [22, 3, 36, 2, 37, ],
+ 'Q': [20, 4, 16, 4, 17, ],
+ 'H': [24, 4, 12, 4, 13, ],
+ },
+ 10: {
+ 'L': [18, 2, 68, 2, 69, ],
+ 'M': [26, 4, 43, 1, 44, ],
+ 'Q': [24, 6, 19, 2, 20, ],
+ 'H': [28, 6, 15, 2, 16, ],
+ },
+ 11: {
+ 'L': [20, 4, 81, 0, 0, ],
+ 'M': [30, 1, 50, 4, 51, ],
+ 'Q': [28, 4, 22, 4, 23, ],
+ 'H': [24, 3, 12, 8, 13, ],
+ },
+ 12: {
+ 'L': [24, 2, 92, 2, 93, ],
+ 'M': [22, 6, 36, 2, 37, ],
+ 'Q': [26, 4, 20, 6, 21, ],
+ 'H': [28, 7, 14, 4, 15, ],
+ },
+ 13: {
+ 'L': [26, 4, 107, 0, 0, ],
+ 'M': [22, 8, 37, 1, 38, ],
+ 'Q': [24, 8, 20, 4, 21, ],
+ 'H': [22, 12, 11, 4, 12, ],
+ },
+ 14: {
+ 'L': [30, 3, 115, 1, 116, ],
+ 'M': [24, 4, 40, 5, 41, ],
+ 'Q': [20, 11, 16, 5, 17, ],
+ 'H': [24, 11, 12, 5, 13, ],
+ },
+ 15: {
+ 'L': [22, 5, 87, 1, 88, ],
+ 'M': [24, 5, 41, 5, 42, ],
+ 'Q': [30, 5, 24, 7, 25, ],
+ 'H': [24, 11, 12, 7, 13, ],
+ },
+ 16: {
+ 'L': [24, 5, 98, 1, 99, ],
+ 'M': [28, 7, 45, 3, 46, ],
+ 'Q': [24, 15, 19, 2, 20, ],
+ 'H': [30, 3, 15, 13, 16, ],
+ },
+ 17: {
+ 'L': [28, 1, 107, 5, 108, ],
+ 'M': [28, 10, 46, 1, 47, ],
+ 'Q': [28, 1, 22, 15, 23, ],
+ 'H': [28, 2, 14, 17, 15, ],
+ },
+ 18: {
+ 'L': [30, 5, 120, 1, 121, ],
+ 'M': [26, 9, 43, 4, 44, ],
+ 'Q': [28, 17, 22, 1, 23, ],
+ 'H': [28, 2, 14, 19, 15, ],
+ },
+ 19: {
+ 'L': [28, 3, 113, 4, 114, ],
+ 'M': [26, 3, 44, 11, 45, ],
+ 'Q': [26, 17, 21, 4, 22, ],
+ 'H': [26, 9, 13, 16, 14, ],
+ },
+ 20: {
+ 'L': [28, 3, 107, 5, 108, ],
+ 'M': [26, 3, 41, 13, 42, ],
+ 'Q': [30, 15, 24, 5, 25, ],
+ 'H': [28, 15, 15, 10, 16, ],
+ },
+ 21: {
+ 'L': [28, 4, 116, 4, 117, ],
+ 'M': [26, 17, 42, 0, 0, ],
+ 'Q': [28, 17, 22, 6, 23, ],
+ 'H': [30, 19, 16, 6, 17, ],
+ },
+ 22: {
+ 'L': [28, 2, 111, 7, 112, ],
+ 'M': [28, 17, 46, 0, 0, ],
+ 'Q': [30, 7, 24, 16, 25, ],
+ 'H': [24, 34, 13, 0, 0, ],
+ },
+ 23: {
+ 'L': [30, 4, 121, 5, 122, ],
+ 'M': [28, 4, 47, 14, 48, ],
+ 'Q': [30, 11, 24, 14, 25, ],
+ 'H': [30, 16, 15, 14, 16, ],
+ },
+ 24: {
+ 'L': [30, 6, 117, 4, 118, ],
+ 'M': [28, 6, 45, 14, 46, ],
+ 'Q': [30, 11, 24, 16, 25, ],
+ 'H': [30, 30, 16, 2, 17, ],
+ },
+ 25: {
+ 'L': [26, 8, 106, 4, 107, ],
+ 'M': [28, 8, 47, 13, 48, ],
+ 'Q': [30, 7, 24, 22, 25, ],
+ 'H': [30, 22, 15, 13, 16, ],
+ },
+ 26: {
+ 'L': [28, 10, 114, 2, 115, ],
+ 'M': [28, 19, 46, 4, 47, ],
+ 'Q': [28, 28, 22, 6, 23, ],
+ 'H': [30, 33, 16, 4, 17, ],
+ },
+ 27: {
+ 'L': [30, 8, 122, 4, 123, ],
+ 'M': [28, 22, 45, 3, 46, ],
+ 'Q': [30, 8, 23, 26, 24, ],
+ 'H': [30, 12, 15, 28, 16, ],
+ },
+ 28: {
+ 'L': [30, 3, 117, 10, 118, ],
+ 'M': [28, 3, 45, 23, 46, ],
+ 'Q': [30, 4, 24, 31, 25, ],
+ 'H': [30, 11, 15, 31, 16, ],
+ },
+ 29: {
+ 'L': [30, 7, 116, 7, 117, ],
+ 'M': [28, 21, 45, 7, 46, ],
+ 'Q': [30, 1, 23, 37, 24, ],
+ 'H': [30, 19, 15, 26, 16, ],
+ },
+ 30: {
+ 'L': [30, 5, 115, 10, 116, ],
+ 'M': [28, 19, 47, 10, 48, ],
+ 'Q': [30, 15, 24, 25, 25, ],
+ 'H': [30, 23, 15, 25, 16, ],
+ },
+ 31: {
+ 'L': [30, 13, 115, 3, 116, ],
+ 'M': [28, 2, 46, 29, 47, ],
+ 'Q': [30, 42, 24, 1, 25, ],
+ 'H': [30, 23, 15, 28, 16, ],
+ },
+ 32: {
+ 'L': [30, 17, 115, 0, 0, ],
+ 'M': [28, 10, 46, 23, 47, ],
+ 'Q': [30, 10, 24, 35, 25, ],
+ 'H': [30, 19, 15, 35, 16, ],
+ },
+ 33: {
+ 'L': [30, 17, 115, 1, 116, ],
+ 'M': [28, 14, 46, 21, 47, ],
+ 'Q': [30, 29, 24, 19, 25, ],
+ 'H': [30, 11, 15, 46, 16, ],
+ },
+ 34: {
+ 'L': [30, 13, 115, 6, 116, ],
+ 'M': [28, 14, 46, 23, 47, ],
+ 'Q': [30, 44, 24, 7, 25, ],
+ 'H': [30, 59, 16, 1, 17, ],
+ },
+ 35: {
+ 'L': [30, 12, 121, 7, 122, ],
+ 'M': [28, 12, 47, 26, 48, ],
+ 'Q': [30, 39, 24, 14, 25, ],
+ 'H': [30, 22, 15, 41, 16, ],
+ },
+ 36: {
+ 'L': [30, 6, 121, 14, 122, ],
+ 'M': [28, 6, 47, 34, 48, ],
+ 'Q': [30, 46, 24, 10, 25, ],
+ 'H': [30, 2, 15, 64, 16, ],
+ },
+ 37: {
+ 'L': [30, 17, 122, 4, 123, ],
+ 'M': [28, 29, 46, 14, 47, ],
+ 'Q': [30, 49, 24, 10, 25, ],
+ 'H': [30, 24, 15, 46, 16, ],
+ },
+ 38: {
+ 'L': [30, 4, 122, 18, 123, ],
+ 'M': [28, 13, 46, 32, 47, ],
+ 'Q': [30, 48, 24, 14, 25, ],
+ 'H': [30, 42, 15, 32, 16, ],
+ },
+ 39: {
+ 'L': [30, 20, 117, 4, 118, ],
+ 'M': [28, 40, 47, 7, 48, ],
+ 'Q': [30, 43, 24, 22, 25, ],
+ 'H': [30, 10, 15, 67, 16, ],
+ },
+ 40: {
+ 'L': [30, 19, 118, 6, 119, ],
+ 'M': [28, 18, 47, 31, 48, ],
+ 'Q': [30, 34, 24, 34, 25, ],
+ 'H': [30, 20, 15, 61, 16, ],
+ },
+}
+
+#: This table lists all of the generator polynomials used by QR Codes.
+#: They are indexed by the number of "ECC Code Words" (see table above).
+#: This table is taken from:
+#:
+#: http://www.matchadesign.com/blog/qr-code-demystified-part-4/
+generator_polynomials = {
+ 7: [87, 229, 146, 149, 238, 102, 21],
+ 10: [251, 67, 46, 61, 118, 70, 64, 94, 32, 45],
+ 13: [74, 152, 176, 100, 86, 100, 106, 104, 130, 218, 206, 140, 78],
+ 15: [8, 183, 61, 91, 202, 37, 51, 58, 58, 237, 140, 124, 5, 99, 105],
+ 16: [120, 104, 107, 109, 102, 161, 76, 3, 91, 191, 147, 169, 182, 194,
+ 225, 120],
+ 17: [43, 139, 206, 78, 43, 239, 123, 206, 214, 147, 24, 99, 150, 39,
+ 243, 163, 136],
+ 18: [215, 234, 158, 94, 184, 97, 118, 170, 79, 187, 152, 148, 252, 179,
+ 5, 98, 96, 153],
+ 20: [17, 60, 79, 50, 61, 163, 26, 187, 202, 180, 221, 225, 83, 239, 156,
+ 164, 212, 212, 188, 190],
+ 22: [210, 171, 247, 242, 93, 230, 14, 109, 221, 53, 200, 74, 8, 172, 98,
+ 80, 219, 134, 160, 105, 165, 231],
+ 24: [229, 121, 135, 48, 211, 117, 251, 126, 159, 180, 169, 152, 192, 226,
+ 228, 218, 111, 0, 117, 232, 87, 96, 227, 21],
+ 26: [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],
+ 28: [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],
+ 30: [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]
+}
+
+#: This table contains the log and values used in GF(256) arithmetic.
+#: They are used to generate error correction codes for QR Codes.
+#: This table is taken from:
+#:
+#: vhttp://www.thonky.com/qr-code-tutorial/log-antilog-table/
+galois_log = [
+ 1, 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, 76, 152,
+ 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96, 192, 157, 39, 78,
+ 156, 37, 74, 148, 53, 106, 212, 181, 119, 238, 193, 159, 35, 70, 140, 5,
+ 10, 20, 40, 80, 160, 93, 186, 105, 210, 185, 111, 222, 161, 95, 190, 97,
+ 194, 153, 47, 94, 188, 101, 202, 137, 15, 30, 60, 120, 240, 253, 231, 211,
+ 187, 107, 214, 177, 127, 254, 225, 223, 163, 91, 182, 113, 226, 217, 175,
+ 67, 134, 17, 34, 68, 136, 13, 26, 52, 104, 208, 189, 103, 206, 129, 31,
+ 62, 124, 248, 237, 199, 147, 59, 118, 236, 197, 151, 51, 102, 204, 133,
+ 23, 46, 92, 184, 109, 218, 169, 79, 158, 33, 66, 132, 21, 42, 84, 168, 77,
+ 154, 41, 82, 164, 85, 170, 73, 146, 57, 114, 228, 213, 183, 115, 230, 209,
+ 191, 99, 198, 145, 63, 126, 252, 229, 215, 179, 123, 246, 241, 255, 227,
+ 219, 171, 75, 150, 49, 98, 196, 149, 55, 110, 220, 165, 87, 174, 65, 130,
+ 25, 50, 100, 200, 141, 7, 14, 28, 56, 112, 224, 221, 167, 83, 166, 81,
+ 162, 89, 178, 121, 242, 249, 239, 195, 155, 43, 86, 172, 69, 138, 9, 18,
+ 36, 72, 144, 61, 122, 244, 245, 247, 243, 251, 235, 203, 139, 11, 22, 44,
+ 88, 176, 125, 250, 233, 207, 131, 27, 54, 108, 216, 173, 71, 142, 1,]
+
+#: This table contains the antilog and values used in GF(256) arithmetic.
+#: They are used to generate error correction codes for QR Codes.
+#: This table is taken from:
+#:
+#: http://www.thonky.com/qr-code-tutorial/log-antilog-table/
+galois_antilog = [
+ None, 0, 1, 25, 2, 50, 26, 198, 3, 223, 51, 238, 27, 104, 199, 75, 4, 100,
+ 224, 14, 52, 141, 239, 129, 28, 193, 105, 248, 200, 8, 76, 113, 5, 138,
+ 101, 47, 225, 36, 15, 33, 53, 147, 142, 218, 240, 18, 130, 69, 29, 181,
+ 194, 125, 106, 39, 249, 185, 201, 154, 9, 120, 77, 228, 114, 166, 6, 191,
+ 139, 98, 102, 221, 48, 253, 226, 152, 37, 179, 16, 145, 34, 136, 54, 208,
+ 148, 206, 143, 150, 219, 189, 241, 210, 19, 92, 131, 56, 70, 64, 30, 66,
+ 182, 163, 195, 72, 126, 110, 107, 58, 40, 84, 250, 133, 186, 61, 202, 94,
+ 155, 159, 10, 21, 121, 43, 78, 212, 229, 172, 115, 243, 167, 87, 7, 112,
+ 192, 247, 140, 128, 99, 13, 103, 74, 222, 237, 49, 197, 254, 24, 227, 165,
+ 153, 119, 38, 184, 180, 124, 17, 68, 146, 217, 35, 32, 137, 46, 55, 63,
+ 209, 91, 149, 188, 207, 205, 144, 135, 151, 178, 220, 252, 190, 97, 242,
+ 86, 211, 171, 20, 42, 93, 158, 132, 60, 57, 83, 71, 109, 65, 162, 31, 45,
+ 67, 216, 183, 123, 164, 118, 196, 23, 73, 236, 127, 12, 111, 246, 108,
+ 161, 59, 82, 41, 157, 85, 170, 251, 96, 134, 177, 187, 204, 62, 90, 203,
+ 89, 95, 176, 156, 169, 160, 81, 11, 245, 22, 235, 122, 117, 44, 215, 79,
+ 174, 213, 233, 230, 231, 173, 232, 116, 214, 244, 234, 168, 80, 88, 175,]
+
+#: This table contains the coordinates for the position adjustment patterns.
+#: The index of the table corresponds to the QR Code's version number.
+#: This table is taken from:
+#:
+#: http://www.thonky.com/qr-code-tutorial/part-3-mask-pattern/
+position_adjustment = [
+ None, #There is not version 0
+ None, #Version 1 does not need adjustment
+ [6, 18, ],
+ [6, 22, ],
+ [6, 26, ],
+ [6, 30, ],
+ [6, 34, ],
+ [6, 22, 38, ],
+ [6, 24, 42, ],
+ [6, 26, 46, ],
+ [6, 28, 50, ],
+ [6, 30, 54, ],
+ [6, 32, 58, ],
+ [6, 34, 62, ],
+ [6, 26, 46, 66, ],
+ [6, 26, 48, 70, ],
+ [6, 26, 50, 74, ],
+ [6, 30, 54, 78, ],
+ [6, 30, 56, 82, ],
+ [6, 30, 58, 86, ],
+ [6, 34, 62, 90, ],
+ [6, 28, 50, 72, 94, ],
+ [6, 26, 50, 74, 98, ],
+ [6, 30, 54, 78, 102, ],
+ [6, 28, 54, 80, 106, ],
+ [6, 32, 58, 84, 110, ],
+ [6, 30, 58, 86, 114, ],
+ [6, 34, 62, 90, 118, ],
+ [6, 26, 50, 74, 98, 122, ],
+ [6, 30, 54, 78, 102, 126, ],
+ [6, 26, 52, 78, 104, 130, ],
+ [6, 30, 56, 82, 108, 134, ],
+ [6, 34, 60, 86, 112, 138, ],
+ [6, 30, 58, 86, 114, 142, ],
+ [6, 34, 62, 90, 118, 146, ],
+ [6, 30, 54, 78, 102, 126, 150, ],
+ [6, 24, 50, 76, 102, 128, 154, ],
+ [6, 28, 54, 80, 106, 132, 158, ],
+ [6, 32, 58, 84, 110, 136, 162, ],
+ [6, 26, 54, 82, 110, 138, 166, ],
+ [6, 30, 58, 86, 114, 142, 170, ],
+]
+
+#: This table specifies the bit pattern to be added to a QR Code's
+#: image to specify what version the code is. Note, this pattern
+#: is not used for versions 1-6. This table is taken from:
+#:
+#: http://www.thonky.com/qr-code-tutorial/part-3-mask-pattern/
+version_pattern = [None, None, None, None, None, None, None, #0-6
+ '000111110010010100', '001000010110111100', '001001101010011001',
+ '001010010011010011', '001011101111110110', '001100011101100010',
+ '001101100001000111', '001110011000001101', '001111100100101000',
+ '010000101101111000', '010001010001011101', '010010101000010111',
+ '010011010100110010', '010100100110100110', '010101011010000011',
+ '010110100011001001', '010111011111101100', '011000111011000100',
+ '011001000111100001', '011010111110101011', '011011000010001110',
+ '011100110000011010', '011101001100111111', '011110110101110101',
+ '011111001001010000', '100000100111010101', '100001011011110000',
+ '100010100010111010', '100011011110011111', '100100101100001011',
+ '100101010000101110', '100110101001100100', '100111010101000001',
+ '101000110001101001'
+]
+
+#: This table contains the bit fields needed to specify the error code level and
+#: mask pattern used by a QR Code. This table is take from:
+#:
+#: http://www.thonky.com/qr-code-tutorial/part-3-mask-pattern/
+type_bits = {
+ 'L': {
+ 0: '111011111000100',
+ 1: '111001011110011',
+ 2: '111110110101010',
+ 3: '111100010011101',
+ 4: '110011000101111',
+ 5: '110001100011000',
+ 6: '110110001000001',
+ 7: '110100101110110',
+ },
+ 'M': {
+ 0: '101010000010010',
+ 1: '101000100100101',
+ 2: '101111001111100',
+ 3: '101101101001011',
+ 4: '100010111111001',
+ 5: '100000011001110',
+ 6: '100111110010111',
+ 7: '100101010100000',
+ },
+ 'Q': {
+ 0: '011010101011111',
+ 1: '011000001101000',
+ 2: '011111100110001',
+ 3: '011101000000110',
+ 4: '010010010110100',
+ 5: '010000110000011',
+ 6: '010111011011010',
+ 7: '010101111101101',
+ },
+ 'H': {
+ 0: '001011010001001',
+ 1: '001001110111110',
+ 2: '001110011100111',
+ 3: '001100111010000',
+ 4: '000011101100010',
+ 5: '000001001010101',
+ 6: '000110100001100',
+ 7: '000100000111011',
+ },
+}
+
+#: This table contains *functions* to compute whether to change current bit when
+#: creating the masks. All of the functions in the table return a boolean value.
+#: A True result means you should add the bit to the QR Code exactly as is. A
+#: False result means you should add the opposite bit. This table was taken
+#: from:
+#:
+#: http://www.thonky.com/qr-code-tutorial/mask-patterns/
+mask_patterns = [
+ lambda row, col: (row + col) % 2 == 0,
+ lambda row, col: row % 2 == 0,
+ lambda row, col: col % 3 == 0,
+ lambda row, col: (row + col) % 3 == 0,
+ lambda row, col: ((row // 2) + (col // 3)) % 2 == 0,
+ lambda row, col: ((row * col) % 2) + ((row * col) % 3) == 0,
+ lambda row, col: (((row * col) % 2) + ((row * col) % 3)) % 2 == 0,
+ lambda row, col: (((row + col) % 2) + ((row * col) % 3)) % 2 == 0]
+
+
+#: This is a table of ASCII escape code for terminal colors. QR codes
+#: are drawn using a space with a colored background. Hence, only
+#: codes affecting background colors have been added.
+#: http://misc.flogisoft.com/bash/tip_colors_and_formatting
+term_colors = {
+ 'default': 49,
+ 'background': 49,
+
+ 'reverse': 7,
+ 'reversed': 7,
+ 'inverse': 7,
+ 'inverted': 7,
+
+ 'black': 40,
+ 'red': 41,
+ 'green': 42,
+ 'yellow': 43,
+ 'blue': 44,
+ 'magenta': 45,
+ 'cyan': 46,
+ 'light gray': 47,
+ 'light grey': 47,
+ 'dark gray': 100,
+ 'dark grey': 100,
+ 'light red': 101,
+ 'light green': 102,
+ 'light blue': 103,
+ 'light yellow': 104,
+ 'light magenta': 105,
+ 'light cyan': 106,
+ 'white': 107
+}
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..861a9f5
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,5 @@
+[egg_info]
+tag_build =
+tag_date = 0
+tag_svn_revision = 0
+
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..9fac429
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,76 @@
+# Copyright (c) 2013, Michael Nooner
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+from setuptools import setup
+import sys, os.path, shutil
+
+version = '1.2.1'
+
+if sys.version_info < (2, 6, 0) and sys.version_info < (3, 0, 0):
+ sys.stderr.write("pyqrcode requires Python 2.6+ or 3.\n")
+ sys.exit(1)
+
+
+#Make the README.rst file the long description
+#This only happens when we are building from the
+#source.
+if os.path.exists('docs/README.rst'):
+ print('Reading README.rst file')
+ with open( 'docs/README.rst', 'r') as f:
+ longdesc = f.read()
+ shutil.copyfile('docs/README.rst', 'README.rst')
+else:
+ longdesc = None
+
+setup(name='PyQRCode',
+ packages=['pyqrcode'],
+ version=version,
+ description='A QR code generator written purely in Python with SVG, EPS, PNG and terminal output.',
+ author='Michael Nooner',
+ author_email='mnooner256@gmail.com',
+ url='https://github.com/mnooner256/pyqrcode',
+ keywords=['qrcode', 'qr'],
+ license='BSD',
+ extras_require = {
+ 'PNG': ["pypng>=0.0.13"],
+ },
+ classifiers = [
+ 'Development Status :: 4 - Beta',
+ 'Environment :: Console',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: BSD License',
+ 'Topic :: Software Development :: Libraries :: Python Modules',
+ 'Natural Language :: English',
+ 'Operating System :: OS Independent',
+ 'Operating System :: POSIX',
+ 'Operating System :: Microsoft :: Windows',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 2.6',
+ 'Programming Language :: Python :: 2.7',
+ ],
+ long_description=longdesc,
+)
+
+if os.path.exists('docs/README.rst'):
+ os.remove('README.rst')