#include <stdio.h>
#include <string.h>
#include "common.h"
#include "../mqrspec.h"
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
};
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();
}
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}
};
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);
}
void print_format(void)
{
unsigned int format;
int i, j;
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.
*/
int datalen[4][3] = {
{ 20, 0, 0},
{ 40, 32, 0},
{ 84, 68, 0},
{128, 112, 80},
};
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(void)
{
test_newFrame();
test_newframe_invalid();
//print_format();
test_format();
test_dataLength();
MQRspec_clearCache();
report();
return 0;
}