Edit

kc3-lang/libqrencode/tests/test_mqrspec.c

Branch :

  • Show log

    Commit

  • Author : fukuchi
    Date : 2009-06-03 20:48:24
    Hash : 0ac44406
    Message : Bug fix.

  • tests/test_mqrspec.c
  • #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<=4; version++) {
    		for(l=0; l<3; 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;
    }