[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit
Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/app/qrencode/qrspec.c b/ap/app/qrencode/qrspec.c
new file mode 100644
index 0000000..a42706f
--- /dev/null
+++ b/ap/app/qrencode/qrspec.c
@@ -0,0 +1,562 @@
+/*
+ * qrencode - QR Code encoder
+ *
+ * QR Code specification in convenient format.
+ * Copyright (C) 2006-2011 Kentaro Fukuchi <kentaro@fukuchi.org>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#ifdef HAVE_LIBPTHREAD
+#include <pthread.h>
+#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<w - 1; x++) {
+ QRspec_putAlignmentMarker(frame, width, 6, cx);
+ QRspec_putAlignmentMarker(frame, width, cx, 6);
+ cx += d;
+ }
+
+ cy = alignmentPattern[version][0];
+ for(y=0; y<w-1; y++) {
+ cx = alignmentPattern[version][0];
+ for(x=0; x<w-1; x++) {
+ QRspec_putAlignmentMarker(frame, width, cx, cy);
+ cx += d;
+ }
+ cy += d;
+ }
+}
+
+/******************************************************************************
+ * Version information pattern
+ *****************************************************************************/
+
+/**
+ * Version information pattern (BCH coded).
+ * See Table 1 in Appendix D (pp.68) of JIS X0510:2004.
+ */
+static const unsigned int versionPattern[QRSPEC_VERSION_MAX - 6] = {
+ 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
+ 0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
+ 0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,
+ 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,
+ 0x27541, 0x28c69
+};
+
+unsigned int QRspec_getVersionPattern(int version)
+{
+ if(version < 7 || version > 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<width-15; x++) {
+ *p = 0x90 | (x & 1);
+ *q = 0x90 | (x & 1);
+ p++;
+ q += width;
+ }
+ /* Alignment pattern */
+ QRspec_putAlignmentPattern(version, frame, width);
+
+ /* Version information */
+ if(version >= 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
+}