1
0
mirror of https://github.com/woo-j/zint.git synced 2024-12-27 11:21:30 +03:00
zint/backend/dmatrix.c
2009-06-11 20:37:47 +00:00

1318 lines
46 KiB
C

/* dmatrix.c - Handles Data Matrix 2-D symbology */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <robin@zint.org.uk>
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 <string.h>
#include <stdio.h>
#ifdef _MSC_VER
#include <malloc.h>
#endif
#include "dmatrix.h"
#include "common.h"
#ifdef _MSC_VER
#include "dm200.h"
#else
extern int data_matrix_200(struct zint_symbol *symbol, unsigned char source[]);
#endif
#define B11SET " 0123456789"
#define B27SET " ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define B37SET " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
#define B41SET " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,-/"
void crc_machine(char data_prefix_bitstream[], int scheme, unsigned char source[])
{
int input_length, i;
input_length = ustrlen(source);
char xor_register[17];
#ifndef _MSC_VER
char precrc_bitstream[(input_length * 8) + 18];
char precrc_bitstream_reversed[(input_length * 8) + 18];
#else
char* precrc_bitstream = (char*)_alloca((input_length * 8) + 18);
char* precrc_bitstream_reversed = (char*)_alloca((input_length * 8) + 18);
#endif
int machine_cycles;
char input_bit, out1, out2, out3;
switch(scheme) {
case 11: strcpy(precrc_bitstream, "0000000100000000"); break;
case 27: strcpy(precrc_bitstream, "0000001000000000"); break;
case 41: strcpy(precrc_bitstream, "0000001100000000"); break;
case 37: strcpy(precrc_bitstream, "0000010000000000"); break;
default: strcpy(precrc_bitstream, "0000010100000000"); break;
}
for(i = 0; i < input_length; i++) {
if(source[i] & 0x80) { concat(precrc_bitstream, "1"); } else { concat(precrc_bitstream, "0"); }
if(source[i] & 0x40) { concat(precrc_bitstream, "1"); } else { concat(precrc_bitstream, "0"); }
if(source[i] & 0x20) { concat(precrc_bitstream, "1"); } else { concat(precrc_bitstream, "0"); }
if(source[i] & 0x10) { concat(precrc_bitstream, "1"); } else { concat(precrc_bitstream, "0"); }
if(source[i] & 0x08) { concat(precrc_bitstream, "1"); } else { concat(precrc_bitstream, "0"); }
if(source[i] & 0x04) { concat(precrc_bitstream, "1"); } else { concat(precrc_bitstream, "0"); }
if(source[i] & 0x02) { concat(precrc_bitstream, "1"); } else { concat(precrc_bitstream, "0"); }
if(source[i] & 0x01) { concat(precrc_bitstream, "1"); } else { concat(precrc_bitstream, "0"); }
}
/* pre-CRC bit stream byte reversal */
for(i = 0; i < (input_length + 2); i++) {
precrc_bitstream_reversed[0 + (i * 8)] = precrc_bitstream[7 + (i * 8)];
precrc_bitstream_reversed[1 + (i * 8)] = precrc_bitstream[6 + (i * 8)];
precrc_bitstream_reversed[2 + (i * 8)] = precrc_bitstream[5 + (i * 8)];
precrc_bitstream_reversed[3 + (i * 8)] = precrc_bitstream[4 + (i * 8)];
precrc_bitstream_reversed[4 + (i * 8)] = precrc_bitstream[3 + (i * 8)];
precrc_bitstream_reversed[5 + (i * 8)] = precrc_bitstream[2 + (i * 8)];
precrc_bitstream_reversed[6 + (i * 8)] = precrc_bitstream[1 + (i * 8)];
precrc_bitstream_reversed[7 + (i * 8)] = precrc_bitstream[0 + (i * 8)];
}
precrc_bitstream_reversed[strlen(precrc_bitstream)] = '\0';
machine_cycles = strlen(precrc_bitstream_reversed);
/* Start up the machine */
for(i = 0; i < 16; i++) {
xor_register[i] = '0';
}
input_bit = precrc_bitstream_reversed[0];
if(input_bit != xor_register[15]) { out1 = '1'; } else { out1 = '0'; }
if(input_bit != xor_register[11]) { out2 = '1'; } else { out2 = '0'; }
if(input_bit != xor_register[4]) { out3 = '1'; } else { out3 = '0'; }
for(i = 0; i < machine_cycles; i++) {
xor_register[15] = xor_register[14];
xor_register[14] = xor_register[13];
xor_register[13] = xor_register[12];
xor_register[12] = out2;
xor_register[11] = xor_register[10];
xor_register[10] = xor_register[9];
xor_register[9] = xor_register[8];
xor_register[8] = xor_register[7];
xor_register[7] = xor_register[6];
xor_register[6] = xor_register[5];
xor_register[5] = out3;
xor_register[4] = xor_register[3];
xor_register[3] = xor_register[2];
xor_register[2] = xor_register[1];
xor_register[1] = xor_register[0];
xor_register[0] = out1;
input_bit = precrc_bitstream_reversed[(i + 1)];
if(input_bit != xor_register[15]) { out1 = '1'; } else { out1 = '0'; }
if(out1 != xor_register[11]) { out2 = '1'; } else { out2 = '0'; }
if(out1 != xor_register[4]) { out3 = '1'; } else { out3 = '0'; }
}
for(i = 0; i < 16; i++) {
data_prefix_bitstream[i + 5] = xor_register[15 - i];
}
data_prefix_bitstream[16 + 5] = '\0';
return;
}
void i1_base11(char binary_string[], unsigned char source[])
{
int input_length, blocks, remainder, i, j;
char block_binary[22];
int block_value, c[6], weight[6];
int binary_posn;
input_length = ustrlen(source);
binary_posn = strlen(binary_string);
blocks = input_length / 6;
remainder = input_length % 6;
weight[0] = 1;
weight[1] = 11;
weight[2] = 121;
weight[3] = 1331;
weight[4] = 14641;
weight[5] = 161051;
for(i = 0; i < blocks; i++) {
strcpy(block_binary, "");
block_value = 0;
binary_posn = strlen(binary_string);
for(j = 0; j < 6; j++) {
c[j] = posn(B11SET, source[(i * 6) + j]);
c[j] *= weight[j];
block_value += c[j];
}
if(block_value & 0x100000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x80000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x40000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x20000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x10000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x8000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x4000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x2000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x1000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x800) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x400) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x200) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x100) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x80) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
for(j = 0; j < strlen(block_binary); j++) {
binary_string[strlen(block_binary) + binary_posn - j - 1] = block_binary[j];
}
binary_string[strlen(block_binary) + binary_posn] = '\0';
binary_posn = strlen(binary_string);
}
strcpy(block_binary, "");
block_value = 0;
binary_posn = strlen(binary_string);
for(j = 0; j < remainder; j++) {
c[j] = posn(B11SET, source[(i * 6) + j]);
c[j] *= weight[j];
block_value += c[j];
}
switch(remainder) {
case 5:
if(block_value & 0x20000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x10000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x8000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x4000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
case 4:
if(block_value & 0x2000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x1000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x800) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
case 3:
if(block_value & 0x400) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x200) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x100) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x80) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
case 2:
if(block_value & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
case 1:
if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
default:
break;
}
for(j = 0; j < strlen(block_binary); j++) {
binary_string[strlen(block_binary) + binary_posn - j - 1] = block_binary[j];
}
binary_string[strlen(block_binary) + binary_posn] = '\0';
binary_posn = strlen(binary_string);
return;
}
void i2_base27(char binary_string[], unsigned char source[])
{
int input_length, blocks, remainder, i, j;
char block_binary[25];
int block_value, c[5], weight[5];
int binary_posn;
input_length = ustrlen(source);
blocks = input_length / 5;
remainder = input_length % 5;
binary_posn = strlen(binary_string);
weight[0] = 1;
weight[1] = 27;
weight[2] = 729;
weight[3] = 19683;
weight[4] = 531441;
for(i = 0; i < blocks; i++) {
strcpy(block_binary, "");
block_value = 0;
for(j = 0; j < 5; j++) {
c[j] = posn(B27SET, source[(i * 5) + j]);
c[j] *= weight[j];
block_value += c[j];
}
if(block_value & 0x800000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x400000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x200000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x100000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x80000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x40000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x20000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x10000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x8000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x4000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x2000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x1000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x800) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x400) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x200) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x100) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x80) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
for(j = 0; j < strlen(block_binary); j++) {
binary_string[strlen(block_binary) + binary_posn - j - 1] = block_binary[j];
}
binary_string[strlen(block_binary) + binary_posn] = '\0';
binary_posn = strlen(binary_string);
}
strcpy(block_binary, "");
block_value = 0;
for(j = 0; j < remainder; j++) {
c[j] = posn(B27SET, source[(i * 5) + j]);
c[j] *= weight[j];
block_value += c[j];
}
switch(remainder) {
case 4:
if(block_value & 0x80000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x40000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x20000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x10000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x8000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
case 3:
if(block_value & 0x4000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x2000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x1000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x800) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x400) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
case 2:
if(block_value & 0x200) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x100) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x80) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
case 1:
if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
default:
break;
}
for(j = 0; j < strlen(block_binary); j++) {
binary_string[strlen(block_binary) + binary_posn - j - 1] = block_binary[j];
}
binary_string[strlen(block_binary) + binary_posn] = '\0';
binary_posn = strlen(binary_string);
return;
}
void i3_base37(char binary_string[], unsigned char source[])
{
int input_length, blocks, remainder, i, j;
char block_binary[22];
int block_value, c[6], weight[6];
int binary_posn;
input_length = ustrlen(source);
blocks = input_length / 4;
remainder = input_length % 4;
binary_posn = strlen(binary_string);
weight[0] = 1;
weight[1] = 37;
weight[2] = 1369;
weight[3] = 50653;
for(i = 0; i < blocks; i++) {
strcpy(block_binary, "");
block_value = 0;
for(j = 0; j < 4; j++) {
c[j] = posn(B37SET, source[(i * 4) + j]);
c[j] *= weight[j];
block_value += c[j];
}
if(block_value & 0x100000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x80000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x40000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x20000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x10000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x8000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x4000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x2000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x1000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x800) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x400) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x200) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x100) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x80) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
for(j = 0; j < strlen(block_binary); j++) {
binary_string[strlen(block_binary) + binary_posn - j - 1] = block_binary[j];
}
binary_string[strlen(block_binary) + binary_posn] = '\0';
binary_posn = strlen(binary_string);
}
strcpy(block_binary, "");
block_value = 0;
for(j = 0; j < remainder; j++) {
c[j] = posn(B37SET, source[(i * 4) + j]);
c[j] *= weight[j];
block_value += c[j];
}
switch(remainder) {
case 3:
if(block_value & 0x8000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x4000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x2000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x1000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x800) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
case 2:
if(block_value & 0x400) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x200) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x100) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x80) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
case 1:
if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
default:
break;
}
for(j = 0; j < strlen(block_binary); j++) {
binary_string[strlen(block_binary) + binary_posn - j - 1] = block_binary[j];
}
binary_string[strlen(block_binary) + binary_posn] = '\0';
binary_posn = strlen(binary_string);
return;
}
void i4_base41(char binary_string[], unsigned char source[])
{
int input_length, blocks, remainder, i, j;
char block_binary[23];
int block_value, c[6], weight[6];
int binary_posn;
input_length = ustrlen(source);
blocks = input_length / 4;
remainder = input_length % 4;
binary_posn = strlen(binary_string);
weight[0] = 1;
weight[1] = 41;
weight[2] = 1681;
weight[3] = 68921;
for(i = 0; i < blocks; i++) {
strcpy(block_binary, "");
block_value = 0;
for(j = 0; j < 4; j++) {
c[j] = posn(B41SET, source[(i * 4) + j]);
c[j] *= weight[j];
block_value += c[j];
}
if(block_value & 0x200000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x100000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x80000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x40000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x20000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x10000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x8000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x4000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x2000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x1000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x800) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x400) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x200) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x100) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x80) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
for(j = 0; j < strlen(block_binary); j++) {
binary_string[strlen(block_binary) + binary_posn - j - 1] = block_binary[j];
}
binary_string[strlen(block_binary) + binary_posn] = '\0';
binary_posn = strlen(binary_string);
}
strcpy(block_binary, "");
block_value = 0;
for(j = 0; j < remainder; j++) {
c[j] = posn(B41SET, source[(i * 4) + j]);
c[j] *= weight[j];
block_value += c[j];
}
switch(remainder) {
case 3:
if(block_value & 0x10000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x8000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x4000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x2000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x1000) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x800) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
case 2:
if(block_value & 0x400) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x200) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x100) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x80) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
case 1:
if(block_value & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(block_value & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
default:
break;
}
for(j = 0; j < strlen(block_binary); j++) {
binary_string[strlen(block_binary) + binary_posn - j - 1] = block_binary[j];
}
binary_string[strlen(block_binary) + binary_posn] = '\0';
binary_posn = strlen(binary_string);
return;
}
void base128(char binary_string[], unsigned char source[])
{
int i, j, input_length;
char block_binary[9];
int binary_posn;
input_length = ustrlen(source);
binary_posn = strlen(binary_string);
for(i = 0; i < input_length; i++) {
strcpy(block_binary, "");
if(source[i] & 0x40) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(source[i] & 0x20) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(source[i] & 0x10) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(source[i] & 0x08) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(source[i] & 0x04) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(source[i] & 0x02) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
if(source[i] & 0x01) { concat(block_binary, "1"); } else { concat(block_binary, "0"); }
for(j = 0; j < strlen(block_binary); j++) {
binary_string[strlen(block_binary) + binary_posn - j - 1] = block_binary[j];
}
binary_string[strlen(block_binary) + binary_posn] = '\0';
binary_posn = strlen(binary_string);
}
return;
}
void protect_ecc000(char protected_stream[], char unprotected_stream[])
{
/* ECC 000 - No processing needed */
strcpy(protected_stream, unprotected_stream);
}
void protect_ecc050(char protected_stream[], char unprotected_stream[])
{
/* ECC 050 - 4-3-3 convolutional code */
/* State machine illustrated in figure K1 */
char top_reg[4];
char mid_reg[4];
char low_reg[4];
char u1, u2, u3;
char output[6];
char gate_input[8];
int i, blocks, j, count;
strcpy(protected_stream, "");
for(i = 0; i < 3; i++) {
top_reg[i] = '0';
mid_reg[i] = '0';
low_reg[i] = '0';
}
for(i = 0; i < (strlen(unprotected_stream) % 3); i++){
concat(unprotected_stream, "0");
}
blocks = strlen(unprotected_stream) / 3;
blocks += 3;
for(i = 0; i < blocks; i++) {
if(i < (blocks - 3)) {
u1 = unprotected_stream[3 * i];
u2 = unprotected_stream[(3 * i) + 1];
u3 = unprotected_stream[(3 * i) + 2];
} else {
u1 = '0';
u2 = '0';
u3 = '0';
}
/* Gate 1 */
for(j = 0; j < 8; j++) {
gate_input[j] = '0';
}
gate_input[0] = u1;
gate_input[1] = mid_reg[2];
gate_input[2] = low_reg[0];
gate_input[3] = low_reg[1];
gate_input[4] = low_reg[2];
count = 0;
for(j = 0; j < 5; j++) {
if(gate_input[j] == '1') {
count++;
}
}
if((count & 0x01) == 0x01) { output[0] = '1'; } else { output[0] = '0'; }
/* Gate 2 */
for(j = 0; j < 8; j++) {
gate_input[j] = '0';
}
gate_input[0] = top_reg[1];
gate_input[1] = top_reg[2];
gate_input[2] = u2;
gate_input[3] = mid_reg[0];
gate_input[4] = mid_reg[2];
count = 0;
for(j = 0; j < 5; j++) {
if(gate_input[j] == '1') {
count++;
}
}
if((count & 0x01) == 0x01) { output[1] = '1'; } else { output[1] = '0'; }
/* Gate 3 */
for(j = 0; j < 8; j++) {
gate_input[j] = '0';
}
gate_input[0] = top_reg[0];
gate_input[1] = top_reg[1];
gate_input[2] = top_reg[2];
gate_input[3] = mid_reg[0];
gate_input[4] = u3;
gate_input[5] = low_reg[0];
count = 0;
for(j = 0; j < 6; j++) {
if(gate_input[j] == '1') {
count++;
}
}
if((count & 0x01) == 0x01) { output[2] = '1'; } else { output[2] = '0'; }
/* Gate 4 */
for(j = 0; j < 8; j++) {
gate_input[j] = '0';
}
gate_input[0] = u1;
gate_input[1] = top_reg[0];
gate_input[2] = u2;
gate_input[3] = mid_reg[0];
gate_input[4] = mid_reg[1];
gate_input[5] = u3;
gate_input[6] = low_reg[0];
gate_input[7] = low_reg[2];
count = 0;
for(j = 0; j < 8; j++) {
if(gate_input[j] == '1') {
count++;
}
}
if((count & 0x01) == 0x01) { output[3] = '1'; } else { output[3] = '0'; }
output[4] = '\0';
concat(protected_stream, output);
/* Shift registers right */
top_reg[2] = top_reg[1];
top_reg[1] = top_reg[0];
top_reg[0] = u1;
mid_reg[2] = mid_reg[1];
mid_reg[1] = mid_reg[0];
mid_reg[0] = u2;
low_reg[2] = low_reg[1];
low_reg[1] = low_reg[0];
low_reg[0] = u3;
}
}
void protect_ecc080(char protected_stream[], char unprotected_stream[])
{
/* ECC 080 - 3-2-11 convolutional code */
/* State machine illustrated in figure K2 */
/* NOTE: Figure K.2 of ISO/IEC 16022:2006 has an error in that input 2 of gate 1 and input 1 of gate 2 are
both connected to module 2 _and_ module 3 of the top register. This is obviously not correct so I have
made a guess at the correct interpretation and made a comment where a correction may be needed if this
guess is not correct */
char top_reg[12];
char low_reg[12];
char u1, u2;
char output[4];
char gate_input[12];
int i, j, count, blocks;
strcpy(protected_stream, "");
for(i = 0; i < 12; i++) {
top_reg[i] = '0';
low_reg[i] = '0';
}
for(i = 0; i < (strlen(unprotected_stream) % 2); i++){
concat(unprotected_stream, "0");
}
blocks = strlen(unprotected_stream) / 2;
blocks += 11;
for(i = 0; i < blocks; i++) {
if(i < (blocks - 11)) {
u1 = unprotected_stream[2 * i];
u2 = unprotected_stream[(2 * i) + 1];
} else {
u1 = '0';
u2 = '0';
}
/* Gate 1 */
for(j = 0; j < 12; j++) {
gate_input[j] = '0';
}
gate_input[0] = u1;
gate_input[1] = top_reg[0];
gate_input[2] = top_reg[3]; /* ? top_reg[2] ? */
gate_input[3] = top_reg[4];
gate_input[4] = top_reg[5];
gate_input[5] = top_reg[6];
gate_input[6] = top_reg[9];
gate_input[7] = low_reg[2];
gate_input[8] = low_reg[6];
gate_input[9] = low_reg[7];
gate_input[10] = low_reg[10];
count = 0;
for(j = 0; j < 11; j++) {
if(gate_input[j] == '1') {
count++;
}
}
if((count & 0x01) == 0x01) { output[0] = '1'; } else { output[0] = '0'; }
/* Gate 2 */
for(j = 0; j < 12; j++) {
gate_input[j] = '0';
}
gate_input[0] = top_reg[0];
gate_input[1] = top_reg[2]; /* ? top_reg[3] ? */
gate_input[2] = top_reg[4];
gate_input[3] = top_reg[7];
gate_input[4] = top_reg[8];
gate_input[5] = top_reg[9];
gate_input[6] = u2;
gate_input[7] = low_reg[2];
gate_input[8] = low_reg[5];
gate_input[9] = low_reg[7];
gate_input[10] = low_reg[8];
count = 0;
for(j = 0; j < 11; j++) {
if(gate_input[j] == '1') {
count++;
}
}
if((count & 0x01) == 0x01) { output[1] = '1'; } else { output[1] = '0'; }
/* Gate 3 */
for(j = 0; j < 12; j++) {
gate_input[j] = '0';
}
gate_input[0] = u1;
gate_input[1] = top_reg[4];
gate_input[2] = top_reg[5];
gate_input[3] = top_reg[6];
gate_input[4] = u2;
gate_input[5] = low_reg[0];
gate_input[6] = low_reg[1];
gate_input[7] = low_reg[3];
gate_input[8] = low_reg[6];
gate_input[9] = low_reg[8];
gate_input[10] = low_reg[10];
count = 0;
for(j = 0; j < 11; j++) {
if(gate_input[j] == '1') {
count++;
}
}
if((count & 0x01) == 0x01) { output[2] = '1'; } else { output[2] = '0'; }
output[3] = '\0';
concat(protected_stream, output);
/* Shift registers right */
top_reg[9] = top_reg[8];
top_reg[8] = top_reg[7];
top_reg[7] = top_reg[6];
top_reg[6] = top_reg[5];
top_reg[5] = top_reg[4];
top_reg[4] = top_reg[3];
top_reg[3] = top_reg[2];
top_reg[2] = top_reg[1];
top_reg[1] = top_reg[0];
top_reg[0] = u1;
low_reg[10] = low_reg[9];
low_reg[9] = low_reg[8];
low_reg[8] = low_reg[7];
low_reg[7] = low_reg[6];
low_reg[6] = low_reg[5];
low_reg[5] = low_reg[4];
low_reg[4] = low_reg[3];
low_reg[3] = low_reg[2];
low_reg[2] = low_reg[1];
low_reg[1] = low_reg[0];
low_reg[0] = u2;
}
}
void protect_ecc100(char protected_stream[], char unprotected_stream[])
{
/* ECC 100 - 2-1-15 convolutional code */
/* State machine illustrated in figure k3 */
char reg[16];
char u;
char output[3];
char gate_input[10];
int i, j, count, blocks;
strcpy(protected_stream, "");
for(i = 0; i < 16; i++) {
reg[i] = '0';
}
blocks = strlen(unprotected_stream);
blocks += 15;
for(i = 0; i < blocks; i++) {
if(i < (blocks - 15)) {
u = unprotected_stream[i];
} else {
u = '0';
}
/* Gate 1 */
for(j = 0; j < 10; j++) {
gate_input[j] = '0';
}
gate_input[0] = u;
gate_input[1] = reg[1];
gate_input[2] = reg[4];
gate_input[3] = reg[5];
gate_input[4] = reg[6];
gate_input[5] = reg[7];
gate_input[6] = reg[8];
gate_input[7] = reg[9];
gate_input[8] = reg[14];
count = 0;
for(j = 0; j < 9; j++) {
if(gate_input[j] == '1') {
count++;
}
}
if((count & 0x01) == 0x01) { output[0] = '1'; } else { output[0] = '0'; }
/* Gate 2 */
for(j = 0; j < 10; j++) {
gate_input[j] = '0';
}
gate_input[0] = u;
gate_input[1] = reg[0];
gate_input[2] = reg[2];
gate_input[3] = reg[3];
gate_input[4] = reg[5];
gate_input[5] = reg[10];
gate_input[6] = reg[12];
gate_input[7] = reg[13];
gate_input[8] = reg[14];
count = 0;
for(j = 0; j < 9; j++) {
if(gate_input[j] == '1') {
count++;
}
}
if((count & 0x01) == 0x01) { output[1] = '1'; } else { output[1] = '0'; }
output[2] = '\0';
concat(protected_stream, output);
/* Shift register right */
reg[14] = reg[13];
reg[13] = reg[12];
reg[12] = reg[11];
reg[11] = reg[10];
reg[10] = reg[9];
reg[9] = reg[8];
reg[8] = reg[7];
reg[7] = reg[6];
reg[6] = reg[5];
reg[5] = reg[4];
reg[4] = reg[3];
reg[3] = reg[2];
reg[2] = reg[1];
reg[1] = reg[0];
reg[0] = u;
}
}
void protect_ecc140(char protected_stream[], char unprotected_stream[])
{
/* ECC 140 - 4-1-13 convolutional coding */
/* State machine illustrated in figure k3 */
char reg[13];
char u;
char output[5];
char gate_input[12];
int i, j, count, blocks;
strcpy(protected_stream, "");
for(i = 0; i < 13; i++) {
reg[i] = '0';
}
blocks = strlen(unprotected_stream);
blocks += 13;
for(i = 0; i < blocks; i++) {
if(i < (blocks - 13)) {
u = unprotected_stream[i];
} else {
u = '0';
}
/* Gate 1 */
for(j = 0; j < 12; j++) {
gate_input[j] = '0';
}
gate_input[0] = u;
gate_input[1] = reg[3];
gate_input[2] = reg[6];
gate_input[3] = reg[9];
gate_input[4] = reg[11];
gate_input[5] = reg[12];
count = 0;
for(j = 0; j < 6; j++) {
if(gate_input[j] == '1') {
count++;
}
}
if((count & 0x01) == 0x01) { output[0] = '1'; } else { output[0] = '0'; }
/* Gate 2 */
for(j = 0; j < 12; j++) {
gate_input[j] = '0';
}
gate_input[0] = u;
gate_input[1] = reg[2];
gate_input[2] = reg[3];
gate_input[3] = reg[6];
gate_input[4] = reg[7];
gate_input[5] = reg[8];
gate_input[6] = reg[9];
gate_input[7] = reg[10];
gate_input[8] = reg[12];
count = 0;
for(j = 0; j < 9; j++) {
if(gate_input[j] == '1') {
count++;
}
}
if((count & 0x01) == 0x01) { output[1] = '1'; } else { output[1] = '0'; }
/* Gate 3 */
for(j = 0; j < 12; j++) {
gate_input[j] = '0';
}
gate_input[0] = u;
gate_input[1] = reg[0];
gate_input[2] = reg[1];
gate_input[3] = reg[3];
gate_input[4] = reg[4];
gate_input[5] = reg[6];
gate_input[6] = reg[8];
gate_input[7] = reg[10];
gate_input[8] = reg[11];
gate_input[9] = reg[12];
count = 0;
for(j = 0; j < 10; j++) {
if(gate_input[j] == '1') {
count++;
}
}
if((count & 0x01) == 0x01) { output[2] = '1'; } else { output[2] = '0'; }
/* Gate 4 */
for(j = 0; j < 12; j++) {
gate_input[j] = '0';
}
gate_input[0] = u;
gate_input[1] = reg[0];
gate_input[2] = reg[1];
gate_input[3] = reg[3];
gate_input[4] = reg[4];
gate_input[5] = reg[6];
gate_input[6] = reg[8];
gate_input[7] = reg[9];
gate_input[8] = reg[10];
gate_input[9] = reg[11];
gate_input[10] = reg[12];
count = 0;
for(j = 0; j < 11; j++) {
if(gate_input[j] == '1') {
count++;
}
}
if((count & 0x01) == 0x01) { output[3] = '1'; } else { output[3] = '0'; }
output[4] = '\0';
concat(protected_stream, output);
/* Shift register right */
reg[12] = reg[11];
reg[11] = reg[10];
reg[10] = reg[9];
reg[9] = reg[8];
reg[8] = reg[7];
reg[7] = reg[6];
reg[6] = reg[5];
reg[5] = reg[4];
reg[4] = reg[3];
reg[3] = reg[2];
reg[2] = reg[1];
reg[1] = reg[0];
reg[0] = u;
}
}
int matrix89(struct zint_symbol *symbol, unsigned char source[])
{
int i, j, input_length, scheme;
input_length = ustrlen(source);
char unprotected_stream[2210];
char data_prefix_bitstream[31];
char protected_stream[6630];
char unrandomized_stream[2210];
char master_random_stream[2214];
char randomized_stream[2210];
char header[20];
int symbol_size, hex_segment, width;
int error_number;
error_number = 0;
symbol_size = 0;
for(i = 0; i < input_length; i++) {
if(source[i] > 127) {
strcpy(symbol->errtxt, "Data Matrix ECC 000 - 140 doesn't support extended ASCII");
return ERROR_INVALID_DATA;
}
}
/* Decide which encoding scheme to use */
scheme = 128;
if(!(is_sane(B41SET, source))) { scheme = 41; }
if(!(is_sane(B37SET, source))) { scheme = 37; }
if(!(is_sane(B27SET, source))) { scheme = 27; }
if(!(is_sane(B11SET, source))) { scheme = 11; }
/* Data Prefix Bit Stream = Format ID + CRC + Data Length */
/* Format ID (5 bits) */
switch(scheme) {
case 11: strcpy(data_prefix_bitstream, "00000"); break;
case 27: strcpy(data_prefix_bitstream, "00001"); break;
case 37: strcpy(data_prefix_bitstream, "00011"); break;
case 41: strcpy(data_prefix_bitstream, "00010"); break;
default: strcpy(data_prefix_bitstream, "00100"); break;
}
/* CRC Value (16 bit) */
crc_machine(data_prefix_bitstream, scheme, source);
/* Data length (9 bit) */
if(input_length & 0x01) { concat(data_prefix_bitstream, "1"); } else { concat(data_prefix_bitstream, "0"); }
if(input_length & 0x02) { concat(data_prefix_bitstream, "1"); } else { concat(data_prefix_bitstream, "0"); }
if(input_length & 0x04) { concat(data_prefix_bitstream, "1"); } else { concat(data_prefix_bitstream, "0"); }
if(input_length & 0x08) { concat(data_prefix_bitstream, "1"); } else { concat(data_prefix_bitstream, "0"); }
if(input_length & 0x10) { concat(data_prefix_bitstream, "1"); } else { concat(data_prefix_bitstream, "0"); }
if(input_length & 0x20) { concat(data_prefix_bitstream, "1"); } else { concat(data_prefix_bitstream, "0"); }
if(input_length & 0x40) { concat(data_prefix_bitstream, "1"); } else { concat(data_prefix_bitstream, "0"); }
if(input_length & 0x80) { concat(data_prefix_bitstream, "1"); } else { concat(data_prefix_bitstream, "0"); }
if(input_length & 0x100) { concat(data_prefix_bitstream, "1"); } else { concat(data_prefix_bitstream, "0"); }
/* Unprotected Bit Stream = Data Prefix Bitstream + Encoded Data */
strcpy(unprotected_stream, data_prefix_bitstream);
switch(scheme) {
case 11:
if(input_length >= 618) {
strcpy(symbol->errtxt, "Input data too long"); return ERROR_TOO_LONG;
}
break;
case 27:
if(input_length >= 450) {
strcpy(symbol->errtxt, "Input data too long"); return ERROR_TOO_LONG;
}
break;
case 37:
if(input_length >= 412) {
strcpy(symbol->errtxt, "Input data too long"); return ERROR_TOO_LONG;
}
break;
case 41:
if(input_length >= 396) {
strcpy(symbol->errtxt, "Input data too long"); return ERROR_TOO_LONG;
}
break;
case 128:
if(input_length >= 311) {
strcpy(symbol->errtxt, "Input data too long"); return ERROR_TOO_LONG;
}
break;
}
switch(scheme) {
case 11: i1_base11(unprotected_stream, source); break;
case 27: i2_base27(unprotected_stream, source); break;
case 37: i3_base37(unprotected_stream, source); break;
case 41: i4_base41(unprotected_stream, source); break;
default: base128(unprotected_stream, source); break;
}
/* Header (ECC Bit field) LSB first */
switch(symbol->option_1) {
case 2: strcpy(header, "0111111"); break; /* ECC 000 */
case 3: strcpy(header, "0111000000000111000"); break; /* ECC 050 */
case 4: strcpy(header, "0111000000111000111"); break; /* ECC 080 */
case 5: strcpy(header, "0111000000111111111"); break; /* ECC 100 */
case 6: strcpy(header, "0111000111000111111"); break; /* ECC 140 */
}
/* Generate Protected Bit Stream */
switch(symbol->option_1) {
case 2: protect_ecc000(protected_stream, unprotected_stream); break;
case 3: protect_ecc050(protected_stream, unprotected_stream); break;
case 4: protect_ecc080(protected_stream, unprotected_stream); break;
case 5: protect_ecc100(protected_stream, unprotected_stream); break;
case 6: protect_ecc140(protected_stream, unprotected_stream); break;
}
if((strlen(protected_stream) + strlen(header)) > 2209) {
strcpy(symbol->errtxt, "Input data too long");
return ERROR_TOO_LONG;
}
/* Construct Unrandomized Bit Stream */
strcpy(unrandomized_stream, header);
concat(unrandomized_stream, protected_stream);
/* Determine Symbol Size */
for(i = 20; i >= 0; i--) {
if(MatrixMaxCapacities[i] > strlen(unrandomized_stream)) {
symbol_size = i;
}
}
if((symbol->option_2 < 0) || (symbol->option_2 > 21)) {
strcpy(symbol->errtxt, "Invalid symbol size");
error_number = WARN_INVALID_OPTION;
symbol->option_2 = 0;
}
if((symbol->option_2 - 1) > symbol_size) {
symbol_size = (symbol->option_2 - 1);
}
if(((symbol->option_2 - 1) < symbol_size) && (symbol->option_2 != 0)) {
strcpy(symbol->errtxt, "Unable to fit data in specified symbol size");
error_number = WARN_INVALID_OPTION;
}
/* Add trailer (pad bits) */
input_length = strlen(unrandomized_stream);
for(i = input_length; i < MatrixMaxCapacities[symbol_size]; i++) {
concat(unrandomized_stream, "0");
}
/* Load master random stream */
strcpy(master_random_stream, "");
for(i = 0; i < 276; i++) {
hex_segment = MasterRandomStream[i];
if(hex_segment & 0x80) { concat(master_random_stream, "1"); } else { concat(master_random_stream, "0"); }
if(hex_segment & 0x40) { concat(master_random_stream, "1"); } else { concat(master_random_stream, "0"); }
if(hex_segment & 0x20) { concat(master_random_stream, "1"); } else { concat(master_random_stream, "0"); }
if(hex_segment & 0x10) { concat(master_random_stream, "1"); } else { concat(master_random_stream, "0"); }
if(hex_segment & 0x08) { concat(master_random_stream, "1"); } else { concat(master_random_stream, "0"); }
if(hex_segment & 0x04) { concat(master_random_stream, "1"); } else { concat(master_random_stream, "0"); }
if(hex_segment & 0x02) { concat(master_random_stream, "1"); } else { concat(master_random_stream, "0"); }
if(hex_segment & 0x01) { concat(master_random_stream, "1"); } else { concat(master_random_stream, "0"); }
}
/* Randomizing Algorithm */
strcpy(randomized_stream, "");
for(i = 0; i < strlen(unrandomized_stream); i++) {
if(unrandomized_stream[i] != master_random_stream[i]) {
concat(randomized_stream, "1");
} else {
concat(randomized_stream, "0");
}
}
/* Placement Algorithm */
width = (symbol_size * 2) + 7;
symbol->row_height[0] = 1;
/* Fill corners */
set_module(symbol, 0, 0);
set_module(symbol, 0, width + 1);
set_module(symbol, width + 1, 0);
set_module(symbol, width + 1, width + 1);
for(i = 0; i < width; i++) {
/* Fill sides */
set_module(symbol, i + 1, 0);
set_module(symbol, width + 1, i + 1);
if((i % 2) == 0) {
set_module(symbol, i, width + 1);
set_module(symbol, 0, i);
}
for(j = 0; j < width; j++) {
switch(symbol_size) {
case 0: if(randomized_stream[tableh1[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 1: if(randomized_stream[tableh2[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 2: if(randomized_stream[tableh3[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 3: if(randomized_stream[tableh4[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 4: if(randomized_stream[tableh5[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 5: if(randomized_stream[tableh6[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 6: if(randomized_stream[tableh7[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 7: if(randomized_stream[tableh8[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 8: if(randomized_stream[tableh9[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 9: if(randomized_stream[tableh10[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 10: if(randomized_stream[tableh11[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 11: if(randomized_stream[tableh12[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 12: if(randomized_stream[tableh13[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 13: if(randomized_stream[tableh14[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 14: if(randomized_stream[tableh15[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 15: if(randomized_stream[tableh16[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 16: if(randomized_stream[tableh17[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 17: if(randomized_stream[tableh18[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 18: if(randomized_stream[tableh19[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 19: if(randomized_stream[tableh20[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
case 20: if(randomized_stream[tableh21[(i * width) + j]] == '1') { set_module(symbol, i + 1, j + 1); } break;
}
}
symbol->row_height[i + 1] = 1;
}
symbol->row_height[width + 1] = 1;
symbol->rows = width + 2;
symbol->width = width + 2;
return error_number;
}
int dmatrix(struct zint_symbol *symbol, unsigned char source[])
{
int error_number;
if(symbol->option_1 <= 1) {
/* ECC 200 */
error_number = data_matrix_200(symbol, source);
} else {
/* ECC 000 - 140 */
error_number = matrix89(symbol, source);
}
return error_number;
}