From 50ed255c576fc2fc92e1da12b5e7db0ed04ae44b Mon Sep 17 00:00:00 2001 From: hooper114 Date: Sat, 31 Oct 2009 13:16:36 +0000 Subject: [PATCH] Move Micro QR to qr.c --- backend/micqr.c | 953 ------------------------------------------------ backend/micqr.h | 103 ------ 2 files changed, 1056 deletions(-) delete mode 100644 backend/micqr.c delete mode 100644 backend/micqr.h diff --git a/backend/micqr.c b/backend/micqr.c deleted file mode 100644 index 043800aa..00000000 --- a/backend/micqr.c +++ /dev/null @@ -1,953 +0,0 @@ -/* micqr.c - Handles Micro QR Code versions M1 - M4 */ - -/* - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#include -#include -#include -#include "common.h" -#include "reedsol.h" -#include "micqr.h" - -#define NUMERIC 1 -#define ALPHANUM 2 -#define BYTE 3 -#define KANJI 4 - -#define RHODIUM "0123456789ABCDEFGHIJKLNMOPQRSTUVWXYZ $%*+-./:" - -void qrnumeric_encode(char binary[], unsigned char source[], int length) -{ /* Encodes numeric data according to section 6.4.3 */ - - int blocks, remainder, i; - char block_binary[11]; - int block_value; - - block_value = 0; - blocks = length / 3; - remainder = length % 3; - - for(i = 0; i < blocks; i++) { - block_value = ctoi(source[(i * 3)]) * 100; - block_value += ctoi(source[(i * 3) + 1]) * 10; - block_value += ctoi(source[(i * 3) + 2]); - - strcpy(block_binary, ""); - if(block_value & 0x200) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x100) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x80) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - concat(binary, block_binary); - } - - if(remainder == 2) { - block_value = ctoi(source[(i * 3)]) * 10; - block_value += ctoi(source[(i * 3) + 1]); - } - if(remainder == 1) { - block_value = ctoi(source[(i * 3)]); - } - - strcpy(block_binary, ""); - switch(remainder) { - case 2: - if(block_value & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - case 1: - if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - break; - } - concat(binary, block_binary); - - return; -} - -void qralpha_encode(char binary[], unsigned char source[], int length) -{ /* Encodes alphanumeric data according to 6.4.4 */ - - int blocks, remainder, i; - char block_binary[12]; - int block_value; - - blocks = length / 2; - remainder = length % 2; - - for(i = 0; i < blocks; i++) { - block_value = posn(RHODIUM, source[i * 2]) * 45; - block_value += posn(RHODIUM, source[(i * 2) + 1]); - - strcpy(block_binary, ""); - if(block_value & 0x400) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x200) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x100) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x80) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - concat(binary, block_binary); - } - - if(remainder == 1) { - block_value = posn(RHODIUM, source[i * 2]); - - strcpy(block_binary, ""); - if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); } - concat(binary, block_binary); - } - - return; -} - -void qrbyte_encode(char binary[], unsigned char source[], int length) -{ /* Encodes byte mode data according to 6.4.5 */ - - int i; - - for(i = 0; i < length; i++) { - if(source[i] & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } - if(source[i] & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } - if(source[i] & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } - if(source[i] & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } - if(source[i] & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } - if(source[i] & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } - if(source[i] & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } - if(source[i] & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } - } - - return; -} - -int qrkanji_encode(char binary[], unsigned char source[], int length) -{ /* Assumes input is in Shift-JIS format */ - int i, h, val, count; - - count = 0; - - for(i = 0; i < length; i += 2) { - val = (source[i] << 8) | source[i+1]; - if(val <= 0x9ffc) { - val -= 0x8140; - } else { - val -= 0xc140; - } - h = (val >> 8) * 0xc0; - val = (val & 0xff) + h; - - if(val & 0x1000) { concat(binary, "1"); } else { concat(binary, "0"); } - if(val & 0x800) { concat(binary, "1"); } else { concat(binary, "0"); } - if(val & 0x400) { concat(binary, "1"); } else { concat(binary, "0"); } - if(val & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } - if(val & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } - if(val & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } - if(val & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } - if(val & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } - if(val & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } - if(val & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } - if(val & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } - if(val & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } - if(val & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } - count++; - } - - return count; -} - -void versionm1(char binary_data[], unsigned char source[], int length) -{ - int i, latch; - int bits_total, bits_left, remainder; - int data_codewords, ecc_codewords; - unsigned char data_blocks[4], ecc_blocks[3]; - - bits_total = 20; - latch = 0; - - /* Character count indicator */ - if(length & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(length & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(length & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - - qrnumeric_encode(binary_data, source, length); - - /* Add terminator */ - bits_left = bits_total - strlen(binary_data); - if(bits_left <= 3) { - for(i = 0; i < bits_left; i++) { - concat(binary_data, "0"); - } - latch = 1; - } else { - concat(binary_data, "000"); - } - - if(latch == 0) { - /* Manage last (4-bit) block */ - bits_left = bits_total - strlen(binary_data); - if(bits_left <= 4) { - for(i = 0; i < bits_left; i++) { - concat(binary_data, "0"); - } - latch = 1; - } - } - - if(latch == 0) { - /* Complete current byte */ - remainder = 8 - (strlen(binary_data) % 8); - if(remainder == 8) { remainder = 0; } - for(i = 0; i < remainder; i++) { - concat(binary_data, "0"); - } - - /* Add padding */ - bits_left = bits_total - strlen(binary_data); - if(bits_left > 4) { - remainder = (bits_left - 4) / 8; - for(i = 0; i < remainder; i++) { - if((i % 2) == 0) { concat(binary_data, "11101100"); } - if((i % 2) == 1) { concat(binary_data, "00010001"); } - } - } - concat(binary_data, "0000"); - } - - data_codewords = 3; - ecc_codewords = 2; - - /* Copy data into codewords */ - for(i = 0; i < (data_codewords - 1); i++) { - data_blocks[i] = 0; - if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; } - if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; } - if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; } - if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; } - if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; } - if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; } - if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; } - if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; } - } - data_blocks[2] = 0; - if(binary_data[16] == '1') { data_blocks[2] += 0x08; } - if(binary_data[17] == '1') { data_blocks[2] += 0x04; } - if(binary_data[18] == '1') { data_blocks[2] += 0x02; } - if(binary_data[19] == '1') { data_blocks[2] += 0x01; } - - /* Calculate Reed-Solomon error codewords */ - rs_init_gf(0x11d); - rs_init_code(ecc_codewords, 0); - rs_encode(data_codewords,data_blocks,ecc_blocks); - rs_free(); - - /* Add Reed-Solomon codewords to binary data */ - for(i = 0; i < ecc_codewords; i++) { - if(ecc_blocks[ecc_codewords - i - 1] & 0x80) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x40) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x20) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x08) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - } - - return; -} - -void versionm2(char binary_data[], unsigned char source[], int length, int char_system, int ecc_mode) -{ - int i, latch; - int bits_total, bits_left, remainder; - int data_codewords, ecc_codewords; - unsigned char data_blocks[6], ecc_blocks[7]; - - latch = 0; - - if(ecc_mode == 1) { bits_total = 40; } - if(ecc_mode == 2) { bits_total = 32; } - - /* Mode indicator */ - if(char_system == NUMERIC) { concat(binary_data, "0"); } - if(char_system == ALPHANUM) { concat(binary_data, "1"); } - - /* Character count indicator */ - if(char_system == NUMERIC) { - if(length & 0x08) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - } - if(length & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(length & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(length & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - - if(char_system == NUMERIC) { qrnumeric_encode(binary_data, source, length); } - if(char_system == ALPHANUM) { qralpha_encode(binary_data, source, length); } - - /* Add terminator */ - bits_left = bits_total - strlen(binary_data); - if(bits_left <= 5) { - for(i = 0; i < bits_left; i++) { - concat(binary_data, "0"); - } - latch = 1; - } else { - concat(binary_data, "00000"); - } - - if(latch == 0) { - /* Complete current byte */ - remainder = 8 - (strlen(binary_data) % 8); - if(remainder == 8) { remainder = 0; } - for(i = 0; i < remainder; i++) { - concat(binary_data, "0"); - } - - /* Add padding */ - bits_left = bits_total - strlen(binary_data); - remainder = bits_left / 8; - for(i = 0; i < remainder; i++) { - if((i % 2) == 0) { concat(binary_data, "11101100"); } - if((i % 2) == 1) { concat(binary_data, "00010001"); } - } - } - - if(ecc_mode == 1) { data_codewords = 5; ecc_codewords = 5; } - if(ecc_mode == 2) { data_codewords = 4; ecc_codewords = 6; } - - /* Copy data into codewords */ - for(i = 0; i < data_codewords; i++) { - data_blocks[i] = 0; - if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; } - if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; } - if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; } - if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; } - if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; } - if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; } - if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; } - if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; } - } - - /* Calculate Reed-Solomon error codewords */ - rs_init_gf(0x11d); - rs_init_code(ecc_codewords, 0); - rs_encode(data_codewords,data_blocks,ecc_blocks); - rs_free(); - - /* Add Reed-Solomon codewords to binary data */ - for(i = 0; i < ecc_codewords; i++) { - if(ecc_blocks[ecc_codewords - i - 1] & 0x80) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x40) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x20) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x08) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - } - - return; -} - -void versionm3(char binary_data[], unsigned char source[], int length, int char_system, int ecc_mode) -{ - int i, latch; - int bits_total, bits_left, remainder; - int data_codewords, ecc_codewords; - unsigned char data_blocks[12], ecc_blocks[9]; - int sjis_count; - - latch = 0; - - if(ecc_mode == 1) { bits_total = 84; } - if(ecc_mode == 2) { bits_total = 68; } - - /* Mode indicator */ - if(char_system == NUMERIC) { concat(binary_data, "00"); } - if(char_system == ALPHANUM) { concat(binary_data, "01"); } - if(char_system == BYTE) { concat(binary_data, "10"); } - if(char_system == KANJI) { concat(binary_data, "11"); } - - /* Character count indicator */ - if(char_system == KANJI) { - concat(binary_data, "XXX"); /* Place holder */ - } else { - if(char_system == NUMERIC) { - if(length & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - } - if(length & 0x08) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(length & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(length & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(length & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - } - - if(char_system == NUMERIC) { qrnumeric_encode(binary_data, source, length); } - if(char_system == ALPHANUM) { qralpha_encode(binary_data, source, length); } - if(char_system == BYTE) { qrbyte_encode(binary_data, source, length); } - if(char_system == KANJI) { sjis_count = qrkanji_encode(binary_data, source, length); } - - if(char_system == KANJI) { - if(sjis_count & 0x04) { binary_data[2] = '1'; } else { binary_data[2] = '0'; } - if(sjis_count & 0x02) { binary_data[3] = '1'; } else { binary_data[3] = '0'; } - if(sjis_count & 0x01) { binary_data[4] = '1'; } else { binary_data[4] = '0'; } - } - - /* Add terminator */ - bits_left = bits_total - strlen(binary_data); - if(bits_left <= 7) { - for(i = 0; i < bits_left; i++) { - concat(binary_data, "0"); - } - latch = 1; - } else { - concat(binary_data, "0000000"); - } - - if(latch == 0) { - /* Manage last (4-bit) block */ - bits_left = bits_total - strlen(binary_data); - if(bits_left <= 4) { - for(i = 0; i < bits_left; i++) { - concat(binary_data, "0"); - } - latch = 1; - } - } - - if(latch == 0) { - /* Complete current byte */ - remainder = 8 - (strlen(binary_data) % 8); - if(remainder == 8) { remainder = 0; } - for(i = 0; i < remainder; i++) { - concat(binary_data, "0"); - } - - /* Add padding */ - bits_left = bits_total - strlen(binary_data); - if(bits_left > 4) { - remainder = (bits_left - 4) / 8; - for(i = 0; i < remainder; i++) { - if((i % 2) == 0) { concat(binary_data, "11101100"); } - if((i % 2) == 1) { concat(binary_data, "00010001"); } - } - } - concat(binary_data, "0000"); - } - - if(ecc_mode == 1) { data_codewords = 11; ecc_codewords = 6; } - if(ecc_mode == 2) { data_codewords = 9; ecc_codewords = 8; } - - /* Copy data into codewords */ - for(i = 0; i < (data_codewords - 1); i++) { - data_blocks[i] = 0; - if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; } - if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; } - if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; } - if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; } - if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; } - if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; } - if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; } - if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; } - } - - if(ecc_mode == 1) { - data_blocks[11] = 0; - if(binary_data[80] == '1') { data_blocks[2] += 0x08; } - if(binary_data[81] == '1') { data_blocks[2] += 0x04; } - if(binary_data[82] == '1') { data_blocks[2] += 0x02; } - if(binary_data[83] == '1') { data_blocks[2] += 0x01; } - } - - if(ecc_mode == 2) { - data_blocks[9] = 0; - if(binary_data[64] == '1') { data_blocks[2] += 0x08; } - if(binary_data[65] == '1') { data_blocks[2] += 0x04; } - if(binary_data[66] == '1') { data_blocks[2] += 0x02; } - if(binary_data[67] == '1') { data_blocks[2] += 0x01; } - } - - /* Calculate Reed-Solomon error codewords */ - rs_init_gf(0x11d); - rs_init_code(ecc_codewords, 0); - rs_encode(data_codewords,data_blocks,ecc_blocks); - rs_free(); - - /* Add Reed-Solomon codewords to binary data */ - for(i = 0; i < ecc_codewords; i++) { - if(ecc_blocks[ecc_codewords - i - 1] & 0x80) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x40) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x20) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x08) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - } - - return; -} - -void versionm4(char binary_data[], unsigned char source[], int length, int char_system, int ecc_mode) -{ - int i, latch; - int bits_total, bits_left, remainder; - int data_codewords, ecc_codewords; - unsigned char data_blocks[17], ecc_blocks[15]; - int sjis_count; - - latch = 0; - - if(ecc_mode == 1) { bits_total = 128; } - if(ecc_mode == 2) { bits_total = 112; } - if(ecc_mode == 3) { bits_total = 80; } - - /* Mode indicator */ - if(char_system == NUMERIC) { concat(binary_data, "000"); } - if(char_system == ALPHANUM) { concat(binary_data, "001"); } - if(char_system == BYTE) { concat(binary_data, "010"); } - if(char_system == KANJI) { concat(binary_data, "011"); } - - /* Character count indicator */ - if(char_system == KANJI) { - concat(binary_data, "XXXX"); /* Place holder */ - } else { - if(char_system == NUMERIC) { - if(length & 0x20) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - } - if(length & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(length & 0x08) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(length & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(length & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(length & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - } - - if(char_system == NUMERIC) { qrnumeric_encode(binary_data, source, length); } - if(char_system == ALPHANUM) { qralpha_encode(binary_data, source, length); } - if(char_system == BYTE) { qrbyte_encode(binary_data, source, length); } - if(char_system == KANJI) { sjis_count = qrkanji_encode(binary_data, source, length); } - - if(char_system == KANJI) { - if(sjis_count & 0x08) { binary_data[3] = '1'; } else { binary_data[3] = '0'; } - if(sjis_count & 0x04) { binary_data[4] = '1'; } else { binary_data[4] = '0'; } - if(sjis_count & 0x02) { binary_data[5] = '1'; } else { binary_data[5] = '0'; } - if(sjis_count & 0x01) { binary_data[6] = '1'; } else { binary_data[6] = '0'; } - } - - /* Add terminator */ - bits_left = bits_total - strlen(binary_data); - if(bits_left <= 9) { - for(i = 0; i < bits_left; i++) { - concat(binary_data, "0"); - } - latch = 1; - } else { - concat(binary_data, "000000000"); - } - - if(latch == 0) { - /* Complete current byte */ - remainder = 8 - (strlen(binary_data) % 8); - if(remainder == 8) { remainder = 0; } - for(i = 0; i < remainder; i++) { - concat(binary_data, "0"); - } - - /* Add padding */ - bits_left = bits_total - strlen(binary_data); - remainder = bits_left / 8; - for(i = 0; i < remainder; i++) { - if((i % 2) == 0) { concat(binary_data, "11101100"); } - if((i % 2) == 1) { concat(binary_data, "00010001"); } - } - } - - if(ecc_mode == 1) { data_codewords = 16; ecc_codewords = 8; } - if(ecc_mode == 2) { data_codewords = 14; ecc_codewords = 10; } - if(ecc_mode == 3) { data_codewords = 10; ecc_codewords = 14; } - - /* Copy data into codewords */ - for(i = 0; i < data_codewords; i++) { - data_blocks[i] = 0; - if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; } - if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; } - if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; } - if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; } - if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; } - if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; } - if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; } - if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; } - } - - /* Calculate Reed-Solomon error codewords */ - rs_init_gf(0x11d); - rs_init_code(ecc_codewords, 0); - rs_encode(data_codewords,data_blocks,ecc_blocks); - rs_free(); - - /* Add Reed-Solomon codewords to binary data */ - for(i = 0; i < ecc_codewords; i++) { - if(ecc_blocks[ecc_codewords - i - 1] & 0x80) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x40) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x20) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x08) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[ecc_codewords - i - 1] & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - } - - return; -} - -int microqr(struct zint_symbol *symbol, unsigned char source[], int length) -{ - int symbol_size; - int char_system; - char binary_data[200]; - int latch; - char bitmask[17][17]; - char imagemap[17][17]; - char candidate[17][17]; - char pattern_bit; - int width, i, j, pattern_no; - int sum1, sum2, evaluation[4], format, format_full, kanji; - -#ifndef _MSC_VER - unsigned char local_source[length + 1]; -#else - unsigned char* local_source = (unsigned char*)_alloca(length + 1); -#endif - for(i = 0; i < length; i++) { - local_source[i] = source[i]; - } - - /* Analise input data and select encoding method - zint does not attempt to - optimise the symbol by switching encoding method part way through the symbol, - but merely chooses an encoding method for the whole symbol */ - char_system = BYTE; - symbol_size = 0; - - for(i = 0; i < length; i++) { - if(local_source[i] == '\0') { - strcpy(symbol->errtxt, "QR Code not yet able to handle NULL characters"); - return ERROR_INVALID_DATA; - } - } - - kanji = 0; - - if(kanji) { - char_system = KANJI; - } else { - if(is_sane(RHODIUM, local_source, length) == 0) { char_system = ALPHANUM; } - if(is_sane(NEON, local_source, length) == 0) { char_system = NUMERIC; } - } - width = 0; - format = 0; - - if(symbol->option_1 == 4) { - strcpy(symbol->errtxt, "Error correction level H not available for Micro QR symbols"); - return ERROR_INVALID_OPTION; - } - - if((symbol->option_1 < 1) || (symbol->option_1 > 4)) { - symbol->option_1 = 1; - } - - /* Check that the data is not too long */ - /* Note that there is no switching between error correction levels - this decision is left - to the user: invalid combinations fail */ - latch = 0; - switch(symbol->option_1) { - case 1: /* ECC Level L */ - switch(char_system) { - case NUMERIC: if(length > 35) latch = 1; break; - case ALPHANUM: if(length > 21) latch = 1; break; - case BYTE: if(length > 15) latch = 1; break; - case KANJI: if(length > 18) latch = 1; break; - } - break; - case 2: /* ECC Level M */ - switch(char_system) { - case NUMERIC: if(length > 30) latch = 1; break; - case ALPHANUM: if(length > 18) latch = 1; break; - case BYTE: if(length > 13) latch = 1; break; - case KANJI: if(length > 16) latch = 1; break; - } - break; - case 3: /* ECC Level Q */ - symbol_size = 4; /* Only size M4 supports level Q */ - switch(char_system) { - case NUMERIC: if(length > 21) latch = 1; break; - case ALPHANUM: if(length > 13) latch = 1; break; - case BYTE: if(length > 9) latch = 1; break; - case KANJI: if(length > 10) latch = 1; break; - } - break; - } - - if(latch == 1) { - strcpy(symbol->errtxt, "Input data too long"); - return ERROR_TOO_LONG; - } - - symbol_size = symbol->option_2; - - if((symbol_size < 0) || (symbol_size > 4)) { - symbol_size = 0; - } - - /* Decide symbol size */ - if(symbol_size == 0) { - if(symbol->option_1 == 1) { /* ECC Level L */ - switch(char_system) { - case NUMERIC: - symbol_size = 4; - if(length <= 23) { symbol_size = 3; } - if(length <= 10) { symbol_size = 2; } - if(length <= 5) { symbol_size = 1; } - break; - case ALPHANUM: - symbol_size = 4; - if(length <= 14) { symbol_size = 3; } - if(length <= 6) { symbol_size = 2; } - break; - case BYTE: - symbol_size = 4; - if(length <= 9) { symbol_size = 3; } - break; - case KANJI: - symbol_size = 4; - if(length <= 12) { symbol_size = 3; } - } - } else { /* ECC Level M */ - switch(char_system) { - case NUMERIC: - symbol_size = 4; - if(length <= 18) { symbol_size = 3; } - if(length <= 8) { symbol_size = 2; } - break; - case ALPHANUM: - symbol_size = 4; - if(length <= 11) { symbol_size = 3; } - if(length <= 5) { symbol_size = 2; } - break; - case BYTE: - symbol_size = 4; - if(length <= 7) { symbol_size = 3; } - break; - case KANJI: - symbol_size = 4; - if(length <= 8) { symbol_size = 3; } - } - } - } - - strcpy(binary_data, ""); - switch(symbol_size) { - case 1: versionm1(binary_data, local_source, length); break; - case 2: versionm2(binary_data, local_source, length, char_system, symbol->option_1); break; - case 3: versionm3(binary_data, local_source, length, char_system, symbol->option_1); break; - case 4: versionm4(binary_data, local_source, length, char_system, symbol->option_1); break; - } - - switch(symbol_size) { - case 1: width = 11; break; - case 2: width = 13; break; - case 3: width = 15; break; - case 4: width = 17; break; - } - - for(i = 0; i < 17; i++) { - for(j = 0; j < 17; j++) { - bitmask[i][j] = '0'; - imagemap[i][j] = '0'; - candidate[i][j] = '0'; - } - } - - - /* "bitmask" seperates data area */ - for(i = 1; i < width; i++) { - for(j = 1; j < width; j++) { - bitmask[i][j] = '1'; - } - } - - for(i = 1; i < 9; i++) { - for(j = 1; j < 9; j++) { - bitmask[i][j] = '0'; - } - } - - /* Copy data into symbol grid */ - for(i = 0; i < width; i++) { - for(j = 0; j < width; j++) { - if(bitmask[i][j] == '1') { - switch(symbol_size) { - case 1: imagemap[i][j] = binary_data[fig11m1[(i * width) + j]]; break; - case 2: imagemap[i][j] = binary_data[fig11m2[(i * width) + j]]; break; - case 3: imagemap[i][j] = binary_data[fig11m3[(i * width) + j]]; break; - case 4: imagemap[i][j] = binary_data[fig11m4[(i * width) + j]]; break; - } - } - } - } - - /* XOR with data masks and evaluate */ - for(pattern_no = 0; pattern_no < 4; pattern_no++) { - for(i = 0; i < width; i++) { - for(j = 0; j < width; j++) { - pattern_bit = '0'; - candidate[i][j] = '0'; - switch(pattern_no) { - case 0: if((i % 2) == 0) { pattern_bit = '1'; } break; - case 1: if((((i / 2) + (j / 3)) % 2) == 0) { pattern_bit = '1'; } break; - case 2: if((((i * j) % 2 + (i * j) % 3) % 2) == 0) { pattern_bit = '1'; } break; - case 3: if((((i + j) % 2 + (i * j) % 3) % 2) == 0) { pattern_bit = '1'; } break; - } - if(bitmask[i][j] == '1') { - if(pattern_bit != imagemap[i][j]) { candidate[i][j] = '1'; } - } - } - } - - sum1 = 0; - sum2 = 0; - for(i = 1; i < width; i++) { - if(candidate[i][width - 1] == '1') { sum1++; } - if(candidate[width - 1][i] == '1') { sum2++; } - } - - if(sum1 <= sum2) { evaluation[pattern_no] = (sum1 * 16) + sum2; } else { evaluation[pattern_no] = (sum2 * 16) + sum1; } - } - - /* Choose best data mask */ - j = evaluation[0]; - pattern_no = 0; - for(i = 1; i < 4; i++) { - if(evaluation[i] > j) { - pattern_no = i; - j = evaluation[i]; - } - } - - /* Apply data mask */ - for(i = 0; i < width; i++) { - for(j = 0; j < width; j++) { - pattern_bit = '0'; - candidate[i][j] = '0'; - switch(pattern_no) { - case 0: if((i % 2) == 0) { pattern_bit = '1'; } break; - case 1: if((((i / 2) + (j / 3)) % 2) == 0) { pattern_bit = '1'; } break; - case 2: if((((i * j) % 2 + (i * j) % 3) % 2) == 0) { pattern_bit = '1'; } break; - case 3: if((((i + j) % 2 + (i * j) % 3) % 2) == 0) { pattern_bit = '1'; } break; - } - if(bitmask[i][j] == '1') { - if(pattern_bit != imagemap[i][j]) { candidate[i][j] = '1'; } - } - } - } - - /* Calculate format data */ - switch(symbol_size) { - case 1: format = 0; - break; - case 2: switch(symbol->option_1) { - case 1: format = 1; break; - case 2: format = 2; break; - } - break; - case 3: switch(symbol->option_1) { - case 1: format = 3; break; - case 2: format = 4; break; - } - break; - case 4: switch(symbol->option_1) { - case 1: format = 5; break; - case 2: format = 6; break; - case 3: format = 7; break; - } - break; - } - - format *= 4; - format += pattern_no; - format_full = tablec1[format]; - - if(format_full & 0x4000) { candidate[8][1] = '1'; } - if(format_full & 0x2000) { candidate[8][2] = '1'; } - if(format_full & 0x1000) { candidate[8][3] = '1'; } - if(format_full & 0x800) { candidate[8][4] = '1'; } - if(format_full & 0x400) { candidate[8][5] = '1'; } - if(format_full & 0x200) { candidate[8][6] = '1'; } - if(format_full & 0x100) { candidate[8][7] = '1'; } - if(format_full & 0x80) { candidate[8][8] = '1'; } - if(format_full & 0x40) { candidate[7][8] = '1'; } - if(format_full & 0x20) { candidate[6][8] = '1'; } - if(format_full & 0x10) { candidate[5][8] = '1'; } - if(format_full & 0x08) { candidate[4][8] = '1'; } - if(format_full & 0x04) { candidate[3][8] = '1'; } - if(format_full & 0x02) { candidate[2][8] = '1'; } - if(format_full & 0x01) { candidate[1][8] = '1'; } - - /* Add timer pattern */ - for(i = 0; i < width; i += 2) { - candidate[i][0] = '1'; - candidate[0][i] = '1'; - } - - /* Add finder pattern */ - for(i = 0; i < 7; i ++) { - for(j = 0; j < 7; j++) { - if(finder[(i * 7) + j] == 1) { - candidate[i][j] = '1'; - } - } - } - - /* Copy data into symbol */ - for(i = 0; i < width; i++) { - for(j = 0; j < width; j++) { - if(candidate[i][j] == '1') { set_module(symbol, i, j); } - } - symbol->row_height[i] = 1; - } - symbol->rows = width; - symbol->width = width; - - return 0; -} \ No newline at end of file diff --git a/backend/micqr.h b/backend/micqr.h deleted file mode 100644 index d791a351..00000000 --- a/backend/micqr.h +++ /dev/null @@ -1,103 +0,0 @@ -/* micqr.h - Bit placement for Micro QR Code versions M1 - M4 */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -int fig11m1[] = { - 0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,19,18, - 0,0,0,0,0,0,0,0,0,17,16, - 0,0,0,0,0,0,0,0,0,15,14, - 0,0,0,0,0,0,0,0,0,13,12, - 0,0,0,0,0,0,0,0,0,11,10, - 0,0,0,0,0,0,0,0,0,9,8, - 0,0,0,0,0,0,0,0,0,7,6, - 0,0,0,0,0,0,0,0,0,5,4, - 0,35,33,29,28,27,26,21,20,3,2, - 0,34,32,31,30,25,24,23,22,1,0 -}; - -int fig11m2[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,25,24,23,22, - 0,0,0,0,0,0,0,0,0,27,26,21,20, - 0,0,0,0,0,0,0,0,0,29,28,19,18, - 0,0,0,0,0,0,0,0,0,31,30,17,16, - 0,0,0,0,0,0,0,0,0,33,32,15,14, - 0,0,0,0,0,0,0,0,0,35,34,13,12, - 0,0,0,0,0,0,0,0,0,37,36,11,10, - 0,0,0,0,0,0,0,0,0,39,38,9,8, - 0,73,72,71,70,57,56,55,54,41,40,7,6, - 0,75,74,69,68,59,58,53,52,43,42,5,4, - 0,77,76,67,66,61,60,51,50,45,44,3,2, - 0,79,78,65,64,63,62,49,48,47,46,1,0 -}; - -int fig11m3[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,83,82,29,28,27,26, - 0,0,0,0,0,0,0,0,0,81,80,31,30,25,24, - 0,0,0,0,0,0,0,0,0,79,78,33,32,23,22, - 0,0,0,0,0,0,0,0,0,77,76,35,34,21,20, - 0,0,0,0,0,0,0,0,0,75,74,37,36,19,18, - 0,0,0,0,0,0,0,0,0,73,72,39,38,17,16, - 0,0,0,0,0,0,0,0,0,71,70,41,40,15,14, - 0,0,0,0,0,0,0,0,0,69,68,43,42,13,12, - 0,131,130,109,108,107,106,85,84,67,66,45,44,11,10, - 0,129,128,111,110,105,104,87,86,65,64,47,46,9,8, - 0,127,126,113,112,103,102,89,88,63,62,49,48,7,6, - 0,125,124,115,114,101,100,91,90,61,60,51,50,5,4, - 0,123,122,117,116,99,98,93,92,59,58,53,52,3,2, - 0,121,120,119,118,97,96,95,94,57,56,55,54,1,0 -}; - -int fig11m4[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,97,96,95,94,33,32,31,30, - 0,0,0,0,0,0,0,0,0,99,98,93,92,35,34,29,28, - 0,0,0,0,0,0,0,0,0,101,100,91,90,37,36,27,26, - 0,0,0,0,0,0,0,0,0,103,102,89,88,39,38,25,24, - 0,0,0,0,0,0,0,0,0,105,104,87,86,41,40,23,22, - 0,0,0,0,0,0,0,0,0,107,106,85,84,43,42,21,20, - 0,0,0,0,0,0,0,0,0,109,108,83,82,45,44,19,18, - 0,0,0,0,0,0,0,0,0,111,110,81,80,47,46,17,16, - 0,177,176,175,174,145,144,143,142,113,112,79,78,49,48,15,14, - 0,179,178,173,172,147,146,141,140,115,114,77,76,51,50,13,12, - 0,181,180,171,170,149,148,139,138,117,116,75,74,53,52,11,10, - 0,183,182,169,168,151,150,137,136,119,118,73,72,55,54,9,8, - 0,185,184,167,166,153,152,135,134,121,120,70,69,57,56,7,6, - 0,187,186,165,164,155,154,133,132,123,122,68,67,59,58,5,4, - 0,189,188,163,162,157,156,131,130,125,124,66,65,61,60,3,2, - 0,191,190,161,160,159,158,129,128,127,126,64,63,62,0,1,0 -}; - -int finder[] = { - 1,1,1,1,1,1,1, - 1,0,0,0,0,0,1, - 1,0,1,1,1,0,1, - 1,0,1,1,1,0,1, - 1,0,1,1,1,0,1, - 1,0,0,0,0,0,1, - 1,1,1,1,1,1,1 -}; - -int tablec1[] = { 0x4445, 0x4172, 0x4e2b, 0x4b1c, 0x55ae, 0x5099, 0x5fc0, 0x5af7, 0x6793, 0x62a4, 0x6dfd, 0x68ca, 0x7678, 0x734f, - 0x7c16, 0x7921, 0x06de, 0x03e9, 0x0cb0, 0x0987, 0x1735, 0x1202, 0x1d5b, 0x186c, 0x2508, 0x203f, 0x2f66, 0x2a51, 0x34e3, - 0x31d4, 0x3e8d, 0x3bba -};