unsigned char *Mask_mask(int width, unsigned char *frame, QRecLevel level) { int i; unsigned char *mask, *bestMask; int minDemerit = INT_MAX; int blacks; int bratio; int demerit; int w2 = width * width; mask = (unsigned char *)malloc(w2); if(mask == NULL) return NULL; bestMask = NULL; for(i=0; i<maskNum; i++) { // n1 = n2 = n3 = n4 = 0; demerit = 0; blacks = maskMakers[i](width, frame, mask); blacks += Mask_writeFormatInformation(width, mask, i, level); bratio = (200 * blacks + w2) / w2 / 2; /* (int)(100*blacks/w2+0.5) */ demerit = (abs(bratio - 50) / 5) * N4; // n4 = demerit; demerit += Mask_evaluateSymbol(width, mask); // printf("(%d,%d,%d,%d)=%d\n", n1, n2, n3 ,n4, demerit); if(demerit < minDemerit) { minDemerit = demerit; free(bestMask); bestMask = mask; mask = (unsigned char *)malloc(w2); if(mask == NULL) break; } } free(mask); return bestMask; }
/* .#.#.#.#.# * #.#.#.#.#. * ..##..##.. * ##..##..## * ...###...# * ###...###. * ....####.. * ####....## * .....##### * #####..... */ void test_eval2(void) { unsigned char *frame; int w = 10; int demerit; int x; frame = (unsigned char *)malloc(w * w); testStart("Test mask evaluation (run length penalty check)"); for(x=0; x<w; x++) { frame[ x] = x & 1; frame[w + x] = (x & 1) ^ 1; frame[w*2 + x] = (x / 2) & 1; frame[w*3 + x] = ((x / 2) & 1) ^ 1; frame[w*4 + x] = (x / 3) & 1; frame[w*5 + x] = ((x / 3) & 1) ^ 1; frame[w*6 + x] = (x / 4) & 1; frame[w*7 + x] = ((x / 4) & 1) ^ 1; frame[w*8 + x] = (x / 5) & 1; frame[w*9 + x] = ((x / 5) & 1) ^ 1; } demerit = Mask_evaluateSymbol(w, frame); testEndExp(demerit == N1 * 4 + N2 * 4); free(frame); }
void test_eval(void) { unsigned char *frame; int w = 6; int demerit; frame = (unsigned char *)malloc(w * w); testStart("Test mask evaluation (all white)"); memset(frame, 0, w * w); demerit = Mask_evaluateSymbol(w, frame); testEndExp(demerit == ((N1 + 1)*w*2 + N2 * (w - 1) * (w - 1))); testStart("Test mask evaluation (all black)"); memset(frame, 1, w * w); demerit = Mask_evaluateSymbol(w, frame); testEndExp(demerit == ((N1 + 1)*w*2 + N2 * (w - 1) * (w - 1))); free(frame); }
void test_eval3(void) { unsigned char *frame; int w = 15; int demerit; int x, y; static unsigned char pattern[7][15] = { {0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0}, // N3x1 {1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1}, // N3x1 {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1}, // N3x1 {1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0}, // 0 {1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1}, // N3x2 {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0}, // N3 + (N1+1) {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1} // (N1+1) }; frame = (unsigned char *)malloc(w * w); testStart("Test mask evaluation (1:1:3:1:1 check)"); for(y=0; y<5; y++) { for(x=0; x<w; x++) { frame[w*y*2 + x] = pattern[y][x]; frame[w*(y*2+1) + x] = pattern[y][x]^1; } } for(x=0; x<w; x++) { frame[w*10 + x] = x & 1; } for(y=5; y<7; y++) { for(x=0; x<w; x++) { frame[w*(y*2+1) + x] = pattern[y][x]; frame[w*(y*2+2) + x] = pattern[y][x]^1; } } /* for(y=0; y<w; y++) { for(x=0; x<w; x++) { printf("%s", frame[w*y+x]?"##":".."); } printf("\n"); } */ demerit = Mask_evaluateSymbol(w, frame); testEndExp(demerit == N3 * 10 + (N1 + 1) * 4); free(frame); }
unsigned char *Mask_mask(int width, unsigned char *frame, QRecLevel level) { int i; unsigned char *mask, *bestMask; int minDemerit = INT_MAX; // int bestMaskNum = 0; int blacks; int demerit = 0; mask = (unsigned char *)malloc(width * width); if(mask == NULL) return NULL; bestMask = NULL; for(i=0; i<8; i++) { // n1 = n2 = n3 = n4 = 0; // demerit = 0; blacks = maskMakers[i](width, frame, mask); blacks += Mask_writeFormatInformation(width, mask, i, level); blacks = 100 * blacks / (width * width); demerit = (abs(blacks - 50) / 5) * N4; // n4 = demerit; demerit += Mask_evaluateSymbol(width, mask); // printf("(%d,%d,%d,%d)=%d\n", n1, n2, n3 ,n4, demerit); if(demerit < minDemerit) { minDemerit = demerit; // bestMaskNum = i; if(bestMask != NULL) { free(bestMask); } bestMask = (unsigned char *)malloc(width * width); if(bestMask == NULL) break; memcpy(bestMask, mask, width * width); } } free(mask); return bestMask; }