unsigned char *MMask_mask(int version, unsigned char *frame, QRecLevel level) { int i; unsigned char *mask, *bestMask; int maxScore = 0; int score; int width; width = MQRspec_getWidth(version); mask = (unsigned char *)malloc(width * width); if(mask == NULL) return NULL; bestMask = NULL; for(i=0; i<maskNum; i++) { score = 0; maskMakers[i](width, frame, mask); MMask_writeFormatInformation(version, width, mask, i, level); score = MMask_evaluateSymbol(width, mask); if(score > maxScore) { maxScore = score; free(bestMask); bestMask = mask; mask = (unsigned char *)malloc(width * width); if(mask == NULL) break; } } free(mask); return bestMask; }
extern unsigned char *FrameFiller_testMQR(int version) { int width; unsigned char *frame, *p; FrameFiller *filler; int i, length; width = MQRspec_getWidth(version); frame = MQRspec_newFrame(version); if(frame == NULL) return NULL; filler = FrameFiller_new(width, frame, 1); if(filler == NULL) { free(frame); return NULL; } length = MQRspec_getDataLengthBit(version, QR_ECLEVEL_L) + MQRspec_getECCLength(version, QR_ECLEVEL_L) * 8; for(i=0; i<length; i++) { p = FrameFiller_next(filler); if(p == NULL) { fprintf(stderr, "Frame filler run over the frame!\n"); free(filler); return frame; } *p = (unsigned char)(i & 0x7f) | 0x80; } free(filler); return frame; }
void test_fillerMQR(void) { unsigned char *frame; int i, j, w, e, length; testStart("Micro QR Code Frame filler test"); for(i=1; i<=MQRSPEC_VERSION_MAX; i++) { length = MQRspec_getDataLengthBit(i, QR_ECLEVEL_L) + MQRspec_getECCLength(i, QR_ECLEVEL_L) * 8; frame = FrameFiller_testMQR(i); if(frame == NULL) { assert_nonnull(frame, "Something wrong in version %d\n", i); } else { w = MQRspec_getWidth(i); e = 0; for(j=0; j<w*w; j++) { if(frame[j] == 0) e++; } assert_zero(e, "Not filled bit is found. (%d,%d)\n", j%w,j/w); if(i & 1) { e = w * 9 + 1; } else { e = w * (w - 1) + 1; } assert_equal(frame[e], (unsigned char)((length - 1) & 127) | 0x80, "Number of cell does not match in version %d.\n", i); free(frame); } } testFinish(); }
__STATIC QRcode *QRcode_encodeMaskMQR(QRinput *input, int mask) { int width, version; MQRRawCode *raw; unsigned char *frame, *masked, *p, code, bit; FrameFiller *filler; int i, j; QRcode *qrcode = NULL; if(!input->mqr) { errno = EINVAL; return NULL; } if(input->version <= 0 || input->version > MQRSPEC_VERSION_MAX) { errno = EINVAL; return NULL; } if(input->level > QR_ECLEVEL_Q) { errno = EINVAL; return NULL; } raw = MQRraw_new(input); if(raw == NULL) return NULL; version = raw->version; width = MQRspec_getWidth(version); frame = MQRspec_newFrame(version); if(frame == NULL) { MQRraw_free(raw); return NULL; } filler = FrameFiller_new(width, frame, 1); if(filler == NULL) { MQRraw_free(raw); free(frame); return NULL; } /* inteleaved data and ecc codes */ for(i=0; i<raw->dataLength + raw->eccLength; i++) { code = MQRraw_getCode(raw); if(raw->oddbits && i == raw->dataLength - 1) { bit = 1 << (raw->oddbits - 1); for(j=0; j<raw->oddbits; j++) { p = FrameFiller_next(filler); if(p == NULL) goto EXIT; *p = 0x02 | ((bit & code) != 0); bit = bit >> 1; } } else {
void print_fillerMQR(void) { int width; int version = 3; unsigned char *frame; for(version = 1; version <= MQRSPEC_VERSION_MAX; version++) { width = MQRspec_getWidth(version); frame = FrameFiller_testMQR(version); if(frame == NULL) abort(); printFrame(width, frame); } }
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(); }
unsigned char *MMask_makeMask(int version, unsigned char *frame, int mask, QRecLevel level) { unsigned char *masked; int width; if(mask < 0 || mask >= maskNum) { errno = EINVAL; return NULL; } width = MQRspec_getWidth(version); masked = (unsigned char *)malloc(width * width); if(masked == NULL) return NULL; maskMakers[mask](width, frame, masked); MMask_writeFormatInformation(version, width, masked, mask, level); return masked; }
STATIC_IN_RELEASE QRcode *QRcode_encodeMaskMQR(QRinput *input, int mask) { int width, version; MQRRawCode *raw; unsigned char *frame, *masked, *p, code, bit; int i, j, length; QRcode *qrcode = NULL; FrameFiller filler; if(!input->mqr) { errno = EINVAL; return NULL; } if(input->version <= 0 || input->version > MQRSPEC_VERSION_MAX) { errno = EINVAL; return NULL; } if(input->level > QR_ECLEVEL_Q) { errno = EINVAL; return NULL; } raw = MQRraw_new(input); if(raw == NULL) return NULL; version = raw->version; width = MQRspec_getWidth(version); frame = MQRspec_newFrame(version); if(frame == NULL) { MQRraw_free(raw); return NULL; } FrameFiller_set(&filler, width, frame, 1); /* interleaved data and ecc codes */ for(i = 0; i < raw->dataLength; i++) { code = MQRraw_getCode(raw); bit = 0x80; if(raw->oddbits && i == raw->dataLength - 1) { length = raw->oddbits; } else { length = 8; } for(j = 0; j < length; j++) { p = FrameFiller_next(&filler); if(p == NULL) goto EXIT; *p = ((bit & code) != 0); bit = bit >> 1; } } for(i = 0; i < raw->eccLength; i++) { code = MQRraw_getCode(raw); bit = 0x80; length = 8; for(j = 0; j < length; j++) { p = FrameFiller_next(&filler); if(p == NULL) goto EXIT; *p = 0x02 | ((bit & code) != 0); bit = bit >> 1; } } MQRraw_free(raw); raw = NULL; /* masking */ if(mask == -2) { // just for debug purpose masked = (unsigned char *)malloc(width * width); memcpy(masked, frame, width * width); } else if(mask < 0) { masked = MMask_mask(version, frame, input->level); } else { masked = MMask_makeMask(version, frame, mask, input->level); } if(masked == NULL) { goto EXIT; } qrcode = QRcode_new(version, width, masked); if(qrcode == NULL) { free(masked); } EXIT: MQRraw_free(raw); free(frame); return qrcode; }