diff --git a/backend/gb2312.h b/backend/gb2312.h index f78da006..eca1c502 100644 --- a/backend/gb2312.h +++ b/backend/gb2312.h @@ -19,7 +19,6 @@ */ unsigned long int gb2312_lookup[] = { -{ 0x00A4, 0xA1E8, 0x00A7, 0xA1EC, 0x00A8, 0xA1A7, @@ -7465,4 +7464,4 @@ unsigned long int gb2312_lookup[] = { 0xFFE1, 0xA1EA, 0xFFE3, 0xA3FE, 0xFFE5, 0xA3A4 -} +}; diff --git a/backend/gridmtx.c b/backend/gridmtx.c index d3582324..966dd33d 100644 --- a/backend/gridmtx.c +++ b/backend/gridmtx.c @@ -30,10 +30,997 @@ #include "common.h" #include "reedsol.h" #include "gridmtx.h" +#include "gb2312.h" + +int number_lat(int gbdata[], int length, int position) +{ + /* Attempt to calculate the 'cost' of using numeric mode from a given position in number of bits */ + /* Also ensures that numeric mode is not selected when it cannot be used: for example in + a string which has "2.2.0" (cannot have more than one non-numeric character for each + block of three numeric characters) */ + int sp; + int numb = 0, nonum = 0, done; + int tally = 0; + + sp = position; + + do { + done = 0; + + if((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { numb++; done = 1; } + switch(gbdata[sp]) { + case ' ': + case '+': + case '-': + case '.': + case ',': + nonum++; + done = 1; + } + if((sp + 1) < length) { + if((gbdata[sp] == 0x13) && (gbdata[sp + 1] == 0x10)) { + nonum++; + done = 1; + sp++; + } + } + + if(done == 0) { + tally += 80; + } else { + if(numb == 3) { + if(nonum == 0) { + tally += 10; + } + if(nonum == 1) { + tally += 20; + } + if(nonum > 1) { + tally += 80; + } + numb = 0; + nonum = 0; + } + } + + sp++; + } while ((sp < length) && (sp <= (position + 8))); + + if(numb == 0) { + tally += 80; + } + + if(numb > 1) { + if(nonum == 0) { + tally += 10; + } + if(nonum == 1) { + tally += 20; + } + if(nonum > 1) { + tally += 80; + } + } + + return tally; +} + +int seek_forward(int gbdata[], int length, int position, int current_mode) +{ + /* In complete contrast to the method recommended in Annex D of the ANSI standard this + code uses a look-ahead test in the same manner as Data Matrix. This decision was made + because the "official" algorithm does not provide clear methods for dealing with all + possible combinations of input data */ + + int number_count, byte_count, mixed_count, upper_count, lower_count, chinese_count; + int sp, best_mode, done; + int best_count, last = -1; + int debug = 0; + + if(gbdata[position] > 0xff) { return GM_CHINESE; } + + switch(current_mode) { + case GM_CHINESE: + number_count = 13; + byte_count = 13; + mixed_count = 13; + upper_count = 13; + lower_count = 13; + chinese_count = 0; + break; + case GM_NUMBER: + number_count = 0; + byte_count = 10; + mixed_count = 10; + upper_count = 10; + lower_count = 10; + chinese_count = 10; + break; + case GM_LOWER: + number_count = 5; + byte_count = 7; + mixed_count = 7; + upper_count = 5; + lower_count = 0; + chinese_count = 5; + break; + case GM_UPPER: + number_count = 5; + byte_count = 7; + mixed_count = 7; + upper_count = 0; + lower_count = 5; + chinese_count = 5; + break; + case GM_MIXED: + number_count = 10; + byte_count = 10; + mixed_count = 0; + upper_count = 10; + lower_count = 10; + chinese_count = 10; + break; + case GM_BYTE: + number_count = 4; + byte_count = 0; + mixed_count = 4; + upper_count = 4; + lower_count = 4; + chinese_count = 4; + default: /* Start of symbol */ + number_count = 4; + byte_count = 4; + mixed_count = 4; + upper_count = 4; + lower_count = 4; + chinese_count = 4; + } + + for(sp = position; (sp < length) && (sp <= (position + 8)); sp++) { + + done = 0; + + if(gbdata[sp] >= 0xff) { + byte_count += 17; + mixed_count += 23; + upper_count += 18; + lower_count += 18; + chinese_count += 13; + done = 1; + } + + if((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) { + byte_count += 8; + mixed_count += 6; + upper_count += 10; + lower_count += 5; + chinese_count += 13; + done = 1; + } + + if((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) { + byte_count += 8; + mixed_count += 6; + upper_count += 5; + lower_count += 10; + chinese_count += 13; + done = 1; + } + + if((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { + byte_count += 8; + mixed_count += 6; + upper_count += 8; + lower_count += 8; + chinese_count += 13; + done = 1; + } + + if(gbdata[sp] == ' ') { + byte_count += 8; + mixed_count += 6; + upper_count += 5; + lower_count += 5; + chinese_count += 13; + done = 1; + } + + if(done == 0) { + /* Control character */ + byte_count += 8; + mixed_count += 16; + upper_count += 13; + lower_count += 13; + chinese_count += 13; + } + + if(gbdata[sp] >= 0x7f) { + mixed_count += 20; + upper_count += 20; + lower_count += 20; + } + } + + /* Adjust for */ + for(sp = position; (sp < (length - 1)) && (sp <= (position + 7)); sp++) { + if((gbdata[sp] == 0x13) && (gbdata[sp] == 0x10)) { + chinese_count -= 13; + } + } + + /* Adjust for double digits */ + for(sp = position; (sp < (length - 1)) && (sp <= (position + 7)); sp++) { + if(sp != last) { + if(((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) && ((gbdata[sp + 1] >= '0') && (gbdata[sp + 1] <= '9'))) { + chinese_count -= 13; + last = sp + 1; + } + } + } + + /* Numeric mode is more complex */ + number_count += number_lat(gbdata, length, position); + + if(debug) { printf("C %d / B %d / M %d / U %d / L %d / N %d\n", chinese_count, byte_count, mixed_count, upper_count, lower_count, number_count); } + + best_count = chinese_count; + best_mode = GM_CHINESE; + + if(byte_count <= best_count) { + best_count = byte_count; + best_mode = GM_BYTE; + } + + if(mixed_count <= best_count) { + best_count = mixed_count; + best_mode = GM_MIXED; + } + + if(upper_count <= best_count) { + best_count = upper_count; + best_mode = GM_UPPER; + } + + if(lower_count <= best_count) { + best_count = lower_count; + best_mode = GM_LOWER; + } + + if(number_count <= best_count) { + best_count = number_count; + best_mode = GM_NUMBER; + } + + return best_mode; +} + +void add_byte_count(char binary[], int byte_count_posn, int byte_count) +{ + /* Add the length indicator for byte encoded blocks */ + if(byte_count & 0x100) { binary[byte_count_posn] = '0'; } else { binary[byte_count_posn] = '1'; } + if(byte_count & 0x80) { binary[byte_count_posn + 1] = '0'; } else { binary[byte_count_posn + 1] = '1'; } + if(byte_count & 0x40) { binary[byte_count_posn + 2] = '0'; } else { binary[byte_count_posn + 2] = '1'; } + if(byte_count & 0x20) { binary[byte_count_posn + 3] = '0'; } else { binary[byte_count_posn + 3] = '1'; } + if(byte_count & 0x10) { binary[byte_count_posn + 4] = '0'; } else { binary[byte_count_posn + 4] = '1'; } + if(byte_count & 0x08) { binary[byte_count_posn + 5] = '0'; } else { binary[byte_count_posn + 5] = '1'; } + if(byte_count & 0x04) { binary[byte_count_posn + 6] = '0'; } else { binary[byte_count_posn + 6] = '1'; } + if(byte_count & 0x02) { binary[byte_count_posn + 7] = '0'; } else { binary[byte_count_posn + 7] = '1'; } + if(byte_count & 0x01) { binary[byte_count_posn + 8] = '0'; } else { binary[byte_count_posn + 8] = '1'; } +} + +void add_shift_char(char binary[], int shifty) +{ + /* Add a control character to the data stream */ + int i, debug = 0; + int glyph = 0; + + for(i = 0; i < 64; i++) { + if(shift_set[i] == shifty) { + glyph = i; + } + } + + if(debug) { printf("SHIFT [%d] ", glyph); } + + if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } +} + +int gm_encode(int gbdata[], int length, char binary[]) +{ + /* Create a binary stream representation of the input data. + 7 sets are defined - Chinese characters, Numerals, Lower case letters, Upper case letters, + Mixed numerals and latters, Control characters and 8-bit binary data */ + int sp, current_mode, next_mode, last_mode, glyph = 0; + int c1, c2, done; + int p = 0, ppos; + int numbuf[3], punt = 0; + int number_pad_posn, debug = 0; + int byte_count_posn = 0, byte_count = 0; + int shift, i; + + strcpy(binary, ""); + + sp = 0; + current_mode = 0; + last_mode = 0; + number_pad_posn = 0; + + do { + next_mode = seek_forward(gbdata, length, sp, current_mode); + + if(next_mode != current_mode) { + switch(current_mode) { + case 0: + switch(next_mode) { + case GM_CHINESE: concat(binary, "0001"); break; + case GM_NUMBER: concat(binary, "0010"); break; + case GM_LOWER: concat(binary, "0011"); break; + case GM_UPPER: concat(binary, "0100"); break; + case GM_MIXED: concat(binary, "0101"); break; + case GM_BYTE: concat(binary, "0111"); break; + } + break; + case GM_CHINESE: + switch(next_mode) { + case GM_NUMBER: concat(binary, "1111111100001"); break; // 8161 + case GM_LOWER: concat(binary, "1111111100010"); break; // 8162 + case GM_UPPER: concat(binary, "1111111100011"); break; // 8163 + case GM_MIXED: concat(binary, "1111111100100"); break; // 8164 + case GM_BYTE: concat(binary, "1111111100101"); break; // 8165 + } + break; + case GM_NUMBER: + /* add numeric block padding value */ + switch(p) { + case 1: binary[number_pad_posn] = '1'; binary[number_pad_posn + 1] = '0'; break; // 2 pad digits + case 2: binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '1'; break; // 1 pad digit + case 3: binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '0'; break; // 0 pad digits + } + switch(next_mode) { + case GM_CHINESE: concat(binary, "1111111011"); break; // 1019 + case GM_LOWER: concat(binary, "1111111100"); break; // 1020 + case GM_UPPER: concat(binary, "1111111101"); break; // 1021 + case GM_MIXED: concat(binary, "1111111110"); break; // 1022 + case GM_BYTE: concat(binary, "1111111111"); break; // 1023 + } + break; + case GM_LOWER: + case GM_UPPER: + switch(next_mode) { + case GM_CHINESE: concat(binary, "11100"); break; // 28 + case GM_NUMBER: concat(binary, "11101"); break; // 29 + case GM_LOWER: + case GM_UPPER: concat(binary, "11110"); break; // 30 + case GM_MIXED: concat(binary, "1111100"); break; // 124 + case GM_BYTE: concat(binary, "1111110"); break; // 126 + } + break; + case GM_MIXED: + switch(next_mode) { + case GM_CHINESE: concat(binary, "1111110001"); break; // 1009 + case GM_NUMBER: concat(binary, "1111110010"); break; // 1010 + case GM_LOWER: concat(binary, "1111110011"); break; // 1011 + case GM_UPPER: concat(binary, "1111110100"); break; // 1012 + case GM_BYTE: concat(binary, "1111110111"); break; // 1015 + } + break; + case GM_BYTE: + /* add byte block length indicator */ + add_byte_count(binary, byte_count_posn, byte_count); + byte_count = 0; + switch(next_mode) { + case GM_CHINESE: concat(binary, "0001"); break; // 1 + case GM_NUMBER: concat(binary, "0010"); break; // 2 + case GM_LOWER: concat(binary, "0011"); break; // 3 + case GM_UPPER: concat(binary, "0100"); break; // 4 + case GM_MIXED: concat(binary, "0101"); break; // 5 + } + break; + } + if(debug) { + switch(next_mode) { + case GM_CHINESE: printf("CHIN "); break; + case GM_NUMBER: printf("NUMB "); break; + case GM_LOWER: printf("LOWR "); break; + case GM_UPPER: printf("UPPR "); break; + case GM_MIXED: printf("MIXD "); break; + case GM_BYTE: printf("BYTE "); break; + } + } + } + last_mode = current_mode; + current_mode = next_mode; + + switch(current_mode) { + case GM_CHINESE: + done = 0; + if(gbdata[sp] > 0xff) { + /* GB2312 character */ + c1 = (gbdata[sp] & 0xff00) >> 8; + c2 = gbdata[sp] & 0xff; + + if((c1 >= 0xa0) && (c1 <= 0xa9)) { + glyph = (0x60 * (c1 - 0xa1)) + (c2 - 0xa0); + } + if((c1 >= 0xb0) && (c1 <= 0xf7)) { + glyph = (0x60 * (c1 - 0xb0 + 9)) + (c2 - 0xa0); + } + done = 1; + } + if(!(done)) { + if(sp != (length - 1)) { + if((gbdata[sp] == 0x13) && (gbdata[sp + 1] == 0x10)) { + /* End of Line */ + glyph = 7776; + sp++; + } + done = 1; + } + } + if(!(done)) { + if(sp != (length - 1)) { + if(((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) && + ((gbdata[sp + 1] >= '0') && (gbdata[sp + 1] <= '9'))) { + /* Two digits */ + glyph = 8033 + (10 * (gbdata[sp] - '0')) + (gbdata[sp + 1] - '0'); + sp++; + } + } + } + if(!(done)) { + /* Byte value */ + glyph = 7777 + gbdata[sp]; + } + + if(debug) { printf("[%d] ", glyph); } + + if(glyph & 0x1000) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x800) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x400) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + sp++; + break; + + case GM_NUMBER: + if(last_mode != current_mode) { + /* Reserve a space for numeric digit padding value (2 bits) */ + number_pad_posn = strlen(binary); + concat(binary, "XX"); + } + p = 0; + ppos = -1; + + /* Numeric compression can also include certain combinations of + non-numeric character */ + + numbuf[0] = '0'; + numbuf[1] = '0'; + numbuf[2] = '0'; + do { + if((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { + numbuf[p] = gbdata[sp]; + sp++; + p++; + } + switch(gbdata[sp]) { + case ' ': + case '+': + case '-': + case '.': + case ',': + punt = gbdata[sp]; + sp++; + ppos = p; + break; + } + if(sp < (length - 1)) { + if((gbdata[sp] == 0x13) && (gbdata[sp + 1] == 0x10)) { + /* */ + punt = gbdata[sp]; + sp += 2; + ppos = p; + } + } + } while ((p < 3) && (sp < length)); + + if(ppos != -1) { + switch(punt) { + case ' ': glyph = 0; break; + case '+': glyph = 3; break; + case '-': glyph = 6; break; + case '.': glyph = 9; break; + case ',': glyph = 12; break; + case 0x13: glyph = 15; break; + } + glyph += ppos; + glyph += 1000; + + if(debug) { printf("[%d] ", glyph); } + + if(glyph & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + } + + glyph = (100 * (numbuf[0] - '0')) + (10 * (numbuf[1] - '0')) + (numbuf[2] - '0'); + if(debug) { printf("[%d] ", glyph); } + + if(glyph & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + break; + + case GM_BYTE: + if(last_mode != current_mode) { + /* Reserve space for byte block length indicator (9 bits) */ + byte_count_posn = strlen(binary); + concat(binary, "LLLLLLLLL"); + } + if(byte_count == 512) { + /* Maximum byte block size is 512 bytes. If longer is needed then start a new block */ + add_byte_count(binary, byte_count_posn, byte_count); + concat(binary, "0111"); + byte_count_posn = strlen(binary); + concat(binary, "LLLLLLLLL"); + byte_count = 0; + } + + glyph = gbdata[sp]; + if(debug) { printf("[%d] ", glyph); } + if(glyph & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + sp++; + byte_count++; + break; + + case GM_MIXED: + shift = 1; + if((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { shift = 0; } + if((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) { shift = 0; } + if((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) { shift = 0; } + if(gbdata[sp] == ' ') { shift = 0; } + + if(shift == 0) { + /* Mixed Mode character */ + glyph = posn(EUROPIUM, gbdata[sp]); + if(debug) { printf("[%d] ", glyph); } + + if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + } else { + /* Shift Mode character */ + concat(binary, "1111110110"); /* 1014 - shift indicator */ + add_shift_char(binary, gbdata[sp]); + } + + sp++; + break; + + case GM_UPPER: + shift = 1; + if((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) { shift = 0; } + if(gbdata[sp] == ' ') { shift = 0; } + + if(shift == 0) { + /* Upper Case character */ + glyph = posn("ABCDEFGHIJKLMNOPQRSTUVWXYZ ", gbdata[sp]); + if(debug) { printf("[%d] ", glyph); } + + if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + } else { + /* Shift Mode character */ + concat(binary, "1111101"); /* 127 - shift indicator */ + add_shift_char(binary, gbdata[sp]); + } + + sp++; + break; + + case GM_LOWER: + shift = 1; + if((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) { shift = 0; } + if(gbdata[sp] == ' ') { shift = 0; } + + if(shift == 0) { + /* Lower Case character */ + glyph = posn("abcdefghijklmnopqrstuvwxyz ", gbdata[sp]); + if(debug) { printf("[%d] ", glyph); } + + if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } + if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } + } else { + /* Shift Mode character */ + concat(binary, "1111101"); /* 127 - shift indicator */ + add_shift_char(binary, gbdata[sp]); + } + + sp++; + break; + } + if(strlen(binary) > 9191) { + return ERROR_TOO_LONG; + } + + } while(sp < length); + + if(current_mode == GM_NUMBER) { + /* add numeric block padding value */ + switch(p) { + case 1: binary[number_pad_posn] = '1'; binary[number_pad_posn + 1] = '0'; break; // 2 pad digits + case 2: binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '1'; break; // 1 pad digit + case 3: binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '0'; break; // 0 pad digits + } + } + + if(current_mode == GM_BYTE) { + /* Add byte block length indicator */ + add_byte_count(binary, byte_count_posn, byte_count); + } + + /* Add "end of data" character */ + switch(current_mode) { + case GM_CHINESE: concat(binary, "1111111100000"); break; // 8160 + case GM_NUMBER: concat(binary, "1111111010"); break; // 1018 + case GM_LOWER: + case GM_UPPER: concat(binary, "11011"); break; // 27 + case GM_MIXED: concat(binary, "1111110000"); break; // 1008 + case GM_BYTE: concat(binary, "0000"); break; // 0 + } + + /* Add padding bits if required */ + p = 7 - (strlen(binary) % 7); + if(p == 7) { p = 0; } + for(i = 0; i < p; i++) { + concat(binary, "0"); + } + + if(strlen(binary) > 9191) { + return ERROR_TOO_LONG; + } + return 0; +} + +void gm_add_ecc(char binary[], int data_posn, int layers, int ecc_level, int word[]) +{ + int total_cw, data_cw, i, j, wp; + int n1, b1, n2, b2, e1, b3, e2; + int block_size, data_size, ecc_size, toggle; + int data[1320], block[130]; + unsigned char data_block[115], ecc_block[70]; + + total_cw = gm_total_cw[(layers - 1)]; + data_cw = gm_data_codewords[((layers - 1) * 5) + (ecc_level - 1)]; + + for(i = 0; i < 1320; i++) { + data[i] = 0; + } + + /* Convert from binary sream to 7-bit codewords */ + for(i = 0; i < data_posn; i++) { + if(binary[i * 7] == '1') { data[i] += 0x40; } + if(binary[(i * 7) + 1] == '1') { data[i] += 0x20; } + if(binary[(i * 7) + 2] == '1') { data[i] += 0x10; } + if(binary[(i * 7) + 3] == '1') { data[i] += 0x08; } + if(binary[(i * 7) + 4] == '1') { data[i] += 0x04; } + if(binary[(i * 7) + 5] == '1') { data[i] += 0x02; } + if(binary[(i * 7) + 6] == '1') { data[i] += 0x01; } + } + + /* Add padding codewords */ + data[data_posn] = 0x00; + for(i = (data_posn + 1); i < data_cw; i++) { + if(i % 2) { + data[i] = 0x7e; + toggle = 1; + } else { + data[i] = 0x00; + toggle = 0; + } + } + + /* Get block sizes */ + n1 = gm_n1[(layers - 1)]; + b1 = gm_b1[(layers - 1)]; + n2 = n1 - 1; + b2 = gm_b2[(layers - 1)]; + e1 = gm_ebeb[((layers - 1) * 20) + ((ecc_level - 1) * 4)]; + b3 = gm_ebeb[((layers - 1) * 20) + ((ecc_level - 1) * 4) + 1]; + e2 = gm_ebeb[((layers - 1) * 20) + ((ecc_level - 1) * 4) + 2]; + + /* Split the data into blocks */ + wp = 0; + for(i = 0; i < (b1 + b2); i++) { + if(i < b1) { block_size = n1; } else { block_size = n2; } + if(i < b3) { ecc_size = e1; } else { ecc_size = e2; } + data_size = block_size - ecc_size; + + /* printf("block %d/%d: data %d / ecc %d\n", i + 1, (b1 + b2), data_size, ecc_size);*/ + + for(j = 0; j < data_size; j++) { + data_block[j] = data[wp]; + wp++; + } + + /* Calculate ECC data for this block */ + rs_init_gf(0x89); + rs_init_code(ecc_size, 1); + rs_encode(data_size, data_block, ecc_block); + rs_free(); + + /* Correct error correction data but in reverse order */ + for(j = 0; j < data_size; j++) { + block[j] = data_block[j]; + } + for(j = 0; j < ecc_size; j++) { + block[(j + data_size)] = ecc_block[ecc_size - j - 1]; + } + + for(j = 0; j < n2; j++) { + word[((b1 + b2) * j) + i] = block[j]; + } + if(block_size == n1) { + word[((b1 + b2) * (n1 - 1)) + i] = block[(n1 - 1)]; + } + } +} + +void place_macromodule(char grid[], int x, int y, int word1, int word2, int size) +{ + int i, j; + + i = (x * 6) + 1; + j = (y * 6) + 1; + + if(word2 & 0x40) { grid[(j * size) + i + 2] = '1'; } + if(word2 & 0x20) { grid[(j * size) + i + 3] = '1'; } + if(word2 & 0x10) { grid[((j + 1) * size) + i] = '1'; } + if(word2 & 0x08) { grid[((j + 1) * size) + i + 1] = '1'; } + if(word2 & 0x04) { grid[((j + 1) * size) + i + 2] = '1'; } + if(word2 & 0x02) { grid[((j + 1) * size) + i + 3] = '1'; } + if(word2 & 0x01) { grid[((j + 2) * size) + i] = '1'; } + if(word1 & 0x40) { grid[((j + 2) * size) + i + 1] = '1'; } + if(word1 & 0x20) { grid[((j + 2) * size) + i + 2] = '1'; } + if(word1 & 0x10) { grid[((j + 2) * size) + i + 3] = '1'; } + if(word1 & 0x08) { grid[((j + 3) * size) + i] = '1'; } + if(word1 & 0x04) { grid[((j + 3) * size) + i + 1] = '1'; } + if(word1 & 0x02) { grid[((j + 3) * size) + i + 2] = '1'; } + if(word1 & 0x01) { grid[((j + 3) * size) + i + 3] = '1'; } +} + +void place_data_in_grid(int word[], char grid[], int modules, int size) +{ + int x, y, macromodule, offset; + + offset = 13 - ((modules - 1) / 2); + for(y = 0; y < modules; y++) { + for(x = 0; x < modules; x++) { + macromodule = gm_macro_matrix[((y + offset) * 27) + (x + offset)]; + place_macromodule(grid, x, y, word[macromodule * 2], word[(macromodule * 2) + 1], size); + } + } +} + +void place_layer_id(char* grid, int size, int layers, int modules, int ecc_level) +{ + /* Place the layer ID into each macromodule */ + + int i, j, layer, start, stop; + +#ifndef _MSC_VER + int layerid[layers + 1]; + int id[modules * modules]; +#else + int* layerid = (int *)_alloca((layers + 1) * sizeof(int)); + int* id = (int *)_alloca((modules * modules) * sizeof(int)); +#endif + + /* Calculate Layer IDs */ + for(i = 0; i <= layers; i++) { + if(ecc_level == 1) { + layerid[i] = 3 - (i % 4); + } else { + layerid[i] = (i + 5 - ecc_level) % 4; + } + } + + for(i = 0; i < modules; i++) { + for(j = 0; j < modules; j++) { + id[(i * modules) + j] = 0; + } + } + + /* Calculate which value goes in each macromodule */ + start = modules / 2; + stop = modules / 2; + for(layer = 0; layer <= layers; layer++) { + for(i = start; i <= stop; i++) { + id[(start * modules) + i] = layerid[layer]; + id[(i * modules) + start] = layerid[layer]; + id[((modules - start - 1) * modules) + i] = layerid[layer]; + id[(i * modules) + (modules - start - 1)] = layerid[layer]; + } + start--; + stop++; + } + + /* Place the data in the grid */ + for(i = 0; i < modules; i++) { + for(j = 0; j < modules; j++) { + if(id[(i * modules) + j] & 0x02) { + grid[(((i * 6) + 1) * size) + (j * 6) + 1] = '1'; + } + if(id[(i * modules) + j] & 0x01) { + grid[(((i * 6) + 1) * size) + (j * 6) + 2] = '1'; + } + } + } +} int grid_matrix(struct zint_symbol *symbol, unsigned char source[], int length) { + int size, modules, dark, error_number; + int layers, ecc_level, x, y, i, j, glyph; + char binary[9300]; + int data_cw; + int word[1460]; - strcpy(symbol->errtxt, "Grid Matrix not yet implemented"); - return ERROR_INVALID_OPTION; -} \ No newline at end of file +#ifndef _MSC_VER + int utfdata[length + 1]; + int gbdata[length + 1]; +#else + int* utfdata = (int *)_alloca((length + 1) * sizeof(int)); + int* gbdata = (int *)_alloca((length + 1) * sizeof(int)); +#endif + + for(i = 0; i < 1460; i++) { + word[i] = 0; + } + + switch(symbol->input_mode) { + case DATA_MODE: + for(i = 0; i < length; i++) { + gbdata[i] = (int)source[i]; + } + break; + default: + /* Convert Unicode input to GB-2312 */ + error_number = utf8toutf16(symbol, source, utfdata, &length); + if(error_number != 0) { return error_number; } + + for(i = 0; i < length; i++) { + if(utfdata[i] <= 0xff) { + gbdata[i] = utfdata[i]; + } else { + j = 0; + glyph = 0; + do { + if(gb2312_lookup[j * 2] == utfdata[i]) { + glyph = gb2312_lookup[(j * 2) + 1]; + } + j++; + } while ((j < 7445) && (glyph == 0)); + if(glyph == 0) { + strcpy(symbol->errtxt, "Invalid character in input data"); + return ERROR_INVALID_DATA; + } + gbdata[i] = glyph; + } + } + break; + } + + error_number = gm_encode(gbdata, length, binary); + if(error_number != 0) { + strcpy(symbol->errtxt, "Input data too long"); + return error_number; + } + + /* Determine the size of the symbol */ + data_cw = strlen(binary) / 7; + layers = 13; + for(i = 12; i > 0; i--) { + if(gm_recommend_cw[(i - 1)] >= data_cw) { layers = i; } + } + + ecc_level = 3; + if(layers == 1) { ecc_level = 5; } + if((layers == 2) || (layers == 3)) { ecc_level = 4; } + + gm_add_ecc(binary, data_cw, layers, ecc_level, word); + size = 6 + (layers * 12); + modules = 1 + (layers * 2); + +#ifndef _MSC_VER + char grid[size * size]; +#else + char* grid = (char *)_alloca((size * size) * sizeof(char)); +#endif + + for(x = 0; x < size; x++) { + for(y = 0; y < size; y++) { + grid[(y * size) + x] = '0'; + } + } + + place_data_in_grid(word, grid, modules, size); + place_layer_id(grid, size, layers, modules, ecc_level); + + /* Add macromodule frames */ + for(x = 0; x < modules; x++) { + dark = 1 - (x % 2); + for(y = 0; y < modules; y++) { + if(dark == 1) { + for(i = 0; i < 5; i++) { + grid[((y * 6) * size) + (x * 6) + i] = '1'; + grid[(((y * 6) + 5) * size) + (x * 6) + i] = '1'; + grid[(((y * 6) + i) * size) + (x * 6)] = '1'; + grid[(((y * 6) + i) * size) + (x * 6) + 5] = '1'; + } + grid[(((y * 6) + 5) * size) + (x * 6) + 5] = '1'; + dark = 0; + } else { + dark = 1; + } + } + } + + /* Copy values to symbol */ + symbol->width = size; + symbol->rows = size; + + for(x = 0; x < size; x++) { + for(y = 0; y < size; y++) { + if(grid[(y * size) + x] == '1') { + set_module(symbol, y, x); + } + } + symbol->row_height[x] = 1; + } + + return 0; +} diff --git a/backend/gridmtx.h b/backend/gridmtx.h index 9824a3d1..8279148d 100644 --- a/backend/gridmtx.h +++ b/backend/gridmtx.h @@ -16,4 +16,144 @@ 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. -*/ \ No newline at end of file +*/ + +#define GM_NUMBER 1 +#define GM_LOWER 2 +#define GM_UPPER 3 +#define GM_MIXED 4 +#define GM_CONTROL 5 +#define GM_BYTE 6 +#define GM_CHINESE 7 + +#define EUROPIUM "0123456789ABCDEFGHIJKLMOPRSTUVWXYZabcdefghijklmnopqrstuvwxyz " + +static char shift_set[] = { + /* From Table 7 - Encoding of control characters */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* NULL -> SI */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* DLE -> US */ + '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', + ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~' +}; + +static int gm_recommend_cw[] = { 9, 30, 59, 114, 170, 237, 315, 405, 506, 618, 741, 875, 1021 }; +static int gm_total_cw[] = { 18, 50, 98, 162, 242, 338, 450, 578, 722, 882, 1058, 1250, 1458 }; + +static int gm_data_codewords[] = { + 0, 15, 13, 11, 9, + 45, 40, 35, 30, 25, + 89, 79, 69, 59, 49, + 146, 130, 114, 98, 81, + 218, 194, 170, 146, 121, + 305, 271, 237, 203, 169, + 405, 360, 315, 270, 225, + 521, 463, 405, 347, 289, + 650, 578, 506, 434, 361, + 794, 706, 618, 530, 441, + 953, 847, 741, 635, 529, + 1125, 1000, 875, 750, 625, + 1313, 1167, 1021, 875, 729 +}; + +static int gm_n1[] = { 18, 50, 98, 81, 121, 113, 113, 116, 121, 126, 118, 125, 122 }; +static int gm_b1[] = { 1, 1, 1, 2, 2, 2, 2, 3, 2, 7, 5, 10, 6 }; +static int gm_b2[] = { 0, 0, 0, 0, 0, 1, 2, 2, 4, 0, 4, 0, 6 }; + +static int gm_ebeb[] = { + /* E1 B3 E2 B4 */ + 0, 0, 0, 0, // version 1 + 3, 1, 0, 0, + 5, 1, 0, 0, + 7, 1, 0, 0, + 9, 1, 0, 0, + 5, 1, 0, 0, // version 2 + 10, 1, 0, 0, + 15, 1, 0, 0, + 20, 1, 0, 0, + 25, 1, 0, 0, + 9, 1, 0, 0, // version 3 + 19, 1, 0, 0, + 29, 1, 0, 0, + 39, 1, 0, 0, + 49, 1, 0, 0, + 8, 2, 0, 0, // version 4 + 16, 2, 0, 0, + 24, 2, 0, 0, + 32, 2, 0, 0, + 41, 1, 10, 1, + 12, 2, 0, 0, // version 5 + 24, 2, 0, 0, + 36, 2, 0, 0, + 48, 2, 0, 0, + 61, 1, 60, 1, + 11, 3, 0, 0, // version 6 + 23, 1, 22, 2, + 34, 2, 33, 1, + 45, 3, 0, 0, + 57, 1, 56, 2, + 12, 1, 11, 3, // version 7 + 23, 2, 22, 2, + 34, 3, 33, 1, + 45, 4, 0, 0, + 57, 1, 56, 3, + 12, 2, 11, 3, // version 8 + 23, 5, 0, 0, + 35, 3, 34, 2, + 47, 1, 46, 4, + 58, 4, 57, 1, + 12, 6, 0, 0, // version 9 + 24, 6, 0, 0, + 36, 6, 0, 0, + 48, 6, 0, 0, + 61, 1, 60, 5, + 13, 4, 12, 3, // version 10 + 26, 1, 25, 6, + 38, 5, 37, 2, + 51, 2, 50, 5, + 63, 7, 0, 0, + 12, 6, 11, 3, // version 11 + 24, 4, 23, 5, + 36, 2, 35, 7, + 47, 9, 0, 0, + 59, 7, 58, 2, + 13, 5, 12, 5, // version 12 + 25, 10, 0, 0, + 38, 5, 37, 5, + 50, 10, 0, 0, + 63, 5, 62, 5, + 13, 1, 12, 11, //version 13 + 25, 3, 24, 9, + 37, 5, 36, 7, + 49, 7, 48, 5, + 61, 9, 60, 3 +}; + +static int gm_macro_matrix[] = { + 728,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650, + 727,624,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,651, + 726,623,528,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,553,652, + 725,622,527,440,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,463,554,653, + 724,621,526,439,360,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,381,464,555,654, + 723,620,525,438,359,288,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,307,382,465,556,655, + 722,619,524,437,358,287,224,169,170,171,172,173,174,175,176,177,178,179,180,181,182,241,308,383,466,557,656, + 721,618,523,436,357,286,223,168,121,122,123,124,125,126,127,128,129,130,131,132,183,242,309,384,467,558,657, + 720,617,522,435,356,285,222,167,120,81,82,83,84,85,86,87,88,89,90,133,184,243,310,385,468,559,658, + 719,616,521,434,355,284,221,166,119,80,49,50,51,52,53,54,55,56,91,134,185,244,311,386,469,560,659, + 718,615,520,433,354,283,220,165,118,79,48,25,26,27,28,29,30,57,92,135,186,245,312,387,470,561,660, + 717,614,519,432,353,282,219,164,117,78,47,24,9,10,11,12,31,58,93,136,187,246,313,388,471,562,661, + 716,613,518,431,352,281,218,163,116,77,46,23,8,1,2,13,32,59,94,137,188,247,314,389,472,563,662, + 715,612,517,430,351,280,217,162,115,76,45,22,7,0,3,14,33,60,95,138,189,248,315,390,473,564,663, + 714,611,516,429,350,279,216,161,114,75,44,21,6,5,4,15,34,61,96,139,190,249,316,391,474,565,664, + 713,610,515,428,349,278,215,160,113,74,43,20,19,18,17,16,35,62,97,140,191,250,317,392,475,566,665, + 712,609,514,427,348,277,214,159,112,73,42,41,40,39,38,37,36,63,98,141,192,251,318,393,476,567,666, + 711,608,513,426,347,276,213,158,111,72,71,70,69,68,67,66,65,64,99,142,193,252,319,394,477,568,667, + 710,607,512,425,346,275,212,157,110,109,108,107,106,105,104,103,102,101,100,143,194,253,320,395,478,569,668, + 709,606,511,424,345,274,211,156,155,154,153,152,151,150,149,148,147,146,145,144,195,254,321,396,479,570,669, + 708,605,510,423,344,273,210,209,208,207,206,205,204,203,202,201,200,199,198,197,196,255,322,397,480,571,670, + 707,604,509,422,343,272,271,270,269,268,267,266,265,264,263,262,261,260,259,258,257,256,323,398,481,572,671, + 706,603,508,421,342,341,340,339,338,337,336,335,334,333,332,331,330,329,328,327,326,325,324,399,482,573,672, + 705,602,507,420,419,418,417,416,415,414,413,412,411,410,409,408,407,406,405,404,403,402,401,400,483,574,673, + 704,601,506,505,504,503,502,501,500,499,498,497,496,495,494,493,492,491,490,489,488,487,486,485,484,575,674, + 703,600,599,598,597,596,595,594,593,592,591,590,589,588,587,586,585,584,583,582,581,580,579,578,577,576,675, + 702,701,700,699,698,697,696,695,694,693,692,691,690,689,688,687,686,685,684,683,682,681,680,679,678,677,676, +}; diff --git a/backend/library.c b/backend/library.c index 25cd8b78..aded3998 100644 --- a/backend/library.c +++ b/backend/library.c @@ -1,744 +1,756 @@ -/* library.c - external functions of libzint - - 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 -#ifdef _MSC_VER -#include -#endif -#include "common.h" -#include "gs1.h" - -#define TECHNETIUM "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%" - -struct zint_symbol *ZBarcode_Create() -{ - struct zint_symbol *symbol; - int i, j; - - symbol = (struct zint_symbol*)malloc(sizeof(*symbol)); - if (!symbol) return NULL; - - memset(symbol, 0, sizeof(*symbol)); - symbol->symbology = BARCODE_CODE128; - symbol->height = 0; - symbol->whitespace_width = 0; - symbol->border_width = 0; - symbol->output_options = 0; - symbol->rows = 0; - symbol->width = 0; - strcpy(symbol->fgcolour, "000000"); - strcpy(symbol->bgcolour, "ffffff"); - strcpy(symbol->outfile, "out.png"); - symbol->scale = 1.0; - symbol->option_1 = -1; - symbol->option_2 = 0; - symbol->option_3 = 928; // PDF_MAX - symbol->input_mode = DATA_MODE; - strcpy(symbol->primary, ""); - for(i = 0; i < 178; i++) { - for(j = 0; j < 1000; j++) { - unset_module(symbol, i, j); - } - symbol->row_height[i] = 0; - } - return symbol; -} - - -int ZBarcode_Delete(struct zint_symbol *symbol) -{ - free(symbol); - return 0; -} - -extern int eanx(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN system barcodes */ -extern int c39(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 3 from 9 (or Code 39) */ -extern int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmazentral Nummer (PZN) */ -extern int ec39(struct zint_symbol *symbol, unsigned char source[], int length); /* Extended Code 3 from 9 (or Code 39+) */ -extern int codabar(struct zint_symbol *symbol, unsigned char source[], int length); /* Codabar - a simple substitution cipher */ -extern int matrix_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Standard (& Matrix) */ -extern int industrial_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Industrial */ -extern int iata_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 IATA */ -extern int interleaved_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Interleaved */ -extern int logic_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Data Logic */ -extern int itf14(struct zint_symbol *symbol, unsigned char source[], int length); /* ITF-14 */ -extern int dpleit(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Leitcode */ -extern int dpident(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Identcode */ -extern int c93(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 93 - a re-working of Code 39+, generates 2 check digits */ -extern int code_128(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 128 and NVE-18 */ -extern int ean_128(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN-128 (GS1-128) */ -extern int code_11(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 11 */ -extern int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length); /* MSI Plessey */ -extern int telepen(struct zint_symbol *symbol, unsigned char source[], int length); /* Telepen ASCII */ -extern int telepen_num(struct zint_symbol *symbol, unsigned char source[], int length); /* Telepen Numeric */ -extern int plessey(struct zint_symbol *symbol, unsigned char source[], int length); /* Plessey Code */ -extern int pharma_one(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode One Track */ -extern int flattermarken(struct zint_symbol *symbol, unsigned char source[], int length); /* Flattermarken */ -extern int fim(struct zint_symbol *symbol, unsigned char source[], int length); /* Facing Identification Mark */ -extern int pharma_two(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode Two Track */ -extern int post_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* Postnet */ -extern int planet_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* PLANET */ -extern int imail(struct zint_symbol *symbol, unsigned char source[], int length); /* Intelligent Mail (aka USPS OneCode) */ -extern int royal_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* RM4SCC */ -extern int australia_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Australia Post 4-state */ -extern int code16k(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 16k */ -extern int pdf417enc(struct zint_symbol *symbol, unsigned char source[], int length); /* PDF417 */ -extern int dmatrix(struct zint_symbol *symbol, unsigned char source[], int length); /* Data Matrix (IEC16022) */ -extern int qr_code(struct zint_symbol *symbol, unsigned char source[], int length); /* QR Code */ -extern int micro_pdf417(struct zint_symbol *symbol, unsigned char source[], int length); /* Micro PDF417 */ -extern int maxicode(struct zint_symbol *symbol, unsigned char source[], int length); /* Maxicode */ -extern int rss14(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS-14 */ -extern int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Limited */ -extern int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Expanded */ -extern int composite(struct zint_symbol *symbol, unsigned char source[], int length); /* Composite Symbology */ -extern int kix_code(struct zint_symbol *symbol, unsigned char source[], int length); /* TNT KIX Code */ -extern int aztec(struct zint_symbol *symbol, unsigned char source[], int length); /* Aztec Code */ -extern int code32(struct zint_symbol *symbol, unsigned char source[], int length); /* Italian Pharmacode */ -extern int codablock(struct zint_symbol *symbol, unsigned char source[], int length); /* Codablock F */ -extern int daft_code(struct zint_symbol *symbol, unsigned char source[], int length); /* DAFT Code */ -extern int ean_14(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN-14 */ -extern int nve_18(struct zint_symbol *symbol, unsigned char source[], int length); /* NVE-18 */ -extern int microqr(struct zint_symbol *symbol, unsigned char source[], int length); /* Micro QR Code */ -extern int aztec_runes(struct zint_symbol *symbol, unsigned char source[], int length); /* Aztec Runes */ -extern int korea_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Korea Post */ -extern int japan_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Japanese Post */ -extern int code_49(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 49 */ -extern int channel_code(struct zint_symbol *symbol, unsigned char source[], int length); /* Channel Code */ -extern int code_one(struct zint_symbol *symbol, unsigned char source[], int length); /* Code One */ -extern int grid_matrix(struct zint_symbol *symbol, unsigned char source[], int length); /* Grid Matrix */ - -#ifndef NO_PNG -int png_handle(struct zint_symbol *symbol, int rotate_angle); -#endif - -extern int ps_plot(struct zint_symbol *symbol); -extern int svg_plot(struct zint_symbol *symbol); - -void error_tag(char error_string[], int error_number) -{ - char error_buffer[100]; - - if(error_number != 0) { - strcpy(error_buffer, error_string); - - if(error_number > 4) { - strcpy(error_string, "error: "); - } else { - strcpy(error_string, "warning: "); - } - - concat(error_string, error_buffer); - } -} - -int hibc(struct zint_symbol *symbol, unsigned char source[], int length) -{ - int counter, error_number, i; - char to_process[40], temp[2], check_digit; - - if(length > 36) { - strcpy(symbol->errtxt, "Data too long for HIBC LIC"); - return ERROR_TOO_LONG; - } - to_upper(source); - error_number = is_sane(TECHNETIUM , source, length); - if(error_number == ERROR_INVALID_DATA) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - - strcpy(to_process, "+"); - counter = 41; - for(i = 0; i < length; i++) { - counter += posn(TECHNETIUM, source[i]); - } - counter = counter % 43; - - if(counter < 10) { - check_digit = itoc(counter); - } else { - if(counter < 36) { - check_digit = (counter - 10) + 'A'; - } else { - switch(counter) { - case 36: check_digit = '-'; break; - case 37: check_digit = '.'; break; - case 38: check_digit = ' '; break; - case 39: check_digit = '$'; break; - case 40: check_digit = '/'; break; - case 41: check_digit = '+'; break; - case 42: check_digit = '%'; break; - default: check_digit = ' '; break; /* Keep compiler happy */ - } - } - } - - temp[0] = check_digit; - temp[1] = '\0'; - - concat(to_process, (char *)source); - concat(to_process, temp); - length = strlen(to_process); - - switch(symbol->symbology) { - case BARCODE_HIBC_128: - error_number = code_128(symbol, (unsigned char *)to_process, length); - ustrcpy(symbol->text, (unsigned char*)"*"); - uconcat(symbol->text, (unsigned char*)to_process); - uconcat(symbol->text, (unsigned char*)"*"); - break; - case BARCODE_HIBC_39: - symbol->option_2 = 0; - error_number = c39(symbol, (unsigned char *)to_process, length); - ustrcpy(symbol->text, (unsigned char*)"*"); - uconcat(symbol->text, (unsigned char*)to_process); - uconcat(symbol->text, (unsigned char*)"*"); - break; - case BARCODE_HIBC_DM: - error_number = dmatrix(symbol, (unsigned char *)to_process, length); - break; - case BARCODE_HIBC_QR: - error_number = qr_code(symbol, (unsigned char *)to_process, length); - break; - case BARCODE_HIBC_PDF: - error_number = pdf417enc(symbol, (unsigned char *)to_process, length); - break; - case BARCODE_HIBC_MICPDF: - error_number = micro_pdf417(symbol, (unsigned char *)to_process, length); - break; - case BARCODE_HIBC_BLOCKF: - error_number = codablock(symbol, (unsigned char *)to_process, length); - break; - } - - return error_number; -} - -int gs1_compliant(int symbology) -{ - /* Returns 1 if symbology supports GS1 data */ - - int result = 0; - - switch(symbology) { - case BARCODE_EAN128: - case BARCODE_RSS_EXP: - case BARCODE_RSS_EXPSTACK: - case BARCODE_EANX_CC: - case BARCODE_EAN128_CC: - case BARCODE_RSS14_CC: - case BARCODE_RSS_LTD_CC: - case BARCODE_RSS_EXP_CC: - case BARCODE_UPCA_CC: - case BARCODE_UPCE_CC: - case BARCODE_RSS14STACK_CC: - case BARCODE_RSS14_OMNI_CC: - case BARCODE_RSS_EXPSTACK_CC: - case BARCODE_CODE16K: - case BARCODE_AZTEC: - case BARCODE_DATAMATRIX: - case BARCODE_CODABLOCKF: - case BARCODE_CODEONE: - case BARCODE_CODE49: - case BARCODE_QRCODE: - result = 1; - break; - } - - return result; -} - -int ZBarcode_ValidID(int symbol_id) -{ - /* Checks whether a symbology is supported */ - - int result = 0; - - switch(symbol_id) { - case BARCODE_CODE11: - case BARCODE_C25MATRIX: - case BARCODE_C25INTER: - case BARCODE_C25IATA: - case BARCODE_C25LOGIC: - case BARCODE_C25IND: - case BARCODE_CODE39: - case BARCODE_EXCODE39: - case BARCODE_EANX: - case BARCODE_EAN128: - case BARCODE_CODABAR: - case BARCODE_CODE128: - case BARCODE_DPLEIT: - case BARCODE_DPIDENT: - case BARCODE_CODE16K: - case BARCODE_CODE49: - case BARCODE_CODE93: - case BARCODE_FLAT: - case BARCODE_RSS14: - case BARCODE_RSS_LTD: - case BARCODE_RSS_EXP: - case BARCODE_TELEPEN: - case BARCODE_UPCA: - case BARCODE_UPCE: - case BARCODE_POSTNET: - case BARCODE_MSI_PLESSEY: - case BARCODE_FIM: - case BARCODE_LOGMARS: - case BARCODE_PHARMA: - case BARCODE_PZN: - case BARCODE_PHARMA_TWO: - case BARCODE_PDF417: - case BARCODE_PDF417TRUNC: - case BARCODE_MAXICODE: - case BARCODE_QRCODE: - case BARCODE_CODE128B: - case BARCODE_AUSPOST: - case BARCODE_AUSREPLY: - case BARCODE_AUSROUTE: - case BARCODE_AUSREDIRECT: - case BARCODE_ISBNX: - case BARCODE_RM4SCC: - case BARCODE_DATAMATRIX: - case BARCODE_EAN14: - case BARCODE_CODABLOCKF: - case BARCODE_NVE18: - case BARCODE_JAPANPOST: - case BARCODE_KOREAPOST: - case BARCODE_RSS14STACK: - case BARCODE_RSS14STACK_OMNI: - case BARCODE_RSS_EXPSTACK: - case BARCODE_PLANET: - case BARCODE_MICROPDF417: - case BARCODE_ONECODE: - case BARCODE_PLESSEY: - case BARCODE_TELEPEN_NUM: - case BARCODE_ITF14: - case BARCODE_KIX: - case BARCODE_AZTEC: - case BARCODE_DAFT: - case BARCODE_MICROQR: - case BARCODE_HIBC_128: - case BARCODE_HIBC_39: - case BARCODE_HIBC_DM: - case BARCODE_HIBC_QR: - case BARCODE_HIBC_PDF: - case BARCODE_HIBC_MICPDF: - case BARCODE_HIBC_BLOCKF: - case BARCODE_AZRUNE: - case BARCODE_CODE32: - case BARCODE_EANX_CC: - case BARCODE_EAN128_CC: - case BARCODE_RSS14_CC: - case BARCODE_RSS_LTD_CC: - case BARCODE_RSS_EXP_CC: - case BARCODE_UPCA_CC: - case BARCODE_UPCE_CC: - case BARCODE_RSS14STACK_CC: - case BARCODE_RSS14_OMNI_CC: - case BARCODE_RSS_EXPSTACK_CC: - case BARCODE_CHANNEL: - case BARCODE_CODEONE: - /* case BARCODE_GRIDMATRIX: */ - result = 1; - break; - } - - return result; -} - -int extended_charset(struct zint_symbol *symbol, unsigned char *source, int length) -{ - int error_number = 0; - - /* These are the "elite" standards which can support multiple character sets */ - switch(symbol->symbology) { - case BARCODE_QRCODE: error_number = qr_code(symbol, source, length); break; - case BARCODE_MICROQR: error_number = microqr(symbol, source, length); break; - case BARCODE_GRIDMATRIX: error_number = grid_matrix(symbol, source, length); break; - } - - return error_number; -} - -int reduced_charset(struct zint_symbol *symbol, unsigned char *source, int length) -{ - /* These are the "norm" standards which only support Latin-1 at most */ - int error_number = 0; - -#ifndef _MSC_VER - unsigned char preprocessed[length + 1]; -#else - unsigned char* preprocessed = (unsigned char*)_alloca(length + 1); -#endif - - if(symbol->symbology == BARCODE_CODE16K) { - symbol->whitespace_width = 16; - symbol->border_width = 2; - symbol->output_options = BARCODE_BIND; - } - - if(symbol->symbology == BARCODE_ITF14) { - symbol->whitespace_width = 20; - symbol->border_width = 8; - symbol->output_options = BARCODE_BOX; - } - - switch(symbol->input_mode) { - case DATA_MODE: - case GS1_MODE: - memcpy(preprocessed, source, length); - preprocessed[length] = '\0'; - break; - case UNICODE_MODE: - error_number = latin1_process(symbol, source, preprocessed, &length); - if(error_number != 0) { return error_number; } - break; - } - - switch(symbol->symbology) { - case BARCODE_C25MATRIX: error_number = matrix_two_of_five(symbol, preprocessed, length); break; - case BARCODE_C25IND: error_number = industrial_two_of_five(symbol, preprocessed, length); break; - case BARCODE_C25INTER: error_number = interleaved_two_of_five(symbol, preprocessed, length); break; - case BARCODE_C25IATA: error_number = iata_two_of_five(symbol, preprocessed, length); break; - case BARCODE_C25LOGIC: error_number = logic_two_of_five(symbol, preprocessed, length); break; - case BARCODE_DPLEIT: error_number = dpleit(symbol, preprocessed, length); break; - case BARCODE_DPIDENT: error_number = dpident(symbol, preprocessed, length); break; - case BARCODE_UPCA: error_number = eanx(symbol, preprocessed, length); break; - case BARCODE_UPCE: error_number = eanx(symbol, preprocessed, length); break; - case BARCODE_EANX: error_number = eanx(symbol, preprocessed, length); break; - case BARCODE_EAN128: error_number = ean_128(symbol, preprocessed, length); break; - case BARCODE_CODE39: error_number = c39(symbol, preprocessed, length); break; - case BARCODE_PZN: error_number = pharmazentral(symbol, preprocessed, length); break; - case BARCODE_EXCODE39: error_number = ec39(symbol, preprocessed, length); break; - case BARCODE_CODABAR: error_number = codabar(symbol, preprocessed, length); break; - case BARCODE_CODE93: error_number = c93(symbol, preprocessed, length); break; - case BARCODE_LOGMARS: error_number = c39(symbol, preprocessed, length); break; - case BARCODE_CODE128: error_number = code_128(symbol, preprocessed, length); break; - case BARCODE_CODE128B: error_number = code_128(symbol, preprocessed, length); break; - case BARCODE_NVE18: error_number = nve_18(symbol, preprocessed, length); break; - case BARCODE_CODE11: error_number = code_11(symbol, preprocessed, length); break; - case BARCODE_MSI_PLESSEY: error_number = msi_handle(symbol, preprocessed, length); break; - case BARCODE_TELEPEN: error_number = telepen(symbol, preprocessed, length); break; - case BARCODE_TELEPEN_NUM: error_number = telepen_num(symbol, preprocessed, length); break; - case BARCODE_PHARMA: error_number = pharma_one(symbol, preprocessed, length); break; - case BARCODE_PLESSEY: error_number = plessey(symbol, preprocessed, length); break; - case BARCODE_ITF14: error_number = itf14(symbol, preprocessed, length); break; - case BARCODE_FLAT: error_number = flattermarken(symbol, preprocessed, length); break; - case BARCODE_FIM: error_number = fim(symbol, preprocessed, length); break; - case BARCODE_POSTNET: error_number = post_plot(symbol, preprocessed, length); break; - case BARCODE_PLANET: error_number = planet_plot(symbol, preprocessed, length); break; - case BARCODE_RM4SCC: error_number = royal_plot(symbol, preprocessed, length); break; - case BARCODE_AUSPOST: error_number = australia_post(symbol, preprocessed, length); break; - case BARCODE_AUSREPLY: error_number = australia_post(symbol, preprocessed, length); break; - case BARCODE_AUSROUTE: error_number = australia_post(symbol, preprocessed, length); break; - case BARCODE_AUSREDIRECT: error_number = australia_post(symbol, preprocessed, length); break; - case BARCODE_CODE16K: error_number = code16k(symbol, preprocessed, length); break; - case BARCODE_PHARMA_TWO: error_number = pharma_two(symbol, preprocessed, length); break; - case BARCODE_ONECODE: error_number = imail(symbol, preprocessed, length); break; - case BARCODE_ISBNX: error_number = eanx(symbol, preprocessed, length); break; - case BARCODE_RSS14: error_number = rss14(symbol, preprocessed, length); break; - case BARCODE_RSS14STACK: error_number = rss14(symbol, preprocessed, length); break; - case BARCODE_RSS14STACK_OMNI: error_number = rss14(symbol, preprocessed, length); break; - case BARCODE_RSS_LTD: error_number = rsslimited(symbol, preprocessed, length); break; - case BARCODE_RSS_EXP: error_number = rssexpanded(symbol, preprocessed, length); break; - case BARCODE_RSS_EXPSTACK: error_number = rssexpanded(symbol, preprocessed, length); break; - case BARCODE_EANX_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_EAN128_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_RSS14_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_RSS_LTD_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_RSS_EXP_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_UPCA_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_UPCE_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_RSS14STACK_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_RSS14_OMNI_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_RSS_EXPSTACK_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_KIX: error_number = kix_code(symbol, preprocessed, length); break; - case BARCODE_CODE32: error_number = code32(symbol, preprocessed, length); break; - case BARCODE_CODABLOCKF: error_number = codablock(symbol, preprocessed, length); break; - case BARCODE_DAFT: error_number = daft_code(symbol, preprocessed, length); break; - case BARCODE_EAN14: error_number = ean_14(symbol, preprocessed, length); break; - case BARCODE_AZRUNE: error_number = aztec_runes(symbol, preprocessed, length); break; - case BARCODE_KOREAPOST: error_number = korea_post(symbol, preprocessed, length); break; - case BARCODE_HIBC_128: error_number = hibc(symbol, preprocessed, length); break; - case BARCODE_HIBC_39: error_number = hibc(symbol, preprocessed, length); break; - case BARCODE_HIBC_DM: error_number = hibc(symbol, preprocessed, length); break; - case BARCODE_HIBC_QR: error_number = hibc(symbol, preprocessed, length); break; - case BARCODE_HIBC_PDF: error_number = hibc(symbol, preprocessed, length); break; - case BARCODE_HIBC_MICPDF: error_number = hibc(symbol, preprocessed, length); break; - case BARCODE_HIBC_BLOCKF: error_number = hibc(symbol, preprocessed, length); break; - case BARCODE_JAPANPOST: error_number = japan_post(symbol, preprocessed, length); break; - case BARCODE_CODE49: error_number = code_49(symbol, preprocessed, length); break; - case BARCODE_CHANNEL: error_number = channel_code(symbol, preprocessed, length); break; - case BARCODE_CODEONE: error_number = code_one(symbol, preprocessed, length); break; - case BARCODE_DATAMATRIX: error_number = dmatrix(symbol, source, length); break; - case BARCODE_PDF417: error_number = pdf417enc(symbol, source, length); break; - case BARCODE_PDF417TRUNC: error_number = pdf417enc(symbol, source, length); break; - case BARCODE_MICROPDF417: error_number = micro_pdf417(symbol, source, length); break; - case BARCODE_MAXICODE: error_number = maxicode(symbol, source, length); break; - case BARCODE_AZTEC: error_number = aztec(symbol, source, length); break; - } - - return error_number; -} - -int ZBarcode_Encode(struct zint_symbol *symbol, unsigned char *source, int length) -{ - int error_number, error_buffer, i; - error_number = 0; - - if(length == 0) { - length = ustrlen(source); - } - if(length == 0) { - strcpy(symbol->errtxt, "No input data"); - error_tag(symbol->errtxt, ERROR_INVALID_DATA); - return ERROR_INVALID_DATA; - } - - -#ifndef _MSC_VER - unsigned char local_source[length + 1]; -#else - unsigned char* local_source = (unsigned char*)_alloca(length + 1); -#endif - - /* First check the symbology field */ - if(symbol->symbology < 1) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } - - /* symbol->symbologys 1 to 86 are defined by tbarcode */ - if(symbol->symbology == 5) { symbol->symbology = BARCODE_C25MATRIX; } - if((symbol->symbology >= 10) && (symbol->symbology <= 12)) { symbol->symbology = BARCODE_EANX; } - if((symbol->symbology == 14) || (symbol->symbology == 15)) { symbol->symbology = BARCODE_EANX; } - if(symbol->symbology == 17) { symbol->symbology = BARCODE_UPCA; } - if(symbol->symbology == 19) { strcpy(symbol->errtxt, "Codabar 18 not supported, using Codabar"); symbol->symbology = BARCODE_CODABAR; error_number = WARN_INVALID_OPTION; } - if(symbol->symbology == 26) { symbol->symbology = BARCODE_UPCA; } - if(symbol->symbology == 27) { strcpy(symbol->errtxt, "UPCD1 not supported"); error_number = ERROR_INVALID_OPTION; } - if(symbol->symbology == 33) { symbol->symbology = BARCODE_EAN128; } - if((symbol->symbology == 35) || (symbol->symbology == 36)) { symbol->symbology = BARCODE_UPCA; } - if((symbol->symbology == 38) || (symbol->symbology == 39)) { symbol->symbology = BARCODE_UPCE; } - if((symbol->symbology >= 41) && (symbol->symbology <= 45)) { symbol->symbology = BARCODE_POSTNET; } - if(symbol->symbology == 46) { symbol->symbology = BARCODE_PLESSEY; } - if(symbol->symbology == 48) { symbol->symbology = BARCODE_NVE18; } - if(symbol->symbology == 54) { strcpy(symbol->errtxt, "General Parcel Code not supported, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } - if((symbol->symbology == 59) || (symbol->symbology == 61)) { symbol->symbology = BARCODE_CODE128; } - if(symbol->symbology == 62) { symbol->symbology = BARCODE_CODE93; } - if((symbol->symbology == 64) || (symbol->symbology == 65)) { symbol->symbology = BARCODE_AUSPOST; } - if(symbol->symbology == 73) { strcpy(symbol->errtxt, "Codablock E not supported"); error_number = ERROR_INVALID_OPTION; } - if(symbol->symbology == 78) { symbol->symbology = BARCODE_RSS14; } - if(symbol->symbology == 83) { symbol->symbology = BARCODE_PLANET; } - if(symbol->symbology == 88) { symbol->symbology = BARCODE_EAN128; } - if(symbol->symbology == 91) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } - if((symbol->symbology >= 94) && (symbol->symbology <= 96)) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } - if(symbol->symbology == 100) { symbol->symbology = BARCODE_HIBC_128; } - if(symbol->symbology == 101) { symbol->symbology = BARCODE_HIBC_39; } - if(symbol->symbology == 103) { symbol->symbology = BARCODE_HIBC_DM; } - if(symbol->symbology == 105) { symbol->symbology = BARCODE_HIBC_QR; } - if(symbol->symbology == 107) { symbol->symbology = BARCODE_HIBC_PDF; } - if(symbol->symbology == 109) { symbol->symbology = BARCODE_HIBC_MICPDF; } - if(symbol->symbology == 111) { symbol->symbology = BARCODE_HIBC_BLOCKF; } - if((symbol->symbology >= 112) && (symbol->symbology <= 127)) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } - /* Everything from 128 up is Zint-specific */ - if(symbol->symbology >= 143) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } - - if(error_number > 4) { - error_tag(symbol->errtxt, error_number); - return error_number; - } else { - error_buffer = error_number; - } - - if((symbol->input_mode < 0) || (symbol->input_mode > 2)) { symbol->input_mode = DATA_MODE; } - - if(symbol->input_mode == GS1_MODE) { - for(i = 0; i < length; i++) { - if(source[i] == '\0') { - strcpy(symbol->errtxt, "NULL characters not permitted in GS1 mode"); - return ERROR_INVALID_DATA; - } - } - if(gs1_compliant(symbol->symbology) == 1) { - error_number = ugs1_verify(symbol, source, length, local_source); - if(error_number != 0) { return error_number; } - length = ustrlen(local_source); - } else { - strcpy(symbol->errtxt, "Selected symbology does not support GS1 mode"); - return ERROR_INVALID_OPTION; - } - } else { - memcpy(local_source, source, length); - local_source[length] = '\0'; - } - - switch(symbol->symbology) { - case BARCODE_QRCODE: - case BARCODE_MICROQR: - case BARCODE_GRIDMATRIX: - error_number = extended_charset(symbol, local_source, length); - break; - default: - error_number = reduced_charset(symbol, local_source, length); - break; - } - - - if(error_number == 0) { - error_number = error_buffer; - } - error_tag(symbol->errtxt, error_number); - /*printf("%s\n",symbol->text);*/ - return error_number; -} - -int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle) -{ - int error_number; - char output[4]; - - switch(rotate_angle) { - case 0: - case 90: - case 180: - case 270: - break; - default: - strcpy(symbol->errtxt, "Invalid rotation angle"); - return ERROR_INVALID_OPTION; - break; - } - - if(strlen(symbol->outfile) > 3) { - output[0] = symbol->outfile[strlen(symbol->outfile) - 3]; - output[1] = symbol->outfile[strlen(symbol->outfile) - 2]; - output[2] = symbol->outfile[strlen(symbol->outfile) - 1]; - output[3] = '\0'; - to_upper((unsigned char*)output); - -#ifndef NO_PNG - if(!(strcmp(output, "PNG"))) { - error_number = png_handle(symbol, rotate_angle); - } else { -#endif - if(!(strcmp(output, "EPS"))) { - error_number = ps_plot(symbol); - } else { - if(!(strcmp(output, "SVG"))) { - error_number = svg_plot(symbol); - } else { - strcpy(symbol->errtxt, "Unknown output format"); - error_tag(symbol->errtxt, ERROR_INVALID_OPTION); - return ERROR_INVALID_OPTION; - } - } -#ifndef NO_PNG - } -#endif - } else { - strcpy(symbol->errtxt, "Unknown output format"); - error_tag(symbol->errtxt, ERROR_INVALID_OPTION); - return ERROR_INVALID_OPTION; - } - - error_tag(symbol->errtxt, error_number); - return error_number; -} - -int ZBarcode_Print_Rotated(struct zint_symbol *symbol, int rotate_angle) { - /* Depreciated - will be removed in later version */ - return ZBarcode_Print(symbol, rotate_angle); -} - -int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle) -{ - int error_number; - - error_number = 0; - - error_number = ZBarcode_Encode(symbol, input, length); - if(error_number != 0) { - return error_number; - } - - error_number = ZBarcode_Print(symbol, rotate_angle); - return error_number; -} - -int ZBarcode_Encode_and_Print_Rotated(struct zint_symbol *symbol, unsigned char *input, int rotate_angle) { - /* Depreciated - will be removed in later version */ - return ZBarcode_Encode_and_Print(symbol, input, rotate_angle, strlen((char *)input)); -} - -int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) -{ - FILE *file; - unsigned long fileLen, result; - - file = fopen(filename, "rb"); - if (!file) { - strcpy(symbol->errtxt, "Unable to read input file"); - return ERROR_INVALID_DATA; - } - - /* Get file length */ - fseek(file, 0, SEEK_END); - fileLen = ftell(file); - fseek(file, 0, SEEK_SET); - - if(fileLen > 7100) { - /* The largest amount of data that can be encoded is 7089 numeric digits in QR Code */ - strcpy(symbol->errtxt, "Input file too long"); - fclose(file); - return ERROR_INVALID_DATA; - } - - /* Allocate memory */ -#ifndef _MSC_VER - unsigned char buffer[fileLen + 1]; -#else - unsigned char buffer = (unsigned char *)_alloca(fileLen + 1); -#endif - - /* Read file contents into buffer */ - result = fread(&buffer, fileLen, 1, file); - if(result != fileLen) { - strcpy(symbol->errtxt, "File read error"); - fclose(file); - return ERROR_MEMORY; - } - - fclose(file); - - return ZBarcode_Encode(symbol, buffer, fileLen); -} - -int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, char *filename, int rotate_angle) -{ - int error_number; - - error_number = 0; - - error_number = ZBarcode_Encode_File(symbol, filename); - if(error_number != 0) { - return error_number; - } - - return ZBarcode_Print(symbol, rotate_angle); -} - +/* library.c - external functions of libzint + + 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 +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include "gs1.h" + +#define TECHNETIUM "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%" + +struct zint_symbol *ZBarcode_Create() +{ + struct zint_symbol *symbol; + int i, j; + + symbol = (struct zint_symbol*)malloc(sizeof(*symbol)); + if (!symbol) return NULL; + + memset(symbol, 0, sizeof(*symbol)); + symbol->symbology = BARCODE_CODE128; + symbol->height = 0; + symbol->whitespace_width = 0; + symbol->border_width = 0; + symbol->output_options = 0; + symbol->rows = 0; + symbol->width = 0; + strcpy(symbol->fgcolour, "000000"); + strcpy(symbol->bgcolour, "ffffff"); + strcpy(symbol->outfile, "out.png"); + symbol->scale = 1.0; + symbol->option_1 = -1; + symbol->option_2 = 0; + symbol->option_3 = 928; // PDF_MAX + symbol->input_mode = DATA_MODE; + strcpy(symbol->primary, ""); + for(i = 0; i < 178; i++) { + for(j = 0; j < 1000; j++) { + unset_module(symbol, i, j); + } + symbol->row_height[i] = 0; + } + return symbol; +} + + +int ZBarcode_Delete(struct zint_symbol *symbol) +{ + free(symbol); + return 0; +} + +extern int eanx(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN system barcodes */ +extern int c39(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 3 from 9 (or Code 39) */ +extern int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmazentral Nummer (PZN) */ +extern int ec39(struct zint_symbol *symbol, unsigned char source[], int length); /* Extended Code 3 from 9 (or Code 39+) */ +extern int codabar(struct zint_symbol *symbol, unsigned char source[], int length); /* Codabar - a simple substitution cipher */ +extern int matrix_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Standard (& Matrix) */ +extern int industrial_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Industrial */ +extern int iata_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 IATA */ +extern int interleaved_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Interleaved */ +extern int logic_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Data Logic */ +extern int itf14(struct zint_symbol *symbol, unsigned char source[], int length); /* ITF-14 */ +extern int dpleit(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Leitcode */ +extern int dpident(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Identcode */ +extern int c93(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 93 - a re-working of Code 39+, generates 2 check digits */ +extern int code_128(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 128 and NVE-18 */ +extern int ean_128(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN-128 (GS1-128) */ +extern int code_11(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 11 */ +extern int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length); /* MSI Plessey */ +extern int telepen(struct zint_symbol *symbol, unsigned char source[], int length); /* Telepen ASCII */ +extern int telepen_num(struct zint_symbol *symbol, unsigned char source[], int length); /* Telepen Numeric */ +extern int plessey(struct zint_symbol *symbol, unsigned char source[], int length); /* Plessey Code */ +extern int pharma_one(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode One Track */ +extern int flattermarken(struct zint_symbol *symbol, unsigned char source[], int length); /* Flattermarken */ +extern int fim(struct zint_symbol *symbol, unsigned char source[], int length); /* Facing Identification Mark */ +extern int pharma_two(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode Two Track */ +extern int post_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* Postnet */ +extern int planet_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* PLANET */ +extern int imail(struct zint_symbol *symbol, unsigned char source[], int length); /* Intelligent Mail (aka USPS OneCode) */ +extern int royal_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* RM4SCC */ +extern int australia_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Australia Post 4-state */ +extern int code16k(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 16k */ +extern int pdf417enc(struct zint_symbol *symbol, unsigned char source[], int length); /* PDF417 */ +extern int dmatrix(struct zint_symbol *symbol, unsigned char source[], int length); /* Data Matrix (IEC16022) */ +extern int qr_code(struct zint_symbol *symbol, unsigned char source[], int length); /* QR Code */ +extern int micro_pdf417(struct zint_symbol *symbol, unsigned char source[], int length); /* Micro PDF417 */ +extern int maxicode(struct zint_symbol *symbol, unsigned char source[], int length); /* Maxicode */ +extern int rss14(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS-14 */ +extern int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Limited */ +extern int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Expanded */ +extern int composite(struct zint_symbol *symbol, unsigned char source[], int length); /* Composite Symbology */ +extern int kix_code(struct zint_symbol *symbol, unsigned char source[], int length); /* TNT KIX Code */ +extern int aztec(struct zint_symbol *symbol, unsigned char source[], int length); /* Aztec Code */ +extern int code32(struct zint_symbol *symbol, unsigned char source[], int length); /* Italian Pharmacode */ +extern int codablock(struct zint_symbol *symbol, unsigned char source[], int length); /* Codablock F */ +extern int daft_code(struct zint_symbol *symbol, unsigned char source[], int length); /* DAFT Code */ +extern int ean_14(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN-14 */ +extern int nve_18(struct zint_symbol *symbol, unsigned char source[], int length); /* NVE-18 */ +extern int microqr(struct zint_symbol *symbol, unsigned char source[], int length); /* Micro QR Code */ +extern int aztec_runes(struct zint_symbol *symbol, unsigned char source[], int length); /* Aztec Runes */ +extern int korea_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Korea Post */ +extern int japan_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Japanese Post */ +extern int code_49(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 49 */ +extern int channel_code(struct zint_symbol *symbol, unsigned char source[], int length); /* Channel Code */ +extern int code_one(struct zint_symbol *symbol, unsigned char source[], int length); /* Code One */ +extern int grid_matrix(struct zint_symbol *symbol, unsigned char source[], int length); /* Grid Matrix */ + +#ifndef NO_PNG +int png_handle(struct zint_symbol *symbol, int rotate_angle); +#endif + +extern int ps_plot(struct zint_symbol *symbol); +extern int svg_plot(struct zint_symbol *symbol); + +void error_tag(char error_string[], int error_number) +{ + char error_buffer[100]; + + if(error_number != 0) { + strcpy(error_buffer, error_string); + + if(error_number > 4) { + strcpy(error_string, "error: "); + } else { + strcpy(error_string, "warning: "); + } + + concat(error_string, error_buffer); + } +} + +int hibc(struct zint_symbol *symbol, unsigned char source[], int length) +{ + int counter, error_number, i; + char to_process[40], temp[2], check_digit; + + if(length > 36) { + strcpy(symbol->errtxt, "Data too long for HIBC LIC"); + return ERROR_TOO_LONG; + } + to_upper(source); + error_number = is_sane(TECHNETIUM , source, length); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + strcpy(to_process, "+"); + counter = 41; + for(i = 0; i < length; i++) { + counter += posn(TECHNETIUM, source[i]); + } + counter = counter % 43; + + if(counter < 10) { + check_digit = itoc(counter); + } else { + if(counter < 36) { + check_digit = (counter - 10) + 'A'; + } else { + switch(counter) { + case 36: check_digit = '-'; break; + case 37: check_digit = '.'; break; + case 38: check_digit = ' '; break; + case 39: check_digit = '$'; break; + case 40: check_digit = '/'; break; + case 41: check_digit = '+'; break; + case 42: check_digit = '%'; break; + default: check_digit = ' '; break; /* Keep compiler happy */ + } + } + } + + temp[0] = check_digit; + temp[1] = '\0'; + + concat(to_process, (char *)source); + concat(to_process, temp); + length = strlen(to_process); + + switch(symbol->symbology) { + case BARCODE_HIBC_128: + error_number = code_128(symbol, (unsigned char *)to_process, length); + ustrcpy(symbol->text, (unsigned char*)"*"); + uconcat(symbol->text, (unsigned char*)to_process); + uconcat(symbol->text, (unsigned char*)"*"); + break; + case BARCODE_HIBC_39: + symbol->option_2 = 0; + error_number = c39(symbol, (unsigned char *)to_process, length); + ustrcpy(symbol->text, (unsigned char*)"*"); + uconcat(symbol->text, (unsigned char*)to_process); + uconcat(symbol->text, (unsigned char*)"*"); + break; + case BARCODE_HIBC_DM: + error_number = dmatrix(symbol, (unsigned char *)to_process, length); + break; + case BARCODE_HIBC_QR: + error_number = qr_code(symbol, (unsigned char *)to_process, length); + break; + case BARCODE_HIBC_PDF: + error_number = pdf417enc(symbol, (unsigned char *)to_process, length); + break; + case BARCODE_HIBC_MICPDF: + error_number = micro_pdf417(symbol, (unsigned char *)to_process, length); + break; + case BARCODE_HIBC_BLOCKF: + error_number = codablock(symbol, (unsigned char *)to_process, length); + break; + } + + return error_number; +} + +int gs1_compliant(int symbology) +{ + /* Returns 1 if symbology supports GS1 data */ + + int result = 0; + + switch(symbology) { + case BARCODE_EAN128: + case BARCODE_RSS_EXP: + case BARCODE_RSS_EXPSTACK: + case BARCODE_EANX_CC: + case BARCODE_EAN128_CC: + case BARCODE_RSS14_CC: + case BARCODE_RSS_LTD_CC: + case BARCODE_RSS_EXP_CC: + case BARCODE_UPCA_CC: + case BARCODE_UPCE_CC: + case BARCODE_RSS14STACK_CC: + case BARCODE_RSS14_OMNI_CC: + case BARCODE_RSS_EXPSTACK_CC: + case BARCODE_CODE16K: + case BARCODE_AZTEC: + case BARCODE_DATAMATRIX: + case BARCODE_CODABLOCKF: + case BARCODE_CODEONE: + case BARCODE_CODE49: + case BARCODE_QRCODE: + result = 1; + break; + } + + return result; +} + +int ZBarcode_ValidID(int symbol_id) +{ + /* Checks whether a symbology is supported */ + + int result = 0; + + switch(symbol_id) { + case BARCODE_CODE11: + case BARCODE_C25MATRIX: + case BARCODE_C25INTER: + case BARCODE_C25IATA: + case BARCODE_C25LOGIC: + case BARCODE_C25IND: + case BARCODE_CODE39: + case BARCODE_EXCODE39: + case BARCODE_EANX: + case BARCODE_EAN128: + case BARCODE_CODABAR: + case BARCODE_CODE128: + case BARCODE_DPLEIT: + case BARCODE_DPIDENT: + case BARCODE_CODE16K: + case BARCODE_CODE49: + case BARCODE_CODE93: + case BARCODE_FLAT: + case BARCODE_RSS14: + case BARCODE_RSS_LTD: + case BARCODE_RSS_EXP: + case BARCODE_TELEPEN: + case BARCODE_UPCA: + case BARCODE_UPCE: + case BARCODE_POSTNET: + case BARCODE_MSI_PLESSEY: + case BARCODE_FIM: + case BARCODE_LOGMARS: + case BARCODE_PHARMA: + case BARCODE_PZN: + case BARCODE_PHARMA_TWO: + case BARCODE_PDF417: + case BARCODE_PDF417TRUNC: + case BARCODE_MAXICODE: + case BARCODE_QRCODE: + case BARCODE_CODE128B: + case BARCODE_AUSPOST: + case BARCODE_AUSREPLY: + case BARCODE_AUSROUTE: + case BARCODE_AUSREDIRECT: + case BARCODE_ISBNX: + case BARCODE_RM4SCC: + case BARCODE_DATAMATRIX: + case BARCODE_EAN14: + case BARCODE_CODABLOCKF: + case BARCODE_NVE18: + case BARCODE_JAPANPOST: + case BARCODE_KOREAPOST: + case BARCODE_RSS14STACK: + case BARCODE_RSS14STACK_OMNI: + case BARCODE_RSS_EXPSTACK: + case BARCODE_PLANET: + case BARCODE_MICROPDF417: + case BARCODE_ONECODE: + case BARCODE_PLESSEY: + case BARCODE_TELEPEN_NUM: + case BARCODE_ITF14: + case BARCODE_KIX: + case BARCODE_AZTEC: + case BARCODE_DAFT: + case BARCODE_MICROQR: + case BARCODE_HIBC_128: + case BARCODE_HIBC_39: + case BARCODE_HIBC_DM: + case BARCODE_HIBC_QR: + case BARCODE_HIBC_PDF: + case BARCODE_HIBC_MICPDF: + case BARCODE_HIBC_BLOCKF: + case BARCODE_AZRUNE: + case BARCODE_CODE32: + case BARCODE_EANX_CC: + case BARCODE_EAN128_CC: + case BARCODE_RSS14_CC: + case BARCODE_RSS_LTD_CC: + case BARCODE_RSS_EXP_CC: + case BARCODE_UPCA_CC: + case BARCODE_UPCE_CC: + case BARCODE_RSS14STACK_CC: + case BARCODE_RSS14_OMNI_CC: + case BARCODE_RSS_EXPSTACK_CC: + case BARCODE_CHANNEL: + case BARCODE_CODEONE: + /* case BARCODE_GRIDMATRIX: */ + result = 1; + break; + } + + return result; +} + +int extended_charset(struct zint_symbol *symbol, unsigned char *source, int length) +{ + int error_number = 0; + + /* These are the "elite" standards which can support multiple character sets */ + switch(symbol->symbology) { + case BARCODE_QRCODE: error_number = qr_code(symbol, source, length); break; + case BARCODE_MICROQR: error_number = microqr(symbol, source, length); break; + case BARCODE_GRIDMATRIX: error_number = grid_matrix(symbol, source, length); break; + } + + return error_number; +} + +int reduced_charset(struct zint_symbol *symbol, unsigned char *source, int length) +{ + /* These are the "norm" standards which only support Latin-1 at most */ + int error_number = 0; + +#ifndef _MSC_VER + unsigned char preprocessed[length + 1]; +#else + unsigned char* preprocessed = (unsigned char*)_alloca(length + 1); +#endif + + if(symbol->symbology == BARCODE_CODE16K) { + symbol->whitespace_width = 16; + symbol->border_width = 2; + symbol->output_options = BARCODE_BIND; + } + + if(symbol->symbology == BARCODE_ITF14) { + symbol->whitespace_width = 20; + symbol->border_width = 8; + symbol->output_options = BARCODE_BOX; + } + + switch(symbol->input_mode) { + case DATA_MODE: + case GS1_MODE: + memcpy(preprocessed, source, length); + preprocessed[length] = '\0'; + break; + case UNICODE_MODE: + error_number = latin1_process(symbol, source, preprocessed, &length); + if(error_number != 0) { return error_number; } + break; + } + + switch(symbol->symbology) { + case BARCODE_C25MATRIX: error_number = matrix_two_of_five(symbol, preprocessed, length); break; + case BARCODE_C25IND: error_number = industrial_two_of_five(symbol, preprocessed, length); break; + case BARCODE_C25INTER: error_number = interleaved_two_of_five(symbol, preprocessed, length); break; + case BARCODE_C25IATA: error_number = iata_two_of_five(symbol, preprocessed, length); break; + case BARCODE_C25LOGIC: error_number = logic_two_of_five(symbol, preprocessed, length); break; + case BARCODE_DPLEIT: error_number = dpleit(symbol, preprocessed, length); break; + case BARCODE_DPIDENT: error_number = dpident(symbol, preprocessed, length); break; + case BARCODE_UPCA: error_number = eanx(symbol, preprocessed, length); break; + case BARCODE_UPCE: error_number = eanx(symbol, preprocessed, length); break; + case BARCODE_EANX: error_number = eanx(symbol, preprocessed, length); break; + case BARCODE_EAN128: error_number = ean_128(symbol, preprocessed, length); break; + case BARCODE_CODE39: error_number = c39(symbol, preprocessed, length); break; + case BARCODE_PZN: error_number = pharmazentral(symbol, preprocessed, length); break; + case BARCODE_EXCODE39: error_number = ec39(symbol, preprocessed, length); break; + case BARCODE_CODABAR: error_number = codabar(symbol, preprocessed, length); break; + case BARCODE_CODE93: error_number = c93(symbol, preprocessed, length); break; + case BARCODE_LOGMARS: error_number = c39(symbol, preprocessed, length); break; + case BARCODE_CODE128: error_number = code_128(symbol, preprocessed, length); break; + case BARCODE_CODE128B: error_number = code_128(symbol, preprocessed, length); break; + case BARCODE_NVE18: error_number = nve_18(symbol, preprocessed, length); break; + case BARCODE_CODE11: error_number = code_11(symbol, preprocessed, length); break; + case BARCODE_MSI_PLESSEY: error_number = msi_handle(symbol, preprocessed, length); break; + case BARCODE_TELEPEN: error_number = telepen(symbol, preprocessed, length); break; + case BARCODE_TELEPEN_NUM: error_number = telepen_num(symbol, preprocessed, length); break; + case BARCODE_PHARMA: error_number = pharma_one(symbol, preprocessed, length); break; + case BARCODE_PLESSEY: error_number = plessey(symbol, preprocessed, length); break; + case BARCODE_ITF14: error_number = itf14(symbol, preprocessed, length); break; + case BARCODE_FLAT: error_number = flattermarken(symbol, preprocessed, length); break; + case BARCODE_FIM: error_number = fim(symbol, preprocessed, length); break; + case BARCODE_POSTNET: error_number = post_plot(symbol, preprocessed, length); break; + case BARCODE_PLANET: error_number = planet_plot(symbol, preprocessed, length); break; + case BARCODE_RM4SCC: error_number = royal_plot(symbol, preprocessed, length); break; + case BARCODE_AUSPOST: error_number = australia_post(symbol, preprocessed, length); break; + case BARCODE_AUSREPLY: error_number = australia_post(symbol, preprocessed, length); break; + case BARCODE_AUSROUTE: error_number = australia_post(symbol, preprocessed, length); break; + case BARCODE_AUSREDIRECT: error_number = australia_post(symbol, preprocessed, length); break; + case BARCODE_CODE16K: error_number = code16k(symbol, preprocessed, length); break; + case BARCODE_PHARMA_TWO: error_number = pharma_two(symbol, preprocessed, length); break; + case BARCODE_ONECODE: error_number = imail(symbol, preprocessed, length); break; + case BARCODE_ISBNX: error_number = eanx(symbol, preprocessed, length); break; + case BARCODE_RSS14: error_number = rss14(symbol, preprocessed, length); break; + case BARCODE_RSS14STACK: error_number = rss14(symbol, preprocessed, length); break; + case BARCODE_RSS14STACK_OMNI: error_number = rss14(symbol, preprocessed, length); break; + case BARCODE_RSS_LTD: error_number = rsslimited(symbol, preprocessed, length); break; + case BARCODE_RSS_EXP: error_number = rssexpanded(symbol, preprocessed, length); break; + case BARCODE_RSS_EXPSTACK: error_number = rssexpanded(symbol, preprocessed, length); break; + case BARCODE_EANX_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_EAN128_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_RSS14_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_RSS_LTD_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_RSS_EXP_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_UPCA_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_UPCE_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_RSS14STACK_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_RSS14_OMNI_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_RSS_EXPSTACK_CC: error_number = composite(symbol, preprocessed, length); break; + case BARCODE_KIX: error_number = kix_code(symbol, preprocessed, length); break; + case BARCODE_CODE32: error_number = code32(symbol, preprocessed, length); break; + case BARCODE_CODABLOCKF: error_number = codablock(symbol, preprocessed, length); break; + case BARCODE_DAFT: error_number = daft_code(symbol, preprocessed, length); break; + case BARCODE_EAN14: error_number = ean_14(symbol, preprocessed, length); break; + case BARCODE_AZRUNE: error_number = aztec_runes(symbol, preprocessed, length); break; + case BARCODE_KOREAPOST: error_number = korea_post(symbol, preprocessed, length); break; + case BARCODE_HIBC_128: error_number = hibc(symbol, preprocessed, length); break; + case BARCODE_HIBC_39: error_number = hibc(symbol, preprocessed, length); break; + case BARCODE_HIBC_DM: error_number = hibc(symbol, preprocessed, length); break; + case BARCODE_HIBC_QR: error_number = hibc(symbol, preprocessed, length); break; + case BARCODE_HIBC_PDF: error_number = hibc(symbol, preprocessed, length); break; + case BARCODE_HIBC_MICPDF: error_number = hibc(symbol, preprocessed, length); break; + case BARCODE_HIBC_BLOCKF: error_number = hibc(symbol, preprocessed, length); break; + case BARCODE_JAPANPOST: error_number = japan_post(symbol, preprocessed, length); break; + case BARCODE_CODE49: error_number = code_49(symbol, preprocessed, length); break; + case BARCODE_CHANNEL: error_number = channel_code(symbol, preprocessed, length); break; + case BARCODE_CODEONE: error_number = code_one(symbol, preprocessed, length); break; + case BARCODE_DATAMATRIX: error_number = dmatrix(symbol, source, length); break; + case BARCODE_PDF417: error_number = pdf417enc(symbol, source, length); break; + case BARCODE_PDF417TRUNC: error_number = pdf417enc(symbol, source, length); break; + case BARCODE_MICROPDF417: error_number = micro_pdf417(symbol, source, length); break; + case BARCODE_MAXICODE: error_number = maxicode(symbol, source, length); break; + case BARCODE_AZTEC: error_number = aztec(symbol, source, length); break; + } + + return error_number; +} + +int ZBarcode_Encode(struct zint_symbol *symbol, unsigned char *source, int length) +{ + int error_number, error_buffer, i; + error_number = 0; + + if(length == 0) { + length = ustrlen(source); + } + if(length == 0) { + strcpy(symbol->errtxt, "No input data"); + error_tag(symbol->errtxt, ERROR_INVALID_DATA); + return ERROR_INVALID_DATA; + } + + +#ifndef _MSC_VER + unsigned char local_source[length + 1]; +#else + unsigned char* local_source = (unsigned char*)_alloca(length + 1); +#endif + + /* First check the symbology field */ + if(symbol->symbology < 1) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } + + /* symbol->symbologys 1 to 86 are defined by tbarcode */ + if(symbol->symbology == 5) { symbol->symbology = BARCODE_C25MATRIX; } + if((symbol->symbology >= 10) && (symbol->symbology <= 12)) { symbol->symbology = BARCODE_EANX; } + if((symbol->symbology == 14) || (symbol->symbology == 15)) { symbol->symbology = BARCODE_EANX; } + if(symbol->symbology == 17) { symbol->symbology = BARCODE_UPCA; } + if(symbol->symbology == 19) { strcpy(symbol->errtxt, "Codabar 18 not supported, using Codabar"); symbol->symbology = BARCODE_CODABAR; error_number = WARN_INVALID_OPTION; } + if(symbol->symbology == 26) { symbol->symbology = BARCODE_UPCA; } + if(symbol->symbology == 27) { strcpy(symbol->errtxt, "UPCD1 not supported"); error_number = ERROR_INVALID_OPTION; } + if(symbol->symbology == 33) { symbol->symbology = BARCODE_EAN128; } + if((symbol->symbology == 35) || (symbol->symbology == 36)) { symbol->symbology = BARCODE_UPCA; } + if((symbol->symbology == 38) || (symbol->symbology == 39)) { symbol->symbology = BARCODE_UPCE; } + if((symbol->symbology >= 41) && (symbol->symbology <= 45)) { symbol->symbology = BARCODE_POSTNET; } + if(symbol->symbology == 46) { symbol->symbology = BARCODE_PLESSEY; } + if(symbol->symbology == 48) { symbol->symbology = BARCODE_NVE18; } + if(symbol->symbology == 54) { strcpy(symbol->errtxt, "General Parcel Code not supported, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } + if((symbol->symbology == 59) || (symbol->symbology == 61)) { symbol->symbology = BARCODE_CODE128; } + if(symbol->symbology == 62) { symbol->symbology = BARCODE_CODE93; } + if((symbol->symbology == 64) || (symbol->symbology == 65)) { symbol->symbology = BARCODE_AUSPOST; } + if(symbol->symbology == 73) { strcpy(symbol->errtxt, "Codablock E not supported"); error_number = ERROR_INVALID_OPTION; } + if(symbol->symbology == 78) { symbol->symbology = BARCODE_RSS14; } + if(symbol->symbology == 83) { symbol->symbology = BARCODE_PLANET; } + if(symbol->symbology == 88) { symbol->symbology = BARCODE_EAN128; } + if(symbol->symbology == 91) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } + if((symbol->symbology >= 94) && (symbol->symbology <= 96)) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } + if(symbol->symbology == 100) { symbol->symbology = BARCODE_HIBC_128; } + if(symbol->symbology == 101) { symbol->symbology = BARCODE_HIBC_39; } + if(symbol->symbology == 103) { symbol->symbology = BARCODE_HIBC_DM; } + if(symbol->symbology == 105) { symbol->symbology = BARCODE_HIBC_QR; } + if(symbol->symbology == 107) { symbol->symbology = BARCODE_HIBC_PDF; } + if(symbol->symbology == 109) { symbol->symbology = BARCODE_HIBC_MICPDF; } + if(symbol->symbology == 111) { symbol->symbology = BARCODE_HIBC_BLOCKF; } + if((symbol->symbology >= 112) && (symbol->symbology <= 127)) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } + /* Everything from 128 up is Zint-specific */ + if(symbol->symbology >= 143) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } + + if(error_number > 4) { + error_tag(symbol->errtxt, error_number); + return error_number; + } else { + error_buffer = error_number; + } + + if((symbol->input_mode < 0) || (symbol->input_mode > 2)) { symbol->input_mode = DATA_MODE; } + + if(symbol->input_mode == GS1_MODE) { + for(i = 0; i < length; i++) { + if(source[i] == '\0') { + strcpy(symbol->errtxt, "NULL characters not permitted in GS1 mode"); + return ERROR_INVALID_DATA; + } + } + if(gs1_compliant(symbol->symbology) == 1) { + error_number = ugs1_verify(symbol, source, length, local_source); + if(error_number != 0) { return error_number; } + length = ustrlen(local_source); + } else { + strcpy(symbol->errtxt, "Selected symbology does not support GS1 mode"); + return ERROR_INVALID_OPTION; + } + } else { + memcpy(local_source, source, length); + local_source[length] = '\0'; + } + + switch(symbol->symbology) { + case BARCODE_QRCODE: + case BARCODE_MICROQR: + case BARCODE_GRIDMATRIX: + error_number = extended_charset(symbol, local_source, length); + break; + default: + error_number = reduced_charset(symbol, local_source, length); + break; + } + + + if(error_number == 0) { + error_number = error_buffer; + } + error_tag(symbol->errtxt, error_number); + /*printf("%s\n",symbol->text);*/ + return error_number; +} + +int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle) +{ + int error_number; + char output[4]; + + switch(rotate_angle) { + case 0: + case 90: + case 180: + case 270: + break; + default: + strcpy(symbol->errtxt, "Invalid rotation angle"); + return ERROR_INVALID_OPTION; + break; + } + + if(strlen(symbol->outfile) > 3) { + output[0] = symbol->outfile[strlen(symbol->outfile) - 3]; + output[1] = symbol->outfile[strlen(symbol->outfile) - 2]; + output[2] = symbol->outfile[strlen(symbol->outfile) - 1]; + output[3] = '\0'; + to_upper((unsigned char*)output); + +#ifndef NO_PNG + if(!(strcmp(output, "PNG"))) { + error_number = png_handle(symbol, rotate_angle); + } else { +#endif + if(!(strcmp(output, "EPS"))) { + error_number = ps_plot(symbol); + } else { + if(!(strcmp(output, "SVG"))) { + error_number = svg_plot(symbol); + } else { + strcpy(symbol->errtxt, "Unknown output format"); + error_tag(symbol->errtxt, ERROR_INVALID_OPTION); + return ERROR_INVALID_OPTION; + } + } +#ifndef NO_PNG + } +#endif + } else { + strcpy(symbol->errtxt, "Unknown output format"); + error_tag(symbol->errtxt, ERROR_INVALID_OPTION); + return ERROR_INVALID_OPTION; + } + + error_tag(symbol->errtxt, error_number); + return error_number; +} + +int ZBarcode_Print_Rotated(struct zint_symbol *symbol, int rotate_angle) { + /* Depreciated - will be removed in later version */ + return ZBarcode_Print(symbol, rotate_angle); +} + +int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle) +{ + int error_number; + + error_number = 0; + + error_number = ZBarcode_Encode(symbol, input, length); + if(error_number != 0) { + return error_number; + } + + error_number = ZBarcode_Print(symbol, rotate_angle); + return error_number; +} + +int ZBarcode_Encode_and_Print_Rotated(struct zint_symbol *symbol, unsigned char *input, int rotate_angle) { + /* Depreciated - will be removed in later version */ + return ZBarcode_Encode_and_Print(symbol, input, rotate_angle, strlen((char *)input)); +} + +int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) +{ + FILE *file; + unsigned char *buffer; + unsigned long fileLen; + unsigned int nRead = 0, n = 0; + int ret; + + file = fopen(filename, "rb"); + if (!file) { + strcpy(symbol->errtxt, "Unable to read input file"); + return ERROR_INVALID_DATA; + } + + /* Get file length */ + fseek(file, 0, SEEK_END); + fileLen = ftell(file); + fseek(file, 0, SEEK_SET); + + if(fileLen > 7100) { + /* The largest amount of data that can be encoded is 7089 numeric digits in QR Code */ + strcpy(symbol->errtxt, "Input file too long"); + fclose(file); + return ERROR_INVALID_DATA; + } + + /* Allocate memory */ + buffer = (unsigned char *)malloc(fileLen * sizeof(unsigned char)); + if(!buffer) { + strcpy(symbol->errtxt, "Internal memory error"); + fclose(file); + return ERROR_MEMORY; + } + + /* Read file contents into buffer */ + + do + { + n = fread(buffer + nRead, 1, fileLen - nRead, file); + if (ferror(file)) + { + strcpy(symbol->errtxt, strerror(errno)); + nRead = 0; + return ERROR_INVALID_DATA; + } + nRead += n; + } while (!feof(file) && (0 < n) && (nRead < fileLen)); + + fclose(file); + ret = ZBarcode_Encode(symbol, buffer, nRead); + free(buffer); + return ret; +} + +int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, char *filename, int rotate_angle) +{ + int error_number; + + error_number = 0; + + error_number = ZBarcode_Encode_File(symbol, filename); + if(error_number != 0) { + return error_number; + } + + return ZBarcode_Print(symbol, rotate_angle); +} + diff --git a/frontend_qt4/datawindow.cpp b/frontend_qt4/datawindow.cpp index d082c020..cf8c3114 100644 --- a/frontend_qt4/datawindow.cpp +++ b/frontend_qt4/datawindow.cpp @@ -1,100 +1,103 @@ -/* - Zint Barcode Generator - the open source barcode generator - 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 - -#include "datawindow.h" -#include - -DataWindow::DataWindow() -{ - setupUi(this); - - connect(btnCancel, SIGNAL( clicked( bool )), SLOT(quit_now())); - connect(btnReset, SIGNAL( clicked( bool )), SLOT(clear_data())); - connect(btnOK, SIGNAL( clicked( bool )), SLOT(okay())); -} - -DataWindow::DataWindow(QString input) -{ - setupUi(this); - txtDataInput->setPlainText(input); - txtDataInput->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); - - connect(btnCancel, SIGNAL( clicked( bool )), SLOT(quit_now())); - connect(btnReset, SIGNAL( clicked( bool )), SLOT(clear_data())); - connect(btnOK, SIGNAL( clicked( bool )), SLOT(okay())); - connect(btnFromFile, SIGNAL( clicked( bool )), SLOT(from_file())); -} - -DataWindow::~DataWindow() -{ -} - -void DataWindow::quit_now() -{ - Valid = 0; - close(); -} - -void DataWindow::clear_data() -{ - txtDataInput->clear(); -} - -void DataWindow::okay() -{ - Valid = 1; - DataOutput = txtDataInput->toPlainText(); - close(); -} - -void DataWindow::from_file() -{ - QString fileName; - QFileDialog fdialog; - QFile file; - QString outstream; - char *c; - - fdialog.setFileMode(QFileDialog::ExistingFile); - - if(fdialog.exec()) { - fileName = fdialog.selectedFiles().at(0); - } else { - return; - } - - file.setFileName(fileName); - if(!file.open(QIODevice::ReadOnly)) { - QMessageBox::critical(this, tr("Open Error"), tr("Could not open selected file.")); - return; - } - - while(file.getChar(c)) { - outstream += QChar(*c); - } - - txtDataInput->setPlainText(outstream); - file.close(); +/* + Zint Barcode Generator - the open source barcode generator + 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 + +#include "datawindow.h" +#include + +DataWindow::DataWindow() +{ + setupUi(this); + + connect(btnCancel, SIGNAL( clicked( bool )), SLOT(quit_now())); + connect(btnReset, SIGNAL( clicked( bool )), SLOT(clear_data())); + connect(btnOK, SIGNAL( clicked( bool )), SLOT(okay())); +} + +DataWindow::DataWindow(QString input) +{ + setupUi(this); + txtDataInput->setPlainText(input); + txtDataInput->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); + + connect(btnCancel, SIGNAL( clicked( bool )), SLOT(quit_now())); + connect(btnReset, SIGNAL( clicked( bool )), SLOT(clear_data())); + connect(btnOK, SIGNAL( clicked( bool )), SLOT(okay())); + connect(btnFromFile, SIGNAL( clicked( bool )), SLOT(from_file())); +} + +DataWindow::~DataWindow() +{ +} + +void DataWindow::quit_now() +{ + Valid = 0; + close(); +} + +void DataWindow::clear_data() +{ + txtDataInput->clear(); +} + +void DataWindow::okay() +{ + Valid = 1; + DataOutput = txtDataInput->toPlainText(); + close(); +} + +void DataWindow::from_file() +{ + //QString fileName; + //QFileDialog fdialog; + QFile file; + + //fdialog.setFileMode(QFileDialog::ExistingFile); + // + //if(fdialog.exec()) { + // fileName = fdialog.selectedFiles().at(0); + //} else { + // return; + //} + + QString fileName = QFileDialog::getOpenFileName(this, + tr("Open File"), + "./", + tr("All Files (*);;Text Files (*.txt)")); + if (fileName.isEmpty()) + return; + + file.setFileName(fileName); + if(!file.open(QIODevice::ReadOnly)) { + QMessageBox::critical(this, tr("Open Error"), tr("Could not open selected file.")); + return; + } + + QByteArray outstream = file.readAll(); + + txtDataInput->setPlainText(QString(outstream)); + file.close(); } \ No newline at end of file diff --git a/frontend_qt4/mainwindow.cpp b/frontend_qt4/mainwindow.cpp index 429c1fbb..eb855767 100644 --- a/frontend_qt4/mainwindow.cpp +++ b/frontend_qt4/mainwindow.cpp @@ -31,17 +31,17 @@ MainWindow::MainWindow(QWidget* parent, Qt::WFlags fl) { char bstyle_text[][50] = { - "Australia Post Standard Customer", + "Australia Post Redirect Code", "Australia Post Reply-Paid", "Australia Post Routing Code", - "Australia Post Redirect Code", - "Aztec Code", + "Australia Post Standard Customer", + "Aztec Code (ISO 24778)", "Aztec Runes", "Channel Code", "Codabar", "Codablock-F", "Code 11", - "Code 128", + "Code 128 (ISO 15417)", "Code 16k", "Code 2 of 5 Data Logic", "Code 2 of 5 IATA", @@ -49,7 +49,7 @@ MainWindow::MainWindow(QWidget* parent, Qt::WFlags fl) "Code 2 of 5 Interleaved", "Code 2 of 5 Matrix", "Code 32 (Italian Pharmacode)", - "Code 39", + "Code 39 (ISO 16388)", "Code 39 Extended", "Code 49", "Code 93", @@ -60,37 +60,38 @@ MainWindow::MainWindow(QWidget* parent, Qt::WFlags fl) "Databar Limited", "Databar Stacked", "Databar Stacked Omnidirectional", - "Data Matrix", + "Data Matrix (ISO 16022)", "Deutsche Post Identcode", "Deutsche Post Leitcode", "Dutch Post KIX", "EAN-14", "European Article Number (EAN)", - "FIM", + "Facing Identification Mark (FIM)", "Flattermarken", + "Grid Matrix", "ITF-14", "International Standard Book Number (ISBN)", "Japanese Postal Barcode", "Korean Postal Barcode", "LOGMARS", - "Maxicode", - "MicroPDF417", + "Maxicode (ISO 16023)", + "MicroPDF417 (ISO 24728)", "Micro QR Code", "MSI Plessey", "NVE-18", - "PDF417", + "PDF417 (ISO 15438)", "Pharmacode", "Pharmacode 2-track", "Pharma Zentralnummer (PZN)", "PLANET", "Postnet", - "QR Code", + "QR Code (ISO 18004)", "Royal Mail 4-state Barcode", "Telepen", "Telepen Numeric", "UK Plessey", - "UPC-A", - "UPC-E", + "Universal Product Code (UPC-A)", + "Universal Product Code (UPC-E)", "USPS One Code" }; diff --git a/frontend_qt4/mainwindow.h b/frontend_qt4/mainwindow.h index b25557dc..8af049bc 100644 --- a/frontend_qt4/mainwindow.h +++ b/frontend_qt4/mainwindow.h @@ -38,10 +38,10 @@ class MainWindow : public QWidget, private Ui::mainWindow public: enum BarcodeTypes { - AUSPOST =63, + AUSREDIRECT =68, AUSREPLY =66, AUSROUTE =67, - AUSREDIRECT =68, + AUSPOST =63, AZTEC =92, AZRUNE =128, CHANNEL =140, @@ -75,6 +75,7 @@ public: EANX =13, FIM =49, FLAT =28, + GRIDMATRIX =142, ITF14 =89, ISBNX =69, JAPANPOST =76, diff --git a/frontend_qt4/sequencewindow.cpp b/frontend_qt4/sequencewindow.cpp index 83f378a8..dcb4bea7 100644 --- a/frontend_qt4/sequencewindow.cpp +++ b/frontend_qt4/sequencewindow.cpp @@ -1,192 +1,196 @@ -/* - Zint Barcode Generator - the open source barcode generator - 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 - -#include "sequencewindow.h" -#include "exportwindow.h" -#include - -SequenceWindow::SequenceWindow() -{ - setupUi(this); - QValidator *intvalid = new QIntValidator(this); - - linStartVal->setValidator(intvalid); - linEndVal->setValidator(intvalid); - linIncVal->setValidator(intvalid); - connect(btnClose, SIGNAL( clicked( bool )), SLOT(quit_now())); - connect(btnReset, SIGNAL( clicked( bool )), SLOT(reset_preview())); - connect(btnCreate, SIGNAL( clicked( bool )), SLOT(create_sequence())); - connect(txtPreview, SIGNAL( textChanged()), SLOT(check_generate())); - connect(btnImport, SIGNAL( clicked( bool )), SLOT(import())); - connect(btnExport, SIGNAL( clicked( bool )), SLOT(generate_sequence())); -} - -SequenceWindow::~SequenceWindow() -{ -} - -void SequenceWindow::quit_now() -{ - close(); -} - -void SequenceWindow::reset_preview() -{ - txtPreview->clear(); -} - -QString SequenceWindow::apply_format(QString raw_number) -{ - QString adjusted, reversed; - QString format; - int format_len, input_len, i, inpos; - char format_char; - QChar format_qchar; - - format = linFormat->text(); - input_len = raw_number.length(); - format_len = format.length(); - - inpos = input_len; - - for(i = format_len; i > 0; i--) { - format_qchar = format[i - 1]; - format_char = format_qchar.toAscii(); - switch(format_char) { - case '#': - if (inpos > 0) { - adjusted += raw_number[inpos - 1]; - inpos--; - } else { - adjusted += ' '; - } - break; - case '$': - if (inpos > 0) { - adjusted += raw_number[inpos - 1]; - inpos--; - } else { - adjusted += '0'; - } - break; - case '*': - if (inpos > 0) { - adjusted += raw_number[inpos - 1]; - inpos--; - } else { - adjusted += '*'; - } - break; - default: - adjusted += format_char; - break; - } - } - - for(i = format_len; i > 0; i--) { - reversed += adjusted[i - 1]; - } - - return reversed; -} - -void SequenceWindow::create_sequence() -{ - QString startval, endval, incval, part, outputtext; - int start, stop, step, i; - bool ok; - - startval = linStartVal->text(); - endval = linEndVal->text(); - incval = linIncVal->text(); - start = startval.toInt(&ok, 10); - stop = endval.toInt(&ok, 10); - step = incval.toInt(&ok, 10); - - if((stop <= start) || (step <= 0)) { - QMessageBox::critical(this, tr("Sequence Error"), tr("One or more of the input values is incorrect.")); - return; - } - - for(i = start; i <= stop; i += step) { - part = apply_format(QString::number(i, 10)); - part += '\n'; - outputtext += part; - } - - txtPreview->setPlainText(outputtext); -} - -void SequenceWindow::check_generate() -{ - QString preview_copy; - - preview_copy = txtPreview->toPlainText(); - if(preview_copy.isEmpty()) { - btnExport->setEnabled(false); - } else { - btnExport->setEnabled(true); - } -} - -void SequenceWindow::import() -{ - QString fileName; - QFileDialog fdialog; - QFile file; - QString outstream; - char *c; - - fdialog.setFileMode(QFileDialog::ExistingFile); - - if(fdialog.exec()) { - fileName = fdialog.selectedFiles().at(0); - } else { - return; - } - - file.setFileName(fileName); - if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - QMessageBox::critical(this, tr("Open Error"), tr("Could not open selected file.")); - return; - } - - while(file.getChar(c)) { - outstream += QChar(*c); - } - - txtPreview->setPlainText(outstream); - file.close(); -} - -void SequenceWindow::generate_sequence() -{ - int returnval; - - ExportWindow dlg; - dlg.barcode = barcode; - dlg.output_data = txtPreview->toPlainText(); - returnval = dlg.exec(); +/* + Zint Barcode Generator - the open source barcode generator + 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 + +#include "sequencewindow.h" +#include "exportwindow.h" +#include + +SequenceWindow::SequenceWindow() +{ + setupUi(this); + QValidator *intvalid = new QIntValidator(this); + + linStartVal->setValidator(intvalid); + linEndVal->setValidator(intvalid); + linIncVal->setValidator(intvalid); + connect(btnClose, SIGNAL( clicked( bool )), SLOT(quit_now())); + connect(btnReset, SIGNAL( clicked( bool )), SLOT(reset_preview())); + connect(btnCreate, SIGNAL( clicked( bool )), SLOT(create_sequence())); + connect(txtPreview, SIGNAL( textChanged()), SLOT(check_generate())); + connect(btnImport, SIGNAL( clicked( bool )), SLOT(import())); + connect(btnExport, SIGNAL( clicked( bool )), SLOT(generate_sequence())); +} + +SequenceWindow::~SequenceWindow() +{ +} + +void SequenceWindow::quit_now() +{ + close(); +} + +void SequenceWindow::reset_preview() +{ + txtPreview->clear(); +} + +QString SequenceWindow::apply_format(QString raw_number) +{ + QString adjusted, reversed; + QString format; + int format_len, input_len, i, inpos; + char format_char; + QChar format_qchar; + + format = linFormat->text(); + input_len = raw_number.length(); + format_len = format.length(); + + inpos = input_len; + + for(i = format_len; i > 0; i--) { + format_qchar = format[i - 1]; + format_char = format_qchar.toAscii(); + switch(format_char) { + case '#': + if (inpos > 0) { + adjusted += raw_number[inpos - 1]; + inpos--; + } else { + adjusted += ' '; + } + break; + case '$': + if (inpos > 0) { + adjusted += raw_number[inpos - 1]; + inpos--; + } else { + adjusted += '0'; + } + break; + case '*': + if (inpos > 0) { + adjusted += raw_number[inpos - 1]; + inpos--; + } else { + adjusted += '*'; + } + break; + default: + adjusted += format_char; + break; + } + } + + for(i = format_len; i > 0; i--) { + reversed += adjusted[i - 1]; + } + + return reversed; +} + +void SequenceWindow::create_sequence() +{ + QString startval, endval, incval, part, outputtext; + int start, stop, step, i; + bool ok; + + startval = linStartVal->text(); + endval = linEndVal->text(); + incval = linIncVal->text(); + start = startval.toInt(&ok, 10); + stop = endval.toInt(&ok, 10); + step = incval.toInt(&ok, 10); + + if((stop <= start) || (step <= 0)) { + QMessageBox::critical(this, tr("Sequence Error"), tr("One or more of the input values is incorrect.")); + return; + } + + for(i = start; i <= stop; i += step) { + part = apply_format(QString::number(i, 10)); + part += '\n'; + outputtext += part; + } + + txtPreview->setPlainText(outputtext); +} + +void SequenceWindow::check_generate() +{ + QString preview_copy; + + preview_copy = txtPreview->toPlainText(); + if(preview_copy.isEmpty()) { + btnExport->setEnabled(false); + } else { + btnExport->setEnabled(true); + } +} + +void SequenceWindow::import() +{ + //QString fileName; + //QFileDialog fdialog; + QFile file; + QString selectedFilter; + + //fdialog.setFileMode(QFileDialog::ExistingFile); + + //if(fdialog.exec()) { + // fileName = fdialog.selectedFiles().at(0); + //} else { + // return; + //} + + QString fileName = QFileDialog::getOpenFileName(this, + tr("Import File"), + "./", + tr("All Files (*);;Text Files (*.txt)")); + if (fileName.isEmpty()) + return; + + file.setFileName(fileName); + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QMessageBox::critical(this, tr("Open Error"), tr("Could not open selected file.")); + return; + } + + QByteArray outstream = file.readAll(); + + txtPreview->setPlainText(QString(outstream)); + file.close(); +} + +void SequenceWindow::generate_sequence() +{ + int returnval; + + ExportWindow dlg; + dlg.barcode = barcode; + dlg.output_data = txtPreview->toPlainText(); + returnval = dlg.exec(); } \ No newline at end of file