Add Shift-JIS Kanji support to MicroQR

This commit is contained in:
hooper114 2009-02-21 23:19:31 +00:00
parent 7e0893aa30
commit ee9d0eb601
2 changed files with 87 additions and 18 deletions

View File

@ -29,6 +29,7 @@
#define NUMERIC 1 #define NUMERIC 1
#define ALPHANUM 2 #define ALPHANUM 2
#define BYTE 3 #define BYTE 3
#define KANJI 4
#define QRSET "0123456789ABCDEFGHIJKLNMOPQRSTUVWXYZ $%*+-./:" #define QRSET "0123456789ABCDEFGHIJKLNMOPQRSTUVWXYZ $%*+-./:"
@ -156,6 +157,42 @@ void qrbyte_encode(char binary[], unsigned char source[])
return; return;
} }
int qrkanji_encode(char binary[], unsigned char source[])
{ /* Assumes input is in Shift-JIS format */
int i, len, h, val, count;
len = ustrlen(source);
count = 0;
for(i=0; i<len; 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[]) void versionm1(char binary_data[], unsigned char source[])
{ {
int input_length, i, latch; int input_length, i, latch;
@ -357,6 +394,7 @@ void versionm3(char binary_data[], unsigned char source[], int char_system, int
int bits_total, bits_left, remainder; int bits_total, bits_left, remainder;
int data_codewords, ecc_codewords; int data_codewords, ecc_codewords;
unsigned char data_blocks[12], ecc_blocks[9]; unsigned char data_blocks[12], ecc_blocks[9];
int sjis_count;
input_length = ustrlen(source); input_length = ustrlen(source);
latch = 0; latch = 0;
@ -368,8 +406,12 @@ void versionm3(char binary_data[], unsigned char source[], int char_system, int
if(char_system == NUMERIC) { concat(binary_data, "00"); } if(char_system == NUMERIC) { concat(binary_data, "00"); }
if(char_system == ALPHANUM) { concat(binary_data, "01"); } if(char_system == ALPHANUM) { concat(binary_data, "01"); }
if(char_system == BYTE) { concat(binary_data, "10"); } if(char_system == BYTE) { concat(binary_data, "10"); }
if(char_system == KANJI) { concat(binary_data, "11"); }
/* Character count indicator */ /* Character count indicator */
if(char_system == KANJI) {
concat(binary_data, "XXX"); /* Place holder */
} else {
if(char_system == NUMERIC) { if(char_system == NUMERIC) {
if(input_length & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } if(input_length & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); }
} }
@ -377,10 +419,18 @@ void versionm3(char binary_data[], unsigned char source[], int char_system, int
if(input_length & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } if(input_length & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); }
if(input_length & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } if(input_length & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); }
if(input_length & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } if(input_length & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); }
}
if(char_system == NUMERIC) { qrnumeric_encode(binary_data, source); } if(char_system == NUMERIC) { qrnumeric_encode(binary_data, source); }
if(char_system == ALPHANUM) { qralpha_encode(binary_data, source); } if(char_system == ALPHANUM) { qralpha_encode(binary_data, source); }
if(char_system == BYTE) { qrbyte_encode(binary_data, source); } if(char_system == BYTE) { qrbyte_encode(binary_data, source); }
if(char_system == KANJI) { sjis_count = qrkanji_encode(binary_data, source); }
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 */ /* Add terminator */
bits_left = bits_total - strlen(binary_data); bits_left = bits_total - strlen(binary_data);
@ -483,6 +533,7 @@ void versionm4(char binary_data[], unsigned char source[], int char_system, int
int bits_total, bits_left, remainder; int bits_total, bits_left, remainder;
int data_codewords, ecc_codewords; int data_codewords, ecc_codewords;
unsigned char data_blocks[17], ecc_blocks[15]; unsigned char data_blocks[17], ecc_blocks[15];
int sjis_count;
input_length = ustrlen(source); input_length = ustrlen(source);
latch = 0; latch = 0;
@ -495,8 +546,12 @@ void versionm4(char binary_data[], unsigned char source[], int char_system, int
if(char_system == NUMERIC) { concat(binary_data, "000"); } if(char_system == NUMERIC) { concat(binary_data, "000"); }
if(char_system == ALPHANUM) { concat(binary_data, "001"); } if(char_system == ALPHANUM) { concat(binary_data, "001"); }
if(char_system == BYTE) { concat(binary_data, "010"); } if(char_system == BYTE) { concat(binary_data, "010"); }
if(char_system == KANJI) { concat(binary_data, "011"); }
/* Character count indicator */ /* Character count indicator */
if(char_system == KANJI) {
concat(binary_data, "XXXX"); /* Place holder */
} else {
if(char_system == NUMERIC) { if(char_system == NUMERIC) {
if(input_length & 0x20) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } if(input_length & 0x20) { concat(binary_data, "1"); } else { concat(binary_data, "0"); }
} }
@ -505,10 +560,19 @@ void versionm4(char binary_data[], unsigned char source[], int char_system, int
if(input_length & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } if(input_length & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); }
if(input_length & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } if(input_length & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); }
if(input_length & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } if(input_length & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); }
}
if(char_system == NUMERIC) { qrnumeric_encode(binary_data, source); } if(char_system == NUMERIC) { qrnumeric_encode(binary_data, source); }
if(char_system == ALPHANUM) { qralpha_encode(binary_data, source); } if(char_system == ALPHANUM) { qralpha_encode(binary_data, source); }
if(char_system == BYTE) { qrbyte_encode(binary_data, source); } if(char_system == BYTE) { qrbyte_encode(binary_data, source); }
if(char_system == KANJI) { sjis_count = qrkanji_encode(binary_data, source); }
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 */ /* Add terminator */
bits_left = bits_total - strlen(binary_data); bits_left = bits_total - strlen(binary_data);
@ -598,6 +662,7 @@ int microqr(struct zint_symbol *symbol, unsigned char source[])
symbol_size = 0; symbol_size = 0;
if(is_sane(QRSET, source) == 0) { char_system = ALPHANUM; } if(is_sane(QRSET, source) == 0) { char_system = ALPHANUM; }
if(is_sane(NESET, source) == 0) { char_system = NUMERIC; } if(is_sane(NESET, source) == 0) { char_system = NUMERIC; }
if(symbol->input_mode == KANJI_MODE) { char_system = KANJI; }
width = 0; width = 0;
format = 0; format = 0;
@ -620,6 +685,7 @@ int microqr(struct zint_symbol *symbol, unsigned char source[])
case NUMERIC: if(input_length > 35) latch = 1; break; case NUMERIC: if(input_length > 35) latch = 1; break;
case ALPHANUM: if(input_length > 21) latch = 1; break; case ALPHANUM: if(input_length > 21) latch = 1; break;
case BYTE: if(input_length > 15) latch = 1; break; case BYTE: if(input_length > 15) latch = 1; break;
case KANJI: if(input_length > 18) latch = 1; break;
} }
break; break;
case 2: /* ECC Level M */ case 2: /* ECC Level M */
@ -627,6 +693,7 @@ int microqr(struct zint_symbol *symbol, unsigned char source[])
case NUMERIC: if(input_length > 30) latch = 1; break; case NUMERIC: if(input_length > 30) latch = 1; break;
case ALPHANUM: if(input_length > 18) latch = 1; break; case ALPHANUM: if(input_length > 18) latch = 1; break;
case BYTE: if(input_length > 13) latch = 1; break; case BYTE: if(input_length > 13) latch = 1; break;
case KANJI: if(input_length > 16) latch = 1; break;
} }
break; break;
case 3: /* ECC Level Q */ case 3: /* ECC Level Q */
@ -635,6 +702,7 @@ int microqr(struct zint_symbol *symbol, unsigned char source[])
case NUMERIC: if(input_length > 21) latch = 1; break; case NUMERIC: if(input_length > 21) latch = 1; break;
case ALPHANUM: if(input_length > 13) latch = 1; break; case ALPHANUM: if(input_length > 13) latch = 1; break;
case BYTE: if(input_length > 9) latch = 1; break; case BYTE: if(input_length > 9) latch = 1; break;
case KANJI: if(input_length > 10) latch = 1; break;
} }
break; break;
} }
@ -663,6 +731,9 @@ int microqr(struct zint_symbol *symbol, unsigned char source[])
symbol_size = 4; symbol_size = 4;
if(input_length <= 9) { symbol_size = 3; } if(input_length <= 9) { symbol_size = 3; }
break; break;
case KANJI:
symbol_size = 4;
if(input_length <= 12) { symbol_size = 3; }
} }
} else { /* ECC Level M */ } else { /* ECC Level M */
switch(char_system) { switch(char_system) {
@ -680,6 +751,9 @@ int microqr(struct zint_symbol *symbol, unsigned char source[])
symbol_size = 4; symbol_size = 4;
if(input_length <= 7) { symbol_size = 3; } if(input_length <= 7) { symbol_size = 3; }
break; break;
case KANJI:
symbol_size = 4;
if(input_length <= 8) { symbol_size = 3; }
} }
} }
} }

5
readme
View File

@ -108,11 +108,6 @@ Research
* Italian Postal Code * Italian Postal Code
* Japanese Postal Code * Japanese Postal Code
Programming
-----------
Some things which need to be added to the library:
* Micro QR Code currently does not support Kanji character encoding
Coming Soon Coming Soon
----------- -----------
Features which it is hoped will appear in this library soon: Features which it is hoped will appear in this library soon: