+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/** \mainpage
+ * Libqrencode is a library for encoding data in a QR Code symbol, a kind of 2D
+ * symbology.
+ *
+ * \section encoding Encoding
+ *
+ * There are two methods to encode data: encoding a string/data or
+ * encoding a structured data.
+ *
+ * \subsection encoding-string Encoding a string/data
+ * You can encode a string by calling QRcode_encodeString().
+ * The given string is parsed automatically and encoded. If you want to encode
+ * data that can be represented as a C string style (NUL terminated), you can
+ * simply use this way.
+ *
+ * If the input data contains Kanji (Shift-JIS) characters and you want to
+ * encode them as Kanji in QR Code, you should give QR_MODE_KANJI as a hint.
+ * Otherwise, all of non-alphanumeric characters are encoded as 8 bit data.
+ * If you want to encode a whole string in 8 bit mode, you can use
+ * QRcode_encodeString8bit() instead.
+ *
+ * Please note that a C string can not contain NUL characters. If your data
+ * contains NUL, you must use QRcode_encodeData().
+ *
+ * \subsection encoding-input Encoding a structured data
+ * You can construct a structured input data manually. If the structure of the
+ * input data is known, you can use this way.
+ * At first, create a ::QRinput object by QRinput_new(). Then add input data
+ * to the QRinput object by QRinput_append(). Finally call QRcode_encodeInput()
+ * to encode the QRinput data.
+ * You can reuse the QRinput data again to encode it in other symbols with
+ * different parameters.
+ *
+ * \section result Result
+ * The encoded symbol is resulted as a ::QRcode object. It will contain
+ * its version number, width of the symbol and an array represents the symbol.
+ * See ::QRcode for the details. You can free the object by QRcode_free().
+ *
+ * Please note that the version of the result may be larger than specified.
+ * In such cases, the input data would be too large to be encoded in a
+ * symbol of the specified version.
+ *
+ * \section structured Structured append
+ * Libqrencode can generate "Structured-appended" symbols that enables to split
+ * a large data set into mulitple QR codes. A QR code reader concatenates
+ * multiple QR code symbols into a string.
+ * Just like QRcode_encodeString(), you can use QRcode_encodeStringStructured()
+ * to generate structured-appended symbols. This functions returns an instance
+ * of ::QRcode_List. The returned list is a singly-linked list of QRcode: you
+ * can retrieve each QR code in this way:
+ *
+ * \code
+ * QRcode_List *qrcodes;
+ * QRcode_List *entry;
+ * QRcode *qrcode;
+ *
+ * qrcodes = QRcode_encodeStringStructured(...);
+ * entry = qrcodes;
+ * while(entry != NULL) {
+ * qrcode = entry->code;
+ * // do something
+ * entry = entry->next;
+ * }
+ * QRcode_List_free(entry);
+ * \endcode
+ *
+ * Instead of using auto-parsing functions, you can construct your own
+ * structured input. At first, instantiate an object of ::QRinput_Struct
+ * by calling QRinput_Struct_new(). This object can hold multiple ::QRinput,
+ * and one QR code is generated for a ::QRinput.
+ * QRinput_Struct_appendInput() appends a ::QRinput to a ::QRinput_Struct
+ * object. In order to generate structured-appended symbols, it is required to
+ * embed headers to each symbol. You can use
+ * QRinput_Struct_insertStructuredAppendHeaders() to insert appropriate
+ * headers to each symbol. You should call this function just once before
+ * encoding symbols.
+ */
+
+#ifndef __QRENCODE_H__
+#define __QRENCODE_H__
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/**
+ * Encoding mode.
+ */
+typedef enum {
+ QR_MODE_NUL = -1, ///< Terminator (NUL character). Internal use only
+ QR_MODE_NUM = 0, ///< Numeric mode
+ QR_MODE_AN, ///< Alphabet-numeric mode
+ QR_MODE_8, ///< 8-bit data mode
+ QR_MODE_KANJI, ///< Kanji (shift-jis) mode
+ QR_MODE_STRUCTURE, ///< Internal use only
+ QR_MODE_ECI, ///< ECI mode
+ QR_MODE_FNC1FIRST, ///< FNC1, first position
+ QR_MODE_FNC1SECOND, ///< FNC1, second position
+} QRencodeMode;
+
+/**
+ * Level of error correction.
+ */
+typedef enum {
+ QR_ECLEVEL_L = 0, ///< lowest
+ QR_ECLEVEL_M,
+ QR_ECLEVEL_Q,
+ QR_ECLEVEL_H ///< highest
+} QRecLevel;
+
+/**
+ * Maximum version (size) of QR-code symbol.
+ */
+#define QRSPEC_VERSION_MAX 40
+
+/**
+ * Maximum version (size) of QR-code symbol.
+ */
+#define MQRSPEC_VERSION_MAX 4
+
+
+/******************************************************************************
+ * Input data (qrinput.c)
+ *****************************************************************************/
+
+/**
+ * Singly linked list to contain input strings. An instance of this class
+ * contains its version and error correction level too. It is required to
+ * set them by QRinput_setVersion() and QRinput_setErrorCorrectionLevel(),
+ * or use QRinput_new2() to instantiate an object.
+ */
+typedef struct _QRinput QRinput;
+
+/**
+ * Instantiate an input data object. The version is set to 0 (auto-select)
+ * and the error correction level is set to QR_ECLEVEL_L.
+ * @return an input object (initialized). On error, NULL is returned and errno
+ * is set to indicate the error.
+ * @throw ENOMEM unable to allocate memory.
+ */
+extern QRinput *QRinput_new(void);
+
+/**
+ * Instantiate an input data object.
+ * @param version version number.
+ * @param level Error correction level.
+ * @return an input object (initialized). On error, NULL is returned and errno
+ * is set to indicate the error.
+ * @throw ENOMEM unable to allocate memory for input objects.
+ * @throw EINVAL invalid arguments.
+ */
+extern QRinput *QRinput_new2(int version, QRecLevel level);
+
+/**
+ * Instantiate an input data object. Object's Micro QR Code flag is set.
+ * Unlike with full-sized QR Code, version number must be specified (>0).
+ * @param version version number (1--4).
+ * @param level Error correction level.
+ * @return an input object (initialized). On error, NULL is returned and errno
+ * is set to indicate the error.
+ * @throw ENOMEM unable to allocate memory for input objects.
+ * @throw EINVAL invalid arguments.
+ */
+extern QRinput *QRinput_newMQR(int version, QRecLevel level);
+
+/**
+ * Append data to an input object.
+ * The data is copied and appended to the input object.
+ * @param input input object.
+ * @param mode encoding mode.
+ * @param size size of data (byte).
+ * @param data a pointer to the memory area of the input data.
+ * @retval 0 success.
+ * @retval -1 an error occurred and errno is set to indeicate the error.
+ * See Execptions for the details.
+ * @throw ENOMEM unable to allocate memory.
+ * @throw EINVAL input data is invalid.
+ *
+ */
+extern int QRinput_append(QRinput *input, QRencodeMode mode, int size, const unsigned char *data);
+
+/**
+ * Append ECI header.
+ * @param input input object.
+ * @param ecinum ECI indicator number (0 - 999999)
+ * @retval 0 success.
+ * @retval -1 an error occurred and errno is set to indeicate the error.
+ * See Execptions for the details.
+ * @throw ENOMEM unable to allocate memory.
+ * @throw EINVAL input data is invalid.
+ *
+ */
+extern int QRinput_appendECIheader(QRinput *input, unsigned int ecinum);
+
+/**
+ * Get current version.
+ * @param input input object.
+ * @return current version.
+ */
+extern int QRinput_getVersion(QRinput *input);
+
+/**
+ * Set version of the QR code that is to be encoded.
+ * This function cannot be applied to Micro QR Code.
+ * @param input input object.
+ * @param version version number (0 = auto)
+ * @retval 0 success.
+ * @retval -1 invalid argument.
+ */
+extern int QRinput_setVersion(QRinput *input, int version);
+
+/**
+ * Get current error correction level.
+ * @param input input object.
+ * @return Current error correcntion level.
+ */
+extern QRecLevel QRinput_getErrorCorrectionLevel(QRinput *input);
+
+/**
+ * Set error correction level of the QR code that is to be encoded.
+ * This function cannot be applied to Micro QR Code.
+ * @param input input object.
+ * @param level Error correction level.
+ * @retval 0 success.
+ * @retval -1 invalid argument.
+ */
+extern int QRinput_setErrorCorrectionLevel(QRinput *input, QRecLevel level);
+
+/**
+ * Set version and error correction level of the QR code at once.
+ * This function is recommened for Micro QR Code.
+ * @param input input object.
+ * @param version version number (0 = auto)
+ * @param level Error correction level.
+ * @retval 0 success.
+ * @retval -1 invalid argument.
+ */
+extern int QRinput_setVersionAndErrorCorrectionLevel(QRinput *input, int version, QRecLevel level);
+
+/**
+ * Free the input object.
+ * All of data chunks in the input object are freed too.
+ * @param input input object.
+ */
+extern void QRinput_free(QRinput *input);
+
+/**
+ * Validate the input data.
+ * @param mode encoding mode.
+ * @param size size of data (byte).
+ * @param data a pointer to the memory area of the input data.
+ * @retval 0 success.
+ * @retval -1 invalid arguments.
+ */
+extern int QRinput_check(QRencodeMode mode, int size, const unsigned char *data);
+
+/**
+ * Set of QRinput for structured symbols.
+ */
+typedef struct _QRinput_Struct QRinput_Struct;
+
+/**
+ * Instantiate a set of input data object.
+ * @return an instance of QRinput_Struct. On error, NULL is returned and errno
+ * is set to indicate the error.
+ * @throw ENOMEM unable to allocate memory.
+ */
+extern QRinput_Struct *QRinput_Struct_new(void);
+
+/**
+ * Set parity of structured symbols.
+ * @param s structured input object.
+ * @param parity parity of s.
+ */
+extern void QRinput_Struct_setParity(QRinput_Struct *s, unsigned char parity);
+
+/**
+ * Append a QRinput object to the set. QRinput created by QRinput_newMQR()
+ * will be rejected.
+ * @warning never append the same QRinput object twice or more.
+ * @param s structured input object.
+ * @param input an input object.
+ * @retval >0 number of input objects in the structure.
+ * @retval -1 an error occurred. See Exceptions for the details.
+ * @throw ENOMEM unable to allocate memory.
+ * @throw EINVAL invalid arguments.
+ */
+extern int QRinput_Struct_appendInput(QRinput_Struct *s, QRinput *input);
+
+/**
+ * Free all of QRinput in the set.
+ * @param s a structured input object.
+ */
+extern void QRinput_Struct_free(QRinput_Struct *s);
+
+/**
+ * Split a QRinput to QRinput_Struct. It calculates a parity, set it, then
+ * insert structured-append headers. QRinput created by QRinput_newMQR() will
+ * be rejected.
+ * @param input input object. Version number and error correction level must be
+ * set.
+ * @return a set of input data. On error, NULL is returned, and errno is set
+ * to indicate the error. See Exceptions for the details.
+ * @throw ERANGE input data is too large.
+ * @throw EINVAL invalid input data.
+ * @throw ENOMEM unable to allocate memory.
+ */
+extern QRinput_Struct *QRinput_splitQRinputToStruct(QRinput *input);
+
+/**
+ * Insert structured-append headers to the input structure. It calculates
+ * a parity and set it if the parity is not set yet.
+ * @param s input structure
+ * @retval 0 success.
+ * @retval -1 an error occurred and errno is set to indeicate the error.
+ * See Execptions for the details.
+ * @throw EINVAL invalid input object.
+ * @throw ENOMEM unable to allocate memory.
+ */
+extern int QRinput_Struct_insertStructuredAppendHeaders(QRinput_Struct *s);
+
+/**
+ * Set FNC1-1st position flag.
+ */
+extern int QRinput_setFNC1First(QRinput *input);
+
+/**
+ * Set FNC1-2nd position flag and application identifier.
+ */
+extern int QRinput_setFNC1Second(QRinput *input, unsigned char appid);
+
+/******************************************************************************
+ * QRcode output (qrencode.c)
+ *****************************************************************************/
+
+/**
+ * QRcode class.
+ * Symbol data is represented as an array contains width*width uchars.
+ * Each uchar represents a module (dot). If the less significant bit of
+ * the uchar is 1, the corresponding module is black. The other bits are
+ * meaningless for usual applications, but here its specification is described.
+ *
+ *
+ * MSB 76543210 LSB
+ * |||||||`- 1=black/0=white
+ * ||||||`-- data and ecc code area
+ * |||||`--- format information
+ * ||||`---- version information
+ * |||`----- timing pattern
+ * ||`------ alignment pattern
+ * |`------- finder pattern and separator
+ * `-------- non-data modules (format, timing, etc.)
+ *
+ */
+typedef struct {
+ int version; ///< version of the symbol
+ int width; ///< width of the symbol
+ unsigned char *data; ///< symbol data
+} QRcode;
+
+/**
+ * Singly-linked list of QRcode. Used to represent a structured symbols.
+ * A list is terminated with NULL.
+ */
+typedef struct _QRcode_List {
+ QRcode *code;
+ struct _QRcode_List *next;
+} QRcode_List;
+
+/**
+ * Create a symbol from the input data.
+ * @warning This function is THREAD UNSAFE when pthread is disabled.
+ * @param input input data.
+ * @return an instance of QRcode class. The version of the result QRcode may
+ * be larger than the designated version. On error, NULL is returned,
+ * and errno is set to indicate the error. See Exceptions for the
+ * details.
+ * @throw EINVAL invalid input object.
+ * @throw ENOMEM unable to allocate memory for input objects.
+ */
+extern QRcode *QRcode_encodeInput(QRinput *input);
+
+/**
+ * Create a symbol from the string. The library automatically parses the input
+ * string and encodes in a QR Code symbol.
+ * @warning This function is THREAD UNSAFE when pthread is disabled.
+ * @param string input string. It must be NUL terminated.
+ * @param version version of the symbol. If 0, the library chooses the minimum
+ * version for the given input data.
+ * @param level error correction level.
+ * @param hint tell the library how Japanese Kanji characters should be
+ * encoded. If QR_MODE_KANJI is given, the library assumes that the
+ * given string contains Shift-JIS characters and encodes them in
+ * Kanji-mode. If QR_MODE_8 is given, all of non-alphanumerical
+ * characters will be encoded as is. If you want to embed UTF-8
+ * string, choose this. Other mode will cause EINVAL error.
+ * @param casesensitive case-sensitive(1) or not(0).
+ * @return an instance of QRcode class. The version of the result QRcode may
+ * be larger than the designated version. On error, NULL is returned,
+ * and errno is set to indicate the error. See Exceptions for the
+ * details.
+ * @throw EINVAL invalid input object.
+ * @throw ENOMEM unable to allocate memory for input objects.
+ * @throw ERANGE input data is too large.
+ */
+extern QRcode *QRcode_encodeString(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
+
+/**
+ * Same to QRcode_encodeString(), but encode whole data in 8-bit mode.
+ * @warning This function is THREAD UNSAFE when pthread is disabled.
+ */
+extern QRcode *QRcode_encodeString8bit(const char *string, int version, QRecLevel level);
+
+/**
+ * Micro QR Code version of QRcode_encodeString().
+ * @warning This function is THREAD UNSAFE when pthread is disabled.
+ */
+extern QRcode *QRcode_encodeStringMQR(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
+
+/**
+ * Micro QR Code version of QRcode_encodeString8bit().
+ * @warning This function is THREAD UNSAFE when pthread is disabled.
+ */
+extern QRcode *QRcode_encodeString8bitMQR(const char *string, int version, QRecLevel level);
+
+/**
+ * Encode byte stream (may include '\0') in 8-bit mode.
+ * @warning This function is THREAD UNSAFE when pthread is disabled.
+ * @param size size of the input data.
+ * @param data input data.
+ * @param version version of the symbol. If 0, the library chooses the minimum
+ * version for the given input data.
+ * @param level error correction level.
+ * @throw EINVAL invalid input object.
+ * @throw ENOMEM unable to allocate memory for input objects.
+ * @throw ERANGE input data is too large.
+ */
+extern QRcode *QRcode_encodeData(int size, const unsigned char *data, int version, QRecLevel level);
+
+/**
+ * Micro QR Code version of QRcode_encodeData().
+ * @warning This function is THREAD UNSAFE when pthread is disabled.
+ */
+extern QRcode *QRcode_encodeDataMQR(int size, const unsigned char *data, int version, QRecLevel level);
+
+/**
+ * Free the instance of QRcode class.
+ * @param qrcode an instance of QRcode class.
+ */
+extern void QRcode_free(QRcode *qrcode);
+
+/**
+ * Create structured symbols from the input data.
+ * @warning This function is THREAD UNSAFE when pthread is disabled.
+ * @param s
+ * @return a singly-linked list of QRcode.
+ */
+extern QRcode_List *QRcode_encodeInputStructured(QRinput_Struct *s);
+
+/**
+ * Create structured symbols from the string. The library automatically parses
+ * the input string and encodes in a QR Code symbol.
+ * @warning This function is THREAD UNSAFE when pthread is disabled.
+ * @param string input string. It must be NUL terminated.
+ * @param version version of the symbol.
+ * @param level error correction level.
+ * @param hint tell the library how Japanese Kanji characters should be
+ * encoded. If QR_MODE_KANJI is given, the library assumes that the
+ * given string contains Shift-JIS characters and encodes them in
+ * Kanji-mode. If QR_MODE_8 is given, all of non-alphanumerical
+ * characters will be encoded as is. If you want to embed UTF-8
+ * string, choose this. Other mode will cause EINVAL error.
+ * @param casesensitive case-sensitive(1) or not(0).
+ * @return a singly-linked list of QRcode. On error, NULL is returned, and
+ * errno is set to indicate the error. See Exceptions for the details.
+ * @throw EINVAL invalid input object.
+ * @throw ENOMEM unable to allocate memory for input objects.
+ */
+extern QRcode_List *QRcode_encodeStringStructured(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
+
+/**
+ * Same to QRcode_encodeStringStructured(), but encode whole data in 8-bit mode.
+ * @warning This function is THREAD UNSAFE when pthread is disabled.
+ */
+extern QRcode_List *QRcode_encodeString8bitStructured(const char *string, int version, QRecLevel level);
+
+/**
+ * Create structured symbols from byte stream (may include '\0'). Wholde data
+ * are encoded in 8-bit mode.
+ * @warning This function is THREAD UNSAFE when pthread is disabled.
+ * @param size size of the input data.
+ * @param data input dat.
+ * @param version version of the symbol.
+ * @param level error correction level.
+ * @return a singly-linked list of QRcode. On error, NULL is returned, and
+ * errno is set to indicate the error. See Exceptions for the details.
+ * @throw EINVAL invalid input object.
+ * @throw ENOMEM unable to allocate memory for input objects.
+ */
+extern QRcode_List *QRcode_encodeDataStructured(int size, const unsigned char *data, int version, QRecLevel level);
+
+/**
+ * Return the number of symbols included in a QRcode_List.
+ * @param qrlist a head entry of a QRcode_List.
+ * @return number of symbols in the list.
+ */
+extern int QRcode_List_size(QRcode_List *qrlist);
+
+/**
+ * Free the QRcode_List.
+ * @param qrlist a head entry of a QRcode_List.
+ */
+extern void QRcode_List_free(QRcode_List *qrlist);
+
+
+/******************************************************************************
+ * System utilities
+ *****************************************************************************/
+
+/**
+ * Return a string that identifies the library version.
+ * @param major_version
+ * @param minor_version
+ * @param micro_version
+ */
+extern void QRcode_APIVersion(int *major_version, int *minor_version, int *micro_version);
+
+/**
+ * Return a string that identifies the library version.
+ * @return a string identifies the library version. The string is held by the
+ * library. Do NOT free it.
+ */
+extern char *QRcode_APIVersionString(void);
+
+/**
+ * Clear all caches. This is only for debug purpose. If you are attacking a
+ * complicated memory leak bug, try this to reduce the reachable blocks record.
+ * @warning This function is THREAD UNSAFE when pthread is disabled.
+ */
+extern void QRcode_clearCache(void);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __QRENCODE_H__ */
diff --git a/src/qqrencode/qrencode/qrencode_inner.h b/src/qqrencode/qrencode/qrencode_inner.h
new file mode 100644
index 0000000..3c40d06
--- /dev/null
+++ b/src/qqrencode/qrencode/qrencode_inner.h
@@ -0,0 +1,88 @@
+/**
+ * qrencode - QR Code encoder
+ *
+ * Header for test use
+ * Copyright (C) 2006-2011 Kentaro Fukuchi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __QRENCODE_INNER_H__
+#define __QRENCODE_INNER_H__
+
+/**
+ * This header file includes definitions for test use.
+ */
+
+/******************************************************************************
+ * Raw code
+ *****************************************************************************/
+
+typedef struct {
+ int dataLength;
+ unsigned char *data;
+ int eccLength;
+ unsigned char *ecc;
+} RSblock;
+
+typedef struct {
+ int version;
+ int dataLength;
+ int eccLength;
+ unsigned char *datacode;
+ unsigned char *ecccode;
+ int b1;
+ int blocks;
+ RSblock *rsblock;
+ int count;
+} QRRawCode;
+
+extern QRRawCode *QRraw_new(QRinput *input);
+extern unsigned char QRraw_getCode(QRRawCode *raw);
+extern void QRraw_free(QRRawCode *raw);
+
+/******************************************************************************
+ * Raw code for Micro QR Code
+ *****************************************************************************/
+
+typedef struct {
+ int version;
+ int dataLength;
+ int eccLength;
+ unsigned char *datacode;
+ unsigned char *ecccode;
+ RSblock *rsblock;
+ int oddbits;
+ int count;
+} MQRRawCode;
+
+extern MQRRawCode *MQRraw_new(QRinput *input);
+extern unsigned char MQRraw_getCode(MQRRawCode *raw);
+extern void MQRraw_free(MQRRawCode *raw);
+
+/******************************************************************************
+ * Frame filling
+ *****************************************************************************/
+extern unsigned char *FrameFiller_test(int version);
+extern unsigned char *FrameFiller_testMQR(int version);
+
+/******************************************************************************
+ * QR-code encoding
+ *****************************************************************************/
+extern QRcode *QRcode_encodeMask(QRinput *input, int mask);
+extern QRcode *QRcode_encodeMaskMQR(QRinput *input, int mask);
+extern QRcode *QRcode_new(int version, int width, unsigned char *data);
+
+#endif /* __QRENCODE_INNER_H__ */
diff --git a/src/qqrencode/qrencode/qrinput.c b/src/qqrencode/qrencode/qrinput.c
new file mode 100644
index 0000000..64ce5df
--- /dev/null
+++ b/src/qqrencode/qrencode/qrinput.c
@@ -0,0 +1,1729 @@
+/*
+ * qrencode - QR Code encoder
+ *
+ * Input data chunk class
+ * Copyright (C) 2006-2011 Kentaro Fukuchi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include
+#include
+#include
+#include
+
+#include "qrencode.h"
+#include "qrspec.h"
+#include "mqrspec.h"
+#include "bitstream.h"
+#include "qrinput.h"
+
+/******************************************************************************
+ * Utilities
+ *****************************************************************************/
+int QRinput_isSplittableMode(QRencodeMode mode)
+{
+ return (mode >= QR_MODE_NUM && mode <= QR_MODE_KANJI);
+}
+
+/******************************************************************************
+ * Entry of input data
+ *****************************************************************************/
+
+static QRinput_List *QRinput_List_newEntry(QRencodeMode mode, int size, const unsigned char *data)
+{
+ QRinput_List *entry;
+
+ if(QRinput_check(mode, size, data)) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ entry = (QRinput_List *)malloc(sizeof(QRinput_List));
+ if(entry == NULL) return NULL;
+
+ entry->mode = mode;
+ entry->size = size;
+ if(size > 0) {
+ entry->data = (unsigned char *)malloc(size);
+ if(entry->data == NULL) {
+ free(entry);
+ return NULL;
+ }
+ memcpy(entry->data, data, size);
+ }
+ entry->bstream = NULL;
+ entry->next = NULL;
+
+ return entry;
+}
+
+static void QRinput_List_freeEntry(QRinput_List *entry)
+{
+ if(entry != NULL) {
+ free(entry->data);
+ BitStream_free(entry->bstream);
+ free(entry);
+ }
+}
+
+static QRinput_List *QRinput_List_dup(QRinput_List *entry)
+{
+ QRinput_List *n;
+
+ n = (QRinput_List *)malloc(sizeof(QRinput_List));
+ if(n == NULL) return NULL;
+
+ n->mode = entry->mode;
+ n->size = entry->size;
+ n->data = (unsigned char *)malloc(n->size);
+ if(n->data == NULL) {
+ free(n);
+ return NULL;
+ }
+ memcpy(n->data, entry->data, entry->size);
+ n->bstream = NULL;
+ n->next = NULL;
+
+ return n;
+}
+
+/******************************************************************************
+ * Input Data
+ *****************************************************************************/
+
+QRinput *QRinput_new(void)
+{
+ return QRinput_new2(0, QR_ECLEVEL_L);
+}
+
+QRinput *QRinput_new2(int version, QRecLevel level)
+{
+ QRinput *input;
+
+ if(version < 0 || version > QRSPEC_VERSION_MAX || level > QR_ECLEVEL_H) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ input = (QRinput *)malloc(sizeof(QRinput));
+ if(input == NULL) return NULL;
+
+ input->head = NULL;
+ input->tail = NULL;
+ input->version = version;
+ input->level = level;
+ input->mqr = 0;
+ input->fnc1 = 0;
+
+ return input;
+}
+
+QRinput *QRinput_newMQR(int version, QRecLevel level)
+{
+ QRinput *input;
+
+ if(version <= 0 || version > MQRSPEC_VERSION_MAX) goto INVALID;
+ if((MQRspec_getECCLength(version, level) == 0)) goto INVALID;
+
+ input = QRinput_new2(version, level);
+ if(input == NULL) return NULL;
+
+ input->mqr = 1;
+
+ return input;
+
+INVALID:
+ errno = EINVAL;
+ return NULL;
+}
+
+int QRinput_getVersion(QRinput *input)
+{
+ return input->version;
+}
+
+int QRinput_setVersion(QRinput *input, int version)
+{
+ if(input->mqr || version < 0 || version > QRSPEC_VERSION_MAX) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ input->version = version;
+
+ return 0;
+}
+
+QRecLevel QRinput_getErrorCorrectionLevel(QRinput *input)
+{
+ return input->level;
+}
+
+int QRinput_setErrorCorrectionLevel(QRinput *input, QRecLevel level)
+{
+ if(input->mqr || level > QR_ECLEVEL_H) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ input->level = level;
+
+ return 0;
+}
+
+int QRinput_setVersionAndErrorCorrectionLevel(QRinput *input, int version, QRecLevel level)
+{
+ if(input->mqr) {
+ if(version <= 0 || version > MQRSPEC_VERSION_MAX) goto INVALID;
+ if((MQRspec_getECCLength(version, level) == 0)) goto INVALID;
+ } else {
+ if(version < 0 || version > QRSPEC_VERSION_MAX) goto INVALID;
+ if(level > QR_ECLEVEL_H) goto INVALID;
+ }
+
+ input->version = version;
+ input->level = level;
+
+ return 0;
+
+INVALID:
+ errno = EINVAL;
+ return -1;
+}
+
+static void QRinput_appendEntry(QRinput *input, QRinput_List *entry)
+{
+ if(input->tail == NULL) {
+ input->head = entry;
+ input->tail = entry;
+ } else {
+ input->tail->next = entry;
+ input->tail = entry;
+ }
+ entry->next = NULL;
+}
+
+int QRinput_append(QRinput *input, QRencodeMode mode, int size, const unsigned char *data)
+{
+ QRinput_List *entry;
+
+ entry = QRinput_List_newEntry(mode, size, data);
+ if(entry == NULL) {
+ return -1;
+ }
+
+ QRinput_appendEntry(input, entry);
+
+ return 0;
+}
+
+/**
+ * Insert a structured-append header to the head of the input data.
+ * @param input input data.
+ * @param size number of structured symbols.
+ * @param number index number of the symbol. (1 <= number <= size)
+ * @param parity parity among input data. (NOTE: each symbol of a set of structured symbols has the same parity data)
+ * @retval 0 success.
+ * @retval -1 error occurred and errno is set to indeicate the error. See Execptions for the details.
+ * @throw EINVAL invalid parameter.
+ * @throw ENOMEM unable to allocate memory.
+ */
+static int QRinput_insertStructuredAppendHeader(QRinput *input, int size, int number, unsigned char parity)
+{
+ QRinput_List *entry;
+ unsigned char buf[3];
+
+ if(size > MAX_STRUCTURED_SYMBOLS) {
+ errno = EINVAL;
+ return -1;
+ }
+ if(number <= 0 || number > size) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ buf[0] = (unsigned char)size;
+ buf[1] = (unsigned char)number;
+ buf[2] = parity;
+ entry = QRinput_List_newEntry(QR_MODE_STRUCTURE, 3, buf);
+ if(entry == NULL) {
+ return -1;
+ }
+
+ entry->next = input->head;
+ input->head = entry;
+
+ return 0;
+}
+
+int QRinput_appendECIheader(QRinput *input, unsigned int ecinum)
+{
+ unsigned char data[4];
+
+ if(ecinum > 999999) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* We manually create byte array of ecinum because
+ (unsigned char *)&ecinum may cause bus error on some architectures, */
+ data[0] = ecinum & 0xff;
+ data[1] = (ecinum >> 8) & 0xff;
+ data[2] = (ecinum >> 16) & 0xff;
+ data[3] = (ecinum >> 24) & 0xff;
+ return QRinput_append(input, QR_MODE_ECI, 4, data);
+}
+
+void QRinput_free(QRinput *input)
+{
+ QRinput_List *list, *next;
+
+ if(input != NULL) {
+ list = input->head;
+ while(list != NULL) {
+ next = list->next;
+ QRinput_List_freeEntry(list);
+ list = next;
+ }
+ free(input);
+ }
+}
+
+static unsigned char QRinput_calcParity(QRinput *input)
+{
+ unsigned char parity = 0;
+ QRinput_List *list;
+ int i;
+
+ list = input->head;
+ while(list != NULL) {
+ if(list->mode != QR_MODE_STRUCTURE) {
+ for(i=list->size-1; i>=0; i--) {
+ parity ^= list->data[i];
+ }
+ }
+ list = list->next;
+ }
+
+ return parity;
+}
+
+QRinput *QRinput_dup(QRinput *input)
+{
+ QRinput *n;
+ QRinput_List *list, *e;
+
+ if(input->mqr) {
+ n = QRinput_newMQR(input->version, input->level);
+ } else {
+ n = QRinput_new2(input->version, input->level);
+ }
+ if(n == NULL) return NULL;
+
+ list = input->head;
+ while(list != NULL) {
+ e = QRinput_List_dup(list);
+ if(e == NULL) {
+ QRinput_free(n);
+ return NULL;
+ }
+ QRinput_appendEntry(n, e);
+ list = list->next;
+ }
+
+ return n;
+}
+
+/******************************************************************************
+ * Numeric data
+ *****************************************************************************/
+
+/**
+ * Check the input data.
+ * @param size
+ * @param data
+ * @return result
+ */
+static int QRinput_checkModeNum(int size, const char *data)
+{
+ int i;
+
+ for(i=0; i '9')
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * Estimates the length of the encoded bit stream of numeric data.
+ * @param size
+ * @return number of bits
+ */
+int QRinput_estimateBitsModeNum(int size)
+{
+ int w;
+ int bits;
+
+ w = size / 3;
+ bits = w * 10;
+ switch(size - w * 3) {
+ case 1:
+ bits += 4;
+ break;
+ case 2:
+ bits += 7;
+ break;
+ default:
+ break;
+ }
+
+ return bits;
+}
+
+/**
+ * Convert the number data to a bit stream.
+ * @param entry
+ * @param mqr
+ * @retval 0 success
+ * @retval -1 an error occurred and errno is set to indeicate the error.
+ * See Execptions for the details.
+ * @throw ENOMEM unable to allocate memory.
+ */
+static int QRinput_encodeModeNum(QRinput_List *entry, int version, int mqr)
+{
+ int words, i, ret;
+ unsigned int val;
+
+ entry->bstream = BitStream_new();
+ if(entry->bstream == NULL) return -1;
+
+ if(mqr) {
+ if(version > 1) {
+ ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_NUM);
+ if(ret < 0) goto ABORT;
+ }
+ ret = BitStream_appendNum(entry->bstream, MQRspec_lengthIndicator(QR_MODE_NUM, version), entry->size);
+ if(ret < 0) goto ABORT;
+ } else {
+ ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_NUM);
+ if(ret < 0) goto ABORT;
+
+ ret = BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_NUM, version), entry->size);
+ if(ret < 0) goto ABORT;
+ }
+
+ words = entry->size / 3;
+ for(i=0; idata[i*3 ] - '0') * 100;
+ val += (entry->data[i*3+1] - '0') * 10;
+ val += (entry->data[i*3+2] - '0');
+
+ ret = BitStream_appendNum(entry->bstream, 10, val);
+ if(ret < 0) goto ABORT;
+ }
+
+ if(entry->size - words * 3 == 1) {
+ val = entry->data[words*3] - '0';
+ ret = BitStream_appendNum(entry->bstream, 4, val);
+ if(ret < 0) goto ABORT;
+ } else if(entry->size - words * 3 == 2) {
+ val = (entry->data[words*3 ] - '0') * 10;
+ val += (entry->data[words*3+1] - '0');
+ BitStream_appendNum(entry->bstream, 7, val);
+ if(ret < 0) goto ABORT;
+ }
+
+ return 0;
+ABORT:
+ BitStream_free(entry->bstream);
+ entry->bstream = NULL;
+ return -1;
+}
+
+/******************************************************************************
+ * Alphabet-numeric data
+ *****************************************************************************/
+
+const signed char QRinput_anTable[128] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1,
+ -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+};
+
+/**
+ * Check the input data.
+ * @param size
+ * @param data
+ * @return result
+ */
+static int QRinput_checkModeAn(int size, const char *data)
+{
+ int i;
+
+ for(i=0; ibstream = BitStream_new();
+ if(entry->bstream == NULL) return -1;
+
+ if(mqr) {
+ if(version < 2) {
+ errno = EINVAL;
+ goto ABORT;
+ }
+ ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_AN);
+ if(ret < 0) goto ABORT;
+ ret = BitStream_appendNum(entry->bstream, MQRspec_lengthIndicator(QR_MODE_AN, version), entry->size);
+ if(ret < 0) goto ABORT;
+ } else {
+ ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_AN);
+ if(ret < 0) goto ABORT;
+ ret = BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_AN, version), entry->size);
+ if(ret < 0) goto ABORT;
+ }
+
+ words = entry->size / 2;
+ for(i=0; idata[i*2 ]) * 45;
+ val += (unsigned int)QRinput_lookAnTable(entry->data[i*2+1]);
+
+ ret = BitStream_appendNum(entry->bstream, 11, val);
+ if(ret < 0) goto ABORT;
+ }
+
+ if(entry->size & 1) {
+ val = (unsigned int)QRinput_lookAnTable(entry->data[words * 2]);
+
+ ret = BitStream_appendNum(entry->bstream, 6, val);
+ if(ret < 0) goto ABORT;
+ }
+
+ return 0;
+ABORT:
+ BitStream_free(entry->bstream);
+ entry->bstream = NULL;
+ return -1;
+}
+
+/******************************************************************************
+ * 8 bit data
+ *****************************************************************************/
+
+/**
+ * Estimates the length of the encoded bit stream of 8 bit data.
+ * @param size
+ * @return number of bits
+ */
+int QRinput_estimateBitsMode8(int size)
+{
+ return size * 8;
+}
+
+/**
+ * Convert the 8bits data to a bit stream.
+ * @param entry
+ * @param mqr
+ * @retval 0 success
+ * @retval -1 an error occurred and errno is set to indeicate the error.
+ * See Execptions for the details.
+ * @throw ENOMEM unable to allocate memory.
+ */
+static int QRinput_encodeMode8(QRinput_List *entry, int version, int mqr)
+{
+ int ret;
+
+ entry->bstream = BitStream_new();
+ if(entry->bstream == NULL) return -1;
+
+ if(mqr) {
+ if(version < 3) {
+ errno = EINVAL;
+ goto ABORT;
+ }
+ ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_8);
+ if(ret < 0) goto ABORT;
+ ret = BitStream_appendNum(entry->bstream, MQRspec_lengthIndicator(QR_MODE_8, version), entry->size);
+ if(ret < 0) goto ABORT;
+ } else {
+ ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_8);
+ if(ret < 0) goto ABORT;
+ ret = BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_8, version), entry->size);
+ if(ret < 0) goto ABORT;
+ }
+
+ ret = BitStream_appendBytes(entry->bstream, entry->size, entry->data);
+ if(ret < 0) goto ABORT;
+
+ return 0;
+ABORT:
+ BitStream_free(entry->bstream);
+ entry->bstream = NULL;
+ return -1;
+}
+
+
+/******************************************************************************
+ * Kanji data
+ *****************************************************************************/
+
+/**
+ * Estimates the length of the encoded bit stream of kanji data.
+ * @param size
+ * @return number of bits
+ */
+int QRinput_estimateBitsModeKanji(int size)
+{
+ return (size / 2) * 13;
+}
+
+/**
+ * Check the input data.
+ * @param size
+ * @param data
+ * @return result
+ */
+static int QRinput_checkModeKanji(int size, const unsigned char *data)
+{
+ int i;
+ unsigned int val;
+
+ if(size & 1)
+ return -1;
+
+ for(i=0; i 0x9ffc && val < 0xe040) || val > 0xebbf) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Convert the kanji data to a bit stream.
+ * @param entry
+ * @param mqr
+ * @retval 0 success
+ * @retval -1 an error occurred and errno is set to indeicate the error.
+ * See Execptions for the details.
+ * @throw ENOMEM unable to allocate memory.
+ * @throw EINVAL invalid version.
+ */
+static int QRinput_encodeModeKanji(QRinput_List *entry, int version, int mqr)
+{
+ int ret, i;
+ unsigned int val, h;
+
+ entry->bstream = BitStream_new();
+ if(entry->bstream == NULL) return -1;
+
+ if(mqr) {
+ if(version < 2) {
+ errno = EINVAL;
+ goto ABORT;
+ }
+ ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_KANJI);
+ if(ret < 0) goto ABORT;
+ ret = BitStream_appendNum(entry->bstream, MQRspec_lengthIndicator(QR_MODE_KANJI, version), entry->size/2);
+ if(ret < 0) goto ABORT;
+ } else {
+ ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_KANJI);
+ if(ret < 0) goto ABORT;
+ ret = BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_KANJI, version), entry->size/2);
+ if(ret < 0) goto ABORT;
+ }
+
+ for(i=0; isize; i+=2) {
+ val = ((unsigned int)entry->data[i] << 8) | entry->data[i+1];
+ if(val <= 0x9ffc) {
+ val -= 0x8140;
+ } else {
+ val -= 0xc140;
+ }
+ h = (val >> 8) * 0xc0;
+ val = (val & 0xff) + h;
+
+ ret = BitStream_appendNum(entry->bstream, 13, val);
+ if(ret < 0) goto ABORT;
+ }
+
+ return 0;
+ABORT:
+ BitStream_free(entry->bstream);
+ entry->bstream = NULL;
+ return -1;
+}
+
+/******************************************************************************
+ * Structured Symbol
+ *****************************************************************************/
+
+/**
+ * Convert a structure symbol code to a bit stream.
+ * @param entry
+ * @param mqr
+ * @retval 0 success
+ * @retval -1 an error occurred and errno is set to indeicate the error.
+ * See Execptions for the details.
+ * @throw ENOMEM unable to allocate memory.
+ * @throw EINVAL invalid entry.
+ */
+static int QRinput_encodeModeStructure(QRinput_List *entry, int mqr)
+{
+ int ret;
+
+ if(mqr) {
+ errno = EINVAL;
+ return -1;
+ }
+ entry->bstream = BitStream_new();
+ if(entry->bstream == NULL) return -1;
+
+ ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_STRUCTURE);
+ if(ret < 0) goto ABORT;
+ ret = BitStream_appendNum(entry->bstream, 4, entry->data[1] - 1);
+ if(ret < 0) goto ABORT;
+ ret = BitStream_appendNum(entry->bstream, 4, entry->data[0] - 1);
+ if(ret < 0) goto ABORT;
+ ret = BitStream_appendNum(entry->bstream, 8, entry->data[2]);
+ if(ret < 0) goto ABORT;
+
+ return 0;
+ABORT:
+ BitStream_free(entry->bstream);
+ entry->bstream = NULL;
+ return -1;
+}
+
+/******************************************************************************
+ * FNC1
+ *****************************************************************************/
+
+static int QRinput_checkModeFNC1Second(int size, const unsigned char *data)
+{
+ if(size != 1) return -1;
+
+ return 0;
+}
+
+static int QRinput_encodeModeFNC1Second(QRinput_List *entry, int version)
+{
+ int ret;
+
+ entry->bstream = BitStream_new();
+ if(entry->bstream == NULL) return -1;
+
+ ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_FNC1SECOND);
+ if(ret < 0) goto ABORT;
+
+ ret = BitStream_appendBytes(entry->bstream, 1, entry->data);
+ if(ret < 0) goto ABORT;
+
+ return 0;
+ABORT:
+ BitStream_free(entry->bstream);
+ entry->bstream = NULL;
+ return -1;
+}
+
+/******************************************************************************
+ * ECI header
+ *****************************************************************************/
+static unsigned int QRinput_decodeECIfromByteArray(unsigned char *data)
+{
+ int i;
+ unsigned int ecinum;
+
+ ecinum = 0;
+ for(i=0; i<4; i++) {
+ ecinum = ecinum << 8;
+ ecinum |= data[3-i];
+ }
+
+ return ecinum;
+}
+
+int QRinput_estimateBitsModeECI(unsigned char *data)
+{
+ unsigned int ecinum;
+
+ ecinum = QRinput_decodeECIfromByteArray(data);;
+
+ /* See Table 4 of JISX 0510:2004 pp.17. */
+ if(ecinum < 128) {
+ return MODE_INDICATOR_SIZE + 8;
+ } else if(ecinum < 16384) {
+ return MODE_INDICATOR_SIZE + 16;
+ } else {
+ return MODE_INDICATOR_SIZE + 24;
+ }
+}
+
+static int QRinput_encodeModeECI(QRinput_List *entry, int version)
+{
+ int ret, words;
+ unsigned int ecinum, code;
+
+ entry->bstream = BitStream_new();
+ if(entry->bstream == NULL) return -1;
+
+ ecinum = QRinput_decodeECIfromByteArray(entry->data);;
+
+ /* See Table 4 of JISX 0510:2004 pp.17. */
+ if(ecinum < 128) {
+ words = 1;
+ code = ecinum;
+ } else if(ecinum < 16384) {
+ words = 2;
+ code = 0x8000 + ecinum;
+ } else {
+ words = 3;
+ code = 0xc0000 + ecinum;
+ }
+
+ ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_ECI);
+ if(ret < 0) goto ABORT;
+
+ ret = BitStream_appendNum(entry->bstream, words * 8, code);
+ if(ret < 0) goto ABORT;
+
+ return 0;
+ABORT:
+ BitStream_free(entry->bstream);
+ entry->bstream = NULL;
+ return -1;
+}
+
+/******************************************************************************
+ * Validation
+ *****************************************************************************/
+
+int QRinput_check(QRencodeMode mode, int size, const unsigned char *data)
+{
+ if((mode == QR_MODE_FNC1FIRST && size < 0) || size <= 0) return -1;
+
+ switch(mode) {
+ case QR_MODE_NUM:
+ return QRinput_checkModeNum(size, (const char *)data);
+ case QR_MODE_AN:
+ return QRinput_checkModeAn(size, (const char *)data);
+ case QR_MODE_KANJI:
+ return QRinput_checkModeKanji(size, data);
+ case QR_MODE_8:
+ return 0;
+ case QR_MODE_STRUCTURE:
+ return 0;
+ case QR_MODE_ECI:
+ return 0;
+ case QR_MODE_FNC1FIRST:
+ return 0;
+ case QR_MODE_FNC1SECOND:
+ return QRinput_checkModeFNC1Second(size, data);
+ case QR_MODE_NUL:
+ break;
+ }
+
+ return -1;
+}
+
+/******************************************************************************
+ * Estimation of the bit length
+ *****************************************************************************/
+
+/**
+ * Estimates the length of the encoded bit stream on the current version.
+ * @param entry
+ * @param version version of the symbol
+ * @param mqr
+ * @return number of bits
+ */
+static int QRinput_estimateBitStreamSizeOfEntry(QRinput_List *entry, int version, int mqr)
+{
+ int bits = 0;
+ int l, m;
+ int num;
+
+ if(version == 0) version = 1;
+
+ switch(entry->mode) {
+ case QR_MODE_NUM:
+ bits = QRinput_estimateBitsModeNum(entry->size);
+ break;
+ case QR_MODE_AN:
+ bits = QRinput_estimateBitsModeAn(entry->size);
+ break;
+ case QR_MODE_8:
+ bits = QRinput_estimateBitsMode8(entry->size);
+ break;
+ case QR_MODE_KANJI:
+ bits = QRinput_estimateBitsModeKanji(entry->size);
+ break;
+ case QR_MODE_STRUCTURE:
+ return STRUCTURE_HEADER_SIZE;
+ case QR_MODE_ECI:
+ bits = QRinput_estimateBitsModeECI(entry->data);
+ break;
+ case QR_MODE_FNC1FIRST:
+ return MODE_INDICATOR_SIZE;
+ case QR_MODE_FNC1SECOND:
+ return MODE_INDICATOR_SIZE + 8;
+ default:
+ return 0;
+ }
+
+ if(mqr) {
+ l = QRspec_lengthIndicator(entry->mode, version);
+ m = version - 1;
+ bits += l + m;
+ } else {
+ l = QRspec_lengthIndicator(entry->mode, version);
+ m = 1 << l;
+ num = (entry->size + m - 1) / m;
+
+ bits += num * (MODE_INDICATOR_SIZE + l);
+ }
+
+ return bits;
+}
+
+/**
+ * Estimates the length of the encoded bit stream of the data.
+ * @param input input data
+ * @param version version of the symbol
+ * @return number of bits
+ */
+static int QRinput_estimateBitStreamSize(QRinput *input, int version)
+{
+ QRinput_List *list;
+ int bits = 0;
+
+ list = input->head;
+ while(list != NULL) {
+ bits += QRinput_estimateBitStreamSizeOfEntry(list, version, input->mqr);
+ list = list->next;
+ }
+
+ return bits;
+}
+
+/**
+ * Estimates the required version number of the symbol.
+ * @param input input data
+ * @return required version number
+ */
+static int QRinput_estimateVersion(QRinput *input)
+{
+ int bits;
+ int version, prev;
+
+ version = 0;
+ do {
+ prev = version;
+ bits = QRinput_estimateBitStreamSize(input, prev);
+ version = QRspec_getMinimumVersion((bits + 7) / 8, input->level);
+ if (version < 0) {
+ return -1;
+ }
+ } while (version > prev);
+
+ return version;
+}
+
+/**
+ * Returns required length in bytes for specified mode, version and bits.
+ * @param mode
+ * @param version
+ * @param bits
+ * @return required length of code words in bytes.
+ */
+static int QRinput_lengthOfCode(QRencodeMode mode, int version, int bits)
+{
+ int payload, size, chunks, remain, maxsize;
+
+ payload = bits - 4 - QRspec_lengthIndicator(mode, version);
+ switch(mode) {
+ case QR_MODE_NUM:
+ chunks = payload / 10;
+ remain = payload - chunks * 10;
+ size = chunks * 3;
+ if(remain >= 7) {
+ size += 2;
+ } else if(remain >= 4) {
+ size += 1;
+ }
+ break;
+ case QR_MODE_AN:
+ chunks = payload / 11;
+ remain = payload - chunks * 11;
+ size = chunks * 2;
+ if(remain >= 6) size++;
+ break;
+ case QR_MODE_8:
+ size = payload / 8;
+ break;
+ case QR_MODE_KANJI:
+ size = (payload / 13) * 2;
+ break;
+ case QR_MODE_STRUCTURE:
+ size = payload / 8;
+ break;
+ default:
+ size = 0;
+ break;
+ }
+ maxsize = QRspec_maximumWords(mode, version);
+ if(size < 0) size = 0;
+ if(maxsize > 0 && size > maxsize) size = maxsize;
+
+ return size;
+}
+
+/******************************************************************************
+ * Data conversion
+ *****************************************************************************/
+
+/**
+ * Convert the input data in the data chunk to a bit stream.
+ * @param entry
+ * @return number of bits (>0) or -1 for failure.
+ */
+static int QRinput_encodeBitStream(QRinput_List *entry, int version, int mqr)
+{
+ int words, ret;
+ QRinput_List *st1 = NULL, *st2 = NULL;
+
+ if(entry->bstream != NULL) {
+ BitStream_free(entry->bstream);
+ entry->bstream = NULL;
+ }
+
+ words = QRspec_maximumWords(entry->mode, version);
+ if(words != 0 && entry->size > words) {
+ st1 = QRinput_List_newEntry(entry->mode, words, entry->data);
+ if(st1 == NULL) goto ABORT;
+ st2 = QRinput_List_newEntry(entry->mode, entry->size - words, &entry->data[words]);
+ if(st2 == NULL) goto ABORT;
+
+ ret = QRinput_encodeBitStream(st1, version, mqr);
+ if(ret < 0) goto ABORT;
+ ret = QRinput_encodeBitStream(st2, version, mqr);
+ if(ret < 0) goto ABORT;
+ entry->bstream = BitStream_new();
+ if(entry->bstream == NULL) goto ABORT;
+ ret = BitStream_append(entry->bstream, st1->bstream);
+ if(ret < 0) goto ABORT;
+ ret = BitStream_append(entry->bstream, st2->bstream);
+ if(ret < 0) goto ABORT;
+ QRinput_List_freeEntry(st1);
+ QRinput_List_freeEntry(st2);
+ } else {
+ ret = 0;
+ switch(entry->mode) {
+ case QR_MODE_NUM:
+ ret = QRinput_encodeModeNum(entry, version, mqr);
+ break;
+ case QR_MODE_AN:
+ ret = QRinput_encodeModeAn(entry, version, mqr);
+ break;
+ case QR_MODE_8:
+ ret = QRinput_encodeMode8(entry, version, mqr);
+ break;
+ case QR_MODE_KANJI:
+ ret = QRinput_encodeModeKanji(entry, version, mqr);
+ break;
+ case QR_MODE_STRUCTURE:
+ ret = QRinput_encodeModeStructure(entry, mqr);
+ break;
+ case QR_MODE_ECI:
+ ret = QRinput_encodeModeECI(entry, version);
+ break;
+ case QR_MODE_FNC1SECOND:
+ ret = QRinput_encodeModeFNC1Second(entry, version);
+ break;
+ default:
+ break;
+ }
+ if(ret < 0) return -1;
+ }
+
+ return BitStream_size(entry->bstream);
+ABORT:
+ QRinput_List_freeEntry(st1);
+ QRinput_List_freeEntry(st2);
+ return -1;
+}
+
+/**
+ * Convert the input data to a bit stream.
+ * @param input input data.
+ * @retval 0 success
+ * @retval -1 an error occurred and errno is set to indeicate the error.
+ * See Execptions for the details.
+ * @throw ENOMEM unable to allocate memory.
+ */
+static int QRinput_createBitStream(QRinput *input)
+{
+ QRinput_List *list;
+ int bits, total = 0;
+
+ list = input->head;
+ while(list != NULL) {
+ bits = QRinput_encodeBitStream(list, input->version, input->mqr);
+ if(bits < 0) return -1;
+ total += bits;
+ list = list->next;
+ }
+
+ return total;
+}
+
+/**
+ * Convert the input data to a bit stream.
+ * When the version number is given and that is not sufficient, it is increased
+ * automatically.
+ * @param input input data.
+ * @retval 0 success
+ * @retval -1 an error occurred and errno is set to indeicate the error.
+ * See Execptions for the details.
+ * @throw ENOMEM unable to allocate memory.
+ * @throw ERANGE input is too large.
+ */
+static int QRinput_convertData(QRinput *input)
+{
+ int bits;
+ int ver;
+
+ ver = QRinput_estimateVersion(input);
+ if(ver > QRinput_getVersion(input)) {
+ QRinput_setVersion(input, ver);
+ }
+
+ for(;;) {
+ bits = QRinput_createBitStream(input);
+ if(bits < 0) return -1;
+ ver = QRspec_getMinimumVersion((bits + 7) / 8, input->level);
+ if(ver < 0) {
+ errno = ERANGE;
+ return -1;
+ } else if(ver > QRinput_getVersion(input)) {
+ QRinput_setVersion(input, ver);
+ } else {
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Append padding bits for the input data.
+ * @param bstream Bitstream to be appended.
+ * @param input input data.
+ * @retval 0 success
+ * @retval -1 an error occurred and errno is set to indeicate the error.
+ * See Execptions for the details.
+ * @throw ERANGE input data is too large.
+ * @throw ENOMEM unable to allocate memory.
+ */
+static int QRinput_appendPaddingBit(BitStream *bstream, QRinput *input)
+{
+ int bits, maxbits, words, maxwords, i, ret;
+ BitStream *padding = NULL;
+ unsigned char *padbuf;
+ int padlen;
+
+ bits = BitStream_size(bstream);
+ maxwords = QRspec_getDataLength(input->version, input->level);
+ maxbits = maxwords * 8;
+
+ if(maxbits < bits) {
+ errno = ERANGE;
+ return -1;
+ }
+ if(maxbits == bits) {
+ return 0;
+ }
+
+ if(maxbits - bits <= 4) {
+ ret = BitStream_appendNum(bstream, maxbits - bits, 0);
+ goto DONE;
+ }
+
+ words = (bits + 4 + 7) / 8;
+
+ padding = BitStream_new();
+ if(padding == NULL) return -1;
+ ret = BitStream_appendNum(padding, words * 8 - bits, 0);
+ if(ret < 0) goto DONE;
+
+ padlen = maxwords - words;
+ if(padlen > 0) {
+ padbuf = (unsigned char *)malloc(padlen);
+ if(padbuf == NULL) {
+ ret = -1;
+ goto DONE;
+ }
+ for(i=0; iversion, input->level);
+ maxwords = maxbits / 8;
+
+ if(maxbits < bits) {
+ errno = ERANGE;
+ return -1;
+ }
+ if(maxbits == bits) {
+ return 0;
+ }
+
+ termbits = input->version * 2 + 1;
+
+ if(maxbits - bits <= termbits) {
+ ret = BitStream_appendNum(bstream, maxbits - bits, 0);
+ goto DONE;
+ }
+
+ bits += termbits;
+
+ words = (bits + 7) / 8;
+ if(maxbits - words * 8 > 0) {
+ termbits += words * 8 - bits;
+ if(words == maxwords) termbits += maxbits - words * 8;
+ } else {
+ termbits += words * 8 - bits;
+ }
+ padding = BitStream_new();
+ if(padding == NULL) return -1;
+ ret = BitStream_appendNum(padding, termbits, 0);
+ if(ret < 0) goto DONE;
+
+ padlen = maxwords - words;
+ if(padlen > 0) {
+ padbuf = (unsigned char *)malloc(padlen);
+ if(padbuf == NULL) {
+ ret = -1;
+ goto DONE;
+ }
+ for(i=0; i 0) {
+ ret = BitStream_appendNum(padding, termbits, 0);
+ if(ret < 0) goto DONE;
+ }
+ }
+
+ ret = BitStream_append(bstream, padding);
+
+DONE:
+ BitStream_free(padding);
+ return ret;
+}
+
+static int QRinput_insertFNC1Header(QRinput *input)
+{
+ QRinput_List *entry = NULL;
+
+ if(input->fnc1 == 1) {
+ entry = QRinput_List_newEntry(QR_MODE_FNC1FIRST, 0, NULL);
+ } else if(input->fnc1 == 2) {
+ entry = QRinput_List_newEntry(QR_MODE_FNC1SECOND, 1, &(input->appid));
+ }
+ if(entry == NULL) {
+ return -1;
+ }
+
+ if(input->head->mode != QR_MODE_STRUCTURE || input->head->mode != QR_MODE_ECI) {
+ entry->next = input->head;
+ input->head = entry;
+ } else {
+ entry->next = input->head->next;
+ input->head->next = entry;
+ }
+
+ return 0;
+}
+
+/**
+ * Merge all bit streams in the input data.
+ * @param input input data.
+ * @return merged bit stream
+ */
+
+static BitStream *QRinput_mergeBitStream(QRinput *input)
+{
+ BitStream *bstream;
+ QRinput_List *list;
+ int ret;
+
+ if(input->mqr) {
+ if(QRinput_createBitStream(input) < 0) {
+ return NULL;
+ }
+ } else {
+ if(input->fnc1) {
+ if(QRinput_insertFNC1Header(input) < 0) {
+ return NULL;
+ }
+ }
+ if(QRinput_convertData(input) < 0) {
+ return NULL;
+ }
+ }
+
+ bstream = BitStream_new();
+ if(bstream == NULL) return NULL;
+
+ list = input->head;
+ while(list != NULL) {
+ ret = BitStream_append(bstream, list->bstream);
+ if(ret < 0) {
+ BitStream_free(bstream);
+ return NULL;
+ }
+ list = list->next;
+ }
+
+ return bstream;
+}
+
+/**
+ * Merge all bit streams in the input data and append padding bits
+ * @param input input data.
+ * @return padded merged bit stream
+ */
+
+static BitStream *QRinput_getBitStream(QRinput *input)
+{
+ BitStream *bstream;
+ int ret;
+
+ bstream = QRinput_mergeBitStream(input);
+ if(bstream == NULL) {
+ return NULL;
+ }
+ if(input->mqr) {
+ ret = QRinput_appendPaddingBitMQR(bstream, input);
+ } else {
+ ret = QRinput_appendPaddingBit(bstream, input);
+ }
+ if(ret < 0) {
+ BitStream_free(bstream);
+ return NULL;
+ }
+
+ return bstream;
+}
+
+/**
+ * Pack all bit streams padding bits into a byte array.
+ * @param input input data.
+ * @return padded merged byte stream
+ */
+
+unsigned char *QRinput_getByteStream(QRinput *input)
+{
+ BitStream *bstream;
+ unsigned char *array;
+
+ bstream = QRinput_getBitStream(input);
+ if(bstream == NULL) {
+ return NULL;
+ }
+ array = BitStream_toByte(bstream);
+ BitStream_free(bstream);
+
+ return array;
+}
+
+/******************************************************************************
+ * Structured input data
+ *****************************************************************************/
+
+static QRinput_InputList *QRinput_InputList_newEntry(QRinput *input)
+{
+ QRinput_InputList *entry;
+
+ entry = (QRinput_InputList *)malloc(sizeof(QRinput_InputList));
+ if(entry == NULL) return NULL;
+
+ entry->input = input;
+ entry->next = NULL;
+
+ return entry;
+}
+
+static void QRinput_InputList_freeEntry(QRinput_InputList *entry)
+{
+ if(entry != NULL) {
+ QRinput_free(entry->input);
+ free(entry);
+ }
+}
+
+QRinput_Struct *QRinput_Struct_new(void)
+{
+ QRinput_Struct *s;
+
+ s = (QRinput_Struct *)malloc(sizeof(QRinput_Struct));
+ if(s == NULL) return NULL;
+
+ s->size = 0;
+ s->parity = -1;
+ s->head = NULL;
+ s->tail = NULL;
+
+ return s;
+}
+
+void QRinput_Struct_setParity(QRinput_Struct *s, unsigned char parity)
+{
+ s->parity = (int)parity;
+}
+
+int QRinput_Struct_appendInput(QRinput_Struct *s, QRinput *input)
+{
+ QRinput_InputList *e;
+
+ if(input->mqr) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ e = QRinput_InputList_newEntry(input);
+ if(e == NULL) return -1;
+
+ s->size++;
+ if(s->tail == NULL) {
+ s->head = e;
+ s->tail = e;
+ } else {
+ s->tail->next = e;
+ s->tail = e;
+ }
+
+ return s->size;
+}
+
+void QRinput_Struct_free(QRinput_Struct *s)
+{
+ QRinput_InputList *list, *next;
+
+ if(s != NULL) {
+ list = s->head;
+ while(list != NULL) {
+ next = list->next;
+ QRinput_InputList_freeEntry(list);
+ list = next;
+ }
+ free(s);
+ }
+}
+
+static unsigned char QRinput_Struct_calcParity(QRinput_Struct *s)
+{
+ QRinput_InputList *list;
+ unsigned char parity = 0;
+
+ list = s->head;
+ while(list != NULL) {
+ parity ^= QRinput_calcParity(list->input);
+ list = list->next;
+ }
+
+ QRinput_Struct_setParity(s, parity);
+
+ return parity;
+}
+
+static int QRinput_List_shrinkEntry(QRinput_List *entry, int bytes)
+{
+ unsigned char *data;
+
+ data = (unsigned char *)malloc(bytes);
+ if(data == NULL) return -1;
+
+ memcpy(data, entry->data, bytes);
+ free(entry->data);
+ entry->data = data;
+ entry->size = bytes;
+
+ return 0;
+}
+
+static int QRinput_splitEntry(QRinput_List *entry, int bytes)
+{
+ QRinput_List *e;
+ int ret;
+
+ e = QRinput_List_newEntry(entry->mode, entry->size - bytes, entry->data + bytes);
+ if(e == NULL) {
+ return -1;
+ }
+
+ ret = QRinput_List_shrinkEntry(entry, bytes);
+ if(ret < 0) {
+ QRinput_List_freeEntry(e);
+ return -1;
+ }
+
+ e->next = entry->next;
+ entry->next = e;
+
+ return 0;
+}
+
+QRinput_Struct *QRinput_splitQRinputToStruct(QRinput *input)
+{
+ QRinput *p;
+ QRinput_Struct *s;
+ int bits, maxbits, nextbits, bytes, ret;
+ QRinput_List *list, *next, *prev;
+
+ if(input->mqr) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ s = QRinput_Struct_new();
+ if(s == NULL) return NULL;
+
+ input = QRinput_dup(input);
+ if(input == NULL) {
+ QRinput_Struct_free(s);
+ return NULL;
+ }
+
+ QRinput_Struct_setParity(s, QRinput_calcParity(input));
+ maxbits = QRspec_getDataLength(input->version, input->level) * 8 - STRUCTURE_HEADER_SIZE;
+
+ if(maxbits <= 0) {
+ QRinput_Struct_free(s);
+ QRinput_free(input);
+ return NULL;
+ }
+
+ bits = 0;
+ list = input->head;
+ prev = NULL;
+ while(list != NULL) {
+ nextbits = QRinput_estimateBitStreamSizeOfEntry(list, input->version, input->mqr);
+ if(bits + nextbits <= maxbits) {
+ ret = QRinput_encodeBitStream(list, input->version, input->mqr);
+ if(ret < 0) goto ABORT;
+ bits += ret;
+ prev = list;
+ list = list->next;
+ } else {
+ bytes = QRinput_lengthOfCode(list->mode, input->version, maxbits - bits);
+ p = QRinput_new2(input->version, input->level);
+ if(p == NULL) goto ABORT;
+ if(bytes > 0) {
+ /* Splits this entry into 2 entries. */
+ ret = QRinput_splitEntry(list, bytes);
+ if(ret < 0) {
+ QRinput_free(p);
+ goto ABORT;
+ }
+ /* First half is the tail of the current input. */
+ next = list->next;
+ list->next = NULL;
+ /* Second half is the head of the next input, p.*/
+ p->head = next;
+ /* Renew QRinput.tail. */
+ p->tail = input->tail;
+ input->tail = list;
+ /* Point to the next entry. */
+ prev = list;
+ list = next;
+ } else {
+ /* Current entry will go to the next input. */
+ prev->next = NULL;
+ p->head = list;
+ p->tail = input->tail;
+ input->tail = prev;
+ }
+ ret = QRinput_Struct_appendInput(s, input);
+ if(ret < 0) {
+ QRinput_free(p);
+ goto ABORT;
+ }
+ input = p;
+ bits = 0;
+ }
+ }
+ ret = QRinput_Struct_appendInput(s, input);
+ if(ret < 0) goto ABORT;
+ if(s->size > MAX_STRUCTURED_SYMBOLS) {
+ QRinput_Struct_free(s);
+ errno = ERANGE;
+ return NULL;
+ }
+ ret = QRinput_Struct_insertStructuredAppendHeaders(s);
+ if(ret < 0) {
+ QRinput_Struct_free(s);
+ return NULL;
+ }
+
+ return s;
+
+ABORT:
+ QRinput_free(input);
+ QRinput_Struct_free(s);
+ return NULL;
+}
+
+int QRinput_Struct_insertStructuredAppendHeaders(QRinput_Struct *s)
+{
+ int num, i;
+ QRinput_InputList *list;
+
+ if(s->parity < 0) {
+ QRinput_Struct_calcParity(s);
+ }
+ num = 0;
+ list = s->head;
+ while(list != NULL) {
+ num++;
+ list = list->next;
+ }
+ i = 1;
+ list = s->head;
+ while(list != NULL) {
+ if(QRinput_insertStructuredAppendHeader(list->input, num, i, s->parity))
+ return -1;
+ i++;
+ list = list->next;
+ }
+
+ return 0;
+}
+
+/******************************************************************************
+ * Extended encoding mode (FNC1 and ECI)
+ *****************************************************************************/
+
+int QRinput_setFNC1First(QRinput *input)
+{
+ if(input->mqr) {
+ errno = EINVAL;
+ return -1;
+ }
+ input->fnc1 = 1;
+
+ return 0;
+}
+
+int QRinput_setFNC1Second(QRinput *input, unsigned char appid)
+{
+ if(input->mqr) {
+ errno = EINVAL;
+ return -1;
+ }
+ input->fnc1 = 2;
+ input->appid = appid;
+
+ return 0;
+}
diff --git a/src/qqrencode/qrencode/qrinput.h b/src/qqrencode/qrencode/qrinput.h
new file mode 100644
index 0000000..9e6bad6
--- /dev/null
+++ b/src/qqrencode/qrencode/qrinput.h
@@ -0,0 +1,123 @@
+/*
+ * qrencode - QR Code encoder
+ *
+ * Input data chunk class
+ * Copyright (C) 2006-2011 Kentaro Fukuchi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __QRINPUT_H__
+#define __QRINPUT_H__
+
+#include "qrencode.h"
+#include "bitstream.h"
+
+int QRinput_isSplittableMode(QRencodeMode mode);
+
+/******************************************************************************
+ * Entry of input data
+ *****************************************************************************/
+typedef struct _QRinput_List QRinput_List;
+
+struct _QRinput_List {
+ QRencodeMode mode;
+ int size; ///< Size of data chunk (byte).
+ unsigned char *data; ///< Data chunk.
+ BitStream *bstream;
+ QRinput_List *next;
+};
+
+/******************************************************************************
+ * Input Data
+ *****************************************************************************/
+struct _QRinput {
+ int version;
+ QRecLevel level;
+ QRinput_List *head;
+ QRinput_List *tail;
+ int mqr;
+ int fnc1;
+ unsigned char appid;
+};
+
+/******************************************************************************
+ * Structured append input data
+ *****************************************************************************/
+typedef struct _QRinput_InputList QRinput_InputList;
+
+struct _QRinput_InputList {
+ QRinput *input;
+ QRinput_InputList *next;
+};
+
+struct _QRinput_Struct {
+ int size; ///< number of structured symbols
+ int parity;
+ QRinput_InputList *head;
+ QRinput_InputList *tail;
+};
+
+/**
+ * Pack all bit streams padding bits into a byte array.
+ * @param input input data.
+ * @return padded merged byte stream
+ */
+extern unsigned char *QRinput_getByteStream(QRinput *input);
+
+
+extern int QRinput_estimateBitsModeNum(int size);
+extern int QRinput_estimateBitsModeAn(int size);
+extern int QRinput_estimateBitsMode8(int size);
+extern int QRinput_estimateBitsModeKanji(int size);
+
+extern QRinput *QRinput_dup(QRinput *input);
+
+extern const signed char QRinput_anTable[128];
+
+/**
+ * Look up the alphabet-numeric convesion table (see JIS X0510:2004, pp.19).
+ * @param __c__ character
+ * @return value
+ */
+#define QRinput_lookAnTable(__c__) \
+ ((__c__ & 0x80)?-1:QRinput_anTable[(int)__c__])
+
+/**
+ * Length of a standard mode indicator in bits.
+ */
+
+#define MODE_INDICATOR_SIZE 4
+
+/**
+ * Length of a segment of structured-append header.
+ */
+#define STRUCTURE_HEADER_SIZE 20
+
+/**
+ * Maximum number of symbols in a set of structured-appended symbols.
+ */
+#define MAX_STRUCTURED_SYMBOLS 16
+
+#ifdef WITH_TESTS
+extern BitStream *QRinput_mergeBitStream(QRinput *input);
+extern BitStream *QRinput_getBitStream(QRinput *input);
+extern int QRinput_estimateBitStreamSize(QRinput *input, int version);
+extern int QRinput_splitEntry(QRinput_List *entry, int bytes);
+extern int QRinput_lengthOfCode(QRencodeMode mode, int version, int bits);
+extern int QRinput_insertStructuredAppendHeader(QRinput *input, int size, int index, unsigned char parity);
+#endif
+
+#endif /* __QRINPUT_H__ */
diff --git a/src/qqrencode/qrencode/qrspec.c b/src/qqrencode/qrencode/qrspec.c
new file mode 100644
index 0000000..a42706f
--- /dev/null
+++ b/src/qqrencode/qrencode/qrspec.c
@@ -0,0 +1,562 @@
+/*
+ * qrencode - QR Code encoder
+ *
+ * QR Code specification in convenient format.
+ * Copyright (C) 2006-2011 Kentaro Fukuchi
+ *
+ * The following data / specifications are taken from
+ * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
+ * or
+ * "Automatic identification and data capture techniques --
+ * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include
+#include
+#include
+#include
+#ifdef HAVE_LIBPTHREAD
+#include
+#endif
+
+#include "qrspec.h"
+#include "qrinput.h"
+
+/******************************************************************************
+ * Version and capacity
+ *****************************************************************************/
+
+typedef struct {
+ int width; //< Edge length of the symbol
+ int words; //< Data capacity (bytes)
+ int remainder; //< Remainder bit (bits)
+ int ec[4]; //< Number of ECC code (bytes)
+} QRspec_Capacity;
+
+/**
+ * Table of the capacity of symbols
+ * See Table 1 (pp.13) and Table 12-16 (pp.30-36), JIS X0510:2004.
+ */
+static const QRspec_Capacity qrspecCapacity[QRSPEC_VERSION_MAX + 1] = {
+ { 0, 0, 0, { 0, 0, 0, 0}},
+ { 21, 26, 0, { 7, 10, 13, 17}}, // 1
+ { 25, 44, 7, { 10, 16, 22, 28}},
+ { 29, 70, 7, { 15, 26, 36, 44}},
+ { 33, 100, 7, { 20, 36, 52, 64}},
+ { 37, 134, 7, { 26, 48, 72, 88}}, // 5
+ { 41, 172, 7, { 36, 64, 96, 112}},
+ { 45, 196, 0, { 40, 72, 108, 130}},
+ { 49, 242, 0, { 48, 88, 132, 156}},
+ { 53, 292, 0, { 60, 110, 160, 192}},
+ { 57, 346, 0, { 72, 130, 192, 224}}, //10
+ { 61, 404, 0, { 80, 150, 224, 264}},
+ { 65, 466, 0, { 96, 176, 260, 308}},
+ { 69, 532, 0, { 104, 198, 288, 352}},
+ { 73, 581, 3, { 120, 216, 320, 384}},
+ { 77, 655, 3, { 132, 240, 360, 432}}, //15
+ { 81, 733, 3, { 144, 280, 408, 480}},
+ { 85, 815, 3, { 168, 308, 448, 532}},
+ { 89, 901, 3, { 180, 338, 504, 588}},
+ { 93, 991, 3, { 196, 364, 546, 650}},
+ { 97, 1085, 3, { 224, 416, 600, 700}}, //20
+ {101, 1156, 4, { 224, 442, 644, 750}},
+ {105, 1258, 4, { 252, 476, 690, 816}},
+ {109, 1364, 4, { 270, 504, 750, 900}},
+ {113, 1474, 4, { 300, 560, 810, 960}},
+ {117, 1588, 4, { 312, 588, 870, 1050}}, //25
+ {121, 1706, 4, { 336, 644, 952, 1110}},
+ {125, 1828, 4, { 360, 700, 1020, 1200}},
+ {129, 1921, 3, { 390, 728, 1050, 1260}},
+ {133, 2051, 3, { 420, 784, 1140, 1350}},
+ {137, 2185, 3, { 450, 812, 1200, 1440}}, //30
+ {141, 2323, 3, { 480, 868, 1290, 1530}},
+ {145, 2465, 3, { 510, 924, 1350, 1620}},
+ {149, 2611, 3, { 540, 980, 1440, 1710}},
+ {153, 2761, 3, { 570, 1036, 1530, 1800}},
+ {157, 2876, 0, { 570, 1064, 1590, 1890}}, //35
+ {161, 3034, 0, { 600, 1120, 1680, 1980}},
+ {165, 3196, 0, { 630, 1204, 1770, 2100}},
+ {169, 3362, 0, { 660, 1260, 1860, 2220}},
+ {173, 3532, 0, { 720, 1316, 1950, 2310}},
+ {177, 3706, 0, { 750, 1372, 2040, 2430}} //40
+};
+
+int QRspec_getDataLength(int version, QRecLevel level)
+{
+ return qrspecCapacity[version].words - qrspecCapacity[version].ec[level];
+}
+
+int QRspec_getECCLength(int version, QRecLevel level)
+{
+ return qrspecCapacity[version].ec[level];
+}
+
+int QRspec_getMinimumVersion(int size, QRecLevel level)
+{
+ int i;
+ int words;
+
+ for(i=1; i<= QRSPEC_VERSION_MAX; i++) {
+ words = qrspecCapacity[i].words - qrspecCapacity[i].ec[level];
+ if(words >= size) return i;
+ }
+
+ return -1;
+}
+
+int QRspec_getWidth(int version)
+{
+ return qrspecCapacity[version].width;
+}
+
+int QRspec_getRemainder(int version)
+{
+ return qrspecCapacity[version].remainder;
+}
+
+/******************************************************************************
+ * Length indicator
+ *****************************************************************************/
+
+static const int lengthTableBits[4][3] = {
+ {10, 12, 14},
+ { 9, 11, 13},
+ { 8, 16, 16},
+ { 8, 10, 12}
+};
+
+int QRspec_lengthIndicator(QRencodeMode mode, int version)
+{
+ int l;
+
+ if(!QRinput_isSplittableMode(mode)) return 0;
+ if(version <= 9) {
+ l = 0;
+ } else if(version <= 26) {
+ l = 1;
+ } else {
+ l = 2;
+ }
+
+ return lengthTableBits[mode][l];
+}
+
+int QRspec_maximumWords(QRencodeMode mode, int version)
+{
+ int l;
+ int bits;
+ int words;
+
+ if(!QRinput_isSplittableMode(mode)) return 0;
+ if(version <= 9) {
+ l = 0;
+ } else if(version <= 26) {
+ l = 1;
+ } else {
+ l = 2;
+ }
+
+ bits = lengthTableBits[mode][l];
+ words = (1 << bits) - 1;
+ if(mode == QR_MODE_KANJI) {
+ words *= 2; // the number of bytes is required
+ }
+
+ return words;
+}
+
+/******************************************************************************
+ * Error correction code
+ *****************************************************************************/
+
+/**
+ * Table of the error correction code (Reed-Solomon block)
+ * See Table 12-16 (pp.30-36), JIS X0510:2004.
+ */
+static const int eccTable[QRSPEC_VERSION_MAX+1][4][2] = {
+ {{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}},
+ {{ 1, 0}, { 1, 0}, { 1, 0}, { 1, 0}}, // 1
+ {{ 1, 0}, { 1, 0}, { 1, 0}, { 1, 0}},
+ {{ 1, 0}, { 1, 0}, { 2, 0}, { 2, 0}},
+ {{ 1, 0}, { 2, 0}, { 2, 0}, { 4, 0}},
+ {{ 1, 0}, { 2, 0}, { 2, 2}, { 2, 2}}, // 5
+ {{ 2, 0}, { 4, 0}, { 4, 0}, { 4, 0}},
+ {{ 2, 0}, { 4, 0}, { 2, 4}, { 4, 1}},
+ {{ 2, 0}, { 2, 2}, { 4, 2}, { 4, 2}},
+ {{ 2, 0}, { 3, 2}, { 4, 4}, { 4, 4}},
+ {{ 2, 2}, { 4, 1}, { 6, 2}, { 6, 2}}, //10
+ {{ 4, 0}, { 1, 4}, { 4, 4}, { 3, 8}},
+ {{ 2, 2}, { 6, 2}, { 4, 6}, { 7, 4}},
+ {{ 4, 0}, { 8, 1}, { 8, 4}, {12, 4}},
+ {{ 3, 1}, { 4, 5}, {11, 5}, {11, 5}},
+ {{ 5, 1}, { 5, 5}, { 5, 7}, {11, 7}}, //15
+ {{ 5, 1}, { 7, 3}, {15, 2}, { 3, 13}},
+ {{ 1, 5}, {10, 1}, { 1, 15}, { 2, 17}},
+ {{ 5, 1}, { 9, 4}, {17, 1}, { 2, 19}},
+ {{ 3, 4}, { 3, 11}, {17, 4}, { 9, 16}},
+ {{ 3, 5}, { 3, 13}, {15, 5}, {15, 10}}, //20
+ {{ 4, 4}, {17, 0}, {17, 6}, {19, 6}},
+ {{ 2, 7}, {17, 0}, { 7, 16}, {34, 0}},
+ {{ 4, 5}, { 4, 14}, {11, 14}, {16, 14}},
+ {{ 6, 4}, { 6, 14}, {11, 16}, {30, 2}},
+ {{ 8, 4}, { 8, 13}, { 7, 22}, {22, 13}}, //25
+ {{10, 2}, {19, 4}, {28, 6}, {33, 4}},
+ {{ 8, 4}, {22, 3}, { 8, 26}, {12, 28}},
+ {{ 3, 10}, { 3, 23}, { 4, 31}, {11, 31}},
+ {{ 7, 7}, {21, 7}, { 1, 37}, {19, 26}},
+ {{ 5, 10}, {19, 10}, {15, 25}, {23, 25}}, //30
+ {{13, 3}, { 2, 29}, {42, 1}, {23, 28}},
+ {{17, 0}, {10, 23}, {10, 35}, {19, 35}},
+ {{17, 1}, {14, 21}, {29, 19}, {11, 46}},
+ {{13, 6}, {14, 23}, {44, 7}, {59, 1}},
+ {{12, 7}, {12, 26}, {39, 14}, {22, 41}}, //35
+ {{ 6, 14}, { 6, 34}, {46, 10}, { 2, 64}},
+ {{17, 4}, {29, 14}, {49, 10}, {24, 46}},
+ {{ 4, 18}, {13, 32}, {48, 14}, {42, 32}},
+ {{20, 4}, {40, 7}, {43, 22}, {10, 67}},
+ {{19, 6}, {18, 31}, {34, 34}, {20, 61}},//40
+};
+
+void QRspec_getEccSpec(int version, QRecLevel level, int spec[5])
+{
+ int b1, b2;
+ int data, ecc;
+
+ b1 = eccTable[version][level][0];
+ b2 = eccTable[version][level][1];
+ data = QRspec_getDataLength(version, level);
+ ecc = QRspec_getECCLength(version, level);
+
+ if(b2 == 0) {
+ spec[0] = b1;
+ spec[1] = data / b1;
+ spec[2] = ecc / b1;
+ spec[3] = spec[4] = 0;
+ } else {
+ spec[0] = b1;
+ spec[1] = data / (b1 + b2);
+ spec[2] = ecc / (b1 + b2);
+ spec[3] = b2;
+ spec[4] = spec[1] + 1;
+ }
+}
+
+/******************************************************************************
+ * Alignment pattern
+ *****************************************************************************/
+
+/**
+ * Positions of alignment patterns.
+ * This array includes only the second and the third position of the alignment
+ * patterns. Rest of them can be calculated from the distance between them.
+ *
+ * See Table 1 in Appendix E (pp.71) of JIS X0510:2004.
+ */
+static const int alignmentPattern[QRSPEC_VERSION_MAX+1][2] = {
+ { 0, 0},
+ { 0, 0}, {18, 0}, {22, 0}, {26, 0}, {30, 0}, // 1- 5
+ {34, 0}, {22, 38}, {24, 42}, {26, 46}, {28, 50}, // 6-10
+ {30, 54}, {32, 58}, {34, 62}, {26, 46}, {26, 48}, //11-15
+ {26, 50}, {30, 54}, {30, 56}, {30, 58}, {34, 62}, //16-20
+ {28, 50}, {26, 50}, {30, 54}, {28, 54}, {32, 58}, //21-25
+ {30, 58}, {34, 62}, {26, 50}, {30, 54}, {26, 52}, //26-30
+ {30, 56}, {34, 60}, {30, 58}, {34, 62}, {30, 54}, //31-35
+ {24, 50}, {28, 54}, {32, 58}, {26, 54}, {30, 58}, //35-40
+};
+
+/**
+ * Put an alignment marker.
+ * @param frame
+ * @param width
+ * @param ox,oy center coordinate of the pattern
+ */
+static void QRspec_putAlignmentMarker(unsigned char *frame, int width, int ox, int oy)
+{
+ static const unsigned char finder[] = {
+ 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
+ 0xa1, 0xa0, 0xa0, 0xa0, 0xa1,
+ 0xa1, 0xa0, 0xa1, 0xa0, 0xa1,
+ 0xa1, 0xa0, 0xa0, 0xa0, 0xa1,
+ 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
+ };
+ int x, y;
+ const unsigned char *s;
+
+ frame += (oy - 2) * width + ox - 2;
+ s = finder;
+ for(y=0; y<5; y++) {
+ for(x=0; x<5; x++) {
+ frame[x] = s[x];
+ }
+ frame += width;
+ s += 5;
+ }
+}
+
+static void QRspec_putAlignmentPattern(int version, unsigned char *frame, int width)
+{
+ int d, w, x, y, cx, cy;
+
+ if(version < 2) return;
+
+ d = alignmentPattern[version][1] - alignmentPattern[version][0];
+ if(d < 0) {
+ w = 2;
+ } else {
+ w = (width - alignmentPattern[version][0]) / d + 2;
+ }
+
+ if(w * w - 3 == 1) {
+ x = alignmentPattern[version][0];
+ y = alignmentPattern[version][0];
+ QRspec_putAlignmentMarker(frame, width, x, y);
+ return;
+ }
+
+ cx = alignmentPattern[version][0];
+ for(x=1; x QRSPEC_VERSION_MAX) return 0;
+
+ return versionPattern[version - 7];
+}
+
+/******************************************************************************
+ * Format information
+ *****************************************************************************/
+
+/* See calcFormatInfo in tests/test_qrspec.c */
+static const unsigned int formatInfo[4][8] = {
+ {0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976},
+ {0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0},
+ {0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed},
+ {0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b}
+};
+
+unsigned int QRspec_getFormatInfo(int mask, QRecLevel level)
+{
+ if(mask < 0 || mask > 7) return 0;
+
+ return formatInfo[level][mask];
+}
+
+/******************************************************************************
+ * Frame
+ *****************************************************************************/
+
+/**
+ * Cache of initial frames.
+ */
+/* C99 says that static storage shall be initialized to a null pointer
+ * by compiler. */
+static unsigned char *frames[QRSPEC_VERSION_MAX + 1];
+#ifdef HAVE_LIBPTHREAD
+static pthread_mutex_t frames_mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
+/**
+ * Put a finder pattern.
+ * @param frame
+ * @param width
+ * @param ox,oy upper-left coordinate of the pattern
+ */
+static void putFinderPattern(unsigned char *frame, int width, int ox, int oy)
+{
+ static const unsigned char finder[] = {
+ 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
+ 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1,
+ 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
+ 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
+ 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
+ 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1,
+ 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
+ };
+ int x, y;
+ const unsigned char *s;
+
+ frame += oy * width + ox;
+ s = finder;
+ for(y=0; y<7; y++) {
+ for(x=0; x<7; x++) {
+ frame[x] = s[x];
+ }
+ frame += width;
+ s += 7;
+ }
+}
+
+
+static unsigned char *QRspec_createFrame(int version)
+{
+ unsigned char *frame, *p, *q;
+ int width;
+ int x, y;
+ unsigned int verinfo, v;
+
+ width = qrspecCapacity[version].width;
+ frame = (unsigned char *)malloc(width * width);
+ if(frame == NULL) return NULL;
+
+ memset(frame, 0, width * width);
+ /* Finder pattern */
+ putFinderPattern(frame, width, 0, 0);
+ putFinderPattern(frame, width, width - 7, 0);
+ putFinderPattern(frame, width, 0, width - 7);
+ /* Separator */
+ p = frame;
+ q = frame + width * (width - 7);
+ for(y=0; y<7; y++) {
+ p[7] = 0xc0;
+ p[width - 8] = 0xc0;
+ q[7] = 0xc0;
+ p += width;
+ q += width;
+ }
+ memset(frame + width * 7, 0xc0, 8);
+ memset(frame + width * 8 - 8, 0xc0, 8);
+ memset(frame + width * (width - 8), 0xc0, 8);
+ /* Mask format information area */
+ memset(frame + width * 8, 0x84, 9);
+ memset(frame + width * 9 - 8, 0x84, 8);
+ p = frame + 8;
+ for(y=0; y<8; y++) {
+ *p = 0x84;
+ p += width;
+ }
+ p = frame + width * (width - 7) + 8;
+ for(y=0; y<7; y++) {
+ *p = 0x84;
+ p += width;
+ }
+ /* Timing pattern */
+ p = frame + width * 6 + 8;
+ q = frame + width * 8 + 6;
+ for(x=1; x= 7) {
+ verinfo = QRspec_getVersionPattern(version);
+
+ p = frame + width * (width - 11);
+ v = verinfo;
+ for(x=0; x<6; x++) {
+ for(y=0; y<3; y++) {
+ p[width * y + x] = 0x88 | (v & 1);
+ v = v >> 1;
+ }
+ }
+
+ p = frame + width - 11;
+ v = verinfo;
+ for(y=0; y<6; y++) {
+ for(x=0; x<3; x++) {
+ p[x] = 0x88 | (v & 1);
+ v = v >> 1;
+ }
+ p += width;
+ }
+ }
+ /* and a little bit... */
+ frame[width * (width - 8) + 8] = 0x81;
+
+ return frame;
+}
+
+unsigned char *QRspec_newFrame(int version)
+{
+ unsigned char *frame;
+ int width;
+
+ if(version < 1 || version > QRSPEC_VERSION_MAX) return NULL;
+
+#ifdef HAVE_LIBPTHREAD
+ pthread_mutex_lock(&frames_mutex);
+#endif
+ if(frames[version] == NULL) {
+ frames[version] = QRspec_createFrame(version);
+ }
+#ifdef HAVE_LIBPTHREAD
+ pthread_mutex_unlock(&frames_mutex);
+#endif
+ if(frames[version] == NULL) return NULL;
+
+ width = qrspecCapacity[version].width;
+ frame = (unsigned char *)malloc(width * width);
+ if(frame == NULL) return NULL;
+ memcpy(frame, frames[version], width * width);
+
+ return frame;
+}
+
+void QRspec_clearCache(void)
+{
+ int i;
+
+#ifdef HAVE_LIBPTHREAD
+ pthread_mutex_lock(&frames_mutex);
+#endif
+ for(i=1; i<=QRSPEC_VERSION_MAX; i++) {
+ free(frames[i]);
+ frames[i] = NULL;
+ }
+#ifdef HAVE_LIBPTHREAD
+ pthread_mutex_unlock(&frames_mutex);
+#endif
+}
diff --git a/src/qqrencode/qrencode/qrspec.h b/src/qqrencode/qrencode/qrspec.h
new file mode 100644
index 0000000..54a3d9f
--- /dev/null
+++ b/src/qqrencode/qrencode/qrspec.h
@@ -0,0 +1,181 @@
+/*
+ * qrencode - QR Code encoder
+ *
+ * QR Code specification in convenient format.
+ * Copyright (C) 2006-2011 Kentaro Fukuchi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __QRSPEC_H__
+#define __QRSPEC_H__
+
+#include "qrencode.h"
+
+/******************************************************************************
+ * Version and capacity
+ *****************************************************************************/
+
+/**
+ * Maximum width of a symbol
+ */
+#define QRSPEC_WIDTH_MAX 177
+
+/**
+ * Return maximum data code length (bytes) for the version.
+ * @param version
+ * @param level
+ * @return maximum size (bytes)
+ */
+extern int QRspec_getDataLength(int version, QRecLevel level);
+
+/**
+ * Return maximum error correction code length (bytes) for the version.
+ * @param version
+ * @param level
+ * @return ECC size (bytes)
+ */
+extern int QRspec_getECCLength(int version, QRecLevel level);
+
+/**
+ * Return a version number that satisfies the input code length.
+ * @param size input code length (byte)
+ * @param level
+ * @return version number
+ */
+extern int QRspec_getMinimumVersion(int size, QRecLevel level);
+
+/**
+ * Return the width of the symbol for the version.
+ * @param version
+ * @return width
+ */
+extern int QRspec_getWidth(int version);
+
+/**
+ * Return the numer of remainder bits.
+ * @param version
+ * @return number of remainder bits
+ */
+extern int QRspec_getRemainder(int version);
+
+/******************************************************************************
+ * Length indicator
+ *****************************************************************************/
+
+/**
+ * Return the size of lenght indicator for the mode and version.
+ * @param mode
+ * @param version
+ * @return the size of the appropriate length indicator (bits).
+ */
+extern int QRspec_lengthIndicator(QRencodeMode mode, int version);
+
+/**
+ * Return the maximum length for the mode and version.
+ * @param mode
+ * @param version
+ * @return the maximum length (bytes)
+ */
+extern int QRspec_maximumWords(QRencodeMode mode, int version);
+
+/******************************************************************************
+ * Error correction code
+ *****************************************************************************/
+
+/**
+ * Return an array of ECC specification.
+ * @param version
+ * @param level
+ * @param spec an array of ECC specification contains as following:
+ * {# of type1 blocks, # of data code, # of ecc code,
+ * # of type2 blocks, # of data code}
+ */
+void QRspec_getEccSpec(int version, QRecLevel level, int spec[5]);
+
+#define QRspec_rsBlockNum(__spec__) (__spec__[0] + __spec__[3])
+#define QRspec_rsBlockNum1(__spec__) (__spec__[0])
+#define QRspec_rsDataCodes1(__spec__) (__spec__[1])
+#define QRspec_rsEccCodes1(__spec__) (__spec__[2])
+#define QRspec_rsBlockNum2(__spec__) (__spec__[3])
+#define QRspec_rsDataCodes2(__spec__) (__spec__[4])
+#define QRspec_rsEccCodes2(__spec__) (__spec__[2])
+
+#define QRspec_rsDataLength(__spec__) \
+ ((QRspec_rsBlockNum1(__spec__) * QRspec_rsDataCodes1(__spec__)) + \
+ (QRspec_rsBlockNum2(__spec__) * QRspec_rsDataCodes2(__spec__)))
+#define QRspec_rsEccLength(__spec__) \
+ (QRspec_rsBlockNum(__spec__) * QRspec_rsEccCodes1(__spec__))
+
+/******************************************************************************
+ * Version information pattern
+ *****************************************************************************/
+
+/**
+ * Return BCH encoded version information pattern that is used for the symbol
+ * of version 7 or greater. Use lower 18 bits.
+ * @param version
+ * @return BCH encoded version information pattern
+ */
+extern unsigned int QRspec_getVersionPattern(int version);
+
+/******************************************************************************
+ * Format information
+ *****************************************************************************/
+
+/**
+ * Return BCH encoded format information pattern.
+ * @param mask
+ * @param level
+ * @return BCH encoded format information pattern
+ */
+extern unsigned int QRspec_getFormatInfo(int mask, QRecLevel level);
+
+/******************************************************************************
+ * Frame
+ *****************************************************************************/
+
+/**
+ * Return a copy of initialized frame.
+ * When the same version is requested twice or more, a copy of cached frame
+ * is returned.
+ * @param version
+ * @return Array of unsigned char. You can free it by free().
+ */
+extern unsigned char *QRspec_newFrame(int version);
+
+/**
+ * Clear the frame cache. Typically for debug.
+ */
+extern void QRspec_clearCache(void);
+
+/******************************************************************************
+ * Mode indicator
+ *****************************************************************************/
+
+/**
+ * Mode indicator. See Table 2 of JIS X0510:2004, pp.16.
+ */
+#define QRSPEC_MODEID_ECI 7
+#define QRSPEC_MODEID_NUM 1
+#define QRSPEC_MODEID_AN 2
+#define QRSPEC_MODEID_8 4
+#define QRSPEC_MODEID_KANJI 8
+#define QRSPEC_MODEID_FNC1FIRST 5
+#define QRSPEC_MODEID_FNC1SECOND 9
+#define QRSPEC_MODEID_STRUCTURE 3
+#define QRSPEC_MODEID_TERMINATOR 0
+
+#endif /* __QRSPEC_H__ */
diff --git a/src/qqrencode/qrencode/rscode.c b/src/qqrencode/qrencode/rscode.c
new file mode 100644
index 0000000..edc32e2
--- /dev/null
+++ b/src/qqrencode/qrencode/rscode.c
@@ -0,0 +1,327 @@
+/*
+ * qrencode - QR Code encoder
+ *
+ * Reed solomon encoder. This code is taken from Phil Karn's libfec then
+ * editted and packed into a pair of .c and .h files.
+ *
+ * Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
+ * (libfec is released under the GNU Lesser General Public License.)
+ *
+ * Copyright (C) 2006-2011 Kentaro Fukuchi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include
+#include
+#ifdef HAVE_LIBPTHREAD
+# include
+#endif
+
+#include "rscode.h"
+
+/* Stuff specific to the 8-bit symbol version of the general purpose RS codecs
+ *
+ */
+typedef unsigned char data_t;
+
+
+/**
+ * Reed-Solomon codec control block
+ */
+struct _RS {
+ int mm; /* Bits per symbol */
+ int nn; /* Symbols per block (= (1<= rs->nn) {
+ x -= rs->nn;
+ x = (x >> rs->mm) + (x & rs->nn);
+ }
+ return x;
+}
+
+
+#define MODNN(x) modnn(rs,x)
+
+#define MM (rs->mm)
+#define NN (rs->nn)
+#define ALPHA_TO (rs->alpha_to)
+#define INDEX_OF (rs->index_of)
+#define GENPOLY (rs->genpoly)
+#define NROOTS (rs->nroots)
+#define FCR (rs->fcr)
+#define PRIM (rs->prim)
+#define IPRIM (rs->iprim)
+#define PAD (rs->pad)
+#define A0 (NN)
+
+
+/* Initialize a Reed-Solomon codec
+ * symsize = symbol size, bits
+ * gfpoly = Field generator polynomial coefficients
+ * fcr = first root of RS code generator polynomial, index form
+ * prim = primitive element to generate polynomial roots
+ * nroots = RS code generator polynomial degree (number of roots)
+ * pad = padding bytes at front of shortened block
+ */
+static RS *init_rs_char(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad)
+{
+ RS *rs;
+
+
+/* Common code for intializing a Reed-Solomon control block (char or int symbols)
+ * Copyright 2004 Phil Karn, KA9Q
+ * May be used under the terms of the GNU Lesser General Public License (LGPL)
+ */
+//#undef NULL
+//#define NULL ((void *)0)
+
+ int i, j, sr,root,iprim;
+
+ rs = NULL;
+ /* Check parameter ranges */
+ if(symsize < 0 || symsize > (int)(8*sizeof(data_t))){
+ goto done;
+ }
+
+ if(fcr < 0 || fcr >= (1<= (1<= (1<= ((1<mm = symsize;
+ rs->nn = (1<pad = pad;
+
+ rs->alpha_to = (data_t *)malloc(sizeof(data_t)*(rs->nn+1));
+ if(rs->alpha_to == NULL){
+ free(rs);
+ rs = NULL;
+ goto done;
+ }
+ rs->index_of = (data_t *)malloc(sizeof(data_t)*(rs->nn+1));
+ if(rs->index_of == NULL){
+ free(rs->alpha_to);
+ free(rs);
+ rs = NULL;
+ goto done;
+ }
+
+ /* Generate Galois field lookup tables */
+ rs->index_of[0] = A0; /* log(zero) = -inf */
+ rs->alpha_to[A0] = 0; /* alpha**-inf = 0 */
+ sr = 1;
+ for(i=0;inn;i++){
+ rs->index_of[sr] = i;
+ rs->alpha_to[i] = sr;
+ sr <<= 1;
+ if(sr & (1<nn;
+ }
+ if(sr != 1){
+ /* field generator polynomial is not primitive! */
+ free(rs->alpha_to);
+ free(rs->index_of);
+ free(rs);
+ rs = NULL;
+ goto done;
+ }
+
+ /* Form RS code generator polynomial from its roots */
+ rs->genpoly = (data_t *)malloc(sizeof(data_t)*(nroots+1));
+ if(rs->genpoly == NULL){
+ free(rs->alpha_to);
+ free(rs->index_of);
+ free(rs);
+ rs = NULL;
+ goto done;
+ }
+ rs->fcr = fcr;
+ rs->prim = prim;
+ rs->nroots = nroots;
+ rs->gfpoly = gfpoly;
+
+ /* Find prim-th root of 1, used in decoding */
+ for(iprim=1;(iprim % prim) != 0;iprim += rs->nn)
+ ;
+ rs->iprim = iprim / prim;
+
+ rs->genpoly[0] = 1;
+ for (i = 0,root=fcr*prim; i < nroots; i++,root += prim) {
+ rs->genpoly[i+1] = 1;
+
+ /* Multiply rs->genpoly[] by @**(root + x) */
+ for (j = i; j > 0; j--){
+ if (rs->genpoly[j] != 0)
+ rs->genpoly[j] = rs->genpoly[j-1] ^ rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[j]] + root)];
+ else
+ rs->genpoly[j] = rs->genpoly[j-1];
+ }
+ /* rs->genpoly[0] can never be zero */
+ rs->genpoly[0] = rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[0]] + root)];
+ }
+ /* convert rs->genpoly[] to index form for quicker encoding */
+ for (i = 0; i <= nroots; i++)
+ rs->genpoly[i] = rs->index_of[rs->genpoly[i]];
+ done:;
+
+ return rs;
+}
+
+RS *init_rs(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad)
+{
+ RS *rs;
+
+#ifdef HAVE_LIBPTHREAD
+ pthread_mutex_lock(&rslist_mutex);
+#endif
+ for(rs = rslist; rs != NULL; rs = rs->next) {
+ if(rs->pad != pad) continue;
+ if(rs->nroots != nroots) continue;
+ if(rs->mm != symsize) continue;
+ if(rs->gfpoly != gfpoly) continue;
+ if(rs->fcr != fcr) continue;
+ if(rs->prim != prim) continue;
+
+ goto DONE;
+ }
+
+ rs = init_rs_char(symsize, gfpoly, fcr, prim, nroots, pad);
+ if(rs == NULL) goto DONE;
+ rs->next = rslist;
+ rslist = rs;
+
+DONE:
+#ifdef HAVE_LIBPTHREAD
+ pthread_mutex_unlock(&rslist_mutex);
+#endif
+ return rs;
+}
+
+
+void free_rs_char(RS *rs)
+{
+ free(rs->alpha_to);
+ free(rs->index_of);
+ free(rs->genpoly);
+ free(rs);
+}
+
+void free_rs_cache(void)
+{
+ RS *rs, *next;
+
+#ifdef HAVE_LIBPTHREAD
+ pthread_mutex_lock(&rslist_mutex);
+#endif
+ rs = rslist;
+ while(rs != NULL) {
+ next = rs->next;
+ free_rs_char(rs);
+ rs = next;
+ }
+ rslist = NULL;
+#ifdef HAVE_LIBPTHREAD
+ pthread_mutex_unlock(&rslist_mutex);
+#endif
+}
+
+/* The guts of the Reed-Solomon encoder, meant to be #included
+ * into a function body with the following typedefs, macros and variables supplied
+ * according to the code parameters:
+
+ * data_t - a typedef for the data symbol
+ * data_t data[] - array of NN-NROOTS-PAD and type data_t to be encoded
+ * data_t parity[] - an array of NROOTS and type data_t to be written with parity symbols
+ * NROOTS - the number of roots in the RS code generator polynomial,
+ * which is the same as the number of parity symbols in a block.
+ Integer variable or literal.
+ *
+ * NN - the total number of symbols in a RS block. Integer variable or literal.
+ * PAD - the number of pad symbols in a block. Integer variable or literal.
+ * ALPHA_TO - The address of an array of NN elements to convert Galois field
+ * elements in index (log) form to polynomial form. Read only.
+ * INDEX_OF - The address of an array of NN elements to convert Galois field
+ * elements in polynomial form to index (log) form. Read only.
+ * MODNN - a function to reduce its argument modulo NN. May be inline or a macro.
+ * GENPOLY - an array of NROOTS+1 elements containing the generator polynomial in index form
+
+ * The memset() and memmove() functions are used. The appropriate header
+ * file declaring these functions (usually ) must be included by the calling
+ * program.
+
+ * Copyright 2004, Phil Karn, KA9Q
+ * May be used under the terms of the GNU Lesser General Public License (LGPL)
+ */
+
+#undef A0
+#define A0 (NN) /* Special reserved value encoding zero in index form */
+
+void encode_rs_char(RS *rs, const data_t *data, data_t *parity)
+{
+ int i, j;
+ data_t feedback;
+
+ memset(parity,0,NROOTS*sizeof(data_t));
+
+ for(i=0;i
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __RSCODE_H__
+#define __RSCODE_H__
+
+/*
+ * General purpose RS codec, 8-bit symbols.
+ */
+
+typedef struct _RS RS;
+
+extern RS *init_rs(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad);
+extern void encode_rs_char(RS *rs, const unsigned char *data, unsigned char *parity);
+extern void free_rs_char(RS *rs);
+extern void free_rs_cache(void);
+
+#endif /* __RSCODE_H__ */
diff --git a/src/qqrencode/qrencode/split.c b/src/qqrencode/qrencode/split.c
new file mode 100644
index 0000000..a2cb0e0
--- /dev/null
+++ b/src/qqrencode/qrencode/split.c
@@ -0,0 +1,326 @@
+/*
+ * qrencode - QR Code encoder
+ *
+ * Input data splitter.
+ * Copyright (C) 2006-2011 Kentaro Fukuchi
+ *
+ * The following data / specifications are taken from
+ * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
+ * or
+ * "Automatic identification and data capture techniques --
+ * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include
+#include
+#include
+#include "qrencode.h"
+#include "qrinput.h"
+#include "qrspec.h"
+#include "split.h"
+
+#define isdigit(__c__) ((unsigned char)((signed char)(__c__) - '0') < 10)
+#define isalnum(__c__) (QRinput_lookAnTable(__c__) >= 0)
+
+#if !HAVE_STRDUP
+#undef strdup
+char *strdup(const char *s)
+{
+ size_t len = strlen(s) + 1;
+ void *new = malloc(len);
+ if(new == NULL) return NULL;
+ return (char *)memcpy(new, s, len);
+}
+#endif
+
+static QRencodeMode Split_identifyMode(const char *string, QRencodeMode hint)
+{
+ unsigned char c, d;
+ unsigned int word;
+
+ c = string[0];
+
+ if(c == '\0') return QR_MODE_NUL;
+ if(isdigit(c)) {
+ return QR_MODE_NUM;
+ } else if(isalnum(c)) {
+ return QR_MODE_AN;
+ } else if(hint == QR_MODE_KANJI) {
+ d = string[1];
+ if(d != '\0') {
+ word = ((unsigned int)c << 8) | d;
+ if((word >= 0x8140 && word <= 0x9ffc) || (word >= 0xe040 && word <= 0xebbf)) {
+ return QR_MODE_KANJI;
+ }
+ }
+ }
+
+ return QR_MODE_8;
+}
+
+static int Split_eatNum(const char *string, QRinput *input, QRencodeMode hint);
+static int Split_eatAn(const char *string, QRinput *input, QRencodeMode hint);
+static int Split_eat8(const char *string, QRinput *input, QRencodeMode hint);
+static int Split_eatKanji(const char *string, QRinput *input, QRencodeMode hint);
+
+static int Split_eatNum(const char *string, QRinput *input,QRencodeMode hint)
+{
+ const char *p;
+ int ret;
+ int run;
+ int dif;
+ int ln;
+ QRencodeMode mode;
+
+ ln = QRspec_lengthIndicator(QR_MODE_NUM, input->version);
+
+ p = string;
+ while(isdigit(*p)) {
+ p++;
+ }
+ run = p - string;
+ mode = Split_identifyMode(p, hint);
+ if(mode == QR_MODE_8) {
+ dif = QRinput_estimateBitsModeNum(run) + 4 + ln
+ + QRinput_estimateBitsMode8(1) /* + 4 + l8 */
+ - QRinput_estimateBitsMode8(run + 1) /* - 4 - l8 */;
+ if(dif > 0) {
+ return Split_eat8(string, input, hint);
+ }
+ }
+ if(mode == QR_MODE_AN) {
+ dif = QRinput_estimateBitsModeNum(run) + 4 + ln
+ + QRinput_estimateBitsModeAn(1) /* + 4 + la */
+ - QRinput_estimateBitsModeAn(run + 1) /* - 4 - la */;
+ if(dif > 0) {
+ return Split_eatAn(string, input, hint);
+ }
+ }
+
+ ret = QRinput_append(input, QR_MODE_NUM, run, (unsigned char *)string);
+ if(ret < 0) return -1;
+
+ return run;
+}
+
+static int Split_eatAn(const char *string, QRinput *input, QRencodeMode hint)
+{
+ const char *p, *q;
+ int ret;
+ int run;
+ int dif;
+ int la, ln;
+
+ la = QRspec_lengthIndicator(QR_MODE_AN, input->version);
+ ln = QRspec_lengthIndicator(QR_MODE_NUM, input->version);
+
+ p = string;
+ while(isalnum(*p)) {
+ if(isdigit(*p)) {
+ q = p;
+ while(isdigit(*q)) {
+ q++;
+ }
+ dif = QRinput_estimateBitsModeAn(p - string) /* + 4 + la */
+ + QRinput_estimateBitsModeNum(q - p) + 4 + ln
+ + (isalnum(*q)?(4 + ln):0)
+ - QRinput_estimateBitsModeAn(q - string) /* - 4 - la */;
+ if(dif < 0) {
+ break;
+ } else {
+ p = q;
+ }
+ } else {
+ p++;
+ }
+ }
+
+ run = p - string;
+
+ if(*p && !isalnum(*p)) {
+ dif = QRinput_estimateBitsModeAn(run) + 4 + la
+ + QRinput_estimateBitsMode8(1) /* + 4 + l8 */
+ - QRinput_estimateBitsMode8(run + 1) /* - 4 - l8 */;
+ if(dif > 0) {
+ return Split_eat8(string, input, hint);
+ }
+ }
+
+ ret = QRinput_append(input, QR_MODE_AN, run, (unsigned char *)string);
+ if(ret < 0) return -1;
+
+ return run;
+}
+
+static int Split_eatKanji(const char *string, QRinput *input, QRencodeMode hint)
+{
+ const char *p;
+ int ret;
+ int run;
+
+ p = string;
+ while(Split_identifyMode(p, hint) == QR_MODE_KANJI) {
+ p += 2;
+ }
+ run = p - string;
+ ret = QRinput_append(input, QR_MODE_KANJI, run, (unsigned char *)string);
+ if(ret < 0) return -1;
+
+ return run;
+}
+
+static int Split_eat8(const char *string, QRinput *input, QRencodeMode hint)
+{
+ const char *p, *q;
+ QRencodeMode mode;
+ int ret;
+ int run;
+ int dif;
+ int la, ln, l8;
+ int swcost;
+
+ la = QRspec_lengthIndicator(QR_MODE_AN, input->version);
+ ln = QRspec_lengthIndicator(QR_MODE_NUM, input->version);
+ l8 = QRspec_lengthIndicator(QR_MODE_8, input->version);
+
+ p = string + 1;
+ while(*p != '\0') {
+ mode = Split_identifyMode(p, hint);
+ if(mode == QR_MODE_KANJI) {
+ break;
+ }
+ if(mode == QR_MODE_NUM) {
+ q = p;
+ while(isdigit(*q)) {
+ q++;
+ }
+ if(Split_identifyMode(q, hint) == QR_MODE_8) {
+ swcost = 4 + l8;
+ } else {
+ swcost = 0;
+ }
+ dif = QRinput_estimateBitsMode8(p - string) /* + 4 + l8 */
+ + QRinput_estimateBitsModeNum(q - p) + 4 + ln
+ + swcost
+ - QRinput_estimateBitsMode8(q - string) /* - 4 - l8 */;
+ if(dif < 0) {
+ break;
+ } else {
+ p = q;
+ }
+ } else if(mode == QR_MODE_AN) {
+ q = p;
+ while(isalnum(*q)) {
+ q++;
+ }
+ if(Split_identifyMode(q, hint) == QR_MODE_8) {
+ swcost = 4 + l8;
+ } else {
+ swcost = 0;
+ }
+ dif = QRinput_estimateBitsMode8(p - string) /* + 4 + l8 */
+ + QRinput_estimateBitsModeAn(q - p) + 4 + la
+ + swcost
+ - QRinput_estimateBitsMode8(q - string) /* - 4 - l8 */;
+ if(dif < 0) {
+ break;
+ } else {
+ p = q;
+ }
+ } else {
+ p++;
+ }
+ }
+
+ run = p - string;
+ ret = QRinput_append(input, QR_MODE_8, run, (unsigned char *)string);
+ if(ret < 0) return -1;
+
+ return run;
+}
+
+static int Split_splitString(const char *string, QRinput *input,
+ QRencodeMode hint)
+{
+ int length;
+ QRencodeMode mode;
+
+ if(*string == '\0') return 0;
+
+ mode = Split_identifyMode(string, hint);
+ if(mode == QR_MODE_NUM) {
+ length = Split_eatNum(string, input, hint);
+ } else if(mode == QR_MODE_AN) {
+ length = Split_eatAn(string, input, hint);
+ } else if(mode == QR_MODE_KANJI && hint == QR_MODE_KANJI) {
+ length = Split_eatKanji(string, input, hint);
+ } else {
+ length = Split_eat8(string, input, hint);
+ }
+ if(length == 0) return 0;
+ if(length < 0) return -1;
+ return Split_splitString(&string[length], input, hint);
+}
+
+static char *dupAndToUpper(const char *str, QRencodeMode hint)
+{
+ char *newstr, *p;
+ QRencodeMode mode;
+
+ newstr = strdup(str);
+ if(newstr == NULL) return NULL;
+
+ p = newstr;
+ while(*p != '\0') {
+ mode = Split_identifyMode(p, hint);
+ if(mode == QR_MODE_KANJI) {
+ p += 2;
+ } else {
+ if (*p >= 'a' && *p <= 'z') {
+ *p = (char)((int)*p - 32);
+ }
+ p++;
+ }
+ }
+
+ return newstr;
+}
+
+int Split_splitStringToQRinput(const char *string, QRinput *input,
+ QRencodeMode hint, int casesensitive)
+{
+ char *newstr;
+ int ret;
+
+ if(string == NULL || *string == '\0') {
+ errno = EINVAL;
+ return -1;
+ }
+ if(!casesensitive) {
+ newstr = dupAndToUpper(string, hint);
+ if(newstr == NULL) return -1;
+ ret = Split_splitString(newstr, input, hint);
+ free(newstr);
+ } else {
+ ret = Split_splitString(string, input, hint);
+ }
+
+ return ret;
+}
diff --git a/src/qqrencode/qrencode/split.h b/src/qqrencode/qrencode/split.h
new file mode 100644
index 0000000..b2cdbe5
--- /dev/null
+++ b/src/qqrencode/qrencode/split.h
@@ -0,0 +1,47 @@
+/*
+ * qrencode - QR Code encoder
+ *
+ * Input data splitter.
+ * Copyright (C) 2006-2011 Kentaro Fukuchi
+ *
+ * The following data / specifications are taken from
+ * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
+ * or
+ * "Automatic identification and data capture techniques --
+ * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __SPLIT_H__
+#define __SPLIT_H__
+
+#include "qrencode.h"
+
+/**
+ * Split the input string (null terminated) into QRinput.
+ * @param string input string
+ * @param hint give QR_MODE_KANJI if the input string contains Kanji character encoded in Shift-JIS. If not, give QR_MODE_8.
+ * @param casesensitive 0 for case-insensitive encoding (all alphabet characters are replaced to UPPER-CASE CHARACTERS.
+ * @retval 0 success.
+ * @retval -1 an error occurred. errno is set to indicate the error. See
+ * Exceptions for the details.
+ * @throw EINVAL invalid input object.
+ * @throw ENOMEM unable to allocate memory for input objects.
+ */
+extern int Split_splitStringToQRinput(const char *string, QRinput *input,
+ QRencodeMode hint, int casesensitive);
+
+#endif /* __SPLIT_H__ */