2008-07-14 01:15:55 +04:00
/* common.c - Contains functions needed for a number of barcodes */
/*
libzint - the open source barcode library
2021-01-11 21:11:41 +03:00
Copyright ( C ) 2008 - 2021 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
*/
2019-10-17 12:06:21 +03:00
/* vim: set ts=4 sw=4 et : */
2020-12-21 22:30:07 +03:00
# ifdef ZINT_TEST
2008-07-14 01:15:55 +04:00
# include <stdio.h>
2020-12-21 22:30:07 +03:00
# endif
2020-05-02 03:02:37 +03:00
# ifdef _MSC_VER
# include <malloc.h>
# endif
2008-07-14 01:15:55 +04:00
# include "common.h"
2020-12-19 20:13:35 +03:00
/* Converts a character 0-9, A-F to its equivalent integer value */
2019-12-19 03:37:55 +03:00
INTERNAL int ctoi ( const char source ) {
2016-02-20 12:38:03 +03:00
if ( ( source > = ' 0 ' ) & & ( source < = ' 9 ' ) )
return ( source - ' 0 ' ) ;
2017-10-21 14:45:50 +03:00
if ( ( source > = ' A ' ) & & ( source < = ' F ' ) )
return ( source - ' A ' + 10 ) ;
if ( ( source > = ' a ' ) & & ( source < = ' f ' ) )
return ( source - ' a ' + 10 ) ;
return - 1 ;
2008-07-14 01:15:55 +04:00
}
2020-12-19 20:13:35 +03:00
/* Converts an integer value to its hexadecimal character */
INTERNAL char itoc ( const int source ) {
if ( ( source > = 0 ) & & ( source < = 9 ) ) {
return ( ' 0 ' + source ) ;
} else {
return ( ' A ' + ( source - 10 ) ) ;
}
2019-12-04 16:45:01 +03:00
}
2020-12-19 20:13:35 +03:00
/* Converts decimal string of length <= 9 to integer value. Returns -1 if not numeric */
INTERNAL int to_int ( const unsigned char source [ ] , const int length ) {
int val = 0 ;
2017-05-14 10:15:08 +03:00
int i ;
2017-10-23 22:37:52 +03:00
2017-05-14 10:15:08 +03:00
for ( i = 0 ; i < length ; i + + ) {
2020-12-19 20:13:35 +03:00
if ( source [ i ] < ' 0 ' | | source [ i ] > ' 9 ' ) {
return - 1 ;
2017-05-14 10:15:08 +03:00
}
2020-12-19 20:13:35 +03:00
val * = 10 ;
val + = source [ i ] - ' 0 ' ;
2017-05-14 10:15:08 +03:00
}
2020-12-19 20:13:35 +03:00
return val ;
2017-07-21 16:16:23 +03:00
}
2019-12-19 03:37:55 +03:00
2016-02-20 12:38:03 +03:00
/* Converts lower case characters to upper case in a string source[] */
2019-12-19 03:37:55 +03:00
INTERNAL void to_upper ( unsigned char source [ ] ) {
2020-12-19 20:13:35 +03:00
int i , src_len = ( int ) 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 ' ) ) {
2020-08-05 00:22:26 +03:00
source [ i ] = ( source [ i ] - ' a ' ) + ' A ' ;
2016-02-20 12:38:03 +03:00
}
}
2008-07-14 01:15:55 +04:00
}
2021-01-11 21:11:41 +03:00
/* Returns the number of times a character occurs in a string */
INTERNAL int chr_cnt ( const unsigned char string [ ] , const int length , const unsigned char c ) {
int count = 0 ;
int i ;
for ( i = 0 ; i < length ; i + + ) {
if ( string [ i ] = = c ) {
count + + ;
}
}
return count ;
}
2016-02-20 12:38:03 +03:00
/* Verifies that a string only uses valid characters */
2020-12-19 20:13:35 +03:00
INTERNAL int is_sane ( const char test_string [ ] , const unsigned char source [ ] , const int length ) {
int i , j , lt = ( int ) strlen ( test_string ) ;
2016-02-20 12:38:03 +03:00
for ( i = 0 ; i < length ; i + + ) {
2017-09-10 18:03:09 +03:00
unsigned int latch = FALSE ;
2016-02-20 12:38:03 +03:00
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
}
2017-05-29 12:43:47 +03:00
/* Replaces huge switch statements for looking up in tables */
2019-12-19 03:37:55 +03:00
INTERNAL void lookup ( const char set_string [ ] , const char * table [ ] , const char data , char dest [ ] ) {
2020-10-26 15:21:43 +03:00
int i , n = ( int ) 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 ] ) {
2017-05-29 12:43:47 +03:00
strcat ( dest , table [ i ] ) ;
2020-10-26 15:21:43 +03:00
break ;
2016-02-20 12:38:03 +03:00
}
}
2008-07-14 01:15:55 +04:00
}
2021-09-27 01:55:16 +03:00
/* Returns the position of data in set_string */
INTERNAL int posn ( const char set_string [ ] , const char data ) {
int i , n = ( int ) strlen ( set_string ) ;
for ( i = 0 ; i < n ; i + + ) {
if ( data = = set_string [ i ] ) {
return i ;
}
}
return - 1 ;
}
2020-12-19 20:13:35 +03:00
/* Convert an integer value to a string representing its binary equivalent */
INTERNAL void bin_append ( const int arg , const int length , char * binary ) {
int bin_posn = ( int ) strlen ( binary ) ;
bin_append_posn ( arg , length , binary , bin_posn ) ;
binary [ bin_posn + length ] = ' \0 ' ;
}
/* Convert an integer value to a string representing its binary equivalent at a set position */
INTERNAL int bin_append_posn ( const int arg , const int length , char * binary , const int bin_posn ) {
int i ;
int start ;
start = 0x01 < < ( length - 1 ) ;
for ( i = 0 ; i < length ; i + + ) {
if ( arg & ( start > > i ) ) {
binary [ bin_posn + i ] = ' 1 ' ;
} else {
binary [ bin_posn + i ] = ' 0 ' ;
}
}
return bin_posn + length ;
}
2020-11-01 21:32:55 +03:00
# ifndef COMMON_INLINE
/* Return true (1) if a module is dark/black, otherwise false (0) */
2019-12-19 03:37:55 +03:00
INTERNAL int module_is_set ( const struct zint_symbol * symbol , const int y_coord , const int x_coord ) {
2020-11-01 21:32:55 +03:00
return ( symbol - > encoded_data [ y_coord ] [ x_coord > > 3 ] > > ( x_coord & 0x07 ) ) & 1 ;
2009-06-01 00:33:54 +04:00
}
2016-02-20 12:38:03 +03:00
/* Set a module to dark/black */
2019-12-19 03:37:55 +03:00
INTERNAL void set_module ( struct zint_symbol * symbol , const int y_coord , const int x_coord ) {
2020-11-01 21:32:55 +03:00
symbol - > encoded_data [ y_coord ] [ x_coord > > 3 ] | = 1 < < ( x_coord & 0x07 ) ;
}
/* Return true (1-8) if a module is colour, otherwise false (0) */
INTERNAL int module_colour_is_set ( const struct zint_symbol * symbol , const int y_coord , const int x_coord ) {
return symbol - > encoded_data [ y_coord ] [ x_coord ] ;
2020-06-04 20:45:25 +03:00
}
/* Set a module to a colour */
INTERNAL void set_module_colour ( struct zint_symbol * symbol , const int y_coord , const int x_coord , const int colour ) {
symbol - > encoded_data [ y_coord ] [ x_coord ] = colour ;
2009-06-01 00:33:54 +04:00
}
2020-11-01 21:32:55 +03:00
# endif
2009-06-01 00:33:54 +04:00
2020-09-30 14:19:12 +03:00
/* Set a dark/black module to white (i.e. unset) */
2019-12-19 03:37:55 +03:00
INTERNAL void unset_module ( struct zint_symbol * symbol , const int y_coord , const int x_coord ) {
2020-11-01 21:32:55 +03:00
symbol - > encoded_data [ y_coord ] [ x_coord > > 3 ] & = ~ ( 1 < < ( x_coord & 0x07 ) ) ;
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 */
2019-12-19 03:37:55 +03:00
INTERNAL void expand ( struct zint_symbol * symbol , const char data [ ] ) {
2016-02-20 12:38:03 +03:00
2020-10-26 15:21:43 +03:00
int reader , n = ( int ) strlen ( data ) ;
2016-02-20 12:38:03 +03:00
int writer , i ;
2020-10-26 15:21:43 +03:00
int latch , num ;
2016-02-20 12:38:03 +03:00
writer = 0 ;
2020-10-26 15:21:43 +03:00
latch = 1 ;
2016-02-20 12:38:03 +03:00
for ( reader = 0 ; reader < n ; reader + + ) {
2020-10-26 15:21:43 +03:00
num = ctoi ( data [ reader ] ) ;
for ( i = 0 ; i < num ; i + + ) {
if ( latch ) {
2016-02-20 12:38:03 +03:00
set_module ( symbol , symbol - > rows , writer ) ;
}
writer + + ;
}
2020-10-26 15:21:43 +03:00
latch = ! latch ;
2016-02-20 12:38:03 +03:00
}
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
2020-09-30 14:19:12 +03:00
/* Indicates which symbologies can have row binding */
2019-12-19 03:37:55 +03:00
INTERNAL int is_stackable ( const int symbology ) {
2020-09-30 14:19:12 +03:00
if ( symbology < BARCODE_PHARMA_TWO & & symbology ! = BARCODE_POSTNET ) {
2017-05-29 12:43:47 +03:00
return 1 ;
2016-09-04 13:04:41 +03:00
}
2017-10-23 22:37:52 +03:00
2016-09-04 13:04:41 +03:00
switch ( symbology ) {
case BARCODE_CODE128B :
case BARCODE_ISBNX :
case BARCODE_EAN14 :
case BARCODE_NVE18 :
case BARCODE_KOREAPOST :
case BARCODE_PLESSEY :
case BARCODE_TELEPEN_NUM :
case BARCODE_ITF14 :
case BARCODE_CODE32 :
2016-09-12 23:47:40 +03:00
case BARCODE_CODABLOCKF :
2020-05-16 12:22:33 +03:00
case BARCODE_HIBC_BLOCKF :
2017-05-29 12:43:47 +03:00
return 1 ;
2020-12-19 20:13:35 +03:00
break ;
2016-09-04 13:04:41 +03:00
}
2017-05-29 12:43:47 +03:00
return 0 ;
2008-12-25 00:29:31 +03:00
}
2020-09-30 14:19:12 +03:00
/* Indicates which symbols can have addon (EAN-2 and EAN-5) */
2019-12-19 03:37:55 +03:00
INTERNAL int is_extendable ( const int symbology ) {
2020-07-15 21:00:12 +03:00
switch ( symbology ) {
case BARCODE_EANX :
case BARCODE_EANX_CHK :
case BARCODE_UPCA :
case BARCODE_UPCA_CHK :
case BARCODE_UPCE :
case BARCODE_UPCE_CHK :
case BARCODE_ISBNX :
case BARCODE_EANX_CC :
case BARCODE_UPCA_CC :
case BARCODE_UPCE_CC :
return 1 ;
2020-12-19 20:13:35 +03:00
break ;
2016-02-20 12:38:03 +03:00
}
return 0 ;
2009-06-18 14:20:23 +04:00
}
2019-10-17 12:06:21 +03:00
/* Indicates which symbols can have composite 2D component data */
2020-08-05 17:58:21 +03:00
INTERNAL int is_composite ( const int symbology ) {
2020-07-29 22:43:08 +03:00
return symbology > = BARCODE_EANX_CC & & symbology < = BARCODE_DBAR_EXPSTK_CC ;
2019-10-17 12:06:21 +03:00
}
2020-12-19 20:13:35 +03:00
/* Whether next two characters are digits */
2020-06-04 20:45:25 +03:00
INTERNAL int istwodigits ( const unsigned char source [ ] , const int length , const int position ) {
if ( ( position + 1 < length ) & & ( source [ position ] > = ' 0 ' ) & & ( source [ position ] < = ' 9 ' )
& & ( source [ position + 1 ] > = ' 0 ' ) & & ( source [ position + 1 ] < = ' 9 ' ) ) {
return 1 ;
2016-02-20 12:38:03 +03:00
}
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
}
2019-11-27 19:16:14 +03:00
/* State machine to decode UTF-8 to Unicode codepoints (state 0 means done, state 12 means error) */
2020-07-10 21:39:32 +03:00
INTERNAL unsigned int decode_utf8 ( unsigned int * state , unsigned int * codep , const unsigned char byte ) {
2019-11-27 19:16:14 +03:00
/*
Copyright ( c ) 2008 - 2009 Bjoern Hoehrmann < bjoern @ hoehrmann . de >
2021-06-19 15:11:23 +03:00
Permission is hereby granted , free of charge , to any person obtaining a copy of this software and associated
documentation files ( the " Software " ) , to deal in the Software without restriction , including without
limitation the rights to use , copy , modify , merge , publish , distribute , sublicense , and / or sell copies of the
Software , and to permit persons to whom the Software is furnished to do so , subject to the following
conditions :
2019-11-27 19:16:14 +03:00
2021-06-19 15:11:23 +03:00
The above copyright notice and this permission notice shall be included in all copies or substantial portions
of the Software .
2019-11-27 19:16:14 +03:00
See https : //bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
*/
static const unsigned char utf8d [ ] = {
/* The first part of the table maps bytes to character classes that
* reduce the size of the transition table and create bitmasks . */
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 ,
7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 ,
8 , 8 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,
10 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 3 , 3 , 11 , 6 , 6 , 6 , 5 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 ,
/* The second part is a transition table that maps a combination
* of a state of the automaton and a character class to a state . */
0 , 12 , 24 , 36 , 60 , 96 , 84 , 12 , 12 , 12 , 48 , 72 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 ,
12 , 0 , 12 , 12 , 12 , 12 , 12 , 0 , 12 , 0 , 12 , 12 , 12 , 24 , 12 , 12 , 12 , 12 , 12 , 24 , 12 , 24 , 12 , 12 ,
12 , 12 , 12 , 12 , 12 , 12 , 12 , 24 , 12 , 12 , 12 , 12 , 12 , 24 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 24 , 12 , 12 ,
12 , 12 , 12 , 12 , 12 , 12 , 12 , 36 , 12 , 36 , 12 , 12 , 12 , 36 , 12 , 12 , 12 , 12 , 12 , 36 , 12 , 36 , 12 , 12 ,
12 , 36 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 , 12 ,
} ;
unsigned int type = utf8d [ byte ] ;
* codep = * state ! = 0 ? ( byte & 0x3fu ) | ( * codep < < 6 ) : ( 0xff > > type ) & byte ;
* state = utf8d [ 256 + * state + type ] ;
return * state ;
}
2021-03-21 20:35:52 +03:00
/* Is string valid UTF-8? */
INTERNAL int is_valid_utf8 ( const unsigned char source [ ] , const int length ) {
int i ;
unsigned int codepoint , state = 0 ;
for ( i = 0 ; i < length ; i + + ) {
if ( decode_utf8 ( & state , & codepoint , source [ i ] ) = = 12 ) {
return 0 ;
}
}
return state = = 0 ;
}
2020-11-27 15:54:44 +03:00
/* Convert UTF-8 to Unicode. If `disallow_4byte` unset, allow all values (UTF-32). If `disallow_4byte` set,
* only allow codepoints < = U + FFFF ( ie four - byte sequences not allowed ) ( UTF - 16 , no surrogates ) */
INTERNAL int utf8_to_unicode ( struct zint_symbol * symbol , const unsigned char source [ ] , unsigned int vals [ ] ,
2020-12-19 20:13:35 +03:00
int * length , const int disallow_4byte ) {
2020-11-27 15:54:44 +03:00
int bpos ;
int jpos ;
2019-11-27 19:16:14 +03:00
unsigned int codepoint , state = 0 ;
2016-02-20 12:38:03 +03:00
bpos = 0 ;
jpos = 0 ;
2019-11-27 19:16:14 +03:00
while ( bpos < * length ) {
do {
decode_utf8 ( & state , & codepoint , source [ bpos + + ] ) ;
} while ( bpos < * length & & state ! = 0 & & state ! = 12 ) ;
if ( state ! = 0 ) {
strcpy ( symbol - > errtxt , " 240: Corrupt Unicode data " ) ;
return ZINT_ERROR_INVALID_DATA ;
}
2019-12-08 19:15:34 +03:00
if ( disallow_4byte & & codepoint > 0xffff ) {
2019-11-27 19:16:14 +03:00
strcpy ( symbol - > errtxt , " 242: Unicode sequences of more than 3 bytes not supported " ) ;
return ZINT_ERROR_INVALID_DATA ;
2016-02-20 12:38:03 +03:00
}
2019-11-27 19:16:14 +03:00
vals [ jpos ] = codepoint ;
jpos + + ;
}
2019-12-04 16:45:01 +03:00
2016-02-20 12:38:03 +03:00
* length = jpos ;
2019-11-27 19:16:14 +03:00
return 0 ;
2009-10-06 23:03:00 +04:00
}
2009-09-29 13:45:46 +04:00
2021-06-19 15:11:23 +03:00
/* Set symbol height, returning a warning if not within minimum and/or maximum if given.
` default_height ` does not include height of fixed - height rows ( i . e . separators / composite data ) */
INTERNAL int set_height ( struct zint_symbol * symbol , const float min_row_height , const float default_height ,
const float max_height , const int no_errtxt ) {
int error_number = 0 ;
float fixed_height = 0.0f ;
2016-10-14 20:56:49 +03:00
int zero_count = 0 ;
2021-06-19 15:11:23 +03:00
float row_height ;
2016-10-14 20:56:49 +03:00
int i ;
2021-06-19 15:11:23 +03:00
int rows = symbol - > rows ? symbol - > rows : 1 ; /* Sometimes called before expand() */
2017-10-23 22:37:52 +03:00
2021-06-19 15:11:23 +03:00
for ( i = 0 ; i < rows ; i + + ) {
if ( symbol - > row_height [ i ] ) {
fixed_height + = symbol - > row_height [ i ] ;
} else {
2016-10-14 20:56:49 +03:00
zero_count + + ;
}
}
2017-10-23 22:37:52 +03:00
2021-06-19 15:11:23 +03:00
if ( zero_count ) {
if ( symbol - > height ) {
Add compliant height, using ZINT_COMPLIANT_HEIGHT flag for back-compatibility
Rename barcode funcs to same as BARCODE_XXX name
library: barcode funcs array for dispatch, used for ZBarcode_ValidID() also
general: change is_sane() comparison to nonzero from ZINT_ERROR_INVALID_OPTION
MAILMARK: fuller error messages
CODABAR: add option to show check character in HRT
zint.h: use 0xNNNN for OR-able defines
GUI: add guard descent height reset button, add Zint version to window title,
static get_zint_version() method, use QStringLiteral (QSL shorthand),
use SIGNAL(toggled()), add errtxt "popup" and status bar, add icons,
add saveAs shortcut, add main menu, context menus and actions, add help,
reset_view() -> reset_colours(), add copy to clipboard as EMF/GIF/PNG/TIF,
lessen triggering of update_preview(), shorten names of getters/setters,
simplify/shorten some update_preview() logic in switch,
CODEONE disable structapp for Version S
qzint.cpp: add on_errored signal, add missing getters, add test
2021-10-09 02:13:39 +03:00
row_height = stripf ( ( symbol - > height - fixed_height ) / zero_count ) ;
2021-06-19 15:11:23 +03:00
} else if ( default_height ) {
Add compliant height, using ZINT_COMPLIANT_HEIGHT flag for back-compatibility
Rename barcode funcs to same as BARCODE_XXX name
library: barcode funcs array for dispatch, used for ZBarcode_ValidID() also
general: change is_sane() comparison to nonzero from ZINT_ERROR_INVALID_OPTION
MAILMARK: fuller error messages
CODABAR: add option to show check character in HRT
zint.h: use 0xNNNN for OR-able defines
GUI: add guard descent height reset button, add Zint version to window title,
static get_zint_version() method, use QStringLiteral (QSL shorthand),
use SIGNAL(toggled()), add errtxt "popup" and status bar, add icons,
add saveAs shortcut, add main menu, context menus and actions, add help,
reset_view() -> reset_colours(), add copy to clipboard as EMF/GIF/PNG/TIF,
lessen triggering of update_preview(), shorten names of getters/setters,
simplify/shorten some update_preview() logic in switch,
CODEONE disable structapp for Version S
qzint.cpp: add on_errored signal, add missing getters, add test
2021-10-09 02:13:39 +03:00
row_height = stripf ( default_height / zero_count ) ;
2021-06-19 15:11:23 +03:00
} else {
Add compliant height, using ZINT_COMPLIANT_HEIGHT flag for back-compatibility
Rename barcode funcs to same as BARCODE_XXX name
library: barcode funcs array for dispatch, used for ZBarcode_ValidID() also
general: change is_sane() comparison to nonzero from ZINT_ERROR_INVALID_OPTION
MAILMARK: fuller error messages
CODABAR: add option to show check character in HRT
zint.h: use 0xNNNN for OR-able defines
GUI: add guard descent height reset button, add Zint version to window title,
static get_zint_version() method, use QStringLiteral (QSL shorthand),
use SIGNAL(toggled()), add errtxt "popup" and status bar, add icons,
add saveAs shortcut, add main menu, context menus and actions, add help,
reset_view() -> reset_colours(), add copy to clipboard as EMF/GIF/PNG/TIF,
lessen triggering of update_preview(), shorten names of getters/setters,
simplify/shorten some update_preview() logic in switch,
CODEONE disable structapp for Version S
qzint.cpp: add on_errored signal, add missing getters, add test
2021-10-09 02:13:39 +03:00
row_height = stripf ( min_row_height ) ;
2021-06-19 15:11:23 +03:00
}
if ( row_height < 0.5f ) { /* Absolute minimum */
row_height = 0.5f ;
}
if ( min_row_height & & row_height < min_row_height ) {
error_number = ZINT_WARN_NONCOMPLIANT ;
if ( ! no_errtxt ) {
strcpy ( symbol - > errtxt , " 247: Height not compliant with standards " ) ;
2016-10-14 20:56:49 +03:00
}
}
Add compliant height, using ZINT_COMPLIANT_HEIGHT flag for back-compatibility
Rename barcode funcs to same as BARCODE_XXX name
library: barcode funcs array for dispatch, used for ZBarcode_ValidID() also
general: change is_sane() comparison to nonzero from ZINT_ERROR_INVALID_OPTION
MAILMARK: fuller error messages
CODABAR: add option to show check character in HRT
zint.h: use 0xNNNN for OR-able defines
GUI: add guard descent height reset button, add Zint version to window title,
static get_zint_version() method, use QStringLiteral (QSL shorthand),
use SIGNAL(toggled()), add errtxt "popup" and status bar, add icons,
add saveAs shortcut, add main menu, context menus and actions, add help,
reset_view() -> reset_colours(), add copy to clipboard as EMF/GIF/PNG/TIF,
lessen triggering of update_preview(), shorten names of getters/setters,
simplify/shorten some update_preview() logic in switch,
CODEONE disable structapp for Version S
qzint.cpp: add on_errored signal, add missing getters, add test
2021-10-09 02:13:39 +03:00
symbol - > height = stripf ( row_height * zero_count + fixed_height ) ;
2021-06-19 15:11:23 +03:00
} else {
Add compliant height, using ZINT_COMPLIANT_HEIGHT flag for back-compatibility
Rename barcode funcs to same as BARCODE_XXX name
library: barcode funcs array for dispatch, used for ZBarcode_ValidID() also
general: change is_sane() comparison to nonzero from ZINT_ERROR_INVALID_OPTION
MAILMARK: fuller error messages
CODABAR: add option to show check character in HRT
zint.h: use 0xNNNN for OR-able defines
GUI: add guard descent height reset button, add Zint version to window title,
static get_zint_version() method, use QStringLiteral (QSL shorthand),
use SIGNAL(toggled()), add errtxt "popup" and status bar, add icons,
add saveAs shortcut, add main menu, context menus and actions, add help,
reset_view() -> reset_colours(), add copy to clipboard as EMF/GIF/PNG/TIF,
lessen triggering of update_preview(), shorten names of getters/setters,
simplify/shorten some update_preview() logic in switch,
CODEONE disable structapp for Version S
qzint.cpp: add on_errored signal, add missing getters, add test
2021-10-09 02:13:39 +03:00
symbol - > height = stripf ( fixed_height ) ; /* Ignore any given height */
2021-06-19 15:11:23 +03:00
}
if ( max_height & & symbol - > height > max_height ) {
error_number = ZINT_WARN_NONCOMPLIANT ;
if ( ! no_errtxt ) {
strcpy ( symbol - > errtxt , " 248: Height not compliant with standards " ) ;
}
2016-10-14 20:56:49 +03:00
}
2021-06-19 15:11:23 +03:00
return error_number ;
2016-10-14 20:56:49 +03:00
}
2017-10-23 22:37:52 +03:00
Add Structured Append support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, MAXICODE, MICROPDF417, PDF417, QRCODE, ULTRA
DOTCODE: use pre-calculated generator poly coeffs in Reed-Solomon for
performance improvement
PDF417/MICROPDF417: use common routine pdf417_initial()
GUI: code lines <= 118, shorthand widget_obj(),
shorten calling upcean_addon_gap(), upcean_guard_descent()
various backend: var name debug -> debug_print
2021-09-28 23:42:44 +03:00
/* Removes excess precision from floats - see https://stackoverflow.com/q/503436 */
2021-09-27 01:55:16 +03:00
INTERNAL float stripf ( const float arg ) {
return * ( ( volatile const float * ) & arg ) ;
}
2020-12-19 20:13:35 +03:00
/* Returns red component if any of ultra colour indexing "0CBMRYGKW" */
INTERNAL int colour_to_red ( const int colour ) {
2020-08-12 15:19:56 +03:00
int return_val = 0 ;
2021-08-10 14:04:25 +03:00
switch ( colour ) {
2020-08-12 15:19:56 +03:00
case 8 : // White
case 3 : // Magenta
case 4 : // Red
case 5 : // Yellow
return_val = 255 ;
break ;
}
return return_val ;
}
2020-12-19 20:13:35 +03:00
/* Returns green component if any of ultra colour indexing "0CBMRYGKW" */
INTERNAL int colour_to_green ( const int colour ) {
2020-08-12 15:19:56 +03:00
int return_val = 0 ;
2021-08-10 14:04:25 +03:00
switch ( colour ) {
2020-08-12 15:19:56 +03:00
case 8 : // White
case 1 : // Cyan
case 5 : // Yellow
case 6 : // Green
return_val = 255 ;
break ;
}
return return_val ;
}
2020-12-19 20:13:35 +03:00
/* Returns blue component if any of ultra colour indexing "0CBMRYGKW" */
INTERNAL int colour_to_blue ( const int colour ) {
2020-08-12 15:19:56 +03:00
int return_val = 0 ;
2021-08-10 14:04:25 +03:00
switch ( colour ) {
2020-08-12 15:19:56 +03:00
case 8 : // White
case 1 : // Cyan
case 2 : // Blue
case 3 : // Magenta
return_val = 255 ;
break ;
}
return return_val ;
}
2019-12-19 03:37:55 +03:00
# ifdef ZINT_TEST
2019-12-16 20:31:52 +03:00
/* Dumps hex-formatted codewords in symbol->errtxt (for use in testing) */
2020-12-19 20:13:35 +03:00
void debug_test_codeword_dump ( struct zint_symbol * symbol , const unsigned char * codewords , const int length ) {
2019-12-16 20:31:52 +03:00
int i , max = length , cnt_len = 0 ;
if ( length > 30 ) { /* 30*3 < errtxt 92 (100 - "Warning ") chars */
sprintf ( symbol - > errtxt , " (%d) " , length ) ; /* Place the number of codewords at the front */
2021-06-10 13:15:39 +03:00
cnt_len = ( int ) strlen ( symbol - > errtxt ) ;
2019-12-16 20:31:52 +03:00
max = 30 - ( cnt_len + 2 ) / 3 ;
}
for ( i = 0 ; i < max ; i + + ) {
sprintf ( symbol - > errtxt + cnt_len + i * 3 , " %02X " , codewords [ i ] ) ;
}
symbol - > errtxt [ strlen ( symbol - > errtxt ) - 1 ] = ' \0 ' ; /* Zap last space */
}
2020-04-10 00:08:54 +03:00
2020-12-19 20:13:35 +03:00
/* Dumps decimal-formatted codewords in symbol->errtxt (for use in testing) */
void debug_test_codeword_dump_int ( struct zint_symbol * symbol , const int * codewords , const int length ) {
2020-04-10 00:08:54 +03:00
int i , max = 0 , cnt_len , errtxt_len ;
char temp [ 20 ] ;
errtxt_len = sprintf ( symbol - > errtxt , " (%d) " , length ) ; /* Place the number of codewords at the front */
for ( i = 0 , cnt_len = errtxt_len ; i < length ; i + + ) {
cnt_len + = sprintf ( temp , " %d " , codewords [ i ] ) ;
if ( cnt_len > 92 ) {
break ;
}
max + + ;
}
for ( i = 0 ; i < max ; i + + ) {
errtxt_len + = sprintf ( symbol - > errtxt + errtxt_len , " %d " , codewords [ i ] ) ;
}
symbol - > errtxt [ strlen ( symbol - > errtxt ) - 1 ] = ' \0 ' ; /* Zap last space */
}
2019-12-19 03:37:55 +03:00
# endif