summaryrefslogtreecommitdiff
path: root/genqrcode/tests/test_mqrspec.c
diff options
context:
space:
mode:
Diffstat (limited to 'genqrcode/tests/test_mqrspec.c')
-rw-r--r--genqrcode/tests/test_mqrspec.c181
1 files changed, 181 insertions, 0 deletions
diff --git a/genqrcode/tests/test_mqrspec.c b/genqrcode/tests/test_mqrspec.c
new file mode 100644
index 0000000000..3a4b18950b
--- /dev/null
+++ b/genqrcode/tests/test_mqrspec.c
@@ -0,0 +1,181 @@
+#include <stdio.h>
+#include <string.h>
+#include "common.h"
+#include "../mqrspec.h"
+
+static unsigned char v4frame[] = {
+ 0xc1,0xc1,0xc1,0xc1,0xc1,0xc1,0xc1,0xc0,0x91,0x90,0x91,0x90,0x91,0x90,0x91,0x90,0x91,
+ 0xc1,0xc0,0xc0,0xc0,0xc0,0xc0,0xc1,0xc0,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xc1,0xc0,0xc1,0xc1,0xc1,0xc0,0xc1,0xc0,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xc1,0xc0,0xc1,0xc1,0xc1,0xc0,0xc1,0xc0,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xc1,0xc0,0xc1,0xc1,0xc1,0xc0,0xc1,0xc0,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xc1,0xc0,0xc0,0xc0,0xc0,0xc0,0xc1,0xc0,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xc1,0xc1,0xc1,0xc1,0xc1,0xc1,0xc1,0xc0,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x91,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x91,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x91,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x91,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x91,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+};
+
+static void test_newFrame(void)
+{
+ int width, i, y;
+ unsigned char *frame;
+
+ testStart("Test empty frames");
+ for(i=1; i<MQRSPEC_VERSION_MAX; i++) {
+ frame = MQRspec_newFrame(i);
+ width = MQRspec_getWidth(i);
+ for(y=0; y<width; y++) {
+ assert_zero(memcmp(&frame[y * width], &v4frame[y * MQRSPEC_WIDTH_MAX], width), "Mismatch found in version %d, line %d.\n", i, y);
+ }
+ free(frame);
+ }
+ testFinish();
+}
+
+static void test_newframe_invalid(void)
+{
+ unsigned char *frame;
+
+ testStart("Checking MQRspec_newFrame with invalid version.");
+ frame = MQRspec_newFrame(0);
+ assert_null(frame, "MQRspec_newFrame(0) returns non-NULL.");
+ frame = MQRspec_newFrame(MQRSPEC_VERSION_MAX+1);
+ assert_null(frame, "MQRspec_newFrame(0) returns non-NULL.");
+ testFinish();
+}
+
+/* See Table 10 (pp.115) of Appendix 1, JIS X0510:2004 */
+static unsigned int calcFormatInfo(int type, int mask)
+{
+ unsigned int data, ecc, b, code;
+ int i, c;
+
+ data = (type << 12) | (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) ^ 0x4445;
+}
+
+/* See Table 10 of Appendix 1. (pp.115) */
+static const int typeTable[4][3] = {
+ { 0, -1, -1},
+ { 1, 2, -1},
+ { 3, 4, -1},
+ { 5, 6, 7}
+};
+
+static void test_format(void)
+{
+ unsigned int format;
+ int version, l, mask;
+ int type;
+ int err = 0;
+
+ testStart("Format info test");
+ for(version=1; version<=MQRSPEC_VERSION_MAX; version++) {
+ for(l=QR_ECLEVEL_L; l<=QR_ECLEVEL_Q; l++) {
+ for(mask=0; mask<4; mask++) {
+ format = MQRspec_getFormatInfo(mask, version, (QRecLevel)l);
+ type = typeTable[version - 1][l];
+ if(type == -1) {
+ if(format != 0) {
+ printf("Error in version %d, level %d, mask %d\n",
+ version, l, mask);
+ err++;
+ }
+ } else {
+ if(format != calcFormatInfo(type, mask)) {
+ printf("Error in version %d, level %d, mask %d\n",
+ version, l, mask);
+ err++;
+ }
+ }
+ }
+ }
+ }
+ testEnd(err);
+}
+
+static void print_format(void)
+{
+ unsigned int format;
+ int i, j;
+
+ puts("\nPrinting hex strings of format information.");
+ for(i=0; i<4; i++) {
+ for(j=0; j<8; j++) {
+ format = calcFormatInfo(j, i);
+ printf("0x%04x, ", format);
+ }
+ printf("\n");
+ }
+}
+
+/**
+ * See Table 7 of Appendix 1.
+ */
+static int datalen[4][3] = {
+ { 20, 0, 0},
+ { 40, 32, 0},
+ { 84, 68, 0},
+ {128, 112, 80},
+};
+
+static void test_dataLength(void)
+{
+ int v, l;
+ int bits;
+ int err = 0;
+
+ testStart("Test dataLength");
+ for(v=0; v<4; v++) {
+ for(l=0; l<3; l++) {
+ bits = MQRspec_getDataLengthBit(v+1, (QRecLevel)l);
+ if(bits != datalen[v][l]) {
+ printf("Error in version %d, level %d.\n", v, l);
+ err++;
+ }
+ }
+ }
+ testEnd(err);
+}
+
+int main(int argc, char **argv)
+{
+ int tests = 4;
+ testInit(tests);
+ test_newFrame();
+ test_newframe_invalid();
+ test_format();
+ test_dataLength();
+ testReport(tests);
+
+ if(argc > 1) {
+ print_format();
+ }
+
+ return 0;
+}