mirror of
https://github.com/zint/zint
synced 2024-11-16 20:57:25 +13:00
Han Xin - Add Numeric mode, Text mode and Binary byte mode encoding
This commit is contained in:
parent
0230426b0f
commit
a5440244c4
317
backend/hanxin.c
317
backend/hanxin.c
@ -41,7 +41,322 @@
|
|||||||
#include "reedsol.h"
|
#include "reedsol.h"
|
||||||
#include "hanxin.h"
|
#include "hanxin.h"
|
||||||
|
|
||||||
|
/* Calculate the approximate length of the binary string */
|
||||||
|
int calculate_binlength(char mode[], int length) {
|
||||||
|
int i;
|
||||||
|
char lastmode = ' ';
|
||||||
|
int est_binlen = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
switch (mode[i]) {
|
||||||
|
case 'n':
|
||||||
|
if (lastmode != 'n') {
|
||||||
|
est_binlen += 14;
|
||||||
|
lastmode = 'n';
|
||||||
|
}
|
||||||
|
est_binlen += 4;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
if (lastmode != 't') {
|
||||||
|
est_binlen += 10;
|
||||||
|
lastmode = 't';
|
||||||
|
}
|
||||||
|
est_binlen += 6;
|
||||||
|
case 'b':
|
||||||
|
if (lastmode != 'b') {
|
||||||
|
est_binlen += 17;
|
||||||
|
lastmode = 'b';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return est_binlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate mode switching */
|
||||||
|
void hx_define_mode(char mode[], const unsigned char source[], int length) {
|
||||||
|
int i;
|
||||||
|
char lastmode = 't';
|
||||||
|
|
||||||
|
for(i = 0; i < length; i++) {
|
||||||
|
if ((source[i] >= '0') && (source[i] <= '9')) {
|
||||||
|
mode[i] = 'n';
|
||||||
|
if (lastmode != 'n') {
|
||||||
|
lastmode = 'n';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((source[i] <= 127) && ((source[i] <= 27) || (source[i] >= 32))) {
|
||||||
|
mode[i] = 't';
|
||||||
|
if (lastmode != 't') {
|
||||||
|
lastmode = 't';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mode[i] = 'b';
|
||||||
|
if (lastmode != 'b') {
|
||||||
|
lastmode = 'b';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mode[length] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find which submode to use for a text character */
|
||||||
|
int getsubmode(char input) {
|
||||||
|
int submode = 2;
|
||||||
|
|
||||||
|
if ((input >= '0') && (input <= '9')) {
|
||||||
|
submode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((input >= 'A') && (input <= 'Z')) {
|
||||||
|
submode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((input >= 'a') && (input <= 'z')) {
|
||||||
|
submode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return submode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert Text 1 sub-mode character to encoding value, as given in table 3 */
|
||||||
|
int lookup_text1(char input) {
|
||||||
|
int encoding_value = 0;
|
||||||
|
|
||||||
|
if ((input >= '0') && (input <= '9')) {
|
||||||
|
encoding_value = input - '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((input >= 'A') && (input <= 'Z')) {
|
||||||
|
encoding_value = input - 'A' + 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((input >= 'a') && (input <= 'z')) {
|
||||||
|
encoding_value = input - 'a' + 36;
|
||||||
|
}
|
||||||
|
|
||||||
|
return encoding_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert Text 2 sub-mode character to encoding value, as given in table 4 */
|
||||||
|
int lookup_text2(char input) {
|
||||||
|
int encoding_value = 0;
|
||||||
|
|
||||||
|
if ((input >= 0) && (input <= 27)) {
|
||||||
|
encoding_value = input;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((input >= ' ') && (input <= '/')) {
|
||||||
|
encoding_value = input - ' ' + 28;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((input >= '[') && (input <= 96)) {
|
||||||
|
encoding_value = input - '[' + 51;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((input >= '{') && (input <= 127)) {
|
||||||
|
encoding_value = input - '{' + 57;
|
||||||
|
}
|
||||||
|
|
||||||
|
return encoding_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert input data to binary stream */
|
||||||
|
void calculate_binary(char binary[], char mode[], const unsigned char source[], int length) {
|
||||||
|
int block_length;
|
||||||
|
int position = 0;
|
||||||
|
int i, p, count, encoding_value;
|
||||||
|
int debug = 1;
|
||||||
|
|
||||||
|
do {
|
||||||
|
block_length = 0;
|
||||||
|
do {
|
||||||
|
block_length++;
|
||||||
|
} while (mode[position + block_length] == mode[position]);
|
||||||
|
|
||||||
|
switch(mode[position]) {
|
||||||
|
case 'n':
|
||||||
|
/* Numeric mode */
|
||||||
|
/* Mode indicator */
|
||||||
|
strcat(binary, "0001");
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
printf("Numeric\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
while (i < block_length) {
|
||||||
|
int first = 0, second = 0, third = 0;
|
||||||
|
|
||||||
|
first = posn(NEON, (char) source[position + i]);
|
||||||
|
count = 1;
|
||||||
|
encoding_value = first;
|
||||||
|
|
||||||
|
if (i + 1 < block_length && mode[position + i + 1] == 'n') {
|
||||||
|
second = posn(NEON, (char) source[position + i + 1]);
|
||||||
|
count = 2;
|
||||||
|
encoding_value = (encoding_value * 10) + second;
|
||||||
|
|
||||||
|
if (i + 2 < block_length && mode[position + i + 2] == 'n') {
|
||||||
|
third = posn(NEON, (char) source[position + i + 2]);
|
||||||
|
count = 3;
|
||||||
|
encoding_value = (encoding_value * 10) + third;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (p = 0; p < 10; p++) {
|
||||||
|
if (encoding_value & (0x200 >> p)) {
|
||||||
|
strcat(binary, "1");
|
||||||
|
} else {
|
||||||
|
strcat(binary, "0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
printf("0x%4X (%d)", encoding_value, encoding_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
i += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mode terminator depends on number of characters in last group (Table 2) */
|
||||||
|
switch (count) {
|
||||||
|
case 1:
|
||||||
|
strcat(binary, "1111111101");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
strcat(binary, "1111111110");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
strcat(binary, "1111111111");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
printf(" (TERM %d)\n", count);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
/* Text mode */
|
||||||
|
if (position != 0) {
|
||||||
|
/* Mode indicator */
|
||||||
|
strcat(binary, "0010");
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
printf("Text\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int submode = 1;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
while (i < block_length) {
|
||||||
|
|
||||||
|
if (getsubmode(source[i + position]) != submode) {
|
||||||
|
/* Change submode */
|
||||||
|
strcat(binary, "111110");
|
||||||
|
submode = getsubmode(source[i + position]);
|
||||||
|
if (debug) {
|
||||||
|
printf("SWITCH ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (submode == 1) {
|
||||||
|
encoding_value = lookup_text1((char) source[i + position]);
|
||||||
|
} else {
|
||||||
|
encoding_value = lookup_text2((char) source[i + position]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (p = 0; p < 6; p++) {
|
||||||
|
if (encoding_value & (0x20 >> p)) {
|
||||||
|
strcat(binary, "1");
|
||||||
|
} else {
|
||||||
|
strcat(binary, "0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
printf("%c (%d) ", (char) source[i], encoding_value);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Terminator */
|
||||||
|
strcat(binary, "111111");
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
/* Binary Mode */
|
||||||
|
/* Mode indicator */
|
||||||
|
strcat(binary, "0011");
|
||||||
|
|
||||||
|
/* Count indicator */
|
||||||
|
for (p = 0; p < 13; p++) {
|
||||||
|
if (block_length & (0x1000 >> p)) {
|
||||||
|
strcat(binary, "1");
|
||||||
|
} else {
|
||||||
|
strcat(binary, "0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
printf("Binary (length %d)\n", block_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
while (i < block_length) {
|
||||||
|
|
||||||
|
/* 8-bit bytes with no conversion */
|
||||||
|
for (p = 0; p < 8; p++) {
|
||||||
|
if (source[i + position] & (0x80 >> p)) {
|
||||||
|
strcat(binary, "1");
|
||||||
|
} else {
|
||||||
|
strcat(binary, "0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
printf("%d ", source[i + position]);
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
position += block_length;
|
||||||
|
|
||||||
|
} while (position < length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Han Xin Code - main */
|
||||||
int han_xin(struct zint_symbol *symbol, const unsigned char source[], int length) {
|
int han_xin(struct zint_symbol *symbol, const unsigned char source[], int length) {
|
||||||
printf("Sucessfully init HAN XIN\n");
|
char mode[length + 1];
|
||||||
|
int est_binlen;
|
||||||
|
|
||||||
|
hx_define_mode(mode, source, length);
|
||||||
|
|
||||||
|
est_binlen = calculate_binlength(mode, length);
|
||||||
|
|
||||||
|
char binary[est_binlen + 10];
|
||||||
|
binary[0] = '\0';
|
||||||
|
|
||||||
|
calculate_binary(binary, mode, source, length);
|
||||||
|
|
||||||
|
printf("Binary: %s\n", binary);
|
||||||
|
|
||||||
|
strcpy(symbol->errtxt, "Under Construction!");
|
||||||
return ZINT_ERROR_INVALID_OPTION;
|
return ZINT_ERROR_INVALID_OPTION;
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user