]> git.sur5r.net Git - glabels/blobdiff - qrencode-3.1.0/tests/test_qrspec.c
Organized master branch to be top-level directory for glabels, instead of
[glabels] / qrencode-3.1.0 / tests / test_qrspec.c
diff --git a/qrencode-3.1.0/tests/test_qrspec.c b/qrencode-3.1.0/tests/test_qrspec.c
new file mode 100644 (file)
index 0000000..792915f
--- /dev/null
@@ -0,0 +1,307 @@
+#include <stdio.h>
+#include <string.h>
+#include "common.h"
+#include "../qrspec.h"
+
+void print_eccTable(void)
+{
+       int i, j;
+       int ecc;
+       int data;
+       int spec[5];
+
+       for(i=1; i<=QRSPEC_VERSION_MAX; i++) {
+               printf("Version %2d\n", i);
+               for(j=0; j<4; j++) {
+                       QRspec_getEccSpec(i, (QRecLevel)j, spec);
+                       data = QRspec_rsBlockNum1(spec) * QRspec_rsDataCodes1(spec)
+                            + QRspec_rsBlockNum2(spec) * QRspec_rsDataCodes2(spec);
+                       ecc  = QRspec_rsBlockNum1(spec) * QRspec_rsEccCodes1(spec)
+                            + QRspec_rsBlockNum2(spec) * QRspec_rsEccCodes2(spec);
+                       printf("%3d\t", ecc);
+                       printf("%2d\t", QRspec_rsBlockNum1(spec));
+                       printf("(%3d, %3d, %3d)\n",
+                                  QRspec_rsDataCodes1(spec) + QRspec_rsEccCodes1(spec),
+                                  QRspec_rsDataCodes1(spec),
+                                  QRspec_rsEccCodes1(spec));
+                       if(QRspec_rsBlockNum2(spec) > 0) {
+                               printf("\t%2d\t", QRspec_rsBlockNum2(spec));
+                               printf("(%3d, %3d, %3d)\n",
+                                          QRspec_rsDataCodes2(spec) + QRspec_rsEccCodes2(spec),
+                                          QRspec_rsDataCodes2(spec),
+                                          QRspec_rsEccCodes2(spec));
+                       }
+               }
+       }
+}
+
+void test_eccTable(void)
+{
+       int i, j;
+       int ecc;
+       int data;
+       int err = 0;
+       int spec[5];
+
+       testStart("Checking ECC table.");
+       for(i=1; i<=QRSPEC_VERSION_MAX; i++) {
+               for(j=0; j<4; j++) {
+                       QRspec_getEccSpec(i, (QRecLevel)j, spec);
+                       data = QRspec_rsBlockNum1(spec) * QRspec_rsDataCodes1(spec)
+                            + QRspec_rsBlockNum2(spec) * QRspec_rsDataCodes2(spec);
+                       ecc  = QRspec_rsBlockNum1(spec) * QRspec_rsEccCodes1(spec)
+                            + QRspec_rsBlockNum2(spec) * QRspec_rsEccCodes2(spec);
+                       if(data + ecc != QRspec_getDataLength(i, (QRecLevel)j) + QRspec_getECCLength(i, (QRecLevel)j)) {
+                               printf("Error in version %d, level %d: invalid size\n", i, j);
+                               printf("%d %d %d %d %d %d\n", spec[0], spec[1], spec[2], spec[3], spec[4], spec[2]);
+                               err++;
+                       }
+                       if(ecc != QRspec_getECCLength(i, (QRecLevel)j)) {
+                               printf("Error in version %d, level %d: invalid data\n", i, j);
+                               printf("%d %d %d %d %d %d\n", spec[0], spec[1], spec[2], spec[3], spec[4], spec[2]);
+                               err++;
+                       }
+               }
+       }
+       testEnd(err);
+}
+
+void test_eccTable2(void)
+{
+       int i;
+       int spec[5];
+
+       const int correct[7][6] = {
+               { 8,  1, 0,  2, 60, 38},
+               { 8,  1, 1,  2, 61, 39},
+               {24,  2, 0, 11, 54, 24},
+               {24,  2, 1, 16, 55, 25},
+               {32,  0, 0, 17, 145, 115},
+               {40,  3, 0, 20, 45, 15},
+               {40,  3, 1, 61, 46, 16},
+       };
+
+       testStart("Checking ECC table(2)");
+       for(i=0; i<7; i++) {
+               QRspec_getEccSpec(correct[i][0], (QRecLevel)correct[i][1], spec);
+               if(correct[i][2] == 0) {
+                       assert_equal(QRspec_rsBlockNum1(spec), correct[i][3],
+                               "Error in version %d, level %d. rsBlockNum1 was %d, expected %d.\n",
+                               correct[i][0], correct[i][1],
+                               QRspec_rsBlockNum1(spec), correct[i][3]);
+                       assert_equal(QRspec_rsDataCodes1(spec) + QRspec_rsEccCodes1(spec), correct[i][4],
+                               "Error in version %d, level %d. rsDataCodes1 + rsEccCodes1 was %d, expected %d.\n",
+                               correct[i][0], correct[i][1],
+                               QRspec_rsDataCodes1(spec) + QRspec_rsEccCodes1(spec), correct[i][4]);
+                       assert_equal(QRspec_rsDataCodes1(spec), correct[i][5],
+                               "Error in version %d, level %d. rsDataCodes1 was %d, expected %d.\n",
+                               correct[i][0], correct[i][1],
+                               QRspec_rsDataCodes1(spec), correct[i][5]);
+               } else {
+                       assert_equal(QRspec_rsBlockNum2(spec), correct[i][3],
+                               "Error in version %d, level %d. rsBlockNum2 was %d, expected %d.\n",
+                               correct[i][0], correct[i][1],
+                               QRspec_rsBlockNum2(spec), correct[i][3]);
+                       assert_equal(QRspec_rsDataCodes2(spec) + QRspec_rsEccCodes2(spec), correct[i][4],
+                               "Error in version %d, level %d. rsDataCodes2 + rsEccCodes2 was %d, expected %d.\n",
+                               correct[i][0], correct[i][1],
+                               QRspec_rsDataCodes2(spec) + QRspec_rsEccCodes2(spec), correct[i][4]);
+                       assert_equal(QRspec_rsDataCodes2(spec), correct[i][5],
+                               "Error in version %d, level %d. rsDataCodes2 was %d, expected %d.\n",
+                               correct[i][0], correct[i][1],
+                               QRspec_rsDataCodes2(spec), correct[i][5]);
+               }
+       }
+       testFinish();
+}
+
+void test_newframe(void)
+{
+       unsigned char buf[QRSPEC_WIDTH_MAX * QRSPEC_WIDTH_MAX];
+       int i, width;
+       size_t len;
+       FILE *fp;
+       unsigned char *frame;
+
+       testStart("Checking newly created frame.");
+       fp = fopen("frame", "rb");
+       if(fp == NULL) {
+               perror("Failed to open \"frame\":");
+               abort();
+       }
+       for(i=1; i<=QRSPEC_VERSION_MAX; i++) {
+               frame = QRspec_newFrame(i);
+               width = QRspec_getWidth(i);
+               len = fread(buf, 1, width * width, fp);
+               if((int)len != width * width) {
+                       perror("Failed to read the pattern file:");
+                       abort();
+               }
+               assert_zero(memcmp(frame, buf, len), "frame pattern mismatch (version %d)\n", i);
+               free(frame);
+       }
+
+       testFinish();
+       fclose(fp);
+}
+
+#if 0
+/* This test is used to check positions of alignment pattern. See Appendix E
+ * (pp.71) of JIS X0510:2004 and compare to the output. Before comment out
+ * this test, change the value of the pattern marker's center dot from 0xa1
+ * to 0xb1 (QRspec_putAlignmentMarker() : finder).
+ */
+void test_alignment(void)
+{
+       unsigned char *frame;
+       int i, x, y, width, c;
+
+       testStart("Checking alignment pattern.");
+       for(i=2; i<=QRSPEC_VERSION_MAX; i++) {
+               printf("%2d", i);
+               frame = QRspec_newFrame(i);
+               width = QRspec_getWidth(i);
+               c = 0;
+               for(x=0; x<width * width; x++) {
+                       if(frame[x] == 0xb1) {
+                               c++;
+                       }
+               }
+               printf("|%2d|   6", c);
+               y = width - 7;
+               for(x=0; x < width; x++) {
+                       if(frame[y * width + x] == 0xb1) {
+                               printf(", %3d", x);
+                       }
+               }
+               printf("\n");
+               free(frame);
+       }
+       testFinish();
+}
+#endif
+
+void test_verpat(void)
+{
+       int version;
+       unsigned int pattern;
+       int err = 0;
+       unsigned int data;
+       unsigned int code;
+       int i, c;
+       unsigned int mask;
+
+       for(version=7; version <= QRSPEC_VERSION_MAX; version++) {
+               pattern = QRspec_getVersionPattern(version);
+               if((pattern >> 12) != (unsigned int)version) {
+                       printf("Error in version %d.\n", version);
+                       err++;
+                       continue;
+               }
+               mask = 0x40;
+               for(i=0; mask != 0; i++) {
+                       if(version & mask) break;
+                       mask = mask >> 1;
+               }
+               c = 6 - i;
+               data = version << 12;
+               code = 0x1f25 << c;
+               mask = 0x40000 >> (6 - c);
+               for(i=0; i<=c; i++) {
+                       if(mask & data) {
+                               data ^= code;
+                       }
+                       code = code >> 1;
+                       mask = mask >> 1;
+               }
+               data = (version << 12) | (data & 0xfff);
+               if(data != pattern) {
+                       printf("Error in version %d\n", version);
+                       err++;
+               }
+       }
+}
+
+void print_newFrame(void)
+{
+       int width;
+       int x, y;
+       unsigned char *frame;
+
+       frame = QRspec_newFrame(7);
+       width = QRspec_getWidth(7);
+       for(y=0; y<width; y++) {
+               for(x=0; x<width; x++) {
+                       printf("%02x ", frame[y * width + x]);
+               }
+               printf("\n");
+       }
+       free(frame);
+}
+
+/* See Table 22 (pp.45) and Appendix C (pp. 65) of JIS X0510:2004 */
+static unsigned int levelIndicator[4] = {1, 0, 3, 2};
+static unsigned int calcFormatInfo(int mask, QRecLevel level)
+{
+       unsigned int data, ecc, b, code;
+       int i, c;
+
+       data = (levelIndicator[level] << 13) | (mask << 10);
+       ecc = data;
+       b = 1 << 14;
+       for(i=0; b != 0; i++) {
+               if(ecc & b) break;
+               b = b >> 1;
+       }
+       c = 4 - i;
+       code = 0x537 << c ; //10100110111
+       b = 1 << (10 + c);
+       for(i=0; i<=c; i++) {
+               if(b & ecc) {
+                       ecc ^= code;
+               }
+               code = code >> 1;
+               b = b >> 1;
+       }
+       
+       return (data | ecc) ^ 0x5412;
+}
+
+void test_format(void)
+{
+       unsigned int format;
+       int i, j;
+       int err = 0;
+
+       testStart("Format info test");
+       for(i=0; i<4; i++) {
+               for(j=0; j<8; j++) {
+                       format = calcFormatInfo(j, (QRecLevel)i);
+//                     printf("0x%04x, ", format);
+                       if(format != QRspec_getFormatInfo(j, (QRecLevel)i)) {
+                               printf("Level %d, mask %x\n", i, j);
+                               err++;
+                       }
+               }
+//             printf("\n");
+       }
+       testEnd(err);
+}
+
+int main(int argc, char **argv)
+{
+       test_eccTable();
+       test_eccTable2();
+       //print_eccTable();
+       test_newframe();
+       //test_alignment();
+       test_verpat();
+       //print_newFrame();
+       test_format();
+
+       QRspec_clearCache();
+
+       report();
+
+       return 0;
+}