diff options
Diffstat (limited to 'backend/code1.c')
-rw-r--r-- | backend/code1.c | 1770 |
1 files changed, 1770 insertions, 0 deletions
diff --git a/backend/code1.c b/backend/code1.c new file mode 100644 index 0000000..8ba456b --- /dev/null +++ b/backend/code1.c @@ -0,0 +1,1770 @@ +/* code1.c - USS Code One */ + +/* + libzint - the open source barcode library + Copyright (C) 2009-2020 Robin Stuart <rstuart114@gmail.com> + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ +/* vim: set ts=4 sw=4 et : */ + +#include "common.h" +#include "code1.h" +#include "reedsol.h" +#include "large.h" +#include <stdio.h> +#include <math.h> + +static void horiz(struct zint_symbol *symbol, int row_no, int full) { + int i; + + if (full) { + for (i = 0; i < symbol->width; i++) { + set_module(symbol, row_no, i); + } + } else { + for (i = 1; i < symbol->width - 1; i++) { + set_module(symbol, row_no, i); + } + } +} + +static void central_finder(struct zint_symbol *symbol, int start_row, int row_count, int full_rows) { + int i; + + for (i = 0; i < row_count; i++) { + if (i < full_rows) { + horiz(symbol, start_row + (i * 2), 1); + } else { + horiz(symbol, start_row + (i * 2), 0); + if (i != row_count - 1) { + set_module(symbol, start_row + (i * 2) + 1, 1); + set_module(symbol, start_row + (i * 2) + 1, symbol->width - 2); + } + } + } +} + +static void vert(struct zint_symbol *symbol, int column, int height, int top) { + int i; + + if (top) { + for (i = 0; i < height; i++) { + set_module(symbol, i, column); + } + } else { + for (i = 0; i < height; i++) { + set_module(symbol, symbol->rows - i - 1, column); + } + } +} + +static void spigot(struct zint_symbol *symbol, int row_no) { + int i; + + for (i = symbol->width - 1; i > 0; i--) { + if (module_is_set(symbol, row_no, i - 1)) { + set_module(symbol, row_no, i); + } + } +} + +static int isedi(unsigned char input) { + int result = 0; + + if (input == 13) { + result = 1; + } + if (input == '*') { + result = 1; + } + if (input == '>') { + result = 1; + } + if (input == ' ') { + result = 1; + } + if ((input >= '0') && (input <= '9')) { + result = 1; + } + if ((input >= 'A') && (input <= 'Z')) { + result = 1; + } + + return result; +} + +static int dq4bi(unsigned char source[], int sourcelen, int position) { + int i; + + for (i = 0; ((position + i) < sourcelen) && isedi(source[position + i]); i++); + + if ((position + i) == sourcelen) { + /* Reached end of input */ + return 0; + } + if (i == 0) { + /* Not EDI */ + return 0; + } + + if (source[position + i - 1] == 13) { + return 1; + } + if (source[position + i - 1] == '*') { + return 1; + } + if (source[position + i - 1] == '>') { + return 1; + } + + return 0; +} + +static int c1_look_ahead_test(unsigned char source[], int sourcelen, int position, int current_mode, int gs1) { + float ascii_count, c40_count, text_count, edi_count, byte_count; + char reduced_char; + int done, best_scheme, sp; + + /* Step J */ + if (current_mode == C1_ASCII) { + ascii_count = 0.0; + c40_count = 1.0; + text_count = 1.0; + edi_count = 1.0; + byte_count = 2.0; + } else { + ascii_count = 1.0; + c40_count = 2.0; + text_count = 2.0; + edi_count = 2.0; + byte_count = 3.0; + } + + switch (current_mode) { + case C1_C40: c40_count = 0.0; + break; + case C1_TEXT: text_count = 0.0; + break; + case C1_BYTE: byte_count = 0.0; + break; + case C1_EDI: edi_count = 0.0; + break; + } + + for (sp = position; (sp < sourcelen) && (sp <= (position + 8)); sp++) { + + if (source[sp] <= 127) { + reduced_char = source[sp]; + } else { + reduced_char = source[sp] - 127; + } + + /* Step L */ + if ((source[sp] >= '0') && (source[sp] <= '9')) { + ascii_count += 0.5; + } else { + ascii_count = ceil(ascii_count); + if (source[sp] > 127) { + ascii_count += 2.0; + } else { + ascii_count += 1.0; + } + } + + /* Step M */ + done = 0; + if (reduced_char == ' ') { + c40_count += (2.0 / 3.0); + done = 1; + } + if ((reduced_char >= '0') && (reduced_char <= '9')) { + c40_count += (2.0 / 3.0); + done = 1; + } + if ((reduced_char >= 'A') && (reduced_char <= 'Z')) { + c40_count += (2.0 / 3.0); + done = 1; + } + if (source[sp] > 127) { + c40_count += (4.0 / 3.0); + } + if (done == 0) { + c40_count += (4.0 / 3.0); + } + + /* Step N */ + done = 0; + if (reduced_char == ' ') { + text_count += (2.0 / 3.0); + done = 1; + } + if ((reduced_char >= '0') && (reduced_char <= '9')) { + text_count += (2.0 / 3.0); + done = 1; + } + if ((reduced_char >= 'a') && (reduced_char <= 'z')) { + text_count += (2.0 / 3.0); + done = 1; + } + if (source[sp] > 127) { + text_count += (4.0 / 3.0); + } + if (done == 0) { + text_count += (4.0 / 3.0); + } + + /* Step O */ + done = 0; + if (source[sp] == 13) { + edi_count += (2.0 / 3.0); + done = 1; + } + if (source[sp] == '*') { + edi_count += (2.0 / 3.0); + done = 1; + } + if (source[sp] == '>') { + edi_count += (2.0 / 3.0); + done = 1; + } + if (source[sp] == ' ') { + edi_count += (2.0 / 3.0); + done = 1; + } + if ((source[sp] >= '0') && (source[sp] <= '9')) { + edi_count += (2.0 / 3.0); + done = 1; + } + if ((source[sp] >= 'A') && (source[sp] <= 'Z')) { + edi_count += (2.0 / 3.0); + done = 1; + } + if (source[sp] > 127) { + edi_count += (13.0 / 3.0); + } else { + if (done == 0) { + edi_count += (10.0 / 3.0); + } + } + + /* Step P */ + if (gs1 && (source[sp] == '[')) { + byte_count += 3.0; + } else { + byte_count += 1.0; + } + + } + + ascii_count = ceil(ascii_count); + c40_count = ceil(c40_count); + text_count = ceil(text_count); + edi_count = ceil(edi_count); + byte_count = ceil(byte_count); + best_scheme = C1_ASCII; + + if (sp == sourcelen) { + /* Step K */ + int best_count = (int) edi_count; + + if (text_count <= best_count) { + best_count = (int) text_count; + best_scheme = C1_TEXT; + } + + if (c40_count <= best_count) { + best_count = (int) c40_count; + best_scheme = C1_C40; + } + + if (ascii_count <= best_count) { + best_count = (int) ascii_count; + best_scheme = C1_ASCII; + } + + if (byte_count <= best_count) { + // best_count = (int) byte_count; + best_scheme = C1_BYTE; + } + } else { + /* Step Q */ + + if (((edi_count + 1.0 <= ascii_count) && (edi_count + 1.0 <= c40_count)) && + ((edi_count + 1.0 <= byte_count) && (edi_count + 1.0 <= text_count))) { + best_scheme = C1_EDI; + } + + if ((c40_count + 1.0 <= ascii_count) && (c40_count + 1.0 <= text_count)) { + + if (c40_count < edi_count) { + best_scheme = C1_C40; + } else { + if (c40_count == edi_count) { + if (dq4bi(source, sourcelen, position)) { + best_scheme = C1_EDI; + } else { + best_scheme = C1_C40; + } + } + } + } + + if (((text_count + 1.0 <= ascii_count) && (text_count + 1.0 <= c40_count)) && + ((text_count + 1.0 <= byte_count) && (text_count + 1.0 <= edi_count))) { + best_scheme = C1_TEXT; + } + + if (((ascii_count + 1.0 <= byte_count) && (ascii_count + 1.0 <= c40_count)) && + ((ascii_count + 1.0 <= text_count) && (ascii_count + 1.0 <= edi_count))) { + best_scheme = C1_ASCII; + } + + if (((byte_count + 1.0 <= ascii_count) && (byte_count + 1.0 <= c40_count)) && + ((byte_count + 1.0 <= text_count) && (byte_count + 1.0 <= edi_count))) { + best_scheme = C1_BYTE; + } + } + + return best_scheme; +} + +static int c1_encode(struct zint_symbol *symbol, unsigned char source[], unsigned int target[], int length) { + int current_mode, next_mode; + int sp, tp, gs1, i, j, p, latch; + int c40_buffer[6], c40_p; + int text_buffer[6], text_p; + int edi_buffer[6], edi_p; + char decimal_binary[40]; + int byte_start = 0; + + sp = 0; + tp = 0; + memset(c40_buffer, 0, sizeof(*c40_buffer)); + c40_p = 0; + memset(text_buffer, 0, sizeof(*text_buffer)); + text_p = 0; + memset(edi_buffer, 0, sizeof(*edi_buffer)); + edi_p = 0; + strcpy(decimal_binary, ""); + + if ((symbol->input_mode & 0x07) == GS1_MODE) { + gs1 = 1; + } else { + gs1 = 0; + } + if (gs1) { + /* FNC1 */ + target[tp] = 232; + tp++; + } + + /* Step A */ + current_mode = C1_ASCII; + next_mode = C1_ASCII; + + do { + if (current_mode != next_mode) { + /* Change mode */ + switch (next_mode) { + case C1_C40: target[tp] = 230; + tp++; + break; + case C1_TEXT: target[tp] = 239; + tp++; + break; + case C1_EDI: target[tp] = 238; + tp++; + break; + case C1_BYTE: target[tp] = 231; + tp++; + break; + } + } + + if ((current_mode != C1_BYTE) && (next_mode == C1_BYTE)) { + byte_start = tp; + } + current_mode = next_mode; + + if (current_mode == C1_ASCII) { + /* Step B - ASCII encodation */ + next_mode = C1_ASCII; + + if ((length - sp) >= 21) { + /* Step B1 */ + j = 0; + + for (i = 0; i < 21; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if (j == 21) { + next_mode = C1_DECIMAL; + bin_append(15, 4, decimal_binary); + } + } + + if ((next_mode == C1_ASCII) && ((length - sp) >= 13)) { + /* Step B2 */ + j = 0; + + for (i = 0; i < 13; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if (j == 13) { + latch = 0; + for (i = sp + 13; i < length; i++) { + if (!((source[i] >= '0') && (source[i] <= '9'))) { + latch = 1; + } + } + + if (!(latch)) { + next_mode = C1_DECIMAL; + bin_append(15, 4, decimal_binary); + } + } + } + + if (next_mode == C1_ASCII) { /* Step B3 */ + if (istwodigits(source, length, sp)) { + target[tp] = (10 * ctoi(source[sp])) + ctoi(source[sp + 1]) + 130; + tp++; + sp += 2; + } else { + if ((gs1) && (source[sp] == '[')) { + if ((length - sp) >= 15) { + /* Step B4 */ + j = 0; + + for (i = 0; i < 15; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if (j == 15) { + target[tp] = 236; /* FNC1 and change to Decimal */ + tp++; + sp++; + next_mode = C1_DECIMAL; + } + } + + if ((length - sp) >= 7) { /* Step B5 */ + j = 0; + + for (i = 0; i < 7; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if (j == 7) { + latch = 0; + for (i = sp + 7; i < length; i++) { + if (!((source[i] >= '0') && (source[i] <= '9'))) { + latch = 1; + } + } + + if (!(latch)) { + target[tp] = 236; /* FNC1 and change to Decimal */ + tp++; + sp++; + next_mode = C1_DECIMAL; + } + } + } + } + + if (next_mode == C1_ASCII) { + + /* Step B6 */ + next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1); + + if (next_mode == C1_ASCII) { + if (source[sp] > 127) { + /* Step B7 */ + target[tp] = 235; /* FNC4 */ + tp++; + target[tp] = (source[sp] - 128) + 1; + tp++; + sp++; + } else { + /* Step B8 */ + if ((gs1) && (source[sp] == '[')) { + target[tp] = 232; /* FNC1 */ + tp++; + sp++; + } else { + target[tp] = source[sp] + 1; + tp++; + sp++; + } + } + } + } + } + } + } + + if (current_mode == C1_C40) { + /* Step C - C40 encodation */ + + next_mode = C1_C40; + if (c40_p == 0) { + int done = 0; + if ((length - sp) >= 12) { + j = 0; + + for (i = 0; i < 12; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if (j == 12) { + next_mode = C1_ASCII; + done = 1; + } + } + + if ((length - sp) >= 8) { + int latch = 0; + j = 0; + + for (i = 0; i < 8; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if ((length - sp) == 8) { + latch = 1; + } else { + latch = 1; + for (j = sp + 8; j < length; j++) { + if ((source[j] <= '0') || (source[j] >= '9')) { + latch = 0; + } + } + } + + if ((j == 8) && latch) { + next_mode = C1_ASCII; + done = 1; + } + } + + if (!(done)) { + next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1); + } + } + + if (next_mode != C1_C40) { + target[tp] = 255; /* Unlatch */ + tp++; + } else { + int shift_set, value; + if (source[sp] > 127) { + c40_buffer[c40_p] = 1; + c40_p++; + c40_buffer[c40_p] = 30; /* Upper Shift */ + c40_p++; + shift_set = c40_shift[source[sp] - 128]; + value = c40_value[source[sp] - 128]; + } else { + shift_set = c40_shift[source[sp]]; + value = c40_value[source[sp]]; + } + + if (gs1 && (source[sp] == '[')) { + shift_set = 2; + value = 27; /* FNC1 */ + } + + if (shift_set != 0) { + c40_buffer[c40_p] = shift_set - 1; + c40_p++; + } + c40_buffer[c40_p] = value; + c40_p++; + + if (c40_p >= 3) { + int iv; + + iv = (1600 * c40_buffer[0]) + (40 * c40_buffer[1]) + (c40_buffer[2]) + 1; + target[tp] = iv / 256; + tp++; + target[tp] = iv % 256; + tp++; + + c40_buffer[0] = c40_buffer[3]; + c40_buffer[1] = c40_buffer[4]; + c40_buffer[2] = c40_buffer[5]; + c40_buffer[3] = 0; + c40_buffer[4] = 0; + c40_buffer[5] = 0; + c40_p -= 3; + } + sp++; + } + } + + if (current_mode == C1_TEXT) { + /* Step D - Text encodation */ + + next_mode = C1_TEXT; + if (text_p == 0) { + int done = 0; + if ((length - sp) >= 12) { + j = 0; + + for (i = 0; i < 12; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if (j == 12) { + next_mode = C1_ASCII; + done = 1; + } + } + + if ((length - sp) >= 8) { + int latch = 0; + j = 0; + + for (i = 0; i < 8; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if ((length - sp) == 8) { + latch = 1; + } else { + latch = 1; + for (j = sp + 8; j < length; j++) { + if ((source[j] <= '0') || (source[j] >= '9')) { + latch = 0; + } + } + } + + if ((j == 8) && latch) { + next_mode = C1_ASCII; + done = 1; + } + } + + if (!(done)) { + next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1); + } + } + + if (next_mode != C1_TEXT) { + target[tp] = 255; + tp++; /* Unlatch */ + } else { + int shift_set, value; + if (source[sp] > 127) { + text_buffer[text_p] = 1; + text_p++; + text_buffer[text_p] = 30; + text_p++; /* Upper Shift */ + shift_set = text_shift[source[sp] - 128]; + value = text_value[source[sp] - 128]; + } else { + shift_set = text_shift[source[sp]]; + value = text_value[source[sp]]; + } + + if (gs1 && (source[sp] == '[')) { + shift_set = 2; + value = 27; /* FNC1 */ + } + + if (shift_set != 0) { + text_buffer[text_p] = shift_set - 1; + text_p++; + } + text_buffer[text_p] = value; + text_p++; + + if (text_p >= 3) { + int iv; + + iv = (1600 * text_buffer[0]) + (40 * text_buffer[1]) + (text_buffer[2]) + 1; + target[tp] = iv / 256; + tp++; + target[tp] = iv % 256; + tp++; + + text_buffer[0] = text_buffer[3]; + text_buffer[1] = text_buffer[4]; + text_buffer[2] = text_buffer[5]; + text_buffer[3] = 0; + text_buffer[4] = 0; + text_buffer[5] = 0; + text_p -= 3; + } + sp++; + } + } + + if (current_mode == C1_EDI) { + /* Step E - EDI Encodation */ + + next_mode = C1_EDI; + if (edi_p == 0) { + if ((length - sp) >= 12) { + j = 0; + + for (i = 0; i < 12; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if (j == 12) { + next_mode = C1_ASCII; + } + } + + if ((length - sp) >= 8) { + int latch = 0; + j = 0; + + for (i = 0; i < 8; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if ((length - sp) == 8) { + latch = 1; + } else { + latch = 1; + for (j = sp + 8; j < length; j++) { + if ((source[j] <= '0') || (source[j] >= '9')) { + latch = 0; + } + } + } + + if ((j == 8) && latch) { + next_mode = C1_ASCII; + } + } + + if (!((isedi(source[sp]) && isedi(source[sp + 1])) && isedi(source[sp + 2]))) { + next_mode = C1_ASCII; + } + } + + if (next_mode != C1_EDI) { + target[tp] = 255; /* Unlatch */ + tp++; + } else { + int value = 0; + if (source[sp] == 13) { + value = 0; + } + if (source[sp] == '*') { + value = 1; + } + if (source[sp] == '>') { + value = 2; + } + if (source[sp] == ' ') { + value = 3; + } + if ((source[sp] >= '0') && (source[sp] <= '9')) { + value = source[sp] - '0' + 4; + } + if ((source[sp] >= 'A') && (source[sp] <= 'Z')) { + value = source[sp] - 'A' + 14; + } + + edi_buffer[edi_p] = value; + edi_p++; + + if (edi_p >= 3) { + int iv; + + iv = (1600 * edi_buffer[0]) + (40 * edi_buffer[1]) + (edi_buffer[2]) + 1; + target[tp] = iv / 256; + tp++; + target[tp] = iv % 256; + tp++; + + edi_buffer[0] = edi_buffer[3]; + edi_buffer[1] = edi_buffer[4]; + edi_buffer[2] = edi_buffer[5]; + edi_buffer[3] = 0; + edi_buffer[4] = 0; + edi_buffer[5] = 0; + edi_p -= 3; + } + sp++; + } + } + + if (current_mode == C1_DECIMAL) { + /* Step F - Decimal encodation */ + int decimal_count, data_left; + + next_mode = C1_DECIMAL; + + data_left = length - sp; + decimal_count = 0; + + if (data_left >= 1) { + if ((source[sp] >= '0') && (source[sp] <= '9')) { + decimal_count = 1; + } + } + if (data_left >= 2) { + if ((decimal_count == 1) && ((source[sp + 1] >= '0') && (source[sp + 1] <= '9'))) { + decimal_count = 2; + } + } + if (data_left >= 3) { + if ((decimal_count == 2) && ((source[sp + 2] >= '0') && (source[sp + 2] <= '9'))) { + decimal_count = 3; + } + } + + if (decimal_count != 3) { + size_t bits_left_in_byte, target_count; + int sub_target; + /* Finish Decimal mode and go back to ASCII */ + + bin_append(63, 6, decimal_binary); /* Unlatch */ + + target_count = 3; + if (strlen(decimal_binary) <= 16) { + target_count = 2; + } + if (strlen(decimal_binary) <= 8) { + target_count = 1; + } + bits_left_in_byte = (8 * target_count) - strlen(decimal_binary); + if (bits_left_in_byte == 8) { + bits_left_in_byte = 0; + } + + if (bits_left_in_byte == 2) { + bin_append(1, 2, decimal_binary); + } + + if ((bits_left_in_byte == 4) || (bits_left_in_byte == 6)) { + if (decimal_count >= 1) { + bin_append(ctoi(source[sp]) + 1, 4, decimal_binary); + sp++; + } else { + bin_append(15, 4, decimal_binary); + } + } + + if (bits_left_in_byte == 6) { + bin_append(1, 2, decimal_binary); + } + + /* Binary buffer is full - transfer to target */ + if (target_count >= 1) { + sub_target = 0; + + for (i = 0; i < 8; i++) { + if (decimal_binary[i] == '1') { + sub_target += 128 >> i; + } + } + target[tp] = sub_target; + tp++; + } + if (target_count >= 2) { + sub_target = 0; + + for (i = 0; i < 8; i++) { + if (decimal_binary[i + 8] == '1') { + sub_target += 128 >> i; + } + } + target[tp] = sub_target; + tp++; + } + if (target_count == 3) { + sub_target = 0; + + for (i = 0; i < 8; i++) { + if (decimal_binary[i + 16] == '1') { + sub_target += 128 >> i; + } + } + target[tp] = sub_target; + tp++; + } + + next_mode = C1_ASCII; + } else { + /* There are three digits - convert the value to binary */ + bin_append((100 * ctoi(source[sp])) + (10 * ctoi(source[sp + 1])) + ctoi(source[sp + 2]) + 1, 10, decimal_binary); + sp += 3; + } + + if (strlen(decimal_binary) >= 24) { + int target1 = 0, target2 = 0, target3 = 0; + char temp_binary[40]; + + /* Binary buffer is full - transfer to target */ + + for (p = 0; p < 8; p++) { + if (decimal_binary[p] == '1') { + target1 += (0x80 >> p); + } + if (decimal_binary[p + 8] == '1') { + target2 += (0x80 >> p); + } + if (decimal_binary[p + 16] == '1') { + target3 += (0x80 >> p); + } + } + target[tp] = target1; + tp++; + target[tp] = target2; + tp++; + target[tp] = target3; + tp++; + + strcpy(temp_binary, ""); + if (strlen(decimal_binary) > 24) { + for (i = 0; i <= (int) (strlen(decimal_binary) - 24); i++) { + temp_binary[i] = decimal_binary[i + 24]; + } + strcpy(decimal_binary, temp_binary); + } + } + } + + if (current_mode == C1_BYTE) { + next_mode = C1_BYTE; + + if (gs1 && (source[sp] == '[')) { + next_mode = C1_ASCII; + } else { + if (source[sp] <= 127) { + next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1); + } + } + + if (next_mode != C1_BYTE) { + /* Insert byte field length */ + if ((tp - byte_start) <= 249) { + for (i = tp; i >= byte_start; i--) { + target[i + 1] = target[i]; + } + target[byte_start] = (tp - byte_start); + tp++; + } else { + for (i = tp; i >= byte_start; i--) { + target[i + 2] = target[i]; + } + target[byte_start] = 249 + ((tp - byte_start) / 250); + target[byte_start + 1] = ((tp - byte_start) % 250); + tp += 2; + } + } else { + target[tp] = source[sp]; + tp++; + sp++; + } + } + + if (tp > 1480) { + /* Data is too large for symbol */ + strcpy(symbol->errtxt, "511: Input data too long"); + return 0; + } + } while (sp < length); + + /* Empty buffers */ + if (c40_p == 2) { + int iv; + + c40_buffer[2] = 1; + iv = (1600 * c40_buffer[0]) + (40 * c40_buffer[1]) + (c40_buffer[2]) + 1; + target[tp] = iv / 256; + tp++; + target[tp] = iv % 256; + tp++; + target[tp] = 255; + tp++; /* Unlatch */ + } + if (c40_p == 1) { + int iv; + + c40_buffer[1] = 1; + c40_buffer[2] = 31; /* Pad */ + iv = (1600 * c40_buffer[0]) + (40 * c40_buffer[1]) + (c40_buffer[2]) + 1; + target[tp] = iv / 256; + tp++; + target[tp] = iv % 256; + tp++; + target[tp] = 255; + tp++; /* Unlatch */ + } + if (text_p == 2) { + int iv; + + text_buffer[2] = 1; + iv = (1600 * text_buffer[0]) + (40 * text_buffer[1]) + (text_buffer[2]) + 1; + target[tp] = iv / 256; + tp++; + target[tp] = iv % 256; + tp++; + target[tp] = 255; + tp++; /* Unlatch */ + } + if (text_p == 1) { + int iv; + + text_buffer[1] = 1; + text_buffer[2] = 31; /* Pad */ + iv = (1600 * text_buffer[0]) + (40 * text_buffer[1]) + (text_buffer[2]) + 1; + target[tp] = iv / 256; + tp++; + target[tp] = iv % 256; + tp++; + target[tp] = 255; + tp++; /* Unlatch */ + } + + if (current_mode == C1_DECIMAL) { + size_t bits_left_in_byte, target_count; + int sub_target; + /* Finish Decimal mode and go back to ASCII */ + + bin_append(63, 6, decimal_binary); /* Unlatch */ + + target_count = 3; + if (strlen(decimal_binary) <= 16) { + target_count = 2; + } + if (strlen(decimal_binary) <= 8) { + target_count = 1; + } + bits_left_in_byte = (8 * target_count) - strlen(decimal_binary); + if (bits_left_in_byte == 8) { + bits_left_in_byte = 0; + } + + if (bits_left_in_byte == 2) { + bin_append(1, 2, decimal_binary); + } + + if ((bits_left_in_byte == 4) || (bits_left_in_byte == 6)) { + bin_append(15, 4, decimal_binary); + } + + if (bits_left_in_byte == 6) { + bin_append(1, 2, decimal_binary); + } + + /* Binary buffer is full - transfer to target */ + if (target_count >= 1) { + sub_target = 0; + + for (i = 0; i < 8; i++) { + if (decimal_binary[i] == '1') { + sub_target += 128 >> i; + } + } + target[tp] = sub_target; + tp++; + } + if (target_count >= 2) { + sub_target = 0; + + for (i = 0; i < 8; i++) { + if (decimal_binary[i + 8] == '1') { + sub_target += 128 >> i; + } + } + target[tp] = sub_target; + tp++; + } + if (target_count == 3) { + sub_target = 0; + + for (i = 0; i < 8; i++) { + if (decimal_binary[i + 16] == '1') { + sub_target += 128 >> i; + } + } + target[tp] = sub_target; + tp++; + } + } + + if (current_mode == C1_BYTE) { + /* Insert byte field length */ + if ((tp - byte_start) <= 249) { + for (i = tp; i >= byte_start; i--) { + target[i + 1] = target[i]; + } + target[byte_start] = (tp - byte_start); + tp++; + } else { + for (i = tp; i >= byte_start; i--) { + target[i + 2] = target[i]; + } + target[byte_start] = 249 + ((tp - byte_start) / 250); + target[byte_start + 1] = ((tp - byte_start) % 250); + tp += 2; + } + } + + /* Re-check length of data */ + if (tp > 1480) { + /* Data is too large for symbol */ + strcpy(symbol->errtxt, "512: Input data too long"); + return 0; + } + /* + printf("targets:\n"); + for(i = 0; i < tp; i++) { + printf("[%d]", target[i]); + } + printf("\n"); + */ + return tp; +} + +static void block_copy(struct zint_symbol *symbol, char grid[][120], int start_row, int start_col, int height, int width, int row_offset, int col_offset) { + int i, j; + + for (i = start_row; i < (start_row + height); i++) { + for (j = start_col; j < (start_col + width); j++) { + if (grid[i][j] == '1') { + set_module(symbol, i + row_offset, j + col_offset); + } + } + } +} + +INTERNAL int code_one(struct zint_symbol *symbol, unsigned char source[], int length) { + int size = 1, i, j; + + char datagrid[136][120]; + int row, col; + int sub_version = 0; + + if ((symbol->option_2 < 0) || (symbol->option_2 > 10)) { + strcpy(symbol->errtxt, "513: Invalid symbol size"); + return ZINT_ERROR_INVALID_OPTION; + } + + if (symbol->option_2 == 9) { + /* Version S */ + int codewords; + large_int elreg; + unsigned int data[15], ecc[15]; + int stream[30]; + int block_width; + + if (length > 18) { + strcpy(symbol->errtxt, "514: Input data too long"); + return ZINT_ERROR_TOO_LONG; + } + if (is_sane(NEON, source, length) == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "515: Invalid input data (Version S encodes numeric input only)"); + return ZINT_ERROR_INVALID_DATA; + } + + sub_version = 3; + codewords = 12; + block_width = 6; /* Version S-30 */ + if (length <= 12) { + /* Version S-20 */ + sub_version = 2; + codewords = 8; + block_width = 4; + } + if (length <= 6) { + /* Version S-10 */ + sub_version = 1; + codewords = 4; + block_width = 2; + } + + large_load_str_u64(&elreg, source, length); + + for (i = 0; i < 15; i++) { + data[i] = 0; + ecc[i] = 0; + } + + large_uint_array(&elreg, data, codewords, 5 /*bits*/); + + rs_init_gf(0x25); + rs_init_code(codewords, 1); + rs_encode_long(codewords, data, ecc); + rs_free(); + + for (i = 0; i < codewords; i++) { + stream[i] = data[i]; + stream[i + codewords] = ecc[codewords - i - 1]; + } + + for (i = 0; i < 136; i++) { + for (j = 0; j < 120; j++) { + datagrid[i][j] = '0'; + } + } + + i = 0; + for (row = 0; row < 2; row++) { + for (col = 0; col < block_width; col++) { + if (stream[i] & 0x10) { + datagrid[row * 2][col * 5] = '1'; + } + if (stream[i] & 0x08) { + datagrid[row * 2][(col * 5) + 1] = '1'; + } + if (stream[i] & 0x04) { + datagrid[row * 2][(col * 5) + 2] = '1'; + } + if (stream[i] & 0x02) { + datagrid[(row * 2) + 1][col * 5] = '1'; + } + if (stream[i] & 0x01) { + datagrid[(row * 2) + 1][(col * 5) + 1] = '1'; + } + if (stream[i + 1] & 0x10) { + datagrid[row * 2][(col * 5) + 3] = '1'; + } + if (stream[i + 1] & 0x08) { + datagrid[row * 2][(col * 5) + 4] = '1'; + } + if (stream[i + 1] & 0x04) { + datagrid[(row * 2) + 1][(col * 5) + 2] = '1'; + } + if (stream[i + 1] & 0x02) { + datagrid[(row * 2) + 1][(col * 5) + 3] = '1'; + } + if (stream[i + 1] & 0x01) { + datagrid[(row * 2) + 1][(col * 5) + 4] = '1'; + } + i += 2; + } + } + + size = 9; + symbol->rows = 8; + symbol->width = 10 * sub_version + 1; + } + + if (symbol->option_2 == 10) { + /* Version T */ + unsigned int data[80] = {0}; /* Allow for doubled digits */ + unsigned int ecc[22]; + unsigned int stream[60]; + int data_length; + int data_cw, ecc_cw, block_width; + + if (length > 80) { + strcpy(symbol->errtxt, "519: Input data too long"); + return ZINT_ERROR_TOO_LONG; + } + + data_length = c1_encode(symbol, source, data, length); + + if (data_length == 0) { + return ZINT_ERROR_TOO_LONG; + } + + if (data_length > 38) { + strcpy(symbol->errtxt, "516: Input data too long"); + return ZINT_ERROR_TOO_LONG; + } + + size = 10; + sub_version = 3; + data_cw = 38; + ecc_cw = 22; + block_width = 12; + if (data_length <= 24) { + sub_version = 2; + data_cw = 24; + ecc_cw = 16; + block_width = 8; + } + if (data_length <= 10) { + sub_version = 1; + data_cw = 10; + ecc_cw = 10; + block_width = 4; + } + + for (i = data_length; i < data_cw; i++) { + data[i] = 129; /* Pad */ + } + + /* Calculate error correction data */ + rs_init_gf(0x12d); + rs_init_code(ecc_cw, 1); + rs_encode_long(data_cw, data, ecc); + rs_free(); + + /* "Stream" combines data and error correction data */ + for (i = 0; i < data_cw; i++) { + stream[i] = data[i]; + } + for (i = 0; i < ecc_cw; i++) { + stream[data_cw + i] = ecc[ecc_cw - i - 1]; + } + + for (i = 0; i < 136; i++) { + for (j = 0; j < 120; j++) { + datagrid[i][j] = '0'; + } + } + + i = 0; + for (row = 0; row < 5; row++) { + for (col = 0; col < block_width; col++) { + if (stream[i] & 0x80) { + datagrid[row * 2][col * 4] = '1'; + } + if (stream[i] & 0x40) { + datagrid[row * 2][(col * 4) + 1] = '1'; + } + if (stream[i] & 0x20) { + datagrid[row * 2][(col * 4) + 2] = '1'; + } + if (stream[i] & 0x10) { + datagrid[row * 2][(col * 4) + 3] = '1'; + } + if (stream[i] & 0x08) { + datagrid[(row * 2) + 1][col * 4] = '1'; + } + if (stream[i] & 0x04) { + datagrid[(row * 2) + 1][(col * 4) + 1] = '1'; + } + if (stream[i] & 0x02) { + datagrid[(row * 2) + 1][(col * 4) + 2] = '1'; + } + if (stream[i] & 0x01) { + datagrid[(row * 2) + 1][(col * 4) + 3] = '1'; + } + i++; + } + } + + symbol->rows = 16; + symbol->width = (sub_version * 16) + 1; + } + + if ((symbol->option_2 != 9) && (symbol->option_2 != 10)) { + /* Version A to H */ + unsigned int data[1500], ecc[600]; + unsigned int sub_data[190], sub_ecc[75]; + unsigned int stream[2100]; + int data_length; + int data_blocks; + + for (i = 0; i < 1500; i++) { + data[i] = 0; + } + data_length = c1_encode(symbol, source, data, length); + + if (data_length == 0) { + strcpy(symbol->errtxt, "517: Input data is too long"); + return ZINT_ERROR_TOO_LONG; + } + + for (i = 7; i >= 0; i--) { + if (c1_data_length[i] >= data_length) { + size = i + 1; + } + } + + if (symbol->option_2 > size) { + size = symbol->option_2; + } + + if ((symbol-> option_2 != 0) && (symbol->option_2 < size)) { + strcpy(symbol->errtxt, "518: Input too long for selected symbol size"); + return ZINT_ERROR_TOO_LONG; + } + + for (i = data_length; i < c1_data_length[size - 1]; i++) { + data[i] = 129; /* Pad */ + } + + /* Calculate error correction data */ + data_length = c1_data_length[size - 1]; + for (i = 0; i < 190; i++) { + sub_data[i] = 0; + } + for (i = 0; i < 75; i++) { + sub_ecc[i] = 0; + } + + data_blocks = c1_blocks[size - 1]; + + rs_init_gf(0x12d); + rs_init_code(c1_ecc_blocks[size - 1], 0); + for (i = 0; i < data_blocks; i++) { + for (j = 0; j < c1_data_blocks[size - 1]; j++) { + + sub_data[j] = data[j * data_blocks + i]; + } + rs_encode_long(c1_data_blocks[size - 1], sub_data, sub_ecc); + for (j = 0; j < c1_ecc_blocks[size - 1]; j++) { + ecc[c1_ecc_length[size - 1] - (j * data_blocks + i) - 1] = sub_ecc[j]; + } + } + rs_free(); + + /* "Stream" combines data and error correction data */ + for (i = 0; i < data_length; i++) { + stream[i] = data[i]; + } + for (i = 0; i < c1_ecc_length[size - 1]; i++) { + stream[data_length + i] = ecc[i]; + } + + for (i = 0; i < 136; i++) { + for (j = 0; j < 120; j++) { + datagrid[i][j] = '0'; + } + } + + i = 0; + for (row = 0; row < c1_grid_height[size - 1]; row++) { + for (col = 0; col < c1_grid_width[size - 1]; col++) { + if (stream[i] & 0x80) { + datagrid[row * 2][col * 4] = '1'; + } + if (stream[i] & 0x40) { + datagrid[row * 2][(col * 4) + 1] = '1'; + } + if (stream[i] & 0x20) { + datagrid[row * 2][(col * 4) + 2] = '1'; + } + if (stream[i] & 0x10) { + datagrid[row * 2][(col * 4) + 3] = '1'; + } + if (stream[i] & 0x08) { + datagrid[(row * 2) + 1][col * 4] = '1'; + } + if (stream[i] & 0x04) { + datagrid[(row * 2) + 1][(col * 4) + 1] = '1'; + } + if (stream[i] & 0x02) { + datagrid[(row * 2) + 1][(col * 4) + 2] = '1'; + } + if (stream[i] & 0x01) { + datagrid[(row * 2) + 1][(col * 4) + 3] = '1'; + } + i++; + } + } + + symbol->rows = c1_height[size - 1]; + symbol->width = c1_width[size - 1]; + } + + switch (size) { + case 1: /* Version A */ + central_finder(symbol, 6, 3, 1); + vert(symbol, 4, 6, 1); + vert(symbol, 12, 5, 0); + set_module(symbol, 5, 12); + spigot(symbol, 0); + spigot(symbol, 15); + block_copy(symbol, datagrid, 0, 0, 5, 4, 0, 0); + block_copy(symbol, datagrid, 0, 4, 5, 12, 0, 2); + block_copy(symbol, datagrid, 5, 0, 5, 12, 6, 0); + block_copy(symbol, datagrid, 5, 12, 5, 4, 6, 2); + break; + case 2: /* Version B */ + central_finder(symbol, 8, 4, 1); + vert(symbol, 4, 8, 1); + vert(symbol, 16, 7, 0); + set_module(symbol, 7, 16); + spigot(symbol, 0); + spigot(symbol, 21); + block_copy(symbol, datagrid, 0, 0, 7, 4, 0, 0); + block_copy(symbol, datagrid, 0, 4, 7, 16, 0, 2); + block_copy(symbol, datagrid, 7, 0, 7, 16, 8, 0); + block_copy(symbol, datagrid, 7, 16, 7, 4, 8, 2); + break; + case 3: /* Version C */ + central_finder(symbol, 11, 4, 2); + vert(symbol, 4, 11, 1); + vert(symbol, 26, 13, 1); + vert(symbol, 4, 10, 0); + vert(symbol, 26, 10, 0); + spigot(symbol, 0); + spigot(symbol, 27); + block_copy(symbol, datagrid, 0, 0, 10, 4, 0, 0); + block_copy(symbol, datagrid, 0, 4, 10, 20, 0, 2); + block_copy(symbol, datagrid, 0, 24, 10, 4, 0, 4); + block_copy(symbol, datagrid, 10, 0, 10, 4, 8, 0); + block_copy(symbol, datagrid, 10, 4, 10, 20, 8, 2); + block_copy(symbol, datagrid, 10, 24, 10, 4, 8, 4); + break; + case 4: /* Version D */ + central_finder(symbol, 16, 5, 1); + vert(symbol, 4, 16, 1); + vert(symbol, 20, 16, 1); + vert(symbol, 36, 16, 1); + vert(symbol, 4, 15, 0); + vert(symbol, 20, 15, 0); + vert(symbol, 36, 15, 0); + spigot(symbol, 0); + spigot(symbol, 12); + spigot(symbol, 27); + spigot(symbol, 39); + block_copy(symbol, datagrid, 0, 0, 15, 4, 0, 0); + block_copy(symbol, datagrid, 0, 4, 15, 14, 0, 2); + block_copy(symbol, datagrid, 0, 18, 15, 14, 0, 4); + block_copy(symbol, datagrid, 0, 32, 15, 4, 0, 6); + block_copy(symbol, datagrid, 15, 0, 15, 4, 10, 0); + block_copy(symbol, datagrid, 15, 4, 15, 14, 10, 2); + block_copy(symbol, datagrid, 15, 18, 15, 14, 10, 4); + block_copy(symbol, datagrid, 15, 32, 15, 4, 10, 6); + break; + case 5: /* Version E */ + central_finder(symbol, 22, 5, 2); + vert(symbol, 4, 22, 1); + vert(symbol, 26, 24, 1); + vert(symbol, 48, 22, 1); + vert(symbol, 4, 21, 0); + vert(symbol, 26, 21, 0); + vert(symbol, 48, 21, 0); + spigot(symbol, 0); + spigot(symbol, 12); + spigot(symbol, 39); + spigot(symbol, 51); + block_copy(symbol, datagrid, 0, 0, 21, 4, 0, 0); + block_copy(symbol, datagrid, 0, 4, 21, 20, 0, 2); + block_copy(symbol, datagrid, 0, 24, 21, 20, 0, 4); + block_copy(symbol, datagrid, 0, 44, 21, 4, 0, 6); + block_copy(symbol, datagrid, 21, 0, 21, 4, 10, 0); + block_copy(symbol, datagrid, 21, 4, 21, 20, 10, 2); + block_copy(symbol, datagrid, 21, 24, 21, 20, 10, 4); + block_copy(symbol, datagrid, 21, 44, 21, 4, 10, 6); + break; + case 6: /* Version F */ + central_finder(symbol, 31, 5, 3); + vert(symbol, 4, 31, 1); + vert(symbol, 26, 35, 1); + vert(symbol, 48, 31, 1); + vert(symbol, 70, 35, 1); + vert(symbol, 4, 30, 0); + vert(symbol, 26, 30, 0); + vert(symbol, 48, 30, 0); + vert(symbol, 70, 30, 0); + spigot(symbol, 0); + spigot(symbol, 12); + spigot(symbol, 24); + spigot(symbol, 45); + spigot(symbol, 57); + spigot(symbol, 69); + block_copy(symbol, datagrid, 0, 0, 30, 4, 0, 0); + block_copy(symbol, datagrid, 0, 4, 30, 20, 0, 2); + block_copy(symbol, datagrid, 0, 24, 30, 20, 0, 4); + block_copy(symbol, datagrid, 0, 44, 30, 20, 0, 6); + block_copy(symbol, datagrid, 0, 64, 30, 4, 0, 8); + block_copy(symbol, datagrid, 30, 0, 30, 4, 10, 0); + block_copy(symbol, datagrid, 30, 4, 30, 20, 10, 2); + block_copy(symbol, datagrid, 30, 24, 30, 20, 10, 4); + block_copy(symbol, datagrid, 30, 44, 30, 20, 10, 6); + block_copy(symbol, datagrid, 30, 64, 30, 4, 10, 8); + break; + case 7: /* Version G */ + central_finder(symbol, 47, 6, 2); + vert(symbol, 6, 47, 1); + vert(symbol, 27, 49, 1); + vert(symbol, 48, 47, 1); + vert(symbol, 69, 49, 1); + vert(symbol, 90, 47, 1); + vert(symbol, 6, 46, 0); + vert(symbol, 27, 46, 0); + vert(symbol, 48, 46, 0); + vert(symbol, 69, 46, 0); + vert(symbol, 90, 46, 0); + spigot(symbol, 0); + spigot(symbol, 12); + spigot(symbol, 24); + spigot(symbol, 36); + spigot(symbol, 67); + spigot(symbol, 79); + spigot(symbol, 91); + spigot(symbol, 103); + block_copy(symbol, datagrid, 0, 0, 46, 6, 0, 0); + block_copy(symbol, datagrid, 0, 6, 46, 19, 0, 2); + block_copy(symbol, datagrid, 0, 25, 46, 19, 0, 4); + block_copy(symbol, datagrid, 0, 44, 46, 19, 0, 6); + block_copy(symbol, datagrid, 0, 63, 46, 19, 0, 8); + block_copy(symbol, datagrid, 0, 82, 46, 6, 0, 10); + block_copy(symbol, datagrid, 46, 0, 46, 6, 12, 0); + block_copy(symbol, datagrid, 46, 6, 46, 19, 12, 2); + block_copy(symbol, datagrid, 46, 25, 46, 19, 12, 4); + block_copy(symbol, datagrid, 46, 44, 46, 19, 12, 6); + block_copy(symbol, datagrid, 46, 63, 46, 19, 12, 8); + block_copy(symbol, datagrid, 46, 82, 46, 6, 12, 10); + break; + case 8: /* Version H */ + central_finder(symbol, 69, 6, 3); + vert(symbol, 6, 69, 1); + vert(symbol, 26, 73, 1); + vert(symbol, 46, 69, 1); + vert(symbol, 66, 73, 1); + vert(symbol, 86, 69, 1); + vert(symbol, 106, 73, 1); + vert(symbol, 126, 69, 1); + vert(symbol, 6, 68, 0); + vert(symbol, 26, 68, 0); + vert(symbol, 46, 68, 0); + vert(symbol, 66, 68, 0); + vert(symbol, 86, 68, 0); + vert(symbol, 106, 68, 0); + vert(symbol, 126, 68, 0); + spigot(symbol, 0); + spigot(symbol, 12); + spigot(symbol, 24); + spigot(symbol, 36); + spigot(symbol, 48); + spigot(symbol, 60); + spigot(symbol, 87); + spigot(symbol, 99); + spigot(symbol, 111); + spigot(symbol, 123); + spigot(symbol, 135); + spigot(symbol, 147); + block_copy(symbol, datagrid, 0, 0, 68, 6, 0, 0); + block_copy(symbol, datagrid, 0, 6, 68, 18, 0, 2); + block_copy(symbol, datagrid, 0, 24, 68, 18, 0, 4); + block_copy(symbol, datagrid, 0, 42, 68, 18, 0, 6); + block_copy(symbol, datagrid, 0, 60, 68, 18, 0, 8); + block_copy(symbol, datagrid, 0, 78, 68, 18, 0, 10); + block_copy(symbol, datagrid, 0, 96, 68, 18, 0, 12); + block_copy(symbol, datagrid, 0, 114, 68, 6, 0, 14); + block_copy(symbol, datagrid, 68, 0, 68, 6, 12, 0); + block_copy(symbol, datagrid, 68, 6, 68, 18, 12, 2); + block_copy(symbol, datagrid, 68, 24, 68, 18, 12, 4); + block_copy(symbol, datagrid, 68, 42, 68, 18, 12, 6); + block_copy(symbol, datagrid, 68, 60, 68, 18, 12, 8); + block_copy(symbol, datagrid, 68, 78, 68, 18, 12, 10); + block_copy(symbol, datagrid, 68, 96, 68, 18, 12, 12); + block_copy(symbol, datagrid, 68, 114, 68, 6, 12, 14); + break; + case 9: /* Version S */ + horiz(symbol, 5, 1); + horiz(symbol, 7, 1); + set_module(symbol, 6, 0); + set_module(symbol, 6, symbol->width - 1); + unset_module(symbol, 7, 1); + unset_module(symbol, 7, symbol->width - 2); + switch (sub_version) { + case 1: /* Version S-10 */ + set_module(symbol, 0, 5); + block_copy(symbol, datagrid, 0, 0, 4, 5, 0, 0); + block_copy(symbol, datagrid, 0, 5, 4, 5, 0, 1); + break; + case 2: /* Version S-20 */ + set_module(symbol, 0, 10); + set_module(symbol, 4, 10); + block_copy(symbol, datagrid, 0, 0, 4, 10, 0, 0); + block_copy(symbol, datagrid, 0, 10, 4, 10, 0, 1); + break; + case 3: /* Version S-30 */ + set_module(symbol, 0, 15); + set_module(symbol, 4, 15); + set_module(symbol, 6, 15); + block_copy(symbol, datagrid, 0, 0, 4, 15, 0, 0); + block_copy(symbol, datagrid, 0, 15, 4, 15, 0, 1); + break; + } + break; + case 10: /* Version T */ + horiz(symbol, 11, 1); + horiz(symbol, 13, 1); + horiz(symbol, 15, 1); + set_module(symbol, 12, 0); + set_module(symbol, 12, symbol->width - 1); + set_module(symbol, 14, 0); + set_module(symbol, 14, symbol->width - 1); + unset_module(symbol, 13, 1); + unset_module(symbol, 13, symbol->width - 2); + unset_module(symbol, 15, 1); + unset_module(symbol, 15, symbol->width - 2); + switch (sub_version) { + case 1: /* Version T-16 */ + set_module(symbol, 0, 8); + set_module(symbol, 10, 8); + block_copy(symbol, datagrid, 0, 0, 10, 8, 0, 0); + block_copy(symbol, datagrid, 0, 8, 10, 8, 0, 1); + break; + case 2: /* Version T-32 */ + set_module(symbol, 0, 16); + set_module(symbol, 10, 16); + set_module(symbol, 12, 16); + block_copy(symbol, datagrid, 0, 0, 10, 16, 0, 0); + block_copy(symbol, datagrid, 0, 16, 10, 16, 0, 1); + break; + case 3: /* Verion T-48 */ + set_module(symbol, 0, 24); + set_module(symbol, 10, 24); + set_module(symbol, 12, 24); + set_module(symbol, 14, 24); + block_copy(symbol, datagrid, 0, 0, 10, 24, 0, 0); + block_copy(symbol, datagrid, 0, 24, 10, 24, 0, 1); + break; + } + break; + } + + for (i = 0; i < symbol->rows; i++) { + symbol->row_height[i] = 1; + } + + return 0; +} |