2008-07-13 21:15:55 +00:00
/* 2of5.c - Handles Code 2 of 5 barcodes */
/*
libzint - the open source barcode library
2008-11-17 08:47:42 +00:00
Copyright ( C ) 2008 Robin Stuart < robin @ zint . org . uk >
2008-07-13 21:15:55 +00:00
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>
# include <stdlib.h>
# include "common.h"
static char * C25MatrixTable [ 10 ] = { " 113311 " , " 311131 " , " 131131 " , " 331111 " , " 113131 " , " 313111 " ,
" 133111 " , " 111331 " , " 311311 " , " 131311 " } ;
static char * C25IndustTable [ 10 ] = { " 1111313111 " , " 3111111131 " , " 1131111131 " , " 3131111111 " , " 1111311131 " ,
" 3111311111 " , " 1131311111 " , " 1111113131 " , " 3111113111 " , " 1131113111 " } ;
static char * C25InterTable [ 10 ] = { " 11331 " , " 31113 " , " 13113 " , " 33111 " , " 11313 " , " 31311 " , " 13311 " , " 11133 " ,
" 31131 " , " 13131 " } ;
int matrix_two_of_five ( struct zint_symbol * symbol , unsigned char source [ ] )
{ /* Code 2 of 5 Standard (Code 2 of 5 Matrix) */
2008-09-19 08:47:28 +00:00
int i , error_number ;
2008-07-13 21:15:55 +00:00
char dest [ 1000 ] ;
2008-09-19 08:47:28 +00:00
error_number = 0 ;
2008-07-13 21:15:55 +00:00
strcpy ( dest , " " ) ;
2008-09-30 15:05:53 +00:00
if ( ustrlen ( source ) > 80 ) {
2009-05-31 20:33:54 +00:00
strcpy ( symbol - > errtxt , " Input too long " ) ;
2008-07-13 21:15:55 +00:00
return ERROR_TOO_LONG ;
}
2008-09-19 08:47:28 +00:00
error_number = is_sane ( NESET , source ) ;
if ( error_number = = ERROR_INVALID_DATA ) {
2009-05-31 20:33:54 +00:00
strcpy ( symbol - > errtxt , " Invalid characters in data " ) ;
2008-09-19 08:47:28 +00:00
return error_number ;
2008-07-13 21:15:55 +00:00
}
/* start character */
concat ( dest , " 411111 " ) ;
2008-09-30 15:05:53 +00:00
for ( i = 0 ; i < = ustrlen ( source ) ; i + + ) {
2008-07-13 21:15:55 +00:00
lookup ( NESET , C25MatrixTable , source [ i ] , dest ) ;
}
/* Stop character */
concat ( dest , " 41111 " ) ;
expand ( symbol , dest ) ;
2009-02-19 19:09:57 +00:00
ustrcpy ( symbol - > text , source ) ;
2008-09-19 08:47:28 +00:00
return error_number ;
2008-07-13 21:15:55 +00:00
}
int industrial_two_of_five ( struct zint_symbol * symbol , unsigned char source [ ] )
{ /* Code 2 of 5 Industrial */
2008-09-19 08:47:28 +00:00
int i , error_number ;
2008-07-13 21:15:55 +00:00
char dest [ 1000 ] ;
2008-09-19 08:47:28 +00:00
error_number = 0 ;
2008-07-13 21:15:55 +00:00
strcpy ( dest , " " ) ;
2008-09-30 15:05:53 +00:00
if ( ustrlen ( source ) > 45 ) {
2009-05-31 20:33:54 +00:00
strcpy ( symbol - > errtxt , " Input too long " ) ;
2008-07-13 21:15:55 +00:00
return ERROR_TOO_LONG ;
}
2008-09-19 08:47:28 +00:00
error_number = is_sane ( NESET , source ) ;
if ( error_number = = ERROR_INVALID_DATA ) {
2009-05-31 20:33:54 +00:00
strcpy ( symbol - > errtxt , " Invalid character in data " ) ;
2008-09-19 08:47:28 +00:00
return error_number ;
2008-07-13 21:15:55 +00:00
}
/* start character */
concat ( dest , " 313111 " ) ;
2008-09-30 15:05:53 +00:00
for ( i = 0 ; i < = ustrlen ( source ) ; i + + ) {
2008-07-13 21:15:55 +00:00
lookup ( NESET , C25IndustTable , source [ i ] , dest ) ;
}
/* Stop character */
concat ( dest , " 31113 " ) ;
expand ( symbol , dest ) ;
2009-02-19 19:09:57 +00:00
ustrcpy ( symbol - > text , source ) ;
2008-09-19 08:47:28 +00:00
return error_number ;
2008-07-13 21:15:55 +00:00
}
int iata_two_of_five ( struct zint_symbol * symbol , unsigned char source [ ] )
{ /* Code 2 of 5 IATA */
2008-09-19 08:47:28 +00:00
int i , error_number ;
2008-07-13 21:15:55 +00:00
char dest [ 1000 ] ;
2008-09-19 08:47:28 +00:00
error_number = 0 ;
2008-07-13 21:15:55 +00:00
strcpy ( dest , " " ) ;
2008-09-30 15:05:53 +00:00
if ( ustrlen ( source ) > 45 ) {
2009-05-31 20:33:54 +00:00
strcpy ( symbol - > errtxt , " Input too long " ) ;
2008-07-13 21:15:55 +00:00
return ERROR_TOO_LONG ;
}
2008-09-19 08:47:28 +00:00
error_number = is_sane ( NESET , source ) ;
if ( error_number = = ERROR_INVALID_DATA ) {
2009-05-31 20:33:54 +00:00
strcpy ( symbol - > errtxt , " Invalid characters in data " ) ;
2008-09-19 08:47:28 +00:00
return error_number ;
2008-07-13 21:15:55 +00:00
}
/* start */
concat ( dest , " 1111 " ) ;
2008-09-30 15:05:53 +00:00
for ( i = 0 ; i < ustrlen ( source ) ; i + + ) {
2008-07-13 21:15:55 +00:00
lookup ( NESET , C25IndustTable , source [ i ] , dest ) ;
}
/* stop */
concat ( dest , " 311 " ) ;
expand ( symbol , dest ) ;
2009-02-19 19:09:57 +00:00
ustrcpy ( symbol - > text , source ) ;
2008-09-19 08:47:28 +00:00
return error_number ;
2008-07-13 21:15:55 +00:00
}
int logic_two_of_five ( struct zint_symbol * symbol , unsigned char source [ ] )
{ /* Code 2 of 5 Data Logic */
2008-09-19 08:47:28 +00:00
int i , error_number ;
2008-07-13 21:15:55 +00:00
char dest [ 1000 ] ;
2008-09-19 08:47:28 +00:00
error_number = 0 ;
2008-07-13 21:15:55 +00:00
strcpy ( dest , " " ) ;
2008-09-30 15:05:53 +00:00
if ( ustrlen ( source ) > 80 ) {
2009-05-31 20:33:54 +00:00
strcpy ( symbol - > errtxt , " Input too long " ) ;
2008-07-13 21:15:55 +00:00
return ERROR_TOO_LONG ;
}
2008-09-19 08:47:28 +00:00
error_number = is_sane ( NESET , source ) ;
if ( error_number = = ERROR_INVALID_DATA ) {
2009-05-31 20:33:54 +00:00
strcpy ( symbol - > errtxt , " Invalid characters in data " ) ;
2008-09-19 08:47:28 +00:00
return error_number ;
2008-07-13 21:15:55 +00:00
}
/* start character */
concat ( dest , " 1111 " ) ;
2008-09-30 15:05:53 +00:00
for ( i = 0 ; i < = ustrlen ( source ) ; i + + ) {
2008-07-13 21:15:55 +00:00
lookup ( NESET , C25MatrixTable , source [ i ] , dest ) ;
}
/* Stop character */
concat ( dest , " 311 " ) ;
expand ( symbol , dest ) ;
2009-02-19 19:09:57 +00:00
ustrcpy ( symbol - > text , source ) ;
2008-09-19 08:47:28 +00:00
return error_number ;
2008-07-13 21:15:55 +00:00
}
int interleaved_two_of_five ( struct zint_symbol * symbol , unsigned char source [ ] )
{ /* Code 2 of 5 Interleaved */
2008-09-19 08:47:28 +00:00
int i , j , k , error_number ;
2008-07-13 21:15:55 +00:00
char bars [ 7 ] , spaces [ 7 ] , mixed [ 14 ] , dest [ 1000 ] ;
2008-09-19 08:47:28 +00:00
error_number = 0 ;
2008-07-13 21:15:55 +00:00
strcpy ( dest , " " ) ;
2008-09-30 15:05:53 +00:00
if ( ustrlen ( source ) > 90 ) {
2009-05-31 20:33:54 +00:00
strcpy ( symbol - > errtxt , " Input too long " ) ;
2008-07-13 21:15:55 +00:00
return ERROR_TOO_LONG ;
}
2008-09-19 08:47:28 +00:00
error_number = is_sane ( NESET , source ) ;
if ( error_number = = ERROR_INVALID_DATA ) {
2009-05-31 20:33:54 +00:00
strcpy ( symbol - > errtxt , " Invalid characters in data " ) ;
2008-09-19 08:47:28 +00:00
return error_number ;
2008-07-13 21:15:55 +00:00
}
/* Input must be an even number of characters for Interlaced 2 of 5 to work:
if an odd number of characters has been entered then add a leading zero */
2008-09-30 15:05:53 +00:00
if ( ( ustrlen ( source ) % 2 ) ! = 0 )
2008-07-13 21:15:55 +00:00
{
/* there are an odd number of input characters */
unsigned int length ;
char temp [ 100 ] ;
2008-09-30 15:05:53 +00:00
length = ustrlen ( source ) ;
2008-07-13 21:15:55 +00:00
2008-10-03 08:07:05 +00:00
strcpy ( temp , ( char * ) source ) ;
2008-07-13 21:15:55 +00:00
source [ 0 ] = ' 0 ' ;
for ( i = 0 ; i < = length ; i + + )
{
source [ i + 1 ] = temp [ i ] ;
}
}
/* start character */
concat ( dest , " 1111 " ) ;
2008-09-30 15:05:53 +00:00
for ( i = 0 ; i < ustrlen ( source ) ; i + = 2 )
2008-07-13 21:15:55 +00:00
{
/* look up the bars and the spaces and put them in two strings */
strcpy ( bars , " " ) ;
lookup ( NESET , C25InterTable , source [ i ] , bars ) ;
strcpy ( spaces , " " ) ;
lookup ( NESET , C25InterTable , source [ i + 1 ] , spaces ) ;
/* then merge (interlace) the strings together */
k = 0 ;
for ( j = 0 ; j < = 4 ; j + + )
{
mixed [ k ] = bars [ j ] ; k + + ;
mixed [ k ] = spaces [ j ] ; k + + ;
}
mixed [ k ] = ' \0 ' ;
concat ( dest , mixed ) ;
}
/* Stop character */
concat ( dest , " 311 " ) ;
expand ( symbol , dest ) ;
2009-02-19 19:09:57 +00:00
ustrcpy ( symbol - > text , source ) ;
2008-09-19 08:47:28 +00:00
return error_number ;
2008-07-13 21:15:55 +00:00
}
int itf14 ( struct zint_symbol * symbol , unsigned char source [ ] )
{
2008-10-12 21:05:53 +00:00
int i , error_number , h , zeroes ;
2008-07-13 21:15:55 +00:00
unsigned int count , check_digit ;
2008-10-12 21:05:53 +00:00
char localstr [ 15 ] ;
2008-10-13 20:29:04 +00:00
char checkstr [ 3 ] ;
2008-07-13 21:15:55 +00:00
2008-09-19 08:47:28 +00:00
error_number = 0 ;
2008-07-13 21:15:55 +00:00
count = 0 ;
2008-09-30 15:05:53 +00:00
h = ustrlen ( source ) ;
2008-07-13 21:15:55 +00:00
2008-10-12 21:05:53 +00:00
if ( h > 13 ) {
2009-05-31 20:33:54 +00:00
strcpy ( symbol - > errtxt , " Input too long " ) ;
2008-07-13 21:15:55 +00:00
return ERROR_TOO_LONG ;
}
2008-09-19 08:47:28 +00:00
error_number = is_sane ( NESET , source ) ;
if ( error_number = = ERROR_INVALID_DATA ) {
2009-05-31 20:33:54 +00:00
strcpy ( symbol - > errtxt , " Invalid character in data " ) ;
2008-09-19 08:47:28 +00:00
return error_number ;
2008-07-13 21:15:55 +00:00
}
2008-10-12 21:05:53 +00:00
/* Add leading zeros as required */
strcpy ( localstr , " " ) ;
zeroes = 13 - ustrlen ( source ) ;
for ( i = 0 ; i < zeroes ; i + + ) {
concat ( localstr , " 0 " ) ;
}
concat ( localstr , ( char * ) source ) ;
2008-07-13 21:15:55 +00:00
/* Calculate the check digit - the same method used for EAN-13 */
2009-07-04 20:49:17 +00:00
for ( i = 12 ; i > = 0 ; i - - )
2008-07-13 21:15:55 +00:00
{
2008-10-12 21:05:53 +00:00
count + = ctoi ( localstr [ i ] ) ;
2008-07-13 21:15:55 +00:00
2009-07-04 20:49:17 +00:00
if ( ( i % 2 ) = = 0 )
2008-07-13 21:15:55 +00:00
{
2008-10-12 21:05:53 +00:00
count + = 2 * ctoi ( localstr [ i ] ) ;
2008-07-13 21:15:55 +00:00
}
}
check_digit = 10 - ( count % 10 ) ;
if ( check_digit = = 10 ) { check_digit = 0 ; }
2008-10-13 20:29:04 +00:00
checkstr [ 0 ] = itoc ( check_digit ) ;
checkstr [ 1 ] = ' \0 ' ;
concat ( localstr , checkstr ) ;
2008-10-12 21:05:53 +00:00
error_number = interleaved_two_of_five ( symbol , ( unsigned char * ) localstr ) ;
2009-02-19 19:09:57 +00:00
ustrcpy ( symbol - > text , ( unsigned char * ) localstr ) ;
2008-09-19 08:47:28 +00:00
return error_number ;
2008-07-13 21:15:55 +00:00
}
int dpleit ( struct zint_symbol * symbol , unsigned char source [ ] )
{ /* Deutshe Post Leitcode */
2008-09-19 08:47:28 +00:00
int i , error_number ;
2008-07-13 21:15:55 +00:00
unsigned int h , count , check_digit ;
2008-10-12 21:05:53 +00:00
char localstr [ 15 ] , checkstr [ 3 ] ;
int zeroes ;
2008-07-13 21:15:55 +00:00
2008-09-19 08:47:28 +00:00
error_number = 0 ;
2008-07-13 21:15:55 +00:00
count = 0 ;
2008-09-30 15:05:53 +00:00
h = ustrlen ( source ) ;
2008-10-12 21:05:53 +00:00
if ( h > 13 ) {
2009-05-31 20:33:54 +00:00
strcpy ( symbol - > errtxt , " Input wrong length " ) ;
2008-07-13 21:15:55 +00:00
return ERROR_TOO_LONG ;
}
2008-09-19 08:47:28 +00:00
error_number = is_sane ( NESET , source ) ;
if ( error_number = = ERROR_INVALID_DATA ) {
2009-05-31 20:33:54 +00:00
strcpy ( symbol - > errtxt , " Invalid characters in data " ) ;
2008-09-19 08:47:28 +00:00
return error_number ;
2008-07-13 21:15:55 +00:00
}
2008-10-12 21:05:53 +00:00
strcpy ( localstr , " " ) ;
zeroes = 13 - h ;
for ( i = 0 ; i < zeroes ; i + + )
concat ( localstr , " 0 " ) ;
concat ( localstr , ( char * ) source ) ;
for ( i = 12 ; i > = 0 ; i - - )
2008-07-13 21:15:55 +00:00
{
2008-10-12 21:05:53 +00:00
count + = 4 * ctoi ( localstr [ i ] ) ;
2008-07-13 21:15:55 +00:00
if ( ! ( ( i % 2 ) = = 0 ) )
{
2008-10-12 21:05:53 +00:00
count + = 5 * ctoi ( localstr [ i ] ) ;
2008-07-13 21:15:55 +00:00
}
}
check_digit = 10 - ( count % 10 ) ;
if ( check_digit = = 10 ) { check_digit = 0 ; }
2008-10-12 21:05:53 +00:00
checkstr [ 0 ] = itoc ( check_digit ) ;
checkstr [ 1 ] = ' \0 ' ;
2008-10-13 20:29:04 +00:00
concat ( localstr , checkstr ) ;
2008-10-12 21:05:53 +00:00
error_number = interleaved_two_of_five ( symbol , ( unsigned char * ) localstr ) ;
2009-02-19 19:09:57 +00:00
ustrcpy ( symbol - > text , ( unsigned char * ) localstr ) ;
2008-09-19 08:47:28 +00:00
return error_number ;
2008-07-13 21:15:55 +00:00
}
int dpident ( struct zint_symbol * symbol , unsigned char source [ ] )
{ /* Deutsche Post Identcode */
2008-10-12 21:05:53 +00:00
int i , error_number , zeroes ;
2008-07-13 21:15:55 +00:00
unsigned int h , count , check_digit ;
2008-10-12 21:05:53 +00:00
char localstr [ 13 ] , checkstr [ 3 ] ;
2008-07-13 21:15:55 +00:00
count = 0 ;
2008-09-30 15:05:53 +00:00
h = ustrlen ( source ) ;
2008-10-12 21:05:53 +00:00
if ( h > 11 ) {
2009-05-31 20:33:54 +00:00
strcpy ( symbol - > errtxt , " Input wrong length " ) ;
2008-07-13 21:15:55 +00:00
return ERROR_TOO_LONG ;
}
2008-09-19 08:47:28 +00:00
error_number = is_sane ( NESET , source ) ;
if ( error_number = = ERROR_INVALID_DATA ) {
2009-05-31 20:33:54 +00:00
strcpy ( symbol - > errtxt , " Invalid characters in data " ) ;
2008-09-19 08:47:28 +00:00
return error_number ;
2008-07-13 21:15:55 +00:00
}
2008-10-12 21:05:53 +00:00
strcpy ( localstr , " " ) ;
zeroes = 11 - h ;
for ( i = 0 ; i < zeroes ; i + + )
2008-10-13 20:29:04 +00:00
concat ( localstr , " 0 " ) ;
concat ( localstr , ( char * ) source ) ;
2008-10-12 21:05:53 +00:00
for ( i = 10 ; i > = 0 ; i - - )
2008-07-13 21:15:55 +00:00
{
2008-10-12 21:05:53 +00:00
count + = 4 * ctoi ( localstr [ i ] ) ;
2008-07-13 21:15:55 +00:00
if ( ! ( ( i % 2 ) = = 0 ) )
{
2008-10-12 21:05:53 +00:00
count + = 5 * ctoi ( localstr [ i ] ) ;
2008-07-13 21:15:55 +00:00
}
}
check_digit = 10 - ( count % 10 ) ;
if ( check_digit = = 10 ) { check_digit = 0 ; }
2008-10-12 21:05:53 +00:00
checkstr [ 0 ] = itoc ( check_digit ) ;
checkstr [ 1 ] = ' \0 ' ;
2008-10-13 20:29:04 +00:00
concat ( localstr , checkstr ) ;
2008-10-12 21:05:53 +00:00
error_number = interleaved_two_of_five ( symbol , ( unsigned char * ) localstr ) ;
2009-02-19 19:09:57 +00:00
ustrcpy ( symbol - > text , ( unsigned char * ) localstr ) ;
2008-09-19 08:47:28 +00:00
return error_number ;
2008-07-13 21:15:55 +00:00
}