2008-07-14 01:15:55 +04:00
/* common.c - Contains functions needed for a number of barcodes */
/*
libzint - the open source barcode library
2016-02-20 12:38:03 +03:00
Copyright ( C ) 2008 - 2016 Robin Stuart < rstuart114 @ gmail . com >
2008-07-14 01:15:55 +04:00
2013-05-16 21:26:38 +04:00
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions
are met :
2008-07-14 01:15:55 +04:00
2016-02-20 12:38:03 +03:00
1. Redistributions of source code must retain the above copyright
notice , this list of conditions and the following disclaimer .
2013-05-16 21:26:38 +04:00
2. Redistributions in binary form must reproduce the above copyright
notice , this list of conditions and the following disclaimer in the
2016-02-20 12:38:03 +03:00
documentation and / or other materials provided with the distribution .
2013-05-16 21:26:38 +04:00
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
2016-02-20 12:38:03 +03:00
without specific prior written permission .
2008-07-14 01:15:55 +04:00
2013-05-16 21:26:38 +04:00
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
2016-02-20 12:38:03 +03:00
OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF
2013-05-16 21:26:38 +04:00
SUCH DAMAGE .
2016-02-20 12:38:03 +03:00
*/
2008-07-14 01:15:55 +04:00
# include <string.h>
# include <stdio.h>
# include <stdlib.h>
# include "common.h"
2016-02-20 12:38:03 +03:00
/* Local replacement for strlen() with unsigned char strings */
2012-12-31 17:41:59 +04:00
int ustrlen ( const unsigned char data [ ] ) {
2016-03-03 00:12:38 +03:00
return strlen ( ( const char * ) data ) ;
2008-09-30 19:05:53 +04:00
}
2016-02-20 12:38:03 +03:00
/* Local replacement for strcpy() with unsigned char strings */
2008-07-14 01:15:55 +04:00
2016-03-03 00:12:38 +03:00
void ustrcpy ( unsigned char target [ ] , const unsigned char source [ ] ) {
strcpy ( ( char * ) target , ( const char * ) source ) ;
2009-02-19 22:09:57 +03:00
}
2016-02-20 12:38:03 +03:00
/* Converts a character 0-9 to its equivalent integer value */
2016-02-29 22:42:32 +03:00
int ctoi ( const char source ) {
2016-02-20 12:38:03 +03:00
if ( ( source > = ' 0 ' ) & & ( source < = ' 9 ' ) )
return ( source - ' 0 ' ) ;
return ( source - ' A ' + 10 ) ;
2008-07-14 01:15:55 +04:00
}
2016-02-20 12:38:03 +03:00
/* Converts an integer value to its hexadecimal character */
2016-02-29 22:42:32 +03:00
char itoc ( const int source ) {
2016-02-20 12:38:03 +03:00
if ( ( source > = 0 ) & & ( source < = 9 ) ) {
return ( ' 0 ' + source ) ;
} else {
return ( ' A ' + ( source - 10 ) ) ;
}
2008-07-14 01:15:55 +04:00
}
2016-02-20 12:38:03 +03:00
/* Converts lower case characters to upper case in a string source[] */
2016-02-29 22:42:32 +03:00
void to_upper ( unsigned char source [ ] ) {
2016-02-20 12:38:03 +03:00
unsigned int i , src_len = ustrlen ( source ) ;
2008-07-14 01:15:55 +04:00
2016-02-20 12:38:03 +03:00
for ( i = 0 ; i < src_len ; i + + ) {
if ( ( source [ i ] > = ' a ' ) & & ( source [ i ] < = ' z ' ) ) {
source [ i ] = ( source [ i ] - ' a ' ) + ' A ' ;
}
}
2008-07-14 01:15:55 +04:00
}
2016-02-20 12:38:03 +03:00
/* Verifies that a string only uses valid characters */
2016-04-06 23:55:14 +03:00
int is_sane ( const char test_string [ ] , const unsigned char source [ ] , const int length ) {
2016-02-20 12:38:03 +03:00
unsigned int i , j , latch ;
unsigned int lt = strlen ( test_string ) ;
for ( i = 0 ; i < length ; i + + ) {
latch = FALSE ;
for ( j = 0 ; j < lt ; j + + ) {
if ( source [ i ] = = test_string [ j ] ) {
latch = TRUE ;
break ;
}
}
if ( ! ( latch ) ) {
return ZINT_ERROR_INVALID_DATA ;
}
}
return 0 ;
2008-07-14 01:15:55 +04:00
}
2016-02-20 12:38:03 +03:00
/* Returns the position of data in set_string */
2016-04-06 23:55:14 +03:00
int posn ( const char set_string [ ] , const char data ) {
2016-02-20 12:38:03 +03:00
unsigned int i , n = strlen ( set_string ) ;
2008-07-14 01:15:55 +04:00
2016-02-20 12:38:03 +03:00
for ( i = 0 ; i < n ; i + + ) {
if ( data = = set_string [ i ] ) {
return i ;
}
}
return 0 ;
2008-07-14 01:15:55 +04:00
}
2016-02-20 12:38:03 +03:00
/* Replaces huge switch statements for looking up in tables */
2016-04-06 23:55:14 +03:00
void lookup ( const char set_string [ ] , const char * table [ ] , const char data , char dest [ ] ) {
2016-02-20 12:38:03 +03:00
unsigned int i , n = strlen ( set_string ) ;
2008-07-14 01:15:55 +04:00
2016-02-20 12:38:03 +03:00
for ( i = 0 ; i < n ; i + + ) {
if ( data = = set_string [ i ] ) {
2016-03-03 00:12:38 +03:00
strcat ( dest , table [ i ] ) ;
2016-02-20 12:38:03 +03:00
}
}
2008-07-14 01:15:55 +04:00
}
2016-02-20 12:38:03 +03:00
/* Return true (1) if a module is dark/black, orherwise false (0) */
2016-02-29 22:42:32 +03:00
int module_is_set ( const struct zint_symbol * symbol , const int y_coord , const int x_coord ) {
2016-02-20 12:38:03 +03:00
return ( symbol - > encoded_data [ y_coord ] [ x_coord / 7 ] > > ( x_coord % 7 ) ) & 1 ;
2009-06-01 00:33:54 +04:00
}
2016-02-20 12:38:03 +03:00
/* Set a module to dark/black */
2016-02-29 22:42:32 +03:00
void set_module ( struct zint_symbol * symbol , const int y_coord , const int x_coord ) {
2016-02-20 12:38:03 +03:00
symbol - > encoded_data [ y_coord ] [ x_coord / 7 ] | = 1 < < ( x_coord % 7 ) ;
2009-06-01 00:33:54 +04:00
}
2016-02-20 12:38:03 +03:00
/* Set (or unset) a module to white */
2016-02-29 22:42:32 +03:00
void unset_module ( struct zint_symbol * symbol , const int y_coord , const int x_coord ) {
2016-02-20 12:38:03 +03:00
symbol - > encoded_data [ y_coord ] [ x_coord / 7 ] & = ~ ( 1 < < ( x_coord % 7 ) ) ;
2009-06-01 00:33:54 +04:00
}
2016-02-20 12:38:03 +03:00
/* Expands from a width pattern to a bit pattern */
2016-04-06 23:55:14 +03:00
void expand ( struct zint_symbol * symbol , const char data [ ] ) {
2016-02-20 12:38:03 +03:00
unsigned int reader , n = strlen ( data ) ;
int writer , i ;
char latch ;
writer = 0 ;
latch = ' 1 ' ;
for ( reader = 0 ; reader < n ; reader + + ) {
for ( i = 0 ; i < ctoi ( data [ reader ] ) ; i + + ) {
if ( latch = = ' 1 ' ) {
set_module ( symbol , symbol - > rows , writer ) ;
}
writer + + ;
}
latch = ( latch = = ' 1 ' ? ' 0 ' : ' 1 ' ) ;
}
if ( symbol - > symbology ! = BARCODE_PHARMA ) {
if ( writer > symbol - > width ) {
symbol - > width = writer ;
}
} else {
/* Pharmacode One ends with a space - adjust for this */
if ( writer > symbol - > width + 2 ) {
symbol - > width = writer - 2 ;
}
}
symbol - > rows = symbol - > rows + 1 ;
2008-07-14 01:15:55 +04:00
}
2008-12-25 00:29:31 +03:00
2016-02-20 12:38:03 +03:00
/* Indicates which symbologies can have row binding */
2016-03-03 00:12:38 +03:00
int is_stackable ( const int symbology ) {
2016-02-20 12:38:03 +03:00
if ( symbology < BARCODE_PDF417 ) {
return 1 ;
}
if ( symbology = = BARCODE_CODE128B ) {
return 1 ;
}
if ( symbology = = BARCODE_ISBNX ) {
return 1 ;
}
if ( symbology = = BARCODE_EAN14 ) {
return 1 ;
}
if ( symbology = = BARCODE_NVE18 ) {
return 1 ;
}
if ( symbology = = BARCODE_KOREAPOST ) {
return 1 ;
}
if ( symbology = = BARCODE_PLESSEY ) {
return 1 ;
}
if ( symbology = = BARCODE_TELEPEN_NUM ) {
return 1 ;
}
if ( symbology = = BARCODE_ITF14 ) {
return 1 ;
}
if ( symbology = = BARCODE_CODE32 ) {
return 1 ;
}
return 0 ;
2008-12-25 00:29:31 +03:00
}
2016-02-20 12:38:03 +03:00
/* Indicates which symbols can have addon (EAN-2 and EAN-5) */
2016-02-29 22:42:32 +03:00
int is_extendable ( const int symbology ) {
2016-02-20 12:38:03 +03:00
if ( symbology = = BARCODE_EANX ) {
return 1 ;
}
if ( symbology = = BARCODE_UPCA ) {
return 1 ;
}
if ( symbology = = BARCODE_UPCE ) {
return 1 ;
}
if ( symbology = = BARCODE_ISBNX ) {
return 1 ;
}
if ( symbology = = BARCODE_UPCA_CC ) {
return 1 ;
}
if ( symbology = = BARCODE_UPCE_CC ) {
return 1 ;
}
if ( symbology = = BARCODE_EANX_CC ) {
return 1 ;
}
return 0 ;
2009-06-18 14:20:23 +04:00
}
2016-02-29 22:42:32 +03:00
int istwodigits ( const unsigned char source [ ] , const int position ) {
2016-02-20 12:38:03 +03:00
if ( ( source [ position ] > = ' 0 ' ) & & ( source [ position ] < = ' 9 ' ) ) {
if ( ( source [ position + 1 ] > = ' 0 ' ) & & ( source [ position + 1 ] < = ' 9 ' ) ) {
return 1 ;
}
}
2012-12-31 17:41:59 +04:00
2016-02-20 12:38:03 +03:00
return 0 ;
2009-07-05 00:48:42 +04:00
}
2016-02-29 22:42:32 +03:00
int utf8toutf16 ( struct zint_symbol * symbol , const unsigned char source [ ] , int vals [ ] , int * length ) {
2016-02-20 12:38:03 +03:00
int bpos , jpos , error_number ;
int next ;
bpos = 0 ;
jpos = 0 ;
error_number = 0 ;
next = 0 ;
do {
if ( source [ bpos ] < = 0x7f ) {
/* 1 byte mode (7-bit ASCII) */
vals [ jpos ] = source [ bpos ] ;
next = bpos + 1 ;
jpos + + ;
} else {
if ( ( source [ bpos ] > = 0x80 ) & & ( source [ bpos ] < = 0xbf ) ) {
strcpy ( symbol - > errtxt , " Corrupt Unicode data " ) ;
return ZINT_ERROR_INVALID_DATA ;
}
if ( ( source [ bpos ] > = 0xc0 ) & & ( source [ bpos ] < = 0xc1 ) ) {
strcpy ( symbol - > errtxt , " Overlong encoding not supported " ) ;
return ZINT_ERROR_INVALID_DATA ;
}
if ( ( source [ bpos ] > = 0xc2 ) & & ( source [ bpos ] < = 0xdf ) ) {
/* 2 byte mode */
vals [ jpos ] = ( ( source [ bpos ] & 0x1f ) < < 6 ) + ( source [ bpos + 1 ] & 0x3f ) ;
next = bpos + 2 ;
jpos + + ;
} else
if ( ( source [ bpos ] > = 0xe0 ) & & ( source [ bpos ] < = 0xef ) ) {
/* 3 byte mode */
vals [ jpos ] = ( ( source [ bpos ] & 0x0f ) < < 12 ) + ( ( source [ bpos + 1 ] & 0x3f ) < < 6 ) + ( source [ bpos + 2 ] & 0x3f ) ;
next = bpos + 3 ;
jpos + + ;
} else
if ( source [ bpos ] > = 0xf0 ) {
strcpy ( symbol - > errtxt , " Unicode sequences of more than 3 bytes not supported " ) ;
return ZINT_ERROR_INVALID_DATA ;
}
}
bpos = next ;
} while ( bpos < * length ) ;
* length = jpos ;
return error_number ;
2009-10-06 23:03:00 +04:00
}
2009-09-29 13:45:46 +04:00